1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

upgrade readline to version 4.3

client/completion_hash.cc:
  correct headers of functions for readline 4.3 (add const modifier to char*)
client/completion_hash.h:
  correct headers of functions for readline 4.3 (add const modifier to char*)
client/mysql.cc:
  correct functions for readline 4.3
This commit is contained in:
unknown
2002-11-19 18:26:53 +04:00
parent 0fb3b8d9ab
commit 953f6c51fe
62 changed files with 14264 additions and 7179 deletions

View File

@@ -27,7 +27,7 @@
#include <my_sys.h> #include <my_sys.h>
#include "completion_hash.h" #include "completion_hash.h"
uint hashpjw(char *arKey, uint nKeyLength) uint hashpjw(const char *arKey, uint nKeyLength)
{ {
uint h = 0, g, i; uint h = 0, g, i;
@@ -111,7 +111,7 @@ int completion_hash_update(HashTable *ht, char *arKey, uint nKeyLength,
return SUCCESS; return SUCCESS;
} }
static Bucket *completion_hash_find(HashTable *ht, char *arKey, static Bucket *completion_hash_find(HashTable *ht, const char *arKey,
uint nKeyLength) uint nKeyLength)
{ {
uint h, nIndex; uint h, nIndex;
@@ -156,7 +156,7 @@ int completion_hash_exists(HashTable *ht, char *arKey, uint nKeyLength)
return 0; return 0;
} }
Bucket *find_all_matches(HashTable *ht, char *str, uint length, Bucket *find_all_matches(HashTable *ht, const char *str, uint length,
uint *res_length) uint *res_length)
{ {
Bucket *b; Bucket *b;

View File

@@ -43,14 +43,14 @@ typedef struct hashtable {
uint nTableSize; uint nTableSize;
uint initialized; uint initialized;
MEM_ROOT mem_root; MEM_ROOT mem_root;
uint(*pHashFunction) (char *arKey, uint nKeyLength); uint(*pHashFunction) (const char *arKey, uint nKeyLength);
Bucket **arBuckets; Bucket **arBuckets;
} HashTable; } HashTable;
extern int completion_hash_init(HashTable *ht, uint nSize); extern int completion_hash_init(HashTable *ht, uint nSize);
extern int completion_hash_update(HashTable *ht, char *arKey, uint nKeyLength, char *str); extern int completion_hash_update(HashTable *ht, char *arKey, uint nKeyLength, char *str);
extern int hash_exists(HashTable *ht, char *arKey); extern int hash_exists(HashTable *ht, char *arKey);
extern Bucket *find_all_matches(HashTable *ht, char *str, uint length, uint *res_length); extern Bucket *find_all_matches(HashTable *ht, const char *str, uint length, uint *res_length);
extern Bucket *find_longest_match(HashTable *ht, char *str, uint length, uint *res_length); extern Bucket *find_longest_match(HashTable *ht, char *str, uint length, uint *res_length);
extern void add_word(HashTable *ht,char *str); extern void add_word(HashTable *ht,char *str);
extern void completion_hash_clean(HashTable *ht); extern void completion_hash_clean(HashTable *ht);

View File

@@ -1049,8 +1049,8 @@ static bool add_line(String &buffer,char *line,char *in_string)
#ifdef HAVE_READLINE #ifdef HAVE_READLINE
static char *new_command_generator(char *text, int); static char *new_command_generator(const char *text, int);
static char **new_mysql_completion (char *text, int start, int end); static char **new_mysql_completion (const char *text, int start, int end);
/* /*
Tell the GNU Readline library how to complete. We want to try to complete Tell the GNU Readline library how to complete. We want to try to complete
@@ -1058,8 +1058,8 @@ static char **new_mysql_completion (char *text, int start, int end);
if not. if not.
*/ */
char **no_completion (char *text __attribute__ ((unused)), char *no_completion (const char *text __attribute__ ((unused)),
char *word __attribute__ ((unused))) int )
{ {
return 0; /* No filename completion */ return 0; /* No filename completion */
} }
@@ -1071,8 +1071,8 @@ static void initialize_readline (char *name)
/* Tell the completer that we want a crack first. */ /* Tell the completer that we want a crack first. */
/* rl_attempted_completion_function = (CPPFunction *)mysql_completion;*/ /* rl_attempted_completion_function = (CPPFunction *)mysql_completion;*/
rl_attempted_completion_function = (CPPFunction *) new_mysql_completion; rl_attempted_completion_function = &new_mysql_completion;
rl_completion_entry_function=(Function *) no_completion; rl_completion_entry_function= &no_completion;
} }
/* /*
@@ -1082,17 +1082,17 @@ static void initialize_readline (char *name)
array of matches, or NULL if there aren't any. array of matches, or NULL if there aren't any.
*/ */
static char **new_mysql_completion (char *text, static char **new_mysql_completion (const char *text,
int start __attribute__((unused)), int start __attribute__((unused)),
int end __attribute__((unused))) int end __attribute__((unused)))
{ {
if (!status.batch && !quick) if (!status.batch && !quick)
return completion_matches(text, (CPFunction*) new_command_generator); return rl_completion_matches(text, new_command_generator);
else else
return (char**) 0; return (char**) 0;
} }
static char *new_command_generator(char *text,int state) static char *new_command_generator(const char *text,int state)
{ {
static int textlen; static int textlen;
char *ptr; char *ptr;

View File

@@ -2,7 +2,7 @@
Version 2, June 1991 Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc. Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA 59 Temple Place, Suite 330, Boston, MA 02111 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
@@ -305,7 +305,7 @@ the "copyright" line and a pointer to where the full notice is found.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.

View File

@@ -1,73 +1,81 @@
Basic Installation Basic Installation
================== ==================
These are generic installation instructions. These are installation instructions for Readline-4.3.
The `configure' shell script attempts to guess correct values for The simplest way to compile readline is:
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, a file
`config.cache' that saves the results of its tests to speed up
reconfiguring, and a file `config.log' containing compiler output
(useful mainly for debugging `configure').
If you need to do unusual things to compile the package, please try 1. `cd' to the directory containing the readline source code and type
to figure out how `configure' could check whether to do them, and mail `./configure' to configure readline for your system. If you're
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If at some point `config.cache'
contains results you don't want to keep, you may remove or edit it.
The file `configure.in' is used to create `configure' by a program
called `autoconf'. You only need `configure.in' if you want to change
it or regenerate `configure' using a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute `sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself. `configure' itself.
Running `configure' takes awhile. While running, it prints some Running `configure' takes some time. While running, it prints some
messages telling which features it is checking for. messages telling which features it is checking for.
2. Type `make' to compile the package. 2. Type `make' to compile readline and build the static readline
and history libraries. If supported, the shared readline and history
libraries will be built also. See below for instructions on compiling
the other parts of the distribution. Typing `make everything' will
cause the static and shared libraries (if supported) and the example
programs to be built.
3. Optionally, type `make check' to run any self-tests that come with 3. Type `make install' to install the static readline and history
the package. libraries, the readline include files, the documentation, and, if
supported, the shared readline and history libraries.
4. Type `make install' to install the programs and any data files and 4. You can remove the created libraries and object files from the
documentation. build directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile readline for
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get for the readline developers, and should be used with care.
all sorts of other programs in order to regenerate files that came
with the distribution. The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It
uses those values to create a `Makefile' in the build directory,
and Makefiles in the `doc', `shlib', and `examples'
subdirectories. It also creates a `config.h' file containing
system-dependent definitions. Finally, it creates a shell script
`config.status' that you can run in the future to recreate the
current configuration, a file `config.cache' that saves the
results of its tests to speed up reconfiguring, and a file
`config.log' containing compiler output (useful mainly for
debugging `configure').
If you need to do unusual things to compile readline, please try
to figure out how `configure' could check whether to do them, and
mail diffs or instructions to <bug-readline@gnu.org> so they can
be considered for the next release. If at some point
`config.cache' contains results you don't want to keep, you may
remove or edit it.
The file `configure.in' is used to create `configure' by a
program called `autoconf'. You only need `configure.in' if you
want to change it or regenerate `configure' using a newer version
of `autoconf'. The readline `configure.in' requires autoconf
version 2.50 or newer.
Compilers and Options Compilers and Options
===================== =====================
Some systems require unusual options for compilation or linking that Some systems require unusual options for compilation or linking that
the `configure' script does not know about. You can give `configure' the `configure' script does not know about. You can give `configure'
initial values for variables by setting them in the environment. Using initial values for variables by setting them in the environment. Using
a Bourne-compatible shell, you can do that on the command line like a Bourne-compatible shell, you can do that on the command line like
this: this:
CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure
Or on systems that have the `env' program, you can do it like this: Or on systems that have the `env' program, you can do it like this:
env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure
Compiling For Multiple Architectures Compiling For Multiple Architectures
==================================== ====================================
You can compile the package for more than one kind of computer at the You can compile readline for more than one kind of computer at the
same time, by placing the object files for each architecture in their same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the supports the `VPATH' variable, such as GNU `make'. `cd' to the
@@ -75,80 +83,59 @@ directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'. source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not supports the `VPATH' If you have to use a `make' that does not supports the `VPATH'
variable, you have to compile the package for one architecture at a time variable, you have to compile readline for one architecture at a
in the source code directory. After you have installed the package for time in the source code directory. After you have installed
one architecture, use `make distclean' before reconfiguring for another readline for one architecture, use `make distclean' before
architecture. reconfiguring for another architecture.
Installation Names Installation Names
================== ==================
By default, `make install' will install the package's files in By default, `make install' will install the readline libraries in
`/usr/local/bin', `/usr/local/man', etc. You can specify an `/usr/local/lib', the include files in
installation prefix other than `/usr/local' by giving `configure' the `/usr/local/include/readline', the man pages in `/usr/local/man',
option `--prefix=PATH'. and the info files in `/usr/local/info'. You can specify an
installation prefix other than `/usr/local' by giving `configure'
the option `--prefix=PATH' or by supplying a value for the
DESTDIR variable when running `make install'.
You can specify separate installation prefixes for You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you architecture-specific files and architecture-independent files.
give `configure' the option `--exec-prefix=PATH', the package will use If you give `configure' the option `--exec-prefix=PATH', the
PATH as the prefix for installing programs and libraries. readline Makefiles will use PATH as the prefix for installing the
Documentation and other data files will still use the regular prefix. libraries. Documentation and other data files will still use the
regular prefix.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type Specifying the System Type
========================== ==========================
There may be some features `configure' can not figure out There may be some features `configure' can not figure out
automatically, but needs to determine by the type of host the package automatically, but need to determine by the type of host readline
will run on. Usually `configure' can figure that out, but if it prints will run on. Usually `configure' can figure that out, but if it
a message saying it can not guess the host type, give it the prints a message saying it can not guess the host type, give it
`--host=TYPE' option. TYPE can either be a short name for the system the `--host=TYPE' option. TYPE can either be a short name for
type, such as `sun4', or a canonical name with three fields: the system type, such as `sun4', or a canonical name with three
CPU-COMPANY-SYSTEM fields: CPU-COMPANY-SYSTEM (e.g., i386-unknown-freebsd4.2).
See the file `config.sub' for the possible values of each field. If See the file `config.sub' for the possible values of each field.
`config.sub' isn't included in this package, then this package doesn't
need to know the host type.
If you are building compiler tools for cross-compiling, you can also
use the `--target=TYPE' option to select the type of system they will
produce code for and the `--build=TYPE' option to select the type of
system on which you are compiling the package.
Sharing Defaults Sharing Defaults
================ ================
If you want to set default values for `configure' scripts to share, If you want to set default values for `configure' scripts to share,
you can create a site shell script called `config.site' that gives you can create a site shell script called `config.site' that gives
default values for variables like `CC', `cache_file', and `prefix'. default values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then `configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the `PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script. `CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script. A warning: the readline `configure' looks for a site script, but not
all `configure' scripts do.
Operation Controls Operation Controls
================== ==================
`configure' recognizes the following options to control how it `configure' recognizes the following options to control how it
operates. operates.
`--cache-file=FILE' `--cache-file=FILE'
@@ -174,3 +161,113 @@ operates.
`configure' also accepts some other, not widely useful, options. `configure' also accepts some other, not widely useful, options.
Optional Features
=================
The readline `configure' recognizes a single `--with-PACKAGE' option:
`--with-curses'
This tells readline that it can find the termcap library functions
(tgetent, et al.) in the curses library, rather than a separate
termcap library. Readline uses the termcap functions, but does not
link with the termcap or curses library itself, allowing applications
which link with readline the to choose an appropriate library.
This option tells readline to link the example programs with the
curses library rather than libtermcap.
`configure' also recognizes two `--enable-FEATURE' options:
`--enable-shared'
Build the shared libraries by default on supported platforms. The
default is `yes'.
`--enable-static'
Build the static libraries by default. The default is `yes'.
Shared Libraries
================
There is support for building shared versions of the readline and
history libraries. The configure script creates a Makefile in
the `shlib' subdirectory, and typing `make shared' will cause
shared versions of the readline and history libraries to be built
on supported platforms.
If `configure' is given the `--enable-shared' option, it will attempt
to build the shared libraries by default on supported platforms.
Configure calls the script support/shobj-conf to test whether or
not shared library creation is supported and to generate the values
of variables that are substituted into shlib/Makefile. If you
try to build shared libraries on an unsupported platform, `make'
will display a message asking you to update support/shobj-conf for
your platform.
If you need to update support/shobj-conf, you will need to create
a `stanza' for your operating system and compiler. The script uses
the value of host_os and ${CC} as determined by configure. For
instance, FreeBSD 4.2 with any version of gcc is identified as
`freebsd4.2-gcc*'.
In the stanza for your operating system-compiler pair, you will need to
define several variables. They are:
SHOBJ_CC The C compiler used to compile source files into shareable
object files. This is normally set to the value of ${CC}
by configure, and should not need to be changed.
SHOBJ_CFLAGS Flags to pass to the C compiler ($SHOBJ_CC) to create
position-independent code. If you are using gcc, this
should probably be set to `-fpic'.
SHOBJ_LD The link editor to be used to create the shared library from
the object files created by $SHOBJ_CC. If you are using
gcc, a value of `gcc' will probably work.
SHOBJ_LDFLAGS Flags to pass to SHOBJ_LD to enable shared object creation.
If you are using gcc, `-shared' may be all that is necessary.
These should be the flags needed for generic shared object
creation.
SHLIB_XLDFLAGS Additional flags to pass to SHOBJ_LD for shared library
creation. Many systems use the -R option to the link
editor to embed a path within the library for run-time
library searches. A reasonable value for such systems would
be `-R$(libdir)'.
SHLIB_LIBS Any additional libraries that shared libraries should be
linked against when they are created.
SHLIB_LIBSUFF The suffix to add to `libreadline' and `libhistory' when
generating the filename of the shared library. Many systems
use `so'; HP-UX uses `sl'.
SHLIB_LIBVERSION The string to append to the filename to indicate the version
of the shared library. It should begin with $(SHLIB_LIBSUFF),
and possibly include version information that allows the
run-time loader to load the version of the shared library
appropriate for a particular program. Systems using shared
libraries similar to SunOS 4.x use major and minor library
version numbers; for those systems a value of
`$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)$(SHLIB_MINOR)' is appropriate.
Systems based on System V Release 4 don't use minor version
numbers; use `$(SHLIB_LIBSUFF).$(SHLIB_MAJOR)' on those systems.
Other Unix versions use different schemes.
SHLIB_STATUS Set this to `supported' when you have defined the other
necessary variables. Make uses this to determine whether
or not shared library creation should be attempted. If
shared libraries are not supported, this will be set to
`unsupported'.
You should look at the existing stanzas in support/shobj-conf for ideas.
Once you have updated support/shobj-conf, re-run configure and type
`make shared' or `make'. The shared libraries will be created in the
shlib subdirectory.
If shared libraries are created, `make install' will install them.
You may install only the shared libraries by running `make
install-shared' from the top-level build directory. Running `make
install' in the shlib subdirectory will also work. If you don't want
to install any created shared libraries, run `make install-static'.

View File

@@ -15,7 +15,7 @@ libreadline_a_SOURCES = readline.c funmap.c keymaps.c \
callback.c terminal.c xmalloc.c \ callback.c terminal.c xmalloc.c \
history.c histsearch.c histexpand.c \ history.c histsearch.c histexpand.c \
histfile.c nls.c search.c \ histfile.c nls.c search.c \
shell.c tilde.c shell.c tilde.c misc.c text.c mbutil.c
pkginclude_HEADERS = readline.h chardefs.h keymaps.h history.h tilde.h pkginclude_HEADERS = readline.h chardefs.h keymaps.h history.h tilde.h

View File

@@ -1,7 +1,7 @@
Introduction Introduction
============ ============
This is the Gnu Readline library, version 4.0. This is the Gnu Readline library, version 4.3.
The Readline library provides a set of functions for use by applications The Readline library provides a set of functions for use by applications
that allow users to edit command lines as they are typed in. Both that allow users to edit command lines as they are typed in. Both
@@ -16,8 +16,8 @@ may be used without Readline in applications which desire its
capabilities. capabilities.
The Readline library is free software, distributed under the terms of The Readline library is free software, distributed under the terms of
the GNU Public License, version 2. For more information, see the file the [GNU] General Public License, version 2. For more information, see
COPYING. the file COPYING.
To build the library, try typing `./configure', then `make'. The To build the library, try typing `./configure', then `make'. The
configuration process is automated, so no further intervention should configuration process is automated, so no further intervention should
@@ -37,6 +37,9 @@ to customize and control the build process.
The file rlconf.h contains C preprocessor defines that enable and disable The file rlconf.h contains C preprocessor defines that enable and disable
certain Readline features. certain Readline features.
The special make target `everything' will build the static and shared
libraries (if the target platform supports them) and the examples.
Examples Examples
======== ========
@@ -54,6 +57,9 @@ a Makefile in the `shlib' subdirectory, and typing `make shared'
will cause shared versions of the Readline and History libraries will cause shared versions of the Readline and History libraries
to be built on supported platforms. to be built on supported platforms.
If `configure' is given the `--enable-shared' option, it will attempt
to build the shared libraries by default on supported platforms.
Configure calls the script support/shobj-conf to test whether or Configure calls the script support/shobj-conf to test whether or
not shared library creation is supported and to generate the values not shared library creation is supported and to generate the values
of variables that are substituted into shlib/Makefile. If you of variables that are substituted into shlib/Makefile. If you
@@ -64,8 +70,8 @@ your platform.
If you need to update support/shobj-conf, you will need to create If you need to update support/shobj-conf, you will need to create
a `stanza' for your operating system and compiler. The script uses a `stanza' for your operating system and compiler. The script uses
the value of host_os and ${CC} as determined by configure. For the value of host_os and ${CC} as determined by configure. For
instance, FreeBSD 2.2.5 with any version of gcc is identified as instance, FreeBSD 4.2 with any version of gcc is identified as
`freebsd2.2.5-gcc*'. `freebsd4.2-gcc*'.
In the stanza for your operating system-compiler pair, you will need to In the stanza for your operating system-compiler pair, you will need to
define several variables. They are: define several variables. They are:
@@ -122,18 +128,21 @@ Once you have updated support/shobj-conf, re-run configure and type
`make shared'. The shared libraries will be created in the shlib `make shared'. The shared libraries will be created in the shlib
subdirectory. subdirectory.
Since shared libraries are not created on all platforms, `make install' If shared libraries are created, `make install' will install them.
will not automatically install the shared libraries. To install them, You may install only the shared libraries by running `make
change the current directory to shlib and type `make install'. Running install-shared' from the top-level build directory. Running `make
`make install-shared' from the top-level build directory will also work. install' in the shlib subdirectory will also work. If you don't want
to install any created shared libraries, run `make install-static'.
Documentation Documentation
============= =============
The documentation for the Readline and History libraries appears in the The documentation for the Readline and History libraries appears in
`doc' subdirectory. There are two texinfo files and a Unix-style manual the `doc' subdirectory. There are three texinfo files and a
page describing the programming facilities available in the Readline Unix-style manual page describing the facilities available in the
library. The texinfo files include both user and programmer's manuals. Readline library. The texinfo files include both user and
programmer's manuals. HTML versions of the manuals appear in the
`doc' subdirectory as well.
Reporting Bugs Reporting Bugs
============== ==============
@@ -144,7 +153,7 @@ Bug reports for Readline should be sent to:
When reporting a bug, please include the following information: When reporting a bug, please include the following information:
* the version number and release status of Readline (e.g., 4.0-release) * the version number and release status of Readline (e.g., 4.2-release)
* the machine and OS that it is running on * the machine and OS that it is running on
* a list of the compilation flags or the contents of `config.h', if * a list of the compilation flags or the contents of `config.h', if
appropriate appropriate

View File

@@ -18,18 +18,31 @@
You should have received a copy of the GNU General Public License along 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 with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_STDLIB_H_) #if !defined (_STDLIB_H_)
#define _STDLIB_H_ 1 #define _STDLIB_H_ 1
/* String conversion functions. */ /* String conversion functions. */
extern int atoi (); extern int atoi ();
extern long int atol ();
extern double atof ();
extern double strtod ();
/* Memory allocation functions. */ /* Memory allocation functions. */
extern char *malloc (); /* Generic pointer type. */
extern char *realloc (); #ifndef PTR_T
#if defined (__STDC__)
# define PTR_T void *
#else
# define PTR_T char *
#endif
#endif /* PTR_T */
extern PTR_T malloc ();
extern PTR_T realloc ();
extern void free (); extern void free ();
/* Other miscellaneous functions. */ /* Other miscellaneous functions. */

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -18,7 +18,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
@@ -29,22 +29,20 @@
#if defined (READLINE_CALLBACKS) #if defined (READLINE_CALLBACKS)
#include <stdlib.h>
#include <sys/types.h> #include <sys/types.h>
#ifdef HAVE_STDLIB_H
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif
#include <stdio.h> #include <stdio.h>
/* System-specific feature definitions and include files. */ /* System-specific feature definitions and include files. */
#include "rldefs.h" #include "rldefs.h"
#include "readline.h" #include "readline.h"
#include "rlprivate.h"
extern void readline_internal_setup ();
extern char *readline_internal_teardown ();
extern int readline_internal_char ();
extern void _rl_init_line_state ();
extern int _rl_meta_flag;
extern char *rl_prompt;
extern int rl_visible_prompt_length;
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
@@ -61,7 +59,7 @@ extern int rl_visible_prompt_length;
text read in at each end of line. The terminal is kept prepped and 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. */ signals handled all the time, except during calls to the user's function. */
VFunction *rl_linefunc; /* user callback function */ rl_vcpfunc_t *rl_linefunc; /* user callback function */
static int in_handler; /* terminal_prepped and signals set? */ static int in_handler; /* terminal_prepped and signals set? */
/* Make sure the terminal is set up, initialize readline, and prompt. */ /* Make sure the terminal is set up, initialize readline, and prompt. */
@@ -87,11 +85,10 @@ _rl_callback_newline ()
/* Install a readline handler, set up the terminal, and issue the prompt. */ /* Install a readline handler, set up the terminal, and issue the prompt. */
void void
rl_callback_handler_install (prompt, linefunc) rl_callback_handler_install (prompt, linefunc)
char *prompt; const char *prompt;
VFunction *linefunc; rl_vcpfunc_t *linefunc;
{ {
rl_prompt = prompt; rl_set_prompt (prompt);
rl_visible_prompt_length = rl_prompt ? rl_expand_prompt (rl_prompt) : 0;
rl_linefunc = linefunc; rl_linefunc = linefunc;
_rl_callback_newline (); _rl_callback_newline ();
} }
@@ -111,24 +108,33 @@ rl_callback_read_char ()
eof = readline_internal_char (); eof = readline_internal_char ();
if (rl_done) /* We loop in case some function has pushed input back with rl_execute_next. */
for (;;)
{ {
line = readline_internal_teardown (eof); if (rl_done)
{
line = readline_internal_teardown (eof);
(*rl_deprep_term_function) (); (*rl_deprep_term_function) ();
#if defined (HANDLE_SIGNALS) #if defined (HANDLE_SIGNALS)
rl_clear_signals (); rl_clear_signals ();
#endif #endif
in_handler = 0; in_handler = 0;
(*rl_linefunc) (line); (*rl_linefunc) (line);
/* If the user did not clear out the line, do it for him. */ /* If the user did not clear out the line, do it for him. */
if (rl_line_buffer[0]) if (rl_line_buffer[0])
_rl_init_line_state (); _rl_init_line_state ();
/* Redisplay the prompt if readline_handler_{install,remove} not called. */ /* Redisplay the prompt if readline_handler_{install,remove}
if (in_handler == 0 && rl_linefunc) not called. */
_rl_callback_newline (); if (in_handler == 0 && rl_linefunc)
_rl_callback_newline ();
}
if (rl_pending_input)
eof = readline_internal_char ();
else
break;
} }
} }

View File

@@ -7,7 +7,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -18,21 +18,23 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#ifndef _CHARDEFS_H_ #ifndef _CHARDEFS_H_
#define _CHARDEFS_H_ #define _CHARDEFS_H_
#ifndef _m_ctype_h
#include <ctype.h> #include <ctype.h>
#endif
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
# if defined (HAVE_STRING_H) # if defined (HAVE_STRING_H)
# if ! defined (STDC_HEADERS) && defined (HAVE_MEMORY_H)
# include <memory.h>
# endif
# include <string.h> # include <string.h>
# else
# include <strings.h>
# endif /* HAVE_STRING_H */ # endif /* HAVE_STRING_H */
# if defined (HAVE_STRINGS_H)
# include <strings.h>
# endif /* HAVE_STRINGS_H */
#else #else
# include <string.h> # include <string.h>
#endif /* !HAVE_CONFIG_H */ #endif /* !HAVE_CONFIG_H */
@@ -42,7 +44,10 @@
#endif #endif
#ifdef CTRL #ifdef CTRL
#undef CTRL # undef CTRL
#endif
#ifdef UNCTRL
# undef UNCTRL
#endif #endif
/* Some character stuff. */ /* Some character stuff. */
@@ -53,7 +58,7 @@
#define meta_character_bit 0x080 /* x0000000, must be on. */ #define meta_character_bit 0x080 /* x0000000, must be on. */
#define largest_char 255 /* Largest character value. */ #define largest_char 255 /* Largest character value. */
#define CTRL_CHAR(c) ((c) < control_character_threshold && (c) >= 0) #define CTRL_CHAR(c) ((c) < control_character_threshold && (((c) & 0x80) == 0))
#define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char) #define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char)
#define CTRL(c) ((c) & control_character_mask) #define CTRL(c) ((c) & control_character_mask)
@@ -62,33 +67,59 @@
#define UNMETA(c) ((c) & (~meta_character_bit)) #define UNMETA(c) ((c) & (~meta_character_bit))
#define UNCTRL(c) _rl_to_upper(((c)|control_character_bit)) #define UNCTRL(c) _rl_to_upper(((c)|control_character_bit))
/* Old versions #if defined STDC_HEADERS || (!defined (isascii) && !defined (HAVE_ISASCII))
#define _rl_lowercase_p(c) (((c) > ('a' - 1) && (c) < ('z' + 1))) # define IN_CTYPE_DOMAIN(c) 1
#define _rl_uppercase_p(c) (((c) > ('A' - 1) && (c) < ('Z' + 1))) #else
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9') # define IN_CTYPE_DOMAIN(c) isascii(c)
*/ #endif
#define _rl_lowercase_p(c) (islower(c)) #if !defined (isxdigit) && !defined (HAVE_ISXDIGIT)
#define _rl_uppercase_p(c) (isupper(c)) # define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
#define _rl_digit_p(x) (isdigit (x)) #endif
#define _rl_pure_alphabetic(c) (_rl_lowercase_p(c) || _rl_uppercase_p(c)) #define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
#define ALPHABETIC(c) (_rl_lowercase_p(c) || _rl_uppercase_p(c) || _rl_digit_p(c))
/* Old versions /* Some systems define these; we want our definitions. */
# define _rl_to_upper(c) (_rl_lowercase_p(c) ? ((c) - 32) : (c)) #undef ISPRINT
# define _rl_to_lower(c) (_rl_uppercase_p(c) ? ((c) + 32) : (c))
*/ #define ISALNUM(c) (IN_CTYPE_DOMAIN (c) && isalnum (c))
#define ISALPHA(c) (IN_CTYPE_DOMAIN (c) && isalpha (c))
#define ISDIGIT(c) (IN_CTYPE_DOMAIN (c) && isdigit (c))
#define ISLOWER(c) (IN_CTYPE_DOMAIN (c) && islower (c))
#define ISPRINT(c) (IN_CTYPE_DOMAIN (c) && isprint (c))
#define ISUPPER(c) (IN_CTYPE_DOMAIN (c) && isupper (c))
#define ISXDIGIT(c) (IN_CTYPE_DOMAIN (c) && isxdigit (c))
#define _rl_lowercase_p(c) (NON_NEGATIVE(c) && ISLOWER(c))
#define _rl_uppercase_p(c) (NON_NEGATIVE(c) && ISUPPER(c))
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9')
#define _rl_pure_alphabetic(c) (NON_NEGATIVE(c) && ISALPHA(c))
#define ALPHABETIC(c) (NON_NEGATIVE(c) && ISALNUM(c))
#ifndef _rl_to_upper #ifndef _rl_to_upper
# define _rl_to_upper(c) (islower(c) ? toupper(c) : (c)) # define _rl_to_upper(c) (_rl_lowercase_p(c) ? toupper((unsigned char)c) : (c))
# define _rl_to_lower(c) (isupper(c) ? tolower(c) : (c)) # define _rl_to_lower(c) (_rl_uppercase_p(c) ? tolower((unsigned char)c) : (c))
#endif #endif
#ifndef _rl_digit_value #ifndef _rl_digit_value
#define _rl_digit_value(x) ((x) - '0') # define _rl_digit_value(x) ((x) - '0')
#endif #endif
#ifndef _rl_isident
# define _rl_isident(c) (ISALNUM(c) || (c) == '_')
#endif
#ifndef ISOCTAL
# define ISOCTAL(c) ((c) >= '0' && (c) <= '7')
#endif
#define OCTVALUE(c) ((c) - '0')
#define HEXVALUE(c) \
(((c) >= 'a' && (c) <= 'f') \
? (c)-'a'+10 \
: (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0')
#ifndef NEWLINE #ifndef NEWLINE
#define NEWLINE '\n' #define NEWLINE '\n'
#endif #endif
@@ -125,18 +156,4 @@
#endif #endif
#define ESC CTRL('[') #define ESC CTRL('[')
#ifndef ISOCTAL
#define ISOCTAL(c) ((c) >= '0' && (c) <= '7')
#endif
#define OCTVALUE(c) ((c) - '0')
#ifndef isxdigit
# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
#endif
#define HEXVALUE(c) \
(((c) >= 'a' && (c) <= 'f') \
? (c)-'a'+10 \
: (c) >= 'A' && (c) <= 'F' ? (c)-'A'+10 : (c)-'0')
#endif /* _CHARDEFS_H_ */ #endif /* _CHARDEFS_H_ */

File diff suppressed because it is too large Load Diff

6170
readline/configure vendored

File diff suppressed because it is too large Load Diff

View File

@@ -4,34 +4,49 @@ dnl
dnl report bugs to chet@po.cwru.edu dnl report bugs to chet@po.cwru.edu
dnl dnl
dnl Process this file with autoconf to produce a configure script. dnl Process this file with autoconf to produce a configure script.
AC_REVISION([for Readline 4.0, version 2.14, from autoconf version] AC_ACVERSION) AC_REVISION([for Readline 4.3, version 2.45, from autoconf version] AC_ACVERSION)
LIBVERSION=4.0
AC_INIT(readline.h) AC_INIT(readline, 4.3, bug-readline@gnu.org)
AC_CONFIG_HEADER(config.h)
dnl make sure we are using a recent autoconf version dnl make sure we are using a recent autoconf version
AC_PREREQ(2.10) AC_PREREQ(2.50)
AC_CONFIG_SRCDIR(readline.h)
AC_CONFIG_AUX_DIR(./support) AC_CONFIG_AUX_DIR(./support)
AC_CONFIG_HEADERS(config.h)
dnl update the value of RL_READLINE_VERSION in readline.h when this changes
LIBVERSION=4.3
AC_CANONICAL_HOST AC_CANONICAL_HOST
dnl configure defaults dnl configure defaults
opt_curses=no opt_curses=no
opt_shared=no
dnl arguments to configure dnl arguments to configure
AC_ARG_WITH(curses, --with-curses use the curses library instead of the termcap library,opt_curses=$withval) AC_ARG_WITH(curses, AC_HELP_STRING([--with-curses], [use the curses library instead of the termcap library]), opt_curses=$withval)
if test "$opt_curses" = "yes"; then if test "$opt_curses" = "yes"; then
prefer_curses=yes prefer_curses=yes
fi fi
dnl option parsing for optional features
opt_static_libs=yes
opt_shared_libs=yes
AC_ARG_ENABLE(shared, AC_HELP_STRING([--enable-shared], [build shared libraries [[default=YES]]]), opt_shared_libs=$enableval)
AC_ARG_ENABLE(static, AC_HELP_STRING([--enable-static], [build static libraries [[default=YES]]]), opt_static_libs=$enableval)
echo ""
echo "Beginning configuration for readline-$LIBVERSION for ${host_cpu}-${host_vendor}-${host_os}"
echo ""
# We want these before the checks, so the checks can modify their values. # We want these before the checks, so the checks can modify their values.
test -z "$CFLAGS" && CFLAGS=-g auto_cflags=1 test -z "$CFLAGS" && CFLAGS=-g auto_cflags=1
AC_PROG_MAKE_SET
AC_PROG_CC AC_PROG_CC
dnl AC_AIX
AC_MINIX AC_MINIX
# If we're using gcc and the user hasn't specified CFLAGS, add -O to CFLAGS. # If we're using gcc and the user hasn't specified CFLAGS, add -O to CFLAGS.
@@ -39,7 +54,7 @@ test -n "$GCC" && test -n "$auto_cflags" && CFLAGS="$CFLAGS -O"
AC_PROG_GCC_TRADITIONAL AC_PROG_GCC_TRADITIONAL
AC_PROG_INSTALL AC_PROG_INSTALL
AC_CHECK_PROG(AR, ar, ar) AC_CHECK_PROG(AR, ar, , ar)
dnl Set default for ARFLAGS, since autoconf does not have a macro for it. dnl Set default for ARFLAGS, since autoconf does not have a macro for it.
dnl This allows people to set it when running configure or make dnl This allows people to set it when running configure or make
test -n "$ARFLAGS" || ARFLAGS="cr" test -n "$ARFLAGS" || ARFLAGS="cr"
@@ -48,32 +63,42 @@ AC_PROG_RANLIB
MAKE_SHELL=/bin/sh MAKE_SHELL=/bin/sh
AC_SUBST(MAKE_SHELL) AC_SUBST(MAKE_SHELL)
AC_RETSIGTYPE AC_C_CONST
AC_C_PROTOTYPES
AC_C_CHAR_UNSIGNED
AC_TYPE_SIGNAL
AC_TYPE_SIZE_T
AC_CHECK_TYPE(ssize_t, int)
AC_HEADER_STAT AC_HEADER_STAT
AC_HEADER_DIRENT AC_HEADER_DIRENT
AC_CHECK_FUNCS(strcasecmp select setenv putenv tcgetattr setlocale lstat) AC_CHECK_FUNCS(lstat memmove putenv select setenv setlocale \
strcasecmp strpbrk tcgetattr vsnprintf isascii isxdigit)
AC_FUNC_STRCOLL AC_FUNC_STRCOLL
AC_CHECK_HEADERS(unistd.h stdlib.h varargs.h stdarg.h string.h \ AC_CHECK_HEADERS(unistd.h stdlib.h varargs.h stdarg.h string.h strings.h \
sys/ptem.h sys/pte.h sys/stream.h sys/select.h \ limits.h sys/ptem.h sys/pte.h sys/stream.h sys/select.h \
termcap.h termios.h termio.h sys/file.h locale.h) termcap.h termios.h termio.h sys/file.h locale.h memory.h )
BASH_SIGNAL_CHECK BASH_SYS_SIGNAL_VINTAGE
BASH_REINSTALL_SIGHANDLERS BASH_SYS_REINSTALL_SIGHANDLERS
BASH_FUNC_POSIX_SETJMP BASH_FUNC_POSIX_SETJMP
BASH_FUNC_LSTAT BASH_FUNC_LSTAT
BASH_CHECK_GETPW_FUNCS
BASH_FUNC_STRCOLL BASH_FUNC_STRCOLL
BASH_CHECK_GETPW_FUNCS
AC_HEADER_TIOCGWINSZ
BASH_TYPE_SIGHANDLER BASH_TYPE_SIGHANDLER
BASH_HAVE_TIOCGWINSZ
BASH_HAVE_TIOCSTAT BASH_HAVE_TIOCSTAT
BASH_HAVE_FIONREAD BASH_HAVE_FIONREAD
BASH_MISC_SPEED_T BASH_CHECK_SPEED_T
BASH_STRUCT_WINSIZE BASH_STRUCT_WINSIZE
BASH_STRUCT_DIRENT_D_INO BASH_STRUCT_DIRENT_D_INO
BASH_STRUCT_DIRENT_D_FILENO BASH_STRUCT_DIRENT_D_FILENO
@@ -84,11 +109,18 @@ aix*) prefer_curses=yes ;;
esac esac
BASH_CHECK_LIB_TERMCAP BASH_CHECK_LIB_TERMCAP
if test "$TERMCAP_LIB" = "./lib/termcap/libtermcap.a"; then if test "$TERMCAP_LIB" = "./lib/termcap/libtermcap.a"; then
TERMCAP_LIB=-ltermcap #default if test "$prefer_curses" = yes; then
TERMCAP_LIB=-lcurses
else
TERMCAP_LIB=-ltermcap #default
fi
fi fi
BASH_CHECK_MULTIBYTE
case "$host_cpu" in case "$host_cpu" in
*cray*) LOCAL_CFLAGS=-DCRAY ;; *cray*) LOCAL_CFLAGS=-DCRAY ;;
*s390*) LOCAL_CFLAGS=-fsigned-char ;;
esac esac
case "$host_os" in case "$host_os" in
@@ -102,7 +134,7 @@ esac
# #
if test -f ${srcdir}/support/shobj-conf; then if test -f ${srcdir}/support/shobj-conf; then
AC_MSG_CHECKING(configuration for building shared libraries) AC_MSG_CHECKING(configuration for building shared libraries)
eval `${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C ${CC} -c ${host_cpu} -o ${host_os} -v ${host_vendor}` eval `${CONFIG_SHELL-/bin/sh} ${srcdir}/support/shobj-conf -C "${CC}" -c ${host_cpu} -o ${host_os} -v ${host_vendor}`
AC_SUBST(SHOBJ_CC) AC_SUBST(SHOBJ_CC)
AC_SUBST(SHOBJ_CFLAGS) AC_SUBST(SHOBJ_CFLAGS)
AC_SUBST(SHOBJ_LD) AC_SUBST(SHOBJ_LD)
@@ -116,9 +148,40 @@ if test -f ${srcdir}/support/shobj-conf; then
AC_SUBST(SHLIB_LIBVERSION) AC_SUBST(SHLIB_LIBVERSION)
AC_SUBST(SHLIB_LIBS) AC_SUBST(SHLIB_LIBS)
AC_MSG_RESULT($SHLIB_STATUS) AC_MSG_RESULT($SHLIB_STATUS)
# SHLIB_STATUS is either `supported' or `unsupported'. If it's
# `unsupported', turn off any default shared library building
if test "$SHLIB_STATUS" = 'unsupported'; then
opt_shared_libs=no
fi
# shared library versioning
# quoted for m4 so I can use character classes
SHLIB_MAJOR=[`expr "$LIBVERSION" : '\([0-9]\)\..*'`]
SHLIB_MINOR=[`expr "$LIBVERSION" : '[0-9]\.\([0-9]\).*'`]
AC_SUBST(SHLIB_MAJOR)
AC_SUBST(SHLIB_MINOR)
fi fi
BUILD_DIR=`pwd` if test "$opt_static_libs" = "yes"; then
STATIC_TARGET=static
STATIC_INSTALL_TARGET=install-static
fi
if test "$opt_shared_libs" = "yes"; then
SHARED_TARGET=shared
SHARED_INSTALL_TARGET=install-shared
fi
AC_SUBST(STATIC_TARGET)
AC_SUBST(SHARED_TARGET)
AC_SUBST(STATIC_INSTALL_TARGET)
AC_SUBST(SHARED_INSTALL_TARGET)
case "$host_os" in
msdosdjgpp*) BUILD_DIR=`pwd.exe` ;; # to prevent //d/path/file
*) BUILD_DIR=`pwd` ;;
esac
AC_SUBST(BUILD_DIR) AC_SUBST(BUILD_DIR)
AC_SUBST(CFLAGS) AC_SUBST(CFLAGS)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -18,15 +18,13 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
# include <config.h> # include <config.h>
#endif #endif
extern char *xmalloc (), *xrealloc ();
#if !defined (BUFSIZ) #if !defined (BUFSIZ)
#include <stdio.h> #include <stdio.h>
#endif /* BUFSIZ */ #endif /* BUFSIZ */
@@ -40,7 +38,15 @@ extern char *xmalloc (), *xrealloc ();
#include "rlconf.h" #include "rlconf.h"
#include "readline.h" #include "readline.h"
extern int _rl_qsort_string_compare (); #include "xmalloc.h"
#ifdef __STDC__
typedef int QSFUNC (const void *, const void *);
#else
typedef int QSFUNC ();
#endif
extern int _rl_qsort_string_compare PARAMS((char **, char **));
FUNMAP **funmap; FUNMAP **funmap;
static int funmap_size; static int funmap_size;
@@ -54,7 +60,8 @@ static FUNMAP default_funmap[] = {
{ "abort", rl_abort }, { "abort", rl_abort },
{ "accept-line", rl_newline }, { "accept-line", rl_newline },
{ "arrow-key-prefix", rl_arrow_keys }, { "arrow-key-prefix", rl_arrow_keys },
{ "backward-char", rl_backward }, { "backward-byte", rl_backward_byte },
{ "backward-char", rl_backward_char },
{ "backward-delete-char", rl_rubout }, { "backward-delete-char", rl_rubout },
{ "backward-kill-line", rl_backward_kill_line }, { "backward-kill-line", rl_backward_kill_line },
{ "backward-kill-word", rl_backward_kill_word }, { "backward-kill-word", rl_backward_kill_word },
@@ -85,7 +92,8 @@ static FUNMAP default_funmap[] = {
{ "end-of-line", rl_end_of_line }, { "end-of-line", rl_end_of_line },
{ "exchange-point-and-mark", rl_exchange_point_and_mark }, { "exchange-point-and-mark", rl_exchange_point_and_mark },
{ "forward-backward-delete-char", rl_rubout_or_delete }, { "forward-backward-delete-char", rl_rubout_or_delete },
{ "forward-char", rl_forward }, { "forward-byte", rl_forward_byte },
{ "forward-char", rl_forward_char },
{ "forward-search-history", rl_forward_search_history }, { "forward-search-history", rl_forward_search_history },
{ "forward-word", rl_forward_word }, { "forward-word", rl_forward_word },
{ "history-search-backward", rl_history_search_backward }, { "history-search-backward", rl_history_search_backward },
@@ -102,7 +110,8 @@ static FUNMAP default_funmap[] = {
{ "non-incremental-reverse-search-history", rl_noninc_reverse_search }, { "non-incremental-reverse-search-history", rl_noninc_reverse_search },
{ "non-incremental-forward-search-history-again", rl_noninc_forward_search_again }, { "non-incremental-forward-search-history-again", rl_noninc_forward_search_again },
{ "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again }, { "non-incremental-reverse-search-history-again", rl_noninc_reverse_search_again },
#ifdef __CYGWIN32__ { "overwrite-mode", rl_overwrite_mode },
#ifdef __CYGWIN__
{ "paste-from-clipboard", rl_paste_from_clipboard }, { "paste-from-clipboard", rl_paste_from_clipboard },
#endif #endif
{ "possible-completions", rl_possible_completions }, { "possible-completions", rl_possible_completions },
@@ -136,7 +145,6 @@ static FUNMAP default_funmap[] = {
{ "vi-arg-digit", rl_vi_arg_digit }, { "vi-arg-digit", rl_vi_arg_digit },
{ "vi-back-to-indent", rl_vi_back_to_indent }, { "vi-back-to-indent", rl_vi_back_to_indent },
{ "vi-bWord", rl_vi_bWord }, { "vi-bWord", rl_vi_bWord },
{ "vi-bracktype", rl_vi_bracktype },
{ "vi-bword", rl_vi_bword }, { "vi-bword", rl_vi_bword },
{ "vi-change-case", rl_vi_change_case }, { "vi-change-case", rl_vi_change_case },
{ "vi-change-char", rl_vi_change_char }, { "vi-change-char", rl_vi_change_char },
@@ -176,18 +184,20 @@ static FUNMAP default_funmap[] = {
{ "vi-yank-to", rl_vi_yank_to }, { "vi-yank-to", rl_vi_yank_to },
#endif /* VI_MODE */ #endif /* VI_MODE */
{(char *)NULL, (Function *)NULL } {(char *)NULL, (rl_command_func_t *)NULL }
}; };
int int
rl_add_funmap_entry (const char *name, Function *function) rl_add_funmap_entry (name, function)
const char *name;
rl_command_func_t *function;
{ {
if (funmap_entry + 2 >= funmap_size) if (funmap_entry + 2 >= funmap_size)
{ {
funmap_size += 64; funmap_size += 64;
funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *)); funmap = (FUNMAP **)xrealloc (funmap, funmap_size * sizeof (FUNMAP *));
} }
funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP)); funmap[funmap_entry] = (FUNMAP *)xmalloc (sizeof (FUNMAP));
funmap[funmap_entry]->name = name; funmap[funmap_entry]->name = name;
funmap[funmap_entry]->function = function; funmap[funmap_entry]->function = function;
@@ -217,36 +227,27 @@ rl_initialize_funmap ()
/* Produce a NULL terminated array of known function names. The array /* Produce a NULL terminated array of known function names. The array
is sorted. The array itself is allocated, but not the strings inside. is sorted. The array itself is allocated, but not the strings inside.
You should free () the array when you done, but not the pointrs. */ You should free () the array when you done, but not the pointrs. */
char ** const char **
rl_funmap_names () rl_funmap_names ()
{ {
char **result; const char **result;
int result_size, result_index; int result_size, result_index;
/* Make sure that the function map has been initialized. */ /* Make sure that the function map has been initialized. */
rl_initialize_funmap (); rl_initialize_funmap ();
for (result_index = result_size = 0, result = (char **)NULL; funmap[result_index]; result_index++) for (result_index = result_size = 0, result = (const char **)NULL; funmap[result_index]; result_index++)
{ {
if (result_index + 2 > result_size) if (result_index + 2 > result_size)
{ {
result_size += 20; result_size += 20;
result = (char **)xrealloc (result, result_size * sizeof (char *)); result = (const char **)xrealloc (result, result_size * sizeof (char *));
} }
result[result_index] = (char*) funmap[result_index]->name; result[result_index] = funmap[result_index]->name;
result[result_index + 1] = (char *)NULL; result[result_index + 1] = (char *)NULL;
} }
qsort (result, result_index, sizeof (char *), _rl_qsort_string_compare); qsort (result, result_index, sizeof (char *), (QSFUNC *)_rl_qsort_string_compare);
return (result); return (result);
} }
/* Things that mean `Control'. */
const char *possible_control_prefixes[] = {
"Control-", "C-", "CTRL-", (char *)NULL
};
const char *possible_meta_prefixes[] = {
"Meta", "M-", (char *)NULL
};

View File

@@ -7,7 +7,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -18,7 +18,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
@@ -41,18 +41,21 @@
# include <unistd.h> # include <unistd.h>
#endif #endif
#if defined (HAVE_STRING_H) #include "rlmbutil.h"
# include <string.h>
#else
# include <strings.h>
#endif /* !HAVE_STRING_H */
#include "history.h" #include "history.h"
#include "histlib.h" #include "histlib.h"
#include "rlshell.h"
#include "xmalloc.h"
#define HISTORY_WORD_DELIMITERS " \t\n;&()|<>" #define HISTORY_WORD_DELIMITERS " \t\n;&()|<>"
#define HISTORY_QUOTE_CHARACTERS "\"'`" #define HISTORY_QUOTE_CHARACTERS "\"'`"
typedef int _hist_search_func_t PARAMS((const char *, int));
extern int rl_byte_oriented; /* declared in mbutil.c */
static char error_pointer; static char error_pointer;
static char *subst_lhs; static char *subst_lhs;
@@ -60,15 +63,10 @@ static char *subst_rhs;
static int subst_lhs_len; static int subst_lhs_len;
static int subst_rhs_len; static int subst_rhs_len;
static char *get_history_word_specifier (); static char *get_history_word_specifier PARAMS((char *, char *, int *));
static char *history_find_word (); static char *history_find_word PARAMS((char *, int));
extern int history_offset; static char *quote_breaks PARAMS((char *));
extern char *single_quote ();
static char *quote_breaks ();
extern char *xmalloc (), *xrealloc ();
/* Variables exported by this file. */ /* Variables exported by this file. */
/* The character that represents the start of a history expansion /* The character that represents the start of a history expansion
@@ -87,15 +85,18 @@ char history_comment_char = '\0';
/* The list of characters which inhibit the expansion of text if found /* The list of characters which inhibit the expansion of text if found
immediately following history_expansion_char. */ immediately following history_expansion_char. */
const char *history_no_expand_chars = " \t\n\r="; char *history_no_expand_chars = (char*)" \t\n\r=";
/* If set to a non-zero value, single quotes inhibit history expansion. /* If set to a non-zero value, single quotes inhibit history expansion.
The default is 0. */ The default is 0. */
int history_quotes_inhibit_expansion = 0; int history_quotes_inhibit_expansion = 0;
/* Used to split words by history_tokenize_internal. */
char *history_word_delimiters = (char*)HISTORY_WORD_DELIMITERS;
/* If set, this points to a function that is called to verify that a /* If set, this points to a function that is called to verify that a
particular history expansion should be performed. */ particular history expansion should be performed. */
Function *history_inhibit_expansion_function; rl_linebuf_func_t *history_inhibit_expansion_function;
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
@@ -124,7 +125,7 @@ static char *search_match;
line = get_history_event ("!echo:p", &index, 0); */ line = get_history_event ("!echo:p", &index, 0); */
char * char *
get_history_event (string, caller_index, delimiting_quote) get_history_event (string, caller_index, delimiting_quote)
char *string; const char *string;
int *caller_index; int *caller_index;
int delimiting_quote; int delimiting_quote;
{ {
@@ -132,7 +133,7 @@ get_history_event (string, caller_index, delimiting_quote)
register char c; register char c;
HIST_ENTRY *entry; HIST_ENTRY *entry;
int which, sign, local_index, substring_okay; int which, sign, local_index, substring_okay;
Function *search_func; _hist_search_func_t *search_func;
char *temp; char *temp;
/* The event can be specified in a number of ways. /* The event can be specified in a number of ways.
@@ -201,15 +202,33 @@ get_history_event (string, caller_index, delimiting_quote)
/* Only a closing `?' or a newline delimit a substring search string. */ /* Only a closing `?' or a newline delimit a substring search string. */
for (local_index = i; (c = string[i]); i++) for (local_index = i; (c = string[i]); i++)
if ((!substring_okay && (whitespace (c) || c == ':' || #if defined (HANDLE_MULTIBYTE)
(history_search_delimiter_chars && member (c, history_search_delimiter_chars)) || if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
string[i] == delimiting_quote)) || {
string[i] == '\n' || int v;
(substring_okay && string[i] == '?')) mbstate_t ps;
break;
memset (&ps, 0, sizeof (mbstate_t));
/* These produce warnings because we're passing a const string to a
function that takes a non-const string. */
_rl_adjust_point (string, i, &ps);
if ((v = _rl_get_char_len (string + i, &ps)) > 1)
{
i += v - 1;
continue;
}
}
else
#endif /* HANDLE_MULTIBYTE */
if ((!substring_okay && (whitespace (c) || c == ':' ||
(history_search_delimiter_chars && member (c, history_search_delimiter_chars)) ||
string[i] == delimiting_quote)) ||
string[i] == '\n' ||
(substring_okay && string[i] == '?'))
break;
which = i - local_index; which = i - local_index;
temp = xmalloc (1 + which); temp = (char *)xmalloc (1 + which);
if (which) if (which)
strncpy (temp, string + local_index, which); strncpy (temp, string + local_index, which);
temp[which] = '\0'; temp[which] = '\0';
@@ -249,7 +268,7 @@ get_history_event (string, caller_index, delimiting_quote)
{ {
entry = current_history (); entry = current_history ();
history_offset = history_length; history_offset = history_length;
/* If this was a substring search, then remember the /* If this was a substring search, then remember the
string that we matched for word substitution. */ string that we matched for word substitution. */
if (substring_okay) if (substring_okay)
@@ -311,7 +330,7 @@ quote_breaks (s)
len += 2; len += 2;
} }
r = ret = xmalloc (len); r = ret = (char *)xmalloc (len);
*r++ = '\''; *r++ = '\'';
for (p = s; p && *p; ) for (p = s; p && *p; )
{ {
@@ -376,7 +395,7 @@ hist_error(s, start, current, errtype)
break; break;
} }
temp = xmalloc (ll + elen + 3); temp = (char *)xmalloc (ll + elen + 3);
strncpy (temp, s + start, ll); strncpy (temp, s + start, ll);
temp[ll] = ':'; temp[ll] = ':';
temp[ll + 1] = ' '; temp[ll + 1] = ' ';
@@ -402,17 +421,37 @@ get_subst_pattern (str, iptr, delimiter, is_rhs, lenptr)
int *iptr, delimiter, is_rhs, *lenptr; int *iptr, delimiter, is_rhs, *lenptr;
{ {
register int si, i, j, k; register int si, i, j, k;
char *s = (char *) NULL; char *s;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps;
#endif
s = (char *)NULL;
i = *iptr; i = *iptr;
#if defined (HANDLE_MULTIBYTE)
memset (&ps, 0, sizeof (mbstate_t));
_rl_adjust_point (str, i, &ps);
#endif
for (si = i; str[si] && str[si] != delimiter; si++) for (si = i; str[si] && str[si] != delimiter; si++)
if (str[si] == '\\' && str[si + 1] == delimiter) #if defined (HANDLE_MULTIBYTE)
si++; if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int v;
if ((v = _rl_get_char_len (str + si, &ps)) > 1)
si += v - 1;
else if (str[si] == '\\' && str[si + 1] == delimiter)
si++;
}
else
#endif /* HANDLE_MULTIBYTE */
if (str[si] == '\\' && str[si + 1] == delimiter)
si++;
if (si > i || is_rhs) if (si > i || is_rhs)
{ {
s = xmalloc (si - i + 1); s = (char *)xmalloc (si - i + 1);
for (j = 0, k = i; k < si; j++, k++) for (j = 0, k = i; k < si; j++, k++)
{ {
/* Remove a backslash quoting the search string delimiter. */ /* Remove a backslash quoting the search string delimiter. */
@@ -439,13 +478,13 @@ postproc_subst_rhs ()
char *new; char *new;
int i, j, new_size; int i, j, new_size;
new = xmalloc (new_size = subst_rhs_len + subst_lhs_len); new = (char *)xmalloc (new_size = subst_rhs_len + subst_lhs_len);
for (i = j = 0; i < subst_rhs_len; i++) for (i = j = 0; i < subst_rhs_len; i++)
{ {
if (subst_rhs[i] == '&') if (subst_rhs[i] == '&')
{ {
if (j + subst_lhs_len >= new_size) if (j + subst_lhs_len >= new_size)
new = xrealloc (new, (new_size = new_size * 2 + subst_lhs_len)); new = (char *)xrealloc (new, (new_size = new_size * 2 + subst_lhs_len));
strcpy (new + j, subst_lhs); strcpy (new + j, subst_lhs);
j += subst_lhs_len; j += subst_lhs_len;
} }
@@ -455,7 +494,7 @@ postproc_subst_rhs ()
if (subst_rhs[i] == '\\' && subst_rhs[i + 1] == '&') if (subst_rhs[i] == '\\' && subst_rhs[i + 1] == '&')
i++; i++;
if (j >= new_size) if (j >= new_size)
new = xrealloc (new, new_size *= 2); new = (char *)xrealloc (new, new_size *= 2);
new[j++] = subst_rhs[i]; new[j++] = subst_rhs[i];
} }
} }
@@ -481,8 +520,13 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
int substitute_globally, want_quotes, print_only; int substitute_globally, want_quotes, print_only;
char *event, *temp, *result, *tstr, *t, c, *word_spec; char *event, *temp, *result, *tstr, *t, c, *word_spec;
int result_len; int result_len;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps;
result = xmalloc (result_len = 128); memset (&ps, 0, sizeof (mbstate_t));
#endif
result = (char *)xmalloc (result_len = 128);
i = start; i = start;
@@ -511,11 +555,24 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
quote, then this expansion takes place inside of the quote, then this expansion takes place inside of the
quoted string. If we have to search for some text ("!foo"), quoted string. If we have to search for some text ("!foo"),
allow the delimiter to end the search string. */ allow the delimiter to end the search string. */
if (i && (string[i - 1] == '\'' || string[i - 1] == '"')) #if defined (HANDLE_MULTIBYTE)
quoted_search_delimiter = string[i - 1]; if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int c, l;
l = _rl_find_prev_mbchar (string, i, MB_FIND_ANY);
c = string[l];
/* XXX - original patch had i - 1 ??? If i == 0 it would fail. */
if (i && (c == '\'' || c == '"'))
quoted_search_delimiter = c;
}
else
#endif /* HANDLE_MULTIBYTE */
if (i && (string[i - 1] == '\'' || string[i - 1] == '"'))
quoted_search_delimiter = string[i - 1];
event = get_history_event (string, &i, quoted_search_delimiter); event = get_history_event (string, &i, quoted_search_delimiter);
} }
if (event == 0) if (event == 0)
{ {
*ret_string = hist_error (string, start, i, EVENT_NOT_FOUND); *ret_string = hist_error (string, start, i, EVENT_NOT_FOUND);
@@ -625,13 +682,26 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
case '&': case '&':
case 's': case 's':
{ {
char *new_event, *t; char *new_event;
int delimiter, failed, si, l_temp; int delimiter, failed, si, l_temp;
if (c == 's') if (c == 's')
{ {
if (i + 2 < (int)strlen (string)) if (i + 2 < (int)strlen (string))
delimiter = string[i + 2]; {
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
_rl_adjust_point (string, i + 2, &ps);
if (_rl_get_char_len (string + i + 2, &ps) > 1)
delimiter = 0;
else
delimiter = string[i + 2];
}
else
#endif /* HANDLE_MULTIBYTE */
delimiter = string[i + 2];
}
else else
break; /* no search delimiter */ break; /* no search delimiter */
@@ -695,7 +765,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (STREQN (temp+si, subst_lhs, subst_lhs_len)) if (STREQN (temp+si, subst_lhs, subst_lhs_len))
{ {
int len = subst_rhs_len - subst_lhs_len + l_temp; int len = subst_rhs_len - subst_lhs_len + l_temp;
new_event = xmalloc (1 + len); new_event = (char *)xmalloc (1 + len);
strncpy (new_event, temp, si); strncpy (new_event, temp, si);
strncpy (new_event + si, subst_rhs, subst_rhs_len); strncpy (new_event + si, subst_rhs, subst_rhs_len);
strncpy (new_event + si + subst_rhs_len, strncpy (new_event + si + subst_rhs_len,
@@ -744,7 +814,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
char *x; char *x;
if (want_quotes == 'q') if (want_quotes == 'q')
x = single_quote (temp); x = sh_single_quote (temp);
else if (want_quotes == 'x') else if (want_quotes == 'x')
x = quote_breaks (temp); x = quote_breaks (temp);
else else
@@ -756,7 +826,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
n = strlen (temp); n = strlen (temp);
if (n >= result_len) if (n >= result_len)
result = xrealloc (result, n + 2); result = (char *)xrealloc (result, n + 2);
strcpy (result, temp); strcpy (result, temp);
free (temp); free (temp);
@@ -787,7 +857,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
{ \ { \
while (j >= result_len) \ while (j >= result_len) \
result_len += 128; \ result_len += 128; \
result = xrealloc (result, result_len); \ result = (char *)xrealloc (result, result_len); \
} \ } \
strcpy (result + j - sl, s); \ strcpy (result + j - sl, s); \
} \ } \
@@ -797,7 +867,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
do \ do \
{ \ { \
if (j >= result_len - 1) \ if (j >= result_len - 1) \
result = xrealloc (result, result_len += 64); \ result = (char *)xrealloc (result, result_len += 64); \
result[j++] = c; \ result[j++] = c; \
result[j] = '\0'; \ result[j] = '\0'; \
} \ } \
@@ -816,9 +886,17 @@ history_expand (hstring, output)
int result_len; int result_len;
char *result; char *result;
#if defined (HANDLE_MULTIBYTE)
char mb[MB_LEN_MAX];
mbstate_t ps;
#endif
/* Used when adding the string. */ /* Used when adding the string. */
char *temp; char *temp;
if (output == 0)
return 0;
/* Setting the history expansion character to 0 inhibits all /* Setting the history expansion character to 0 inhibits all
history expansion. */ history expansion. */
if (history_expansion_char == 0) if (history_expansion_char == 0)
@@ -826,9 +904,9 @@ history_expand (hstring, output)
*output = savestring (hstring); *output = savestring (hstring);
return (0); return (0);
} }
/* Prepare the buffer for printing error messages. */ /* Prepare the buffer for printing error messages. */
result = xmalloc (result_len = 256); result = (char *)xmalloc (result_len = 256);
result[0] = '\0'; result[0] = '\0';
only_printing = modified = 0; only_printing = modified = 0;
@@ -845,7 +923,7 @@ history_expand (hstring, output)
that is the substitution that we do. */ that is the substitution that we do. */
if (hstring[0] == history_subst_char) if (hstring[0] == history_subst_char)
{ {
string = xmalloc (l + 5); string = (char *)xmalloc (l + 5);
string[0] = string[1] = history_expansion_char; string[0] = string[1] = history_expansion_char;
string[2] = ':'; string[2] = ':';
@@ -855,6 +933,10 @@ history_expand (hstring, output)
} }
else else
{ {
#if defined (HANDLE_MULTIBYTE)
memset (&ps, 0, sizeof (mbstate_t));
#endif
string = hstring; string = hstring;
/* If not quick substitution, still maybe have to do expansion. */ /* If not quick substitution, still maybe have to do expansion. */
@@ -862,13 +944,26 @@ history_expand (hstring, output)
is NOT an expansion. */ is NOT an expansion. */
for (i = 0; string[i]; i++) for (i = 0; string[i]; i++)
{ {
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int v;
v = _rl_get_char_len (string + i, &ps);
if (v > 1)
{
i += v - 1;
continue;
}
}
#endif /* HANDLE_MULTIBYTE */
cc = string[i + 1]; cc = string[i + 1];
/* The history_comment_char, if set, appearing that the beginning /* The history_comment_char, if set, appearing at the beginning
of a word signifies that the rest of the line should not have of a word signifies that the rest of the line should not have
history expansion performed on it. history expansion performed on it.
Skip the rest of the line and break out of the loop. */ Skip the rest of the line and break out of the loop. */
if (history_comment_char && string[i] == history_comment_char && if (history_comment_char && string[i] == history_comment_char &&
(i == 0 || member (string[i - 1], HISTORY_WORD_DELIMITERS))) (i == 0 || member (string[i - 1], history_word_delimiters)))
{ {
while (string[i]) while (string[i])
i++; i++;
@@ -905,7 +1000,7 @@ history_expand (hstring, output)
i++; i++;
} }
} }
if (string[i] != history_expansion_char) if (string[i] != history_expansion_char)
{ {
free (result); free (result);
@@ -926,6 +1021,30 @@ history_expand (hstring, output)
continue; continue;
} }
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int k, c;
c = tchar;
memset (mb, 0, sizeof (mb));
for (k = 0; k < MB_LEN_MAX; k++)
{
mb[k] = (char)c;
memset (&ps, 0, sizeof (mbstate_t));
if (_rl_get_char_len (mb, &ps) == -2)
c = string[++i];
else
break;
}
if (strlen (mb) > 1)
{
ADD_STRING (mb);
break;
}
}
#endif /* HANDLE_MULTIBYTE */
if (tchar == history_expansion_char) if (tchar == history_expansion_char)
tchar = -3; tchar = -3;
else if (tchar == history_comment_char) else if (tchar == history_comment_char)
@@ -954,7 +1073,7 @@ history_expand (hstring, output)
hist_string_extract_single_quoted (string, &i); hist_string_extract_single_quoted (string, &i);
slen = i - quote + 2; slen = i - quote + 2;
temp = xmalloc (slen); temp = (char *)xmalloc (slen);
strncpy (temp, string + quote, slen); strncpy (temp, string + quote, slen);
temp[slen - 1] = '\0'; temp[slen - 1] = '\0';
ADD_STRING (temp); ADD_STRING (temp);
@@ -966,9 +1085,9 @@ history_expand (hstring, output)
} }
case -2: /* history_comment_char */ case -2: /* history_comment_char */
if (i == 0 || member (string[i - 1], HISTORY_WORD_DELIMITERS)) if (i == 0 || member (string[i - 1], history_word_delimiters))
{ {
temp = xmalloc (l - i + 1); temp = (char *)xmalloc (l - i + 1);
strcpy (temp, string + i); strcpy (temp, string + i);
ADD_STRING (temp); ADD_STRING (temp);
free (temp); free (temp);
@@ -1000,7 +1119,7 @@ history_expand (hstring, output)
{ {
if (result) if (result)
{ {
temp = xmalloc (1 + strlen (result)); temp = (char *)xmalloc (1 + strlen (result));
strcpy (temp, result); strcpy (temp, result);
ADD_STRING (temp); ADD_STRING (temp);
free (temp); free (temp);
@@ -1134,7 +1253,14 @@ get_history_word_specifier (spec, from, caller_index)
i++; i++;
last = '$'; last = '$';
} }
else if (!spec[i] || spec[i] == ':') /* could be modifier separator */ #if 0
else if (!spec[i] || spec[i] == ':')
/* check against `:' because there could be a modifier separator */
#else
else
/* csh seems to allow anything to terminate the word spec here,
leaving it as an abbreviation. */
#endif
last = -1; /* x- abbreviates x-$ omitting word `$' */ last = -1; /* x- abbreviates x-$ omitting word `$' */
} }
@@ -1154,7 +1280,7 @@ get_history_word_specifier (spec, from, caller_index)
char * char *
history_arg_extract (first, last, string) history_arg_extract (first, last, string)
int first, last; int first, last;
char *string; const char *string;
{ {
register int i, len; register int i, len;
char *result; char *result;
@@ -1190,7 +1316,7 @@ history_arg_extract (first, last, string)
{ {
for (size = 0, i = first; i < last; i++) for (size = 0, i = first; i < last; i++)
size += strlen (list[i]) + 1; size += strlen (list[i]) + 1;
result = xmalloc (size + 1); result = (char *)xmalloc (size + 1);
result[0] = '\0'; result[0] = '\0';
for (i = first, offset = 0; i < last; i++) for (i = first, offset = 0; i < last; i++)
@@ -1220,13 +1346,18 @@ history_arg_extract (first, last, string)
*INDP. */ *INDP. */
static char ** static char **
history_tokenize_internal (string, wind, indp) history_tokenize_internal (string, wind, indp)
char *string; const char *string;
int wind, *indp; int wind, *indp;
{ {
char **result; char **result;
register int i, start, result_index, size; register int i, start, result_index, size;
int len, delimiter; int len, delimiter;
/* If we're searching for a string that's not part of a word (e.g., " "),
make sure we set *INDP to a reasonable value. */
if (indp && wind != -1)
*indp = -1;
/* Get a token, and stuff it into RESULT. The tokens are split /* Get a token, and stuff it into RESULT. The tokens are split
exactly where the shell would split them. */ exactly where the shell would split them. */
for (i = result_index = size = 0, result = (char **)NULL; string[i]; ) for (i = result_index = size = 0, result = (char **)NULL; string[i]; )
@@ -1240,7 +1371,7 @@ history_tokenize_internal (string, wind, indp)
return (result); return (result);
start = i; start = i;
if (member (string[i], "()\n")) if (member (string[i], "()\n"))
{ {
i++; i++;
@@ -1301,7 +1432,7 @@ history_tokenize_internal (string, wind, indp)
continue; continue;
} }
if (!delimiter && (member (string[i], HISTORY_WORD_DELIMITERS))) if (!delimiter && (member (string[i], history_word_delimiters)))
break; break;
if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS)) if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS))
@@ -1318,7 +1449,7 @@ history_tokenize_internal (string, wind, indp)
len = i - start; len = i - start;
if (result_index + 2 >= size) if (result_index + 2 >= size)
result = (char **)xrealloc (result, ((size += 10) * sizeof (char *))); result = (char **)xrealloc (result, ((size += 10) * sizeof (char *)));
result[result_index] = xmalloc (1 + len); result[result_index] = (char *)xmalloc (1 + len);
strncpy (result[result_index], string + start, len); strncpy (result[result_index], string + start, len);
result[result_index][len] = '\0'; result[result_index][len] = '\0';
result[++result_index] = (char *)NULL; result[++result_index] = (char *)NULL;
@@ -1331,7 +1462,7 @@ history_tokenize_internal (string, wind, indp)
parsed out of STRING. */ parsed out of STRING. */
char ** char **
history_tokenize (string) history_tokenize (string)
char *string; const char *string;
{ {
return (history_tokenize_internal (string, -1, (int *)NULL)); return (history_tokenize_internal (string, -1, (int *)NULL));
} }
@@ -1348,7 +1479,7 @@ history_find_word (line, ind)
int i, wind; int i, wind;
words = history_tokenize_internal (line, ind, &wind); words = history_tokenize_internal (line, ind, &wind);
if (wind == -1) if (wind == -1 || words == 0)
return ((char *)NULL); return ((char *)NULL);
s = words[wind]; s = words[wind];
for (i = 0; i < wind; i++) for (i = 0; i < wind; i++)

View File

@@ -7,7 +7,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -18,7 +18,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
/* The goal is to make the implementation transparent, so that you /* The goal is to make the implementation transparent, so that you
don't have to know what data types are used, just what functions don't have to know what data types are used, just what functions
@@ -35,7 +35,7 @@
#ifndef _MINIX #ifndef _MINIX
# include <sys/file.h> # include <sys/file.h>
#endif #endif
#include <sys/stat.h> #include "posixstat.h"
#include <fcntl.h> #include <fcntl.h>
#if defined (HAVE_STDLIB_H) #if defined (HAVE_STDLIB_H)
@@ -48,21 +48,39 @@
# include <unistd.h> # include <unistd.h>
#endif #endif
#if defined (HAVE_STRING_H) #if defined (__EMX__) || defined (__CYGWIN__)
# include <string.h> # undef HAVE_MMAP
#else #endif
# include <strings.h>
#endif /* !HAVE_STRING_H */
#if defined (__EMX__) #ifdef HAVE_MMAP
# include <sys/mman.h>
# ifdef MAP_FILE
# define MAP_RFLAGS (MAP_FILE|MAP_PRIVATE)
# define MAP_WFLAGS (MAP_FILE|MAP_SHARED)
# else
# define MAP_RFLAGS MAP_PRIVATE
# define MAP_WFLAGS MAP_SHARED
# endif
# ifndef MAP_FAILED
# define MAP_FAILED ((void *)-1)
# endif
#endif /* HAVE_MMAP */
/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
on win 95/98/nt), we want to open files with O_BINARY mode so that there
is no \n -> \r\n conversion performed. On other systems, we don't want to
mess around with O_BINARY at all, so we ensure that it's defined to 0. */
#if defined (__EMX__) || defined (__CYGWIN__)
# ifndef O_BINARY # ifndef O_BINARY
# define O_BINARY 0 # define O_BINARY 0
# endif # endif
#else /* !__EMX__ */ #else /* !__EMX__ && !__CYGWIN__ */
/* If we're not compiling for __EMX__, we don't want this at all. Ever. */
# undef O_BINARY # undef O_BINARY
# define O_BINARY 0 # define O_BINARY 0
#endif /* !__EMX__ */ #endif /* !__EMX__ && !__CYGWIN__ */
#include <errno.h> #include <errno.h>
#if !defined (errno) #if !defined (errno)
@@ -72,17 +90,15 @@ extern int errno;
#include "history.h" #include "history.h"
#include "histlib.h" #include "histlib.h"
/* Functions imported from shell.c */ #include "rlshell.h"
extern char *get_env_value (); #include "xmalloc.h"
extern char *xmalloc (), *xrealloc ();
/* Return the string that should be used in the place of this /* Return the string that should be used in the place of this
filename. This only matters when you don't specify the filename. This only matters when you don't specify the
filename to read_history (), or write_history (). */ filename to read_history (), or write_history (). */
static char * static char *
history_filename (filename) history_filename (filename)
char *filename; const char *filename;
{ {
char *return_val; char *return_val;
const char *home; const char *home;
@@ -92,8 +108,8 @@ history_filename (filename)
if (return_val) if (return_val)
return (return_val); return (return_val);
home = get_env_value ("HOME"); home = sh_get_env_value ("HOME");
if (home == 0) if (home == 0)
{ {
@@ -103,10 +119,14 @@ history_filename (filename)
else else
home_len = strlen (home); home_len = strlen (home);
return_val = xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */ return_val = (char *)xmalloc (2 + home_len + 8); /* strlen(".history") == 8 */
strcpy (return_val, home); strcpy (return_val, home);
return_val[home_len] = '/'; return_val[home_len] = '/';
#if defined (__MSDOS__)
strcpy (return_val + home_len + 1, "_history");
#else
strcpy (return_val + home_len + 1, ".history"); strcpy (return_val + home_len + 1, ".history");
#endif
return (return_val); return (return_val);
} }
@@ -116,7 +136,7 @@ history_filename (filename)
successful, or errno if not. */ successful, or errno if not. */
int int
read_history (filename) read_history (filename)
char *filename; const char *filename;
{ {
return (read_history_range (filename, 0, -1)); return (read_history_range (filename, 0, -1));
} }
@@ -128,13 +148,14 @@ read_history (filename)
~/.history. Returns 0 if successful, or errno if not. */ ~/.history. Returns 0 if successful, or errno if not. */
int int
read_history_range (filename, from, to) read_history_range (filename, from, to)
char *filename; const char *filename;
int from, to; int from, to;
{ {
char *input, *buffer; register char *line_start, *line_end;
int file, current_line; char *input, *buffer, *bufend;
int file, current_line, chars_read;
struct stat finfo; struct stat finfo;
size_t line_start, line_end, file_size; size_t file_size;
buffer = (char *)NULL; buffer = (char *)NULL;
input = history_filename (filename); input = history_filename (filename);
@@ -150,57 +171,67 @@ read_history_range (filename, from, to)
{ {
#if defined (EFBIG) #if defined (EFBIG)
errno = EFBIG; errno = EFBIG;
#elif defined (EOVERFLOW)
errno = EOVERFLOW;
#endif #endif
goto error_and_exit; goto error_and_exit;
} }
buffer = xmalloc (file_size + 1); #ifdef HAVE_MMAP
#if 0 /* We map read/write and private so we can change newlines to NULs without
if (read (file, buffer, file_size) != file_size) affecting the underlying object. */
buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0);
if ((void *)buffer == MAP_FAILED)
goto error_and_exit;
chars_read = file_size;
#else #else
if (read (file, buffer, file_size) < 0) buffer = (char *)malloc (file_size + 1);
if (buffer == 0)
goto error_and_exit;
chars_read = read (file, buffer, file_size);
#endif #endif
if (chars_read < 0)
{ {
error_and_exit: error_and_exit:
chars_read = errno;
if (file >= 0) if (file >= 0)
close (file); close (file);
FREE (input); FREE (input);
#ifndef HAVE_MMAP
FREE (buffer); FREE (buffer);
#endif
return (errno); return (chars_read);
} }
close (file); close (file);
/* Set TO to larger than end of file if negative. */ /* Set TO to larger than end of file if negative. */
if (to < 0) if (to < 0)
to = file_size; to = chars_read;
/* Start at beginning of file, work to end. */ /* Start at beginning of file, work to end. */
line_start = line_end = current_line = 0; bufend = buffer + chars_read;
current_line = 0;
/* Skip lines until we are at FROM. */ /* Skip lines until we are at FROM. */
while (line_start < file_size && current_line < from) for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++)
{ if (*line_end == '\n')
for (line_end = line_start; line_end < file_size; line_end++) {
if (buffer[line_end] == '\n') current_line++;
{ line_start = line_end + 1;
current_line++; }
line_start = line_end + 1;
if (current_line == from)
break;
}
}
/* If there are lines left to gobble, then gobble them now. */ /* If there are lines left to gobble, then gobble them now. */
for (line_end = line_start; line_end < file_size; line_end++) for (line_end = line_start; line_end < bufend; line_end++)
if (buffer[line_end] == '\n') if (*line_end == '\n')
{ {
buffer[line_end] = '\0'; *line_end = '\0';
if (buffer[line_start]) if (*line_start)
add_history (buffer + line_start); add_history (line_start);
current_line++; current_line++;
@@ -211,30 +242,52 @@ read_history_range (filename, from, to)
} }
FREE (input); FREE (input);
#ifndef HAVE_MMAP
FREE (buffer); FREE (buffer);
#else
munmap (buffer, file_size);
#endif
return (0); return (0);
} }
/* Truncate the history file FNAME, leaving only LINES trailing lines. /* Truncate the history file FNAME, leaving only LINES trailing lines.
If FNAME is NULL, then use ~/.history. */ If FNAME is NULL, then use ~/.history. Returns 0 on success, errno
on failure. */
int int
history_truncate_file (fname, lines) history_truncate_file (fname, lines)
char *fname; const char *fname;
int lines; int lines;
{ {
register int i; char *buffer, *filename, *bp;
int file, chars_read; int file, chars_read, rv;
char *buffer, *filename;
struct stat finfo; struct stat finfo;
size_t file_size; size_t file_size;
buffer = (char *)NULL; buffer = (char *)NULL;
filename = history_filename (fname); filename = history_filename (fname);
file = open (filename, O_RDONLY|O_BINARY, 0666); file = open (filename, O_RDONLY|O_BINARY, 0666);
rv = 0;
/* Don't try to truncate non-regular files. */
if (file == -1 || fstat (file, &finfo) == -1) if (file == -1 || fstat (file, &finfo) == -1)
goto truncate_exit; {
rv = errno;
if (file != -1)
close (file);
goto truncate_exit;
}
if (S_ISREG (finfo.st_mode) == 0)
{
close (file);
#ifdef EFTYPE
rv = EFTYPE;
#else
rv = EINVAL;
#endif
goto truncate_exit;
}
file_size = (size_t)finfo.st_size; file_size = (size_t)finfo.st_size;
@@ -243,23 +296,36 @@ history_truncate_file (fname, lines)
{ {
close (file); close (file);
#if defined (EFBIG) #if defined (EFBIG)
errno = EFBIG; rv = errno = EFBIG;
#elif defined (EOVERFLOW)
rv = errno = EOVERFLOW;
#else
rv = errno = EINVAL;
#endif #endif
goto truncate_exit; goto truncate_exit;
} }
buffer = xmalloc (file_size + 1); buffer = (char *)malloc (file_size + 1);
if (buffer == 0)
{
close (file);
goto truncate_exit;
}
chars_read = read (file, buffer, file_size); chars_read = read (file, buffer, file_size);
close (file); close (file);
if (chars_read <= 0) if (chars_read <= 0)
goto truncate_exit; {
rv = (chars_read < 0) ? errno : 0;
goto truncate_exit;
}
/* Count backwards from the end of buffer until we have passed /* Count backwards from the end of buffer until we have passed
LINES lines. */ LINES lines. */
for (i = chars_read - 1; lines && i; i--) for (bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
{ {
if (buffer[i] == '\n') if (*bp == '\n')
lines--; lines--;
} }
@@ -268,22 +334,22 @@ history_truncate_file (fname, lines)
anything. It's the first line if we don't find a newline between 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 the current value of i and 0. Otherwise, write from the start of
this line until the end of the buffer. */ this line until the end of the buffer. */
for ( ; i; i--) for ( ; bp > buffer; bp--)
if (buffer[i] == '\n') if (*bp == '\n')
{ {
i++; bp++;
break; break;
} }
/* Write only if there are more lines in the file than we want to /* Write only if there are more lines in the file than we want to
truncate to. */ truncate to. */
if (i && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1)) if (bp > buffer && ((file = open (filename, O_WRONLY|O_TRUNC|O_BINARY, 0600)) != -1))
{ {
write (file, buffer + i, file_size - i); write (file, bp, chars_read - (bp - buffer));
#if defined (__BEOS__) #if defined (__BEOS__)
/* BeOS ignores O_TRUNC. */ /* BeOS ignores O_TRUNC. */
ftruncate (file, file_size - i); ftruncate (file, chars_read - (bp - buffer));
#endif #endif
close (file); close (file);
@@ -294,7 +360,7 @@ history_truncate_file (fname, lines)
FREE (buffer); FREE (buffer);
free (filename); free (filename);
return 0; return rv;
} }
/* Workhorse function for writing history. Writes NELEMENT entries /* Workhorse function for writing history. Writes NELEMENT entries
@@ -302,15 +368,21 @@ history_truncate_file (fname, lines)
wish to replace FILENAME with the entries. */ wish to replace FILENAME with the entries. */
static int static int
history_do_write (filename, nelements, overwrite) history_do_write (filename, nelements, overwrite)
char *filename; const char *filename;
int nelements, overwrite; int nelements, overwrite;
{ {
register int i; register int i;
char *output; char *output;
int file, mode; int file, mode, rv;
size_t cursize;
#ifdef HAVE_MMAP
mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY;
#else
mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY; mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
#endif
output = history_filename (filename); output = history_filename (filename);
rv = 0;
if ((file = open (output, mode, 0600)) == -1) if ((file = open (output, mode, 0600)) == -1)
{ {
@@ -318,6 +390,10 @@ history_do_write (filename, nelements, overwrite)
return (errno); return (errno);
} }
#ifdef HAVE_MMAP
cursize = overwrite ? 0 : lseek (file, 0, SEEK_END);
#endif
if (nelements > history_length) if (nelements > history_length)
nelements = history_length; nelements = history_length;
@@ -335,7 +411,28 @@ history_do_write (filename, nelements, overwrite)
buffer_size += 1 + strlen (the_history[i]->line); buffer_size += 1 + strlen (the_history[i]->line);
/* Allocate the buffer, and fill it. */ /* Allocate the buffer, and fill it. */
buffer = xmalloc (buffer_size); #ifdef HAVE_MMAP
if (ftruncate (file, buffer_size+cursize) == -1)
goto mmap_error;
buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize);
if ((void *)buffer == MAP_FAILED)
{
mmap_error:
rv = errno;
FREE (output);
close (file);
return rv;
}
#else
buffer = (char *)malloc (buffer_size);
if (buffer == 0)
{
rv = errno;
FREE (output);
close (file);
return rv;
}
#endif
for (j = 0, i = history_length - nelements; i < history_length; i++) for (j = 0, i = history_length - nelements; i < history_length; i++)
{ {
@@ -344,15 +441,21 @@ history_do_write (filename, nelements, overwrite)
buffer[j++] = '\n'; buffer[j++] = '\n';
} }
write (file, buffer, buffer_size); #ifdef HAVE_MMAP
if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0)
rv = errno;
#else
if (write (file, buffer, buffer_size) < 0)
rv = errno;
free (buffer); free (buffer);
#endif
} }
close (file); close (file);
FREE (output); FREE (output);
return (0); return (rv);
} }
/* Append NELEMENT entries to FILENAME. The entries appended are from /* Append NELEMENT entries to FILENAME. The entries appended are from
@@ -360,7 +463,7 @@ history_do_write (filename, nelements, overwrite)
int int
append_history (nelements, filename) append_history (nelements, filename)
int nelements; int nelements;
char *filename; const char *filename;
{ {
return (history_do_write (filename, nelements, HISTORY_APPEND)); return (history_do_write (filename, nelements, HISTORY_APPEND));
} }
@@ -370,7 +473,7 @@ append_history (nelements, filename)
are as in read_history ().*/ are as in read_history ().*/
int int
write_history (filename) write_history (filename)
char *filename; const char *filename;
{ {
return (history_do_write (filename, history_length, HISTORY_OVERWRITE)); return (history_do_write (filename, history_length, HISTORY_OVERWRITE));
} }

View File

@@ -6,7 +6,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -17,27 +17,24 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_HISTLIB_H_) #if !defined (_HISTLIB_H_)
#define _HISTLIB_H_ #define _HISTLIB_H_
/* Function pointers can be declared as (Function *)foo. */ #if defined (HAVE_STRING_H)
#if !defined (_FUNCTION_DEF) # include <string.h>
# define _FUNCTION_DEF #else
typedef int Function (); # include <strings.h>
typedef void VFunction (); #endif /* !HAVE_STRING_H */
typedef char *CPFunction ();
typedef char **CPPFunction ();
#endif /* _FUNCTION_DEF */
#if !defined (STREQ)
#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) #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 STREQN(a, b, n) (((n) == 0) ? (1) \
: ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
#endif
#ifndef savestring #ifndef savestring
# ifndef strcpy
extern char *strcpy ();
# endif
#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x)) #define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
#endif #endif
@@ -79,4 +76,7 @@ extern char *strchr ();
#define HISTORY_APPEND 0 #define HISTORY_APPEND 0
#define HISTORY_OVERWRITE 1 #define HISTORY_OVERWRITE 1
/* Some variable definitions shared across history source files. */
extern int history_offset;
#endif /* !_HISTLIB_H_ */ #endif /* !_HISTLIB_H_ */

View File

@@ -7,7 +7,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -18,7 +18,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
/* The goal is to make the implementation transparent, so that you /* The goal is to make the implementation transparent, so that you
don't have to know what data types are used, just what functions don't have to know what data types are used, just what functions
@@ -44,16 +44,10 @@
# include <unistd.h> # include <unistd.h>
#endif #endif
#if defined (HAVE_STRING_H)
# include <string.h>
#else
# include <strings.h>
#endif /* !HAVE_STRING_H */
#include "history.h" #include "history.h"
#include "histlib.h" #include "histlib.h"
extern char *xmalloc (), *xrealloc (); #include "xmalloc.h"
/* The number of slots to increase the_history by. */ /* The number of slots to increase the_history by. */
#define DEFAULT_HISTORY_GROW_SIZE 50 #define DEFAULT_HISTORY_GROW_SIZE 50
@@ -71,9 +65,13 @@ static HIST_ENTRY **the_history = (HIST_ENTRY **)NULL;
history that we save. */ history that we save. */
static int history_stifled; static int history_stifled;
/* The current number of slots allocated to the input_history. */
static int history_size;
/* If HISTORY_STIFLED is non-zero, then this is the maximum number of /* If HISTORY_STIFLED is non-zero, then this is the maximum number of
entries to remember. */ entries to remember. */
int max_input_history; int history_max_entries;
int max_input_history; /* backwards compatibility */
/* The current location of the interactive history pointer. Just makes /* The current location of the interactive history pointer. Just makes
life easier for outside callers. */ life easier for outside callers. */
@@ -82,9 +80,6 @@ int history_offset;
/* The number of strings currently stored in the history list. */ /* The number of strings currently stored in the history list. */
int history_length; int history_length;
/* The current number of slots allocated to the input_history. */
static int history_size;
/* The logical `base' of the history array. It defaults to 1. */ /* The logical `base' of the history array. It defaults to 1. */
int history_base = 1; int history_base = 1;
@@ -134,9 +129,7 @@ history_total_bytes ()
{ {
register int i, result; register int i, result;
result = 0; for (i = result = 0; the_history && the_history[i]; i++)
for (i = 0; the_history && the_history[i]; i++)
result += strlen (the_history[i]->line); result += strlen (the_history[i]->line);
return (result); return (result);
@@ -161,7 +154,7 @@ history_set_pos (pos)
history_offset = pos; history_offset = pos;
return (1); return (1);
} }
/* Return the current history array. The caller has to be carefull, since this /* Return the current history array. The caller has to be carefull, since this
is the actual array of data, and could be bashed or made corrupt easily. is the actual array of data, and could be bashed or made corrupt easily.
The array is terminated with a NULL pointer. */ The array is terminated with a NULL pointer. */
@@ -217,16 +210,16 @@ history_get (offset)
is set to NULL. */ is set to NULL. */
void void
add_history (string) add_history (string)
char *string; const char *string;
{ {
HIST_ENTRY *temp; HIST_ENTRY *temp;
if (history_stifled && (history_length == max_input_history)) if (history_stifled && (history_length == history_max_entries))
{ {
register int i; register int i;
/* If the history is stifled, and history_length is zero, /* If the history is stifled, and history_length is zero,
and it equals max_input_history, we don't save items. */ and it equals history_max_entries, we don't save items. */
if (history_length == 0) if (history_length == 0)
return; return;
@@ -277,15 +270,15 @@ add_history (string)
HIST_ENTRY * HIST_ENTRY *
replace_history_entry (which, line, data) replace_history_entry (which, line, data)
int which; int which;
char *line; const char *line;
histdata_t data; histdata_t data;
{ {
HIST_ENTRY *temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY)); HIST_ENTRY *temp, *old_value;
HIST_ENTRY *old_value;
if (which >= history_length) if (which >= history_length)
return ((HIST_ENTRY *)NULL); return ((HIST_ENTRY *)NULL);
temp = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
old_value = the_history[which]; old_value = the_history[which];
temp->line = savestring (line); temp->line = savestring (line);
@@ -303,12 +296,12 @@ remove_history (which)
int which; int which;
{ {
HIST_ENTRY *return_value; HIST_ENTRY *return_value;
register int i;
if (which >= history_length || !history_length) if (which >= history_length || !history_length)
return_value = (HIST_ENTRY *)NULL; return_value = (HIST_ENTRY *)NULL;
else else
{ {
register int i;
return_value = the_history[which]; return_value = the_history[which];
for (i = which; i < history_length; i++) for (i = which; i < history_length; i++)
@@ -325,13 +318,13 @@ void
stifle_history (max) stifle_history (max)
int max; int max;
{ {
register int i, j;
if (max < 0) if (max < 0)
max = 0; max = 0;
if (history_length > max) if (history_length > max)
{ {
register int i, j;
/* This loses because we cannot free the data. */ /* This loses because we cannot free the data. */
for (i = 0, j = history_length - max; i < j; i++) for (i = 0, j = history_length - max; i < j; i++)
{ {
@@ -347,22 +340,22 @@ stifle_history (max)
} }
history_stifled = 1; history_stifled = 1;
max_input_history = max; max_input_history = history_max_entries = max;
} }
/* Stop stifling the history. This returns the previous amount the /* Stop stifling the history. This returns the previous maximum
history was stifled by. The value is positive if the history was number of history entries. The value is positive if the history
stifled, negative if it wasn't. */ was stifled, negative if it wasn't. */
int int
unstifle_history () unstifle_history ()
{ {
if (history_stifled) if (history_stifled)
{ {
history_stifled = 0; history_stifled = 0;
return (-max_input_history); return (history_max_entries);
} }
else
return (max_input_history); return (-history_max_entries);
} }
int int

View File

@@ -6,7 +6,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -17,7 +17,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#ifndef _HISTORY_H_ #ifndef _HISTORY_H_
#define _HISTORY_H_ #define _HISTORY_H_
@@ -28,16 +28,10 @@ extern "C" {
#if defined READLINE_LIBRARY #if defined READLINE_LIBRARY
# include "rlstdc.h" # include "rlstdc.h"
# include "rltypedefs.h"
#else #else
# include <readline/rlstdc.h> # include <readline/rlstdc.h>
#endif # include <readline/rltypedefs.h>
#if !defined (_FUNCTION_DEF)
# define _FUNCTION_DEF
typedef int Function ();
typedef void VFunction ();
typedef char *CPFunction ();
typedef char **CPPFunction ();
#endif #endif
#ifdef __STDC__ #ifdef __STDC__
@@ -68,81 +62,81 @@ typedef struct _hist_state {
/* Begin a session in which the history functions might be used. This /* Begin a session in which the history functions might be used. This
just initializes the interactive variables. */ just initializes the interactive variables. */
extern void using_history __P((void)); extern void using_history PARAMS((void));
/* Return the current HISTORY_STATE of the history. */ /* Return the current HISTORY_STATE of the history. */
extern HISTORY_STATE *history_get_history_state __P((void)); extern HISTORY_STATE *history_get_history_state PARAMS((void));
/* Set the state of the current history array to STATE. */ /* Set the state of the current history array to STATE. */
extern void history_set_history_state __P((HISTORY_STATE *)); extern void history_set_history_state PARAMS((HISTORY_STATE *));
/* Manage the history list. */ /* Manage the history list. */
/* Place STRING at the end of the history list. /* Place STRING at the end of the history list.
The associated data field (if any) is set to NULL. */ The associated data field (if any) is set to NULL. */
extern void add_history __P((char *)); extern void add_history PARAMS((const char *));
/* A reasonably useless function, only here for completeness. WHICH /* A reasonably useless function, only here for completeness. WHICH
is the magic number that tells us which element to delete. The is the magic number that tells us which element to delete. The
elements are numbered from 0. */ elements are numbered from 0. */
extern HIST_ENTRY *remove_history __P((int)); extern HIST_ENTRY *remove_history PARAMS((int));
/* Make the history entry at WHICH have LINE and DATA. This returns /* Make the history entry at WHICH have LINE and DATA. This returns
the old entry so you can dispose of the data. In the case of an the old entry so you can dispose of the data. In the case of an
invalid WHICH, a NULL pointer is returned. */ invalid WHICH, a NULL pointer is returned. */
extern HIST_ENTRY *replace_history_entry __P((int, char *, histdata_t)); extern HIST_ENTRY *replace_history_entry PARAMS((int, const char *, histdata_t));
/* Clear the history list and start over. */ /* Clear the history list and start over. */
extern void clear_history __P((void)); extern void clear_history PARAMS((void));
/* Stifle the history list, remembering only MAX number of entries. */ /* Stifle the history list, remembering only MAX number of entries. */
extern void stifle_history __P((int)); extern void stifle_history PARAMS((int));
/* Stop stifling the history. This returns the previous amount the /* Stop stifling the history. This returns the previous amount the
history was stifled by. The value is positive if the history was history was stifled by. The value is positive if the history was
stifled, negative if it wasn't. */ stifled, negative if it wasn't. */
extern int unstifle_history __P((void)); extern int unstifle_history PARAMS((void));
/* Return 1 if the history is stifled, 0 if it is not. */ /* Return 1 if the history is stifled, 0 if it is not. */
extern int history_is_stifled __P((void)); extern int history_is_stifled PARAMS((void));
/* Information about the history list. */ /* Information about the history list. */
/* Return a NULL terminated array of HIST_ENTRY which is the current input /* 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 history. Element 0 of this list is the beginning of time. If there
is no history, return NULL. */ is no history, return NULL. */
extern HIST_ENTRY **history_list __P((void)); extern HIST_ENTRY **history_list PARAMS((void));
/* Returns the number which says what history element we are now /* Returns the number which says what history element we are now
looking at. */ looking at. */
extern int where_history __P((void)); extern int where_history PARAMS((void));
/* Return the history entry at the current position, as determined by /* Return the history entry at the current position, as determined by
history_offset. If there is no entry there, return a NULL pointer. */ history_offset. If there is no entry there, return a NULL pointer. */
HIST_ENTRY *current_history __P((void)); extern HIST_ENTRY *current_history PARAMS((void));
/* Return the history entry which is logically at OFFSET in the history /* Return the history entry which is logically at OFFSET in the history
array. OFFSET is relative to history_base. */ array. OFFSET is relative to history_base. */
extern HIST_ENTRY *history_get __P((int)); extern HIST_ENTRY *history_get PARAMS((int));
/* Return the number of bytes that the primary history entries are using. /* Return the number of bytes that the primary history entries are using.
This just adds up the lengths of the_history->lines. */ This just adds up the lengths of the_history->lines. */
extern int history_total_bytes __P((void)); extern int history_total_bytes PARAMS((void));
/* Moving around the history list. */ /* Moving around the history list. */
/* Set the position in the history list to POS. */ /* Set the position in the history list to POS. */
int history_set_pos __P((int)); extern int history_set_pos PARAMS((int));
/* Back up history_offset to the previous history entry, and return /* Back up history_offset to the previous history entry, and return
a pointer to that entry. If there is no previous entry, return a pointer to that entry. If there is no previous entry, return
a NULL pointer. */ a NULL pointer. */
extern HIST_ENTRY *previous_history __P((void)); extern HIST_ENTRY *previous_history PARAMS((void));
/* Move history_offset forward to the next item in the input_history, /* Move history_offset forward to the next item in the input_history,
and return the a pointer to that entry. If there is no next entry, and return the a pointer to that entry. If there is no next entry,
return a NULL pointer. */ return a NULL pointer. */
extern HIST_ENTRY *next_history __P((void)); extern HIST_ENTRY *next_history PARAMS((void));
/* Searching the history list. */ /* Searching the history list. */
@@ -152,45 +146,45 @@ extern HIST_ENTRY *next_history __P((void));
current_history () is the history entry, and the value of this function 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 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. */ found in. Otherwise, nothing is changed, and a -1 is returned. */
extern int history_search __P((char *, int)); extern int history_search PARAMS((const char *, int));
/* Search the history for STRING, starting at history_offset. /* Search the history for STRING, starting at history_offset.
The search is anchored: matching lines must begin with string. The search is anchored: matching lines must begin with string.
DIRECTION is as in history_search(). */ DIRECTION is as in history_search(). */
extern int history_search_prefix __P((char *, int)); extern int history_search_prefix PARAMS((const char *, int));
/* Search for STRING in the history list, starting at POS, an /* Search for STRING in the history list, starting at POS, an
absolute index into the list. DIR, if negative, says to search absolute index into the list. DIR, if negative, says to search
backwards from POS, else forwards. backwards from POS, else forwards.
Returns the absolute index of the history element where STRING Returns the absolute index of the history element where STRING
was found, or -1 otherwise. */ was found, or -1 otherwise. */
extern int history_search_pos __P((char *, int, int)); extern int history_search_pos PARAMS((const char *, int, int));
/* Managing the history file. */ /* Managing the history file. */
/* Add the contents of FILENAME to the history list, a line at a time. /* 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 If FILENAME is NULL, then read from ~/.history. Returns 0 if
successful, or errno if not. */ successful, or errno if not. */
extern int read_history __P((char *)); extern int read_history PARAMS((const char *));
/* Read a range of lines from FILENAME, adding them to the history list. /* 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 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 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 until the end of the file. If FILENAME is NULL, then read from
~/.history. Returns 0 if successful, or errno if not. */ ~/.history. Returns 0 if successful, or errno if not. */
extern int read_history_range __P((char *, int, int)); extern int read_history_range PARAMS((const char *, int, int));
/* Write the current history to FILENAME. If FILENAME is NULL, /* Write the current history to FILENAME. If FILENAME is NULL,
then write the history list to ~/.history. Values returned then write the history list to ~/.history. Values returned
are as in read_history (). */ are as in read_history (). */
extern int write_history __P((char *)); extern int write_history PARAMS((const char *));
/* Append NELEMENT entries to FILENAME. The entries appended are from /* Append NELEMENT entries to FILENAME. The entries appended are from
the end of the list minus NELEMENTs up to the end of the list. */ the end of the list minus NELEMENTs up to the end of the list. */
int append_history __P((int, char *)); extern int append_history PARAMS((int, const char *));
/* Truncate the history file, leaving only the last NLINES lines. */ /* Truncate the history file, leaving only the last NLINES lines. */
extern int history_truncate_file __P((char *, int)); extern int history_truncate_file PARAMS((const char *, int));
/* History expansion. */ /* History expansion. */
@@ -206,12 +200,12 @@ extern int history_truncate_file __P((char *, int));
If an error ocurred in expansion, then OUTPUT contains a descriptive If an error ocurred in expansion, then OUTPUT contains a descriptive
error message. */ error message. */
extern int history_expand __P((char *, char **)); extern int history_expand PARAMS((char *, char **));
/* Extract a string segment consisting of the FIRST through LAST /* Extract a string segment consisting of the FIRST through LAST
arguments present in STRING. Arguments are broken up as in arguments present in STRING. Arguments are broken up as in
the shell. */ the shell. */
extern char *history_arg_extract __P((int, int, char *)); extern char *history_arg_extract PARAMS((int, int, const char *));
/* Return the text of the history event beginning at the current /* Return the text of the history event beginning at the current
offset into STRING. Pass STRING with *INDEX equal to the offset into STRING. Pass STRING with *INDEX equal to the
@@ -219,27 +213,31 @@ extern char *history_arg_extract __P((int, int, char *));
DELIMITING_QUOTE is a character that is allowed to end the string DELIMITING_QUOTE is a character that is allowed to end the string
specification for what to search for in addition to the normal specification for what to search for in addition to the normal
characters `:', ` ', `\t', `\n', and sometimes `?'. */ characters `:', ` ', `\t', `\n', and sometimes `?'. */
extern char *get_history_event __P((char *, int *, int)); extern char *get_history_event PARAMS((const char *, int *, int));
/* Return an array of tokens, much as the shell might. The tokens are /* Return an array of tokens, much as the shell might. The tokens are
parsed out of STRING. */ parsed out of STRING. */
extern char **history_tokenize __P((char *)); extern char **history_tokenize PARAMS((const char *));
/* Exported history variables. */ /* Exported history variables. */
extern int history_base; extern int history_base;
extern int history_length; extern int history_length;
extern int max_input_history; extern int history_max_entries;
extern char history_expansion_char; extern char history_expansion_char;
extern char history_subst_char; extern char history_subst_char;
extern char *history_word_delimiters;
extern char history_comment_char; extern char history_comment_char;
extern const char *history_no_expand_chars; extern char *history_no_expand_chars;
extern const char *history_search_delimiter_chars; extern char *history_search_delimiter_chars;
extern int history_quotes_inhibit_expansion; extern int history_quotes_inhibit_expansion;
/* Backwards compatibility */
extern int max_input_history;
/* If set, this function is called to decide whether or not a particular /* If set, this function is called to decide whether or not a particular
history expansion should be treated as a special case for the calling history expansion should be treated as a special case for the calling
application and not expanded. */ application and not expanded. */
extern Function *history_inhibit_expansion_function; extern rl_linebuf_func_t *history_inhibit_expansion_function;
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -7,7 +7,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -18,7 +18,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
@@ -32,27 +32,22 @@
#else #else
# include "ansi_stdlib.h" # include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */ #endif /* HAVE_STDLIB_H */
#if defined (HAVE_UNISTD_H) #if defined (HAVE_UNISTD_H)
# ifdef _MINIX # ifdef _MINIX
# include <sys/types.h> # include <sys/types.h>
# endif # endif
# include <unistd.h> # include <unistd.h>
#endif #endif
#if defined (HAVE_STRING_H)
# include <string.h>
#else
# include <strings.h>
#endif /* !HAVE_STRING_H */
#include "history.h" #include "history.h"
#include "histlib.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 /* The list of alternate characters that can delimit a history search
string. */ string. */
const char *history_search_delimiter_chars = (char *)NULL; char *history_search_delimiter_chars = (char *)NULL;
static int history_search_internal PARAMS((const char *, int, int));
/* Search the history for STRING, starting at history_offset. /* Search the history for STRING, starting at history_offset.
If DIRECTION < 0, then the search is through previous entries, else If DIRECTION < 0, then the search is through previous entries, else
@@ -66,7 +61,7 @@ const char *history_search_delimiter_chars = (char *)NULL;
static int static int
history_search_internal (string, direction, anchored) history_search_internal (string, direction, anchored)
char *string; const char *string;
int direction, anchored; int direction, anchored;
{ {
register int i, reverse; register int i, reverse;
@@ -162,7 +157,7 @@ history_search_internal (string, direction, anchored)
/* Do a non-anchored search for STRING through the history in DIRECTION. */ /* Do a non-anchored search for STRING through the history in DIRECTION. */
int int
history_search (string, direction) history_search (string, direction)
char *string; const char *string;
int direction; int direction;
{ {
return (history_search_internal (string, direction, NON_ANCHORED_SEARCH)); return (history_search_internal (string, direction, NON_ANCHORED_SEARCH));
@@ -171,7 +166,7 @@ history_search (string, direction)
/* Do an anchored search for string through the history in DIRECTION. */ /* Do an anchored search for string through the history in DIRECTION. */
int int
history_search_prefix (string, direction) history_search_prefix (string, direction)
char *string; const char *string;
int direction; int direction;
{ {
return (history_search_internal (string, direction, ANCHORED_SEARCH)); return (history_search_internal (string, direction, ANCHORED_SEARCH));
@@ -182,7 +177,7 @@ history_search_prefix (string, direction)
which point to begin searching. */ which point to begin searching. */
int int
history_search_pos (string, dir, pos) history_search_pos (string, dir, pos)
char *string; const char *string;
int dir, pos; int dir, pos;
{ {
int ret, old; int ret, old;

View File

@@ -18,7 +18,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
@@ -42,7 +42,7 @@
#endif /* HAVE_STDLIB_H */ #endif /* HAVE_STDLIB_H */
#if defined (HAVE_SELECT) #if defined (HAVE_SELECT)
# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX) || defined(TIME_WITH_SYS_TIME) # if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)
# include <sys/time.h> # include <sys/time.h>
# endif # endif
#endif /* HAVE_SELECT */ #endif /* HAVE_SELECT */
@@ -63,48 +63,31 @@ extern int errno;
/* System-specific feature definitions and include files. */ /* System-specific feature definitions and include files. */
#include "rldefs.h" #include "rldefs.h"
#include "rlmbutil.h"
/* Some standard library routines. */ /* Some standard library routines. */
#include "readline.h" #include "readline.h"
#include "rlprivate.h"
#include "rlshell.h"
#include "xmalloc.h"
/* What kind of non-blocking I/O do we have? */ /* What kind of non-blocking I/O do we have? */
#if !defined (O_NDELAY) && defined (O_NONBLOCK) #if !defined (O_NDELAY) && defined (O_NONBLOCK)
# define O_NDELAY O_NONBLOCK /* Posix style */ # define O_NDELAY O_NONBLOCK /* Posix style */
#endif #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 /* Non-null means it is a pointer to a function to run while waiting for
character input. */ character input. */
Function *rl_event_hook = (Function *)NULL; rl_hook_func_t *rl_event_hook = (rl_hook_func_t *)NULL;
Function *rl_getc_function = rl_getc; rl_getc_func_t *rl_getc_function = rl_getc;
static int _keyboard_input_timeout = 100000; /* 0.1 seconds; it's in usec */
static int ibuffer_space PARAMS((void));
static int rl_get_char PARAMS((int *));
static int rl_gather_tyi PARAMS((void));
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
@@ -156,8 +139,8 @@ rl_get_char (key)
/* Stuff KEY into the *front* of the input buffer. /* Stuff KEY into the *front* of the input buffer.
Returns non-zero if successful, zero if there is Returns non-zero if successful, zero if there is
no space left in the buffer. */ no space left in the buffer. */
static int int
rl_unget_char (key) _rl_unget_char (key)
int key; int key;
{ {
if (ibuffer_space ()) if (ibuffer_space ())
@@ -171,33 +154,12 @@ rl_unget_char (key)
return (0); return (0);
} }
#if defined(__EMX__) /* If a character is available to be read, then read it and stuff it into
int waiting_char = -1; IBUFFER. Otherwise, just return. Returns number of characters read
#endif (0 if none available) and -1 on error (EIO). */
static int
/* If a character is available to be read, then read it
and stuff it into IBUFFER. Otherwise, just return. */
static void
rl_gather_tyi () rl_gather_tyi ()
{ {
#if defined (__EMX__)
if (isatty (0) && (waiting_char = _read_kbd(0, 0, 0)) != -1 && ibuffer_space ())
{
int i;
i = (*rl_getc_function) (rl_instream);
rl_stuff_char (i);
}
#elif 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; int tty;
register int tem, result; register int tem, result;
int chars_avail; int chars_avail;
@@ -215,14 +177,18 @@ rl_gather_tyi ()
FD_SET (tty, &readfds); FD_SET (tty, &readfds);
FD_SET (tty, &exceptfds); FD_SET (tty, &exceptfds);
timeout.tv_sec = 0; timeout.tv_sec = 0;
timeout.tv_usec = 100000; /* 0.1 seconds */ timeout.tv_usec = _keyboard_input_timeout;
if (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) <= 0) result = select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout);
return; /* Nothing to read. */ if (result <= 0)
return 0; /* Nothing to read. */
#endif #endif
result = -1; result = -1;
#if defined (FIONREAD) #if defined (FIONREAD)
errno = 0;
result = ioctl (tty, FIONREAD, &chars_avail); result = ioctl (tty, FIONREAD, &chars_avail);
if (result == -1 && errno == EIO)
return -1;
#endif #endif
#if defined (O_NDELAY) #if defined (O_NDELAY)
@@ -235,14 +201,14 @@ rl_gather_tyi ()
fcntl (tty, F_SETFL, tem); fcntl (tty, F_SETFL, tem);
if (chars_avail == -1 && errno == EAGAIN) if (chars_avail == -1 && errno == EAGAIN)
return; return 0;
} }
#endif /* O_NDELAY */ #endif /* O_NDELAY */
/* If there's nothing available, don't waste time trying to read /* If there's nothing available, don't waste time trying to read
something. */ something. */
if (chars_avail <= 0) if (chars_avail <= 0)
return; return 0;
tem = ibuffer_space (); tem = ibuffer_space ();
@@ -266,23 +232,36 @@ rl_gather_tyi ()
if (chars_avail) if (chars_avail)
rl_stuff_char (input); rl_stuff_char (input);
} }
#endif /* !__GO32__ */
return 1;
}
int
rl_set_keyboard_input_timeout (u)
int u;
{
int o;
o = _keyboard_input_timeout;
if (u > 0)
_keyboard_input_timeout = u;
return (o);
} }
/* Is there input available to be read on the readline input file /* Is there input available to be read on the readline input file
descriptor? Only works if the system has select(2) or FIONREAD. */ descriptor? Only works if the system has select(2) or FIONREAD.
Uses the value of _keyboard_input_timeout as the timeout; if another
readline function wants to specify a timeout and not leave it up to
the user, it should use _rl_input_queued(timeout_value_in_microseconds)
instead. */
int int
_rl_input_available () _rl_input_available ()
{ {
#if defined (__EMX__)
if (isatty (0) && (waiting_char = _read_kbd(0, 0, 0)) != -1)
return 1;
#else /* __EMX__ */
#if defined(HAVE_SELECT) #if defined(HAVE_SELECT)
fd_set readfds, exceptfds; fd_set readfds, exceptfds;
struct timeval timeout; struct timeval timeout;
#endif #endif
#if defined(FIONREAD) #if !defined (HAVE_SELECT) && defined(FIONREAD)
int chars_avail; int chars_avail;
#endif #endif
int tty; int tty;
@@ -295,28 +274,41 @@ _rl_input_available ()
FD_SET (tty, &readfds); FD_SET (tty, &readfds);
FD_SET (tty, &exceptfds); FD_SET (tty, &exceptfds);
timeout.tv_sec = 0; timeout.tv_sec = 0;
timeout.tv_usec = 100000; /* 0.1 seconds */ timeout.tv_usec = _keyboard_input_timeout;
return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0); return (select (tty + 1, &readfds, (fd_set *)NULL, &exceptfds, &timeout) > 0);
#endif #else
#if defined (FIONREAD) #if defined (FIONREAD)
if (ioctl (tty, FIONREAD, &chars_avail) == 0) if (ioctl (tty, FIONREAD, &chars_avail) == 0)
return (chars_avail); return (chars_avail);
#endif #endif
#endif /* !__EMX__ */
#endif
return 0; return 0;
} }
int
_rl_input_queued (t)
int t;
{
int old_timeout, r;
old_timeout = rl_set_keyboard_input_timeout (t);
r = _rl_input_available ();
rl_set_keyboard_input_timeout (old_timeout);
return r;
}
void void
_rl_insert_typein (c) _rl_insert_typein (c)
int c; int c;
{ {
int key, t, i; int key, t, i;
char *string; char *string;
i = key = 0; i = key = 0;
string = xmalloc (ibuffer_len + 1); string = (char *)xmalloc (ibuffer_len + 1);
string[i++] = (char) c; string[i++] = (char) c;
while ((t = rl_get_char (&key)) && while ((t = rl_get_char (&key)) &&
@@ -325,7 +317,7 @@ _rl_insert_typein (c)
string[i++] = key; string[i++] = key;
if (t) if (t)
rl_unget_char (key); _rl_unget_char (key);
string[i] = '\0'; string[i] = '\0';
rl_insert_text (string); rl_insert_text (string);
@@ -345,6 +337,7 @@ rl_stuff_char (key)
{ {
key = NEWLINE; key = NEWLINE;
rl_pending_input = EOF; rl_pending_input = EOF;
RL_SETSTATE (RL_STATE_INPUTPENDING);
} }
ibuffer[push_index++] = key; ibuffer[push_index++] = key;
if (push_index >= ibuffer_len) if (push_index >= ibuffer_len)
@@ -359,6 +352,16 @@ rl_execute_next (c)
int c; int c;
{ {
rl_pending_input = c; rl_pending_input = c;
RL_SETSTATE (RL_STATE_INPUTPENDING);
return 0;
}
/* Clear any pending input pushed with rl_execute_next() */
int
rl_clear_pending_input ()
{
rl_pending_input = 0;
RL_UNSETSTATE (RL_STATE_INPUTPENDING);
return 0; return 0;
} }
@@ -379,7 +382,7 @@ rl_read_key ()
if (rl_pending_input) if (rl_pending_input)
{ {
c = rl_pending_input; c = rl_pending_input;
rl_pending_input = 0; rl_clear_pending_input ();
} }
else else
{ {
@@ -393,7 +396,13 @@ rl_read_key ()
while (rl_event_hook && rl_get_char (&c) == 0) while (rl_event_hook && rl_get_char (&c) == 0)
{ {
(*rl_event_hook) (); (*rl_event_hook) ();
rl_gather_tyi (); if (rl_done) /* XXX - experimental */
return ('\n');
if (rl_gather_tyi () < 0) /* XXX - EIO */
{
rl_done = 1;
return ('\n');
}
} }
} }
else else
@@ -410,96 +419,9 @@ int
rl_getc (stream) rl_getc (stream)
FILE *stream; FILE *stream;
{ {
int result, flags; int result;
unsigned char c; unsigned char c;
#if defined (__EMX__)
if (isatty (0))
{
int key;
if (waiting_char != -1)
{
key = waiting_char;
waiting_char = -1;
}
else
{
#ifdef __RSXNT__
pc_flush();
#endif
key = _read_kbd(0, 1, 0);
}
while (key == 0)
{
key |= (_read_kbd(0, 1, 0) << 8);
/* printf("<%04X> ", key);
fflush(stdout); */
switch (key)
{
case 0x4B00: /* left arrow */
key = 'B' - 64;
break;
case 0x4D00: /* right arrow */
key = 'F' - 64;
break;
case 0x7300: /* ctrl left arrow */
key = 27;
waiting_char = 'B';
break;
case 0x7400: /* ctrl right arrow */
key = 27;
waiting_char = 'F';
break;
case 0x4800: /* up arrow */
key = 'P' - 64;
break;
case 0x5000: /* down arrow */
key = 'N' - 64;
break;
case 0x8D00: /* ctrl up arrow */
key = 'R' - 64;
break;
case 0x9100: /* ctrl down arrow */
key = 'S' - 64;
break;
case 0x4700: /* home key */
key = 'A' - 64;
break;
case 0x4F00: /* end key */
key = 'E' - 64;
break;
case 0x7700: /* ctrl home key */
key = 27;
waiting_char = '<';
break;
case 0x7500: /* ctrl end key */
key = 27;
waiting_char = '>';
break;
case 0x5300: /* delete key */
key = 'D' - 64;
break;
case 0x5200: /* insert key */
key = 'V' - 64;
break;
default: /* ignore all other special keys, read next */
key = _read_kbd(0, 1, 0);
break;
}
}
return (key & 0xFF);
}
#endif /* __EMX__ */
#if defined (__GO32__)
if (isatty (0))
return (getkey () & 0x7F);
#endif /* __GO32__ */
while (1) while (1)
{ {
result = read (fileno (stream), &c, sizeof (unsigned char)); result = read (fileno (stream), &c, sizeof (unsigned char));
@@ -518,40 +440,101 @@ rl_getc (stream)
#endif #endif
#if defined (EWOULDBLOCK) #if defined (EWOULDBLOCK)
if (errno == EWOULDBLOCK) # define X_EWOULDBLOCK EWOULDBLOCK
#else
# define X_EWOULDBLOCK -99
#endif
#if defined (EAGAIN)
# define X_EAGAIN EAGAIN
#else
# define X_EAGAIN -99
#endif
if (errno == X_EWOULDBLOCK || errno == X_EAGAIN)
{ {
if ((flags = fcntl (fileno (stream), F_GETFL, 0)) < 0) if (sh_unset_nodelay_mode (fileno (stream)) < 0)
return (EOF); return (EOF);
if (flags & O_NDELAY)
{
flags &= ~O_NDELAY;
fcntl (fileno (stream), F_SETFL, flags);
continue;
}
continue; continue;
} }
#endif /* EWOULDBLOCK */
#if defined (_POSIX_VERSION) && defined (EAGAIN) && defined (O_NONBLOCK) #undef X_EWOULDBLOCK
if (errno == EAGAIN) #undef X_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, /* If the error that we received was SIGINT, then try again,
this is simply an interrupted system call to read (). this is simply an interrupted system call to read ().
Otherwise, some error ocurred, also signifying EOF. */ Otherwise, some error ocurred, also signifying EOF. */
if (errno != EINTR) if (errno != EINTR)
return (EOF); return (EOF);
#endif /* !__GO32__ */
} }
} }
#if defined (HANDLE_MULTIBYTE)
/* read multibyte char */
int
_rl_read_mbchar (mbchar, size)
char *mbchar;
int size;
{
int mb_len = 0;
size_t mbchar_bytes_length;
wchar_t wc;
mbstate_t ps, ps_back;
memset(&ps, 0, sizeof (mbstate_t));
memset(&ps_back, 0, sizeof (mbstate_t));
while (mb_len < size)
{
RL_SETSTATE(RL_STATE_MOREINPUT);
mbchar[mb_len++] = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
mbchar_bytes_length = mbrtowc (&wc, mbchar, mb_len, &ps);
if (mbchar_bytes_length == (size_t)(-1))
break; /* invalid byte sequence for the current locale */
else if (mbchar_bytes_length == (size_t)(-2))
{
/* shorted bytes */
ps = ps_back;
continue;
}
else if (mbchar_bytes_length > (size_t)(0))
break;
}
return mb_len;
}
/* Read a multibyte-character string whose first character is FIRST into
the buffer MB of length MBLEN. Returns the last character read, which
may be FIRST. Used by the search functions, among others. Very similar
to _rl_read_mbchar. */
int
_rl_read_mbstring (first, mb, mblen)
int first;
char *mb;
int mblen;
{
int i, c;
mbstate_t ps;
c = first;
memset (mb, 0, mblen);
for (i = 0; i < mblen; i++)
{
mb[i] = (char)c;
memset (&ps, 0, sizeof (mbstate_t));
if (_rl_get_char_len (mb, &ps) == -2)
{
/* Read more for multibyte character */
RL_SETSTATE (RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE (RL_STATE_MOREINPUT);
}
else
break;
}
return c;
}
#endif /* HANDLE_MULTIBYTE */

View File

@@ -4,7 +4,7 @@
/* */ /* */
/* **************************************************************** */ /* **************************************************************** */
/* Copyright (C) 1987,1989 Free Software Foundation, Inc. /* Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file contains the Readline Library (the Library), a set of This file contains the Readline Library (the Library), a set of
routines for providing Emacs style line input to programs that ask routines for providing Emacs style line input to programs that ask
@@ -12,7 +12,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -23,7 +23,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
@@ -45,32 +45,33 @@
#endif #endif
#include "rldefs.h" #include "rldefs.h"
#include "rlmbutil.h"
#include "readline.h" #include "readline.h"
#include "history.h" #include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* Variables exported to other files in the readline library. */ /* Variables exported to other files in the readline library. */
unsigned char *_rl_isearch_terminators = (unsigned char *)NULL; char *_rl_isearch_terminators = (char *)NULL;
/* Variables imported from other files in the readline library. */ /* Variables imported from other files in the readline library. */
extern Keymap _rl_keymap; extern HIST_ENTRY *_rl_saved_line_for_history;
extern HIST_ENTRY *saved_line_for_history;
extern int rl_line_buffer_len;
extern int rl_point, rl_end;
extern char *rl_line_buffer;
extern int rl_execute_next (); /* Forward declarations */
extern void rl_extend_line_buffer (); static int rl_search_history PARAMS((int, int));
extern int _rl_input_available ();
extern char *xmalloc (), *xrealloc ();
static int rl_search_history ();
/* Last line found by the current incremental search, so we don't `find' /* Last line found by the current incremental search, so we don't `find'
identical lines many times in a row. */ identical lines many times in a row. */
static char *prev_line_found; static char *prev_line_found;
/* Last search string and its length. */
static char *last_isearch_string;
static int last_isearch_string_len;
static char default_isearch_terminators[] = "\033\012";
/* Search backwards through the history looking for a string which is typed /* Search backwards through the history looking for a string which is typed
interactively. Start with the current line. */ interactively. Start with the current line. */
int int
@@ -97,15 +98,14 @@ rl_forward_search_history (sign, key)
static void static void
rl_display_search (search_string, reverse_p, where) rl_display_search (search_string, reverse_p, where)
char *search_string; char *search_string;
int reverse_p; int reverse_p, where __attribute__((unused));
int where __attribute__((unused));
{ {
char *message; char *message;
int msglen, searchlen; int msglen, searchlen;
searchlen = (search_string && *search_string) ? strlen (search_string) : 0; searchlen = (search_string && *search_string) ? strlen (search_string) : 0;
message = xmalloc (searchlen + 33); message = (char *)xmalloc (searchlen + 33);
msglen = 0; msglen = 0;
#if defined (NOTDEF) #if defined (NOTDEF)
@@ -135,7 +135,7 @@ rl_display_search (search_string, reverse_p, where)
strcpy (message + msglen, "': "); strcpy (message + msglen, "': ");
rl_message ("%s", message, 0); rl_message ("%s", message);
free (message); free (message);
(*rl_redisplay_function) (); (*rl_redisplay_function) ();
} }
@@ -145,7 +145,8 @@ rl_display_search (search_string, reverse_p, where)
DIRECTION is which direction to search; >= 0 means forward, < 0 means DIRECTION is which direction to search; >= 0 means forward, < 0 means
backwards. */ backwards. */
static int static int
rl_search_history (int direction, int invoking_key __attribute__((unused))) rl_search_history (direction, invoking_key)
int direction, invoking_key __attribute__((unused));
{ {
/* The string that the user types in to search for. */ /* The string that the user types in to search for. */
char *search_string; char *search_string;
@@ -166,8 +167,12 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
HIST_ENTRY **hlist; HIST_ENTRY **hlist;
register int i; register int i;
int orig_point, orig_line, last_found_line; int orig_point, orig_mark, orig_line, last_found_line;
int c, found, failed, sline_len; int c, found, failed, sline_len;
int n, wstart, wlen;
#if defined (HANDLE_MULTIBYTE)
char mb[MB_LEN_MAX];
#endif
/* The line currently being searched. */ /* The line currently being searched. */
char *sline; char *sline;
@@ -181,19 +186,21 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
/* The list of characters which terminate the search, but are not /* The list of characters which terminate the search, but are not
subsequently executed. If the variable isearch-terminators has subsequently executed. If the variable isearch-terminators has
been set, we use that value, otherwise we use ESC and C-J. */ been set, we use that value, otherwise we use ESC and C-J. */
unsigned char *isearch_terminators; char *isearch_terminators;
RL_SETSTATE(RL_STATE_ISEARCH);
orig_point = rl_point; orig_point = rl_point;
orig_mark = rl_mark;
last_found_line = orig_line = where_history (); last_found_line = orig_line = where_history ();
reverse = direction < 0; reverse = direction < 0;
hlist = history_list (); hlist = history_list ();
allocated_line = (char *)NULL; allocated_line = (char *)NULL;
isearch_terminators = _rl_isearch_terminators ? _rl_isearch_terminators isearch_terminators = _rl_isearch_terminators ? _rl_isearch_terminators
: (unsigned char *)"\033\012"; : default_isearch_terminators;
/* Create an arrary of pointers to the lines that we want to search. */ /* Create an arrary of pointers to the lines that we want to search. */
maybe_replace_line (); rl_maybe_replace_line ();
i = 0; i = 0;
if (hlist) if (hlist)
for (i = 0; hlist[i]; i++); for (i = 0; hlist[i]; i++);
@@ -204,12 +211,12 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
for (i = 0; i < hlen; i++) for (i = 0; i < hlen; i++)
lines[i] = hlist[i]->line; lines[i] = hlist[i]->line;
if (saved_line_for_history) if (_rl_saved_line_for_history)
lines[i] = saved_line_for_history->line; lines[i] = _rl_saved_line_for_history->line;
else else
{ {
/* Keep track of this so we can free it. */ /* Keep track of this so we can free it. */
allocated_line = xmalloc (1 + strlen (rl_line_buffer)); allocated_line = (char *)xmalloc (1 + strlen (rl_line_buffer));
strcpy (allocated_line, &rl_line_buffer[0]); strcpy (allocated_line, &rl_line_buffer[0]);
lines[i] = allocated_line; lines[i] = allocated_line;
} }
@@ -222,7 +229,7 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
rl_save_prompt (); rl_save_prompt ();
/* Initialize search parameters. */ /* Initialize search parameters. */
search_string = xmalloc (search_string_size = 128); search_string = (char *)xmalloc (search_string_size = 128);
*search_string = '\0'; *search_string = '\0';
search_string_index = 0; search_string_index = 0;
prev_line_found = (char *)0; /* XXX */ prev_line_found = (char *)0; /* XXX */
@@ -239,12 +246,20 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
found = failed = 0; found = failed = 0;
for (;;) for (;;)
{ {
Function *f = (Function *)NULL; rl_command_func_t *f = (rl_command_func_t *)NULL;
/* Read a key and decide how to proceed. */ /* Read a key and decide how to proceed. */
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key (); c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (_rl_keymap[c].type == ISFUNC) #if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
#endif
/* Translate the keys we do something with to opcodes. */
if (c >= 0 && _rl_keymap[c].type == ISFUNC)
{ {
f = _rl_keymap[c].function; f = _rl_keymap[c].function;
@@ -252,34 +267,56 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
c = reverse ? -1 : -2; c = reverse ? -1 : -2;
else if (f == rl_forward_search_history) else if (f == rl_forward_search_history)
c = !reverse ? -1 : -2; c = !reverse ? -1 : -2;
else if (f == rl_rubout)
c = -3;
else if (c == CTRL ('G'))
c = -4;
else if (c == CTRL ('W')) /* XXX */
c = -5;
else if (c == CTRL ('Y')) /* XXX */
c = -6;
} }
#if 0
/* 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)
#else
/* The characters in isearch_terminators (set from the user-settable /* The characters in isearch_terminators (set from the user-settable
variable isearch-terminators) are used to terminate the search but variable isearch-terminators) are used to terminate the search but
not subsequently execute the character as a command. The default not subsequently execute the character as a command. The default
value is "\033\012" (ESC and C-J). */ value is "\033\012" (ESC and C-J). */
if (strchr((char*) isearch_terminators, c)) if (strchr (isearch_terminators, c))
#endif
{ {
/* ESC still terminates the search, but if there is pending /* ESC still terminates the search, but if there is pending
input or if input arrives within 0.1 seconds (on systems input or if input arrives within 0.1 seconds (on systems
with select(2)) it is used as a prefix character with select(2)) it is used as a prefix character
with rl_execute_next. WATCH OUT FOR THIS! This is intended 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 allow the arrow keys to be used like ^F and ^B are used
to terminate the search and execute the movement command. */ to terminate the search and execute the movement command.
if (c == ESC && _rl_input_available ()) /* XXX */ XXX - since _rl_input_available depends on the application-
settable keyboard timeout value, this could alternatively
use _rl_input_queued(100000) */
if (c == ESC && _rl_input_available ())
rl_execute_next (ESC); rl_execute_next (ESC);
break; break;
} }
if (c >= 0 && (CTRL_CHAR (c) || META_CHAR (c) || c == RUBOUT) && c != CTRL ('G')) #define ENDSRCH_CHAR(c) \
((CTRL_CHAR (c) || META_CHAR (c) || (c) == RUBOUT) && ((c) != CTRL ('G')))
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{ {
if (c >= 0 && strlen (mb) == 1 && ENDSRCH_CHAR (c))
{
/* This sets rl_pending_input to c; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (c);
break;
}
}
else
#endif
if (c >= 0 && ENDSRCH_CHAR (c))
{
/* This sets rl_pending_input to c; it will be picked up the next
time rl_read_key is called. */
rl_execute_next (c); rl_execute_next (c);
break; break;
} }
@@ -288,13 +325,24 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
{ {
case -1: case -1:
if (search_string_index == 0) if (search_string_index == 0)
continue; {
if (last_isearch_string)
{
search_string_size = 64 + last_isearch_string_len;
search_string = (char *)xrealloc (search_string, search_string_size);
strcpy (search_string, last_isearch_string);
search_string_index = last_isearch_string_len;
rl_display_search (search_string, reverse, -1);
break;
}
continue;
}
else if (reverse) else if (reverse)
--line_index; --line_index;
else if (line_index != sline_len) else if (line_index != sline_len)
++line_index; ++line_index;
else else
ding (); rl_ding ();
break; break;
/* switch directions */ /* switch directions */
@@ -303,40 +351,96 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
reverse = direction < 0; reverse = direction < 0;
break; break;
case CTRL ('G'): /* delete character from search string. */
strcpy (rl_line_buffer, lines[orig_line]); case -3: /* C-H, DEL */
/* This is tricky. To do this right, we need to keep a
stack of search positions for the current search, with
sentinels marking the beginning and end. But this will
do until we have a real isearch-undo. */
if (search_string_index == 0)
rl_ding ();
else
search_string[--search_string_index] = '\0';
break;
case -4: /* C-G */
rl_replace_line (lines[orig_line], 0);
rl_point = orig_point; rl_point = orig_point;
rl_end = strlen (rl_line_buffer); rl_mark = orig_mark;
rl_restore_prompt(); rl_restore_prompt();
rl_clear_message (); rl_clear_message ();
if (allocated_line) if (allocated_line)
free (allocated_line); free (allocated_line);
free (lines); free (lines);
RL_UNSETSTATE(RL_STATE_ISEARCH);
return 0; return 0;
#if 0 case -5: /* C-W */
/* delete character from search string. */ /* skip over portion of line we already matched */
case -3: wstart = rl_point + search_string_index;
if (search_string_index == 0) if (wstart >= rl_end)
ding ();
else
{ {
search_string[--search_string_index] = '\0'; rl_ding ();
/* This is tricky. To do this right, we need to keep a break;
stack of search positions for the current search, with
sentinels marking the beginning and end. */
} }
/* if not in a word, move to one. */
if (rl_alphabetic(rl_line_buffer[wstart]) == 0)
{
rl_ding ();
break;
}
n = wstart;
while (n < rl_end && rl_alphabetic(rl_line_buffer[n]))
n++;
wlen = n - wstart + 1;
if (search_string_index + wlen + 1 >= search_string_size)
{
search_string_size += wlen + 1;
search_string = (char *)xrealloc (search_string, search_string_size);
}
for (; wstart < n; wstart++)
search_string[search_string_index++] = rl_line_buffer[wstart];
search_string[search_string_index] = '\0';
break;
case -6: /* C-Y */
/* skip over portion of line we already matched */
wstart = rl_point + search_string_index;
if (wstart >= rl_end)
{
rl_ding ();
break;
}
n = rl_end - wstart + 1;
if (search_string_index + n + 1 >= search_string_size)
{
search_string_size += n + 1;
search_string = (char *)xrealloc (search_string, search_string_size);
}
for (n = wstart; n < rl_end; n++)
search_string[search_string_index++] = rl_line_buffer[n];
search_string[search_string_index] = '\0';
break; break;
#endif
default: default:
/* Add character to search string and continue search. */ /* Add character to search string and continue search. */
if (search_string_index + 2 >= search_string_size) if (search_string_index + 2 >= search_string_size)
{ {
search_string_size += 128; search_string_size += 128;
search_string = xrealloc (search_string, search_string_size); search_string = (char *)xrealloc (search_string, search_string_size);
} }
search_string[search_string_index++] = c; #if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
int j, l;
for (j = 0, l = strlen (mb); j < l; )
search_string[search_string_index++] = mb[j++];
}
else
#endif
search_string[search_string_index++] = c;
search_string[search_string_index] = '\0'; search_string[search_string_index] = '\0';
break; break;
} }
@@ -391,7 +495,7 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
if (failed) if (failed)
{ {
/* We cannot find the search string. Ding the bell. */ /* We cannot find the search string. Ding the bell. */
ding (); rl_ding ();
i = last_found_line; i = last_found_line;
continue; /* XXX - was break */ continue; /* XXX - was break */
} }
@@ -401,17 +505,9 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
the location. */ the location. */
if (found) if (found)
{ {
int line_len;
prev_line_found = lines[i]; prev_line_found = lines[i];
line_len = strlen (lines[i]); rl_replace_line (lines[i], 0);
if (line_len >= rl_line_buffer_len)
rl_extend_line_buffer (line_len);
strcpy (rl_line_buffer, lines[i]);
rl_point = line_index; rl_point = line_index;
rl_end = line_len;
last_found_line = i; last_found_line = i;
rl_display_search (search_string, reverse, (i == orig_line) ? -1 : i); rl_display_search (search_string, reverse, (i == orig_line) ? -1 : i);
} }
@@ -427,23 +523,38 @@ rl_search_history (int direction, int invoking_key __attribute__((unused)))
rl_restore_prompt (); rl_restore_prompt ();
/* Free the search string. */ /* Save the search string for possible later use. */
free (search_string); FREE (last_isearch_string);
last_isearch_string = search_string;
last_isearch_string_len = search_string_index;
if (last_found_line < orig_line) if (last_found_line < orig_line)
rl_get_previous_history (orig_line - last_found_line, 0); rl_get_previous_history (orig_line - last_found_line, 0);
else else
rl_get_next_history (last_found_line - orig_line, 0); rl_get_next_history (last_found_line - orig_line, 0);
/* If the string was not found, put point at the end of the line. */ /* If the string was not found, put point at the end of the last matching
line. If last_found_line == orig_line, we didn't find any matching
history lines at all, so put point back in its original position. */
if (line_index < 0) if (line_index < 0)
line_index = strlen (rl_line_buffer); {
if (last_found_line == orig_line)
line_index = orig_point;
else
line_index = strlen (rl_line_buffer);
rl_mark = orig_mark;
}
rl_point = line_index; rl_point = line_index;
/* Don't worry about where to put the mark here; rl_get_previous_history
and rl_get_next_history take care of it. */
rl_clear_message (); rl_clear_message ();
if (allocated_line) FREE (allocated_line);
free (allocated_line);
free (lines); free (lines);
RL_UNSETSTATE(RL_STATE_ISEARCH);
return 0; return 0;
} }

View File

@@ -7,7 +7,7 @@
Readline is free software; you can redistribute it and/or modify it 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 under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 1, or (at your option) any Free Software Foundation; either version 2, or (at your option) any
later version. later version.
Readline is distributed in the hope that it will be useful, but Readline is distributed in the hope that it will be useful, but
@@ -17,7 +17,7 @@
You should have received a copy of the GNU General Public License 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 along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
@@ -30,18 +30,18 @@
# include "ansi_stdlib.h" # include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */ #endif /* HAVE_STDLIB_H */
#include <stdio.h> /* for FILE * definition for readline.h */
#include "readline.h"
#include "rlconf.h" #include "rlconf.h"
#include "keymaps.h"
#include "emacs_keymap.c" #include "emacs_keymap.c"
#if defined (VI_MODE) #if defined (VI_MODE)
#include "vi_keymap.c" #include "vi_keymap.c"
#endif #endif
extern int rl_do_lowercase_version (); #include "xmalloc.h"
extern int rl_rubout (), rl_insert ();
extern char *xmalloc (), *xrealloc ();
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
@@ -61,7 +61,7 @@ rl_make_bare_keymap ()
for (i = 0; i < KEYMAP_SIZE; i++) for (i = 0; i < KEYMAP_SIZE; i++)
{ {
keymap[i].type = ISFUNC; keymap[i].type = ISFUNC;
keymap[i].function = (Function *)NULL; keymap[i].function = (rl_command_func_t *)NULL;
} }
for (i = 'A'; i < ('Z' + 1); i++) for (i = 'A'; i < ('Z' + 1); i++)

View File

@@ -7,7 +7,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -18,25 +18,23 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#ifndef _KEYMAPS_H_ #ifndef _KEYMAPS_H_
#define _KEYMAPS_H_ #define _KEYMAPS_H_
#ifdef __cplusplus
extern "C" {
#endif
#if defined (READLINE_LIBRARY) #if defined (READLINE_LIBRARY)
# include "rlstdc.h" # include "rlstdc.h"
# include "chardefs.h" # include "chardefs.h"
# include "rltypedefs.h"
#else #else
# include <readline/rlstdc.h> # include <readline/rlstdc.h>
# include <readline/chardefs.h> # include <readline/chardefs.h>
#endif # include <readline/rltypedefs.h>
#if !defined (_FUNCTION_DEF)
# define _FUNCTION_DEF
typedef int Function ();
typedef void VFunction ();
typedef char *CPFunction ();
typedef char **CPPFunction ();
#endif #endif
/* A keymap contains one entry for each key in the ASCII set. /* A keymap contains one entry for each key in the ASCII set.
@@ -46,16 +44,17 @@ typedef char **CPPFunction ();
TYPE says which kind of thing FUNCTION is. */ TYPE says which kind of thing FUNCTION is. */
typedef struct _keymap_entry { typedef struct _keymap_entry {
char type; char type;
Function *function; rl_command_func_t *function;
} KEYMAP_ENTRY; } KEYMAP_ENTRY;
/* This must be large enough to hold bindings for all of the characters /* This must be large enough to hold bindings for all of the characters
in a desired character set (e.g, 128 for ASCII, 256 for ISO Latin-x, in a desired character set (e.g, 128 for ASCII, 256 for ISO Latin-x,
and so on). */ and so on) plus one for subsequence matching. */
#define KEYMAP_SIZE 256 #define KEYMAP_SIZE 257
#define ANYOTHERKEY KEYMAP_SIZE-1
/* I wanted to make the above structure contain a union of: /* I wanted to make the above structure contain a union of:
union { Function *function; struct _keymap_entry *keymap; } value; union { rl_command_func_t *function; struct _keymap_entry *keymap; } value;
but this made it impossible for me to create a static array. but this made it impossible for me to create a static array.
Maybe I need C lessons. */ Maybe I need C lessons. */
@@ -72,29 +71,33 @@ extern KEYMAP_ENTRY_ARRAY vi_insertion_keymap, vi_movement_keymap;
/* Return a new, empty keymap. /* Return a new, empty keymap.
Free it with free() when you are done. */ Free it with free() when you are done. */
extern Keymap rl_make_bare_keymap __P((void)); extern Keymap rl_make_bare_keymap PARAMS((void));
/* Return a new keymap which is a copy of MAP. */ /* Return a new keymap which is a copy of MAP. */
extern Keymap rl_copy_keymap __P((Keymap)); extern Keymap rl_copy_keymap PARAMS((Keymap));
/* Return a new keymap with the printing characters bound to rl_insert, /* Return a new keymap with the printing characters bound to rl_insert,
the lowercase Meta characters bound to run their equivalents, and the lowercase Meta characters bound to run their equivalents, and
the Meta digits bound to produce numeric arguments. */ the Meta digits bound to produce numeric arguments. */
extern Keymap rl_make_keymap __P((void)); extern Keymap rl_make_keymap PARAMS((void));
/* Free the storage associated with a keymap. */ /* Free the storage associated with a keymap. */
extern void rl_discard_keymap __P((Keymap)); extern void rl_discard_keymap PARAMS((Keymap));
/* These functions actually appear in bind.c */ /* These functions actually appear in bind.c */
/* Return the keymap corresponding to a given name. Names look like /* Return the keymap corresponding to a given name. Names look like
`emacs' or `emacs-meta' or `vi-insert'. */ `emacs' or `emacs-meta' or `vi-insert'. */
extern Keymap rl_get_keymap_by_name __P((char *)); extern Keymap rl_get_keymap_by_name PARAMS((const char *));
/* Return the current keymap. */ /* Return the current keymap. */
extern Keymap rl_get_keymap __P((void)); extern Keymap rl_get_keymap PARAMS((void));
/* Set the current keymap to MAP. */ /* Set the current keymap to MAP. */
extern void rl_set_keymap __P((Keymap)); extern void rl_set_keymap PARAMS((Keymap));
#ifdef __cplusplus
}
#endif
#endif /* _KEYMAPS_H_ */ #endif /* _KEYMAPS_H_ */

View File

@@ -7,7 +7,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -18,7 +18,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
@@ -46,17 +46,8 @@
#include "readline.h" #include "readline.h"
#include "history.h" #include "history.h"
extern int _rl_last_command_was_kill; #include "rlprivate.h"
extern int rl_editing_mode; #include "xmalloc.h"
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_fix_point ();
extern void _rl_abort_internal ();
extern char *xmalloc (), *xrealloc ();
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
@@ -79,10 +70,16 @@ static int rl_kill_index;
/* How many slots we have in the kill ring. */ /* How many slots we have in the kill ring. */
static int rl_kill_ring_length; static int rl_kill_ring_length;
static int _rl_copy_to_kill_ring PARAMS((char *, int));
static int region_kill_internal PARAMS((int));
static int _rl_copy_word_as_kill PARAMS((int, int));
static int rl_yank_nth_arg_internal PARAMS((int, int, int));
/* How to say that you only want to save a certain amount /* How to say that you only want to save a certain amount
of kill material. */ of kill material. */
int int
rl_set_retained_kills (int num __attribute__((unused))) rl_set_retained_kills (num)
int num __attribute__((unused));
{ {
return 0; return 0;
} }
@@ -137,7 +134,7 @@ _rl_copy_to_kill_ring (text, append)
if (_rl_last_command_was_kill && rl_editing_mode != vi_mode) if (_rl_last_command_was_kill && rl_editing_mode != vi_mode)
{ {
old = rl_kill_ring[slot]; old = rl_kill_ring[slot];
new = xmalloc (1 + strlen (old) + strlen (text)); new = (char *)xmalloc (1 + strlen (old) + strlen (text));
if (append) if (append)
{ {
@@ -204,18 +201,21 @@ int
rl_kill_word (count, key) rl_kill_word (count, key)
int count, key; int count, key;
{ {
int orig_point = rl_point; int orig_point;
if (count < 0) if (count < 0)
return (rl_backward_kill_word (-count, key)); return (rl_backward_kill_word (-count, key));
else else
{ {
orig_point = rl_point;
rl_forward_word (count, key); rl_forward_word (count, key);
if (rl_point != orig_point) if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point); rl_kill_text (orig_point, rl_point);
rl_point = orig_point; rl_point = orig_point;
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
} }
return 0; return 0;
} }
@@ -225,16 +225,20 @@ int
rl_backward_kill_word (count, ignore) rl_backward_kill_word (count, ignore)
int count, ignore; int count, ignore;
{ {
int orig_point = rl_point; int orig_point;
if (count < 0) if (count < 0)
return (rl_kill_word (-count, ignore)); return (rl_kill_word (-count, ignore));
else else
{ {
orig_point = rl_point;
rl_backward_word (count, ignore); rl_backward_word (count, ignore);
if (rl_point != orig_point) if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point); rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
} }
return 0; return 0;
} }
@@ -245,16 +249,19 @@ int
rl_kill_line (direction, ignore) rl_kill_line (direction, ignore)
int direction, ignore; int direction, ignore;
{ {
int orig_point = rl_point; int orig_point;
if (direction < 0) if (direction < 0)
return (rl_backward_kill_line (1, ignore)); return (rl_backward_kill_line (1, ignore));
else else
{ {
orig_point = rl_point;
rl_end_of_line (1, ignore); rl_end_of_line (1, ignore);
if (orig_point != rl_point) if (orig_point != rl_point)
rl_kill_text (orig_point, rl_point); rl_kill_text (orig_point, rl_point);
rl_point = orig_point; rl_point = orig_point;
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
} }
return 0; return 0;
} }
@@ -265,18 +272,22 @@ int
rl_backward_kill_line (direction, ignore) rl_backward_kill_line (direction, ignore)
int direction, ignore; int direction, ignore;
{ {
int orig_point = rl_point; int orig_point;
if (direction < 0) if (direction < 0)
return (rl_kill_line (1, ignore)); return (rl_kill_line (1, ignore));
else else
{ {
if (!rl_point) if (!rl_point)
ding (); rl_ding ();
else else
{ {
orig_point = rl_point;
rl_beg_of_line (1, ignore); rl_beg_of_line (1, ignore);
rl_kill_text (orig_point, rl_point); if (rl_point != orig_point)
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
} }
} }
return 0; return 0;
@@ -284,12 +295,13 @@ rl_backward_kill_line (direction, ignore)
/* Kill the whole line, no matter where point is. */ /* Kill the whole line, no matter where point is. */
int int
rl_kill_full_line (int count __attribute__((unused)), rl_kill_full_line (count, ignore)
int ignore __attribute__((unused))) int count __attribute__((unused)), ignore __attribute__((unused));
{ {
rl_begin_undo_group (); rl_begin_undo_group ();
rl_point = 0; rl_point = 0;
rl_kill_text (rl_point, rl_end); rl_kill_text (rl_point, rl_end);
rl_mark = 0;
rl_end_undo_group (); rl_end_undo_group ();
return 0; return 0;
} }
@@ -301,12 +313,13 @@ rl_kill_full_line (int count __attribute__((unused)),
/* This does what C-w does in Unix. We can't prevent people from /* This does what C-w does in Unix. We can't prevent people from
using behaviour that they expect. */ using behaviour that they expect. */
int int
rl_unix_word_rubout (int count, int key __attribute__((unused))) rl_unix_word_rubout (count, key)
int count, key __attribute__((unused));
{ {
int orig_point; int orig_point;
if (rl_point == 0) if (rl_point == 0)
ding (); rl_ding ();
else else
{ {
orig_point = rl_point; orig_point = rl_point;
@@ -323,6 +336,8 @@ rl_unix_word_rubout (int count, int key __attribute__((unused)))
} }
rl_kill_text (orig_point, rl_point); rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
} }
return 0; return 0;
} }
@@ -334,15 +349,17 @@ rl_unix_word_rubout (int count, int key __attribute__((unused)))
into the line at all, and if you aren't, then you know what you are into the line at all, and if you aren't, then you know what you are
doing. */ doing. */
int int
rl_unix_line_discard (int count __attribute__((unused)), rl_unix_line_discard (count, key)
int key __attribute__((unused))) int count __attribute__((unused)), key __attribute__((unused));
{ {
if (rl_point == 0) if (rl_point == 0)
ding (); rl_ding ();
else else
{ {
rl_kill_text (rl_point, 0); rl_kill_text (rl_point, 0);
rl_point = 0; rl_point = 0;
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
} }
return 0; return 0;
} }
@@ -355,38 +372,37 @@ region_kill_internal (delete)
{ {
char *text; char *text;
if (rl_mark == rl_point) if (rl_mark != rl_point)
{ {
_rl_last_command_was_kill++; text = rl_copy_text (rl_point, rl_mark);
return 0; if (delete)
rl_delete_text (rl_point, rl_mark);
_rl_copy_to_kill_ring (text, rl_point < rl_mark);
} }
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++; _rl_last_command_was_kill++;
return 0; return 0;
} }
/* Copy the text in the region to the kill ring. */ /* Copy the text in the region to the kill ring. */
int int
rl_copy_region_to_kill (int count __attribute__((unused)), rl_copy_region_to_kill (count, ignore)
int key __attribute__((unused))) int count __attribute__((unused)), ignore __attribute__((unused));
{ {
return (region_kill_internal (0)); return (region_kill_internal (0));
} }
/* Kill the text between the point and mark. */ /* Kill the text between the point and mark. */
int int
rl_kill_region (int count __attribute__((unused)), rl_kill_region (count, ignore)
int key __attribute__((unused))) int count __attribute__((unused)), ignore __attribute__((unused));
{ {
int r; int r, npoint;
npoint = (rl_point < rl_mark) ? rl_point : rl_mark;
r = region_kill_internal (1); r = region_kill_internal (1);
_rl_fix_point (1); _rl_fix_point (1);
rl_point = npoint;
return r; return r;
} }
@@ -440,11 +456,11 @@ rl_copy_backward_word (count, key)
return (_rl_copy_word_as_kill (count, -1)); return (_rl_copy_word_as_kill (count, -1));
} }
/* Yank back the last killed text. This ignores arguments. */ /* Yank back the last killed text. This ignores arguments. */
int int
rl_yank (int count __attribute__((unused)), rl_yank (count, ignore)
int key __attribute__((unused))) int count __attribute__((unused)), ignore __attribute__((unused));
{ {
if (rl_kill_ring == 0) if (rl_kill_ring == 0)
{ {
@@ -462,8 +478,8 @@ rl_yank (int count __attribute__((unused)),
delete that text from the line, rotate the index down, and delete that text from the line, rotate the index down, and
yank back some other text. */ yank back some other text. */
int int
rl_yank_pop (int count __attribute__((unused)), rl_yank_pop (count, key)
int key __attribute__((unused))) int count __attribute__((unused)), key __attribute__((unused));
{ {
int l, n; int l, n;
@@ -501,7 +517,9 @@ rl_yank_nth_arg_internal (count, ignore, history_skip)
{ {
register HIST_ENTRY *entry; register HIST_ENTRY *entry;
char *arg; char *arg;
int i; int i, pos;
pos = where_history ();
if (history_skip) if (history_skip)
{ {
@@ -510,30 +528,26 @@ rl_yank_nth_arg_internal (count, ignore, history_skip)
} }
entry = previous_history (); entry = previous_history ();
if (entry)
history_set_pos (pos);
if (entry == 0)
{ {
if (history_skip) rl_ding ();
{
for (i = 0; i < history_skip; i++)
next_history ();
}
next_history ();
}
else
{
ding ();
return -1; return -1;
} }
arg = history_arg_extract (count, count, entry->line); arg = history_arg_extract (count, count, entry->line);
if (!arg || !*arg) if (!arg || !*arg)
{ {
ding (); rl_ding ();
return -1; return -1;
} }
rl_begin_undo_group (); rl_begin_undo_group ();
_rl_set_mark_at_pos (rl_point);
#if defined (VI_MODE) #if defined (VI_MODE)
/* Vi mode always inserts a space before yanking the argument, and it /* Vi mode always inserts a space before yanking the argument, and it
inserts it right *after* rl_point. */ inserts it right *after* rl_point. */
@@ -590,7 +604,7 @@ rl_yank_last_arg (count, key)
if (history_skip < 0) if (history_skip < 0)
history_skip = 0; history_skip = 0;
} }
if (explicit_arg_p) if (explicit_arg_p)
retval = rl_yank_nth_arg_internal (count_passed, key, history_skip); retval = rl_yank_nth_arg_internal (count_passed, key, history_skip);
else else
@@ -601,7 +615,7 @@ rl_yank_last_arg (count, key)
} }
/* A special paste command for users of Cygnus's cygwin32. */ /* A special paste command for users of Cygnus's cygwin32. */
#if defined (__CYGWIN32__) #if defined (__CYGWIN__)
#include <windows.h> #include <windows.h>
int int
@@ -621,12 +635,13 @@ rl_paste_from_clipboard (count, key)
if (ptr) if (ptr)
{ {
len = ptr - data; len = ptr - data;
ptr = xmalloc (len + 1); ptr = (char *)xmalloc (len + 1);
ptr[len] = '\0'; ptr[len] = '\0';
strncpy (ptr, data, len); strncpy (ptr, data, len);
} }
else else
ptr = data; ptr = data;
_rl_set_mark_at_pos (rl_point);
rl_insert_text (ptr); rl_insert_text (ptr);
if (ptr != data) if (ptr != data)
free (ptr); free (ptr);
@@ -634,4 +649,4 @@ rl_paste_from_clipboard (count, key)
} }
return (0); return (0);
} }
#endif /* __CYGWIN32__ */ #endif /* __CYGWIN__ */

View File

@@ -7,7 +7,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -18,7 +18,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
@@ -46,19 +46,8 @@
#include "readline.h" #include "readline.h"
#include "history.h" #include "history.h"
#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0) #include "rlprivate.h"
#include "xmalloc.h"
/* 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 ();
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
@@ -66,12 +55,9 @@ extern char *xmalloc (), *xrealloc ();
/* */ /* */
/* **************************************************************** */ /* **************************************************************** */
/* 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, /* The currently executing macro string. If this is non-zero,
then it is a malloc ()'ed string where input is coming from. */ then it is a malloc ()'ed string where input is coming from. */
char *_rl_executing_macro = (char *)NULL; char *rl_executing_macro = (char *)NULL;
/* The offset in the above string to the next character to be read. */ /* The offset in the above string to the next character to be read. */
static int executing_macro_index; static int executing_macro_index;
@@ -90,7 +76,7 @@ static int current_macro_index;
It is a linked list of string/index for each saved macro. */ It is a linked list of string/index for each saved macro. */
struct saved_macro { struct saved_macro {
struct saved_macro *next; struct saved_macro *next;
const char *string; char *string;
int sindex; int sindex;
}; };
@@ -100,11 +86,13 @@ static struct saved_macro *macro_list = (struct saved_macro *)NULL;
/* Set up to read subsequent input from STRING. /* Set up to read subsequent input from STRING.
STRING is free ()'ed when we are done with it. */ STRING is free ()'ed when we are done with it. */
void void
_rl_with_macro_input (const char *string) _rl_with_macro_input (string)
char *string;
{ {
_rl_push_executing_macro (); _rl_push_executing_macro ();
_rl_executing_macro = (char*) string; rl_executing_macro = string;
executing_macro_index = 0; executing_macro_index = 0;
RL_SETSTATE(RL_STATE_MACROINPUT);
} }
/* Return the next character available from a macro, or 0 if /* Return the next character available from a macro, or 0 if
@@ -112,16 +100,16 @@ _rl_with_macro_input (const char *string)
int int
_rl_next_macro_key () _rl_next_macro_key ()
{ {
if (_rl_executing_macro == 0) if (rl_executing_macro == 0)
return (0); return (0);
if (_rl_executing_macro[executing_macro_index] == 0) if (rl_executing_macro[executing_macro_index] == 0)
{ {
_rl_pop_executing_macro (); _rl_pop_executing_macro ();
return (_rl_next_macro_key ()); return (_rl_next_macro_key ());
} }
return (_rl_executing_macro[executing_macro_index++]); return (rl_executing_macro[executing_macro_index++]);
} }
/* Save the currently executing macro on a stack of saved macros. */ /* Save the currently executing macro on a stack of saved macros. */
@@ -133,7 +121,7 @@ _rl_push_executing_macro ()
saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro)); saver = (struct saved_macro *)xmalloc (sizeof (struct saved_macro));
saver->next = macro_list; saver->next = macro_list;
saver->sindex = executing_macro_index; saver->sindex = executing_macro_index;
saver->string = _rl_executing_macro; saver->string = rl_executing_macro;
macro_list = saver; macro_list = saver;
} }
@@ -145,20 +133,21 @@ _rl_pop_executing_macro ()
{ {
struct saved_macro *macro; struct saved_macro *macro;
if (_rl_executing_macro) FREE (rl_executing_macro);
free (_rl_executing_macro); rl_executing_macro = (char *)NULL;
_rl_executing_macro = (char *)NULL;
executing_macro_index = 0; executing_macro_index = 0;
if (macro_list) if (macro_list)
{ {
macro = macro_list; macro = macro_list;
_rl_executing_macro = (char*) macro_list->string; rl_executing_macro = macro_list->string;
executing_macro_index = macro_list->sindex; executing_macro_index = macro_list->sindex;
macro_list = macro_list->next; macro_list = macro_list->next;
free (macro); free (macro);
} }
if (rl_executing_macro == 0)
RL_UNSETSTATE(RL_STATE_MACROINPUT);
} }
/* Add a character to the macro being built. */ /* Add a character to the macro being built. */
@@ -169,9 +158,9 @@ _rl_add_macro_char (c)
if (current_macro_index + 1 >= current_macro_size) if (current_macro_index + 1 >= current_macro_size)
{ {
if (current_macro == 0) if (current_macro == 0)
current_macro = xmalloc (current_macro_size = 25); current_macro = (char *)xmalloc (current_macro_size = 25);
else else
current_macro = xrealloc (current_macro, current_macro_size += 25); current_macro = (char *)xrealloc (current_macro, current_macro_size += 25);
} }
current_macro[current_macro_index++] = c; current_macro[current_macro_index++] = c;
@@ -188,14 +177,11 @@ _rl_kill_kbd_macro ()
} }
current_macro_size = current_macro_index = 0; current_macro_size = current_macro_index = 0;
if (_rl_executing_macro) FREE (rl_executing_macro);
{ rl_executing_macro = (char *) NULL;
free (_rl_executing_macro);
_rl_executing_macro = (char *) NULL;
}
executing_macro_index = 0; executing_macro_index = 0;
_rl_defining_kbd_macro = 0; RL_UNSETSTATE(RL_STATE_MACRODEF);
} }
/* Begin defining a keyboard macro. /* Begin defining a keyboard macro.
@@ -205,10 +191,10 @@ _rl_kill_kbd_macro ()
definition to the end of the existing macro, and start by definition to the end of the existing macro, and start by
re-executing the existing macro. */ re-executing the existing macro. */
int int
rl_start_kbd_macro (int count __attribute__((unused)), rl_start_kbd_macro (ignore1, ignore2)
int key __attribute__((unused))) int ignore1 __attribute__((unused)), ignore2 __attribute__((unused));
{ {
if (_rl_defining_kbd_macro) if (RL_ISSTATE (RL_STATE_MACRODEF))
{ {
_rl_abort_internal (); _rl_abort_internal ();
return -1; return -1;
@@ -222,7 +208,7 @@ rl_start_kbd_macro (int count __attribute__((unused)),
else else
current_macro_index = 0; current_macro_index = 0;
_rl_defining_kbd_macro = 1; RL_SETSTATE(RL_STATE_MACRODEF);
return 0; return 0;
} }
@@ -230,9 +216,10 @@ rl_start_kbd_macro (int count __attribute__((unused)),
A numeric argument says to execute the macro right now, A numeric argument says to execute the macro right now,
that many times, counting the definition as the first time. */ that many times, counting the definition as the first time. */
int int
rl_end_kbd_macro (int count, int ignore __attribute__((unused))) rl_end_kbd_macro (count, ignore)
int count, ignore __attribute__((unused));
{ {
if (_rl_defining_kbd_macro == 0) if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
{ {
_rl_abort_internal (); _rl_abort_internal ();
return -1; return -1;
@@ -241,7 +228,7 @@ rl_end_kbd_macro (int count, int ignore __attribute__((unused)))
current_macro_index -= rl_key_sequence_length - 1; current_macro_index -= rl_key_sequence_length - 1;
current_macro[current_macro_index] = '\0'; current_macro[current_macro_index] = '\0';
_rl_defining_kbd_macro = 0; RL_UNSETSTATE(RL_STATE_MACRODEF);
return (rl_call_last_kbd_macro (--count, 0)); return (rl_call_last_kbd_macro (--count, 0));
} }
@@ -249,14 +236,15 @@ rl_end_kbd_macro (int count, int ignore __attribute__((unused)))
/* Execute the most recently defined keyboard macro. /* Execute the most recently defined keyboard macro.
COUNT says how many times to execute it. */ COUNT says how many times to execute it. */
int int
rl_call_last_kbd_macro (int count, int key __attribute__((unused))) rl_call_last_kbd_macro (count, ignore)
int count, ignore __attribute__((unused));
{ {
if (current_macro == 0) if (current_macro == 0)
_rl_abort_internal (); _rl_abort_internal ();
if (_rl_defining_kbd_macro) if (RL_ISSTATE (RL_STATE_MACRODEF))
{ {
ding (); /* no recursive macros */ rl_ding (); /* no recursive macros */
current_macro[--current_macro_index] = '\0'; /* erase this char */ current_macro[--current_macro_index] = '\0'; /* erase this char */
return 0; return 0;
} }

337
readline/mbutil.c Normal file
View File

@@ -0,0 +1,337 @@
/* mbutil.c -- readline multibyte character utility functions */
/* Copyright (C) 2001 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#include <sys/types.h>
#include <fcntl.h>
#include "posixjmp.h"
#if defined (HAVE_UNISTD_H)
# include <unistd.h> /* for _POSIX_VERSION */
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include <stdio.h>
#include <ctype.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"
#if defined (TIOCSTAT_IN_SYS_IOCTL)
# include <sys/ioctl.h>
#endif /* TIOCSTAT_IN_SYS_IOCTL */
/* Some standard library routines. */
#include "readline.h"
#include "rlprivate.h"
#include "xmalloc.h"
/* Declared here so it can be shared between the readline and history
libraries. */
#if defined (HANDLE_MULTIBYTE)
int rl_byte_oriented = 0;
#else
int rl_byte_oriented = 1;
#endif
/* **************************************************************** */
/* */
/* Multibyte Character Utility Functions */
/* */
/* **************************************************************** */
#if defined(HANDLE_MULTIBYTE)
static int
_rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
char *string;
int seed, count, find_non_zero;
{
size_t tmp = 0;
mbstate_t ps;
int point = 0;
wchar_t wc;
memset(&ps, 0, sizeof (mbstate_t));
if (seed < 0)
seed = 0;
if (count <= 0)
return seed;
point = seed + _rl_adjust_point(string, seed, &ps);
/* if this is true, means that seed was not pointed character
started byte. So correct the point and consume count */
if (seed < point)
count --;
while (count > 0)
{
tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps);
if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
{
/* invalid bytes. asume a byte represents a character */
point++;
count--;
/* reset states. */
memset(&ps, 0, sizeof(mbstate_t));
}
else if (tmp == (size_t)0)
/* found '\0' char */
break;
else
{
/* valid bytes */
point += tmp;
if (find_non_zero)
{
if (wcwidth (wc) == 0)
continue;
else
count--;
}
else
count--;
}
}
if (find_non_zero)
{
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
while (wcwidth (wc) == 0)
{
point += tmp;
tmp = mbrtowc (&wc, string + point, strlen (string + point), &ps);
if (tmp == (size_t)(0) || tmp == (size_t)(-1) || tmp == (size_t)(-2))
break;
}
}
return point;
}
static int
_rl_find_prev_mbchar_internal (string, seed, find_non_zero)
char *string;
int seed, find_non_zero;
{
mbstate_t ps;
int prev, non_zero_prev, point, length;
size_t tmp;
wchar_t wc;
memset(&ps, 0, sizeof(mbstate_t));
length = strlen(string);
if (seed < 0)
return 0;
else if (length < seed)
return length;
prev = non_zero_prev = point = 0;
while (point < seed)
{
tmp = mbrtowc (&wc, string + point, length - point, &ps);
if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
{
/* in this case, bytes are invalid or shorted to compose
multibyte char, so assume that the first byte represents
a single character anyway. */
tmp = 1;
/* clear the state of the byte sequence, because
in this case effect of mbstate is undefined */
memset(&ps, 0, sizeof (mbstate_t));
}
else if (tmp == 0)
break; /* Found '\0' char. Can this happen? */
else
{
if (find_non_zero)
{
if (wcwidth (wc) != 0)
prev = point;
}
else
prev = point;
}
point += tmp;
}
return prev;
}
/* return the number of bytes parsed from the multibyte sequence starting
at src, if a non-L'\0' wide character was recognized. It returns 0,
if a L'\0' wide character was recognized. It returns (size_t)(-1),
if an invalid multibyte sequence was encountered. It returns (size_t)(-2)
if it couldn't parse a complete multibyte character. */
int
_rl_get_char_len (src, ps)
char *src;
mbstate_t *ps;
{
size_t tmp;
tmp = mbrlen((const char *)src, (size_t)strlen (src), ps);
if (tmp == (size_t)(-2))
{
/* shorted to compose multibyte char */
memset (ps, 0, sizeof(mbstate_t));
return -2;
}
else if (tmp == (size_t)(-1))
{
/* invalid to compose multibyte char */
/* initialize the conversion state */
memset (ps, 0, sizeof(mbstate_t));
return -1;
}
else if (tmp == (size_t)0)
return 0;
else
return (int)tmp;
}
/* compare the specified two characters. If the characters matched,
return 1. Otherwise return 0. */
int
_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2)
char *buf1, *buf2;
mbstate_t *ps1, *ps2;
int pos1, pos2;
{
int i, w1, w2;
if ((w1 = _rl_get_char_len (&buf1[pos1], ps1)) <= 0 ||
(w2 = _rl_get_char_len (&buf2[pos2], ps2)) <= 0 ||
(w1 != w2) ||
(buf1[pos1] != buf2[pos2]))
return 0;
for (i = 1; i < w1; i++)
if (buf1[pos1+i] != buf2[pos2+i])
return 0;
return 1;
}
/* adjust pointed byte and find mbstate of the point of string.
adjusted point will be point <= adjusted_point, and returns
differences of the byte(adjusted_point - point).
if point is invalied (point < 0 || more than string length),
it returns -1 */
int
_rl_adjust_point(string, point, ps)
char *string;
int point;
mbstate_t *ps;
{
size_t tmp = 0;
int length;
int pos = 0;
length = strlen(string);
if (point < 0)
return -1;
if (length < point)
return -1;
while (pos < point)
{
tmp = mbrlen (string + pos, length - pos, ps);
if((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
{
/* in this case, bytes are invalid or shorted to compose
multibyte char, so assume that the first byte represents
a single character anyway. */
pos++;
/* clear the state of the byte sequence, because
in this case effect of mbstate is undefined */
memset (ps, 0, sizeof (mbstate_t));
}
else
pos += tmp;
}
return (pos - point);
}
int
_rl_is_mbchar_matched (string, seed, end, mbchar, length)
char *string;
int seed, end;
char *mbchar;
int length;
{
int i;
if ((end - seed) < length)
return 0;
for (i = 0; i < length; i++)
if (string[seed + i] != mbchar[i])
return 0;
return 1;
}
#endif /* HANDLE_MULTIBYTE */
/* Find next `count' characters started byte point of the specified seed.
If flags is MB_FIND_NONZERO, we look for non-zero-width multibyte
characters. */
#undef _rl_find_next_mbchar
int
_rl_find_next_mbchar (string, seed, count, flags)
char *string __attribute__((unused));
int seed, count, flags __attribute__((unused));
{
#if defined (HANDLE_MULTIBYTE)
return _rl_find_next_mbchar_internal (string, seed, count, flags);
#else
return (seed + count);
#endif
}
/* Find previous character started byte point of the specified seed.
Returned point will be point <= seed. If flags is MB_FIND_NONZERO,
we look for non-zero-width multibyte characters. */
#undef _rl_find_prev_mbchar
int
_rl_find_prev_mbchar (string, seed, flags)
char *string __attribute__((unused));
int seed, flags __attribute__((unused));
{
#if defined (HANDLE_MULTIBYTE)
return _rl_find_prev_mbchar_internal (string, seed, flags);
#else
return ((seed == 0) ? seed : seed - 1);
#endif
}

496
readline/misc.c Normal file
View File

@@ -0,0 +1,496 @@
/* misc.c -- miscellaneous bindable readline functions. */
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
# include <config.h>
#endif
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif /* HAVE_UNISTD_H */
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#if defined (HAVE_LOCALE_H)
# include <locale.h>
#endif
#include <stdio.h>
/* System-specific feature definitions and include files. */
#include "rldefs.h"
#include "rlmbutil.h"
/* Some standard library routines. */
#include "readline.h"
#include "history.h"
#include "rlprivate.h"
#include "rlshell.h"
#include "xmalloc.h"
static int rl_digit_loop PARAMS((void));
static void _rl_history_set_point PARAMS((void));
/* Forward declarations used in this file */
void _rl_free_history_entry PARAMS((HIST_ENTRY *));
/* If non-zero, rl_get_previous_history and rl_get_next_history attempt
to preserve the value of rl_point from line to line. */
int _rl_history_preserve_point = 0;
/* Saved target point for when _rl_history_preserve_point is set. Special
value of -1 means that point is at the end of the line. */
int _rl_history_saved_point = -1;
/* **************************************************************** */
/* */
/* Numeric Arguments */
/* */
/* **************************************************************** */
/* Handle C-u style numeric args, as well as M--, and M-digits. */
static int
rl_digit_loop ()
{
int key, c, sawminus, sawdigits;
rl_save_prompt ();
RL_SETSTATE(RL_STATE_NUMERICARG);
sawminus = sawdigits = 0;
while (1)
{
if (rl_numeric_arg > 1000000)
{
sawdigits = rl_explicit_arg = rl_numeric_arg = 0;
rl_ding ();
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return 1;
}
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
RL_SETSTATE(RL_STATE_MOREINPUT);
key = c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (c < 0)
{
_rl_abort_internal ();
return -1;
}
/* If we see a key bound to `universal-argument' after seeing digits,
it ends the argument but is otherwise ignored. */
if (_rl_keymap[c].type == ISFUNC &&
_rl_keymap[c].function == rl_universal_argument)
{
if (sawdigits == 0)
{
rl_numeric_arg *= 4;
continue;
}
else
{
RL_SETSTATE(RL_STATE_MOREINPUT);
key = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return (_rl_dispatch (key, _rl_keymap));
}
}
c = UNMETA (c);
if (_rl_digit_p (c))
{
rl_numeric_arg = rl_explicit_arg ? (rl_numeric_arg * 10) + c - '0' : c - '0';
sawdigits = rl_explicit_arg = 1;
}
else if (c == '-' && rl_explicit_arg == 0)
{
rl_numeric_arg = sawminus = 1;
rl_arg_sign = -1;
}
else
{
/* Make M-- command equivalent to M--1 command. */
if (sawminus && rl_numeric_arg == 1 && rl_explicit_arg == 0)
rl_explicit_arg = 1;
rl_restore_prompt ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return (_rl_dispatch (key, _rl_keymap));
}
}
/*NOTREACHED*/
}
/* Add the current digit to the argument in progress. */
int
rl_digit_argument (ignore, key)
int ignore __attribute__((unused)), key;
{
rl_execute_next (key);
return (rl_digit_loop ());
}
/* What to do when you abort reading an argument. */
int
rl_discard_argument ()
{
rl_ding ();
rl_clear_message ();
_rl_init_argument ();
return 0;
}
/* Create a default argument. */
int
_rl_init_argument ()
{
rl_numeric_arg = rl_arg_sign = 1;
rl_explicit_arg = 0;
return 0;
}
/* C-u, universal argument. Multiply the current argument by 4.
Read a key. If the key has nothing to do with arguments, then
dispatch on it. If the key is the abort character then abort. */
int
rl_universal_argument (count, key)
int count __attribute__((unused)), key __attribute__((unused));
{
rl_numeric_arg *= 4;
return (rl_digit_loop ());
}
/* **************************************************************** */
/* */
/* History Utilities */
/* */
/* **************************************************************** */
/* We already have a history library, and that is what we use to control
the history features of readline. This is our local interface to
the history mechanism. */
/* While we are editing the history, this is the saved
version of the original line. */
HIST_ENTRY *_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
/* Set the history pointer back to the last entry in the history. */
void
_rl_start_using_history ()
{
using_history ();
if (_rl_saved_line_for_history)
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
}
/* Free the contents (and containing structure) of a HIST_ENTRY. */
void
_rl_free_history_entry (entry)
HIST_ENTRY *entry;
{
if (entry == 0)
return;
if (entry->line)
free (entry->line);
free (entry);
}
/* Perhaps put back the current line if it has changed. */
int
rl_maybe_replace_line ()
{
HIST_ENTRY *temp;
temp = current_history ();
/* If the current line has changed, save the changes. */
if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
{
temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
free (temp->line);
free (temp);
}
return 0;
}
/* Restore the _rl_saved_line_for_history if there is one. */
int
rl_maybe_unsave_line ()
{
if (_rl_saved_line_for_history)
{
rl_replace_line (_rl_saved_line_for_history->line, 0);
rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
rl_point = rl_end; /* rl_replace_line sets rl_end */
}
else
rl_ding ();
return 0;
}
/* Save the current line in _rl_saved_line_for_history. */
int
rl_maybe_save_line ()
{
if (_rl_saved_line_for_history == 0)
{
_rl_saved_line_for_history = (HIST_ENTRY *)xmalloc (sizeof (HIST_ENTRY));
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
_rl_saved_line_for_history->data = (char *)rl_undo_list;
}
return 0;
}
int
_rl_free_saved_history_line ()
{
if (_rl_saved_line_for_history)
{
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
}
return 0;
}
static void
_rl_history_set_point ()
{
rl_point = (_rl_history_preserve_point && _rl_history_saved_point != -1)
? _rl_history_saved_point
: rl_end;
if (rl_point > rl_end)
rl_point = rl_end;
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
rl_point = 0;
#endif /* VI_MODE */
if (rl_editing_mode == emacs_mode)
rl_mark = (rl_point == rl_end ? 0 : rl_end);
}
void
rl_replace_from_history (entry, flags)
HIST_ENTRY *entry;
int flags __attribute__((unused)); /* currently unused */
{
rl_replace_line (entry->line, 0);
rl_undo_list = (UNDO_LIST *)entry->data;
rl_point = rl_end;
rl_mark = 0;
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
{
rl_point = 0;
rl_mark = rl_end;
}
#endif
}
/* **************************************************************** */
/* */
/* History Commands */
/* */
/* **************************************************************** */
/* Meta-< goes to the start of the history. */
int
rl_beginning_of_history (count, key)
int count __attribute__((unused)), key;
{
return (rl_get_previous_history (1 + where_history (), key));
}
/* Meta-> goes to the end of the history. (The current line). */
int
rl_end_of_history (count, key)
int count __attribute__((unused)), key __attribute__((unused));
{
rl_maybe_replace_line ();
using_history ();
rl_maybe_unsave_line ();
return 0;
}
/* Move down to the next history line. */
int
rl_get_next_history (count, key)
int count, key;
{
HIST_ENTRY *temp;
if (count < 0)
return (rl_get_previous_history (-count, key));
if (count == 0)
return 0;
rl_maybe_replace_line ();
/* either not saved by rl_newline or at end of line, so set appropriately. */
if (_rl_history_saved_point == -1 && (rl_point || rl_end))
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
temp = (HIST_ENTRY *)NULL;
while (count)
{
temp = next_history ();
if (!temp)
break;
--count;
}
if (temp == 0)
rl_maybe_unsave_line ();
else
{
rl_replace_from_history (temp, 0);
_rl_history_set_point ();
}
return 0;
}
/* Get the previous item out of our interactive history, making it the current
line. If there is no previous history, just ding. */
int
rl_get_previous_history (count, key)
int count, key;
{
HIST_ENTRY *old_temp, *temp;
if (count < 0)
return (rl_get_next_history (-count, key));
if (count == 0)
return 0;
/* either not saved by rl_newline or at end of line, so set appropriately. */
if (_rl_history_saved_point == -1 && (rl_point || rl_end))
_rl_history_saved_point = (rl_point == rl_end) ? -1 : rl_point;
/* If we don't have a line saved, then save this one. */
rl_maybe_save_line ();
/* If the current line has changed, save the changes. */
rl_maybe_replace_line ();
temp = old_temp = (HIST_ENTRY *)NULL;
while (count)
{
temp = previous_history ();
if (temp == 0)
break;
old_temp = temp;
--count;
}
/* If there was a large argument, and we moved back to the start of the
history, that is not an error. So use the last value found. */
if (!temp && old_temp)
temp = old_temp;
if (temp == 0)
rl_ding ();
else
{
rl_replace_from_history (temp, 0);
_rl_history_set_point ();
}
return 0;
}
/* **************************************************************** */
/* */
/* Editing Modes */
/* */
/* **************************************************************** */
/* How to toggle back and forth between editing modes. */
int
rl_vi_editing_mode (count, key)
int count __attribute__((unused)), key;
{
#if defined (VI_MODE)
_rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */
rl_editing_mode = vi_mode;
rl_vi_insertion_mode (1, key);
#endif /* VI_MODE */
return 0;
}
int
rl_emacs_editing_mode (count, key)
int count __attribute__((unused)), key __attribute__((unused));
{
rl_editing_mode = emacs_mode;
_rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
_rl_keymap = emacs_standard_keymap;
return 0;
}
/* Function for the rest of the library to use to set insert/overwrite mode. */
void
_rl_set_insert_mode (im, force)
int im, force __attribute__((unused));
{
#ifdef CURSOR_MODE
_rl_set_cursor (im, force);
#endif
rl_insert_mode = im;
}
/* Toggle overwrite mode. A positive explicit argument selects overwrite
mode. A negative or zero explicit argument selects insert mode. */
int
rl_overwrite_mode (count, key)
int count, key __attribute__((unused));
{
if (rl_explicit_arg == 0)
_rl_set_insert_mode (rl_insert_mode ^ 1, 0);
else if (count > 0)
_rl_set_insert_mode (RL_IM_OVERWRITE, 0);
else
_rl_set_insert_mode (RL_IM_INSERT, 0);
return 0;
}

View File

@@ -7,7 +7,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -18,7 +18,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
@@ -27,6 +27,8 @@
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h>
#if defined (HAVE_UNISTD_H) #if defined (HAVE_UNISTD_H)
# include <unistd.h> # include <unistd.h>
#endif /* HAVE_UNISTD_H */ #endif /* HAVE_UNISTD_H */
@@ -44,13 +46,9 @@
#include <ctype.h> #include <ctype.h>
#include "rldefs.h" #include "rldefs.h"
#include "readline.h"
extern int _rl_convert_meta_chars_to_ascii; #include "rlshell.h"
extern int _rl_output_meta_chars; #include "rlprivate.h"
extern int _rl_meta_flag;
/* Functions imported from shell.c */
extern char *get_env_value ();
#if !defined (HAVE_SETLOCALE) #if !defined (HAVE_SETLOCALE)
/* A list of legal values for the LANG or LC_CTYPE environment variables. /* A list of legal values for the LANG or LC_CTYPE environment variables.
@@ -70,12 +68,11 @@ static char *legal_lang_values[] =
"iso88599", "iso88599",
"iso885910", "iso885910",
"koi8r", "koi8r",
"koi8-r",
0 0
}; };
static char *normalize_codeset (); static char *normalize_codeset PARAMS((char *));
static char *find_codeset (); static char *find_codeset PARAMS((char *, size_t *));
#endif /* !HAVE_SETLOCALE */ #endif /* !HAVE_SETLOCALE */
/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value /* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
@@ -108,9 +105,9 @@ _rl_init_eightbit ()
/* We don't have setlocale. Finesse it. Check the environment for the /* We don't have setlocale. Finesse it. Check the environment for the
appropriate variables and set eight-bit mode if they have the right appropriate variables and set eight-bit mode if they have the right
values. */ values. */
lspec = get_env_value ("LC_ALL"); lspec = sh_get_env_value ("LC_ALL");
if (lspec == 0) lspec = get_env_value ("LC_CTYPE"); if (lspec == 0) lspec = sh_get_env_value ("LC_CTYPE");
if (lspec == 0) lspec = get_env_value ("LANG"); if (lspec == 0) lspec = sh_get_env_value ("LANG");
if (lspec == 0 || (t = normalize_codeset (lspec)) == 0) if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
return (0); return (0);
for (i = 0; t && legal_lang_values[i]; i++) for (i = 0; t && legal_lang_values[i]; i++)
@@ -144,10 +141,10 @@ normalize_codeset (codeset)
all_digits = 1; all_digits = 1;
for (len = 0, i = 0; i < namelen; i++) for (len = 0, i = 0; i < namelen; i++)
{ {
if (isalnum (codeset[i])) if (ISALNUM ((unsigned char)codeset[i]))
{ {
len++; len++;
all_digits &= isdigit (codeset[i]); all_digits &= _rl_digit_p (codeset[i]);
} }
} }
@@ -165,9 +162,9 @@ normalize_codeset (codeset)
} }
for (i = 0; i < namelen; i++) for (i = 0; i < namelen; i++)
if (isalpha (codeset[i])) if (ISALPHA ((unsigned char)codeset[i]))
*wp++ = (isupper (codeset[i])) ? tolower (codeset[i]) : codeset[i]; *wp++ = _rl_to_lower (codeset[i]);
else if (isdigit (codeset[i])) else if (_rl_digit_p (codeset[i]))
*wp++ = codeset[i]; *wp++ = codeset[i];
*wp = '\0'; *wp = '\0';

View File

@@ -7,7 +7,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -18,23 +18,11 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#include "rlconf.h" #include "rlconf.h"
#if !defined (PAREN_MATCHING)
extern int rl_insert ();
int
rl_insert_close (count, invoking_key)
int count, invoking_key;
{
return (rl_insert (count, invoking_key));
}
#else /* PAREN_MATCHING */
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
# include <config.h> # include <config.h>
#endif #endif
@@ -42,6 +30,10 @@ rl_insert_close (count, invoking_key)
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (FD_SET) && !defined (HAVE_SELECT) #if defined (FD_SET) && !defined (HAVE_SELECT)
# define HAVE_SELECT # define HAVE_SELECT
#endif #endif
@@ -64,8 +56,9 @@ extern char *strchr (), *strrchr ();
#endif /* !strchr && !__STDC__ */ #endif /* !strchr && !__STDC__ */
#include "readline.h" #include "readline.h"
#include "rlprivate.h"
extern int rl_explicit_arg; static int find_matching_open PARAMS((char *, int, int));
/* Non-zero means try to blink the matching open parenthesis when the /* Non-zero means try to blink the matching open parenthesis when the
close parenthesis is inserted. */ close parenthesis is inserted. */
@@ -75,14 +68,46 @@ int rl_blink_matching_paren = 1;
int rl_blink_matching_paren = 0; int rl_blink_matching_paren = 0;
#endif /* !HAVE_SELECT */ #endif /* !HAVE_SELECT */
static int find_matching_open (); static int _paren_blink_usec = 500000;
/* Change emacs_standard_keymap to have bindings for paren matching when
ON_OR_OFF is 1, change them back to self_insert when ON_OR_OFF == 0. */
void
_rl_enable_paren_matching (on_or_off)
int on_or_off;
{
if (on_or_off)
{ /* ([{ */
rl_bind_key_in_map (')', rl_insert_close, emacs_standard_keymap);
rl_bind_key_in_map (']', rl_insert_close, emacs_standard_keymap);
rl_bind_key_in_map ('}', rl_insert_close, emacs_standard_keymap);
}
else
{ /* ([{ */
rl_bind_key_in_map (')', rl_insert, emacs_standard_keymap);
rl_bind_key_in_map (']', rl_insert, emacs_standard_keymap);
rl_bind_key_in_map ('}', rl_insert, emacs_standard_keymap);
}
}
int
rl_set_paren_blink_timeout (u)
int u;
{
int o;
o = _paren_blink_usec;
if (u > 0)
_paren_blink_usec = u;
return (o);
}
int int
rl_insert_close (count, invoking_key) rl_insert_close (count, invoking_key)
int count, invoking_key; int count, invoking_key;
{ {
if (rl_explicit_arg || !rl_blink_matching_paren) if (rl_explicit_arg || !rl_blink_matching_paren)
rl_insert (count, invoking_key); _rl_insert_char (count, invoking_key);
else else
{ {
#if defined (HAVE_SELECT) #if defined (HAVE_SELECT)
@@ -90,7 +115,7 @@ rl_insert_close (count, invoking_key)
struct timeval timer; struct timeval timer;
fd_set readfds; fd_set readfds;
rl_insert (1, invoking_key); _rl_insert_char (1, invoking_key);
(*rl_redisplay_function) (); (*rl_redisplay_function) ();
match_point = match_point =
find_matching_open (rl_line_buffer, rl_point - 2, invoking_key); find_matching_open (rl_line_buffer, rl_point - 2, invoking_key);
@@ -102,7 +127,7 @@ rl_insert_close (count, invoking_key)
FD_ZERO (&readfds); FD_ZERO (&readfds);
FD_SET (fileno (rl_instream), &readfds); FD_SET (fileno (rl_instream), &readfds);
timer.tv_sec = 0; timer.tv_sec = 0;
timer.tv_usec = 500000; timer.tv_usec = _paren_blink_usec;
orig_point = rl_point; orig_point = rl_point;
rl_point = match_point; rl_point = match_point;
@@ -110,7 +135,7 @@ rl_insert_close (count, invoking_key)
ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer); ready = select (1, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timer);
rl_point = orig_point; rl_point = orig_point;
#else /* !HAVE_SELECT */ #else /* !HAVE_SELECT */
rl_insert (count, invoking_key); _rl_insert_char (count, invoking_key);
#endif /* !HAVE_SELECT */ #endif /* !HAVE_SELECT */
} }
return 0; return 0;
@@ -152,5 +177,3 @@ find_matching_open (string, from, closer)
} }
return (i); return (i);
} }
#endif /* PAREN_MATCHING */

View File

@@ -6,7 +6,7 @@
Bash is free software; you can redistribute it and/or modify it Bash is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
Bash is distributed in the hope that it will be useful, but WITHOUT Bash is distributed in the hope that it will be useful, but WITHOUT
@@ -16,7 +16,7 @@
You should have received a copy of the GNU General Public License 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 along with Bash; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
/* This file should be included instead of <dirent.h> or <sys/dir.h>. */ /* This file should be included instead of <dirent.h> or <sys/dir.h>. */
@@ -46,4 +46,12 @@
# define d_fileno d_ino # define d_fileno d_ino
#endif #endif
#if defined (_POSIX_SOURCE) && (!defined (STRUCT_DIRENT_HAS_D_INO) || defined (BROKEN_DIRENT_D_INO))
/* Posix does not require that the d_ino field be present, and some
systems do not provide it. */
# define REAL_DIR_ENTRY(dp) 1
#else
# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
#endif /* _POSIX_SOURCE */
#endif /* !_POSIXDIR_H_ */ #endif /* !_POSIXDIR_H_ */

View File

@@ -1,5 +1,23 @@
/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */ /* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */
/* 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 2, or (at your option)
any later version.
Bash is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with Bash; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#ifndef _POSIXJMP_H_ #ifndef _POSIXJMP_H_
#define _POSIXJMP_H_ #define _POSIXJMP_H_

View File

@@ -7,7 +7,7 @@
Bash is free software; you can redistribute it and/or modify it Bash is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
Bash is distributed in the hope that it will be useful, but WITHOUT Bash is distributed in the hope that it will be useful, but WITHOUT
@@ -17,7 +17,7 @@
You should have received a copy of the GNU General Public License 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 along with Bash; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
/* This file should be included instead of <sys/stat.h>. /* This file should be included instead of <sys/stat.h>.
It relies on the local sys/stat.h to work though. */ It relies on the local sys/stat.h to work though. */

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -18,7 +18,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_READLINE_H_) #if !defined (_READLINE_H_)
#define _READLINE_H_ #define _READLINE_H_
@@ -29,14 +29,21 @@ extern "C" {
#if defined (READLINE_LIBRARY) #if defined (READLINE_LIBRARY)
# include "rlstdc.h" # include "rlstdc.h"
# include "rltypedefs.h"
# include "keymaps.h" # include "keymaps.h"
# include "tilde.h" # include "tilde.h"
#else #else
# include <readline/rlstdc.h> # include <readline/rlstdc.h>
# include <readline/rltypedefs.h>
# include <readline/keymaps.h> # include <readline/keymaps.h>
# include <readline/tilde.h> # include <readline/tilde.h>
#endif #endif
/* Hex-encoded Readline version number. */
#define RL_READLINE_VERSION 0x0403 /* Readline 4.3 */
#define RL_VERSION_MAJOR 4
#define RL_VERSION_MINOR 3
/* Readline data structures. */ /* Readline data structures. */
/* Maintaining the state of undo. We remember individual deletes and inserts /* Maintaining the state of undo. We remember individual deletes and inserts
@@ -61,7 +68,7 @@ extern UNDO_LIST *rl_undo_list;
/* The data structure for mapping textual names to code addresses. */ /* The data structure for mapping textual names to code addresses. */
typedef struct _funmap { typedef struct _funmap {
const char *name; const char *name;
Function *function; rl_command_func_t *function;
} FUNMAP; } FUNMAP;
extern FUNMAP **funmap; extern FUNMAP **funmap;
@@ -73,184 +80,191 @@ extern FUNMAP **funmap;
/* **************************************************************** */ /* **************************************************************** */
/* Bindable commands for numeric arguments. */ /* Bindable commands for numeric arguments. */
extern int rl_digit_argument __P((int, int)); extern int rl_digit_argument PARAMS((int, int));
extern int rl_universal_argument __P((int, int)); extern int rl_universal_argument PARAMS((int, int));
/* Bindable commands for moving the cursor. */ /* Bindable commands for moving the cursor. */
extern int rl_forward __P((int, int)); extern int rl_forward_byte PARAMS((int, int));
extern int rl_backward __P((int, int)); extern int rl_forward_char PARAMS((int, int));
extern int rl_beg_of_line __P((int, int)); extern int rl_forward PARAMS((int, int));
extern int rl_end_of_line __P((int, int)); extern int rl_backward_byte PARAMS((int, int));
extern int rl_forward_word __P((int, int)); extern int rl_backward_char PARAMS((int, int));
extern int rl_backward_word __P((int, int)); extern int rl_backward PARAMS((int, int));
extern int rl_refresh_line __P((int, int)); extern int rl_beg_of_line PARAMS((int, int));
extern int rl_clear_screen __P((int, int)); extern int rl_end_of_line PARAMS((int, int));
extern int rl_arrow_keys __P((int, int)); extern int rl_forward_word PARAMS((int, int));
extern int rl_backward_word PARAMS((int, int));
extern int rl_refresh_line PARAMS((int, int));
extern int rl_clear_screen PARAMS((int, int));
extern int rl_arrow_keys PARAMS((int, int));
/* Bindable commands for inserting and deleting text. */ /* Bindable commands for inserting and deleting text. */
extern int rl_insert __P((int, int)); extern int rl_insert PARAMS((int, int));
extern int rl_quoted_insert __P((int, int)); extern int rl_quoted_insert PARAMS((int, int));
extern int rl_tab_insert __P((int, int)); extern int rl_tab_insert PARAMS((int, int));
extern int rl_newline __P((int, int)); extern int rl_newline PARAMS((int, int));
extern int rl_do_lowercase_version __P((int, int)); extern int rl_do_lowercase_version PARAMS((int, int));
extern int rl_rubout __P((int, int)); extern int rl_rubout PARAMS((int, int));
extern int rl_delete __P((int, int)); extern int rl_delete PARAMS((int, int));
extern int rl_rubout_or_delete __P((int, int)); extern int rl_rubout_or_delete PARAMS((int, int));
extern int rl_delete_horizontal_space __P((int, int)); extern int rl_delete_horizontal_space PARAMS((int, int));
extern int rl_delete_or_show_completions __P((int, int)); extern int rl_delete_or_show_completions PARAMS((int, int));
extern int rl_insert_comment __P((int, int)); extern int rl_insert_comment PARAMS((int, int));
/* Bindable commands for changing case. */ /* Bindable commands for changing case. */
extern int rl_upcase_word __P((int, int)); extern int rl_upcase_word PARAMS((int, int));
extern int rl_downcase_word __P((int, int)); extern int rl_downcase_word PARAMS((int, int));
extern int rl_capitalize_word __P((int, int)); extern int rl_capitalize_word PARAMS((int, int));
/* Bindable commands for transposing characters and words. */ /* Bindable commands for transposing characters and words. */
extern int rl_transpose_words __P((int, int)); extern int rl_transpose_words PARAMS((int, int));
extern int rl_transpose_chars __P((int, int)); extern int rl_transpose_chars PARAMS((int, int));
/* Bindable commands for searching within a line. */ /* Bindable commands for searching within a line. */
extern int rl_char_search __P((int, int)); extern int rl_char_search PARAMS((int, int));
extern int rl_backward_char_search __P((int, int)); extern int rl_backward_char_search PARAMS((int, int));
/* Bindable commands for readline's interface to the command history. */ /* Bindable commands for readline's interface to the command history. */
extern int rl_beginning_of_history __P((int, int)); extern int rl_beginning_of_history PARAMS((int, int));
extern int rl_end_of_history __P((int, int)); extern int rl_end_of_history PARAMS((int, int));
extern int rl_get_next_history __P((int, int)); extern int rl_get_next_history PARAMS((int, int));
extern int rl_get_previous_history __P((int, int)); extern int rl_get_previous_history PARAMS((int, int));
/* Bindable commands for managing the mark and region. */ /* Bindable commands for managing the mark and region. */
extern int rl_set_mark __P((int, int)); extern int rl_set_mark PARAMS((int, int));
extern int rl_exchange_point_and_mark __P((int, int)); extern int rl_exchange_point_and_mark PARAMS((int, int));
/* Bindable commands to set the editing mode (emacs or vi). */ /* Bindable commands to set the editing mode (emacs or vi). */
extern int rl_vi_editing_mode __P((int, int)); extern int rl_vi_editing_mode PARAMS((int, int));
extern int rl_emacs_editing_mode __P((int, int)); extern int rl_emacs_editing_mode PARAMS((int, int));
/* Bindable commands to change the insert mode (insert or overwrite) */
extern int rl_overwrite_mode PARAMS((int, int));
/* Bindable commands for managing key bindings. */ /* Bindable commands for managing key bindings. */
extern int rl_re_read_init_file __P((int, int)); extern int rl_re_read_init_file PARAMS((int, int));
extern int rl_dump_functions __P((int, int)); extern int rl_dump_functions PARAMS((int, int));
extern int rl_dump_macros __P((int, int)); extern int rl_dump_macros PARAMS((int, int));
extern int rl_dump_variables __P((int, int)); extern int rl_dump_variables PARAMS((int, int));
/* Bindable commands for word completion. */ /* Bindable commands for word completion. */
extern int rl_complete __P((int, int)); extern int rl_complete PARAMS((int, int));
extern int rl_possible_completions __P((int, int)); extern int rl_possible_completions PARAMS((int, int));
extern int rl_insert_completions __P((int, int)); extern int rl_insert_completions PARAMS((int, int));
extern int rl_menu_complete __P((int, int)); extern int rl_menu_complete PARAMS((int, int));
/* Bindable commands for killing and yanking text, and managing the kill ring. */ /* Bindable commands for killing and yanking text, and managing the kill ring. */
extern int rl_kill_word __P((int, int)); extern int rl_kill_word PARAMS((int, int));
extern int rl_backward_kill_word __P((int, int)); extern int rl_backward_kill_word PARAMS((int, int));
extern int rl_kill_line __P((int, int)); extern int rl_kill_line PARAMS((int, int));
extern int rl_backward_kill_line __P((int, int)); extern int rl_backward_kill_line PARAMS((int, int));
extern int rl_kill_full_line __P((int, int)); extern int rl_kill_full_line PARAMS((int, int));
extern int rl_unix_word_rubout __P((int, int)); extern int rl_unix_word_rubout PARAMS((int, int));
extern int rl_unix_line_discard __P((int, int)); extern int rl_unix_line_discard PARAMS((int, int));
extern int rl_copy_region_to_kill __P((int, int)); extern int rl_copy_region_to_kill PARAMS((int, int));
extern int rl_kill_region __P((int, int)); extern int rl_kill_region PARAMS((int, int));
extern int rl_copy_forward_word __P((int, int)); extern int rl_copy_forward_word PARAMS((int, int));
extern int rl_copy_backward_word __P((int, int)); extern int rl_copy_backward_word PARAMS((int, int));
extern int rl_yank __P((int, int)); extern int rl_yank PARAMS((int, int));
extern int rl_yank_pop __P((int, int)); extern int rl_yank_pop PARAMS((int, int));
extern int rl_yank_nth_arg __P((int, int)); extern int rl_yank_nth_arg PARAMS((int, int));
extern int rl_yank_last_arg __P((int, int)); extern int rl_yank_last_arg PARAMS((int, int));
/* Not available unless __CYGWIN32__ is defined. */ /* Not available unless __CYGWIN__ is defined. */
#ifdef __CYGWIN32__ #ifdef __CYGWIN__
extern int rl_paste_from_clipboard __P((int, int)); extern int rl_paste_from_clipboard PARAMS((int, int));
#endif #endif
/* Bindable commands for incremental searching. */ /* Bindable commands for incremental searching. */
extern int rl_reverse_search_history __P((int, int)); extern int rl_reverse_search_history PARAMS((int, int));
extern int rl_forward_search_history __P((int, int)); extern int rl_forward_search_history PARAMS((int, int));
/* Bindable keyboard macro commands. */ /* Bindable keyboard macro commands. */
extern int rl_start_kbd_macro __P((int, int)); extern int rl_start_kbd_macro PARAMS((int, int));
extern int rl_end_kbd_macro __P((int, int)); extern int rl_end_kbd_macro PARAMS((int, int));
extern int rl_call_last_kbd_macro __P((int, int)); extern int rl_call_last_kbd_macro PARAMS((int, int));
/* Bindable undo commands. */ /* Bindable undo commands. */
extern int rl_revert_line __P((int, int)); extern int rl_revert_line PARAMS((int, int));
extern int rl_undo_command __P((int, int)); extern int rl_undo_command PARAMS((int, int));
/* Bindable tilde expansion commands. */ /* Bindable tilde expansion commands. */
extern int rl_tilde_expand __P((int, int)); extern int rl_tilde_expand PARAMS((int, int));
/* Bindable terminal control commands. */ /* Bindable terminal control commands. */
extern int rl_restart_output __P((int, int)); extern int rl_restart_output PARAMS((int, int));
extern int rl_stop_output __P((int, int)); extern int rl_stop_output PARAMS((int, int));
/* Miscellaneous bindable commands. */ /* Miscellaneous bindable commands. */
extern int rl_abort __P((int, int)); extern int rl_abort PARAMS((int, int));
extern int rl_tty_status __P((int, int)); extern int rl_tty_status PARAMS((int, int));
/* Bindable commands for incremental and non-incremental history searching. */ /* Bindable commands for incremental and non-incremental history searching. */
extern int rl_history_search_forward __P((int, int)); extern int rl_history_search_forward PARAMS((int, int));
extern int rl_history_search_backward __P((int, int)); extern int rl_history_search_backward PARAMS((int, int));
extern int rl_noninc_forward_search __P((int, int)); extern int rl_noninc_forward_search PARAMS((int, int));
extern int rl_noninc_reverse_search __P((int, int)); extern int rl_noninc_reverse_search PARAMS((int, int));
extern int rl_noninc_forward_search_again __P((int, int)); extern int rl_noninc_forward_search_again PARAMS((int, int));
extern int rl_noninc_reverse_search_again __P((int, int)); extern int rl_noninc_reverse_search_again PARAMS((int, int));
/* Not available unless readline is compiled -DPAREN_MATCHING. */ /* Bindable command used when inserting a matching close character. */
extern int rl_insert_close __P((int, int)); extern int rl_insert_close PARAMS((int, int));
/* Not available unless READLINE_CALLBACKS is defined. */ /* Not available unless READLINE_CALLBACKS is defined. */
extern void rl_callback_handler_install __P((char *, VFunction *)); extern void rl_callback_handler_install PARAMS((const char *, rl_vcpfunc_t *));
extern void rl_callback_read_char __P((void)); extern void rl_callback_read_char PARAMS((void));
extern void rl_callback_handler_remove __P((void)); extern void rl_callback_handler_remove PARAMS((void));
/* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */ /* Things for vi mode. Not available unless readline is compiled -DVI_MODE. */
/* VI-mode bindable commands. */ /* VI-mode bindable commands. */
extern int rl_vi_redo __P((int, int)); extern int rl_vi_redo PARAMS((int, int));
extern int rl_vi_undo __P((int, int)); extern int rl_vi_undo PARAMS((int, int));
extern int rl_vi_yank_arg __P((int, int)); extern int rl_vi_yank_arg PARAMS((int, int));
extern int rl_vi_fetch_history __P((int, int)); extern int rl_vi_fetch_history PARAMS((int, int));
extern int rl_vi_search_again __P((int, int)); extern int rl_vi_search_again PARAMS((int, int));
extern int rl_vi_search __P((int, int)); extern int rl_vi_search PARAMS((int, int));
extern int rl_vi_complete __P((int, int)); extern int rl_vi_complete PARAMS((int, int));
extern int rl_vi_tilde_expand __P((int, int)); extern int rl_vi_tilde_expand PARAMS((int, int));
extern int rl_vi_prev_word __P((int, int)); extern int rl_vi_prev_word PARAMS((int, int));
extern int rl_vi_next_word __P((int, int)); extern int rl_vi_next_word PARAMS((int, int));
extern int rl_vi_end_word __P((int, int)); extern int rl_vi_end_word PARAMS((int, int));
extern int rl_vi_insert_beg __P((int, int)); extern int rl_vi_insert_beg PARAMS((int, int));
extern int rl_vi_append_mode __P((int, int)); extern int rl_vi_append_mode PARAMS((int, int));
extern int rl_vi_append_eol __P((int, int)); extern int rl_vi_append_eol PARAMS((int, int));
extern int rl_vi_eof_maybe __P((int, int)); extern int rl_vi_eof_maybe PARAMS((int, int));
extern int rl_vi_insertion_mode __P((int, int)); extern int rl_vi_insertion_mode PARAMS((int, int));
extern int rl_vi_movement_mode __P((int, int)); extern int rl_vi_movement_mode PARAMS((int, int));
extern int rl_vi_arg_digit __P((int, int)); extern int rl_vi_arg_digit PARAMS((int, int));
extern int rl_vi_change_case __P((int, int)); extern int rl_vi_change_case PARAMS((int, int));
extern int rl_vi_put __P((int, int)); extern int rl_vi_put PARAMS((int, int));
extern int rl_vi_column __P((int, int)); extern int rl_vi_column PARAMS((int, int));
extern int rl_vi_delete_to __P((int, int)); extern int rl_vi_delete_to PARAMS((int, int));
extern int rl_vi_change_to __P((int, int)); extern int rl_vi_change_to PARAMS((int, int));
extern int rl_vi_yank_to __P((int, int)); extern int rl_vi_yank_to PARAMS((int, int));
extern int rl_vi_delete __P((int, int)); extern int rl_vi_delete PARAMS((int, int));
extern int rl_vi_back_to_indent __P((int, int)); extern int rl_vi_back_to_indent PARAMS((int, int));
extern int rl_vi_first_print __P((int, int)); extern int rl_vi_first_print PARAMS((int, int));
extern int rl_vi_char_search __P((int, int)); extern int rl_vi_char_search PARAMS((int, int));
extern int rl_vi_match __P((int, int)); extern int rl_vi_match PARAMS((int, int));
extern int rl_vi_change_char __P((int, int)); extern int rl_vi_change_char PARAMS((int, int));
extern int rl_vi_subst __P((int, int)); extern int rl_vi_subst PARAMS((int, int));
extern int rl_vi_overstrike __P((int, int)); extern int rl_vi_overstrike PARAMS((int, int));
extern int rl_vi_overstrike_delete __P((int, int)); extern int rl_vi_overstrike_delete PARAMS((int, int));
extern int rl_vi_replace __P((int, int)); extern int rl_vi_replace PARAMS((int, int));
extern int rl_vi_set_mark __P((int, int)); extern int rl_vi_set_mark PARAMS((int, int));
extern int rl_vi_goto_mark __P((int, int)); extern int rl_vi_goto_mark PARAMS((int, int));
/* VI-mode utility functions. */ /* VI-mode utility functions. */
extern int rl_vi_check __P((void)); extern int rl_vi_check PARAMS((void));
extern int rl_vi_domove __P((int, int *)); extern int rl_vi_domove PARAMS((int, int *));
extern int rl_vi_bracktype __P((int)); extern int rl_vi_bracktype PARAMS((int));
/* VI-mode pseudo-bindable commands, used as utility functions. */ /* VI-mode pseudo-bindable commands, used as utility functions. */
extern int rl_vi_fWord __P((int, int)); extern int rl_vi_fWord PARAMS((int, int));
extern int rl_vi_bWord __P((int, int)); extern int rl_vi_bWord PARAMS((int, int));
extern int rl_vi_eWord __P((int, int)); extern int rl_vi_eWord PARAMS((int, int));
extern int rl_vi_fword __P((int, int)); extern int rl_vi_fword PARAMS((int, int));
extern int rl_vi_bword __P((int, int)); extern int rl_vi_bword PARAMS((int, int));
extern int rl_vi_eword __P((int, int)); extern int rl_vi_eword PARAMS((int, int));
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
@@ -260,141 +274,176 @@ extern int rl_vi_eword __P((int, int));
/* Readline functions. */ /* Readline functions. */
/* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */ /* Read a line of input. Prompt with PROMPT. A NULL PROMPT means none. */
extern char *readline __P((char *)); extern char *readline PARAMS((const char *));
extern int rl_initialize __P((void)); extern int rl_set_prompt PARAMS((const char *));
extern int rl_expand_prompt PARAMS((char *));
extern int rl_discard_argument __P((void)); extern int rl_initialize PARAMS((void));
/* Undocumented; unused by readline */
extern int rl_discard_argument PARAMS((void));
/* Utility functions to bind keys to readline commands. */ /* Utility functions to bind keys to readline commands. */
extern int rl_add_defun __P((char *, Function *, int)); extern int rl_add_defun PARAMS((const char *, rl_command_func_t *, int));
extern int rl_bind_key __P((int, Function *)); extern int rl_bind_key PARAMS((int, rl_command_func_t *));
extern int rl_bind_key_in_map __P((int, Function *, Keymap)); extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap));
extern int rl_unbind_key __P((int)); extern int rl_unbind_key PARAMS((int));
extern int rl_unbind_key_in_map __P((int, Keymap)); extern int rl_unbind_key_in_map PARAMS((int, Keymap));
extern int rl_unbind_function_in_map __P((Function *, Keymap)); extern int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap));
extern int rl_unbind_command_in_map __P((char *, Keymap)); extern int rl_unbind_command_in_map PARAMS((const char *, Keymap));
extern int rl_set_key __P((char *, Function *, Keymap)); extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_generic_bind __P((int, char *, char *, Keymap)); extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap));
extern int rl_variable_bind __P((char *, char *)); extern int rl_variable_bind PARAMS((const char *, const char *));
/* Backwards compatibility, use rl_generic_bind instead. */ /* Backwards compatibility, use rl_generic_bind instead. */
extern int rl_macro_bind __P((char *, char *, Keymap)); extern int rl_macro_bind PARAMS((const char *, const char *, Keymap));
/* Undocumented in the texinfo manual; not really useful to programs. */ /* Undocumented in the texinfo manual; not really useful to programs. */
extern int rl_translate_keyseq __P((char *, char *, int *)); extern int rl_translate_keyseq PARAMS((const char *, char *, int *));
extern char *rl_untranslate_keyseq __P((int)); extern char *rl_untranslate_keyseq PARAMS((int));
extern Function *rl_named_function __P((char *)); extern rl_command_func_t *rl_named_function PARAMS((const char *));
extern Function *rl_function_of_keyseq __P((const char *, Keymap, int *)); extern rl_command_func_t *rl_function_of_keyseq PARAMS((const char *, Keymap, int *));
extern void rl_list_funmap_names __P((void)); extern void rl_list_funmap_names PARAMS((void));
extern char **rl_invoking_keyseqs_in_map __P((Function *, Keymap)); extern char **rl_invoking_keyseqs_in_map PARAMS((rl_command_func_t *, Keymap));
extern char **rl_invoking_keyseqs __P((Function *)); extern char **rl_invoking_keyseqs PARAMS((rl_command_func_t *));
extern void rl_function_dumper PARAMS((int));
extern void rl_macro_dumper PARAMS((int));
extern void rl_variable_dumper PARAMS((int));
extern void rl_function_dumper __P((int)); extern int rl_read_init_file PARAMS((const char *));
extern void rl_macro_dumper __P((int)); extern int rl_parse_and_bind PARAMS((char *));
extern void rl_variable_dumper __P((int));
extern int rl_read_init_file __P((const char *));
extern int rl_parse_and_bind __P((char *));
/* Functions for manipulating keymaps. */ /* Functions for manipulating keymaps. */
extern Keymap rl_make_bare_keymap __P((void)); extern Keymap rl_make_bare_keymap PARAMS((void));
extern Keymap rl_copy_keymap __P((Keymap)); extern Keymap rl_copy_keymap PARAMS((Keymap));
extern Keymap rl_make_keymap __P((void)); extern Keymap rl_make_keymap PARAMS((void));
extern void rl_discard_keymap __P((Keymap)); extern void rl_discard_keymap PARAMS((Keymap));
extern Keymap rl_get_keymap_by_name __P((char *)); extern Keymap rl_get_keymap_by_name PARAMS((const char *));
extern const char *rl_get_keymap_name __P((Keymap)); extern char *rl_get_keymap_name PARAMS((Keymap));
extern void rl_set_keymap __P((Keymap)); extern void rl_set_keymap PARAMS((Keymap));
extern Keymap rl_get_keymap __P((void)); extern Keymap rl_get_keymap PARAMS((void));
extern void rl_set_keymap_from_edit_mode __P((void)); /* Undocumented; used internally only. */
extern const char *rl_get_keymap_name_from_edit_mode __P((void)); extern void rl_set_keymap_from_edit_mode PARAMS((void));
extern char *rl_get_keymap_name_from_edit_mode PARAMS((void));
/* Functions for manipulating the funmap, which maps command names to functions. */ /* Functions for manipulating the funmap, which maps command names to functions. */
extern int rl_add_funmap_entry __P((const char *, Function *)); extern int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *));
extern void rl_initialize_funmap __P((void)); extern const char **rl_funmap_names PARAMS((void));
extern char **rl_funmap_names __P((void)); /* Undocumented, only used internally -- there is only one funmap, and this
function may be called only once. */
extern void rl_initialize_funmap PARAMS((void));
/* Utility functions for managing keyboard macros. */ /* Utility functions for managing keyboard macros. */
extern void rl_push_macro_input __P((char *)); extern void rl_push_macro_input PARAMS((char *));
/* Functions for undoing, from undo.c */ /* Functions for undoing, from undo.c */
extern void rl_add_undo __P((enum undo_code, int, int, char *)); extern void rl_add_undo PARAMS((enum undo_code, int, int, char *));
extern void free_undo_list __P((void)); extern void rl_free_undo_list PARAMS((void));
extern int rl_do_undo __P((void)); extern int rl_do_undo PARAMS((void));
extern int rl_begin_undo_group __P((void)); extern int rl_begin_undo_group PARAMS((void));
extern int rl_end_undo_group __P((void)); extern int rl_end_undo_group PARAMS((void));
extern int rl_modifying __P((int, int)); extern int rl_modifying PARAMS((int, int));
/* Functions for redisplay. */ /* Functions for redisplay. */
extern void rl_redisplay __P((void)); extern void rl_redisplay PARAMS((void));
extern int rl_on_new_line __P((void)); extern int rl_on_new_line PARAMS((void));
extern int rl_forced_update_display __P((void)); extern int rl_on_new_line_with_prompt PARAMS((void));
extern int rl_clear_message __P((void)); extern int rl_forced_update_display PARAMS((void));
extern int rl_reset_line_state __P((void)); extern int rl_clear_message PARAMS((void));
extern int rl_reset_line_state PARAMS((void));
extern int rl_crlf PARAMS((void));
#if defined (__STDC__) && defined (USE_VARARGS) && defined (PREFER_STDARG) #if (defined (__STDC__) || defined (__cplusplus)) && defined (USE_VARARGS) && defined (PREFER_STDARG)
extern int rl_message (const char *, ...); extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
#else #else
extern int rl_message (); extern int rl_message ();
#endif #endif
extern int rl_show_char PARAMS((int));
/* Undocumented in texinfo manual. */ /* Undocumented in texinfo manual. */
extern int rl_show_char __P((int)); extern int rl_character_len PARAMS((int, int));
extern int rl_character_len __P((int, int));
extern int crlf __P((void));
/* Save and restore internal prompt redisplay information. */ /* Save and restore internal prompt redisplay information. */
extern void rl_save_prompt __P((void)); extern void rl_save_prompt PARAMS((void));
extern void rl_restore_prompt __P((void)); extern void rl_restore_prompt PARAMS((void));
/* Modifying text. */ /* Modifying text. */
extern int rl_insert_text __P((const char *)); extern void rl_replace_line PARAMS((const char *, int));
extern int rl_delete_text __P((int, int)); extern int rl_insert_text PARAMS((const char *));
extern int rl_kill_text __P((int, int)); extern int rl_delete_text PARAMS((int, int));
extern char *rl_copy_text __P((int, int)); extern int rl_kill_text PARAMS((int, int));
extern char *rl_copy_text PARAMS((int, int));
/* Terminal and tty mode management. */ /* Terminal and tty mode management. */
extern void rl_prep_terminal __P((int)); extern void rl_prep_terminal PARAMS((int));
extern void rl_deprep_terminal __P((void)); extern void rl_deprep_terminal PARAMS((void));
extern void rltty_set_default_bindings __P((Keymap)); extern void rl_tty_set_default_bindings PARAMS((Keymap));
extern int rl_reset_terminal __P((char *)); extern int rl_reset_terminal PARAMS((const char *));
extern void rl_resize_terminal __P((void)); extern void rl_resize_terminal PARAMS((void));
extern void rl_set_screen_size PARAMS((int, int));
extern void rl_get_screen_size PARAMS((int *, int *));
/* `Public' utility functions . */ extern char *rl_get_termcap PARAMS((const char *));
extern void rl_extend_line_buffer __P((int));
extern int ding __P((void));
/* Functions for character input. */ /* Functions for character input. */
extern int rl_stuff_char __P((int)); extern int rl_stuff_char PARAMS((int));
extern int rl_execute_next __P((int)); extern int rl_execute_next PARAMS((int));
extern int rl_read_key __P((void)); extern int rl_clear_pending_input PARAMS((void));
extern int rl_getc __P((FILE *)); extern int rl_read_key PARAMS((void));
extern int rl_getc PARAMS((FILE *));
extern int rl_set_keyboard_input_timeout PARAMS((int));
/* `Public' utility functions . */
extern void rl_extend_line_buffer PARAMS((int));
extern int rl_ding PARAMS((void));
extern int rl_alphabetic PARAMS((int));
/* Readline signal handling, from signals.c */ /* Readline signal handling, from signals.c */
extern int rl_set_signals __P((void)); extern int rl_set_signals PARAMS((void));
extern int rl_clear_signals __P((void)); extern int rl_clear_signals PARAMS((void));
extern void rl_cleanup_after_signal __P((void)); extern void rl_cleanup_after_signal PARAMS((void));
extern void rl_reset_after_signal __P((void)); extern void rl_reset_after_signal PARAMS((void));
extern void rl_free_line_state __P((void)); extern void rl_free_line_state PARAMS((void));
extern int rl_set_paren_blink_timeout PARAMS((int));
/* Undocumented. */ /* Undocumented. */
extern int rl_expand_prompt __P((char *)); extern int rl_maybe_save_line PARAMS((void));
extern int rl_maybe_unsave_line PARAMS((void));
extern int maybe_save_line __P((void)); extern int rl_maybe_replace_line PARAMS((void));
extern int maybe_unsave_line __P((void));
extern int maybe_replace_line __P((void));
/* Completion functions. */ /* Completion functions. */
extern int rl_complete_internal __P((int)); extern int rl_complete_internal PARAMS((int));
extern void rl_display_match_list __P((char **, int, int)); extern void rl_display_match_list PARAMS((char **, int, int));
extern char **completion_matches __P((const char *, CPFunction *)); extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *));
extern char *username_completion_function __P((const char *, int)); extern char *rl_username_completion_function PARAMS((const char *, int));
extern char *filename_completion_function __P((const char *, int)); extern char *rl_filename_completion_function PARAMS((const char *, int));
extern int rl_completion_mode PARAMS((rl_command_func_t *));
#if 0
/* Backwards compatibility (compat.c). These will go away sometime. */
extern void free_undo_list PARAMS((void));
extern int maybe_save_line PARAMS((void));
extern int maybe_unsave_line PARAMS((void));
extern int maybe_replace_line PARAMS((void));
extern int ding PARAMS((void));
extern int alphabetic PARAMS((int));
extern int crlf PARAMS((void));
extern char **completion_matches PARAMS((char *, rl_compentry_func_t *));
extern char *username_completion_function PARAMS((const char *, int));
extern char *filename_completion_function PARAMS((const char *, int));
#endif
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
@@ -403,7 +452,22 @@ extern char *filename_completion_function __P((const char *, int));
/* **************************************************************** */ /* **************************************************************** */
/* The version of this incarnation of the readline library. */ /* The version of this incarnation of the readline library. */
extern const char *rl_library_version; extern const char *rl_library_version; /* e.g., "4.2" */
extern int rl_readline_version; /* e.g., 0x0402 */
/* True if this is real GNU readline. */
extern int rl_gnu_readline_p;
/* Flags word encapsulating the current readline state. */
extern int rl_readline_state;
/* Says which editing mode readline is currently using. 1 means emacs mode;
0 means vi mode. */
extern int rl_editing_mode;
/* Insert or overwrite mode for emacs mode. 1 means insert mode; 0 means
overwrite mode. Reset to insert mode on each input line. */
extern int rl_insert_mode;
/* The name of the calling program. You should initialize this to /* The name of the calling program. You should initialize this to
whatever was in argv[0]. It is used when parsing conditionals. */ whatever was in argv[0]. It is used when parsing conditionals. */
@@ -417,7 +481,8 @@ extern char *rl_prompt;
extern char *rl_line_buffer; extern char *rl_line_buffer;
/* The location of point, and end. */ /* The location of point, and end. */
extern int rl_point, rl_end; extern int rl_point;
extern int rl_end;
/* The mark, or saved cursor position. */ /* The mark, or saved cursor position. */
extern int rl_mark; extern int rl_mark;
@@ -434,29 +499,44 @@ extern int rl_pending_input;
or directly from an application. */ or directly from an application. */
extern int rl_dispatching; extern int rl_dispatching;
/* Non-zero if the user typed a numeric argument before executing the
current function. */
extern int rl_explicit_arg;
/* The current value of the numeric argument specified by the user. */
extern int rl_numeric_arg;
/* The address of the last command function Readline executed. */
extern rl_command_func_t *rl_last_func;
/* The name of the terminal to use. */ /* The name of the terminal to use. */
extern char *rl_terminal_name; extern const char *rl_terminal_name;
/* The input and output streams. */ /* The input and output streams. */
extern FILE *rl_instream, *rl_outstream; extern FILE *rl_instream;
extern FILE *rl_outstream;
/* If non-zero, then this is the address of a function to call just /* If non-zero, then this is the address of a function to call just
before readline_internal () prints the first prompt. */ before readline_internal () prints the first prompt. */
extern Function *rl_startup_hook; extern rl_hook_func_t *rl_startup_hook;
/* If non-zero, this is the address of a function to call just before /* If non-zero, this is the address of a function to call just before
readline_internal_setup () returns and readline_internal starts readline_internal_setup () returns and readline_internal starts
reading input characters. */ reading input characters. */
extern Function *rl_pre_input_hook; extern rl_hook_func_t *rl_pre_input_hook;
/* The address of a function to call periodically while Readline is /* The address of a function to call periodically while Readline is
awaiting character input, or NULL, for no event handling. */ awaiting character input, or NULL, for no event handling. */
extern Function *rl_event_hook; extern rl_hook_func_t *rl_event_hook;
extern Function *rl_getc_function; /* The address of the function to call to fetch a character from the current
extern VFunction *rl_redisplay_function; Readline input stream */
extern VFunction *rl_prep_term_function; extern rl_getc_func_t *rl_getc_function;
extern VFunction *rl_deprep_term_function;
extern rl_voidfunc_t *rl_redisplay_function;
extern rl_vintfunc_t *rl_prep_term_function;
extern rl_voidfunc_t *rl_deprep_term_function;
/* Dispatch variables. */ /* Dispatch variables. */
extern Keymap rl_executing_keymap; extern Keymap rl_executing_keymap;
@@ -468,6 +548,18 @@ extern Keymap rl_binding_keymap;
rl_newline. */ rl_newline. */
extern int rl_erase_empty_line; extern int rl_erase_empty_line;
/* If non-zero, the application has already printed the prompt (rl_prompt)
before calling readline, so readline should not output it the first time
redisplay is done. */
extern int rl_already_prompted;
/* A non-zero value means to read only this many characters rather than
up to a character bound to accept-line. */
extern int rl_num_chars_to_read;
/* The text of a currently-executing keyboard macro. */
extern char *rl_executing_macro;
/* Variables to control readline signal handling. */ /* Variables to control readline signal handling. */
/* If non-zero, readline will install its own signal handlers for /* If non-zero, readline will install its own signal handlers for
SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */ SIGINT, SIGTERM, SIGQUIT, SIGALRM, SIGTSTP, SIGTTIN, and SIGTTOU. */
@@ -482,9 +574,9 @@ extern int rl_catch_sigwinch;
/* Completion variables. */ /* Completion variables. */
/* Pointer to the generator function for completion_matches (). /* Pointer to the generator function for completion_matches ().
NULL means to use filename_entry_function (), the default filename NULL means to use rl_filename_completion_function (), the default
completer. */ filename completer. */
extern Function *rl_completion_entry_function; extern rl_compentry_func_t *rl_completion_entry_function;
/* If rl_ignore_some_completions_function is non-NULL it is the address /* If rl_ignore_some_completions_function is non-NULL it is the address
of a function to call after all of the possible matches have been of a function to call after all of the possible matches have been
@@ -492,7 +584,7 @@ extern Function *rl_completion_entry_function;
The function is called with one argument; a NULL terminated array The function is called with one argument; a NULL terminated array
of (char *). If your function removes any of the elements, they of (char *). If your function removes any of the elements, they
must be free()'ed. */ must be free()'ed. */
extern Function *rl_ignore_some_completions_function; extern rl_compignore_func_t *rl_ignore_some_completions_function;
/* Pointer to alternative function to create matches. /* Pointer to alternative function to create matches.
Function is called with TEXT, START, and END. Function is called with TEXT, START, and END.
@@ -501,7 +593,7 @@ extern Function *rl_ignore_some_completions_function;
If this function exists and returns NULL then call the value of If this function exists and returns NULL then call the value of
rl_completion_entry_function to try to match, otherwise use the rl_completion_entry_function to try to match, otherwise use the
array of strings returned. */ array of strings returned. */
extern CPPFunction *rl_attempted_completion_function; extern rl_completion_func_t *rl_attempted_completion_function;
/* The basic list of characters that signal a break between words for the /* The basic list of characters that signal a break between words for the
completer routine. The initial contents of this variable is what completer routine. The initial contents of this variable is what
@@ -517,23 +609,34 @@ extern const char *rl_completer_word_break_characters;
Completion occurs on the entire substring, and within the substring Completion occurs on the entire substring, and within the substring
rl_completer_word_break_characters are treated as any other character, rl_completer_word_break_characters are treated as any other character,
unless they also appear within this list. */ unless they also appear within this list. */
extern char *rl_completer_quote_characters; extern const char *rl_completer_quote_characters;
/* List of quote characters which cause a word break. */ /* List of quote characters which cause a word break. */
extern const char *rl_basic_quote_characters; extern const char *rl_basic_quote_characters;
/* List of characters that need to be quoted in filenames by the completer. */ /* List of characters that need to be quoted in filenames by the completer. */
extern char *rl_filename_quote_characters; extern const char *rl_filename_quote_characters;
/* List of characters that are word break characters, but should be left /* 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 in TEXT when it is passed to the completion function. The shell uses
this to help determine what kind of completing to do. */ this to help determine what kind of completing to do. */
extern char *rl_special_prefixes; extern const char *rl_special_prefixes;
/* If non-zero, then this is the address of a function to call when /* If non-zero, then this is the address of a function to call when
completing on a directory name. The function is called with completing on a directory name. The function is called with
the address of a string (the current directory name) as an arg. */ the address of a string (the current directory name) as an arg. It
extern Function *rl_directory_completion_hook; changes what is displayed when the possible completions are printed
or inserted. */
extern rl_icppfunc_t *rl_directory_completion_hook;
/* If non-zero, this is the address of a function to call when completing
a directory name. This function takes the address of the directory name
to be modified as an argument. Unlike rl_directory_completion_hook, it
only modifies the directory name used in opendir(2), not what is displayed
when the possible completions are printed or inserted. It is called
before rl_directory_completion_hook. I'm not happy with how this works
yet, so it's undocumented. */
extern rl_icppfunc_t *rl_directory_rewrite_hook;
/* Backwards compatibility with previous versions of readline. */ /* Backwards compatibility with previous versions of readline. */
#define rl_symbolic_link_hook rl_directory_completion_hook #define rl_symbolic_link_hook rl_directory_completion_hook
@@ -545,7 +648,7 @@ extern Function *rl_directory_completion_hook;
where MATCHES is the array of strings that matched, NUM_MATCHES is the where MATCHES is the array of strings that matched, NUM_MATCHES is the
number of strings in that array, and MAX_LENGTH is the length of the number of strings in that array, and MAX_LENGTH is the length of the
longest string in that array. */ longest string in that array. */
extern VFunction *rl_completion_display_matches_hook; extern rl_compdisp_func_t *rl_completion_display_matches_hook;
/* Non-zero means that the results of the matches are to be treated /* 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 as filenames. This is ALWAYS zero on entry, and can only be changed
@@ -563,17 +666,17 @@ extern int rl_filename_quoting_desired;
Called with the text to quote, the type of match found (single or multiple) 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 and a pointer to the quoting character to be used, which the function can
reset if desired. */ reset if desired. */
extern CPFunction *rl_filename_quoting_function; extern rl_quote_func_t *rl_filename_quoting_function;
/* Function to call to remove quoting characters from a filename. Called /* Function to call to remove quoting characters from a filename. Called
before completion is attempted, so the embedded quotes do not interfere before completion is attempted, so the embedded quotes do not interfere
with matching names in the file system. */ with matching names in the file system. */
extern CPFunction *rl_filename_dequoting_function; extern rl_dequote_func_t *rl_filename_dequoting_function;
/* Function to call to decide whether or not a word break character is /* 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 quoted. If a character is quoted, it does not break words for the
completer. */ completer. */
extern Function *rl_char_is_quoted_p; extern rl_linebuf_func_t *rl_char_is_quoted_p;
/* Non-zero means to suppress normal filename completion after the /* Non-zero means to suppress normal filename completion after the
user-specified completion function has been called. */ user-specified completion function has been called. */
@@ -588,11 +691,26 @@ extern int rl_completion_type;
default is a space. Nothing is added if this is '\0'. */ default is a space. Nothing is added if this is '\0'. */
extern int rl_completion_append_character; extern int rl_completion_append_character;
/* If set to non-zero by an application completion function,
rl_completion_append_character will not be appended. */
extern int rl_completion_suppress_append;
/* Up to this many items will be displayed in response to a /* Up to this many items will be displayed in response to a
possible-completions call. After that, we ask the user if she possible-completions call. After that, we ask the user if she
is sure she wants to see them all. The default value is 100. */ is sure she wants to see them all. The default value is 100. */
extern int rl_completion_query_items; extern int rl_completion_query_items;
/* If non-zero, a slash will be appended to completed filenames that are
symbolic links to directory names, subject to the value of the
mark-directories variable (which is user-settable). This exists so
that application completion functions can override the user's preference
(set via the mark-symlinked-directories variable) if appropriate.
It's set to the value of _rl_complete_mark_symlink_dirs in
rl_complete_internal before any application-specific completion
function is called, so without that function doing anything, the user's
preferences are honored. */
extern int rl_completion_mark_symlink_dirs;
/* If non-zero, then disallow duplicates in the matches. */ /* If non-zero, then disallow duplicates in the matches. */
extern int rl_ignore_completion_duplicates; extern int rl_ignore_completion_duplicates;
@@ -610,9 +728,69 @@ extern int rl_inhibit_completion;
#define SINGLE_MATCH 1 #define SINGLE_MATCH 1
#define MULT_MATCH 2 #define MULT_MATCH 2
#if !defined (savestring) /* Possible state values for rl_readline_state */
extern char *savestring (); /* XXX backwards compatibility */ #define RL_STATE_NONE 0x00000 /* no state; before first call */
#endif
#define RL_STATE_INITIALIZING 0x00001 /* initializing */
#define RL_STATE_INITIALIZED 0x00002 /* initialization done */
#define RL_STATE_TERMPREPPED 0x00004 /* terminal is prepped */
#define RL_STATE_READCMD 0x00008 /* reading a command key */
#define RL_STATE_METANEXT 0x00010 /* reading input after ESC */
#define RL_STATE_DISPATCHING 0x00020 /* dispatching to a command */
#define RL_STATE_MOREINPUT 0x00040 /* reading more input in a command function */
#define RL_STATE_ISEARCH 0x00080 /* doing incremental search */
#define RL_STATE_NSEARCH 0x00100 /* doing non-inc search */
#define RL_STATE_SEARCH 0x00200 /* doing a history search */
#define RL_STATE_NUMERICARG 0x00400 /* reading numeric argument */
#define RL_STATE_MACROINPUT 0x00800 /* getting input from a macro */
#define RL_STATE_MACRODEF 0x01000 /* defining keyboard macro */
#define RL_STATE_OVERWRITE 0x02000 /* overwrite mode */
#define RL_STATE_COMPLETING 0x04000 /* doing completion */
#define RL_STATE_SIGHANDLER 0x08000 /* in readline sighandler */
#define RL_STATE_UNDOING 0x10000 /* doing an undo */
#define RL_STATE_INPUTPENDING 0x20000 /* rl_execute_next called */
#define RL_STATE_DONE 0x80000 /* done; accepted line */
#define RL_SETSTATE(x) (rl_readline_state |= (x))
#define RL_UNSETSTATE(x) (rl_readline_state &= ~(x))
#define RL_ISSTATE(x) (rl_readline_state & (x))
struct readline_state {
/* line state */
int point;
int end;
int mark;
char *buffer;
int buflen;
UNDO_LIST *ul;
char *prompt;
/* global state */
int rlstate;
int done;
Keymap kmap;
/* input state */
rl_command_func_t *lastfunc;
int insmode;
int edmode;
int kseqlen;
FILE *inf;
FILE *outf;
int pendingin;
char *macro;
/* signal state */
int catchsigs;
int catchsigwinch;
/* reserved for future expansion, so the struct size doesn't change */
char reserved[64];
};
extern int rl_save_state PARAMS((struct readline_state *));
extern int rl_restore_state PARAMS((struct readline_state *));
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@@ -8,7 +8,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -19,7 +19,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_RLCONF_H_) #if !defined (_RLCONF_H_)
#define _RLCONF_H_ #define _RLCONF_H_
@@ -30,10 +30,6 @@
/* Define this to get an indication of file type when listing completions. */ /* Define this to get an indication of file type when listing completions. */
#define VISIBLE_STATS #define VISIBLE_STATS
/* If defined, readline shows opening parens and braces when closing
paren or brace entered. */
/* #define PAREN_MATCHING */
/* This definition is needed by readline.c, rltty.c, and signals.c. */ /* This definition is needed by readline.c, rltty.c, and signals.c. */
/* If on, then readline handles signals in a way that doesn't screw. */ /* If on, then readline handles signals in a way that doesn't screw. */
#define HANDLE_SIGNALS #define HANDLE_SIGNALS
@@ -58,4 +54,7 @@
X `callback' style. */ X `callback' style. */
#define READLINE_CALLBACKS #define READLINE_CALLBACKS
/* Define this if you want the cursor to indicate insert or overwrite mode. */
/* #define CURSOR_MODE */
#endif /* _RLCONF_H_ */ #endif /* _RLCONF_H_ */

View File

@@ -10,7 +10,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -21,7 +21,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_RLDEFS_H_) #if !defined (_RLDEFS_H_)
#define _RLDEFS_H_ #define _RLDEFS_H_
@@ -30,6 +30,8 @@
# include "config.h" # include "config.h"
#endif #endif
#include "rlstdc.h"
#if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING) #if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING)
# define TERMIOS_TTY_DRIVER # define TERMIOS_TTY_DRIVER
#else #else
@@ -71,7 +73,14 @@ extern char *strchr (), *strrchr ();
#define _rl_stricmp strcasecmp #define _rl_stricmp strcasecmp
#define _rl_strnicmp strncasecmp #define _rl_strnicmp strncasecmp
#else #else
extern int _rl_stricmp (), _rl_strnicmp (); extern int _rl_stricmp PARAMS((char *, char *));
extern int _rl_strnicmp PARAMS((char *, char *, int));
#endif
#if defined (HAVE_STRPBRK)
# define _rl_strpbrk(a,b) strpbrk((a),(b))
#else
extern char *_rl_strpbrk PARAMS((const char *, const char *));
#endif #endif
#if !defined (emacs_mode) #if !defined (emacs_mode)
@@ -80,6 +89,13 @@ extern int _rl_stricmp (), _rl_strnicmp ();
# define emacs_mode 1 # define emacs_mode 1
#endif #endif
#if !defined (RL_IM_INSERT)
# define RL_IM_INSERT 1
# define RL_IM_OVERWRITE 0
#
# define RL_IM_DEFAULT RL_IM_INSERT
#endif
/* If you cast map[key].function to type (Keymap) on a Cray, /* If you cast map[key].function to type (Keymap) on a Cray,
the compiler takes the value of map[key].function and the compiler takes the value of map[key].function and
divides it by 4 to convert between pointer types (pointers divides it by 4 to convert between pointer types (pointers
@@ -87,15 +103,14 @@ extern int _rl_stricmp (), _rl_strnicmp ();
This is not what is wanted. */ This is not what is wanted. */
#if defined (CRAY) #if defined (CRAY)
# define FUNCTION_TO_KEYMAP(map, key) (Keymap)((int)map[key].function) # define FUNCTION_TO_KEYMAP(map, key) (Keymap)((int)map[key].function)
# define KEYMAP_TO_FUNCTION(data) (Function *)((int)(data)) # define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)((int)(data))
#else #else
# define FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function) # define FUNCTION_TO_KEYMAP(map, key) (Keymap)(map[key].function)
# define KEYMAP_TO_FUNCTION(data) (Function *)(data) # define KEYMAP_TO_FUNCTION(data) (rl_command_func_t *)(data)
#endif #endif
#ifndef savestring #ifndef savestring
extern char *xmalloc (); #define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
#endif #endif
/* Possible values for _rl_bell_preference. */ /* Possible values for _rl_bell_preference. */
@@ -113,22 +128,28 @@ extern char *xmalloc ();
/* Possible values for the found_quote flags word used by the completion /* Possible values for the found_quote flags word used by the completion
functions. It says what kind of (shell-like) quoting we found anywhere functions. It says what kind of (shell-like) quoting we found anywhere
in the line. */ in the line. */
#define RL_QF_SINGLE_QUOTE 0x1 #define RL_QF_SINGLE_QUOTE 0x01
#define RL_QF_DOUBLE_QUOTE 0x2 #define RL_QF_DOUBLE_QUOTE 0x02
#define RL_QF_BACKSLASH 0x4 #define RL_QF_BACKSLASH 0x04
#define RL_QF_OTHER_QUOTE 0x08
/* Default readline line buffer length. */ /* Default readline line buffer length. */
#define DEFAULT_BUFFER_SIZE 256 #define DEFAULT_BUFFER_SIZE 256
#if !defined (STREQ) #if !defined (STREQ)
#define STREQ(a, b) (((a)[0] == (b)[0]) && (strcmp ((a), (b)) == 0)) #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 STREQN(a, b, n) (((n) == 0) ? (1) \
: ((a)[0] == (b)[0]) && (strncmp ((a), (b), (n)) == 0))
#endif #endif
#if !defined (FREE) #if !defined (FREE)
# define FREE(x) if (x) free (x) # define FREE(x) if (x) free (x)
#endif #endif
#if !defined (SWAP)
# define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0)
#endif
/* CONFIGURATION SECTION */ /* CONFIGURATION SECTION */
#include "rlconf.h" #include "rlconf.h"

108
readline/rlmbutil.h Normal file
View File

@@ -0,0 +1,108 @@
/* rlmbutil.h -- utility functions for multibyte characters. */
/* Copyright (C) 2001 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_RL_MBUTIL_H_)
#define _RL_MBUTIL_H_
#include "rlstdc.h"
/************************************************/
/* check multibyte capability for I18N code */
/************************************************/
/* For platforms which support the ISO C amendement 1 functionality we
support user defined character classes. */
/* Solaris 2.5 has a bug: <wchar.h> must be included before <wctype.h>. */
#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H)
# include <wchar.h>
# include <wctype.h>
# if defined (HAVE_MBSRTOWCS) /* system is supposed to support XPG5 */
# define HANDLE_MULTIBYTE 1
# endif
#endif
/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T)
# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0)
# define mbsrtowcs(dest, src, len, ps) (mbsrtowcs) (dest, src, len, 0)
# define wcrtomb(s, wc, ps) (wcrtomb) (s, wc, 0)
# define mbrtowc(pwc, s, n, ps) (mbrtowc) (pwc, s, n, 0)
# define mbrlen(s, n, ps) (mbrlen) (s, n, 0)
# define mbstate_t int
#endif
/* Make sure MB_LEN_MAX is at least 16 on systems that claim to be able to
handle multibyte chars (some systems define MB_LEN_MAX as 1) */
#ifdef HANDLE_MULTIBYTE
# include <limits.h>
# if defined(MB_LEN_MAX) && (MB_LEN_MAX < 16)
# undef MB_LEN_MAX
# endif
# if !defined (MB_LEN_MAX)
# define MB_LEN_MAX 16
# endif
#endif
/************************************************/
/* end of multibyte capability checks for I18N */
/************************************************/
/*
* Flags for _rl_find_prev_mbchar and _rl_find_next_mbchar:
*
* MB_FIND_ANY find any multibyte character
* MB_FIND_NONZERO find a non-zero-width multibyte character
*/
#define MB_FIND_ANY 0x00
#define MB_FIND_NONZERO 0x01
extern int _rl_find_prev_mbchar PARAMS((char *, int, int));
extern int _rl_find_next_mbchar PARAMS((char *, int, int, int));
#ifdef HANDLE_MULTIBYTE
extern int _rl_compare_chars PARAMS((char *, int, mbstate_t *, char *, int, mbstate_t *));
extern int _rl_get_char_len PARAMS((char *, mbstate_t *));
extern int _rl_adjust_point PARAMS((char *, int, mbstate_t *));
extern int _rl_read_mbchar PARAMS((char *, int));
extern int _rl_read_mbstring PARAMS((int, char *, int));
extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
#else /* !HANDLE_MULTIBYTE */
#undef MB_LEN_MAX
#undef MB_CUR_MAX
#define MB_LEN_MAX 1
#define MB_CUR_MAX 1
#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1))
#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2))
#endif /* !HANDLE_MULTIBYTE */
extern int rl_byte_oriented;
#endif /* _RL_MBUTIL_H_ */

284
readline/rlprivate.h Normal file
View File

@@ -0,0 +1,284 @@
/* rlprivate.h -- functions and variables global to the readline library,
but not intended for use by applications. */
/* Copyright (C) 1999 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_RL_PRIVATE_H_)
#define _RL_PRIVATE_H_
#include "rlconf.h" /* for VISIBLE_STATS */
#include "rlstdc.h"
#include "posixjmp.h" /* defines procenv_t */
/*************************************************************************
* *
* Global functions undocumented in texinfo manual and not in readline.h *
* *
*************************************************************************/
/*************************************************************************
* *
* Global variables undocumented in texinfo manual and not in readline.h *
* *
*************************************************************************/
/* complete.c */
extern int rl_complete_with_tilde_expansion;
#if defined (VISIBLE_STATS)
extern int rl_visible_stats;
#endif /* VISIBLE_STATS */
/* readline.c */
extern int rl_line_buffer_len;
extern int rl_arg_sign;
extern int rl_visible_prompt_length;
extern int readline_echoing_p;
extern int rl_key_sequence_length;
extern int rl_byte_oriented;
/* display.c */
extern int rl_display_fixed;
/* parens.c */
extern int rl_blink_matching_paren;
/*************************************************************************
* *
* Global functions and variables unsed and undocumented *
* *
*************************************************************************/
/* kill.c */
extern int rl_set_retained_kills PARAMS((int));
/* terminal.c */
extern void _rl_set_screen_size PARAMS((int, int));
/* undo.c */
extern int _rl_fix_last_undo_of_type PARAMS((unsigned int, int, int));
/* util.c */
extern char *_rl_savestring PARAMS((const char *));
/*************************************************************************
* *
* Functions and variables private to the readline library *
* *
*************************************************************************/
/* NOTE: Functions and variables prefixed with `_rl_' are
pseudo-global: they are global so they can be shared
between files in the readline library, but are not intended
to be visible to readline callers. */
/*************************************************************************
* Undocumented private functions *
*************************************************************************/
#if defined(READLINE_CALLBACKS)
/* readline.c */
extern void readline_internal_setup PARAMS((void));
extern char *readline_internal_teardown PARAMS((int));
extern int readline_internal_char PARAMS((void));
#endif /* READLINE_CALLBACKS */
/* bind.c */
extern void _rl_bind_if_unbound PARAMS((const char *, rl_command_func_t *));
/* complete.c */
extern char _rl_find_completion_word PARAMS((int *, int *));
extern void _rl_free_match_list PARAMS((char **));
/* display.c */
extern char *_rl_strip_prompt PARAMS((char *));
extern void _rl_move_cursor_relative PARAMS((int, const char *));
extern void _rl_move_vert PARAMS((int));
extern void _rl_save_prompt PARAMS((void));
extern void _rl_restore_prompt PARAMS((void));
extern char *_rl_make_prompt_for_search PARAMS((int));
extern void _rl_erase_at_end_of_line PARAMS((int));
extern void _rl_clear_to_eol PARAMS((int));
extern void _rl_clear_screen PARAMS((void));
extern void _rl_update_final PARAMS((void));
extern void _rl_redisplay_after_sigwinch PARAMS((void));
extern void _rl_clean_up_for_exit PARAMS((void));
extern void _rl_erase_entire_line PARAMS((void));
extern int _rl_current_display_line PARAMS((void));
/* input.c */
extern int _rl_any_typein PARAMS((void));
extern int _rl_input_available PARAMS((void));
extern int _rl_input_queued PARAMS((int));
extern void _rl_insert_typein PARAMS((int));
extern int _rl_unget_char PARAMS((int));
/* macro.c */
extern void _rl_with_macro_input PARAMS((char *));
extern int _rl_next_macro_key PARAMS((void));
extern void _rl_push_executing_macro PARAMS((void));
extern void _rl_pop_executing_macro PARAMS((void));
extern void _rl_add_macro_char PARAMS((int));
extern void _rl_kill_kbd_macro PARAMS((void));
/* misc.c */
extern int _rl_init_argument PARAMS((void));
extern void _rl_start_using_history PARAMS((void));
extern int _rl_free_saved_history_line PARAMS((void));
extern void _rl_set_insert_mode PARAMS((int, int));
/* nls.c */
extern int _rl_init_eightbit PARAMS((void));
/* parens.c */
extern void _rl_enable_paren_matching PARAMS((int));
/* readline.c */
extern void _rl_init_line_state PARAMS((void));
extern void _rl_set_the_line PARAMS((void));
extern int _rl_dispatch PARAMS((int, Keymap));
extern int _rl_dispatch_subseq PARAMS((int, Keymap, int));
/* rltty.c */
extern int _rl_disable_tty_signals PARAMS((void));
extern int _rl_restore_tty_signals PARAMS((void));
/* terminal.c */
extern void _rl_get_screen_size PARAMS((int, int));
extern int _rl_init_terminal_io PARAMS((const char *));
#ifdef _MINIX
extern void _rl_output_character_function PARAMS((int));
#else
extern int _rl_output_character_function PARAMS((int));
#endif
extern void _rl_output_some_chars PARAMS((const char *, int));
extern int _rl_backspace PARAMS((int));
extern void _rl_enable_meta_key PARAMS((void));
extern void _rl_control_keypad PARAMS((int));
extern void _rl_set_cursor PARAMS((int, int));
/* text.c */
extern void _rl_fix_point PARAMS((int));
extern int _rl_replace_text PARAMS((const char *, int, int));
extern int _rl_insert_char PARAMS((int, int));
extern int _rl_overwrite_char PARAMS((int, int));
extern int _rl_overwrite_rubout PARAMS((int, int));
extern int _rl_rubout_char PARAMS((int, int));
#if defined (HANDLE_MULTIBYTE)
extern int _rl_char_search_internal PARAMS((int, int, char *, int));
#else
extern int _rl_char_search_internal PARAMS((int, int, int));
#endif
extern int _rl_set_mark_at_pos PARAMS((int));
/* util.c */
extern int _rl_abort_internal PARAMS((void));
extern char *_rl_strindex PARAMS((const char *, const char *));
extern int _rl_qsort_string_compare PARAMS((char **, char **));
extern int (_rl_uppercase_p) PARAMS((int));
extern int (_rl_lowercase_p) PARAMS((int));
extern int (_rl_pure_alphabetic) PARAMS((int));
extern int (_rl_digit_p) PARAMS((int));
extern int (_rl_to_lower) PARAMS((int));
extern int (_rl_to_upper) PARAMS((int));
extern int (_rl_digit_value) PARAMS((int));
/* vi_mode.c */
extern void _rl_vi_initialize_line PARAMS((void));
extern void _rl_vi_reset_last PARAMS((void));
extern void _rl_vi_set_last PARAMS((int, int, int));
extern int _rl_vi_textmod_command PARAMS((int));
extern void _rl_vi_done_inserting PARAMS((void));
/*************************************************************************
* Undocumented private variables *
*************************************************************************/
/* bind.c */
extern const char *_rl_possible_control_prefixes[];
extern const char *_rl_possible_meta_prefixes[];
/* complete.c */
extern int _rl_complete_show_all;
extern int _rl_complete_mark_directories;
extern int _rl_complete_mark_symlink_dirs;
extern int _rl_print_completions_horizontally;
extern int _rl_completion_case_fold;
extern int _rl_match_hidden_files;
extern int _rl_page_completions;
/* display.c */
extern int _rl_vis_botlin;
extern int _rl_last_c_pos;
extern int _rl_suppress_redisplay;
extern char *rl_display_prompt;
/* isearch.c */
extern char *_rl_isearch_terminators;
/* macro.c */
extern char *_rl_executing_macro;
/* misc.c */
extern int _rl_history_preserve_point;
extern int _rl_history_saved_point;
/* readline.c */
extern int _rl_horizontal_scroll_mode;
extern int _rl_mark_modified_lines;
extern int _rl_bell_preference;
extern int _rl_meta_flag;
extern int _rl_convert_meta_chars_to_ascii;
extern int _rl_output_meta_chars;
extern char *_rl_comment_begin;
extern unsigned char _rl_parsing_conditionalized_out;
extern Keymap _rl_keymap;
extern FILE *_rl_in_stream;
extern FILE *_rl_out_stream;
extern int _rl_last_command_was_kill;
extern int _rl_eof_char;
extern procenv_t readline_top_level;
/* terminal.c */
extern int _rl_enable_keypad;
extern int _rl_enable_meta;
extern char *_rl_term_clreol;
extern char *_rl_term_clrpag;
extern char *_rl_term_im;
extern char *_rl_term_ic;
extern char *_rl_term_ei;
extern char *_rl_term_DC;
extern char *_rl_term_up;
extern char *_rl_term_dc;
extern char *_rl_term_cr;
extern char *_rl_term_IC;
extern int _rl_screenheight;
extern int _rl_screenwidth;
extern int _rl_screenchars;
extern int _rl_terminal_can_insert;
extern int _rl_term_autowrap;
/* undo.c */
extern int _rl_doing_an_undo;
extern int _rl_undo_group_level;
#endif /* _RL_PRIVATE_H_ */

34
readline/rlshell.h Normal file
View File

@@ -0,0 +1,34 @@
/* rlshell.h -- utility functions normally provided by bash. */
/* Copyright (C) 1999 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_RL_SHELL_H_)
#define _RL_SHELL_H_
#include "rlstdc.h"
extern char *sh_single_quote PARAMS((char *));
extern void sh_set_lines_and_columns PARAMS((int, int));
extern char *sh_get_env_value PARAMS((const char *));
extern char *sh_get_home_dir PARAMS((void));
extern int sh_unset_nodelay_mode PARAMS((int));
#endif /* _RL_SHELL_H_ */

View File

@@ -7,7 +7,7 @@
Bash is free software; you can redistribute it and/or modify it Bash is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
Bash is distributed in the hope that it will be useful, but WITHOUT Bash is distributed in the hope that it will be useful, but WITHOUT
@@ -17,7 +17,7 @@
You should have received a copy of the GNU General Public License 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 along with Bash; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_RL_STDC_H_) #if !defined (_RL_STDC_H_)
#define _RL_STDC_H_ #define _RL_STDC_H_
@@ -26,58 +26,20 @@
/* A function can be defined using prototypes and compile on both ANSI C /* A function can be defined using prototypes and compile on both ANSI C
and traditional C compilers with something like this: and traditional C compilers with something like this:
extern char *func __P((char *, char *, int)); */ extern char *func PARAMS((char *, char *, int)); */
#if defined (__STDC__) || defined(__cplusplus) #if !defined (PARAMS)
# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus)
# define PARAMS(protos) protos
# else
# define PARAMS(protos) ()
# endif
#endif
# if !defined (__P) #ifndef __attribute__
# define __P(protos) protos # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
# define __attribute__(x)
# endif # endif
# define __STRING(x) #x
# if !defined (__GNUC__) && !defined(__cplusplus) && !defined(inline)
# define inline
# endif
#else /* !__STDC__ */
# if !defined (__P)
# define __P(protos) ()
# endif
# define __STRING(x) "x"
#if defined (__GNUC__) /* gcc with -traditional */
# if !defined (const)
# define const __const
# endif
# if !defined (inline)
# define inline __inline
# endif
# if !defined (signed)
# define signed __signed
# endif
# if !defined (volatile)
# define volatile __volatile
# endif
#else /* !__GNUC__ */
# if !defined (const)
# define const
# endif
# if !defined (inline)
# define inline
# endif
# if !defined (signed)
# define signed
# endif
# if !defined (volatile)
# define volatile
# endif
#endif /* !__GNUC__ */
#endif /* !__STDC__ */
#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
#define __attribute__(A)
#endif #endif
#endif /* !_RL_STDC_H_ */ #endif /* !_RL_STDC_H_ */

View File

@@ -8,7 +8,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -19,7 +19,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
@@ -43,28 +43,19 @@
#include "rltty.h" #include "rltty.h"
#include "readline.h" #include "readline.h"
#include "rlprivate.h"
#if !defined (errno) #if !defined (errno)
extern int errno; extern int errno;
#endif /* !errno */ #endif /* !errno */
extern int readline_echoing_p; rl_vintfunc_t *rl_prep_term_function = rl_prep_terminal;
extern int _rl_eof_char; rl_voidfunc_t *rl_deprep_term_function = rl_deprep_terminal;
extern int _rl_enable_keypad, _rl_enable_meta; static void block_sigint PARAMS((void));
static void release_sigint PARAMS((void));
extern void _rl_control_keypad (); static void set_winsize PARAMS((int));
#if defined (__GO32__)
# 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;
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
@@ -104,6 +95,7 @@ block_sigint ()
# endif /* HAVE_USG_SIGHOLD */ # endif /* HAVE_USG_SIGHOLD */
# endif /* !HAVE_BSD_SIGNALS */ # endif /* !HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */ #endif /* !HAVE_POSIX_SIGNALS */
sigint_blocked = 1; sigint_blocked = 1;
} }
@@ -111,7 +103,7 @@ block_sigint ()
static void static void
release_sigint () release_sigint ()
{ {
if (!sigint_blocked) if (sigint_blocked == 0)
return; return;
#if defined (HAVE_POSIX_SIGNALS) #if defined (HAVE_POSIX_SIGNALS)
@@ -138,32 +130,27 @@ release_sigint ()
/* Non-zero means that the terminal is in a prepped state. */ /* Non-zero means that the terminal is in a prepped state. */
static int terminal_prepped; static int terminal_prepped;
static _RL_TTY_CHARS _rl_tty_chars, _rl_last_tty_chars;
/* If non-zero, means that this process has called tcflow(fd, TCOOFF) /* If non-zero, means that this process has called tcflow(fd, TCOOFF)
and output is suspended. */ and output is suspended. */
#if defined (__ksr1__) #if defined (__ksr1__)
static int ksrflow; static int ksrflow;
#endif #endif
#if defined (TIOCGWINSZ)
/* Dummy call to force a backgrounded readline to stop before it tries /* Dummy call to force a backgrounded readline to stop before it tries
to get the tty settings. */ to get the tty settings. */
static void static void
set_winsize (tty) set_winsize (tty)
int tty; int tty;
{ {
#if defined (TIOCGWINSZ)
struct winsize w; struct winsize w;
if (ioctl (tty, TIOCGWINSZ, &w) == 0) if (ioctl (tty, TIOCGWINSZ, &w) == 0)
(void) ioctl (tty, TIOCSWINSZ, &w); (void) ioctl (tty, TIOCSWINSZ, &w);
}
#else
static void
set_winsize (tty)
int tty;
{
// dummy function, required by other code. What should be doing?
}
#endif /* TIOCGWINSZ */ #endif /* TIOCGWINSZ */
}
#if defined (NEW_TTY_DRIVER) #if defined (NEW_TTY_DRIVER)
@@ -191,6 +178,50 @@ struct bsdtty {
static TIOTYPE otio; static TIOTYPE otio;
static void save_tty_chars PARAMS((TIOTYPE *));
static int _get_tty_settings PARAMS((int, TIOTYPE *));
static int get_tty_settings PARAMS((int, TIOTYPE *));
static int _set_tty_settings PARAMS((int, TIOTYPE *));
static int set_tty_settings PARAMS((int, TIOTYPE *));
static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
static void
save_tty_chars (tiop)
TIOTYPE *tiop;
{
_rl_last_tty_chars = _rl_tty_chars;
if (tiop->flags & SGTTY_SET)
{
_rl_tty_chars.t_erase = tiop->sgttyb.sg_erase;
_rl_tty_chars.t_kill = tiop->sgttyb.sg_kill;
}
if (tiop->flags & TCHARS_SET)
{
_rl_tty_chars.t_intr = tiop->tchars.t_intrc;
_rl_tty_chars.t_quit = tiop->tchars.t_quitc;
_rl_tty_chars.t_start = tiop->tchars.t_startc;
_rl_tty_chars.t_stop = tiop->tchars.t_stopc;
_rl_tty_chars.t_eof = tiop->tchars.t_eofc;
_rl_tty_chars.t_eol = '\n';
_rl_tty_chars.t_eol2 = tiop->tchars.t_brkc;
}
if (tiop->flags & LTCHARS_SET)
{
_rl_tty_chars.t_susp = tiop->ltchars.t_suspc;
_rl_tty_chars.t_dsusp = tiop->ltchars.t_dsuspc;
_rl_tty_chars.t_reprint = tiop->ltchars.t_rprntc;
_rl_tty_chars.t_flush = tiop->ltchars.t_flushc;
_rl_tty_chars.t_werase = tiop->ltchars.t_werasc;
_rl_tty_chars.t_lnext = tiop->ltchars.t_lnextc;
}
_rl_tty_chars.t_status = -1;
}
static int static int
get_tty_settings (tty, tiop) get_tty_settings (tty, tiop)
int tty; int tty;
@@ -200,22 +231,23 @@ get_tty_settings (tty, tiop)
tiop->flags = tiop->lflag = 0; tiop->flags = tiop->lflag = 0;
ioctl (tty, TIOCGETP, &(tiop->sgttyb)); if (ioctl (tty, TIOCGETP, &(tiop->sgttyb)) < 0)
return -1;
tiop->flags |= SGTTY_SET; tiop->flags |= SGTTY_SET;
#if defined (TIOCLGET) #if defined (TIOCLGET)
ioctl (tty, TIOCLGET, &(tiop->lflag)); if (ioctl (tty, TIOCLGET, &(tiop->lflag)) == 0)
tiop->flags |= LFLAG_SET; tiop->flags |= LFLAG_SET;
#endif #endif
#if defined (TIOCGETC) #if defined (TIOCGETC)
ioctl (tty, TIOCGETC, &(tiop->tchars)); if (ioctl (tty, TIOCGETC, &(tiop->tchars)) == 0)
tiop->flags |= TCHARS_SET; tiop->flags |= TCHARS_SET;
#endif #endif
#if defined (TIOCGLTC) #if defined (TIOCGLTC)
ioctl (tty, TIOCGLTC, &(tiop->ltchars)); if (ioctl (tty, TIOCGLTC, &(tiop->ltchars)) == 0)
tiop->flags |= LTCHARS_SET; tiop->flags |= LTCHARS_SET;
#endif #endif
return 0; return 0;
@@ -261,24 +293,23 @@ set_tty_settings (tty, tiop)
} }
static void static void
prepare_terminal_settings (meta_flag, otio, tiop) prepare_terminal_settings (meta_flag, oldtio, tiop)
int meta_flag; int meta_flag;
TIOTYPE otio, *tiop; TIOTYPE oldtio, *tiop;
{ {
#if !defined (__GO32__) readline_echoing_p = (oldtio.sgttyb.sg_flags & ECHO);
readline_echoing_p = (otio.sgttyb.sg_flags & ECHO);
/* Copy the original settings to the structure we're going to use for /* Copy the original settings to the structure we're going to use for
our settings. */ our settings. */
tiop->sgttyb = otio.sgttyb; tiop->sgttyb = oldtio.sgttyb;
tiop->lflag = otio.lflag; tiop->lflag = oldtio.lflag;
#if defined (TIOCGETC) #if defined (TIOCGETC)
tiop->tchars = otio.tchars; tiop->tchars = oldtio.tchars;
#endif #endif
#if defined (TIOCGLTC) #if defined (TIOCGLTC)
tiop->ltchars = otio.ltchars; tiop->ltchars = oldtio.ltchars;
#endif #endif
tiop->flags = otio.flags; tiop->flags = oldtio.flags;
/* First, the basic settings to put us into character-at-a-time, no-echo /* First, the basic settings to put us into character-at-a-time, no-echo
input mode. */ input mode. */
@@ -291,8 +322,8 @@ prepare_terminal_settings (meta_flag, otio, tiop)
#if !defined (ANYP) #if !defined (ANYP)
# define ANYP (EVENP | ODDP) # define ANYP (EVENP | ODDP)
#endif #endif
if (((otio.sgttyb.sg_flags & ANYP) == ANYP) || if (((oldtio.sgttyb.sg_flags & ANYP) == ANYP) ||
((otio.sgttyb.sg_flags & ANYP) == 0)) ((oldtio.sgttyb.sg_flags & ANYP) == 0))
{ {
tiop->sgttyb.sg_flags |= ANYP; tiop->sgttyb.sg_flags |= ANYP;
@@ -311,13 +342,13 @@ prepare_terminal_settings (meta_flag, otio, tiop)
tiop->tchars.t_startc = -1; /* C-q */ tiop->tchars.t_startc = -1; /* C-q */
/* If there is an XON character, bind it to restart the output. */ /* If there is an XON character, bind it to restart the output. */
if (otio.tchars.t_startc != -1) if (oldtio.tchars.t_startc != -1)
rl_bind_key (otio.tchars.t_startc, rl_restart_output); rl_bind_key (oldtio.tchars.t_startc, rl_restart_output);
# endif /* USE_XON_XOFF */ # endif /* USE_XON_XOFF */
/* If there is an EOF char, bind _rl_eof_char to it. */ /* If there is an EOF char, bind _rl_eof_char to it. */
if (otio.tchars.t_eofc != -1) if (oldtio.tchars.t_eofc != -1)
_rl_eof_char = otio.tchars.t_eofc; _rl_eof_char = oldtio.tchars.t_eofc;
# if defined (NO_KILL_INTR) # if defined (NO_KILL_INTR)
/* Get rid of terminal-generated SIGQUIT and SIGINT. */ /* Get rid of terminal-generated SIGQUIT and SIGINT. */
@@ -331,7 +362,6 @@ prepare_terminal_settings (meta_flag, otio, tiop)
tiop->ltchars.t_dsuspc = -1; /* C-y */ tiop->ltchars.t_dsuspc = -1; /* C-y */
tiop->ltchars.t_lnextc = -1; /* C-v */ tiop->ltchars.t_lnextc = -1; /* C-v */
#endif /* TIOCGLTC */ #endif /* TIOCGLTC */
#endif /* !__GO32__ */
} }
#else /* !defined (NEW_TTY_DRIVER) */ #else /* !defined (NEW_TTY_DRIVER) */
@@ -357,18 +387,71 @@ prepare_terminal_settings (meta_flag, otio, tiop)
# define TIOTYPE struct termio # define TIOTYPE struct termio
# define DRAIN_OUTPUT(fd) # define DRAIN_OUTPUT(fd)
# define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop)) # define GETATTR(tty, tiop) (ioctl (tty, TCGETA, tiop))
# define SETATTR(tty, tiop) (ioctl (tty, TCSETA, tiop)) # define SETATTR(tty, tiop) (ioctl (tty, TCSETAW, tiop))
#endif /* !TERMIOS_TTY_DRIVER */ #endif /* !TERMIOS_TTY_DRIVER */
static TIOTYPE otio; static TIOTYPE otio;
static void save_tty_chars PARAMS((TIOTYPE *));
static int _get_tty_settings PARAMS((int, TIOTYPE *));
static int get_tty_settings PARAMS((int, TIOTYPE *));
static int _set_tty_settings PARAMS((int, TIOTYPE *));
static int set_tty_settings PARAMS((int, TIOTYPE *));
static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
#if defined (FLUSHO) #if defined (FLUSHO)
# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO) # define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
#else #else
# define OUTPUT_BEING_FLUSHED(tp) 0 # define OUTPUT_BEING_FLUSHED(tp) 0
#endif #endif
#if defined (_AIX) || (defined (FLUSHO) && defined (_AIX41)) static void
save_tty_chars (tiop)
TIOTYPE *tiop;
{
_rl_last_tty_chars = _rl_tty_chars;
_rl_tty_chars.t_eof = tiop->c_cc[VEOF];
_rl_tty_chars.t_eol = tiop->c_cc[VEOL];
#ifdef VEOL2
_rl_tty_chars.t_eol2 = tiop->c_cc[VEOL2];
#endif
_rl_tty_chars.t_erase = tiop->c_cc[VERASE];
#ifdef VWERASE
_rl_tty_chars.t_werase = tiop->c_cc[VWERASE];
#endif
_rl_tty_chars.t_kill = tiop->c_cc[VKILL];
#ifdef VREPRINT
_rl_tty_chars.t_reprint = tiop->c_cc[VREPRINT];
#endif
_rl_tty_chars.t_intr = tiop->c_cc[VINTR];
_rl_tty_chars.t_quit = tiop->c_cc[VQUIT];
#ifdef VSUSP
_rl_tty_chars.t_susp = tiop->c_cc[VSUSP];
#endif
#ifdef VDSUSP
_rl_tty_chars.t_dsusp = tiop->c_cc[VDSUSP];
#endif
#ifdef VSTART
_rl_tty_chars.t_start = tiop->c_cc[VSTART];
#endif
#ifdef VSTOP
_rl_tty_chars.t_stop = tiop->c_cc[VSTOP];
#endif
#ifdef VLNEXT
_rl_tty_chars.t_lnext = tiop->c_cc[VLNEXT];
#endif
#ifdef VDISCARD
_rl_tty_chars.t_flush = tiop->c_cc[VDISCARD];
#endif
#ifdef VSTATUS
_rl_tty_chars.t_status = tiop->c_cc[VSTATUS];
#endif
}
#if defined (_AIX) || defined (_AIX41)
/* Currently this is only used on AIX */
static void static void
rltty_warning (msg) rltty_warning (msg)
char *msg; char *msg;
@@ -377,7 +460,6 @@ rltty_warning (msg)
} }
#endif #endif
#if defined (_AIX) #if defined (_AIX)
void void
setopost(tp) setopost(tp)
@@ -392,14 +474,12 @@ TIOTYPE *tp;
#endif #endif
static int static int
get_tty_settings (tty, tiop) _get_tty_settings (tty, tiop)
int tty; int tty;
TIOTYPE *tiop; TIOTYPE *tiop;
{ {
int ioctl_ret; int ioctl_ret;
set_winsize (tty);
while (1) while (1)
{ {
ioctl_ret = GETATTR (tty, tiop); ioctl_ret = GETATTR (tty, tiop);
@@ -423,6 +503,19 @@ get_tty_settings (tty, tiop)
break; break;
} }
return 0;
}
static int
get_tty_settings (tty, tiop)
int tty;
TIOTYPE *tiop;
{
set_winsize (tty);
if (_get_tty_settings (tty, tiop) < 0)
return -1;
#if defined (_AIX) #if defined (_AIX)
setopost(tiop); setopost(tiop);
#endif #endif
@@ -431,7 +524,7 @@ get_tty_settings (tty, tiop)
} }
static int static int
set_tty_settings (tty, tiop) _set_tty_settings (tty, tiop)
int tty; int tty;
TIOTYPE *tiop; TIOTYPE *tiop;
{ {
@@ -441,7 +534,17 @@ set_tty_settings (tty, tiop)
return -1; return -1;
errno = 0; errno = 0;
} }
return 0;
}
static int
set_tty_settings (tty, tiop)
int tty;
TIOTYPE *tiop;
{
if (_set_tty_settings (tty, tiop) < 0)
return -1;
#if 0 #if 0
#if defined (TERMIOS_TTY_DRIVER) #if defined (TERMIOS_TTY_DRIVER)
@@ -458,22 +561,22 @@ set_tty_settings (tty, tiop)
ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */ ioctl (tty, TCXONC, 1); /* Simulate a ^Q. */
#endif /* !TERMIOS_TTY_DRIVER */ #endif /* !TERMIOS_TTY_DRIVER */
#endif #endif /* 0 */
return 0; return 0;
} }
static void static void
prepare_terminal_settings (meta_flag, otio, tiop) prepare_terminal_settings (meta_flag, oldtio, tiop)
int meta_flag; int meta_flag;
TIOTYPE otio, *tiop; TIOTYPE oldtio, *tiop;
{ {
readline_echoing_p = (otio.c_lflag & ECHO); readline_echoing_p = (oldtio.c_lflag & ECHO);
tiop->c_lflag &= ~(ICANON | ECHO); tiop->c_lflag &= ~(ICANON | ECHO);
if ((unsigned char) otio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE) if ((unsigned char) oldtio.c_cc[VEOF] != (unsigned char) _POSIX_VDISABLE)
_rl_eof_char = otio.c_cc[VEOF]; _rl_eof_char = oldtio.c_cc[VEOF];
#if defined (USE_XON_XOFF) #if defined (USE_XON_XOFF)
#if defined (IXANY) #if defined (IXANY)
@@ -504,7 +607,7 @@ prepare_terminal_settings (meta_flag, otio, tiop)
if (OUTPUT_BEING_FLUSHED (tiop)) if (OUTPUT_BEING_FLUSHED (tiop))
{ {
tiop->c_lflag &= ~FLUSHO; tiop->c_lflag &= ~FLUSHO;
otio.c_lflag &= ~FLUSHO; oldtio.c_lflag &= ~FLUSHO;
} }
#endif #endif
@@ -530,7 +633,6 @@ void
rl_prep_terminal (meta_flag) rl_prep_terminal (meta_flag)
int meta_flag; int meta_flag;
{ {
#if !defined (__GO32__)
int tty; int tty;
TIOTYPE tio; TIOTYPE tio;
@@ -550,6 +652,8 @@ rl_prep_terminal (meta_flag)
otio = tio; otio = tio;
save_tty_chars (&otio);
prepare_terminal_settings (meta_flag, otio, &tio); prepare_terminal_settings (meta_flag, otio, &tio);
if (set_tty_settings (tty, &tio) < 0) if (set_tty_settings (tty, &tio) < 0)
@@ -563,16 +667,15 @@ rl_prep_terminal (meta_flag)
fflush (rl_outstream); fflush (rl_outstream);
terminal_prepped = 1; terminal_prepped = 1;
RL_SETSTATE(RL_STATE_TERMPREPPED);
release_sigint (); release_sigint ();
#endif /* !__GO32__ */
} }
/* Restore the terminal's normal settings and modes. */ /* Restore the terminal's normal settings and modes. */
void void
rl_deprep_terminal () rl_deprep_terminal ()
{ {
#if !defined (__GO32__)
int tty; int tty;
if (!terminal_prepped) if (!terminal_prepped)
@@ -595,9 +698,9 @@ rl_deprep_terminal ()
} }
terminal_prepped = 0; terminal_prepped = 0;
RL_UNSETSTATE(RL_STATE_TERMPREPPED);
release_sigint (); release_sigint ();
#endif /* !__GO32__ */
} }
/* **************************************************************** */ /* **************************************************************** */
@@ -607,8 +710,8 @@ rl_deprep_terminal ()
/* **************************************************************** */ /* **************************************************************** */
int int
rl_restart_output (int count __attribute__((unused)), rl_restart_output (count, key)
int key __attribute__((unused))) int count __attribute__((unused)), key __attribute__((unused));
{ {
int fildes = fileno (rl_outstream); int fildes = fileno (rl_outstream);
#if defined (TIOCSTART) #if defined (TIOCSTART)
@@ -640,8 +743,8 @@ rl_restart_output (int count __attribute__((unused)),
} }
int int
rl_stop_output (int count __attribute__((unused)), rl_stop_output (count, key)
int key __attribute__((unused))) int count __attribute__((unused)), key __attribute__((unused));
{ {
int fildes = fileno (rl_instream); int fildes = fileno (rl_instream);
@@ -672,6 +775,9 @@ rl_stop_output (int count __attribute__((unused)),
/* Default Key Bindings */ /* Default Key Bindings */
/* */ /* */
/* **************************************************************** */ /* **************************************************************** */
/* Set the system's default editing characters to their readline equivalents
in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
void void
rltty_set_default_bindings (kmap) rltty_set_default_bindings (kmap)
Keymap kmap; Keymap kmap;
@@ -686,8 +792,8 @@ rltty_set_default_bindings (kmap)
{ \ { \
int ic; \ int ic; \
ic = sc; \ ic = sc; \
if (ic != -1 && kmap[ic].type == ISFUNC) \ if (ic != -1 && kmap[(unsigned char)ic].type == ISFUNC) \
kmap[ic].function = func; \ kmap[(unsigned char)ic].function = func; \
} \ } \
while (0) while (0)
@@ -735,3 +841,71 @@ rltty_set_default_bindings (kmap)
} }
#endif /* !NEW_TTY_DRIVER */ #endif /* !NEW_TTY_DRIVER */
} }
/* New public way to set the system default editing chars to their readline
equivalents. */
void
rl_tty_set_default_bindings (kmap)
Keymap kmap;
{
rltty_set_default_bindings (kmap);
}
#if defined (HANDLE_SIGNALS)
#if defined (NEW_TTY_DRIVER)
int
_rl_disable_tty_signals ()
{
return 0;
}
int
_rl_restore_tty_signals ()
{
return 0;
}
#else
static TIOTYPE sigstty, nosigstty;
static int tty_sigs_disabled = 0;
int
_rl_disable_tty_signals ()
{
if (tty_sigs_disabled)
return 0;
if (_get_tty_settings (fileno (rl_instream), &sigstty) < 0)
return -1;
nosigstty = sigstty;
nosigstty.c_lflag &= ~ISIG;
nosigstty.c_iflag &= ~IXON;
if (_set_tty_settings (fileno (rl_instream), &nosigstty) < 0)
return (_set_tty_settings (fileno (rl_instream), &sigstty));
tty_sigs_disabled = 1;
return 0;
}
int
_rl_restore_tty_signals ()
{
int r;
if (tty_sigs_disabled == 0)
return 0;
r = _set_tty_settings (fileno (rl_instream), &sigstty);
if (r == 0)
tty_sigs_disabled = 0;
return r;
}
#endif /* !NEW_TTY_DRIVER */
#endif /* HANDLE_SIGNALS */

View File

@@ -8,7 +8,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -19,10 +19,10 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_RLTTY_H_) #if !defined (_RLTTY_H_)
#define _RLTTY_H #define _RLTTY_H_
/* Posix systems use termios and the Posix signal functions. */ /* Posix systems use termios and the Posix signal functions. */
#if defined (TERMIOS_TTY_DRIVER) #if defined (TERMIOS_TTY_DRIVER)
@@ -60,4 +60,23 @@
# endif /* !_SVR4_DISABLE */ # endif /* !_SVR4_DISABLE */
#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */ #endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
typedef struct _rl_tty_chars {
char t_eof;
char t_eol;
char t_eol2;
char t_erase;
char t_werase;
char t_kill;
char t_reprint;
char t_intr;
char t_quit;
char t_susp;
char t_dsusp;
char t_start;
char t_stop;
char t_lnext;
char t_flush;
char t_status;
} _RL_TTY_CHARS;
#endif /* _RLTTY_H_ */ #endif /* _RLTTY_H_ */

88
readline/rltypedefs.h Normal file
View File

@@ -0,0 +1,88 @@
/* rltypedefs.h -- Type declarations for readline functions. */
/* Copyright (C) 2000 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#ifndef _RL_TYPEDEFS_H_
#define _RL_TYPEDEFS_H_
#ifdef __cplusplus
extern "C" {
#endif
/* Old-style */
#if !defined (_FUNCTION_DEF)
# define _FUNCTION_DEF
typedef int Function ();
typedef void VFunction ();
typedef char *CPFunction ();
typedef char **CPPFunction ();
#endif /* _FUNCTION_DEF */
/* New style. */
#if !defined (_RL_FUNCTION_TYPEDEF)
# define _RL_FUNCTION_TYPEDEF
/* Bindable functions */
typedef int rl_command_func_t PARAMS((int, int));
/* Typedefs for the completion system */
typedef char *rl_compentry_func_t PARAMS((const char *, int));
typedef char **rl_completion_func_t PARAMS((const char *, int, int));
typedef char *rl_quote_func_t PARAMS((char *, int, char *));
typedef char *rl_dequote_func_t PARAMS((char *, int));
typedef int rl_compignore_func_t PARAMS((char **));
typedef void rl_compdisp_func_t PARAMS((char **, int, int));
/* Type for input and pre-read hook functions like rl_event_hook */
typedef int rl_hook_func_t PARAMS((void));
/* Input function type */
typedef int rl_getc_func_t PARAMS((FILE *));
/* Generic function that takes a character buffer (which could be the readline
line buffer) and an index into it (which could be rl_point) and returns
an int. */
typedef int rl_linebuf_func_t PARAMS((char *, int));
/* `Generic' function pointer typedefs */
typedef int rl_intfunc_t PARAMS((int));
#define rl_ivoidfunc_t rl_hook_func_t
typedef int rl_icpfunc_t PARAMS((char *));
typedef int rl_icppfunc_t PARAMS((char **));
typedef void rl_voidfunc_t PARAMS((void));
typedef void rl_vintfunc_t PARAMS((int));
typedef void rl_vcpfunc_t PARAMS((char *));
typedef void rl_vcppfunc_t PARAMS((char **));
#endif /* _RL_FUNCTION_TYPEDEF */
#ifdef __cplusplus
}
#endif
#endif /* _RL_TYPEDEFS_H_ */

View File

@@ -9,7 +9,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -20,7 +20,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_RLWINSIZE_H_) #if !defined (_RLWINSIZE_H_)
#define _RLWINSIZE_H_ #define _RLWINSIZE_H_
@@ -55,4 +55,3 @@
#endif /* _RL_WINSIZE_H */ #endif /* _RL_WINSIZE_H */

View File

@@ -8,7 +8,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -19,7 +19,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
@@ -40,33 +40,56 @@
#endif #endif
#include "rldefs.h" #include "rldefs.h"
#include "rlmbutil.h"
#include "readline.h" #include "readline.h"
#include "history.h" #include "history.h"
#include "rlprivate.h"
#include "xmalloc.h"
#ifdef abs #ifdef abs
# undef abs # undef abs
#endif #endif
#define abs(x) (((x) >= 0) ? (x) : -(x)) #define abs(x) (((x) >= 0) ? (x) : -(x))
extern char *xmalloc (), *xrealloc (); extern HIST_ENTRY *_rl_saved_line_for_history;
/* Variables imported from readline.c */
extern int rl_point, rl_end, rl_line_buffer_len;
extern int rl_editing_mode;
extern char *rl_prompt;
extern char *rl_line_buffer;
extern HIST_ENTRY *saved_line_for_history;
extern Function *rl_last_func;
/* Functions imported from the rest of the library. */ /* Functions imported from the rest of the library. */
extern int _rl_free_history_entry (); extern int _rl_free_history_entry PARAMS((HIST_ENTRY *));
extern char *_rl_make_prompt_for_search ();
extern void rl_extend_line_buffer ();
static char *noninc_search_string = (char *) NULL; static char *noninc_search_string = (char *) NULL;
static int noninc_history_pos; static int noninc_history_pos;
static char *prev_line_found = (char *) NULL; static char *prev_line_found = (char *) NULL;
static int rl_history_search_len;
static int rl_history_search_pos;
static char *history_search_string;
static int history_string_size;
static void make_history_line_current PARAMS((HIST_ENTRY *));
static int noninc_search_from_pos PARAMS((char *, int, int));
static void noninc_dosearch PARAMS((char *, int));
static void noninc_search PARAMS((int, int));
static int rl_history_search_internal PARAMS((int, int));
static void rl_history_search_reinit PARAMS((void));
/* Make the data from the history entry ENTRY be the contents of the
current line. This doesn't do anything with rl_point; the caller
must set it. */
static void
make_history_line_current (entry)
HIST_ENTRY *entry;
{
rl_replace_line (entry->line, 0);
rl_undo_list = (UNDO_LIST *)entry->data;
if (_rl_saved_line_for_history)
_rl_free_history_entry (_rl_saved_line_for_history);
_rl_saved_line_for_history = (HIST_ENTRY *)NULL;
}
/* Search the history list for STRING starting at absolute history position /* Search the history list for STRING starting at absolute history position
POS. If STRING begins with `^', the search must match STRING at the POS. If STRING begins with `^', the search must match STRING at the
beginning of a history line, otherwise a full substring match is performed beginning of a history line, otherwise a full substring match is performed
@@ -79,13 +102,19 @@ noninc_search_from_pos (string, pos, dir)
{ {
int ret, old; int ret, old;
old = where_history (); if (pos < 0)
history_set_pos (pos); return -1;
old = where_history ();
if (history_set_pos (pos) == 0)
return -1;
RL_SETSTATE(RL_STATE_SEARCH);
if (*string == '^') if (*string == '^')
ret = history_search_prefix (string + 1, dir); ret = history_search_prefix (string + 1, dir);
else else
ret = history_search (string, dir); ret = history_search (string, dir);
RL_UNSETSTATE(RL_STATE_SEARCH);
if (ret != -1) if (ret != -1)
ret = where_history (); ret = where_history ();
@@ -102,12 +131,12 @@ noninc_dosearch (string, dir)
char *string; char *string;
int dir; int dir;
{ {
int oldpos, pos, line_len; int oldpos, pos;
HIST_ENTRY *entry; HIST_ENTRY *entry;
if (string == 0 || *string == '\0' || noninc_history_pos < 0) if (string == 0 || *string == '\0' || noninc_history_pos < 0)
{ {
ding (); rl_ding ();
return; return;
} }
@@ -115,10 +144,10 @@ noninc_dosearch (string, dir)
if (pos == -1) if (pos == -1)
{ {
/* Search failed, current history position unchanged. */ /* Search failed, current history position unchanged. */
maybe_unsave_line (); rl_maybe_unsave_line ();
rl_clear_message (); rl_clear_message ();
rl_point = 0; rl_point = 0;
ding (); rl_ding ();
return; return;
} }
@@ -132,19 +161,12 @@ noninc_dosearch (string, dir)
#endif #endif
history_set_pos (oldpos); history_set_pos (oldpos);
line_len = strlen (entry->line); make_history_line_current (entry);
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);
rl_point = 0; rl_point = 0;
rl_clear_message (); rl_mark = rl_end;
if (saved_line_for_history) rl_clear_message ();
_rl_free_history_entry (saved_line_for_history);
saved_line_for_history = (HIST_ENTRY *)NULL;
} }
/* Search non-interactively through the history list. DIR < 0 means to /* Search non-interactively through the history list. DIR < 0 means to
@@ -157,11 +179,15 @@ noninc_search (dir, pchar)
int dir; int dir;
int pchar; int pchar;
{ {
int saved_point, c; int saved_point, saved_mark, c;
char *p; char *p;
#if defined (HANDLE_MULTIBYTE)
char mb[MB_LEN_MAX];
#endif
maybe_save_line (); rl_maybe_save_line ();
saved_point = rl_point; saved_point = rl_point;
saved_mark = rl_mark;
/* Use the line buffer to read the search string. */ /* Use the line buffer to read the search string. */
rl_line_buffer[0] = 0; rl_line_buffer[0] = 0;
@@ -171,23 +197,37 @@ noninc_search (dir, pchar)
rl_message (p, 0, 0); rl_message (p, 0, 0);
free (p); free (p);
#define SEARCH_RETURN rl_restore_prompt (); return #define SEARCH_RETURN rl_restore_prompt (); RL_UNSETSTATE(RL_STATE_NSEARCH); return
RL_SETSTATE(RL_STATE_NSEARCH);
/* Read the search string. */ /* Read the search string. */
while ((c = rl_read_key ())) while (1)
{ {
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
c = _rl_read_mbstring (c, mb, MB_LEN_MAX);
#endif
if (c == 0)
break;
switch (c) switch (c)
{ {
case CTRL('H'): case CTRL('H'):
case RUBOUT: case RUBOUT:
if (rl_point == 0) if (rl_point == 0)
{ {
maybe_unsave_line (); rl_maybe_unsave_line ();
rl_clear_message (); rl_clear_message ();
rl_point = saved_point; rl_point = saved_point;
rl_mark = saved_mark;
SEARCH_RETURN; SEARCH_RETURN;
} }
rl_rubout (1, c); _rl_rubout_char (1, c);
break; break;
case CTRL('W'): case CTRL('W'):
@@ -206,20 +246,28 @@ noninc_search (dir, pchar)
case CTRL('C'): case CTRL('C'):
case CTRL('G'): case CTRL('G'):
maybe_unsave_line (); rl_maybe_unsave_line ();
rl_clear_message (); rl_clear_message ();
rl_point = saved_point; rl_point = saved_point;
ding (); rl_mark = saved_mark;
rl_ding ();
SEARCH_RETURN; SEARCH_RETURN;
default: default:
rl_insert (1, c); #if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_insert_text (mb);
else
#endif
_rl_insert_char (1, c);
break; break;
} }
(*rl_redisplay_function) (); (*rl_redisplay_function) ();
} }
dosearch: dosearch:
rl_mark = saved_mark;
/* If rl_point == 0, we want to re-use the previous search string and /* If rl_point == 0, we want to re-use the previous search string and
start from the saved history position. If there's no previous search start from the saved history position. If there's no previous search
string, punt. */ string, punt. */
@@ -227,7 +275,7 @@ noninc_search (dir, pchar)
{ {
if (!noninc_search_string) if (!noninc_search_string)
{ {
ding (); rl_ding ();
SEARCH_RETURN; SEARCH_RETURN;
} }
} }
@@ -235,19 +283,20 @@ noninc_search (dir, pchar)
{ {
/* We want to start the search from the current history position. */ /* We want to start the search from the current history position. */
noninc_history_pos = where_history (); noninc_history_pos = where_history ();
if (noninc_search_string) FREE (noninc_search_string);
free (noninc_search_string);
noninc_search_string = savestring (rl_line_buffer); noninc_search_string = savestring (rl_line_buffer);
} }
rl_restore_prompt (); rl_restore_prompt ();
noninc_dosearch (noninc_search_string, dir); noninc_dosearch (noninc_search_string, dir);
RL_UNSETSTATE(RL_STATE_NSEARCH);
} }
/* Search forward through the history list for a string. If the vi-mode /* Search forward through the history list for a string. If the vi-mode
code calls this, KEY will be `?'. */ code calls this, KEY will be `?'. */
int int
rl_noninc_forward_search (int count __attribute__((unused)), int key) rl_noninc_forward_search (count, key)
int count __attribute__((unused)), key __attribute__((unused));
{ {
noninc_search (1, (key == '?') ? '?' : 0); noninc_search (1, (key == '?') ? '?' : 0);
return 0; return 0;
@@ -256,7 +305,8 @@ rl_noninc_forward_search (int count __attribute__((unused)), int key)
/* Reverse search the history list for a string. If the vi-mode code /* Reverse search the history list for a string. If the vi-mode code
calls this, KEY will be `/'. */ calls this, KEY will be `/'. */
int int
rl_noninc_reverse_search (int count __attribute__((unused)), int key) rl_noninc_reverse_search (count, key)
int count __attribute__((unused)), key __attribute__((unused));
{ {
noninc_search (-1, (key == '/') ? '/' : 0); noninc_search (-1, (key == '/') ? '/' : 0);
return 0; return 0;
@@ -265,12 +315,12 @@ rl_noninc_reverse_search (int count __attribute__((unused)), int key)
/* Search forward through the history list for the last string searched /* Search forward through the history list for the last string searched
for. If there is no saved search string, abort. */ for. If there is no saved search string, abort. */
int int
rl_noninc_forward_search_again (int count __attribute__((unused)), rl_noninc_forward_search_again (count, key)
int key __attribute__((unused))) int count __attribute__((unused)), key __attribute__((unused));
{ {
if (!noninc_search_string) if (!noninc_search_string)
{ {
ding (); rl_ding ();
return (-1); return (-1);
} }
noninc_dosearch (noninc_search_string, 1); noninc_dosearch (noninc_search_string, 1);
@@ -280,12 +330,12 @@ rl_noninc_forward_search_again (int count __attribute__((unused)),
/* Reverse search in the history list for the last string searched /* Reverse search in the history list for the last string searched
for. If there is no saved search string, abort. */ for. If there is no saved search string, abort. */
int int
rl_noninc_reverse_search_again (int count __attribute__((unused)), rl_noninc_reverse_search_again (count, key)
int key __attribute__((unused))) int count __attribute__((unused)), key __attribute__((unused));
{ {
if (!noninc_search_string) if (!noninc_search_string)
{ {
ding (); rl_ding ();
return (-1); return (-1);
} }
noninc_dosearch (noninc_search_string, -1); noninc_dosearch (noninc_search_string, -1);
@@ -293,69 +343,105 @@ rl_noninc_reverse_search_again (int count __attribute__((unused)),
} }
static int static int
rl_history_search_internal (count, direction) rl_history_search_internal (count, dir)
int count, direction; int count, dir;
{ {
HIST_ENTRY *temp, *old_temp; HIST_ENTRY *temp;
int line_len; int ret, oldpos;
maybe_save_line (); rl_maybe_save_line ();
temp = (HIST_ENTRY *)NULL;
temp = old_temp = (HIST_ENTRY *)NULL; /* Search COUNT times through the history for a line whose prefix
matches history_search_string. When this loop finishes, TEMP,
if non-null, is the history line to copy into the line buffer. */
while (count) while (count)
{ {
temp = (direction < 0) ? previous_history () : next_history (); ret = noninc_search_from_pos (history_search_string, rl_history_search_pos + dir, dir);
if (temp == 0) if (ret == -1)
break; break;
/* On an empty prefix, make this the same as previous-history. */
if (rl_point == 0) /* Get the history entry we found. */
{ rl_history_search_pos = ret;
count--; oldpos = where_history ();
continue; history_set_pos (rl_history_search_pos);
} temp = current_history ();
if (STREQN (rl_line_buffer, temp->line, rl_point)) history_set_pos (oldpos);
{
/* Don't find multiple instances of the same line. */ /* Don't find multiple instances of the same line. */
if (prev_line_found && STREQ (prev_line_found, temp->line)) if (prev_line_found && STREQ (prev_line_found, temp->line))
continue; continue;
if (direction < 0) prev_line_found = temp->line;
old_temp = temp; count--;
prev_line_found = temp->line;
count--;
}
} }
/* If we didn't find anything at all, return. */
if (temp == 0) if (temp == 0)
{ {
if (direction < 0 && old_temp) rl_maybe_unsave_line ();
temp = old_temp; rl_ding ();
else /* If you don't want the saved history line (last match) to show up
{ in the line buffer after the search fails, change the #if 0 to
maybe_unsave_line (); #if 1 */
ding (); #if 0
return 1; if (rl_point > rl_history_search_len)
} {
rl_point = rl_end = rl_history_search_len;
rl_line_buffer[rl_end] = '\0';
rl_mark = 0;
}
#else
rl_point = rl_history_search_len; /* rl_maybe_unsave_line changes it */
rl_mark = rl_end;
#endif
return 1;
} }
line_len = strlen (temp->line); /* Copy the line we found into the current line buffer. */
if (line_len >= rl_line_buffer_len) make_history_line_current (temp);
rl_extend_line_buffer (line_len);
strcpy (rl_line_buffer, temp->line); rl_point = rl_history_search_len;
rl_undo_list = (UNDO_LIST *)temp->data; rl_mark = rl_end;
rl_end = line_len;
return 0; return 0;
} }
static void
rl_history_search_reinit ()
{
rl_history_search_pos = where_history ();
rl_history_search_len = rl_point;
prev_line_found = (char *)NULL;
if (rl_point)
{
if (rl_history_search_len >= history_string_size - 2)
{
history_string_size = rl_history_search_len + 2;
history_search_string = (char *)xrealloc (history_search_string, history_string_size);
}
history_search_string[0] = '^';
strncpy (history_search_string + 1, rl_line_buffer, rl_point);
history_search_string[rl_point + 1] = '\0';
}
_rl_free_saved_history_line ();
}
/* Search forward in the history for the string of characters /* Search forward in the history for the string of characters
from the start of the line to rl_point. This is a non-incremental from the start of the line to rl_point. This is a non-incremental
search. */ search. */
int int
rl_history_search_forward (int count, int ignore __attribute__((unused))) rl_history_search_forward (count, ignore)
int count, ignore;
{ {
if (count == 0) if (count == 0)
return (0); return (0);
if (rl_last_func != rl_history_search_forward)
prev_line_found = (char *)NULL; if (rl_last_func != rl_history_search_forward &&
rl_last_func != rl_history_search_backward)
rl_history_search_reinit ();
if (rl_history_search_len == 0)
return (rl_get_next_history (count, ignore));
return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1)); return (rl_history_search_internal (abs (count), (count > 0) ? 1 : -1));
} }
@@ -363,11 +449,17 @@ rl_history_search_forward (int count, int ignore __attribute__((unused)))
from the start of the line to rl_point. This is a non-incremental from the start of the line to rl_point. This is a non-incremental
search. */ search. */
int int
rl_history_search_backward (int count, int ignore __attribute__((unused))) rl_history_search_backward (count, ignore)
int count, ignore;
{ {
if (count == 0) if (count == 0)
return (0); return (0);
if (rl_last_func != rl_history_search_backward)
prev_line_found = (char *)NULL; if (rl_last_func != rl_history_search_forward &&
rl_last_func != rl_history_search_backward)
rl_history_search_reinit ();
if (rl_history_search_len == 0)
return (rl_get_previous_history (count, ignore));
return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1)); return (rl_history_search_internal (abs (count), (count > 0) ? -1 : 1));
} }

View File

@@ -8,7 +8,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -19,14 +19,13 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
# include <config.h> # include <config.h>
#endif #endif
#include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#if defined (HAVE_UNISTD_H) #if defined (HAVE_UNISTD_H)
@@ -39,36 +38,61 @@
# include "ansi_stdlib.h" # include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */ #endif /* HAVE_STDLIB_H */
#if defined (HAVE_STDIO_H)
# include <stdio.h>
#endif /* HAVE_STDIO_H */
#if defined (HAVE_STRING_H) #if defined (HAVE_STRING_H)
# include <string.h> # include <string.h>
#else #else
# include <strings.h> # include <strings.h>
#endif /* !HAVE_STRING_H */ #endif /* !HAVE_STRING_H */
#if defined (HAVE_LIMITS_H)
# include <limits.h>
#endif
#include <fcntl.h>
#include <pwd.h> #include <pwd.h>
#include <stdio.h>
#include "rlstdc.h"
#include "rlshell.h"
#include "xmalloc.h"
#if !defined (HAVE_GETPW_DECLS) #if !defined (HAVE_GETPW_DECLS)
extern struct passwd *getpwuid (); extern struct passwd *getpwuid PARAMS((uid_t));
#endif /* !HAVE_GETPW_DECLS */ #endif /* !HAVE_GETPW_DECLS */
extern char *xmalloc (); #ifndef NULL
# define NULL 0
#endif
#ifndef CHAR_BIT
# define CHAR_BIT 8
#endif
/* Nonzero if the integer type T is signed. */
#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
/* Bound on length of the string representing an integer value of type T.
Subtract one for the sign bit if T is signed;
302 / 1000 is log10 (2) rounded up;
add one for integer division truncation;
add one more for a minus sign if t is signed. */
#define INT_STRLEN_BOUND(t) \
((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 \
+ 1 + TYPE_SIGNED (t))
/* All of these functions are resolved from bash if we are linking readline /* All of these functions are resolved from bash if we are linking readline
as part of bash. */ as part of bash. */
/* Does shell-like quoting using single quotes. */ /* Does shell-like quoting using single quotes. */
char * char *
single_quote (string) sh_single_quote (string)
char *string; char *string;
{ {
register int c; register int c;
char *result, *r, *s; char *result, *r, *s;
result = (char *)xmalloc (3 + (3 * strlen (string))); result = (char *)xmalloc (3 + (4 * strlen (string)));
r = result; r = result;
*r++ = '\''; *r++ = '\'';
@@ -93,24 +117,24 @@ single_quote (string)
/* Set the environment variables LINES and COLUMNS to lines and cols, /* Set the environment variables LINES and COLUMNS to lines and cols,
respectively. */ respectively. */
void void
set_lines_and_columns (lines, cols) sh_set_lines_and_columns (lines, cols)
int lines, cols; int lines, cols;
{ {
char *b; char *b;
#if defined (HAVE_PUTENV) #if defined (HAVE_PUTENV)
b = xmalloc (24); b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
sprintf (b, "LINES=%d", lines); sprintf (b, "LINES=%d", lines);
putenv (b); putenv (b);
b = xmalloc (24); b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1);
sprintf (b, "COLUMNS=%d", cols); sprintf (b, "COLUMNS=%d", cols);
putenv (b); putenv (b);
#else /* !HAVE_PUTENV */ #else /* !HAVE_PUTENV */
# if defined (HAVE_SETENV) # if defined (HAVE_SETENV)
b = xmalloc (8); b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
sprintf (b, "%d", lines); sprintf (b, "%d", lines);
setenv ("LINES", b, 1); setenv ("LINES", b, 1);
b = xmalloc (8); b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
sprintf (b, "%d", cols); sprintf (b, "%d", cols);
setenv ("COLUMNS", b, 1); setenv ("COLUMNS", b, 1);
# endif /* HAVE_SETENV */ # endif /* HAVE_SETENV */
@@ -118,14 +142,14 @@ set_lines_and_columns (lines, cols)
} }
char * char *
get_env_value (varname) sh_get_env_value (varname)
char *varname; const char *varname;
{ {
return ((char *)getenv (varname)); return ((char *)getenv (varname));
} }
char * char *
get_home_dir () sh_get_home_dir ()
{ {
char *home_dir; char *home_dir;
struct passwd *entry; struct passwd *entry;
@@ -136,3 +160,37 @@ get_home_dir ()
home_dir = entry->pw_dir; home_dir = entry->pw_dir;
return (home_dir); return (home_dir);
} }
#if !defined (O_NDELAY)
# if defined (FNDELAY)
# define O_NDELAY FNDELAY
# endif
#endif
int
sh_unset_nodelay_mode (fd)
int fd;
{
int flags, bflags;
if ((flags = fcntl (fd, F_GETFL, 0)) < 0)
return -1;
bflags = 0;
#ifdef O_NONBLOCK
bflags |= O_NONBLOCK;
#endif
#ifdef O_NDELAY
bflags |= O_NDELAY;
#endif
if (flags & bflags)
{
flags &= ~bflags;
return (fcntl (fd, F_SETFL, flags));
}
return 0;
}

View File

@@ -7,7 +7,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -18,7 +18,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
@@ -40,15 +40,13 @@
# include <sys/ioctl.h> # include <sys/ioctl.h>
#endif /* GWINSZ_IN_SYS_IOCTL */ #endif /* GWINSZ_IN_SYS_IOCTL */
#if defined (__GO32__)
# undef HANDLE_SIGNALS
#endif /* __GO32__ */
#if defined (HANDLE_SIGNALS) #if defined (HANDLE_SIGNALS)
/* Some standard library routines. */ /* Some standard library routines. */
#include "readline.h" #include "readline.h"
#include "history.h" #include "history.h"
#include "rlprivate.h"
#if !defined (RETSIGTYPE) #if !defined (RETSIGTYPE)
# if defined (VOID_SIGHANDLER) # if defined (VOID_SIGHANDLER)
# define RETSIGTYPE void # define RETSIGTYPE void
@@ -63,23 +61,20 @@
# define SIGHANDLER_RETURN return (0) # define SIGHANDLER_RETURN return (0)
#endif #endif
/* This typedef is equivalant to the one for Function; it allows us /* This typedef is equivalent to the one for Function; it allows us
to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */ to say SigHandler *foo = signal (SIGKILL, SIG_IGN); */
typedef RETSIGTYPE SigHandler (); typedef RETSIGTYPE SigHandler ();
extern int readline_echoing_p; #if defined (HAVE_POSIX_SIGNALS)
extern int rl_pending_input; typedef struct sigaction sighandler_cxt;
extern int _rl_meta_flag; # define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
#else
typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
# define sigemptyset(m)
#endif /* !HAVE_POSIX_SIGNALS */
extern void free_undo_list (); static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
extern void _rl_get_screen_size (); static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
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 ();
static SigHandler *rl_set_sighandler ();
/* Exported variables for use by applications. */ /* Exported variables for use by applications. */
@@ -101,14 +96,6 @@ static int sigwinch_set_flag;
/* */ /* */
/* **************************************************************** */ /* **************************************************************** */
#if defined (HAVE_POSIX_SIGNALS)
typedef struct sigaction sighandler_cxt;
# define rl_sigaction(s, nh, oh) sigaction(s, nh, oh)
#else
typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt;
# define sigemptyset(m)
#endif /* !HAVE_POSIX_SIGNALS */
static sighandler_cxt old_int, old_term, old_alrm, old_quit; static sighandler_cxt old_int, old_term, old_alrm, old_quit;
#if defined (SIGTSTP) #if defined (SIGTSTP)
static sighandler_cxt old_tstp, old_ttou, old_ttin; static sighandler_cxt old_tstp, old_ttou, old_ttin;
@@ -133,6 +120,8 @@ rl_signal_handler (sig)
# endif /* !HAVE_BSD_SIGNALS */ # endif /* !HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */ #endif /* !HAVE_POSIX_SIGNALS */
RL_SETSTATE(RL_STATE_SIGHANDLER);
#if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS) #if !defined (HAVE_BSD_SIGNALS) && !defined (HAVE_POSIX_SIGNALS)
/* Since the signal will not be blocked while we are in the signal /* Since the signal will not be blocked while we are in the signal
handler, ignore it until rl_clear_signals resets the catcher. */ handler, ignore it until rl_clear_signals resets the catcher. */
@@ -165,6 +154,10 @@ rl_signal_handler (sig)
# endif /* HAVE_BSD_SIGNALS */ # endif /* HAVE_BSD_SIGNALS */
#endif /* !HAVE_POSIX_SIGNALS */ #endif /* !HAVE_POSIX_SIGNALS */
#if defined (__EMX__)
signal (sig, SIG_ACK);
#endif
kill (getpid (), sig); kill (getpid (), sig);
/* Let the signal that we just sent through. */ /* Let the signal that we just sent through. */
@@ -179,6 +172,7 @@ rl_signal_handler (sig)
rl_reset_after_signal (); rl_reset_after_signal ();
} }
RL_UNSETSTATE(RL_STATE_SIGHANDLER);
SIGHANDLER_RETURN; SIGHANDLER_RETURN;
} }
@@ -199,6 +193,7 @@ rl_sigwinch_handler (sig)
rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch); rl_set_sighandler (SIGWINCH, rl_sigwinch_handler, &dummy_winch);
#endif #endif
RL_SETSTATE(RL_STATE_SIGHANDLER);
rl_resize_terminal (); rl_resize_terminal ();
/* If another sigwinch handler has been installed, call it. */ /* If another sigwinch handler has been installed, call it. */
@@ -206,6 +201,7 @@ rl_sigwinch_handler (sig)
if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL) if (oh && oh != (SigHandler *)SIG_IGN && oh != (SigHandler *)SIG_DFL)
(*oh) (sig); (*oh) (sig);
RL_UNSETSTATE(RL_STATE_SIGHANDLER);
SIGHANDLER_RETURN; SIGHANDLER_RETURN;
} }
#endif /* SIGWINCH */ #endif /* SIGWINCH */
@@ -232,17 +228,25 @@ rl_set_sighandler (sig, handler, ohandler)
SigHandler *handler; SigHandler *handler;
sighandler_cxt *ohandler; sighandler_cxt *ohandler;
{ {
sighandler_cxt old_handler;
#if defined (HAVE_POSIX_SIGNALS) #if defined (HAVE_POSIX_SIGNALS)
struct sigaction act; struct sigaction act;
act.sa_handler = handler; act.sa_handler = handler;
act.sa_flags = 0; act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */
sigemptyset (&act.sa_mask); sigemptyset (&act.sa_mask);
sigemptyset (&ohandler->sa_mask); sigemptyset (&ohandler->sa_mask);
sigaction (sig, &act, ohandler); sigaction (sig, &act, &old_handler);
#else #else
ohandler->sa_handler = (SigHandler *)signal (sig, handler); old_handler.sa_handler = (SigHandler *)signal (sig, handler);
#endif /* !HAVE_POSIX_SIGNALS */ #endif /* !HAVE_POSIX_SIGNALS */
/* XXX -- assume we have memcpy */
/* If rl_set_signals is called twice in a row, don't set the old handler to
rl_signal_handler, because that would cause infinite recursion. */
if (handler != rl_signal_handler || old_handler.sa_handler != rl_signal_handler)
memcpy (ohandler, &old_handler, sizeof (sighandler_cxt));
return (ohandler->sa_handler); return (ohandler->sa_handler);
} }
@@ -360,7 +364,7 @@ rl_cleanup_after_signal ()
_rl_clean_up_for_exit (); _rl_clean_up_for_exit ();
(*rl_deprep_term_function) (); (*rl_deprep_term_function) ();
rl_clear_signals (); rl_clear_signals ();
rl_pending_input = 0; rl_clear_pending_input ();
} }
/* Reset the terminal and readline state after a signal handler returns. */ /* Reset the terminal and readline state after a signal handler returns. */
@@ -380,7 +384,7 @@ rl_free_line_state ()
{ {
register HIST_ENTRY *entry; register HIST_ENTRY *entry;
free_undo_list (); rl_free_undo_list ();
entry = current_history (); entry = current_history ();
if (entry) if (entry)

View File

@@ -8,7 +8,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -19,7 +19,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_RLTCAP_H_) #if !defined (_RLTCAP_H_)
#define _RLTCAP_H_ #define _RLTCAP_H_

View File

@@ -7,7 +7,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -18,7 +18,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
@@ -46,9 +46,7 @@
# include <locale.h> # include <locale.h>
#endif #endif
#include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <setjmp.h>
/* System-specific feature definitions and include files. */ /* System-specific feature definitions and include files. */
#include "rldefs.h" #include "rldefs.h"
@@ -64,18 +62,12 @@
#include "readline.h" #include "readline.h"
#include "history.h" #include "history.h"
/* Variables and functions imported from readline.c */ #include "rlprivate.h"
extern FILE *_rl_in_stream, *_rl_out_stream; #include "rlshell.h"
extern int readline_echoing_p; #include "xmalloc.h"
extern int _rl_bell_preference;
extern Keymap _rl_keymap;
/* Functions imported from bind.c */ #define CUSTOM_REDISPLAY_FUNC() (rl_redisplay_function != rl_redisplay)
extern void _rl_bind_if_unbound (); #define CUSTOM_INPUT_FUNC() (rl_getc_function != rl_getc)
/* Functions imported from shell.c */
extern void set_lines_and_columns ();
extern char *get_env_value ();
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
@@ -88,9 +80,6 @@ static char *term_string_buffer = (char *)NULL;
static int tcap_initialized; static int tcap_initialized;
/* Non-zero means this terminal can't really do anything. */
static int dumb_term;
#if !defined (__linux__) #if !defined (__linux__)
# if defined (__EMX__) || defined (NEED_EXTERN_PC) # if defined (__EMX__) || defined (NEED_EXTERN_PC)
extern extern
@@ -99,27 +88,36 @@ char PC, *BC, *UP;
#endif /* __linux__ */ #endif /* __linux__ */
/* Some strings to control terminal actions. These are output by tputs (). */ /* Some strings to control terminal actions. These are output by tputs (). */
char *term_goto, *term_clreol, *term_clrpag, *term_backspace; char *_rl_term_clreol;
char *term_cr, *term_pc; char *_rl_term_clrpag;
char *_rl_term_cr;
char *_rl_term_backspace;
char *_rl_term_goto;
char *_rl_term_pc;
/* Non-zero if we determine that the terminal can do character insertion. */ /* Non-zero if we determine that the terminal can do character insertion. */
int terminal_can_insert = 0; int _rl_terminal_can_insert = 0;
/* How to insert characters. */ /* How to insert characters. */
char *term_im, *term_ei, *term_ic, *term_ip, *term_IC; char *_rl_term_im;
char *_rl_term_ei;
char *_rl_term_ic;
char *_rl_term_ip;
char *_rl_term_IC;
/* How to delete characters. */ /* How to delete characters. */
char *term_dc, *term_DC; char *_rl_term_dc;
char *_rl_term_DC;
#if defined (HACK_TERMCAP_MOTION) #if defined (HACK_TERMCAP_MOTION)
char *term_forward_char; char *_rl_term_forward_char;
#endif /* HACK_TERMCAP_MOTION */ #endif /* HACK_TERMCAP_MOTION */
/* How to go up a line. */ /* How to go up a line. */
char *term_up; char *_rl_term_up;
/* A visible bell, if the terminal can be made to flash the screen. */ /* A visible bell; char if the terminal can be made to flash the screen. */
static char *visible_bell; static char *_rl_visible_bell;
/* Non-zero means the terminal can auto-wrap lines. */ /* Non-zero means the terminal can auto-wrap lines. */
int _rl_term_autowrap; int _rl_term_autowrap;
@@ -128,20 +126,36 @@ int _rl_term_autowrap;
static int term_has_meta; static int term_has_meta;
/* The sequences to write to turn on and off the meta key, if this /* The sequences to write to turn on and off the meta key, if this
terminal has one. */ terminal has one. */
static char *term_mm, *term_mo; static char *_rl_term_mm;
static char *_rl_term_mo;
/* The key sequences output by the arrow keys, if this terminal has any. */ /* The key sequences output by the arrow keys, if this terminal has any. */
static char *term_ku, *term_kd, *term_kr, *term_kl; static char *_rl_term_ku;
static char *_rl_term_kd;
static char *_rl_term_kr;
static char *_rl_term_kl;
/* How to initialize and reset the arrow keys, if this terminal has any. */ /* How to initialize and reset the arrow keys, if this terminal has any. */
static char *term_ks, *term_ke; static char *_rl_term_ks;
static char *_rl_term_ke;
/* The key sequences sent by the Home and End keys, if any. */ /* The key sequences sent by the Home and End keys, if any. */
static char *term_kh, *term_kH; static char *_rl_term_kh;
static char *_rl_term_kH;
static char *_rl_term_at7; /* @7 */
/* Insert key */
static char *_rl_term_kI;
/* Cursor control */
static char *_rl_term_vs; /* very visible */
static char *_rl_term_ve; /* normal */
static void bind_termcap_arrow_keys PARAMS((Keymap));
/* Variables that hold the screen dimensions, used by the display code. */ /* Variables that hold the screen dimensions, used by the display code. */
int screenwidth, screenheight, screenchars; int _rl_screenwidth, _rl_screenheight, _rl_screenchars;
/* Non-zero means the user wants to enable the keypad. */ /* Non-zero means the user wants to enable the keypad. */
int _rl_enable_keypad; int _rl_enable_keypad;
@@ -149,6 +163,22 @@ int _rl_enable_keypad;
/* Non-zero means the user wants to enable a meta key. */ /* Non-zero means the user wants to enable a meta key. */
int _rl_enable_meta = 1; int _rl_enable_meta = 1;
#if defined (__EMX__)
static void
_emx_get_screensize (swp, shp)
int *swp, *shp;
{
int sz[2];
_scrsize (sz);
if (swp)
*swp = sz[0];
if (shp)
*shp = sz[1];
}
#endif
/* Get readline's idea of the screen size. TTY is a file descriptor open /* 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 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 values of $LINES and $COLUMNS. The tests for TERM_STRING_BUFFER being
@@ -161,124 +191,148 @@ _rl_get_screen_size (tty, ignore_env)
#if defined (TIOCGWINSZ) #if defined (TIOCGWINSZ)
struct winsize window_size; struct winsize window_size;
#endif /* TIOCGWINSZ */ #endif /* TIOCGWINSZ */
#if defined (__EMX__)
int sz[2];
#endif
#if defined (TIOCGWINSZ) #if defined (TIOCGWINSZ)
if (ioctl (tty, TIOCGWINSZ, &window_size) == 0) if (ioctl (tty, TIOCGWINSZ, &window_size) == 0)
{ {
screenwidth = (int) window_size.ws_col; _rl_screenwidth = (int) window_size.ws_col;
screenheight = (int) window_size.ws_row; _rl_screenheight = (int) window_size.ws_row;
} }
#endif /* TIOCGWINSZ */ #endif /* TIOCGWINSZ */
#if defined (__EMX__) #if defined (__EMX__)
_scrsize (sz); _emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
screenwidth = sz[0];
screenheight = sz[1];
#endif #endif
/* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV /* Environment variable COLUMNS overrides setting of "co" if IGNORE_ENV
is unset. */ is unset. */
if (screenwidth <= 0) if (_rl_screenwidth <= 0)
{ {
if (ignore_env == 0 && (ss = get_env_value ("COLUMNS"))) if (ignore_env == 0 && (ss = sh_get_env_value ("COLUMNS")))
screenwidth = atoi (ss); _rl_screenwidth = atoi (ss);
if (screenwidth <= 0 && term_string_buffer) #if !defined (__DJGPP__)
screenwidth = tgetnum ("co"); if (_rl_screenwidth <= 0 && term_string_buffer)
_rl_screenwidth = tgetnum ("co");
#endif
} }
/* Environment variable LINES overrides setting of "li" if IGNORE_ENV /* Environment variable LINES overrides setting of "li" if IGNORE_ENV
is unset. */ is unset. */
if (screenheight <= 0) if (_rl_screenheight <= 0)
{ {
if (ignore_env == 0 && (ss = get_env_value ("LINES"))) if (ignore_env == 0 && (ss = sh_get_env_value ("LINES")))
screenheight = atoi (ss); _rl_screenheight = atoi (ss);
if (screenheight <= 0 && term_string_buffer) #if !defined (__DJGPP__)
screenheight = tgetnum ("li"); if (_rl_screenheight <= 0 && term_string_buffer)
_rl_screenheight = tgetnum ("li");
#endif
} }
/* If all else fails, default to 80x24 terminal. */ /* If all else fails, default to 80x24 terminal. */
if (screenwidth <= 1) if (_rl_screenwidth <= 1)
screenwidth = 80; _rl_screenwidth = 80;
if (screenheight <= 0) if (_rl_screenheight <= 0)
screenheight = 24; _rl_screenheight = 24;
/* If we're being compiled as part of bash, set the environment /* If we're being compiled as part of bash, set the environment
variables $LINES and $COLUMNS to new values. Otherwise, just variables $LINES and $COLUMNS to new values. Otherwise, just
do a pair of putenv () or setenv () calls. */ do a pair of putenv () or setenv () calls. */
set_lines_and_columns (screenheight, screenwidth); sh_set_lines_and_columns (_rl_screenheight, _rl_screenwidth);
if (!_rl_term_autowrap) if (_rl_term_autowrap == 0)
screenwidth--; _rl_screenwidth--;
screenchars = screenwidth * screenheight; _rl_screenchars = _rl_screenwidth * _rl_screenheight;
} }
void void
_rl_set_screen_size (rows, cols) _rl_set_screen_size (rows, cols)
int rows, cols; int rows, cols;
{ {
screenheight = rows; if (rows == 0 || cols == 0)
screenwidth = cols; return;
_rl_screenheight = rows;
_rl_screenwidth = cols;
if (_rl_term_autowrap == 0) if (_rl_term_autowrap == 0)
screenwidth--; _rl_screenwidth--;
screenchars = screenwidth * screenheight; _rl_screenchars = _rl_screenwidth * _rl_screenheight;
} }
extern void _rl_redisplay_after_sigwinch(); void
rl_set_screen_size (rows, cols)
int rows, cols;
{
_rl_set_screen_size (rows, cols);
}
void
rl_get_screen_size (rows, cols)
int *rows, *cols;
{
if (rows)
*rows = _rl_screenheight;
if (cols)
*cols = _rl_screenwidth;
}
void void
rl_resize_terminal () rl_resize_terminal ()
{ {
if (readline_echoing_p) if (readline_echoing_p)
{ {
_rl_get_screen_size (fileno (rl_instream), 1); _rl_get_screen_size (fileno (rl_instream), 1);
_rl_redisplay_after_sigwinch (); if (CUSTOM_REDISPLAY_FUNC ())
rl_forced_update_display ();
else
_rl_redisplay_after_sigwinch ();
} }
} }
struct _tc_string { struct _tc_string {
const char *tc_var; const char *tc_var;
char **tc_value; char **tc_value;
}; };
/* This should be kept sorted, just in case we decide to change the /* This should be kept sorted, just in case we decide to change the
search algorithm to something smarter. */ search algorithm to something smarter. */
static struct _tc_string tc_strings[] = static struct _tc_string tc_strings[] =
{ {
{"DC", &term_DC}, { "@7", &_rl_term_at7 },
{"IC", &term_IC}, { "DC", &_rl_term_DC },
{"ce", &term_clreol}, { "IC", &_rl_term_IC },
{"cl", &term_clrpag}, { "ce", &_rl_term_clreol },
{"cr", &term_cr}, { "cl", &_rl_term_clrpag },
{"dc", &term_dc}, { "cr", &_rl_term_cr },
{"ei", &term_ei}, { "dc", &_rl_term_dc },
{"ic", &term_ic}, { "ei", &_rl_term_ei },
{"im", &term_im}, { "ic", &_rl_term_ic },
{"kd", &term_kd}, { "im", &_rl_term_im },
{"kh", &term_kh}, /* home */ { "kH", &_rl_term_kH }, /* home down ?? */
{"kH", &term_kH}, /* end */ { "kI", &_rl_term_kI }, /* insert */
{"kl", &term_kl}, { "kd", &_rl_term_kd },
{"kr", &term_kr}, { "ke", &_rl_term_ke }, /* end keypad mode */
{"ku", &term_ku}, { "kh", &_rl_term_kh }, /* home */
{"ks", &term_ks}, { "kl", &_rl_term_kl },
{"ke", &term_ke}, { "kr", &_rl_term_kr },
{"le", &term_backspace}, { "ks", &_rl_term_ks }, /* start keypad mode */
{"mm", &term_mm}, { "ku", &_rl_term_ku },
{"mo", &term_mo}, { "le", &_rl_term_backspace },
{ "mm", &_rl_term_mm },
{ "mo", &_rl_term_mo },
#if defined (HACK_TERMCAP_MOTION) #if defined (HACK_TERMCAP_MOTION)
{"nd", &term_forward_char}, { "nd", &_rl_term_forward_char },
#endif #endif
{"pc", &term_pc}, { "pc", &_rl_term_pc },
{"up", &term_up}, { "up", &_rl_term_up },
{"vb", &visible_bell}, { "vb", &_rl_visible_bell },
{ "vs", &_rl_term_vs },
{ "ve", &_rl_term_ve },
}; };
#define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string)) #define NUM_TC_STRINGS (sizeof (tc_strings) / sizeof (struct _tc_string))
@@ -289,73 +343,99 @@ static void
get_term_capabilities (bp) get_term_capabilities (bp)
char **bp; char **bp;
{ {
register int i; #if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */
register unsigned int i;
for (i = 0; i < (int) NUM_TC_STRINGS; i++) for (i = 0; i < NUM_TC_STRINGS; i++)
# ifdef __LCC__
*(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
# else
*(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp); *(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
# endif
#endif
tcap_initialized = 1; tcap_initialized = 1;
} }
int int
_rl_init_terminal_io (terminal_name) _rl_init_terminal_io (terminal_name)
char *terminal_name; const char *terminal_name;
{ {
#if defined (__GO32__)
screenwidth = ScreenCols ();
screenheight = ScreenRows ();
screenchars = screenwidth * screenheight;
term_cr = (char*) "\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__ */
const char *term; const char *term;
char *buffer; char *buffer;
int tty; int tty, tgetent_ret;
Keymap xkeymap;
term = terminal_name ? terminal_name : get_env_value ("TERM"); term = terminal_name ? terminal_name : sh_get_env_value ("TERM");
_rl_term_clrpag = _rl_term_cr = _rl_term_clreol = (char *)NULL;
if (term_string_buffer == 0) tty = rl_instream ? fileno (rl_instream) : 0;
term_string_buffer = xmalloc (2032); _rl_screenwidth = _rl_screenheight = 0;
if (term_buffer == 0)
term_buffer = xmalloc (4080);
buffer = term_string_buffer;
term_clrpag = term_cr = term_clreol = (char *)NULL;
if (term == 0) if (term == 0)
term = "dumb"; term = "dumb";
if (tgetent (term_buffer, term) <= 0) /* I've separated this out for later work on not calling tgetent at all
if the calling application has supplied a custom redisplay function,
(and possibly if the application has supplied a custom input function). */
if (CUSTOM_REDISPLAY_FUNC())
{ {
dumb_term = 1; tgetent_ret = -1;
screenwidth = 79; }
screenheight = 24; else
screenchars = 79 * 24; {
term_cr = (char*) "\r"; if (term_string_buffer == 0)
term_im = term_ei = term_ic = term_IC = (char *)NULL; term_string_buffer = (char *)xmalloc(2032);
term_up = term_dc = term_DC = visible_bell = (char *)NULL;
term_ku = term_kd = term_kl = term_kr = (char *)NULL; if (term_buffer == 0)
term_buffer = (char *)xmalloc(4080);
buffer = term_string_buffer;
tgetent_ret = tgetent (term_buffer, term);
}
if (tgetent_ret <= 0)
{
FREE (term_string_buffer);
FREE (term_buffer);
buffer = term_buffer = term_string_buffer = (char *)NULL;
_rl_term_autowrap = 0; /* used by _rl_get_screen_size */
#if defined (__EMX__)
_emx_get_screensize (&_rl_screenwidth, &_rl_screenheight);
_rl_screenwidth--;
#else /* !__EMX__ */
_rl_get_screen_size (tty, 0);
#endif /* !__EMX__ */
/* Defaults. */
if (_rl_screenwidth <= 0 || _rl_screenheight <= 0)
{
_rl_screenwidth = 79;
_rl_screenheight = 24;
}
/* Everything below here is used by the redisplay code (tputs). */
_rl_screenchars = _rl_screenwidth * _rl_screenheight;
_rl_term_cr = (char*)"\r";
_rl_term_im = _rl_term_ei = _rl_term_ic = _rl_term_IC = (char *)NULL;
_rl_term_up = _rl_term_dc = _rl_term_DC = _rl_visible_bell = (char *)NULL;
_rl_term_ku = _rl_term_kd = _rl_term_kl = _rl_term_kr = (char *)NULL;
_rl_term_kh = _rl_term_kH = _rl_term_kI = (char *)NULL;
_rl_term_ks = _rl_term_ke = _rl_term_at7 = (char *)NULL;
_rl_term_mm = _rl_term_mo = (char *)NULL;
_rl_term_ve = _rl_term_vs = (char *)NULL;
#if defined (HACK_TERMCAP_MOTION) #if defined (HACK_TERMCAP_MOTION)
term_forward_char = (char *)NULL; term_forward_char = (char *)NULL;
#endif #endif
terminal_can_insert = 0; _rl_terminal_can_insert = term_has_meta = 0;
/* Reasonable defaults for tgoto(). Readline currently only uses
tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
change that later... */
PC = '\0';
BC = _rl_term_backspace = (char*)"\b";
UP = _rl_term_up;
return 0; return 0;
} }
@@ -363,16 +443,12 @@ _rl_init_terminal_io (terminal_name)
/* Set up the variables that the termcap library expects the application /* Set up the variables that the termcap library expects the application
to provide. */ to provide. */
PC = term_pc ? *term_pc : 0; PC = _rl_term_pc ? *_rl_term_pc : 0;
BC = term_backspace; BC = _rl_term_backspace;
UP = term_up; UP = _rl_term_up;
if (!term_cr) if (!_rl_term_cr)
term_cr = (char*) "\r"; _rl_term_cr = (char*)"\r";
tty = rl_instream ? fileno (rl_instream) : 0;
screenwidth = screenheight = 0;
_rl_term_autowrap = tgetflag ("am") && tgetflag ("xn"); _rl_term_autowrap = tgetflag ("am") && tgetflag ("xn");
@@ -382,53 +458,57 @@ _rl_init_terminal_io (terminal_name)
character insertion if *any one of* the capabilities `IC', character insertion if *any one of* the capabilities `IC',
`im', `ic' or `ip' is provided." But we can't do anything if `im', `ic' or `ip' is provided." But we can't do anything if
only `ip' is provided, so... */ only `ip' is provided, so... */
terminal_can_insert = (term_IC || term_im || term_ic); _rl_terminal_can_insert = (_rl_term_IC || _rl_term_im || _rl_term_ic);
/* Check to see if this terminal has a meta key and clear the capability /* Check to see if this terminal has a meta key and clear the capability
variables if there is none. */ variables if there is none. */
term_has_meta = (tgetflag ("km") || tgetflag ("MT")); term_has_meta = (tgetflag ("km") || tgetflag ("MT"));
if (!term_has_meta) if (!term_has_meta)
term_mm = term_mo = (char *)NULL; _rl_term_mm = _rl_term_mo = (char *)NULL;
/* Attempt to find and bind the arrow keys. Do not override already /* Attempt to find and bind the arrow keys. Do not override already
bound keys in an overzealous attempt, however. */ bound keys in an overzealous attempt, however. */
xkeymap = _rl_keymap;
_rl_keymap = emacs_standard_keymap; bind_termcap_arrow_keys (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) #if defined (VI_MODE)
_rl_keymap = vi_movement_keymap; bind_termcap_arrow_keys (vi_movement_keymap);
_rl_bind_if_unbound (term_ku, rl_get_previous_history); bind_termcap_arrow_keys (vi_insertion_keymap);
_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 */ #endif /* VI_MODE */
_rl_keymap = xkeymap;
#endif /* !__GO32__ */
return 0; return 0;
} }
/* Bind the arrow key sequences from the termcap description in MAP. */
static void
bind_termcap_arrow_keys (map)
Keymap map;
{
Keymap xkeymap;
xkeymap = _rl_keymap;
_rl_keymap = map;
_rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
_rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
_rl_bind_if_unbound (_rl_term_kr, rl_forward);
_rl_bind_if_unbound (_rl_term_kl, rl_backward);
_rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
_rl_bind_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
_rl_keymap = xkeymap;
}
char * char *
rl_get_termcap (cap) rl_get_termcap (cap)
char *cap; const char *cap;
{ {
register int i; register unsigned int i;
if (tcap_initialized == 0) if (tcap_initialized == 0)
return ((char *)NULL); return ((char *)NULL);
for (i = 0; i < (int) NUM_TC_STRINGS; i++) 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) if (tc_strings[i].tc_var[0] == cap[0] && strcmp (tc_strings[i].tc_var, cap) == 0)
return *(tc_strings[i].tc_value); return *(tc_strings[i].tc_value);
@@ -440,7 +520,7 @@ rl_get_termcap (cap)
has changed. */ has changed. */
int int
rl_reset_terminal (terminal_name) rl_reset_terminal (terminal_name)
char *terminal_name; const char *terminal_name;
{ {
_rl_init_terminal_io (terminal_name); _rl_init_terminal_io (terminal_name);
return 0; return 0;
@@ -462,10 +542,11 @@ _rl_output_character_function (c)
return putc (c, _rl_out_stream); return putc (c, _rl_out_stream);
} }
#endif /* !_MINIX */ #endif /* !_MINIX */
/* Write COUNT characters from STRING to the output stream. */ /* Write COUNT characters from STRING to the output stream. */
void void
_rl_output_some_chars (string, count) _rl_output_some_chars (string, count)
char *string; const char *string;
int count; int count;
{ {
fwrite (string, 1, count, _rl_out_stream); fwrite (string, 1, count, _rl_out_stream);
@@ -478,12 +559,10 @@ _rl_backspace (count)
{ {
register int i; register int i;
#if !defined (__GO32__) if (_rl_term_backspace)
if (term_backspace)
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
tputs (term_backspace, 1, _rl_output_character_function); tputs (_rl_term_backspace, 1, _rl_output_character_function);
else else
#endif /* !__GO32__ */
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
putc ('\b', _rl_out_stream); putc ('\b', _rl_out_stream);
return 0; return 0;
@@ -491,11 +570,11 @@ _rl_backspace (count)
/* Move to the start of the next line. */ /* Move to the start of the next line. */
int int
crlf () rl_crlf ()
{ {
#if defined (NEW_TTY_DRIVER) #if defined (NEW_TTY_DRIVER)
if (term_cr) if (_rl_term_cr)
tputs (term_cr, 1, _rl_output_character_function); tputs (_rl_term_cr, 1, _rl_output_character_function);
#endif /* NEW_TTY_DRIVER */ #endif /* NEW_TTY_DRIVER */
putc ('\n', _rl_out_stream); putc ('\n', _rl_out_stream);
return 0; return 0;
@@ -503,20 +582,19 @@ crlf ()
/* Ring the terminal bell. */ /* Ring the terminal bell. */
int int
ding () rl_ding ()
{ {
if (readline_echoing_p) if (readline_echoing_p)
{ {
#if !defined (__GO32__)
switch (_rl_bell_preference) switch (_rl_bell_preference)
{ {
case NO_BELL: case NO_BELL:
default: default:
break; break;
case VISIBLE_BELL: case VISIBLE_BELL:
if (visible_bell) if (_rl_visible_bell)
{ {
tputs (visible_bell, 1, _rl_output_character_function); tputs (_rl_visible_bell, 1, _rl_output_character_function);
break; break;
} }
/* FALLTHROUGH */ /* FALLTHROUGH */
@@ -525,10 +603,6 @@ ding ()
fflush (stderr); fflush (stderr);
break; break;
} }
#else /* __GO32__ */
fprintf (stderr, "\007");
fflush (stderr);
#endif /* __GO32__ */
return (0); return (0);
} }
return (-1); return (-1);
@@ -543,16 +617,46 @@ ding ()
void void
_rl_enable_meta_key () _rl_enable_meta_key ()
{ {
if (term_has_meta && term_mm) #if !defined (__DJGPP__)
tputs (term_mm, 1, _rl_output_character_function); if (term_has_meta && _rl_term_mm)
tputs (_rl_term_mm, 1, _rl_output_character_function);
#endif
} }
void void
_rl_control_keypad (on) _rl_control_keypad (on)
int on; int on;
{ {
if (on && term_ks) #if !defined (__DJGPP__)
tputs (term_ks, 1, _rl_output_character_function); if (on && _rl_term_ks)
else if (!on && term_ke) tputs (_rl_term_ks, 1, _rl_output_character_function);
tputs (term_ke, 1, _rl_output_character_function); else if (!on && _rl_term_ke)
tputs (_rl_term_ke, 1, _rl_output_character_function);
#endif
}
/* **************************************************************** */
/* */
/* Controlling the Cursor */
/* */
/* **************************************************************** */
/* Set the cursor appropriately depending on IM, which is one of the
insert modes (insert or overwrite). Insert mode gets the normal
cursor. Overwrite mode gets a very visible cursor. Only does
anything if we have both capabilities. */
void
_rl_set_cursor (im, force)
int im, force;
{
if (_rl_term_ve && _rl_term_vs)
{
if (force || im != rl_insert_mode)
{
if (im == RL_IM_OVERWRITE)
tputs (_rl_term_vs, 1, _rl_output_character_function);
else
tputs (_rl_term_ve, 1, _rl_output_character_function);
}
}
} }

1540
readline/text.c Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -7,7 +7,7 @@
Readline is free software; you can redistribute it and/or modify it 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 under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 1, or (at your option) any Free Software Foundation; either version 2, or (at your option) any
later version. later version.
Readline is distributed in the hope that it will be useful, but Readline is distributed in the hope that it will be useful, but
@@ -17,7 +17,7 @@
You should have received a copy of the GNU General Public License 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 along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
# include <config.h> # include <config.h>
@@ -47,16 +47,19 @@
#include "tilde.h" #include "tilde.h"
#if defined (TEST) || defined (STATIC_MALLOC)
static void *xmalloc (), *xrealloc ();
#else
# include "xmalloc.h"
#endif /* TEST || STATIC_MALLOC */
#if !defined (HAVE_GETPW_DECLS) #if !defined (HAVE_GETPW_DECLS)
extern struct passwd *getpwuid (), *getpwnam (); extern struct passwd *getpwuid PARAMS((uid_t));
extern struct passwd *getpwnam PARAMS((const char *));
#endif /* !HAVE_GETPW_DECLS */ #endif /* !HAVE_GETPW_DECLS */
#if !defined (savestring) #if !defined (savestring)
extern char *xmalloc (); #define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x))
# ifndef strcpy
extern char *strcpy ();
# endif
#define savestring(x) strcpy (xmalloc (1 + strlen (x)), (x))
#endif /* !savestring */ #endif /* !savestring */
#if !defined (NULL) #if !defined (NULL)
@@ -67,62 +70,63 @@ extern char *strcpy ();
# endif /* !__STDC__ */ # endif /* !__STDC__ */
#endif /* !NULL */ #endif /* !NULL */
#if defined (TEST) || defined (STATIC_MALLOC)
static char *xmalloc (), *xrealloc ();
#else
extern char *xmalloc (), *xrealloc ();
#endif /* TEST || STATIC_MALLOC */
/* If being compiled as part of bash, these will be satisfied from /* If being compiled as part of bash, these will be satisfied from
variables.o. If being compiled as part of readline, they will variables.o. If being compiled as part of readline, they will
be satisfied from shell.o. */ be satisfied from shell.o. */
extern char *get_home_dir (); extern char *sh_get_home_dir PARAMS((void));
extern char *get_env_value (); extern char *sh_get_env_value PARAMS((const char *));
/* The default value of tilde_additional_prefixes. This is set to /* The default value of tilde_additional_prefixes. This is set to
whitespace preceding a tilde so that simple programs which do not whitespace preceding a tilde so that simple programs which do not
perform any word separation get desired behaviour. */ perform any word separation get desired behaviour. */
static const char *default_prefixes[] = static const char *default_prefixes[] =
{ " ~", "\t~", (char *)NULL }; { " ~", "\t~", (const char *)NULL };
/* The default value of tilde_additional_suffixes. This is set to /* The default value of tilde_additional_suffixes. This is set to
whitespace or newline so that simple programs which do not whitespace or newline so that simple programs which do not
perform any word separation get desired behaviour. */ perform any word separation get desired behaviour. */
static const char *default_suffixes[] = static const char *default_suffixes[] =
{ " ", "\n", (char *)NULL }; { " ", "\n", (const char *)NULL };
/* If non-null, this contains the address of a function that the application /* If non-null, this contains the address of a function that the application
wants called before trying the standard tilde expansions. The function wants called before trying the standard tilde expansions. The function
is called with the text sans tilde, and returns a malloc()'ed string is called with the text sans tilde, and returns a malloc()'ed string
which is the expansion, or a NULL pointer if the expansion fails. */ which is the expansion, or a NULL pointer if the expansion fails. */
CPFunction *tilde_expansion_preexpansion_hook = (CPFunction *)NULL; tilde_hook_func_t *tilde_expansion_preexpansion_hook = (tilde_hook_func_t *)NULL;
/* If non-null, this contains the address of a function to call if the /* If non-null, this contains the address of a function to call if the
standard meaning for expanding a tilde fails. The function is called standard meaning for expanding a tilde fails. The function is called
with the text (sans tilde, as in "foo"), and returns a malloc()'ed string with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
which is the expansion, or a NULL pointer if there is no expansion. */ which is the expansion, or a NULL pointer if there is no expansion. */
CPFunction *tilde_expansion_failure_hook = (CPFunction *)NULL; tilde_hook_func_t *tilde_expansion_failure_hook = (tilde_hook_func_t *)NULL;
/* When non-null, this is a NULL terminated array of strings which /* When non-null, this is a NULL terminated array of strings which
are duplicates for a tilde prefix. Bash uses this to expand are duplicates for a tilde prefix. Bash uses this to expand
`=~' and `:~'. */ `=~' and `:~'. */
const char ** tilde_additional_prefixes = default_prefixes; char **tilde_additional_prefixes = (char **)default_prefixes;
/* When non-null, this is a NULL terminated array of strings which match /* When non-null, this is a NULL terminated array of strings which match
the end of a username, instead of just "/". Bash sets this to the end of a username, instead of just "/". Bash sets this to
`:' and `=~'. */ `:' and `=~'. */
const char **tilde_additional_suffixes = default_suffixes; char **tilde_additional_suffixes = (char **)default_suffixes;
static int tilde_find_prefix PARAMS((const char *, int *));
static int tilde_find_suffix PARAMS((const char *));
static char *isolate_tilde_prefix PARAMS((const char *, int *));
static char *glue_prefix_and_suffix PARAMS((char *, const char *, int));
/* Find the start of a tilde expansion in STRING, and return the index of /* Find the start of a tilde expansion in STRING, and return the index of
the tilde which starts the expansion. Place the length of the text the tilde which starts the expansion. Place the length of the text
which identified this tilde starter in LEN, excluding the tilde itself. */ which identified this tilde starter in LEN, excluding the tilde itself. */
static int static int
tilde_find_prefix (string, len) tilde_find_prefix (string, len)
char *string; const char *string;
int *len; int *len;
{ {
register int i, j, string_len; register int i, j, string_len;
register const char **prefixes = tilde_additional_prefixes; register char **prefixes;
prefixes = tilde_additional_prefixes;
string_len = strlen (string); string_len = strlen (string);
*len = 0; *len = 0;
@@ -151,17 +155,21 @@ tilde_find_prefix (string, len)
the character which ends the tilde definition. */ the character which ends the tilde definition. */
static int static int
tilde_find_suffix (string) tilde_find_suffix (string)
char *string; const char *string;
{ {
register int i, j, string_len; register int i, j, string_len;
register const char **suffixes; register char **suffixes;
suffixes = tilde_additional_suffixes; suffixes = tilde_additional_suffixes;
string_len = strlen (string); string_len = strlen (string);
for (i = 0; i < string_len; i++) for (i = 0; i < string_len; i++)
{ {
#if defined (__MSDOS__)
if (string[i] == '/' || string[i] == '\\' /* || !string[i] */)
#else
if (string[i] == '/' /* || !string[i] */) if (string[i] == '/' /* || !string[i] */)
#endif
break; break;
for (j = 0; suffixes && suffixes[j]; j++) for (j = 0; suffixes && suffixes[j]; j++)
@@ -176,16 +184,16 @@ tilde_find_suffix (string)
/* Return a new string which is the result of tilde expanding STRING. */ /* Return a new string which is the result of tilde expanding STRING. */
char * char *
tilde_expand (string) tilde_expand (string)
char *string; const char *string;
{ {
char *result; char *result;
int result_size, result_index; int result_size, result_index;
result_index = result_size = 0; result_index = result_size = 0;
if ((result = strchr (string, '~'))) if ((result = (char*)strchr(string, '~')))
result = xmalloc (result_size = (strlen (string) + 16)); result = (char *)xmalloc (result_size = (strlen (string) + 16));
else else
result = xmalloc (result_size = (strlen (string) + 1)); result = (char *)xmalloc (result_size = (strlen (string) + 1));
/* Scan through STRING expanding tildes as we come to them. */ /* Scan through STRING expanding tildes as we come to them. */
while (1) while (1)
@@ -199,7 +207,7 @@ tilde_expand (string)
/* Copy the skipped text into the result. */ /* Copy the skipped text into the result. */
if ((result_index + start + 1) > result_size) if ((result_index + start + 1) > result_size)
result = xrealloc (result, 1 + (result_size += (start + 20))); result = (char *)xrealloc (result, 1 + (result_size += (start + 20)));
strncpy (result + result_index, string, start); strncpy (result + result_index, string, start);
result_index += start; result_index += start;
@@ -216,7 +224,7 @@ tilde_expand (string)
break; break;
/* Expand the entire tilde word, and copy it into RESULT. */ /* Expand the entire tilde word, and copy it into RESULT. */
tilde_word = xmalloc (1 + end); tilde_word = (char *)xmalloc (1 + end);
strncpy (tilde_word, string, end); strncpy (tilde_word, string, end);
tilde_word[end] = '\0'; tilde_word[end] = '\0';
string += end; string += end;
@@ -225,11 +233,18 @@ tilde_expand (string)
free (tilde_word); free (tilde_word);
len = strlen (expansion); len = strlen (expansion);
if ((result_index + len + 1) > result_size) #ifdef __CYGWIN__
result = xrealloc (result, 1 + (result_size += (len + 20))); /* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when
$HOME for `user' is /. On cygwin, // denotes a network drive. */
if (len > 1 || *expansion != '/' || *string != '/')
#endif
{
if ((result_index + len + 1) > result_size)
result = (char *)xrealloc (result, 1 + (result_size += (len + 20)));
strcpy (result + result_index, expansion); strcpy (result + result_index, expansion);
result_index += len; result_index += len;
}
free (expansion); free (expansion);
} }
@@ -243,14 +258,18 @@ tilde_expand (string)
the location it points to. */ the location it points to. */
static char * static char *
isolate_tilde_prefix (fname, lenp) isolate_tilde_prefix (fname, lenp)
char *fname; const char *fname;
int *lenp; int *lenp;
{ {
char *ret; char *ret;
int i; int i;
ret = xmalloc (strlen (fname)); ret = (char *)xmalloc (strlen (fname));
#if defined (__MSDOS__)
for (i = 1; fname[i] && fname[i] != '/' && fname[i] != '\\'; i++)
#else
for (i = 1; fname[i] && fname[i] != '/'; i++) for (i = 1; fname[i] && fname[i] != '/'; i++)
#endif
ret[i - 1] = fname[i]; ret[i - 1] = fname[i];
ret[i - 1] = '\0'; ret[i - 1] = '\0';
if (lenp) if (lenp)
@@ -262,7 +281,8 @@ isolate_tilde_prefix (fname, lenp)
SUFFIND. */ SUFFIND. */
static char * static char *
glue_prefix_and_suffix (prefix, suffix, suffind) glue_prefix_and_suffix (prefix, suffix, suffind)
char *prefix, *suffix; char *prefix;
const char *suffix;
int suffind; int suffind;
{ {
char *ret; char *ret;
@@ -270,8 +290,8 @@ glue_prefix_and_suffix (prefix, suffix, suffind)
plen = (prefix && *prefix) ? strlen (prefix) : 0; plen = (prefix && *prefix) ? strlen (prefix) : 0;
slen = strlen (suffix + suffind); slen = strlen (suffix + suffind);
ret = xmalloc (plen + slen + 1); ret = (char *)xmalloc (plen + slen + 1);
if (prefix && *prefix) if (plen)
strcpy (ret, prefix); strcpy (ret, prefix);
strcpy (ret + plen, suffix + suffind); strcpy (ret + plen, suffix + suffind);
return ret; return ret;
@@ -282,7 +302,7 @@ glue_prefix_and_suffix (prefix, suffix, suffind)
This always returns a newly-allocated string, never static storage. */ This always returns a newly-allocated string, never static storage. */
char * char *
tilde_expand_word (filename) tilde_expand_word (filename)
char *filename; const char *filename;
{ {
char *dirname, *expansion, *username; char *dirname, *expansion, *username;
int user_len; int user_len;
@@ -300,12 +320,12 @@ tilde_expand_word (filename)
if (filename[1] == '\0' || filename[1] == '/') if (filename[1] == '\0' || filename[1] == '/')
{ {
/* Prefix $HOME to the rest of the string. */ /* Prefix $HOME to the rest of the string. */
expansion = get_env_value ("HOME"); expansion = sh_get_env_value ("HOME");
/* If there is no HOME variable, look up the directory in /* If there is no HOME variable, look up the directory in
the password database. */ the password database. */
if (expansion == 0) if (expansion == 0)
expansion = get_home_dir (); expansion = sh_get_home_dir ();
return (glue_prefix_and_suffix (expansion, filename, 1)); return (glue_prefix_and_suffix (expansion, filename, 1));
} }
@@ -394,28 +414,28 @@ main (argc, argv)
static void memory_error_and_abort (); static void memory_error_and_abort ();
static char * static void *
xmalloc (bytes) xmalloc (bytes)
int bytes; size_t bytes;
{ {
char *temp = (char *)malloc (bytes); void *temp = (char *)malloc (bytes);
if (!temp) if (!temp)
memory_error_and_abort (); memory_error_and_abort ();
return (temp); return (temp);
} }
static char * static void *
xrealloc (pointer, bytes) xrealloc (pointer, bytes)
char *pointer; void *pointer;
int bytes; int bytes;
{ {
char *temp; void *temp;
if (!pointer) if (!pointer)
temp = (char *)malloc (bytes); temp = malloc (bytes);
else else
temp = (char *)realloc (pointer, bytes); temp = realloc (pointer, bytes);
if (!temp) if (!temp)
memory_error_and_abort (); memory_error_and_abort ();

View File

@@ -8,7 +8,7 @@
The Library is free software; you can redistribute it and/or modify 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 it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
The Library is distributed in the hope that it will be useful, but The Library is distributed in the hope that it will be useful, but
@@ -19,47 +19,60 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_TILDE_H_) #if !defined (_TILDE_H_)
# define _TILDE_H_ # define _TILDE_H_
/* Function pointers can be declared as (Function *)foo. */ #ifdef __cplusplus
#if !defined (_FUNCTION_DEF) extern "C" {
# define _FUNCTION_DEF #endif
typedef int Function ();
typedef void VFunction (); /* A function can be defined using prototypes and compile on both ANSI C
typedef char *CPFunction (); and traditional C compilers with something like this:
typedef char **CPPFunction (); extern char *func PARAMS((char *, char *, int)); */
#endif /* _FUNCTION_DEF */
#if !defined (PARAMS)
# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus)
# define PARAMS(protos) protos
# else
# define PARAMS(protos) ()
# endif
#endif
typedef char *tilde_hook_func_t PARAMS((char *));
/* If non-null, this contains the address of a function that the application /* If non-null, this contains the address of a function that the application
wants called before trying the standard tilde expansions. The function wants called before trying the standard tilde expansions. The function
is called with the text sans tilde, and returns a malloc()'ed string is called with the text sans tilde, and returns a malloc()'ed string
which is the expansion, or a NULL pointer if the expansion fails. */ which is the expansion, or a NULL pointer if the expansion fails. */
extern CPFunction *tilde_expansion_preexpansion_hook; extern tilde_hook_func_t *tilde_expansion_preexpansion_hook;
/* If non-null, this contains the address of a function to call if the /* If non-null, this contains the address of a function to call if the
standard meaning for expanding a tilde fails. The function is called standard meaning for expanding a tilde fails. The function is called
with the text (sans tilde, as in "foo"), and returns a malloc()'ed string with the text (sans tilde, as in "foo"), and returns a malloc()'ed string
which is the expansion, or a NULL pointer if there is no expansion. */ which is the expansion, or a NULL pointer if there is no expansion. */
extern CPFunction *tilde_expansion_failure_hook; extern tilde_hook_func_t *tilde_expansion_failure_hook;
/* When non-null, this is a NULL terminated array of strings which /* When non-null, this is a NULL terminated array of strings which
are duplicates for a tilde prefix. Bash uses this to expand are duplicates for a tilde prefix. Bash uses this to expand
`=~' and `:~'. */ `=~' and `:~'. */
extern const char **tilde_additional_prefixes; extern char **tilde_additional_prefixes;
/* When non-null, this is a NULL terminated array of strings which match /* When non-null, this is a NULL terminated array of strings which match
the end of a username, instead of just "/". Bash sets this to the end of a username, instead of just "/". Bash sets this to
`:' and `=~'. */ `:' and `=~'. */
extern const char **tilde_additional_suffixes; extern char **tilde_additional_suffixes;
/* Return a new string which is the result of tilde expanding STRING. */ /* Return a new string which is the result of tilde expanding STRING. */
extern char *tilde_expand (); extern char *tilde_expand PARAMS((const char *));
/* Do the work of tilde expansion on FILENAME. FILENAME starts with a /* Do the work of tilde expansion on FILENAME. FILENAME starts with a
tilde. If there is no expansion, call tilde_expansion_failure_hook. */ tilde. If there is no expansion, call tilde_expansion_failure_hook. */
extern char *tilde_expand_word (); extern char *tilde_expand_word PARAMS((const char *));
#ifdef __cplusplus
}
#endif
#endif /* _TILDE_H_ */ #endif /* _TILDE_H_ */

View File

@@ -8,7 +8,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -19,7 +19,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
@@ -47,7 +47,8 @@
#include "readline.h" #include "readline.h"
#include "history.h" #include "history.h"
#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0) #include "rlprivate.h"
#include "xmalloc.h"
/* Non-zero tells rl_delete_text and rl_insert_text to not add to /* Non-zero tells rl_delete_text and rl_insert_text to not add to
the undo list. */ the undo list. */
@@ -84,7 +85,7 @@ rl_add_undo (what, start, end, text)
/* Free the existing undo list. */ /* Free the existing undo list. */
void void
free_undo_list () rl_free_undo_list ()
{ {
while (rl_undo_list) while (rl_undo_list)
{ {
@@ -105,17 +106,18 @@ int
rl_do_undo () rl_do_undo ()
{ {
UNDO_LIST *release; UNDO_LIST *release;
int waiting_for_begin = 0; int waiting_for_begin, start, end;
int start = 0, end = 0;
#define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i))) #define TRANS(i) ((i) == -1 ? rl_point : ((i) == -2 ? rl_end : (i)))
start = end = waiting_for_begin = 0;
do do
{ {
if (!rl_undo_list) if (!rl_undo_list)
return (0); return (0);
_rl_doing_an_undo = 1; _rl_doing_an_undo = 1;
RL_SETSTATE(RL_STATE_UNDOING);
/* To better support vi-mode, a start or end value of -1 means /* To better support vi-mode, a start or end value of -1 means
rl_point, and a value of -2 means rl_end. */ rl_point, and a value of -2 means rl_end. */
@@ -150,11 +152,12 @@ rl_do_undo ()
if (waiting_for_begin) if (waiting_for_begin)
waiting_for_begin--; waiting_for_begin--;
else else
ding (); rl_ding ();
break; break;
} }
_rl_doing_an_undo = 0; _rl_doing_an_undo = 0;
RL_UNSETSTATE(RL_STATE_UNDOING);
release = rl_undo_list; release = rl_undo_list;
rl_undo_list = rl_undo_list->next; rl_undo_list = rl_undo_list->next;
@@ -168,13 +171,14 @@ rl_do_undo ()
int int
_rl_fix_last_undo_of_type (type, start, end) _rl_fix_last_undo_of_type (type, start, end)
int type, start, end; unsigned int type;
int start, end;
{ {
UNDO_LIST *rl; UNDO_LIST *rl;
for (rl = rl_undo_list; rl; rl = rl->next) for (rl = rl_undo_list; rl; rl = rl->next)
{ {
if ((int) rl->what == type) if (rl->what == type)
{ {
rl->start = start; rl->start = start;
rl->end = end; rl->end = end;
@@ -225,11 +229,11 @@ rl_modifying (start, end)
/* Revert the current line to its previous state. */ /* Revert the current line to its previous state. */
int int
rl_revert_line (int count __attribute__((unused)), rl_revert_line (count, key)
int key __attribute__((unused))) int count __attribute__((unused)), key __attribute__((unused));
{ {
if (!rl_undo_list) if (!rl_undo_list)
ding (); rl_ding ();
else else
{ {
while (rl_undo_list) while (rl_undo_list)
@@ -240,7 +244,8 @@ rl_revert_line (int count __attribute__((unused)),
/* Do some undoing of things that were done. */ /* Do some undoing of things that were done. */
int int
rl_undo_command (int count, int key __attribute__((unused))) rl_undo_command (count, key)
int count, key __attribute__((unused));
{ {
if (count < 0) if (count < 0)
return 0; /* Nothing to do. */ return 0; /* Nothing to do. */
@@ -251,7 +256,7 @@ rl_undo_command (int count, int key __attribute__((unused)))
count--; count--;
else else
{ {
ding (); rl_ding ();
break; break;
} }
} }

View File

@@ -7,7 +7,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -18,7 +18,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
@@ -52,24 +52,8 @@
/* Some standard library routines. */ /* Some standard library routines. */
#include "readline.h" #include "readline.h"
#define SWAP(s, e) do { int t; t = s; s = e; e = t; } while (0) #include "rlprivate.h"
#include "xmalloc.h"
/* Pseudo-globals imported from readline.c */
extern int readline_echoing_p;
extern procenv_t 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_replace_text ();
extern void _rl_pop_executing_macro ();
extern void _rl_set_the_line ();
extern void _rl_init_argument ();
extern char *xmalloc (), *xrealloc ();
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
@@ -84,7 +68,7 @@ int _rl_allow_pathname_alphabetic_chars = 0;
static const char *pathname_alphabetic_chars = "/-_=~.#$"; static const char *pathname_alphabetic_chars = "/-_=~.#$";
int int
alphabetic (c) rl_alphabetic (c)
int c; int c;
{ {
if (ALPHABETIC (c)) if (ALPHABETIC (c))
@@ -98,36 +82,36 @@ alphabetic (c)
int int
_rl_abort_internal () _rl_abort_internal ()
{ {
ding (); rl_ding ();
rl_clear_message (); rl_clear_message ();
_rl_init_argument (); _rl_init_argument ();
rl_pending_input = 0; rl_clear_pending_input ();
_rl_defining_kbd_macro = 0; RL_UNSETSTATE (RL_STATE_MACRODEF);
while (_rl_executing_macro) while (rl_executing_macro)
_rl_pop_executing_macro (); _rl_pop_executing_macro ();
rl_last_func = (Function *)NULL; rl_last_func = (rl_command_func_t *)NULL;
longjmp (readline_top_level, 1); longjmp (readline_top_level, 1);
return (0); return (0);
} }
int int
rl_abort (int count __attribute__((unused)), rl_abort (count, key)
int key __attribute__((unused))) int count __attribute__((unused)), key __attribute__((unused));
{ {
return (_rl_abort_internal ()); return (_rl_abort_internal ());
} }
int int
rl_tty_status (int count __attribute__((unused)), rl_tty_status (count, key)
int key __attribute__((unused))) int count __attribute__((unused)), key __attribute__((unused));
{ {
#if defined (TIOCSTAT) #if defined (TIOCSTAT)
ioctl (1, TIOCSTAT, (char *)0); ioctl (1, TIOCSTAT, (char *)0);
rl_refresh_line (count, key); rl_refresh_line (count, key);
#else #else
ding (); rl_ding ();
#endif #endif
return 0; return 0;
} }
@@ -146,7 +130,7 @@ rl_copy_text (from, to)
SWAP (from, to); SWAP (from, to);
length = to - from; length = to - from;
copy = xmalloc (1 + length); copy = (char *)xmalloc (1 + length);
strncpy (copy, rl_line_buffer + from, length); strncpy (copy, rl_line_buffer + from, length);
copy[length] = '\0'; copy[length] = '\0';
return (copy); return (copy);
@@ -161,7 +145,7 @@ rl_extend_line_buffer (len)
while (len >= rl_line_buffer_len) while (len >= rl_line_buffer_len)
{ {
rl_line_buffer_len += DEFAULT_BUFFER_SIZE; rl_line_buffer_len += DEFAULT_BUFFER_SIZE;
rl_line_buffer = xrealloc (rl_line_buffer, rl_line_buffer_len); rl_line_buffer = (char *)xrealloc (rl_line_buffer, rl_line_buffer_len);
} }
_rl_set_the_line (); _rl_set_the_line ();
@@ -170,8 +154,8 @@ rl_extend_line_buffer (len)
/* A function for simple tilde expansion. */ /* A function for simple tilde expansion. */
int int
rl_tilde_expand (int ignore __attribute__((unused)), rl_tilde_expand (ignore, key)
int key __attribute__((unused))) int ignore __attribute__((unused)), key __attribute__((unused));
{ {
register int start, end; register int start, end;
char *homedir, *temp; char *homedir, *temp;
@@ -207,7 +191,7 @@ rl_tilde_expand (int ignore __attribute__((unused)),
if (rl_line_buffer[start] == '~') if (rl_line_buffer[start] == '~')
{ {
len = end - start + 1; len = end - start + 1;
temp = xmalloc (len + 1); temp = (char *)xmalloc (len + 1);
strncpy (temp, rl_line_buffer + start, len); strncpy (temp, rl_line_buffer + start, len);
temp[len] = '\0'; temp[len] = '\0';
homedir = tilde_expand (temp); homedir = tilde_expand (temp);
@@ -229,16 +213,51 @@ rl_tilde_expand (int ignore __attribute__((unused)),
match in s1. The compare is case insensitive. */ match in s1. The compare is case insensitive. */
char * char *
_rl_strindex (s1, s2) _rl_strindex (s1, s2)
register char *s1, *s2; register const char *s1, *s2;
{ {
register int i, l, len; register int i, l, len;
for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++) for (i = 0, l = strlen (s2), len = strlen (s1); (len - i) >= l; i++)
if (_rl_strnicmp (s1 + i, s2, l) == 0) if (_rl_strnicmp (s1 + i, s2, l) == 0)
return (s1 + i); return ((char *) (s1 + i));
return ((char *)NULL); return ((char *)NULL);
} }
#ifndef HAVE_STRPBRK
/* Find the first occurrence in STRING1 of any character from STRING2.
Return a pointer to the character in STRING1. */
char *
_rl_strpbrk (string1, string2)
const char *string1, *string2;
{
register const char *scan;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps;
register int i, v;
memset (&ps, 0, sizeof (mbstate_t));
#endif
for (; *string1; string1++)
{
for (scan = string2; *scan; scan++)
{
if (*string1 == *scan)
return ((char *)string1);
}
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
v = _rl_get_char_len (string1, &ps);
if (v > 1)
string += v - 1; /* -1 to account for auto-increment in loop */
}
#endif
}
return ((char *)NULL);
}
#endif
#if !defined (HAVE_STRCASECMP) #if !defined (HAVE_STRCASECMP)
/* Compare at most COUNT characters from string1 to string2. Case /* Compare at most COUNT characters from string1 to string2. Case
doesn't matter. */ doesn't matter. */
@@ -297,69 +316,23 @@ _rl_qsort_string_compare (s1, s2)
#endif #endif
} }
/* Function equivalents for the macros defined in chartypes.h. */ /* Function equivalents for the macros defined in chardefs.h. */
#undef _rl_uppercase_p #define FUNCTION_FOR_MACRO(f) int (f) (c) int c; { return f (c); }
int
_rl_uppercase_p (c)
int c;
{
return (isupper (c));
}
#undef _rl_lowercase_p FUNCTION_FOR_MACRO (_rl_digit_p)
int FUNCTION_FOR_MACRO (_rl_digit_value)
_rl_lowercase_p (c) FUNCTION_FOR_MACRO (_rl_lowercase_p)
int c; FUNCTION_FOR_MACRO (_rl_pure_alphabetic)
{ FUNCTION_FOR_MACRO (_rl_to_lower)
return (islower (c)); FUNCTION_FOR_MACRO (_rl_to_upper)
} FUNCTION_FOR_MACRO (_rl_uppercase_p)
#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);
}
/* Backwards compatibility, now that savestring has been removed from /* Backwards compatibility, now that savestring has been removed from
all `public' readline header files. */ all `public' readline header files. */
#undef _rl_savestring #undef _rl_savestring
char * char *
_rl_savestring (s) _rl_savestring (s)
char *s; const char *s;
{ {
return ((char *)strcpy (xmalloc (1 + (int)strlen (s)), (s))); return (strcpy ((char *)xmalloc (1 + (int)strlen (s)), (s)));
} }

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@
The GNU Readline Library is free software; you can redistribute it The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 1, or as published by the Free Software Foundation; either version 2, or
(at your option) any later version. (at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be The GNU Readline Library is distributed in the hope that it will be
@@ -19,7 +19,7 @@
The GNU General Public License is often shipped with GNU software, and 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 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, have a copy of the license, write to the Free Software Foundation,
675 Mass Ave, Cambridge, MA 02139, USA. */ 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY #define READLINE_LIBRARY
/* **************************************************************** */ /* **************************************************************** */
@@ -51,54 +51,23 @@
/* Some standard library routines. */ /* Some standard library routines. */
#include "rldefs.h" #include "rldefs.h"
#include "rlmbutil.h"
#include "readline.h" #include "readline.h"
#include "history.h" #include "history.h"
#ifndef _rl_digit_p #include "rlprivate.h"
#define _rl_digit_p(c) ((c) >= '0' && (c) <= '9') #include "xmalloc.h"
#endif
#ifndef _rl_digit_value
#define _rl_digit_value(c) ((c) - '0')
#endif
#ifndef member #ifndef member
#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0) #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
#endif #endif
#ifndef isident
#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
extern char *xmalloc (), *xrealloc ();
/* Variables imported from readline.c */
extern int rl_point, rl_end, rl_mark;
extern FILE *rl_instream;
extern int rl_line_buffer_len, rl_explicit_arg, rl_numeric_arg;
extern Keymap _rl_keymap;
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. */ /* Non-zero means enter insertion mode. */
static int _rl_vi_doing_insert; static int _rl_vi_doing_insert;
/* Command keys which do movement for xxx_to commands. */ /* Command keys which do movement for xxx_to commands. */
static const char *vi_motion = " hl^$0ftFt;,%wbeWBE|"; static const char *vi_motion = " hl^$0ftFT;,%wbeWBE|";
/* Keymap used for vi replace characters. Created dynamically since /* Keymap used for vi replace characters. Created dynamically since
rarely used. */ rarely used. */
@@ -118,7 +87,11 @@ 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_repeat = 1;
static int _rl_vi_last_arg_sign = 1; static int _rl_vi_last_arg_sign = 1;
static int _rl_vi_last_motion; static int _rl_vi_last_motion;
#if defined (HANDLE_MULTIBYTE)
static char _rl_vi_last_search_mbchar[MB_LEN_MAX];
#else
static int _rl_vi_last_search_char; static int _rl_vi_last_search_char;
#endif
static int _rl_vi_last_replacement; static int _rl_vi_last_replacement;
static int _rl_vi_last_key_before_insert; static int _rl_vi_last_key_before_insert;
@@ -129,20 +102,18 @@ static int vi_redoing;
static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~"; static const char *vi_textmod = "_*\\AaIiCcDdPpYyRrSsXx~";
/* Arrays for the saved marks. */ /* Arrays for the saved marks. */
static int vi_mark_chars[27]; static int vi_mark_chars['z' - 'a' + 1];
static int rl_digit_loop1 (); static void _rl_vi_stuff_insert PARAMS((int));
static void _rl_vi_save_insert PARAMS((UNDO_LIST *));
static int rl_digit_loop1 PARAMS((void));
void void
_rl_vi_initialize_line () _rl_vi_initialize_line ()
{ {
#ifndef __QNXNTO__
register uint i;
#else
register unsigned int i; register unsigned int i;
#endif
for (i = 0; i < (int) sizeof (vi_mark_chars) / sizeof (int); i++) for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
vi_mark_chars[i] = -1; vi_mark_chars[i] = -1;
} }
@@ -189,12 +160,15 @@ int
rl_vi_redo (count, c) rl_vi_redo (count, c)
int count, c __attribute__((unused)); int count, c __attribute__((unused));
{ {
int r;
if (!rl_explicit_arg) if (!rl_explicit_arg)
{ {
rl_numeric_arg = _rl_vi_last_repeat; rl_numeric_arg = _rl_vi_last_repeat;
rl_arg_sign = _rl_vi_last_arg_sign; rl_arg_sign = _rl_vi_last_arg_sign;
} }
r = 0;
vi_redoing = 1; vi_redoing = 1;
/* If we're redoing an insert with `i', stuff in the inserted text /* If we're redoing an insert with `i', stuff in the inserted text
and do not go into insertion mode. */ and do not go into insertion mode. */
@@ -206,10 +180,10 @@ rl_vi_redo (count, c)
rl_point--; rl_point--;
} }
else else
_rl_dispatch (_rl_vi_last_command, _rl_keymap); r = _rl_dispatch (_rl_vi_last_command, _rl_keymap);
vi_redoing = 0; vi_redoing = 0;
return (0); return (r);
} }
/* A placeholder for further expansion. */ /* A placeholder for further expansion. */
@@ -219,10 +193,10 @@ rl_vi_undo (count, key)
{ {
return (rl_undo_command (count, key)); return (rl_undo_command (count, key));
} }
/* Yank the nth arg from the previous line into this line at point. */ /* Yank the nth arg from the previous line into this line at point. */
int int
rl_vi_yank_arg (count, key) rl_vi_yank_arg (count, key)
int count, key __attribute__((unused)); int count, key __attribute__((unused));
{ {
/* Readline thinks that the first word on a line is the 0th, while vi /* Readline thinks that the first word on a line is the 0th, while vi
@@ -295,7 +269,7 @@ rl_vi_search (count, key)
break; break;
default: default:
ding (); rl_ding ();
break; break;
} }
return (0); return (0);
@@ -351,7 +325,7 @@ rl_vi_prev_word (count, key)
if (rl_point == 0) if (rl_point == 0)
{ {
ding (); rl_ding ();
return (0); return (0);
} }
@@ -373,7 +347,7 @@ rl_vi_next_word (count, key)
if (rl_point >= (rl_end - 1)) if (rl_point >= (rl_end - 1))
{ {
ding (); rl_ding ();
return (0); return (0);
} }
@@ -391,7 +365,7 @@ rl_vi_end_word (count, key)
{ {
if (count < 0) if (count < 0)
{ {
ding (); rl_ding ();
return -1; return -1;
} }
@@ -481,14 +455,14 @@ rl_vi_fword (count, ignore)
while (count-- && rl_point < (rl_end - 1)) while (count-- && rl_point < (rl_end - 1))
{ {
/* Move to white space (really non-identifer). */ /* Move to white space (really non-identifer). */
if (isident (rl_line_buffer[rl_point])) if (_rl_isident (rl_line_buffer[rl_point]))
{ {
while (isident (rl_line_buffer[rl_point]) && rl_point < rl_end) while (_rl_isident (rl_line_buffer[rl_point]) && rl_point < rl_end)
rl_point++; rl_point++;
} }
else /* if (!whitespace (rl_line_buffer[rl_point])) */ else /* if (!whitespace (rl_line_buffer[rl_point])) */
{ {
while (!isident (rl_line_buffer[rl_point]) && while (!_rl_isident (rl_line_buffer[rl_point]) &&
!whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end) !whitespace (rl_line_buffer[rl_point]) && rl_point < rl_end)
rl_point++; rl_point++;
} }
@@ -518,9 +492,9 @@ rl_vi_bword (count, ignore)
back so we don't get messed up by the rl_point++ down there in back so we don't get messed up by the rl_point++ down there in
the while loop. Without this code, words like `l;' screw up the the while loop. Without this code, words like `l;' screw up the
function. */ function. */
last_is_ident = isident (rl_line_buffer[rl_point - 1]); last_is_ident = _rl_isident (rl_line_buffer[rl_point - 1]);
if ((isident (rl_line_buffer[rl_point]) && !last_is_ident) || if ((_rl_isident (rl_line_buffer[rl_point]) && !last_is_ident) ||
(!isident (rl_line_buffer[rl_point]) && last_is_ident)) (!_rl_isident (rl_line_buffer[rl_point]) && last_is_ident))
rl_point--; rl_point--;
while (rl_point > 0 && whitespace (rl_line_buffer[rl_point])) while (rl_point > 0 && whitespace (rl_line_buffer[rl_point]))
@@ -528,10 +502,10 @@ rl_vi_bword (count, ignore)
if (rl_point > 0) if (rl_point > 0)
{ {
if (isident (rl_line_buffer[rl_point])) if (_rl_isident (rl_line_buffer[rl_point]))
while (--rl_point >= 0 && isident (rl_line_buffer[rl_point])); while (--rl_point >= 0 && _rl_isident (rl_line_buffer[rl_point]));
else else
while (--rl_point >= 0 && !isident (rl_line_buffer[rl_point]) && while (--rl_point >= 0 && !_rl_isident (rl_line_buffer[rl_point]) &&
!whitespace (rl_line_buffer[rl_point])); !whitespace (rl_line_buffer[rl_point]));
rl_point++; rl_point++;
} }
@@ -553,10 +527,10 @@ rl_vi_eword (count, ignore)
if (rl_point < rl_end) if (rl_point < rl_end)
{ {
if (isident (rl_line_buffer[rl_point])) if (_rl_isident (rl_line_buffer[rl_point]))
while (++rl_point < rl_end && isident (rl_line_buffer[rl_point])); while (++rl_point < rl_end && _rl_isident (rl_line_buffer[rl_point]));
else else
while (++rl_point < rl_end && !isident (rl_line_buffer[rl_point]) while (++rl_point < rl_end && !_rl_isident (rl_line_buffer[rl_point])
&& !whitespace (rl_line_buffer[rl_point])); && !whitespace (rl_line_buffer[rl_point]));
} }
rl_point--; rl_point--;
@@ -578,7 +552,17 @@ rl_vi_append_mode (count, key)
int count __attribute__((unused)), key; int count __attribute__((unused)), key;
{ {
if (rl_point < rl_end) if (rl_point < rl_end)
rl_point++; {
if (MB_CUR_MAX == 1 || rl_byte_oriented)
rl_point++;
else
{
int point = rl_point;
rl_forward_char (1, key);
if (point == rl_point)
rl_point = rl_end;
}
}
rl_vi_insertion_mode (1, key); rl_vi_insertion_mode (1, key);
return (0); return (0);
} }
@@ -632,17 +616,18 @@ _rl_vi_save_insert (up)
if (len >= vi_insert_buffer_size) if (len >= vi_insert_buffer_size)
{ {
vi_insert_buffer_size += (len + 32) - (len % 32); vi_insert_buffer_size += (len + 32) - (len % 32);
vi_insert_buffer = xrealloc (vi_insert_buffer, vi_insert_buffer_size); vi_insert_buffer = (char *)xrealloc (vi_insert_buffer, vi_insert_buffer_size);
} }
strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1); strncpy (vi_insert_buffer, rl_line_buffer + start, len - 1);
vi_insert_buffer[len-1] = '\0'; vi_insert_buffer[len-1] = '\0';
} }
void void
_rl_vi_done_inserting () _rl_vi_done_inserting ()
{ {
if (_rl_vi_doing_insert) if (_rl_vi_doing_insert)
{ {
/* The `C', `s', and `S' commands set this. */
rl_end_undo_group (); rl_end_undo_group ();
/* Now, the text between rl_undo_list->next->start and /* Now, the text between rl_undo_list->next->start and
rl_undo_list->next->end is what was inserted while in insert rl_undo_list->next->end is what was inserted while in insert
@@ -671,7 +656,7 @@ rl_vi_movement_mode (count, key)
int count __attribute__((unused)), key; int count __attribute__((unused)), key;
{ {
if (rl_point > 0) if (rl_point > 0)
rl_backward (1, key); rl_backward_char (1, key);
_rl_keymap = vi_movement_keymap; _rl_keymap = vi_movement_keymap;
_rl_vi_done_inserting (); _rl_vi_done_inserting ();
@@ -688,6 +673,51 @@ rl_vi_arg_digit (count, c)
return (rl_digit_argument (count, c)); return (rl_digit_argument (count, c));
} }
/* Change the case of the next COUNT characters. */
#if defined (HANDLE_MULTIBYTE)
static int
_rl_vi_change_mbchar_case (count)
int count;
{
wchar_t wc;
char mb[MB_LEN_MAX];
mbstate_t ps;
memset (&ps, 0, sizeof (mbstate_t));
if (_rl_adjust_point (rl_line_buffer, rl_point, &ps) > 0)
count--;
while (count-- && rl_point < rl_end)
{
mbrtowc (&wc, rl_line_buffer + rl_point, rl_end - rl_point, &ps);
if (iswupper (wc))
wc = towlower (wc);
else if (iswlower (wc))
wc = towupper (wc);
else
{
/* Just skip over chars neither upper nor lower case */
rl_forward_char (1, 0);
continue;
}
/* Vi is kind of strange here. */
if (wc)
{
wctomb (mb, wc);
rl_begin_undo_group ();
rl_delete (1, 0);
rl_insert_text (mb);
rl_end_undo_group ();
rl_vi_check ();
}
else
rl_forward_char (1, 0);
}
return 0;
}
#endif
int int
rl_vi_change_case (count, ignore) rl_vi_change_case (count, ignore)
int count, ignore __attribute__((unused)); int count, ignore __attribute__((unused));
@@ -698,6 +728,11 @@ rl_vi_change_case (count, ignore)
if (rl_point >= rl_end) if (rl_point >= rl_end)
return (0); return (0);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
return (_rl_vi_change_mbchar_case (count));
#endif
while (count-- && rl_point < rl_end) while (count-- && rl_point < rl_end)
{ {
if (_rl_uppercase_p (rl_line_buffer[rl_point])) if (_rl_uppercase_p (rl_line_buffer[rl_point]))
@@ -707,7 +742,7 @@ rl_vi_change_case (count, ignore)
else else
{ {
/* Just skip over characters neither upper nor lower case. */ /* Just skip over characters neither upper nor lower case. */
rl_forward (1, c); rl_forward_char (1, c);
continue; continue;
} }
@@ -716,12 +751,12 @@ rl_vi_change_case (count, ignore)
{ {
rl_begin_undo_group (); rl_begin_undo_group ();
rl_delete (1, c); rl_delete (1, c);
rl_insert (1, c); _rl_insert_char (1, c);
rl_end_undo_group (); rl_end_undo_group ();
rl_vi_check (); rl_vi_check ();
} }
else else
rl_forward (1, c); rl_forward_char (1, c);
} }
return (0); return (0);
} }
@@ -731,10 +766,10 @@ rl_vi_put (count, key)
int count __attribute__((unused)), key; int count __attribute__((unused)), key;
{ {
if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end)) if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
rl_point++; rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
rl_yank (1, key); rl_yank (1, key);
rl_backward (1, key); rl_backward_char (1, key);
return (0); return (0);
} }
@@ -742,7 +777,12 @@ int
rl_vi_check () rl_vi_check ()
{ {
if (rl_point && rl_point == rl_end) if (rl_point && rl_point == rl_end)
rl_point--; {
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
else
rl_point--;
}
return (0); return (0);
} }
@@ -765,7 +805,9 @@ rl_vi_domove (key, nextkey)
int old_end; int old_end;
rl_mark = rl_point; rl_mark = rl_point;
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key (); c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
*nextkey = c; *nextkey = c;
if (!member (c, vi_motion)) if (!member (c, vi_motion))
@@ -776,7 +818,9 @@ rl_vi_domove (key, nextkey)
rl_numeric_arg = _rl_digit_value (c); rl_numeric_arg = _rl_digit_value (c);
rl_digit_loop1 (); rl_digit_loop1 ();
rl_numeric_arg *= save; rl_numeric_arg *= save;
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key (); /* real command */ c = rl_read_key (); /* real command */
RL_UNSETSTATE(RL_STATE_MOREINPUT);
*nextkey = c; *nextkey = c;
} }
else if (key == c && (key == 'd' || key == 'y' || key == 'c')) else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
@@ -840,24 +884,36 @@ rl_vi_domove (key, nextkey)
} }
if (rl_mark < rl_point) if (rl_mark < rl_point)
exchange (rl_point, rl_mark); SWAP (rl_point, rl_mark);
return (0); return (0);
} }
/* A simplified loop for vi. Don't dispatch key at end. /* A simplified loop for vi. Don't dispatch key at end.
Don't recognize minus sign? */ Don't recognize minus sign?
Should this do rl_save_prompt/rl_restore_prompt? */
static int static int
rl_digit_loop1 () rl_digit_loop1 ()
{ {
int key, c; int key, c;
RL_SETSTATE(RL_STATE_NUMERICARG);
while (1) while (1)
{ {
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg, 0); if (rl_numeric_arg > 1000000)
{
rl_explicit_arg = rl_numeric_arg = 0;
rl_ding ();
rl_clear_message ();
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return 1;
}
rl_message ("(arg: %d) ", rl_arg_sign * rl_numeric_arg);
RL_SETSTATE(RL_STATE_MOREINPUT);
key = c = rl_read_key (); key = c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (_rl_keymap[c].type == ISFUNC && if (c >= 0 && _rl_keymap[c].type == ISFUNC &&
_rl_keymap[c].function == rl_universal_argument) _rl_keymap[c].function == rl_universal_argument)
{ {
rl_numeric_arg *= 4; rl_numeric_arg *= 4;
@@ -880,6 +936,8 @@ rl_digit_loop1 ()
break; break;
} }
} }
RL_UNSETSTATE(RL_STATE_NUMERICARG);
return (0); return (0);
} }
@@ -896,7 +954,7 @@ rl_vi_delete_to (count, key)
if (rl_vi_domove (key, &c)) if (rl_vi_domove (key, &c))
{ {
ding (); rl_ding ();
return -1; return -1;
} }
@@ -924,7 +982,7 @@ rl_vi_change_to (count, key)
if (rl_vi_domove (key, &c)) if (rl_vi_domove (key, &c))
{ {
ding (); rl_ding ();
return -1; return -1;
} }
@@ -974,7 +1032,7 @@ rl_vi_yank_to (count, key)
if (rl_vi_domove (key, &c)) if (rl_vi_domove (key, &c))
{ {
ding (); rl_ding ();
return -1; return -1;
} }
@@ -1000,19 +1058,22 @@ rl_vi_delete (count, key)
if (rl_end == 0) if (rl_end == 0)
{ {
ding (); rl_ding ();
return -1; return -1;
} }
end = rl_point + count; if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
end = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
else
end = rl_point + count;
if (end >= rl_end) if (end >= rl_end)
end = rl_end; end = rl_end;
rl_kill_text (rl_point, end); rl_kill_text (rl_point, end);
if (rl_point > 0 && rl_point == rl_end) if (rl_point > 0 && rl_point == rl_end)
rl_backward (1, key); rl_backward_char (1, key);
return (0); return (0);
} }
@@ -1037,7 +1098,12 @@ int
rl_vi_char_search (count, key) rl_vi_char_search (count, key)
int count, key; int count, key;
{ {
#if defined (HANDLE_MULTIBYTE)
static char *target;
static int mb_len;
#else
static char target; static char target;
#endif
static int orig_dir, dir; static int orig_dir, dir;
if (key == ';' || key == ',') if (key == ';' || key == ',')
@@ -1045,9 +1111,22 @@ rl_vi_char_search (count, key)
else else
{ {
if (vi_redoing) if (vi_redoing)
#if defined (HANDLE_MULTIBYTE)
target = _rl_vi_last_search_mbchar;
#else
target = _rl_vi_last_search_char; target = _rl_vi_last_search_char;
#endif
else else
_rl_vi_last_search_char = target = rl_getc (rl_instream); {
#if defined (HANDLE_MULTIBYTE)
mb_len = _rl_read_mbchar (_rl_vi_last_search_mbchar, MB_LEN_MAX);
target = _rl_vi_last_search_mbchar;
#else
RL_SETSTATE(RL_STATE_MOREINPUT);
_rl_vi_last_search_char = target = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
#endif
}
switch (key) switch (key)
{ {
@@ -1069,7 +1148,11 @@ rl_vi_char_search (count, key)
} }
} }
#if defined (HANDLE_MULTIBYTE)
return (_rl_char_search_internal (count, dir, target, mb_len));
#else
return (_rl_char_search_internal (count, dir, target)); return (_rl_char_search_internal (count, dir, target));
#endif
} }
/* Match brackets */ /* Match brackets */
@@ -1077,19 +1160,30 @@ int
rl_vi_match (ignore, key) rl_vi_match (ignore, key)
int ignore __attribute__((unused)), key; int ignore __attribute__((unused)), key;
{ {
int count = 1, brack, pos; int count = 1, brack, pos, tmp, pre;
pos = rl_point; pos = rl_point;
if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0) if ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
{ {
while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 && if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point < rl_end - 1) {
rl_forward (1, key); while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0)
{
pre = rl_point;
rl_forward_char (1, key);
if (pre == rl_point)
break;
}
}
else
while ((brack = rl_vi_bracktype (rl_line_buffer[rl_point])) == 0 &&
rl_point < rl_end - 1)
rl_forward_char (1, key);
if (brack <= 0) if (brack <= 0)
{ {
rl_point = pos; rl_point = pos;
ding (); rl_ding ();
return -1; return -1;
} }
} }
@@ -1100,7 +1194,16 @@ rl_vi_match (ignore, key)
{ {
while (count) while (count)
{ {
if (--pos >= 0) tmp = pos;
if (MB_CUR_MAX == 1 || rl_byte_oriented)
pos--;
else
{
pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
if (tmp == pos)
pos--;
}
if (pos >= 0)
{ {
int b = rl_vi_bracktype (rl_line_buffer[pos]); int b = rl_vi_bracktype (rl_line_buffer[pos]);
if (b == -brack) if (b == -brack)
@@ -1110,7 +1213,7 @@ rl_vi_match (ignore, key)
} }
else else
{ {
ding (); rl_ding ();
return -1; return -1;
} }
} }
@@ -1119,7 +1222,12 @@ rl_vi_match (ignore, key)
{ /* brack > 0 */ { /* brack > 0 */
while (count) while (count)
{ {
if (++pos < rl_end) if (MB_CUR_MAX == 1 || rl_byte_oriented)
pos++;
else
pos = _rl_find_next_mbchar (rl_line_buffer, pos, 1, MB_FIND_ANY);
if (pos < rl_end)
{ {
int b = rl_vi_bracktype (rl_line_buffer[pos]); int b = rl_vi_bracktype (rl_line_buffer[pos]);
if (b == -brack) if (b == -brack)
@@ -1129,7 +1237,7 @@ rl_vi_match (ignore, key)
} }
else else
{ {
ding (); rl_ding ();
return -1; return -1;
} }
} }
@@ -1154,6 +1262,11 @@ rl_vi_bracktype (c)
} }
} }
/* XXX - think about reading an entire mbchar with _rl_read_mbchar and
inserting it in one bunch instead of the loop below (like in
rl_vi_char_search or _rl_vi_change_mbchar_case. Set c to mbchar[0]
for test against 033 or ^C. Make sure that _rl_read_mbchar does
this right. */
int int
rl_vi_change_char (count, key) rl_vi_change_char (count, key)
int count, key __attribute__((unused)); int count, key __attribute__((unused));
@@ -1163,7 +1276,11 @@ rl_vi_change_char (count, key)
if (vi_redoing) if (vi_redoing)
c = _rl_vi_last_replacement; c = _rl_vi_last_replacement;
else else
_rl_vi_last_replacement = c = rl_getc (rl_instream); {
RL_SETSTATE(RL_STATE_MOREINPUT);
_rl_vi_last_replacement = c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
}
if (c == '\033' || c == CTRL ('C')) if (c == '\033' || c == CTRL ('C'))
return -1; return -1;
@@ -1173,9 +1290,19 @@ rl_vi_change_char (count, key)
rl_begin_undo_group (); rl_begin_undo_group ();
rl_delete (1, c); rl_delete (1, c);
rl_insert (1, c); #if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
while (_rl_insert_char (1, c))
{
RL_SETSTATE (RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE (RL_STATE_MOREINPUT);
}
else
#endif
_rl_insert_char (1, c);
if (count == 0) if (count == 0)
rl_backward (1, c); rl_backward_char (1, c);
rl_end_undo_group (); rl_end_undo_group ();
} }
@@ -1186,66 +1313,29 @@ int
rl_vi_subst (count, key) rl_vi_subst (count, key)
int count, key; int count, key;
{ {
rl_begin_undo_group (); /* If we are redoing, rl_vi_change_to will stuff the last motion char */
if (vi_redoing == 0)
rl_stuff_char ((key == 'S') ? 'c' : ' '); /* `S' == `cc', `s' == `c ' */
if (_rl_uppercase_p (key)) return (rl_vi_change_to (count, 'c'));
{
rl_beg_of_line (1, key);
rl_kill_line (1, key);
}
else
rl_delete_text (rl_point, rl_point+count);
rl_end_undo_group ();
_rl_vi_set_last (key, count, rl_arg_sign);
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 int
rl_vi_overstrike (count, key) rl_vi_overstrike (count, key)
int count, key; int count, key;
{ {
int i;
if (_rl_vi_doing_insert == 0) if (_rl_vi_doing_insert == 0)
{ {
_rl_vi_doing_insert = 1; _rl_vi_doing_insert = 1;
rl_begin_undo_group (); rl_begin_undo_group ();
} }
for (i = 0; i < count; i++) if (count > 0)
{ {
vi_replace_count++; _rl_overwrite_char (count, key);
rl_begin_undo_group (); vi_replace_count += count;
if (rl_point < rl_end)
{
rl_delete (1, key);
rl_insert (1, key);
}
else
rl_insert (1, key);
rl_end_undo_group ();
} }
return (0); return (0);
} }
@@ -1259,7 +1349,7 @@ rl_vi_overstrike_delete (count, key)
{ {
if (vi_replace_count == 0) if (vi_replace_count == 0)
{ {
ding (); rl_ding ();
break; break;
} }
s = rl_point; s = rl_point;
@@ -1268,7 +1358,7 @@ rl_vi_overstrike_delete (count, key)
vi_replace_count--; vi_replace_count--;
if (rl_point == s) if (rl_point == s)
rl_backward (1, key); rl_backward_char (1, key);
} }
if (vi_replace_count == 0 && _rl_vi_doing_insert) if (vi_replace_count == 0 && _rl_vi_doing_insert)
@@ -1329,7 +1419,7 @@ rl_vi_possible_completions()
} }
else if (rl_line_buffer[rl_point - 1] == ';') else if (rl_line_buffer[rl_point - 1] == ';')
{ {
ding (); rl_ding ();
return (0); return (0);
} }
@@ -1347,10 +1437,13 @@ rl_vi_set_mark (count, key)
{ {
int ch; int ch;
RL_SETSTATE(RL_STATE_MOREINPUT);
ch = rl_read_key (); ch = rl_read_key ();
if (_rl_lowercase_p (ch) == 0) RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (ch < 'a' || ch > 'z')
{ {
ding (); rl_ding ();
return -1; return -1;
} }
ch -= 'a'; ch -= 'a';
@@ -1364,22 +1457,25 @@ rl_vi_goto_mark (count, key)
{ {
int ch; int ch;
RL_SETSTATE(RL_STATE_MOREINPUT);
ch = rl_read_key (); ch = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (ch == '`') if (ch == '`')
{ {
rl_point = rl_mark; rl_point = rl_mark;
return 0; return 0;
} }
else if (_rl_lowercase_p (ch) == 0) else if (ch < 'a' || ch > 'z')
{ {
ding (); rl_ding ();
return -1; return -1;
} }
ch -= 'a'; ch -= 'a';
if (vi_mark_chars[ch] == -1) if (vi_mark_chars[ch] == -1)
{ {
ding (); rl_ding ();
return -1; return -1;
} }
rl_point = vi_mark_chars[ch]; rl_point = vi_mark_chars[ch];

View File

@@ -7,7 +7,7 @@
Readline is free software; you can redistribute it and/or modify it 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 under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 1, or (at your option) any Free Software Foundation; either version 2, or (at your option) any
later version. later version.
Readline is distributed in the hope that it will be useful, but Readline is distributed in the hope that it will be useful, but
@@ -17,7 +17,8 @@
You should have received a copy of the GNU General Public License 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 along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H) #if defined (HAVE_CONFIG_H)
#include <config.h> #include <config.h>
@@ -31,7 +32,7 @@
# include "ansi_stdlib.h" # include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */ #endif /* HAVE_STDLIB_H */
static void memory_error_and_abort (); #include "xmalloc.h"
/* **************************************************************** */ /* **************************************************************** */
/* */ /* */
@@ -39,35 +40,6 @@ static void memory_error_and_abort ();
/* */ /* */
/* **************************************************************** */ /* **************************************************************** */
/* 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;
temp = (char *)malloc (bytes);
if (temp == 0)
memory_error_and_abort ("xmalloc");
return (temp);
}
char *
xrealloc (pointer, bytes)
char *pointer;
int bytes;
{
char *temp;
temp = pointer ? (char *)realloc (pointer, bytes) : (char *)malloc (bytes);
if (temp == 0)
memory_error_and_abort ("xrealloc");
return (temp);
}
static void static void
memory_error_and_abort (fname) memory_error_and_abort (fname)
char *fname; char *fname;
@@ -76,11 +48,40 @@ memory_error_and_abort (fname)
exit (2); exit (2);
} }
/* Return a pointer to free()able block of memory large enough
to hold BYTES number of bytes. If the memory cannot be allocated,
print an error message and abort. */
PTR_T
xmalloc (bytes)
size_t bytes;
{
PTR_T temp;
temp = malloc (bytes);
if (temp == 0)
memory_error_and_abort ("xmalloc");
return (temp);
}
PTR_T
xrealloc (pointer, bytes)
PTR_T pointer;
size_t bytes;
{
PTR_T temp;
temp = pointer ? realloc (pointer, bytes) : malloc (bytes);
if (temp == 0)
memory_error_and_abort ("xrealloc");
return (temp);
}
/* Use this as the function to call when adding unwind protects so we /* Use this as the function to call when adding unwind protects so we
don't need to know what free() returns. */ don't need to know what free() returns. */
void void
xfree (string) xfree (string)
char *string; PTR_T string;
{ {
if (string) if (string)
free (string); free (string);

46
readline/xmalloc.h Normal file
View File

@@ -0,0 +1,46 @@
/* xmalloc.h -- memory allocation that aborts on errors. */
/* Copyright (C) 1999 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#if !defined (_XMALLOC_H_)
#define _XMALLOC_H_
#if defined (READLINE_LIBRARY)
# include "rlstdc.h"
#else
# include <readline/rlstdc.h>
#endif
#ifndef PTR_T
#ifdef __STDC__
# define PTR_T void *
#else
# define PTR_T char *
#endif
#endif /* !PTR_T */
extern PTR_T xmalloc PARAMS((size_t));
extern PTR_T xrealloc PARAMS((void *, size_t));
extern void xfree PARAMS((void *));
#endif /* _XMALLOC_H_ */