mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-07-03 18:30:49 +02:00
bash-3.1 remove leftover and stray files
This commit is contained in:
@@ -1,54 +0,0 @@
|
||||
# simple makefile to create texindex
|
||||
#
|
||||
# Copyright (C) 1996 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 2, 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 USA.
|
||||
|
||||
topdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = .:@srcdir@
|
||||
BUILD_DIR = @BUILD_DIR@
|
||||
|
||||
CC = @CC@
|
||||
RM = rm
|
||||
|
||||
SHELL = @MAKE_SHELL@
|
||||
|
||||
DEFS = @DEFS@
|
||||
CFLAGS = @CFLAGS@ @LOCAL_CFLAGS@
|
||||
LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
|
||||
INCLUDES = -I. -I../.. -I$(topdir)
|
||||
|
||||
CCFLAGS = $(CFLAGS) $(DEFS) $(CPPFLAGS) ${INCLUDES}
|
||||
|
||||
.c.o:
|
||||
$(RM) -f $@
|
||||
$(CC) $(CCFLAGS) -c $<
|
||||
|
||||
OBJECTS = texindex.o getopt.o getopt1.o
|
||||
SOURCES = texindex.c getopt.c getopt1.c
|
||||
|
||||
all: texindex
|
||||
|
||||
texindex: $(OBJECTS)
|
||||
$(CC) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBS)
|
||||
|
||||
clean:
|
||||
$(RM) $(OBJECTS) texindex
|
||||
|
||||
distclean mostlyclean realclean maintainer-clean: clean
|
||||
$(RM) Makefile
|
||||
@@ -1,158 +0,0 @@
|
||||
## -*- text -*- ####################################################
|
||||
# #
|
||||
# Makefile for the GNU Glob Library. #
|
||||
# #
|
||||
####################################################################
|
||||
#
|
||||
# Copyright (C) 1996 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 2, 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 USA.
|
||||
|
||||
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
|
||||
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:
|
||||
$(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) $@ )
|
||||
|
||||
######################################################################
|
||||
# #
|
||||
# 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)/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
|
||||
@@ -1,888 +0,0 @@
|
||||
/* glob.c -- file-name wildcard pattern matching for Bash.
|
||||
|
||||
Copyright (C) 1985-2002 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 2, 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 USA. */
|
||||
|
||||
/* To whomever it may concern: I have never seen the code which most
|
||||
Unix programs use to perform this function. I wrote this from scratch
|
||||
based on specifications for the pattern matching. --RMS. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
|
||||
#pragma alloca
|
||||
#endif /* _AIX && RISC6000 && !__GNUC__ */
|
||||
|
||||
#include "bashtypes.h"
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "bashansi.h"
|
||||
#include "posixdir.h"
|
||||
#include "posixstat.h"
|
||||
#include "shmbutil.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
#include "filecntl.h"
|
||||
#if !defined (F_OK)
|
||||
# define F_OK 0
|
||||
#endif
|
||||
|
||||
#include "stdc.h"
|
||||
#include "memalloc.h"
|
||||
#include "quit.h"
|
||||
|
||||
#include "glob.h"
|
||||
#include "strmatch.h"
|
||||
|
||||
#if !defined (HAVE_BCOPY) && !defined (bcopy)
|
||||
# define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
|
||||
#endif /* !HAVE_BCOPY && !bcopy */
|
||||
|
||||
#if !defined (NULL)
|
||||
# if defined (__STDC__)
|
||||
# define NULL ((void *) 0)
|
||||
# else
|
||||
# define NULL 0x0
|
||||
# endif /* __STDC__ */
|
||||
#endif /* !NULL */
|
||||
|
||||
#if !defined (FREE)
|
||||
# define FREE(x) if (x) free (x)
|
||||
#endif
|
||||
|
||||
/* Don't try to alloca() more than this much memory for `struct globval'
|
||||
in glob_vector() */
|
||||
#ifndef ALLOCA_MAX
|
||||
# define ALLOCA_MAX 128 /* Testing, was 100000 */
|
||||
#endif
|
||||
|
||||
extern void throw_to_top_level __P((void));
|
||||
extern int test_eaccess __P((char *, int));
|
||||
|
||||
extern int extended_glob;
|
||||
|
||||
/* Global variable which controls whether or not * matches .*.
|
||||
Non-zero means don't match .*. */
|
||||
int noglob_dot_filenames = 1;
|
||||
|
||||
/* Global variable which controls whether or not filename globbing
|
||||
is done without regard to case. */
|
||||
int glob_ignore_case = 0;
|
||||
|
||||
/* Global variable to return to signify an error in globbing. */
|
||||
char *glob_error_return;
|
||||
|
||||
/* Some forward declarations. */
|
||||
static int skipname __P((char *, char *));
|
||||
#if HANDLE_MULTIBYTE
|
||||
static int mbskipname __P((char *, char *));
|
||||
#endif
|
||||
#if HANDLE_MULTIBYTE
|
||||
static void udequote_pathname __P((char *));
|
||||
static void wdequote_pathname __P((char *));
|
||||
#else
|
||||
# define dequote_pathname udequote_pathname
|
||||
#endif
|
||||
static void dequote_pathname __P((char *));
|
||||
static int glob_testdir __P((char *));
|
||||
static char **glob_dir_to_array __P((char *, char **, int));
|
||||
|
||||
/* Compile `glob_loop.c' for single-byte characters. */
|
||||
#define CHAR unsigned char
|
||||
#define INT int
|
||||
#define L(CS) CS
|
||||
#define INTERNAL_GLOB_PATTERN_P internal_glob_pattern_p
|
||||
#include "glob_loop.c"
|
||||
|
||||
/* Compile `glob_loop.c' again for multibyte characters. */
|
||||
#if HANDLE_MULTIBYTE
|
||||
|
||||
#define CHAR wchar_t
|
||||
#define INT wint_t
|
||||
#define L(CS) L##CS
|
||||
#define INTERNAL_GLOB_PATTERN_P internal_glob_wpattern_p
|
||||
#include "glob_loop.c"
|
||||
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
/* And now a function that calls either the single-byte or multibyte version
|
||||
of internal_glob_pattern_p. */
|
||||
int
|
||||
glob_pattern_p (pattern)
|
||||
const char *pattern;
|
||||
{
|
||||
#if HANDLE_MULTIBYTE
|
||||
size_t n;
|
||||
wchar_t *wpattern;
|
||||
int r;
|
||||
|
||||
if (MB_CUR_MAX == 1)
|
||||
return (internal_glob_pattern_p (pattern));
|
||||
|
||||
/* Convert strings to wide chars, and call the multibyte version. */
|
||||
n = xdupmbstowcs (&wpattern, NULL, pattern);
|
||||
if (n == (size_t)-1)
|
||||
/* Oops. Invalid multibyte sequence. Try it as single-byte sequence. */
|
||||
return (internal_glob_pattern_p (pattern));
|
||||
|
||||
r = internal_glob_wpattern_p (wpattern);
|
||||
free (wpattern);
|
||||
|
||||
return r;
|
||||
#else
|
||||
return (internal_glob_pattern_p (pattern));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return 1 if DNAME should be skipped according to PAT. Mostly concerned
|
||||
with matching leading `.'. */
|
||||
|
||||
static int
|
||||
skipname (pat, dname)
|
||||
char *pat;
|
||||
char *dname;
|
||||
{
|
||||
/* If a leading dot need not be explicitly matched, and the pattern
|
||||
doesn't start with a `.', don't match `.' or `..' */
|
||||
if (noglob_dot_filenames == 0 && pat[0] != '.' &&
|
||||
(pat[0] != '\\' || pat[1] != '.') &&
|
||||
(dname[0] == '.' &&
|
||||
(dname[1] == '\0' || (dname[1] == '.' && dname[2] == '\0'))))
|
||||
return 1;
|
||||
|
||||
/* If a dot must be explicity matched, check to see if they do. */
|
||||
else if (noglob_dot_filenames && dname[0] == '.' && pat[0] != '.' &&
|
||||
(pat[0] != '\\' || pat[1] != '.'))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if HANDLE_MULTIBYTE
|
||||
/* Return 1 if DNAME should be skipped according to PAT. Handles multibyte
|
||||
characters in PAT and DNAME. Mostly concerned with matching leading `.'. */
|
||||
|
||||
static int
|
||||
mbskipname (pat, dname)
|
||||
char *pat, *dname;
|
||||
{
|
||||
int ret;
|
||||
wchar_t *pat_wc, *dn_wc;
|
||||
size_t pat_n, dn_n, n;
|
||||
|
||||
pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
|
||||
dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
|
||||
|
||||
ret = 0;
|
||||
if (pat_n != (size_t)-1 && dn_n !=(size_t)-1)
|
||||
{
|
||||
/* If a leading dot need not be explicitly matched, and the
|
||||
pattern doesn't start with a `.', don't match `.' or `..' */
|
||||
if (noglob_dot_filenames == 0 && pat_wc[0] != L'.' &&
|
||||
(pat_wc[0] != L'\\' || pat_wc[1] != L'.') &&
|
||||
(dn_wc[0] == L'.' &&
|
||||
(dn_wc[1] == L'\0' || (dn_wc[1] == L'.' && dn_wc[2] == L'\0'))))
|
||||
ret = 1;
|
||||
|
||||
/* If a leading dot must be explicity matched, check to see if the
|
||||
pattern and dirname both have one. */
|
||||
else if (noglob_dot_filenames && dn_wc[0] == L'.' &&
|
||||
pat_wc[0] != L'.' &&
|
||||
(pat_wc[0] != L'\\' || pat_wc[1] != L'.'))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
FREE (pat_wc);
|
||||
FREE (dn_wc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
|
||||
static void
|
||||
udequote_pathname (pathname)
|
||||
char *pathname;
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
for (i = j = 0; pathname && pathname[i]; )
|
||||
{
|
||||
if (pathname[i] == '\\')
|
||||
i++;
|
||||
|
||||
pathname[j++] = pathname[i++];
|
||||
|
||||
if (pathname[i - 1] == 0)
|
||||
break;
|
||||
}
|
||||
pathname[j] = '\0';
|
||||
}
|
||||
|
||||
#if HANDLE_MULTIBYTE
|
||||
/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
|
||||
static void
|
||||
wdequote_pathname (pathname)
|
||||
char *pathname;
|
||||
{
|
||||
mbstate_t ps;
|
||||
size_t len, n;
|
||||
wchar_t *wpathname;
|
||||
int i, j;
|
||||
wchar_t *orig_wpathname;
|
||||
|
||||
len = strlen (pathname);
|
||||
/* Convert the strings into wide characters. */
|
||||
n = xdupmbstowcs (&wpathname, NULL, pathname);
|
||||
if (n == (size_t) -1)
|
||||
/* Something wrong. */
|
||||
return;
|
||||
orig_wpathname = wpathname;
|
||||
|
||||
for (i = j = 0; wpathname && wpathname[i]; )
|
||||
{
|
||||
if (wpathname[i] == L'\\')
|
||||
i++;
|
||||
|
||||
wpathname[j++] = wpathname[i++];
|
||||
|
||||
if (wpathname[i - 1] == L'\0')
|
||||
break;
|
||||
}
|
||||
wpathname[j] = L'\0';
|
||||
|
||||
/* Convert the wide character string into unibyte character set. */
|
||||
memset (&ps, '\0', sizeof(mbstate_t));
|
||||
n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps);
|
||||
pathname[len] = '\0';
|
||||
|
||||
/* Can't just free wpathname here; wcsrtombs changes it in many cases. */
|
||||
free (orig_wpathname);
|
||||
}
|
||||
|
||||
static void
|
||||
dequote_pathname (pathname)
|
||||
char *pathname;
|
||||
{
|
||||
if (MB_CUR_MAX > 1)
|
||||
wdequote_pathname (pathname);
|
||||
else
|
||||
udequote_pathname (pathname);
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
/* Test whether NAME exists. */
|
||||
|
||||
#if defined (HAVE_LSTAT)
|
||||
# define GLOB_TESTNAME(name) (lstat (name, &finfo))
|
||||
#else /* !HAVE_LSTAT */
|
||||
# if !defined (AFS)
|
||||
# define GLOB_TESTNAME(name) (test_eaccess (nextname, F_OK))
|
||||
# else /* AFS */
|
||||
# define GLOB_TESTNAME(name) (access (nextname, F_OK))
|
||||
# endif /* AFS */
|
||||
#endif /* !HAVE_LSTAT */
|
||||
|
||||
/* Return 0 if DIR is a directory, -1 otherwise. */
|
||||
static int
|
||||
glob_testdir (dir)
|
||||
char *dir;
|
||||
{
|
||||
struct stat finfo;
|
||||
|
||||
if (stat (dir, &finfo) < 0)
|
||||
return (-1);
|
||||
|
||||
if (S_ISDIR (finfo.st_mode) == 0)
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Return a vector of names of files in directory DIR
|
||||
whose names match glob pattern PAT.
|
||||
The names are not in any particular order.
|
||||
Wildcards at the beginning of PAT do not match an initial period.
|
||||
|
||||
The vector is terminated by an element that is a null pointer.
|
||||
|
||||
To free the space allocated, first free the vector's elements,
|
||||
then free the vector.
|
||||
|
||||
Return 0 if cannot get enough memory to hold the pointer
|
||||
and the names.
|
||||
|
||||
Return -1 if cannot access directory DIR.
|
||||
Look in errno for more information. */
|
||||
|
||||
char **
|
||||
glob_vector (pat, dir, flags)
|
||||
char *pat;
|
||||
char *dir;
|
||||
int flags;
|
||||
{
|
||||
struct globval
|
||||
{
|
||||
struct globval *next;
|
||||
char *name;
|
||||
};
|
||||
|
||||
DIR *d;
|
||||
register struct dirent *dp;
|
||||
struct globval *lastlink;
|
||||
register struct globval *nextlink;
|
||||
register char *nextname, *npat;
|
||||
unsigned int count;
|
||||
int lose, skip;
|
||||
register char **name_vector;
|
||||
register unsigned int i;
|
||||
int mflags; /* Flags passed to strmatch (). */
|
||||
int nalloca;
|
||||
struct globval *firstmalloc, *tmplink;
|
||||
|
||||
lastlink = 0;
|
||||
count = lose = skip = 0;
|
||||
|
||||
firstmalloc = 0;
|
||||
|
||||
/* If PAT is empty, skip the loop, but return one (empty) filename. */
|
||||
if (pat == 0 || *pat == '\0')
|
||||
{
|
||||
if (glob_testdir (dir) < 0)
|
||||
return ((char **) &glob_error_return);
|
||||
|
||||
nextlink = (struct globval *)alloca (sizeof (struct globval));
|
||||
if (nextlink == NULL)
|
||||
return ((char **) NULL);
|
||||
|
||||
nextlink->next = (struct globval *)0;
|
||||
nextname = (char *) malloc (1);
|
||||
if (nextname == 0)
|
||||
lose = 1;
|
||||
else
|
||||
{
|
||||
lastlink = nextlink;
|
||||
nextlink->name = nextname;
|
||||
nextname[0] = '\0';
|
||||
count = 1;
|
||||
}
|
||||
|
||||
skip = 1;
|
||||
}
|
||||
|
||||
/* If the filename pattern (PAT) does not contain any globbing characters,
|
||||
we can dispense with reading the directory, and just see if there is
|
||||
a filename `DIR/PAT'. If there is, and we can access it, just make the
|
||||
vector to return and bail immediately. */
|
||||
if (skip == 0 && glob_pattern_p (pat) == 0)
|
||||
{
|
||||
int dirlen;
|
||||
struct stat finfo;
|
||||
|
||||
if (glob_testdir (dir) < 0)
|
||||
return ((char **) &glob_error_return);
|
||||
|
||||
dirlen = strlen (dir);
|
||||
nextname = (char *)malloc (dirlen + strlen (pat) + 2);
|
||||
npat = (char *)malloc (strlen (pat) + 1);
|
||||
if (nextname == 0 || npat == 0)
|
||||
lose = 1;
|
||||
else
|
||||
{
|
||||
strcpy (npat, pat);
|
||||
dequote_pathname (npat);
|
||||
|
||||
strcpy (nextname, dir);
|
||||
nextname[dirlen++] = '/';
|
||||
strcpy (nextname + dirlen, npat);
|
||||
|
||||
if (GLOB_TESTNAME (nextname) >= 0)
|
||||
{
|
||||
free (nextname);
|
||||
nextlink = (struct globval *)alloca (sizeof (struct globval));
|
||||
if (nextlink)
|
||||
{
|
||||
nextlink->next = (struct globval *)0;
|
||||
lastlink = nextlink;
|
||||
nextlink->name = npat;
|
||||
count = 1;
|
||||
}
|
||||
else
|
||||
lose = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
free (nextname);
|
||||
free (npat);
|
||||
}
|
||||
}
|
||||
|
||||
skip = 1;
|
||||
}
|
||||
|
||||
if (skip == 0)
|
||||
{
|
||||
/* Open the directory, punting immediately if we cannot. If opendir
|
||||
is not robust (i.e., it opens non-directories successfully), test
|
||||
that DIR is a directory and punt if it's not. */
|
||||
#if defined (OPENDIR_NOT_ROBUST)
|
||||
if (glob_testdir (dir) < 0)
|
||||
return ((char **) &glob_error_return);
|
||||
#endif
|
||||
|
||||
d = opendir (dir);
|
||||
if (d == NULL)
|
||||
return ((char **) &glob_error_return);
|
||||
|
||||
/* Compute the flags that will be passed to strmatch(). We don't
|
||||
need to do this every time through the loop. */
|
||||
mflags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
|
||||
|
||||
#ifdef FNM_CASEFOLD
|
||||
if (glob_ignore_case)
|
||||
mflags |= FNM_CASEFOLD;
|
||||
#endif
|
||||
|
||||
if (extended_glob)
|
||||
mflags |= FNM_EXTMATCH;
|
||||
|
||||
/* Scan the directory, finding all names that match.
|
||||
For each name that matches, allocate a struct globval
|
||||
on the stack and store the name in it.
|
||||
Chain those structs together; lastlink is the front of the chain. */
|
||||
while (1)
|
||||
{
|
||||
/* Make globbing interruptible in the shell. */
|
||||
if (interrupt_state)
|
||||
{
|
||||
lose = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
dp = readdir (d);
|
||||
if (dp == NULL)
|
||||
break;
|
||||
|
||||
/* If this directory entry is not to be used, try again. */
|
||||
if (REAL_DIR_ENTRY (dp) == 0)
|
||||
continue;
|
||||
|
||||
#if 0
|
||||
if (dp->d_name == 0 || *dp->d_name == 0)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
#if HANDLE_MULTIBYTE
|
||||
if (MB_CUR_MAX > 1 && mbskipname (pat, dp->d_name))
|
||||
continue;
|
||||
else
|
||||
#endif
|
||||
if (skipname (pat, dp->d_name))
|
||||
continue;
|
||||
|
||||
if (strmatch (pat, dp->d_name, mflags) != FNM_NOMATCH)
|
||||
{
|
||||
if (nalloca < ALLOCA_MAX)
|
||||
{
|
||||
nextlink = (struct globval *) alloca (sizeof (struct globval));
|
||||
nalloca += sizeof (struct globval);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextlink = (struct globval *) malloc (sizeof (struct globval));
|
||||
if (firstmalloc == 0)
|
||||
firstmalloc = nextlink;
|
||||
}
|
||||
nextname = (char *) malloc (D_NAMLEN (dp) + 1);
|
||||
if (nextlink == 0 || nextname == 0)
|
||||
{
|
||||
lose = 1;
|
||||
break;
|
||||
}
|
||||
nextlink->next = lastlink;
|
||||
lastlink = nextlink;
|
||||
nextlink->name = nextname;
|
||||
bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
(void) closedir (d);
|
||||
}
|
||||
|
||||
if (lose == 0)
|
||||
{
|
||||
name_vector = (char **) malloc ((count + 1) * sizeof (char *));
|
||||
lose |= name_vector == NULL;
|
||||
}
|
||||
|
||||
/* Have we run out of memory? */
|
||||
if (lose)
|
||||
{
|
||||
tmplink = 0;
|
||||
|
||||
/* Here free the strings we have got. */
|
||||
while (lastlink)
|
||||
{
|
||||
if (firstmalloc)
|
||||
{
|
||||
if (lastlink == firstmalloc)
|
||||
firstmalloc = 0;
|
||||
tmplink = lastlink;
|
||||
}
|
||||
free (lastlink->name);
|
||||
lastlink = lastlink->next;
|
||||
FREE (tmplink);
|
||||
}
|
||||
|
||||
QUIT;
|
||||
|
||||
return ((char **)NULL);
|
||||
}
|
||||
|
||||
|
||||
tmplink = lastlink; /* save in case we need to free */
|
||||
/* Copy the name pointers from the linked list into the vector. */
|
||||
for (i = 0; i < count; ++i)
|
||||
{
|
||||
name_vector[i] = lastlink->name;
|
||||
lastlink = lastlink->next;
|
||||
}
|
||||
lastlink = tmplink; /* restore in case we need to free */
|
||||
|
||||
name_vector[count] = NULL;
|
||||
|
||||
/* If we allocated some of the struct globvals, free them now. */
|
||||
if (firstmalloc)
|
||||
{
|
||||
tmplink = 0;
|
||||
while (lastlink)
|
||||
{
|
||||
tmplink = lastlink;
|
||||
if (lastlink == firstmalloc)
|
||||
lastlink = firstmalloc = 0;
|
||||
else
|
||||
lastlink = lastlink->next;
|
||||
free (tmplink);
|
||||
}
|
||||
}
|
||||
|
||||
return (name_vector);
|
||||
}
|
||||
|
||||
/* Return a new array which is the concatenation of each string in ARRAY
|
||||
to DIR. This function expects you to pass in an allocated ARRAY, and
|
||||
it takes care of free()ing that array. Thus, you might think of this
|
||||
function as side-effecting ARRAY. This should handle GX_MARKDIRS. */
|
||||
static char **
|
||||
glob_dir_to_array (dir, array, flags)
|
||||
char *dir, **array;
|
||||
int flags;
|
||||
{
|
||||
register unsigned int i, l;
|
||||
int add_slash;
|
||||
char **result, *new;
|
||||
struct stat sb;
|
||||
|
||||
l = strlen (dir);
|
||||
if (l == 0)
|
||||
{
|
||||
if (flags & GX_MARKDIRS)
|
||||
for (i = 0; array[i]; i++)
|
||||
{
|
||||
if ((stat (array[i], &sb) == 0) && S_ISDIR (sb.st_mode))
|
||||
{
|
||||
l = strlen (array[i]);
|
||||
new = (char *)realloc (array[i], l + 2);
|
||||
if (new == 0)
|
||||
return NULL;
|
||||
new[l] = '/';
|
||||
new[l+1] = '\0';
|
||||
array[i] = new;
|
||||
}
|
||||
}
|
||||
return (array);
|
||||
}
|
||||
|
||||
add_slash = dir[l - 1] != '/';
|
||||
|
||||
i = 0;
|
||||
while (array[i] != NULL)
|
||||
++i;
|
||||
|
||||
result = (char **) malloc ((i + 1) * sizeof (char *));
|
||||
if (result == NULL)
|
||||
return (NULL);
|
||||
|
||||
for (i = 0; array[i] != NULL; i++)
|
||||
{
|
||||
/* 3 == 1 for NUL, 1 for slash at end of DIR, 1 for GX_MARKDIRS */
|
||||
result[i] = (char *) malloc (l + strlen (array[i]) + 3);
|
||||
|
||||
if (result[i] == NULL)
|
||||
return (NULL);
|
||||
|
||||
strcpy (result[i], dir);
|
||||
if (add_slash)
|
||||
result[i][l] = '/';
|
||||
strcpy (result[i] + l + add_slash, array[i]);
|
||||
if (flags & GX_MARKDIRS)
|
||||
{
|
||||
if ((stat (result[i], &sb) == 0) && S_ISDIR (sb.st_mode))
|
||||
{
|
||||
size_t rlen;
|
||||
rlen = strlen (result[i]);
|
||||
result[i][rlen] = '/';
|
||||
result[i][rlen+1] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
result[i] = NULL;
|
||||
|
||||
/* Free the input array. */
|
||||
for (i = 0; array[i] != NULL; i++)
|
||||
free (array[i]);
|
||||
free ((char *) array);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* Do globbing on PATHNAME. Return an array of pathnames that match,
|
||||
marking the end of the array with a null-pointer as an element.
|
||||
If no pathnames match, then the array is empty (first element is null).
|
||||
If there isn't enough memory, then return NULL.
|
||||
If a file system error occurs, return -1; `errno' has the error code. */
|
||||
char **
|
||||
glob_filename (pathname, flags)
|
||||
char *pathname;
|
||||
int flags;
|
||||
{
|
||||
char **result;
|
||||
unsigned int result_size;
|
||||
char *directory_name, *filename;
|
||||
unsigned int directory_len;
|
||||
int free_dirname; /* flag */
|
||||
|
||||
result = (char **) malloc (sizeof (char *));
|
||||
result_size = 1;
|
||||
if (result == NULL)
|
||||
return (NULL);
|
||||
|
||||
result[0] = NULL;
|
||||
|
||||
directory_name = NULL;
|
||||
|
||||
/* Find the filename. */
|
||||
filename = strrchr (pathname, '/');
|
||||
if (filename == NULL)
|
||||
{
|
||||
filename = pathname;
|
||||
directory_name = "";
|
||||
directory_len = 0;
|
||||
free_dirname = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
directory_len = (filename - pathname) + 1;
|
||||
directory_name = (char *) malloc (directory_len + 1);
|
||||
|
||||
if (directory_name == 0) /* allocation failed? */
|
||||
return (NULL);
|
||||
|
||||
bcopy (pathname, directory_name, directory_len);
|
||||
directory_name[directory_len] = '\0';
|
||||
++filename;
|
||||
free_dirname = 1;
|
||||
}
|
||||
|
||||
/* If directory_name contains globbing characters, then we
|
||||
have to expand the previous levels. Just recurse. */
|
||||
if (glob_pattern_p (directory_name))
|
||||
{
|
||||
char **directories;
|
||||
register unsigned int i;
|
||||
|
||||
if (directory_name[directory_len - 1] == '/')
|
||||
directory_name[directory_len - 1] = '\0';
|
||||
|
||||
directories = glob_filename (directory_name, flags & ~GX_MARKDIRS);
|
||||
|
||||
if (free_dirname)
|
||||
{
|
||||
free (directory_name);
|
||||
directory_name = NULL;
|
||||
}
|
||||
|
||||
if (directories == NULL)
|
||||
goto memory_error;
|
||||
else if (directories == (char **)&glob_error_return)
|
||||
{
|
||||
free ((char *) result);
|
||||
return ((char **) &glob_error_return);
|
||||
}
|
||||
else if (*directories == NULL)
|
||||
{
|
||||
free ((char *) directories);
|
||||
free ((char *) result);
|
||||
return ((char **) &glob_error_return);
|
||||
}
|
||||
|
||||
/* We have successfully globbed the preceding directory name.
|
||||
For each name in DIRECTORIES, call glob_vector on it and
|
||||
FILENAME. Concatenate the results together. */
|
||||
for (i = 0; directories[i] != NULL; ++i)
|
||||
{
|
||||
char **temp_results;
|
||||
|
||||
/* Scan directory even on a NULL pathname. That way, `*h/'
|
||||
returns only directories ending in `h', instead of all
|
||||
files ending in `h' with a `/' appended. */
|
||||
temp_results = glob_vector (filename, directories[i], flags & ~GX_MARKDIRS);
|
||||
|
||||
/* Handle error cases. */
|
||||
if (temp_results == NULL)
|
||||
goto memory_error;
|
||||
else if (temp_results == (char **)&glob_error_return)
|
||||
/* This filename is probably not a directory. Ignore it. */
|
||||
;
|
||||
else
|
||||
{
|
||||
char **array;
|
||||
register unsigned int l;
|
||||
|
||||
array = glob_dir_to_array (directories[i], temp_results, flags);
|
||||
l = 0;
|
||||
while (array[l] != NULL)
|
||||
++l;
|
||||
|
||||
result =
|
||||
(char **)realloc (result, (result_size + l) * sizeof (char *));
|
||||
|
||||
if (result == NULL)
|
||||
goto memory_error;
|
||||
|
||||
for (l = 0; array[l] != NULL; ++l)
|
||||
result[result_size++ - 1] = array[l];
|
||||
|
||||
result[result_size - 1] = NULL;
|
||||
|
||||
/* Note that the elements of ARRAY are not freed. */
|
||||
free ((char *) array);
|
||||
}
|
||||
}
|
||||
/* Free the directories. */
|
||||
for (i = 0; directories[i]; i++)
|
||||
free (directories[i]);
|
||||
|
||||
free ((char *) directories);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* If there is only a directory name, return it. */
|
||||
if (*filename == '\0')
|
||||
{
|
||||
result = (char **) realloc ((char *) result, 2 * sizeof (char *));
|
||||
if (result == NULL)
|
||||
return (NULL);
|
||||
/* Handle GX_MARKDIRS here. */
|
||||
result[0] = (char *) malloc (directory_len + 1);
|
||||
if (result[0] == NULL)
|
||||
goto memory_error;
|
||||
bcopy (directory_name, result[0], directory_len + 1);
|
||||
if (free_dirname)
|
||||
free (directory_name);
|
||||
result[1] = NULL;
|
||||
return (result);
|
||||
}
|
||||
else
|
||||
{
|
||||
char **temp_results;
|
||||
|
||||
/* There are no unquoted globbing characters in DIRECTORY_NAME.
|
||||
Dequote it before we try to open the directory since there may
|
||||
be quoted globbing characters which should be treated verbatim. */
|
||||
if (directory_len > 0)
|
||||
dequote_pathname (directory_name);
|
||||
|
||||
/* We allocated a small array called RESULT, which we won't be using.
|
||||
Free that memory now. */
|
||||
free (result);
|
||||
|
||||
/* Just return what glob_vector () returns appended to the
|
||||
directory name. */
|
||||
temp_results = glob_vector (filename,
|
||||
(directory_len == 0 ? "." : directory_name),
|
||||
flags & ~GX_MARKDIRS);
|
||||
|
||||
if (temp_results == NULL || temp_results == (char **)&glob_error_return)
|
||||
{
|
||||
if (free_dirname)
|
||||
free (directory_name);
|
||||
return (temp_results);
|
||||
}
|
||||
|
||||
result = glob_dir_to_array (directory_name, temp_results, flags);
|
||||
if (free_dirname)
|
||||
free (directory_name);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* We get to memory_error if the program has run out of memory, or
|
||||
if this is the shell, and we have been interrupted. */
|
||||
memory_error:
|
||||
if (result != NULL)
|
||||
{
|
||||
register unsigned int i;
|
||||
for (i = 0; result[i] != NULL; ++i)
|
||||
free (result[i]);
|
||||
free ((char *) result);
|
||||
}
|
||||
|
||||
if (free_dirname && directory_name)
|
||||
free (directory_name);
|
||||
|
||||
QUIT;
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#if defined (TEST)
|
||||
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 1; i < argc; ++i)
|
||||
{
|
||||
char **value = glob_filename (argv[i], 0);
|
||||
if (value == NULL)
|
||||
puts ("Out of memory.");
|
||||
else if (value == &glob_error_return)
|
||||
perror (argv[i]);
|
||||
else
|
||||
for (i = 0; value[i] != NULL; i++)
|
||||
puts (value[i]);
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
#endif /* TEST. */
|
||||
@@ -1,885 +0,0 @@
|
||||
/* glob.c -- file-name wildcard pattern matching for Bash.
|
||||
|
||||
Copyright (C) 1985-2002 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 2, 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 USA. */
|
||||
|
||||
/* To whomever it may concern: I have never seen the code which most
|
||||
Unix programs use to perform this function. I wrote this from scratch
|
||||
based on specifications for the pattern matching. --RMS. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
|
||||
#pragma alloca
|
||||
#endif /* _AIX && RISC6000 && !__GNUC__ */
|
||||
|
||||
#include "bashtypes.h"
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "bashansi.h"
|
||||
#include "posixdir.h"
|
||||
#include "posixstat.h"
|
||||
#include "shmbutil.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
#include "filecntl.h"
|
||||
#if !defined (F_OK)
|
||||
# define F_OK 0
|
||||
#endif
|
||||
|
||||
#include "stdc.h"
|
||||
#include "memalloc.h"
|
||||
#include "quit.h"
|
||||
|
||||
#include "glob.h"
|
||||
#include "strmatch.h"
|
||||
|
||||
#if !defined (HAVE_BCOPY) && !defined (bcopy)
|
||||
# define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
|
||||
#endif /* !HAVE_BCOPY && !bcopy */
|
||||
|
||||
#if !defined (NULL)
|
||||
# if defined (__STDC__)
|
||||
# define NULL ((void *) 0)
|
||||
# else
|
||||
# define NULL 0x0
|
||||
# endif /* __STDC__ */
|
||||
#endif /* !NULL */
|
||||
|
||||
#if !defined (FREE)
|
||||
# define FREE(x) if (x) free (x)
|
||||
#endif
|
||||
|
||||
/* Don't try to alloca() more than this much memory for `struct globval'
|
||||
in glob_vector() */
|
||||
#ifndef ALLOCA_MAX
|
||||
# define ALLOCA_MAX 128 /* Testing, was 100000 */
|
||||
#endif
|
||||
|
||||
extern void throw_to_top_level __P((void));
|
||||
extern int test_eaccess __P((char *, int));
|
||||
|
||||
extern int extended_glob;
|
||||
|
||||
/* Global variable which controls whether or not * matches .*.
|
||||
Non-zero means don't match .*. */
|
||||
int noglob_dot_filenames = 1;
|
||||
|
||||
/* Global variable which controls whether or not filename globbing
|
||||
is done without regard to case. */
|
||||
int glob_ignore_case = 0;
|
||||
|
||||
/* Global variable to return to signify an error in globbing. */
|
||||
char *glob_error_return;
|
||||
|
||||
/* Some forward declarations. */
|
||||
static int skipname __P((char *, char *));
|
||||
#if HANDLE_MULTIBYTE
|
||||
static int mbskipname __P((char *, char *));
|
||||
#endif
|
||||
#if HANDLE_MULTIBYTE
|
||||
static void udequote_pathname __P((char *));
|
||||
static void wdequote_pathname __P((char *));
|
||||
#else
|
||||
# define dequote_pathname udequote_pathname
|
||||
#endif
|
||||
static void dequote_pathname __P((char *));
|
||||
static int glob_testdir __P((char *));
|
||||
static char **glob_dir_to_array __P((char *, char **, int));
|
||||
|
||||
/* Compile `glob_loop.c' for single-byte characters. */
|
||||
#define CHAR unsigned char
|
||||
#define INT int
|
||||
#define L(CS) CS
|
||||
#define INTERNAL_GLOB_PATTERN_P internal_glob_pattern_p
|
||||
#include "glob_loop.c"
|
||||
|
||||
/* Compile `glob_loop.c' again for multibyte characters. */
|
||||
#if HANDLE_MULTIBYTE
|
||||
|
||||
#define CHAR wchar_t
|
||||
#define INT wint_t
|
||||
#define L(CS) L##CS
|
||||
#define INTERNAL_GLOB_PATTERN_P internal_glob_wpattern_p
|
||||
#include "glob_loop.c"
|
||||
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
/* And now a function that calls either the single-byte or multibyte version
|
||||
of internal_glob_pattern_p. */
|
||||
int
|
||||
glob_pattern_p (pattern)
|
||||
const char *pattern;
|
||||
{
|
||||
#if HANDLE_MULTIBYTE
|
||||
size_t n;
|
||||
wchar_t *wpattern;
|
||||
int r;
|
||||
|
||||
if (MB_CUR_MAX == 1)
|
||||
return (internal_glob_pattern_p (pattern));
|
||||
|
||||
/* Convert strings to wide chars, and call the multibyte version. */
|
||||
n = xdupmbstowcs (&wpattern, NULL, pattern);
|
||||
if (n == (size_t)-1)
|
||||
/* Oops. Invalid multibyte sequence. Try it as single-byte sequence. */
|
||||
return (internal_glob_pattern_p (pattern));
|
||||
|
||||
r = internal_glob_wpattern_p (wpattern);
|
||||
free (wpattern);
|
||||
|
||||
return r;
|
||||
#else
|
||||
return (internal_glob_pattern_p (pattern));
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Return 1 if DNAME should be skipped according to PAT. Mostly concerned
|
||||
with matching leading `.'. */
|
||||
|
||||
static int
|
||||
skipname (pat, dname)
|
||||
char *pat;
|
||||
char *dname;
|
||||
{
|
||||
/* If a leading dot need not be explicitly matched, and the pattern
|
||||
doesn't start with a `.', don't match `.' or `..' */
|
||||
if (noglob_dot_filenames == 0 && pat[0] != '.' &&
|
||||
(pat[0] != '\\' || pat[1] != '.') &&
|
||||
(dname[0] == '.' &&
|
||||
(dname[1] == '\0' || (dname[1] == '.' && dname[2] == '\0'))))
|
||||
return 1;
|
||||
|
||||
/* If a dot must be explicity matched, check to see if they do. */
|
||||
else if (noglob_dot_filenames && dname[0] == '.' && pat[0] != '.' &&
|
||||
(pat[0] != '\\' || pat[1] != '.'))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if HANDLE_MULTIBYTE
|
||||
/* Return 1 if DNAME should be skipped according to PAT. Handles multibyte
|
||||
characters in PAT and DNAME. Mostly concerned with matching leading `.'. */
|
||||
|
||||
static int
|
||||
mbskipname (pat, dname)
|
||||
char *pat, *dname;
|
||||
{
|
||||
int ret;
|
||||
wchar_t *pat_wc, *dn_wc;
|
||||
size_t pat_n, dn_n, n;
|
||||
|
||||
pat_n = xdupmbstowcs (&pat_wc, NULL, pat);
|
||||
dn_n = xdupmbstowcs (&dn_wc, NULL, dname);
|
||||
|
||||
ret = 0;
|
||||
if (pat_n != (size_t)-1 && dn_n !=(size_t)-1)
|
||||
{
|
||||
/* If a leading dot need not be explicitly matched, and the
|
||||
pattern doesn't start with a `.', don't match `.' or `..' */
|
||||
if (noglob_dot_filenames == 0 && pat_wc[0] != L'.' &&
|
||||
(pat_wc[0] != L'\\' || pat_wc[1] != L'.') &&
|
||||
(dn_wc[0] == L'.' &&
|
||||
(dn_wc[1] == L'\0' || (dn_wc[1] == L'.' && dn_wc[2] == L'\0'))))
|
||||
ret = 1;
|
||||
|
||||
/* If a leading dot must be explicity matched, check to see if the
|
||||
pattern and dirname both have one. */
|
||||
else if (noglob_dot_filenames && dn_wc[0] == L'.' &&
|
||||
pat_wc[0] != L'.' &&
|
||||
(pat_wc[0] != L'\\' || pat_wc[1] != L'.'))
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
FREE (pat_wc);
|
||||
FREE (dn_wc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
|
||||
static void
|
||||
udequote_pathname (pathname)
|
||||
char *pathname;
|
||||
{
|
||||
register int i, j;
|
||||
|
||||
for (i = j = 0; pathname && pathname[i]; )
|
||||
{
|
||||
if (pathname[i] == '\\')
|
||||
i++;
|
||||
|
||||
pathname[j++] = pathname[i++];
|
||||
|
||||
if (pathname[i - 1] == 0)
|
||||
break;
|
||||
}
|
||||
pathname[j] = '\0';
|
||||
}
|
||||
|
||||
#if HANDLE_MULTIBYTE
|
||||
/* Remove backslashes quoting characters in PATHNAME by modifying PATHNAME. */
|
||||
static void
|
||||
wdequote_pathname (pathname)
|
||||
char *pathname;
|
||||
{
|
||||
mbstate_t ps;
|
||||
size_t len, n;
|
||||
wchar_t *wpathname;
|
||||
int i, j;
|
||||
wchar_t *orig_wpathname;
|
||||
|
||||
len = strlen (pathname);
|
||||
/* Convert the strings into wide characters. */
|
||||
n = xdupmbstowcs (&wpathname, NULL, pathname);
|
||||
if (n == (size_t) -1)
|
||||
/* Something wrong. */
|
||||
return;
|
||||
orig_wpathname = wpathname;
|
||||
|
||||
for (i = j = 0; wpathname && wpathname[i]; )
|
||||
{
|
||||
if (wpathname[i] == L'\\')
|
||||
i++;
|
||||
|
||||
wpathname[j++] = wpathname[i++];
|
||||
|
||||
if (wpathname[i - 1] == L'\0')
|
||||
break;
|
||||
}
|
||||
wpathname[j] = L'\0';
|
||||
|
||||
/* Convert the wide character string into unibyte character set. */
|
||||
memset (&ps, '\0', sizeof(mbstate_t));
|
||||
n = wcsrtombs(pathname, (const wchar_t **)&wpathname, len, &ps);
|
||||
pathname[len] = '\0';
|
||||
|
||||
/* Can't just free wpathname here; wcsrtombs changes it in many cases. */
|
||||
free (orig_wpathname);
|
||||
}
|
||||
|
||||
static void
|
||||
dequote_pathname (pathname)
|
||||
char *pathname;
|
||||
{
|
||||
if (MB_CUR_MAX > 1)
|
||||
wdequote_pathname (pathname);
|
||||
else
|
||||
udequote_pathname (pathname);
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
/* Test whether NAME exists. */
|
||||
|
||||
#if defined (HAVE_LSTAT)
|
||||
# define GLOB_TESTNAME(name) (lstat (name, &finfo))
|
||||
#else /* !HAVE_LSTAT */
|
||||
# if !defined (AFS)
|
||||
# define GLOB_TESTNAME(name) (test_eaccess (nextname, F_OK))
|
||||
# else /* AFS */
|
||||
# define GLOB_TESTNAME(name) (access (nextname, F_OK))
|
||||
# endif /* AFS */
|
||||
#endif /* !HAVE_LSTAT */
|
||||
|
||||
/* Return 0 if DIR is a directory, -1 otherwise. */
|
||||
static int
|
||||
glob_testdir (dir)
|
||||
char *dir;
|
||||
{
|
||||
struct stat finfo;
|
||||
|
||||
if (stat (dir, &finfo) < 0)
|
||||
return (-1);
|
||||
|
||||
if (S_ISDIR (finfo.st_mode) == 0)
|
||||
return (-1);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Return a vector of names of files in directory DIR
|
||||
whose names match glob pattern PAT.
|
||||
The names are not in any particular order.
|
||||
Wildcards at the beginning of PAT do not match an initial period.
|
||||
|
||||
The vector is terminated by an element that is a null pointer.
|
||||
|
||||
To free the space allocated, first free the vector's elements,
|
||||
then free the vector.
|
||||
|
||||
Return 0 if cannot get enough memory to hold the pointer
|
||||
and the names.
|
||||
|
||||
Return -1 if cannot access directory DIR.
|
||||
Look in errno for more information. */
|
||||
|
||||
char **
|
||||
glob_vector (pat, dir, flags)
|
||||
char *pat;
|
||||
char *dir;
|
||||
int flags;
|
||||
{
|
||||
struct globval
|
||||
{
|
||||
struct globval *next;
|
||||
char *name;
|
||||
};
|
||||
|
||||
DIR *d;
|
||||
register struct dirent *dp;
|
||||
struct globval *lastlink;
|
||||
register struct globval *nextlink;
|
||||
register char *nextname, *npat;
|
||||
unsigned int count;
|
||||
int lose, skip;
|
||||
register char **name_vector;
|
||||
register unsigned int i;
|
||||
int mflags; /* Flags passed to strmatch (). */
|
||||
int nalloca;
|
||||
struct globval *firstmalloc, *tmplink;
|
||||
|
||||
lastlink = 0;
|
||||
count = lose = skip = 0;
|
||||
|
||||
firstmalloc = 0;
|
||||
|
||||
/* If PAT is empty, skip the loop, but return one (empty) filename. */
|
||||
if (pat == 0 || *pat == '\0')
|
||||
{
|
||||
if (glob_testdir (dir) < 0)
|
||||
return ((char **) &glob_error_return);
|
||||
|
||||
nextlink = (struct globval *)alloca (sizeof (struct globval));
|
||||
if (nextlink == NULL)
|
||||
return ((char **) NULL);
|
||||
|
||||
nextlink->next = (struct globval *)0;
|
||||
nextname = (char *) malloc (1);
|
||||
if (nextname == 0)
|
||||
lose = 1;
|
||||
else
|
||||
{
|
||||
lastlink = nextlink;
|
||||
nextlink->name = nextname;
|
||||
nextname[0] = '\0';
|
||||
count = 1;
|
||||
}
|
||||
|
||||
skip = 1;
|
||||
}
|
||||
|
||||
/* If the filename pattern (PAT) does not contain any globbing characters,
|
||||
we can dispense with reading the directory, and just see if there is
|
||||
a filename `DIR/PAT'. If there is, and we can access it, just make the
|
||||
vector to return and bail immediately. */
|
||||
if (skip == 0 && glob_pattern_p (pat) == 0)
|
||||
{
|
||||
int dirlen;
|
||||
struct stat finfo;
|
||||
|
||||
if (glob_testdir (dir) < 0)
|
||||
return ((char **) &glob_error_return);
|
||||
|
||||
dirlen = strlen (dir);
|
||||
nextname = (char *)malloc (dirlen + strlen (pat) + 2);
|
||||
npat = (char *)malloc (strlen (pat) + 1);
|
||||
if (nextname == 0 || npat == 0)
|
||||
lose = 1;
|
||||
else
|
||||
{
|
||||
strcpy (npat, pat);
|
||||
dequote_pathname (npat);
|
||||
|
||||
strcpy (nextname, dir);
|
||||
nextname[dirlen++] = '/';
|
||||
strcpy (nextname + dirlen, npat);
|
||||
|
||||
if (GLOB_TESTNAME (nextname) >= 0)
|
||||
{
|
||||
free (nextname);
|
||||
nextlink = (struct globval *)alloca (sizeof (struct globval));
|
||||
if (nextlink)
|
||||
{
|
||||
nextlink->next = (struct globval *)0;
|
||||
lastlink = nextlink;
|
||||
nextlink->name = npat;
|
||||
count = 1;
|
||||
}
|
||||
else
|
||||
lose = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
free (nextname);
|
||||
free (npat);
|
||||
}
|
||||
}
|
||||
|
||||
skip = 1;
|
||||
}
|
||||
|
||||
if (skip == 0)
|
||||
{
|
||||
/* Open the directory, punting immediately if we cannot. If opendir
|
||||
is not robust (i.e., it opens non-directories successfully), test
|
||||
that DIR is a directory and punt if it's not. */
|
||||
#if defined (OPENDIR_NOT_ROBUST)
|
||||
if (glob_testdir (dir) < 0)
|
||||
return ((char **) &glob_error_return);
|
||||
#endif
|
||||
|
||||
d = opendir (dir);
|
||||
if (d == NULL)
|
||||
return ((char **) &glob_error_return);
|
||||
|
||||
/* Compute the flags that will be passed to strmatch(). We don't
|
||||
need to do this every time through the loop. */
|
||||
mflags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
|
||||
|
||||
#ifdef FNM_CASEFOLD
|
||||
if (glob_ignore_case)
|
||||
mflags |= FNM_CASEFOLD;
|
||||
#endif
|
||||
|
||||
if (extended_glob)
|
||||
mflags |= FNM_EXTMATCH;
|
||||
|
||||
/* Scan the directory, finding all names that match.
|
||||
For each name that matches, allocate a struct globval
|
||||
on the stack and store the name in it.
|
||||
Chain those structs together; lastlink is the front of the chain. */
|
||||
while (1)
|
||||
{
|
||||
/* Make globbing interruptible in the shell. */
|
||||
if (interrupt_state)
|
||||
{
|
||||
lose = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
dp = readdir (d);
|
||||
if (dp == NULL)
|
||||
break;
|
||||
|
||||
/* If this directory entry is not to be used, try again. */
|
||||
if (REAL_DIR_ENTRY (dp) == 0)
|
||||
continue;
|
||||
|
||||
#if 0
|
||||
if (dp->d_name == 0 || *dp->d_name == 0)
|
||||
continue;
|
||||
#endif
|
||||
|
||||
#if HANDLE_MULTIBYTE
|
||||
if (MB_CUR_MAX > 1 && mbskipname (pat, dp->d_name))
|
||||
continue;
|
||||
else
|
||||
#endif
|
||||
if (skipname (pat, dp->d_name))
|
||||
continue;
|
||||
|
||||
if (strmatch (pat, dp->d_name, mflags) != FNM_NOMATCH)
|
||||
{
|
||||
if (nalloca < ALLOCA_MAX)
|
||||
{
|
||||
nextlink = (struct globval *) alloca (sizeof (struct globval));
|
||||
nalloca += sizeof (struct globval);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextlink = (struct globval *) malloc (sizeof (struct globval));
|
||||
if (firstmalloc == 0)
|
||||
firstmalloc = nextlink;
|
||||
}
|
||||
nextname = (char *) malloc (D_NAMLEN (dp) + 1);
|
||||
if (nextlink == 0 || nextname == 0)
|
||||
{
|
||||
lose = 1;
|
||||
break;
|
||||
}
|
||||
nextlink->next = lastlink;
|
||||
lastlink = nextlink;
|
||||
nextlink->name = nextname;
|
||||
bcopy (dp->d_name, nextname, D_NAMLEN (dp) + 1);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
|
||||
(void) closedir (d);
|
||||
}
|
||||
|
||||
if (lose == 0)
|
||||
{
|
||||
name_vector = (char **) malloc ((count + 1) * sizeof (char *));
|
||||
lose |= name_vector == NULL;
|
||||
}
|
||||
|
||||
/* Have we run out of memory? */
|
||||
if (lose)
|
||||
{
|
||||
tmplink = 0;
|
||||
|
||||
/* Here free the strings we have got. */
|
||||
while (lastlink)
|
||||
{
|
||||
if (firstmalloc)
|
||||
{
|
||||
if (lastlink == firstmalloc)
|
||||
firstmalloc = 0;
|
||||
tmplink = lastlink;
|
||||
}
|
||||
free (lastlink->name);
|
||||
lastlink = lastlink->next;
|
||||
FREE (tmplink);
|
||||
}
|
||||
|
||||
QUIT;
|
||||
|
||||
return ((char **)NULL);
|
||||
}
|
||||
|
||||
/* Copy the name pointers from the linked list into the vector. */
|
||||
for (tmplink = lastlink, i = 0; i < count; ++i)
|
||||
{
|
||||
name_vector[i] = tmplink->name;
|
||||
tmplink = tmplink->next;
|
||||
}
|
||||
|
||||
name_vector[count] = NULL;
|
||||
|
||||
/* If we allocated some of the struct globvals, free them now. */
|
||||
if (firstmalloc)
|
||||
{
|
||||
tmplink = 0;
|
||||
while (lastlink)
|
||||
{
|
||||
tmplink = lastlink;
|
||||
if (lastlink == firstmalloc)
|
||||
lastlink = firstmalloc = 0;
|
||||
else
|
||||
lastlink = lastlink->next;
|
||||
free (tmplink);
|
||||
}
|
||||
}
|
||||
|
||||
return (name_vector);
|
||||
}
|
||||
|
||||
/* Return a new array which is the concatenation of each string in ARRAY
|
||||
to DIR. This function expects you to pass in an allocated ARRAY, and
|
||||
it takes care of free()ing that array. Thus, you might think of this
|
||||
function as side-effecting ARRAY. This should handle GX_MARKDIRS. */
|
||||
static char **
|
||||
glob_dir_to_array (dir, array, flags)
|
||||
char *dir, **array;
|
||||
int flags;
|
||||
{
|
||||
register unsigned int i, l;
|
||||
int add_slash;
|
||||
char **result, *new;
|
||||
struct stat sb;
|
||||
|
||||
l = strlen (dir);
|
||||
if (l == 0)
|
||||
{
|
||||
if (flags & GX_MARKDIRS)
|
||||
for (i = 0; array[i]; i++)
|
||||
{
|
||||
if ((stat (array[i], &sb) == 0) && S_ISDIR (sb.st_mode))
|
||||
{
|
||||
l = strlen (array[i]);
|
||||
new = (char *)realloc (array[i], l + 2);
|
||||
if (new == 0)
|
||||
return NULL;
|
||||
new[l] = '/';
|
||||
new[l+1] = '\0';
|
||||
array[i] = new;
|
||||
}
|
||||
}
|
||||
return (array);
|
||||
}
|
||||
|
||||
add_slash = dir[l - 1] != '/';
|
||||
|
||||
i = 0;
|
||||
while (array[i] != NULL)
|
||||
++i;
|
||||
|
||||
result = (char **) malloc ((i + 1) * sizeof (char *));
|
||||
if (result == NULL)
|
||||
return (NULL);
|
||||
|
||||
for (i = 0; array[i] != NULL; i++)
|
||||
{
|
||||
/* 3 == 1 for NUL, 1 for slash at end of DIR, 1 for GX_MARKDIRS */
|
||||
result[i] = (char *) malloc (l + strlen (array[i]) + 3);
|
||||
|
||||
if (result[i] == NULL)
|
||||
return (NULL);
|
||||
|
||||
strcpy (result[i], dir);
|
||||
if (add_slash)
|
||||
result[i][l] = '/';
|
||||
strcpy (result[i] + l + add_slash, array[i]);
|
||||
if (flags & GX_MARKDIRS)
|
||||
{
|
||||
if ((stat (result[i], &sb) == 0) && S_ISDIR (sb.st_mode))
|
||||
{
|
||||
size_t rlen;
|
||||
rlen = strlen (result[i]);
|
||||
result[i][rlen] = '/';
|
||||
result[i][rlen+1] = '\0';
|
||||
}
|
||||
}
|
||||
}
|
||||
result[i] = NULL;
|
||||
|
||||
/* Free the input array. */
|
||||
for (i = 0; array[i] != NULL; i++)
|
||||
free (array[i]);
|
||||
free ((char *) array);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* Do globbing on PATHNAME. Return an array of pathnames that match,
|
||||
marking the end of the array with a null-pointer as an element.
|
||||
If no pathnames match, then the array is empty (first element is null).
|
||||
If there isn't enough memory, then return NULL.
|
||||
If a file system error occurs, return -1; `errno' has the error code. */
|
||||
char **
|
||||
glob_filename (pathname, flags)
|
||||
char *pathname;
|
||||
int flags;
|
||||
{
|
||||
char **result;
|
||||
unsigned int result_size;
|
||||
char *directory_name, *filename;
|
||||
unsigned int directory_len;
|
||||
int free_dirname; /* flag */
|
||||
|
||||
result = (char **) malloc (sizeof (char *));
|
||||
result_size = 1;
|
||||
if (result == NULL)
|
||||
return (NULL);
|
||||
|
||||
result[0] = NULL;
|
||||
|
||||
directory_name = NULL;
|
||||
|
||||
/* Find the filename. */
|
||||
filename = strrchr (pathname, '/');
|
||||
if (filename == NULL)
|
||||
{
|
||||
filename = pathname;
|
||||
directory_name = "";
|
||||
directory_len = 0;
|
||||
free_dirname = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
directory_len = (filename - pathname) + 1;
|
||||
directory_name = (char *) malloc (directory_len + 1);
|
||||
|
||||
if (directory_name == 0) /* allocation failed? */
|
||||
return (NULL);
|
||||
|
||||
bcopy (pathname, directory_name, directory_len);
|
||||
directory_name[directory_len] = '\0';
|
||||
++filename;
|
||||
free_dirname = 1;
|
||||
}
|
||||
|
||||
/* If directory_name contains globbing characters, then we
|
||||
have to expand the previous levels. Just recurse. */
|
||||
if (glob_pattern_p (directory_name))
|
||||
{
|
||||
char **directories;
|
||||
register unsigned int i;
|
||||
|
||||
if (directory_name[directory_len - 1] == '/')
|
||||
directory_name[directory_len - 1] = '\0';
|
||||
|
||||
directories = glob_filename (directory_name, flags & ~GX_MARKDIRS);
|
||||
|
||||
if (free_dirname)
|
||||
{
|
||||
free (directory_name);
|
||||
directory_name = NULL;
|
||||
}
|
||||
|
||||
if (directories == NULL)
|
||||
goto memory_error;
|
||||
else if (directories == (char **)&glob_error_return)
|
||||
{
|
||||
free ((char *) result);
|
||||
return ((char **) &glob_error_return);
|
||||
}
|
||||
else if (*directories == NULL)
|
||||
{
|
||||
free ((char *) directories);
|
||||
free ((char *) result);
|
||||
return ((char **) &glob_error_return);
|
||||
}
|
||||
|
||||
/* We have successfully globbed the preceding directory name.
|
||||
For each name in DIRECTORIES, call glob_vector on it and
|
||||
FILENAME. Concatenate the results together. */
|
||||
for (i = 0; directories[i] != NULL; ++i)
|
||||
{
|
||||
char **temp_results;
|
||||
|
||||
/* Scan directory even on a NULL pathname. That way, `*h/'
|
||||
returns only directories ending in `h', instead of all
|
||||
files ending in `h' with a `/' appended. */
|
||||
temp_results = glob_vector (filename, directories[i], flags & ~GX_MARKDIRS);
|
||||
|
||||
/* Handle error cases. */
|
||||
if (temp_results == NULL)
|
||||
goto memory_error;
|
||||
else if (temp_results == (char **)&glob_error_return)
|
||||
/* This filename is probably not a directory. Ignore it. */
|
||||
;
|
||||
else
|
||||
{
|
||||
char **array;
|
||||
register unsigned int l;
|
||||
|
||||
array = glob_dir_to_array (directories[i], temp_results, flags);
|
||||
l = 0;
|
||||
while (array[l] != NULL)
|
||||
++l;
|
||||
|
||||
result =
|
||||
(char **)realloc (result, (result_size + l) * sizeof (char *));
|
||||
|
||||
if (result == NULL)
|
||||
goto memory_error;
|
||||
|
||||
for (l = 0; array[l] != NULL; ++l)
|
||||
result[result_size++ - 1] = array[l];
|
||||
|
||||
result[result_size - 1] = NULL;
|
||||
|
||||
/* Note that the elements of ARRAY are not freed. */
|
||||
free ((char *) array);
|
||||
}
|
||||
}
|
||||
/* Free the directories. */
|
||||
for (i = 0; directories[i]; i++)
|
||||
free (directories[i]);
|
||||
|
||||
free ((char *) directories);
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* If there is only a directory name, return it. */
|
||||
if (*filename == '\0')
|
||||
{
|
||||
result = (char **) realloc ((char *) result, 2 * sizeof (char *));
|
||||
if (result == NULL)
|
||||
return (NULL);
|
||||
/* Handle GX_MARKDIRS here. */
|
||||
result[0] = (char *) malloc (directory_len + 1);
|
||||
if (result[0] == NULL)
|
||||
goto memory_error;
|
||||
bcopy (directory_name, result[0], directory_len + 1);
|
||||
if (free_dirname)
|
||||
free (directory_name);
|
||||
result[1] = NULL;
|
||||
return (result);
|
||||
}
|
||||
else
|
||||
{
|
||||
char **temp_results;
|
||||
|
||||
/* There are no unquoted globbing characters in DIRECTORY_NAME.
|
||||
Dequote it before we try to open the directory since there may
|
||||
be quoted globbing characters which should be treated verbatim. */
|
||||
if (directory_len > 0)
|
||||
dequote_pathname (directory_name);
|
||||
|
||||
/* We allocated a small array called RESULT, which we won't be using.
|
||||
Free that memory now. */
|
||||
free (result);
|
||||
|
||||
/* Just return what glob_vector () returns appended to the
|
||||
directory name. */
|
||||
temp_results = glob_vector (filename,
|
||||
(directory_len == 0 ? "." : directory_name),
|
||||
flags & ~GX_MARKDIRS);
|
||||
|
||||
if (temp_results == NULL || temp_results == (char **)&glob_error_return)
|
||||
{
|
||||
if (free_dirname)
|
||||
free (directory_name);
|
||||
return (temp_results);
|
||||
}
|
||||
|
||||
result = glob_dir_to_array (directory_name, temp_results, flags);
|
||||
if (free_dirname)
|
||||
free (directory_name);
|
||||
return (result);
|
||||
}
|
||||
|
||||
/* We get to memory_error if the program has run out of memory, or
|
||||
if this is the shell, and we have been interrupted. */
|
||||
memory_error:
|
||||
if (result != NULL)
|
||||
{
|
||||
register unsigned int i;
|
||||
for (i = 0; result[i] != NULL; ++i)
|
||||
free (result[i]);
|
||||
free ((char *) result);
|
||||
}
|
||||
|
||||
if (free_dirname && directory_name)
|
||||
free (directory_name);
|
||||
|
||||
QUIT;
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#if defined (TEST)
|
||||
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 1; i < argc; ++i)
|
||||
{
|
||||
char **value = glob_filename (argv[i], 0);
|
||||
if (value == NULL)
|
||||
puts ("Out of memory.");
|
||||
else if (value == &glob_error_return)
|
||||
perror (argv[i]);
|
||||
else
|
||||
for (i = 0; value[i] != NULL; i++)
|
||||
puts (value[i]);
|
||||
}
|
||||
|
||||
exit (0);
|
||||
}
|
||||
#endif /* TEST. */
|
||||
@@ -1,754 +0,0 @@
|
||||
/* Copyright (C) 1991-2005 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 2, 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; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
int FCT __P((CHAR *, CHAR *, int));
|
||||
|
||||
static int GMATCH __P((CHAR *, CHAR *, CHAR *, CHAR *, int));
|
||||
static CHAR *PARSE_COLLSYM __P((CHAR *, INT *));
|
||||
static CHAR *BRACKMATCH __P((CHAR *, U_CHAR, int));
|
||||
static int EXTMATCH __P((INT, CHAR *, CHAR *, CHAR *, CHAR *, int));
|
||||
static CHAR *PATSCAN __P((CHAR *, CHAR *, INT));
|
||||
|
||||
int
|
||||
FCT (pattern, string, flags)
|
||||
CHAR *pattern;
|
||||
CHAR *string;
|
||||
int flags;
|
||||
{
|
||||
CHAR *se, *pe;
|
||||
|
||||
if (string == 0 || pattern == 0)
|
||||
return FNM_NOMATCH;
|
||||
|
||||
se = string + STRLEN ((XCHAR *)string);
|
||||
pe = pattern + STRLEN ((XCHAR *)pattern);
|
||||
|
||||
return (GMATCH (string, se, pattern, pe, flags));
|
||||
}
|
||||
|
||||
/* Match STRING against the filename pattern PATTERN, returning zero if
|
||||
it matches, FNM_NOMATCH if not. */
|
||||
static int
|
||||
GMATCH (string, se, pattern, pe, flags)
|
||||
CHAR *string, *se;
|
||||
CHAR *pattern, *pe;
|
||||
int flags;
|
||||
{
|
||||
CHAR *p, *n; /* pattern, string */
|
||||
INT c; /* current pattern character - XXX U_CHAR? */
|
||||
INT sc; /* current string character - XXX U_CHAR? */
|
||||
|
||||
p = pattern;
|
||||
n = string;
|
||||
|
||||
if (string == 0 || pattern == 0)
|
||||
return FNM_NOMATCH;
|
||||
|
||||
#if DEBUG_MATCHING
|
||||
fprintf(stderr, "gmatch: string = %s; se = %s\n", string, se);
|
||||
fprintf(stderr, "gmatch: pattern = %s; pe = %s\n", pattern, pe);
|
||||
#endif
|
||||
|
||||
while (p < pe)
|
||||
{
|
||||
c = *p++;
|
||||
c = FOLD (c);
|
||||
|
||||
sc = n < se ? *n : '\0';
|
||||
|
||||
#ifdef EXTENDED_GLOB
|
||||
/* EXTMATCH () will handle recursively calling GMATCH, so we can
|
||||
just return what EXTMATCH() returns. */
|
||||
if ((flags & FNM_EXTMATCH) && *p == L('(') &&
|
||||
(c == L('+') || c == L('*') || c == L('?') || c == L('@') || c == L('!'))) /* ) */
|
||||
{
|
||||
int lflags;
|
||||
/* If we're not matching the start of the string, we're not
|
||||
concerned about the special cases for matching `.' */
|
||||
lflags = (n == string) ? flags : (flags & ~FNM_PERIOD);
|
||||
return (EXTMATCH (c, n, se, p, pe, lflags));
|
||||
}
|
||||
#endif /* EXTENDED_GLOB */
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case L('?'): /* Match single character */
|
||||
if (sc == '\0')
|
||||
return FNM_NOMATCH;
|
||||
else if ((flags & FNM_PATHNAME) && sc == L('/'))
|
||||
/* If we are matching a pathname, `?' can never match a `/'. */
|
||||
return FNM_NOMATCH;
|
||||
else if ((flags & FNM_PERIOD) && sc == L('.') &&
|
||||
(n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/'))))
|
||||
/* `?' cannot match a `.' if it is the first character of the
|
||||
string or if it is the first character following a slash and
|
||||
we are matching a pathname. */
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case L('\\'): /* backslash escape removes special meaning */
|
||||
if (p == pe)
|
||||
return FNM_NOMATCH;
|
||||
|
||||
if ((flags & FNM_NOESCAPE) == 0)
|
||||
{
|
||||
c = *p++;
|
||||
/* A trailing `\' cannot match. */
|
||||
if (p > pe)
|
||||
return FNM_NOMATCH;
|
||||
c = FOLD (c);
|
||||
}
|
||||
if (FOLD (sc) != (U_CHAR)c)
|
||||
return FNM_NOMATCH;
|
||||
break;
|
||||
|
||||
case '*': /* Match zero or more characters */
|
||||
if (p == pe)
|
||||
return 0;
|
||||
|
||||
if ((flags & FNM_PERIOD) && sc == L('.') &&
|
||||
(n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/'))))
|
||||
/* `*' cannot match a `.' if it is the first character of the
|
||||
string or if it is the first character following a slash and
|
||||
we are matching a pathname. */
|
||||
return FNM_NOMATCH;
|
||||
|
||||
/* Collapse multiple consecutive `*' and `?', but make sure that
|
||||
one character of the string is consumed for each `?'. */
|
||||
for (c = *p++; (c == L('?') || c == L('*')); c = *p++)
|
||||
{
|
||||
if ((flags & FNM_PATHNAME) && sc == L('/'))
|
||||
/* A slash does not match a wildcard under FNM_PATHNAME. */
|
||||
return FNM_NOMATCH;
|
||||
#ifdef EXTENDED_GLOB
|
||||
else if ((flags & FNM_EXTMATCH) && c == L('?') && *p == L('(')) /* ) */
|
||||
{
|
||||
CHAR *newn;
|
||||
for (newn = n; newn < se; ++newn)
|
||||
{
|
||||
if (EXTMATCH (c, newn, se, p, pe, flags) == 0)
|
||||
return (0);
|
||||
}
|
||||
/* We didn't match. If we have a `?(...)', that's failure. */
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
#endif
|
||||
else if (c == L('?'))
|
||||
{
|
||||
if (sc == L('\0'))
|
||||
return FNM_NOMATCH;
|
||||
/* One character of the string is consumed in matching
|
||||
this ? wildcard, so *??? won't match if there are
|
||||
fewer than three characters. */
|
||||
n++;
|
||||
sc = n < se ? *n : '\0';
|
||||
}
|
||||
|
||||
#ifdef EXTENDED_GLOB
|
||||
/* Handle ******(patlist) */
|
||||
if ((flags & FNM_EXTMATCH) && c == L('*') && *p == L('(')) /*)*/
|
||||
{
|
||||
CHAR *newn;
|
||||
/* We need to check whether or not the extended glob
|
||||
pattern matches the remainder of the string.
|
||||
If it does, we match the entire pattern. */
|
||||
for (newn = n; newn < se; ++newn)
|
||||
{
|
||||
if (EXTMATCH (c, newn, se, p, pe, flags) == 0)
|
||||
return (0);
|
||||
}
|
||||
/* We didn't match the extended glob pattern, but
|
||||
that's OK, since we can match 0 or more occurrences.
|
||||
We need to skip the glob pattern and see if we
|
||||
match the rest of the string. */
|
||||
newn = PATSCAN (p + 1, pe, 0);
|
||||
/* If NEWN is 0, we have an ill-formed pattern. */
|
||||
p = newn ? newn : pe;
|
||||
}
|
||||
#endif
|
||||
if (p == pe)
|
||||
break;
|
||||
}
|
||||
|
||||
/* If we've hit the end of the pattern and the last character of
|
||||
the pattern was handled by the loop above, we've succeeded.
|
||||
Otherwise, we need to match that last character. */
|
||||
if (p == pe && (c == L('?') || c == L('*')))
|
||||
return (0);
|
||||
|
||||
/* General case, use recursion. */
|
||||
{
|
||||
U_CHAR c1;
|
||||
|
||||
c1 = ((flags & FNM_NOESCAPE) == 0 && c == L('\\')) ? *p : c;
|
||||
c1 = FOLD (c1);
|
||||
for (--p; n < se; ++n)
|
||||
{
|
||||
/* Only call strmatch if the first character indicates a
|
||||
possible match. We can check the first character if
|
||||
we're not doing an extended glob match. */
|
||||
if ((flags & FNM_EXTMATCH) == 0 && c != L('[') && FOLD (*n) != c1) /*]*/
|
||||
continue;
|
||||
|
||||
/* If we're doing an extended glob match and the pattern is not
|
||||
one of the extended glob patterns, we can check the first
|
||||
character. */
|
||||
if ((flags & FNM_EXTMATCH) && p[1] != L('(') && /*)*/
|
||||
STRCHR (L("?*+@!"), *p) == 0 && c != L('[') && FOLD (*n) != c1) /*]*/
|
||||
continue;
|
||||
|
||||
/* Otherwise, we just recurse. */
|
||||
if (GMATCH (n, se, p, pe, flags & ~FNM_PERIOD) == 0)
|
||||
return (0);
|
||||
}
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
|
||||
case L('['):
|
||||
{
|
||||
if (sc == L('\0') || n == se)
|
||||
return FNM_NOMATCH;
|
||||
|
||||
/* A character class cannot match a `.' if it is the first
|
||||
character of the string or if it is the first character
|
||||
following a slash and we are matching a pathname. */
|
||||
if ((flags & FNM_PERIOD) && sc == L('.') &&
|
||||
(n == string || ((flags & FNM_PATHNAME) && n[-1] == L('/'))))
|
||||
return (FNM_NOMATCH);
|
||||
|
||||
p = BRACKMATCH (p, sc, flags);
|
||||
if (p == 0)
|
||||
return FNM_NOMATCH;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if ((U_CHAR)c != FOLD (sc))
|
||||
return (FNM_NOMATCH);
|
||||
}
|
||||
|
||||
++n;
|
||||
}
|
||||
|
||||
if (n == se)
|
||||
return (0);
|
||||
|
||||
if ((flags & FNM_LEADING_DIR) && *n == L('/'))
|
||||
/* The FNM_LEADING_DIR flag says that "foo*" matches "foobar/frobozz". */
|
||||
return 0;
|
||||
|
||||
return (FNM_NOMATCH);
|
||||
}
|
||||
|
||||
/* Parse a bracket expression collating symbol ([.sym.]) starting at P, find
|
||||
the value of the symbol, and move P past the collating symbol expression.
|
||||
The value is returned in *VP, if VP is not null. */
|
||||
static CHAR *
|
||||
PARSE_COLLSYM (p, vp)
|
||||
CHAR *p;
|
||||
INT *vp;
|
||||
{
|
||||
register int pc;
|
||||
INT val;
|
||||
|
||||
p++; /* move past the `.' */
|
||||
|
||||
for (pc = 0; p[pc]; pc++)
|
||||
if (p[pc] == L('.') && p[pc+1] == L(']'))
|
||||
break;
|
||||
val = COLLSYM (p, pc);
|
||||
if (vp)
|
||||
*vp = val;
|
||||
return (p + pc + 2);
|
||||
}
|
||||
|
||||
/* Use prototype definition here because of type promotion. */
|
||||
static CHAR *
|
||||
#if defined (PROTOTYPES)
|
||||
BRACKMATCH (CHAR *p, U_CHAR test, int flags)
|
||||
#else
|
||||
BRACKMATCH (p, test, flags)
|
||||
CHAR *p;
|
||||
U_CHAR test;
|
||||
int flags;
|
||||
#endif
|
||||
{
|
||||
register CHAR cstart, cend, c;
|
||||
register int not; /* Nonzero if the sense of the character class is inverted. */
|
||||
int brcnt;
|
||||
INT pc;
|
||||
CHAR *savep;
|
||||
|
||||
test = FOLD (test);
|
||||
|
||||
savep = p;
|
||||
|
||||
/* POSIX.2 3.13.1 says that an exclamation mark (`!') shall replace the
|
||||
circumflex (`^') in its role in a `nonmatching list'. A bracket
|
||||
expression starting with an unquoted circumflex character produces
|
||||
unspecified results. This implementation treats the two identically. */
|
||||
if (not = (*p == L('!') || *p == L('^')))
|
||||
++p;
|
||||
|
||||
c = *p++;
|
||||
for (;;)
|
||||
{
|
||||
/* Initialize cstart and cend in case `-' is the last
|
||||
character of the pattern. */
|
||||
cstart = cend = c;
|
||||
|
||||
/* POSIX.2 equivalence class: [=c=]. See POSIX.2 2.8.3.2. Find
|
||||
the end of the equivalence class, move the pattern pointer past
|
||||
it, and check for equivalence. XXX - this handles only
|
||||
single-character equivalence classes, which is wrong, or at
|
||||
least incomplete. */
|
||||
if (c == L('[') && *p == L('=') && p[2] == L('=') && p[3] == L(']'))
|
||||
{
|
||||
pc = FOLD (p[1]);
|
||||
p += 4;
|
||||
if (COLLEQUIV (test, pc))
|
||||
{
|
||||
/*[*/ /* Move past the closing `]', since the first thing we do at
|
||||
the `matched:' label is back p up one. */
|
||||
p++;
|
||||
goto matched;
|
||||
}
|
||||
else
|
||||
{
|
||||
c = *p++;
|
||||
if (c == L('\0'))
|
||||
return ((test == L('[')) ? savep : (CHAR *)0); /*]*/
|
||||
c = FOLD (c);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* POSIX.2 character class expression. See POSIX.2 2.8.3.2. */
|
||||
if (c == L('[') && *p == L(':'))
|
||||
{
|
||||
CHAR *close, *ccname;
|
||||
|
||||
pc = 0; /* make sure invalid char classes don't match. */
|
||||
/* Find end of character class name */
|
||||
for (close = p + 1; *close != '\0'; close++)
|
||||
if (*close == L(':') && *(close+1) == L(']'))
|
||||
break;
|
||||
|
||||
if (*close != L('\0'))
|
||||
{
|
||||
ccname = (CHAR *)malloc ((close - p) * sizeof (CHAR));
|
||||
if (ccname == 0)
|
||||
pc = 0;
|
||||
else
|
||||
{
|
||||
bcopy (p + 1, ccname, (close - p - 1) * sizeof (CHAR));
|
||||
*(ccname + (close - p - 1)) = L('\0');
|
||||
pc = IS_CCLASS (test, (XCHAR *)ccname);
|
||||
}
|
||||
if (pc == -1)
|
||||
pc = 0;
|
||||
else
|
||||
p = close + 2;
|
||||
|
||||
free (ccname);
|
||||
}
|
||||
|
||||
if (pc)
|
||||
{
|
||||
/*[*/ /* Move past the closing `]', since the first thing we do at
|
||||
the `matched:' label is back p up one. */
|
||||
p++;
|
||||
goto matched;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* continue the loop here, since this expression can't be
|
||||
the first part of a range expression. */
|
||||
c = *p++;
|
||||
if (c == L('\0'))
|
||||
return ((test == L('[')) ? savep : (CHAR *)0);
|
||||
else if (c == L(']'))
|
||||
break;
|
||||
c = FOLD (c);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/* POSIX.2 collating symbols. See POSIX.2 2.8.3.2. Find the end of
|
||||
the symbol name, make sure it is terminated by `.]', translate
|
||||
the name to a character using the external table, and do the
|
||||
comparison. */
|
||||
if (c == L('[') && *p == L('.'))
|
||||
{
|
||||
p = PARSE_COLLSYM (p, &pc);
|
||||
/* An invalid collating symbol cannot be the first point of a
|
||||
range. If it is, we set cstart to one greater than `test',
|
||||
so any comparisons later will fail. */
|
||||
cstart = (pc == INVALID) ? test + 1 : pc;
|
||||
}
|
||||
|
||||
if (!(flags & FNM_NOESCAPE) && c == L('\\'))
|
||||
{
|
||||
if (*p == '\0')
|
||||
return (CHAR *)0;
|
||||
cstart = cend = *p++;
|
||||
}
|
||||
|
||||
cstart = cend = FOLD (cstart);
|
||||
|
||||
/* POSIX.2 2.8.3.1.2 says: `An expression containing a `[' that
|
||||
is not preceded by a backslash and is not part of a bracket
|
||||
expression produces undefined results.' This implementation
|
||||
treats the `[' as just a character to be matched if there is
|
||||
not a closing `]'. */
|
||||
if (c == L('\0'))
|
||||
return ((test == L('[')) ? savep : (CHAR *)0);
|
||||
|
||||
c = *p++;
|
||||
c = FOLD (c);
|
||||
|
||||
if ((flags & FNM_PATHNAME) && c == L('/'))
|
||||
/* [/] can never match when matching a pathname. */
|
||||
return (CHAR *)0;
|
||||
|
||||
/* This introduces a range, unless the `-' is the last
|
||||
character of the class. Find the end of the range
|
||||
and move past it. */
|
||||
if (c == L('-') && *p != L(']'))
|
||||
{
|
||||
cend = *p++;
|
||||
if (!(flags & FNM_NOESCAPE) && cend == L('\\'))
|
||||
cend = *p++;
|
||||
if (cend == L('\0'))
|
||||
return (CHAR *)0;
|
||||
if (cend == L('[') && *p == L('.'))
|
||||
{
|
||||
p = PARSE_COLLSYM (p, &pc);
|
||||
/* An invalid collating symbol cannot be the second part of a
|
||||
range expression. If we get one, we set cend to one fewer
|
||||
than the test character to make sure the range test fails. */
|
||||
cend = (pc == INVALID) ? test - 1 : pc;
|
||||
}
|
||||
cend = FOLD (cend);
|
||||
|
||||
c = *p++;
|
||||
|
||||
/* POSIX.2 2.8.3.2: ``The ending range point shall collate
|
||||
equal to or higher than the starting range point; otherwise
|
||||
the expression shall be treated as invalid.'' Note that this
|
||||
applies to only the range expression; the rest of the bracket
|
||||
expression is still checked for matches. */
|
||||
if (RANGECMP (cstart, cend) > 0)
|
||||
{
|
||||
if (c == L(']'))
|
||||
break;
|
||||
c = FOLD (c);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (RANGECMP (test, cstart) >= 0 && RANGECMP (test, cend) <= 0)
|
||||
goto matched;
|
||||
|
||||
if (c == L(']'))
|
||||
break;
|
||||
}
|
||||
/* No match. */
|
||||
return (!not ? (CHAR *)0 : p);
|
||||
|
||||
matched:
|
||||
/* Skip the rest of the [...] that already matched. */
|
||||
c = *--p;
|
||||
brcnt = 1;
|
||||
while (brcnt > 0)
|
||||
{
|
||||
/* A `[' without a matching `]' is just another character to match. */
|
||||
if (c == L('\0'))
|
||||
return ((test == L('[')) ? savep : (CHAR *)0);
|
||||
|
||||
c = *p++;
|
||||
if (c == L('[') && (*p == L('=') || *p == L(':') || *p == L('.')))
|
||||
brcnt++;
|
||||
else if (c == L(']'))
|
||||
brcnt--;
|
||||
else if (!(flags & FNM_NOESCAPE) && c == L('\\'))
|
||||
{
|
||||
if (*p == '\0')
|
||||
return (CHAR *)0;
|
||||
/* XXX 1003.2d11 is unclear if this is right. */
|
||||
++p;
|
||||
}
|
||||
}
|
||||
return (not ? (CHAR *)0 : p);
|
||||
}
|
||||
|
||||
#if defined (EXTENDED_GLOB)
|
||||
/* ksh-like extended pattern matching:
|
||||
|
||||
[?*+@!](pat-list)
|
||||
|
||||
where pat-list is a list of one or patterns separated by `|'. Operation
|
||||
is as follows:
|
||||
|
||||
?(patlist) match zero or one of the given patterns
|
||||
*(patlist) match zero or more of the given patterns
|
||||
+(patlist) match one or more of the given patterns
|
||||
@(patlist) match exactly one of the given patterns
|
||||
!(patlist) match anything except one of the given patterns
|
||||
*/
|
||||
|
||||
/* Scan a pattern starting at STRING and ending at END, keeping track of
|
||||
embedded () and []. If DELIM is 0, we scan until a matching `)'
|
||||
because we're scanning a `patlist'. Otherwise, we scan until we see
|
||||
DELIM. In all cases, we never scan past END. The return value is the
|
||||
first character after the matching DELIM. */
|
||||
static CHAR *
|
||||
PATSCAN (string, end, delim)
|
||||
CHAR *string, *end;
|
||||
INT delim;
|
||||
{
|
||||
int pnest, bnest;
|
||||
INT cchar;
|
||||
CHAR *s, c, *bfirst;
|
||||
|
||||
pnest = bnest = 0;
|
||||
cchar = 0;
|
||||
bfirst = NULL;
|
||||
|
||||
for (s = string; c = *s; s++)
|
||||
{
|
||||
if (s >= end)
|
||||
return (s);
|
||||
switch (c)
|
||||
{
|
||||
case L('\\'):
|
||||
continue;
|
||||
|
||||
case L('\0'):
|
||||
return ((CHAR *)NULL);
|
||||
|
||||
/* `[' is not special inside a bracket expression, but it may
|
||||
introduce one of the special POSIX bracket expressions
|
||||
([.SYM.], [=c=], [: ... :]) that needs special handling. */
|
||||
case L('['):
|
||||
if (bnest == 0)
|
||||
{
|
||||
bfirst = s + 1;
|
||||
if (*bfirst == L('!') || *bfirst == L('^'))
|
||||
bfirst++;
|
||||
bnest++;
|
||||
}
|
||||
else if (s[1] == L(':') || s[1] == L('.') || s[1] == L('='))
|
||||
cchar = s[1];
|
||||
break;
|
||||
|
||||
/* `]' is not special if it's the first char (after a leading `!'
|
||||
or `^') in a bracket expression or if it's part of one of the
|
||||
special POSIX bracket expressions ([.SYM.], [=c=], [: ... :]) */
|
||||
case L(']'):
|
||||
if (bnest)
|
||||
{
|
||||
if (cchar && s[-1] == cchar)
|
||||
cchar = 0;
|
||||
else if (s != bfirst)
|
||||
{
|
||||
bnest--;
|
||||
bfirst = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case L('('):
|
||||
if (bnest == 0)
|
||||
pnest++;
|
||||
break;
|
||||
|
||||
case L(')'):
|
||||
if (bnest == 0 && pnest-- <= 0)
|
||||
return ++s;
|
||||
break;
|
||||
|
||||
case L('|'):
|
||||
if (bnest == 0 && pnest == 0 && delim == L('|'))
|
||||
return ++s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Return 0 if dequoted pattern matches S in the current locale. */
|
||||
static int
|
||||
STRCOMPARE (p, pe, s, se)
|
||||
CHAR *p, *pe, *s, *se;
|
||||
{
|
||||
int ret;
|
||||
CHAR c1, c2;
|
||||
|
||||
c1 = *pe;
|
||||
c2 = *se;
|
||||
|
||||
*pe = *se = '\0';
|
||||
#if HAVE_MULTIBYTE || defined (HAVE_STRCOLL)
|
||||
ret = STRCOLL ((XCHAR *)p, (XCHAR *)s);
|
||||
#else
|
||||
ret = STRCMP ((XCHAR *)p, (XCHAR *)s);
|
||||
#endif
|
||||
|
||||
*pe = c1;
|
||||
*se = c2;
|
||||
|
||||
return (ret == 0 ? ret : FNM_NOMATCH);
|
||||
}
|
||||
|
||||
/* Match a ksh extended pattern specifier. Return FNM_NOMATCH on failure or
|
||||
0 on success. This is handed the entire rest of the pattern and string
|
||||
the first time an extended pattern specifier is encountered, so it calls
|
||||
gmatch recursively. */
|
||||
static int
|
||||
EXTMATCH (xc, s, se, p, pe, flags)
|
||||
INT xc; /* select which operation */
|
||||
CHAR *s, *se;
|
||||
CHAR *p, *pe;
|
||||
int flags;
|
||||
{
|
||||
CHAR *prest; /* pointer to rest of pattern */
|
||||
CHAR *psub; /* pointer to sub-pattern */
|
||||
CHAR *pnext; /* pointer to next sub-pattern */
|
||||
CHAR *srest; /* pointer to rest of string */
|
||||
int m1, m2;
|
||||
|
||||
#if DEBUG_MATCHING
|
||||
fprintf(stderr, "extmatch: xc = %c\n", xc);
|
||||
fprintf(stderr, "extmatch: s = %s; se = %s\n", s, se);
|
||||
fprintf(stderr, "extmatch: p = %s; pe = %s\n", p, pe);
|
||||
#endif
|
||||
|
||||
prest = PATSCAN (p + (*p == L('(')), pe, 0); /* ) */
|
||||
if (prest == 0)
|
||||
/* If PREST is 0, we failed to scan a valid pattern. In this
|
||||
case, we just want to compare the two as strings. */
|
||||
return (STRCOMPARE (p - 1, pe, s, se));
|
||||
|
||||
switch (xc)
|
||||
{
|
||||
case L('+'): /* match one or more occurrences */
|
||||
case L('*'): /* match zero or more occurrences */
|
||||
/* If we can get away with no matches, don't even bother. Just
|
||||
call GMATCH on the rest of the pattern and return success if
|
||||
it succeeds. */
|
||||
if (xc == L('*') && (GMATCH (s, se, prest, pe, flags) == 0))
|
||||
return 0;
|
||||
|
||||
/* OK, we have to do this the hard way. First, we make sure one of
|
||||
the subpatterns matches, then we try to match the rest of the
|
||||
string. */
|
||||
for (psub = p + 1; ; psub = pnext)
|
||||
{
|
||||
pnext = PATSCAN (psub, pe, L('|'));
|
||||
for (srest = s; srest <= se; srest++)
|
||||
{
|
||||
/* Match this substring (S -> SREST) against this
|
||||
subpattern (psub -> pnext - 1) */
|
||||
m1 = GMATCH (s, srest, psub, pnext - 1, flags) == 0;
|
||||
/* OK, we matched a subpattern, so make sure the rest of the
|
||||
string matches the rest of the pattern. Also handle
|
||||
multiple matches of the pattern. */
|
||||
if (m1)
|
||||
m2 = (GMATCH (srest, se, prest, pe, flags) == 0) ||
|
||||
(s != srest && GMATCH (srest, se, p - 1, pe, flags) == 0);
|
||||
if (m1 && m2)
|
||||
return (0);
|
||||
}
|
||||
if (pnext == prest)
|
||||
break;
|
||||
}
|
||||
return (FNM_NOMATCH);
|
||||
|
||||
case L('?'): /* match zero or one of the patterns */
|
||||
case L('@'): /* match exactly one of the patterns */
|
||||
/* If we can get away with no matches, don't even bother. Just
|
||||
call gmatch on the rest of the pattern and return success if
|
||||
it succeeds. */
|
||||
if (xc == L('?') && (GMATCH (s, se, prest, pe, flags) == 0))
|
||||
return 0;
|
||||
|
||||
/* OK, we have to do this the hard way. First, we see if one of
|
||||
the subpatterns matches, then, if it does, we try to match the
|
||||
rest of the string. */
|
||||
for (psub = p + 1; ; psub = pnext)
|
||||
{
|
||||
pnext = PATSCAN (psub, pe, L('|'));
|
||||
srest = (prest == pe) ? se : s;
|
||||
for ( ; srest <= se; srest++)
|
||||
{
|
||||
if (GMATCH (s, srest, psub, pnext - 1, flags) == 0 &&
|
||||
GMATCH (srest, se, prest, pe, flags) == 0)
|
||||
return (0);
|
||||
}
|
||||
if (pnext == prest)
|
||||
break;
|
||||
}
|
||||
return (FNM_NOMATCH);
|
||||
|
||||
case '!': /* match anything *except* one of the patterns */
|
||||
for (srest = s; srest <= se; srest++)
|
||||
{
|
||||
m1 = 0;
|
||||
for (psub = p + 1; ; psub = pnext)
|
||||
{
|
||||
pnext = PATSCAN (psub, pe, L('|'));
|
||||
/* If one of the patterns matches, just bail immediately. */
|
||||
if (m1 = (GMATCH (s, srest, psub, pnext - 1, flags) == 0))
|
||||
break;
|
||||
if (pnext == prest)
|
||||
break;
|
||||
}
|
||||
if (m1 == 0 && GMATCH (srest, se, prest, pe, flags) == 0)
|
||||
return (0);
|
||||
}
|
||||
return (FNM_NOMATCH);
|
||||
}
|
||||
|
||||
return (FNM_NOMATCH);
|
||||
}
|
||||
#endif /* EXTENDED_GLOB */
|
||||
|
||||
#undef IS_CCLASS
|
||||
#undef FOLD
|
||||
#undef CHAR
|
||||
#undef U_CHAR
|
||||
#undef XCHAR
|
||||
#undef INT
|
||||
#undef INVALID
|
||||
#undef FCT
|
||||
#undef GMATCH
|
||||
#undef COLLSYM
|
||||
#undef PARSE_COLLSYM
|
||||
#undef PATSCAN
|
||||
#undef STRCOMPARE
|
||||
#undef EXTMATCH
|
||||
#undef BRACKMATCH
|
||||
#undef STRCHR
|
||||
#undef STRCOLL
|
||||
#undef STRLEN
|
||||
#undef STRCMP
|
||||
#undef COLLEQUIV
|
||||
#undef RANGECMP
|
||||
#undef L
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,138 +0,0 @@
|
||||
# Skeleton Makefile for the GNU malloc code
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1996 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 2, 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 USA.
|
||||
|
||||
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@
|
||||
|
||||
DEFS = @DEFS@
|
||||
LOCAL_DEFS = @LOCAL_DEFS@
|
||||
|
||||
LIBBUILD = ${BUILD_DIR}/lib
|
||||
|
||||
BASHINCDIR = ${topdir}/include
|
||||
|
||||
INTL_LIBSRC = ${topdir}/lib/intl
|
||||
INTL_BUILDDIR = ${LIBBUILD}/intl
|
||||
INTL_INC = @INTL_INC@
|
||||
LIBINTL_H = @LIBINTL_H@
|
||||
|
||||
INCLUDES = -I. -I../.. -I$(topdir) -I$(BASHINCDIR) -I$(topdir)/lib $(INTL_INC)
|
||||
|
||||
CCFLAGS = ${PROFILE_FLAGS} ${INCLUDES} $(DEFS) $(LOCAL_DEFS) $(LOCAL_CFLAGS) \
|
||||
$(CFLAGS) $(MALLOC_CFLAGS) $(CPPFLAGS)
|
||||
|
||||
.c.o:
|
||||
$(CC) $(CCFLAGS) -c $<
|
||||
|
||||
.s.o:
|
||||
$(CC) $(CCFLAGS) -c $<
|
||||
|
||||
MALLOC_SOURCE = malloc.c
|
||||
STUB_SOURCE = stub.c
|
||||
|
||||
ALLOCA_SOURCE = alloca.c
|
||||
ALLOCA_OBJECT = alloca.o
|
||||
|
||||
MALLOC_SRC = @MALLOC_SRC@
|
||||
MALLOC = @MALLOC@
|
||||
ALLOCA = @ALLOCA@
|
||||
|
||||
MALLOC_OBJS = malloc.o $(ALLOCA) trace.o stats.o table.o watch.o
|
||||
STUB_OBJS = $(ALLOCA) stub.o
|
||||
|
||||
.PHONY: malloc stubmalloc
|
||||
|
||||
all: malloc
|
||||
|
||||
malloc: ${MALLOC_OBJS}
|
||||
${RM} libmalloc.a
|
||||
${AR} ${ARFLAGS} libmalloc.a ${MALLOC_OBJS}
|
||||
-test -n "$(RANLIB)" && $(RANLIB) libmalloc.a
|
||||
|
||||
stubmalloc: ${STUB_OBJS}
|
||||
${RM} libmalloc.a
|
||||
${AR} ${ARFLAGS} libmalloc.a ${STUB_OBJS}
|
||||
-test -n "$(RANLIB)" && $(RANLIB) libmalloc.a
|
||||
|
||||
alloca: ${ALLOCA}
|
||||
${RM} libmalloc.a
|
||||
${AR} ${ARFLAGS} libmalloc.a ${ALLOCA}
|
||||
-test -n "$(RANLIB)" && $(RANLIB) libmalloc.a
|
||||
|
||||
alloca.o: $(srcdir)/$(ALLOCA_SOURCE)
|
||||
$(CC) $(CCFLAGS) -c $(srcdir)/$(ALLOCA_SOURCE)
|
||||
@- if test "$(ALLOCA_OBJECT)" != alloca.o ; then \
|
||||
mv $(ALLOCA_OBJECT) alloca.o >/dev/null 2>&1 ; \
|
||||
fi
|
||||
|
||||
mostlyclean clean:
|
||||
$(RM) *.o libmalloc.a
|
||||
|
||||
distclean realclean maintainer-clean: clean
|
||||
$(RM) Makefile
|
||||
|
||||
alloca.o: $(BUILD_DIR)/config.h
|
||||
malloc.o: $(BUILD_DIR)/config.h $(topdir)/bashtypes.h getpagesize.h
|
||||
xmalloc.o: $(BUILD_DIR)/config.h $(BASHINCDIR)/ansi_stdlib.h
|
||||
trace.o: ${BUILD_DIR}/config.h
|
||||
table.o: ${BUILD_DIR}/config.h
|
||||
|
||||
malloc.o: ${srcdir}/imalloc.h ${srcdir}/mstats.h
|
||||
malloc.o: ${srcdir}/table.h ${srcdir}/watch.h
|
||||
stats.o: ${srcdir}/imalloc.h ${srcdir}/mstats.h
|
||||
trace.o: ${srcdir}/imalloc.h
|
||||
table.o: ${srcdir}/imalloc.h ${srcdir}/table.h
|
||||
watch.o: ${srcdir}/imalloc.h ${srcdir}/watch.h
|
||||
|
||||
malloc.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
|
||||
stats.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
|
||||
trace.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
|
||||
table.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
|
||||
watch.o: ${topdir}/bashintl.h ${LIBINTL_H} ${BASHINCDIR}/gettext.h
|
||||
|
||||
# Rules for deficient makes, like SunOS and Solaris
|
||||
stub.o: stub.c
|
||||
malloc.o: malloc.c
|
||||
table.o: table.c
|
||||
trace.o: trace.c
|
||||
stats.o: stats.c
|
||||
watch.o: watch.c
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,68 +0,0 @@
|
||||
/* Functions (currently) for use by the shell to do malloc debugging and
|
||||
tracking. */
|
||||
/* Copyright (C) 2001-2003 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 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 USA. */
|
||||
|
||||
#ifndef _SH_MALLOC_H
|
||||
#define _SH_MALLOC_H
|
||||
|
||||
#ifndef __P
|
||||
# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus)
|
||||
# define __P(protos) protos
|
||||
# else
|
||||
# define __P(protos) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Generic pointer type. */
|
||||
#ifndef PTR_T
|
||||
|
||||
#if defined (__STDC__)
|
||||
# define PTR_T void *
|
||||
#else
|
||||
# define PTR_T char *
|
||||
#endif
|
||||
|
||||
#endif /* PTR_T */
|
||||
|
||||
|
||||
extern PTR_T sh_malloc __P((size_t, const char *, int));
|
||||
extern PTR_T sh_realloc __P((PTR_T, size_t, const char *, int));
|
||||
extern void sh_free __P((PTR_T, const char *, int));
|
||||
|
||||
extern PTR_T sh_memalign __P((unsigned int, size_t, const char *, int));
|
||||
|
||||
extern PTR_T sh_calloc __P((size_t, size_t, const char *, int));
|
||||
extern void sh_cfree __P((PTR_T, const char *, int));
|
||||
|
||||
extern PTR_T sh_valloc __P((size_t, const char *, int));
|
||||
|
||||
/* trace.c */
|
||||
extern int malloc_set_trace __P((int));
|
||||
extern void malloc_set_tracefp (); /* full prototype requires stdio.h */
|
||||
extern void malloc_set_tracefn __P((char *, char *));
|
||||
|
||||
/* table.c */
|
||||
extern void mregister_dump_table __P((void));
|
||||
extern void mregister_table_init __P((void));
|
||||
extern int malloc_set_register __P((int));
|
||||
|
||||
/* stats.c */
|
||||
extern void print_malloc_stats __P((char *));
|
||||
extern void fprint_malloc_stats (); /* full prototype requires stdio.h */
|
||||
extern void trace_malloc_stats __P((char *, char *));
|
||||
|
||||
#endif
|
||||
@@ -1,122 +0,0 @@
|
||||
/* trace.c - tracing functions for malloc */
|
||||
|
||||
/* Copyright (C) 2001-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 2, 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; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "imalloc.h"
|
||||
|
||||
extern int malloc_trace;
|
||||
|
||||
static int _mtrace_verbose = 0;
|
||||
|
||||
extern FILE *_imalloc_fopen __P((char *, char *, char *, char *, size_t));
|
||||
|
||||
#ifdef MALLOC_TRACE
|
||||
|
||||
FILE *_mtrace_fp = NULL;
|
||||
extern char _malloc_trace_buckets[];
|
||||
|
||||
void
|
||||
mtrace_alloc (tag, mem, size, file, line)
|
||||
const char *tag;
|
||||
PTR_T mem;
|
||||
size_t size;
|
||||
const char *file;
|
||||
int line;
|
||||
{
|
||||
if (_mtrace_fp == NULL)
|
||||
_mtrace_fp = stderr;
|
||||
|
||||
if (_mtrace_verbose)
|
||||
fprintf (_mtrace_fp, "alloc: %s: %p (%d bytes) from '%s:%d'\n",
|
||||
tag, mem, size, file ? file : "unknown", line);
|
||||
else
|
||||
fprintf (_mtrace_fp, "alloc:%p:%d:%s:%d\n",
|
||||
mem, size, file ? file : "unknown", line);
|
||||
}
|
||||
|
||||
void
|
||||
mtrace_free (mem, size, file, line)
|
||||
PTR_T mem;
|
||||
int size;
|
||||
const char *file;
|
||||
int line;
|
||||
{
|
||||
if (_mtrace_fp == NULL)
|
||||
_mtrace_fp = stderr;
|
||||
|
||||
if (_mtrace_verbose)
|
||||
fprintf (_mtrace_fp, "free: %p (%d bytes) from '%s:%d'\n",
|
||||
mem, size, file ? file : "unknown", line);
|
||||
else
|
||||
fprintf (_mtrace_fp, "free:%p:%d:%s:%d\n",
|
||||
mem, size, file ? file : "unknown", line);
|
||||
}
|
||||
#endif /* MALLOC_TRACE */
|
||||
|
||||
int
|
||||
malloc_set_trace (n)
|
||||
int n;
|
||||
{
|
||||
int old;
|
||||
|
||||
old = malloc_trace;
|
||||
malloc_trace = n;
|
||||
_mtrace_verbose = (n > 1);
|
||||
return old;
|
||||
}
|
||||
|
||||
void
|
||||
malloc_set_tracefp (fp)
|
||||
FILE *fp;
|
||||
{
|
||||
#ifdef MALLOC_TRACE
|
||||
_mtrace_fp = fp ? fp : stderr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
malloc_trace_bin (n)
|
||||
int n;
|
||||
{
|
||||
#ifdef MALLOC_TRACE
|
||||
_malloc_trace_buckets[n] = 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
#define TRACEROOT "/var/tmp/maltrace/trace."
|
||||
|
||||
void
|
||||
malloc_set_tracefn (s, fn)
|
||||
char *s;
|
||||
char *fn;
|
||||
{
|
||||
#ifdef MALLOC_TRACE
|
||||
FILE *fp;
|
||||
char defname[sizeof (TRACEROOT) + 64];
|
||||
|
||||
fp = _imalloc_fopen (s, fn, TRACEROOT, defname, sizeof (defname));
|
||||
if (fp)
|
||||
malloc_set_tracefp (fp);
|
||||
#endif
|
||||
}
|
||||
@@ -1,366 +0,0 @@
|
||||
## -*- text -*- #############################################################
|
||||
# #
|
||||
# Makefile for the Bash versions of the GNU Readline and History Libraries. #
|
||||
# #
|
||||
#############################################################################
|
||||
|
||||
# Copyright (C) 1994 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 2, 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 USA.
|
||||
|
||||
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@
|
||||
|
||||
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
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,156 +0,0 @@
|
||||
/* callback.c -- functions to use readline as an X `callback' mechanism. */
|
||||
|
||||
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#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"
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* 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;
|
||||
|
||||
(*rl_prep_term_function) (_rl_meta_flag);
|
||||
|
||||
#if defined (HANDLE_SIGNALS)
|
||||
rl_set_signals ();
|
||||
#endif
|
||||
}
|
||||
|
||||
readline_internal_setup ();
|
||||
}
|
||||
|
||||
/* 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_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;
|
||||
|
||||
if (rl_linefunc == NULL)
|
||||
{
|
||||
fprintf (stderr, "readline: readline_callback_read_char() called with no handler!\r\n");
|
||||
abort ();
|
||||
}
|
||||
|
||||
eof = readline_internal_char ();
|
||||
|
||||
/* We loop in case some function has pushed input back with rl_execute_next. */
|
||||
for (;;)
|
||||
{
|
||||
if (rl_done)
|
||||
{
|
||||
line = readline_internal_teardown (eof);
|
||||
|
||||
(*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 ();
|
||||
}
|
||||
if (rl_pending_input || _rl_pushed_input_available ())
|
||||
eof = readline_internal_char ();
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Remove the handler, and make sure the terminal is in its normal state. */
|
||||
void
|
||||
rl_callback_handler_remove ()
|
||||
{
|
||||
rl_linefunc = NULL;
|
||||
if (in_handler)
|
||||
{
|
||||
in_handler = 0;
|
||||
(*rl_deprep_term_function) ();
|
||||
#if defined (HANDLE_SIGNALS)
|
||||
rl_clear_signals ();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,163 +0,0 @@
|
||||
/* chardefs.h -- Character definitions for readline. */
|
||||
|
||||
/* Copyright (C) 1994 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#ifndef _CHARDEFS_H_
|
||||
#define _CHARDEFS_H_
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# if defined (HAVE_STRING_H)
|
||||
# if ! defined (STDC_HEADERS) && defined (HAVE_MEMORY_H)
|
||||
# include <memory.h>
|
||||
# endif
|
||||
# include <string.h>
|
||||
# endif /* HAVE_STRING_H */
|
||||
# if defined (HAVE_STRINGS_H)
|
||||
# include <strings.h>
|
||||
# endif /* HAVE_STRINGS_H */
|
||||
#else
|
||||
# include <string.h>
|
||||
#endif /* !HAVE_CONFIG_H */
|
||||
|
||||
#ifndef whitespace
|
||||
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
|
||||
#endif
|
||||
|
||||
#ifdef CTRL
|
||||
# undef CTRL
|
||||
#endif
|
||||
#ifdef UNCTRL
|
||||
# undef UNCTRL
|
||||
#endif
|
||||
|
||||
/* Some character stuff. */
|
||||
#define control_character_threshold 0x020 /* Smaller than this is control. */
|
||||
#define control_character_mask 0x1f /* 0x20 - 1 */
|
||||
#define meta_character_threshold 0x07f /* Larger than this is Meta. */
|
||||
#define control_character_bit 0x40 /* 0x000000, must be off. */
|
||||
#define meta_character_bit 0x080 /* x0000000, must be on. */
|
||||
#define largest_char 255 /* Largest character value. */
|
||||
|
||||
#define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0))
|
||||
#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char)
|
||||
|
||||
#define CTRL(c) ((c) & control_character_mask)
|
||||
#define META(c) ((c) | meta_character_bit)
|
||||
|
||||
#define UNMETA(c) ((c) & (~meta_character_bit))
|
||||
#define UNCTRL(c) _rl_to_upper(((c)|control_character_bit))
|
||||
|
||||
#if defined STDC_HEADERS || (!defined (isascii) && !defined (HAVE_ISASCII))
|
||||
# define IN_CTYPE_DOMAIN(c) 1
|
||||
#else
|
||||
# define IN_CTYPE_DOMAIN(c) isascii(c)
|
||||
#endif
|
||||
|
||||
#if !defined (isxdigit) && !defined (HAVE_ISXDIGIT)
|
||||
# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
|
||||
#endif
|
||||
|
||||
#if defined (CTYPE_NON_ASCII)
|
||||
# define NON_NEGATIVE(c) 1
|
||||
#else
|
||||
# define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
|
||||
#endif
|
||||
|
||||
/* Some systems define these; we want our definitions. */
|
||||
#undef ISPRINT
|
||||
|
||||
#define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c))
|
||||
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
|
||||
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
|
||||
#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
|
||||
#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
|
||||
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
|
||||
#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
|
||||
|
||||
#define _rl_lowercase_p(c) (NON_NEGATIVE(c) && ISLOWER(c))
|
||||
#define _rl_uppercase_p(c) (NON_NEGATIVE(c) && ISUPPER(c))
|
||||
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
|
||||
|
||||
#define _rl_pure_alphabetic(c) (NON_NEGATIVE(c) && ISALPHA(c))
|
||||
#define ALPHABETIC(c) (NON_NEGATIVE(c) && ISALNUM(c))
|
||||
|
||||
#ifndef _rl_to_upper
|
||||
# define _rl_to_upper(c) (_rl_lowercase_p(c) ? toupper((unsigned char)c) : (c))
|
||||
# define _rl_to_lower(c) (_rl_uppercase_p(c) ? tolower((unsigned char)c) : (c))
|
||||
#endif
|
||||
|
||||
#ifndef _rl_digit_value
|
||||
# define _rl_digit_value(x) ((x) - '0')
|
||||
#endif
|
||||
|
||||
#ifndef _rl_isident
|
||||
# define _rl_isident(c) (ISALNUM(c) || (c) == '_')
|
||||
#endif
|
||||
|
||||
#ifndef ISOCTAL
|
||||
# define ISOCTAL(c) ((c) >= '0' && (c) <= '7')
|
||||
#endif
|
||||
#define OCTVALUE(c) ((c) - '0')
|
||||
|
||||
#define HEXVALUE(c) \
|
||||
(((c) >= 'a' && (c) <= 'f') \
|
||||
? (c)-'a'+10 \
|
||||
: (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0')
|
||||
|
||||
#ifndef NEWLINE
|
||||
#define NEWLINE '\n'
|
||||
#endif
|
||||
|
||||
#ifndef RETURN
|
||||
#define RETURN CTRL('M')
|
||||
#endif
|
||||
|
||||
#ifndef RUBOUT
|
||||
#define RUBOUT 0x7f
|
||||
#endif
|
||||
|
||||
#ifndef TAB
|
||||
#define TAB '\t'
|
||||
#endif
|
||||
|
||||
#ifdef ABORT_CHAR
|
||||
#undef ABORT_CHAR
|
||||
#endif
|
||||
#define ABORT_CHAR CTRL('G')
|
||||
|
||||
#ifdef PAGE
|
||||
#undef PAGE
|
||||
#endif
|
||||
#define PAGE CTRL('L')
|
||||
|
||||
#ifdef SPACE
|
||||
#undef SPACE
|
||||
#endif
|
||||
#define SPACE ' ' /* XXX - was 0x20 */
|
||||
|
||||
#ifdef ESC
|
||||
#undef ESC
|
||||
#endif
|
||||
#define ESC CTRL('[')
|
||||
|
||||
#endif /* _CHARDEFS_H_ */
|
||||
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
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
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,88 +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.)
|
||||
|
||||
@setchapternewpage odd
|
||||
|
||||
@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-2004 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.1 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 have freedom to copy and modify
|
||||
this GNU Manual, like GNU software. Copies published by the Free
|
||||
Software Foundation raise funds for GNU development.''
|
||||
@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.
|
||||
* Copying This Manual:: Copying This Manual.
|
||||
@end menu
|
||||
@end ifnottex
|
||||
|
||||
@include rluser.texi
|
||||
|
||||
@node Copying This Manual
|
||||
@appendix Copying This Manual
|
||||
|
||||
@menu
|
||||
* GNU Free Documentation License:: License for copying this manual.
|
||||
@end menu
|
||||
|
||||
@include fdl.texi
|
||||
|
||||
@bye
|
||||
@@ -1,10 +0,0 @@
|
||||
@ignore
|
||||
Copyright (C) 1988-2005 Free Software Foundation, Inc.
|
||||
@end ignore
|
||||
|
||||
@set EDITION 5.1-beta1
|
||||
@set VERSION 5.1-beta1
|
||||
@set UPDATED 7 October 2005
|
||||
@set UPDATED-MONTH October 2005
|
||||
|
||||
@set LASTCHANGE Fri Oct 7 20:28:03 EDT 2005
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* rl - command-line interface to read a line from the standard input
|
||||
* (or another fd) using readline.
|
||||
*
|
||||
* usage: rl [-p prompt] [-u unit] [-d default] [-n nchars]
|
||||
*/
|
||||
|
||||
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "posixstat.h"
|
||||
|
||||
#if defined (READLINE_LIBRARY)
|
||||
# include "readline.h"
|
||||
# include "history.h"
|
||||
#else
|
||||
# include <readline/readline.h>
|
||||
# include <readline/history.h>
|
||||
#endif
|
||||
|
||||
extern int optind;
|
||||
extern char *optarg;
|
||||
|
||||
#if !defined (strchr) && !defined (__STDC__)
|
||||
extern char *strrchr();
|
||||
#endif
|
||||
|
||||
static char *progname;
|
||||
static char *deftext;
|
||||
|
||||
static int
|
||||
set_deftext ()
|
||||
{
|
||||
if (deftext)
|
||||
{
|
||||
rl_insert_text (deftext);
|
||||
deftext = (char *)NULL;
|
||||
rl_startup_hook = (rl_hook_func_t *)NULL;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
usage()
|
||||
{
|
||||
fprintf (stderr, "%s: usage: %s [-p prompt] [-u unit] [-d default] [-n nchars]\n",
|
||||
progname, progname);
|
||||
}
|
||||
|
||||
int
|
||||
main (argc, argv)
|
||||
int argc;
|
||||
char **argv;
|
||||
{
|
||||
char *temp, *prompt;
|
||||
struct stat sb;
|
||||
int opt, fd, nch;
|
||||
FILE *ifp;
|
||||
|
||||
progname = strrchr(argv[0], '/');
|
||||
if (progname == 0)
|
||||
progname = argv[0];
|
||||
else
|
||||
progname++;
|
||||
|
||||
/* defaults */
|
||||
prompt = "readline$ ";
|
||||
fd = nch = 0;
|
||||
deftext = (char *)0;
|
||||
|
||||
while ((opt = getopt(argc, argv, "p:u:d:n:")) != EOF)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'p':
|
||||
prompt = optarg;
|
||||
break;
|
||||
case 'u':
|
||||
fd = atoi(optarg);
|
||||
if (fd < 0)
|
||||
{
|
||||
fprintf (stderr, "%s: bad file descriptor `%s'\n", progname, optarg);
|
||||
exit (2);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
deftext = optarg;
|
||||
break;
|
||||
case 'n':
|
||||
nch = atoi(optarg);
|
||||
if (nch < 0)
|
||||
{
|
||||
fprintf (stderr, "%s: bad value for -n: `%s'\n", progname, optarg);
|
||||
exit (2);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
usage ();
|
||||
exit (2);
|
||||
}
|
||||
}
|
||||
|
||||
if (fd != 0)
|
||||
{
|
||||
if (fstat (fd, &sb) < 0)
|
||||
{
|
||||
fprintf (stderr, "%s: %d: bad file descriptor\n", progname, fd);
|
||||
exit (1);
|
||||
}
|
||||
ifp = fdopen (fd, "r");
|
||||
rl_instream = ifp;
|
||||
}
|
||||
|
||||
if (deftext && *deftext)
|
||||
rl_startup_hook = set_deftext;
|
||||
|
||||
if (nch > 0)
|
||||
rl_num_chars_to_read = nch;
|
||||
|
||||
temp = readline (prompt);
|
||||
|
||||
/* Test for EOF. */
|
||||
if (temp == 0)
|
||||
exit (1);
|
||||
|
||||
printf ("%s\n", temp);
|
||||
exit (0);
|
||||
}
|
||||
@@ -1,254 +0,0 @@
|
||||
/* funmap.c -- attach names to functions. */
|
||||
|
||||
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#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 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 },
|
||||
{ "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 },
|
||||
{ "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 },
|
||||
{ "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-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-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-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-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
@@ -1,441 +0,0 @@
|
||||
/* history.c -- standalone history library */
|
||||
|
||||
/* Copyright (C) 1989-2003 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the GNU History Library (the Library), a set of
|
||||
routines for managing the text of previously typed lines.
|
||||
|
||||
The Library 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, or (at your option)
|
||||
any later version.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
/* 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 carefull, 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)
|
||||
? (HIST_ENTRY *)NULL
|
||||
: the_history[local_index];
|
||||
}
|
||||
|
||||
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 = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
|
||||
temp->line = savestring (string);
|
||||
temp->data = (char *)NULL;
|
||||
|
||||
temp->timestamp = 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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* 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)
|
||||
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;
|
||||
}
|
||||
@@ -1,566 +0,0 @@
|
||||
/* input.c -- character input functions for readline. */
|
||||
|
||||
/* Copyright (C) 1994-2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#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 */
|
||||
|
||||
#if defined (HAVE_SELECT)
|
||||
# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)
|
||||
# include <sys/time.h>
|
||||
# endif
|
||||
#endif /* HAVE_SELECT */
|
||||
#if defined (HAVE_SYS_SELECT_H)
|
||||
# include <sys/select.h>
|
||||
#endif
|
||||
|
||||
#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 (pop_index >= ibuffer_len)
|
||||
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 - 1;
|
||||
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
|
||||
|
||||
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;
|
||||
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 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--)
|
||||
{
|
||||
k = (*rl_getc_function) (rl_instream);
|
||||
rl_stuff_char (k);
|
||||
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
|
||||
|
||||
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);
|
||||
free (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 (push_index >= ibuffer_len)
|
||||
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 && rl_get_char (&c) == 0)
|
||||
{
|
||||
(*rl_event_hook) ();
|
||||
if (rl_done) /* XXX - experimental */
|
||||
return ('\n');
|
||||
if (rl_gather_tyi () < 0) /* XXX - EIO */
|
||||
{
|
||||
rl_done = 1;
|
||||
return ('\n');
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (rl_get_char (&c) == 0)
|
||||
c = (*rl_getc_function) (rl_instream);
|
||||
}
|
||||
}
|
||||
|
||||
return (c);
|
||||
}
|
||||
|
||||
int
|
||||
rl_getc (stream)
|
||||
FILE *stream;
|
||||
{
|
||||
int result;
|
||||
unsigned char c;
|
||||
|
||||
while (1)
|
||||
{
|
||||
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 (EOF);
|
||||
}
|
||||
}
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
/* read multibyte char */
|
||||
int
|
||||
_rl_read_mbchar (mbchar, size)
|
||||
char *mbchar;
|
||||
int size;
|
||||
{
|
||||
int mb_len = 0;
|
||||
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));
|
||||
|
||||
while (mb_len < size)
|
||||
{
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
mbchar[mb_len++] = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
|
||||
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 MBLEN. 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, mblen)
|
||||
int first;
|
||||
char *mb;
|
||||
int mblen;
|
||||
{
|
||||
int i, c;
|
||||
mbstate_t ps;
|
||||
|
||||
c = first;
|
||||
memset (mb, 0, mblen);
|
||||
for (i = 0; i < mblen; 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 */
|
||||
@@ -1,560 +0,0 @@
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* I-Search and Searching */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the Readline Library (the Library), a set of
|
||||
routines for providing Emacs style line input to programs that ask
|
||||
for it.
|
||||
|
||||
The Library 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, or (at your option)
|
||||
any later version.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#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;
|
||||
|
||||
/* Variables imported from other files in the readline library. */
|
||||
extern HIST_ENTRY *_rl_saved_line_for_history;
|
||||
|
||||
/* Forward declarations */
|
||||
static int rl_search_history PARAMS((int, int));
|
||||
|
||||
/* Last line found by the current incremental search, so we don't `find'
|
||||
identical lines many times in a row. */
|
||||
static char *prev_line_found;
|
||||
|
||||
/* Last search string and its length. */
|
||||
static char *last_isearch_string;
|
||||
static int last_isearch_string_len;
|
||||
|
||||
static char *default_isearch_terminators = "\033\012";
|
||||
|
||||
/* 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 1 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);
|
||||
free (message);
|
||||
(*rl_redisplay_function) ();
|
||||
}
|
||||
|
||||
/* 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;
|
||||
{
|
||||
/* The string that the user types in to search for. */
|
||||
char *search_string;
|
||||
|
||||
/* The current length of SEARCH_STRING. */
|
||||
int search_string_index;
|
||||
|
||||
/* The amount of space that SEARCH_STRING has allocated to it. */
|
||||
int search_string_size;
|
||||
|
||||
/* The list of lines to search through. */
|
||||
char **lines, *allocated_line;
|
||||
|
||||
/* The length of LINES. */
|
||||
int hlen;
|
||||
|
||||
/* Where we get LINES from. */
|
||||
HIST_ENTRY **hlist;
|
||||
|
||||
register int i;
|
||||
int orig_point, orig_mark, orig_line, last_found_line;
|
||||
int c, found, failed, sline_len;
|
||||
int n, wstart, wlen;
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
char mb[MB_LEN_MAX];
|
||||
#endif
|
||||
|
||||
/* The line currently being searched. */
|
||||
char *sline;
|
||||
|
||||
/* Offset in that line. */
|
||||
int line_index;
|
||||
|
||||
/* Non-zero if we are doing a reverse search. */
|
||||
int reverse;
|
||||
|
||||
/* The list of characters which terminate the search, but are not
|
||||
subsequently executed. If the variable isearch-terminators has
|
||||
been set, we use that value, otherwise we use ESC and C-J. */
|
||||
char *isearch_terminators;
|
||||
|
||||
RL_SETSTATE(RL_STATE_ISEARCH);
|
||||
orig_point = rl_point;
|
||||
orig_mark = rl_mark;
|
||||
last_found_line = orig_line = where_history ();
|
||||
reverse = direction < 0;
|
||||
hlist = history_list ();
|
||||
allocated_line = (char *)NULL;
|
||||
|
||||
isearch_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
|
||||
: default_isearch_terminators;
|
||||
|
||||
/* Create an arrary of pointers to the lines that we want to search. */
|
||||
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. */
|
||||
lines = (char **)xmalloc ((1 + (hlen = i)) * sizeof (char *));
|
||||
for (i = 0; i < hlen; i++)
|
||||
lines[i] = hlist[i]->line;
|
||||
|
||||
if (_rl_saved_line_for_history)
|
||||
lines[i] = _rl_saved_line_for_history->line;
|
||||
else
|
||||
{
|
||||
/* Keep track of this so we can free it. */
|
||||
allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
|
||||
strcpy (allocated_line, &rl_line_buffer[0]);
|
||||
lines[i] = allocated_line;
|
||||
}
|
||||
|
||||
hlen++;
|
||||
|
||||
/* The line where we start the search. */
|
||||
i = orig_line;
|
||||
|
||||
rl_save_prompt ();
|
||||
|
||||
/* Initialize search parameters. */
|
||||
search_string = (char *)xmalloc (search_string_size = 128);
|
||||
*search_string = '\0';
|
||||
search_string_index = 0;
|
||||
prev_line_found = (char *)0; /* XXX */
|
||||
|
||||
/* Normalize DIRECTION into 1 or -1. */
|
||||
direction = (direction >= 0) ? 1 : -1;
|
||||
|
||||
rl_display_search (search_string, reverse, -1);
|
||||
|
||||
sline = rl_line_buffer;
|
||||
sline_len = strlen (sline);
|
||||
line_index = rl_point;
|
||||
|
||||
found = failed = 0;
|
||||
for (;;)
|
||||
{
|
||||
rl_command_func_t *f = (rl_command_func_t *)NULL;
|
||||
|
||||
/* Read a key and decide how to proceed. */
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
c = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
|
||||
#endif
|
||||
|
||||
/* Translate the keys we do something with to opcodes. */
|
||||
if (c >= 0 && _rl_keymap[c].type == ISFUNC)
|
||||
{
|
||||
f = _rl_keymap[c].function;
|
||||
|
||||
if (f == rl_reverse_search_history)
|
||||
c = reverse ? -1 : -2;
|
||||
else if (f == rl_forward_search_history)
|
||||
c = !reverse ? -1 : -2;
|
||||
else if (f == rl_rubout)
|
||||
c = -3;
|
||||
else if (c == CTRL ('G'))
|
||||
c = -4;
|
||||
else if (c == CTRL ('W')) /* XXX */
|
||||
c = -5;
|
||||
else if (c == CTRL ('Y')) /* XXX */
|
||||
c = -6;
|
||||
}
|
||||
|
||||
/* The characters in isearch_terminators (set from the user-settable
|
||||
variable isearch-terminators) are used to terminate the search but
|
||||
not subsequently execute the character as a command. The default
|
||||
value is "\033\012" (ESC and C-J). */
|
||||
if (strchr (isearch_terminators, c))
|
||||
{
|
||||
/* 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 (c == ESC && _rl_input_available ())
|
||||
rl_execute_next (ESC);
|
||||
break;
|
||||
}
|
||||
|
||||
#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 (c >= 0 && strlen (mb) == 1 && ENDSRCH_CHAR (c))
|
||||
{
|
||||
/* This sets rl_pending_input to c; it will be picked up the next
|
||||
time rl_read_key is called. */
|
||||
rl_execute_next (c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (c >= 0 && ENDSRCH_CHAR (c))
|
||||
{
|
||||
/* This sets rl_pending_input to c; it will be picked up the next
|
||||
time rl_read_key is called. */
|
||||
rl_execute_next (c);
|
||||
break;
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case -1:
|
||||
if (search_string_index == 0)
|
||||
{
|
||||
if (last_isearch_string)
|
||||
{
|
||||
search_string_size = 64 + last_isearch_string_len;
|
||||
search_string = (char *)xrealloc (search_string, search_string_size);
|
||||
strcpy (search_string, last_isearch_string);
|
||||
search_string_index = last_isearch_string_len;
|
||||
rl_display_search (search_string, reverse, -1);
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (reverse)
|
||||
--line_index;
|
||||
else if (line_index != sline_len)
|
||||
++line_index;
|
||||
else
|
||||
rl_ding ();
|
||||
break;
|
||||
|
||||
/* switch directions */
|
||||
case -2:
|
||||
direction = -direction;
|
||||
reverse = direction < 0;
|
||||
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 (search_string_index == 0)
|
||||
rl_ding ();
|
||||
else
|
||||
search_string[--search_string_index] = '\0';
|
||||
|
||||
break;
|
||||
|
||||
case -4: /* C-G */
|
||||
rl_replace_line (lines[orig_line], 0);
|
||||
rl_point = orig_point;
|
||||
rl_mark = orig_mark;
|
||||
rl_restore_prompt();
|
||||
rl_clear_message ();
|
||||
if (allocated_line)
|
||||
free (allocated_line);
|
||||
free (lines);
|
||||
RL_UNSETSTATE(RL_STATE_ISEARCH);
|
||||
return 0;
|
||||
|
||||
case -5: /* C-W */
|
||||
/* skip over portion of line we already matched */
|
||||
wstart = rl_point + search_string_index;
|
||||
if (wstart >= rl_end)
|
||||
{
|
||||
rl_ding ();
|
||||
break;
|
||||
}
|
||||
|
||||
/* if not in a word, move to one. */
|
||||
if (rl_alphabetic(rl_line_buffer[wstart]) == 0)
|
||||
{
|
||||
rl_ding ();
|
||||
break;
|
||||
}
|
||||
n = wstart;
|
||||
while (n < rl_end && rl_alphabetic(rl_line_buffer[n]))
|
||||
n++;
|
||||
wlen = n - wstart + 1;
|
||||
if (search_string_index + wlen + 1 >= search_string_size)
|
||||
{
|
||||
search_string_size += wlen + 1;
|
||||
search_string = (char *)xrealloc (search_string, search_string_size);
|
||||
}
|
||||
for (; wstart < n; wstart++)
|
||||
search_string[search_string_index++] = rl_line_buffer[wstart];
|
||||
search_string[search_string_index] = '\0';
|
||||
break;
|
||||
|
||||
case -6: /* C-Y */
|
||||
/* skip over portion of line we already matched */
|
||||
wstart = rl_point + search_string_index;
|
||||
if (wstart >= rl_end)
|
||||
{
|
||||
rl_ding ();
|
||||
break;
|
||||
}
|
||||
n = rl_end - wstart + 1;
|
||||
if (search_string_index + n + 1 >= search_string_size)
|
||||
{
|
||||
search_string_size += n + 1;
|
||||
search_string = (char *)xrealloc (search_string, search_string_size);
|
||||
}
|
||||
for (n = wstart; n < rl_end; n++)
|
||||
search_string[search_string_index++] = rl_line_buffer[n];
|
||||
search_string[search_string_index] = '\0';
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Add character to search string and continue search. */
|
||||
if (search_string_index + 2 >= search_string_size)
|
||||
{
|
||||
search_string_size += 128;
|
||||
search_string = (char *)xrealloc (search_string, search_string_size);
|
||||
}
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
|
||||
{
|
||||
int j, l;
|
||||
for (j = 0, l = strlen (mb); j < l; )
|
||||
search_string[search_string_index++] = mb[j++];
|
||||
}
|
||||
else
|
||||
#endif
|
||||
search_string[search_string_index++] = c;
|
||||
search_string[search_string_index] = '\0';
|
||||
break;
|
||||
}
|
||||
|
||||
for (found = failed = 0;;)
|
||||
{
|
||||
int limit = sline_len - search_string_index + 1;
|
||||
|
||||
/* Search the current line. */
|
||||
while (reverse ? (line_index >= 0) : (line_index < limit))
|
||||
{
|
||||
if (STREQN (search_string, sline + line_index, search_string_index))
|
||||
{
|
||||
found++;
|
||||
break;
|
||||
}
|
||||
else
|
||||
line_index += direction;
|
||||
}
|
||||
if (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. */
|
||||
i += direction;
|
||||
|
||||
/* At limit for direction? */
|
||||
if (reverse ? (i < 0) : (i == hlen))
|
||||
{
|
||||
failed++;
|
||||
break;
|
||||
}
|
||||
|
||||
/* We will need these later. */
|
||||
sline = lines[i];
|
||||
sline_len = strlen (sline);
|
||||
}
|
||||
while ((prev_line_found && STREQ (prev_line_found, lines[i])) ||
|
||||
(search_string_index > sline_len));
|
||||
|
||||
if (failed)
|
||||
break;
|
||||
|
||||
/* Now set up the line for searching... */
|
||||
line_index = reverse ? sline_len - search_string_index : 0;
|
||||
}
|
||||
|
||||
if (failed)
|
||||
{
|
||||
/* We cannot find the search string. Ding the bell. */
|
||||
rl_ding ();
|
||||
i = last_found_line;
|
||||
continue; /* XXX - was break */
|
||||
}
|
||||
|
||||
/* 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 (found)
|
||||
{
|
||||
prev_line_found = lines[i];
|
||||
rl_replace_line (lines[i], 0);
|
||||
rl_point = line_index;
|
||||
last_found_line = i;
|
||||
rl_display_search (search_string, reverse, (i == orig_line) ? -1 : i);
|
||||
}
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
/* First put back the original state. */
|
||||
strcpy (rl_line_buffer, lines[orig_line]);
|
||||
|
||||
rl_restore_prompt ();
|
||||
|
||||
/* Save the search string for possible later use. */
|
||||
FREE (last_isearch_string);
|
||||
last_isearch_string = search_string;
|
||||
last_isearch_string_len = search_string_index;
|
||||
|
||||
if (last_found_line < orig_line)
|
||||
rl_get_previous_history (orig_line - last_found_line, 0);
|
||||
else
|
||||
rl_get_next_history (last_found_line - orig_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 (line_index < 0)
|
||||
{
|
||||
if (last_found_line == orig_line)
|
||||
line_index = orig_point;
|
||||
else
|
||||
line_index = strlen (rl_line_buffer);
|
||||
rl_mark = orig_mark;
|
||||
}
|
||||
|
||||
rl_point = line_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 ();
|
||||
|
||||
FREE (allocated_line);
|
||||
free (lines);
|
||||
|
||||
RL_UNSETSTATE(RL_STATE_ISEARCH);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,666 +0,0 @@
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* I-Search and Searching */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the Readline Library (the Library), a set of
|
||||
routines for providing Emacs style line input to programs that ask
|
||||
for it.
|
||||
|
||||
The Library 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, or (at your option)
|
||||
any later version.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#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. */
|
||||
static char *prev_line_found;
|
||||
|
||||
/* Last search string and its length. */
|
||||
static char *last_isearch_string;
|
||||
static int last_isearch_string_len;
|
||||
|
||||
static char *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->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);
|
||||
|
||||
free (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 1 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);
|
||||
free (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;
|
||||
|
||||
/* Translate the keys we do something with to opcodes. */
|
||||
if (c >= 0 && _rl_keymap[c].type == ISFUNC)
|
||||
{
|
||||
f = _rl_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;
|
||||
}
|
||||
|
||||
/* The characters in isearch_terminators (set from the user-settable
|
||||
variable isearch-terminators) are used to terminate the search but
|
||||
not subsequently execute the character as a command. The default
|
||||
value is "\033\012" (ESC and C-J). */
|
||||
if (strchr (cxt->search_terminators, cxt->lastc))
|
||||
{
|
||||
/* 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 c; 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
|
||||
@@ -1,373 +0,0 @@
|
||||
/* mbutil.c -- readline multibyte character utility functions */
|
||||
|
||||
/* Copyright (C) 2001-2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#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"
|
||||
|
||||
/* Declared here so it can be shared between the readline and history
|
||||
libraries. */
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
int rl_byte_oriented = 0;
|
||||
#else
|
||||
int rl_byte_oriented = 1;
|
||||
#endif
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Multibyte Character Utility Functions */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#if defined(HANDLE_MULTIBYTE)
|
||||
|
||||
static int
|
||||
_rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
|
||||
char *string;
|
||||
int seed, count, find_non_zero;
|
||||
{
|
||||
size_t tmp;
|
||||
mbstate_t ps;
|
||||
int point;
|
||||
wchar_t wc;
|
||||
|
||||
tmp = 0;
|
||||
|
||||
memset(&ps, 0, sizeof (mbstate_t));
|
||||
if (seed < 0)
|
||||
seed = 0;
|
||||
if (count <= 0)
|
||||
return seed;
|
||||
|
||||
point = seed + _rl_adjust_point (string, seed, &ps);
|
||||
/* if this is true, means that seed was not pointed character
|
||||
started byte. So correct the point and consume count */
|
||||
if (seed < point)
|
||||
count--;
|
||||
|
||||
while (count > 0)
|
||||
{
|
||||
tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps);
|
||||
if (MB_INVALIDCH ((size_t)tmp))
|
||||
{
|
||||
/* invalid bytes. asume a byte represents a character */
|
||||
point++;
|
||||
count--;
|
||||
/* reset states. */
|
||||
memset(&ps, 0, sizeof(mbstate_t));
|
||||
}
|
||||
else if (MB_NULLWCH (tmp))
|
||||
break; /* found wide '\0' */
|
||||
else
|
||||
{
|
||||
/* valid bytes */
|
||||
point += tmp;
|
||||
if (find_non_zero)
|
||||
{
|
||||
if (wcwidth (wc) == 0)
|
||||
continue;
|
||||
else
|
||||
count--;
|
||||
}
|
||||
else
|
||||
count--;
|
||||
}
|
||||
}
|
||||
|
||||
if (find_non_zero)
|
||||
{
|
||||
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
|
||||
while (tmp > 0 && wcwidth (wc) == 0)
|
||||
{
|
||||
point += tmp;
|
||||
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
|
||||
if (MB_NULLWCH (tmp) || MB_INVALIDCH (tmp))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return point;
|
||||
}
|
||||
|
||||
static int
|
||||
_rl_find_prev_mbchar_internal (string, seed, find_non_zero)
|
||||
char *string;
|
||||
int seed, find_non_zero;
|
||||
{
|
||||
mbstate_t ps;
|
||||
int prev, non_zero_prev, point, length;
|
||||
size_t tmp;
|
||||
wchar_t wc;
|
||||
|
||||
memset(&ps, 0, sizeof(mbstate_t));
|
||||
length = strlen(string);
|
||||
|
||||
if (seed < 0)
|
||||
return 0;
|
||||
else if (length < seed)
|
||||
return length;
|
||||
|
||||
prev = non_zero_prev = point = 0;
|
||||
while (point < seed)
|
||||
{
|
||||
tmp = mbrtowc (&wc, string + point, length - point, &ps);
|
||||
if (MB_INVALIDCH ((size_t)tmp))
|
||||
{
|
||||
/* in this case, bytes are invalid or shorted to compose
|
||||
multibyte char, so assume that the first byte represents
|
||||
a single character anyway. */
|
||||
tmp = 1;
|
||||
/* clear the state of the byte sequence, because
|
||||
in this case effect of mbstate is undefined */
|
||||
memset(&ps, 0, sizeof (mbstate_t));
|
||||
|
||||
/* Since we're assuming that this byte represents a single
|
||||
non-zero-width character, don't forget about it. */
|
||||
prev = point;
|
||||
}
|
||||
else if (MB_NULLWCH (tmp))
|
||||
break; /* Found '\0' char. Can this happen? */
|
||||
else
|
||||
{
|
||||
if (find_non_zero)
|
||||
{
|
||||
if (wcwidth (wc) != 0)
|
||||
prev = point;
|
||||
}
|
||||
else
|
||||
prev = point;
|
||||
}
|
||||
|
||||
point += tmp;
|
||||
}
|
||||
|
||||
return prev;
|
||||
}
|
||||
|
||||
/* return the number of bytes parsed from the multibyte sequence starting
|
||||
at src, if a non-L'\0' wide character was recognized. It returns 0,
|
||||
if a L'\0' wide character was recognized. It returns (size_t)(-1),
|
||||
if an invalid multibyte sequence was encountered. It returns (size_t)(-2)
|
||||
if it couldn't parse a complete multibyte character. */
|
||||
int
|
||||
_rl_get_char_len (src, ps)
|
||||
char *src;
|
||||
mbstate_t *ps;
|
||||
{
|
||||
size_t tmp;
|
||||
|
||||
tmp = mbrlen((const char *)src, (size_t)strlen (src), ps);
|
||||
if (tmp == (size_t)(-2))
|
||||
{
|
||||
/* shorted to compose multibyte char */
|
||||
if (ps)
|
||||
memset (ps, 0, sizeof(mbstate_t));
|
||||
return -2;
|
||||
}
|
||||
else if (tmp == (size_t)(-1))
|
||||
{
|
||||
/* invalid to compose multibyte char */
|
||||
/* initialize the conversion state */
|
||||
if (ps)
|
||||
memset (ps, 0, sizeof(mbstate_t));
|
||||
return -1;
|
||||
}
|
||||
else if (tmp == (size_t)0)
|
||||
return 0;
|
||||
else
|
||||
return (int)tmp;
|
||||
}
|
||||
|
||||
/* compare the specified two characters. If the characters matched,
|
||||
return 1. Otherwise return 0. */
|
||||
int
|
||||
_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2)
|
||||
char *buf1;
|
||||
int pos1;
|
||||
mbstate_t *ps1;
|
||||
char *buf2;
|
||||
int pos2;
|
||||
mbstate_t *ps2;
|
||||
{
|
||||
int i, w1, w2;
|
||||
|
||||
if ((w1 = _rl_get_char_len (&buf1[pos1], ps1)) <= 0 ||
|
||||
(w2 = _rl_get_char_len (&buf2[pos2], ps2)) <= 0 ||
|
||||
(w1 != w2) ||
|
||||
(buf1[pos1] != buf2[pos2]))
|
||||
return 0;
|
||||
|
||||
for (i = 1; i < w1; i++)
|
||||
if (buf1[pos1+i] != buf2[pos2+i])
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* adjust pointed byte and find mbstate of the point of string.
|
||||
adjusted point will be point <= adjusted_point, and returns
|
||||
differences of the byte(adjusted_point - point).
|
||||
if point is invalied (point < 0 || more than string length),
|
||||
it returns -1 */
|
||||
int
|
||||
_rl_adjust_point(string, point, ps)
|
||||
char *string;
|
||||
int point;
|
||||
mbstate_t *ps;
|
||||
{
|
||||
size_t tmp = 0;
|
||||
int length;
|
||||
int pos = 0;
|
||||
|
||||
length = strlen(string);
|
||||
if (point < 0)
|
||||
return -1;
|
||||
if (length < point)
|
||||
return -1;
|
||||
|
||||
while (pos < point)
|
||||
{
|
||||
tmp = mbrlen (string + pos, length - pos, ps);
|
||||
if (MB_INVALIDCH ((size_t)tmp))
|
||||
{
|
||||
/* in this case, bytes are invalid or shorted to compose
|
||||
multibyte char, so assume that the first byte represents
|
||||
a single character anyway. */
|
||||
pos++;
|
||||
/* clear the state of the byte sequence, because
|
||||
in this case effect of mbstate is undefined */
|
||||
if (ps)
|
||||
memset (ps, 0, sizeof (mbstate_t));
|
||||
}
|
||||
else if (MB_NULLWCH (tmp))
|
||||
pos++;
|
||||
else
|
||||
pos += tmp;
|
||||
}
|
||||
|
||||
return (pos - point);
|
||||
}
|
||||
|
||||
int
|
||||
_rl_is_mbchar_matched (string, seed, end, mbchar, length)
|
||||
char *string;
|
||||
int seed, end;
|
||||
char *mbchar;
|
||||
int length;
|
||||
{
|
||||
int i;
|
||||
|
||||
if ((end - seed) < length)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < length; i++)
|
||||
if (string[seed + i] != mbchar[i])
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
wchar_t
|
||||
_rl_char_value (buf, ind)
|
||||
char *buf;
|
||||
int ind;
|
||||
{
|
||||
size_t tmp;
|
||||
wchar_t wc;
|
||||
mbstate_t ps;
|
||||
int l;
|
||||
|
||||
if (MB_LEN_MAX == 1 || rl_byte_oriented)
|
||||
return ((wchar_t) buf[ind]);
|
||||
l = strlen (buf);
|
||||
if (ind >= l - 1)
|
||||
return ((wchar_t) buf[ind]);
|
||||
memset (&ps, 0, sizeof (mbstate_t));
|
||||
tmp = mbrtowc (&wc, buf + ind, l - ind, &ps);
|
||||
if (MB_INVALIDCH (tmp) || MB_NULLWCH (tmp))
|
||||
return ((wchar_t) buf[ind]);
|
||||
return wc;
|
||||
}
|
||||
#endif /* HANDLE_MULTIBYTE */
|
||||
|
||||
/* Find next `count' characters started byte point of the specified seed.
|
||||
If flags is MB_FIND_NONZERO, we look for non-zero-width multibyte
|
||||
characters. */
|
||||
#undef _rl_find_next_mbchar
|
||||
int
|
||||
_rl_find_next_mbchar (string, seed, count, flags)
|
||||
char *string;
|
||||
int seed, count, flags;
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
return _rl_find_next_mbchar_internal (string, seed, count, flags);
|
||||
#else
|
||||
return (seed + count);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Find previous character started byte point of the specified seed.
|
||||
Returned point will be point <= seed. If flags is MB_FIND_NONZERO,
|
||||
we look for non-zero-width multibyte characters. */
|
||||
#undef _rl_find_prev_mbchar
|
||||
int
|
||||
_rl_find_prev_mbchar (string, seed, flags)
|
||||
char *string;
|
||||
int seed, flags;
|
||||
{
|
||||
#if defined (HANDLE_MULTIBYTE)
|
||||
return _rl_find_prev_mbchar_internal (string, seed, flags);
|
||||
#else
|
||||
return ((seed == 0) ? seed : seed - 1);
|
||||
#endif
|
||||
}
|
||||
@@ -1,510 +0,0 @@
|
||||
/* misc.c -- miscellaneous bindable readline functions. */
|
||||
|
||||
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#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;
|
||||
|
||||
/* 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 */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
/* Handle C-u style numeric args, as well as M--, and M-digits. */
|
||||
static int
|
||||
rl_digit_loop ()
|
||||
{
|
||||
int key, c, sawminus, sawdigits;
|
||||
|
||||
rl_save_prompt ();
|
||||
|
||||
RL_SETSTATE(RL_STATE_NUMERICARG);
|
||||
sawminus = sawdigits = 0;
|
||||
while (1)
|
||||
{
|
||||
if (rl_numeric_arg > 1000000)
|
||||
{
|
||||
sawdigits = rl_explicit_arg = rl_numeric_arg = 0;
|
||||
rl_ding ();
|
||||
rl_restore_prompt ();
|
||||
rl_clear_message ();
|
||||
RL_UNSETSTATE(RL_STATE_NUMERICARG);
|
||||
return 1;
|
||||
}
|
||||
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
|
||||
RL_SETSTATE(RL_STATE_MOREINPUT);
|
||||
key = c = rl_read_key ();
|
||||
RL_UNSETSTATE(RL_STATE_MOREINPUT);
|
||||
|
||||
if (c < 0)
|
||||
{
|
||||
_rl_abort_internal ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* 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 (sawdigits == 0)
|
||||
{
|
||||
rl_numeric_arg *= 4;
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
return (_rl_dispatch (key, _rl_keymap));
|
||||
}
|
||||
}
|
||||
|
||||
c = UNMETA (c);
|
||||
|
||||
if (_rl_digit_p (c))
|
||||
{
|
||||
rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + c - '0' : c - '0';
|
||||
sawdigits = rl_explicit_arg = 1;
|
||||
}
|
||||
else if (c == '-' && rl_explicit_arg == 0)
|
||||
{
|
||||
rl_numeric_arg = sawminus = 1;
|
||||
rl_arg_sign = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Make M-- command equivalent to M--1 command. */
|
||||
if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0)
|
||||
rl_explicit_arg = 1;
|
||||
rl_restore_prompt ();
|
||||
rl_clear_message ();
|
||||
RL_UNSETSTATE(RL_STATE_NUMERICARG);
|
||||
return (_rl_dispatch (key, _rl_keymap));
|
||||
}
|
||||
}
|
||||
|
||||
/*NOTREACHED*/
|
||||
}
|
||||
|
||||
/* Add the current digit to the argument in progress. */
|
||||
int
|
||||
rl_digit_argument (ignore, key)
|
||||
int ignore, key;
|
||||
{
|
||||
rl_execute_next (key);
|
||||
return (rl_digit_loop ());
|
||||
}
|
||||
|
||||
/* What to do when you abort reading an argument. */
|
||||
int
|
||||
rl_discard_argument ()
|
||||
{
|
||||
rl_ding ();
|
||||
rl_clear_message ();
|
||||
_rl_init_argument ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Create a default argument. */
|
||||
int
|
||||
_rl_init_argument ()
|
||||
{
|
||||
rl_numeric_arg = rl_arg_sign = 1;
|
||||
rl_explicit_arg = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* 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_numeric_arg *= 4;
|
||||
return (rl_digit_loop ());
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* 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;
|
||||
if (entry->line)
|
||||
free (entry->line);
|
||||
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);
|
||||
}
|
||||
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->data = (char *)rl_undo_list;
|
||||
}
|
||||
#if 0
|
||||
else if (STREQ (rl_line_buffer, _rl_saved_line_for_history->line) == 0)
|
||||
{
|
||||
free (_rl_saved_line_for_history->line);
|
||||
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
|
||||
_rl_saved_line_for_history->data = (char *)rl_undo_list; /* XXX possible memleak */
|
||||
}
|
||||
#endif
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* 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_insertion_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;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,844 +0,0 @@
|
||||
/* Readline.h -- the names of functions callable from within readline. */
|
||||
|
||||
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#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 0x0501 /* Readline 5.1 */
|
||||
#define RL_VERSION_MAJOR 5
|
||||
#define RL_VERSION_MINOR 1
|
||||
|
||||
/* 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_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_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_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));
|
||||
|
||||
/* 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 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 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, 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;
|
||||
|
||||
/* 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. */
|
||||
extern rl_icppfunc_t *rl_directory_completion_hook;
|
||||
|
||||
/* If non-zero, this is the address of a function to call when completing
|
||||
a directory name. This function takes the address of the directory name
|
||||
to be modified as an argument. Unlike rl_directory_completion_hook, it
|
||||
only modifies the directory name used in opendir(2), not what is displayed
|
||||
when the possible completions are printed or inserted. It is called
|
||||
before rl_directory_completion_hook. I'm not happy with how this works
|
||||
yet, so it's undocumented. */
|
||||
extern rl_icppfunc_t *rl_directory_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;
|
||||
|
||||
/* 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, 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;
|
||||
|
||||
/* 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 0x000001 /* initializing */
|
||||
#define RL_STATE_INITIALIZED 0x000002 /* initialization done */
|
||||
#define RL_STATE_TERMPREPPED 0x000004 /* terminal is prepped */
|
||||
#define RL_STATE_READCMD 0x000008 /* reading a command key */
|
||||
#define RL_STATE_METANEXT 0x000010 /* reading input after ESC */
|
||||
#define RL_STATE_DISPATCHING 0x000020 /* dispatching to a command */
|
||||
#define RL_STATE_MOREINPUT 0x000040 /* reading more input in a command function */
|
||||
#define RL_STATE_ISEARCH 0x000080 /* doing incremental search */
|
||||
#define RL_STATE_NSEARCH 0x000100 /* doing non-inc search */
|
||||
#define RL_STATE_SEARCH 0x000200 /* doing a history search */
|
||||
#define RL_STATE_NUMERICARG 0x000400 /* reading numeric argument */
|
||||
#define RL_STATE_MACROINPUT 0x000800 /* getting input from a macro */
|
||||
#define RL_STATE_MACRODEF 0x001000 /* defining keyboard macro */
|
||||
#define RL_STATE_OVERWRITE 0x002000 /* overwrite mode */
|
||||
#define RL_STATE_COMPLETING 0x004000 /* doing completion */
|
||||
#define RL_STATE_SIGHANDLER 0x008000 /* in readline sighandler */
|
||||
#define RL_STATE_UNDOING 0x010000 /* doing an undo */
|
||||
#define RL_STATE_INPUTPENDING 0x020000 /* rl_execute_next called */
|
||||
#define RL_STATE_TTYCSAVED 0x040000 /* tty special chars saved */
|
||||
#define RL_STATE_CALLBACK 0x080000 /* using the callback interface */
|
||||
#define RL_STATE_VIMOTION 0x100000 /* reading vi motion arg */
|
||||
#define RL_STATE_MULTIKEY 0x200000 /* reading multiple-key command */
|
||||
#define RL_STATE_VICMDONCE 0x400000 /* entered vi command mode at least once */
|
||||
|
||||
#define RL_STATE_DONE 0x800000 /* 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_ */
|
||||
@@ -1,160 +0,0 @@
|
||||
/* rldefs.h -- an attempt to isolate some of the system-specific defines
|
||||
for readline. This should be included after any files that define
|
||||
system-specific constants like _POSIX_VERSION or USG. */
|
||||
|
||||
/* Copyright (C) 1987,1989 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the Readline Library (the Library), a set of
|
||||
routines for providing Emacs style line input to programs that ask
|
||||
for it.
|
||||
|
||||
The Library 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, or (at your option)
|
||||
any later version.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#if !defined (_RLDEFS_H_)
|
||||
#define _RLDEFS_H_
|
||||
|
||||
#if defined (HAVE_CONFIG_H)
|
||||
# include "config.h"
|
||||
#endif
|
||||
|
||||
#include "rlstdc.h"
|
||||
|
||||
#if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING)
|
||||
# define TERMIOS_TTY_DRIVER
|
||||
#else
|
||||
# if defined (HAVE_TERMIO_H)
|
||||
# define TERMIO_TTY_DRIVER
|
||||
# else
|
||||
# if !defined (__MINGW32__)
|
||||
# define NEW_TTY_DRIVER
|
||||
# else
|
||||
# define NO_TTY_DRIVER
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* Posix macro to check file in statbuf for directory-ness.
|
||||
This requires that <sys/stat.h> be included before this test. */
|
||||
#if defined (S_IFDIR) && !defined (S_ISDIR)
|
||||
# define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR)
|
||||
#endif
|
||||
|
||||
/* Decide which flavor of the header file describing the C library
|
||||
string functions to include and include it. */
|
||||
|
||||
#if defined (HAVE_STRING_H)
|
||||
# include <string.h>
|
||||
#else /* !HAVE_STRING_H */
|
||||
# include <strings.h>
|
||||
#endif /* !HAVE_STRING_H */
|
||||
|
||||
#if !defined (strchr) && !defined (__STDC__)
|
||||
extern char *strchr (), *strrchr ();
|
||||
#endif /* !strchr && !__STDC__ */
|
||||
|
||||
#if defined (PREFER_STDARG)
|
||||
# include <stdarg.h>
|
||||
#else
|
||||
# if defined (PREFER_VARARGS)
|
||||
# include <varargs.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_STRCASECMP)
|
||||
#define _rl_stricmp strcasecmp
|
||||
#define _rl_strnicmp strncasecmp
|
||||
#else
|
||||
extern int _rl_stricmp PARAMS((char *, char *));
|
||||
extern int _rl_strnicmp PARAMS((char *, char *, int));
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_STRPBRK) && !defined (HAVE_MULTIBYTE)
|
||||
# define _rl_strpbrk(a,b) strpbrk((a),(b))
|
||||
#else
|
||||
extern char *_rl_strpbrk PARAMS((const char *, const char *));
|
||||
#endif
|
||||
|
||||
#if !defined (emacs_mode)
|
||||
# define no_mode -1
|
||||
# define vi_mode 0
|
||||
# define emacs_mode 1
|
||||
#endif
|
||||
|
||||
#if !defined (RL_IM_INSERT)
|
||||
# define RL_IM_INSERT 1
|
||||
# define RL_IM_OVERWRITE 0
|
||||
#
|
||||
# define RL_IM_DEFAULT RL_IM_INSERT
|
||||
#endif
|
||||
|
||||
/* If you cast map[key].function to type (Keymap) on a Cray,
|
||||
the compiler takes the value of map[key].function and
|
||||
divides it by 4 to convert between pointer types (pointers
|
||||
to functions and pointers to structs are different sizes).
|
||||
This is not what is wanted. */
|
||||
#if defined (CRAY)
|
||||
# define FUNCTION_TO_KEYMAP(map, key) (Keymap)((int)map[key].function)
|
||||
# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)((int)(data))
|
||||
#else
|
||||
# define FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function)
|
||||
# define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)(data)
|
||||
#endif
|
||||
|
||||
#ifndef savestring
|
||||
#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
|
||||
#endif
|
||||
|
||||
/* Possible values for _rl_bell_preference. */
|
||||
#define NO_BELL 0
|
||||
#define AUDIBLE_BELL 1
|
||||
#define VISIBLE_BELL 2
|
||||
|
||||
/* Definitions used when searching the line for characters. */
|
||||
/* NOTE: it is necessary that opposite directions are inverses */
|
||||
#define FTO 1 /* forward to */
|
||||
#define BTO -1 /* backward to */
|
||||
#define FFIND 2 /* forward find */
|
||||
#define BFIND -2 /* backward find */
|
||||
|
||||
/* Possible values for the found_quote flags word used by the completion
|
||||
functions. It says what kind of (shell-like) quoting we found anywhere
|
||||
in the line. */
|
||||
#define RL_QF_SINGLE_QUOTE 0x01
|
||||
#define RL_QF_DOUBLE_QUOTE 0x02
|
||||
#define RL_QF_BACKSLASH 0x04
|
||||
#define RL_QF_OTHER_QUOTE 0x08
|
||||
|
||||
/* Default readline line buffer length. */
|
||||
#define DEFAULT_BUFFER_SIZE 256
|
||||
|
||||
#if !defined (STREQ)
|
||||
#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
|
||||
#define STREQN(a, b, n) (((n) == 0) ? (1) \
|
||||
: ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
|
||||
#endif
|
||||
|
||||
#if !defined (FREE)
|
||||
# define FREE(x) if (x) free (x)
|
||||
#endif
|
||||
|
||||
#if !defined (SWAP)
|
||||
# define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
|
||||
#endif
|
||||
|
||||
/* CONFIGURATION SECTION */
|
||||
#include "rlconf.h"
|
||||
|
||||
#endif /* !_RLDEFS_H_ */
|
||||
@@ -1,140 +0,0 @@
|
||||
/* rlmbutil.h -- utility functions for multibyte characters. */
|
||||
|
||||
/* Copyright (C) 2001 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#if !defined (_RL_MBUTIL_H_)
|
||||
#define _RL_MBUTIL_H_
|
||||
|
||||
#include "rlstdc.h"
|
||||
|
||||
/************************************************/
|
||||
/* check multibyte capability for I18N code */
|
||||
/************************************************/
|
||||
|
||||
/* For platforms which support the ISO C amendement 1 functionality we
|
||||
support user defined character classes. */
|
||||
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
|
||||
#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H)
|
||||
# include <wchar.h>
|
||||
# include <wctype.h>
|
||||
# if defined (HAVE_MBSRTOWCS) && defined (HAVE_MBRTOWC) && defined (HAVE_MBRLEN) && defined (HAVE_WCWIDTH)
|
||||
/* system is supposed to support XPG5 */
|
||||
# define HANDLE_MULTIBYTE 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* If we don't want multibyte chars even on a system that supports them, let
|
||||
the configuring user turn multibyte support off. */
|
||||
#if defined (NO_MULTIBYTE_SUPPORT)
|
||||
# undef HANDLE_MULTIBYTE
|
||||
#endif
|
||||
|
||||
/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
|
||||
#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T)
|
||||
# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0)
|
||||
# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0)
|
||||
# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0)
|
||||
# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
|
||||
# define mbrlen(s, n, ps) (mbrlen) (s, n, 0)
|
||||
# define mbstate_t int
|
||||
#endif
|
||||
|
||||
/* Make sure MB_LEN_MAX is at least 16 on systems that claim to be able to
|
||||
handle multibyte chars (some systems define MB_LEN_MAX as 1) */
|
||||
#ifdef HANDLE_MULTIBYTE
|
||||
# include <limits.h>
|
||||
# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16)
|
||||
# undef MB_LEN_MAX
|
||||
# endif
|
||||
# if !defined (MB_LEN_MAX)
|
||||
# define MB_LEN_MAX 16
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/************************************************/
|
||||
/* end of multibyte capability checks for I18N */
|
||||
/************************************************/
|
||||
|
||||
/*
|
||||
* Flags for _rl_find_prev_mbchar and _rl_find_next_mbchar:
|
||||
*
|
||||
* MB_FIND_ANY find any multibyte character
|
||||
* MB_FIND_NONZERO find a non-zero-width multibyte character
|
||||
*/
|
||||
|
||||
#define MB_FIND_ANY 0x00
|
||||
#define MB_FIND_NONZERO 0x01
|
||||
|
||||
extern int _rl_find_prev_mbchar PARAMS((char *, int, int));
|
||||
extern int _rl_find_next_mbchar PARAMS((char *, int, int, int));
|
||||
|
||||
#ifdef HANDLE_MULTIBYTE
|
||||
|
||||
extern int _rl_compare_chars PARAMS((char *, int, mbstate_t *, char *, int, mbstate_t *));
|
||||
extern int _rl_get_char_len PARAMS((char *, mbstate_t *));
|
||||
extern int _rl_adjust_point PARAMS((char *, int, mbstate_t *));
|
||||
|
||||
extern int _rl_read_mbchar PARAMS((char *, int));
|
||||
extern int _rl_read_mbstring PARAMS((int, char *, int));
|
||||
|
||||
extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
|
||||
|
||||
extern wchar_t _rl_char_value PARAMS((char *, int));
|
||||
extern int _rl_walphabetic PARAMS((wchar_t));
|
||||
|
||||
#define MB_NEXTCHAR(b,s,c,f) \
|
||||
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \
|
||||
? _rl_find_next_mbchar ((b), (s), (c), (f)) \
|
||||
: ((s) + (c)))
|
||||
#define MB_PREVCHAR(b,s,f) \
|
||||
((MB_CUR_MAX > 1 && rl_byte_oriented == 0) \
|
||||
? _rl_find_prev_mbchar ((b), (s), (f)) \
|
||||
: ((s) - 1))
|
||||
|
||||
#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2)
|
||||
#define MB_NULLWCH(x) ((x) == 0)
|
||||
|
||||
#else /* !HANDLE_MULTIBYTE */
|
||||
|
||||
#undef MB_LEN_MAX
|
||||
#undef MB_CUR_MAX
|
||||
|
||||
#define MB_LEN_MAX 1
|
||||
#define MB_CUR_MAX 1
|
||||
|
||||
#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1))
|
||||
#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2))
|
||||
|
||||
#define _rl_char_value(buf,ind) ((buf)[(ind)])
|
||||
|
||||
#define _rl_walphabetic(c) (rl_alphabetic (c))
|
||||
|
||||
#define MB_NEXTCHAR(b,s,c,f) ((s) + (c))
|
||||
#define MB_PREVCHAR(b,s,f) ((s) - 1)
|
||||
|
||||
#define MB_INVALIDCH(x) (0)
|
||||
#define MB_NULLWCH(x) (0)
|
||||
|
||||
#endif /* !HANDLE_MULTIBYTE */
|
||||
|
||||
extern int rl_byte_oriented;
|
||||
|
||||
#endif /* _RL_MBUTIL_H_ */
|
||||
@@ -1,418 +0,0 @@
|
||||
/* rlprivate.h -- functions and variables global to the readline library,
|
||||
but not intended for use by applications. */
|
||||
|
||||
/* Copyright (C) 1999-2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#if !defined (_RL_PRIVATE_H_)
|
||||
#define _RL_PRIVATE_H_
|
||||
|
||||
#include "rlconf.h" /* for VISIBLE_STATS */
|
||||
#include "rlstdc.h"
|
||||
#include "posixjmp.h" /* defines procenv_t */
|
||||
|
||||
/*************************************************************************
|
||||
* *
|
||||
* 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
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
/* 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 readline_echoing_p;
|
||||
extern int rl_key_sequence_length;
|
||||
extern int rl_byte_oriented;
|
||||
|
||||
extern _rl_keyseq_cxt *_rl_kscxt;
|
||||
|
||||
/* 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 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));
|
||||
|
||||
/* 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 *));
|
||||
|
||||
/* 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));
|
||||
|
||||
/* util.c */
|
||||
extern int _rl_abort_internal PARAMS((void));
|
||||
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));
|
||||
|
||||
/*************************************************************************
|
||||
* Undocumented private variables *
|
||||
*************************************************************************/
|
||||
|
||||
/* bind.c */
|
||||
extern const char *_rl_possible_control_prefixes[];
|
||||
extern const char *_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_print_completions_horizontally;
|
||||
extern int _rl_completion_case_fold;
|
||||
extern int _rl_match_hidden_files;
|
||||
extern int _rl_page_completions;
|
||||
|
||||
/* display.c */
|
||||
extern int _rl_vis_botlin;
|
||||
extern int _rl_last_c_pos;
|
||||
extern int _rl_suppress_redisplay;
|
||||
extern int _rl_want_redisplay;
|
||||
extern char *rl_display_prompt;
|
||||
|
||||
/* 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_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 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 readline_top_level;
|
||||
|
||||
/* search.c */
|
||||
extern _rl_search_cxt *_rl_nscxt;
|
||||
|
||||
/* 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 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;
|
||||
|
||||
#endif /* _RL_PRIVATE_H_ */
|
||||
@@ -1,989 +0,0 @@
|
||||
/* rltty.c -- functions to prepare and restore the terminal for readline's
|
||||
use. */
|
||||
|
||||
/* Copyright (C) 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#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 block_sigint PARAMS((void));
|
||||
static void release_sigint PARAMS((void));
|
||||
|
||||
static void set_winsize PARAMS((int));
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Signal Management */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
static sigset_t sigint_set, sigint_oset;
|
||||
#else /* !HAVE_POSIX_SIGNALS */
|
||||
# if defined (HAVE_BSD_SIGNALS)
|
||||
static int sigint_oldmask;
|
||||
# endif /* HAVE_BSD_SIGNALS */
|
||||
#endif /* !HAVE_POSIX_SIGNALS */
|
||||
|
||||
static int sigint_blocked;
|
||||
|
||||
/* Cause SIGINT to not be delivered until the corresponding call to
|
||||
release_sigint(). */
|
||||
static void
|
||||
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. */
|
||||
static void
|
||||
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;
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* 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 (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_tty_chars.t_intr = tiop->tchars.t_intrc;
|
||||
_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_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;
|
||||
}
|
||||
readline_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;
|
||||
{
|
||||
readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
|
||||
|
||||
/* 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_tty_chars.t_intr = tiop->c_cc[VINTR];
|
||||
_rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
|
||||
#ifdef VSUSP
|
||||
_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;
|
||||
{
|
||||
fprintf (stderr, "readline: warning: %s\n", msg);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined (_AIX)
|
||||
void
|
||||
setopost(tp)
|
||||
TIOTYPE *tp;
|
||||
{
|
||||
if ((tp->c_oflag & OPOST) == 0)
|
||||
{
|
||||
rltty_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) && defined (_AIX41)
|
||||
rltty_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;
|
||||
{
|
||||
readline_echoing_p = (oldtio.c_lflag & ECHO);
|
||||
|
||||
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. */
|
||||
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. */
|
||||
block_sigint ();
|
||||
|
||||
tty = fileno (rl_instream);
|
||||
|
||||
if (get_tty_settings (tty, &tio) < 0)
|
||||
{
|
||||
#if defined (ENOTSUP)
|
||||
/* MacOS X, at least, lies about the value of errno if tcgetattr fails. */
|
||||
if (errno == ENOTTY || errno == ENOTSUP)
|
||||
#else
|
||||
if (errno == ENOTTY)
|
||||
#endif
|
||||
readline_echoing_p = 1; /* XXX */
|
||||
release_sigint ();
|
||||
return;
|
||||
}
|
||||
|
||||
otio = tio;
|
||||
|
||||
if (_rl_bind_stty_chars)
|
||||
rl_tty_unset_default_bindings (_rl_keymap);
|
||||
save_tty_chars (&otio);
|
||||
RL_SETSTATE(RL_STATE_TTYCSAVED);
|
||||
if (_rl_bind_stty_chars)
|
||||
_rl_bind_tty_special_chars (_rl_keymap, tio);
|
||||
|
||||
prepare_terminal_settings (meta_flag, otio, &tio);
|
||||
|
||||
if (set_tty_settings (tty, &tio) < 0)
|
||||
{
|
||||
release_sigint ();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_rl_enable_keypad)
|
||||
_rl_control_keypad (1);
|
||||
|
||||
fflush (rl_outstream);
|
||||
terminal_prepped = 1;
|
||||
RL_SETSTATE(RL_STATE_TERMPREPPED);
|
||||
|
||||
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. */
|
||||
block_sigint ();
|
||||
|
||||
tty = fileno (rl_instream);
|
||||
|
||||
if (_rl_enable_keypad)
|
||||
_rl_control_keypad (0);
|
||||
|
||||
fflush (rl_outstream);
|
||||
|
||||
if (set_tty_settings (tty, &otio) < 0)
|
||||
{
|
||||
release_sigint ();
|
||||
return;
|
||||
}
|
||||
|
||||
terminal_prepped = 0;
|
||||
RL_UNSETSTATE(RL_STATE_TERMPREPPED);
|
||||
|
||||
release_sigint ();
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* 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;
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* Default Key Bindings */
|
||||
/* */
|
||||
/* **************************************************************** */
|
||||
|
||||
#define SET_SPECIAL(sc, func) set_special_char(kmap, &ttybuff, sc, func)
|
||||
|
||||
#if 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 (__MINGW32__)
|
||||
TIOTYPE ttybuff;
|
||||
int tty;
|
||||
static int called = 0;
|
||||
|
||||
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;
|
||||
{
|
||||
#if !defined (__MINGW32__)
|
||||
rltty_set_default_bindings (kmap);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* 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 (__MINGW32__)
|
||||
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 */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,572 +0,0 @@
|
||||
/* search.c - code for non-incremental searching in emacs and vi modes. */
|
||||
|
||||
/* Copyright (C) 1992-2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the Readline Library (the Library), a set of
|
||||
routines for providing Emacs style line input to programs that ask
|
||||
for it.
|
||||
|
||||
The Library 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, or (at your option)
|
||||
any later version.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#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 UNDO_LIST *noninc_saved_undo_list;
|
||||
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 command lines copied
|
||||
to the edit line. That's ambiguous, but we're going to interpret it
|
||||
to mean that the undo list starts 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 (p, 0, 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));
|
||||
}
|
||||
@@ -1,200 +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 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#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
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <pwd.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "rlstdc.h"
|
||||
#include "rlshell.h"
|
||||
#include "xmalloc.h"
|
||||
|
||||
#if !defined (HAVE_GETPW_DECLS)
|
||||
extern struct passwd *getpwuid PARAMS((uid_t));
|
||||
#endif /* !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;
|
||||
entry = getpwuid (getuid ());
|
||||
if (entry)
|
||||
home_dir = entry->pw_dir;
|
||||
return (home_dir);
|
||||
}
|
||||
|
||||
#if !defined (O_NDELAY)
|
||||
# if defined (FNDELAY)
|
||||
# define O_NDELAY FNDELAY
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int
|
||||
sh_unset_nodelay_mode (fd)
|
||||
int fd;
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,422 +0,0 @@
|
||||
/* signals.c -- signal handling support for readline. */
|
||||
|
||||
/* Copyright (C) 1987-2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#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 */
|
||||
|
||||
#if defined (HANDLE_SIGNALS)
|
||||
/* Some standard library routines. */
|
||||
#include "readline.h"
|
||||
#include "history.h"
|
||||
|
||||
#include "rlprivate.h"
|
||||
|
||||
#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 *));
|
||||
|
||||
/* 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
|
||||
|
||||
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. */
|
||||
|
||||
static RETSIGTYPE
|
||||
rl_signal_handler (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_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_cleanup_after_signal ();
|
||||
|
||||
#if defined (HAVE_POSIX_SIGNALS)
|
||||
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
|
||||
|
||||
kill (getpid (), sig);
|
||||
|
||||
/* 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;
|
||||
act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
|
||||
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 (rl_catch_signals && signals_set_flag == 0)
|
||||
{
|
||||
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 (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_signals ();
|
||||
rl_clear_pending_input ();
|
||||
}
|
||||
|
||||
/* 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_init_argument ();
|
||||
}
|
||||
|
||||
#endif /* HANDLE_SIGNALS */
|
||||
@@ -1,679 +0,0 @@
|
||||
/* terminal.c -- controlling the terminal with termcap. */
|
||||
|
||||
/* Copyright (C) 1996-2005 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#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"
|
||||
|
||||
#define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
|
||||
#define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* 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;
|
||||
|
||||
#if defined (HACK_TERMCAP_MOTION)
|
||||
char *_rl_term_forward_char;
|
||||
#endif /* HACK_TERMCAP_MOTION */
|
||||
|
||||
/* 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;
|
||||
|
||||
/* 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
|
||||
|
||||
/* 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 */
|
||||
|
||||
#if defined (TIOCGWINSZ)
|
||||
if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
|
||||
{
|
||||
_rl_screenwidth = (int) window_size.ws_col;
|
||||
_rl_screenheight = (int) window_size.ws_row;
|
||||
}
|
||||
#endif /* TIOCGWINSZ */
|
||||
|
||||
#if defined (__EMX__)
|
||||
_emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
|
||||
#endif
|
||||
|
||||
/* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
|
||||
is unset. */
|
||||
if (_rl_screenwidth <= 0)
|
||||
{
|
||||
if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
|
||||
_rl_screenwidth = atoi (ss);
|
||||
|
||||
#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 !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 (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 ()
|
||||
{
|
||||
if (readline_echoing_p)
|
||||
{
|
||||
_rl_get_screen_size (fileno (rl_instream), 1);
|
||||
if (CUSTOM_REDISPLAY_FUNC ())
|
||||
rl_forced_update_display ();
|
||||
else
|
||||
_rl_redisplay_after_sigwinch ();
|
||||
}
|
||||
}
|
||||
|
||||
struct _tc_string {
|
||||
const char *tc_var;
|
||||
char **tc_value;
|
||||
};
|
||||
|
||||
/* This should be kept sorted, just in case we decide to change the
|
||||
search algorithm to something smarter. */
|
||||
static 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 },
|
||||
#if defined (HACK_TERMCAP_MOTION)
|
||||
{ "nd", &_rl_term_forward_char },
|
||||
#endif
|
||||
{ "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;
|
||||
#if defined (HACK_TERMCAP_MOTION)
|
||||
term_forward_char = (char *)NULL;
|
||||
#endif
|
||||
_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") || tgetflag ("MT"));
|
||||
if (!term_has_meta)
|
||||
_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)
|
||||
if (_rl_term_cr)
|
||||
tputs (_rl_term_cr, 1, _rl_output_character_function);
|
||||
#endif /* NEW_TTY_DRIVER */
|
||||
putc ('\n', _rl_out_stream);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Ring the terminal bell. */
|
||||
int
|
||||
rl_ding ()
|
||||
{
|
||||
if (readline_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);
|
||||
}
|
||||
}
|
||||
}
|
||||
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
File diff suppressed because it is too large
Load Diff
@@ -1,355 +0,0 @@
|
||||
/* util.c -- readline utility functions */
|
||||
|
||||
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
#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 *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 (wc)
|
||||
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_init_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 (readline_top_level, 1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
rl_abort (count, key)
|
||||
int count, key;
|
||||
{
|
||||
return (_rl_abort_internal ());
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
free (temp);
|
||||
|
||||
_rl_replace_text (homedir, start, end);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* **************************************************************** */
|
||||
/* */
|
||||
/* 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. */
|
||||
int
|
||||
_rl_strnicmp (string1, string2, count)
|
||||
char *string1, *string2;
|
||||
int count;
|
||||
{
|
||||
register char ch1, ch2;
|
||||
|
||||
while (count)
|
||||
{
|
||||
ch1 = *string1++;
|
||||
ch2 = *string2++;
|
||||
if (_rl_to_upper(ch1) == _rl_to_upper(ch2))
|
||||
count--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
return (count);
|
||||
}
|
||||
|
||||
/* strcmp (), but caseless. */
|
||||
int
|
||||
_rl_stricmp (string1, string2)
|
||||
char *string1, *string2;
|
||||
{
|
||||
register char ch1, ch2;
|
||||
|
||||
while (*string1 && *string2)
|
||||
{
|
||||
ch1 = *string1++;
|
||||
ch2 = *string2++;
|
||||
if (_rl_to_upper(ch1) != _rl_to_upper(ch2))
|
||||
return (1);
|
||||
}
|
||||
return (*string1 - *string2);
|
||||
}
|
||||
#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)
|
||||
|
||||
/* 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)));
|
||||
}
|
||||
@@ -1,877 +0,0 @@
|
||||
/* vi_keymap.c -- the keymap for vi_mode in readline (). */
|
||||
|
||||
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of the GNU Readline Library, a library for
|
||||
reading lines of text with interactive input and history editing.
|
||||
|
||||
The GNU Readline Library 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, or
|
||||
(at your option) any later version.
|
||||
|
||||
The GNU Readline Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#if !defined (BUFSIZ)
|
||||
#include <stdio.h>
|
||||
#endif /* !BUFSIZ */
|
||||
|
||||
#include "readline.h"
|
||||
|
||||
#if 0
|
||||
extern KEYMAP_ENTRY_ARRAY vi_escape_keymap;
|
||||
#endif
|
||||
|
||||
/* The keymap arrays for handling vi mode. */
|
||||
KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
|
||||
/* The regular control keys come first. */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */
|
||||
{ ISFUNC, rl_vi_eof_maybe }, /* Control-d */
|
||||
{ ISFUNC, rl_emacs_editing_mode }, /* Control-e */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */
|
||||
{ ISFUNC, rl_abort }, /* Control-g */
|
||||
{ ISFUNC, rl_backward_char }, /* Control-h */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-i */
|
||||
{ ISFUNC, rl_newline }, /* Control-j */
|
||||
{ ISFUNC, rl_kill_line }, /* Control-k */
|
||||
{ ISFUNC, rl_clear_screen }, /* Control-l */
|
||||
{ ISFUNC, rl_newline }, /* Control-m */
|
||||
{ ISFUNC, rl_get_next_history }, /* Control-n */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */
|
||||
{ ISFUNC, rl_get_previous_history }, /* Control-p */
|
||||
{ ISFUNC, rl_quoted_insert }, /* Control-q */
|
||||
{ ISFUNC, rl_reverse_search_history }, /* Control-r */
|
||||
{ ISFUNC, rl_forward_search_history }, /* Control-s */
|
||||
{ ISFUNC, rl_transpose_chars }, /* Control-t */
|
||||
{ ISFUNC, rl_unix_line_discard }, /* Control-u */
|
||||
{ ISFUNC, rl_quoted_insert }, /* Control-v */
|
||||
{ ISFUNC, rl_unix_word_rubout }, /* Control-w */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */
|
||||
{ ISFUNC, rl_yank }, /* Control-y */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
|
||||
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-[ */ /* vi_escape_keymap */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
|
||||
{ ISFUNC, rl_vi_undo }, /* Control-_ */
|
||||
|
||||
/* The start of printing characters. */
|
||||
{ ISFUNC, rl_forward_char }, /* SPACE */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ! */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* " */
|
||||
{ ISFUNC, rl_insert_comment }, /* # */
|
||||
{ ISFUNC, rl_end_of_line }, /* $ */
|
||||
{ ISFUNC, rl_vi_match }, /* % */
|
||||
{ ISFUNC, rl_vi_tilde_expand }, /* & */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ' */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ( */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ) */
|
||||
{ ISFUNC, rl_vi_complete }, /* * */
|
||||
{ ISFUNC, rl_get_next_history}, /* + */
|
||||
{ ISFUNC, rl_vi_char_search }, /* , */
|
||||
{ ISFUNC, rl_get_previous_history }, /* - */
|
||||
{ ISFUNC, rl_vi_redo }, /* . */
|
||||
{ ISFUNC, rl_vi_search }, /* / */
|
||||
|
||||
/* Regular digits. */
|
||||
{ ISFUNC, rl_beg_of_line }, /* 0 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 1 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 2 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 3 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 4 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 5 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 6 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 7 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 8 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 9 */
|
||||
|
||||
/* A little more punctuation. */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* : */
|
||||
{ ISFUNC, rl_vi_char_search }, /* ; */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* < */
|
||||
{ ISFUNC, rl_vi_complete }, /* = */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* > */
|
||||
{ ISFUNC, rl_vi_search }, /* ? */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* @ */
|
||||
|
||||
/* Uppercase alphabet. */
|
||||
{ ISFUNC, rl_vi_append_eol }, /* A */
|
||||
{ ISFUNC, rl_vi_prev_word}, /* B */
|
||||
{ ISFUNC, rl_vi_change_to }, /* C */
|
||||
{ ISFUNC, rl_vi_delete_to }, /* D */
|
||||
{ ISFUNC, rl_vi_end_word }, /* E */
|
||||
{ ISFUNC, rl_vi_char_search }, /* F */
|
||||
{ ISFUNC, rl_vi_fetch_history }, /* G */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* H */
|
||||
{ ISFUNC, rl_vi_insert_beg }, /* I */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* J */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* K */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* L */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* M */
|
||||
{ ISFUNC, rl_vi_search_again }, /* N */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* O */
|
||||
{ ISFUNC, rl_vi_put }, /* P */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Q */
|
||||
{ ISFUNC, rl_vi_replace }, /* R */
|
||||
{ ISFUNC, rl_vi_subst }, /* S */
|
||||
{ ISFUNC, rl_vi_char_search }, /* T */
|
||||
{ ISFUNC, rl_revert_line }, /* U */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* V */
|
||||
{ ISFUNC, rl_vi_next_word }, /* W */
|
||||
{ ISFUNC, rl_rubout }, /* X */
|
||||
{ ISFUNC, rl_vi_yank_to }, /* Y */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Z */
|
||||
|
||||
/* Some more punctuation. */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* [ */
|
||||
{ ISFUNC, rl_vi_complete }, /* \ */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ] */
|
||||
{ ISFUNC, rl_vi_first_print }, /* ^ */
|
||||
{ ISFUNC, rl_vi_yank_arg }, /* _ */
|
||||
{ ISFUNC, rl_vi_goto_mark }, /* ` */
|
||||
|
||||
/* Lowercase alphabet. */
|
||||
{ ISFUNC, rl_vi_append_mode }, /* a */
|
||||
{ ISFUNC, rl_vi_prev_word }, /* b */
|
||||
{ ISFUNC, rl_vi_change_to }, /* c */
|
||||
{ ISFUNC, rl_vi_delete_to }, /* d */
|
||||
{ ISFUNC, rl_vi_end_word }, /* e */
|
||||
{ ISFUNC, rl_vi_char_search }, /* f */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* g */
|
||||
{ ISFUNC, rl_backward_char }, /* h */
|
||||
{ ISFUNC, rl_vi_insertion_mode }, /* i */
|
||||
{ ISFUNC, rl_get_next_history }, /* j */
|
||||
{ ISFUNC, rl_get_previous_history }, /* k */
|
||||
{ ISFUNC, rl_forward_char }, /* l */
|
||||
{ ISFUNC, rl_vi_set_mark }, /* m */
|
||||
{ ISFUNC, rl_vi_search_again }, /* n */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* o */
|
||||
{ ISFUNC, rl_vi_put }, /* p */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* q */
|
||||
{ ISFUNC, rl_vi_change_char }, /* r */
|
||||
{ ISFUNC, rl_vi_subst }, /* s */
|
||||
{ ISFUNC, rl_vi_char_search }, /* t */
|
||||
{ ISFUNC, rl_vi_undo }, /* u */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* v */
|
||||
{ ISFUNC, rl_vi_next_word }, /* w */
|
||||
{ ISFUNC, rl_vi_delete }, /* x */
|
||||
{ ISFUNC, rl_vi_yank_to }, /* y */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* z */
|
||||
|
||||
/* Final punctuation. */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* { */
|
||||
{ ISFUNC, rl_vi_column }, /* | */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* } */
|
||||
{ ISFUNC, rl_vi_change_case }, /* ~ */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* RUBOUT */
|
||||
|
||||
#if KEYMAP_SIZE > 128
|
||||
/* Undefined keys. */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }
|
||||
#endif /* KEYMAP_SIZE > 128 */
|
||||
};
|
||||
|
||||
|
||||
KEYMAP_ENTRY_ARRAY vi_insertion_keymap = {
|
||||
/* The regular control keys come first. */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */
|
||||
{ ISFUNC, rl_insert }, /* Control-a */
|
||||
{ ISFUNC, rl_insert }, /* Control-b */
|
||||
{ ISFUNC, rl_insert }, /* Control-c */
|
||||
{ ISFUNC, rl_vi_eof_maybe }, /* Control-d */
|
||||
{ ISFUNC, rl_insert }, /* Control-e */
|
||||
{ ISFUNC, rl_insert }, /* Control-f */
|
||||
{ ISFUNC, rl_insert }, /* Control-g */
|
||||
{ ISFUNC, rl_rubout }, /* Control-h */
|
||||
{ ISFUNC, rl_complete }, /* Control-i */
|
||||
{ ISFUNC, rl_newline }, /* Control-j */
|
||||
{ ISFUNC, rl_insert }, /* Control-k */
|
||||
{ ISFUNC, rl_insert }, /* Control-l */
|
||||
{ ISFUNC, rl_newline }, /* Control-m */
|
||||
{ ISFUNC, rl_insert }, /* Control-n */
|
||||
{ ISFUNC, rl_insert }, /* Control-o */
|
||||
{ ISFUNC, rl_insert }, /* Control-p */
|
||||
{ ISFUNC, rl_insert }, /* Control-q */
|
||||
{ ISFUNC, rl_reverse_search_history }, /* Control-r */
|
||||
{ ISFUNC, rl_forward_search_history }, /* Control-s */
|
||||
{ ISFUNC, rl_transpose_chars }, /* Control-t */
|
||||
{ ISFUNC, rl_unix_line_discard }, /* Control-u */
|
||||
{ ISFUNC, rl_quoted_insert }, /* Control-v */
|
||||
{ ISFUNC, rl_unix_word_rubout }, /* Control-w */
|
||||
{ ISFUNC, rl_insert }, /* Control-x */
|
||||
{ ISFUNC, rl_yank }, /* Control-y */
|
||||
{ ISFUNC, rl_insert }, /* Control-z */
|
||||
|
||||
{ ISFUNC, rl_vi_movement_mode }, /* Control-[ */
|
||||
{ ISFUNC, rl_insert }, /* Control-\ */
|
||||
{ ISFUNC, rl_insert }, /* Control-] */
|
||||
{ ISFUNC, rl_insert }, /* Control-^ */
|
||||
{ ISFUNC, rl_vi_undo }, /* Control-_ */
|
||||
|
||||
/* The start of printing characters. */
|
||||
{ ISFUNC, rl_insert }, /* SPACE */
|
||||
{ ISFUNC, rl_insert }, /* ! */
|
||||
{ ISFUNC, rl_insert }, /* " */
|
||||
{ ISFUNC, rl_insert }, /* # */
|
||||
{ ISFUNC, rl_insert }, /* $ */
|
||||
{ ISFUNC, rl_insert }, /* % */
|
||||
{ ISFUNC, rl_insert }, /* & */
|
||||
{ ISFUNC, rl_insert }, /* ' */
|
||||
{ ISFUNC, rl_insert }, /* ( */
|
||||
{ ISFUNC, rl_insert }, /* ) */
|
||||
{ ISFUNC, rl_insert }, /* * */
|
||||
{ ISFUNC, rl_insert }, /* + */
|
||||
{ ISFUNC, rl_insert }, /* , */
|
||||
{ ISFUNC, rl_insert }, /* - */
|
||||
{ ISFUNC, rl_insert }, /* . */
|
||||
{ ISFUNC, rl_insert }, /* / */
|
||||
|
||||
/* Regular digits. */
|
||||
{ ISFUNC, rl_insert }, /* 0 */
|
||||
{ ISFUNC, rl_insert }, /* 1 */
|
||||
{ ISFUNC, rl_insert }, /* 2 */
|
||||
{ ISFUNC, rl_insert }, /* 3 */
|
||||
{ ISFUNC, rl_insert }, /* 4 */
|
||||
{ ISFUNC, rl_insert }, /* 5 */
|
||||
{ ISFUNC, rl_insert }, /* 6 */
|
||||
{ ISFUNC, rl_insert }, /* 7 */
|
||||
{ ISFUNC, rl_insert }, /* 8 */
|
||||
{ ISFUNC, rl_insert }, /* 9 */
|
||||
|
||||
/* A little more punctuation. */
|
||||
{ ISFUNC, rl_insert }, /* : */
|
||||
{ ISFUNC, rl_insert }, /* ; */
|
||||
{ ISFUNC, rl_insert }, /* < */
|
||||
{ ISFUNC, rl_insert }, /* = */
|
||||
{ ISFUNC, rl_insert }, /* > */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* @ */
|
||||
|
||||
/* Uppercase alphabet. */
|
||||
{ ISFUNC, rl_insert }, /* A */
|
||||
{ ISFUNC, rl_insert }, /* B */
|
||||
{ ISFUNC, rl_insert }, /* C */
|
||||
{ ISFUNC, rl_insert }, /* D */
|
||||
{ ISFUNC, rl_insert }, /* E */
|
||||
{ ISFUNC, rl_insert }, /* F */
|
||||
{ ISFUNC, rl_insert }, /* G */
|
||||
{ ISFUNC, rl_insert }, /* H */
|
||||
{ ISFUNC, rl_insert }, /* I */
|
||||
{ ISFUNC, rl_insert }, /* J */
|
||||
{ ISFUNC, rl_insert }, /* K */
|
||||
{ ISFUNC, rl_insert }, /* L */
|
||||
{ ISFUNC, rl_insert }, /* M */
|
||||
{ ISFUNC, rl_insert }, /* N */
|
||||
{ ISFUNC, rl_insert }, /* O */
|
||||
{ ISFUNC, rl_insert }, /* P */
|
||||
{ ISFUNC, rl_insert }, /* Q */
|
||||
{ ISFUNC, rl_insert }, /* R */
|
||||
{ ISFUNC, rl_insert }, /* S */
|
||||
{ ISFUNC, rl_insert }, /* T */
|
||||
{ ISFUNC, rl_insert }, /* U */
|
||||
{ ISFUNC, rl_insert }, /* V */
|
||||
{ ISFUNC, rl_insert }, /* W */
|
||||
{ ISFUNC, rl_insert }, /* X */
|
||||
{ ISFUNC, rl_insert }, /* Y */
|
||||
{ ISFUNC, rl_insert }, /* Z */
|
||||
|
||||
/* Some more punctuation. */
|
||||
{ ISFUNC, rl_insert }, /* [ */
|
||||
{ ISFUNC, rl_insert }, /* \ */
|
||||
{ ISFUNC, rl_insert }, /* ] */
|
||||
{ ISFUNC, rl_insert }, /* ^ */
|
||||
{ ISFUNC, rl_insert }, /* _ */
|
||||
{ ISFUNC, rl_insert }, /* ` */
|
||||
|
||||
/* Lowercase alphabet. */
|
||||
{ ISFUNC, rl_insert }, /* a */
|
||||
{ ISFUNC, rl_insert }, /* b */
|
||||
{ ISFUNC, rl_insert }, /* c */
|
||||
{ ISFUNC, rl_insert }, /* d */
|
||||
{ ISFUNC, rl_insert }, /* e */
|
||||
{ ISFUNC, rl_insert }, /* f */
|
||||
{ ISFUNC, rl_insert }, /* g */
|
||||
{ ISFUNC, rl_insert }, /* h */
|
||||
{ ISFUNC, rl_insert }, /* i */
|
||||
{ ISFUNC, rl_insert }, /* j */
|
||||
{ ISFUNC, rl_insert }, /* k */
|
||||
{ ISFUNC, rl_insert }, /* l */
|
||||
{ ISFUNC, rl_insert }, /* m */
|
||||
{ ISFUNC, rl_insert }, /* n */
|
||||
{ ISFUNC, rl_insert }, /* o */
|
||||
{ ISFUNC, rl_insert }, /* p */
|
||||
{ ISFUNC, rl_insert }, /* q */
|
||||
{ ISFUNC, rl_insert }, /* r */
|
||||
{ ISFUNC, rl_insert }, /* s */
|
||||
{ ISFUNC, rl_insert }, /* t */
|
||||
{ ISFUNC, rl_insert }, /* u */
|
||||
{ ISFUNC, rl_insert }, /* v */
|
||||
{ ISFUNC, rl_insert }, /* w */
|
||||
{ ISFUNC, rl_insert }, /* x */
|
||||
{ ISFUNC, rl_insert }, /* y */
|
||||
{ ISFUNC, rl_insert }, /* z */
|
||||
|
||||
/* Final punctuation. */
|
||||
{ ISFUNC, rl_insert }, /* { */
|
||||
{ ISFUNC, rl_insert }, /* | */
|
||||
{ ISFUNC, rl_insert }, /* } */
|
||||
{ ISFUNC, rl_insert }, /* ~ */
|
||||
{ ISFUNC, rl_rubout }, /* RUBOUT */
|
||||
|
||||
#if KEYMAP_SIZE > 128
|
||||
/* Pure 8-bit characters (128 - 159).
|
||||
These might be used in some
|
||||
character sets. */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
{ ISFUNC, rl_insert }, /* ? */
|
||||
|
||||
/* ISO Latin-1 characters (160 - 255) */
|
||||
{ ISFUNC, rl_insert }, /* No-break space */
|
||||
{ ISFUNC, rl_insert }, /* Inverted exclamation mark */
|
||||
{ ISFUNC, rl_insert }, /* Cent sign */
|
||||
{ ISFUNC, rl_insert }, /* Pound sign */
|
||||
{ ISFUNC, rl_insert }, /* Currency sign */
|
||||
{ ISFUNC, rl_insert }, /* Yen sign */
|
||||
{ ISFUNC, rl_insert }, /* Broken bar */
|
||||
{ ISFUNC, rl_insert }, /* Section sign */
|
||||
{ ISFUNC, rl_insert }, /* Diaeresis */
|
||||
{ ISFUNC, rl_insert }, /* Copyright sign */
|
||||
{ ISFUNC, rl_insert }, /* Feminine ordinal indicator */
|
||||
{ ISFUNC, rl_insert }, /* Left pointing double angle quotation mark */
|
||||
{ ISFUNC, rl_insert }, /* Not sign */
|
||||
{ ISFUNC, rl_insert }, /* Soft hyphen */
|
||||
{ ISFUNC, rl_insert }, /* Registered sign */
|
||||
{ ISFUNC, rl_insert }, /* Macron */
|
||||
{ ISFUNC, rl_insert }, /* Degree sign */
|
||||
{ ISFUNC, rl_insert }, /* Plus-minus sign */
|
||||
{ ISFUNC, rl_insert }, /* Superscript two */
|
||||
{ ISFUNC, rl_insert }, /* Superscript three */
|
||||
{ ISFUNC, rl_insert }, /* Acute accent */
|
||||
{ ISFUNC, rl_insert }, /* Micro sign */
|
||||
{ ISFUNC, rl_insert }, /* Pilcrow sign */
|
||||
{ ISFUNC, rl_insert }, /* Middle dot */
|
||||
{ ISFUNC, rl_insert }, /* Cedilla */
|
||||
{ ISFUNC, rl_insert }, /* Superscript one */
|
||||
{ ISFUNC, rl_insert }, /* Masculine ordinal indicator */
|
||||
{ ISFUNC, rl_insert }, /* Right pointing double angle quotation mark */
|
||||
{ ISFUNC, rl_insert }, /* Vulgar fraction one quarter */
|
||||
{ ISFUNC, rl_insert }, /* Vulgar fraction one half */
|
||||
{ ISFUNC, rl_insert }, /* Vulgar fraction three quarters */
|
||||
{ ISFUNC, rl_insert }, /* Inverted questionk mark */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter a with grave */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter a with acute */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter a with circumflex */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter a with tilde */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter a with diaeresis */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter a with ring above */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter ae */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter c with cedilla */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter e with grave */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter e with acute */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter e with circumflex */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter e with diaeresis */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter i with grave */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter i with acute */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter i with circumflex */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter i with diaeresis */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter eth (Icelandic) */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter n with tilde */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter o with grave */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter o with acute */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter o with circumflex */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter o with tilde */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter o with diaeresis */
|
||||
{ ISFUNC, rl_insert }, /* Multiplication sign */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter o with stroke */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter u with grave */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter u with acute */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter u with circumflex */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter u with diaeresis */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter Y with acute */
|
||||
{ ISFUNC, rl_insert }, /* Latin capital letter thorn (Icelandic) */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter sharp s (German) */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter a with grave */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter a with acute */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter a with circumflex */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter a with tilde */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter a with diaeresis */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter a with ring above */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter ae */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter c with cedilla */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter e with grave */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter e with acute */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter e with circumflex */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter e with diaeresis */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter i with grave */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter i with acute */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter i with circumflex */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter i with diaeresis */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter eth (Icelandic) */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter n with tilde */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter o with grave */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter o with acute */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter o with circumflex */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter o with tilde */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter o with diaeresis */
|
||||
{ ISFUNC, rl_insert }, /* Division sign */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter o with stroke */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter u with grave */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter u with acute */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter u with circumflex */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter u with diaeresis */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter y with acute */
|
||||
{ ISFUNC, rl_insert }, /* Latin small letter thorn (Icelandic) */
|
||||
{ ISFUNC, rl_insert } /* Latin small letter y with diaeresis */
|
||||
#endif /* KEYMAP_SIZE > 128 */
|
||||
};
|
||||
|
||||
/* Unused for the time being. */
|
||||
#if 0
|
||||
KEYMAP_ENTRY_ARRAY vi_escape_keymap = {
|
||||
/* The regular control keys come first. */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-@ */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-a */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-b */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-c */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-d */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-e */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-f */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-g */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-h */
|
||||
{ ISFUNC, rl_tab_insert}, /* Control-i */
|
||||
{ ISFUNC, rl_emacs_editing_mode}, /* Control-j */
|
||||
{ ISFUNC, rl_kill_line }, /* Control-k */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-l */
|
||||
{ ISFUNC, rl_emacs_editing_mode}, /* Control-m */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-n */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-o */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-p */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-q */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-r */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-s */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-t */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-u */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-v */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-w */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-x */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-y */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-z */
|
||||
|
||||
{ ISFUNC, rl_vi_movement_mode }, /* Control-[ */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-\ */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-] */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* Control-^ */
|
||||
{ ISFUNC, rl_vi_undo }, /* Control-_ */
|
||||
|
||||
/* The start of printing characters. */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* SPACE */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ! */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* " */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* # */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* $ */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* % */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* & */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ' */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ( */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ) */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* * */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* + */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* , */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* - */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* . */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* / */
|
||||
|
||||
/* Regular digits. */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 0 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 1 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 2 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 3 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 4 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 5 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 6 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 7 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 8 */
|
||||
{ ISFUNC, rl_vi_arg_digit }, /* 9 */
|
||||
|
||||
/* A little more punctuation. */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* : */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ; */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* < */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* = */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* > */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ? */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* @ */
|
||||
|
||||
/* Uppercase alphabet. */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* A */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* B */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* C */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* D */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* E */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* F */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* G */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* H */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* I */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* J */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* K */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* L */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* M */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* N */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* O */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* P */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* Q */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* R */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* S */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* T */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* U */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* V */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* W */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* X */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* Y */
|
||||
{ ISFUNC, rl_do_lowercase_version }, /* Z */
|
||||
|
||||
/* Some more punctuation. */
|
||||
{ ISFUNC, rl_arrow_keys }, /* [ */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* \ */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ] */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ^ */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* _ */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ` */
|
||||
|
||||
/* Lowercase alphabet. */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* a */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* b */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* c */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* d */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* e */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* f */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* g */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* h */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* i */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* j */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* k */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* l */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* m */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* n */
|
||||
{ ISFUNC, rl_arrow_keys }, /* o */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* p */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* q */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* r */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* s */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* t */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* u */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* v */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* w */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* x */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* y */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* z */
|
||||
|
||||
/* Final punctuation. */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* { */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* | */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* } */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }, /* ~ */
|
||||
{ ISFUNC, rl_backward_kill_word }, /* RUBOUT */
|
||||
|
||||
#if KEYMAP_SIZE > 128
|
||||
/* Undefined keys. */
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 },
|
||||
{ ISFUNC, (rl_command_func_t *)0x0 }
|
||||
#endif /* KEYMAP_SIZE > 128 */
|
||||
};
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,455 +0,0 @@
|
||||
#
|
||||
# Makefile for the Bash library
|
||||
#
|
||||
#
|
||||
# Copyright (C) 1998-2002 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 2, 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 USA.
|
||||
|
||||
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@
|
||||
|
||||
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 strindex.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 xstrchr.c zcatfd.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 \
|
||||
netconn.o netopen.o timeval.o makepath.o pathcanon.o \
|
||||
pathphys.o tmpfile.o stringlist.o stringvec.o spell.o shquote.o \
|
||||
strtrans.o strindex.o snprintf.o mailstat.o fmtulong.o \
|
||||
fmtullong.o fmtumax.o xstrchr.o zcatfd.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 )
|
||||
|
||||
# rules for losing makes, like SunOS
|
||||
clktck.o: clktck.c
|
||||
clock.o: clock.c
|
||||
fmtullong.o: fmtullong.c
|
||||
fmtulong.o: fmtulong.c
|
||||
fmtumax.o: fmtumax.c
|
||||
getcwd.o: getcwd.c
|
||||
getenv.o: getenv.c
|
||||
inet_aton.o: inet_aton.c
|
||||
itos.o: itos.c
|
||||
mailstat.o: mailstat.c
|
||||
makepath.o: makepath.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
|
||||
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
|
||||
strindex.o: strindex.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
|
||||
vprint.o: vprint.c
|
||||
xstrchr.o: xstrchr.c
|
||||
zcatfd.o: zcatfd.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
|
||||
clktck.o: ${BUILD_DIR}/config.h
|
||||
clock.o: ${BUILD_DIR}/config.h
|
||||
fmtullong.o: ${BUILD_DIR}/config.h
|
||||
fmtulong.o: ${BUILD_DIR}/config.h
|
||||
fmtumax.o: ${BUILD_DIR}/config.h
|
||||
getcwd.o: ${BUILD_DIR}/config.h
|
||||
getenv.o: ${BUILD_DIR}/config.h
|
||||
inet_aton.o: ${BUILD_DIR}/config.h
|
||||
itos.o: ${BUILD_DIR}/config.h
|
||||
mailstat.o: ${BUILD_DIR}/config.h
|
||||
makepath.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
|
||||
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
|
||||
strindex.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
|
||||
vprint.o: ${BUILD_DIR}/config.h
|
||||
xstrchr.o: ${BUILD_DIR}/config.h
|
||||
zcatfd.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
|
||||
|
||||
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
|
||||
|
||||
strindex.o: ${BASHINCDIR}/stdc.h ${topdir}/bashansi.h
|
||||
strindex.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
|
||||
|
||||
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
|
||||
|
||||
xstrchr.o: ${topdir}/bashansi.h
|
||||
xstrchr.o: ${BASHINCDIR}/ansi_stdlib.h
|
||||
xstrchr.o: ${BASHINCDIR}/shmbutil.h
|
||||
@@ -1,83 +0,0 @@
|
||||
/* netconn.c -- is a particular file descriptor a network connection?. */
|
||||
|
||||
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Bash, the Bourne Again SHell.
|
||||
|
||||
Bash is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2, 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; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <bashtypes.h>
|
||||
#if ! defined(_MINIX) && defined (HAVE_SYS_FILE_H)
|
||||
# include <sys/file.h>
|
||||
#endif
|
||||
#include <posixstat.h>
|
||||
#include <filecntl.h>
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* The second and subsequent conditions must match those used to decide
|
||||
whether or not to call getpeername() in isnetconn(). */
|
||||
#if defined (HAVE_SYS_SOCKET_H) && defined (HAVE_GETPEERNAME) && !defined (SVR4_2)
|
||||
# include <sys/socket.h>
|
||||
#endif
|
||||
|
||||
/* Is FD a socket or network connection? */
|
||||
int
|
||||
isnetconn (fd)
|
||||
int fd;
|
||||
{
|
||||
#if defined (HAVE_GETPEERNAME) && !defined (SVR4_2) && !defined (__BEOS__)
|
||||
int rv;
|
||||
socklen_t l;
|
||||
struct sockaddr sa;
|
||||
|
||||
l = sizeof(sa);
|
||||
rv = getpeername(fd, &sa, &l);
|
||||
/* Posix.2 says getpeername can return these errors. */
|
||||
return ((rv < 0 && (errno == ENOTSOCK || errno == ENOTCONN || errno == EINVAL)) ? 0 : 1);
|
||||
#else /* !HAVE_GETPEERNAME || SVR4_2 || __BEOS__ */
|
||||
# if defined (SVR4) || defined (SVR4_2)
|
||||
/* Sockets on SVR4 and SVR4.2 are character special (streams) devices. */
|
||||
struct stat sb;
|
||||
|
||||
if (isatty (fd))
|
||||
return (0);
|
||||
if (fstat (fd, &sb) < 0)
|
||||
return (0);
|
||||
# if defined (S_ISFIFO)
|
||||
if (S_ISFIFO (sb.st_mode))
|
||||
return (0);
|
||||
# endif /* S_ISFIFO */
|
||||
return (S_ISCHR (sb.st_mode));
|
||||
# else /* !SVR4 && !SVR4_2 */
|
||||
# if defined (S_ISSOCK) && !defined (__BEOS__)
|
||||
struct stat sb;
|
||||
|
||||
if (fstat (fd, &sb) < 0)
|
||||
return (0);
|
||||
return (S_ISSOCK (sb.st_mode));
|
||||
# else /* !S_ISSOCK || __BEOS__ */
|
||||
return (0);
|
||||
# endif /* !S_ISSOCK || __BEOS__ */
|
||||
# endif /* !SVR4 && !SVR4_2 */
|
||||
#endif /* !HAVE_GETPEERNAME || SVR4_2 || __BEOS__ */
|
||||
}
|
||||
@@ -1,295 +0,0 @@
|
||||
/* pathphys.c -- Return pathname with all symlinks expanded. */
|
||||
|
||||
/* 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 2, 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; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <bashtypes.h>
|
||||
#ifndef _MINIX
|
||||
# include <sys/param.h>
|
||||
#endif
|
||||
#include <posixstat.h>
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <filecntl.h>
|
||||
#include <bashansi.h>
|
||||
#include <stdio.h>
|
||||
#include <chartypes.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "shell.h"
|
||||
|
||||
#if !defined (MAXSYMLINKS)
|
||||
# define MAXSYMLINKS 32
|
||||
#endif
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
extern char *get_working_directory __P((char *));
|
||||
|
||||
static int
|
||||
_path_readlink (path, buf, bufsiz)
|
||||
char *path;
|
||||
char *buf;
|
||||
int bufsiz;
|
||||
{
|
||||
#ifdef HAVE_READLINK
|
||||
return readlink (path, buf, bufsiz);
|
||||
#else
|
||||
errno = EINVAL;
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Look for ROOTEDPATH, PATHSEP, DIRSEP, and ISDIRSEP in ../../general.h */
|
||||
|
||||
#define DOUBLE_SLASH(p) ((p[0] == '/') && (p[1] == '/') && p[2] != '/')
|
||||
|
||||
/*
|
||||
* Return PATH with all symlinks expanded in newly-allocated memory.
|
||||
* This always gets an absolute pathname.
|
||||
*/
|
||||
|
||||
char *
|
||||
sh_physpath (path, flags)
|
||||
char *path;
|
||||
int flags;
|
||||
{
|
||||
char tbuf[PATH_MAX+1], linkbuf[PATH_MAX+1];
|
||||
char *result, *p, *q, *qsave, *qbase, *workpath;
|
||||
int double_slash_path, linklen, nlink;
|
||||
|
||||
linklen = strlen (path);
|
||||
|
||||
#if 0
|
||||
/* First sanity check -- punt immediately if the name is too long. */
|
||||
if (linklen >= PATH_MAX)
|
||||
return (savestring (path));
|
||||
#endif
|
||||
|
||||
nlink = 0;
|
||||
q = result = (char *)xmalloc (PATH_MAX + 1);
|
||||
|
||||
/* Even if we get something longer than PATH_MAX, we might be able to
|
||||
shorten it, so we try. */
|
||||
if (linklen >= PATH_MAX)
|
||||
workpath = savestring (path);
|
||||
else
|
||||
{
|
||||
workpath = (char *)xmalloc (PATH_MAX + 1);
|
||||
strcpy (workpath, path);
|
||||
}
|
||||
|
||||
/* This always gets an absolute pathname. */
|
||||
|
||||
/* POSIX.2 says to leave a leading `//' alone. On cygwin, we skip over any
|
||||
leading `x:' (dos drive name). */
|
||||
#if defined (__CYGWIN__)
|
||||
qbase = (ISALPHA((unsigned char)workpath[0]) && workpath[1] == ':') ? workpath + 3 : workpath + 1;
|
||||
#else
|
||||
qbase = workpath + 1;
|
||||
#endif
|
||||
double_slash_path = DOUBLE_SLASH (workpath);
|
||||
qbase += double_slash_path;
|
||||
|
||||
for (p = workpath; p < qbase; )
|
||||
*q++ = *p++;
|
||||
qbase = q;
|
||||
|
||||
/*
|
||||
* invariants:
|
||||
* qbase points to the portion of the result path we want to modify
|
||||
* p points at beginning of path element we're considering.
|
||||
* q points just past the last path element we wrote (no slash).
|
||||
*
|
||||
* XXX -- need to fix error checking for too-long pathnames
|
||||
*/
|
||||
|
||||
while (*p)
|
||||
{
|
||||
if (ISDIRSEP(p[0])) /* null element */
|
||||
p++;
|
||||
else if(p[0] == '.' && PATHSEP(p[1])) /* . and ./ */
|
||||
p += 1; /* don't count the separator in case it is nul */
|
||||
else if (p[0] == '.' && p[1] == '.' && PATHSEP(p[2])) /* .. and ../ */
|
||||
{
|
||||
p += 2; /* skip `..' */
|
||||
if (q > qbase)
|
||||
{
|
||||
while (--q > qbase && ISDIRSEP(*q) == 0)
|
||||
;
|
||||
}
|
||||
}
|
||||
else /* real path element */
|
||||
{
|
||||
/* add separator if not at start of work portion of result */
|
||||
qsave = q;
|
||||
if (q != qbase)
|
||||
*q++ = DIRSEP;
|
||||
while (*p && (ISDIRSEP(*p) == 0))
|
||||
{
|
||||
if (q - result >= PATH_MAX)
|
||||
{
|
||||
#ifdef ENAMETOOLONG
|
||||
errno = ENAMETOOLONG;
|
||||
#else
|
||||
errno = EINVAL;
|
||||
#endif
|
||||
goto error;
|
||||
}
|
||||
|
||||
*q++ = *p++;
|
||||
}
|
||||
|
||||
*q = '\0';
|
||||
|
||||
linklen = _path_readlink (result, linkbuf, PATH_MAX);
|
||||
if (linklen < 0) /* if errno == EINVAL, it's not a symlink */
|
||||
{
|
||||
if (errno != EINVAL)
|
||||
goto error;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* It's a symlink, and the value is in LINKBUF. */
|
||||
nlink++;
|
||||
if (nlink > MAXSYMLINKS)
|
||||
{
|
||||
#ifdef ELOOP
|
||||
errno = ELOOP;
|
||||
#else
|
||||
errno = EINVAL;
|
||||
#endif
|
||||
error:
|
||||
free (result);
|
||||
free (workpath);
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
linkbuf[linklen] = '\0';
|
||||
|
||||
/* If the new path length would overrun PATH_MAX, punt now. */
|
||||
if ((strlen (p) + linklen + 2) >= PATH_MAX)
|
||||
{
|
||||
#ifdef ENAMETOOLONG
|
||||
errno = ENAMETOOLONG;
|
||||
#else
|
||||
errno = EINVAL;
|
||||
#endif
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Form the new pathname by copying the link value to a temporary
|
||||
buffer and appending the rest of `workpath'. Reset p to point
|
||||
to the start of the rest of the path. If the link value is an
|
||||
absolute pathname, reset p, q, and qbase. If not, reset p
|
||||
and q. */
|
||||
strcpy (tbuf, linkbuf);
|
||||
tbuf[linklen] = '/';
|
||||
strcpy (tbuf + linklen, p);
|
||||
strcpy (workpath, tbuf);
|
||||
|
||||
if (ABSPATH(linkbuf))
|
||||
{
|
||||
q = result;
|
||||
/* Duplicating some code here... */
|
||||
#if defined (__CYGWIN__)
|
||||
qbase = (ISALPHA((unsigned char)workpath[0]) && workpath[1] == ':') ? workpath + 3 : workpath + 1;
|
||||
#else
|
||||
qbase = workpath + 1;
|
||||
#endif
|
||||
double_slash_path = DOUBLE_SLASH (workpath);
|
||||
qbase += double_slash_path;
|
||||
|
||||
for (p = workpath; p < qbase; )
|
||||
*q++ = *p++;
|
||||
qbase = q;
|
||||
}
|
||||
else
|
||||
{
|
||||
p = workpath;
|
||||
q = qsave;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*q = '\0';
|
||||
free (workpath);
|
||||
|
||||
/* If the result starts with `//', but the original path does not, we
|
||||
can turn the // into /. Because of how we set `qbase', this should never
|
||||
be true, but it's a sanity check. */
|
||||
if (DOUBLE_SLASH(result) && double_slash_path == 0)
|
||||
{
|
||||
if (result[2] == '\0') /* short-circuit for bare `//' */
|
||||
result[1] = '\0';
|
||||
else
|
||||
strcpy (result, result + 1);
|
||||
}
|
||||
|
||||
return (result);
|
||||
}
|
||||
|
||||
char *
|
||||
sh_realpath (pathname, resolved)
|
||||
const char *pathname;
|
||||
char *resolved;
|
||||
{
|
||||
char *tdir, *wd;
|
||||
|
||||
if (pathname == 0 || *pathname == '\0')
|
||||
{
|
||||
errno = (pathname == 0) ? EINVAL : ENOENT;
|
||||
return ((char *)NULL);
|
||||
}
|
||||
|
||||
if (ABSPATH (pathname) == 0)
|
||||
{
|
||||
wd = get_working_directory ("sh_realpath");
|
||||
if (wd == 0)
|
||||
return ((char *)NULL);
|
||||
tdir = sh_makepath ((char *)pathname, wd, 0);
|
||||
free (wd);
|
||||
}
|
||||
else
|
||||
tdir = savestring (pathname);
|
||||
|
||||
wd = sh_physpath (tdir, 0);
|
||||
free (tdir);
|
||||
|
||||
if (resolved == 0)
|
||||
return (wd);
|
||||
|
||||
if (wd)
|
||||
{
|
||||
strncpy (resolved, wd, PATH_MAX - 1);
|
||||
resolved[PATH_MAX - 1] = '\0';
|
||||
return resolved;
|
||||
}
|
||||
else
|
||||
{
|
||||
resolved[0] = '\0';
|
||||
return wd;
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
/* 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 2, 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; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
/*
|
||||
* shmatch.c -- shell interface to posix regular expression matching.
|
||||
*/
|
||||
|
||||
#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;
|
||||
|
||||
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)
|
||||
rflags |= REG_ICASE;
|
||||
#if !defined (ARRAY_VARS)
|
||||
rflags |= REG_NOSUB;
|
||||
#endif
|
||||
|
||||
if (regcomp (®ex, 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 (®ex, 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 (®ex);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif /* HAVE_POSIX_REGEXP */
|
||||
@@ -1,275 +0,0 @@
|
||||
/* 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 2, 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; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#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++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
-2104
File diff suppressed because it is too large
Load Diff
@@ -1,868 +0,0 @@
|
||||
/*
|
||||
* 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.
|
||||
*
|
||||
* This file is also shipped with GAWK (GNU Awk), gawk specific bits of
|
||||
* code are included if GAWK is defined.
|
||||
*
|
||||
* Arnold Robbins
|
||||
* January, February, March, 1991
|
||||
* Updated March, April 1992
|
||||
* 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
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
#include <config.h>
|
||||
|
||||
#ifndef GAWK
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#endif
|
||||
#if defined(TM_IN_SYS_TIME)
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#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 */
|
||||
#ifndef GAWK
|
||||
#define POSIX_SEMANTICS 1 /* call tzset() if TZ changes */
|
||||
#endif
|
||||
|
||||
#undef strchr /* avoid AIX weirdness */
|
||||
|
||||
extern void tzset(void);
|
||||
static int weeknumber(const struct tm *timeptr, int firstweekday);
|
||||
static int iso8601wknum(const struct tm *timeptr);
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define inline __inline__
|
||||
#else
|
||||
#define inline /**/
|
||||
#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 */
|
||||
|
||||
/* 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, 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, "%02d", (timeptr->tm_year + 1900) / 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 = 1900 + timeptr->tm_year + 1;
|
||||
else if (timeptr->tm_mon == 0 && w >= 52)
|
||||
y = 1900 + timeptr->tm_year - 1;
|
||||
else
|
||||
y = 1900 + timeptr->tm_year;
|
||||
|
||||
if (*format == 'G')
|
||||
sprintf(tbuf, "%d", y);
|
||||
else
|
||||
sprintf(tbuf, "%02d", 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) || defined(GAWK)
|
||||
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) || defined(GAWK) */
|
||||
|
||||
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, "%d", 1900 + 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 */
|
||||
#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
|
||||
off = -(daylight ? timezone : altzone) / 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, "%02d%02d", 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-%4d",
|
||||
range(1, timeptr->tm_mday, 31),
|
||||
months_a[range(0, timeptr->tm_mon, 11)],
|
||||
timeptr->tm_year + 1900);
|
||||
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(int 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 + 1900);
|
||||
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 */
|
||||
@@ -1,44 +0,0 @@
|
||||
/* Copyright (C) 1991, 1994 Free Software Foundation, Inc.
|
||||
NOTE: The canonical source of this file is maintained with the GNU C Library.
|
||||
Bugs can be reported to bug-glibc@prep.ai.mit.edu.
|
||||
|
||||
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, 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. */
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_STRPBRK)
|
||||
|
||||
#include <stdc.h>
|
||||
|
||||
/* Find the first ocurrence in S of any character in ACCEPT. */
|
||||
char *
|
||||
strpbrk (s, accept)
|
||||
register const char *s;
|
||||
register const char *accept;
|
||||
{
|
||||
while (*s != '\0')
|
||||
{
|
||||
const char *a = accept;
|
||||
while (*a != '\0')
|
||||
if (*a++ == *s)
|
||||
return (char *) s;
|
||||
++s;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
@@ -1,102 +0,0 @@
|
||||
/* Convert string representation of a number into an intmax_t value.
|
||||
Copyright 1999, 2001 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 2, 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. */
|
||||
|
||||
/* Written by Paul Eggert. Modified by Chet Ramey for Bash. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <stdc.h>
|
||||
|
||||
/* Verify a requirement at compile-time (unlike assert, which is runtime). */
|
||||
#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
|
||||
|
||||
#ifndef HAVE_DECL_STRTOL
|
||||
"this configure-time declaration test was not run"
|
||||
#endif
|
||||
#if !HAVE_DECL_STRTOL
|
||||
extern long strtol __P((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DECL_STRTOLL
|
||||
"this configure-time declaration test was not run"
|
||||
#endif
|
||||
#if !HAVE_DECL_STRTOLL && HAVE_LONG_LONG
|
||||
extern long long strtoll __P((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
intmax_t
|
||||
strtoimax (ptr, endptr, base)
|
||||
const char *ptr;
|
||||
char **endptr;
|
||||
int base;
|
||||
{
|
||||
#if HAVE_LONG_LONG
|
||||
verify(size_is_that_of_long_or_long_long,
|
||||
(sizeof (intmax_t) == sizeof (long) ||
|
||||
sizeof (intmax_t) == sizeof (long long)));
|
||||
|
||||
if (sizeof (intmax_t) != sizeof (long))
|
||||
return (strtoll (ptr, endptr, base));
|
||||
#else
|
||||
verify (size_is_that_of_long, sizeof (intmax_t) == sizeof (long));
|
||||
#endif
|
||||
|
||||
return (strtol (ptr, endptr, base));
|
||||
}
|
||||
|
||||
#ifdef TESTING
|
||||
# include <stdio.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
char *p, *endptr;
|
||||
intmax_t x;
|
||||
#if HAVE_LONG_LONG
|
||||
long long y;
|
||||
#endif
|
||||
long z;
|
||||
|
||||
printf ("sizeof intmax_t: %d\n", sizeof (intmax_t));
|
||||
|
||||
#if HAVE_LONG_LONG
|
||||
printf ("sizeof long long: %d\n", sizeof (long long));
|
||||
#endif
|
||||
printf ("sizeof long: %d\n", sizeof (long));
|
||||
|
||||
x = strtoimax("42", &endptr, 10);
|
||||
#if HAVE_LONG_LONG
|
||||
y = strtoll("42", &endptr, 10);
|
||||
#else
|
||||
y = -1;
|
||||
#endif
|
||||
z = strtol("42", &endptr, 10);
|
||||
|
||||
printf ("%lld %lld %ld\n", x, y, z);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
#endif
|
||||
@@ -1,102 +0,0 @@
|
||||
/* Convert string representation of a number into an uintmax_t value.
|
||||
Copyright 1999, 2001 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 2, 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. */
|
||||
|
||||
/* Written by Paul Eggert. Modified by Chet Ramey for Bash. */
|
||||
|
||||
#if HAVE_CONFIG_H
|
||||
# include <config.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_INTTYPES_H
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#if HAVE_STDLIB_H
|
||||
# include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include <stdc.h>
|
||||
|
||||
/* Verify a requirement at compile-time (unlike assert, which is runtime). */
|
||||
#define verify(name, assertion) struct name { char a[(assertion) ? 1 : -1]; }
|
||||
|
||||
#ifndef HAVE_DECL_STRTOUL
|
||||
"this configure-time declaration test was not run"
|
||||
#endif
|
||||
#if !HAVE_DECL_STRTOUL
|
||||
extern unsigned long strtoul __P((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_DECL_STRTOULL
|
||||
"this configure-time declaration test was not run"
|
||||
#endif
|
||||
#if !HAVE_DECL_STRTOULL && HAVE_UNSIGNED_LONG_LONG
|
||||
extern unsigned long long strtoull __P((const char *, char **, int));
|
||||
#endif
|
||||
|
||||
uintmax_t
|
||||
strtoumax (ptr, endptr, base)
|
||||
const char *ptr;
|
||||
char **endptr;
|
||||
int base;
|
||||
{
|
||||
#if HAVE_UNSIGNED_LONG_LONG
|
||||
verify (size_is_that_of_unsigned_long_or_unsigned_long_long,
|
||||
(sizeof (uintmax_t) == sizeof (unsigned long) ||
|
||||
sizeof (uintmax_t) == sizeof (unsigned long long)));
|
||||
|
||||
if (sizeof (uintmax_t) != sizeof (unsigned long))
|
||||
return (strtoull (ptr, endptr, base));
|
||||
#else
|
||||
verify (size_is_that_of_unsigned_long, sizeof (uintmax_t) == sizeof (unsigned long));
|
||||
#endif
|
||||
|
||||
return (strtoul (ptr, endptr, base));
|
||||
}
|
||||
|
||||
#ifdef TESTING
|
||||
# include <stdio.h>
|
||||
int
|
||||
main ()
|
||||
{
|
||||
char *p, *endptr;
|
||||
uintmax_t x;
|
||||
#if HAVE_UNSIGNED_LONG_LONG
|
||||
unsigned long long y;
|
||||
#endif
|
||||
unsigned long z;
|
||||
|
||||
printf ("sizeof uintmax_t: %d\n", sizeof (uintmax_t));
|
||||
|
||||
#if HAVE_UNSIGNED_LONG_LONG
|
||||
printf ("sizeof unsigned long long: %d\n", sizeof (unsigned long long));
|
||||
#endif
|
||||
printf ("sizeof unsigned long: %d\n", sizeof (unsigned long));
|
||||
|
||||
x = strtoumax("42", &endptr, 10);
|
||||
#if HAVE_LONG_LONG
|
||||
y = strtoull("42", &endptr, 10);
|
||||
#else
|
||||
y = 0;
|
||||
#endif
|
||||
z = strtoul("42", &endptr, 10);
|
||||
|
||||
printf ("%llu %llu %lu\n", x, y, z);
|
||||
|
||||
exit (0);
|
||||
}
|
||||
#endif
|
||||
@@ -1,81 +0,0 @@
|
||||
/* Handle window size changes and information. */
|
||||
|
||||
/* Copyright (C) 2005 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 2, 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; see the file COPYING. If not, write to the Free Software
|
||||
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdc.h>
|
||||
|
||||
#include "bashtypes.h"
|
||||
|
||||
#if defined (HAVE_UNISTD_H)
|
||||
# include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#if !defined (STRUCT_WINSIZE_IN_SYS_IOCTL)
|
||||
/* For struct winsize on SCO */
|
||||
/* sys/ptem.h has winsize but needs mblk_t from sys/stream.h */
|
||||
# if defined (HAVE_SYS_PTEM_H) && defined (TIOCGWINSZ) && defined (SIGWINCH)
|
||||
# if defined (HAVE_SYS_STREAM_H)
|
||||
# include <sys/stream.h>
|
||||
# endif
|
||||
# include <sys/ptem.h>
|
||||
# endif /* HAVE_SYS_PTEM_H && TIOCGWINSZ && SIGWINCH */
|
||||
#endif /* !STRUCT_WINSIZE_IN_SYS_IOCTL */
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Return the fd from which we are actually getting input. */
|
||||
#define input_tty() (shell_tty != -1) ? shell_tty : fileno (stderr)
|
||||
|
||||
#if !defined (errno)
|
||||
extern int errno;
|
||||
#endif /* !errno */
|
||||
|
||||
extern int shell_tty;
|
||||
|
||||
#if defined (READLINE)
|
||||
extern void rl_set_screen_size __P((int, int));
|
||||
#endif
|
||||
|
||||
void
|
||||
get_new_window_size (from_sig, rp, cp)
|
||||
int from_sig;
|
||||
{
|
||||
#if defined (TIOCGWINSZ)
|
||||
struct winsize win;
|
||||
int tty;
|
||||
|
||||
tty = input_tty ();
|
||||
if (tty >= 0 && (ioctl (tty, TIOCGWINSZ, &win) == 0) &&
|
||||
win.ws_row > 0 && win.ws_col > 0)
|
||||
{
|
||||
sh_set_lines_and_columns (win.ws_row, win.ws_col);
|
||||
#if defined (READLINE)
|
||||
rl_set_screen_size (win.ws_row, win.ws_col);
|
||||
if (rp)
|
||||
*rp = win.ws_row;
|
||||
if (cp)
|
||||
*cp = win.ws_col;
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
## -*- text -*- ####################################################
|
||||
# #
|
||||
# Makefile for termcap replacement libbrary. #
|
||||
# #
|
||||
####################################################################
|
||||
|
||||
# Copyright (C) 1996 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 2, 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 USA.
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = .:@srcdir@
|
||||
topdir = @top_srcdir@
|
||||
BUILD_DIR = @BUILD_DIR@
|
||||
|
||||
libdir = @libdir@
|
||||
|
||||
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@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
|
||||
DEFS = @DEFS@
|
||||
|
||||
INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib -I$(srcdir)
|
||||
|
||||
CCFLAGS = $(CFLAGS) $(DEFS) $(CPPFLAGS) ${INCLUDES}
|
||||
|
||||
# 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:
|
||||
$(CC) -c $(CCFLAGS) $<
|
||||
|
||||
SOURCES = termcap.c tparam.c
|
||||
OBJECTS = termcap.o tparam.o
|
||||
|
||||
DOCUMENTATION = termcap.texinfo
|
||||
|
||||
THINGS_TO_TAR = $(SOURCES) $(DOCUMENTATION)
|
||||
|
||||
##########################################################################
|
||||
|
||||
all: libtermcap.a
|
||||
|
||||
libtermcap.a: $(OBJECTS)
|
||||
$(RM) -f $@
|
||||
$(AR) $(ARFLAGS) $@ $(OBJECTS)
|
||||
-test -n "$(RANLIB)" && $(RANLIB) $@
|
||||
|
||||
install:
|
||||
|
||||
clean:
|
||||
$(RM) *.o *.a *.log *.cp *.tp *.vr *.fn *.aux *.pg *.toc
|
||||
|
||||
mostlyclean: clean
|
||||
|
||||
distclean maintainer-clean: clean
|
||||
$(RM) Makefile
|
||||
|
||||
$(DESTDIR)$(libdir)/libtermcap.a: libtermcap.a
|
||||
${INSTALL_DATA} -c -m 644 libtermcap.a $@
|
||||
-test -n "$(RANLIB)" && $(RANLIB) -t $@
|
||||
|
||||
termcap.o: $(BUILD_DIR)/config.h
|
||||
tparam.o: $(BUILD_DIR)/config.h
|
||||
version.o: $(BUILD_DIR)/config.h
|
||||
@@ -1,127 +0,0 @@
|
||||
## -*- text -*- ####################################################
|
||||
# #
|
||||
# Makefile for the GNU Tilde Library. #
|
||||
# #
|
||||
####################################################################
|
||||
|
||||
# Copyright (C) 1996 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 2, 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 USA.
|
||||
|
||||
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
|
||||
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)
|
||||
|
||||
.c.o:
|
||||
$(CC) -c $(CCFLAGS) $<
|
||||
|
||||
# The name of the library target.
|
||||
LIBRARY_NAME = libtilde.a
|
||||
|
||||
# The C code source files for this library.
|
||||
CSOURCES = $(srcdir)/tilde.c
|
||||
|
||||
# The header files for this library.
|
||||
HSOURCES = $(srcdir)/tilde.h
|
||||
|
||||
OBJECTS = tilde.o
|
||||
|
||||
# The texinfo files which document this library.
|
||||
DOCSOURCE = doc/tilde.texi
|
||||
DOCOBJECT = doc/tilde.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) $@
|
||||
|
||||
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:
|
||||
$(INSTALL_DATA) -c -m 644 $(LIBRARY_NAME) $(libdir)/$(LIBRARY_NAME)
|
||||
-test -n "$(RANLIB)" && $(RANLIB) -t $(libdir)/$(LIBRARY_NAME)
|
||||
|
||||
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) $@ )
|
||||
|
||||
######################################################################
|
||||
# #
|
||||
# Dependencies for the object files which make up this library. #
|
||||
# #
|
||||
######################################################################
|
||||
|
||||
tilde.o: tilde.h $(BASHINCDIR)/ansi_stdlib.h
|
||||
tilde.o: $(BUILD_DIR)/config.h
|
||||
|
||||
# Rules for deficient makes, like SunOS and Solaris
|
||||
tilde.o: tilde.c
|
||||
@@ -1,491 +0,0 @@
|
||||
/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */
|
||||
|
||||
/* Copyright (C) 1988,1989 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU 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 2, 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; see the file COPYING. If not, write to the Free
|
||||
Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#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>
|
||||
#include <pwd.h>
|
||||
|
||||
#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)
|
||||
extern struct passwd *getpwuid PARAMS((uid_t));
|
||||
extern struct passwd *getpwnam PARAMS((const char *));
|
||||
#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);
|
||||
free (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;
|
||||
}
|
||||
free (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);
|
||||
free (username);
|
||||
free (expansion);
|
||||
return (dirname);
|
||||
}
|
||||
}
|
||||
|
||||
/* No preexpansion hook, or the preexpansion hook failed. Look in the
|
||||
password database. */
|
||||
dirname = (char *)NULL;
|
||||
user_entry = getpwnam (username);
|
||||
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);
|
||||
}
|
||||
}
|
||||
free (username);
|
||||
/* 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);
|
||||
}
|
||||
else
|
||||
{
|
||||
free (username);
|
||||
dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len);
|
||||
}
|
||||
|
||||
endpwent ();
|
||||
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 */
|
||||
@@ -1,81 +0,0 @@
|
||||
/* tilde.h: Externally available variables and function in libtilde.a. */
|
||||
|
||||
/* Copyright (C) 1992 Free Software Foundation, Inc.
|
||||
|
||||
This file contains the Readline Library (the Library), a set of
|
||||
routines for providing Emacs style line input to programs that ask
|
||||
for it.
|
||||
|
||||
The Library 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, or (at your option)
|
||||
any later version.
|
||||
|
||||
The Library 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.
|
||||
|
||||
The GNU General Public License is often shipped with GNU software, and
|
||||
is generally kept in a file called COPYING or LICENSE. If you do not
|
||||
have a copy of the license, write to the Free Software Foundation,
|
||||
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
|
||||
|
||||
#if !defined (_TILDE_H_)
|
||||
# define _TILDE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* A function can be defined using prototypes and compile on both ANSI C
|
||||
and traditional C compilers with something like this:
|
||||
extern char *func PARAMS((char *, char *, int)); */
|
||||
|
||||
#if !defined (PARAMS)
|
||||
# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus)
|
||||
# define PARAMS(protos) protos
|
||||
# else
|
||||
# define PARAMS(protos) ()
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef char *tilde_hook_func_t PARAMS((char *));
|
||||
|
||||
/* 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. */
|
||||
extern tilde_hook_func_t *tilde_expansion_preexpansion_hook;
|
||||
|
||||
/* 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. */
|
||||
extern tilde_hook_func_t *tilde_expansion_failure_hook;
|
||||
|
||||
/* When non-null, this is a NULL terminated array of strings which
|
||||
are duplicates for a tilde prefix. Bash uses this to expand
|
||||
`=~' and `:~'. */
|
||||
extern char **tilde_additional_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 `=~'. */
|
||||
extern char **tilde_additional_suffixes;
|
||||
|
||||
/* Return a new string which is the result of tilde expanding STRING. */
|
||||
extern char *tilde_expand PARAMS((const char *));
|
||||
|
||||
/* Do the work of tilde expansion on FILENAME. FILENAME starts with a
|
||||
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
|
||||
extern char *tilde_expand_word PARAMS((const char *));
|
||||
|
||||
/* Find the portion of the string beginning with ~ that should be expanded. */
|
||||
extern char *tilde_find_word PARAMS((const char *, int *));
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _TILDE_H_ */
|
||||
Reference in New Issue
Block a user