Imported from ../bash-2.0.tar.gz.

This commit is contained in:
Jari Aalto 1996-12-23 17:02:34 +00:00
commit ccc6cda312
502 changed files with 91988 additions and 69123 deletions

View file

@ -1,23 +0,0 @@
GETOPT = ${topdir}/builtins/getopt.o
OBJECTS = texindex.o $(GETOPT)
SOURCES = texindex.c
LDFLAGS = -g
srcdir = .
VPATH = .:$(srcdir)
.c.o:
rm -f $@
$(CC) $(CFLAGS) -c $<
all: texindex
texindex: texindex.o
$(CC) $(LDFLAGS) -o $@ $(OBJECTS) $(LIBS)
clean:
rm -f texindex.o
realclean distclean maintainer-clean: clean
rm -f texindex

View file

@ -1,129 +0,0 @@
/* Declarations for getopt.
Copyright (C) 1989, 1990, 1991, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _GETOPT_H
#define _GETOPT_H 1
#ifdef __cplusplus
extern "C" {
#endif
/* For communication from `getopt' to the caller.
When `getopt' finds an option that takes an argument,
the argument value is returned here.
Also, when `ordering' is RETURN_IN_ORDER,
each non-option ARGV-element is returned here. */
extern char *optarg;
/* Index in ARGV of the next element to be scanned.
This is used for communication to and from the caller
and for communication between successive calls to `getopt'.
On entry to `getopt', zero means this is the first call; initialize.
When `getopt' returns EOF, this is the index of the first of the
non-option elements that the caller should itself scan.
Otherwise, `optind' communicates from one call to the next
how much of ARGV has been scanned so far. */
extern int optind;
/* Callers store zero here to inhibit the error message `getopt' prints
for unrecognized options. */
extern int opterr;
/* Set to an option character which was unrecognized. */
extern int optopt;
/* Describe the long-named options requested by the application.
The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
of `struct option' terminated by an element containing a name which is
zero.
The field `has_arg' is:
no_argument (or 0) if the option does not take an argument,
required_argument (or 1) if the option requires an argument,
optional_argument (or 2) if the option takes an optional argument.
If the field `flag' is not NULL, it points to a variable that is set
to the value given in the field `val' when the option is found, but
left unchanged if the option is not found.
To have a long-named option do something other than set an `int' to
a compiled-in constant, such as set a value from `optarg', set the
option's `flag' field to zero and its `val' field to a nonzero
value (the equivalent single-letter option character, if there is
one). For long options that have a zero `flag' field, `getopt'
returns the contents of the `val' field. */
struct option
{
#if __STDC__
const char *name;
#else
char *name;
#endif
/* has_arg can't be an enum because some compilers complain about
type mismatches in all the code that assumes it is an int. */
int has_arg;
int *flag;
int val;
};
/* Names for the values of the `has_arg' field of `struct option'. */
#define no_argument 0
#define required_argument 1
#define optional_argument 2
#if __STDC__
#if defined(__GNU_LIBRARY__)
/* Many other libraries have conflicting prototypes for getopt, with
differences in the consts, in stdlib.h. To avoid compilation
errors, only prototype getopt for the GNU C library. */
extern int getopt (int argc, char *const *argv, const char *shortopts);
#else /* not __GNU_LIBRARY__ */
extern int getopt ();
#endif /* not __GNU_LIBRARY__ */
extern int getopt_long (int argc, char *const *argv, const char *shortopts,
const struct option *longopts, int *longind);
extern int getopt_long_only (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind);
/* Internal only. Users should not call this directly. */
extern int _getopt_internal (int argc, char *const *argv,
const char *shortopts,
const struct option *longopts, int *longind,
int long_only);
#else /* not __STDC__ */
extern int getopt ();
extern int getopt_long ();
extern int getopt_long_only ();
extern int _getopt_internal ();
#endif /* not __STDC__ */
#ifdef __cplusplus
}
#endif
#endif /* _GETOPT_H */

File diff suppressed because it is too large Load diff

View file

@ -4,39 +4,46 @@
# #
####################################################################
# This Makefile is hand made from a template file, found in
# ../template. Each library must provide several Makefile
# targets: `all', `clean', `documentation', `install', and
# `what-tar'. The `what-tar' target reports the names of the
# files that need to be included in a tarfile to build the full
# code and documentation for this library.
srcdir = @srcdir@
VPATH = .:@srcdir@
topdir = @top_srcdir@
BUILD_DIR = @BUILD_DIR@
# Please note that the values for INCLUDES, CC, AR, RM, CP,
# RANLIB, and selfdir are passed in from ../Makefile, and do
# not need to be defined here.
srcdir = .
VPATH = .:$(srcdir)
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
CC = @CC@
RANLIB = @RANLIB@
AR = @AR@
RM = rm
CP = cp
MV = mv
CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@ @LOCAL_LDFLAGS@
DEFS = @DEFS@
INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib
CCFLAGS = $(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 $(CFLAGS) $(INCLUDES) $(LOCAL_DEFINES) $(CPPFLAGS) $<
# LOCAL_DEFINES are flags that are specific to this library.
# Define -DUSG if you are using a System V operating system.
LOCAL_DEFINES = $(LOCAL_INCLUDES) #-DUSG
# For libraries which include headers from other libraries.
LOCAL_INCLUDES = -I..
$(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)fnmatch.c
CSOURCES = $(srcdir)/glob.c $(srcdir)/fnmatch.c
# The header files for this library.
HSOURCES = $(srcdir)fnmatch.h
HSOURCES = $(srcdir)/fnmatch.h
OBJECTS = glob.o fnmatch.o
@ -58,8 +65,8 @@ all: $(LIBRARY_NAME)
$(LIBRARY_NAME): $(OBJECTS)
$(RM) -f $@
$(AR) cq $@ $(OBJECTS)
-[ -n "$(RANLIB)" ] && $(RANLIB) $@
$(AR) cr $@ $(OBJECTS)
-test -n "$(RANLIB)" && $(RANLIB) $@
what-tar:
@for file in $(THINGS_TO_TAR); do \
@ -67,24 +74,24 @@ what-tar:
done
documentation: force
-(cd doc && $(MAKE) $(MFLAGS))
-(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:
-$(MV) $(bindir)/$(LIBRARY_NAME) $(bindir)/$(LIBRARY_NAME)-old
$(CP) $(LIBRARY_NAME) $(bindir)/$(LIBRARY_NAME)
-[ -n "$(RANLIB)" ] && $(RANLIB) -t $(bindir)/$(LIBRARY_NAME)
clean:
rm -f $(OBJECTS) $(LIBRARY_NAME)
-(cd doc && $(MAKE) $(MFLAGS) $@)
-(cd doc && $(MAKE) $(MFLAGS) $@ )
maintainer-clean realclean mostlyclean distclean: clean
-(cd doc && $(MAKE) $(MFLAGS) $@)
realclean distclean maintainer-clean: clean
-( cd doc && $(MAKE) $(MFLAGS) $@ )
$(RM) -f Makefile
mostlyclean: clean
-( cd doc && $(MAKE) $(MFLAGS) $@ )
######################################################################
# #
@ -93,3 +100,6 @@ maintainer-clean realclean mostlyclean distclean: clean
######################################################################
fnmatch.o: fnmatch.c fnmatch.h
fnmatch.o: $(BUILD_DIR)/config.h
glob.o: $(BUILD_DIR)/config.h

View file

@ -1,5 +1,5 @@
all:
cp glob.texi glob.info
maintainer-clean realclean distclean clean:
clean distclean mostlyclean maintainer-clean:
rm -f glob.?? glob.info

View file

@ -68,10 +68,14 @@ fnmatch (pattern, string, flags)
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
return (FNM_NOMATCH);
for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
if (((flags & FNM_PATHNAME) && *n == '/') ||
(c == '?' && *n == '\0'))
return (FNM_NOMATCH);
for (c = *p++; c == '?' || c == '*'; c = *p++)
{
if (((flags & FNM_PATHNAME) && *n == '/') ||
(c == '?' && *n == '\0'))
return (FNM_NOMATCH);
if (c == '?')
n++;
}
if (c == '\0')
return (0);

View file

@ -14,45 +14,48 @@
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., 675 Mass Ave, Cambridge, MA 02139, 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. */
#if defined (SHELL)
# if defined (HAVE_STDLIB_H)
# include <stdlib.h>
# else
#include <config.h>
#if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
#pragma alloca
#endif /* _AIX && RISC6000 && !__GNUC__ */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# if defined (SHELL)
# include "ansi_stdlib.h"
# endif /* HAVE_STDLIB_H */
# include <config.h>
# endif /* SHELL */
#endif
#include <sys/types.h>
#if !defined (SHELL) && (defined (_POSIX_VERSION) || defined (USGr3))
# if !defined (HAVE_DIRENT_H)
# define HAVE_DIRENT_H
# endif /* !HAVE_DIRENT_H */
#endif /* !SHELL && (_POSIX_VERSION || USGr3) */
#if defined (HAVE_DIRENT_H)
# include <dirent.h>
# if !defined (direct)
# define direct dirent
# endif /* !direct */
# define D_NAMLEN(d) strlen ((d)->d_name)
#else /* !HAVE_DIRENT_H */
# define D_NAMLEN(d) ((d)->d_namlen)
# if defined (USG)
# if defined (Xenix)
# include <sys/ndir.h>
# else /* !Xenix (but USG...) */
# include "ndir.h"
# endif /* !Xenix */
# else /* !USG */
# if defined (HAVE_SYS_NDIR_H)
# include <sys/ndir.h>
# endif
# if defined (HAVE_SYS_DIR_H)
# include <sys/dir.h>
# endif /* !USG */
# endif /* HAVE_SYS_DIR_H */
# if defined (HAVE_NDIR_H)
# include <ndir.h>
# endif
# if !defined (dirent)
# define dirent direct
# endif
#endif /* !HAVE_DIRENT_H */
#if defined (_POSIX_SOURCE)
@ -63,34 +66,18 @@
# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
#endif /* _POSIX_SOURCE */
#if defined (USG) || defined (NeXT)
# if !defined (HAVE_STRING_H)
# define HAVE_STRING_H
# endif /* !HAVE_STRING_H */
#endif /* USG || NeXT */
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if defined (USG)
# if !defined (isc386)
# include <memory.h>
# endif /* !isc386 */
# if defined (RISC6000)
extern void bcopy ();
# else /* !RISC6000 */
# define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
# endif /* !RISC6000 */
#endif /* USG */
#include "fnmatch.h"
#if !defined (HAVE_BCOPY)
# define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
#endif /* !HAVE_BCOPY */
/* If the opendir () on your system lets you open non-directory files,
then we consider that not robust. Define OPENDIR_NOT_ROBUST in the
SYSDEP_CFLAGS for your machines entry in machines.h. */
then we consider that not robust. */
#if defined (OPENDIR_NOT_ROBUST)
# if defined (SHELL)
# include "posixstat.h"
@ -99,7 +86,10 @@ extern void bcopy ();
# endif /* !SHELL */
#endif /* OPENDIR_NOT_ROBUST */
#if !defined (HAVE_STDLIB_H)
#include "memalloc.h"
#include "fnmatch.h"
#if !defined (HAVE_STDLIB_H) && !defined (SHELL)
extern char *malloc (), *realloc ();
extern void free ();
#endif /* !HAVE_STDLIB_H */
@ -123,7 +113,6 @@ int noglob_dot_filenames = 1;
/* Global variable to return to signify an error in globbing. */
char *glob_error_return;
/* Return nonzero if PATTERN has any special globbing chars in it. */
int
glob_pattern_p (pattern)
@ -205,7 +194,7 @@ glob_vector (pat, dir)
};
DIR *d;
register struct direct *dp;
register struct dirent *dp;
struct globval *lastlink;
register struct globval *nextlink;
register char *nextname;
@ -365,7 +354,14 @@ glob_dir_to_array (dir, array)
+ strlen (array[i]) + 1);
if (result[i] == NULL)
return (NULL);
sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]);
#if 1
strcpy (result[i], dir);
if (add_slash)
result[i][l] = '/';
strcpy (result[i] + l + add_slash, array[i]);
#else
(void)sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]);
#endif
}
result[i] = NULL;
@ -432,7 +428,7 @@ glob_filename (pathname)
goto memory_error;
else if (directories == (char **)&glob_error_return)
{
free ((char *)result);
free ((char *) result);
return ((char **) &glob_error_return);
}
else if (*directories == NULL)

30
lib/glob/glob.h Normal file
View file

@ -0,0 +1,30 @@
/* File-name wildcard pattern matching for GNU.
Copyright (C) 1985, 1988, 1989 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 1, 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _GLOB_H_
#define _GLOB_H_
#include "stdc.h"
extern int glob_pattern_p __P((char *));
extern char **glob_vector __P((char *, char *));
extern char **glob_filename __P((char *));
extern char *glob_error_return;
extern int noglob_dot_filenames;
#endif /* _GLOB_H_ */

View file

@ -1,28 +0,0 @@
# Skeleton Makefile for the GNU malloc code
#
# Maybe this should really create a library instead of just compiling
# source files
srcdir = .
VPATH = .:$(srcdir)
.c.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
.s.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
MALLOC_SOURCE = malloc.c
ALLOCA_SOURCE = alloca.c
ALLOCA_OBJECT = alloca.o
malloc.o: malloc.c getpagesize.h
$(ALLOCA_OBJECT): $(ALLOCA_SOURCE)
alloca.o: $(ALLOCA_SOURCE)
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
@- if [ "$(ALLOCA_OBJECT)" != alloca.o ]; then \
mv $(ALLOCA_OBJECT) alloca.o >/dev/null 2>&1 ; \
fi

68
lib/malloc/Makefile.in Normal file
View file

@ -0,0 +1,68 @@
# Skeleton Makefile for the GNU malloc code
#
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@
RM = rm -f
CP = cp
MV = mv
CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
DEFS = @DEFS@
INCLUDES = -I. -I../.. -I$(topdir) -I$(topdir)/lib
CCFLAGS = ${INCLUDES} $(DEFS) $(LOCAL_CFLAGS) $(CFLAGS) $(MALLOC_CFLAGS) $(CPPFLAGS)
.c.o:
$(CC) $(CCFLAGS) -c $<
.s.o:
$(CC) $(CCFLAGS) -c $<
MALLOC_SOURCE = malloc.c
ALLOCA_SOURCE = alloca.c
ALLOCA_OBJECT = alloca.o
MALLOC_SRC = @MALLOC_SRC@
MALLOC = @MALLOC@
ALLOCA = @ALLOCA@
libmalloc.a: $(MALLOC) $(ALLOCA) stub.o
$(RM) $@
$(AR) cr $@ $(MALLOC) $(ALLOCA) stub.o
-test -n "$(RANLIB)" && $(RANLIB) $@
malloc.o: malloc.c getpagesize.h
alloca.o: $(ALLOCA_SOURCE)
$(CC) $(CCFLAGS) -c $(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
xmalloc.o: $(BUILD_DIR)/config.h
gmalloc.o: $(BUILD_DIR)/config.h

1579
lib/malloc/gmalloc.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -58,34 +58,27 @@ what you give them. Help stamp out software-hoarding! */
#endif
*/
/* Define this to have free() write 0xcf into memory as it's freed, to
uncover callers that refer to freed memory. */
/* SCO 3.2v4 getcwd and possibly other libc routines fail with MEMSCRAMBLE */
#if !defined (NO_MEMSCRAMBLE)
# define MEMSCRAMBLE
#endif
#if defined (emacs) || defined (HAVE_CONFIG_H)
# include "config.h"
# include <config.h>
#endif /* emacs */
#if !defined (USG)
# if defined (HPUX) || defined (UnixPC) || defined (Xenix)
# define USG
# endif /* HPUX || UnixPC || Xenix */
#endif /* !USG */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
/* Determine which kind of system this is. */
#include <sys/types.h>
#include <signal.h>
#if !defined (USG) && !defined (USGr4)
# ifndef SIGTSTP
# ifndef USG
# define USG
# endif /* !USG */
# else /* SIGTSTP */
# ifdef SIGIO
# define BSD4_2
# endif /* SIGIO */
# endif /* SIGTSTP */
#endif /* !USG && !USGr4 */
#ifndef BSD4_2
/* Define getpagesize () if the system does not. */
/* Define getpagesize () if the system does not. */
#ifndef HAVE_GETPAGESIZE
# include "getpagesize.h"
#endif
@ -100,6 +93,10 @@ what you give them. Help stamp out software-hoarding! */
# undef HAVE_RESOURCE
#endif
#if !defined (NULL)
# define NULL 0
#endif
#define start_of_data() &etext
#define ISALLOC ((char) 0xf7) /* magic byte that implies allocation */
@ -111,12 +108,11 @@ what you give them. Help stamp out software-hoarding! */
beginning of the block. */
extern char etext;
#if !defined (NO_SBRK_DECL)
#if !defined (SBRK_DECLARED)
extern char *sbrk ();
#endif /* !NO_SBRK_DECL */
#endif /* !SBRK_DECLARED */
/* These two are for user programs to look at, when they are interested. */
unsigned int malloc_sbrk_used; /* amount of data space used now */
unsigned int malloc_sbrk_unused; /* amount more we can have */
@ -143,7 +139,7 @@ struct mhead {
/* Remainder are valid only when block is allocated */
unsigned short mh_size; /* size, if < 0x10000 */
#ifdef rcheck
unsigned mh_nbytes; /* number of bytes allocated */
unsigned int mh_nbytes; /* number of bytes allocated */
int mh_magic4; /* should be == MAGIC4 */
#endif /* rcheck */
};
@ -241,7 +237,7 @@ malloc_usable_size (mem)
return blocksize - sizeof (struct mhead) - EXTRA;
}
static void
morecore (nu) /* ask system for more memory */
register int nu; /* size index to get more of */
@ -249,11 +245,19 @@ morecore (nu) /* ask system for more memory */
register char *cp;
register int nblks;
register unsigned int siz;
int oldmask;
#if defined (BSD4_2)
/* Block all signals in case we are executed from a signal handler. */
#if defined (HAVE_BSD_SIGNALS)
int oldmask;
oldmask = sigsetmask (-1);
#endif /* BSD4_2 */
#else
# if defined (HAVE_POSIX_SIGNALS)
sigset_t set, oset;
sigfillset (&set);
sigemptyset (&oset);
sigprocmask (SIG_BLOCK, &set, &oset);
# endif /* HAVE_POSIX_SIGNALS */
#endif /* HAVE_BSD_SIGNALS */
if (!data_space_start)
{
@ -331,9 +335,13 @@ morecore (nu) /* ask system for more memory */
}
CHAIN ((struct mhead *) cp) = 0;
#if defined (BSD4_2)
#if defined (HAVE_BSD_SIGNALS)
sigsetmask (oldmask);
#endif /* BSD4_2 */
#else
# if defined (HAVE_POSIX_SIGNALS)
sigprocmask (SIG_SETMASK, &oset, (sigset_t *)NULL);
# endif
#endif /* HAVE_BSD_SIGNALS */
}
static void
@ -373,10 +381,26 @@ getpool ()
cp += 8 << nu;
}
}
#if defined (MEMSCRAMBLE) || !defined (NO_CALLOC)
static char *
zmemset (s, c, n)
char *s;
int c;
register int n;
{
register char *sp;
sp = s;
while (--n >= 0)
*sp++ = c;
return (s);
}
#endif /* MEMSCRAMBLE || !NO_CALLOC */
char *
malloc (n) /* get a block */
unsigned n;
unsigned int n;
{
register struct mhead *p;
register unsigned int nbytes;
@ -436,6 +460,9 @@ malloc (n) /* get a block */
#else /* not rcheck */
p -> mh_size = n;
#endif /* not rcheck */
#ifdef MEMSCRAMBLE
zmemset ((char *)(p + 1), 0xdf, n); /* scramble previous contents */
#endif
#ifdef MSTATS
nmalloc[nunits]++;
nmal++;
@ -474,7 +501,7 @@ free (mem)
if (p -> mh_alloc == ISFREE)
botch ("free: Called with already freed block argument\n");
else
botch ("free: Called with bad argument\n");
botch ("free: Called with unallocated block argument\n");
}
ASSERT (p -> mh_magic4 == MAGIC4);
@ -483,6 +510,18 @@ free (mem)
ASSERT (*ap++ == MAGIC1); ASSERT (*ap == MAGIC1);
#endif /* rcheck */
}
#ifdef MEMSCRAMBLE
{
register int n;
#ifdef rcheck
n = p->mh_nbytes;
#else /* not rcheck */
n = p->mh_size;
#endif /* not rcheck */
zmemset (mem, 0xcf, n);
}
#endif
{
register int nunits = p -> mh_index;
@ -506,7 +545,7 @@ free (mem)
char *
realloc (mem, n)
char *mem;
register unsigned n;
register unsigned int n;
{
register struct mhead *p;
register unsigned int tocopy;
@ -565,12 +604,14 @@ realloc (mem, n)
char *
memalign (alignment, size)
unsigned alignment, size;
unsigned int alignment, size;
{
register char *ptr = malloc (size + alignment);
register char *ptr;
register char *aligned;
register struct mhead *p;
ptr = malloc (size + alignment);
if (ptr == 0)
return 0;
/* If entire block has the desired alignment, just accept it. */
@ -587,16 +628,44 @@ memalign (alignment, size)
return aligned;
}
#if !defined (HPUX) && !defined (Multimax) && !defined (Multimax32k)
#if !defined (HPUX)
/* This runs into trouble with getpagesize on HPUX, and Multimax machines.
Patching out seems cleaner than the ugly fix needed. */
#if defined (__STDC__)
void *
#else
char *
#endif
valloc (size)
size_t size;
{
return memalign (getpagesize (), size);
}
#endif /* !HPUX && !Multimax && !Multimax32k */
#endif /* !HPUX */
#ifndef NO_CALLOC
char *
calloc (n, s)
size_t n, s;
{
size_t total;
char *result;
total = n * s;
result = malloc (total);
if (result)
zmemset (result, 0, total);
return result;
}
void
cfree (p)
char *p;
{
free (p);
}
#endif /* !NO_CALLOC */
#ifdef MSTATS
/* Return statistics describing allocation of blocks of size 2**n. */
@ -633,7 +702,7 @@ malloc_stats (size)
return v;
}
#endif /* MSTATS */
/*
* This function returns the total number of bytes that the process
* will be allowed to allocate via the sbrk(2) system call. On

4
lib/malloc/stub.c Normal file
View file

@ -0,0 +1,4 @@
void
bash_malloc_stub()
{
}

View file

@ -19,8 +19,10 @@
along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if defined (ALREADY_HAVE_XMALLOC)
#else
#if defined (HAVE_CONFIG_H)
#include <config.h>
#endif
#include <stdio.h>
#if defined (HAVE_STDLIB_H)
@ -44,9 +46,10 @@ char *
xmalloc (bytes)
int bytes;
{
char *temp = (char *)malloc (bytes);
char *temp;
if (!temp)
temp = (char *)malloc (bytes);
if (temp == 0)
memory_error_and_abort ("xmalloc");
return (temp);
}
@ -58,12 +61,9 @@ xrealloc (pointer, bytes)
{
char *temp;
if (!pointer)
temp = (char *)malloc (bytes);
else
temp = (char *)realloc (pointer, bytes);
temp = pointer ? (char *)realloc (pointer, bytes) : (char *)malloc (bytes);
if (!temp)
if (temp == 0)
memory_error_and_abort ("xrealloc");
return (temp);
}
@ -72,7 +72,16 @@ static void
memory_error_and_abort (fname)
char *fname;
{
fprintf (stderr, "%s: Out of virtual memory!\n", fname);
abort ();
fprintf (stderr, "%s: out of virtual memory\n", fname);
exit (2);
}
/* Use this as the function to call when adding unwind protects so we
don't need to know what free() returns. */
void
xfree (string)
char *string;
{
if (string)
free (string);
}
#endif /* !ALREADY_HAVE_XMALLOC */

View file

@ -1,53 +0,0 @@
# Copyright (C) 1991 Free Software Foundation, Inc.
# This file is part of the GNU C Library.
# The GNU C Library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Library General Public License
# as published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
# The GNU C 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
# Library General Public License for more details.
# You should have received a copy of the GNU Library General Public
# License along with the GNU C Library; see the file COPYING.LIB. If
# not, write to the Free Software Foundation, Inc., 675 Mass Ave,
# Cambridge, MA 02139, USA.
# Makefile for standalone distribution of malloc.
srcdir = .
VPATH = .:$(srcdir)
all: libmalloc.a
sources = calloc.c cfree.c free.c malloc.c mcheck.c morecore.c \
memalign.c mstats.c mtrace.c realloc.c valloc.c
objects = calloc.o cfree.o free.o malloc.o mcheck.o morecore.o \
memalign.o mstats.o mtrace.o realloc.o valloc.o
headers = malloc.h getpagesize.h
libmalloc.a: $(objects)
ar crv $@ $(objects)
ranlib $@
.c.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -I. -c $< $(OUTPUT_OPTION)
.PHONY: clean realclean malloc-clean malloc-realclean
clean malloc-clean:
-rm -f libmalloc.a $(objects) core
realclean malloc-realclean: clean
-rm -f TAGS tags *~
calloc.o: malloc.h
free.o: malloc.h
malloc.o: malloc.h
mcheck.o: malloc.h
memalign.o: malloc.h
mstats.o: malloc.h
mtrace.o: malloc.h
realloc.o: malloc.h
valloc.o: malloc.h getpagesize.h

View file

@ -1,189 +0,0 @@
/* alloca -- (mostly) portable public-domain implementation -- D A Gwyn
last edit: 86/05/30 rms
include config.h, since on VMS it renames some symbols.
Use xmalloc instead of malloc.
This implementation of the PWB library alloca() function,
which is used to allocate space off the run-time stack so
that it is automatically reclaimed upon procedure exit,
was inspired by discussions with J. Q. Johnson of Cornell.
It should work under any C implementation that uses an
actual procedure stack (as opposed to a linked list of
frames). There are some preprocessor constants that can
be defined when compiling for your specific system, for
improved efficiency; however, the defaults should be okay.
The general concept of this implementation is to keep
track of all alloca()-allocated blocks, and reclaim any
that are found to be deeper in the stack than the current
invocation. This heuristic does not reclaim storage as
soon as it becomes invalid, but it will do so eventually.
As a special case, alloca(0) reclaims storage without
allocating any. It is a good idea to use alloca(0) in
your main control loop, etc. to force garbage collection.
*/
#ifndef lint
static char SCCSid[] = "@(#)alloca.c 1.1"; /* for the "what" utility */
#endif
#ifdef emacs
#include "config.h"
#ifdef static
/* actually, only want this if static is defined as ""
-- this is for usg, in which emacs must undefine static
in order to make unexec workable
*/
#ifndef STACK_DIRECTION
you
lose
-- must know STACK_DIRECTION at compile-time
#endif /* STACK_DIRECTION undefined */
#endif /* static */
#endif /* emacs */
#ifdef X3J11
typedef void *pointer; /* generic pointer type */
#else
typedef char *pointer; /* generic pointer type */
#endif /* X3J11 */
#define NULL 0 /* null pointer constant */
extern void free();
extern pointer xmalloc();
/*
Define STACK_DIRECTION if you know the direction of stack
growth for your system; otherwise it will be automatically
deduced at run-time.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown
*/
#ifndef STACK_DIRECTION
#define STACK_DIRECTION 0 /* direction unknown */
#endif
#if STACK_DIRECTION != 0
#define STACK_DIR STACK_DIRECTION /* known at compile-time */
#else /* STACK_DIRECTION == 0; need run-time code */
static int stack_dir; /* 1 or -1 once known */
#define STACK_DIR stack_dir
static void
find_stack_direction (/* void */)
{
static char *addr = NULL; /* address of first
`dummy', once known */
auto char dummy; /* to get stack address */
if (addr == NULL)
{ /* initial entry */
addr = &dummy;
find_stack_direction (); /* recurse once */
}
else /* second entry */
if (&dummy > addr)
stack_dir = 1; /* stack grew upward */
else
stack_dir = -1; /* stack grew downward */
}
#endif /* STACK_DIRECTION == 0 */
/*
An "alloca header" is used to:
(a) chain together all alloca()ed blocks;
(b) keep track of stack depth.
It is very important that sizeof(header) agree with malloc()
alignment chunk size. The following default should work okay.
*/
#ifndef ALIGN_SIZE
#define ALIGN_SIZE sizeof(double)
#endif
typedef union hdr
{
char align[ALIGN_SIZE]; /* to force sizeof(header) */
struct
{
union hdr *next; /* for chaining headers */
char *deep; /* for stack depth measure */
} h;
} header;
/*
alloca( size ) returns a pointer to at least `size' bytes of
storage which will be automatically reclaimed upon exit from
the procedure that called alloca(). Originally, this space
was supposed to be taken from the current stack frame of the
caller, but that method cannot be made to work for some
implementations of C, for example under Gould's UTX/32.
*/
static header *last_alloca_header = NULL; /* -> last alloca header */
pointer
alloca (size) /* returns pointer to storage */
unsigned size; /* # bytes to allocate */
{
auto char probe; /* probes stack depth: */
register char *depth = &probe;
#if STACK_DIRECTION == 0
if (STACK_DIR == 0) /* unknown growth direction */
find_stack_direction ();
#endif
/* Reclaim garbage, defined as all alloca()ed storage that
was allocated from deeper in the stack than currently. */
{
register header *hp; /* traverses linked list */
for (hp = last_alloca_header; hp != NULL;)
if (STACK_DIR > 0 && hp->h.deep > depth
|| STACK_DIR < 0 && hp->h.deep < depth)
{
register header *np = hp->h.next;
free ((pointer) hp); /* collect garbage */
hp = np; /* -> next header */
}
else
break; /* rest are not deeper */
last_alloca_header = hp; /* -> last valid storage */
}
if (size == 0)
return NULL; /* no allocation required */
/* Allocate combined header + user data storage. */
{
register pointer new = xmalloc (sizeof (header) + size);
/* address of header */
((header *)new)->h.next = last_alloca_header;
((header *)new)->h.deep = depth;
last_alloca_header = (header *)new;
/* User storage begins just after header. */
return (pointer)((char *)new + sizeof(header));
}
}

View file

@ -1,39 +0,0 @@
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#include <malloc.h>
#endif
/* Allocate an array of NMEMB elements each SIZE bytes long.
The entire array is initialized to zeros. */
__ptr_t
calloc (nmemb, size)
register size_t nmemb;
register size_t size;
{
register __ptr_t result = malloc (nmemb * size);
if (result != NULL)
(void) memset (result, 0, nmemb * size);
return result;
}

View file

@ -1,43 +0,0 @@
/* Copyright (C) 1991, 1993 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
The GNU C 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with the GNU C Library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#include <malloc.h>
#endif
#undef cfree
#ifdef _LIBC
#include <ansidecl.h>
#include <gnu-stabs.h>
function_alias(cfree, free, void, (ptr),
DEFUN(cfree, (ptr), PTR ptr))
#else
void
cfree (ptr)
__ptr_t ptr;
{
free (ptr);
}
#endif

View file

@ -1,212 +0,0 @@
/* Free a block of memory allocated by `malloc'.
Copyright 1990, 1991, 1992 Free Software Foundation
Written May 1989 by Mike Haertel.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#include <malloc.h>
#endif
/* Debugging hook for free. */
void (*__free_hook) __P ((__ptr_t __ptr));
/* List of blocks allocated by memalign. */
struct alignlist *_aligned_blocks = NULL;
/* Return memory to the heap.
Like `free' but don't call a __free_hook if there is one. */
void
_free_internal (ptr)
__ptr_t ptr;
{
int type;
size_t block, blocks;
register size_t i;
struct list *prev, *next;
block = BLOCK (ptr);
type = _heapinfo[block].busy.type;
switch (type)
{
case 0:
/* Get as many statistics as early as we can. */
--_chunks_used;
_bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE;
_bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE;
/* Find the free cluster previous to this one in the free list.
Start searching at the last block referenced; this may benefit
programs with locality of allocation. */
i = _heapindex;
if (i > block)
while (i > block)
i = _heapinfo[i].free.prev;
else
{
do
i = _heapinfo[i].free.next;
while (i > 0 && i < block);
i = _heapinfo[i].free.prev;
}
/* Determine how to link this block into the free list. */
if (block == i + _heapinfo[i].free.size)
{
/* Coalesce this block with its predecessor. */
_heapinfo[i].free.size += _heapinfo[block].busy.info.size;
block = i;
}
else
{
/* Really link this block back into the free list. */
_heapinfo[block].free.size = _heapinfo[block].busy.info.size;
_heapinfo[block].free.next = _heapinfo[i].free.next;
_heapinfo[block].free.prev = i;
_heapinfo[i].free.next = block;
_heapinfo[_heapinfo[block].free.next].free.prev = block;
++_chunks_free;
}
/* Now that the block is linked in, see if we can coalesce it
with its successor (by deleting its successor from the list
and adding in its size). */
if (block + _heapinfo[block].free.size == _heapinfo[block].free.next)
{
_heapinfo[block].free.size
+= _heapinfo[_heapinfo[block].free.next].free.size;
_heapinfo[block].free.next
= _heapinfo[_heapinfo[block].free.next].free.next;
_heapinfo[_heapinfo[block].free.next].free.prev = block;
--_chunks_free;
}
/* Now see if we can return stuff to the system. */
blocks = _heapinfo[block].free.size;
if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit
&& (*__morecore) (0) == ADDRESS (block + blocks))
{
register size_t bytes = blocks * BLOCKSIZE;
_heaplimit -= blocks;
(*__morecore) (-bytes);
_heapinfo[_heapinfo[block].free.prev].free.next
= _heapinfo[block].free.next;
_heapinfo[_heapinfo[block].free.next].free.prev
= _heapinfo[block].free.prev;
block = _heapinfo[block].free.prev;
--_chunks_free;
_bytes_free -= bytes;
}
/* Set the next search to begin at this block. */
_heapindex = block;
break;
default:
/* Do some of the statistics. */
--_chunks_used;
_bytes_used -= 1 << type;
++_chunks_free;
_bytes_free += 1 << type;
/* Get the address of the first free fragment in this block. */
prev = (struct list *) ((char *) ADDRESS (block) +
(_heapinfo[block].busy.info.frag.first << type));
if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1
&& _fragblocks[type] > 1)
{
/* If all fragments of this block are free, remove them
from the fragment list and free the whole block. */
--_fragblocks[type];
next = prev;
for (i = 1; i < (size_t) (BLOCKSIZE >> type); ++i)
next = next->next;
prev->prev->next = next;
if (next != NULL)
next->prev = prev->prev;
_heapinfo[block].busy.type = 0;
_heapinfo[block].busy.info.size = 1;
/* Keep the statistics accurate. */
++_chunks_used;
_bytes_used += BLOCKSIZE;
_chunks_free -= BLOCKSIZE >> type;
_bytes_free -= BLOCKSIZE;
free (ADDRESS (block));
}
else if (_heapinfo[block].busy.info.frag.nfree != 0)
{
/* If some fragments of this block are free, link this
fragment into the fragment list after the first free
fragment of this block. */
next = (struct list *) ptr;
next->next = prev->next;
next->prev = prev;
prev->next = next;
if (next->next != NULL)
next->next->prev = next;
++_heapinfo[block].busy.info.frag.nfree;
}
else
{
/* No fragments of this block are free, so link this
fragment into the fragment list and announce that
it is the first free fragment of this block. */
prev = (struct list *) ptr;
_heapinfo[block].busy.info.frag.nfree = 1;
_heapinfo[block].busy.info.frag.first = (unsigned long int)
((unsigned long int) ((char *) ptr - (char *) NULL)
% BLOCKSIZE >> type);
prev->next = _fraghead[type].next;
prev->prev = &_fraghead[type];
prev->prev->next = prev;
if (prev->next != NULL)
prev->next->prev = prev;
}
break;
}
}
/* Return memory to the heap. */
void
free (ptr)
__ptr_t ptr;
{
register struct alignlist *l;
if (ptr == NULL)
return;
for (l = _aligned_blocks; l != NULL; l = l->next)
if (l->aligned == ptr)
{
l->aligned = NULL; /* Mark the slot in the list as free. */
ptr = l->exact;
break;
}
if (__free_hook != NULL)
(*__free_hook) (ptr);
else
_free_internal (ptr);
}

View file

@ -1,56 +0,0 @@
/* Emulation of getpagesize() for systems that need it.
Copyright (C) 1991 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., 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (USG)
extern size_t getpagesize __P ((void));
# if !defined (HAVE_GETPAGESIZE)
# define HAVE_GETPAGESIZE
# endif /* !HAVE_GETPAGESIZE */
#endif /* !USG */
#if !defined (HAVE_GETPAGESIZE) && defined (HAVE_UNISTD_H)
# include <unistd.h>
# if defined (_SC_PAGESIZE)
# define getpagesize() sysconf(_SC_PAGESIZE)
# endif /* _SC_PAGESIZE */
#endif
#if !defined (HAVE_GETPAGESIZE)
# include <sys/param.h>
# if defined (PAGESIZE)
# define getpagesize() PAGESIZE
# else /* !PAGESIZE */
# if defined (EXEC_PAGESIZE)
# define getpagesize() EXEC_PAGESIZE
# else /* !EXEC_PAGESIZE */
# if defined (NBPG)
# if !defined (CLSIZE)
# define CLSIZE 1
# endif /* !CLSIZE */
# define getpagesize() (NBPG * CLSIZE)
# else /* !NBPG */
# if defined (NBPC)
# define getpagesize() NBPC
# endif /* NBPC */
# endif /* !NBPG */
# endif /* !EXEC_PAGESIZE */
# endif /* !PAGESIZE */
#endif /* !getpagesize */
#if !defined (HAVE_GETPAGESIZE) && !defined (getpagesize)
# define getpagesize() 4096 /* Just punt and use reasonable value */
#endif /* !HAVE_GETPAGESIZE && !getpagesize */

View file

@ -1,16 +0,0 @@
.file "alloca.s"
.text
.align 4
.def alloca; .val alloca; .scl 2; .type 044; .endef
.globl alloca
alloca:
popl %edx
popl %eax
addl $3,%eax
andl $0xfffffffc,%eax
subl %eax,%esp
movl %esp,%eax
pushl %eax
pushl %edx
ret
.def alloca; .val .; .scl -1; .endef

View file

@ -1,324 +0,0 @@
/* Memory allocator `malloc'.
Copyright 1990, 1991, 1992, 1993 Free Software Foundation
Written May 1989 by Mike Haertel.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#include <malloc.h>
#endif
/* How to really get more memory. */
__ptr_t (*__morecore) __P ((ptrdiff_t __size)) = __default_morecore;
/* Debugging hook for `malloc'. */
__ptr_t (*__malloc_hook) __P ((size_t __size));
/* Pointer to the base of the first block. */
char *_heapbase;
/* Block information table. Allocated with align/__free (not malloc/free). */
malloc_info *_heapinfo;
/* Number of info entries. */
static size_t heapsize;
/* Search index in the info table. */
size_t _heapindex;
/* Limit of valid info table indices. */
size_t _heaplimit;
/* Count of large blocks allocated for each fragment size. */
int _fragblocks[BLOCKLOG];
/* Free lists for each fragment size. */
struct list _fraghead[BLOCKLOG];
/* Instrumentation. */
size_t _chunks_used;
size_t _bytes_used;
size_t _chunks_free;
size_t _bytes_free;
/* Are you experienced? */
int __malloc_initialized;
void (*__after_morecore_hook) __P ((void));
/* Aligned allocation. */
static __ptr_t align __P ((size_t));
static __ptr_t
align (size)
size_t size;
{
__ptr_t result;
unsigned long int adj;
result = (*__morecore) (size);
adj = (unsigned long int) ((unsigned long int) ((char *) result -
(char *) NULL)) % BLOCKSIZE;
if (adj != 0)
{
adj = BLOCKSIZE - adj;
(void) (*__morecore) (adj);
result = (char *) result + adj;
}
if (__after_morecore_hook)
(*__after_morecore_hook) ();
return result;
}
/* Set everything up and remember that we have. */
static int initialize __P ((void));
static int
initialize ()
{
heapsize = HEAP / BLOCKSIZE;
_heapinfo = (malloc_info *) align (heapsize * sizeof (malloc_info));
_bytes_used = heapsize * sizeof (malloc_info);
_chunks_used++;
if (_heapinfo == NULL)
return 0;
memset (_heapinfo, 0, heapsize * sizeof (malloc_info));
_heapinfo[0].free.size = 0;
_heapinfo[0].free.next = _heapinfo[0].free.prev = 0;
_heapindex = 0;
_heapbase = (char *) _heapinfo;
__malloc_initialized = 1;
return 1;
}
/* Get neatly aligned memory, initializing or
growing the heap info table as necessary. */
static __ptr_t morecore __P ((size_t));
static __ptr_t
morecore (size)
size_t size;
{
__ptr_t result;
malloc_info *newinfo, *oldinfo;
size_t newsize;
result = align (size);
if (result == NULL)
return NULL;
/* Check if we need to grow the info table. */
if ((size_t) BLOCK ((char *) result + size) > heapsize)
{
newsize = heapsize;
while ((size_t) BLOCK ((char *) result + size) > newsize)
newsize *= 2;
newinfo = (malloc_info *) align (newsize * sizeof (malloc_info));
if (newinfo == NULL)
{
(*__morecore) (-size);
return NULL;
}
_bytes_used += newsize * sizeof (malloc_info);
_chunks_used++;
memset (newinfo, 0, newsize * sizeof (malloc_info));
memcpy (newinfo, _heapinfo, heapsize * sizeof (malloc_info));
oldinfo = _heapinfo;
newinfo[BLOCK (oldinfo)].busy.type = 0;
newinfo[BLOCK (oldinfo)].busy.info.size
= BLOCKIFY (heapsize * sizeof (malloc_info));
_heapinfo = newinfo;
heapsize = newsize;
}
_heaplimit = BLOCK ((char *) result + size);
return result;
}
/* Allocate memory from the heap. */
__ptr_t
malloc (size)
size_t size;
{
__ptr_t result;
size_t block, blocks, lastblocks, start;
register size_t i;
struct list *next;
if (size == 0)
return NULL;
if (__malloc_hook != NULL)
return (*__malloc_hook) (size);
if (!__malloc_initialized)
if (!initialize ())
return NULL;
if (size < sizeof (struct list))
size = sizeof (struct list);
/* Determine the allocation policy based on the request size. */
if (size <= BLOCKSIZE / 2)
{
/* Small allocation to receive a fragment of a block.
Determine the logarithm to base two of the fragment size. */
register size_t log = 1;
--size;
while ((size /= 2) != 0)
++log;
/* Look in the fragment lists for a
free fragment of the desired size. */
next = _fraghead[log].next;
if (next != NULL)
{
/* There are free fragments of this size.
Pop a fragment out of the fragment list and return it.
Update the block's nfree and first counters. */
result = (__ptr_t) next;
next->prev->next = next->next;
if (next->next != NULL)
next->next->prev = next->prev;
block = BLOCK (result);
if (--_heapinfo[block].busy.info.frag.nfree != 0)
_heapinfo[block].busy.info.frag.first = (unsigned long int)
((unsigned long int) ((char *) next->next - (char *) NULL)
% BLOCKSIZE) >> log;
/* Update the statistics. */
++_chunks_used;
_bytes_used += 1 << log;
--_chunks_free;
_bytes_free -= 1 << log;
}
else
{
/* No free fragments of the desired size, so get a new block
and break it into fragments, returning the first. */
result = malloc (BLOCKSIZE);
if (result == NULL)
return NULL;
++_fragblocks[log];
/* Link all fragments but the first into the free list. */
for (i = 1; i < (size_t) (BLOCKSIZE >> log); ++i)
{
next = (struct list *) ((char *) result + (i << log));
next->next = _fraghead[log].next;
next->prev = &_fraghead[log];
next->prev->next = next;
if (next->next != NULL)
next->next->prev = next;
}
/* Initialize the nfree and first counters for this block. */
block = BLOCK (result);
_heapinfo[block].busy.type = log;
_heapinfo[block].busy.info.frag.nfree = i - 1;
_heapinfo[block].busy.info.frag.first = i - 1;
_chunks_free += (BLOCKSIZE >> log) - 1;
_bytes_free += BLOCKSIZE - (1 << log);
_bytes_used -= BLOCKSIZE - (1 << log);
}
}
else
{
/* Large allocation to receive one or more blocks.
Search the free list in a circle starting at the last place visited.
If we loop completely around without finding a large enough
space we will have to get more memory from the system. */
blocks = BLOCKIFY (size);
start = block = _heapindex;
while (_heapinfo[block].free.size < blocks)
{
block = _heapinfo[block].free.next;
if (block == start)
{
/* Need to get more from the system. Check to see if
the new core will be contiguous with the final free
block; if so we don't need to get as much. */
block = _heapinfo[0].free.prev;
lastblocks = _heapinfo[block].free.size;
if (_heaplimit != 0 && block + lastblocks == _heaplimit &&
(*__morecore) (0) == ADDRESS (block + lastblocks) &&
(morecore ((blocks - lastblocks) * BLOCKSIZE)) != NULL)
{
/* Note that morecore() can change the location of
the final block if it moves the info table and the
old one gets coalesced into the final block. */
block = _heapinfo[0].free.prev;
_heapinfo[block].free.size += blocks - lastblocks;
continue;
}
result = morecore (blocks * BLOCKSIZE);
if (result == NULL)
return NULL;
block = BLOCK (result);
_heapinfo[block].busy.type = 0;
_heapinfo[block].busy.info.size = blocks;
++_chunks_used;
_bytes_used += blocks * BLOCKSIZE;
return result;
}
}
/* At this point we have found a suitable free list entry.
Figure out how to remove what we need from the list. */
result = ADDRESS (block);
if (_heapinfo[block].free.size > blocks)
{
/* The block we found has a bit left over,
so relink the tail end back into the free list. */
_heapinfo[block + blocks].free.size
= _heapinfo[block].free.size - blocks;
_heapinfo[block + blocks].free.next
= _heapinfo[block].free.next;
_heapinfo[block + blocks].free.prev
= _heapinfo[block].free.prev;
_heapinfo[_heapinfo[block].free.prev].free.next
= _heapinfo[_heapinfo[block].free.next].free.prev
= _heapindex = block + blocks;
}
else
{
/* The block exactly matches our requirements,
so just remove it from the list. */
_heapinfo[_heapinfo[block].free.next].free.prev
= _heapinfo[block].free.prev;
_heapinfo[_heapinfo[block].free.prev].free.next
= _heapindex = _heapinfo[block].free.next;
--_chunks_free;
}
_heapinfo[block].busy.type = 0;
_heapinfo[block].busy.info.size = blocks;
++_chunks_used;
_bytes_used += blocks * BLOCKSIZE;
_bytes_free -= blocks * BLOCKSIZE;
}
return result;
}

View file

@ -1,268 +0,0 @@
/* Declarations for `malloc' and friends.
Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Written May 1989 by Mike Haertel.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
#ifndef _MALLOC_H
#define _MALLOC_H 1
#ifdef _MALLOC_INTERNAL
/* Harmless, gets __GNU_LIBRARY__ defined.
We must do this before #defining size_t and ptrdiff_t
because <stdio.h> tries to typedef them on some systems. */
#include <stdio.h>
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#if defined (__cplusplus) || (defined (__STDC__) && __STDC__)
#undef __P
#define __P(args) args
#undef __ptr_t
#define __ptr_t void *
#else /* Not C++ or ANSI C. */
#undef __P
#define __P(args) ()
#undef const
#define const
#undef __ptr_t
#define __ptr_t char *
#endif /* C++ or ANSI C. */
#ifndef NULL
#define NULL 0
#endif
#ifdef __STDC__
#include <stddef.h>
#else
#undef size_t
#define size_t unsigned int
#undef ptrdiff_t
#define ptrdiff_t int
#endif
/* Allocate SIZE bytes of memory. */
extern __ptr_t malloc __P ((size_t __size));
/* Re-allocate the previously allocated block
in __ptr_t, making the new block SIZE bytes long. */
extern __ptr_t realloc __P ((__ptr_t __ptr, size_t __size));
/* Allocate NMEMB elements of SIZE bytes each, all initialized to 0. */
extern __ptr_t calloc __P ((size_t __nmemb, size_t __size));
/* Free a block allocated by `malloc', `realloc' or `calloc'. */
extern void free __P ((__ptr_t __ptr));
/* Allocate SIZE bytes allocated to ALIGNMENT bytes. */
extern __ptr_t memalign __P ((size_t __alignment, size_t __size));
/* Allocate SIZE bytes on a page boundary. */
extern __ptr_t valloc __P ((size_t __size));
#ifdef _MALLOC_INTERNAL
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#if defined(__GNU_LIBRARY__) || defined(STDC_HEADERS) || defined(USG)
#include <string.h>
#else
#ifndef memset
#define memset(s, zero, n) bzero ((s), (n))
#endif
#ifndef memcpy
#define memcpy(d, s, n) bcopy ((s), (d), (n))
#endif
#ifndef memmove
#define memmove(d, s, n) bcopy ((s), (d), (n))
#endif
#endif
#if defined(__GNU_LIBRARY__) || defined(__STDC__)
#include <limits.h>
#else
#define CHAR_BIT 8
#endif
/* The allocator divides the heap into blocks of fixed size; large
requests receive one or more whole blocks, and small requests
receive a fragment of a block. Fragment sizes are powers of two,
and all fragments of a block are the same size. When all the
fragments in a block have been freed, the block itself is freed. */
#define INT_BIT (CHAR_BIT * sizeof(int))
#define BLOCKLOG (INT_BIT > 16 ? 12 : 9)
#define BLOCKSIZE (1 << BLOCKLOG)
#define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE)
/* Determine the amount of memory spanned by the initial heap table
(not an absolute limit). */
#define HEAP (INT_BIT > 16 ? 4194304 : 65536)
/* Number of contiguous free blocks allowed to build up at the end of
memory before they will be returned to the system. */
#define FINAL_FREE_BLOCKS 8
/* Data structure giving per-block information. */
typedef union
{
/* Heap information for a busy block. */
struct
{
/* Zero for a large block, or positive giving the
logarithm to the base two of the fragment size. */
int type;
union
{
struct
{
size_t nfree; /* Free fragments in a fragmented block. */
size_t first; /* First free fragment of the block. */
} frag;
/* Size (in blocks) of a large cluster. */
size_t size;
} info;
} busy;
/* Heap information for a free block
(that may be the first of a free cluster). */
struct
{
size_t size; /* Size (in blocks) of a free cluster. */
size_t next; /* Index of next free cluster. */
size_t prev; /* Index of previous free cluster. */
} free;
} malloc_info;
/* Pointer to first block of the heap. */
extern char *_heapbase;
/* Table indexed by block number giving per-block information. */
extern malloc_info *_heapinfo;
/* Address to block number and vice versa. */
#define BLOCK(A) (((char *) (A) - _heapbase) / BLOCKSIZE + 1)
#define ADDRESS(B) ((__ptr_t) (((B) - 1) * BLOCKSIZE + _heapbase))
/* Current search index for the heap table. */
extern size_t _heapindex;
/* Limit of valid info table indices. */
extern size_t _heaplimit;
/* Doubly linked lists of free fragments. */
struct list
{
struct list *next;
struct list *prev;
};
/* Count of blocks for each fragment size. */
extern int _fragblocks[];
/* Free list headers for each fragment size. */
extern struct list _fraghead[];
/* List of blocks allocated with `memalign' (or `valloc'). */
struct alignlist
{
struct alignlist *next;
__ptr_t aligned; /* The address that memaligned returned. */
__ptr_t exact; /* The address that malloc returned. */
};
extern struct alignlist *_aligned_blocks;
/* Instrumentation. */
extern size_t _chunks_used;
extern size_t _bytes_used;
extern size_t _chunks_free;
extern size_t _bytes_free;
/* Internal version of `free' used in `morecore' (malloc.c). */
extern void _free_internal __P ((__ptr_t __ptr));
#endif /* _MALLOC_INTERNAL. */
/* Underlying allocation function; successive calls should
return contiguous pieces of memory. */
extern __ptr_t (*__morecore) __P ((ptrdiff_t __size));
/* Default value of `__morecore'. */
extern __ptr_t __default_morecore __P ((ptrdiff_t __size));
/* If not NULL, this function is called after each time
`__morecore' is called to increase the data size. */
extern void (*__after_morecore_hook) __P ((void));
/* Nonzero if `malloc' has been called and done its initialization. */
extern int __malloc_initialized;
/* Hooks for debugging versions. */
extern void (*__free_hook) __P ((__ptr_t __ptr));
extern __ptr_t (*__malloc_hook) __P ((size_t __size));
extern __ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, size_t __size));
/* Activate a standard collection of debugging hooks. */
extern int mcheck __P ((void (*__bfunc) __P ((char *)),
void (*__afunc) __P ((void))));
/* Activate a standard collection of tracing hooks. */
extern void mtrace __P ((void));
/* Statistics available to the user. */
struct mstats
{
size_t bytes_total; /* Total size of the heap. */
size_t chunks_used; /* Chunks allocated by the user. */
size_t bytes_used; /* Byte total of user-allocated chunks. */
size_t chunks_free; /* Chunks in the free list. */
size_t bytes_free; /* Byte total of chunks in the free list. */
};
/* Pick up the current statistics. */
extern struct mstats mstats __P ((void));
/* Call WARNFUN with a warning message when memory usage is high. */
extern void memory_warnings __P ((__ptr_t __start,
void (*__warnfun) __P ((__const char *))));
/* Relocating allocator. */
/* Allocate SIZE bytes, and store the address in *HANDLEPTR. */
extern __ptr_t r_alloc __P ((__ptr_t *__handleptr, size_t __size));
/* Free the storage allocated in HANDLEPTR. */
extern void r_alloc_free __P ((__ptr_t *__handleptr));
/* Adjust the block at HANDLEPTR to be SIZE bytes long. */
extern __ptr_t r_re_alloc __P ((__ptr_t *__handleptr, size_t __size));
#ifdef __cplusplus
}
#endif
#endif /* malloc.h */

View file

@ -1,133 +0,0 @@
/* Standard debugging hooks for `malloc'.
Copyright 1990, 1991, 1992, 1993 Free Software Foundation
Written May 1989 by Mike Haertel.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#include <malloc.h>
#endif
/* Old hook values. */
static void (*old_free_hook) __P ((__ptr_t ptr));
static __ptr_t (*old_malloc_hook) __P ((size_t size));
static __ptr_t (*old_realloc_hook) __P ((__ptr_t ptr, size_t size));
/* Function to call when something awful happens. */
static void (*abortfunc) __P ((void));
/* Arbitrary magical numbers. */
#define MAGICWORD 0xfedabeeb
#define MAGICBYTE ((char) 0xd7)
struct hdr
{
size_t size; /* Exact size requested by user. */
unsigned long int magic; /* Magic number to check header integrity. */
};
static void checkhdr __P ((const struct hdr *));
static void
checkhdr (hdr)
const struct hdr *hdr;
{
if (hdr->magic != MAGICWORD || ((char *) &hdr[1])[hdr->size] != MAGICBYTE)
(*abortfunc) ();
}
static void freehook __P ((__ptr_t));
static void
freehook (ptr)
__ptr_t ptr;
{
struct hdr *hdr = ((struct hdr *) ptr) - 1;
checkhdr (hdr);
hdr->magic = 0;
__free_hook = old_free_hook;
free (hdr);
__free_hook = freehook;
}
static __ptr_t mallochook __P ((size_t));
static __ptr_t
mallochook (size)
size_t size;
{
struct hdr *hdr;
__malloc_hook = old_malloc_hook;
hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1);
__malloc_hook = mallochook;
if (hdr == NULL)
return NULL;
hdr->size = size;
hdr->magic = MAGICWORD;
((char *) &hdr[1])[size] = MAGICBYTE;
return (__ptr_t) (hdr + 1);
}
static __ptr_t reallochook __P ((__ptr_t, size_t));
static __ptr_t
reallochook (ptr, size)
__ptr_t ptr;
size_t size;
{
struct hdr *hdr = ((struct hdr *) ptr) - 1;
checkhdr (hdr);
__free_hook = old_free_hook;
__malloc_hook = old_malloc_hook;
__realloc_hook = old_realloc_hook;
hdr = (struct hdr *) realloc ((__ptr_t) hdr, sizeof (struct hdr) + size + 1);
__free_hook = freehook;
__malloc_hook = mallochook;
__realloc_hook = reallochook;
if (hdr == NULL)
return NULL;
hdr->size = size;
((char *) &hdr[1])[size] = MAGICBYTE;
return (__ptr_t) (hdr + 1);
}
int
mcheck (func)
void (*func) __P ((void));
{
extern void abort __P ((void));
static int mcheck_used = 0;
abortfunc = (func != NULL) ? func : abort;
/* These hooks may not be safely inserted if malloc is already in use. */
if (!__malloc_initialized && !mcheck_used)
{
old_free_hook = __free_hook;
__free_hook = freehook;
old_malloc_hook = __malloc_hook;
__malloc_hook = mallochook;
old_realloc_hook = __realloc_hook;
__realloc_hook = reallochook;
mcheck_used = 1;
}
return mcheck_used ? 0 : -1;
}

View file

@ -1,61 +0,0 @@
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#include <malloc.h>
#endif
__ptr_t
memalign (alignment, size)
size_t alignment;
size_t size;
{
__ptr_t result;
unsigned long int adj;
size = ((size + alignment - 1) / alignment) * alignment;
result = malloc (size);
if (result == NULL)
return NULL;
adj = (unsigned long int) ((unsigned long int) ((char *) result -
(char *) NULL)) % alignment;
if (adj != 0)
{
struct alignlist *l;
for (l = _aligned_blocks; l != NULL; l = l->next)
if (l->aligned == NULL)
/* This slot is free. Use it. */
break;
if (l == NULL)
{
l = (struct alignlist *) malloc (sizeof (struct alignlist));
if (l == NULL)
{
free (result);
return NULL;
}
}
l->exact = result;
result = l->aligned = (char *) result + alignment - adj;
l->next = _aligned_blocks;
_aligned_blocks = l;
}
return result;
}

View file

@ -1,44 +0,0 @@
/* Copyright (C) 1991, 1992 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C 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 C 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.
You should have received a copy of the GNU General Public License
along with the GNU C Library; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#include <malloc.h>
#endif
#ifndef __GNU_LIBRARY__
#define __sbrk sbrk
#endif
extern __ptr_t __sbrk __P ((int increment));
#ifndef NULL
#define NULL 0
#endif
/* Allocate INCREMENT more bytes of data space,
and return the start of data space, or NULL on errors.
If INCREMENT is negative, shrink data space. */
__ptr_t
__default_morecore (increment)
ptrdiff_t increment;
{
__ptr_t result = __sbrk ((int) increment);
if (result == (__ptr_t) -1)
return NULL;
return result;
}

View file

@ -1,39 +0,0 @@
/* Access the statistics maintained by `malloc'.
Copyright 1990, 1991, 1992 Free Software Foundation
Written May 1989 by Mike Haertel.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#include <malloc.h>
#endif
struct mstats
mstats ()
{
struct mstats result;
result.bytes_total = (char *) (*__morecore) (0) - _heapbase;
result.chunks_used = _chunks_used;
result.bytes_used = _bytes_used;
result.chunks_free = _chunks_free;
result.bytes_free = _bytes_free;
return result;
}

View file

@ -1,36 +0,0 @@
#
# Awk program to analyze mtrace.c output.
#
$1 == "+" { if (allocated[$2] != "")
print "+", $2, "Alloc", NR, "duplicate:", allocated[$2];
else
allocated[$2] = $3;
}
$1 == "-" { if (allocated[$2] != "") {
allocated[$2] = "";
if (allocated[$2] != "")
print "DELETE FAILED", $2, allocated[$2];
} else
print "-", $2, "Free", NR, "was never alloc'd";
}
$1 == "<" { if (allocated[$2] != "")
allocated[$2] = "";
else
print "-", $2, "Realloc", NR, "was never alloc'd";
}
$1 == ">" { if (allocated[$2] != "")
print "+", $2, "Realloc", NR, "duplicate:", allocated[$2];
else
allocated[$2] = $3;
}
# Ignore "= Start"
$1 == "=" { }
# Ignore failed realloc attempts for now
$1 == "!" { }
END { for (x in allocated)
if (allocated[x] != "")
print "+", x, allocated[x];
}

View file

@ -1,150 +0,0 @@
/* More debugging hooks for `malloc'.
Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
Written April 2, 1991 by John Gilmore of Cygnus Support.
Based on mcheck.c by Mike Haertel.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#include <malloc.h>
#endif
/* Don't #include <stdio.h> because <malloc.h> did it for us. */
#ifndef __GNU_LIBRARY__
extern char *getenv ();
#else
#include <stdlib.h>
#endif
static FILE *mallstream;
static char mallenv[]= "MALLOC_TRACE";
static char mallbuf[BUFSIZ]; /* Buffer for the output. */
/* Address to breakpoint on accesses to... */
__ptr_t mallwatch;
/* Old hook values. */
static void (*tr_old_free_hook) __P ((__ptr_t ptr));
static __ptr_t (*tr_old_malloc_hook) __P ((size_t size));
static __ptr_t (*tr_old_realloc_hook) __P ((__ptr_t ptr, size_t size));
/* This function is called when the block being alloc'd, realloc'd, or
freed has an address matching the variable "mallwatch". In a debugger,
set "mallwatch" to the address of interest, then put a breakpoint on
tr_break. */
void tr_break __P ((void));
void
tr_break ()
{
}
static void tr_freehook __P ((__ptr_t));
static void
tr_freehook (ptr)
__ptr_t ptr;
{
fprintf (mallstream, "- %p\n", ptr); /* Be sure to print it first. */
if (ptr == mallwatch)
tr_break ();
__free_hook = tr_old_free_hook;
free (ptr);
__free_hook = tr_freehook;
}
static __ptr_t tr_mallochook __P ((size_t));
static __ptr_t
tr_mallochook (size)
size_t size;
{
__ptr_t hdr;
__malloc_hook = tr_old_malloc_hook;
hdr = (__ptr_t) malloc (size);
__malloc_hook = tr_mallochook;
/* We could be printing a NULL here; that's OK. */
fprintf (mallstream, "+ %p %x\n", hdr, size);
if (hdr == mallwatch)
tr_break ();
return hdr;
}
static __ptr_t tr_reallochook __P ((__ptr_t, size_t));
static __ptr_t
tr_reallochook (ptr, size)
__ptr_t ptr;
size_t size;
{
__ptr_t hdr;
if (ptr == mallwatch)
tr_break ();
__free_hook = tr_old_free_hook;
__malloc_hook = tr_old_malloc_hook;
__realloc_hook = tr_old_realloc_hook;
hdr = (__ptr_t) realloc (ptr, size);
__free_hook = tr_freehook;
__malloc_hook = tr_mallochook;
__realloc_hook = tr_reallochook;
if (hdr == NULL)
/* Failed realloc. */
fprintf (mallstream, "! %p %x\n", ptr, size);
else
fprintf (mallstream, "< %p\n> %p %x\n", ptr, hdr, size);
if (hdr == mallwatch)
tr_break ();
return hdr;
}
/* We enable tracing if either the environment variable MALLOC_TRACE
is set, or if the variable mallwatch has been patched to an address
that the debugging user wants us to stop on. When patching mallwatch,
don't forget to set a breakpoint on tr_break! */
void
mtrace ()
{
char *mallfile;
mallfile = getenv (mallenv);
if (mallfile != NULL || mallwatch != NULL)
{
mallstream = fopen (mallfile != NULL ? mallfile : "/dev/null", "w");
if (mallstream != NULL)
{
/* Be sure it doesn't malloc its buffer! */
setbuf (mallstream, mallbuf);
fprintf (mallstream, "= Start\n");
tr_old_free_hook = __free_hook;
__free_hook = tr_freehook;
tr_old_malloc_hook = __malloc_hook;
__malloc_hook = tr_mallochook;
tr_old_realloc_hook = __realloc_hook;
__realloc_hook = tr_reallochook;
}
}
}

View file

@ -1,146 +0,0 @@
/* Change the size of a block allocated by `malloc'.
Copyright 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
Written May 1989 by Mike Haertel.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#include <malloc.h>
#endif
#define min(A, B) ((A) < (B) ? (A) : (B))
/* Debugging hook for realloc. */
__ptr_t (*__realloc_hook) __P ((__ptr_t __ptr, size_t __size));
/* Resize the given region to the new size, returning a pointer
to the (possibly moved) region. This is optimized for speed;
some benchmarks seem to indicate that greater compactness is
achieved by unconditionally allocating and copying to a
new region. This module has incestuous knowledge of the
internals of both free and malloc. */
__ptr_t
realloc (ptr, size)
__ptr_t ptr;
size_t size;
{
__ptr_t result;
int type;
size_t block, blocks, oldlimit;
if (size == 0)
{
free (ptr);
return malloc (0);
}
else if (ptr == NULL)
return malloc (size);
if (__realloc_hook != NULL)
return (*__realloc_hook) (ptr, size);
block = BLOCK (ptr);
type = _heapinfo[block].busy.type;
switch (type)
{
case 0:
/* Maybe reallocate a large block to a small fragment. */
if (size <= BLOCKSIZE / 2)
{
result = malloc (size);
if (result != NULL)
{
memcpy (result, ptr, size);
free (ptr);
return result;
}
}
/* The new size is a large allocation as well;
see if we can hold it in place. */
blocks = BLOCKIFY (size);
if (blocks < _heapinfo[block].busy.info.size)
{
/* The new size is smaller; return
excess memory to the free list. */
_heapinfo[block + blocks].busy.type = 0;
_heapinfo[block + blocks].busy.info.size
= _heapinfo[block].busy.info.size - blocks;
_heapinfo[block].busy.info.size = blocks;
free (ADDRESS (block + blocks));
result = ptr;
}
else if (blocks == _heapinfo[block].busy.info.size)
/* No size change necessary. */
result = ptr;
else
{
/* Won't fit, so allocate a new region that will.
Free the old region first in case there is sufficient
adjacent free space to grow without moving. */
blocks = _heapinfo[block].busy.info.size;
/* Prevent free from actually returning memory to the system. */
oldlimit = _heaplimit;
_heaplimit = 0;
free (ptr);
_heaplimit = oldlimit;
result = malloc (size);
if (result == NULL)
{
/* Now we're really in trouble. We have to unfree
the thing we just freed. Unfortunately it might
have been coalesced with its neighbors. */
if (_heapindex == block)
(void) malloc (blocks * BLOCKSIZE);
else
{
__ptr_t previous = malloc ((block - _heapindex) * BLOCKSIZE);
(void) malloc (blocks * BLOCKSIZE);
free (previous);
}
return NULL;
}
if (ptr != result)
memmove (result, ptr, blocks * BLOCKSIZE);
}
break;
default:
/* Old size is a fragment; type is logarithm
to base two of the fragment size. */
if (size > (size_t) (1 << (type - 1)) && size <= (size_t) (1 << type))
/* The new size is the same kind of fragment. */
result = ptr;
else
{
/* The new size is different; allocate a new space,
and copy the lesser of the new size and the old. */
result = malloc (size);
if (result == NULL)
return NULL;
memcpy (result, ptr, min (size, (size_t) 1 << type));
free (ptr);
}
break;
}
return result;
}

View file

@ -1,48 +0,0 @@
/* Allocate memory on a page boundary.
Copyright (C) 1991, 1992, 1993 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB. If
not, write to the Free Software Foundation, Inc., 675 Mass Ave,
Cambridge, MA 02139, USA.
The author may be reached (Email) at the address mike@ai.mit.edu,
or (US mail) as Mike Haertel c/o Free Software Foundation. */
#ifndef _MALLOC_INTERNAL
#define _MALLOC_INTERNAL
#include <malloc.h>
#endif
#if defined (emacs) || defined (HAVE_CONFIG_H)
#include "config.h"
#endif
#ifdef __GNU_LIBRARY__
extern size_t __getpagesize __P ((void));
#else
#include "getpagesize.h"
#define __getpagesize() getpagesize()
#endif
static size_t pagesize;
__ptr_t
valloc (size)
size_t size;
{
if (pagesize == 0)
pagesize = __getpagesize ();
return memalign (pagesize, size);
}

View file

@ -1,63 +0,0 @@
;; alloca386.s 1.2
;; GNU-compatible stack allocation function for Xenix/386.
;; Written by Chip Salzenberg at ComDev.
;; Last modified 90/01/11
;;> Is your alloca clearly better than the one in i386-alloca.s? I haven't
;;> looked at either.
;;
;;They're different because Xenix/386 has a different assembler. SCO
;;Xenix has the Microsoft C compiler and the Microsoft macro assembler,
;;called "masm". MASM's assembler syntax is quite different from AT&T's
;;in all sorts of ways. Xenix people can't use the AT&T version.
;;--
;;Chip Salzenberg at ComDev/TCT <chip@tct.uucp>, <uunet!ateng!tct!chip>
TITLE $alloca386
.386
DGROUP GROUP CONST, _BSS, _DATA
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_TEXT SEGMENT DWORD USE32 PUBLIC 'CODE'
ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP, ES: DGROUP
PUBLIC _alloca
_alloca PROC NEAR
; Get argument.
pop edx ; edx -> return address
pop eax ; eax = amount to allocate
; Validate allocation amount.
add eax,3
and eax,not 3
cmp eax,0
jg aa_size_ok
mov eax,4
aa_size_ok:
; Allocate stack space.
mov ecx,esp ; ecx -> old stack pointer
sub esp,eax ; perform allocation
mov eax,esp ; eax -> new stack pointer
; Copy the three saved register variables from old stack top to new stack top.
; They may not be there. So we waste twelve bytes. Big fat hairy deal.
push DWORD PTR 8[ecx]
push DWORD PTR 4[ecx]
push DWORD PTR 0[ecx]
; Push something so the caller can pop it off.
push eax
; Return to caller.
jmp edx
_alloca ENDP
_TEXT ENDS
END

View file

@ -1,69 +0,0 @@
/* xmalloc.c -- safe versions of malloc and realloc */
/* Copyright (C) 1991 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h>
static void memory_error_and_abort ();
/* **************************************************************** */
/* */
/* Memory Allocation and Deallocation. */
/* */
/* **************************************************************** */
/* Return a pointer to free()able block of memory large enough
to hold BYTES number of bytes. If the memory cannot be allocated,
print an error message and abort. */
char *
xmalloc (bytes)
int bytes;
{
char *temp = (char *)malloc (bytes);
if (!temp)
memory_error_and_abort ("xmalloc");
return (temp);
}
char *
xrealloc (pointer, bytes)
char *pointer;
int bytes;
{
char *temp;
if (!pointer)
temp = (char *)malloc (bytes);
else
temp = (char *)realloc (pointer, bytes);
if (!temp)
memory_error_and_abort ("xrealloc");
return (temp);
}
static void
memory_error_and_abort (fname)
char *fname;
{
fprintf (stderr, "%s: Out of virtual memory!\n", fname);
abort ();
}

View file

@ -33,4 +33,13 @@
#define SET_CLOSE_ON_EXEC(fd) (fcntl ((fd), F_SETFD, FD_CLOEXEC))
#define SET_OPEN_ON_EXEC(fd) (fcntl ((fd), F_SETFD, FD_NCLOEXEC))
/* How to open a file in non-blocking mode, the Posix.1 way. */
#if !defined (O_NONBLOCK)
# if defined (O_NDELAY)
# define O_NONBLOCK O_NDELAY
# else
# define O_NONBLOCK 0
# endif
#endif
#endif /* ! _FILECNTL_H_ */

View file

@ -19,8 +19,8 @@
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (__MEMALLOC_H__)
# define __MEMALLOC_H__
#if !defined (_MEMALLOC_H_)
# define _MEMALLOC_H_
#if defined (sparc) && defined (sun) && !defined (HAVE_ALLOCA_H)
# define HAVE_ALLOCA_H
@ -34,8 +34,6 @@
# define HAVE_ALLOCA
#endif /* HAVE_ALLOCA_H && !HAVE_ALLOCA */
#if !defined (BUILDING_MAKEFILE)
#if defined (__GNUC__)
# undef alloca
# define alloca __builtin_alloca
@ -46,11 +44,15 @@
# else /* !IBMESA */
# include <alloca.h>
# endif /* !IBMESA */
# else
# else /* !HAVE_ALLOCA_H */
# if defined (hpux_9) && defined (__STDC__) && !defined (alloca)
extern void *alloca ();
# else
# if !defined (alloca)
extern char *alloca ();
# endif /* !alloca */
# endif /* !hpux_9 || !__STDC__ && !alloca */
# endif /* !HAVE_ALLOCA_H */
#endif /* !__GNUC__ */
#endif /* !BUILDING_MAKEFILE */
#endif /* __MEMALLOC_H__ */
#endif /* _MEMALLOC_H_ */

View file

@ -0,0 +1,49 @@
/* posixdir.h -- Posix directory reading includes and defines. */
/* Copyright (C) 1987,1991 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This file should be included instead of <dirent.h> or <sys/dir.h>. */
#if !defined (_POSIXDIR_H_)
#define _POSIXDIR_H_
#if defined (HAVE_DIRENT_H)
# include <dirent.h>
# define D_NAMLEN(d) (strlen ((d)->d_name))
#else
# if defined (HAVE_SYS_NDIR_H)
# include <sys/ndir.h>
# endif
# if defined (HAVE_SYS_DIR_H)
# include <sys/dir.h>
# endif
# if defined (HAVE_NDIR_H)
# include <ndir.h>
# endif
# if !defined (dirent)
# define dirent direct
# endif /* !dirent */
# define D_NAMLEN(d) ((d)->d_namlen)
#endif /* !HAVE_DIRENT_H */
#if defined (STRUCT_DIRENT_HAS_D_INO)
# define d_fileno d_ino
#endif
#endif /* !_POSIXDIR_H_ */

View file

@ -21,34 +21,27 @@
/* This file should be included instead of <sys/stat.h>.
It relies on the local sys/stat.h to work though. */
#if !defined (_POSIXSTAT_H)
#define _POSIXSTAT_H
#if !defined (_POSIXSTAT_H_)
#define _POSIXSTAT_H_
#include <sys/stat.h>
#if defined (isc386)
# if !defined (S_IFDIR)
# define S_IFDIR 0040000
# endif /* !S_IFDIR */
# if !defined (S_IFMT)
# define S_IFMT 0170000
# endif /* !S_IFMT */
#endif /* isc386 */
/* This text is taken directly from the Cadmus I was trying to
compile on:
the following MACROs are defined for X/OPEN compatibility
however, is the param correct ??
#define S_ISBLK(s) ((s.st_mode & S_IFMT) == S_IFBLK)
Well, the answer is no. Thus... */
#if defined (BrainDeath)
#if defined (STAT_MACROS_BROKEN)
# undef S_ISBLK
# undef S_ISCHR
# undef S_ISDIR
# undef S_ISFIFO
# undef S_ISREG
#endif /* BrainDeath */
# undef S_ISLNK
#endif /* STAT_MACROS_BROKEN */
/* These are guaranteed to work only on isc386 */
#if !defined (S_IFDIR) && !defined (S_ISDIR)
# define S_IFDIR 0040000
#endif /* !S_IFDIR && !S_ISDIR */
#if !defined (S_IFMT)
# define S_IFMT 0170000
#endif /* !S_IFMT */
/* Posix 1003.1 5.6.1.1 <sys/stat.h> file types */
@ -114,7 +107,7 @@
/*
* POSIX 1003.1 5.6.1.2 <sys/stat.h> File Modes
*/
#if !defined (S_IRWXU)
# if !defined (S_IREAD)
# define S_IREAD 00400
@ -146,4 +139,4 @@
#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH)
#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
#endif /* _POSIXSTAT_H */
#endif /* _POSIXSTAT_H_ */

View file

@ -19,14 +19,15 @@
along with Bash; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (__STDC_H__)
#define __STDC_H__
#if !defined (_STDC_H_)
#define _STDC_H_
/* Adapted from BSD /usr/include/sys/cdefs.h. */
/* A function can be defined using prototypes and compile on both ANSI C
and traditional C compilers with something like this:
extern char *func __P((char *, char *, int)); */
#if defined (__STDC__)
# if !defined (__P)
@ -75,4 +76,4 @@
#endif /* !__STDC__ */
#endif /* !__STDC_H__ */
#endif /* !_STDC_H_ */

View file

@ -1,46 +1,40 @@
GNU GENERAL PUBLIC LICENSE
Version 1, February 1989
Version 2, June 1991
Copyright (C) 1989 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
The Free Software Foundation has exempted Bash from the requirement of
Paragraph 2c of the General Public License. This is to say, there is
no requirement for Bash to print a notice when it is started
interactively in the usual way. We made this exception because users
and standards expect shells not to print such messages. This
exception applies to any program that serves as a shell and that is
based primarily on Bash as opposed to other GNU software.
Preamble
The license agreements of most software companies try to keep users
at the mercy of those companies. By contrast, our General Public
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. The
General Public License applies to the Free Software Foundation's
software and to any other program whose authors commit to using it.
You can use it for your programs, too.
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Specifically, the General Public License is designed to make
sure that you have the freedom to give away or sell copies of free
software, that you receive source code or can get it if you want it,
that you can change the software or use pieces of it in new free
programs; and that you know you can do these things.
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of a such a program, whether
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must tell them their rights.
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
@ -53,122 +47,209 @@ want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any program or other work which
contains a notice placed by the copyright holder saying it may be
distributed under the terms of this General Public License. The
"Program", below, refers to any such program or work, and a "work based
on the Program" means either the Program or any work containing the
Program or a portion of it, either verbatim or with modifications. Each
licensee is addressed as "you".
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
1. You may copy and distribute verbatim copies of the Program's source
code as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice and
disclaimer of warranty; keep intact all the notices that refer to this
General Public License and to the absence of any warranty; and give any
other recipients of the Program a copy of this General Public License
along with the Program. You may charge a fee for the physical act of
transferring a copy.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
2. You may modify your copy or copies of the Program or any portion of
it, and copy and distribute such modifications under the terms of Paragraph
1 above, provided that you also do the following:
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
a) cause the modified files to carry prominent notices stating that
you changed the files and the date of any change; and
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
b) cause the whole of any work that you distribute or publish, that
in whole or in part contains the Program or any part thereof, either
with or without modifications, to be licensed at no charge to all
third parties under the terms of this General Public License (except
that you may choose to grant warranty protection to some or all
third parties, at your option).
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
c) If the modified program normally reads commands interactively when
run, you must cause it, when started running for such interactive use
in the simplest and most usual way, to print or display an
announcement including an appropriate copyright notice and a notice
that there is no warranty (or else, saying that you provide a
warranty) and that users may redistribute the program under these
conditions, and telling the user how to view a copy of this General
Public License.
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
d) You may charge a fee for the physical act of transferring a
copy, and you may at your option offer warranty protection in
exchange for a fee.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
Mere aggregation of another independent work with the Program (or its
derivative) on a volume of a storage or distribution medium does not bring
the other work under the scope of these terms.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
3. You may copy and distribute the Program (or a portion or derivative of
it, under Paragraph 2) in object code or executable form under the terms of
Paragraphs 1 and 2 above provided that you also do one of the following:
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
a) accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of
Paragraphs 1 and 2 above; or,
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
b) accompany it with a written offer, valid for at least three
years, to give any third party free (except for a nominal charge
for the cost of distribution) a complete machine-readable copy of the
corresponding source code, to be distributed under the terms of
Paragraphs 1 and 2 above; or,
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
c) accompany it with the information you received as to where the
corresponding source code may be obtained. (This alternative is
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form alone.)
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
Source code for a work means the preferred form of the work for making
modifications to it. For an executable file, complete source code means
all the source code for all modules it contains; but, as a special
exception, it need not include source code for modules which are standard
libraries that accompany the operating system on which the executable
file runs, or for standard header files or definitions files that
accompany that operating system.
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
4. You may not copy, modify, sublicense, distribute or transfer the
Program except as expressly provided under this General Public License.
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
the Program is void, and will automatically terminate your rights to use
the Program under this License. However, parties who have received
copies, or rights to use copies, from you under this General Public
License will not have their licenses terminated so long as such parties
remain in full compliance.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. By copying, distributing or modifying the Program (or any work based
on the Program) you indicate your acceptance of this license to do so,
and all its terms and conditions.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the original
licensor to copy, distribute or modify the Program subject to these
terms and conditions. You may not impose any further restrictions on the
recipients' exercise of the rights granted herein.
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
7. The Free Software Foundation may publish revised and/or new versions
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of the license which applies to it and "any
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
the license, you may choose any version ever published by the Free Software
this License, you may choose any version ever published by the Free Software
Foundation.
8. If you wish to incorporate parts of the Program into other free
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
@ -176,7 +257,7 @@ of promoting the sharing and reuse of software generally.
NO WARRANTY
9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
@ -186,7 +267,7 @@ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
@ -201,22 +282,21 @@ POSSIBILITY OF SUCH DAMAGES.
Appendix: How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to humanity, the best way to achieve this is to make it
free software which everyone can redistribute and change under these
terms.
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest to
attach them to the start of each source file to most effectively convey
the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
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
@ -232,26 +312,28 @@ Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19xx name of author
Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the
appropriate parts of the General Public License. Of course, the
commands you use may be called something other than `show w' and `show
c'; they could even be mouse-clicks or menu items--whatever suits your
program.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here a sample; alter the names:
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
program `Gnomovision' (a program to direct compilers to make passes
at assemblers) written by James Hacker.
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
That's all there is to it!
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View file

@ -1,134 +0,0 @@
## -*- text -*- ####################################################
# #
# Makefile for the GNU Readline and History Libraries. #
# #
####################################################################
srcdir = .
VPATH = .:$(srcdir)
INSTALL = install -c
INSTALL_PROGRAM = ${INSTALL}
INSTALL_DATA = ${INSTALL} -m 644
RANLIB = ranlib
AR = ar
RM = rm
CP = cp
MV = mv
# See the file STANDALONE for the -D defines that readline understands
DEFS =
# For libraries which include headers from other libraries.
LOCAL_INCLUDES = -I. -I..
CPPFLAGS = $(DEFS) $(LOCAL_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 $(CPPFLAGS) $(CFLAGS) $<
# 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)history.c $(srcdir)tilde.c \
$(srcdir)xmalloc.c
# The header files for this library.
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h \
posixstat.h tilde.h rlconf.h
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 \
history.o tilde.o xmalloc.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)
##########################################################################
all: libreadline.a libhistory.a
libreadline.a: $(OBJECTS)
$(RM) -f $@
$(AR) cq $@ $(OBJECTS)
-[ -n "$(RANLIB)" ] && $(RANLIB) $@
libhistory.a: history.o
$(RM) -f $@
$(AR) cq $@ history.o
-[ -n "$(RANLIB)" ] && $(RANLIB) $@
documentation: force
[ ! -d doc ] && mkdir doc
(if [ -d doc ]; then cd doc; $(MAKE) $(MFLAGS); fi)
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: installdirs libreadline.a
${INSTALL_DATA} readline.h keymaps.h chardefs.h history.h \
$(incdir)/readline
-${MV} $(libdir)/libreadline.a $(libdir)/libreadline.old
${INSTALL_DATA} libreadline.a $(bindir)/libreadline.a
-[ -n "$(RANLIB)" ] && $(RANLIB) -t $(bindir)/libreadline.a
installdirs:
[ ! -d $(incdir)/readline ] && { \
mkdir $(incdir)/readline && chmod chmod 755 $(incdir)/readline; }
uninstall:
cd $(incdir)/readline && ${RM} -f ${INSTALLED_HEADERS}
cd $(libdir) && ${RM} -f libreadline.a libreadline.old
tags: force
etags $(CSOURCES) $(HSOURCES)
TAGS: force
ctags -x $(CSOURCES) $(HSOURCES) > $@
readline: readline.h rldefs.h chardefs.h
readline: $(OBJECTS)
$(CC) $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
$(LOCAL_INCLUDES) -DTEST -o readline readline.c vi_mode.o funmap.o \
keymaps.o -ltermcap
clean:
$(RM) -f $(OBJECTS) libreadline.a libhistory.a
(if [ -d doc ]; then cd doc; $(MAKE) $(MFLAGS) $@; fi)
maintainer-clean realclean distclean mostlyclean: clean
(if [ -d doc ]; then cd doc; $(MAKE) $(MFLAGS) $@; fi)
# Dependencies
readline.o: readline.c readline.h rldefs.h rlconf.h chardefs.h
readline.o: keymaps.h history.h
vi_mode.o: rldefs.h rlconf.h readline.h history.h
funmap.o: funmap.c readline.h rlconf.h
keymaps.o: keymaps.c emacs_keymap.c vi_keymap.c keymaps.h chardefs.h rlconf.h
history.o: history.h memalloc.h
isearch.o: memalloc.h readline.h history.h
search.o: memalloc.h readline.h history.h
display.o: readline.h history.h rldefs.h rlconf.h
complete.o: readline.h rldefs.h rlconf.h
rltty.o: rldefs.h rlconf.h readline.h
bind.o: rldefs.h rlconf.h readline.h history.h
signals.o: rldefs.h rlconf.h readline.h history.h
parens.o: readline.h

192
lib/readline/Makefile.in Normal file
View file

@ -0,0 +1,192 @@
## -*- text -*- ####################################################
# #
# Makefile for the GNU Readline and History Libraries. #
# #
####################################################################
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@
RM = rm -f
CP = cp
MV = mv
# See the file STANDALONE for the -D defines that readline understands
CFLAGS = @CFLAGS@
LOCAL_CFLAGS = @LOCAL_CFLAGS@
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LDFLAGS@
DEFS = @DEFS@
INCLUDES = -I. -I$(BUILD_DIR) -I$(topdir) -I$(topdir)/lib
CCFLAGS = $(DEFS) $(APP_CFLAGS) $(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 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)/tilde.c \
# The header files for this library.
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \
posixstat.h tilde.h rlconf.h tcap.h
HISTOBJ = history.o histexpand.o histfile.o histsearch.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 \
nls.o xmalloc.o \
$(HISTOBJ) $(TILDEOBJ)
# 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
##########################################################################
all: libreadline.a libhistory.a
libreadline.a: $(OBJECTS)
$(RM) -f $@
$(AR) cr $@ $(OBJECTS)
-test -n "$(RANLIB)" && $(RANLIB) $@
libhistory.a: $(HISTOBJ) xmalloc.o
$(RM) -f $@
$(AR) cr $@ $(HISTOBJ) xmalloc.o
-test -n "$(RANLIB)" && $(RANLIB) $@
documentation: force
test -d doc || mkdir doc
-( 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: installdirs libreadline.a
for file in $(INSTALLED_HEADERS) ; do \
$(INSTALL_DATA) $(srcdir)/$$file $(includedir)/readline ; \
done
-${MV} $(libdir)/libreadline.a $(libdir)/libreadline.old
${INSTALL_DATA} libreadline.a $(libdir)/libreadline.a
-test -n "$(RANLIB)" && $(RANLIB) -t $(bindir)/libreadline.a
installdirs: $(topdir)/support/mkdirs
$(SHELL) $(topdir)/support/mkdirs $(includedir) \
$(includedir)/readline $(libdir) $(infodir) $(man3dir)
uninstall:
cd $(includedir)/readline && ${RM} -f ${INSTALLED_HEADERS}
cd $(libdir) && ${RM} -f libreadline.a libreadline.old
tags: force
etags $(CSOURCES) $(HSOURCES)
TAGS: force
ctags -x $(CSOURCES) $(HSOURCES) > $@
readline: readline.h rldefs.h chardefs.h
readline: $(OBJECTS)
$(CC) $(CFLAGS) $(CPPFLAGS) $(READLINE_DEFINES) \
$(LOCAL_INCLUDES) -DTEST -o readline readline.c vi_mode.o funmap.o \
keymaps.o -ltermcap
clean: force
$(RM) $(OBJECTS) *.a
-( cd doc && $(MAKE) $(MFLAGS) $@ )
distclean realclean maintainer-clean: clean
-( cd doc && $(MAKE) $(MFLAGS) $@ )
$(RM) Makefile
mostlyclean: clean
-( cd doc && $(MAKE) $(MFLAGS) $@ )
# Dependencies
readline.o: readline.c readline.h rldefs.h rlconf.h chardefs.h tcap.h
readline.o: keymaps.h history.h
vi_mode.o: rldefs.h rlconf.h readline.h history.h
funmap.o: funmap.c readline.h rlconf.h
keymaps.o: keymaps.c emacs_keymap.c vi_keymap.c keymaps.h chardefs.h rlconf.h
history.o: history.h histlib.h
histexpand.o: history.h histlib.h
histsearch.o: history.h histlib.h
histfile.o: history.h histlib.h
isearch.o: readline.h history.h
search.o: readline.h history.h
display.o: readline.h history.h rldefs.h rlconf.h tcap.h
complete.o: readline.h rldefs.h rlconf.h posixdir.h posixstat.h
rltty.o: rldefs.h rlconf.h readline.h rltty.h
bind.o: rldefs.h rlconf.h readline.h history.h
signals.o: rldefs.h rlconf.h readline.h history.h
parens.o: readline.h
kill.o: rldefs.h rlconf.h readline.h history.h
macro.o: rldefs.h rlconf.h readline.h history.h
undo.o: rldefs.h rlconf.h readline.h history.h
input.o: rldefs.h rlconf.h readline.h history.h
callback.o: rlconf.h rldefs.h readline.h
terminal.o: rlconf.h rldefs.h readline.h tcap.h history.h
bind.o: $(BUILD_DIR)/config.h
callback.o: $(BUILD_DIR)/config.h
complete.o: $(BUILD_DIR)/config.h
display.o: $(BUILD_DIR)/config.h
funmap.o: $(BUILD_DIR)/config.h
histexpand.o: $(BUILD_DIR)/config.h
histfile.o: $(BUILD_DIR)/config.h
history.o: $(BUILD_DIR)/config.h
histsearch.o: $(BUILD_DIR)/config.h
input.o: $(BUILD_DIR)/config.h
isearch.o: $(BUILD_DIR)/config.h
keymaps.o: $(BUILD_DIR)/config.h
kill.o: $(BUILD_DIR)/config.h
macro.o: $(BUILD_DIR)/config.h
parens.o: $(BUILD_DIR)/config.h
readline.o: $(BUILD_DIR)/config.h
rltty.o: $(BUILD_DIR)/config.h
search.o: $(BUILD_DIR)/config.h
signals.o: $(BUILD_DIR)/config.h
tilde.o: $(BUILD_DIR)/config.h
undo.o: $(BUILD_DIR)/config.h
util.o: $(BUILD_DIR)/config.h
vi_mode.o: $(BUILD_DIR)/config.h
xmalloc.o: $(BUILD_DIR)/config.h

View file

@ -15,6 +15,7 @@ HAVE_DIRENT_H <dirent.h> exists and is usable
HAVE_SYS_PTEM_H <sys/ptem.h> exists
HAVE_SYS_PTE_H <sys/pte.h> exists
HAVE_SYS_STREAM_H <sys/stream.h> exists
HAVE_SYS_SELECT_H <sys/select.h> exists
System-specific options:

File diff suppressed because it is too large Load diff

144
lib/readline/callback.c Normal file
View file

@ -0,0 +1,144 @@
/* 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include "rlconf.h"
#if defined (READLINE_CALLBACKS)
#include <sys/types.h>
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "readline.h"
extern void readline_internal_startup ();
extern char *readline_internal_teardown ();
extern int readline_internal_char ();
extern int _rl_meta_flag;
extern char *rl_prompt;
extern int rl_visible_prompt_length;
/* **************************************************************** */
/* */
/* 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 readline_char() every time some input is available, and
readline_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. */
VFunction *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)
char *prompt;
VFunction *linefunc;
{
rl_prompt = prompt;
rl_visible_prompt_length = rl_prompt ? rl_expand_prompt (rl_prompt) : 0;
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 ();
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);
/* Redisplay the prompt if readline_handler_{install,remove} not called. */
if (in_handler == 0 && rl_linefunc)
_rl_callback_newline ();
}
}
/* 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

View file

@ -20,16 +20,20 @@
have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _CHARDEFS_H
#define _CHARDEFS_H
#ifndef _CHARDEFS_H_
#define _CHARDEFS_H_
#include <ctype.h>
#if defined (HAVE_STRING_H)
# include <string.h>
#if defined (HAVE_CONFIG_H)
# if defined (HAVE_STRING_H)
# include <string.h>
# else
# include <strings.h>
# endif /* HAVE_STRING_H */
#else
# include <strings.h>
#endif /* HAVE_STRING_H */
# include <string.h>
#endif /* !HAVE_CONFIG_H */
#ifndef whitespace
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
@ -47,39 +51,40 @@
#define meta_character_bit 0x080 /* x0000000, must be on. */
#define largest_char 255 /* Largest character value. */
#define CTRL_CHAR(c) ((c) < control_character_threshold)
#define CTRL_CHAR(c) ((c) < control_character_threshold && (c) >= 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) to_upper(((c)|control_character_bit))
#define UNCTRL(c) _rl_to_upper(((c)|control_character_bit))
/* Old versions
#define lowercase_p(c) (((c) > ('a' - 1) && (c) < ('z' + 1)))
#define uppercase_p(c) (((c) > ('A' - 1) && (c) < ('Z' + 1)))
#define digit_p(c) ((c) >= '0' && (c) <= '9')
#define _rl_lowercase_p(c) (((c) > ('a' - 1) && (c) < ('z' + 1)))
#define _rl_uppercase_p(c) (((c) > ('A' - 1) && (c) < ('Z' + 1)))
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
*/
#define lowercase_p(c) (islower(c))
#define uppercase_p(c) (isupper(c))
#define digit_p(x) (isdigit (x))
#define _rl_lowercase_p(c) (islower(c))
#define _rl_uppercase_p(c) (isupper(c))
#define _rl_digit_p(x) (isdigit (x))
#define pure_alphabetic(c) (lowercase_p(c) || uppercase_p(c))
#define _rl_pure_alphabetic(c) (_rl_lowercase_p(c) || _rl_uppercase_p(c))
#define ALPHABETIC(c) (_rl_lowercase_p(c) || _rl_uppercase_p(c) || _rl_digit_p(c))
/* Old versions
# define to_upper(c) (lowercase_p(c) ? ((c) - 32) : (c))
# define to_lower(c) (uppercase_p(c) ? ((c) + 32) : (c))
# define _rl_to_upper(c) (_rl_lowercase_p(c) ? ((c) - 32) : (c))
# define _rl_to_lower(c) (_rl_uppercase_p(c) ? ((c) + 32) : (c))
*/
#ifndef to_upper
# define to_upper(c) (islower(c) ? toupper(c) : (c))
# define to_lower(c) (isupper(c) ? tolower(c) : (c))
#ifndef _rl_to_upper
# define _rl_to_upper(c) (islower(c) ? toupper(c) : (c))
# define _rl_to_lower(c) (isupper(c) ? tolower(c) : (c))
#endif
#ifndef digit_value
#define digit_value(x) ((x) - '0')
#ifndef _rl_digit_value
#define _rl_digit_value(x) ((x) - '0')
#endif
#ifndef NEWLINE
@ -119,4 +124,4 @@
#define ESC CTRL('[')
#endif /* _CHARDEFS_H */
#endif /* _CHARDEFS_H_ */

File diff suppressed because it is too large Load diff

View file

@ -22,7 +22,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include "config.h"
# include <config.h>
#endif
#include <stdio.h>
@ -43,6 +43,9 @@
/* System-specific feature definitions and include files. */
#include "rldefs.h"
/* Termcap library stuff. */
#include "tcap.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
@ -55,20 +58,22 @@ extern char *strchr (), *strrchr ();
imported from readline.c. */
extern char *rl_prompt;
extern int readline_echoing_p;
extern char *term_clreol, *term_im, *term_ic, *term_ei, *term_DC;
/* Termcap variables. */
extern char *term_up, *term_dc, *term_cr, *term_IC;
extern int screenheight, screenwidth, screenchars;
extern int terminal_can_insert, term_xn;
extern void _rl_output_some_chars ();
extern int _rl_output_character_function ();
extern int _rl_output_meta_chars;
extern int _rl_horizontal_scroll_mode;
extern int _rl_mark_modified_lines;
extern int _rl_prefer_visible_bell;
/* Variables and functions imported from terminal.c */
extern void _rl_output_some_chars ();
extern int _rl_output_character_function ();
extern int _rl_backspace ();
extern char *term_clreol, *term_im, *term_ic, *term_ei, *term_DC;
extern char *term_up, *term_dc, *term_cr, *term_IC;
extern int screenheight, screenwidth, screenchars;
extern int terminal_can_insert, _rl_term_autowrap;
/* Pseudo-global functions (local to the readline library) exported
by this file. */
void _rl_move_cursor_relative (), _rl_output_some_chars ();
@ -76,6 +81,9 @@ void _rl_move_vert ();
static void update_line (), clear_to_eol (), space_to_eol ();
static void delete_chars (), insert_some_chars ();
static void cr ();
static int *inv_lbreaks, *vis_lbreaks;
extern char *xmalloc (), *xrealloc ();
@ -110,10 +118,15 @@ extern char *xmalloc (), *xrealloc ();
this function know that the display has been fixed by setting the
RL_DISPLAY_FIXED variable. This is good for efficiency. */
/* Application-specific redisplay function. */
VFunction *rl_redisplay_function = rl_redisplay;
/* Global variables declared here. */
/* What YOU turn on when you have handled all redisplay yourself. */
int rl_display_fixed = 0;
int _rl_suppress_redisplay = 0;
/* The stuff that gets printed out before the actual text of the line.
This is usually pointing to rl_prompt. */
char *rl_display_prompt = (char *)NULL;
@ -129,7 +142,7 @@ int _rl_vis_botlin = 0;
/* Variables used only in this file. */
/* The last left edge of text that was displayed. This is used when
doing horizontal scrolling. It shifts in thirds of a screenwidth. */
static int last_lmargin = 0;
static int last_lmargin;
/* The line display buffers. One is the line currently displayed on
the screen. The other is the line about to be displayed. */
@ -140,26 +153,32 @@ static char *invisible_line = (char *)NULL;
static char msg_buf[128];
/* Non-zero forces the redisplay even if we thought it was unnecessary. */
static int forced_display = 0;
static int forced_display;
/* Default and initial buffer size. Can grow. */
static int line_size = 1024;
static char *last_prompt_string = (char *)NULL;
static char *local_prompt, *local_prompt_prefix;
static int visible_length, prefix_length;
/* The number of invisible characters in the line currently being
displayed on the screen. */
static int visible_wrap_offset = 0;
static int visible_wrap_offset;
/* static so it can be shared between rl_redisplay and update_line */
static int wrap_offset;
/* The index of the last invisible_character in the prompt string. */
static int last_invisible;
/* The length (buffer offset) of the first line of the last (possibly
multi-line) buffer displayed on the screen. */
static int visible_first_line_len = 0;
static int visible_first_line_len;
/* Expand the prompt string S and return the number of visible
characters in *LP, if LP is not null. This is currently more-or-less
a placeholder for expansion. */
a placeholder for expansion. LIP, if non-null is a place to store the
index of the last invisible character in ther eturned string. */
/* Current implementation:
\001 (^A) start non-visible characters
@ -169,12 +188,12 @@ static int visible_first_line_len = 0;
\002 are assumed to be `visible'. */
static char *
expand_prompt (pmt, lp)
expand_prompt (pmt, lp, lip)
char *pmt;
int *lp;
int *lp, *lip;
{
char *r, *ret, *p;
int l, rl, ignoring;
int l, rl, last, ignoring;
/* Short-circuit if we can. */
if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
@ -185,10 +204,10 @@ expand_prompt (pmt, lp)
return r;
}
l = pmt ? strlen (pmt) : 0;
l = strlen (pmt);
r = ret = xmalloc (l + 1);
for (rl = ignoring = 0, p = pmt; p && *p; p++)
for (rl = ignoring = last = 0, p = pmt; p && *p; p++)
{
/* This code strips the invisible character string markers
RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
@ -200,6 +219,7 @@ expand_prompt (pmt, lp)
else if (ignoring && *p == RL_PROMPT_END_IGNORE)
{
ignoring = 0;
last = r - ret - 1;
continue;
}
else
@ -213,6 +233,8 @@ expand_prompt (pmt, lp)
*r = '\0';
if (lp)
*lp = rl;
if (lip)
*lip = last;
return ret;
}
@ -246,15 +268,16 @@ rl_expand_prompt (prompt)
if (local_prompt_prefix)
free (local_prompt_prefix);
local_prompt = local_prompt_prefix = (char *)0;
last_invisible = 0;
if (prompt == 0 || *prompt == '\0')
if (prompt == 0 || *prompt == 0)
return (0);
p = strrchr (prompt, '\n');
if (!p)
{
/* The prompt is only one line. */
local_prompt = expand_prompt (prompt, &visible_length);
local_prompt = expand_prompt (prompt, &visible_length, &last_invisible);
local_prompt_prefix = (char *)0;
return (visible_length);
}
@ -262,11 +285,11 @@ rl_expand_prompt (prompt)
{
/* The prompt spans multiple lines. */
t = ++p;
local_prompt = expand_prompt (p, &visible_length);
local_prompt = expand_prompt (p, &visible_length, &last_invisible);
c = *t; *t = '\0';
/* The portion of the prompt string up to and including the
final newline is now null-terminated. */
local_prompt_prefix = expand_prompt (prompt, &prefix_length);
local_prompt_prefix = expand_prompt (prompt, &prefix_length, (int *)NULL);
*t = c;
return (prefix_length);
}
@ -276,9 +299,10 @@ rl_expand_prompt (prompt)
void
rl_redisplay ()
{
register int in, out, c, linenum;
register char *line = invisible_line;
int c_pos = 0, inv_botlin = 0, wrap_offset, wrap_column;
register int in, out, c, linenum, cursor_linenum;
register char *line;
int c_pos, inv_botlin, lb_botlin, lb_linenum;
int newlines, lpos;
char *prompt_this_line;
if (!readline_echoing_p)
@ -287,25 +311,32 @@ rl_redisplay ()
if (!rl_display_prompt)
rl_display_prompt = "";
if (!invisible_line)
if (invisible_line == 0)
{
visible_line = xmalloc (line_size);
invisible_line = xmalloc (line_size);
line = invisible_line;
for (in = 0; in < line_size; in++)
{
visible_line[in] = 0;
invisible_line[in] = 1;
}
/* should be enough, but then again, this is just for testing. */
inv_lbreaks = (int *)malloc (256 * sizeof (int));
vis_lbreaks = (int *)malloc (256 * sizeof (int));
inv_lbreaks[0] = vis_lbreaks[0] = 0;
rl_on_new_line ();
}
/* Draw the line into the buffer. */
c_pos = -1;
line = invisible_line;
out = inv_botlin = 0;
/* Mark the line as modified or not. We only do this for history
lines. */
out = 0;
if (_rl_mark_modified_lines && current_history () && rl_undo_list)
{
line[out++] = '*';
@ -322,15 +353,17 @@ rl_redisplay ()
one passed to readline()), use the values we have already expanded.
If not, use what's already in rl_display_prompt. WRAP_OFFSET is the
number of non-visible characters in the prompt string. */
if (rl_display_prompt == rl_prompt)
if (rl_display_prompt == rl_prompt || local_prompt)
{
int local_len = local_prompt ? strlen (local_prompt) : 0;
if (local_prompt_prefix && forced_display)
_rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix));
if (local_len > 0)
strncpy (line + out, local_prompt, local_len);
out += local_len;
{
strncpy (line + out, local_prompt, local_len);
out += local_len;
}
line[out] = '\0';
wrap_offset = local_len - visible_length;
}
@ -344,7 +377,13 @@ rl_redisplay ()
{
prompt_this_line++;
if (forced_display)
_rl_output_some_chars (rl_display_prompt, prompt_this_line - rl_display_prompt);
{
_rl_output_some_chars (rl_display_prompt, prompt_this_line - rl_display_prompt);
/* Make sure we are at column zero even after a newline,
regardless of the state of terminal output processing. */
if (prompt_this_line[-2] != '\r')
cr ();
}
}
pmtlen = strlen (prompt_this_line);
@ -354,7 +393,20 @@ rl_redisplay ()
wrap_offset = 0;
}
for (in = 0; in < rl_end; in++)
#define CHECK_LPOS() \
do { \
lpos++; \
if (lpos >= screenwidth) \
{ \
inv_lbreaks[++newlines] = out; \
lpos = 0; \
} \
} while (0)
/* inv_lbreaks[i] is where line i starts in the buffer. */
inv_lbreaks[newlines = 0] = 0;
for (in = 0, lpos = out - wrap_offset; in < rl_end; in++)
{
c = (unsigned char)rl_line_buffer[in];
@ -367,42 +419,88 @@ rl_redisplay ()
}
if (in == rl_point)
c_pos = out;
{
c_pos = out;
lb_linenum = newlines;
}
if (META_CHAR (c))
{
if (_rl_output_meta_chars == 0)
{
sprintf (line + out, "\\%o", c);
if (lpos + 4 >= screenwidth)
{
register int temp;
temp = screenwidth - lpos;
inv_lbreaks[++newlines] = out + temp;
lpos = 4 - temp;
}
else
lpos += 4;
out += 4;
}
else
line[out++] = c;
{
line[out++] = c;
CHECK_LPOS();
}
}
#if defined (DISPLAY_TABS)
else if (c == '\t')
{
register int newout = (out | (int)7) + 1;
while (out < newout)
line[out++] = ' ';
register int temp, newout;
newout = (out | (int)7) + 1;
temp = newout - out;
if (lpos + temp >= screenwidth)
{
register int temp2;
temp2 = screenwidth - lpos;
inv_lbreaks[++newlines] = out + temp2;
lpos = temp - temp2;
while (out < newout)
line[out++] = ' ';
}
else
{
while (out < newout)
line[out++] = ' ';
lpos += temp;
}
}
#endif
else if (c < ' ')
else if (c == '\n' && _rl_horizontal_scroll_mode == 0 && term_up && *term_up)
{
line[out++] = '\0'; /* XXX - sentinel */
inv_lbreaks[++newlines] = out;
lpos = 0;
}
else if (CTRL_CHAR (c) || c == RUBOUT)
{
line[out++] = '^';
line[out++] = UNCTRL (c); /* XXX was c ^ 0x40 */
}
else if (c == 127)
{
line[out++] = '^';
line[out++] = '?';
CHECK_LPOS();
line[out++] = CTRL_CHAR (c) ? UNCTRL (c) : '?';
CHECK_LPOS();
}
else
line[out++] = c;
{
line[out++] = c;
CHECK_LPOS();
}
}
line[out] = '\0';
if (c_pos < 0)
c_pos = out;
{
c_pos = out;
lb_linenum = newlines;
}
inv_botlin = lb_botlin = newlines;
inv_lbreaks[newlines+1] = out;
cursor_linenum = lb_linenum;
/* C_POS == position in buffer where cursor should be placed. */
@ -415,10 +513,9 @@ rl_redisplay ()
otherwise, let long lines display in a single terminal line, and
horizontally scroll it. */
if (!_rl_horizontal_scroll_mode && term_up && *term_up)
if (_rl_horizontal_scroll_mode == 0 && term_up && *term_up)
{
int total_screen_chars = screenchars;
int nleft, cursor_linenum, pos, changed_screen_line;
int nleft, pos, changed_screen_line;
if (!rl_display_fixed || forced_display)
{
@ -426,42 +523,35 @@ rl_redisplay ()
/* If we have more than a screenful of material to display, then
only display a screenful. We should display the last screen,
not the first. I'll fix this in a minute. */
if (out >= total_screen_chars)
out = total_screen_chars - 1;
/* Number of screen lines to display. The first line wraps at
(screenwidth + wrap_offset) chars, the rest of the lines have
screenwidth chars. */
nleft = out - wrap_offset + term_xn - 1;
inv_botlin = (nleft > 0) ? nleft / screenwidth : 0;
not the first. */
if (out >= screenchars)
out = screenchars - 1;
/* The first line is at character position 0 in the buffer. The
second and subsequent lines start at N * screenwidth, offset by
OFFSET. OFFSET is wrap_offset for the invisible line and
visible_wrap_offset for the line currently displayed. */
second and subsequent lines start at inv_lbreaks[N], offset by
OFFSET (which has already been calculated above). */
#define W_OFFSET(line, offset) ((line) == 0 ? offset : 0)
#define L_OFFSET(n, offset) ((n) > 0 ? ((n) * screenwidth) + (offset) : 0)
#define VIS_CHARS(line) &visible_line[L_OFFSET((line), visible_wrap_offset)]
#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
#define INV_LINE(line) &invisible_line[L_OFFSET((line), wrap_offset)]
#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
/* For each line in the buffer, do the updating display. */
for (linenum = 0; linenum <= inv_botlin; linenum++)
{
update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum,
screenwidth + W_OFFSET(linenum, visible_wrap_offset),
screenwidth + W_OFFSET(linenum, wrap_offset),
inv_botlin);
VIS_LLEN(linenum), INV_LLEN(linenum), inv_botlin);
/* If this is the line with the prompt, we might need to
compensate for invisible characters in the new line. Do
this only if there is not more than one new line (which
implies that we completely overwrite the old visible line)
and the new line is shorter than the old. */
and the new line is shorter than the old. Make sure we are
at the end of the new line before clearing. */
if (linenum == 0 &&
inv_botlin == 0 &&
inv_botlin == 0 && _rl_last_c_pos == out &&
(wrap_offset > visible_wrap_offset) &&
(_rl_last_c_pos < visible_first_line_len))
{
@ -472,7 +562,7 @@ rl_redisplay ()
/* Since the new first line is now visible, save its length. */
if (linenum == 0)
visible_first_line_len = (inv_botlin > 0) ? screenwidth : out - wrap_offset;
visible_first_line_len = (inv_botlin > 0) ? inv_lbreaks[1] : out - wrap_offset;
}
/* We may have deleted some lines. If so, clear the left over
@ -491,11 +581,6 @@ rl_redisplay ()
}
_rl_vis_botlin = inv_botlin;
/* Move the cursor where it should be. */
/* Which line? */
nleft = c_pos - wrap_offset + term_xn - 1;
cursor_linenum = (nleft > 0) ? nleft / screenwidth : 0;
/* CHANGED_SCREEN_LINE is set to 1 if we have moved to a
different screen line during this redisplay. */
changed_screen_line = _rl_last_v_pos != cursor_linenum;
@ -512,10 +597,12 @@ rl_redisplay ()
/* We have to reprint the prompt if it contains invisible
characters, since it's not generally OK to just reprint
the characters from the current cursor position. */
the characters from the current cursor position. But we
only need to reprint it if the cursor is before the last
invisible character in the prompt string. */
nleft = visible_length + wrap_offset;
if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 &&
_rl_last_c_pos <= nleft && local_prompt)
_rl_last_c_pos <= last_invisible && local_prompt)
{
if (term_cr)
tputs (term_cr, 1, _rl_output_character_function);
@ -525,17 +612,17 @@ rl_redisplay ()
/* Where on that line? And where does that line start
in the buffer? */
pos = L_OFFSET(cursor_linenum, wrap_offset);
pos = inv_lbreaks[cursor_linenum];
/* nleft == number of characters in the line buffer between the
start of the line and the cursor position. */
nleft = c_pos - pos;
/* Since backspace() doesn't know about invisible characters in the
/* Since _rl_backspace() doesn't know about invisible characters in the
prompt, and there's no good way to tell it, we compensate for
those characters here and call backspace() directly. */
those characters here and call _rl_backspace() directly. */
if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos)
{
backspace (_rl_last_c_pos - nleft);
_rl_backspace (_rl_last_c_pos - nleft);
_rl_last_c_pos = nleft;
}
@ -638,8 +725,11 @@ rl_redisplay ()
/* Swap visible and non-visible lines. */
{
char *temp = visible_line;
int *itemp = vis_lbreaks;
visible_line = invisible_line;
invisible_line = temp;
vis_lbreaks = inv_lbreaks;
inv_lbreaks = itemp;
rl_display_fixed = 0;
/* If we are displaying on a single line, and last_lmargin is > 0, we
are not displaying any invisible characters, so set visible_wrap_offset
@ -670,10 +760,11 @@ new: eddie> Oh, my little buggy says to me, as lurgid as
static void
update_line (old, new, current_line, omax, nmax, inv_botlin)
register char *old, *new;
int current_line, omax, nmax;
int current_line, omax, nmax, inv_botlin;
{
register char *ofd, *ols, *oe, *nfd, *nls, *ne;
int temp, lendiff, wsatend, od, nd;
int current_invis_chars;
/* If we're at the right edge of a terminal that supports xn, we're
ready to wrap around, so do so. This fixes problems with knowing
@ -681,7 +772,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
emulators. In this calculation, TEMP is the physical screen
position of the cursor. */
temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
if (temp == screenwidth && term_xn && !_rl_horizontal_scroll_mode
if (temp == screenwidth && _rl_term_autowrap && !_rl_horizontal_scroll_mode
&& _rl_last_v_pos == current_line - 1)
{
if (new[0])
@ -734,33 +825,53 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
nls++;
}
_rl_move_vert (current_line);
/* count of invisible characters in the current invisible line. */
current_invis_chars = W_OFFSET (current_line, wrap_offset);
if (_rl_last_v_pos != current_line)
{
_rl_move_vert (current_line);
if (current_line == 0 && visible_wrap_offset)
_rl_last_c_pos += visible_wrap_offset;
}
/* If this is the first line and there are invisible characters in the
prompt string, and the prompt string has not changed, then redraw
the entire prompt string. We can only do this reliably if the
terminal supports a `cr' capability.
prompt string, and the prompt string has not changed, and the current
cursor position is before the last invisible character in the prompt,
and the index of the character to move to is past the end of the prompt
string, then redraw the entire prompt string. We can only do this
reliably if the terminal supports a `cr' capability.
This is more than just an efficiency hack -- there is a problem with
redrawing portions of the prompt string if they contain terminal
escape sequences (like drawing the `unbold' sequence without a
corresponding `bold') that manifests itself on certain terminals. */
This is not an efficiency hack -- there is a problem with redrawing
portions of the prompt string if they contain terminal escape
sequences (like drawing the `unbold' sequence without a corresponding
`bold') that manifests itself on certain terminals. */
lendiff = local_prompt ? strlen (local_prompt) : 0;
od = ofd - old; /* index of first difference in visible line */
if (current_line == 0 && !_rl_horizontal_scroll_mode &&
lendiff > visible_length &&
_rl_last_c_pos > 0 && (ofd - old) >= lendiff && term_cr)
term_cr && lendiff > visible_length && _rl_last_c_pos > 0 &&
od > lendiff && _rl_last_c_pos < last_invisible)
{
tputs (term_cr, 1, _rl_output_character_function);
_rl_output_some_chars (local_prompt, lendiff);
_rl_last_c_pos = lendiff;
}
_rl_move_cursor_relative (ofd - old, old);
_rl_move_cursor_relative (od, old);
/* if (len (new) > len (old)) */
lendiff = (nls - nfd) - (ols - ofd);
/* If we are changing the number of invisible characters in a line, and
the spot of first difference is before the end of the invisible chars,
lendiff needs to be adjusted. */
if (current_line == 0 && !_rl_horizontal_scroll_mode &&
current_invis_chars != visible_wrap_offset)
{
temp = visible_wrap_offset - current_invis_chars;
lendiff += temp;
}
/* Insert (diff (len (old), len (new)) ch. */
temp = ne - nfd;
if (lendiff > 0)
@ -771,25 +882,36 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
use the terminal's capabilities. If we're growing the number
of lines, make sure we actually cause the new line to wrap
around on auto-wrapping terminals. */
if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!term_xn || !gl))
if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!_rl_term_autowrap || !gl))
{
/* If lendiff > visible_length and _rl_last_c_pos == 0 and
_rl_horizontal_scroll_mode == 1, inserting the characters with
term_IC or term_ic will screw up the screen because of the
invisible characters. We need to just draw them. */
if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 ||
lendiff <= visible_length))
lendiff <= visible_length || !current_invis_chars))
{
insert_some_chars (nfd, lendiff);
_rl_last_c_pos += lendiff;
}
else
else if (*ols == 0)
{
/* At the end of a line the characters do not have to
be "inserted". They can just be placed on the screen. */
/* However, this screws up the rest of this block, which
assumes you've done the insert because you can. */
_rl_output_some_chars (nfd, lendiff);
_rl_last_c_pos += lendiff;
}
else
{
/* We have horizontal scrolling and we are not inserting at
the end. We have invisible characters in this line. This
is a dumb update. */
_rl_output_some_chars (nfd, temp);
_rl_last_c_pos += temp;
return;
}
/* Copy (new) chars to screen from first diff to last match. */
temp = nls - nfd;
if ((temp - lendiff) > 0)
@ -837,7 +959,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
_rl_last_c_pos += temp;
}
lendiff = (oe - old) - (ne - new);
if (term_xn && current_line < inv_botlin)
if (_rl_term_autowrap && current_line < inv_botlin)
space_to_eol (lendiff);
else
clear_to_eol (lendiff);
@ -846,6 +968,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
}
/* Tell the update routines that we have moved onto a new (empty) line. */
int
rl_on_new_line ()
{
if (visible_line)
@ -853,21 +976,26 @@ rl_on_new_line ()
_rl_last_c_pos = _rl_last_v_pos = 0;
_rl_vis_botlin = last_lmargin = 0;
if (vis_lbreaks)
vis_lbreaks[0] = vis_lbreaks[1] = 0;
visible_wrap_offset = 0;
return 0;
}
/* Actually update the display, period. */
int
rl_forced_update_display ()
{
if (visible_line)
{
register char *temp = visible_line;
while (*temp) *temp++ = '\0';
while (*temp)
*temp++ = '\0';
}
rl_on_new_line ();
forced_display++;
rl_redisplay ();
(*rl_redisplay_function) ();
return 0;
}
@ -888,7 +1016,8 @@ _rl_move_cursor_relative (new, data)
of moving backwards. */
/* i == current physical cursor position. */
i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset);
if (CR_FASTER (new, _rl_last_c_pos) || (term_xn && i == screenwidth))
if (new == 0 || CR_FASTER (new, _rl_last_c_pos) ||
(_rl_term_autowrap && i == screenwidth))
{
#if defined (__MSDOS__)
putc ('\r', rl_outstream);
@ -924,7 +1053,7 @@ _rl_move_cursor_relative (new, data)
#endif /* HACK_TERMCAP_MOTION */
}
else if (_rl_last_c_pos != new)
backspace (_rl_last_c_pos - new);
_rl_backspace (_rl_last_c_pos - new);
_rl_last_c_pos = new;
}
@ -966,6 +1095,7 @@ _rl_move_vert (to)
/* Physically print C on rl_outstream. This is for functions which know
how to optimize the display. Return the number of characters output. */
int
rl_show_char (c)
int c;
{
@ -978,14 +1108,14 @@ rl_show_char (c)
}
#if defined (DISPLAY_TABS)
if (c < 32 && c != '\t')
if ((CTRL_CHAR (c) && c != '\t') || c == RUBOUT)
#else
if (c < 32)
if (CTRL_CHAR (c) || c == RUBOUT)
#endif /* !DISPLAY_TABS */
{
fprintf (rl_outstream, "C-");
n += 2;
c += 64;
c = CTRL_CHAR (c) ? UNCTRL (c) : '?';
}
putc (c, rl_outstream);
@ -1013,47 +1143,65 @@ rl_character_len (c, pos)
#endif /* !DISPLAY_TABS */
}
if (CTRL_CHAR (c) || c == RUBOUT)
return (2);
return ((isprint (uc)) ? 1 : 2);
}
/* How to print things in the "echo-area". The prompt is treated as a
mini-modeline. */
#if defined (HAVE_VARARGS_H)
#if defined (USE_VARARGS)
int
#if defined (PREFER_STDARG)
rl_message (const char *format, ...)
#else
rl_message (va_alist)
va_dcl
#endif
{
char *format;
va_list args;
#if defined (PREFER_VARARGS)
char *format;
#endif
#if defined (PREFER_STDARG)
va_start (args, format);
#else
va_start (args);
format = va_arg (args, char *);
#endif
vsprintf (msg_buf, format, args);
va_end (args);
rl_display_prompt = msg_buf;
rl_redisplay ();
(*rl_redisplay_function) ();
return 0;
}
#else /* !HAVE_VARARGS_H */
#else /* !USE_VARARGS */
int
rl_message (format, arg1, arg2)
char *format;
{
sprintf (msg_buf, format, arg1, arg2);
rl_display_prompt = msg_buf;
rl_redisplay ();
(*rl_redisplay_function) ();
return 0;
}
#endif /* !HAVE_VARARGS_H */
#endif /* !USE_VARARGS */
/* How to clear things from the "echo-area". */
int
rl_clear_message ()
{
rl_display_prompt = rl_prompt;
rl_redisplay ();
(*rl_redisplay_function) ();
return 0;
}
int
rl_reset_line_state ()
{
rl_on_new_line ();
@ -1063,6 +1211,70 @@ rl_reset_line_state ()
return 0;
}
static char *saved_local_prompt;
static char *saved_local_prefix;
static int saved_last_invisible;
static int saved_visible_length;
void
_rl_save_prompt ()
{
saved_local_prompt = local_prompt;
saved_local_prefix = local_prompt_prefix;
saved_last_invisible = last_invisible;
saved_visible_length = visible_length;
local_prompt = local_prompt_prefix = (char *)0;
last_invisible = visible_length = 0;
}
void
_rl_restore_prompt ()
{
if (local_prompt)
free (local_prompt);
if (local_prompt_prefix)
free (local_prompt_prefix);
local_prompt = saved_local_prompt;
local_prompt_prefix = saved_local_prefix;
last_invisible = saved_last_invisible;
visible_length = saved_visible_length;
}
char *
_rl_make_prompt_for_search (pchar)
int pchar;
{
int len;
char *pmt;
_rl_save_prompt ();
if (saved_local_prompt == 0)
{
len = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
pmt = xmalloc (len + 2);
if (len)
strcpy (pmt, rl_prompt);
pmt[len] = pchar;
pmt[len+1] = '\0';
}
else
{
len = *saved_local_prompt ? strlen (saved_local_prompt) : 0;
pmt = xmalloc (len + 2);
if (len)
strcpy (pmt, saved_local_prompt);
pmt[len] = pchar;
pmt[len+1] = '\0';
local_prompt = savestring (pmt);
last_invisible = saved_last_invisible;
visible_length = saved_visible_length + 1;
}
return pmt;
}
/* Quick redisplay hack when erasing characters at the end of the line. */
void
_rl_erase_at_end_of_line (l)
@ -1070,10 +1282,10 @@ _rl_erase_at_end_of_line (l)
{
register int i;
backspace (l);
_rl_backspace (l);
for (i = 0; i < l; i++)
putc (' ', rl_outstream);
backspace (l);
_rl_backspace (l);
for (i = 0; i < l; i++)
visible_line[--_rl_last_c_pos] = '\0';
rl_display_fixed++;
@ -1132,7 +1344,7 @@ insert_some_chars (string, count)
/* If IC is defined, then we do not have to "enter" insert mode. */
if (term_IC)
{
char *tgoto (), *buffer;
char *buffer;
buffer = tgoto (term_IC, 0, count);
tputs (buffer, 1, _rl_output_character_function);
_rl_output_some_chars (string, count);
@ -1186,7 +1398,7 @@ delete_chars (count)
if (term_DC && *term_DC)
{
char *tgoto (), *buffer;
char *buffer;
buffer = tgoto (term_DC, count, count);
tputs (buffer, count, _rl_output_character_function);
}
@ -1205,17 +1417,20 @@ _rl_update_final ()
int full_lines;
full_lines = 0;
if (_rl_vis_botlin && visible_line[screenwidth * _rl_vis_botlin] == 0)
/* If the cursor is the only thing on an otherwise-blank last line,
compensate so we don't print an extra CRLF. */
if (_rl_vis_botlin && _rl_last_c_pos == 0 &&
visible_line[inv_lbreaks[_rl_vis_botlin]+1] == 0)
{
_rl_vis_botlin--;
full_lines = 1;
}
_rl_move_vert (_rl_vis_botlin);
if (full_lines && term_xn)
/* If we've wrapped lines, remove the final xterm line-wrap flag. */
if (full_lines && _rl_term_autowrap && (VIS_LLEN(_rl_vis_botlin) == screenwidth))
{
/* Remove final line-wrap flag in xterm. */
char *last_line;
last_line = &visible_line[screenwidth * _rl_vis_botlin];
last_line = &visible_line[inv_lbreaks[_rl_vis_botlin]];
_rl_move_cursor_relative (screenwidth - 1, last_line);
clear_to_eol (0);
putc (last_line[screenwidth - 1], rl_outstream);
@ -1274,3 +1489,15 @@ _rl_redisplay_after_sigwinch ()
else
rl_forced_update_display ();
}
void
_rl_clean_up_for_exit ()
{
if (readline_echoing_p)
{
_rl_move_vert (_rl_vis_botlin);
_rl_vis_botlin = 0;
fflush (rl_outstream);
rl_restart_output ();
}
}

View file

@ -1,10 +1,11 @@
# This makefile for History library documentation is in -*- text -*- mode.
# This makefile for Readline library documentation is in -*- text -*- mode.
# Emacs likes it that way.
TEXI2DVI = texi2dvi
DOC_SUPPORT = ../../doc-support/
TEXINDEX = $(DOC_SUPPORT)/texindex
RM = rm -f
TEX = tex
INSTALL_DATA = cp
infodir = /usr/local/info
RLSRC = rlman.texinfo rluser.texinfo rltech.texinfo
HISTSRC = hist.texinfo hsuser.texinfo hstech.texinfo
@ -12,26 +13,23 @@ HISTSRC = hist.texinfo hsuser.texinfo hstech.texinfo
DVIOBJ = readline.dvi history.dvi
INFOOBJ = readline.info history.info
PSOBJ = readline.ps history.ps
HTMLOBJ = readline.html history.html
all: info dvi
all: info dvi html
readline.dvi: $(RLSRC)
$(TEX) rlman.texinfo
$(TEXINDEX) rlman.??
$(TEX) rlman.texinfo
$(TEXI2DVI) rlman.texinfo
mv rlman.dvi readline.dvi
readline.info: $(RLSRC)
makeinfo rlman.texinfo
makeinfo --no-split -o $@ rlman.texinfo
history.dvi: ${HISTSRC}
$(TEX) hist.texinfo
$(TEXINDEX) hist.??
$(TEX) hist.texinfo
$(TEXI2DVI) hist.texinfo
mv hist.dvi history.dvi
history.info: ${HISTSRC}
makeinfo hist.texinfo
makeinfo --no-split -o $@ hist.texinfo
readline.ps: readline.dvi
dvips -D 300 -o $@ readline.dvi
@ -39,17 +37,33 @@ readline.ps: readline.dvi
history.ps: history.dvi
dvips -D 300 -o $@ history.dvi
readline.html: ${RLSRC}
texi2html rlman.texinfo
sed -e 's:rlman.html:readline.html:' -e 's:rlman_toc.html:readline_toc.html:' rlman.html > readline.html
sed -e 's:rlman.html:readline.html:' -e 's:rlman_toc.html:readline_toc.html:' rlman_toc.html > readline_toc.html
rm -f rlman.html rlman_toc.html
history.html: ${HISTSRC}
texi2html hist.texinfo
sed -e 's:hist.html:history.html:' -e 's:hist_toc.html:history_toc.html:' hist.html > history.html
sed -e 's:hist.html:history.html:' -e 's:hist_toc.html:history_toc.html:' hist_toc.html > history_toc.html
rm -f hist.html hist_toc.html
info: $(INFOOBJ)
dvi: $(DVIOBJ)
ps: $(PSOBJ)
html: $(HTMLOBJ)
$(TEXINDEX):
(cd $(DOC_SUPPORT); $(MAKE) $(MFLAGS) CFLAGS='$(CFLAGS)' texindex)
distclean mostlyclean clean:
rm -f *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
clean:
$(RM) *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr *.cps *.pgs \
*.fns *.kys *.tps *.vrs *.o core
maintainer-clean realclean: clean
rm -f *.dvi *.info *.info-* *.ps
distclean: clean
mostlyclean: clean
maintainer-clean: clean
$(RM) *.dvi *.info *.info-* *.ps *.html
install: info
${INSTALL_DATA} readline.info $(infodir)/readline.info
${INSTALL_DATA} history.info $(infodir)/history.info

View file

@ -7,20 +7,20 @@
@setchapternewpage odd
@ignore
last change: Wed Jul 20 09:57:17 EDT 1994
last change: Thu Mar 21 16:07:29 EST 1996
@end ignore
@set EDITION 2.0
@set VERSION 2.0
@set UPDATED 20 July 1994
@set UPDATE-MONTH July 1994
@set EDITION 2.1
@set VERSION 2.1
@set UPDATED 21 March 1996
@set UPDATE-MONTH March 1996
@ifinfo
This document describes the GNU History library, a programming tool that
provides a consistent user interface for recalling lines of previously
typed input.
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
Copyright (C) 1988, 1991, 1993, 1995, 1996 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@ -45,7 +45,6 @@ by the Foundation.
@end ifinfo
@titlepage
@sp 10
@title GNU History Library
@subtitle Edition @value{EDITION}, for @code{History Library} Version @value{VERSION}.
@subtitle @value{UPDATE-MONTH}

Binary file not shown.

View file

@ -1,744 +0,0 @@
This is Info file history.info, produced by Makeinfo-1.55 from the
input file hist.texinfo.
This document describes the GNU History library, a programming tool
that provides a consistent user interface for recalling lines of
previously typed input.
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice pare
preserved on all copies.
Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that this permission notice may be stated in a
translation approved by the Foundation.

File: history.info, Node: Top, Next: Using History Interactively, Prev: (DIR), Up: (DIR)
GNU History Library
*******************
This document describes the GNU History library, a programming tool
that provides a consistent user interface for recalling lines of
previously typed input.
* Menu:
* Using History Interactively:: GNU History User's Manual.
* Programming with GNU History:: GNU History Programmer's Manual.
* Concept Index:: Index of concepts described in this manual.
* Function and Variable Index:: Index of externally visible functions
and variables.

File: history.info, Node: Using History Interactively, Next: Programming with GNU History, Prev: Top, Up: Top
Using History Interactively
***************************
This chapter describes how to use the GNU History Library
interactively, from a user's standpoint. It should be considered a
user's guide. For information on using the GNU History Library in your
own programs, *note Programming with GNU History::..
* Menu:
* History Interaction:: What it feels like using History as a user.

File: history.info, Node: History Interaction, Up: Using History Interactively
History Interaction
===================
The History library provides a history expansion feature that is
similar to the history expansion provided by `csh'. The following text
describes the syntax used to manipulate the history information.
History expansion takes place in two parts. The first is to
determine which line from the previous history should be used during
substitution. The second is to select portions of that line for
inclusion into the current one. The line selected from the previous
history is called the "event", and the portions of that line that are
acted upon are called "words". The line is broken into words in the
same fashion that Bash does, so that several English (or Unix) words
surrounded by quotes are considered as one word.
* Menu:
* Event Designators:: How to specify which history line to use.
* Word Designators:: Specifying which words are of interest.
* Modifiers:: Modifying the results of substitution.

File: history.info, Node: Event Designators, Next: Word Designators, Up: History Interaction
Event Designators
-----------------
An event designator is a reference to a command line entry in the
history list.
`!'
Start a history substitution, except when followed by a space, tab,
the end of the line, = or (.
`!!'
Refer to the previous command. This is a synonym for `!-1'.
`!n'
Refer to command line N.
`!-n'
Refer to the command N lines back.
`!string'
Refer to the most recent command starting with STRING.
`!?string'[`?']
Refer to the most recent command containing STRING.
`!#'
The entire command line typed so far.
`^string1^string2^'
Quick Substitution. Repeat the last command, replacing STRING1
with STRING2. Equivalent to `!!:s/string1/string2/'.

File: history.info, Node: Word Designators, Next: Modifiers, Prev: Event Designators, Up: History Interaction
Word Designators
----------------
A : separates the event specification from the word designator. It
can be omitted if the word designator begins with a ^, $, * or %.
Words are numbered from the beginning of the line, with the first word
being denoted by a 0 (zero).
`0 (zero)'
The `0'th word. For many applications, this is the command word.
`n'
The Nth word.
`^'
The first argument; that is, word 1.
`$'
The last argument.
`%'
The word matched by the most recent `?string?' search.
`x-y'
A range of words; `-Y' abbreviates `0-Y'.
`*'
All of the words, except the `0'th. This is a synonym for `1-$'.
It is not an error to use * if there is just one word in the event;
the empty string is returned in that case.
`x*'
Abbreviates `x-$'
`x-'
Abbreviates `x-$' like `x*', but omits the last word.

File: history.info, Node: Modifiers, Prev: Word Designators, Up: History Interaction
Modifiers
---------
After the optional word designator, you can add a sequence of one or
more of the following modifiers, each preceded by a :.
`h'
Remove a trailing pathname component, leaving only the head.
`r'
Remove a trailing suffix of the form `.'SUFFIX, leaving the
basename.
`e'
Remove all but the trailing suffix.
`t'
Remove all leading pathname components, leaving the tail.
`p'
Print the new command but do not execute it.
`s/old/new/'
Substitute NEW for the first occurrence of OLD in the event line.
Any delimiter may be used in place of /. The delimiter may be
quoted in OLD and NEW with a single backslash. If & appears in
NEW, it is replaced by OLD. A single backslash will quote the &.
The final delimiter is optional if it is the last character on the
input line.
`&'
Repeat the previous substitution.
`g'
Cause changes to be applied over the entire event line. Used in
conjunction with `s', as in `gs/old/new/', or with `&'.

File: history.info, Node: Programming with GNU History, Next: Concept Index, Prev: Using History Interactively, Up: Top
Programming with GNU History
****************************
This chapter describes how to interface programs that you write with
the GNU History Library. It should be considered a technical guide.
For information on the interactive use of GNU History, *note Using
History Interactively::..
* Menu:
* Introduction to History:: What is the GNU History library for?
* History Storage:: How information is stored.
* History Functions:: Functions that you can use.
* History Variables:: Variables that control behaviour.
* History Programming Example:: Example of using the GNU History Library.

File: history.info, Node: Introduction to History, Next: History Storage, Up: Programming with GNU History
Introduction to History
=======================
Many programs read input from the user a line at a time. The GNU
History library is able to keep track of those lines, associate
arbitrary data with each line, and utilize information from previous
lines in composing new ones.
The programmer using the History library has available functions for
remembering lines on a history list, associating arbitrary data with a
line, removing lines from the list, searching through the list for a
line containing an arbitrary text string, and referencing any line in
the list directly. In addition, a history "expansion" function is
available which provides for a consistent user interface across
different programs.
The user using programs written with the History library has the
benefit of a consistent user interface with a set of well-known
commands for manipulating the text of previous lines and using that text
in new commands. The basic history manipulation commands are similar to
the history substitution provided by `csh'.
If the programmer desires, he can use the Readline library, which
includes some history manipulation by default, and has the added
advantage of command line editing.

File: history.info, Node: History Storage, Next: History Functions, Prev: Introduction to History, Up: Programming with GNU History
History Storage
===============
The history list is an array of history entries. A history entry is
declared as follows:
typedef struct _hist_entry {
char *line;
char *data;
} HIST_ENTRY;
The history list itself might therefore be declared as
HIST_ENTRY **the_history_list;
The state of the History library is encapsulated into a single
structure:
/* A structure used to pass the current state of the history stuff around. */
typedef struct _hist_state {
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
int offset; /* The location pointer within this array. */
int length; /* Number of elements within this array. */
int size; /* Number of slots allocated to this array. */
int flags;
} HISTORY_STATE;
If the flags member includes `HS_STIFLED', the history has been
stifled.

File: history.info, Node: History Functions, Next: History Variables, Prev: History Storage, Up: Programming with GNU History
History Functions
=================
This section describes the calling sequence for the various functions
present in GNU History.
* Menu:
* Initializing History and State Management:: Functions to call when you
want to use history in a
program.
* History List Management:: Functions used to manage the list
of history entries.
* Information About the History List:: Functions returning information about
the history list.
* Moving Around the History List:: Functions used to change the position
in the history list.
* Searching the History List:: Functions to search the history list
for entries containing a string.
* Managing the History File:: Functions that read and write a file
containing the history list.
* History Expansion:: Functions to perform csh-like history
expansion.

File: history.info, Node: Initializing History and State Management, Next: History List Management, Up: History Functions
Initializing History and State Management
-----------------------------------------
This section describes functions used to initialize and manage the
state of the History library when you want to use the history functions
in your program.
- Function: void using_history ()
Begin a session in which the history functions might be used. This
initializes the interactive variables.
- Function: HISTORY_STATE * history_get_history_state ()
Return a structure describing the current state of the input
history.
- Function: void history_set_history_state (HISTORY_STATE *state)
Set the state of the history list according to STATE.

File: history.info, Node: History List Management, Next: Information About the History List, Prev: Initializing History and State Management, Up: History Functions
History List Management
-----------------------
These functions manage individual entries on the history list, or set
parameters managing the list itself.
- Function: void add_history (char *string)
Place STRING at the end of the history list. The associated data
field (if any) is set to `NULL'.
- Function: HIST_ENTRY * remove_history (int which)
Remove history entry at offset WHICH from the history. The
removed element is returned so you can free the line, data, and
containing structure.
- Function: HIST_ENTRY * replace_history_entry (int which, char *line,
char *data)
Make the history entry at offset 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.
- Function: void stifle_history (int max)
Stifle the history list, remembering only the last MAX entries.
- Function: int unstifle_history ()
Stop stifling the history. This returns the previous amount the
history was stifled. The value is positive if the history was
stifled, negative if it wasn't.
- Function: int history_is_stifled ()
Returns non-zero if the history is stifled, zero if it is not.

File: history.info, Node: Information About the History List, Next: Moving Around the History List, Prev: History List Management, Up: History Functions
Information About the History List
----------------------------------
These functions return information about the entire history list or
individual list entries.
- Function: HIST_ENTRY ** history_list ()
Return a `NULL' terminated array of `HIST_ENTRY' which is the
current input history. Element 0 of this list is the beginning of
time. If there is no history, return `NULL'.
- Function: int where_history ()
Returns the offset of the current history element.
- Function: HIST_ENTRY * current_history ()
Return the history entry at the current position, as determined by
`where_history ()'. If there is no entry there, return a `NULL'
pointer.
- Function: HIST_ENTRY * history_get (int offset)
Return the history entry at position OFFSET, starting from
`history_base'. If there is no entry there, or if OFFSET is
greater than the history length, return a `NULL' pointer.
- Function: int history_total_bytes ()
Return the number of bytes that the primary history entries are
using. This function returns the sum of the lengths of all the
lines in the history.

File: history.info, Node: Moving Around the History List, Next: Searching the History List, Prev: Information About the History List, Up: History Functions
Moving Around the History List
------------------------------
These functions allow the current index into the history list to be
set or changed.
- Function: int history_set_pos (int pos)
Set the position in the history list to POS, an absolute index
into the list.
- Function: HIST_ENTRY * previous_history ()
Back up the current history offset to the previous history entry,
and return a pointer to that entry. If there is no previous
entry, return a `NULL' pointer.
- Function: HIST_ENTRY * next_history ()
Move the current history offset forward to the next history entry,
and return the a pointer to that entry. If there is no next
entry, return a `NULL' pointer.

File: history.info, Node: Searching the History List, Next: Managing the History File, Prev: Moving Around the History List, Up: History Functions
Searching the History List
--------------------------
These functions allow searching of the history list for entries
containing a specific string. Searching may be performed both forward
and backward from the current history position. The search may be
"anchored", meaning that the string must match at the beginning of the
history entry.
- Function: int history_search (char *string, int direction)
Search the history for STRING, starting at the current history
offset. If DIRECTION < 0, then the search is through previous
entries, else through subsequent. If STRING is found, then the
current history index is set to that history entry, and the value
returned is the offset in the line of the entry where STRING was
found. Otherwise, nothing is changed, and a -1 is returned.
- Function: int history_search_prefix (char *string, int direction)
Search the history for STRING, starting at the current history
offset. The search is anchored: matching lines must begin with
STRING. If DIRECTION < 0, then the search is through previous
entries, else through subsequent. If STRING is found, then the
current history index is set to that entry, and the return value
is 0. Otherwise, nothing is changed, and a -1 is returned.
- Function: int history_search_pos (char *string, int direction, int
pos)
Search for STRING in the history list, starting at POS, an
absolute index into the list. If DIRECTION is negative, the search
proceeds backward from POS, otherwise forward. Returns the
absolute index of the history element where STRING was found, or
-1 otherwise.

File: history.info, Node: Managing the History File, Next: History Expansion, Prev: Searching the History List, Up: History Functions
Managing the History File
-------------------------
The History library can read the history from and write it to a file.
This section documents the functions for managing a history file.
- Function: int read_history (char *filename)
Add the contents of FILENAME to the history list, a line at a
time. If FILENAME is `NULL', then read from `~/.history'.
Returns 0 if successful, or errno if not.
- Function: int read_history_range (char *filename, int from, int to)
Read a range of lines from FILENAME, adding them to the history
list. Start reading at line FROM and end at TO. If FROM is zero,
start at the beginning. If TO is less than FROM, then read until
the end of the file. If FILENAME is `NULL', then read from
`~/.history'. Returns 0 if successful, or `errno' if not.
- Function: int write_history (char *filename)
Write the current history to FILENAME, overwriting FILENAME if
necessary. If FILENAME is `NULL', then write the history list to
`~/.history'. Values returned are as in `read_history ()'.
- Function: int append_history (int nelements, char *filename)
Append the last NELEMENTS of the history list to FILENAME.
- Function: int history_truncate_file (char *filename, int nlines)
Truncate the history file FILENAME, leaving only the last NLINES
lines.

File: history.info, Node: History Expansion, Prev: Managing the History File, Up: History Functions
History Expansion
-----------------
These functions implement `csh'-like history expansion.
- Function: int history_expand (char *string, char **output)
Expand STRING, placing the result into OUTPUT, a pointer to a
string (*note History Interaction::.). Returns:
`0'
If no expansions took place (or, if the only change in the
text was the de-slashifying of the history expansion
character);
`1'
if expansions did take place;
`-1'
if there was an error in expansion;
`2'
if the returned line should only be displayed, but not
executed, as with the `:p' modifier (*note Modifiers::.).
If an error ocurred in expansion, then OUTPUT contains a
descriptive error message.
- Function: char * history_arg_extract (int first, int last, char
*string)
Extract a string segment consisting of the FIRST through LAST
arguments present in STRING. Arguments are broken up as in Bash.
- Function: char * get_history_event (char *string, int *cindex, int
qchar)
Returns the text of the history event beginning at STRING +
*CINDEX. *CINDEX is modified to point to after the event
specifier. At function entry, CINDEX points to the index into
STRING where the history event specification begins. QCHAR is a
character that is allowed to end the event specification in
addition to the "normal" terminating characters.
- Function: char ** history_tokenize (char *string)
Return an array of tokens parsed out of STRING, much as the shell
might. The tokens are split on white space and on the characters
`()<>;&|$', and shell quoting conventions are obeyed.

File: history.info, Node: History Variables, Next: History Programming Example, Prev: History Functions, Up: Programming with GNU History
History Variables
=================
This section describes the externally visible variables exported by
the GNU History Library.
- Variable: int history_base
The logical offset of the first entry in the history list.
- Variable: int history_length
The number of entries currently stored in the history list.
- Variable: int max_input_history
The maximum number of history entries. This must be changed using
`stifle_history ()'.
- Variable: char history_expansion_char
The character that starts a history event. The default is `!'.
- Variable: char history_subst_char
The character that invokes word substitution if found at the start
of a line. The default is `^'.
- Variable: char history_comment_char
During tokenization, if this character is seen as the first
character of a word, then it and all subsequent characters up to a
newline are ignored, suppressing history expansion for the
remainder of the line. This is disabled by default.
- Variable: char * history_no_expand_chars
The list of characters which inhibit history expansion if found
immediately following HISTORY_EXPANSION_CHAR. The default is
whitespace and `='.

File: history.info, Node: History Programming Example, Prev: History Variables, Up: Programming with GNU History
History Programming Example
===========================
The following program demonstrates simple use of the GNU History
Library.
main ()
{
char line[1024], *t;
int len, done = 0;
line[0] = 0;
using_history ();
while (!done)
{
printf ("history$ ");
fflush (stdout);
t = fgets (line, sizeof (line) - 1, stdin);
if (t && *t)
{
len = strlen (t);
if (t[len - 1] == '\n')
t[len - 1] = '\0';
}
if (!t)
strcpy (line, "quit");
if (line[0])
{
char *expansion;
int result;
result = history_expand (line, &expansion);
if (result)
fprintf (stderr, "%s\n", expansion);
if (result < 0 || result == 2)
{
free (expansion);
continue;
}
add_history (expansion);
strncpy (line, expansion, sizeof (line) - 1);
free (expansion);
}
if (strcmp (line, "quit") == 0)
done = 1;
else if (strcmp (line, "save") == 0)
write_history ("history_file");
else if (strcmp (line, "read") == 0)
read_history ("history_file");
else if (strcmp (line, "list") == 0)
{
register HIST_ENTRY **the_list;
register int i;
the_list = history_list ();
if (the_list)
for (i = 0; the_list[i]; i++)
printf ("%d: %s\n", i + history_base, the_list[i]->line);
}
else if (strncmp (line, "delete", 6) == 0)
{
int which;
if ((sscanf (line + 6, "%d", &which)) == 1)
{
HIST_ENTRY *entry = remove_history (which);
if (!entry)
fprintf (stderr, "No such entry %d\n", which);
else
{
free (entry->line);
free (entry);
}
}
else
{
fprintf (stderr, "non-numeric arg given to `delete'\n");
}
}
}
}

File: history.info, Node: Concept Index, Next: Function and Variable Index, Prev: Programming with GNU History, Up: Top
Concept Index
*************
* Menu:
* anchored search: Searching the History List.
* event designators: Event Designators.
* expansion: History Interaction.
* history events: Event Designators.
* History Searching: Searching the History List.

File: history.info, Node: Function and Variable Index, Prev: Concept Index, Up: Top
Function and Variable Index
***************************
* Menu:
* add_history: History List Management.
* append_history: Managing the History File.
* current_history: Information About the History List.
* get_history_event: History Expansion.
* history_arg_extract: History Expansion.
* history_base: History Variables.
* history_comment_char: History Variables.
* history_expand: History Expansion.
* history_expansion_char: History Variables.
* history_get: Information About the History List.
* history_get_history_state: Initializing History and State Management.
* history_is_stifled: History List Management.
* history_length: History Variables.
* history_list: Information About the History List.
* history_no_expand_chars: History Variables.
* history_search: Searching the History List.
* history_search_pos: Searching the History List.
* history_search_prefix: Searching the History List.
* history_set_history_state: Initializing History and State Management.
* history_set_pos: Moving Around the History List.
* history_subst_char: History Variables.
* history_tokenize: History Expansion.
* history_total_bytes: Information About the History List.
* history_truncate_file: Managing the History File.
* max_input_history: History Variables.
* next_history: Moving Around the History List.
* previous_history: Moving Around the History List.
* read_history: Managing the History File.
* read_history_range: Managing the History File.
* remove_history: History List Management.
* replace_history_entry: History List Management.
* stifle_history: History List Management.
* unstifle_history: History List Management.
* using_history: Initializing History and State Management.
* where_history: Information About the History List.
* write_history: Managing the History File.

Tag Table:
Node: Top975
Node: Using History Interactively1569
Node: History Interaction2077
Node: Event Designators3122
Node: Word Designators3952
Node: Modifiers4936
Node: Programming with GNU History6065
Node: Introduction to History6791
Node: History Storage8112
Node: History Functions9205
Node: Initializing History and State Management10176
Node: History List Management10968
Node: Information About the History List12396
Node: Moving Around the History List13702
Node: Searching the History List14587
Node: Managing the History File16419
Node: History Expansion17925
Node: History Variables19769
Node: History Programming Example21138
Node: Concept Index23742
Node: Function and Variable Index24223

End Tag Table

File diff suppressed because it is too large Load diff

View file

@ -1,7 +1,7 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
Copyright (C) 1988, 1991, 1994, 1996 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
@ -168,6 +168,10 @@ This returns the old entry so you can dispose of the data. In the case
of an invalid @var{which}, a @code{NULL} pointer is returned.
@end deftypefun
@deftypefun void clear_history ()
Clear the history list by deleting all the entries.
@end deftypefun
@deftypefun void stifle_history (int max)
Stifle the history list, remembering only the last @var{max} entries.
@end deftypefun
@ -400,6 +404,17 @@ following @var{history_expansion_char}. The default is whitespace and
@samp{=}.
@end deftypevar
@deftypevar {char *} history_search_delimiter_chars
The list of additional characters which can delimit a history search
string, in addition to whitespace, @samp{:} and @samp{?} in the case of
a substring search. The default is empty.
@end deftypevar
@deftypevar int history_quotes_inhibit_expansion
If non-zero, single-quoted words are not scanned for the history expansion
character. The default value is 0.
@end deftypevar
@node History Programming Example
@section History Programming Example

View file

@ -1,7 +1,7 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
Copyright (C) 1988, 1991, 1996 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
@ -39,26 +39,124 @@ information on using the GNU History Library in your own programs,
@pxref{Programming with GNU History}.
@end ifclear
@ifset BashFeatures
@menu
* Bash History Facilities:: How Bash lets you manipulate your command
history.
* History Interaction:: What it feels like using History as a user.
@end menu
@end ifset
@ifclear BashFeatures
@menu
* History Interaction:: What it feels like using History as a user.
@end menu
@end ifclear
@ifset BashFeatures
@node Bash History Facilities
@section Bash History Facilities
@cindex command history
@cindex history list
When the @samp{-o history} option to the @code{set} builtin
is enabled (@pxref{The Set Builtin}),
the shell provides access to the @var{command history},
the list of commands previously typed. The text of the last
@code{HISTSIZE}
commands (default 500) is saved in a history list. The shell
stores each command in the history list prior to parameter and
variable expansion
but after history expansion is performed, subject to the
values of the shell variables
@code{HISTIGNORE} and @code{HISTCONTROL}.
When the shell starts up, the history is initialized from the
file named by the @code{HISTFILE} variable (default @file{~/.bash_history}).
@code{HISTFILE} is truncated, if necessary, to contain no more than
the number of lines specified by the value of the @code{HISTFILESIZE}
variable. When an interactive shell exits, the last
@code{HISTSIZE} lines are copied from the history list to @code{HISTFILE}.
If the @code{histappend} shell option is set (@pxref{Bash Builtins}),
the lines are appended to the history file,
otherwise the history file is overwritten.
If @code{HISTFILE}
is unset, or if the history file is unwritable, the history is
not saved. After saving the history, the history file is truncated
to contain no more than @code{$HISTFILESIZE}
lines. If @code{HISTFILESIZE} is not set, no truncation is performed.
The builtin command @code{fc} (@pxref{Korn Shell Builtins})
may be used to list or edit and re-execute a portion of
the history list. The @code{history} builtin (@pxref{C Shell Builtins})
can be used to display or modify the history list and
manipulate the history file.
When using the command-line editing, search commands
are available in each editing mode that provide access to the
history list.
The shell allows control over which commands are saved on the history
list. The @code{HISTCONTROL} and @code{HISTIGNORE}
variables may be set to cause the shell to save only a subset of the
commands entered.
The @code{cmdhist}
shell option, if enabled, causes the shell to attempt to save each
line of a multi-line command in the same history entry, adding
semicolons where necessary to preserve syntactic correctness.
The @code{lithist}
shell option causes the shell to save the command with embedded newlines
instead of semicolons.
@xref{Bash Builtins} for a description of @code{shopt}.
@end ifset
@node History Interaction
@section History Interaction
@cindex expansion
@section Interactive History Expansion
@cindex history expansion
The History library provides a history expansion feature that is similar
to the history expansion provided by @code{csh}. The following text
to the history expansion provided by @code{csh}. This section
describes the syntax used to manipulate the history information.
History expansions introduce words from the history list into
the input stream, making it easy to repeat commands, insert the
arguments to a previous command into the current input line, or
fix errors in previous commands quickly.
History expansion takes place in two parts. The first is to determine
which line from the previous history should be used during substitution.
The second is to select portions of that line for inclusion into the
current one. The line selected from the previous history is called the
@dfn{event}, and the portions of that line that are acted upon are
called @dfn{words}. The line is broken into words in the same fashion
called @dfn{words}. Various @dfn{modifiers} are available to manipulate
the selected words. The line is broken into words in the same fashion
that Bash does, so that several English (or Unix) words
surrounded by quotes are considered as one word.
History expansions are introduced by the appearance of the
history expansion character, which is @samp{!} by default.
@ifset BashFeatures
Only @samp{\} and @samp{'} may be used to escape the history expansion
character.
@end ifset
@ifset BashFeatures
Several shell options settable with the @code{shopt}
builtin (@pxref{Bash Builtins}) may be used to tailor
the behavior of history expansion. If the
@code{histverify} shell option is enabled, and Readline
is being used, history substitutions are not immediately passed to
the shell parser.
Instead, the expanded line is reloaded into the Readline
editing buffer for further modification.
If Readline is being used, and the @code{histreedit}
shell option is enabled, a failed history expansion will be
reloaded into the Readline editing buffer for correction.
The @samp{-p} option to the @code{history} builtin command
may be used to see what a history expansion will do before using it.
The @samp{-s} option to the @code{history} builtin may be used to
add commands to the end of the history list without actually executing
them, so that they are available for subsequent recall.
The shell allows control of the various characters used by the
history expansion mechanism with the @code{histchars} variable.
@end ifset
@menu
* Event Designators:: How to specify which history line to use.
@ -80,92 +178,100 @@ history list.
Start a history substitution, except when followed by a space, tab,
the end of the line, @key{=} or @key{(}.
@item @code{!!}
Refer to the previous command. This is a synonym for @code{!-1}.
@item @code{!n}
@item @code{!@var{n}}
Refer to command line @var{n}.
@item @code{!-n}
@item @code{!-@var{n}}
Refer to the command @var{n} lines back.
@item @code{!string}
@item @code{!!}
Refer to the previous command. This is a synonym for @samp{!-1}.
@item @code{!@var{string}}
Refer to the most recent command starting with @var{string}.
@item @code{!?string}[@code{?}]
Refer to the most recent command containing @var{string}.
@item @code{!?@var{string}[?]}
Refer to the most recent command containing @var{string}. The trailing
@samp{?} may be omitted if the @var{string} is followed immediately by
a newline.
@item @code{^@var{string1}^@var{string2}^}
Quick Substitution. Repeat the last command, replacing @var{string1}
with @var{string2}. Equivalent to
@code{!!:s/@var{string1}/@var{string2}/}.
@item @code{!#}
The entire command line typed so far.
@item @code{^string1^string2^}
Quick Substitution. Repeat the last command, replacing @var{string1}
with @var{string2}. Equivalent to
@code{!!:s/string1/string2/}.
@end table
@node Word Designators
@subsection Word Designators
A @key{:} separates the event specification from the word designator. It
can be omitted if the word designator begins with a @key{^}, @key{$},
@key{*} or @key{%}. Words are numbered from the beginning of the line,
with the first word being denoted by a 0 (zero).
Word designators are used to select desired words from the event.
A @samp{:} separates the event specification from the word designator. It
can be omitted if the word designator begins with a @samp{^}, @samp{$},
@samp{*}, @samp{-}, or @samp{%}. Words are numbered from the beginning
of the line, with the first word being denoted by 0 (zero). Words are
inserted into the current line separated by single spaces.
@table @code
@item 0 (zero)
The @code{0}th word. For many applications, this is the command word.
@item n
@item @var{n}
The @var{n}th word.
@item ^
The first argument; that is, word 1.
The first argument; that is, word 1.
@item $
The last argument.
@item %
The word matched by the most recent @code{?string?} search.
The word matched by the most recent @samp{?@var{string}?} search.
@item x-y
A range of words; @code{-@var{y}} abbreviates @code{0-@var{y}}.
@item @var{x}-@var{y}
A range of words; @samp{-@var{y}} abbreviates @samp{0-@var{y}}.
@item *
All of the words, except the @code{0}th. This is a synonym for @code{1-$}.
It is not an error to use @key{*} if there is just one word in the event;
All of the words, except the @code{0}th. This is a synonym for @samp{1-$}.
It is not an error to use @samp{*} if there is just one word in the event;
the empty string is returned in that case.
@item x*
Abbreviates @code{x-$}
@item @var{x}*
Abbreviates @samp{@var{x}-$}
@item x-
Abbreviates @code{x-$} like @code{x*}, but omits the last word.
@item @var{x}-
Abbreviates @samp{@var{x}-$} like @samp{@var{x}*}, but omits the last word.
@end table
If a word designator is supplied without an event specification, the
previous command is used as the event.
@node Modifiers
@subsection Modifiers
After the optional word designator, you can add a sequence of one or more
of the following modifiers, each preceded by a @key{:}.
of the following modifiers, each preceded by a @samp{:}.
@table @code
@item h
Remove a trailing pathname component, leaving only the head.
@item t
Remove all leading pathname components, leaving the tail.
@item r
Remove a trailing suffix of the form @samp{.}@var{suffix}, leaving the basename.
Remove a trailing suffix of the form @samp{.@var{suffix}}, leaving
the basename.
@item e
Remove all but the trailing suffix.
@item t
Remove all leading pathname components, leaving the tail.
@item p
Print the new command but do not execute it.
@ -174,17 +280,17 @@ Print the new command but do not execute it.
Quote the substituted words, escaping further substitutions.
@item x
Quote the substituted words as with @code{q},
Quote the substituted words as with @samp{q},
but break into words at spaces, tabs, and newlines.
@end ifset
@item s/old/new/
@item s/@var{old}/@var{new}/
Substitute @var{new} for the first occurrence of @var{old} in the
event line. Any delimiter may be used in place of @key{/}.
event line. Any delimiter may be used in place of @samp{/}.
The delimiter may be quoted in @var{old} and @var{new}
with a single backslash. If @key{&} appears in @var{new},
with a single backslash. If @samp{&} appears in @var{new},
it is replaced by @var{old}. A single backslash will quote
the @key{&}. The final delimiter is optional if it is the last
the @samp{&}. The final delimiter is optional if it is the last
character on the input line.
@item &
@ -192,7 +298,7 @@ Repeat the previous substitution.
@item g
Cause changes to be applied over the entire event line. Used in
conjunction with @code{s}, as in @code{gs/old/new/}, or with
@code{&}.
conjunction with @samp{s}, as in @code{gs/@var{old}/@var{new}/},
or with @samp{&}.
@end table

Binary file not shown.

View file

@ -1,744 +0,0 @@
This is Info file history.info, produced by Makeinfo-1.55 from the
input file hist.texinfo.
This document describes the GNU History library, a programming tool
that provides a consistent user interface for recalling lines of
previously typed input.
Copyright (C) 1988, 1991 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of this
manual provided the copyright notice and this permission notice pare
preserved on all copies.
Permission is granted to copy and distribute modified versions of
this manual under the conditions for verbatim copying, provided that
the entire resulting derived work is distributed under the terms of a
permission notice identical to this one.
Permission is granted to copy and distribute translations of this
manual into another language, under the above conditions for modified
versions, except that this permission notice may be stated in a
translation approved by the Foundation.

File: history.info, Node: Top, Next: Using History Interactively, Prev: (DIR), Up: (DIR)
GNU History Library
*******************
This document describes the GNU History library, a programming tool
that provides a consistent user interface for recalling lines of
previously typed input.
* Menu:
* Using History Interactively:: GNU History User's Manual.
* Programming with GNU History:: GNU History Programmer's Manual.
* Concept Index:: Index of concepts described in this manual.
* Function and Variable Index:: Index of externally visible functions
and variables.

File: history.info, Node: Using History Interactively, Next: Programming with GNU History, Prev: Top, Up: Top
Using History Interactively
***************************
This chapter describes how to use the GNU History Library
interactively, from a user's standpoint. It should be considered a
user's guide. For information on using the GNU History Library in your
own programs, *note Programming with GNU History::..
* Menu:
* History Interaction:: What it feels like using History as a user.

File: history.info, Node: History Interaction, Up: Using History Interactively
History Interaction
===================
The History library provides a history expansion feature that is
similar to the history expansion provided by `csh'. The following text
describes the syntax used to manipulate the history information.
History expansion takes place in two parts. The first is to
determine which line from the previous history should be used during
substitution. The second is to select portions of that line for
inclusion into the current one. The line selected from the previous
history is called the "event", and the portions of that line that are
acted upon are called "words". The line is broken into words in the
same fashion that Bash does, so that several English (or Unix) words
surrounded by quotes are considered as one word.
* Menu:
* Event Designators:: How to specify which history line to use.
* Word Designators:: Specifying which words are of interest.
* Modifiers:: Modifying the results of substitution.

File: history.info, Node: Event Designators, Next: Word Designators, Up: History Interaction
Event Designators
-----------------
An event designator is a reference to a command line entry in the
history list.
`!'
Start a history substitution, except when followed by a space, tab,
the end of the line, = or (.
`!!'
Refer to the previous command. This is a synonym for `!-1'.
`!n'
Refer to command line N.
`!-n'
Refer to the command N lines back.
`!string'
Refer to the most recent command starting with STRING.
`!?string'[`?']
Refer to the most recent command containing STRING.
`!#'
The entire command line typed so far.
`^string1^string2^'
Quick Substitution. Repeat the last command, replacing STRING1
with STRING2. Equivalent to `!!:s/string1/string2/'.

File: history.info, Node: Word Designators, Next: Modifiers, Prev: Event Designators, Up: History Interaction
Word Designators
----------------
A : separates the event specification from the word designator. It
can be omitted if the word designator begins with a ^, $, * or %.
Words are numbered from the beginning of the line, with the first word
being denoted by a 0 (zero).
`0 (zero)'
The `0'th word. For many applications, this is the command word.
`n'
The Nth word.
`^'
The first argument; that is, word 1.
`$'
The last argument.
`%'
The word matched by the most recent `?string?' search.
`x-y'
A range of words; `-Y' abbreviates `0-Y'.
`*'
All of the words, except the `0'th. This is a synonym for `1-$'.
It is not an error to use * if there is just one word in the event;
the empty string is returned in that case.
`x*'
Abbreviates `x-$'
`x-'
Abbreviates `x-$' like `x*', but omits the last word.

File: history.info, Node: Modifiers, Prev: Word Designators, Up: History Interaction
Modifiers
---------
After the optional word designator, you can add a sequence of one or
more of the following modifiers, each preceded by a :.
`h'
Remove a trailing pathname component, leaving only the head.
`r'
Remove a trailing suffix of the form `.'SUFFIX, leaving the
basename.
`e'
Remove all but the trailing suffix.
`t'
Remove all leading pathname components, leaving the tail.
`p'
Print the new command but do not execute it.
`s/old/new/'
Substitute NEW for the first occurrence of OLD in the event line.
Any delimiter may be used in place of /. The delimiter may be
quoted in OLD and NEW with a single backslash. If & appears in
NEW, it is replaced by OLD. A single backslash will quote the &.
The final delimiter is optional if it is the last character on the
input line.
`&'
Repeat the previous substitution.
`g'
Cause changes to be applied over the entire event line. Used in
conjunction with `s', as in `gs/old/new/', or with `&'.

File: history.info, Node: Programming with GNU History, Next: Concept Index, Prev: Using History Interactively, Up: Top
Programming with GNU History
****************************
This chapter describes how to interface programs that you write with
the GNU History Library. It should be considered a technical guide.
For information on the interactive use of GNU History, *note Using
History Interactively::..
* Menu:
* Introduction to History:: What is the GNU History library for?
* History Storage:: How information is stored.
* History Functions:: Functions that you can use.
* History Variables:: Variables that control behaviour.
* History Programming Example:: Example of using the GNU History Library.

File: history.info, Node: Introduction to History, Next: History Storage, Up: Programming with GNU History
Introduction to History
=======================
Many programs read input from the user a line at a time. The GNU
History library is able to keep track of those lines, associate
arbitrary data with each line, and utilize information from previous
lines in composing new ones.
The programmer using the History library has available functions for
remembering lines on a history list, associating arbitrary data with a
line, removing lines from the list, searching through the list for a
line containing an arbitrary text string, and referencing any line in
the list directly. In addition, a history "expansion" function is
available which provides for a consistent user interface across
different programs.
The user using programs written with the History library has the
benefit of a consistent user interface with a set of well-known
commands for manipulating the text of previous lines and using that text
in new commands. The basic history manipulation commands are similar to
the history substitution provided by `csh'.
If the programmer desires, he can use the Readline library, which
includes some history manipulation by default, and has the added
advantage of command line editing.

File: history.info, Node: History Storage, Next: History Functions, Prev: Introduction to History, Up: Programming with GNU History
History Storage
===============
The history list is an array of history entries. A history entry is
declared as follows:
typedef struct _hist_entry {
char *line;
char *data;
} HIST_ENTRY;
The history list itself might therefore be declared as
HIST_ENTRY **the_history_list;
The state of the History library is encapsulated into a single
structure:
/* A structure used to pass the current state of the history stuff around. */
typedef struct _hist_state {
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
int offset; /* The location pointer within this array. */
int length; /* Number of elements within this array. */
int size; /* Number of slots allocated to this array. */
int flags;
} HISTORY_STATE;
If the flags member includes `HS_STIFLED', the history has been
stifled.

File: history.info, Node: History Functions, Next: History Variables, Prev: History Storage, Up: Programming with GNU History
History Functions
=================
This section describes the calling sequence for the various functions
present in GNU History.
* Menu:
* Initializing History and State Management:: Functions to call when you
want to use history in a
program.
* History List Management:: Functions used to manage the list
of history entries.
* Information About the History List:: Functions returning information about
the history list.
* Moving Around the History List:: Functions used to change the position
in the history list.
* Searching the History List:: Functions to search the history list
for entries containing a string.
* Managing the History File:: Functions that read and write a file
containing the history list.
* History Expansion:: Functions to perform csh-like history
expansion.

File: history.info, Node: Initializing History and State Management, Next: History List Management, Up: History Functions
Initializing History and State Management
-----------------------------------------
This section describes functions used to initialize and manage the
state of the History library when you want to use the history functions
in your program.
- Function: void using_history ()
Begin a session in which the history functions might be used. This
initializes the interactive variables.
- Function: HISTORY_STATE * history_get_history_state ()
Return a structure describing the current state of the input
history.
- Function: void history_set_history_state (HISTORY_STATE *state)
Set the state of the history list according to STATE.

File: history.info, Node: History List Management, Next: Information About the History List, Prev: Initializing History and State Management, Up: History Functions
History List Management
-----------------------
These functions manage individual entries on the history list, or set
parameters managing the list itself.
- Function: void add_history (char *string)
Place STRING at the end of the history list. The associated data
field (if any) is set to `NULL'.
- Function: HIST_ENTRY * remove_history (int which)
Remove history entry at offset WHICH from the history. The
removed element is returned so you can free the line, data, and
containing structure.
- Function: HIST_ENTRY * replace_history_entry (int which, char *line,
char *data)
Make the history entry at offset 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.
- Function: void stifle_history (int max)
Stifle the history list, remembering only the last MAX entries.
- Function: int unstifle_history ()
Stop stifling the history. This returns the previous amount the
history was stifled. The value is positive if the history was
stifled, negative if it wasn't.
- Function: int history_is_stifled ()
Returns non-zero if the history is stifled, zero if it is not.

File: history.info, Node: Information About the History List, Next: Moving Around the History List, Prev: History List Management, Up: History Functions
Information About the History List
----------------------------------
These functions return information about the entire history list or
individual list entries.
- Function: HIST_ENTRY ** history_list ()
Return a `NULL' terminated array of `HIST_ENTRY' which is the
current input history. Element 0 of this list is the beginning of
time. If there is no history, return `NULL'.
- Function: int where_history ()
Returns the offset of the current history element.
- Function: HIST_ENTRY * current_history ()
Return the history entry at the current position, as determined by
`where_history ()'. If there is no entry there, return a `NULL'
pointer.
- Function: HIST_ENTRY * history_get (int offset)
Return the history entry at position OFFSET, starting from
`history_base'. If there is no entry there, or if OFFSET is
greater than the history length, return a `NULL' pointer.
- Function: int history_total_bytes ()
Return the number of bytes that the primary history entries are
using. This function returns the sum of the lengths of all the
lines in the history.

File: history.info, Node: Moving Around the History List, Next: Searching the History List, Prev: Information About the History List, Up: History Functions
Moving Around the History List
------------------------------
These functions allow the current index into the history list to be
set or changed.
- Function: int history_set_pos (int pos)
Set the position in the history list to POS, an absolute index
into the list.
- Function: HIST_ENTRY * previous_history ()
Back up the current history offset to the previous history entry,
and return a pointer to that entry. If there is no previous
entry, return a `NULL' pointer.
- Function: HIST_ENTRY * next_history ()
Move the current history offset forward to the next history entry,
and return the a pointer to that entry. If there is no next
entry, return a `NULL' pointer.

File: history.info, Node: Searching the History List, Next: Managing the History File, Prev: Moving Around the History List, Up: History Functions
Searching the History List
--------------------------
These functions allow searching of the history list for entries
containing a specific string. Searching may be performed both forward
and backward from the current history position. The search may be
"anchored", meaning that the string must match at the beginning of the
history entry.
- Function: int history_search (char *string, int direction)
Search the history for STRING, starting at the current history
offset. If DIRECTION < 0, then the search is through previous
entries, else through subsequent. If STRING is found, then the
current history index is set to that history entry, and the value
returned is the offset in the line of the entry where STRING was
found. Otherwise, nothing is changed, and a -1 is returned.
- Function: int history_search_prefix (char *string, int direction)
Search the history for STRING, starting at the current history
offset. The search is anchored: matching lines must begin with
STRING. If DIRECTION < 0, then the search is through previous
entries, else through subsequent. If STRING is found, then the
current history index is set to that entry, and the return value
is 0. Otherwise, nothing is changed, and a -1 is returned.
- Function: int history_search_pos (char *string, int direction, int
pos)
Search for STRING in the history list, starting at POS, an
absolute index into the list. If DIRECTION is negative, the search
proceeds backward from POS, otherwise forward. Returns the
absolute index of the history element where STRING was found, or
-1 otherwise.

File: history.info, Node: Managing the History File, Next: History Expansion, Prev: Searching the History List, Up: History Functions
Managing the History File
-------------------------
The History library can read the history from and write it to a file.
This section documents the functions for managing a history file.
- Function: int read_history (char *filename)
Add the contents of FILENAME to the history list, a line at a
time. If FILENAME is `NULL', then read from `~/.history'.
Returns 0 if successful, or errno if not.
- Function: int read_history_range (char *filename, int from, int to)
Read a range of lines from FILENAME, adding them to the history
list. Start reading at line FROM and end at TO. If FROM is zero,
start at the beginning. If TO is less than FROM, then read until
the end of the file. If FILENAME is `NULL', then read from
`~/.history'. Returns 0 if successful, or `errno' if not.
- Function: int write_history (char *filename)
Write the current history to FILENAME, overwriting FILENAME if
necessary. If FILENAME is `NULL', then write the history list to
`~/.history'. Values returned are as in `read_history ()'.
- Function: int append_history (int nelements, char *filename)
Append the last NELEMENTS of the history list to FILENAME.
- Function: int history_truncate_file (char *filename, int nlines)
Truncate the history file FILENAME, leaving only the last NLINES
lines.

File: history.info, Node: History Expansion, Prev: Managing the History File, Up: History Functions
History Expansion
-----------------
These functions implement `csh'-like history expansion.
- Function: int history_expand (char *string, char **output)
Expand STRING, placing the result into OUTPUT, a pointer to a
string (*note History Interaction::.). Returns:
`0'
If no expansions took place (or, if the only change in the
text was the de-slashifying of the history expansion
character);
`1'
if expansions did take place;
`-1'
if there was an error in expansion;
`2'
if the returned line should only be displayed, but not
executed, as with the `:p' modifier (*note Modifiers::.).
If an error ocurred in expansion, then OUTPUT contains a
descriptive error message.
- Function: char * history_arg_extract (int first, int last, char
*string)
Extract a string segment consisting of the FIRST through LAST
arguments present in STRING. Arguments are broken up as in Bash.
- Function: char * get_history_event (char *string, int *cindex, int
qchar)
Returns the text of the history event beginning at STRING +
*CINDEX. *CINDEX is modified to point to after the event
specifier. At function entry, CINDEX points to the index into
STRING where the history event specification begins. QCHAR is a
character that is allowed to end the event specification in
addition to the "normal" terminating characters.
- Function: char ** history_tokenize (char *string)
Return an array of tokens parsed out of STRING, much as the shell
might. The tokens are split on white space and on the characters
`()<>;&|$', and shell quoting conventions are obeyed.

File: history.info, Node: History Variables, Next: History Programming Example, Prev: History Functions, Up: Programming with GNU History
History Variables
=================
This section describes the externally visible variables exported by
the GNU History Library.
- Variable: int history_base
The logical offset of the first entry in the history list.
- Variable: int history_length
The number of entries currently stored in the history list.
- Variable: int max_input_history
The maximum number of history entries. This must be changed using
`stifle_history ()'.
- Variable: char history_expansion_char
The character that starts a history event. The default is `!'.
- Variable: char history_subst_char
The character that invokes word substitution if found at the start
of a line. The default is `^'.
- Variable: char history_comment_char
During tokenization, if this character is seen as the first
character of a word, then it and all subsequent characters up to a
newline are ignored, suppressing history expansion for the
remainder of the line. This is disabled by default.
- Variable: char * history_no_expand_chars
The list of characters which inhibit history expansion if found
immediately following HISTORY_EXPANSION_CHAR. The default is
whitespace and `='.

File: history.info, Node: History Programming Example, Prev: History Variables, Up: Programming with GNU History
History Programming Example
===========================
The following program demonstrates simple use of the GNU History
Library.
main ()
{
char line[1024], *t;
int len, done = 0;
line[0] = 0;
using_history ();
while (!done)
{
printf ("history$ ");
fflush (stdout);
t = fgets (line, sizeof (line) - 1, stdin);
if (t && *t)
{
len = strlen (t);
if (t[len - 1] == '\n')
t[len - 1] = '\0';
}
if (!t)
strcpy (line, "quit");
if (line[0])
{
char *expansion;
int result;
result = history_expand (line, &expansion);
if (result)
fprintf (stderr, "%s\n", expansion);
if (result < 0 || result == 2)
{
free (expansion);
continue;
}
add_history (expansion);
strncpy (line, expansion, sizeof (line) - 1);
free (expansion);
}
if (strcmp (line, "quit") == 0)
done = 1;
else if (strcmp (line, "save") == 0)
write_history ("history_file");
else if (strcmp (line, "read") == 0)
read_history ("history_file");
else if (strcmp (line, "list") == 0)
{
register HIST_ENTRY **the_list;
register int i;
the_list = history_list ();
if (the_list)
for (i = 0; the_list[i]; i++)
printf ("%d: %s\n", i + history_base, the_list[i]->line);
}
else if (strncmp (line, "delete", 6) == 0)
{
int which;
if ((sscanf (line + 6, "%d", &which)) == 1)
{
HIST_ENTRY *entry = remove_history (which);
if (!entry)
fprintf (stderr, "No such entry %d\n", which);
else
{
free (entry->line);
free (entry);
}
}
else
{
fprintf (stderr, "non-numeric arg given to `delete'\n");
}
}
}
}

File: history.info, Node: Concept Index, Next: Function and Variable Index, Prev: Programming with GNU History, Up: Top
Concept Index
*************
* Menu:
* anchored search: Searching the History List.
* event designators: Event Designators.
* expansion: History Interaction.
* history events: Event Designators.
* History Searching: Searching the History List.

File: history.info, Node: Function and Variable Index, Prev: Concept Index, Up: Top
Function and Variable Index
***************************
* Menu:
* add_history: History List Management.
* append_history: Managing the History File.
* current_history: Information About the History List.
* get_history_event: History Expansion.
* history_arg_extract: History Expansion.
* history_base: History Variables.
* history_comment_char: History Variables.
* history_expand: History Expansion.
* history_expansion_char: History Variables.
* history_get: Information About the History List.
* history_get_history_state: Initializing History and State Management.
* history_is_stifled: History List Management.
* history_length: History Variables.
* history_list: Information About the History List.
* history_no_expand_chars: History Variables.
* history_search: Searching the History List.
* history_search_pos: Searching the History List.
* history_search_prefix: Searching the History List.
* history_set_history_state: Initializing History and State Management.
* history_set_pos: Moving Around the History List.
* history_subst_char: History Variables.
* history_tokenize: History Expansion.
* history_total_bytes: Information About the History List.
* history_truncate_file: Managing the History File.
* max_input_history: History Variables.
* next_history: Moving Around the History List.
* previous_history: Moving Around the History List.
* read_history: Managing the History File.
* read_history_range: Managing the History File.
* remove_history: History List Management.
* replace_history_entry: History List Management.
* stifle_history: History List Management.
* unstifle_history: History List Management.
* using_history: Initializing History and State Management.
* where_history: Information About the History List.
* write_history: Managing the History File.

Tag Table:
Node: Top975
Node: Using History Interactively1569
Node: History Interaction2077
Node: Event Designators3122
Node: Word Designators3952
Node: Modifiers4936
Node: Programming with GNU History6065
Node: Introduction to History6791
Node: History Storage8112
Node: History Functions9205
Node: Initializing History and State Management10176
Node: History List Management10968
Node: Information About the History List12396
Node: Moving Around the History List13702
Node: Searching the History List14587
Node: Managing the History File16419
Node: History Expansion17925
Node: History Variables19769
Node: History Programming Example21138
Node: Concept Index23742
Node: Function and Variable Index24223

End Tag Table

File diff suppressed because it is too large Load diff

View file

@ -7,13 +7,13 @@
@setchapternewpage odd
@ignore
last change: Thu Jul 21 16:02:40 EDT 1994
last change: Thu Mar 21 16:06:39 EST 1996
@end ignore
@set EDITION 2.0
@set VERSION 2.0
@set UPDATED 21 July 1994
@set UPDATE-MONTH July 1994
@set EDITION 2.1
@set VERSION 2.1
@set UPDATED 21 March 1996
@set UPDATE-MONTH March 1996
@ifinfo
This document describes the GNU Readline Library, a utility which aids
@ -45,7 +45,6 @@ by the Foundation.
@end ifinfo
@titlepage
@sp 10
@title GNU Readline Library
@subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}.
@subtitle @value{UPDATE-MONTH}

View file

@ -8,7 +8,7 @@ This document describes the GNU Readline Library, a utility for aiding
in the consitency of user interface across discrete programs that need
to provide a command line interface.
Copyright (C) 1988, 1994 Free Software Foundation, Inc.
Copyright (C) 1988, 1994, 1996 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@ -273,6 +273,10 @@ The prompt Readline uses. This is set from the argument to
@code{readline ()}, and should not be assigned to directly.
@end deftypevar
@deftypevar {char *} rl_library_version
The version number of this revision of the library.
@end deftypevar
@deftypevar {char *} rl_terminal_name
The terminal type, used for initialization.
@end deftypevar
@ -301,6 +305,30 @@ If non-zero, this is the address of a function to call periodically
when readline is waiting for terminal input.
@end deftypevar
@deftypevar {Function *} rl_getc_function
If non-zero, @code{readline} will call indirectly through this pointer
to get a character from the input stream. By default, it is set to
@code{rl_getc}, the default @code{readline} character input function
(@pxref{Utility Functions}).
@end deftypevar
@deftypevar {Function *} rl_redisplay_function
If non-zero, @code{readline} will call indirectly through this pointer
to update the display with the current contents of the editing buffer.
By default, it is set to @code{rl_redisplay}, the default @code{readline}
redisplay function (@pxref{Redisplay}).
@end deftypevar
@deftypevar {Keymap} rl_executing_keymap
This variable is set to the keymap (@pxref{Keymaps}) in which the
currently executing readline function was found.
@end deftypevar
@deftypevar {Keymap} rl_binding_keymap
This variable is set to the keymap (@pxref{Keymaps}) in which the
last key binding occurred.
@end deftypevar
@node Readline Convenience Functions
@section Readline Convenience Functions
@ -314,6 +342,7 @@ when readline is waiting for terminal input.
* Redisplay:: Functions to control line display.
* Modifying Text:: Functions to modify @code{rl_line_buffer}.
* Utility Functions:: Generally useful functions and hooks.
* Alternate Interface:: Using Readline in a `callback' fashion.
@end menu
@node Function Naming
@ -611,6 +640,10 @@ the input stream via @var{pending input} (@pxref{Readline Variables})
and @code{rl_stuff_char ()}, macros, and characters read from the keyboard.
@end deftypefun
@deftypefun int rl_getc (FILE *)
Return the next character available from the keyboard.
@end deftypefun
@deftypefun int rl_stuff_char (int c)
Insert @var{c} into the Readline input stream. It will be "read"
before Readline attempts to read characters from the terminal with
@ -666,6 +699,37 @@ lowercase character.
If @var{c} is a number, return the value it represents.
@end deftypefun
@node Alternate Interface
@subsection Alternate Interface
An alternate interface is available to plain @code{readline()}. Some
applications need to interleave keyboard I/O with file, device, or
window system I/O, typically by using a main loop to @code{select()}
on various file descriptors. To accomodate this need, readline can
also be invoked as a `callback' function from an event loop. There
are functions available to make this easy.
@deftypefun void rl_callback_handler_install (char *prompt, Vfunction *lhandler)
Set up the terminal for readline I/O and display the initial
expanded value of @var{prompt}. Save the value of @var{lhandler} to
use as a callback when a complete line of input has been entered.
@end deftypefun
@deftypefun void rl_callback_read_char ()
Whenever an application determines that keyboard input is available, it
should call @code{rl_callback_read_char()}, which will read the next
character from the current input source. If that character completes the
line, @code{rl_callback_read_char} will invoke the @var{lhandler}
function saved by @code{rl_callback_handler_install} to process the
line. @code{EOF} is indicated by calling @var{lhandler} with a
@code{NULL} line.
@end deftypefun
@deftypefun void rl_callback_handler_remove ()
Restore the terminal to its initial state and remove the line handler.
This may be called from within a callback as well as independently.
@end deftypefun
@subsection An Example
Here is a function which changes lowercase characters to their uppercase
@ -894,6 +958,40 @@ returns @code{NULL}, or if this variable is set to @code{NULL}, then
array of strings returned will be used.
@end deftypevar
@deftypevar {CPFunction *} rl_filename_quoting_function
A pointer to a function that will quote a filename in an application-
specific fashion. This is called if filename completion is being
attempted and one of the characters in @code{rl_filename_quote_characters}
appears in a completed filename. The function is called with
@var{text}, @var{match_type}, and @var{quote_pointer}. The @var{text}
is the filename to be quoted. The @var{match_type} is either
@code{SINGLE_MATCH}, if there is only one completion match, or
@code{MULT_MATCH}. Some functions use this to decide whether or not to
insert a closing quote character. The @var{quote_pointer} is a pointer
to any opening quote character the user typed. Some functions choose
to reset this character.
@end deftypevar
@deftypevar {CPFunction *} rl_filename_dequoting_function
A pointer to a function that will remove application-specific quoting
characters from a filename before completion is attempted, so those
characters do not interfere with matching the text against names in
the filesystem. It is called with @var{text}, the text of the word
to be dequoted, and @var{quote_char}, which is the quoting character
that delimits the filename (usually @samp{'} or @samp{"}). If
@var{quote_char} is zero, the filename was not in an embedded string.
@end deftypevar
@deftypevar {Function *} rl_char_is_quoted_p
A pointer to a function to call that determines whether or not a specific
character in the line buffer is quoted, according to whatever quoting
mechanism the program calling readline uses. The function is called with
two arguments: @var{text}, the text of the line, and @var{index}, the
index of the character in the line. It is used to decide whether a
character found in @code{rl_completer_word_break_characters} should be
used to break words for the completer.
@end deftypevar
@deftypevar int rl_completion_query_items
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
@ -907,6 +1005,10 @@ which break words for completion in Bash, i.e.,
@code{" \t\n\"\\'`@@$><=;|&@{("}.
@end deftypevar
@deftypevar {char *} rl_basic_quote_characters
List of quote characters which can cause a word break.
@end deftypevar
@deftypevar {char *} rl_completer_word_break_characters
The list of characters that signal a break between words for
@code{rl_complete_internal ()}. The default list is the value of
@ -920,6 +1022,11 @@ Completion occurs on the entire substring, and within the substring
unless they also appear within this list.
@end deftypevar
@deftypevar {char *} rl_filename_quote_characters
A list of characters that cause a filename to be quoted by the completer
when they appear in a completed filename. The default is empty.
@end deftypevar
@deftypevar {char *} rl_special_prefixes
The list of characters that are word break characters, but should be
left in @var{text} when it is passed to the completion function.
@ -928,6 +1035,16 @@ For instance, Bash sets this variable to "$@@" so that it can complete
shell variables and hostnames.
@end deftypevar
@deftypevar {int} rl_completion_append_character
When a single completion alternative matches at the end of the command
line, this character is appended to the inserted completion text. The
default is a space character (@samp{ }). Setting this to the null
character (@samp{\0}) prevents anything being appended automatically.
This can be changed in custom completion functions to
provide the ``most sensible word separator character'' according to
an application-specific command line syntax specification.
@end deftypevar
@deftypevar int rl_ignore_completion_duplicates
If non-zero, then disallow duplicates in the matches. Default is 1.
@end deftypevar
@ -945,9 +1062,15 @@ characters.
Non-zero means that the results of the matches are to be quoted using
double quotes (or an application-specific quoting mechanism) if the
completed filename contains any characters in
@code{rl_completer_word_break_chars}. This is @emph{always} non-zero
@code{rl_filename_quote_chars}. This is @emph{always} non-zero
on entry, and can only be changed within a completion entry generator
function.
function. The quoting is effected via a call to the function pointed to
by @code{rl_filename_quoting_function}.
@end deftypevar
@deftypevar int rl_inhibit_completion
If this variable is non-zero, completion is inhibited. The completion
character will be inserted as any other bound to @code{self-insert}.
@end deftypevar
@deftypevar {Function *} rl_ignore_some_completions_function
@ -1174,10 +1297,11 @@ initialize_readline ()
rl_attempted_completion_function = (CPPFunction *)fileman_completion;
@}
/* Attempt to complete on the contents of TEXT. START and END show the
region of TEXT that contains the word to complete. We can use the
entire line in case we want to do some simple parsing. Return the
array of matches, or NULL if there aren't any. */
/* Attempt to complete on the contents of TEXT. START and END bound the
region of rl_line_buffer that contains the word to complete. TEXT is
the word to complete. We can use the entire contents of rl_line_buffer
in case we want to do some simple parsing. Return the array of matches,
or NULL if there aren't any. */
char **
fileman_completion (text, start, end)
char *text;

View file

@ -10,7 +10,7 @@ use these features. There is a document entitled "readline.texinfo"
which contains both end-user and programmer documentation for the GNU
Readline Library.
Copyright (C) 1988 Free Software Foundation, Inc.
Copyright (C) 1988, 1991, 1993, 1996 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
@ -39,7 +39,7 @@ into another language, under the above conditions for modified versions.
@node Command Line Editing
@chapter Command Line Editing
This chapter describes the basic features of the GNU
This chapter describes the basic features of the @sc{GNU}
command line editing interface.
@menu
@ -59,11 +59,12 @@ The following paragraphs describe the notation used to represent
keystrokes.
The text @key{C-k} is read as `Control-K' and describes the character
produced when the Control key is depressed and the @key{k} key is struck.
produced when the @key{k} key is pressed while the Control key
is depressed.
The text @key{M-k} is read as `Meta-K' and describes the character
produced when the meta key (if you have one) is depressed, and the @key{k}
key is struck. If you do not have a meta key, the identical keystroke
key is pressed. If you do not have a meta key, the identical keystroke
can be generated by typing @key{ESC} @i{first}, and then typing @key{k}.
Either process is known as @dfn{metafying} the @key{k} key.
@ -73,7 +74,7 @@ character produced by @dfn{metafying} @key{C-k}.
In addition, several keys have their own names. Specifically,
@key{DEL}, @key{ESC}, @key{LFD}, @key{SPC}, @key{RET}, and @key{TAB} all
stand for themselves when seen in this text, or in an init file
(@pxref{Readline Init File}, for more info).
(@pxref{Readline Init File}).
@node Readline Interaction
@section Readline Interaction
@ -95,10 +96,14 @@ regardless of the location of the cursor within the line.
* Readline Movement Commands:: Moving about the input line.
* Readline Killing Commands:: How to delete text, and how to get it back!
* Readline Arguments:: Giving numeric arguments to commands.
@end menu
* Searching:: Searching through previous lines.
@end menu
@node Readline Bare Essentials
@subsection Readline Bare Essentials
@cindex notation, readline
@cindex command editing
@cindex editing command lines
In order to enter characters into the line, simply type them. The typed
character appears where the cursor was, and then the cursor moves one
@ -164,8 +169,8 @@ operate on characters while meta keystrokes operate on words.
@node Readline Killing Commands
@subsection Readline Killing Commands
@cindex Killing text
@cindex Yanking text
@cindex killing text
@cindex yanking text
@dfn{Killing} text means to delete the text from the line, but to save
it away for later use, usually by @dfn{yanking} (re-inserting)
@ -180,7 +185,7 @@ that when you yank it back, you get it all. The kill
ring is not line specific; the text that you killed on a previously
typed line is available to be yanked back later, when you are typing
another line.
@cindex Kill ring
@cindex kill ring
Here is the list of commands for killing text.
@ -222,24 +227,59 @@ argument acts as a repeat count, other times it is the @i{sign} of the
argument that is significant. If you pass a negative argument to a
command which normally acts in a forward direction, that command will
act in a backward direction. For example, to kill text back to the
start of the line, you might type @key{M--} @key{C-k}.
start of the line, you might type @w{@kbd{M-- C-k}}.
The general way to pass numeric arguments to a command is to type meta
digits before the command. If the first `digit' you type is a minus
sign (@key{-}), then the sign of the argument will be negative. Once
you have typed one meta digit to get the argument started, you can type
the remainder of the digits, and then the command. For example, to give
the @key{C-d} command an argument of 10, you could type @key{M-1 0 C-d}.
the @key{C-d} command an argument of 10, you could type @samp{M-1 0 C-d}.
@node Searching
@subsection Searching for Commands in the History
Readline provides commands for searching through the command history
@ifset BashFeatures
(@pxref{Bash History Facilities})
@end ifset
for lines containing a specified string.
There are two search modes: @var{incremental} and @var{non-incremental}.
Incremental searches begin before the user has finished typing the
search string.
As each character of the search string is typed, readline displays
the next entry from the history matching the string typed so far.
An incremental search requires only as many characters as needed to
find the desired history entry.
The Escape character is used to terminate an incremental search.
Control-J will also terminate the search.
Control-G will abort an incremental search and restore the original
line.
When the search is terminated, the history entry containing the
search string becomes the current line.
To find other matching entries in the history list, type Control-S or
Control-R as appropriate.
This will search backward or forward in the history for the next
entry matching the search string typed so far.
Any other key sequence bound to a readline command will terminate
the search and execute that command.
For instance, a @code{newline} will terminate the search and accept
the line, thereby executing the command from the history list.
Non-incremental searches read the entire search string before starting
to search for matching history lines. The search string may be
typed by the user or part of the contents of the current line.
@node Readline Init File
@section Readline Init File
@cindex initialization file, readline
Although the Readline library comes with a set of Emacs-like
Although the Readline library comes with a set of @code{emacs}-like
keybindings installed by default,
it is possible that you would like to use a different set
of keybindings. You can customize programs that use Readline by putting
commands in an @dfn{init} file in your home directory. The name of this
commands in an @dfn{inputrc} file in your home directory. The name of this
@ifset BashFeatures
file is taken from the value of the shell variable @code{INPUTRC}. If
@end ifset
@ -255,17 +295,20 @@ In addition, the @code{C-x C-r} command re-reads this init file, thus
incorporating any changes that you might have made to it.
@menu
* Readline Init Syntax:: Syntax for the commands in the inputrc file.
* Readline Init File Syntax:: Syntax for the commands in the inputrc file.
* Conditional Init Constructs:: Conditional key bindings in the inputrc file.
* Sample Init File:: An example inputrc file.
@end menu
@node Readline Init Syntax
@subsection Readline Init Syntax
@node Readline Init File Syntax
@subsection Readline Init File Syntax
There are only a few basic constructs allowed in the
Readline init file. Blank lines are ignored.
Lines beginning with a @key{#} are comments.
Lines beginning with a @key{$} indicate conditional
Lines beginning with a @samp{#} are comments.
Lines beginning with a @samp{$} indicate conditional
constructs (@pxref{Conditional Init Constructs}). Other lines
denote variable settings and key bindings.
@ -284,61 +327,20 @@ so few, in fact, that we just list them here:
@table @code
@item editing-mode
@vindex editing-mode
The @code{editing-mode} variable controls which editing mode you are
using. By default, Readline starts up in Emacs editing mode, where
the keystrokes are most similar to Emacs. This variable can be
set to either @code{emacs} or @code{vi}.
@item horizontal-scroll-mode
@vindex horizontal-scroll-mode
This variable can be set to either @code{On} or @code{Off}. Setting it
to @code{On} means that the text of the lines that you edit will scroll
horizontally on a single screen line when they are longer than the width
of the screen, instead of wrapping onto a new screen line. By default,
this variable is set to @code{Off}.
@item mark-modified-lines
@vindex mark-modified-lines
This variable, when set to @code{On}, says to display an asterisk
(@samp{*}) at the start of history lines which have been modified.
This variable is @code{off} by default.
@item bell-style
@vindex bell-style
Controls what happens when Readline wants to ring the terminal bell.
If set to @code{none}, Readline never rings the bell. If set to
@code{visible}, Readline uses a visible bell if one is available.
If set to @code{audible} (the default), Readline attempts to ring
If set to @samp{none}, Readline never rings the bell. If set to
@samp{visible}, Readline uses a visible bell if one is available.
If set to @samp{audible} (the default), Readline attempts to ring
the terminal's bell.
@item comment-begin
@vindex comment-begin
The string to insert at the beginning of the line when the
@code{vi-comment} command is executed. The default value
@code{insert-comment} command is executed. The default value
is @code{"#"}.
@item meta-flag
@vindex meta-flag
If set to @code{on}, Readline will enable eight-bit input (it
will not strip the eighth bit from the characters it reads),
regardless of what the terminal claims it can support. The
default value is @code{off}.
@item convert-meta
@vindex convert-meta
If set to @code{on}, Readline will convert characters with the
eigth bit set to an ASCII key sequence by stripping the eigth
bit and prepending an @key{ESC} character, converting them to a
meta-prefixed key sequence. The default value is @code{on}.
@item output-meta
@vindex output-meta
If set to @code{on}, Readline will display characters with the
eighth bit set directly rather than as a meta-prefixed escape
sequence. The default is @code{off}.
@item completion-query-items
@vindex completion-query-items
The number of possible completions that determines when the user is
@ -348,6 +350,45 @@ Readline will ask the user whether or not he wishes to view
them; otherwise, they are simply listed. The default limit is
@code{100}.
@item convert-meta
@vindex convert-meta
If set to @samp{on}, Readline will convert characters with the
eigth bit set to an ASCII key sequence by stripping the eigth
bit and prepending an @key{ESC} character, converting them to a
meta-prefixed key sequence. The default value is @samp{on}.
@item disable-completion
@vindex disable-completion
If set to @samp{On}, readline will inhibit word completion.
Completion characters will be inserted into the line as if they had
been mapped to @code{self-insert}. The default is @samp{off}.
@item editing-mode
@vindex editing-mode
The @code{editing-mode} variable controls which editing mode you are
using. By default, Readline starts up in Emacs editing mode, where
the keystrokes are most similar to Emacs. This variable can be
set to either @samp{emacs} or @samp{vi}.
@item enable-keypad
@vindex enable-keypad
When set to @samp{on}, readline will try to enable the application
keypad when it is called. Some systems need this to enable the
arrow keys. The default is @samp{off}.
@item expand-tilde
@vindex expand-tilde
If set to @samp{on}, tilde expansion is performed when Readline
attempts word completion. The default is @samp{off}.
@item horizontal-scroll-mode
@vindex horizontal-scroll-mode
This variable can be set to either @samp{on} or @samp{off}. Setting it
to @samp{on} means that the text of the lines that you edit will scroll
horizontally on a single screen line when they are longer than the width
of the screen, instead of wrapping onto a new screen line. By default,
this variable is set to @samp{off}.
@item keymap
@vindex keymap
Sets Readline's idea of the current keymap for key binding commands.
@ -357,7 +398,6 @@ Acceptable @code{keymap} names are
@code{emacs-meta},
@code{emacs-ctlx},
@code{vi},
@code{vi-move},
@code{vi-command}, and
@code{vi-insert}.
@code{vi} is equivalent to @code{vi-command}; @code{emacs} is
@ -365,18 +405,44 @@ equivalent to @code{emacs-standard}. The default value is @code{emacs}.
The value of the @code{editing-mode} variable also affects the
default keymap.
@item mark-directories
If set to @samp{on}, completed directory names have a slash
appended. The default is @samp{on}.
@item mark-modified-lines
@vindex mark-modified-lines
This variable, when set to @samp{on}, says to display an asterisk
(@samp{*}) at the start of history lines which have been modified.
This variable is @samp{off} by default.
@item input-meta
@vindex input-meta
@vindex meta-flag
If set to @samp{on}, Readline will enable eight-bit input (it
will not strip the eighth bit from the characters it reads),
regardless of what the terminal claims it can support. The
default value is @samp{off}. The name @code{meta-flag} is a
synonym for this variable.
@item output-meta
@vindex output-meta
If set to @samp{on}, Readline will display characters with the
eighth bit set directly rather than as a meta-prefixed escape
sequence. The default is @samp{off}.
@item show-all-if-ambiguous
@vindex show-all-if-ambiguous
This alters the default behavior of the completion functions. If
set to @code{on},
set to @samp{on},
words which have more than one possible completion cause the
matches to be listed immediately instead of ringing the bell.
The default value is @code{off}.
The default value is @samp{off}.
@item expand-tilde
@vindex expand-tilde
If set to @code{on}, tilde expansion is performed when Readline
attempts word completion. The default is @code{off}.
@item visible-stats
@vindex visible-stats
If set to @samp{on}, a character denoting a file's type
is appended to the filename when listing possible
completions. The default is @samp{off}.
@end table
@ -399,13 +465,13 @@ comfortable for you.
@example
Control-u: universal-argument
Meta-Rubout: backward-kill-word
Control-o: ">&output"
Control-o: "> output"
@end example
In the above example, @samp{C-u} is bound to the function
@code{universal-argument}, and @samp{C-o} is bound to run the macro
expressed on the right hand side (that is, to insert the text
@samp{>&output} into the line).
@samp{> output} into the line).
@item @w{"@var{keyseq}": @var{function-name} or @var{macro}}
@var{keyseq} differs from @var{keyname} above in that strings
@ -445,10 +511,10 @@ backslash
When entering the text of a macro, single or double quotes should
be used to indicate a macro definition. Unquoted text
is assumed to be a function name. Backslash
will quote any character in the macro text, including @key{"}
and @key{'}.
For example, the following binding will make @kbd{C-x \}
insert a single @key{\} into the line:
will quote any character in the macro text, including @samp{"}
and @samp{'}.
For example, the following binding will make @samp{C-x \}
insert a single @samp{\} into the line:
@example
"\C-x\\": "\\"
@end example
@ -464,7 +530,7 @@ compilation features of the C preprocessor which allows key
bindings and variable settings to be performed as the result
of tests. There are three parser directives used.
@ftable @code
@table @code
@item $if
The @code{$if} construct allows bindings to be made based on the
editing mode, the terminal being used, or the application using
@ -486,7 +552,7 @@ key bindings, perhaps to bind the key sequences output by the
terminal's function keys. The word on the right side of the
@samp{=} is tested against the full name of the terminal and the
portion of the terminal name before the first @samp{-}. This
allows @var{sun} to match both @var{sun} and @var{sun-cmd},
allows @code{sun} to match both @code{sun} and @code{sun-cmd},
for instance.
@item application
@ -497,7 +563,7 @@ This could be used to bind key sequences to functions useful for
a specific program. For instance, the following command adds a
key sequence that quotes the current or previous word in Bash:
@example
$if bash
$if Bash
# Quote the current or previous word
"\C-xq": "\eb\"\ef\""
$endif
@ -511,7 +577,109 @@ This command, as you saw in the previous example, terminates an
@item $else
Commands in this branch of the @code{$if} directive are executed if
the test fails.
@end ftable
@end table
@node Sample Init File
@subsection Sample Init File
Here is an example of an inputrc file. This illustrates key
binding, variable assignment, and conditional syntax.
@example
@page
# This file controls the behaviour of line input editing for
# programs that use the Gnu Readline library. Existing programs
# include FTP, Bash, and Gdb.
#
# You can re-read the inputrc file with C-x C-r.
# Lines beginning with '#' are comments.
#
# Set various bindings for emacs mode.
set editing-mode emacs
$if mode=emacs
Meta-Control-h: backward-kill-word Text after the function name is ignored
#
# Arrow keys in keypad mode
#
#"\M-OD" backward-char
#"\M-OC" forward-char
#"\M-OA" previous-history
#"\M-OB" next-history
#
# Arrow keys in ANSI mode
#
"\M-[D" backward-char
"\M-[C" forward-char
"\M-[A" previous-history
"\M-[B" next-history
#
# Arrow keys in 8 bit keypad mode
#
#"\M-\C-OD" backward-char
#"\M-\C-OC" forward-char
#"\M-\C-OA" previous-history
#"\M-\C-OB" next-history
#
# Arrow keys in 8 bit ANSI mode
#
#"\M-\C-[D" backward-char
#"\M-\C-[C" forward-char
#"\M-\C-[A" previous-history
#"\M-\C-[B" next-history
C-q: quoted-insert
$endif
# An old-style binding. This happens to be the default.
TAB: complete
# Macros that are convenient for shell interaction
$if Bash
# edit the path
"\C-xp": "PATH=$@{PATH@}\e\C-e\C-a\ef\C-f"
# prepare to type a quoted word -- insert open and close double quotes
# and move to just after the open quote
"\C-x\"": "\"\"\C-b"
# insert a backslash (testing backslash escapes in sequences and macros)
"\C-x\\": "\\"
# Quote the current or previous word
"\C-xq": "\eb\"\ef\""
# Add a binding to refresh the line, which is unbound
"\C-xr": redraw-current-line
# Edit variable on current line.
"\M-\C-v": "\C-a\C-k$\C-y\M-\C-e\C-a\C-y="
$endif
# use a visible bell if one is available
set bell-style visible
# don't strip characters to 7 bits when reading
set input-meta on
# allow iso-latin1 characters to be inserted rather than converted to
# prefix-meta sequences
set convert-meta off
# display characters with the eighth bit set directly rather than
# as meta-prefixed characters
set output-meta on
# if there are more than 150 possible completions for a word, ask the
# user if he wants to see all of them
set completion-query-items 150
# For FTP
$if Ftp
"\C-xg": "get \M-?"
"\C-xt": "put \M-?"
"\M-.": yank-last-arg
$endif
@end example
@node Bindable Readline Commands
@section Bindable Readline Commands
@ -527,6 +695,9 @@ the test fails.
* Miscellaneous Commands:: Other miscellaneous commands.
@end menu
This section describes Readline commands that may be bound to key
sequences.
@node Commands For Moving
@subsection Commands For Moving
@ftable @code
@ -608,12 +779,13 @@ for a string supplied by the user.
@item history-search-forward ()
Search forward through the history for the string of characters
between the start of the current line and the current point. This
is a non-incremental search. By default, this command is unbound.
between the start of the current line and the current cursor
position (the `point'). This is a non-incremental search. By
default, this command is unbound.
@item history-search-backward ()
Search backward through the history for the string of characters
between the start of the current line and the current point. This
between the start of the current line and the point. This
is a non-incremental search. By default, this command is unbound.
@item yank-nth-arg (M-C-y)
@ -624,8 +796,8 @@ in the previous command begin with word 0). A negative argument
inserts the @var{n}th word from the end of the previous command.
@item yank-last-arg (M-., M-_)
Insert last argument to the previous command (the last word on the
previous line). With an
Insert last argument to the previous command (the last word of the
previous history entry). With an
argument, behave exactly like @code{yank-nth-arg}.
@end ftable
@ -637,7 +809,7 @@ argument, behave exactly like @code{yank-nth-arg}.
@item delete-char (C-d)
Delete the character under the cursor. If the cursor is at the
beginning of the line, there are no characters in the line, and
the last character typed was not C-d, then return EOF.
the last character typed was not @kbd{C-d}, then return @code{EOF}.
@item backward-delete-char (Rubout)
Delete the character behind the cursor. A numeric arg says to kill
@ -714,6 +886,23 @@ boundary. The killed text is saved on the kill-ring.
@item delete-horizontal-space ()
Delete all spaces and tabs around point. By default, this is unbound.
@item kill-region ()
Kill the text between the point and the @emph{mark} (saved
cursor position. This text is referred to as the @var{region}.
By default, this command is unbound.
@item copy-region-as-kill ()
Copy the text in the region to the kill buffer, so you can yank it
right away. By default, this command is unbound.
@item copy-backward-word ()
Copy the word before point to the kill buffer.
By default, this command is unbound.
@item copy-forward-word ()
Copy the word following point to the kill buffer.
By default, this command is unbound.
@item yank (C-y)
Yank the top of the kill ring into the buffer at the current
cursor position.
@ -729,7 +918,7 @@ the prior command is yank or yank-pop.
@item digit-argument (M-0, M-1, ... M--)
Add this digit to the argument already accumulating, or start a new
argument. M-- starts a negative argument.
argument. @key{M--} starts a negative argument.
@item universal-argument ()
Each time this is executed, the argument count is multiplied by four.
@ -750,18 +939,74 @@ you can do command completion, if you are typing in a symbol to GDB, you
can do symbol name completion, if you are typing in a variable to Bash,
you can do variable name completion, and so on.
@ifset BashFeatures
See the Bash manual page for a complete list of available completion
functions.
Bash attempts completion treating the text as a variable (if the
text begins with @samp{$}), username (if the text begins with
@samp{~}), hostname (if the text begins with @samp{@@}), or
command (including aliases and functions) in turn. If none
of these produces a match, filename completion is attempted.
@end ifset
@item possible-completions (M-?)
List the possible completions of the text before the cursor.
@item insert-completions ()
@item insert-completions (M-*)
Insert all completions of the text before point that would have
been generated by @code{possible-completions}. By default, this
is not bound to a key.
been generated by @code{possible-completions}.
@ifset BashFeatures
@item complete-filename (M-/)
Attempt filename completion on the text before point.
@item possible-filename-completions (C-x /)
List the possible completions of the text before point,
treating it as a filename.
@item complete-username (M-~)
Attempt completion on the text before point, treating
it as a username.
@item possible-username-completions (C-x ~)
List the possible completions of the text before point,
treating it as a username.
@item complete-variable (M-$)
Attempt completion on the text before point, treating
it as a shell variable.
@item possible-variable-completions (C-x $)
List the possible completions of the text before point,
treating it as a shell variable.
@item complete-hostname (M-@@)
Attempt completion on the text before point, treating
it as a hostname.
@item possible-hostname-completions (C-x @@)
List the possible completions of the text before point,
treating it as a hostname.
@item complete-command (M-!)
Attempt completion on the text before point, treating
it as a command name. Command completion attempts to
match the text against aliases, reserved words, shell
functions, builtins, and finally executable filenames,
in that order.
@item possible-command-completions (C-x !)
List the possible completions of the text before point,
treating it as a command name.
@item dynamic-complete-history (M-TAB)
Attempt completion on the text before point, comparing
the text against lines from the history list for possible
completion matches.
@item complete-into-braces (M-@{)
Perform filename completion and return the list of possible completions
enclosed within braces so the list is available to the shell
(@pxref{Brace Expansion}).
@end ifset
@end ftable
@node Keyboard Macros
@ -786,7 +1031,7 @@ in the macro appear as if typed at the keyboard.
@ftable @code
@item re-read-init-file (C-x C-r)
Read in the contents of your init file, and incorporate
Read in the contents of the inputrc file, and incorporate
any bindings or variable assignments found there.
@item abort (C-g)
@ -794,9 +1039,9 @@ Abort the current editing command and
ring the terminal's bell (subject to the setting of
@code{bell-style}).
@item do-uppercase-version (M-a, M-b, ...)
Run the command that is bound to the corresoponding uppercase
character.
@item do-uppercase-version (M-a, M-b, M-@var{x}, @dots{})
If the metafied character @var{x} is lowercase, run the command
that is bound to the corresponding uppercase character.
@item prefix-meta (ESC)
Make the next character that you type be metafied. This is for people
@ -813,13 +1058,59 @@ command enough times to get back to the beginning.
@item tilde-expand (M-~)
Perform tilde expansion on the current word.
@item set-mark (C-@@)
Set the mark to the current point. If a
numeric argument is supplied, the mark is set to that position.
@item exchange-point-and-mark (C-x C-x)
Swap the point with the mark. The current cursor position is set to
the saved position, and the old cursor position is saved as the mark.
@item character-search (C-])
A character is read and point is moved to the next occurrence of that
character. A negative count searches for previous occurrences.
@item character-search-backward (M-C-])
A character is read and point is moved to the previous occurrence
of that character. A negative count searches for subsequent
occurrences.
@item insert-comment (M-#)
The value of the @code{comment-begin}
variable is inserted at the beginning of the current line,
and the line is accepted as if a newline had been typed.
@ifset BashFeatures
This makes the current line a shell comment.
@end ifset
@item dump-functions ()
Print all of the functions and their key bindings to the
readline output stream. If a numeric argument is supplied,
the output is formatted in such a way that it can be made part
of an @var{inputrc} file.
of an @var{inputrc} file. This command is unbound by default.
@item dump-variables ()
Print all of the settable variables and their values to the
readline output stream. If a numeric argument is supplied,
the output is formatted in such a way that it can be made part
of an @var{inputrc} file. This command is unbound by default.
@item dump-macros ()
Print all of the readline key sequences bound to macros and the
strings they ouput. If a numeric argument is supplied,
the output is formatted in such a way that it can be made part
of an @var{inputrc} file. This command is unbound by default.
@ifset BashFeatures
@item glob-expand-word (C-x *)
The word before point is treated as a pattern for pathname expansion,
and the list of matching file names is inserted, replacing the word.
@item glob-list-expansions (C-x g)
The list of expansions that would have been generated by
@code{glob-expand-word}
is inserted into the line, replacing the word before point.
@item display-shell-version (C-x C-v)
Display version information about the current instance of Bash.
@ -841,7 +1132,7 @@ argument is ignored.
@item emacs-editing-mode (C-e)
When in @code{vi} editing mode, this causes a switch back to
emacs editing mode, as if the command @code{set -o emacs} had
@code{emacs} editing mode, as if the command @samp{set -o emacs} had
been executed.
@end ifset
@ -854,15 +1145,15 @@ been executed.
While the Readline library does not have a full set of @code{vi}
editing functions, it does contain enough to allow simple editing
of the line. The Readline @code{vi} mode behaves as specified in
the Posix 1003.2 standard.
the @sc{POSIX} 1003.2 standard.
@ifset BashFeatures
In order to switch interactively between @code{Emacs} and @code{Vi}
editing modes, use the @code{set -o emacs} and @code{set -o vi}
In order to switch interactively between @code{emacs} and @code{vi}
editing modes, use the @samp{set -o emacs} and @samp{set -o vi}
commands (@pxref{The Set Builtin}).
@end ifset
@ifclear BashFeatures
In order to switch interactively between @code{Emacs} and @code{Vi}
In order to switch interactively between @code{emacs} and @code{vi}
editing modes, use the command M-C-j (toggle-editing-mode).
@end ifclear
The Readline default is @code{emacs} mode.
@ -871,5 +1162,5 @@ When you enter a line in @code{vi} mode, you are already placed in
`insertion' mode, as if you had typed an @samp{i}. Pressing @key{ESC}
switches you into `command' mode, where you can edit the text of the
line with the standard @code{vi} movement keys, move to previous
history lines with @samp{k}, and following lines with @samp{j}, and
history lines with @samp{k} and subsequent lines with @samp{j}, and
so forth.

File diff suppressed because it is too large Load diff

View file

@ -33,7 +33,7 @@
KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
/* Control keys. */
{ ISFUNC, (Function *)0x0 }, /* Control-@ */
{ ISFUNC, rl_set_mark }, /* Control-@ */
{ ISFUNC, rl_beg_of_line }, /* Control-a */
{ ISFUNC, rl_backward }, /* Control-b */
{ ISFUNC, (Function *)0x0 }, /* Control-c */
@ -62,7 +62,7 @@ KEYMAP_ENTRY_ARRAY emacs_standard_keymap = {
{ ISFUNC, (Function *)0x0 }, /* Control-z */
{ ISKMAP, (Function *)emacs_meta_keymap }, /* Control-[ */
{ ISFUNC, (Function *)0x0 }, /* Control-\ */
{ ISFUNC, (Function *)0x0 }, /* Control-] */
{ ISFUNC, rl_char_search }, /* Control-] */
{ ISFUNC, (Function *)0x0 }, /* Control-^ */
{ ISFUNC, rl_undo_command }, /* Control-_ */
@ -358,22 +358,22 @@ KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
{ ISFUNC, rl_complete }, /* Meta-Control-[ */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-\ */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-] */
{ ISFUNC, rl_backward_char_search }, /* Meta-Control-] */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-^ */
{ ISFUNC, (Function *)0x0 }, /* Meta-Control-_ */
/* The start of printing characters. */
{ ISFUNC, (Function *)0x0 }, /* Meta-SPACE */
{ ISFUNC, rl_set_mark }, /* Meta-SPACE */
{ ISFUNC, (Function *)0x0 }, /* Meta-! */
{ ISFUNC, (Function *)0x0 }, /* Meta-" */
{ ISFUNC, (Function *)0x0 }, /* Meta-# */
{ ISFUNC, rl_insert_comment },/* Meta-# */
{ ISFUNC, (Function *)0x0 }, /* Meta-$ */
{ ISFUNC, (Function *)0x0 }, /* Meta-% */
{ ISFUNC, rl_tilde_expand }, /* Meta-& */
{ ISFUNC, (Function *)0x0 }, /* Meta-' */
{ ISFUNC, (Function *)0x0 }, /* Meta-( */
{ ISFUNC, (Function *)0x0 }, /* Meta-) */
{ ISFUNC, (Function *)0x0 }, /* Meta-* */
{ ISFUNC, rl_insert_completions }, /* Meta-* */
{ ISFUNC, (Function *)0x0 }, /* Meta-+ */
{ ISFUNC, (Function *)0x0 }, /* Meta-, */
{ ISFUNC, rl_digit_argument }, /* Meta-- */
@ -396,7 +396,7 @@ KEYMAP_ENTRY_ARRAY emacs_meta_keymap = {
{ ISFUNC, (Function *)0x0 }, /* Meta-: */
{ ISFUNC, (Function *)0x0 }, /* Meta-; */
{ ISFUNC, rl_beginning_of_history }, /* Meta-< */
{ ISFUNC, (Function *)0x0 }, /* Meta-= */
{ ISFUNC, rl_possible_completions }, /* Meta-= */
{ ISFUNC, rl_end_of_history }, /* Meta-> */
{ ISFUNC, rl_possible_completions }, /* Meta-? */
{ ISFUNC, (Function *)0x0 }, /* Meta-@ */
@ -632,7 +632,7 @@ KEYMAP_ENTRY_ARRAY emacs_ctlx_keymap = {
{ ISFUNC, rl_undo_command }, /* Control-u */
{ ISFUNC, (Function *)0x0 }, /* Control-v */
{ ISFUNC, (Function *)0x0 }, /* Control-w */
{ ISFUNC, (Function *)0x0 }, /* Control-x */
{ ISFUNC, rl_exchange_point_and_mark },/* Control-x */
{ ISFUNC, (Function *)0x0 }, /* Control-y */
{ ISFUNC, (Function *)0x0 }, /* Control-z */
{ ISFUNC, (Function *)0x0 }, /* Control-[ */

View file

@ -1,12 +1,19 @@
# This is the Makefile for the examples subdirectory of readline. -*- text -*-
#
EXECUTABLES = fileman
CFLAGS = -g -I../..
EXECUTABLES = fileman rltest
CFLAGS = -g -I../.. -I..
LDFLAGS = -g -L..
.c.o:
$(CC) $(CFLAGS) -c $<
all: $(EXECUTABLES)
fileman: fileman.o
$(CC) $(LDFLAGS) -o fileman fileman.o -lreadline -ltermcap
$(CC) $(LDFLAGS) -o $@ fileman.o -lreadline -ltermcap
rltest: rltest.o
$(CC) $(LDFLAGS) -o $@ rltest.o -lreadline -ltermcap
fileman.o: fileman.c
rltest.o: rltest.c

View file

@ -194,10 +194,11 @@ initialize_readline ()
rl_attempted_completion_function = (CPPFunction *)fileman_completion;
}
/* Attempt to complete on the contents of TEXT. START and END show the
region of TEXT that contains the word to complete. We can use the
entire line in case we want to do some simple parsing. Return the
array of matches, or NULL if there aren't any. */
/* Attempt to complete on the contents of TEXT. START and END bound the
region of rl_line_buffer that contains the word to complete. TEXT is
the word to complete. We can use the entire contents of rl_line_buffer
in case we want to do some simple parsing. Return the array of matches,
or NULL if there aren't any. */
char **
fileman_completion (text, start, end)
char *text;

View file

@ -0,0 +1,54 @@
/* **************************************************************** */
/* */
/* Testing Readline */
/* */
/* **************************************************************** */
#include <stdio.h>
#include <sys/types.h>
#include "../readline.h"
#include "../history.h"
main ()
{
HIST_ENTRY **history_list ();
char *temp = (char *)NULL;
char *prompt = "readline$ ";
int done = 0;
while (!done)
{
temp = readline (prompt);
/* Test for EOF. */
if (!temp)
exit (1);
/* If there is anything on the line, print it and remember it. */
if (*temp)
{
fprintf (stderr, "%s\r\n", temp);
add_history (temp);
}
/* Check for `command' that we handle. */
if (strcmp (temp, "quit") == 0)
done = 1;
if (strcmp (temp, "list") == 0)
{
HIST_ENTRY **list = history_list ();
register int i;
if (list)
{
for (i = 0; list[i]; i++)
{
fprintf (stderr, "%d: %s\r\n", i, list[i]->line);
free (list[i]->line);
}
free (list);
}
}
free (temp);
}
}

View file

@ -21,11 +21,11 @@
675 Mass Ave, Cambridge, MA 02139, USA. */
#define READLINE_LIBRARY
#if defined (STATIC_MALLOC)
static char *xmalloc (), *xrealloc ();
#else
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
extern char *xmalloc (), *xrealloc ();
#endif /* STATIC_MALLOC */
#if !defined (BUFSIZ)
#include <stdio.h>
@ -40,18 +40,17 @@ extern char *xmalloc (), *xrealloc ();
#include "rlconf.h"
#include "readline.h"
static int qsort_string_compare ();
extern int _rl_qsort_string_compare ();
FUNMAP **funmap = (FUNMAP **)NULL;
static int funmap_size = 0;
static int funmap_entry = 0;
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 },
@ -64,26 +63,35 @@ static FUNMAP default_funmap[] = {
{ "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-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-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-char", rl_forward },
{ "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 },
{ "next-history", rl_get_next_history },
{ "non-incremental-forward-search-history", rl_noninc_forward_search },
@ -98,6 +106,7 @@ static FUNMAP default_funmap[] = {
{ "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 },
@ -118,6 +127,7 @@ static FUNMAP default_funmap[] = {
{ "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-bracktype", rl_vi_bracktype },
{ "vi-bword", rl_vi_bword },
@ -126,7 +136,6 @@ static FUNMAP default_funmap[] = {
{ "vi-change-to", rl_vi_change_to },
{ "vi-char-search", rl_vi_char_search },
{ "vi-column", rl_vi_column },
{ "vi-comment", rl_vi_comment },
{ "vi-complete", rl_vi_complete },
{ "vi-delete", rl_vi_delete },
{ "vi-delete-to", rl_vi_delete_to },
@ -136,8 +145,10 @@ static FUNMAP default_funmap[] = {
{ "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 },
@ -151,6 +162,7 @@ static FUNMAP default_funmap[] = {
{ "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 },
@ -160,16 +172,16 @@ static FUNMAP default_funmap[] = {
{(char *)NULL, (Function *)NULL }
};
int
rl_add_funmap_entry (name, function)
char *name;
Function *function;
{
if (funmap_entry + 2 >= funmap_size)
if (!funmap)
funmap = (FUNMAP **)xmalloc ((funmap_size = 80) * sizeof (FUNMAP *));
else
funmap =
(FUNMAP **)xrealloc (funmap, (funmap_size += 80) * sizeof (FUNMAP *));
{
funmap_size += 64;
funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *));
}
funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
funmap[funmap_entry]->name = name;
@ -179,7 +191,7 @@ rl_add_funmap_entry (name, function)
return funmap_entry;
}
static int funmap_initialized = 0;
static int funmap_initialized;
/* Make the funmap contain all of the default entries. */
void
@ -203,46 +215,28 @@ rl_initialize_funmap ()
char **
rl_funmap_names ()
{
char **result = (char **)NULL;
char **result;
int result_size, result_index;
result_size = result_index = 0;
/* Make sure that the function map has been initialized. */
rl_initialize_funmap ();
for (result_index = 0; funmap[result_index]; result_index++)
for (result_index = result_size = 0, result = (char **)NULL; funmap[result_index]; result_index++)
{
if (result_index + 2 > result_size)
{
if (!result)
result = (char **)xmalloc ((result_size = 20) * sizeof (char *));
else
result = (char **)
xrealloc (result, (result_size += 20) * sizeof (char *));
result_size += 20;
result = (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 *), qsort_string_compare);
qsort (result, result_index, sizeof (char *), _rl_qsort_string_compare);
return (result);
}
/* Stupid comparison routine for qsort () ing strings. */
static int
qsort_string_compare (s1, s2)
register char **s1, **s2;
{
int r;
r = **s1 - **s2;
if (r == 0)
r = strcmp (*s1, *s2);
return r;
}
/* Things that mean `Control'. */
char *possible_control_prefixes[] = {
"Control-", "C-", "CTRL-", (char *)NULL
@ -251,49 +245,3 @@ char *possible_control_prefixes[] = {
char *possible_meta_prefixes[] = {
"Meta", "M-", (char *)NULL
};
#if defined (STATIC_MALLOC)
/* **************************************************************** */
/* */
/* xmalloc and xrealloc () */
/* */
/* **************************************************************** */
static void memory_error_and_abort ();
static char *
xmalloc (bytes)
int bytes;
{
char *temp = (char *)malloc (bytes);
if (!temp)
memory_error_and_abort ();
return (temp);
}
static char *
xrealloc (pointer, bytes)
char *pointer;
int bytes;
{
char *temp;
if (!pointer)
temp = (char *)malloc (bytes);
else
temp = (char *)realloc (pointer, bytes);
if (!temp)
memory_error_and_abort ();
return (temp);
}
static void
memory_error_and_abort ()
{
fprintf (stderr, "history: Out of virtual memory!\n");
abort ();
}
#endif /* STATIC_MALLOC */

1358
lib/readline/histexpand.c Normal file

File diff suppressed because it is too large Load diff

324
lib/readline/histfile.c Normal file
View file

@ -0,0 +1,324 @@
/* histfile.c - functions to manipulate the history file. */
/* Copyright (C) 1989, 1992 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, 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>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <fcntl.h>
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STRING_H)
# include <string.h>
#else
# include <strings.h>
#endif /* !HAVE_STRING_H */
#include <errno.h>
#if !defined (errno)
extern int errno;
#endif /* !errno */
#include "history.h"
#include "histlib.h"
extern char *xmalloc (), *xrealloc ();
/* Return the string that should be used in the place of this
filename. This only matters when you don't specify the
filename to read_history (), or write_history (). */
static char *
history_filename (filename)
char *filename;
{
char *return_val, *home;
int home_len;
return_val = filename ? savestring (filename) : (char *)NULL;
if (return_val)
return (return_val);
home = getenv ("HOME");
if (home == 0)
{
home = ".";
home_len = 1;
}
else
home_len = strlen (home);
return_val = xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */
strcpy (return_val, home);
return_val[home_len] = '/';
strcpy (return_val + home_len + 1, ".history");
return (return_val);
}
/* Add the contents of FILENAME to the history list, a line at a time.
If FILENAME is NULL, then read from ~/.history. Returns 0 if
successful, or errno if not. */
int
read_history (filename)
char *filename;
{
return (read_history_range (filename, 0, -1));
}
/* Read a range of lines from FILENAME, adding them to the history list.
Start reading at the FROM'th line and end at the TO'th. If FROM
is zero, start at the beginning. If TO is less than FROM, read
until the end of the file. If FILENAME is NULL, then read from
~/.history. Returns 0 if successful, or errno if not. */
int
read_history_range (filename, from, to)
char *filename;
int from, to;
{
register int line_start, line_end;
char *input, *buffer = (char *)NULL;
int file, current_line;
struct stat finfo;
input = history_filename (filename);
file = open (input, O_RDONLY, 0666);
if ((file < 0) || (fstat (file, &finfo) == -1))
goto error_and_exit;
buffer = xmalloc ((int)finfo.st_size + 1);
if (read (file, buffer, finfo.st_size) != finfo.st_size)
{
error_and_exit:
if (file >= 0)
close (file);
FREE (input);
FREE (buffer);
return (errno);
}
close (file);
/* Set TO to larger than end of file if negative. */
if (to < 0)
to = finfo.st_size;
/* Start at beginning of file, work to end. */
line_start = line_end = current_line = 0;
/* Skip lines until we are at FROM. */
while (line_start < finfo.st_size && current_line < from)
{
for (line_end = line_start; line_end < finfo.st_size; line_end++)
if (buffer[line_end] == '\n')
{
current_line++;
line_start = line_end + 1;
if (current_line == from)
break;
}
}
/* If there are lines left to gobble, then gobble them now. */
for (line_end = line_start; line_end < finfo.st_size; line_end++)
if (buffer[line_end] == '\n')
{
buffer[line_end] = '\0';
if (buffer[line_start])
add_history (buffer + line_start);
current_line++;
if (current_line >= to)
break;
line_start = line_end + 1;
}
FREE (input);
FREE (buffer);
return (0);
}
/* Truncate the history file FNAME, leaving only LINES trailing lines.
If FNAME is NULL, then use ~/.history. */
int
history_truncate_file (fname, lines)
char *fname;
register int lines;
{
register int i;
int file, chars_read;
char *buffer = (char *)NULL, *filename;
struct stat finfo;
filename = history_filename (fname);
file = open (filename, O_RDONLY, 0666);
if (file == -1 || fstat (file, &finfo) == -1)
goto truncate_exit;
buffer = xmalloc ((int)finfo.st_size + 1);
chars_read = read (file, buffer, finfo.st_size);
close (file);
if (chars_read <= 0)
goto truncate_exit;
/* Count backwards from the end of buffer until we have passed
LINES lines. */
for (i = chars_read - 1; lines && i; i--)
{
if (buffer[i] == '\n')
lines--;
}
/* If this is the first line, then the file contains exactly the
number of lines we want to truncate to, so we don't need to do
anything. It's the first line if we don't find a newline between
the current value of i and 0. Otherwise, write from the start of
this line until the end of the buffer. */
for ( ; i; i--)
if (buffer[i] == '\n')
{
i++;
break;
}
/* Write only if there are more lines in the file than we want to
truncate to. */
if (i && ((file = open (filename, O_WRONLY|O_TRUNC, 0666)) != -1))
{
write (file, buffer + i, finfo.st_size - i);
close (file);
}
truncate_exit:
FREE (buffer);
free (filename);
return 0;
}
/* Workhorse function for writing history. Writes NELEMENT entries
from the history list to FILENAME. OVERWRITE is non-zero if you
wish to replace FILENAME with the entries. */
static int
history_do_write (filename, nelements, overwrite)
char *filename;
int nelements, overwrite;
{
register int i;
char *output = history_filename (filename);
int file, mode;
mode = overwrite ? O_WRONLY | O_CREAT | O_TRUNC : O_WRONLY | O_APPEND;
if ((file = open (output, mode, 0666)) == -1)
{
FREE (output);
return (errno);
}
if (nelements > history_length)
nelements = history_length;
/* Build a buffer of all the lines to write, and write them in one syscall.
Suggested by Peter Ho (peter@robosts.oxford.ac.uk). */
{
HIST_ENTRY **the_history; /* local */
register int j;
int buffer_size;
char *buffer;
the_history = history_list ();
/* Calculate the total number of bytes to write. */
for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
buffer_size += 1 + strlen (the_history[i]->line);
/* Allocate the buffer, and fill it. */
buffer = xmalloc (buffer_size);
for (j = 0, i = history_length - nelements; i < history_length; i++)
{
strcpy (buffer + j, the_history[i]->line);
j += strlen (the_history[i]->line);
buffer[j++] = '\n';
}
write (file, buffer, buffer_size);
free (buffer);
}
close (file);
FREE (output);
return (0);
}
/* Append NELEMENT entries to FILENAME. The entries appended are from
the end of the list minus NELEMENTs up to the end of the list. */
int
append_history (nelements, filename)
int nelements;
char *filename;
{
return (history_do_write (filename, nelements, HISTORY_APPEND));
}
/* Overwrite FILENAME with the current history. If FILENAME is NULL,
then write the history list to ~/.history. Values returned
are as in read_history ().*/
int
write_history (filename)
char *filename;
{
return (history_do_write (filename, history_length, HISTORY_OVERWRITE));
}

81
lib/readline/histlib.h Normal file
View file

@ -0,0 +1,81 @@
/* histlib.h -- internal definitions for the history library. */
/* Copyright (C) 1989, 1992 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (_HISTLIB_H_)
#define _HISTLIB_H_
/* Function pointers can be declared as (Function *)foo. */
#if !defined (_FUNCTION_DEF)
# define _FUNCTION_DEF
typedef int Function ();
typedef void VFunction ();
typedef char *CPFunction ();
typedef char **CPPFunction ();
#endif /* _FUNCTION_DEF */
#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
#ifndef savestring
# ifndef strcpy
extern char *strcpy ();
# endif
#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
#endif
#ifndef whitespace
#define whitespace(c) (((c) == ' ') || ((c) == '\t'))
#endif
#ifndef _rl_digit_p
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
#endif
#ifndef _rl_digit_value
#define _rl_digit_value(c) ((c) - '0')
#endif
#ifndef member
# ifndef strchr
extern char *strchr ();
# endif
#define member(c, s) ((c) ? ((char *)strchr ((s), (c)) != (char *)NULL) : 0)
#endif
#ifndef FREE
# define FREE(x) if (x) free (x)
#endif
/* Possible history errors passed to hist_error. */
#define EVENT_NOT_FOUND 0
#define BAD_WORD_SPEC 1
#define SUBST_FAILED 2
#define BAD_MODIFIER 3
/* Possible definitions for history starting point specification. */
#define ANCHORED_SEARCH 1
#define NON_ANCHORED_SEARCH 0
/* Possible definitions for what style of writing the history file we want. */
#define HISTORY_APPEND 0
#define HISTORY_OVERWRITE 1
#endif /* !_HISTLIB_H_ */

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,26 @@
/* History.h -- the names of functions that you can call in history. */
/* Copyright (C) 1989, 1992 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, USA. */
#ifndef _HISTORY_H_
#define _HISTORY_H_
/* The structure used to store a history entry. */
typedef struct _hist_entry {
@ -46,6 +68,9 @@ extern HIST_ENTRY *remove_history ();
invalid WHICH, a NULL pointer is returned. */
extern HIST_ENTRY *replace_history_entry ();
/* Clear the history list and start over. */
extern void clear_history ();
/* Stifle the history list, remembering only MAX number of entries. */
extern void stifle_history ();
@ -179,3 +204,7 @@ extern char history_expansion_char;
extern char history_subst_char;
extern char history_comment_char;
extern char *history_no_expand_chars;
extern char *history_search_delimiter_chars;
extern int history_quotes_inhibit_expansion;
#endif /* !_HISTORY_H_ */

197
lib/readline/histsearch.c Normal file
View file

@ -0,0 +1,197 @@
/* histsearch.c -- searching the history list. */
/* Copyright (C) 1989, 1992 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, USA. */
#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)
# include <unistd.h>
#endif
#if defined (HAVE_STRING_H)
# include <string.h>
#else
# include <strings.h>
#endif /* !HAVE_STRING_H */
#include "history.h"
#include "histlib.h"
/* Variables imported from other history library files. */
extern int history_offset;
/* The list of alternate characters that can delimit a history search
string. */
char *history_search_delimiter_chars = (char *)NULL;
/* Search the history for STRING, starting at history_offset.
If DIRECTION < 0, then the search is through previous entries, else
through subsequent. If ANCHORED is non-zero, the string must
appear at the beginning of a history line, otherwise, the string
may appear anywhere in the line. If the string is found, then
current_history () is the history entry, and the value of this
function is the offset in the line of that history entry that the
string was found in. Otherwise, nothing is changed, and a -1 is
returned. */
static int
history_search_internal (string, direction, anchored)
char *string;
int direction, anchored;
{
register int i, reverse;
register char *line;
register int line_index;
int string_len;
HIST_ENTRY **the_history; /* local */
i = history_offset;
reverse = (direction < 0);
/* Take care of trivial cases first. */
if (string == 0 || *string == '\0')
return (-1);
if (!history_length || ((i == history_length) && !reverse))
return (-1);
if (reverse && (i == history_length))
i--;
#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)
the_history = history_list ();
string_len = strlen (string);
while (1)
{
/* Search each line in the history list for STRING. */
/* At limit for direction? */
if ((reverse && i < 0) || (!reverse && i == history_length))
return (-1);
line = the_history[i]->line;
line_index = strlen (line);
/* If STRING is longer than line, no match. */
if (string_len > line_index)
{
NEXT_LINE ();
continue;
}
/* Handle anchored searches first. */
if (anchored == ANCHORED_SEARCH)
{
if (STREQN (string, line, string_len))
{
history_offset = i;
return (0);
}
NEXT_LINE ();
continue;
}
/* Do substring search. */
if (reverse)
{
line_index -= string_len;
while (line_index >= 0)
{
if (STREQN (string, line + line_index, string_len))
{
history_offset = i;
return (line_index);
}
line_index--;
}
}
else
{
register int limit;
limit = line_index - string_len + 1;
line_index = 0;
while (line_index < limit)
{
if (STREQN (string, line + line_index, string_len))
{
history_offset = i;
return (line_index);
}
line_index++;
}
}
NEXT_LINE ();
}
}
/* Do a non-anchored search for STRING through the history in DIRECTION. */
int
history_search (string, direction)
char *string;
int direction;
{
return (history_search_internal (string, direction, NON_ANCHORED_SEARCH));
}
/* Do an anchored search for string through the history in DIRECTION. */
int
history_search_prefix (string, direction)
char *string;
int direction;
{
return (history_search_internal (string, direction, ANCHORED_SEARCH));
}
/* Search for STRING in the history list. DIR is < 0 for searching
backwards. POS is an absolute index into the history list at
which point to begin searching. */
int
history_search_pos (string, dir, pos)
char *string;
int dir, pos;
{
int ret, old;
old = where_history ();
history_set_pos (pos);
if (history_search (string, dir) == -1)
{
history_set_pos (old);
return (-1);
}
ret = where_history ();
history_set_pos (old);
return ret;
}

449
lib/readline/input.c Normal file
View file

@ -0,0 +1,449 @@
/* input.c -- character input functions 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,
675 Mass Ave, Cambridge, MA 02139, USA. */
#define READLINE_LIBRARY
#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"
/* Some standard library routines. */
#include "readline.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
/* Functions imported from other files in the library. */
extern char *xmalloc (), *xrealloc ();
/* Variables and functions from macro.c. */
extern void _rl_add_macro_char ();
extern void _rl_with_macro_input ();
extern int _rl_next_macro_key ();
extern int _rl_defining_kbd_macro;
#if defined (VI_MODE)
extern void _rl_vi_set_last ();
extern int _rl_vi_textmod_command ();
#endif /* VI_MODE */
extern FILE *rl_instream, *rl_outstream;
extern Function *rl_last_func;
extern int rl_key_sequence_length;
extern int rl_pending_input;
extern int rl_editing_mode;
extern Keymap _rl_keymap;
extern int _rl_convert_meta_chars_to_ascii;
#if defined (__GO32__)
# include <pc.h>
#endif /* __GO32__ */
/* Non-null means it is a pointer to a function to run while waiting for
character input. */
Function *rl_event_hook = (Function *)NULL;
Function *rl_getc_function = rl_getc;
/* **************************************************************** */
/* */
/* 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;
}
/* Add KEY to the buffer of characters to be read. */
int
rl_stuff_char (key)
int key;
{
if (key == EOF)
{
key = NEWLINE;
rl_pending_input = EOF;
}
ibuffer[push_index++] = key;
if (push_index >= ibuffer_len)
push_index = 0;
return push_index;
}
/* Make C be the next command to be executed. */
int
rl_execute_next (c)
int c;
{
rl_pending_input = c;
return 0;
}
/* 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);
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. */
static 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);
}
/* If a character is available to be read, then read it
and stuff it into IBUFFER. Otherwise, just return. */
static void
rl_gather_tyi ()
{
#if defined (__GO32__)
char input;
if (isatty (0) && kbhit () && ibuffer_space ())
{
int i;
i = (*rl_getc_function) (rl_instream);
rl_stuff_char (i);
}
#else /* !__GO32__ */
int tty;
register int tem, result;
int chars_avail;
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 = 100000; /* 0.1 seconds */
if (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) <= 0)
return; /* Nothing to read. */
#endif
result = -1;
#if defined (FIONREAD)
result = ioctl (tty, FIONREAD, &chars_avail);
#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;
}
#endif /* O_NDELAY */
/* If there's nothing available, don't waste time trying to read
something. */
if (chars_avail <= 0)
return;
tem = ibuffer_space ();
if (chars_avail > tem)
chars_avail = tem;
/* One cannot read all of the available input. I can only read a single
character at a time, or else programs which require input can be
thwarted. If the buffer is larger than one character, I lose.
Damn! */
if (tem < ibuffer_len)
chars_avail = 0;
if (result != -1)
{
while (chars_avail--)
rl_stuff_char ((*rl_getc_function) (rl_instream));
}
else
{
if (chars_avail)
rl_stuff_char (input);
}
#endif /* !__GO32__ */
}
/* Is there input available to be read on the readline input file
descriptor? Only works if the system has select(2) or FIONREAD. */
int
_rl_input_available ()
{
#if defined(HAVE_SELECT)
fd_set readfds, exceptfds;
struct timeval timeout;
#endif
#if 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 = 100000; /* 0.1 seconds */
return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
#endif
#if defined (FIONREAD)
if (ioctl (tty, FIONREAD, &chars_avail) == 0)
return (chars_avail);
#endif
return 0;
}
void
_rl_insert_typein (c)
int c;
{
int key, t, i;
char *string;
i = key = 0;
string = 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);
}
/* **************************************************************** */
/* */
/* 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_pending_input = 0;
}
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) ();
rl_gather_tyi ();
}
}
else
{
if (rl_get_char (&c) == 0)
c = (*rl_getc_function) (rl_instream);
}
}
return (c);
}
int
rl_getc (stream)
FILE *stream;
{
int result, flags;
unsigned char c;
#if defined (__GO32__)
if (isatty (0))
return (getkey () & 0x7F);
#endif /* __GO32__ */
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 (EWOULDBLOCK)
if (errno == EWOULDBLOCK)
{
if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0)
return (EOF);
if (flags & O_NDELAY)
{
flags &= ~O_NDELAY;
fcntl (fileno (stream), F_SETFL, flags);
continue;
}
continue;
}
#endif /* EWOULDBLOCK */
#if defined (_POSIX_VERSION) && defined (EAGAIN) && defined (O_NONBLOCK)
if (errno == EAGAIN)
{
if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0)
return (EOF);
if (flags & O_NONBLOCK)
{
flags &= ~O_NONBLOCK;
fcntl (fileno (stream), F_SETFL, flags);
continue;
}
}
#endif /* _POSIX_VERSION && EAGAIN && O_NONBLOCK */
#if !defined (__GO32__)
/* 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);
#endif /* !__GO32__ */
}
}

View file

@ -26,19 +26,22 @@
675 Mass Ave, Cambridge, MA 02139, USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#include "memalloc.h"
#include <sys/types.h>
#include "rldefs.h"
#include "readline.h"
#include "history.h"
#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
/* Variables imported from other files in the readline library. */
extern Keymap _rl_keymap;
extern HIST_ENTRY *saved_line_for_history;
@ -46,6 +49,14 @@ extern int rl_line_buffer_len;
extern int rl_point, rl_end;
extern char *rl_line_buffer;
extern void _rl_save_prompt ();
extern void _rl_restore_prompt ();
extern int rl_execute_next ();
extern void rl_extend_line_buffer ();
extern int _rl_input_available ();
extern char *xmalloc (), *xrealloc ();
static int rl_search_history ();
@ -56,18 +67,18 @@ static char *prev_line_found;
/* 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;
int 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;
int key;
int sign, key;
{
return (rl_search_history (sign, key));
}
@ -83,29 +94,43 @@ rl_display_search (search_string, reverse_p, where)
int reverse_p, where;
{
char *message;
int msglen, searchlen;
message = xmalloc (1 + (search_string ? strlen (search_string) : 0) + 30);
*message = '\0';
searchlen = (search_string && *search_string) ? strlen (search_string) : 0;
message = xmalloc (searchlen + 33);
msglen = 0;
#if defined (NOTDEF)
if (where != -1)
sprintf (message, "[%d]", where + history_base);
{
sprintf (message, "[%d]", where + history_base);
msglen = strlen (message);
}
#endif /* NOTDEF */
strcat (message, "(");
message[msglen++] = '(';
if (reverse_p)
strcat (message, "reverse-");
{
strcpy (message + msglen, "reverse-");
msglen += 8;
}
strcat (message, "i-search)`");
strcpy (message + msglen, "i-search)`");
msglen += 10;
if (search_string)
strcat (message, search_string);
{
strcpy (message + msglen, search_string);
msglen += searchlen;
}
strcpy (message + msglen, "': ");
strcat (message, "': ");
rl_message ("%s", message, 0);
free (message);
rl_redisplay ();
(*rl_redisplay_function) ();
}
/* Search through the history looking for an interactively typed string.
@ -114,8 +139,7 @@ rl_display_search (search_string, reverse_p, where)
backwards. */
static int
rl_search_history (direction, invoking_key)
int direction;
int invoking_key;
int direction, invoking_key;
{
/* The string that the user types in to search for. */
char *search_string;
@ -127,19 +151,17 @@ rl_search_history (direction, invoking_key)
int search_string_size;
/* The list of lines to search through. */
char **lines, *allocated_line = (char *)NULL;
char **lines, *allocated_line;
/* The length of LINES. */
int hlen;
/* Where we get LINES from. */
HIST_ENTRY **hlist = history_list ();
HIST_ENTRY **hlist;
register int i = 0;
int orig_point = rl_point;
int orig_line = where_history ();
int last_found_line = orig_line;
int c, done = 0, found, failed, sline_len;
register int i;
int orig_point, orig_line, last_found_line;
int c, found, failed, sline_len;
/* The line currently being searched. */
char *sline;
@ -148,10 +170,17 @@ rl_search_history (direction, invoking_key)
int line_index;
/* Non-zero if we are doing a reverse search. */
int reverse = (direction < 0);
int reverse;
orig_point = rl_point;
last_found_line = orig_line = where_history ();
reverse = direction < 0;
hlist = history_list ();
allocated_line = (char *)NULL;
/* Create an arrary of pointers to the lines that we want to search. */
maybe_replace_line ();
i = 0;
if (hlist)
for (i = 0; hlist[i]; i++);
@ -176,6 +205,8 @@ rl_search_history (direction, invoking_key)
/* The line where we start the search. */
i = orig_line;
_rl_save_prompt ();
/* Initialize search parameters. */
search_string = xmalloc (search_string_size = 128);
*search_string = '\0';
@ -192,14 +223,13 @@ rl_search_history (direction, invoking_key)
line_index = rl_point;
found = failed = 0;
while (!done)
for (;;)
{
Function *f = (Function *)NULL;
/* Read a key and decide how to proceed. */
c = rl_read_key ();
/* Hack C to Do What I Mean. */
if (_rl_keymap[c].type == ISFUNC)
{
f = _rl_keymap[c].function;
@ -210,78 +240,81 @@ rl_search_history (direction, invoking_key)
c = !reverse ? -1 : -2;
}
/* Let NEWLINE (^J) terminate the search for people who don't like
using ESC. ^M can still be used to terminate the search and
immediately execute the command. */
if (c == ESC || c == NEWLINE)
{
/* 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. */
if (c == ESC && _rl_input_available ()) /* XXX */
rl_execute_next (ESC);
break;
}
if (c >= 0 && (CTRL_CHAR (c) || META_CHAR (c) || c == RUBOUT))
{
rl_execute_next (c);
break;
}
switch (c)
{
case ESC:
done = 1;
continue;
case -1:
if (!search_string_index)
if (search_string_index == 0)
continue;
else if (reverse)
--line_index;
else if (line_index != sline_len)
++line_index;
else
{
if (reverse)
--line_index;
else
{
if (line_index != sline_len)
++line_index;
else
ding ();
}
}
ding ();
break;
/* switch directions */
case -2:
direction = -direction;
reverse = (direction < 0);
reverse = direction < 0;
break;
case CTRL ('G'):
strcpy (rl_line_buffer, lines[orig_line]);
rl_point = orig_point;
rl_end = strlen (rl_line_buffer);
_rl_restore_prompt();
rl_clear_message ();
free (allocated_line);
free (lines);
return 0;
default:
if (CTRL_CHAR (c) || META_CHAR (c) || c == RUBOUT)
/* Add character to search string and continue search. */
if (search_string_index + 2 >= search_string_size)
{
rl_execute_next (c);
done = 1;
continue;
}
else
{
/* Add character to search string and continue search. */
if (search_string_index + 2 >= search_string_size)
{
search_string_size += 128;
search_string = xrealloc (search_string, search_string_size);
}
search_string[search_string_index++] = c;
search_string[search_string_index] = '\0';
break;
search_string_size += 128;
search_string = xrealloc (search_string, search_string_size);
}
search_string[search_string_index++] = c;
search_string[search_string_index] = '\0';
break;
}
found = failed = 0;
while (1)
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;
}
if (STREQN (search_string, sline + line_index, search_string_index))
{
found++;
break;
}
else
line_index += direction;
}
@ -314,10 +347,7 @@ rl_search_history (direction, invoking_key)
break;
/* Now set up the line for searching... */
if (reverse)
line_index = sline_len - search_string_index;
else
line_index = 0;
line_index = reverse ? sline_len - search_string_index : 0;
}
if (failed)
@ -357,6 +387,8 @@ rl_search_history (direction, invoking_key)
/* First put back the original state. */
strcpy (rl_line_buffer, lines[orig_line]);
_rl_restore_prompt ();
/* Free the search string. */
free (search_string);

View file

@ -21,7 +21,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include "config.h"
# include <config.h>
#endif
#if defined (HAVE_STDLIB_H)
@ -41,11 +41,7 @@
extern int rl_do_lowercase_version ();
extern int rl_rubout (), rl_insert ();
#if defined (STATIC_MALLOC)
static char *xmalloc (), *xrealloc ();
#else
extern char *xmalloc (), *xrealloc ();
#endif /* STATIC_MALLOC */
/* **************************************************************** */
/* */
@ -109,7 +105,7 @@ rl_make_keymap ()
newmap[i].function = rl_insert;
newmap[TAB].function = rl_insert;
newmap[RUBOUT].function = rl_rubout;
newmap[RUBOUT].function = rl_rubout; /* RUBOUT == 127 */
newmap[CTRL('H')].function = rl_rubout;
#if KEYMAP_SIZE > 128
@ -152,49 +148,3 @@ rl_discard_keymap (map)
}
}
}
#if defined (STATIC_MALLOC)
/* **************************************************************** */
/* */
/* xmalloc and xrealloc () */
/* */
/* **************************************************************** */
static void memory_error_and_abort ();
static char *
xmalloc (bytes)
int bytes;
{
char *temp = (char *)malloc (bytes);
if (!temp)
memory_error_and_abort ();
return (temp);
}
static char *
xrealloc (pointer, bytes)
char *pointer;
int bytes;
{
char *temp;
if (!pointer)
temp = (char *)malloc (bytes);
else
temp = (char *)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 ();
}
#endif /* STATIC_MALLOC */

View file

@ -29,8 +29,8 @@
# include <readline/chardefs.h>
#endif
#if !defined (__FUNCTION_DEF)
# define __FUNCTION_DEF
#if !defined (_FUNCTION_DEF)
# define _FUNCTION_DEF
typedef int Function ();
typedef void VFunction ();
typedef char *CPFunction ();

547
lib/readline/kill.c Normal file
View file

@ -0,0 +1,547 @@
/* kill.c -- kill ring management. */
/* 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, 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> /* for _POSIX_VERSION */
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
extern int _rl_last_command_was_kill;
extern int rl_editing_mode;
extern int rl_explicit_arg;
extern Function *rl_last_func;
extern void _rl_init_argument ();
extern int _rl_set_mark_at_pos ();
extern void _rl_abort_internal ();
extern char *xmalloc (), *xrealloc ();
/* **************************************************************** */
/* */
/* Killing Mechanism */
/* */
/* **************************************************************** */
/* What we assume for a max number of kills. */
#define DEFAULT_MAX_KILLS 10
/* The real variable to look at to find out when to flush kills. */
static int rl_max_kills = DEFAULT_MAX_KILLS;
/* Where to store killed text. */
static char **rl_kill_ring = (char **)NULL;
/* Where we are in the kill ring. */
static int rl_kill_index;
/* How many slots we have in the kill ring. */
static int rl_kill_ring_length;
/* How to say that you only want to save a certain amount
of kill material. */
int
rl_set_retained_kills (num)
int num;
{
return 0;
}
/* Add TEXT to the kill ring, allocating a new kill ring slot as necessary.
This uses TEXT directly, so the caller must not free it. If APPEND is
non-zero, and the last command was a kill, the text is appended to the
current kill ring slot, otherwise prepended. */
static int
_rl_copy_to_kill_ring (text, append)
char *text;
int append;
{
char *old, *new;
int slot;
/* First, find the slot to work with. */
if (_rl_last_command_was_kill == 0)
{
/* Get a new slot. */
if (rl_kill_ring == 0)
{
/* If we don't have any defined, then make one. */
rl_kill_ring = (char **)
xmalloc (((rl_kill_ring_length = 1) + 1) * sizeof (char *));
rl_kill_ring[slot = 0] = (char *)NULL;
}
else
{
/* We have to add a new slot on the end, unless we have
exceeded the max limit for remembering kills. */
slot = rl_kill_ring_length;
if (slot == rl_max_kills)
{
register int i;
free (rl_kill_ring[0]);
for (i = 0; i < slot; i++)
rl_kill_ring[i] = rl_kill_ring[i + 1];
}
else
{
slot = rl_kill_ring_length += 1;
rl_kill_ring = (char **)xrealloc (rl_kill_ring, slot * sizeof (char *));
}
rl_kill_ring[--slot] = (char *)NULL;
}
}
else
slot = rl_kill_ring_length - 1;
/* If the last command was a kill, prepend or append. */
if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
{
old = rl_kill_ring[slot];
new = xmalloc (1 + strlen (old) + strlen (text));
if (append)
{
strcpy (new, old);
strcat (new, text);
}
else
{
strcpy (new, text);
strcat (new, old);
}
free (old);
free (text);
rl_kill_ring[slot] = new;
}
else
rl_kill_ring[slot] = text;
rl_kill_index = slot;
return 0;
}
/* The way to kill something. This appends or prepends to the last
kill, if the last command was a kill command. if FROM is less
than TO, then the text is appended, otherwise prepended. If the
last command was not a kill command, then a new slot is made for
this kill. */
int
rl_kill_text (from, to)
int from, to;
{
char *text;
/* Is there anything to kill? */
if (from == to)
{
_rl_last_command_was_kill++;
return 0;
}
text = rl_copy_text (from, to);
/* Delete the copied text from the line. */
rl_delete_text (from, to);
_rl_copy_to_kill_ring (text, from < to);
_rl_last_command_was_kill++;
return 0;
}
/* Now REMEMBER! In order to do prepending or appending correctly, kill
commands always make rl_point's original position be the FROM argument,
and rl_point's extent be the TO argument. */
/* **************************************************************** */
/* */
/* Killing Commands */
/* */
/* **************************************************************** */
/* Delete the word at point, saving the text in the kill ring. */
int
rl_kill_word (count, key)
int count, key;
{
int orig_point = rl_point;
if (count < 0)
return (rl_backward_kill_word (-count, key));
else
{
rl_forward_word (count, key);
if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point);
rl_point = orig_point;
}
return 0;
}
/* Rubout the word before point, placing it on the kill ring. */
int
rl_backward_kill_word (count, ignore)
int count, ignore;
{
int orig_point = rl_point;
if (count < 0)
return (rl_kill_word (-count, ignore));
else
{
rl_backward_word (count, ignore);
if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point);
}
return 0;
}
/* Kill from here to the end of the line. If DIRECTION is negative, kill
back to the line start instead. */
int
rl_kill_line (direction, ignore)
int direction, ignore;
{
int orig_point = rl_point;
if (direction < 0)
return (rl_backward_kill_line (1, ignore));
else
{
rl_end_of_line (1, ignore);
if (orig_point != rl_point)
rl_kill_text (orig_point, rl_point);
rl_point = orig_point;
}
return 0;
}
/* Kill backwards to the start of the line. If DIRECTION is negative, kill
forwards to the line end instead. */
int
rl_backward_kill_line (direction, ignore)
int direction, ignore;
{
int orig_point = rl_point;
if (direction < 0)
return (rl_kill_line (1, ignore));
else
{
if (!rl_point)
ding ();
else
{
rl_beg_of_line (1, ignore);
rl_kill_text (orig_point, rl_point);
}
}
return 0;
}
/* Kill the whole line, no matter where point is. */
int
rl_kill_full_line (count, ignore)
int count, ignore;
{
rl_begin_undo_group ();
rl_point = 0;
rl_kill_text (rl_point, rl_end);
rl_end_undo_group ();
return 0;
}
/* The next two functions mimic unix line editing behaviour, except they
save the deleted text on the kill ring. This is safer than not saving
it, and since we have a ring, nobody should get screwed. */
/* This does what C-w does in Unix. We can't prevent people from
using behaviour that they expect. */
int
rl_unix_word_rubout (count, key)
int count, key;
{
int orig_point;
if (rl_point == 0)
ding ();
else
{
orig_point = rl_point;
if (count <= 0)
count = 1;
while (count--)
{
while (rl_point && whitespace (rl_line_buffer[rl_point - 1]))
rl_point--;
while (rl_point && (whitespace (rl_line_buffer[rl_point - 1]) == 0))
rl_point--;
}
rl_kill_text (orig_point, rl_point);
}
return 0;
}
/* Here is C-u doing what Unix does. You don't *have* to use these
key-bindings. We have a choice of killing the entire line, or
killing from where we are to the start of the line. We choose the
latter, because if you are a Unix weenie, then you haven't backspaced
into the line at all, and if you aren't, then you know what you are
doing. */
int
rl_unix_line_discard (count, key)
int count, key;
{
if (rl_point == 0)
ding ();
else
{
rl_kill_text (rl_point, 0);
rl_point = 0;
}
return 0;
}
/* Copy the text in the `region' to the kill ring. If DELETE is non-zero,
delete the text from the line as well. */
static int
region_kill_internal (delete)
int delete;
{
char *text;
if (rl_mark == rl_point)
{
_rl_last_command_was_kill++;
return 0;
}
text = rl_copy_text (rl_point, rl_mark);
if (delete)
rl_delete_text (rl_point, rl_mark);
_rl_copy_to_kill_ring (text, rl_point < rl_mark);
_rl_last_command_was_kill++;
return 0;
}
/* Copy the text in the region to the kill ring. */
int
rl_copy_region_to_kill (count, ignore)
int count, ignore;
{
return (region_kill_internal (0));
}
/* Kill the text between the point and mark. */
int
rl_kill_region (count, ignore)
int count, ignore;
{
return (region_kill_internal (1));
}
/* Copy COUNT words to the kill ring. DIR says which direction we look
to find the words. */
static int
_rl_copy_word_as_kill (count, dir)
int count, dir;
{
int om, op, r;
om = rl_mark;
op = rl_point;
if (dir > 0)
rl_forward_word (count, 0);
else
rl_backward_word (count, 0);
rl_mark = rl_point;
if (dir > 0)
rl_backward_word (count, 0);
else
rl_forward_word (count, 0);
r = region_kill_internal (0);
rl_mark = om;
rl_point = op;
return r;
}
int
rl_copy_forward_word (count, key)
int count, key;
{
if (count < 0)
return (rl_copy_backward_word (-count, key));
return (_rl_copy_word_as_kill (count, 1));
}
int
rl_copy_backward_word (count, key)
int count, key;
{
if (count < 0)
return (rl_copy_forward_word (-count, key));
return (_rl_copy_word_as_kill (count, -1));
}
/* Yank back the last killed text. This ignores arguments. */
int
rl_yank (count, ignore)
int count, ignore;
{
if (rl_kill_ring == 0)
{
_rl_abort_internal ();
return -1;
}
_rl_set_mark_at_pos (rl_point);
rl_insert_text (rl_kill_ring[rl_kill_index]);
return 0;
}
/* If the last command was yank, or yank_pop, and the text just
before point is identical to the current kill item, then
delete that text from the line, rotate the index down, and
yank back some other text. */
int
rl_yank_pop (count, key)
int count, key;
{
int l, n;
if (((rl_last_func != rl_yank_pop) && (rl_last_func != rl_yank)) ||
!rl_kill_ring)
{
_rl_abort_internal ();
return -1;
}
l = strlen (rl_kill_ring[rl_kill_index]);
n = rl_point - l;
if (n >= 0 && STREQN (rl_line_buffer + n, rl_kill_ring[rl_kill_index], l))
{
rl_delete_text (n, rl_point);
rl_point = n;
rl_kill_index--;
if (rl_kill_index < 0)
rl_kill_index = rl_kill_ring_length - 1;
rl_yank (1, 0);
return 0;
}
else
{
_rl_abort_internal ();
return -1;
}
}
/* Yank the COUNTth argument from the previous history line. */
int
rl_yank_nth_arg (count, ignore)
int count, ignore;
{
register HIST_ENTRY *entry;
char *arg;
entry = previous_history ();
if (entry)
next_history ();
else
{
ding ();
return -1;
}
arg = history_arg_extract (count, count, entry->line);
if (!arg || !*arg)
{
ding ();
return -1;
}
rl_begin_undo_group ();
#if defined (VI_MODE)
/* Vi mode always inserts a space before yanking the argument, and it
inserts it right *after* rl_point. */
if (rl_editing_mode == vi_mode)
{
rl_vi_append_mode ();
rl_insert_text (" ");
}
#endif /* VI_MODE */
rl_insert_text (arg);
free (arg);
rl_end_undo_group ();
return 0;
}
/* Yank the last argument from the previous history line. This `knows'
how rl_yank_nth_arg treats a count of `$'. With an argument, this
behaves the same as rl_yank_nth_arg. */
int
rl_yank_last_arg (count, key)
int count, key;
{
if (rl_explicit_arg)
return (rl_yank_nth_arg (count, key));
else
return (rl_yank_nth_arg ('$', key));
}

277
lib/readline/macro.c Normal file
View file

@ -0,0 +1,277 @@
/* macro.c -- keyboard macros 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, 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> /* for _POSIX_VERSION */
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
/* Forward definitions. */
void _rl_push_executing_macro (), _rl_pop_executing_macro ();
void _rl_add_macro_char ();
/* Extern declarations. */
extern int rl_explicit_arg;
extern int rl_key_sequence_length;
extern void _rl_abort_internal ();
extern char *xmalloc (), *xrealloc ();
/* **************************************************************** */
/* */
/* Hacking Keyboard Macros */
/* */
/* **************************************************************** */
/* Non-zero means to save keys that we dispatch on in a kbd macro. */
int _rl_defining_kbd_macro = 0;
/* The currently executing macro string. If this is non-zero,
then it is a malloc ()'ed string where input is coming from. */
char *_rl_executing_macro = (char *)NULL;
/* The offset in the above string to the next character to be read. */
static int executing_macro_index;
/* The current macro string being built. Characters get stuffed
in here by add_macro_char (). */
static char *current_macro = (char *)NULL;
/* The size of the buffer allocated to current_macro. */
static int current_macro_size;
/* The index at which characters are being added to current_macro. */
static int current_macro_index;
/* A structure used to save nested macro strings.
It is a linked list of string/index for each saved macro. */
struct saved_macro {
struct saved_macro *next;
char *string;
int sindex;
};
/* The list of saved macros. */
static struct saved_macro *macro_list = (struct saved_macro *)NULL;
/* Set up to read subsequent input from STRING.
STRING is free ()'ed when we are done with it. */
void
_rl_with_macro_input (string)
char *string;
{
_rl_push_executing_macro ();
_rl_executing_macro = string;
executing_macro_index = 0;
}
/* Return the next character available from a macro, or 0 if
there are no macro characters. */
int
_rl_next_macro_key ()
{
if (_rl_executing_macro == 0)
return (0);
if (_rl_executing_macro[executing_macro_index] == 0)
{
_rl_pop_executing_macro ();
return (_rl_next_macro_key ());
}
return (_rl_executing_macro[executing_macro_index++]);
}
/* Save the currently executing macro on a stack of saved macros. */
void
_rl_push_executing_macro ()
{
struct saved_macro *saver;
saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
saver->next = macro_list;
saver->sindex = executing_macro_index;
saver->string = _rl_executing_macro;
macro_list = saver;
}
/* Discard the current macro, replacing it with the one
on the top of the stack of saved macros. */
void
_rl_pop_executing_macro ()
{
struct saved_macro *macro;
if (_rl_executing_macro)
free (_rl_executing_macro);
_rl_executing_macro = (char *)NULL;
executing_macro_index = 0;
if (macro_list)
{
macro = macro_list;
_rl_executing_macro = macro_list->string;
executing_macro_index = macro_list->sindex;
macro_list = macro_list->next;
free (macro);
}
}
/* Add a character to the macro being built. */
void
_rl_add_macro_char (c)
int c;
{
if (current_macro_index + 1 >= current_macro_size)
{
if (current_macro == 0)
current_macro = xmalloc (current_macro_size = 25);
else
current_macro = xrealloc (current_macro, current_macro_size += 25);
}
current_macro[current_macro_index++] = c;
current_macro[current_macro_index] = '\0';
}
void
_rl_kill_kbd_macro ()
{
if (current_macro)
{
free (current_macro);
current_macro = (char *) NULL;
}
current_macro_size = current_macro_index = 0;
if (_rl_executing_macro)
{
free (_rl_executing_macro);
_rl_executing_macro = (char *) NULL;
}
executing_macro_index = 0;
_rl_defining_kbd_macro = 0;
}
/* Begin defining a keyboard macro.
Keystrokes are recorded as they are executed.
End the definition with rl_end_kbd_macro ().
If a numeric argument was explicitly typed, then append this
definition to the end of the existing macro, and start by
re-executing the existing macro. */
int
rl_start_kbd_macro (ignore1, ignore2)
int ignore1, ignore2;
{
if (_rl_defining_kbd_macro)
{
_rl_abort_internal ();
return -1;
}
if (rl_explicit_arg)
{
if (current_macro)
_rl_with_macro_input (savestring (current_macro));
}
else
current_macro_index = 0;
_rl_defining_kbd_macro = 1;
return 0;
}
/* Stop defining a keyboard macro.
A numeric argument says to execute the macro right now,
that many times, counting the definition as the first time. */
int
rl_end_kbd_macro (count, ignore)
int count, ignore;
{
if (_rl_defining_kbd_macro == 0)
{
_rl_abort_internal ();
return -1;
}
current_macro_index -= rl_key_sequence_length - 1;
current_macro[current_macro_index] = '\0';
_rl_defining_kbd_macro = 0;
return (rl_call_last_kbd_macro (--count, 0));
}
/* Execute the most recently defined keyboard macro.
COUNT says how many times to execute it. */
int
rl_call_last_kbd_macro (count, ignore)
int count, ignore;
{
if (current_macro == 0)
_rl_abort_internal ();
if (_rl_defining_kbd_macro)
{
ding (); /* no recursive macros */
current_macro[--current_macro_index] = '\0'; /* erase this char */
return 0;
}
while (count--)
_rl_with_macro_input (savestring (current_macro));
return 0;
}
void
rl_push_macro_input (macro)
char *macro;
{
_rl_with_macro_input (macro);
}

View file

@ -1,56 +0,0 @@
/* memalloc.h -- consolidate code for including alloca.h or malloc.h and
defining alloca. */
/* Copyright (C) 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (__MEMALLOC_H__)
# define __MEMALLOC_H__
#if defined (sparc) && defined (sun) && !defined (HAVE_ALLOCA_H)
# define HAVE_ALLOCA_H
#endif
#if defined (__GNUC__) && !defined (HAVE_ALLOCA)
# define HAVE_ALLOCA
#endif
#if defined (HAVE_ALLOCA_H) && !defined (HAVE_ALLOCA)
# define HAVE_ALLOCA
#endif /* HAVE_ALLOCA_H && !HAVE_ALLOCA */
#if !defined (BUILDING_MAKEFILE)
#if defined (__GNUC__)
# undef alloca
# define alloca __builtin_alloca
#else /* !__GNUC__ */
# if defined (HAVE_ALLOCA_H)
# if defined (IBMESA)
# include <malloc.h>
# else /* !IBMESA */
# include <alloca.h>
# endif /* !IBMESA */
# else
extern char *alloca ();
# endif /* !HAVE_ALLOCA_H */
#endif /* !__GNUC__ */
#endif /* !BUILDING_MAKEFILE */
#endif /* __MEMALLOC_H__ */

198
lib/readline/nls.c Normal file
View file

@ -0,0 +1,198 @@
/* nls.c -- skeletal internationalization code. */
/* Copyright (C) 1996 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, 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 <ctype.h>
#include "rldefs.h"
extern int _rl_convert_meta_chars_to_ascii;
extern int _rl_output_meta_chars;
extern int _rl_meta_flag;
/* A list of legal values for the LANG or LC_CTYPE environment variables.
If a locale name in this list is the value for the LC_ALL, LC_CTYPE,
or LANG environment variable (using the first of those with a value),
readline eight-bit mode is enabled. */
static char *legal_lang_values[] =
{
"iso88591",
"iso88592",
"iso88593",
"iso88594",
"iso88595",
"iso88596",
"iso88597",
"iso88598",
"iso88599",
"iso885910",
"koi8r",
0
};
static char *normalize_codeset ();
static char *find_codeset ();
/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
to decide the defaults for 8-bit character input and output. Returns
1 if we set eight-bit mode. */
int
_rl_init_eightbit ()
{
char *lspec, *t;
int i;
lspec = getenv ("LC_ALL");
if (lspec == 0) lspec = getenv ("LC_CTYPE");
if (lspec == 0) lspec = getenv ("LANG");
if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
return (0);
for (i = 0; t && legal_lang_values[i]; i++)
if (STREQ (t, legal_lang_values[i]))
{
_rl_meta_flag = 1;
_rl_convert_meta_chars_to_ascii = 0;
_rl_output_meta_chars = 1;
#if defined (HAVE_SETLOCALE)
setlocale (LC_CTYPE, lspec);
#endif
break;
}
free (t);
return (legal_lang_values[i] ? 1 : 0);
}
static char *
normalize_codeset (codeset)
char *codeset;
{
size_t namelen, i;
int len, all_digits;
char *wp, *retval;
codeset = find_codeset (codeset, &namelen);
if (codeset == 0)
return (codeset);
all_digits = 1;
for (len = 0, i = 0; i < namelen; i++)
{
if (isalnum (codeset[i]))
{
len++;
all_digits &= isdigit (codeset[i]);
}
}
retval = (char *)malloc ((all_digits ? 3 : 0) + len + 1);
if (retval == 0)
return ((char *)0);
wp = retval;
/* Add `iso' to beginning of an all-digit codeset */
if (all_digits)
{
*wp++ = 'i';
*wp++ = 's';
*wp++ = 'o';
}
for (i = 0; i < namelen; i++)
if (isalpha (codeset[i]))
*wp++ = (isupper (codeset[i])) ? tolower (codeset[i]) : codeset[i];
else if (isdigit (codeset[i]))
*wp++ = codeset[i];
*wp = '\0';
return retval;
}
/* Isolate codeset portion of locale specification. */
static char *
find_codeset (name, lenp)
char *name;
size_t *lenp;
{
char *cp, *language, *result;
cp = language = name;
result = (char *)0;
while (*cp && *cp != '_' && *cp != '@' && *cp != '+' && *cp != ',')
cp++;
/* This does not make sense: language has to be specified. As
an exception we allow the variable to contain only the codeset
name. Perhaps there are funny codeset names. */
if (language == cp)
{
*lenp = strlen (language);
result = language;
}
else
{
/* Next is the territory. */
if (*cp == '_')
do
++cp;
while (*cp && *cp != '.' && *cp != '@' && *cp != '+' && *cp != ',' && *cp != '_');
/* Now, finally, is the codeset. */
result = cp;
if (*cp == '.')
do
++cp;
while (*cp && *cp != '@');
if (cp - result > 2)
{
result++;
*lenp = cp - result;
}
else
{
*lenp = strlen (language);
result = language;
}
}
return result;
}

View file

@ -1,4 +1,4 @@
/* parens.c -- Implemenation of matching parenthesis feature. */
/* parens.c -- Implementation of matching parentheses feature. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
@ -24,7 +24,9 @@
#include "rlconf.h"
#if !defined (PAREN_MATCHING)
extern int rl_insert ();
int
rl_insert_close (count, invoking_key)
int count, invoking_key;
{
@ -33,25 +35,49 @@ rl_insert_close (count, invoking_key)
#else /* PAREN_MATCHING */
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#if defined (FD_SET)
#if defined (FD_SET) && !defined (HAVE_SELECT)
# define HAVE_SELECT
#endif
#if defined (HAVE_SELECT)
# include <sys/time.h>
#endif /* FD_SET */
#endif /* HAVE_SELECT */
#if defined (HAVE_SYS_SELECT_H)
# include <sys/select.h>
#endif
#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__ */
#include "readline.h"
extern int rl_explicit_arg;
/* Non-zero means try to blink the matching open parenthesis when the
close parenthesis is inserted. */
#if defined (FD_SET)
#if defined (HAVE_SELECT)
int rl_blink_matching_paren = 1;
#else /* !FD_SET */
#else /* !HAVE_SELECT */
int rl_blink_matching_paren = 0;
#endif /* !FD_SET */
#endif /* !HAVE_SELECT */
static int find_matching_open ();
int
rl_insert_close (count, invoking_key)
int count, invoking_key;
{
@ -59,13 +85,13 @@ rl_insert_close (count, invoking_key)
rl_insert (count, invoking_key);
else
{
#if defined (FD_SET)
#if defined (HAVE_SELECT)
int orig_point, match_point, ready;
struct timeval timer;
fd_set readfds;
rl_insert (1, invoking_key);
rl_redisplay ();
(*rl_redisplay_function) ();
match_point =
find_matching_open (rl_line_buffer, rl_point - 2, invoking_key);
@ -80,12 +106,12 @@ rl_insert_close (count, invoking_key)
orig_point = rl_point;
rl_point = match_point;
rl_redisplay ();
(*rl_redisplay_function) ();
ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
rl_point = orig_point;
#else /* !FD_SET */
#else /* !HAVE_SELECT */
rl_insert (count, invoking_key);
#endif /* !FD_SET */
#endif /* !HAVE_SELECT */
}
return 0;
}
@ -114,8 +140,8 @@ find_matching_open (string, from, closer)
{
if (delimiter && (string[i] == delimiter))
delimiter = 0;
else if ((string[i] == '\'') || (string[i] == '"'))
delimiter = rl_line_buffer[i];
else if (rl_basic_quote_characters && strchr (rl_basic_quote_characters, string[i]))
delimiter = string[i];
else if (!delimiter && (string[i] == closer))
level++;
else if (!delimiter && (string[i] == opener))

49
lib/readline/posixdir.h Normal file
View file

@ -0,0 +1,49 @@
/* posixdir.h -- Posix directory reading includes and defines. */
/* Copyright (C) 1987,1991 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 1, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* This file should be included instead of <dirent.h> or <sys/dir.h>. */
#if !defined (_POSIXDIR_H_)
#define _POSIXDIR_H_
#if defined (HAVE_DIRENT_H)
# include <dirent.h>
# define D_NAMLEN(d) (strlen ((d)->d_name))
#else
# if defined (HAVE_SYS_NDIR_H)
# include <sys/ndir.h>
# endif
# if defined (HAVE_SYS_DIR_H)
# include <sys/dir.h>
# endif
# if defined (HAVE_NDIR_H)
# include <ndir.h>
# endif
# if !defined (dirent)
# define dirent direct
# endif /* !dirent */
# define D_NAMLEN(d) ((d)->d_namlen)
#endif /* !HAVE_DIRENT_H */
#if defined (STRUCT_DIRENT_HAS_D_INO)
# define d_fileno d_ino
#endif
#endif /* !_POSIXDIR_H_ */

View file

@ -21,34 +21,27 @@
/* This file should be included instead of <sys/stat.h>.
It relies on the local sys/stat.h to work though. */
#if !defined (_POSIXSTAT_H)
#define _POSIXSTAT_H
#if !defined (_POSIXSTAT_H_)
#define _POSIXSTAT_H_
#include <sys/stat.h>
#if defined (isc386)
# if !defined (S_IFDIR)
# define S_IFDIR 0040000
# endif /* !S_IFDIR */
# if !defined (S_IFMT)
# define S_IFMT 0170000
# endif /* !S_IFMT */
#endif /* isc386 */
/* This text is taken directly from the Cadmus I was trying to
compile on:
the following MACROs are defined for X/OPEN compatibility
however, is the param correct ??
#define S_ISBLK(s) ((s.st_mode & S_IFMT) == S_IFBLK)
Well, the answer is no. Thus... */
#if defined (BrainDeath)
#if defined (STAT_MACROS_BROKEN)
# undef S_ISBLK
# undef S_ISCHR
# undef S_ISDIR
# undef S_ISFIFO
# undef S_ISREG
#endif /* BrainDeath */
# undef S_ISLNK
#endif /* STAT_MACROS_BROKEN */
/* These are guaranteed to work only on isc386 */
#if !defined (S_IFDIR) && !defined (S_ISDIR)
# define S_IFDIR 0040000
#endif /* !S_IFDIR && !S_ISDIR */
#if !defined (S_IFMT)
# define S_IFMT 0170000
#endif /* !S_IFMT */
/* Posix 1003.1 5.6.1.1 <sys/stat.h> file types */
@ -114,7 +107,7 @@
/*
* POSIX 1003.1 5.6.1.2 <sys/stat.h> File Modes
*/
#if !defined (S_IRWXU)
# if !defined (S_IREAD)
# define S_IREAD 00400
@ -146,4 +139,4 @@
#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH)
#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
#endif /* _POSIXSTAT_H */
#endif /* _POSIXSTAT_H_ */

File diff suppressed because it is too large Load diff

View file

@ -31,76 +31,7 @@
# include <readline/tilde.h>
#endif
/* The functions for manipulating the text of the line within readline.
Most of these functions are bound to keys by default. */
extern int
rl_tilde_expand (),
rl_beg_of_line (), rl_backward (), rl_delete (), rl_end_of_line (),
rl_forward (), ding (), rl_backward (), rl_newline (), rl_kill_line (),
rl_clear_screen (), rl_get_next_history (), rl_get_previous_history (),
rl_quoted_insert (), rl_reverse_search_history (), rl_transpose_chars (),
rl_unix_line_discard (), rl_quoted_insert (), rl_unix_word_rubout (),
rl_yank (), rl_rubout (), rl_backward_word (), rl_kill_word (),
rl_forward_word (), rl_tab_insert (), rl_yank_pop (), rl_yank_nth_arg (),
rl_backward_kill_word (), rl_backward_kill_line (), rl_transpose_words (),
rl_complete (), rl_possible_completions (), rl_insert_completions (),
rl_do_lowercase_version (), rl_kill_full_line (),
rl_digit_argument (), rl_universal_argument (), rl_abort (),
rl_undo_command (), rl_revert_line (), rl_beginning_of_history (),
rl_end_of_history (), rl_forward_search_history (), rl_insert (),
rl_upcase_word (), rl_downcase_word (), rl_capitalize_word (),
rl_restart_output (), rl_re_read_init_file (), rl_dump_functions (),
rl_delete_horizontal_space (), rl_history_search_forward (),
rl_history_search_backward (), rl_tty_status (), rl_yank_last_arg ();
/* `Public' utility functions. */
extern int rl_insert_text (), rl_delete_text (), rl_kill_text ();
extern int rl_complete_internal ();
extern int rl_expand_prompt ();
extern int rl_initialize ();
extern int rl_set_signals (), rl_clear_signals ();
extern int rl_init_argument (), rl_digit_argument ();
extern int rl_read_key (), rl_getc (), rl_stuff_char ();
extern int maybe_save_line (), maybe_unsave_line (), maybe_replace_line ();
extern int rl_modifying ();
extern int rl_begin_undo_group (), rl_end_undo_group ();
extern void rl_add_undo (), free_undo_list ();
extern int rl_do_undo ();
/* Not available unless readline is compiled -DPAREN_MATCHING. */
extern int rl_insert_close ();
/* These are *both* defined even when VI_MODE is not. */
extern int rl_vi_editing_mode (), rl_emacs_editing_mode ();
/* Non incremental history searching. */
extern int
rl_noninc_forward_search (), rl_noninc_reverse_search (),
rl_noninc_forward_search_again (), rl_noninc_reverse_search_again ();
/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
extern int rl_vi_check (), rl_vi_textmod_command ();
extern int
rl_vi_redo (), rl_vi_tilde_expand (),
rl_vi_movement_mode (), rl_vi_insertion_mode (), rl_vi_arg_digit (),
rl_vi_prev_word (), rl_vi_next_word (), rl_vi_char_search (),
rl_vi_eof_maybe (), rl_vi_append_mode (), rl_vi_put (),
rl_vi_append_eol (), rl_vi_insert_beg (), rl_vi_delete (), rl_vi_comment (),
rl_vi_first_print (), rl_vi_fword (), rl_vi_fWord (), rl_vi_bword (),
rl_vi_bWord (), rl_vi_eword (), rl_vi_eWord (), rl_vi_end_word (),
rl_vi_change_case (), rl_vi_match (), rl_vi_bracktype (),
rl_vi_change_char (), rl_vi_yank_arg (), rl_vi_search (),
rl_vi_search_again (), rl_vi_subst (), rl_vi_overstrike (),
rl_vi_overstrike_delete (), rl_vi_replace(), rl_vi_column (),
rl_vi_delete_to (), rl_vi_change_to (), rl_vi_yank_to (),
rl_vi_complete (), rl_vi_fetch_history ();
/* Keyboard macro commands. */
extern int rl_start_kbd_macro (), rl_end_kbd_macro ();
extern int rl_call_last_kbd_macro ();
extern int rl_arrow_keys(), rl_refresh_line ();
/* Readline data structures. */
/* Maintaining the state of undo. We remember individual deletes and inserts
on a chain of things to do. */
@ -122,19 +53,185 @@ typedef struct undo_list {
extern UNDO_LIST *rl_undo_list;
/* The data structure for mapping textual names to code addresses. */
typedef struct {
typedef struct _funmap {
char *name;
Function *function;
} FUNMAP;
extern FUNMAP **funmap;
/* Functions available to bind to key sequences. */
extern int
rl_tilde_expand (), rl_set_mark (), rl_exchange_point_and_mark (),
rl_beg_of_line (), rl_backward (), rl_delete (), rl_end_of_line (),
rl_forward (), ding (), rl_newline (), rl_kill_line (),
rl_copy_region_to_kill (), rl_kill_region (), rl_char_search (),
rl_clear_screen (), rl_get_next_history (), rl_get_previous_history (),
rl_quoted_insert (), rl_reverse_search_history (), rl_transpose_chars (),
rl_unix_line_discard (), rl_unix_word_rubout (),
rl_yank (), rl_rubout (), rl_backward_word (), rl_kill_word (),
rl_forward_word (), rl_tab_insert (), rl_yank_pop (), rl_yank_nth_arg (),
rl_backward_kill_word (), rl_backward_kill_line (), rl_transpose_words (),
rl_complete (), rl_possible_completions (), rl_insert_completions (),
rl_do_lowercase_version (), rl_kill_full_line (),
rl_digit_argument (), rl_universal_argument (), rl_abort (),
rl_undo_command (), rl_revert_line (), rl_beginning_of_history (),
rl_end_of_history (), rl_forward_search_history (), rl_insert (),
rl_upcase_word (), rl_downcase_word (), rl_capitalize_word (),
rl_restart_output (), rl_re_read_init_file (),
rl_dump_functions (), rl_dump_variables (), rl_dump_macros (),
rl_delete_horizontal_space (), rl_history_search_forward (),
rl_history_search_backward (), rl_tty_status (), rl_yank_last_arg (),
rl_insert_comment (), rl_backward_char_search (),
rl_copy_forward_word (), rl_copy_backward_word ();
/* Not available unless readline is compiled -DPAREN_MATCHING. */
extern int rl_insert_close ();
/* Not available unless READLINE_CALLBACKS is defined. */
extern void rl_callback_handler_install ();
extern void rl_callback_read_char ();
extern void rl_callback_handler_remove ();
/* These are *both* defined even when VI_MODE is not. */
extern int rl_vi_editing_mode (), rl_emacs_editing_mode ();
/* Non incremental history searching. */
extern int
rl_noninc_forward_search (), rl_noninc_reverse_search (),
rl_noninc_forward_search_again (), rl_noninc_reverse_search_again ();
/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
extern int rl_vi_check (), rl_vi_textmod_command ();
extern int
rl_vi_undo (), rl_vi_redo (), rl_vi_tilde_expand (),
rl_vi_movement_mode (), rl_vi_insertion_mode (), rl_vi_arg_digit (),
rl_vi_prev_word (), rl_vi_next_word (), rl_vi_char_search (),
rl_vi_eof_maybe (), rl_vi_append_mode (), rl_vi_put (),
rl_vi_append_eol (), rl_vi_insert_beg (), rl_vi_delete (),
rl_vi_first_print (), rl_vi_fword (), rl_vi_fWord (), rl_vi_bword (),
rl_vi_bWord (), rl_vi_eword (), rl_vi_eWord (), rl_vi_end_word (),
rl_vi_change_case (), rl_vi_match (), rl_vi_bracktype (),
rl_vi_change_char (), rl_vi_yank_arg (), rl_vi_search (),
rl_vi_search_again (), rl_vi_subst (), rl_vi_overstrike (),
rl_vi_overstrike_delete (), rl_vi_replace(), rl_vi_column (),
rl_vi_delete_to (), rl_vi_change_to (), rl_vi_yank_to (),
rl_vi_complete (), rl_vi_fetch_history (), rl_vi_set_mark (),
rl_vi_goto_mark (), rl_vi_back_to_indent ();
/* Keyboard macro commands. */
extern int rl_start_kbd_macro (), rl_end_kbd_macro ();
extern int rl_call_last_kbd_macro ();
extern void rl_push_macro_input ();
extern int rl_arrow_keys(), rl_refresh_line ();
/* **************************************************************** */
/* */
/* Well Published Functions */
/* */
/* **************************************************************** */
/* Readline functions. */
/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */
extern char *readline ();
/* These functions are from bind.c. */
/* rl_add_defun (char *name, Function *function, int key)
Add NAME to the list of named functions. Make FUNCTION
be the function that gets called.
If KEY is not -1, then bind it. */
extern int rl_add_defun ();
extern Keymap rl_make_bare_keymap ();
extern Keymap rl_copy_keymap ();
extern Keymap rl_make_keymap ();
extern void rl_discard_keymap ();
extern Keymap rl_get_keymap (), rl_get_keymap_by_name ();
extern void rl_set_keymap ();
extern char *rl_get_keymap_name ();
extern int rl_bind_key (), rl_bind_key_in_map ();
extern int rl_unbind_key (), rl_unbind_key_in_map ();
extern int rl_set_key ();
extern int rl_generic_bind ();
extern int rl_parse_and_bind ();
/* Backwards compatibility, use rl_generic_bind instead. */
extern int rl_macro_bind (), rl_variable_bind ();
extern int rl_read_init_file ();
extern Function *rl_named_function (), *rl_function_of_keyseq ();
extern char **rl_invoking_keyseqs (), **rl_invoking_keyseqs_in_map ();
extern void rl_function_dumper ();
extern void rl_variable_dumper ();
extern void rl_macro_dumper ();
extern void rl_list_funmap_names ();
/* Undocumented in the texinfo manual; not really useful to programs. */
extern int rl_translate_keyseq ();
extern void rl_initialize_funmap ();
/* Functions for undoing. */
extern int rl_begin_undo_group (), rl_end_undo_group ();
extern void rl_add_undo (), free_undo_list ();
extern int rl_do_undo ();
extern int rl_modifying ();
/* Functions for redisplay. */
extern void rl_redisplay ();
extern int rl_forced_update_display ();
extern int rl_clear_message ();
extern int rl_reset_line_state ();
extern int rl_on_new_line ();
#if defined (__STDC__) && defined (USE_VARARGS) && defined (PREFER_STDARG)
extern int rl_message (const char *, ...);
#else
extern int rl_message ();
#endif
/* Undocumented in texinfo manual. */
extern int rl_character_len ();
extern int rl_show_char ();
extern int crlf ();
/* Modifying text. */
extern int rl_insert_text (), rl_delete_text ();
extern int rl_kill_text ();
extern char *rl_copy_text ();
/* `Public' utility functions. */
extern int rl_reset_terminal ();
extern int rl_stuff_char ();
extern int rl_read_key (), rl_getc ();
extern int rl_initialize ();
/* Undocumented. */
extern int rl_expand_prompt ();
extern int rl_set_signals (), rl_clear_signals ();
extern int maybe_save_line (), maybe_unsave_line (), maybe_replace_line ();
/* Completion functions. */
/* These functions are from complete.c. */
extern int rl_complete_internal ();
/* Return an array of strings which are the result of repeatadly calling
FUNC with TEXT. */
extern char **completion_matches ();
extern char *username_completion_function ();
extern char *filename_completion_function ();
/* **************************************************************** */
/* */
/* Well Published Variables */
/* */
/* **************************************************************** */
/* The version of this incarnation of the readline library. */
extern char *rl_library_version;
/* The name of the calling program. You should initialize this to
whatever was in argv[0]. It is used when parsing conditionals. */
extern char *rl_readline_name;
@ -145,33 +242,36 @@ extern char *rl_line_buffer;
/* The location of point, and end. */
extern int rl_point, rl_end;
extern int rl_mark;
extern int rl_done;
extern int rl_pending_input;
/* The name of the terminal to use. */
extern char *rl_terminal_name;
/* The input and output streams. */
extern FILE *rl_instream, *rl_outstream;
/* 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 char *rl_basic_word_break_characters;
/* If non-zero, then this is the address of a function to call just
before readline_internal () prints the first prompt. */
extern Function *rl_startup_hook;
/* 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 char *rl_completer_word_break_characters;
/* The address of a function to call periodically while Readline is
awaiting character input, or NULL, for no event handling. */
extern Function *rl_event_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 char *rl_completer_quote_characters;
extern Function *rl_getc_function;
extern VFunction *rl_redisplay_function;
extern VFunction *rl_prep_term_function;
extern VFunction *rl_deprep_term_function;
/* 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 char *rl_special_prefixes;
/* Dispatch variables. */
extern Keymap rl_executing_keymap;
extern Keymap rl_binding_keymap;
/* Completion variables. */
/* Pointer to the generator function for completion_matches ().
NULL means to use filename_entry_function (), the default filename
completer. */
@ -194,9 +294,32 @@ extern Function *rl_ignore_some_completions_function;
array of strings returned. */
extern CPPFunction *rl_attempted_completion_function;
/* If non-zero, then this is the address of a function to call just
before readline_internal () prints the first prompt. */
extern Function *rl_startup_hook;
/* 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 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 char *rl_completer_word_break_characters;
/* 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 char *rl_completer_quote_characters;
/* List of quote characters which cause a word break. */
extern char *rl_basic_quote_characters;
/* List of characters that need to be quoted in filenames by the completer. */
extern 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 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
@ -206,14 +329,6 @@ extern Function *rl_directory_completion_hook;
/* Backwards compatibility with previous versions of readline. */
#define rl_symbolic_link_hook rl_directory_completion_hook
/* The address of a function to call periodically while Readline is
awaiting character input, or NULL, for no event handling. */
extern Function *rl_event_hook;
/* Non-zero means that modified history lines are preceded
with an asterisk. */
extern int rl_show_star;
/* 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. */
@ -226,62 +341,49 @@ extern int rl_filename_completion_desired;
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 CPFunction *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 CPFunction *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 Function *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;
/* **************************************************************** */
/* */
/* Well Published Functions */
/* */
/* **************************************************************** */
/* 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;
/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */
extern char *readline ();
/* These functions are from complete.c. */
/* Return an array of strings which are the result of repeatadly calling
FUNC with TEXT. */
extern char **completion_matches ();
extern char *username_completion_function ();
extern char *filename_completion_function ();
/* These functions are from bind.c. */
/* rl_add_defun (char *name, Function *function, int key)
Add NAME to the list of named functions. Make FUNCTION
be the function that gets called.
If KEY is not -1, then bind it. */
extern int rl_add_defun ();
extern int rl_bind_key (), rl_bind_key_in_map ();
extern int rl_unbind_key (), rl_unbind_key_in_map ();
extern int rl_set_key ();
extern int rl_macro_bind (), rl_generic_bind (), rl_variable_bind ();
extern int rl_translate_keyseq ();
extern Function *rl_named_function (), *rl_function_of_keyseq ();
extern int rl_parse_and_bind ();
extern Keymap rl_get_keymap (), rl_get_keymap_by_name ();
extern void rl_set_keymap ();
extern char **rl_invoking_keyseqs (), **rl_invoking_keyseqs_in_map ();
extern void rl_function_dumper ();
extern int rl_read_init_file ();
/* Functions in funmap.c */
extern void rl_list_funmap_names ();
extern void rl_initialize_funmap ();
/* Functions in display.c */
extern void rl_redisplay ();
extern int rl_message (), rl_clear_message ();
extern int rl_reset_line_state ();
extern int rl_character_len ();
extern int rl_show_char ();
extern int crlf (), rl_on_new_line ();
extern int rl_forced_update_display ();
/* 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 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
#if !defined (savestring)
extern char *savestring (); /* XXX backwards compatibility */
#endif

View file

@ -51,7 +51,13 @@
over a character when updating the line rather than rewriting it. */
/* #define HACK_TERMCAP_MOTION */
/* The string inserted by the vi-mode `insert comment' command. */
#define VI_COMMENT_BEGIN_DEFAULT "#"
/* The string inserted by the `insert comment' command. */
#define RL_COMMENT_BEGIN_DEFAULT "#"
/* Define this if you want code that allows readline to be used in an
X `callback' style. */
#if !defined (SHELL)
# define READLINE_CALLBACKS
#endif
#endif /* _RLCONF_H_ */

View file

@ -23,106 +23,33 @@
have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (_RLDEFS_H)
#define _RLDEFS_H
#if !defined (_RLDEFS_H_)
#define _RLDEFS_H_
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
#if !defined (PRAGMA_ALLOCA)
# include "memalloc.h"
#endif
#define NEW_TTY_DRIVER
#define HAVE_BSD_SIGNALS
/* #define USE_XON_XOFF */
#if defined (__linux__) || defined (HAVE_TERMCAP_H)
# include <termcap.h>
#endif /* __linux__ || HAVE_TERMCAP_H */
/* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */
#if defined (USG) && !defined (hpux)
# undef HAVE_BSD_SIGNALS
#endif
/* System V machines use termio. */
#if !defined (_POSIX_VERSION)
# if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || \
defined (DGUX) || defined (HAVE_TERMIO_H)
# undef NEW_TTY_DRIVER
#if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING)
# define TERMIOS_TTY_DRIVER
#else
# if defined (HAVE_TERMIO_H)
# define TERMIO_TTY_DRIVER
# include <termio.h>
# if !defined (TCOON)
# define TCOON 1
# endif
# endif /* USG || hpux || Xenix || sgi || DUGX || HAVE_TERMIO_H */
#endif /* !_POSIX_VERSION */
/* Posix systems use termios and the Posix signal functions. */
#if defined (_POSIX_VERSION)
# if !defined (TERMIOS_MISSING)
# undef NEW_TTY_DRIVER
# define TERMIOS_TTY_DRIVER
# include <termios.h>
# endif /* !TERMIOS_MISSING */
# define HAVE_POSIX_SIGNALS
# if !defined (O_NDELAY)
# define O_NDELAY O_NONBLOCK /* Posix-style non-blocking i/o */
# endif /* O_NDELAY */
#endif /* _POSIX_VERSION */
/* System V.3 machines have the old 4.1 BSD `reliable' signal interface. */
#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
# if defined (USGr3) && !defined (XENIX_22)
# if !defined (HAVE_USG_SIGHOLD)
# define HAVE_USG_SIGHOLD
# endif /* !HAVE_USG_SIGHOLD */
# endif /* USGr3 && !XENIX_22 */
#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
/* Other (BSD) machines use sgtty. */
#if defined (NEW_TTY_DRIVER)
# include <sgtty.h>
# else
# define NEW_TTY_DRIVER
# endif
#endif
#if !defined (SHELL) && (defined (_POSIX_VERSION) || defined (USGr3))
# if !defined (HAVE_DIRENT_H)
# define HAVE_DIRENT_H
# endif /* !HAVE_DIRENT_H */
#endif /* !SHELL && (_POSIX_VERSION || USGr3) */
#if defined (HAVE_DIRENT_H)
# include <dirent.h>
# define D_NAMLEN(d) strlen ((d)->d_name)
#else /* !HAVE_DIRENT_H */
# define D_NAMLEN(d) ((d)->d_namlen)
# if defined (USG)
# if defined (Xenix)
# include <sys/ndir.h>
# else /* !Xenix (but USG...) */
# include "ndir.h"
# endif /* !Xenix */
# else /* !USG */
# include <sys/dir.h>
# endif /* !USG */
# if !defined (dirent)
# define dirent direct
# endif /* !dirent */
#endif /* !HAVE_DIRENT_H */
#if defined (USG) && defined (TIOCGWINSZ) && !defined (Linux)
# if defined (HAVE_SYS_STREAM_H)
# include <sys/stream.h>
# endif /* HAVE_SYS_STREAM_H */
# if defined (HAVE_SYS_PTEM_H)
# include <sys/ptem.h>
# endif /* HAVE_SYS_PTEM_H */
# if defined (HAVE_SYS_PTE_H)
# include <sys/pte.h>
# endif /* HAVE_SYS_PTE_H */
#endif /* USG && TIOCGWINSZ && !Linux */
#if defined (HAVE_SYS_STREAM_H)
# include <sys/stream.h>
#endif /* HAVE_SYS_STREAM_H */
#if defined (HAVE_SYS_PTEM_H)
# include <sys/ptem.h>
# define _IO_PTEM_H /* work around SVR4.2 1.1.4 bug */
#endif /* HAVE_SYS_PTEM_H */
#if defined (HAVE_SYS_PTE_H)
# include <sys/pte.h>
#endif /* HAVE_SYS_PTE_H */
/* Posix macro to check file in statbuf for directory-ness.
This requires that <sys/stat.h> be included before this test. */
@ -133,12 +60,6 @@
/* Decide which flavor of the header file describing the C library
string functions to include and include it. */
#if defined (USG) || defined (NeXT)
# if !defined (HAVE_STRING_H)
# define HAVE_STRING_H
# endif /* !HAVE_STRING_H */
#endif /* USG || NeXT */
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
@ -149,33 +70,20 @@
extern char *strchr (), *strrchr ();
#endif /* !strchr && !__STDC__ */
#if defined (HAVE_VARARGS_H)
# include <varargs.h>
#endif /* HAVE_VARARGS_H */
/* This is needed to include support for TIOCGWINSZ and window resizing. */
#if defined (OSF1) || defined (BSD386) || defined (NetBSD) || \
defined (__BSD_4_4__) || defined (FreeBSD) || defined (_386BSD) || \
defined (AIX)
# define GWINSZ_IN_SYS_IOCTL
#if defined (PREFER_STDARG)
# include <stdarg.h>
#else
# if defined (PREFER_VARARGS)
# include <varargs.h>
# endif
#endif
/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and
it is not already defined. It is used both to determine if a
special character is disabled and to disable certain special
characters. Posix systems should set to 0, USG systems to -1. */
#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE)
# if defined (_SVR4_VDISABLE)
# define _POSIX_VDISABLE _SVR4_VDISABLE
# else
# if defined (_POSIX_VERSION)
# define _POSIX_VDISABLE 0
# else /* !_POSIX_VERSION */
# define _POSIX_VDISABLE -1
# endif /* !_POSIX_VERSION */
# endif /* !_SVR4_VDISABLE */
#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
#if defined (HAVE_STRCASECMP)
#define _rl_stricmp strcasecmp
#define _rl_strnicmp strncasecmp
#else
extern int _rl_stricmp (), _rl_strnicmp ();
#endif
#if !defined (emacs_mode)
# define no_mode -1
@ -206,7 +114,33 @@ extern char *xmalloc ();
#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 0x1
#define RL_QF_DOUBLE_QUOTE 0x2
#define RL_QF_BACKSLASH 0x4
/* 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) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
#endif
#if !defined (FREE)
# define FREE(x) if (x) free (x)
#endif
/* CONFIGURATION SECTION */
#include "rlconf.h"
#endif /* !_RLDEFS_H */
#endif /* !_RLDEFS_H_ */

View file

@ -23,7 +23,7 @@
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include "config.h"
# include <config.h>
#endif
#include <sys/types.h>
@ -36,6 +36,12 @@
#endif /* HAVE_UNISTD_H */
#include "rldefs.h"
#if !defined (SHELL) && defined (GWINSZ_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* !SHELL && GWINSZ_IN_SYS_IOCTL */
#include "rltty.h"
#include "readline.h"
#if !defined (errno)
@ -45,11 +51,19 @@ extern int errno;
extern int readline_echoing_p;
extern int _rl_eof_char;
extern int _rl_enable_keypad, _rl_enable_meta;
#if defined (__GO32__)
# include <sys/pc.h>
# include <pc.h>
# undef HANDLE_SIGNALS
#endif /* __GO32__ */
/* Indirect functions to allow apps control over terminal management. */
extern void rl_prep_terminal (), rl_deprep_terminal ();
VFunction *rl_prep_term_function = rl_prep_terminal;
VFunction *rl_deprep_term_function = rl_deprep_terminal;
/* **************************************************************** */
/* */
/* Signal Management */
@ -64,7 +78,7 @@ static int sigint_oldmask;
# endif /* HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
static int sigint_blocked = 0;
static int sigint_blocked;
/* Cause SIGINT to not be delivered until the corresponding call to
release_sigint(). */
@ -113,52 +127,6 @@ release_sigint ()
sigint_blocked = 0;
}
/* **************************************************************** */
/* */
/* Controlling the Meta Key and Keypad */
/* */
/* **************************************************************** */
extern int term_has_meta;
extern char *term_mm;
extern char *term_mo;
extern char *term_ks;
extern char *term_ke;
static int
outchar (c)
int c;
{
return putc (c, rl_outstream);
}
/* Turn on/off the meta key depending on ON. */
static void
control_meta_key (on)
int on;
{
if (term_has_meta)
{
if (on && term_mm)
tputs (term_mm, 1, outchar);
else if (!on && term_mo)
tputs (term_mo, 1, outchar);
}
}
#if 0
static void
control_keypad (on)
int on;
{
if (on && term_ks)
tputs (term_ks, 1, outchar);
else if (!on && term_ke)
tputs (term_ke, 1, outchar);
}
#endif
/* **************************************************************** */
/* */
/* Saving and Restoring the TTY */
@ -166,13 +134,30 @@ control_keypad (on)
/* **************************************************************** */
/* Non-zero means that the terminal is in a prepped state. */
static int terminal_prepped = 0;
static int terminal_prepped;
/* If non-zero, means that this process has called tcflow(fd, TCOOFF)
and output is suspended. */
#if defined (__ksr1__)
static int ksrflow = 0;
static int ksrflow;
#endif
#if !defined (SHELL) && defined (TIOCGWINSZ)
/* Dummy call to force a backgrounded readline to stop before it tries
to get the tty settings. */
static void
set_winsize (tty)
int tty;
{
struct winsize w;
if (ioctl (tty, TIOCGWINSZ, &w) == 0)
(void) ioctl (tty, TIOCSWINSZ, &w);
}
#else /* SHELL || !TIOCGWINSZ */
# define set_winsize(tty)
#endif /* SHELL || !TIOCGWINSZ */
#if defined (NEW_TTY_DRIVER)
/* Values for the `flags' field of a struct bsdtty. This tells which
@ -204,12 +189,7 @@ get_tty_settings (tty, tiop)
int tty;
TIOTYPE *tiop;
{
#if !defined (SHELL) && defined (TIOCGWINSZ)
struct winsize w;
if (ioctl (tty, TIOCGWINSZ, &w) == 0)
(void) ioctl (tty, TIOCSWINSZ, &w);
#endif
set_winsize (tty);
tiop->flags = tiop->lflag = 0;
@ -234,6 +214,7 @@ get_tty_settings (tty, tiop)
return 0;
}
static int
set_tty_settings (tty, tiop)
int tty;
TIOTYPE *tiop;
@ -360,7 +341,11 @@ prepare_terminal_settings (meta_flag, otio, tiop)
# define TIOTYPE struct termios
# define DRAIN_OUTPUT(fd) tcdrain (fd)
# define GETATTR(tty, tiop) (tcgetattr (tty, tiop))
# define SETATTR(tty, tiop) (tcsetattr (tty, TCSANOW, 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)
@ -376,29 +361,61 @@ static TIOTYPE otio;
# define OUTPUT_BEING_FLUSHED(tp) 0
#endif
static void
rltty_warning (msg)
char *msg;
{
fprintf (stderr, "readline: warning: %s\n", msg);
}
#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;
#if !defined (SHELL) && defined (TIOCGWINSZ)
struct winsize w;
set_winsize (tty);
if (ioctl (tty, TIOCGWINSZ, &w) == 0)
(void) ioctl (tty, TIOCSWINSZ, &w);
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;
}
#if defined (_AIX)
setopost(tiop);
#endif
/* Keep looping if output is being flushed after a ^O (or whatever
the flush character is). */
while ((ioctl_ret = GETATTR (tty, tiop)) < 0 || OUTPUT_BEING_FLUSHED (tiop))
{
if (ioctl_ret < 0 && errno != EINTR)
return -1;
if (OUTPUT_BEING_FLUSHED (tiop))
continue;
errno = 0;
}
return 0;
}
@ -503,7 +520,7 @@ rl_prep_terminal (meta_flag)
int meta_flag;
{
#if !defined (__GO32__)
int tty = fileno (rl_instream);
int tty;
TIOTYPE tio;
if (terminal_prepped)
@ -512,6 +529,8 @@ rl_prep_terminal (meta_flag)
/* Try to keep this function from being INTerrupted. */
block_sigint ();
tty = fileno (rl_instream);
if (get_tty_settings (tty, &tio) < 0)
{
release_sigint ();
@ -528,10 +547,9 @@ rl_prep_terminal (meta_flag)
return;
}
control_meta_key (1);
#if 0
control_keypad (1);
#endif
if (_rl_enable_keypad)
_rl_control_keypad (1);
fflush (rl_outstream);
terminal_prepped = 1;
@ -544,18 +562,19 @@ void
rl_deprep_terminal ()
{
#if !defined (__GO32__)
int tty = fileno (rl_instream);
int tty;
if (!terminal_prepped)
return;
/* Try to keep this function from being INTerrupted. */
/* Try to keep this function from being interrupted. */
block_sigint ();
control_meta_key (0);
#if 0
control_keypad (0);
#endif
tty = fileno (rl_instream);
if (_rl_enable_keypad)
_rl_control_keypad (0);
fflush (rl_outstream);
if (set_tty_settings (tty, &otio) < 0)
@ -576,6 +595,7 @@ rl_deprep_terminal ()
/* */
/* **************************************************************** */
int
rl_restart_output (count, key)
int count, key;
{
@ -608,6 +628,7 @@ rl_restart_output (count, key)
return 0;
}
int
rl_stop_output (count, key)
int count, key;
{
@ -634,7 +655,7 @@ rl_stop_output (count, key)
return 0;
}
/* **************************************************************** */
/* */
/* Default Key Bindings */

61
lib/readline/rltty.h Normal file
View file

@ -0,0 +1,61 @@
/* rltty.h - tty driver-related definitions used by some library files. */
/* Copyright (C) 1995 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (_RLTTY_H_)
#define _RLTTY_H
/* Posix systems use termios and the Posix signal functions. */
#if defined (TERMIOS_TTY_DRIVER)
# include <termios.h>
#endif /* TERMIOS_TTY_DRIVER */
/* System V machines use termio. */
#if defined (TERMIO_TTY_DRIVER)
# include <termio.h>
# if !defined (TCOON)
# define TCOON 1
# endif
#endif /* TERMIO_TTY_DRIVER */
/* Other (BSD) machines use sgtty. */
#if defined (NEW_TTY_DRIVER)
# include <sgtty.h>
#endif
/* Define _POSIX_VDISABLE if we are not using the `new' tty driver and
it is not already defined. It is used both to determine if a
special character is disabled and to disable certain special
characters. Posix systems should set to 0, USG systems to -1. */
#if !defined (NEW_TTY_DRIVER) && !defined (_POSIX_VDISABLE)
# if defined (_SVR4_VDISABLE)
# define _POSIX_VDISABLE _SVR4_VDISABLE
# else
# if defined (_POSIX_VERSION)
# define _POSIX_VDISABLE 0
# else /* !_POSIX_VERSION */
# define _POSIX_VDISABLE -1
# endif /* !_POSIX_VERSION */
# endif /* !_SVR4_DISABLE */
#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
#endif /* _RLTTY_H_ */

View file

@ -22,6 +22,10 @@
675 Mass Ave, Cambridge, MA 02139, USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <stdio.h>
@ -33,16 +37,12 @@
#include "readline.h"
#include "history.h"
#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0))
#define STREQN(a, b, n) (((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
#define abs(x) (((x) > 0) ? (x) : -(x))
extern char *xmalloc (), *xrealloc ();
/* Variables imported from readline.c */
extern int rl_point, rl_end, rl_line_buffer_len;
extern Keymap _rl_keymap;
extern int rl_editing_mode;
extern char *rl_prompt;
extern char *rl_line_buffer;
@ -51,9 +51,12 @@ extern Function *rl_last_func;
/* Functions imported from the rest of the library. */
extern int _rl_free_history_entry ();
extern char *_rl_make_prompt_for_search ();
extern void _rl_restore_prompt ();
extern void rl_extend_line_buffer ();
static char *noninc_search_string = (char *) NULL;
static int noninc_history_pos = 0;
static int noninc_history_pos;
static char *prev_line_found = (char *) NULL;
/* Search the history list for STRING starting at absolute history position
@ -91,7 +94,7 @@ noninc_dosearch (string, dir)
char *string;
int dir;
{
int oldpos, pos;
int oldpos, pos, line_len;
HIST_ENTRY *entry;
if (string == 0 || *string == '\0' || noninc_history_pos < 0)
@ -121,14 +124,10 @@ noninc_dosearch (string, dir)
#endif
history_set_pos (oldpos);
{
int line_len;
line_len = strlen (entry->line);
if (line_len >= rl_line_buffer_len)
rl_extend_line_buffer (line_len);
strcpy (rl_line_buffer, entry->line);
}
line_len = strlen (entry->line);
if (line_len >= rl_line_buffer_len)
rl_extend_line_buffer (line_len);
strcpy (rl_line_buffer, entry->line);
rl_undo_list = (UNDO_LIST *)entry->data;
rl_end = strlen (rl_line_buffer);
@ -150,7 +149,7 @@ noninc_search (dir, pchar)
int dir;
int pchar;
{
int saved_point, c, pmtlen;
int saved_point, c;
char *p;
maybe_save_line ();
@ -160,17 +159,12 @@ noninc_search (dir, pchar)
rl_line_buffer[0] = 0;
rl_end = rl_point = 0;
/* XXX - this needs fixing to work with the prompt expansion stuff - XXX */
pmtlen = (rl_prompt && *rl_prompt) ? strlen (rl_prompt) : 0;
p = xmalloc (2 + pmtlen);
if (pmtlen)
strcpy (p, rl_prompt);
p[pmtlen] = pchar ? pchar : ':';
p[pmtlen + 1] = '\0';
p = _rl_make_prompt_for_search (pchar ? pchar : ':');
rl_message (p, 0, 0);
free (p);
#define SEARCH_RETURN _rl_restore_prompt (); return
/* Read the search string. */
while (c = rl_read_key ())
{
@ -183,9 +177,9 @@ noninc_search (dir, pchar)
maybe_unsave_line ();
rl_clear_message ();
rl_point = saved_point;
return;
SEARCH_RETURN;
}
rl_rubout (1);
rl_rubout (1, c);
break;
case CTRL('W'):
@ -208,13 +202,13 @@ noninc_search (dir, pchar)
rl_clear_message ();
rl_point = saved_point;
ding ();
return;
SEARCH_RETURN;
default:
rl_insert (1, c);
break;
}
rl_redisplay ();
(*rl_redisplay_function) ();
}
dosearch:
@ -226,7 +220,7 @@ noninc_search (dir, pchar)
if (!noninc_search_string)
{
ding ();
return;
SEARCH_RETURN;
}
}
else
@ -238,35 +232,33 @@ noninc_search (dir, pchar)
noninc_search_string = savestring (rl_line_buffer);
}
_rl_restore_prompt ();
noninc_dosearch (noninc_search_string, dir);
}
/* 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;
{
if (key == '?')
noninc_search (1, '?');
else
noninc_search (1, 0);
noninc_search (1, (key == '?') ? '?' : 0);
return 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;
{
if (key == '/')
noninc_search (-1, '/');
else
noninc_search (-1, 0);
noninc_search (-1, (key == '/') ? '/' : 0);
return 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;
{
@ -281,6 +273,7 @@ rl_noninc_forward_search_again (count, key)
/* 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;
{
@ -306,8 +299,14 @@ rl_history_search_internal (count, direction)
while (count)
{
temp = (direction < 0) ? previous_history () : next_history ();
if (!temp)
if (temp == 0)
break;
/* On an empty prefix, make this the same as previous-history. */
if (rl_point == 0)
{
count--;
continue;
}
if (STREQN (rl_line_buffer, temp->line, rl_point))
{
/* Don't find multiple instances of the same line. */
@ -320,7 +319,7 @@ rl_history_search_internal (count, direction)
}
}
if (!temp)
if (temp == 0)
{
if (direction < 0 && old_temp)
temp = old_temp;

View file

@ -21,32 +21,18 @@
675 Mass Ave, Cambridge, MA 02139, USA. */
#define READLINE_LIBRARY
#include <stdio.h>
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h> /* Just for NULL. Yuck. */
#include <sys/types.h>
#include <fcntl.h>
#if !defined (NO_SYS_FILE)
# include <sys/file.h>
#endif /* !NO_SYS_FILE */
#include <signal.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <errno.h>
/* Not all systems declare ERRNO in errno.h... and some systems #define it! */
#if !defined (errno)
extern int errno;
#endif /* !errno */
#include "posixstat.h"
/* System-specific feature definitions and include files. */
#include "rldefs.h"
@ -54,6 +40,11 @@ extern int errno;
# include <sys/ioctl.h>
#endif /* GWINSZ_IN_SYS_IOCTL */
#if defined (__GO32__)
# undef HANDLE_SIGNALS
#endif /* __GO32__ */
#if defined (HANDLE_SIGNALS)
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
@ -63,72 +54,60 @@ extern int rl_pending_input;
extern int _rl_meta_flag;
extern void free_undo_list ();
extern void _rl_get_screen_size ();
extern void _rl_redisplay_after_sigwinch ();
extern void _rl_clean_up_for_exit ();
extern void _rl_kill_kbd_macro ();
extern void _rl_init_argument ();
extern void rl_deprep_terminal (), rl_prep_terminal ();
#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 void
# define SIGHANDLER_RETURN return
#else
# define sighandler int
#endif /* VOID_SIGHANDLER */
# define SIGHANDLER_RETURN return (0)
#endif
/* This typedef is equivalant to the one for Function; it allows us
to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
typedef sighandler SigHandler ();
typedef RETSIGTYPE SigHandler ();
#if defined (__GO32__)
# undef HANDLE_SIGNALS
#endif /* __GO32__ */
static SigHandler *rl_set_sighandler ();
#if defined (STATIC_MALLOC)
static char *xmalloc (), *xrealloc ();
#else
extern char *xmalloc (), *xrealloc ();
#endif /* STATIC_MALLOC */
/* **************************************************************** */
/* */
/* Signal Handling */
/* */
/* **************************************************************** */
#if defined (SIGWINCH)
static SigHandler *old_sigwinch = (SigHandler *)NULL;
#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; } sighandler_cxt;
# define sigemptyset(m)
#endif /* !HAVE_POSIX_SIGNALS */
static sighandler
rl_handle_sigwinch (sig)
int sig;
{
if (readline_echoing_p)
{
_rl_set_screen_size (fileno (rl_instream), 1);
_rl_redisplay_after_sigwinch ();
}
static sighandler_cxt old_int, old_alrm;
if (old_sigwinch &&
old_sigwinch != (SigHandler *)SIG_IGN &&
old_sigwinch != (SigHandler *)SIG_DFL)
(*old_sigwinch) (sig);
#if !defined (VOID_SIGHANDLER)
return (0);
#endif /* VOID_SIGHANDLER */
}
#endif /* SIGWINCH */
#if defined (HANDLE_SIGNALS)
/* Interrupt handling. */
static SigHandler
*old_int = (SigHandler *)NULL,
*old_alrm = (SigHandler *)NULL;
#if !defined (SHELL)
static SigHandler
*old_tstp = (SigHandler *)NULL,
*old_ttou = (SigHandler *)NULL,
*old_ttin = (SigHandler *)NULL,
*old_cont = (SigHandler *)NULL;
static sighandler_cxt old_tstp, old_ttou, old_ttin, old_term;
#endif /* !SHELL */
/* Handle an interrupt character. */
static sighandler
#if defined (SIGWINCH)
static sighandler_cxt old_winch;
#endif
/* Readline signal handler functions. */
static RETSIGTYPE
rl_signal_handler (sig)
int sig;
{
@ -143,9 +122,9 @@ rl_signal_handler (sig)
#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 (sig == SIGINT)
signal (sig, SIG_IGN);
#endif /* !HAVE_BSD_SIGNALS */
if (sig == SIGINT || sig == SIGALRM)
rl_set_sighandler (sig, SIG_IGN, (sighandler_cxt *)NULL);
#endif /* !HAVE_BSD_SIGNALS && !HAVE_POSIX_SIGNALS */
switch (sig)
{
@ -161,7 +140,7 @@ rl_signal_handler (sig)
}
_rl_kill_kbd_macro ();
rl_clear_message ();
rl_init_argument ();
_rl_init_argument ();
#if defined (SIGTSTP)
case SIGTSTP:
@ -169,8 +148,9 @@ rl_signal_handler (sig)
case SIGTTIN:
#endif /* SIGTSTP */
case SIGALRM:
rl_clean_up_for_exit ();
rl_deprep_terminal ();
case SIGTERM:
_rl_clean_up_for_exit ();
(*rl_deprep_term_function) ();
rl_clear_signals ();
rl_pending_input = 0;
@ -194,92 +174,159 @@ rl_signal_handler (sig)
# endif /* HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */
rl_prep_terminal (_rl_meta_flag);
(*rl_prep_term_function) (_rl_meta_flag);
rl_set_signals ();
}
#if !defined (VOID_SIGHANDLER)
return (0);
#endif /* !VOID_SIGHANDLER */
SIGHANDLER_RETURN;
}
#if defined (HAVE_POSIX_SIGNALS)
#if defined (SIGWINCH)
static RETSIGTYPE
rl_handle_sigwinch (sig)
int sig;
{
SigHandler *oh;
if (readline_echoing_p)
{
_rl_get_screen_size (fileno (rl_instream), 1);
_rl_redisplay_after_sigwinch ();
}
/* 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);
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)
rl_set_sighandler (sig, handler, ohandler)
int sig;
SigHandler *handler;
sighandler_cxt *ohandler;
{
struct sigaction act, oact;
#if defined (HAVE_POSIX_SIGNALS)
struct sigaction act;
act.sa_handler = handler;
act.sa_flags = 0;
sigemptyset (&act.sa_mask);
sigemptyset (&oact.sa_mask);
sigaction (sig, &act, &oact);
return (oact.sa_handler);
sigemptyset (&ohandler->sa_mask);
sigaction (sig, &act, ohandler);
#else
ohandler->sa_handler = (SigHandler *)signal (sig, handler);
#endif /* !HAVE_POSIX_SIGNALS */
return (ohandler->sa_handler);
}
#else /* !HAVE_POSIX_SIGNALS */
# define rl_set_sighandler(sig, handler) (SigHandler *)signal (sig, handler)
#endif /* !HAVE_POSIX_SIGNALS */
int
rl_set_signals ()
{
old_int = (SigHandler *)rl_set_sighandler (SIGINT, rl_signal_handler);
if (old_int == (SigHandler *)SIG_IGN)
rl_set_sighandler (SIGINT, SIG_IGN);
sighandler_cxt dummy;
SigHandler *oh;
old_alrm = (SigHandler *)rl_set_sighandler (SIGALRM, rl_signal_handler);
if (old_alrm == (SigHandler *)SIG_IGN)
rl_set_sighandler (SIGALRM, SIG_IGN);
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&dummy.sa_mask);
#endif
oh = rl_set_sighandler (SIGINT, rl_signal_handler, &old_int);
if (oh == (SigHandler *)SIG_IGN)
rl_sigaction (SIGINT, &old_int, &dummy);
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 */
#if !defined (SHELL)
#if defined (SIGTSTP)
old_tstp = (SigHandler *)rl_set_sighandler (SIGTSTP, rl_signal_handler);
if (old_tstp == (SigHandler *)SIG_IGN)
rl_set_sighandler (SIGTSTP, SIG_IGN);
oh = rl_set_sighandler (SIGTSTP, rl_signal_handler, &old_tstp);
if (oh == (SigHandler *)SIG_IGN)
rl_sigaction (SIGTSTP, &old_tstp, &dummy);
#else
oh = (SigHandler *)NULL;
#endif /* SIGTSTP */
#if defined (SIGTTOU)
old_ttou = (SigHandler *)rl_set_sighandler (SIGTTOU, rl_signal_handler);
old_ttin = (SigHandler *)rl_set_sighandler (SIGTTIN, rl_signal_handler);
if (old_tstp == (SigHandler *)SIG_IGN)
#if defined (SIGTTOU)
rl_set_sighandler (SIGTTOU, rl_signal_handler, &old_ttou);
rl_set_sighandler (SIGTTIN, rl_signal_handler, &old_ttin);
if (oh == (SigHandler *)SIG_IGN)
{
rl_set_sighandler (SIGTTOU, SIG_IGN);
rl_set_sighandler (SIGTTIN, SIG_IGN);
rl_set_sighandler (SIGTTOU, SIG_IGN, &dummy);
rl_set_sighandler (SIGTTIN, SIG_IGN, &dummy);
}
#endif /* SIGTTOU */
/* Handle SIGTERM if we're not being compiled as part of bash. */
rl_set_sighandler (SIGTERM, rl_signal_handler, &old_term);
#endif /* !SHELL */
#if defined (SIGWINCH)
old_sigwinch =
(SigHandler *) rl_set_sighandler (SIGWINCH, rl_handle_sigwinch);
rl_set_sighandler (SIGWINCH, rl_handle_sigwinch, &old_winch);
#endif /* SIGWINCH */
return 0;
}
int
rl_clear_signals ()
{
rl_set_sighandler (SIGINT, old_int);
rl_set_sighandler (SIGALRM, old_alrm);
sighandler_cxt dummy;
#if defined (HAVE_POSIX_SIGNALS)
sigemptyset (&dummy.sa_mask);
#endif
rl_sigaction (SIGINT, &old_int, &dummy);
rl_sigaction (SIGALRM, &old_alrm, &dummy);
#if !defined (SHELL)
#if defined (SIGTSTP)
rl_set_sighandler (SIGTSTP, old_tstp);
rl_sigaction (SIGTSTP, &old_tstp, &dummy);
#endif
#if defined (SIGTTOU)
rl_set_sighandler (SIGTTOU, old_ttou);
rl_set_sighandler (SIGTTIN, old_ttin);
rl_sigaction (SIGTTOU, &old_ttou, &dummy);
rl_sigaction (SIGTTIN, &old_ttin, &dummy);
#endif /* SIGTTOU */
rl_sigaction (SIGTERM, &old_term, &dummy);
#endif /* !SHELL */
#if defined (SIGWINCH)
rl_set_sighandler (SIGWINCH, old_sigwinch);
sigemptyset (&dummy.sa_mask);
rl_sigaction (SIGWINCH, &old_winch, &dummy);
#endif
return 0;

57
lib/readline/tcap.h Normal file
View file

@ -0,0 +1,57 @@
/* tcap.h -- termcap library functions and variables. */
/* Copyright (C) 1996 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (_RLTCAP_H_)
#define _RLTCAP_H_
#if defined (HAVE_CONFIG_H)
# include "config.h"
#endif
#if defined (HAVE_TERMCAP_H)
# include <termcap.h>
#else
/* On Solaris2, sys/types.h #includes sys/reg.h, which #defines PC.
Unfortunately, PC is a global variable used by the termcap library. */
#ifdef PC
# undef PC
#endif
extern char PC;
extern char *UP, *BC;
extern short ospeed;
extern int tgetent ();
extern int tgetflag ();
extern int tgetnum ();
extern char *tgetstr ();
extern int tputs ();
extern char *tgoto ();
#endif /* HAVE_TERMCAP_H */
#endif /* !_RLTCAP_H_ */

554
lib/readline/terminal.c Normal file
View file

@ -0,0 +1,554 @@
/* terminal.c -- controlling the terminal with termcap. */
/* Copyright (C) 1996 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, 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 <signal.h>
#include <stdio.h>
#include <setjmp.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "tcap.h"
#if defined (GWINSZ_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* GWINSZ_IN_SYS_IOCTL */
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
/* Variables and functions imported from readline.c */
extern FILE *_rl_in_stream, *_rl_out_stream;
extern int readline_echoing_p;
extern int _rl_bell_preference;
extern Keymap _rl_keymap;
/* **************************************************************** */
/* */
/* Terminal and Termcap */
/* */
/* **************************************************************** */
static char *term_buffer = (char *)NULL;
static char *term_string_buffer = (char *)NULL;
static int tcap_initialized;
/* Non-zero means this terminal can't really do anything. */
static int dumb_term;
#if !defined (__linux__)
/* If this causes problems, add back the `extern'. */
/*extern*/ char PC, *BC, *UP;
#endif /* __linux__ */
/* Some strings to control terminal actions. These are output by tputs (). */
char *term_goto, *term_clreol, *term_cr, *term_clrpag, *term_backspace;
char *term_pc;
/* Non-zero if we determine that the terminal can do character insertion. */
int terminal_can_insert = 0;
/* How to insert characters. */
char *term_im, *term_ei, *term_ic, *term_ip, *term_IC;
/* How to delete characters. */
char *term_dc, *term_DC;
#if defined (HACK_TERMCAP_MOTION)
char *term_forward_char;
#endif /* HACK_TERMCAP_MOTION */
/* How to go up a line. */
char *term_up;
/* A visible bell, if the terminal can be made to flash the screen. */
static char *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 *term_mm, *term_mo;
/* The key sequences output by the arrow keys, if this terminal has any. */
static char *term_ku, *term_kd, *term_kr, *term_kl;
/* How to initialize and reset the arrow keys, if this terminal has any. */
static char *term_ks, *term_ke;
/* The key sequences sent by the Home and End keys, if any. */
static char *term_kh, *term_kH;
/* Variables that hold the screen dimensions, used by the display code. */
int screenwidth, screenheight, 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;
/* Re-initialize the terminal considering that the TERM/TERMCAP variable
has changed. */
int
rl_reset_terminal (terminal_name)
char *terminal_name;
{
_rl_init_terminal_io (terminal_name);
return 0;
}
#if !defined (SHELL)
static void
set_lines_and_columns (lines, cols)
int lines, cols;
{
char *b;
#if defined (HAVE_PUTENV)
b = xmalloc (24);
sprintf (b, "LINES=%d", lines);
putenv (b);
b = xmalloc (24);
sprintf (b, "COLUMNS=%d", cols);
putenv (b);
#else /* !HAVE_PUTENV */
# if defined (HAVE_SETENV)
b = xmalloc (8);
sprintf (b, "%d", lines);
setenv ("LINES", b, 1);
b = xmalloc (8);
sprintf (b, "%d", cols);
setenv ("COLUMNS", b, 1);
# endif /* HAVE_SETENV */
#endif /* !HAVE_PUTENV */
}
#else /* SHELL */
extern void set_lines_and_columns ();
#endif /* SHELL */
/* 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)
{
screenwidth = (int) window_size.ws_col;
screenheight = (int) window_size.ws_row;
}
#endif /* TIOCGWINSZ */
/* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
is unset. */
if (screenwidth <= 0)
{
if (ignore_env == 0 && (ss = getenv ("COLUMNS")))
screenwidth = atoi (ss);
if (screenwidth <= 0 && term_string_buffer)
screenwidth = tgetnum ("co");
}
/* Environment variable LINES overrides setting of "li" if IGNORE_ENV
is unset. */
if (screenheight <= 0)
{
if (ignore_env == 0 && (ss = getenv ("LINES")))
screenheight = atoi (ss);
if (screenheight <= 0 && term_string_buffer)
screenheight = tgetnum ("li");
}
/* If all else fails, default to 80x24 terminal. */
if (screenwidth <= 1)
screenwidth = 80;
if (screenheight <= 0)
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. */
set_lines_and_columns (screenheight, screenwidth);
if (!_rl_term_autowrap)
screenwidth--;
screenchars = screenwidth * screenheight;
}
void
_rl_set_screen_size (rows, cols)
int rows, cols;
{
screenheight = rows;
screenwidth = cols;
if (_rl_term_autowrap == 0)
screenwidth--;
screenchars = screenwidth * screenheight;
}
struct _tc_string {
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[] =
{
"DC", &term_DC,
"IC", &term_IC,
"ce", &term_clreol,
"cl", &term_clrpag,
"cr", &term_cr,
"dc", &term_dc,
"ei", &term_ei,
"ic", &term_ic,
"im", &term_im,
"kd", &term_kd,
"kh", &term_kh, /* home */
"kH", &term_kH, /* end */
"kl", &term_kl,
"kr", &term_kr,
"ku", &term_ku,
"ks", &term_ks,
"ke", &term_ke,
"le", &term_backspace,
"mm", &term_mm,
"mo", &term_mo,
#if defined (HACK_TERMCAP_MOTION)
"nd", &term_forward_char,
#endif
"pc", &term_pc,
"up", &term_up,
"vb", &visible_bell,
};
#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;
{
register int i;
for (i = 0; i < NUM_TC_STRINGS; i++)
*(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
tcap_initialized = 1;
}
int
_rl_init_terminal_io (terminal_name)
char *terminal_name;
{
#if defined (__GO32__)
screenwidth = ScreenCols ();
screenheight = ScreenRows ();
screenchars = screenwidth * screenheight;
term_cr = "\r";
term_im = term_ei = term_ic = term_IC = (char *)NULL;
term_up = term_dc = term_DC = visible_bell = (char *)NULL;
/* Does the __GO32__ have a meta key? I don't know. */
term_has_meta = 0;
term_mm = term_mo = (char *)NULL;
/* It probably has arrow keys, but I don't know what they are. */
term_ku = term_kd = term_kr = term_kl = (char *)NULL;
#if defined (HACK_TERMCAP_MOTION)
term_forward_char = (char *)NULL;
#endif /* HACK_TERMCAP_MOTION */
terminal_can_insert = _rl_term_autowrap = 0;
return;
#else /* !__GO32__ */
char *term, *buffer;
int tty;
Keymap xkeymap;
term = terminal_name ? terminal_name : getenv ("TERM");
if (term_string_buffer == 0)
term_string_buffer = xmalloc (2032);
if (term_buffer == 0)
term_buffer = xmalloc (4080);
buffer = term_string_buffer;
term_clrpag = term_cr = term_clreol = (char *)NULL;
if (term == 0)
term = "dumb";
if (tgetent (term_buffer, term) <= 0)
{
dumb_term = 1;
screenwidth = 79;
screenheight = 24;
screenchars = 79 * 24;
term_cr = "\r";
term_im = term_ei = term_ic = term_IC = (char *)NULL;
term_up = term_dc = term_DC = visible_bell = (char *)NULL;
term_ku = term_kd = term_kl = term_kr = (char *)NULL;
#if defined (HACK_TERMCAP_MOTION)
term_forward_char = (char *)NULL;
#endif
terminal_can_insert = 0;
return 0;
}
get_term_capabilities (&buffer);
/* Set up the variables that the termcap library expects the application
to provide. */
PC = term_pc ? *term_pc : 0;
BC = term_backspace;
UP = term_up;
if (!term_cr)
term_cr = "\r";
tty = rl_instream ? fileno (rl_instream) : 0;
screenwidth = screenheight = 0;
_rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
_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... */
terminal_can_insert = (term_IC || term_im || 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)
term_mm = term_mo = (char *)NULL;
/* Attempt to find and bind the arrow keys. Do not override already
bound keys in an overzealous attempt, however. */
xkeymap = _rl_keymap;
_rl_keymap = emacs_standard_keymap;
_rl_bind_if_unbound (term_ku, rl_get_previous_history);
_rl_bind_if_unbound (term_kd, rl_get_next_history);
_rl_bind_if_unbound (term_kr, rl_forward);
_rl_bind_if_unbound (term_kl, rl_backward);
_rl_bind_if_unbound (term_kh, rl_beg_of_line); /* Home */
_rl_bind_if_unbound (term_kH, rl_end_of_line); /* End */
#if defined (VI_MODE)
_rl_keymap = vi_movement_keymap;
_rl_bind_if_unbound (term_ku, rl_get_previous_history);
_rl_bind_if_unbound (term_kd, rl_get_next_history);
_rl_bind_if_unbound (term_kr, rl_forward);
_rl_bind_if_unbound (term_kl, rl_backward);
_rl_bind_if_unbound (term_kh, rl_beg_of_line); /* Home */
_rl_bind_if_unbound (term_kH, rl_end_of_line); /* End */
#endif /* VI_MODE */
_rl_keymap = xkeymap;
#endif /* !__GO32__ */
return 0;
}
char *
rl_get_termcap (cap)
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);
}
/* A function for the use of tputs () */
int
_rl_output_character_function (c)
int c;
{
return putc (c, _rl_out_stream);
}
/* Write COUNT characters from STRING to the output stream. */
void
_rl_output_some_chars (string, count)
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 !defined (__GO32__)
if (term_backspace)
for (i = 0; i < count; i++)
tputs (term_backspace, 1, _rl_output_character_function);
else
#endif /* !__GO32__ */
for (i = 0; i < count; i++)
putc ('\b', _rl_out_stream);
return 0;
}
/* Move to the start of the next line. */
int
crlf ()
{
#if defined (NEW_TTY_DRIVER)
if (term_cr)
tputs (term_cr, 1, _rl_output_character_function);
#endif /* NEW_TTY_DRIVER */
putc ('\n', _rl_out_stream);
return 0;
}
/* Ring the terminal bell. */
int
ding ()
{
if (readline_echoing_p)
{
#if !defined (__GO32__)
switch (_rl_bell_preference)
{
case NO_BELL:
default:
break;
case VISIBLE_BELL:
if (visible_bell)
{
tputs (visible_bell, 1, _rl_output_character_function);
break;
}
/* FALLTHROUGH */
case AUDIBLE_BELL:
fprintf (stderr, "\007");
fflush (stderr);
break;
}
#else /* __GO32__ */
fprintf (stderr, "\007");
fflush (stderr);
#endif /* __GO32__ */
return (0);
}
return (-1);
}
/* **************************************************************** */
/* */
/* Controlling the Meta Key and Keypad */
/* */
/* **************************************************************** */
static int
outchar (c)
int c;
{
return putc (c, rl_outstream);
}
int
_rl_enable_meta_key ()
{
if (term_has_meta && term_mm)
tputs (term_mm, 1, outchar);
}
void
_rl_control_keypad (on)
int on;
{
if (on && term_ks)
tputs (term_ks, 1, outchar);
else if (!on && term_ke)
tputs (term_ke, 1, outchar);
}

View file

@ -19,6 +19,10 @@
along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if defined (HAVE_STRING_H)
# include <string.h>
#else /* !HAVE_STRING_H */
@ -31,13 +35,14 @@
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include "tilde.h"
#include <sys/types.h>
#include <pwd.h>
#if defined (USG) && !defined (HAVE_GETPW_DECLS)
#include "tilde.h"
#if !defined (HAVE_GETPW_DECLS)
extern struct passwd *getpwuid (), *getpwnam ();
#endif /* USG && !defined (HAVE_GETPW_DECLS) */
#endif /* !HAVE_GETPW_DECLS */
#if !defined (savestring)
extern char *xmalloc ();
@ -171,7 +176,7 @@ tilde_expand (string)
/* Copy the skipped text into the result. */
if ((result_index + start + 1) > result_size)
result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
result = xrealloc (result, 1 + (result_size += (start + 20)));
strncpy (result + result_index, string, start);
result_index += start;
@ -188,7 +193,7 @@ tilde_expand (string)
break;
/* Expand the entire tilde word, and copy it into RESULT. */
tilde_word = (char *)xmalloc (1 + end);
tilde_word = xmalloc (1 + end);
strncpy (tilde_word, string, end);
tilde_word[end] = '\0';
string += end;
@ -198,7 +203,7 @@ tilde_expand (string)
len = strlen (expansion);
if ((result_index + len + 1) > result_size)
result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
result = xrealloc (result, 1 + (result_size += (len + 20)));
strcpy (result + result_index, expansion);
result_index += len;
@ -217,85 +222,90 @@ tilde_expand_word (filename)
char *filename;
{
char *dirname;
char *temp_name;
dirname = filename ? savestring (filename) : (char *)NULL;
if (filename == (char *)0)
return ((char *)NULL);
if (dirname && *dirname == '~')
dirname = savestring (filename);
if (*dirname != '~')
return (dirname);
if (!dirname[1] || dirname[1] == '/')
{
char *temp_name;
if (!dirname[1] || dirname[1] == '/')
/* Prepend $HOME to the rest of the string. */
char *temp_home = (char *)getenv ("HOME");
int home_len;
/* If there is no HOME variable, look up the directory in
the password database. */
if (!temp_home)
{
/* Prepend $HOME to the rest of the string. */
char *temp_home = (char *)getenv ("HOME");
struct passwd *entry;
/* If there is no HOME variable, look up the directory in
the password database. */
if (!temp_home)
entry = getpwuid (getuid ());
if (entry)
temp_home = entry->pw_dir;
}
home_len = temp_home ? strlen (temp_home) : 0;
temp_name = xmalloc (1 + strlen (dirname + 1) + home_len);
if (temp_home)
strcpy (temp_name, temp_home);
strcpy (temp_name + home_len, dirname + 1);
free (dirname);
dirname = temp_name;
}
else
{
char *username;
struct passwd *user_entry;
int i, len;
username = xmalloc (strlen (dirname));
for (i = 1; dirname[i] && dirname[i] != '/'; i++)
username[i - 1] = dirname[i];
username[i - 1] = '\0';
if ((user_entry = getpwnam (username)) == (struct passwd *)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)
{
struct passwd *entry;
char *expansion;
entry = getpwuid (getuid ());
if (entry)
temp_home = entry->pw_dir;
expansion = (*tilde_expansion_failure_hook) (username);
if (expansion)
{
len = strlen (expansion);
temp_name = xmalloc (1 + len + strlen (dirname + i));
strcpy (temp_name, expansion);
strcpy (temp_name + len, dirname + i);
free (expansion);
free (dirname);
dirname = temp_name;
}
}
temp_name = xmalloc (1 + strlen (&dirname[1])
+ (temp_home ? strlen (temp_home) : 0));
temp_name[0] = '\0';
if (temp_home)
strcpy (temp_name, temp_home);
strcat (temp_name, dirname + 1);
free (dirname);
dirname = temp_name;
/* We shouldn't report errors. */
}
else
{
char *username;
struct passwd *user_entry;
int i;
username = xmalloc (strlen (dirname));
for (i = 1; dirname[i] && dirname[i] != '/'; i++)
username[i - 1] = dirname[i];
username[i - 1] = '\0';
if ((user_entry = getpwnam (username)) == 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)
{
char *expansion;
expansion = (*tilde_expansion_failure_hook) (username);
if (expansion)
{
temp_name = xmalloc (1 + strlen (expansion)
+ strlen (&dirname[i]));
strcpy (temp_name, expansion);
strcat (temp_name, &dirname[i]);
free (expansion);
free (dirname);
dirname = temp_name;
}
}
/* We shouldn't report errors. */
}
else
{
temp_name = xmalloc (1 + strlen (user_entry->pw_dir)
+ strlen (&dirname[i]));
strcpy (temp_name, user_entry->pw_dir);
strcat (temp_name, &dirname[i]);
free (dirname);
dirname = temp_name;
}
endpwent ();
free (username);
len = strlen (user_entry->pw_dir);
temp_name = xmalloc (1 + len + strlen (dirname + i));
strcpy (temp_name, user_entry->pw_dir);
strcpy (temp_name + len, dirname + i);
free (dirname);
dirname = temp_name;
}
endpwent ();
free (username);
}
return (dirname);
}
@ -368,7 +378,7 @@ xrealloc (pointer, bytes)
static void
memory_error_and_abort ()
{
fprintf (stderr, "readline: Out of virtual memory!\n");
fprintf (stderr, "readline: out of virtual memory\n");
abort ();
}

View file

@ -1,11 +1,32 @@
/* tilde.h: Externally available variables and function in libtilde.a. */
#if !defined (__TILDE_H__)
# define __TILDE_H__
/* 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, USA. */
#if !defined (_TILDE_H_)
# define _TILDE_H_
/* Function pointers can be declared as (Function *)foo. */
#if !defined (__FUNCTION_DEF)
# define __FUNCTION_DEF
#if !defined (_FUNCTION_DEF)
# define _FUNCTION_DEF
typedef int Function ();
typedef void VFunction ();
typedef char *CPFunction ();
@ -35,4 +56,4 @@ extern char *tilde_expand ();
tilde. If there is no expansion, call tilde_expansion_failure_hook. */
extern char *tilde_expand_word ();
#endif /* __TILDE_H__ */
#endif /* _TILDE_H_ */

261
lib/readline/undo.c Normal file
View file

@ -0,0 +1,261 @@
/* readline.c -- a general facility for reading lines of input
with emacs style editing and completion. */
/* 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, 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> /* 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 <setjmp.h>
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
/* Non-zero tells rl_delete_text and rl_insert_text to not add to
the undo list. */
int _rl_doing_an_undo = 0;
/* How many unclosed undo groups we currently have. */
int _rl_undo_group_level = 0;
/* The current undo list for THE_LINE. */
UNDO_LIST *rl_undo_list = (UNDO_LIST *)NULL;
/* **************************************************************** */
/* */
/* Undo, and Undoing */
/* */
/* **************************************************************** */
/* Remember how to undo something. Concatenate some undos if that
seems right. */
void
rl_add_undo (what, start, end, text)
enum undo_code what;
int start, end;
char *text;
{
UNDO_LIST *temp = (UNDO_LIST *)xmalloc (sizeof (UNDO_LIST));
temp->what = what;
temp->start = start;
temp->end = end;
temp->text = text;
temp->next = rl_undo_list;
rl_undo_list = temp;
}
/* Free the existing undo list. */
void
free_undo_list ()
{
while (rl_undo_list)
{
UNDO_LIST *release = rl_undo_list;
rl_undo_list = rl_undo_list->next;
if (release->what == UNDO_DELETE)
free (release->text);
free (release);
}
rl_undo_list = (UNDO_LIST *)NULL;
}
/* Undo the next thing in the list. Return 0 if there
is nothing to undo, or non-zero if there was. */
int
rl_do_undo ()
{
UNDO_LIST *release;
int waiting_for_begin = 0;
int start, end;
#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i)))
do
{
if (!rl_undo_list)
return (0);
_rl_doing_an_undo = 1;
/* To better support vi-mode, a start or end value of -1 means
rl_point, and a value of -2 means rl_end. */
if (rl_undo_list->what == UNDO_DELETE || rl_undo_list->what == UNDO_INSERT)
{
start = TRANS (rl_undo_list->start);
end = TRANS (rl_undo_list->end);
}
switch (rl_undo_list->what)
{
/* Undoing deletes means inserting some text. */
case UNDO_DELETE:
rl_point = start;
rl_insert_text (rl_undo_list->text);
free (rl_undo_list->text);
break;
/* Undoing inserts means deleting some text. */
case UNDO_INSERT:
rl_delete_text (start, end);
rl_point = start;
break;
/* Undoing an END means undoing everything 'til we get to a BEGIN. */
case UNDO_END:
waiting_for_begin++;
break;
/* Undoing a BEGIN means that we are done with this group. */
case UNDO_BEGIN:
if (waiting_for_begin)
waiting_for_begin--;
else
ding ();
break;
}
_rl_doing_an_undo = 0;
release = rl_undo_list;
rl_undo_list = rl_undo_list->next;
free (release);
}
while (waiting_for_begin);
return (1);
}
#undef TRANS
int
_rl_fix_last_undo_of_type (type, start, end)
int type, start, end;
{
UNDO_LIST *rl;
for (rl = rl_undo_list; rl; rl = rl->next)
{
if (rl->what == type)
{
rl->start = start;
rl->end = end;
return 0;
}
}
return 1;
}
/* Begin a group. Subsequent undos are undone as an atomic operation. */
int
rl_begin_undo_group ()
{
rl_add_undo (UNDO_BEGIN, 0, 0, 0);
_rl_undo_group_level++;
return 0;
}
/* End an undo group started with rl_begin_undo_group (). */
int
rl_end_undo_group ()
{
rl_add_undo (UNDO_END, 0, 0, 0);
_rl_undo_group_level--;
return 0;
}
/* Save an undo entry for the text from START to END. */
int
rl_modifying (start, end)
int start, end;
{
if (start > end)
{
SWAP (start, end);
}
if (start != end)
{
char *temp = rl_copy_text (start, end);
rl_begin_undo_group ();
rl_add_undo (UNDO_DELETE, start, end, temp);
rl_add_undo (UNDO_INSERT, start, end, (char *)NULL);
rl_end_undo_group ();
}
return 0;
}
/* Revert the current line to its previous state. */
int
rl_revert_line (count, key)
int count, key;
{
if (!rl_undo_list)
ding ();
else
{
while (rl_undo_list)
rl_do_undo ();
}
return 0;
}
/* Do some undoing of things that were done. */
int
rl_undo_command (count, key)
int count, key;
{
if (count < 0)
return 0; /* Nothing to do. */
while (count)
{
if (rl_do_undo ())
count--;
else
{
ding ();
break;
}
}
return 0;
}

315
lib/readline/util.c Normal file
View file

@ -0,0 +1,315 @@
/* 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 1, 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,
675 Mass Ave, Cambridge, MA 02139, USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <stdio.h>
#include <sys/types.h>
#include <fcntl.h>
#include <setjmp.h>
#include <ctype.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 */
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#if defined (TIOCSTAT_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* TIOCSTAT_IN_SYS_IOCTL */
/* Some standard library routines. */
#include "readline.h"
#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
/* Pseudo-globals imported from readline.c */
extern int readline_echoing_p;
extern jmp_buf readline_top_level;
extern int rl_line_buffer_len;
extern Function *rl_last_func;
extern int _rl_defining_kbd_macro;
extern char *_rl_executing_macro;
/* Pseudo-global functions imported from other library files. */
extern void _rl_pop_executing_macro ();
extern void _rl_set_the_line ();
extern void _rl_init_argument ();
extern char *xmalloc (), *xrealloc ();
/* **************************************************************** */
/* */
/* 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 char *pathname_alphabetic_chars = "/-_=~.#$";
int
alphabetic (c)
int c;
{
if (ALPHABETIC (c))
return (1);
return (_rl_allow_pathname_alphabetic_chars &&
strchr (pathname_alphabetic_chars, c) != NULL);
}
/* How to abort things. */
int
_rl_abort_internal ()
{
ding ();
rl_clear_message ();
_rl_init_argument ();
rl_pending_input = 0;
_rl_defining_kbd_macro = 0;
while (_rl_executing_macro)
_rl_pop_executing_macro ();
rl_last_func = (Function *)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 ();
#else
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 = 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 = xrealloc (rl_line_buffer, rl_line_buffer_len);
}
_rl_set_the_line ();
}
/* **************************************************************** */
/* */
/* 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 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 (s1 + i);
return ((char *)NULL);
}
#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
}
#if !defined (SHELL)
#ifdef savestring
#undef savestring
#endif
/* Backwards compatibility, now that savestring has been removed from
all `public' readline header files. */
char *
savestring (s)
char *s;
{
return ((char *)strcpy (xmalloc (1 + (int)strlen (s)), (s)));
}
#endif /* !SHELL */
/* Function equivalents for the macros defined in chartypes.h. */
#undef _rl_uppercase_p
int
_rl_uppercase_p (c)
int c;
{
return (isupper (c));
}
#undef _rl_lowercase_p
int
_rl_lowercase_p (c)
int c;
{
return (islower (c));
}
#undef _rl_pure_alphabetic
int
_rl_pure_alphabetic (c)
int c;
{
return (isupper (c) || islower (c));
}
#undef _rl_digit_p
int
_rl_digit_p (c)
int c;
{
return (isdigit (c));
}
#undef _rl_to_lower
int
_rl_to_lower (c)
int c;
{
return (isupper (c) ? tolower (c) : c);
}
#undef _rl_to_upper
int
_rl_to_upper (c)
int c;
{
return (islower (c) ? toupper (c) : c);
}
#undef _rl_digit_value
int
_rl_digit_value (c)
int c;
{
return (isdigit (c) ? c - '0' : c);
}

View file

@ -65,13 +65,13 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
{ ISFUNC, (Function *)0x0 }, /* Control-\ */
{ ISFUNC, (Function *)0x0 }, /* Control-] */
{ ISFUNC, (Function *)0x0 }, /* Control-^ */
{ ISFUNC, rl_undo_command }, /* Control-_ */
{ ISFUNC, rl_vi_undo }, /* Control-_ */
/* The start of printing characters. */
{ ISFUNC, rl_forward }, /* SPACE */
{ ISFUNC, (Function *)0x0 }, /* ! */
{ ISFUNC, (Function *)0x0 }, /* " */
{ ISFUNC, rl_vi_comment }, /* # */
{ ISFUNC, rl_insert_comment }, /* # */
{ ISFUNC, rl_end_of_line }, /* $ */
{ ISFUNC, rl_vi_match }, /* % */
{ ISFUNC, rl_vi_tilde_expand }, /* & */
@ -140,7 +140,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
{ ISFUNC, (Function *)0x0 }, /* ] */
{ ISFUNC, rl_vi_first_print }, /* ^ */
{ ISFUNC, rl_vi_yank_arg }, /* _ */
{ ISFUNC, (Function *)0x0 }, /* ` */
{ ISFUNC, rl_vi_goto_mark }, /* ` */
/* Lowercase alphabet. */
{ ISFUNC, rl_vi_append_mode }, /* a */
@ -155,7 +155,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
{ ISFUNC, rl_get_next_history }, /* j */
{ ISFUNC, rl_get_previous_history }, /* k */
{ ISFUNC, rl_forward }, /* l */
{ ISFUNC, (Function *)0x0 }, /* m */
{ ISFUNC, rl_vi_set_mark }, /* m */
{ ISFUNC, rl_vi_search_again }, /* n */
{ ISFUNC, (Function *)0x0 }, /* o */
{ ISFUNC, rl_vi_put }, /* p */
@ -163,7 +163,7 @@ KEYMAP_ENTRY_ARRAY vi_movement_keymap = {
{ ISFUNC, rl_vi_change_char }, /* r */
{ ISFUNC, rl_vi_subst }, /* s */
{ ISFUNC, rl_vi_char_search }, /* t */
{ ISFUNC, rl_undo_command }, /* u */
{ ISFUNC, rl_vi_undo }, /* u */
{ ISFUNC, (Function *)0x0 }, /* v */
{ ISFUNC, rl_vi_next_word }, /* w */
{ ISFUNC, rl_vi_delete }, /* x */
@ -345,7 +345,7 @@ KEYMAP_ENTRY_ARRAY vi_insertion_keymap = {
{ ISFUNC, rl_insert }, /* Control-\ */
{ ISFUNC, rl_insert }, /* Control-] */
{ ISFUNC, rl_insert }, /* Control-^ */
{ ISFUNC, rl_undo_command }, /* Control-_ */
{ ISFUNC, rl_vi_undo }, /* Control-_ */
/* The start of printing characters. */
{ ISFUNC, rl_insert }, /* SPACE */
@ -630,7 +630,7 @@ KEYMAP_ENTRY_ARRAY vi_escape_keymap = {
{ ISFUNC, (Function *)0x0 }, /* Control-\ */
{ ISFUNC, (Function *)0x0 }, /* Control-] */
{ ISFUNC, (Function *)0x0 }, /* Control-^ */
{ ISFUNC, rl_undo_command }, /* Control-_ */
{ ISFUNC, rl_vi_undo }, /* Control-_ */
/* The start of printing characters. */
{ ISFUNC, (Function *)0x0 }, /* SPACE */

View file

@ -31,6 +31,10 @@
#if defined (VI_MODE)
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#if defined (HAVE_STDLIB_H)
@ -50,12 +54,12 @@
#include "readline.h"
#include "history.h"
#ifndef digit_p
#define digit_p(c) ((c) >= '0' && (c) <= '9')
#ifndef _rl_digit_p
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
#endif
#ifndef digit_value
#define digit_value(c) ((c) - '0')
#ifndef _rl_digit_value
#define _rl_digit_value(c) ((c) - '0')
#endif
#ifndef member
@ -63,22 +67,14 @@
#endif
#ifndef isident
#define isident(c) ((pure_alphabetic (c) || digit_p (c) || c == '_'))
#define isident(c) ((_rl_pure_alphabetic (c) || _rl_digit_p (c) || c == '_'))
#endif
#ifndef exchange
#define exchange(x, y) do {int temp = x; x = y; y = temp;} while (0)
#endif
#ifndef VI_COMMENT_BEGIN_DEFAULT
#define VI_COMMENT_BEGIN_DEFAULT "#"
#endif
#if defined (STATIC_MALLOC)
static char *xmalloc (), *xrealloc ();
#else
extern char *xmalloc (), *xrealloc ();
#endif /* STATIC_MALLOC */
/* Variables imported from readline.c */
extern int rl_point, rl_end, rl_mark, rl_done;
@ -89,47 +85,63 @@ extern char *rl_prompt;
extern char *rl_line_buffer;
extern int rl_arg_sign;
extern int _rl_doing_an_undo;
extern int _rl_undo_group_level;
extern void _rl_dispatch ();
extern int _rl_char_search_internal ();
extern void rl_extend_line_buffer ();
extern int rl_vi_check ();
/* Non-zero means enter insertion mode. */
static int _rl_vi_doing_insert = 0;
static int _rl_vi_doing_insert;
/* String inserted into the line by rl_vi_comment (). */
char *rl_vi_comment_begin = (char *)NULL;
/* *** UNCLEAN *** */
/* Command keys which do movement for xxx_to commands. */
static char *vi_motion = " hl^$0ftFt;,%wbeWBE|";
/* Keymap used for vi replace characters. Created dynamically since
rarely used. */
static Keymap vi_replace_map = (Keymap)NULL;
static Keymap vi_replace_map;
/* The number of characters inserted in the last replace operation. */
static int vi_replace_count = 0;
static int vi_replace_count;
/* If non-zero, we have text inserted after a c[motion] command that put
us implicitly into insert mode. Some people want this text to be
attached to the command so that it is `redoable' with `.'. */
static int vi_continued_command = 0;
static int vi_continued_command;
static char *vi_insert_buffer;
static int vi_insert_buffer_size;
static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
static int _rl_vi_last_repeat = 1;
static int _rl_vi_last_arg_sign = 1;
static int _rl_vi_last_motion = 0;
static int _rl_vi_last_search_char = 0;
static int _rl_vi_last_replacement = 0;
static int _rl_vi_last_motion;
static int _rl_vi_last_search_char;
static int _rl_vi_last_replacement;
static int vi_redoing = 0;
static int _rl_vi_last_key_before_insert;
static int vi_redoing;
/* Text modification commands. These are the `redoable' commands. */
static char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
/* Arrays for the saved marks. */
static int vi_mark_chars[27];
static int rl_digit_loop1 ();
void
_rl_vi_initialize_line ()
{
register int i;
for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
vi_mark_chars[i] = -1;
}
void
_rl_vi_reset_last ()
{
@ -150,15 +162,26 @@ _rl_vi_set_last (key, repeat, sign)
/* Is the command C a VI mode text modification command? */
int
rl_vi_textmod_command (c)
_rl_vi_textmod_command (c)
int c;
{
return (member (c, vi_textmod));
}
static void
_rl_vi_stuff_insert (count)
int count;
{
rl_begin_undo_group ();
while (count--)
rl_insert_text (vi_insert_buffer);
rl_end_undo_group ();
}
/* Bound to `.'. Called from command mode, so we know that we have to
redo a text modification command. The default for _rl_vi_last_command
puts you back into insert mode. */
int
rl_vi_redo (count, c)
int count, c;
{
@ -169,13 +192,32 @@ rl_vi_redo (count, c)
}
vi_redoing = 1;
_rl_dispatch (_rl_vi_last_command, _rl_keymap);
/* If we're redoing an insert with `i', stuff in the inserted text
and do not go into insertion mode. */
if (_rl_vi_last_command == 'i' && vi_insert_buffer && *vi_insert_buffer)
{
_rl_vi_stuff_insert (count);
/* And back up point over the last character inserted. */
if (rl_point > 0)
rl_point--;
}
else
_rl_dispatch (_rl_vi_last_command, _rl_keymap);
vi_redoing = 0;
return (0);
}
/* A placeholder for further expansion. */
int
rl_vi_undo (count, key)
int count, key;
{
return (rl_undo_command (count, key));
}
/* Yank the nth arg from the previous line into this line at point. */
int
rl_vi_yank_arg (count, key)
int count, key;
{
@ -191,10 +233,11 @@ rl_vi_yank_arg (count, key)
/* With an argument, move back that many history lines, else move to the
beginning of history. */
int
rl_vi_fetch_history (count, c)
int count, c;
{
int current = where_history ();
int wanted;
/* Giving an argument of n means we want the nth command in the history
file. The command number is interpreted the same way that the bash
@ -203,11 +246,11 @@ rl_vi_fetch_history (count, c)
output of `history'. */
if (rl_explicit_arg)
{
int wanted = history_base + current - count;
wanted = history_base + where_history () - count;
if (wanted <= 0)
rl_beginning_of_history (0, 0);
else
rl_get_previous_history (wanted);
rl_get_previous_history (wanted, c);
}
else
rl_beginning_of_history (count, 0);
@ -215,6 +258,7 @@ rl_vi_fetch_history (count, c)
}
/* Search again for the last thing searched for. */
int
rl_vi_search_again (count, key)
int count, key;
{
@ -232,6 +276,7 @@ rl_vi_search_again (count, key)
}
/* Do a vi style search. */
int
rl_vi_search (count, key)
int count, key;
{
@ -253,6 +298,7 @@ rl_vi_search (count, key)
}
/* Completion, from vi's point of view. */
int
rl_vi_complete (ignore, key)
int ignore, key;
{
@ -281,6 +327,7 @@ rl_vi_complete (ignore, key)
}
/* Tilde expansion for vi mode. */
int
rl_vi_tilde_expand (ignore, key)
int ignore, key;
{
@ -291,6 +338,7 @@ rl_vi_tilde_expand (ignore, key)
}
/* Previous word in vi mode. */
int
rl_vi_prev_word (count, key)
int count, key;
{
@ -303,7 +351,7 @@ rl_vi_prev_word (count, key)
return (0);
}
if (uppercase_p (key))
if (_rl_uppercase_p (key))
rl_vi_bWord (count);
else
rl_vi_bword (count);
@ -312,6 +360,7 @@ rl_vi_prev_word (count, key)
}
/* Next word in vi mode. */
int
rl_vi_next_word (count, key)
int count, key;
{
@ -324,7 +373,7 @@ rl_vi_next_word (count, key)
return (0);
}
if (uppercase_p (key))
if (_rl_uppercase_p (key))
rl_vi_fWord (count);
else
rl_vi_fword (count);
@ -332,6 +381,7 @@ rl_vi_next_word (count, key)
}
/* Move to the end of the ?next? word. */
int
rl_vi_end_word (count, key)
int count, key;
{
@ -341,7 +391,7 @@ rl_vi_end_word (count, key)
return -1;
}
if (uppercase_p (key))
if (_rl_uppercase_p (key))
rl_vi_eWord (count);
else
rl_vi_eword (count);
@ -349,6 +399,7 @@ rl_vi_end_word (count, key)
}
/* Move forward a word the way that 'W' does. */
int
rl_vi_fWord (count)
int count;
{
@ -365,6 +416,7 @@ rl_vi_fWord (count)
return (0);
}
int
rl_vi_bWord (count)
int count;
{
@ -388,6 +440,7 @@ rl_vi_bWord (count)
return (0);
}
int
rl_vi_eWord (count)
int count;
{
@ -417,6 +470,7 @@ rl_vi_eWord (count)
return (0);
}
int
rl_vi_fword (count)
int count;
{
@ -442,6 +496,7 @@ rl_vi_fword (count)
return (0);
}
int
rl_vi_bword (count)
int count;
{
@ -480,6 +535,7 @@ rl_vi_bword (count)
return (0);
}
int
rl_vi_eword (count)
int count;
{
@ -504,6 +560,7 @@ rl_vi_eword (count)
return (0);
}
int
rl_vi_insert_beg (count, key)
int count, key;
{
@ -512,6 +569,7 @@ rl_vi_insert_beg (count, key)
return (0);
}
int
rl_vi_append_mode (count, key)
int count, key;
{
@ -521,6 +579,7 @@ rl_vi_append_mode (count, key)
return (0);
}
int
rl_vi_append_eol (count, key)
int count, key;
{
@ -530,6 +589,7 @@ rl_vi_append_eol (count, key)
}
/* What to do in the case of C-d. */
int
rl_vi_eof_maybe (count, c)
int count, c;
{
@ -540,13 +600,33 @@ rl_vi_eof_maybe (count, c)
/* Switching from one mode to the other really just involves
switching keymaps. */
int
rl_vi_insertion_mode (count, key)
int count, key;
{
_rl_keymap = vi_insertion_keymap;
_rl_vi_last_key_before_insert = key;
return (0);
}
static void
_rl_vi_save_insert (up)
UNDO_LIST *up;
{
int len, start, end;
start = up->start;
end = up->end;
len = end - start + 1;
if (len >= vi_insert_buffer_size)
{
vi_insert_buffer_size += (len + 32) - (len % 32);
vi_insert_buffer = xrealloc (vi_insert_buffer, vi_insert_buffer_size);
}
strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
vi_insert_buffer[len-1] = '\0';
}
void
_rl_vi_done_inserting ()
{
@ -555,38 +635,49 @@ _rl_vi_done_inserting ()
rl_end_undo_group ();
/* Now, the text between rl_undo_list->next->start and
rl_undo_list->next->end is what was inserted while in insert
mode. */
mode. It gets copied to VI_INSERT_BUFFER because it depends
on absolute indices into the line which may change (though they
probably will not). */
_rl_vi_doing_insert = 0;
_rl_vi_save_insert (rl_undo_list->next);
vi_continued_command = 1;
}
else
vi_continued_command = 0;
{
if (_rl_vi_last_key_before_insert == 'i' && rl_undo_list)
_rl_vi_save_insert (rl_undo_list);
/* XXX - Other keys probably need to be checked. */
else if (_rl_vi_last_key_before_insert == 'C')
rl_end_undo_group ();
while (_rl_undo_group_level > 0)
rl_end_undo_group ();
vi_continued_command = 0;
}
}
int
rl_vi_movement_mode (count, key)
int count, key;
{
if (rl_point > 0)
rl_backward (1);
#if 0
_rl_vi_reset_last ();
#endif
rl_backward (1, key);
_rl_keymap = vi_movement_keymap;
_rl_vi_done_inserting ();
return (0);
}
int
rl_vi_arg_digit (count, c)
int count, c;
{
if (c == '0' && rl_numeric_arg == 1 && !rl_explicit_arg)
return (rl_beg_of_line ());
return (rl_beg_of_line (1, c));
else
return (rl_digit_argument (count, c));
}
int
rl_vi_change_case (count, ignore)
int count, ignore;
{
@ -598,14 +689,14 @@ rl_vi_change_case (count, ignore)
while (count-- && rl_point < rl_end)
{
if (uppercase_p (rl_line_buffer[rl_point]))
c = to_lower (rl_line_buffer[rl_point]);
else if (lowercase_p (rl_line_buffer[rl_point]))
c = to_upper (rl_line_buffer[rl_point]);
if (_rl_uppercase_p (rl_line_buffer[rl_point]))
c = _rl_to_lower (rl_line_buffer[rl_point]);
else if (_rl_lowercase_p (rl_line_buffer[rl_point]))
c = _rl_to_upper (rl_line_buffer[rl_point]);
else
{
/* Just skip over characters neither upper nor lower case. */
rl_forward (1);
rl_forward (1, c);
continue;
}
@ -619,22 +710,24 @@ rl_vi_change_case (count, ignore)
rl_vi_check ();
}
else
rl_forward (1);
rl_forward (1, c);
}
return (0);
}
int
rl_vi_put (count, key)
int count, key;
{
if (!uppercase_p (key) && (rl_point + 1 <= rl_end))
if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
rl_point++;
rl_yank ();
rl_backward (1);
rl_backward (1, key);
return (0);
}
int
rl_vi_check ()
{
if (rl_point && rl_point == rl_end)
@ -642,11 +735,12 @@ rl_vi_check ()
return (0);
}
int
rl_vi_column (count, key)
int count, key;
{
if (count > rl_end)
rl_end_of_line ();
rl_end_of_line (1, key);
else
rl_point = count - 1;
return (0);
@ -665,10 +759,10 @@ rl_vi_domove (key, nextkey)
if (!member (c, vi_motion))
{
if (digit_p (c))
if (_rl_digit_p (c))
{
save = rl_numeric_arg;
rl_numeric_arg = digit_value (c);
rl_numeric_arg = _rl_digit_value (c);
rl_digit_loop1 ();
rl_numeric_arg *= save;
c = rl_read_key (); /* real command */
@ -677,7 +771,7 @@ rl_vi_domove (key, nextkey)
else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
{
rl_mark = rl_end;
rl_beg_of_line ();
rl_beg_of_line (1, c);
_rl_vi_last_motion = c;
return (0);
}
@ -708,13 +802,13 @@ rl_vi_domove (key, nextkey)
/* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
word. If we are not at the end of the line, and we are on a
non-whitespace character, move back one (presumably to whitespace). */
if ((to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
!whitespace (rl_line_buffer[rl_point]))
rl_point--;
/* If cw or cW, back up to the end of a word, so the behaviour of ce
or cE is the actual result. Brute-force, no subtlety. */
if (key == 'c' && rl_point >= rl_mark && (to_upper (c) == 'W'))
if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
{
/* Don't move farther back than where we started. */
while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
@ -760,12 +854,12 @@ rl_digit_loop1 ()
}
c = UNMETA (c);
if (digit_p (c))
if (_rl_digit_p (c))
{
if (rl_explicit_arg)
rl_numeric_arg = (rl_numeric_arg * 10) + digit_value (c);
rl_numeric_arg = (rl_numeric_arg * 10) + _rl_digit_value (c);
else
rl_numeric_arg = digit_value (c);
rl_numeric_arg = _rl_digit_value (c);
rl_explicit_arg = 1;
}
else
@ -778,12 +872,13 @@ rl_digit_loop1 ()
return (0);
}
int
rl_vi_delete_to (count, key)
int count, key;
{
int c;
if (uppercase_p (key))
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
else if (vi_redoing)
rl_stuff_char (_rl_vi_last_motion);
@ -803,12 +898,13 @@ rl_vi_delete_to (count, key)
return (0);
}
int
rl_vi_change_to (count, key)
int count, key;
{
int c, start_pos;
if (uppercase_p (key))
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
else if (vi_redoing)
rl_stuff_char (_rl_vi_last_motion);
@ -828,25 +924,41 @@ rl_vi_change_to (count, key)
rl_mark++;
/* The cursor never moves with c[wW]. */
if ((to_upper (c) == 'W') && rl_point < start_pos)
if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
rl_point = start_pos;
rl_kill_text (rl_point, rl_mark);
rl_begin_undo_group ();
_rl_vi_doing_insert = 1;
_rl_vi_set_last (key, count, rl_arg_sign);
rl_vi_insertion_mode (1, key);
if (vi_redoing)
{
if (vi_insert_buffer && *vi_insert_buffer)
rl_begin_undo_group ();
rl_delete_text (rl_point, rl_mark);
if (vi_insert_buffer && *vi_insert_buffer)
{
rl_insert_text (vi_insert_buffer);
rl_end_undo_group ();
}
}
else
{
rl_begin_undo_group (); /* to make the `u' command work */
rl_kill_text (rl_point, rl_mark);
/* `C' does not save the text inserted for undoing or redoing. */
if (_rl_uppercase_p (key) == 0)
_rl_vi_doing_insert = 1;
_rl_vi_set_last (key, count, rl_arg_sign);
rl_vi_insertion_mode (1, key);
}
return (0);
}
int
rl_vi_yank_to (count, key)
int count, key;
{
int c, save = rl_point;
if (uppercase_p (key))
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
if (rl_vi_domove (key, &c))
@ -869,6 +981,7 @@ rl_vi_yank_to (count, key)
return (0);
}
int
rl_vi_delete (count, key)
int count, key;
{
@ -888,57 +1001,36 @@ rl_vi_delete (count, key)
rl_kill_text (rl_point, end);
if (rl_point > 0 && rl_point == rl_end)
rl_backward (1);
rl_backward (1, key);
return (0);
}
/* Turn the current line into a comment in shell history.
A K*rn shell style function. */
rl_vi_comment (count, key)
int
rl_vi_back_to_indent (count, key)
int count, key;
{
rl_beg_of_line ();
if (rl_vi_comment_begin != (char *)NULL)
rl_insert_text (rl_vi_comment_begin);
else
rl_insert_text (VI_COMMENT_BEGIN_DEFAULT); /* Default. */
rl_redisplay ();
rl_newline (1, '\n');
return (0);
}
rl_vi_first_print (count, key)
int count, key;
{
return (rl_back_to_indent ());
}
rl_back_to_indent (ignore1, ignore2)
int ignore1, ignore2;
{
rl_beg_of_line ();
rl_beg_of_line (1, key);
while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
rl_point++;
return (0);
}
/* 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 */
int
rl_vi_first_print (count, key)
int count, key;
{
return (rl_vi_back_to_indent (1, key));
}
int
rl_vi_char_search (count, key)
int count, key;
{
static char target;
static int orig_dir, dir;
int pos;
if (key == ';' || key == ',')
dir = (key == ';' ? orig_dir : -orig_dir);
dir = key == ';' ? orig_dir : -orig_dir;
else
{
if (vi_redoing)
@ -966,71 +1058,11 @@ rl_vi_char_search (count, key)
}
}
pos = rl_point;
while (count--)
{
if (dir < 0)
{
if (pos == 0)
{
ding ();
return -1;
}
pos--;
do
{
if (rl_line_buffer[pos] == target)
{
if (dir == BTO)
rl_point = pos + 1;
else
rl_point = pos;
break;
}
}
while (pos--);
if (pos < 0)
{
ding ();
return -1;
}
}
else
{ /* dir > 0 */
if (pos >= rl_end)
{
ding ();
return -1;
}
pos++;
do
{
if (rl_line_buffer[pos] == target)
{
if (dir == FTO)
rl_point = pos - 1;
else
rl_point = pos;
break;
}
}
while (++pos < rl_end);
if (pos >= (rl_end - 1))
{
ding ();
return -1;
}
}
}
return (0);
return (_rl_char_search_internal (count, dir, target));
}
/* Match brackets */
int
rl_vi_match (ignore, key)
int ignore, key;
{
@ -1041,7 +1073,7 @@ rl_vi_match (ignore, key)
{
while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
rl_point < rl_end - 1)
rl_forward (1);
rl_forward (1, key);
if (brack <= 0)
{
@ -1111,6 +1143,7 @@ rl_vi_bracktype (c)
}
}
int
rl_vi_change_char (count, key)
int count, key;
{
@ -1131,22 +1164,23 @@ rl_vi_change_char (count, key)
rl_delete (1, c);
rl_insert (1, c);
if (count == 0)
rl_backward (1);
rl_backward (1, c);
rl_end_undo_group ();
}
return (0);
}
int
rl_vi_subst (count, key)
int count, key;
{
rl_begin_undo_group ();
if (uppercase_p (key))
if (_rl_uppercase_p (key))
{
rl_beg_of_line ();
rl_kill_line (1);
rl_beg_of_line (1, key);
rl_kill_line (1, key);
}
else
rl_delete_text (rl_point, rl_point+count);
@ -1155,13 +1189,26 @@ rl_vi_subst (count, key)
_rl_vi_set_last (key, count, rl_arg_sign);
rl_begin_undo_group ();
_rl_vi_doing_insert = 1;
rl_vi_insertion_mode (1, key);
if (vi_redoing)
{
int o = _rl_doing_an_undo;
_rl_doing_an_undo = 1;
if (vi_insert_buffer && *vi_insert_buffer)
rl_insert_text (vi_insert_buffer);
_rl_doing_an_undo = o;
}
else
{
rl_begin_undo_group ();
_rl_vi_doing_insert = 1;
rl_vi_insertion_mode (1, key);
}
return (0);
}
int
rl_vi_overstrike (count, key)
int count, key;
{
@ -1191,8 +1238,9 @@ rl_vi_overstrike (count, key)
return (0);
}
rl_vi_overstrike_delete (count)
int count;
int
rl_vi_overstrike_delete (count, key)
int count, key;
{
int i, s;
@ -1209,7 +1257,7 @@ rl_vi_overstrike_delete (count)
vi_replace_count--;
if (rl_point == s)
rl_backward (1);
rl_backward (1, key);
}
if (vi_replace_count == 0 && _rl_vi_doing_insert)
@ -1221,6 +1269,7 @@ rl_vi_overstrike_delete (count)
return (0);
}
int
rl_vi_replace (count, key)
int count, key;
{
@ -1256,6 +1305,7 @@ rl_vi_replace (count, key)
/* Try to complete the word we are standing on or the word that ends with
the previous character. A space matches everything. Word delimiters are
space and ;. */
int
rl_vi_possible_completions()
{
int save_pos = rl_point;
@ -1279,51 +1329,50 @@ rl_vi_possible_completions()
}
#endif
#if defined (STATIC_MALLOC)
/* **************************************************************** */
/* */
/* xmalloc and xrealloc () */
/* */
/* **************************************************************** */
static void memory_error_and_abort ();
static char *
xmalloc (bytes)
int bytes;
/* Functions to save and restore marks. */
int
rl_vi_set_mark (count, key)
int count, key;
{
char *temp = (char *)malloc (bytes);
int ch;
if (!temp)
memory_error_and_abort ();
return (temp);
ch = rl_read_key ();
if (_rl_lowercase_p (ch) == 0)
{
ding ();
return -1;
}
ch -= 'a';
vi_mark_chars[ch] = rl_point;
return 0;
}
static char *
xrealloc (pointer, bytes)
char *pointer;
int bytes;
int
rl_vi_goto_mark (count, key)
int count, key;
{
char *temp;
int ch;
if (!pointer)
temp = (char *)xmalloc (bytes);
else
temp = (char *)realloc (pointer, bytes);
ch = rl_read_key ();
if (ch == '`')
{
rl_point = rl_mark;
return 0;
}
else if (_rl_lowercase_p (ch) == 0)
{
ding ();
return -1;
}
if (!temp)
memory_error_and_abort ();
return (temp);
ch -= 'a';
if (vi_mark_chars[ch] == -1)
{
ding ();
return -1;
}
rl_point = vi_mark_chars[ch];
return 0;
}
static void
memory_error_and_abort ()
{
fprintf (stderr, "readline: Out of virtual memory!\n");
abort ();
}
#endif /* STATIC_MALLOC */
#endif /* VI_MODE */

View file

@ -19,8 +19,10 @@
along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#if defined (ALREADY_HAVE_XMALLOC)
#else
#if defined (HAVE_CONFIG_H)
#include <config.h>
#endif
#include <stdio.h>
#if defined (HAVE_STDLIB_H)
@ -44,9 +46,10 @@ char *
xmalloc (bytes)
int bytes;
{
char *temp = (char *)malloc (bytes);
char *temp;
if (!temp)
temp = (char *)malloc (bytes);
if (temp == 0)
memory_error_and_abort ("xmalloc");
return (temp);
}
@ -58,12 +61,9 @@ xrealloc (pointer, bytes)
{
char *temp;
if (!pointer)
temp = (char *)malloc (bytes);
else
temp = (char *)realloc (pointer, bytes);
temp = pointer ? (char *)realloc (pointer, bytes) : (char *)malloc (bytes);
if (!temp)
if (temp == 0)
memory_error_and_abort ("xrealloc");
return (temp);
}
@ -72,7 +72,16 @@ static void
memory_error_and_abort (fname)
char *fname;
{
fprintf (stderr, "%s: Out of virtual memory!\n", fname);
abort ();
fprintf (stderr, "%s: out of virtual memory\n", fname);
exit (2);
}
/* Use this as the function to call when adding unwind protects so we
don't need to know what free() returns. */
void
xfree (string)
char *string;
{
if (string)
free (string);
}
#endif /* !ALREADY_HAVE_XMALLOC */

Some files were not shown because too many files have changed in this diff Show more