And here the replacement libedit. Fixes some problems on solaris and hopefully on OpenBSD as well :)
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@7502 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
parent
8cc4b29d20
commit
16d6e9901c
|
@ -0,0 +1,23 @@
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
1. Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in the
|
||||||
|
documentation and/or other materials provided with the distribution.
|
||||||
|
3. Neither the name of the University nor the names of its contributors
|
||||||
|
may be used to endorse or promote products derived from this software
|
||||||
|
without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
SUCH DAMAGE.
|
|
@ -0,0 +1,219 @@
|
||||||
|
2007-08-31 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:26:0
|
||||||
|
|
||||||
|
* libedit.pc.in,Makefile.am,configure.ac,patches/extra_dist_list.sh:
|
||||||
|
Added pkg-config support for libedit. Patch by Masatake YAMATO.
|
||||||
|
|
||||||
|
2007-08-13 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:25:0
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
2007-03-02 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:24:0
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
2006-10-22 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:23:0
|
||||||
|
|
||||||
|
* src/shlib_version: Upstream bumped minor version from 9 to 10.
|
||||||
|
|
||||||
|
* all: sync with upstream source. More readline functions.
|
||||||
|
|
||||||
|
2006-10-22 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:22:0
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
2006-08-29 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:21:0
|
||||||
|
|
||||||
|
* all: License cleanup. All 4-clause advertising BSD licenses has been
|
||||||
|
changed to the 3-clause version by upstream.
|
||||||
|
|
||||||
|
* src/fgetln.c: use src/tools/compat/fgetln.c instead of
|
||||||
|
othersrc/libexec/tnftpd/libnetbsd/fgetln.c
|
||||||
|
|
||||||
|
2006-08-16 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:20:0
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
2006-06-03 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:19:0
|
||||||
|
|
||||||
|
* COPYING: added global license file
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
2006-02-13 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:18:0
|
||||||
|
|
||||||
|
* src/readline.c: Partial rl_getc_function support, patch by Kjeld Borch
|
||||||
|
Egevang.
|
||||||
|
|
||||||
|
* src/readline.c: Make write_history and read_history returncode readline
|
||||||
|
compatible. Upstream patch.
|
||||||
|
|
||||||
|
2006-01-03 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:17:0
|
||||||
|
|
||||||
|
* patches/cvs_export.sh: strlcat.c and strlcpy.c was moved to
|
||||||
|
src/common/lib/libc/string in the upstream cvs repository.
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
2005-10-22 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:16:0
|
||||||
|
|
||||||
|
* patches/*.patch, configure.ac: define SCCSID, undef LIBC_SCCS. Remove
|
||||||
|
fourteen cosmetic patches.
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
2005-09-11 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:15:0
|
||||||
|
|
||||||
|
* src/Makefile.am: fix typo that meant generated files were distributes,
|
||||||
|
and make generated file targets dependent on the the 'makelist' input
|
||||||
|
files.
|
||||||
|
|
||||||
|
* all: sync with upstream source. This is just a manpage update
|
||||||
|
|
||||||
|
2005-08-28 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:14:0
|
||||||
|
|
||||||
|
* src/sys.h: include config.h to avoid "redefinition of
|
||||||
|
`u_int32_t'". Patch by Norihiko Murase.
|
||||||
|
|
||||||
|
* src/search.c: explicitly include sys/types.h, because regex.h on
|
||||||
|
FreeBSD needs it and does not include it itself. Patch by Norihiko Murase.
|
||||||
|
|
||||||
|
* acinclude.m4: added EL_GETPW_R_DRAFT test and use AC_TRY_LINK instead
|
||||||
|
of AC_TRY_COMPILE. Suggested by Norihiko Murase.
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
2005-08-16 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:13:0
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
2005-08-05 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:12:0
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
2005-07-24 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:11:0
|
||||||
|
|
||||||
|
* histedit.h, histedit.c, readline.c, editline/readline.h: From
|
||||||
|
upstream; added remove_history().
|
||||||
|
|
||||||
|
2005-07-07 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:10:0
|
||||||
|
|
||||||
|
* history.c, key.c: From upstream source; Fix memory leaks found by
|
||||||
|
valgrind.
|
||||||
|
|
||||||
|
2005-06-28 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:9:0
|
||||||
|
|
||||||
|
* src/readline.c: getpwent_r is not POSIX, always use getpwent.
|
||||||
|
Reported by Gerrit P. Haase.
|
||||||
|
|
||||||
|
* src/Makefile.am: Added libtool -no-undefined. This is needed on Cygwin
|
||||||
|
to get a shared editline library. Should not affect other platforms.
|
||||||
|
Suggested by Gerrit P. Haase.
|
||||||
|
|
||||||
|
2005-06-15 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:8:0
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
2005-06-01 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:7:0
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
* src/readline.c, src/filecomplete.c: Solaris use POSIX draft versions
|
||||||
|
of getpwent_r, getpwnam_r and getpwuid_r which return 'struct passwd *'.
|
||||||
|
Define HAVE_GETPW_R_POSIX if these functions are (non draft) POSIX
|
||||||
|
compatible. Patch by Julien Torrès.
|
||||||
|
|
||||||
|
2005-05-28 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:6:0
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
2005-03-11 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:5:0
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
2004-12-07 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:4:0
|
||||||
|
|
||||||
|
* src/readline.c: d_namlen (in struct dirent) is not portable, always
|
||||||
|
use strlen. Patch by Scott Rankin.
|
||||||
|
|
||||||
|
2004-11-27 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:3:0
|
||||||
|
|
||||||
|
* src/history.c: bug #26785 fixed upstream, removed local patch.
|
||||||
|
|
||||||
|
2004-11-06 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:2:0
|
||||||
|
|
||||||
|
* all: sync with upstream source.
|
||||||
|
|
||||||
|
* doc/Makefile.am: If mdoc2man fails, remove empty file. Patch by
|
||||||
|
Darren Tucker.
|
||||||
|
|
||||||
|
2004-10-14 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:1:0
|
||||||
|
|
||||||
|
* doc/Makefile.am: 'make install' twice fails. Remove old links before
|
||||||
|
trying to link the man pages. Patch by Rick Richardson.
|
||||||
|
|
||||||
|
2004-09-28 Jess Thrysoee
|
||||||
|
|
||||||
|
* version-info: 0:0:0
|
||||||
|
|
||||||
|
* acinclude.m4 configure.ac src/Makefile.am: Adhere to
|
||||||
|
LibTools library interface versions recommendation.
|
||||||
|
http://www.gnu.org/software/libtool/manual.html#SEC32
|
||||||
|
|
||||||
|
* doc/Makefile.am: name all manpage links as el_* (e.g. el_history.3)
|
||||||
|
to avoid conflicts.
|
||||||
|
|
||||||
|
2004-09-08 Jess Thrysoee
|
||||||
|
|
||||||
|
* all: Initial package.
|
|
@ -0,0 +1,229 @@
|
||||||
|
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software
|
||||||
|
Foundation, Inc.
|
||||||
|
|
||||||
|
This file is free documentation; the Free Software Foundation gives
|
||||||
|
unlimited permission to copy, distribute and modify it.
|
||||||
|
|
||||||
|
Basic Installation
|
||||||
|
==================
|
||||||
|
|
||||||
|
These are generic installation instructions.
|
||||||
|
|
||||||
|
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 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, and a
|
||||||
|
file `config.log' containing compiler output (useful mainly for
|
||||||
|
debugging `configure').
|
||||||
|
|
||||||
|
It can also use an optional file (typically called `config.cache'
|
||||||
|
and enabled with `--cache-file=config.cache' or simply `-C') that saves
|
||||||
|
the results of its tests to speed up reconfiguring. (Caching is
|
||||||
|
disabled by default to prevent problems with accidental use of stale
|
||||||
|
cache files.)
|
||||||
|
|
||||||
|
If you need to do unusual things to compile the package, please try
|
||||||
|
to figure out how `configure' could check whether to do them, and mail
|
||||||
|
diffs or instructions to the address given in the `README' so they can
|
||||||
|
be considered for the next release. If you are using the cache, and at
|
||||||
|
some point `config.cache' contains results you don't want to keep, you
|
||||||
|
may remove or edit it.
|
||||||
|
|
||||||
|
The file `configure.ac' (or `configure.in') is used to create
|
||||||
|
`configure' by a program called `autoconf'. You only need
|
||||||
|
`configure.ac' 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
|
||||||
|
`sh ./configure' instead to prevent `csh' from trying to execute
|
||||||
|
`configure' itself.
|
||||||
|
|
||||||
|
Running `configure' takes awhile. While running, it prints some
|
||||||
|
messages telling which features it is checking for.
|
||||||
|
|
||||||
|
2. Type `make' to compile the package.
|
||||||
|
|
||||||
|
3. Optionally, type `make check' to run any self-tests that come with
|
||||||
|
the package.
|
||||||
|
|
||||||
|
4. Type `make install' to install the programs and any data files and
|
||||||
|
documentation.
|
||||||
|
|
||||||
|
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
|
||||||
|
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
|
||||||
|
all sorts of other programs in order to regenerate files that came
|
||||||
|
with the distribution.
|
||||||
|
|
||||||
|
Compilers and Options
|
||||||
|
=====================
|
||||||
|
|
||||||
|
Some systems require unusual options for compilation or linking that
|
||||||
|
the `configure' script does not know about. Run `./configure --help'
|
||||||
|
for details on some of the pertinent environment variables.
|
||||||
|
|
||||||
|
You can give `configure' initial values for configuration parameters
|
||||||
|
by setting variables in the command line or in the environment. Here
|
||||||
|
is an example:
|
||||||
|
|
||||||
|
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
|
||||||
|
|
||||||
|
*Note Defining Variables::, for more details.
|
||||||
|
|
||||||
|
Compiling For Multiple Architectures
|
||||||
|
====================================
|
||||||
|
|
||||||
|
You can compile the package for more than one kind of computer at the
|
||||||
|
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
|
||||||
|
supports the `VPATH' variable, such as GNU `make'. `cd' to the
|
||||||
|
directory where you want the object files and executables to go and run
|
||||||
|
the `configure' script. `configure' automatically checks for the
|
||||||
|
source code in the directory that `configure' is in and in `..'.
|
||||||
|
|
||||||
|
If you have to use a `make' that does not support the `VPATH'
|
||||||
|
variable, you have to compile the package for one architecture at a
|
||||||
|
time in the source code directory. After you have installed the
|
||||||
|
package for one architecture, use `make distclean' before reconfiguring
|
||||||
|
for another architecture.
|
||||||
|
|
||||||
|
Installation Names
|
||||||
|
==================
|
||||||
|
|
||||||
|
By default, `make install' will install the package's files in
|
||||||
|
`/usr/local/bin', `/usr/local/man', etc. You can specify an
|
||||||
|
installation prefix other than `/usr/local' by giving `configure' the
|
||||||
|
option `--prefix=PATH'.
|
||||||
|
|
||||||
|
You can specify separate installation prefixes for
|
||||||
|
architecture-specific files and architecture-independent files. If you
|
||||||
|
give `configure' the option `--exec-prefix=PATH', the package will use
|
||||||
|
PATH as the prefix for installing programs and libraries.
|
||||||
|
Documentation and other data files will still use the regular prefix.
|
||||||
|
|
||||||
|
In addition, if you use an unusual directory layout you can give
|
||||||
|
options like `--bindir=PATH' to specify different values for particular
|
||||||
|
kinds of files. Run `configure --help' for a list of the directories
|
||||||
|
you can set and what kinds of files go in them.
|
||||||
|
|
||||||
|
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
|
||||||
|
==========================
|
||||||
|
|
||||||
|
There may be some features `configure' cannot figure out
|
||||||
|
automatically, but needs to determine by the type of machine the package
|
||||||
|
will run on. Usually, assuming the package is built to be run on the
|
||||||
|
_same_ architectures, `configure' can figure that out, but if it prints
|
||||||
|
a message saying it cannot guess the machine type, give it the
|
||||||
|
`--build=TYPE' option. TYPE can either be a short name for the system
|
||||||
|
type, such as `sun4', or a canonical name which has the form:
|
||||||
|
|
||||||
|
CPU-COMPANY-SYSTEM
|
||||||
|
|
||||||
|
where SYSTEM can have one of these forms:
|
||||||
|
|
||||||
|
OS KERNEL-OS
|
||||||
|
|
||||||
|
See the file `config.sub' for the possible values of each field. If
|
||||||
|
`config.sub' isn't included in this package, then this package doesn't
|
||||||
|
need to know the machine type.
|
||||||
|
|
||||||
|
If you are _building_ compiler tools for cross-compiling, you should
|
||||||
|
use the `--target=TYPE' option to select the type of system they will
|
||||||
|
produce code for.
|
||||||
|
|
||||||
|
If you want to _use_ a cross compiler, that generates code for a
|
||||||
|
platform different from the build platform, you should specify the
|
||||||
|
"host" platform (i.e., that on which the generated programs will
|
||||||
|
eventually be run) with `--host=TYPE'.
|
||||||
|
|
||||||
|
Sharing Defaults
|
||||||
|
================
|
||||||
|
|
||||||
|
If you want to set default values for `configure' scripts to share,
|
||||||
|
you can create a site shell script called `config.site' that gives
|
||||||
|
default values for variables like `CC', `cache_file', and `prefix'.
|
||||||
|
`configure' looks for `PREFIX/share/config.site' if it exists, then
|
||||||
|
`PREFIX/etc/config.site' if it exists. Or, you can set the
|
||||||
|
`CONFIG_SITE' environment variable to the location of the site script.
|
||||||
|
A warning: not all `configure' scripts look for a site script.
|
||||||
|
|
||||||
|
Defining Variables
|
||||||
|
==================
|
||||||
|
|
||||||
|
Variables not defined in a site shell script can be set in the
|
||||||
|
environment passed to `configure'. However, some packages may run
|
||||||
|
configure again during the build, and the customized values of these
|
||||||
|
variables may be lost. In order to avoid this problem, you should set
|
||||||
|
them in the `configure' command line, using `VAR=value'. For example:
|
||||||
|
|
||||||
|
./configure CC=/usr/local2/bin/gcc
|
||||||
|
|
||||||
|
will cause the specified gcc to be used as the C compiler (unless it is
|
||||||
|
overridden in the site shell script).
|
||||||
|
|
||||||
|
`configure' Invocation
|
||||||
|
======================
|
||||||
|
|
||||||
|
`configure' recognizes the following options to control how it
|
||||||
|
operates.
|
||||||
|
|
||||||
|
`--help'
|
||||||
|
`-h'
|
||||||
|
Print a summary of the options to `configure', and exit.
|
||||||
|
|
||||||
|
`--version'
|
||||||
|
`-V'
|
||||||
|
Print the version of Autoconf used to generate the `configure'
|
||||||
|
script, and exit.
|
||||||
|
|
||||||
|
`--cache-file=FILE'
|
||||||
|
Enable the cache: use and save the results of the tests in FILE,
|
||||||
|
traditionally `config.cache'. FILE defaults to `/dev/null' to
|
||||||
|
disable caching.
|
||||||
|
|
||||||
|
`--config-cache'
|
||||||
|
`-C'
|
||||||
|
Alias for `--cache-file=config.cache'.
|
||||||
|
|
||||||
|
`--quiet'
|
||||||
|
`--silent'
|
||||||
|
`-q'
|
||||||
|
Do not print messages saying which checks are being made. To
|
||||||
|
suppress all normal output, redirect it to `/dev/null' (any error
|
||||||
|
messages will still be shown).
|
||||||
|
|
||||||
|
`--srcdir=DIR'
|
||||||
|
Look for the package's source code in directory DIR. Usually
|
||||||
|
`configure' can determine that directory automatically.
|
||||||
|
|
||||||
|
`configure' also accepts some other, not widely useful, options. Run
|
||||||
|
`configure --help' for more details.
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
|
||||||
|
AUTOMAKE_OPTIONS = foreign
|
||||||
|
|
||||||
|
SUBDIRS = src examples doc
|
||||||
|
|
||||||
|
EXTRA_DIST = libedit.pc.in
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = libedit.pc
|
||||||
|
|
||||||
|
## GENERATED BY SCRIPT - DO NOT EDIT BELOW
|
||||||
|
|
||||||
|
EXTRA_DIST += patches/README \
|
||||||
|
patches/00-vis.h.patch \
|
||||||
|
patches/01-term.c.patch \
|
||||||
|
patches/02-el_term.h.patch \
|
||||||
|
patches/03-unvis.c.patch \
|
||||||
|
patches/04-strlcpy.c.patch \
|
||||||
|
patches/05-strlcat.c.patch \
|
||||||
|
patches/06-readline.c.patch \
|
||||||
|
patches/07-sys.h.patch \
|
||||||
|
patches/08-el.h.patch \
|
||||||
|
patches/09-search.c.patch \
|
||||||
|
patches/10-readline.h.patch \
|
||||||
|
patches/11-el.c.patch \
|
||||||
|
patches/12-history.c.patch \
|
||||||
|
patches/13-vis.c.patch \
|
||||||
|
patches/14-fgetln.c.patch \
|
||||||
|
patches/15-filecomplete.c.patch \
|
||||||
|
patches/16-tc1.c.patch \
|
||||||
|
patches/17-editline.3.roff.patch \
|
||||||
|
patches/18-editrc.5.roff.patch \
|
||||||
|
patches/cvs_export.sh \
|
||||||
|
patches/patches_make.sh \
|
||||||
|
patches/patches_apply.sh \
|
||||||
|
patches/patches_check.sh \
|
||||||
|
patches/extra_dist_list.sh \
|
||||||
|
patches/update_version.sh \
|
||||||
|
patches/update_dist.sh \
|
||||||
|
patches/timestamp.cvsexport
|
||||||
|
|
|
@ -0,0 +1,672 @@
|
||||||
|
# Makefile.in generated by automake 1.9.6 from Makefile.am.
|
||||||
|
# @configure_input@
|
||||||
|
|
||||||
|
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||||
|
# 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||||
|
# This Makefile.in is free software; the Free Software Foundation
|
||||||
|
# gives unlimited permission to copy and/or distribute it,
|
||||||
|
# with or without modifications, as long as this notice is preserved.
|
||||||
|
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||||
|
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
# PARTICULAR PURPOSE.
|
||||||
|
|
||||||
|
@SET_MAKE@
|
||||||
|
|
||||||
|
srcdir = @srcdir@
|
||||||
|
top_srcdir = @top_srcdir@
|
||||||
|
VPATH = @srcdir@
|
||||||
|
pkgdatadir = $(datadir)/@PACKAGE@
|
||||||
|
pkglibdir = $(libdir)/@PACKAGE@
|
||||||
|
pkgincludedir = $(includedir)/@PACKAGE@
|
||||||
|
top_builddir = .
|
||||||
|
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
install_sh_DATA = $(install_sh) -c -m 644
|
||||||
|
install_sh_PROGRAM = $(install_sh) -c
|
||||||
|
install_sh_SCRIPT = $(install_sh) -c
|
||||||
|
INSTALL_HEADER = $(INSTALL_DATA)
|
||||||
|
transform = $(program_transform_name)
|
||||||
|
NORMAL_INSTALL = :
|
||||||
|
PRE_INSTALL = :
|
||||||
|
POST_INSTALL = :
|
||||||
|
NORMAL_UNINSTALL = :
|
||||||
|
PRE_UNINSTALL = :
|
||||||
|
POST_UNINSTALL = :
|
||||||
|
build_triplet = @build@
|
||||||
|
host_triplet = @host@
|
||||||
|
DIST_COMMON = $(am__configure_deps) $(srcdir)/Makefile.am \
|
||||||
|
$(srcdir)/Makefile.in $(srcdir)/config.h.in \
|
||||||
|
$(srcdir)/libedit.pc.in $(top_srcdir)/configure COPYING \
|
||||||
|
ChangeLog INSTALL THANKS config.guess config.sub depcomp \
|
||||||
|
install-sh ltmain.sh missing
|
||||||
|
subdir = .
|
||||||
|
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||||
|
am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \
|
||||||
|
$(top_srcdir)/configure.ac
|
||||||
|
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||||
|
$(ACLOCAL_M4)
|
||||||
|
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||||
|
configure.lineno configure.status.lineno
|
||||||
|
mkinstalldirs = $(install_sh) -d
|
||||||
|
CONFIG_HEADER = config.h
|
||||||
|
CONFIG_CLEAN_FILES = libedit.pc
|
||||||
|
SOURCES =
|
||||||
|
DIST_SOURCES =
|
||||||
|
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
|
||||||
|
html-recursive info-recursive install-data-recursive \
|
||||||
|
install-exec-recursive install-info-recursive \
|
||||||
|
install-recursive installcheck-recursive installdirs-recursive \
|
||||||
|
pdf-recursive ps-recursive uninstall-info-recursive \
|
||||||
|
uninstall-recursive
|
||||||
|
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||||
|
am__vpath_adj = case $$p in \
|
||||||
|
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||||
|
*) f=$$p;; \
|
||||||
|
esac;
|
||||||
|
am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
|
||||||
|
am__installdirs = "$(DESTDIR)$(pkgconfigdir)"
|
||||||
|
pkgconfigDATA_INSTALL = $(INSTALL_DATA)
|
||||||
|
DATA = $(pkgconfig_DATA)
|
||||||
|
ETAGS = etags
|
||||||
|
CTAGS = ctags
|
||||||
|
DIST_SUBDIRS = $(SUBDIRS)
|
||||||
|
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||||
|
distdir = $(PACKAGE)-$(VERSION)
|
||||||
|
top_distdir = $(distdir)
|
||||||
|
am__remove_distdir = \
|
||||||
|
{ test ! -d $(distdir) \
|
||||||
|
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
|
||||||
|
&& rm -fr $(distdir); }; }
|
||||||
|
DIST_ARCHIVES = $(distdir).tar.gz
|
||||||
|
GZIP_ENV = --best
|
||||||
|
distuninstallcheck_listfiles = find . -type f -print
|
||||||
|
distcleancheck_listfiles = find . -type f -print
|
||||||
|
ACLOCAL = @ACLOCAL@
|
||||||
|
ALLOCA = @ALLOCA@
|
||||||
|
AMDEP_FALSE = @AMDEP_FALSE@
|
||||||
|
AMDEP_TRUE = @AMDEP_TRUE@
|
||||||
|
AMTAR = @AMTAR@
|
||||||
|
AR = @AR@
|
||||||
|
AUTOCONF = @AUTOCONF@
|
||||||
|
AUTOHEADER = @AUTOHEADER@
|
||||||
|
AUTOMAKE = @AUTOMAKE@
|
||||||
|
AWK = @AWK@
|
||||||
|
CC = @CC@
|
||||||
|
CCDEPMODE = @CCDEPMODE@
|
||||||
|
CFLAGS = @CFLAGS@
|
||||||
|
CPP = @CPP@
|
||||||
|
CPPFLAGS = @CPPFLAGS@
|
||||||
|
CXX = @CXX@
|
||||||
|
CXXCPP = @CXXCPP@
|
||||||
|
CXXDEPMODE = @CXXDEPMODE@
|
||||||
|
CXXFLAGS = @CXXFLAGS@
|
||||||
|
CYGPATH_W = @CYGPATH_W@
|
||||||
|
DEFS = @DEFS@
|
||||||
|
DEPDIR = @DEPDIR@
|
||||||
|
ECHO = @ECHO@
|
||||||
|
ECHO_C = @ECHO_C@
|
||||||
|
ECHO_N = @ECHO_N@
|
||||||
|
ECHO_T = @ECHO_T@
|
||||||
|
EGREP = @EGREP@
|
||||||
|
EXEEXT = @EXEEXT@
|
||||||
|
F77 = @F77@
|
||||||
|
FFLAGS = @FFLAGS@
|
||||||
|
GREP = @GREP@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
|
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||||
|
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
LIBOBJS = @LIBOBJS@
|
||||||
|
LIBS = @LIBS@
|
||||||
|
LIBTOOL = @LIBTOOL@
|
||||||
|
LN_S = @LN_S@
|
||||||
|
LTLIBOBJS = @LTLIBOBJS@
|
||||||
|
LT_VERSION = @LT_VERSION@
|
||||||
|
MAKEINFO = @MAKEINFO@
|
||||||
|
MANTYPE = @MANTYPE@
|
||||||
|
NROFF = @NROFF@
|
||||||
|
OBJEXT = @OBJEXT@
|
||||||
|
PACKAGE = @PACKAGE@
|
||||||
|
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||||
|
PACKAGE_NAME = @PACKAGE_NAME@
|
||||||
|
PACKAGE_STRING = @PACKAGE_STRING@
|
||||||
|
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||||
|
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||||
|
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||||
|
RANLIB = @RANLIB@
|
||||||
|
SED = @SED@
|
||||||
|
SET_MAKE = @SET_MAKE@
|
||||||
|
SHELL = @SHELL@
|
||||||
|
STRIP = @STRIP@
|
||||||
|
VERSION = @VERSION@
|
||||||
|
ac_ct_CC = @ac_ct_CC@
|
||||||
|
ac_ct_CXX = @ac_ct_CXX@
|
||||||
|
ac_ct_F77 = @ac_ct_F77@
|
||||||
|
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
|
||||||
|
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
|
||||||
|
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
|
||||||
|
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
|
||||||
|
am__include = @am__include@
|
||||||
|
am__leading_dot = @am__leading_dot@
|
||||||
|
am__quote = @am__quote@
|
||||||
|
am__tar = @am__tar@
|
||||||
|
am__untar = @am__untar@
|
||||||
|
bindir = @bindir@
|
||||||
|
build = @build@
|
||||||
|
build_alias = @build_alias@
|
||||||
|
build_cpu = @build_cpu@
|
||||||
|
build_os = @build_os@
|
||||||
|
build_vendor = @build_vendor@
|
||||||
|
datadir = @datadir@
|
||||||
|
datarootdir = @datarootdir@
|
||||||
|
docdir = @docdir@
|
||||||
|
dvidir = @dvidir@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
host = @host@
|
||||||
|
host_alias = @host_alias@
|
||||||
|
host_cpu = @host_cpu@
|
||||||
|
host_os = @host_os@
|
||||||
|
host_vendor = @host_vendor@
|
||||||
|
htmldir = @htmldir@
|
||||||
|
includedir = @includedir@
|
||||||
|
infodir = @infodir@
|
||||||
|
install_sh = @install_sh@
|
||||||
|
libdir = @libdir@
|
||||||
|
libexecdir = @libexecdir@
|
||||||
|
localedir = @localedir@
|
||||||
|
localstatedir = @localstatedir@
|
||||||
|
mandir = @mandir@
|
||||||
|
mkdir_p = @mkdir_p@
|
||||||
|
oldincludedir = @oldincludedir@
|
||||||
|
pdfdir = @pdfdir@
|
||||||
|
prefix = @prefix@
|
||||||
|
program_transform_name = @program_transform_name@
|
||||||
|
psdir = @psdir@
|
||||||
|
sbindir = @sbindir@
|
||||||
|
sharedstatedir = @sharedstatedir@
|
||||||
|
sysconfdir = @sysconfdir@
|
||||||
|
target_alias = @target_alias@
|
||||||
|
AUTOMAKE_OPTIONS = foreign
|
||||||
|
SUBDIRS = src examples doc
|
||||||
|
EXTRA_DIST = libedit.pc.in patches/README patches/00-vis.h.patch \
|
||||||
|
patches/01-term.c.patch patches/02-el_term.h.patch \
|
||||||
|
patches/03-unvis.c.patch patches/04-strlcpy.c.patch \
|
||||||
|
patches/05-strlcat.c.patch patches/06-readline.c.patch \
|
||||||
|
patches/07-sys.h.patch patches/08-el.h.patch \
|
||||||
|
patches/09-search.c.patch patches/10-readline.h.patch \
|
||||||
|
patches/11-el.c.patch patches/12-history.c.patch \
|
||||||
|
patches/13-vis.c.patch patches/14-fgetln.c.patch \
|
||||||
|
patches/15-filecomplete.c.patch patches/16-tc1.c.patch \
|
||||||
|
patches/17-editline.3.roff.patch \
|
||||||
|
patches/18-editrc.5.roff.patch patches/cvs_export.sh \
|
||||||
|
patches/patches_make.sh patches/patches_apply.sh \
|
||||||
|
patches/patches_check.sh patches/extra_dist_list.sh \
|
||||||
|
patches/update_version.sh patches/update_dist.sh \
|
||||||
|
patches/timestamp.cvsexport
|
||||||
|
pkgconfigdir = $(libdir)/pkgconfig
|
||||||
|
pkgconfig_DATA = libedit.pc
|
||||||
|
all: config.h
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) all-recursive
|
||||||
|
|
||||||
|
.SUFFIXES:
|
||||||
|
am--refresh:
|
||||||
|
@:
|
||||||
|
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
|
||||||
|
@for dep in $?; do \
|
||||||
|
case '$(am__configure_deps)' in \
|
||||||
|
*$$dep*) \
|
||||||
|
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign '; \
|
||||||
|
cd $(srcdir) && $(AUTOMAKE) --foreign \
|
||||||
|
&& exit 0; \
|
||||||
|
exit 1;; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
|
||||||
|
cd $(top_srcdir) && \
|
||||||
|
$(AUTOMAKE) --foreign Makefile
|
||||||
|
.PRECIOUS: Makefile
|
||||||
|
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||||
|
@case '$?' in \
|
||||||
|
*config.status*) \
|
||||||
|
echo ' $(SHELL) ./config.status'; \
|
||||||
|
$(SHELL) ./config.status;; \
|
||||||
|
*) \
|
||||||
|
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
|
||||||
|
esac;
|
||||||
|
|
||||||
|
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||||
|
$(SHELL) ./config.status --recheck
|
||||||
|
|
||||||
|
$(top_srcdir)/configure: $(am__configure_deps)
|
||||||
|
cd $(srcdir) && $(AUTOCONF)
|
||||||
|
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
|
||||||
|
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
|
||||||
|
|
||||||
|
config.h: stamp-h1
|
||||||
|
@if test ! -f $@; then \
|
||||||
|
rm -f stamp-h1; \
|
||||||
|
$(MAKE) stamp-h1; \
|
||||||
|
else :; fi
|
||||||
|
|
||||||
|
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
|
||||||
|
@rm -f stamp-h1
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status config.h
|
||||||
|
$(srcdir)/config.h.in: $(am__configure_deps)
|
||||||
|
cd $(top_srcdir) && $(AUTOHEADER)
|
||||||
|
rm -f stamp-h1
|
||||||
|
touch $@
|
||||||
|
|
||||||
|
distclean-hdr:
|
||||||
|
-rm -f config.h stamp-h1
|
||||||
|
libedit.pc: $(top_builddir)/config.status $(srcdir)/libedit.pc.in
|
||||||
|
cd $(top_builddir) && $(SHELL) ./config.status $@
|
||||||
|
|
||||||
|
mostlyclean-libtool:
|
||||||
|
-rm -f *.lo
|
||||||
|
|
||||||
|
clean-libtool:
|
||||||
|
-rm -rf .libs _libs
|
||||||
|
|
||||||
|
distclean-libtool:
|
||||||
|
-rm -f libtool
|
||||||
|
uninstall-info-am:
|
||||||
|
install-pkgconfigDATA: $(pkgconfig_DATA)
|
||||||
|
@$(NORMAL_INSTALL)
|
||||||
|
test -z "$(pkgconfigdir)" || $(mkdir_p) "$(DESTDIR)$(pkgconfigdir)"
|
||||||
|
@list='$(pkgconfig_DATA)'; for p in $$list; do \
|
||||||
|
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||||
|
f=$(am__strip_dir) \
|
||||||
|
echo " $(pkgconfigDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
|
||||||
|
$(pkgconfigDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(pkgconfigdir)/$$f"; \
|
||||||
|
done
|
||||||
|
|
||||||
|
uninstall-pkgconfigDATA:
|
||||||
|
@$(NORMAL_UNINSTALL)
|
||||||
|
@list='$(pkgconfig_DATA)'; for p in $$list; do \
|
||||||
|
f=$(am__strip_dir) \
|
||||||
|
echo " rm -f '$(DESTDIR)$(pkgconfigdir)/$$f'"; \
|
||||||
|
rm -f "$(DESTDIR)$(pkgconfigdir)/$$f"; \
|
||||||
|
done
|
||||||
|
|
||||||
|
# This directory's subdirectories are mostly independent; you can cd
|
||||||
|
# into them and run `make' without going through this Makefile.
|
||||||
|
# To change the values of `make' variables: instead of editing Makefiles,
|
||||||
|
# (1) if the variable is set in `config.status', edit `config.status'
|
||||||
|
# (which will cause the Makefiles to be regenerated when you run `make');
|
||||||
|
# (2) otherwise, pass the desired values on the `make' command line.
|
||||||
|
$(RECURSIVE_TARGETS):
|
||||||
|
@failcom='exit 1'; \
|
||||||
|
for f in x $$MAKEFLAGS; do \
|
||||||
|
case $$f in \
|
||||||
|
*=* | --[!k]*);; \
|
||||||
|
*k*) failcom='fail=yes';; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
dot_seen=no; \
|
||||||
|
target=`echo $@ | sed s/-recursive//`; \
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
echo "Making $$target in $$subdir"; \
|
||||||
|
if test "$$subdir" = "."; then \
|
||||||
|
dot_seen=yes; \
|
||||||
|
local_target="$$target-am"; \
|
||||||
|
else \
|
||||||
|
local_target="$$target"; \
|
||||||
|
fi; \
|
||||||
|
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||||
|
|| eval $$failcom; \
|
||||||
|
done; \
|
||||||
|
if test "$$dot_seen" = "no"; then \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
|
||||||
|
fi; test -z "$$fail"
|
||||||
|
|
||||||
|
mostlyclean-recursive clean-recursive distclean-recursive \
|
||||||
|
maintainer-clean-recursive:
|
||||||
|
@failcom='exit 1'; \
|
||||||
|
for f in x $$MAKEFLAGS; do \
|
||||||
|
case $$f in \
|
||||||
|
*=* | --[!k]*);; \
|
||||||
|
*k*) failcom='fail=yes';; \
|
||||||
|
esac; \
|
||||||
|
done; \
|
||||||
|
dot_seen=no; \
|
||||||
|
case "$@" in \
|
||||||
|
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
|
||||||
|
*) list='$(SUBDIRS)' ;; \
|
||||||
|
esac; \
|
||||||
|
rev=''; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = "."; then :; else \
|
||||||
|
rev="$$subdir $$rev"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
rev="$$rev ."; \
|
||||||
|
target=`echo $@ | sed s/-recursive//`; \
|
||||||
|
for subdir in $$rev; do \
|
||||||
|
echo "Making $$target in $$subdir"; \
|
||||||
|
if test "$$subdir" = "."; then \
|
||||||
|
local_target="$$target-am"; \
|
||||||
|
else \
|
||||||
|
local_target="$$target"; \
|
||||||
|
fi; \
|
||||||
|
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|
||||||
|
|| eval $$failcom; \
|
||||||
|
done && test -z "$$fail"
|
||||||
|
tags-recursive:
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
|
||||||
|
done
|
||||||
|
ctags-recursive:
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
|
||||||
|
done
|
||||||
|
|
||||||
|
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||||
|
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
mkid -fID $$unique
|
||||||
|
tags: TAGS
|
||||||
|
|
||||||
|
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
tags=; \
|
||||||
|
here=`pwd`; \
|
||||||
|
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
|
||||||
|
include_option=--etags-include; \
|
||||||
|
empty_fix=.; \
|
||||||
|
else \
|
||||||
|
include_option=--include; \
|
||||||
|
empty_fix=; \
|
||||||
|
fi; \
|
||||||
|
list='$(SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = .; then :; else \
|
||||||
|
test ! -f $$subdir/TAGS || \
|
||||||
|
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
|
||||||
|
fi; \
|
||||||
|
done; \
|
||||||
|
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
|
||||||
|
test -n "$$unique" || unique=$$empty_fix; \
|
||||||
|
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||||
|
$$tags $$unique; \
|
||||||
|
fi
|
||||||
|
ctags: CTAGS
|
||||||
|
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
|
||||||
|
$(TAGS_FILES) $(LISP)
|
||||||
|
tags=; \
|
||||||
|
here=`pwd`; \
|
||||||
|
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||||
|
unique=`for i in $$list; do \
|
||||||
|
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||||
|
done | \
|
||||||
|
$(AWK) ' { files[$$0] = 1; } \
|
||||||
|
END { for (i in files) print i; }'`; \
|
||||||
|
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|
||||||
|
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||||
|
$$tags $$unique
|
||||||
|
|
||||||
|
GTAGS:
|
||||||
|
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||||
|
&& cd $(top_srcdir) \
|
||||||
|
&& gtags -i $(GTAGS_ARGS) $$here
|
||||||
|
|
||||||
|
distclean-tags:
|
||||||
|
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||||
|
|
||||||
|
distdir: $(DISTFILES)
|
||||||
|
$(am__remove_distdir)
|
||||||
|
mkdir $(distdir)
|
||||||
|
$(mkdir_p) $(distdir)/. $(distdir)/patches
|
||||||
|
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
|
||||||
|
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
|
||||||
|
list='$(DISTFILES)'; for file in $$list; do \
|
||||||
|
case $$file in \
|
||||||
|
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
|
||||||
|
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
|
||||||
|
esac; \
|
||||||
|
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||||
|
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||||
|
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
|
||||||
|
dir="/$$dir"; \
|
||||||
|
$(mkdir_p) "$(distdir)$$dir"; \
|
||||||
|
else \
|
||||||
|
dir=''; \
|
||||||
|
fi; \
|
||||||
|
if test -d $$d/$$file; then \
|
||||||
|
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||||
|
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
|
||||||
|
fi; \
|
||||||
|
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
|
||||||
|
else \
|
||||||
|
test -f $(distdir)/$$file \
|
||||||
|
|| cp -p $$d/$$file $(distdir)/$$file \
|
||||||
|
|| exit 1; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
|
||||||
|
if test "$$subdir" = .; then :; else \
|
||||||
|
test -d "$(distdir)/$$subdir" \
|
||||||
|
|| $(mkdir_p) "$(distdir)/$$subdir" \
|
||||||
|
|| exit 1; \
|
||||||
|
distdir=`$(am__cd) $(distdir) && pwd`; \
|
||||||
|
top_distdir=`$(am__cd) $(top_distdir) && pwd`; \
|
||||||
|
(cd $$subdir && \
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) \
|
||||||
|
top_distdir="$$top_distdir" \
|
||||||
|
distdir="$$distdir/$$subdir" \
|
||||||
|
distdir) \
|
||||||
|
|| exit 1; \
|
||||||
|
fi; \
|
||||||
|
done
|
||||||
|
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
|
||||||
|
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
|
||||||
|
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
|
||||||
|
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|
||||||
|
|| chmod -R a+r $(distdir)
|
||||||
|
dist-gzip: distdir
|
||||||
|
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
dist-bzip2: distdir
|
||||||
|
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
dist-tarZ: distdir
|
||||||
|
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
dist-shar: distdir
|
||||||
|
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
dist-zip: distdir
|
||||||
|
-rm -f $(distdir).zip
|
||||||
|
zip -rq $(distdir).zip $(distdir)
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
dist dist-all: distdir
|
||||||
|
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||||
|
$(am__remove_distdir)
|
||||||
|
|
||||||
|
# This target untars the dist file and tries a VPATH configuration. Then
|
||||||
|
# it guarantees that the distribution is self-contained by making another
|
||||||
|
# tarfile.
|
||||||
|
distcheck: dist
|
||||||
|
case '$(DIST_ARCHIVES)' in \
|
||||||
|
*.tar.gz*) \
|
||||||
|
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(am__untar) ;;\
|
||||||
|
*.tar.bz2*) \
|
||||||
|
bunzip2 -c $(distdir).tar.bz2 | $(am__untar) ;;\
|
||||||
|
*.tar.Z*) \
|
||||||
|
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
|
||||||
|
*.shar.gz*) \
|
||||||
|
GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
|
||||||
|
*.zip*) \
|
||||||
|
unzip $(distdir).zip ;;\
|
||||||
|
esac
|
||||||
|
chmod -R a-w $(distdir); chmod a+w $(distdir)
|
||||||
|
mkdir $(distdir)/_build
|
||||||
|
mkdir $(distdir)/_inst
|
||||||
|
chmod a-w $(distdir)
|
||||||
|
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
|
||||||
|
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
|
||||||
|
&& cd $(distdir)/_build \
|
||||||
|
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
|
||||||
|
$(DISTCHECK_CONFIGURE_FLAGS) \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
|
||||||
|
distuninstallcheck \
|
||||||
|
&& chmod -R a-w "$$dc_install_base" \
|
||||||
|
&& ({ \
|
||||||
|
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
|
||||||
|
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
|
||||||
|
} || { rm -rf "$$dc_destdir"; exit 1; }) \
|
||||||
|
&& rm -rf "$$dc_destdir" \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) dist \
|
||||||
|
&& rm -rf $(DIST_ARCHIVES) \
|
||||||
|
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
|
||||||
|
$(am__remove_distdir)
|
||||||
|
@(echo "$(distdir) archives ready for distribution: "; \
|
||||||
|
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
|
||||||
|
sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
|
||||||
|
distuninstallcheck:
|
||||||
|
@cd $(distuninstallcheck_dir) \
|
||||||
|
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|
||||||
|
|| { echo "ERROR: files left after uninstall:" ; \
|
||||||
|
if test -n "$(DESTDIR)"; then \
|
||||||
|
echo " (check DESTDIR support)"; \
|
||||||
|
fi ; \
|
||||||
|
$(distuninstallcheck_listfiles) ; \
|
||||||
|
exit 1; } >&2
|
||||||
|
distcleancheck: distclean
|
||||||
|
@if test '$(srcdir)' = . ; then \
|
||||||
|
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
|
||||||
|
exit 1 ; \
|
||||||
|
fi
|
||||||
|
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|
||||||
|
|| { echo "ERROR: files left in build directory after distclean:" ; \
|
||||||
|
$(distcleancheck_listfiles) ; \
|
||||||
|
exit 1; } >&2
|
||||||
|
check-am: all-am
|
||||||
|
check: check-recursive
|
||||||
|
all-am: Makefile $(DATA) config.h
|
||||||
|
installdirs: installdirs-recursive
|
||||||
|
installdirs-am:
|
||||||
|
for dir in "$(DESTDIR)$(pkgconfigdir)"; do \
|
||||||
|
test -z "$$dir" || $(mkdir_p) "$$dir"; \
|
||||||
|
done
|
||||||
|
install: install-recursive
|
||||||
|
install-exec: install-exec-recursive
|
||||||
|
install-data: install-data-recursive
|
||||||
|
uninstall: uninstall-recursive
|
||||||
|
|
||||||
|
install-am: all-am
|
||||||
|
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||||
|
|
||||||
|
installcheck: installcheck-recursive
|
||||||
|
install-strip:
|
||||||
|
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||||
|
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||||
|
`test -z '$(STRIP)' || \
|
||||||
|
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||||
|
mostlyclean-generic:
|
||||||
|
|
||||||
|
clean-generic:
|
||||||
|
|
||||||
|
distclean-generic:
|
||||||
|
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||||
|
|
||||||
|
maintainer-clean-generic:
|
||||||
|
@echo "This command is intended for maintainers to use"
|
||||||
|
@echo "it deletes files that may require special tools to rebuild."
|
||||||
|
clean: clean-recursive
|
||||||
|
|
||||||
|
clean-am: clean-generic clean-libtool mostlyclean-am
|
||||||
|
|
||||||
|
distclean: distclean-recursive
|
||||||
|
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||||
|
-rm -f Makefile
|
||||||
|
distclean-am: clean-am distclean-generic distclean-hdr \
|
||||||
|
distclean-libtool distclean-tags
|
||||||
|
|
||||||
|
dvi: dvi-recursive
|
||||||
|
|
||||||
|
dvi-am:
|
||||||
|
|
||||||
|
html: html-recursive
|
||||||
|
|
||||||
|
info: info-recursive
|
||||||
|
|
||||||
|
info-am:
|
||||||
|
|
||||||
|
install-data-am: install-pkgconfigDATA
|
||||||
|
|
||||||
|
install-exec-am:
|
||||||
|
|
||||||
|
install-info: install-info-recursive
|
||||||
|
|
||||||
|
install-man:
|
||||||
|
|
||||||
|
installcheck-am:
|
||||||
|
|
||||||
|
maintainer-clean: maintainer-clean-recursive
|
||||||
|
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||||
|
-rm -rf $(top_srcdir)/autom4te.cache
|
||||||
|
-rm -f Makefile
|
||||||
|
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||||
|
|
||||||
|
mostlyclean: mostlyclean-recursive
|
||||||
|
|
||||||
|
mostlyclean-am: mostlyclean-generic mostlyclean-libtool
|
||||||
|
|
||||||
|
pdf: pdf-recursive
|
||||||
|
|
||||||
|
pdf-am:
|
||||||
|
|
||||||
|
ps: ps-recursive
|
||||||
|
|
||||||
|
ps-am:
|
||||||
|
|
||||||
|
uninstall-am: uninstall-info-am uninstall-pkgconfigDATA
|
||||||
|
|
||||||
|
uninstall-info: uninstall-info-recursive
|
||||||
|
|
||||||
|
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
|
||||||
|
check-am clean clean-generic clean-libtool clean-recursive \
|
||||||
|
ctags ctags-recursive dist dist-all dist-bzip2 dist-gzip \
|
||||||
|
dist-shar dist-tarZ dist-zip distcheck distclean \
|
||||||
|
distclean-generic distclean-hdr distclean-libtool \
|
||||||
|
distclean-recursive distclean-tags distcleancheck distdir \
|
||||||
|
distuninstallcheck dvi dvi-am html html-am info info-am \
|
||||||
|
install install-am install-data install-data-am install-exec \
|
||||||
|
install-exec-am install-info install-info-am install-man \
|
||||||
|
install-pkgconfigDATA install-strip installcheck \
|
||||||
|
installcheck-am installdirs installdirs-am maintainer-clean \
|
||||||
|
maintainer-clean-generic maintainer-clean-recursive \
|
||||||
|
mostlyclean mostlyclean-generic mostlyclean-libtool \
|
||||||
|
mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \
|
||||||
|
uninstall uninstall-am uninstall-info-am \
|
||||||
|
uninstall-pkgconfigDATA
|
||||||
|
|
||||||
|
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||||
|
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||||
|
.NOEXPORT:
|
|
@ -0,0 +1 @@
|
||||||
|
Thanks to the NetBSD Project maintainers of libedit!
|
|
@ -0,0 +1,67 @@
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl read lib version from file (and trim trailing newline)
|
||||||
|
dnl
|
||||||
|
define([EL_RELEASE], [patsubst(esyscmd([. src/shlib_version; echo $major.$minor]), [
|
||||||
|
])])
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl read cvsexport timestamp from file (and trim trailing newline)
|
||||||
|
dnl
|
||||||
|
dnl define([EL_TIMESTAMP_CVSEXPORT], [patsubst(esyscmd([cat patches/timestamp.cvsexport]), [
|
||||||
|
define([EL_TIMESTAMP_CVSEXPORT], [patsubst(esyscmd([date +"%Y%m%d"]), [
|
||||||
|
])])
|
||||||
|
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl NetBSD use the -mdoc macro package for manpages, but e.g.
|
||||||
|
dnl AIX and Solaris only support the -man package.
|
||||||
|
dnl
|
||||||
|
AC_DEFUN([EL_MANTYPE],
|
||||||
|
[
|
||||||
|
MANTYPE=
|
||||||
|
TestPath="/usr/bin${PATH_SEPARATOR}/usr/ucb"
|
||||||
|
AC_PATH_PROGS(NROFF, nroff awf, /bin/false, $TestPath)
|
||||||
|
if ${NROFF} -mdoc ${srcdir}/doc/editrc.5.roff >/dev/null 2>&1; then
|
||||||
|
MANTYPE=mdoc
|
||||||
|
fi
|
||||||
|
AC_SUBST(MANTYPE)
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
dnl
|
||||||
|
dnl Check if getpwnam_r and getpwuid_r are POSIX.1 compatible
|
||||||
|
dnl POSIX draft version returns 'struct passwd *' (used on Solaris)
|
||||||
|
dnl NOTE: getpwent_r is not POSIX so we always use getpwent
|
||||||
|
dnl
|
||||||
|
AC_DEFUN([EL_GETPW_R_POSIX],
|
||||||
|
[
|
||||||
|
AC_MSG_CHECKING([whether getpwnam_r and getpwuid_r are posix like])
|
||||||
|
# The prototype for the POSIX version is:
|
||||||
|
# int getpwnam_r(char *, struct passwd *, char *, size_t, struct passwd **)
|
||||||
|
# int getpwuid_r(uid_t, struct passwd *, char *, size_t, struct passwd **);
|
||||||
|
AC_TRY_LINK([#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <pwd.h>],
|
||||||
|
[getpwnam_r(NULL, NULL, NULL, (size_t)0, NULL);
|
||||||
|
getpwuid_r((uid_t)0, NULL, NULL, (size_t)0, NULL);],
|
||||||
|
[AC_DEFINE([HAVE_GETPW_R_POSIX], 1, [Define to 1 if you have getpwnam_r and getpwuid_r that are POSIX.1 compatible.])
|
||||||
|
AC_MSG_RESULT(yes)],
|
||||||
|
[AC_MSG_RESULT(no)])
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_DEFUN([EL_GETPW_R_DRAFT],
|
||||||
|
[
|
||||||
|
AC_MSG_CHECKING([whether getpwnam_r and getpwuid_r are posix _draft_ like])
|
||||||
|
# The prototype for the POSIX draft version is:
|
||||||
|
# struct passwd *getpwuid_r(uid_t, struct passwd *, char *, int);
|
||||||
|
# struct passwd *getpwnam_r(char *, struct passwd *, char *, int);
|
||||||
|
AC_TRY_LINK([#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <pwd.h>],
|
||||||
|
[getpwnam_r(NULL, NULL, NULL, (size_t)0);
|
||||||
|
getpwuid_r((uid_t)0, NULL, NULL, (size_t)0);],
|
||||||
|
[AC_DEFINE([HAVE_GETPW_R_DRAFT], 1, [Define to 1 if you have getpwnam_r and getpwuid_r that are draft POSIX.1 versions.])
|
||||||
|
AC_MSG_RESULT(yes)],
|
||||||
|
[AC_MSG_RESULT(no)])
|
||||||
|
])
|
|
@ -0,0 +1,235 @@
|
||||||
|
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||||
|
|
||||||
|
/* Define to 1 if the `closedir' function returns void instead of `int'. */
|
||||||
|
#undef CLOSEDIR_VOID
|
||||||
|
|
||||||
|
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
|
||||||
|
systems. This function is required for `alloca.c' support on those systems.
|
||||||
|
*/
|
||||||
|
#undef CRAY_STACKSEG_END
|
||||||
|
|
||||||
|
/* Define to 1 if using `alloca.c'. */
|
||||||
|
#undef C_ALLOCA
|
||||||
|
|
||||||
|
/* Define to 1 if you have `alloca', as a function or macro. */
|
||||||
|
#undef HAVE_ALLOCA
|
||||||
|
|
||||||
|
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
|
||||||
|
*/
|
||||||
|
#undef HAVE_ALLOCA_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <curses.h> header file. */
|
||||||
|
#undef HAVE_CURSES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
|
||||||
|
*/
|
||||||
|
#undef HAVE_DIRENT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||||
|
#undef HAVE_DLFCN_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `endpwent' function. */
|
||||||
|
#undef HAVE_ENDPWENT
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <fcntl.h> header file. */
|
||||||
|
#undef HAVE_FCNTL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `fork' function. */
|
||||||
|
#undef HAVE_FORK
|
||||||
|
|
||||||
|
/* Define to 1 if you have getpwnam_r and getpwuid_r that are draft POSIX.1
|
||||||
|
versions. */
|
||||||
|
#undef HAVE_GETPW_R_DRAFT
|
||||||
|
|
||||||
|
/* Define to 1 if you have getpwnam_r and getpwuid_r that are POSIX.1
|
||||||
|
compatible. */
|
||||||
|
#undef HAVE_GETPW_R_POSIX
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||||
|
#undef HAVE_INTTYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `isascii' function. */
|
||||||
|
#undef HAVE_ISASCII
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `issetugid' function. */
|
||||||
|
#undef HAVE_ISSETUGID
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `curses' library (-lcurses). */
|
||||||
|
#undef HAVE_LIBCURSES
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `ncurses' library (-lncurses). */
|
||||||
|
#undef HAVE_LIBNCURSES
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <limits.h> header file. */
|
||||||
|
#undef HAVE_LIMITS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <malloc.h> header file. */
|
||||||
|
#undef HAVE_MALLOC_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `memchr' function. */
|
||||||
|
#undef HAVE_MEMCHR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <memory.h> header file. */
|
||||||
|
#undef HAVE_MEMORY_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `memset' function. */
|
||||||
|
#undef HAVE_MEMSET
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <ncurses.h> header file. */
|
||||||
|
#undef HAVE_NCURSES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
|
||||||
|
#undef HAVE_NDIR_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `regcomp' function. */
|
||||||
|
#undef HAVE_REGCOMP
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `re_comp' function. */
|
||||||
|
#undef HAVE_RE_COMP
|
||||||
|
|
||||||
|
/* Define to 1 if `stat' has the bug that it succeeds when given the
|
||||||
|
zero-length file name argument. */
|
||||||
|
#undef HAVE_STAT_EMPTY_STRING_BUG
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdint.h> header file. */
|
||||||
|
#undef HAVE_STDINT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||||
|
#undef HAVE_STDLIB_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strcasecmp' function. */
|
||||||
|
#undef HAVE_STRCASECMP
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strchr' function. */
|
||||||
|
#undef HAVE_STRCHR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strcspn' function. */
|
||||||
|
#undef HAVE_STRCSPN
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strdup' function. */
|
||||||
|
#undef HAVE_STRDUP
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strerror' function. */
|
||||||
|
#undef HAVE_STRERROR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <strings.h> header file. */
|
||||||
|
#undef HAVE_STRINGS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <string.h> header file. */
|
||||||
|
#undef HAVE_STRING_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strrchr' function. */
|
||||||
|
#undef HAVE_STRRCHR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strstr' function. */
|
||||||
|
#undef HAVE_STRSTR
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `strtol' function. */
|
||||||
|
#undef HAVE_STRTOL
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/cdefs.h> header file. */
|
||||||
|
#undef HAVE_SYS_CDEFS_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/dir.h> header file, and it defines `DIR'.
|
||||||
|
*/
|
||||||
|
#undef HAVE_SYS_DIR_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/ioctl.h> header file. */
|
||||||
|
#undef HAVE_SYS_IOCTL_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/ndir.h> header file, and it defines `DIR'.
|
||||||
|
*/
|
||||||
|
#undef HAVE_SYS_NDIR_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/param.h> header file. */
|
||||||
|
#undef HAVE_SYS_PARAM_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||||
|
#undef HAVE_SYS_STAT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||||
|
#undef HAVE_SYS_TYPES_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
|
||||||
|
#undef HAVE_SYS_WAIT_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <term.h> header file. */
|
||||||
|
#undef HAVE_TERM_H
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <unistd.h> header file. */
|
||||||
|
#undef HAVE_UNISTD_H
|
||||||
|
|
||||||
|
/* Define to 1 if the system has the type `u_int32_t'. */
|
||||||
|
#undef HAVE_U_INT32_T
|
||||||
|
|
||||||
|
/* Define to 1 if you have the `vfork' function. */
|
||||||
|
#undef HAVE_VFORK
|
||||||
|
|
||||||
|
/* Define to 1 if you have the <vfork.h> header file. */
|
||||||
|
#undef HAVE_VFORK_H
|
||||||
|
|
||||||
|
/* Define to 1 if `fork' works. */
|
||||||
|
#undef HAVE_WORKING_FORK
|
||||||
|
|
||||||
|
/* Define to 1 if `vfork' works. */
|
||||||
|
#undef HAVE_WORKING_VFORK
|
||||||
|
|
||||||
|
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
|
||||||
|
slash. */
|
||||||
|
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
|
||||||
|
|
||||||
|
/* Name of package */
|
||||||
|
#undef PACKAGE
|
||||||
|
|
||||||
|
/* Define to the address where bug reports for this package should be sent. */
|
||||||
|
#undef PACKAGE_BUGREPORT
|
||||||
|
|
||||||
|
/* Define to the full name of this package. */
|
||||||
|
#undef PACKAGE_NAME
|
||||||
|
|
||||||
|
/* Define to the full name and version of this package. */
|
||||||
|
#undef PACKAGE_STRING
|
||||||
|
|
||||||
|
/* Define to the one symbol short name of this package. */
|
||||||
|
#undef PACKAGE_TARNAME
|
||||||
|
|
||||||
|
/* Define to the version of this package. */
|
||||||
|
#undef PACKAGE_VERSION
|
||||||
|
|
||||||
|
/* Define as the return type of signal handlers (`int' or `void'). */
|
||||||
|
#undef RETSIGTYPE
|
||||||
|
|
||||||
|
/* If using the C implementation of alloca, define if you know the
|
||||||
|
direction of stack growth for your system; otherwise it will be
|
||||||
|
automatically deduced at runtime.
|
||||||
|
STACK_DIRECTION > 0 => grows toward higher addresses
|
||||||
|
STACK_DIRECTION < 0 => grows toward lower addresses
|
||||||
|
STACK_DIRECTION = 0 => direction of growth unknown */
|
||||||
|
#undef STACK_DIRECTION
|
||||||
|
|
||||||
|
/* Define to 1 if you have the ANSI C header files. */
|
||||||
|
#undef STDC_HEADERS
|
||||||
|
|
||||||
|
/* Version number of package */
|
||||||
|
#undef VERSION
|
||||||
|
|
||||||
|
/* Solaris's term.h does horrid things. */
|
||||||
|
#undef _SUNOS
|
||||||
|
|
||||||
|
/* Define to empty if `const' does not conform to ANSI C. */
|
||||||
|
#undef const
|
||||||
|
|
||||||
|
/* Define to `int' if <sys/types.h> does not define. */
|
||||||
|
#undef pid_t
|
||||||
|
|
||||||
|
/* Define to `unsigned int' if <sys/types.h> does not define. */
|
||||||
|
#undef size_t
|
||||||
|
|
||||||
|
/* Define as `fork' if `vfork' does not work. */
|
||||||
|
#undef vfork
|
||||||
|
|
||||||
|
|
||||||
|
#include <sys.h>
|
||||||
|
#define SCCSID
|
||||||
|
#undef LIBC_SCCS
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
# -*- Autoconf -*-
|
||||||
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
AC_INIT(libedit, [EL_RELEASE],, libedit-[EL_TIMESTAMP_CVSEXPORT])
|
||||||
|
AC_CONFIG_SRCDIR([src/strlcat.c])
|
||||||
|
AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
|
AM_INIT_AUTOMAKE
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
|
||||||
|
# libtool -version-info
|
||||||
|
AC_SUBST(LT_VERSION, [0:26:0])
|
||||||
|
|
||||||
|
# AC_PROG_LIBTOOL runs AC_CANONICAL_HOST
|
||||||
|
case $host in
|
||||||
|
*-sun-*) AC_DEFINE([_SUNOS], [], [Solaris's term.h does horrid things.]);;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# Checks for programs.
|
||||||
|
AC_PROG_CXX
|
||||||
|
AC_PROG_CC
|
||||||
|
AC_PROG_LN_S
|
||||||
|
AC_PROG_AWK
|
||||||
|
EL_MANTYPE
|
||||||
|
|
||||||
|
AC_CHECK_LIB(curses, tgetent,,
|
||||||
|
[AC_CHECK_LIB(ncurses, tgetent,,
|
||||||
|
[AC_MSG_ERROR([libtermcap, libcurses or libncurses are required!])] )] )
|
||||||
|
|
||||||
|
# Checks for header files.
|
||||||
|
AC_FUNC_ALLOCA
|
||||||
|
AC_HEADER_DIRENT
|
||||||
|
AC_HEADER_STDC
|
||||||
|
AC_HEADER_SYS_WAIT
|
||||||
|
AC_CHECK_HEADERS([fcntl.h limits.h malloc.h stdlib.h string.h sys/ioctl.h sys/param.h unistd.h curses.h ncurses.h sys/cdefs.h])
|
||||||
|
|
||||||
|
AC_CHECK_HEADER([termios.h], [], [AC_MSG_ERROR([termios.h is required!])],[])
|
||||||
|
|
||||||
|
## include curses.h to prevent "Present But Cannot Be Compiled"
|
||||||
|
AC_CHECK_HEADERS([term.h],,,
|
||||||
|
[[#if HAVE_CURSES_H
|
||||||
|
# include <curses.h>
|
||||||
|
#elif HAVE_NCURSES_H
|
||||||
|
# include <ncurses.h>
|
||||||
|
#endif
|
||||||
|
]])
|
||||||
|
|
||||||
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_C_CONST
|
||||||
|
AC_TYPE_PID_T
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
AC_CHECK_TYPES([u_int32_t])
|
||||||
|
|
||||||
|
# Checks for library functions.
|
||||||
|
AC_FUNC_CLOSEDIR_VOID
|
||||||
|
AC_FUNC_FORK
|
||||||
|
AC_PROG_GCC_TRADITIONAL
|
||||||
|
## _AIX is offended by rpl_malloc and rpl_realloc
|
||||||
|
#AC_FUNC_MALLOC
|
||||||
|
#AC_FUNC_REALLOC
|
||||||
|
AC_TYPE_SIGNAL
|
||||||
|
AC_FUNC_STAT
|
||||||
|
AC_CHECK_FUNCS([endpwent isascii memchr memset re_comp regcomp strcasecmp strchr strcspn strdup strerror strrchr strstr strtol issetugid])
|
||||||
|
EL_GETPW_R_POSIX
|
||||||
|
EL_GETPW_R_DRAFT
|
||||||
|
|
||||||
|
AH_BOTTOM([
|
||||||
|
#include <sys.h>
|
||||||
|
#define SCCSID
|
||||||
|
#undef LIBC_SCCS
|
||||||
|
])
|
||||||
|
|
||||||
|
AC_CONFIG_FILES([Makefile
|
||||||
|
libedit.pc
|
||||||
|
src/Makefile
|
||||||
|
doc/Makefile
|
||||||
|
examples/Makefile])
|
||||||
|
AC_OUTPUT
|
|
@ -0,0 +1,2 @@
|
||||||
|
#! /bin/sh
|
||||||
|
./configure "$@" --disable-shared --with-pic
|
|
@ -0,0 +1,31 @@
|
||||||
|
|
||||||
|
EL_MANS = editline.3 editrc.5
|
||||||
|
|
||||||
|
man_MANS = $(EL_MANS)
|
||||||
|
|
||||||
|
EL_MAN_LINKS = el_init.3 el_end.3 el_reset.3 el_gets.3 el_getc.3 \
|
||||||
|
el_push.3 el_parse.3 el_set.3 el_get.3 el_source.3 \
|
||||||
|
el_resize.3 el_line.3 el_insertstr.3 el_deletestr.3 \
|
||||||
|
el_history_init.3 el_history_end.3 el_history.3 el_tok_init.3 \
|
||||||
|
el_tok_end.3 el_tok_reset.3 el_tok_line.3 el_tok_str.3
|
||||||
|
|
||||||
|
install-data-hook: $(EL_MAN_LINKS)
|
||||||
|
|
||||||
|
$(EL_MAN_LINKS):
|
||||||
|
(cd $(DESTDIR)$(man3dir) && rm -f $@ && $(LN_S) editline.3 $@)
|
||||||
|
|
||||||
|
$(EL_MANS):
|
||||||
|
if test "$(MANTYPE)" = "mdoc"; then\
|
||||||
|
cp $(srcdir)/$@.roff $@;\
|
||||||
|
else\
|
||||||
|
$(AWK) -f $(srcdir)/mdoc2man.awk $(srcdir)/$@.roff > $@ || rm -f $@;\
|
||||||
|
fi;
|
||||||
|
|
||||||
|
uninstall-local:
|
||||||
|
(cd $(DESTDIR)$(man3dir) && rm -f $(EL_MAN_LINKS))
|
||||||
|
|
||||||
|
CLEANFILES = $(EL_MANS)
|
||||||
|
EXTRA_DIST = editline.3.roff editrc.5.roff mdoc2man.awk
|
||||||
|
|
||||||
|
changelog.txt: ../ChangeLog
|
||||||
|
@sed 's/@/ (at)/g;s/</\</g;s/>/\>/g;s/è/\è/g' $(srcdir)/$< > $@;
|
|
@ -0,0 +1,826 @@
|
||||||
|
.\" $NetBSD: editline.3,v 1.55 2007/01/12 16:31:13 christos Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\" 3. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
.\" contributors may be used to endorse or promote products derived
|
||||||
|
.\" from this software without specific prior written permission.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.Dd January 12, 2007
|
||||||
|
.Os
|
||||||
|
.Dt EDITLINE 3
|
||||||
|
.Sh NAME
|
||||||
|
.Nm editline ,
|
||||||
|
.Nm el_init ,
|
||||||
|
.Nm el_end ,
|
||||||
|
.Nm el_reset ,
|
||||||
|
.Nm el_gets ,
|
||||||
|
.Nm el_getc ,
|
||||||
|
.Nm el_push ,
|
||||||
|
.Nm el_parse ,
|
||||||
|
.Nm el_set ,
|
||||||
|
.Nm el_get ,
|
||||||
|
.Nm el_source ,
|
||||||
|
.Nm el_resize ,
|
||||||
|
.Nm el_line ,
|
||||||
|
.Nm el_insertstr ,
|
||||||
|
.Nm el_deletestr ,
|
||||||
|
.Nm history_init ,
|
||||||
|
.Nm history_end ,
|
||||||
|
.Nm history ,
|
||||||
|
.Nm tok_init ,
|
||||||
|
.Nm tok_end ,
|
||||||
|
.Nm tok_reset ,
|
||||||
|
.Nm tok_line ,
|
||||||
|
.Nm tok_str
|
||||||
|
.Nd line editor, history and tokenization functions
|
||||||
|
.Sh LIBRARY
|
||||||
|
.Lb libedit
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.In histedit.h
|
||||||
|
.Ft EditLine *
|
||||||
|
.Fn el_init "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr"
|
||||||
|
.Ft void
|
||||||
|
.Fn el_end "EditLine *e"
|
||||||
|
.Ft void
|
||||||
|
.Fn el_reset "EditLine *e"
|
||||||
|
.Ft const char *
|
||||||
|
.Fn el_gets "EditLine *e" "int *count"
|
||||||
|
.Ft int
|
||||||
|
.Fn el_getc "EditLine *e" "char *ch"
|
||||||
|
.Ft void
|
||||||
|
.Fn el_push "EditLine *e" "const char *str"
|
||||||
|
.Ft int
|
||||||
|
.Fn el_parse "EditLine *e" "int argc" "const char *argv[]"
|
||||||
|
.Ft int
|
||||||
|
.Fn el_set "EditLine *e" "int op" "..."
|
||||||
|
.Ft int
|
||||||
|
.Fn el_get "EditLine *e" "int op" "..."
|
||||||
|
.Ft int
|
||||||
|
.Fn el_source "EditLine *e" "const char *file"
|
||||||
|
.Ft void
|
||||||
|
.Fn el_resize "EditLine *e"
|
||||||
|
.Ft const LineInfo *
|
||||||
|
.Fn el_line "EditLine *e"
|
||||||
|
.Ft int
|
||||||
|
.Fn el_insertstr "EditLine *e" "const char *str"
|
||||||
|
.Ft void
|
||||||
|
.Fn el_deletestr "EditLine *e" "int count"
|
||||||
|
.Ft History *
|
||||||
|
.Fn history_init
|
||||||
|
.Ft void
|
||||||
|
.Fn history_end "History *h"
|
||||||
|
.Ft int
|
||||||
|
.Fn history "History *h" "HistEvent *ev" "int op" "..."
|
||||||
|
.Ft Tokenizer *
|
||||||
|
.Fn tok_init "const char *IFS"
|
||||||
|
.Ft void
|
||||||
|
.Fn tok_end "Tokenizer *t"
|
||||||
|
.Ft void
|
||||||
|
.Fn tok_reset "Tokenizer *t"
|
||||||
|
.Ft int
|
||||||
|
.Fn tok_line "Tokenizer *t" "const LineInfo *li" "int *argc" "const char **argv[]" "int *cursorc" "int *cursoro"
|
||||||
|
.Ft int
|
||||||
|
.Fn tok_str "Tokenizer *t" "const char *str" "int *argc" "const char **argv[]"
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
library provides generic line editing, history and tokenization functions,
|
||||||
|
similar to those found in
|
||||||
|
.Xr sh 1 .
|
||||||
|
.Pp
|
||||||
|
These functions are available in the
|
||||||
|
.Nm libedit
|
||||||
|
library (which needs the
|
||||||
|
.Nm libcurses
|
||||||
|
library).
|
||||||
|
Programs should be linked with
|
||||||
|
.Fl ledit
|
||||||
|
.Fl lcurses .
|
||||||
|
.Sh LINE EDITING FUNCTIONS
|
||||||
|
The line editing functions use a common data structure,
|
||||||
|
.Fa EditLine ,
|
||||||
|
which is created by
|
||||||
|
.Fn el_init
|
||||||
|
and freed by
|
||||||
|
.Fn el_end .
|
||||||
|
.Pp
|
||||||
|
The following functions are available:
|
||||||
|
.Bl -tag -width 4n
|
||||||
|
.It Fn el_init
|
||||||
|
Initialise the line editor, and return a data structure
|
||||||
|
to be used by all other line editing functions.
|
||||||
|
.Fa prog
|
||||||
|
is the name of the invoking program, used when reading the
|
||||||
|
.Xr editrc 5
|
||||||
|
file to determine which settings to use.
|
||||||
|
.Fa fin ,
|
||||||
|
.Fa fout
|
||||||
|
and
|
||||||
|
.Fa ferr
|
||||||
|
are the input, output, and error streams (respectively) to use.
|
||||||
|
In this documentation, references to
|
||||||
|
.Dq the tty
|
||||||
|
are actually to this input/output stream combination.
|
||||||
|
.It Fn el_end
|
||||||
|
Clean up and finish with
|
||||||
|
.Fa e ,
|
||||||
|
assumed to have been created with
|
||||||
|
.Fn el_init .
|
||||||
|
.It Fn el_reset
|
||||||
|
Reset the tty and the parser.
|
||||||
|
This should be called after an error which may have upset the tty's
|
||||||
|
state.
|
||||||
|
.It Fn el_gets
|
||||||
|
Read a line from the tty.
|
||||||
|
.Fa count
|
||||||
|
is modified to contain the number of characters read.
|
||||||
|
Returns the line read if successful, or
|
||||||
|
.Dv NULL
|
||||||
|
if no characters were read or if an error occurred.
|
||||||
|
.It Fn el_getc
|
||||||
|
Read a character from the tty.
|
||||||
|
.Fa ch
|
||||||
|
is modified to contain the character read.
|
||||||
|
Returns the number of characters read if successful, \-1 otherwise.
|
||||||
|
.It Fn el_push
|
||||||
|
Pushes
|
||||||
|
.Fa str
|
||||||
|
back onto the input stream.
|
||||||
|
This is used by the macro expansion mechanism.
|
||||||
|
Refer to the description of
|
||||||
|
.Ic bind
|
||||||
|
.Fl s
|
||||||
|
in
|
||||||
|
.Xr editrc 5
|
||||||
|
for more information.
|
||||||
|
.It Fn el_parse
|
||||||
|
Parses the
|
||||||
|
.Fa argv
|
||||||
|
array (which is
|
||||||
|
.Fa argc
|
||||||
|
elements in size)
|
||||||
|
to execute builtin
|
||||||
|
.Nm
|
||||||
|
commands.
|
||||||
|
If the command is prefixed with
|
||||||
|
.Dq prog :
|
||||||
|
then
|
||||||
|
.Fn el_parse
|
||||||
|
will only execute the command if
|
||||||
|
.Dq prog
|
||||||
|
matches the
|
||||||
|
.Fa prog
|
||||||
|
argument supplied to
|
||||||
|
.Fn el_init .
|
||||||
|
The return value is
|
||||||
|
\-1 if the command is unknown,
|
||||||
|
0 if there was no error or
|
||||||
|
.Dq prog
|
||||||
|
didn't match, or
|
||||||
|
1 if the command returned an error.
|
||||||
|
Refer to
|
||||||
|
.Xr editrc 5
|
||||||
|
for more information.
|
||||||
|
.It Fn el_set
|
||||||
|
Set
|
||||||
|
.Nm
|
||||||
|
parameters.
|
||||||
|
.Fa op
|
||||||
|
determines which parameter to set, and each operation has its
|
||||||
|
own parameter list.
|
||||||
|
.Pp
|
||||||
|
The following values for
|
||||||
|
.Fa op
|
||||||
|
are supported, along with the required argument list:
|
||||||
|
.Bl -tag -width 4n
|
||||||
|
.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)"
|
||||||
|
Define prompt printing function as
|
||||||
|
.Fa f ,
|
||||||
|
which is to return a string that contains the prompt.
|
||||||
|
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)"
|
||||||
|
Define right side prompt printing function as
|
||||||
|
.Fa f ,
|
||||||
|
which is to return a string that contains the prompt.
|
||||||
|
.It Dv EL_TERMINAL , Fa "const char *type"
|
||||||
|
Define terminal type of the tty to be
|
||||||
|
.Fa type ,
|
||||||
|
or to
|
||||||
|
.Ev TERM
|
||||||
|
if
|
||||||
|
.Fa type
|
||||||
|
is
|
||||||
|
.Dv NULL .
|
||||||
|
.It Dv EL_EDITOR , Fa "const char *mode"
|
||||||
|
Set editing mode to
|
||||||
|
.Fa mode ,
|
||||||
|
which must be one of
|
||||||
|
.Dq emacs
|
||||||
|
or
|
||||||
|
.Dq vi .
|
||||||
|
.It Dv EL_SIGNAL , Fa "int flag"
|
||||||
|
If
|
||||||
|
.Fa flag
|
||||||
|
is non-zero,
|
||||||
|
.Nm
|
||||||
|
will install its own signal handler for the following signals when
|
||||||
|
reading command input:
|
||||||
|
.Dv SIGCONT ,
|
||||||
|
.Dv SIGHUP ,
|
||||||
|
.Dv SIGINT ,
|
||||||
|
.Dv SIGQUIT ,
|
||||||
|
.Dv SIGSTOP ,
|
||||||
|
.Dv SIGTERM ,
|
||||||
|
.Dv SIGTSTP ,
|
||||||
|
and
|
||||||
|
.Dv SIGWINCH .
|
||||||
|
Otherwise, the current signal handlers will be used.
|
||||||
|
.It Dv EL_BIND , Xo
|
||||||
|
.Fa "const char *" ,
|
||||||
|
.Fa "..." ,
|
||||||
|
.Dv NULL
|
||||||
|
.Xc
|
||||||
|
Perform the
|
||||||
|
.Ic bind
|
||||||
|
builtin command.
|
||||||
|
Refer to
|
||||||
|
.Xr editrc 5
|
||||||
|
for more information.
|
||||||
|
.It Dv EL_ECHOTC , Xo
|
||||||
|
.Fa "const char *" ,
|
||||||
|
.Fa "..." ,
|
||||||
|
.Dv NULL
|
||||||
|
.Xc
|
||||||
|
Perform the
|
||||||
|
.Ic echotc
|
||||||
|
builtin command.
|
||||||
|
Refer to
|
||||||
|
.Xr editrc 5
|
||||||
|
for more information.
|
||||||
|
.It Dv EL_SETTC , Xo
|
||||||
|
.Fa "const char *" ,
|
||||||
|
.Fa "..." ,
|
||||||
|
.Dv NULL
|
||||||
|
.Xc
|
||||||
|
Perform the
|
||||||
|
.Ic settc
|
||||||
|
builtin command.
|
||||||
|
Refer to
|
||||||
|
.Xr editrc 5
|
||||||
|
for more information.
|
||||||
|
.It Dv EL_SETTY , Xo
|
||||||
|
.Fa "const char *" ,
|
||||||
|
.Fa "..." ,
|
||||||
|
.Dv NULL
|
||||||
|
.Xc
|
||||||
|
Perform the
|
||||||
|
.Ic setty
|
||||||
|
builtin command.
|
||||||
|
Refer to
|
||||||
|
.Xr editrc 5
|
||||||
|
for more information.
|
||||||
|
.It Dv EL_TELLTC , Xo
|
||||||
|
.Fa "const char *" ,
|
||||||
|
.Fa "..." ,
|
||||||
|
.Dv NULL
|
||||||
|
.Xc
|
||||||
|
Perform the
|
||||||
|
.Ic telltc
|
||||||
|
builtin command.
|
||||||
|
Refer to
|
||||||
|
.Xr editrc 5
|
||||||
|
for more information.
|
||||||
|
.It Dv EL_ADDFN , Xo
|
||||||
|
.Fa "const char *name" ,
|
||||||
|
.Fa "const char *help" ,
|
||||||
|
.Fa "unsigned char (*func)(EditLine *e, int ch)"
|
||||||
|
.Xc
|
||||||
|
Add a user defined function,
|
||||||
|
.Fn func ,
|
||||||
|
referred to as
|
||||||
|
.Fa name
|
||||||
|
which is invoked when a key which is bound to
|
||||||
|
.Fa name
|
||||||
|
is entered.
|
||||||
|
.Fa help
|
||||||
|
is a description of
|
||||||
|
.Fa name .
|
||||||
|
At invocation time,
|
||||||
|
.Fa ch
|
||||||
|
is the key which caused the invocation.
|
||||||
|
The return value of
|
||||||
|
.Fn func
|
||||||
|
should be one of:
|
||||||
|
.Bl -tag -width "CC_REDISPLAY"
|
||||||
|
.It Dv CC_NORM
|
||||||
|
Add a normal character.
|
||||||
|
.It Dv CC_NEWLINE
|
||||||
|
End of line was entered.
|
||||||
|
.It Dv CC_EOF
|
||||||
|
EOF was entered.
|
||||||
|
.It Dv CC_ARGHACK
|
||||||
|
Expecting further command input as arguments, do nothing visually.
|
||||||
|
.It Dv CC_REFRESH
|
||||||
|
Refresh display.
|
||||||
|
.It Dv CC_REFRESH_BEEP
|
||||||
|
Refresh display, and beep.
|
||||||
|
.It Dv CC_CURSOR
|
||||||
|
Cursor moved, so update and perform
|
||||||
|
.Dv CC_REFRESH .
|
||||||
|
.It Dv CC_REDISPLAY
|
||||||
|
Redisplay entire input line.
|
||||||
|
This is useful if a key binding outputs extra information.
|
||||||
|
.It Dv CC_ERROR
|
||||||
|
An error occurred.
|
||||||
|
Beep, and flush tty.
|
||||||
|
.It Dv CC_FATAL
|
||||||
|
Fatal error, reset tty to known state.
|
||||||
|
.El
|
||||||
|
.It Dv EL_HIST , Xo
|
||||||
|
.Fa "History *(*func)(History *, int op, ...)" ,
|
||||||
|
.Fa "const char *ptr"
|
||||||
|
.Xc
|
||||||
|
Defines which history function to use, which is usually
|
||||||
|
.Fn history .
|
||||||
|
.Fa ptr
|
||||||
|
should be the value returned by
|
||||||
|
.Fn history_init .
|
||||||
|
.It Dv EL_EDITMODE , Fa "int flag"
|
||||||
|
If
|
||||||
|
.Fa flag
|
||||||
|
is non-zero,
|
||||||
|
editing is enabled (the default).
|
||||||
|
Note that this is only an indication, and does not
|
||||||
|
affect the operation of
|
||||||
|
.Nm .
|
||||||
|
At this time, it is the caller's responsibility to
|
||||||
|
check this
|
||||||
|
(using
|
||||||
|
.Fn el_get )
|
||||||
|
to determine if editing should be enabled or not.
|
||||||
|
.It Dv EL_GETCFN , Fa "int (*f)(EditLine *, char *c)"
|
||||||
|
Define the character reading function as
|
||||||
|
.Fa f ,
|
||||||
|
which is to return the number of characters read and store them in
|
||||||
|
.Fa c .
|
||||||
|
This function is called internally by
|
||||||
|
.Fn el_gets
|
||||||
|
and
|
||||||
|
.Fn el_getc .
|
||||||
|
The builtin function can be set or restored with the special function
|
||||||
|
name ``EL_BUILTIN_GETCFN''.
|
||||||
|
.It Dv EL_CLIENTDATA , Fa "void *data"
|
||||||
|
Register
|
||||||
|
.Fa data
|
||||||
|
to be associated with this EditLine structure.
|
||||||
|
It can be retrieved with the corresponding
|
||||||
|
.Fn el_get
|
||||||
|
call.
|
||||||
|
.It Dv EL_SETFP , Fa "int fd" , Fa "FILE *fp"
|
||||||
|
Set the current
|
||||||
|
.Nm editline
|
||||||
|
file pointer for
|
||||||
|
.Dq input
|
||||||
|
.Fa fd
|
||||||
|
=
|
||||||
|
.Dv 0 ,
|
||||||
|
.Dq output
|
||||||
|
.Fa fd
|
||||||
|
=
|
||||||
|
.Dv 1 ,
|
||||||
|
or
|
||||||
|
.Dq error
|
||||||
|
.Fa fd
|
||||||
|
=
|
||||||
|
.Dv 2
|
||||||
|
from
|
||||||
|
.Fa fp .
|
||||||
|
.El
|
||||||
|
.It Fn el_get
|
||||||
|
Get
|
||||||
|
.Nm
|
||||||
|
parameters.
|
||||||
|
.Fa op
|
||||||
|
determines which parameter to retrieve into
|
||||||
|
.Fa result .
|
||||||
|
Returns 0 if successful, \-1 otherwise.
|
||||||
|
.Pp
|
||||||
|
The following values for
|
||||||
|
.Fa op
|
||||||
|
are supported, along with actual type of
|
||||||
|
.Fa result :
|
||||||
|
.Bl -tag -width 4n
|
||||||
|
.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)"
|
||||||
|
Return a pointer to the function that displays the prompt.
|
||||||
|
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)"
|
||||||
|
Return a pointer to the function that displays the rightside prompt.
|
||||||
|
.It Dv EL_EDITOR , Fa "const char *"
|
||||||
|
Return the name of the editor, which will be one of
|
||||||
|
.Dq emacs
|
||||||
|
or
|
||||||
|
.Dq vi .
|
||||||
|
.It Dv EL_GETTC , Fa "const char *name" , Fa "void *value"
|
||||||
|
Return non-zero if
|
||||||
|
.Fa name
|
||||||
|
is a valid
|
||||||
|
.Xr termcap 5
|
||||||
|
capability
|
||||||
|
and set
|
||||||
|
.Fa value
|
||||||
|
to the current value of that capability.
|
||||||
|
.It Dv EL_SIGNAL , Fa "int *"
|
||||||
|
Return non-zero if
|
||||||
|
.Nm
|
||||||
|
has installed private signal handlers (see
|
||||||
|
.Fn el_get
|
||||||
|
above).
|
||||||
|
.It Dv EL_EDITMODE , Fa "int *"
|
||||||
|
Return non-zero if editing is enabled.
|
||||||
|
.It Dv EL_GETCFN , Fa "int (**f)(EditLine *, char *)"
|
||||||
|
Return a pointer to the function that read characters, which is equal to
|
||||||
|
``EL_BUILTIN_GETCFN'' in the case of the default builtin function.
|
||||||
|
.It Dv EL_CLIENTDATA , Fa "void **data"
|
||||||
|
Retrieve
|
||||||
|
.Fa data
|
||||||
|
previously registered with the corresponding
|
||||||
|
.Fn el_set
|
||||||
|
call.
|
||||||
|
.It Dv EL_UNBUFFERED , Fa "int"
|
||||||
|
Sets or clears unbuffered mode.
|
||||||
|
In this mode,
|
||||||
|
.Fn el_gets
|
||||||
|
will return immediately after processing a single character.
|
||||||
|
.It Dv EL_PREP_TERM , Fa "int"
|
||||||
|
Sets or clears terminal editing mode.
|
||||||
|
.It Dv EL_GETFP , Fa "int fd", Fa "FILE **fp"
|
||||||
|
Return in
|
||||||
|
.Fa fp
|
||||||
|
the current
|
||||||
|
.Nm editline
|
||||||
|
file pointer for
|
||||||
|
.Dq input
|
||||||
|
.Fa fd
|
||||||
|
=
|
||||||
|
.Dv 0 ,
|
||||||
|
.Dq output
|
||||||
|
.Fa fd
|
||||||
|
=
|
||||||
|
.Dv 1 ,
|
||||||
|
or
|
||||||
|
.Dq error
|
||||||
|
.Fa fd
|
||||||
|
=
|
||||||
|
.Dv 2 .
|
||||||
|
.El
|
||||||
|
.It Fn el_source
|
||||||
|
Initialise
|
||||||
|
.Nm
|
||||||
|
by reading the contents of
|
||||||
|
.Fa file .
|
||||||
|
.Fn el_parse
|
||||||
|
is called for each line in
|
||||||
|
.Fa file .
|
||||||
|
If
|
||||||
|
.Fa file
|
||||||
|
is
|
||||||
|
.Dv NULL ,
|
||||||
|
try
|
||||||
|
.Pa $PWD/.editrc
|
||||||
|
then
|
||||||
|
.Pa $HOME/.editrc .
|
||||||
|
Refer to
|
||||||
|
.Xr editrc 5
|
||||||
|
for details on the format of
|
||||||
|
.Fa file .
|
||||||
|
.It Fn el_resize
|
||||||
|
Must be called if the terminal size changes.
|
||||||
|
If
|
||||||
|
.Dv EL_SIGNAL
|
||||||
|
has been set with
|
||||||
|
.Fn el_set ,
|
||||||
|
then this is done automatically.
|
||||||
|
Otherwise, it's the responsibility of the application to call
|
||||||
|
.Fn el_resize
|
||||||
|
on the appropriate occasions.
|
||||||
|
.It Fn el_line
|
||||||
|
Return the editing information for the current line in a
|
||||||
|
.Fa LineInfo
|
||||||
|
structure, which is defined as follows:
|
||||||
|
.Bd -literal
|
||||||
|
typedef struct lineinfo {
|
||||||
|
const char *buffer; /* address of buffer */
|
||||||
|
const char *cursor; /* address of cursor */
|
||||||
|
const char *lastchar; /* address of last character */
|
||||||
|
} LineInfo;
|
||||||
|
.Ed
|
||||||
|
.Pp
|
||||||
|
.Fa buffer
|
||||||
|
is not NUL terminated.
|
||||||
|
This function may be called after
|
||||||
|
.Fn el_gets
|
||||||
|
to obtain the
|
||||||
|
.Fa LineInfo
|
||||||
|
structure pertaining to line returned by that function,
|
||||||
|
and from within user defined functions added with
|
||||||
|
.Dv EL_ADDFN .
|
||||||
|
.It Fn el_insertstr
|
||||||
|
Insert
|
||||||
|
.Fa str
|
||||||
|
into the line at the cursor.
|
||||||
|
Returns \-1 if
|
||||||
|
.Fa str
|
||||||
|
is empty or won't fit, and 0 otherwise.
|
||||||
|
.It Fn el_deletestr
|
||||||
|
Delete
|
||||||
|
.Fa count
|
||||||
|
characters before the cursor.
|
||||||
|
.El
|
||||||
|
.Sh HISTORY LIST FUNCTIONS
|
||||||
|
The history functions use a common data structure,
|
||||||
|
.Fa History ,
|
||||||
|
which is created by
|
||||||
|
.Fn history_init
|
||||||
|
and freed by
|
||||||
|
.Fn history_end .
|
||||||
|
.Pp
|
||||||
|
The following functions are available:
|
||||||
|
.Bl -tag -width 4n
|
||||||
|
.It Fn history_init
|
||||||
|
Initialise the history list, and return a data structure
|
||||||
|
to be used by all other history list functions.
|
||||||
|
.It Fn history_end
|
||||||
|
Clean up and finish with
|
||||||
|
.Fa h ,
|
||||||
|
assumed to have been created with
|
||||||
|
.Fn history_init .
|
||||||
|
.It Fn history
|
||||||
|
Perform operation
|
||||||
|
.Fa op
|
||||||
|
on the history list, with optional arguments as needed by the
|
||||||
|
operation.
|
||||||
|
.Fa ev
|
||||||
|
is changed accordingly to operation.
|
||||||
|
The following values for
|
||||||
|
.Fa op
|
||||||
|
are supported, along with the required argument list:
|
||||||
|
.Bl -tag -width 4n
|
||||||
|
.It Dv H_SETSIZE , Fa "int size"
|
||||||
|
Set size of history to
|
||||||
|
.Fa size
|
||||||
|
elements.
|
||||||
|
.It Dv H_GETSIZE
|
||||||
|
Get number of events currently in history.
|
||||||
|
.It Dv H_END
|
||||||
|
Cleans up and finishes with
|
||||||
|
.Fa h ,
|
||||||
|
assumed to be created with
|
||||||
|
.Fn history_init .
|
||||||
|
.It Dv H_CLEAR
|
||||||
|
Clear the history.
|
||||||
|
.It Dv H_FUNC , Xo
|
||||||
|
.Fa "void *ptr" ,
|
||||||
|
.Fa "history_gfun_t first" ,
|
||||||
|
.Fa "history_gfun_t next" ,
|
||||||
|
.Fa "history_gfun_t last" ,
|
||||||
|
.Fa "history_gfun_t prev" ,
|
||||||
|
.Fa "history_gfun_t curr" ,
|
||||||
|
.Fa "history_sfun_t set" ,
|
||||||
|
.Fa "history_vfun_t clear" ,
|
||||||
|
.Fa "history_efun_t enter" ,
|
||||||
|
.Fa "history_efun_t add"
|
||||||
|
.Xc
|
||||||
|
Define functions to perform various history operations.
|
||||||
|
.Fa ptr
|
||||||
|
is the argument given to a function when it's invoked.
|
||||||
|
.It Dv H_FIRST
|
||||||
|
Return the first element in the history.
|
||||||
|
.It Dv H_LAST
|
||||||
|
Return the last element in the history.
|
||||||
|
.It Dv H_PREV
|
||||||
|
Return the previous element in the history.
|
||||||
|
.It Dv H_NEXT
|
||||||
|
Return the next element in the history.
|
||||||
|
.It Dv H_CURR
|
||||||
|
Return the current element in the history.
|
||||||
|
.It Dv H_SET
|
||||||
|
Set the cursor to point to the requested element.
|
||||||
|
.It Dv H_ADD , Fa "const char *str"
|
||||||
|
Append
|
||||||
|
.Fa str
|
||||||
|
to the current element of the history, or perform the
|
||||||
|
.Dv H_ENTER
|
||||||
|
operation with argument
|
||||||
|
.Fa str
|
||||||
|
if there is no current element.
|
||||||
|
.It Dv H_APPEND , Fa "const char *str"
|
||||||
|
Append
|
||||||
|
.Fa str
|
||||||
|
to the last new element of the history.
|
||||||
|
.It Dv H_ENTER , Fa "const char *str"
|
||||||
|
Add
|
||||||
|
.Fa str
|
||||||
|
as a new element to the history, and, if necessary,
|
||||||
|
removing the oldest entry to keep the list to the created size.
|
||||||
|
If
|
||||||
|
.Dv H_SETUNIQUE
|
||||||
|
was has been called with a non-zero arguments, the element
|
||||||
|
will not be entered into the history if its contents match
|
||||||
|
the ones of the current history element.
|
||||||
|
If the element is entered
|
||||||
|
.Fn history
|
||||||
|
returns 1, if it is ignored as a duplicate returns 0.
|
||||||
|
Finally
|
||||||
|
.Fn history
|
||||||
|
returns \-1 if an error occurred.
|
||||||
|
.It Dv H_PREV_STR , Fa "const char *str"
|
||||||
|
Return the closest previous event that starts with
|
||||||
|
.Fa str .
|
||||||
|
.It Dv H_NEXT_STR , Fa "const char *str"
|
||||||
|
Return the closest next event that starts with
|
||||||
|
.Fa str .
|
||||||
|
.It Dv H_PREV_EVENT , Fa "int e"
|
||||||
|
Return the previous event numbered
|
||||||
|
.Fa e .
|
||||||
|
.It Dv H_NEXT_EVENT , Fa "int e"
|
||||||
|
Return the next event numbered
|
||||||
|
.Fa e .
|
||||||
|
.It Dv H_LOAD , Fa "const char *file"
|
||||||
|
Load the history list stored in
|
||||||
|
.Fa file .
|
||||||
|
.It Dv H_SAVE , Fa "const char *file"
|
||||||
|
Save the history list to
|
||||||
|
.Fa file .
|
||||||
|
.It Dv H_SETUNIQUE , Fa "int unique"
|
||||||
|
Set flag that adjacent identical event strings should not be entered
|
||||||
|
into the history.
|
||||||
|
.It Dv H_GETUNIQUE
|
||||||
|
Retrieve the current setting if adjacent identical elements should
|
||||||
|
be entered into the history.
|
||||||
|
.It Dv H_DEL , Fa "int e"
|
||||||
|
Delete the event numbered
|
||||||
|
.Fa e .
|
||||||
|
This function is only provided for
|
||||||
|
.Xr readline 3
|
||||||
|
compatibility.
|
||||||
|
The caller is responsible for free'ing the string in the returned
|
||||||
|
.Fa HistEvent .
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
.Fn history
|
||||||
|
returns \*[Gt]= 0 if the operation
|
||||||
|
.Fa op
|
||||||
|
succeeds.
|
||||||
|
Otherwise, \-1 is returned and
|
||||||
|
.Fa ev
|
||||||
|
is updated to contain more details about the error.
|
||||||
|
.El
|
||||||
|
.Sh TOKENIZATION FUNCTIONS
|
||||||
|
The tokenization functions use a common data structure,
|
||||||
|
.Fa Tokenizer ,
|
||||||
|
which is created by
|
||||||
|
.Fn tok_init
|
||||||
|
and freed by
|
||||||
|
.Fn tok_end .
|
||||||
|
.Pp
|
||||||
|
The following functions are available:
|
||||||
|
.Bl -tag -width 4n
|
||||||
|
.It Fn tok_init
|
||||||
|
Initialise the tokenizer, and return a data structure
|
||||||
|
to be used by all other tokenizer functions.
|
||||||
|
.Fa IFS
|
||||||
|
contains the Input Field Separators, which defaults to
|
||||||
|
.Aq space
|
||||||
|
,
|
||||||
|
.Aq tab
|
||||||
|
,
|
||||||
|
and
|
||||||
|
.Aq newline
|
||||||
|
if
|
||||||
|
.Dv NULL .
|
||||||
|
.It Fn tok_end
|
||||||
|
Clean up and finish with
|
||||||
|
.Fa t ,
|
||||||
|
assumed to have been created with
|
||||||
|
.Fn tok_init .
|
||||||
|
.It Fn tok_reset
|
||||||
|
Reset the tokenizer state.
|
||||||
|
Use after a line has been successfully tokenized
|
||||||
|
by
|
||||||
|
.Fn tok_line
|
||||||
|
or
|
||||||
|
.Fn tok_str
|
||||||
|
and before a new line is to be tokenized.
|
||||||
|
.It Fn tok_line
|
||||||
|
Tokenize
|
||||||
|
.Fa li ,
|
||||||
|
If successful, modify:
|
||||||
|
.Fa argv
|
||||||
|
to contain the words,
|
||||||
|
.Fa argc
|
||||||
|
to contain the number of words,
|
||||||
|
.Fa cursorc
|
||||||
|
(if not
|
||||||
|
.Dv NULL )
|
||||||
|
to contain the index of the word containing the cursor,
|
||||||
|
and
|
||||||
|
.Fa cursoro
|
||||||
|
(if not
|
||||||
|
.Dv NULL )
|
||||||
|
to contain the offset within
|
||||||
|
.Fa argv[cursorc]
|
||||||
|
of the cursor.
|
||||||
|
.Pp
|
||||||
|
Returns
|
||||||
|
0 if successful,
|
||||||
|
\-1 for an internal error,
|
||||||
|
1 for an unmatched single quote,
|
||||||
|
2 for an unmatched double quote,
|
||||||
|
and
|
||||||
|
3 for a backslash quoted
|
||||||
|
.Aq newline .
|
||||||
|
A positive exit code indicates that another line should be read
|
||||||
|
and tokenization attempted again.
|
||||||
|
.
|
||||||
|
.It Fn tok_str
|
||||||
|
A simpler form of
|
||||||
|
.Fn tok_line ;
|
||||||
|
.Fa str
|
||||||
|
is a NUL terminated string to tokenize.
|
||||||
|
.El
|
||||||
|
.
|
||||||
|
.\"XXX.Sh EXAMPLES
|
||||||
|
.\"XXX: provide some examples
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr sh 1 ,
|
||||||
|
.Xr signal 3 ,
|
||||||
|
.Xr termcap 3 ,
|
||||||
|
.Xr editrc 5 ,
|
||||||
|
.Xr termcap 5
|
||||||
|
.Sh HISTORY
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
library first appeared in
|
||||||
|
.Bx 4.4 .
|
||||||
|
.Dv CC_REDISPLAY
|
||||||
|
appeared in
|
||||||
|
.Nx 1.3 .
|
||||||
|
.Dv CC_REFRESH_BEEP ,
|
||||||
|
.Dv EL_EDITMODE
|
||||||
|
and the readline emulation appeared in
|
||||||
|
.Nx 1.4 .
|
||||||
|
.Dv EL_RPROMPT
|
||||||
|
appeared in
|
||||||
|
.Nx 1.5 .
|
||||||
|
.Sh AUTHORS
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
library was written by Christos Zoulas.
|
||||||
|
Luke Mewburn wrote this manual and implemented
|
||||||
|
.Dv CC_REDISPLAY ,
|
||||||
|
.Dv CC_REFRESH_BEEP ,
|
||||||
|
.Dv EL_EDITMODE ,
|
||||||
|
and
|
||||||
|
.Dv EL_RPROMPT .
|
||||||
|
Jaromir Dolecek implemented the readline emulation.
|
||||||
|
.Sh BUGS
|
||||||
|
At this time, it is the responsibility of the caller to
|
||||||
|
check the result of the
|
||||||
|
.Dv EL_EDITMODE
|
||||||
|
operation of
|
||||||
|
.Fn el_get
|
||||||
|
(after an
|
||||||
|
.Fn el_source
|
||||||
|
or
|
||||||
|
.Fn el_parse )
|
||||||
|
to determine if
|
||||||
|
.Nm
|
||||||
|
should be used for further input.
|
||||||
|
I.e.,
|
||||||
|
.Dv EL_EDITMODE
|
||||||
|
is purely an indication of the result of the most recent
|
||||||
|
.Xr editrc 5
|
||||||
|
.Ic edit
|
||||||
|
command.
|
|
@ -0,0 +1,513 @@
|
||||||
|
.\" $NetBSD: editrc.5,v 1.20 2006/08/21 12:45:30 christos Exp $
|
||||||
|
.\"
|
||||||
|
.\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
|
||||||
|
.\" All rights reserved.
|
||||||
|
.\"
|
||||||
|
.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
|
||||||
|
.\"
|
||||||
|
.\" Redistribution and use in source and binary forms, with or without
|
||||||
|
.\" modification, are permitted provided that the following conditions
|
||||||
|
.\" are met:
|
||||||
|
.\" 1. Redistributions of source code must retain the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer.
|
||||||
|
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
.\" notice, this list of conditions and the following disclaimer in the
|
||||||
|
.\" documentation and/or other materials provided with the distribution.
|
||||||
|
.\" 3. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
.\" contributors may be used to endorse or promote products derived
|
||||||
|
.\" from this software without specific prior written permission.
|
||||||
|
.\"
|
||||||
|
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
.\" POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
.\"
|
||||||
|
.Dd October 18, 2003
|
||||||
|
.Os
|
||||||
|
.Dt EDITRC 5
|
||||||
|
.Sh NAME
|
||||||
|
.Nm editrc
|
||||||
|
.Nd configuration file for editline library
|
||||||
|
.Sh SYNOPSIS
|
||||||
|
.Nm
|
||||||
|
.Sh DESCRIPTION
|
||||||
|
The
|
||||||
|
.Nm
|
||||||
|
file defines various settings to be used by the
|
||||||
|
.Xr editline 3
|
||||||
|
library.
|
||||||
|
.Pp
|
||||||
|
The format of each line is:
|
||||||
|
.Dl [prog:]command [arg [...]]
|
||||||
|
.Pp
|
||||||
|
.Ar command
|
||||||
|
is one of the
|
||||||
|
.Xr editline 3
|
||||||
|
builtin commands.
|
||||||
|
Refer to
|
||||||
|
.Sx BUILTIN COMMANDS
|
||||||
|
for more information.
|
||||||
|
.Pp
|
||||||
|
.Ar prog
|
||||||
|
is the program name string that a program defines when it calls
|
||||||
|
.Xr el_init 3
|
||||||
|
to set up
|
||||||
|
.Xr editline 3 ,
|
||||||
|
which is usually
|
||||||
|
.Va argv[0] .
|
||||||
|
.Ar command
|
||||||
|
will be executed for any program which matches
|
||||||
|
.Ar prog .
|
||||||
|
.Pp
|
||||||
|
.Ar prog
|
||||||
|
may also be a
|
||||||
|
.Xr regex 3
|
||||||
|
style
|
||||||
|
regular expression, in which case
|
||||||
|
.Ar command
|
||||||
|
will be executed for any program that matches the regular expression.
|
||||||
|
.Pp
|
||||||
|
If
|
||||||
|
.Ar prog
|
||||||
|
is absent,
|
||||||
|
.Ar command
|
||||||
|
is executed for all programs.
|
||||||
|
.Sh BUILTIN COMMANDS
|
||||||
|
The
|
||||||
|
.Nm editline
|
||||||
|
library has some builtin commands, which affect the way
|
||||||
|
that the line editing and history functions operate.
|
||||||
|
These are based on similar named builtins present in the
|
||||||
|
.Xr tcsh 1
|
||||||
|
shell.
|
||||||
|
.Pp
|
||||||
|
The following builtin commands are available:
|
||||||
|
.Bl -tag -width 4n
|
||||||
|
.It Ic bind Xo
|
||||||
|
.Op Fl a
|
||||||
|
.Op Fl e
|
||||||
|
.Op Fl k
|
||||||
|
.Op Fl l
|
||||||
|
.Op Fl r
|
||||||
|
.Op Fl s
|
||||||
|
.Op Fl v
|
||||||
|
.Op Ar key Op Ar command
|
||||||
|
.Xc
|
||||||
|
Without options, list all bound keys, and the editor command to which
|
||||||
|
each is bound.
|
||||||
|
If
|
||||||
|
.Ar key
|
||||||
|
is supplied, show the bindings for
|
||||||
|
.Ar key .
|
||||||
|
If
|
||||||
|
.Ar key command
|
||||||
|
is supplied, bind
|
||||||
|
.Ar command
|
||||||
|
to
|
||||||
|
.Ar key .
|
||||||
|
Options include:
|
||||||
|
.Bl -tag -width 4n
|
||||||
|
.It Fl e
|
||||||
|
Bind all keys to the standard GNU Emacs-like bindings.
|
||||||
|
.It Fl v
|
||||||
|
Bind all keys to the standard
|
||||||
|
.Xr vi 1 Ns -like
|
||||||
|
bindings.
|
||||||
|
.It Fl a
|
||||||
|
List or change key bindings in the
|
||||||
|
.Xr vi 1
|
||||||
|
mode alternate (command mode) key map.
|
||||||
|
.It Fl k
|
||||||
|
.Ar key
|
||||||
|
is interpreted as a symbolic arrow key name, which may be one of
|
||||||
|
.Sq up ,
|
||||||
|
.Sq down ,
|
||||||
|
.Sq left
|
||||||
|
or
|
||||||
|
.Sq right .
|
||||||
|
.It Fl l
|
||||||
|
List all editor commands and a short description of each.
|
||||||
|
.It Fl r
|
||||||
|
Remove a key's binding.
|
||||||
|
.It Fl s
|
||||||
|
.Ar command
|
||||||
|
is taken as a literal string and treated as terminal input when
|
||||||
|
.Ar key
|
||||||
|
is typed.
|
||||||
|
Bound keys in
|
||||||
|
.Ar command
|
||||||
|
are themselves reinterpreted, and this continues for ten levels of
|
||||||
|
interpretation.
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
.Ar command
|
||||||
|
may be one of the commands documented in
|
||||||
|
.Sx "EDITOR COMMANDS"
|
||||||
|
below, or another key.
|
||||||
|
.Pp
|
||||||
|
.Ar key
|
||||||
|
and
|
||||||
|
.Ar command
|
||||||
|
can contain control characters of the form
|
||||||
|
.Sm off
|
||||||
|
.Sq ^character
|
||||||
|
.Sm on
|
||||||
|
.Po
|
||||||
|
e.g.
|
||||||
|
.Sq ^A
|
||||||
|
.Pc ,
|
||||||
|
and the following backslashed escape sequences:
|
||||||
|
.Pp
|
||||||
|
.Bl -tag -compact -offset indent -width 4n
|
||||||
|
.It Ic \ea
|
||||||
|
Bell
|
||||||
|
.It Ic \eb
|
||||||
|
Backspace
|
||||||
|
.It Ic \ee
|
||||||
|
Escape
|
||||||
|
.It Ic \ef
|
||||||
|
Formfeed
|
||||||
|
.It Ic \en
|
||||||
|
Newline
|
||||||
|
.It Ic \er
|
||||||
|
Carriage return
|
||||||
|
.It Ic \et
|
||||||
|
Horizontal tab
|
||||||
|
.It Ic \ev
|
||||||
|
Vertical tab
|
||||||
|
.Sm off
|
||||||
|
.It Sy \ennn
|
||||||
|
.Sm on
|
||||||
|
The ASCII character corresponding to the octal number
|
||||||
|
.Ar nnn .
|
||||||
|
.El
|
||||||
|
.Pp
|
||||||
|
.Sq \e
|
||||||
|
nullifies the special meaning of the following character,
|
||||||
|
if it has any, notably
|
||||||
|
.Sq \e
|
||||||
|
and
|
||||||
|
.Sq ^ .
|
||||||
|
.It Ic echotc Xo
|
||||||
|
.Op Fl sv
|
||||||
|
.Ar arg
|
||||||
|
.Ar ...
|
||||||
|
.Xc
|
||||||
|
Exercise terminal capabilities given in
|
||||||
|
.Ar arg Ar ... .
|
||||||
|
If
|
||||||
|
.Ar arg
|
||||||
|
is
|
||||||
|
.Sq baud ,
|
||||||
|
.Sq cols ,
|
||||||
|
.Sq lines ,
|
||||||
|
.Sq rows ,
|
||||||
|
.Sq meta or
|
||||||
|
.Sq tabs ,
|
||||||
|
the value of that capability is printed, with
|
||||||
|
.Dq yes
|
||||||
|
or
|
||||||
|
.Dq no
|
||||||
|
indicating that the terminal does or does not have that capability.
|
||||||
|
.Pp
|
||||||
|
.Fl s
|
||||||
|
returns an empty string for non-existent capabilities, rather than
|
||||||
|
causing an error.
|
||||||
|
.Fl v
|
||||||
|
causes messages to be verbose.
|
||||||
|
.It Ic edit Op on | off
|
||||||
|
Enable or disable the
|
||||||
|
.Nm editline
|
||||||
|
functionality in a program.
|
||||||
|
.It Ic history Ar list | Ar size n | Ar unique n
|
||||||
|
The
|
||||||
|
.Ar list
|
||||||
|
command lists all entries in the history.
|
||||||
|
The
|
||||||
|
.Ar size
|
||||||
|
command sets the history size to
|
||||||
|
.Dv n
|
||||||
|
entries.
|
||||||
|
The
|
||||||
|
.Ar unique
|
||||||
|
command controls if history should keep duplicate entries.
|
||||||
|
If
|
||||||
|
.Dv n
|
||||||
|
is non zero, only keep unique history entries.
|
||||||
|
If
|
||||||
|
.Dv n
|
||||||
|
is zero, then keep all entries (the default).
|
||||||
|
.It Ic telltc
|
||||||
|
List the values of all the terminal capabilities (see
|
||||||
|
.Xr termcap 5 ) .
|
||||||
|
.It Ic settc Ar cap Ar val
|
||||||
|
Set the terminal capability
|
||||||
|
.Ar cap
|
||||||
|
to
|
||||||
|
.Ar val ,
|
||||||
|
as defined in
|
||||||
|
.Xr termcap 5 .
|
||||||
|
No sanity checking is done.
|
||||||
|
.It Ic setty Xo
|
||||||
|
.Op Fl a
|
||||||
|
.Op Fl d
|
||||||
|
.Op Fl q
|
||||||
|
.Op Fl x
|
||||||
|
.Op Ar +mode
|
||||||
|
.Op Ar -mode
|
||||||
|
.Op Ar mode
|
||||||
|
.Op Ar char=c
|
||||||
|
.Xc
|
||||||
|
Control which tty modes that
|
||||||
|
.Nm
|
||||||
|
won't allow the user to change.
|
||||||
|
.Fl d ,
|
||||||
|
.Fl q
|
||||||
|
or
|
||||||
|
.Fl x
|
||||||
|
tells
|
||||||
|
.Ic setty
|
||||||
|
to act on the
|
||||||
|
.Sq edit ,
|
||||||
|
.Sq quote
|
||||||
|
or
|
||||||
|
.Sq execute
|
||||||
|
set of tty modes respectively; defaulting to
|
||||||
|
.Fl x .
|
||||||
|
.Pp
|
||||||
|
Without other arguments,
|
||||||
|
.Ic setty
|
||||||
|
lists the modes in the chosen set which are fixed on
|
||||||
|
.Po
|
||||||
|
.Sq +mode
|
||||||
|
.Pc
|
||||||
|
or off
|
||||||
|
.Po
|
||||||
|
.Sq -mode
|
||||||
|
.Pc .
|
||||||
|
.Fl a
|
||||||
|
lists all tty modes in the chosen set regardless of the setting.
|
||||||
|
With
|
||||||
|
.Ar +mode ,
|
||||||
|
.Ar -mode
|
||||||
|
or
|
||||||
|
.Ar mode ,
|
||||||
|
fixes
|
||||||
|
.Ar mode
|
||||||
|
on or off or removes control of
|
||||||
|
.Ar mode
|
||||||
|
in the chosen set.
|
||||||
|
.Pp
|
||||||
|
.Ic Setty
|
||||||
|
can also be used to set tty characters to particular values using
|
||||||
|
.Ar char=value .
|
||||||
|
If
|
||||||
|
.Ar value
|
||||||
|
is empty
|
||||||
|
then the character is set to
|
||||||
|
.Dv _POSIX_VDISABLE .
|
||||||
|
.El
|
||||||
|
.Sh EDITOR COMMANDS
|
||||||
|
The following editor commands are available for use in key bindings:
|
||||||
|
.\" Section automatically generated with makelist
|
||||||
|
.Bl -tag -width 4n
|
||||||
|
.It Ic vi-paste-next
|
||||||
|
Vi paste previous deletion to the right of the cursor.
|
||||||
|
.It Ic vi-paste-prev
|
||||||
|
Vi paste previous deletion to the left of the cursor.
|
||||||
|
.It Ic vi-prev-space-word
|
||||||
|
Vi move to the previous space delimited word.
|
||||||
|
.It Ic vi-prev-word
|
||||||
|
Vi move to the previous word.
|
||||||
|
.It Ic vi-next-space-word
|
||||||
|
Vi move to the next space delimited word.
|
||||||
|
.It Ic vi-next-word
|
||||||
|
Vi move to the next word.
|
||||||
|
.It Ic vi-change-case
|
||||||
|
Vi change case of character under the cursor and advance one character.
|
||||||
|
.It Ic vi-change-meta
|
||||||
|
Vi change prefix command.
|
||||||
|
.It Ic vi-insert-at-bol
|
||||||
|
Vi enter insert mode at the beginning of line.
|
||||||
|
.It Ic vi-replace-char
|
||||||
|
Vi replace character under the cursor with the next character typed.
|
||||||
|
.It Ic vi-replace-mode
|
||||||
|
Vi enter replace mode.
|
||||||
|
.It Ic vi-substitute-char
|
||||||
|
Vi replace character under the cursor and enter insert mode.
|
||||||
|
.It Ic vi-substitute-line
|
||||||
|
Vi substitute entire line.
|
||||||
|
.It Ic vi-change-to-eol
|
||||||
|
Vi change to end of line.
|
||||||
|
.It Ic vi-insert
|
||||||
|
Vi enter insert mode.
|
||||||
|
.It Ic vi-add
|
||||||
|
Vi enter insert mode after the cursor.
|
||||||
|
.It Ic vi-add-at-eol
|
||||||
|
Vi enter insert mode at end of line.
|
||||||
|
.It Ic vi-delete-meta
|
||||||
|
Vi delete prefix command.
|
||||||
|
.It Ic vi-end-word
|
||||||
|
Vi move to the end of the current space delimited word.
|
||||||
|
.It Ic vi-to-end-word
|
||||||
|
Vi move to the end of the current word.
|
||||||
|
.It Ic vi-undo
|
||||||
|
Vi undo last change.
|
||||||
|
.It Ic vi-command-mode
|
||||||
|
Vi enter command mode (use alternative key bindings).
|
||||||
|
.It Ic vi-zero
|
||||||
|
Vi move to the beginning of line.
|
||||||
|
.It Ic vi-delete-prev-char
|
||||||
|
Vi move to previous character (backspace).
|
||||||
|
.It Ic vi-list-or-eof
|
||||||
|
Vi list choices for completion or indicate end of file if empty line.
|
||||||
|
.It Ic vi-kill-line-prev
|
||||||
|
Vi cut from beginning of line to cursor.
|
||||||
|
.It Ic vi-search-prev
|
||||||
|
Vi search history previous.
|
||||||
|
.It Ic vi-search-next
|
||||||
|
Vi search history next.
|
||||||
|
.It Ic vi-repeat-search-next
|
||||||
|
Vi repeat current search in the same search direction.
|
||||||
|
.It Ic vi-repeat-search-prev
|
||||||
|
Vi repeat current search in the opposite search direction.
|
||||||
|
.It Ic vi-next-char
|
||||||
|
Vi move to the character specified next.
|
||||||
|
.It Ic vi-prev-char
|
||||||
|
Vi move to the character specified previous.
|
||||||
|
.It Ic vi-to-next-char
|
||||||
|
Vi move up to the character specified next.
|
||||||
|
.It Ic vi-to-prev-char
|
||||||
|
Vi move up to the character specified previous.
|
||||||
|
.It Ic vi-repeat-next-char
|
||||||
|
Vi repeat current character search in the same search direction.
|
||||||
|
.It Ic vi-repeat-prev-char
|
||||||
|
Vi repeat current character search in the opposite search direction.
|
||||||
|
.It Ic em-delete-or-list
|
||||||
|
Delete character under cursor or list completions if at end of line.
|
||||||
|
.It Ic em-delete-next-word
|
||||||
|
Cut from cursor to end of current word.
|
||||||
|
.It Ic em-yank
|
||||||
|
Paste cut buffer at cursor position.
|
||||||
|
.It Ic em-kill-line
|
||||||
|
Cut the entire line and save in cut buffer.
|
||||||
|
.It Ic em-kill-region
|
||||||
|
Cut area between mark and cursor and save in cut buffer.
|
||||||
|
.It Ic em-copy-region
|
||||||
|
Copy area between mark and cursor to cut buffer.
|
||||||
|
.It Ic em-gosmacs-transpose
|
||||||
|
Exchange the two characters before the cursor.
|
||||||
|
.It Ic em-next-word
|
||||||
|
Move next to end of current word.
|
||||||
|
.It Ic em-upper-case
|
||||||
|
Uppercase the characters from cursor to end of current word.
|
||||||
|
.It Ic em-capitol-case
|
||||||
|
Capitalize the characters from cursor to end of current word.
|
||||||
|
.It Ic em-lower-case
|
||||||
|
Lowercase the characters from cursor to end of current word.
|
||||||
|
.It Ic em-set-mark
|
||||||
|
Set the mark at cursor.
|
||||||
|
.It Ic em-exchange-mark
|
||||||
|
Exchange the cursor and mark.
|
||||||
|
.It Ic em-universal-argument
|
||||||
|
Universal argument (argument times 4).
|
||||||
|
.It Ic em-meta-next
|
||||||
|
Add 8th bit to next character typed.
|
||||||
|
.It Ic em-toggle-overwrite
|
||||||
|
Switch from insert to overwrite mode or vice versa.
|
||||||
|
.It Ic em-copy-prev-word
|
||||||
|
Copy current word to cursor.
|
||||||
|
.It Ic em-inc-search-next
|
||||||
|
Emacs incremental next search.
|
||||||
|
.It Ic em-inc-search-prev
|
||||||
|
Emacs incremental reverse search.
|
||||||
|
.It Ic ed-end-of-file
|
||||||
|
Indicate end of file.
|
||||||
|
.It Ic ed-insert
|
||||||
|
Add character to the line.
|
||||||
|
.It Ic ed-delete-prev-word
|
||||||
|
Delete from beginning of current word to cursor.
|
||||||
|
.It Ic ed-delete-next-char
|
||||||
|
Delete character under cursor.
|
||||||
|
.It Ic ed-kill-line
|
||||||
|
Cut to the end of line.
|
||||||
|
.It Ic ed-move-to-end
|
||||||
|
Move cursor to the end of line.
|
||||||
|
.It Ic ed-move-to-beg
|
||||||
|
Move cursor to the beginning of line.
|
||||||
|
.It Ic ed-transpose-chars
|
||||||
|
Exchange the character to the left of the cursor with the one under it.
|
||||||
|
.It Ic ed-next-char
|
||||||
|
Move to the right one character.
|
||||||
|
.It Ic ed-prev-word
|
||||||
|
Move to the beginning of the current word.
|
||||||
|
.It Ic ed-prev-char
|
||||||
|
Move to the left one character.
|
||||||
|
.It Ic ed-quoted-insert
|
||||||
|
Add the next character typed verbatim.
|
||||||
|
.It Ic ed-digit
|
||||||
|
Adds to argument or enters a digit.
|
||||||
|
.It Ic ed-argument-digit
|
||||||
|
Digit that starts argument.
|
||||||
|
.It Ic ed-unassigned
|
||||||
|
Indicates unbound character.
|
||||||
|
.It Ic ed-tty-sigint
|
||||||
|
Tty interrupt character.
|
||||||
|
.It Ic ed-tty-dsusp
|
||||||
|
Tty delayed suspend character.
|
||||||
|
.It Ic ed-tty-flush-output
|
||||||
|
Tty flush output characters.
|
||||||
|
.It Ic ed-tty-sigquit
|
||||||
|
Tty quit character.
|
||||||
|
.It Ic ed-tty-sigtstp
|
||||||
|
Tty suspend character.
|
||||||
|
.It Ic ed-tty-stop-output
|
||||||
|
Tty disallow output characters.
|
||||||
|
.It Ic ed-tty-start-output
|
||||||
|
Tty allow output characters.
|
||||||
|
.It Ic ed-newline
|
||||||
|
Execute command.
|
||||||
|
.It Ic ed-delete-prev-char
|
||||||
|
Delete the character to the left of the cursor.
|
||||||
|
.It Ic ed-clear-screen
|
||||||
|
Clear screen leaving current line at the top.
|
||||||
|
.It Ic ed-redisplay
|
||||||
|
Redisplay everything.
|
||||||
|
.It Ic ed-start-over
|
||||||
|
Erase current line and start from scratch.
|
||||||
|
.It Ic ed-sequence-lead-in
|
||||||
|
First character in a bound sequence.
|
||||||
|
.It Ic ed-prev-history
|
||||||
|
Move to the previous history line.
|
||||||
|
.It Ic ed-next-history
|
||||||
|
Move to the next history line.
|
||||||
|
.It Ic ed-search-prev-history
|
||||||
|
Search previous in history for a line matching the current.
|
||||||
|
.It Ic ed-search-next-history
|
||||||
|
Search next in history for a line matching the current.
|
||||||
|
.It Ic ed-prev-line
|
||||||
|
Move up one line.
|
||||||
|
.It Ic ed-next-line
|
||||||
|
Move down one line.
|
||||||
|
.It Ic ed-command
|
||||||
|
Editline extended command.
|
||||||
|
.El
|
||||||
|
.\" End of section automatically generated with makelist
|
||||||
|
.Sh SEE ALSO
|
||||||
|
.Xr editline 3 ,
|
||||||
|
.Xr regex 3 ,
|
||||||
|
.Xr termcap 5
|
||||||
|
.Sh AUTHORS
|
||||||
|
The
|
||||||
|
.Nm editline
|
||||||
|
library was written by Christos Zoulas,
|
||||||
|
and this manual was written by Luke Mewburn,
|
||||||
|
with some sections inspired by
|
||||||
|
.Xr tcsh 1 .
|
|
@ -0,0 +1,459 @@
|
||||||
|
#!/usr/bin/awk
|
||||||
|
#
|
||||||
|
# Version history:
|
||||||
|
# v3, I put the program under a proper license
|
||||||
|
# Dan Nelson <dnelson@allantgroup.com> added .An, .Aq and fixed a typo
|
||||||
|
# v2, fixed to work on GNU awk --posix and MacOS X
|
||||||
|
# v1, first attempt, didn't work on MacOS X
|
||||||
|
#
|
||||||
|
# Copyright (c) 2003 Peter Stuge <stuge-mdoc2man@cdy.org>
|
||||||
|
#
|
||||||
|
# Permission to use, copy, modify, and distribute this software for any
|
||||||
|
# purpose with or without fee is hereby granted, provided that the above
|
||||||
|
# copyright notice and this permission notice appear in all copies.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
|
||||||
|
|
||||||
|
BEGIN {
|
||||||
|
optlist=0
|
||||||
|
oldoptlist=0
|
||||||
|
nospace=0
|
||||||
|
synopsis=0
|
||||||
|
reference=0
|
||||||
|
block=0
|
||||||
|
ext=0
|
||||||
|
extopt=0
|
||||||
|
literal=0
|
||||||
|
prenl=0
|
||||||
|
breakw=0
|
||||||
|
line=""
|
||||||
|
proto=0
|
||||||
|
bl_level=0
|
||||||
|
}
|
||||||
|
|
||||||
|
function wtail() {
|
||||||
|
retval=""
|
||||||
|
while(w<nwords) {
|
||||||
|
if(length(retval))
|
||||||
|
retval=retval OFS
|
||||||
|
retval=retval words[++w]
|
||||||
|
}
|
||||||
|
return retval
|
||||||
|
}
|
||||||
|
|
||||||
|
function add(str) {
|
||||||
|
for(;prenl;prenl--)
|
||||||
|
line=line "\n"
|
||||||
|
line=line str
|
||||||
|
}
|
||||||
|
|
||||||
|
! /^\./ {
|
||||||
|
for(;prenl;prenl--)
|
||||||
|
print ""
|
||||||
|
print
|
||||||
|
if(literal)
|
||||||
|
print ".br"
|
||||||
|
next
|
||||||
|
}
|
||||||
|
|
||||||
|
/^\.\\"/ { next }
|
||||||
|
|
||||||
|
{
|
||||||
|
option=0
|
||||||
|
parens=0
|
||||||
|
angles=0
|
||||||
|
sub("^\\.","")
|
||||||
|
nwords=split($0,words)
|
||||||
|
for(w=1;w<=nwords;w++) {
|
||||||
|
skip=0
|
||||||
|
if(match(words[w],"^Li|Pf$")) {
|
||||||
|
skip=1
|
||||||
|
} else if(match(words[w],"^Xo$")) {
|
||||||
|
skip=1
|
||||||
|
ext=1
|
||||||
|
if(length(line)&&!(match(line," $")||prenl))
|
||||||
|
add(OFS)
|
||||||
|
} else if(match(words[w],"^Xc$")) {
|
||||||
|
skip=1
|
||||||
|
ext=0
|
||||||
|
if(!extopt)
|
||||||
|
prenl++
|
||||||
|
w=nwords
|
||||||
|
} else if(match(words[w],"^Bd$")) {
|
||||||
|
skip=1
|
||||||
|
if(match(words[w+1],"-literal")) {
|
||||||
|
literal=1
|
||||||
|
prenl++
|
||||||
|
w=nwords
|
||||||
|
}
|
||||||
|
} else if(match(words[w],"^Po$")) {
|
||||||
|
skip=1
|
||||||
|
add("(")
|
||||||
|
if(!nospace)
|
||||||
|
nospace=1
|
||||||
|
} else if(match(words[w],"^Pc$")) {
|
||||||
|
skip=1
|
||||||
|
add(")")
|
||||||
|
if(!nospace)
|
||||||
|
nospace=1
|
||||||
|
} else if(match(words[w],"^Ed$")) {
|
||||||
|
skip=1
|
||||||
|
literal=0
|
||||||
|
} else if(match(words[w],"^Ns$")) {
|
||||||
|
skip=1
|
||||||
|
if(!nospace)
|
||||||
|
nospace=1
|
||||||
|
sub(" $","",line)
|
||||||
|
} else if(match(words[w],"^No$")) {
|
||||||
|
skip=1
|
||||||
|
sub(" $","",line)
|
||||||
|
add(words[++w])
|
||||||
|
} else if(match(words[w],"^Dq$")) {
|
||||||
|
skip=1
|
||||||
|
add("``")
|
||||||
|
add(words[++w])
|
||||||
|
while(w<nwords&&!match(words[w+1],"^[\\.,]"))
|
||||||
|
add(OFS words[++w])
|
||||||
|
add("''")
|
||||||
|
if(!nospace&&match(words[w+1],"^[\\.,]"))
|
||||||
|
nospace=1
|
||||||
|
} else if(match(words[w],"^Va$")) {
|
||||||
|
skip=1
|
||||||
|
add("\\fI" words[++w])
|
||||||
|
while(w<nwords&&!match(words[w+1],"^[\\.,]"))
|
||||||
|
add(OFS words[++w])
|
||||||
|
add("\\fP")
|
||||||
|
if(!nospace&&match(words[w+1],"^[\\.,]"))
|
||||||
|
nospace=1
|
||||||
|
} else if(match(words[w],"^Sq|Ql$")) {
|
||||||
|
skip=1
|
||||||
|
add("`" words[++w] "'")
|
||||||
|
if(!nospace&&match(words[w+1],"^[\\.,]"))
|
||||||
|
nospace=1
|
||||||
|
} else if(match(words[w],"^Oo$")) {
|
||||||
|
skip=1
|
||||||
|
extopt=1
|
||||||
|
if(!nospace)
|
||||||
|
nospace=1
|
||||||
|
add("[")
|
||||||
|
} else if(match(words[w],"^Oc$")) {
|
||||||
|
skip=1
|
||||||
|
extopt=0
|
||||||
|
add("]")
|
||||||
|
}
|
||||||
|
if(!skip) {
|
||||||
|
if(!nospace&&length(line)&&!(match(line," $")||prenl))
|
||||||
|
add(OFS)
|
||||||
|
if(nospace==1)
|
||||||
|
nospace=0
|
||||||
|
}
|
||||||
|
if(match(words[w],"^Dd$")) {
|
||||||
|
date=wtail()
|
||||||
|
next
|
||||||
|
} else if(match(words[w],"^Dt$")) {
|
||||||
|
id=wtail()
|
||||||
|
next
|
||||||
|
} else if(match(words[w],"^Os$")) {
|
||||||
|
add(".TH " id " \"" date "\" \"" wtail() "\"")
|
||||||
|
} else if(match(words[w],"^Sh$")) {
|
||||||
|
add(".SH")
|
||||||
|
synopsis=match(words[w+1],"SYNOPSIS")
|
||||||
|
} else if(match(words[w],"^Xr$")) {
|
||||||
|
#add("\\fB" words[++w] "\\fP(" words[++w] ")" words[++w])
|
||||||
|
add("\\fB" words[++w] "\\fP(" words[++w] ")")
|
||||||
|
sub("^Ns$", "", words[w+1])
|
||||||
|
add(words[++w])
|
||||||
|
} else if(match(words[w],"^Rs$")) {
|
||||||
|
split("",refauthors)
|
||||||
|
nrefauthors=0
|
||||||
|
reftitle=""
|
||||||
|
refissue=""
|
||||||
|
refdate=""
|
||||||
|
refopt=""
|
||||||
|
reference=1
|
||||||
|
next
|
||||||
|
} else if(match(words[w],"^Re$")) {
|
||||||
|
prenl++
|
||||||
|
for(i=nrefauthors-1;i>0;i--) {
|
||||||
|
add(refauthors[i])
|
||||||
|
if(i>1)
|
||||||
|
add(", ")
|
||||||
|
}
|
||||||
|
if(nrefauthors>1)
|
||||||
|
add(" and ")
|
||||||
|
add(refauthors[0] ", \\fI" reftitle "\\fP")
|
||||||
|
if(length(refissue))
|
||||||
|
add(", " refissue)
|
||||||
|
if(length(refdate))
|
||||||
|
add(", " refdate)
|
||||||
|
if(length(refopt))
|
||||||
|
add(", " refopt)
|
||||||
|
add(".")
|
||||||
|
reference=0
|
||||||
|
} else if(reference) {
|
||||||
|
if(match(words[w],"^%A$")) { refauthors[nrefauthors++]=wtail() }
|
||||||
|
if(match(words[w],"^%T$")) {
|
||||||
|
reftitle=wtail()
|
||||||
|
sub("^\"","",reftitle)
|
||||||
|
sub("\"$","",reftitle)
|
||||||
|
}
|
||||||
|
if(match(words[w],"^%N$")) { refissue=wtail() }
|
||||||
|
if(match(words[w],"^%D$")) { refdate=wtail() }
|
||||||
|
if(match(words[w],"^%O$")) { refopt=wtail() }
|
||||||
|
} else if(match(words[w],"^Nm$")) {
|
||||||
|
if(synopsis) {
|
||||||
|
add(".br")
|
||||||
|
prenl++
|
||||||
|
}
|
||||||
|
n=words[++w]
|
||||||
|
if(!length(name))
|
||||||
|
name=n
|
||||||
|
if(!length(n))
|
||||||
|
n=name
|
||||||
|
add("\\fB" n "\\fP")
|
||||||
|
if(!nospace&&match(words[w+1],"^[\\.,]"))
|
||||||
|
nospace=1
|
||||||
|
} else if(match(words[w],"^Nd$")) {
|
||||||
|
add("\\- " wtail())
|
||||||
|
} else if(match(words[w],"^Fl$")) {
|
||||||
|
add("\\fB\\-" words[++w] "\\fP")
|
||||||
|
if(!nospace&&match(words[w+1],"^[\\.,]"))
|
||||||
|
nospace=1
|
||||||
|
} else if(match(words[w],"^Ar$")) {
|
||||||
|
add("\\fI")
|
||||||
|
if(w==nwords)
|
||||||
|
add("file ...\\fP")
|
||||||
|
else {
|
||||||
|
add(words[++w] "\\fP")
|
||||||
|
while(match(words[w+1],"^\\|$"))
|
||||||
|
add(OFS words[++w] " \\fI" words[++w] "\\fP")
|
||||||
|
}
|
||||||
|
if(!nospace&&match(words[w+1],"^[\\.,]"))
|
||||||
|
nospace=1
|
||||||
|
} else if(match(words[w],"^Cm$")) {
|
||||||
|
add("\\fB" words[++w] "\\fP")
|
||||||
|
while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
|
||||||
|
add(words[++w])
|
||||||
|
} else if(match(words[w],"^Op$")) {
|
||||||
|
option=1
|
||||||
|
if(!nospace)
|
||||||
|
nospace=1
|
||||||
|
add("[")
|
||||||
|
} else if(match(words[w],"^Pp$")) {
|
||||||
|
prenl++
|
||||||
|
} else if(match(words[w],"^An$")) {
|
||||||
|
prenl++
|
||||||
|
} else if(match(words[w],"^Ss$")) {
|
||||||
|
add(".SS")
|
||||||
|
} else if(match(words[w],"^Pa$")&&!option) {
|
||||||
|
add("\\fI")
|
||||||
|
w++
|
||||||
|
if(match(words[w],"^\\."))
|
||||||
|
add("\\&")
|
||||||
|
add(words[w] "\\fP")
|
||||||
|
while(w<nwords&&match(words[w+1],"^[\\.,:;)]"))
|
||||||
|
add(words[++w])
|
||||||
|
} else if(match(words[w],"^Dv$")) {
|
||||||
|
#add(".BR")
|
||||||
|
} else if(match(words[w],"^Em|Ev$")) {
|
||||||
|
add(".IR")
|
||||||
|
} else if(match(words[w],"^Pq$")) {
|
||||||
|
add("(")
|
||||||
|
nospace=1
|
||||||
|
parens=1
|
||||||
|
} else if(match(words[w],"^Aq$")) {
|
||||||
|
add("<")
|
||||||
|
nospace=1
|
||||||
|
angles=1
|
||||||
|
} else if(match(words[w],"^S[xy]$")) {
|
||||||
|
add(".B " wtail())
|
||||||
|
} else if(match(words[w],"^Ic$")) {
|
||||||
|
plain=1
|
||||||
|
add("\\fB")
|
||||||
|
while(w<nwords) {
|
||||||
|
w++
|
||||||
|
if(match(words[w],"^Op$")) {
|
||||||
|
w++
|
||||||
|
add("[")
|
||||||
|
words[nwords]=words[nwords] "]"
|
||||||
|
}
|
||||||
|
if(match(words[w],"^Ar$")) {
|
||||||
|
add("\\fI" words[++w] "\\fP")
|
||||||
|
} else if(match(words[w],"^[\\.,]")) {
|
||||||
|
sub(" $","",line)
|
||||||
|
if(plain) {
|
||||||
|
add("\\fP")
|
||||||
|
plain=0
|
||||||
|
}
|
||||||
|
add(words[w])
|
||||||
|
} else if(match(words[w],"^Xo$")) {
|
||||||
|
} else {
|
||||||
|
if(!plain) {
|
||||||
|
add("\\fB")
|
||||||
|
plain=1
|
||||||
|
}
|
||||||
|
add(words[w])
|
||||||
|
}
|
||||||
|
if(!nospace)
|
||||||
|
add(OFS)
|
||||||
|
}
|
||||||
|
sub(" $","",line)
|
||||||
|
if(plain)
|
||||||
|
add("\\fP")
|
||||||
|
} else if(match(words[w],"^Dl$")) {
|
||||||
|
## remove is ok for editrc.5
|
||||||
|
} else if(match(words[w],"^Bl$")) {
|
||||||
|
++bl_level
|
||||||
|
if (bl_level > 1)
|
||||||
|
add(".RS")
|
||||||
|
oldoptlist=optlist
|
||||||
|
if(match(words[w+1],"-bullet"))
|
||||||
|
optlist=1
|
||||||
|
else if(match(words[w+1],"-enum")) {
|
||||||
|
optlist=2
|
||||||
|
enum=0
|
||||||
|
} else if(match(words[w+1],"-tag"))
|
||||||
|
optlist=3
|
||||||
|
else if(match(words[w+1],"-item"))
|
||||||
|
optlist=4
|
||||||
|
else if(match(words[w+1],"-bullet"))
|
||||||
|
optlist=1
|
||||||
|
w=nwords
|
||||||
|
} else if(match(words[w],"^El$")) {
|
||||||
|
if (bl_level > 1)
|
||||||
|
add(".RE")
|
||||||
|
--bl_level
|
||||||
|
optlist=oldoptlist
|
||||||
|
} else if(match(words[w],"^Bk$")) {
|
||||||
|
if(match(words[w+1],"-words")) {
|
||||||
|
w++
|
||||||
|
breakw=1
|
||||||
|
}
|
||||||
|
} else if(match(words[w],"^Ek$")) {
|
||||||
|
breakw=0
|
||||||
|
} else if(match(words[w],"^It$")&&optlist) {
|
||||||
|
if(optlist==1)
|
||||||
|
add(".IP \\(bu")
|
||||||
|
else if(optlist==2)
|
||||||
|
add(".IP " ++enum ".")
|
||||||
|
else if(optlist==3) {
|
||||||
|
add(".TP")
|
||||||
|
prenl++
|
||||||
|
if(match(words[w+1],"^Pa$|^Ev$")) {
|
||||||
|
add(".B")
|
||||||
|
w++
|
||||||
|
}
|
||||||
|
} else if(optlist==4)
|
||||||
|
add(".IP")
|
||||||
|
} else if(match(words[w],"^Sm$")) {
|
||||||
|
if(match(words[w+1],"off"))
|
||||||
|
nospace=2
|
||||||
|
else if(match(words[w+1],"on"))
|
||||||
|
nospace=0
|
||||||
|
w++
|
||||||
|
} else if(match(words[w],"^Lb$")) {
|
||||||
|
wtail()
|
||||||
|
add("Command Line Editor Library (libedit, -ledit)")
|
||||||
|
} else if(match(words[w],"^In$")) {
|
||||||
|
add(".PP\n")
|
||||||
|
add("\\fB#include <" wtail() ">\\fP")
|
||||||
|
} else if(match(words[w],"^Ft$")) {
|
||||||
|
add(".PP\n")
|
||||||
|
add("\\fI" wtail() "\\fP\n")
|
||||||
|
add(".br")
|
||||||
|
proto=1
|
||||||
|
} else if(match(words[w],"^Fn$")) {
|
||||||
|
add("\\fB" words[++w] "\\fP(")
|
||||||
|
punct=0
|
||||||
|
while(++w<=nwords) {
|
||||||
|
if(match(words[w], "^\".*\"$")) {
|
||||||
|
sub("^\"", "", words[w])
|
||||||
|
sub("\"$", "", words[w])
|
||||||
|
add("\\fI" words[w] "\\fP")
|
||||||
|
if (w!=nwords) {
|
||||||
|
add(", ")
|
||||||
|
}
|
||||||
|
} else if(match(words[w], "^\"")) {
|
||||||
|
sub("^\"", "", words[w])
|
||||||
|
add("\\fI" words[w] " ")
|
||||||
|
} else if (match(words[w], "\"$")) {
|
||||||
|
sub("\"$", "", words[w])
|
||||||
|
add(words[w] "\\fP")
|
||||||
|
if (w!=nwords) {
|
||||||
|
add(", ")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (w==nwords&&(match(words[w], "^[.,]$"))) {
|
||||||
|
punct=1
|
||||||
|
} else {
|
||||||
|
add(words[w] " ")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add(")")
|
||||||
|
if (punct==1) {
|
||||||
|
add(words[w-1])
|
||||||
|
} else {
|
||||||
|
if (proto==1) {
|
||||||
|
add(";")
|
||||||
|
proto=0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if(match(words[w],"^Fa$")) {
|
||||||
|
punct=0
|
||||||
|
add("\\fI")
|
||||||
|
while(++w<=nwords) {
|
||||||
|
if(match(words[w], "^\".*\"$")) {
|
||||||
|
sub("^\"", "", words[w])
|
||||||
|
sub("\"$", "", words[w])
|
||||||
|
add(words[w])
|
||||||
|
} else if(match(words[w], "^\"")) {
|
||||||
|
sub("^\"", "", words[w])
|
||||||
|
add(words[w] " ")
|
||||||
|
} else if (match(words[w], "\"$")) {
|
||||||
|
sub("\"$", "", words[w])
|
||||||
|
add(words[w])
|
||||||
|
} else {
|
||||||
|
if (w==nwords&&(match(words[w], "^[.,]$"))) {
|
||||||
|
punct=1
|
||||||
|
} else {
|
||||||
|
if (w+1==nwords&&(match(words[w+1], "^[.,]$"))) {
|
||||||
|
add(words[w])
|
||||||
|
} else {
|
||||||
|
add(words[w] " ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
add("\\fP")
|
||||||
|
if (punct==1) {
|
||||||
|
add(words[w-1])
|
||||||
|
}
|
||||||
|
} else if(!skip) {
|
||||||
|
add(words[w])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(match(line,"^\\.[^a-zA-Z]"))
|
||||||
|
sub("^\\.","",line)
|
||||||
|
if(parens)
|
||||||
|
add(")")
|
||||||
|
if(angles)
|
||||||
|
add(">")
|
||||||
|
if(option)
|
||||||
|
add("]")
|
||||||
|
if(ext&&!extopt&&!match(line," $"))
|
||||||
|
add(OFS)
|
||||||
|
if(!ext&&!extopt&&length(line)) {
|
||||||
|
print line
|
||||||
|
prenl=0
|
||||||
|
line=""
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
|
||||||
|
LDADD = $(top_builddir)/src/libedit.la
|
||||||
|
AM_CFLAGS = -I$(top_srcdir)/src
|
||||||
|
|
||||||
|
noinst_PROGRAMS = test fileman
|
||||||
|
|
||||||
|
test_SOURCES = test.c
|
||||||
|
fileman_SOURCES = fileman.c
|
|
@ -0,0 +1,492 @@
|
||||||
|
/* fileman.c -- A tiny application which demonstrates how to use the
|
||||||
|
GNU Readline library. This application interactively allows users
|
||||||
|
to manipulate files and their modes.
|
||||||
|
|
||||||
|
NOTE: this was taken from the GNU Readline documentation and ported
|
||||||
|
to libedit. A commad to output the history list was added.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/file.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/errno.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/* GNU readline
|
||||||
|
#include <readline/readline.h>
|
||||||
|
#include <readline/history.h>
|
||||||
|
*/
|
||||||
|
#include <editline/readline.h>
|
||||||
|
|
||||||
|
void * xmalloc (size_t size);
|
||||||
|
void too_dangerous (char *caller);
|
||||||
|
void initialize_readline ();
|
||||||
|
int execute_line (char *line);
|
||||||
|
int valid_argument (char *caller, char *arg);
|
||||||
|
|
||||||
|
typedef int rl_icpfunc_t (char *);
|
||||||
|
|
||||||
|
/* The names of functions that actually do the manipulation. */
|
||||||
|
int com_list (char *);
|
||||||
|
int com_view (char *);
|
||||||
|
int com_history (char *);
|
||||||
|
int com_rename(char *);
|
||||||
|
int com_stat(char *);
|
||||||
|
int com_pwd(char *);
|
||||||
|
int com_delete(char *);
|
||||||
|
int com_help(char *);
|
||||||
|
int com_cd(char *);
|
||||||
|
int com_quit(char *);
|
||||||
|
|
||||||
|
/* A structure which contains information on the commands this program
|
||||||
|
can understand. */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *name; /* User printable name of the function. */
|
||||||
|
rl_icpfunc_t *func; /* Function to call to do the job. */
|
||||||
|
char *doc; /* Documentation for this function. */
|
||||||
|
} COMMAND;
|
||||||
|
|
||||||
|
COMMAND commands[] = {
|
||||||
|
{ "cd", com_cd, "Change to directory DIR" },
|
||||||
|
{ "delete", com_delete, "Delete FILE" },
|
||||||
|
{ "help", com_help, "Display this text" },
|
||||||
|
{ "?", com_help, "Synonym for `help'" },
|
||||||
|
{ "list", com_list, "List files in DIR" },
|
||||||
|
{ "ls", com_list, "Synonym for `list'" },
|
||||||
|
{ "pwd", com_pwd, "Print the current working directory" },
|
||||||
|
{ "quit", com_quit, "Quit using Fileman" },
|
||||||
|
{ "rename", com_rename, "Rename FILE to NEWNAME" },
|
||||||
|
{ "stat", com_stat, "Print out statistics on FILE" },
|
||||||
|
{ "view", com_view, "View the contents of FILE" },
|
||||||
|
{ "history", com_history, "List editline history" },
|
||||||
|
{ (char *)NULL, (rl_icpfunc_t *)NULL, (char *)NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Forward declarations. */
|
||||||
|
char *stripwhite ();
|
||||||
|
COMMAND *find_command ();
|
||||||
|
|
||||||
|
/* The name of this program, as taken from argv[0]. */
|
||||||
|
char *progname;
|
||||||
|
|
||||||
|
/* When non-zero, this means the user is done using this program. */
|
||||||
|
int done;
|
||||||
|
|
||||||
|
char *
|
||||||
|
dupstr (char* s)
|
||||||
|
{
|
||||||
|
char *r;
|
||||||
|
|
||||||
|
r = xmalloc (strlen (s) + 1);
|
||||||
|
strcpy (r, s);
|
||||||
|
return (r);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main (int argc, char **argv)
|
||||||
|
{
|
||||||
|
char *line, *s;
|
||||||
|
|
||||||
|
progname = argv[0];
|
||||||
|
|
||||||
|
initialize_readline(); /* Bind our completer. */
|
||||||
|
|
||||||
|
stifle_history(7);
|
||||||
|
|
||||||
|
/* Loop reading and executing lines until the user quits. */
|
||||||
|
for ( ; done == 0; )
|
||||||
|
{
|
||||||
|
line = readline ("FileMan: ");
|
||||||
|
|
||||||
|
if (!line)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Remove leading and trailing whitespace from the line.
|
||||||
|
Then, if there is anything left, add it to the history list
|
||||||
|
and execute it. */
|
||||||
|
s = stripwhite(line);
|
||||||
|
|
||||||
|
if (*s) {
|
||||||
|
|
||||||
|
char* expansion;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
result = history_expand(s, &expansion);
|
||||||
|
|
||||||
|
if (result < 0 || result == 2) {
|
||||||
|
fprintf(stderr, "%s\n", expansion);
|
||||||
|
} else {
|
||||||
|
add_history(expansion);
|
||||||
|
execute_line(expansion);
|
||||||
|
}
|
||||||
|
free(expansion);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(line);
|
||||||
|
}
|
||||||
|
exit (0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Execute a command line. */
|
||||||
|
int
|
||||||
|
execute_line (char *line)
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
COMMAND *command;
|
||||||
|
char *word;
|
||||||
|
|
||||||
|
/* Isolate the command word. */
|
||||||
|
i = 0;
|
||||||
|
while (line[i] && isspace (line[i]))
|
||||||
|
i++;
|
||||||
|
word = line + i;
|
||||||
|
|
||||||
|
while (line[i] && !isspace (line[i]))
|
||||||
|
i++;
|
||||||
|
|
||||||
|
if (line[i])
|
||||||
|
line[i++] = '\0';
|
||||||
|
|
||||||
|
command = find_command (word);
|
||||||
|
|
||||||
|
if (!command)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s: No such command for FileMan.\n", word);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get argument to command, if any. */
|
||||||
|
while (isspace (line[i]))
|
||||||
|
i++;
|
||||||
|
|
||||||
|
word = line + i;
|
||||||
|
|
||||||
|
/* Call the function. */
|
||||||
|
return ((*(command->func)) (word));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Look up NAME as the name of a command, and return a pointer to that
|
||||||
|
command. Return a NULL pointer if NAME isn't a command name. */
|
||||||
|
COMMAND *
|
||||||
|
find_command (char *name)
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
for (i = 0; commands[i].name; i++)
|
||||||
|
if (strcmp (name, commands[i].name) == 0)
|
||||||
|
return (&commands[i]);
|
||||||
|
|
||||||
|
return ((COMMAND *)NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Strip whitespace from the start and end of STRING. Return a pointer
|
||||||
|
into STRING. */
|
||||||
|
char *
|
||||||
|
stripwhite (char *string)
|
||||||
|
{
|
||||||
|
register char *s, *t;
|
||||||
|
|
||||||
|
for (s = string; isspace (*s); s++)
|
||||||
|
;
|
||||||
|
|
||||||
|
if (*s == 0)
|
||||||
|
return (s);
|
||||||
|
|
||||||
|
t = s + strlen (s) - 1;
|
||||||
|
while (t > s && isspace (*t))
|
||||||
|
t--;
|
||||||
|
*++t = '\0';
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* **************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* Interface to Readline Completion */
|
||||||
|
/* */
|
||||||
|
/* **************************************************************** */
|
||||||
|
|
||||||
|
char *command_generator(const char *, int);
|
||||||
|
char **fileman_completion(const char *, int, int);
|
||||||
|
|
||||||
|
/* Tell the GNU Readline library how to complete. We want to try to
|
||||||
|
complete on command names if this is the first word in the line, or
|
||||||
|
on filenames if not. */
|
||||||
|
void
|
||||||
|
initialize_readline ()
|
||||||
|
{
|
||||||
|
/* Allow conditional parsing of the ~/.inputrc file. */
|
||||||
|
rl_readline_name = "FileMan";
|
||||||
|
|
||||||
|
/* Tell the completer that we want a crack first. */
|
||||||
|
rl_attempted_completion_function = fileman_completion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Attempt to complete on the contents of TEXT. START and END
|
||||||
|
bound the region of rl_line_buffer that contains the word to
|
||||||
|
complete. TEXT is the word to complete. We can use the entire
|
||||||
|
contents of rl_line_buffer in case we want to do some simple
|
||||||
|
parsing. Returnthe array of matches, or NULL if there aren't any. */
|
||||||
|
char **
|
||||||
|
fileman_completion (const char* text, int start, int end)
|
||||||
|
{
|
||||||
|
char **matches;
|
||||||
|
|
||||||
|
matches = (char **)NULL;
|
||||||
|
|
||||||
|
/* If this word is at the start of the line, then it is a command
|
||||||
|
to complete. Otherwise it is the name of a file in the current
|
||||||
|
directory. */
|
||||||
|
if (start == 0)
|
||||||
|
/* TODO */
|
||||||
|
matches = completion_matches (text, command_generator);
|
||||||
|
/* matches = rl_completion_matches (text, command_generator); */
|
||||||
|
|
||||||
|
return (matches);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generator function for command completion. STATE lets us
|
||||||
|
know whether to start from scratch; without any state
|
||||||
|
(i.e. STATE == 0), then we start at the top of the list. */
|
||||||
|
char *
|
||||||
|
command_generator (text, state)
|
||||||
|
const char *text;
|
||||||
|
int state;
|
||||||
|
{
|
||||||
|
static int list_index, len;
|
||||||
|
char *name;
|
||||||
|
|
||||||
|
/* If this is a new word to complete, initialize now. This
|
||||||
|
includes saving the length of TEXT for efficiency, and
|
||||||
|
initializing the index variable to 0. */
|
||||||
|
if (!state)
|
||||||
|
{
|
||||||
|
list_index = 0;
|
||||||
|
len = strlen (text);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the next name which partially matches from the
|
||||||
|
command list. */
|
||||||
|
while (name = commands[list_index].name)
|
||||||
|
{
|
||||||
|
list_index++;
|
||||||
|
|
||||||
|
if (strncmp (name, text, len) == 0)
|
||||||
|
return (dupstr(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If no names matched, then return NULL. */
|
||||||
|
return ((char *)NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* **************************************************************** */
|
||||||
|
/* */
|
||||||
|
/* FileMan Commands */
|
||||||
|
/* */
|
||||||
|
/* **************************************************************** */
|
||||||
|
|
||||||
|
/* String to pass to system (). This is for the LIST, VIEW and RENAME
|
||||||
|
commands. */
|
||||||
|
static char syscom[1024];
|
||||||
|
|
||||||
|
/* List the file(s) named in arg. */
|
||||||
|
int
|
||||||
|
com_list (char *arg)
|
||||||
|
{
|
||||||
|
if (!arg)
|
||||||
|
arg = "";
|
||||||
|
|
||||||
|
sprintf (syscom, "ls -FClg %s", arg);
|
||||||
|
return (system (syscom));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
com_view (char *arg)
|
||||||
|
{
|
||||||
|
if (!valid_argument ("view", arg))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
sprintf (syscom, "more %s", arg);
|
||||||
|
return (system (syscom));
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
com_history(char* arg)
|
||||||
|
{
|
||||||
|
int num, where;
|
||||||
|
HIST_ENTRY *he;
|
||||||
|
|
||||||
|
/* rewind history */
|
||||||
|
while (next_history())
|
||||||
|
;
|
||||||
|
|
||||||
|
for (he = current_history(); he != NULL; he = previous_history()) {
|
||||||
|
printf("%5d %s\n", *((int*)he->data), he->line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
com_rename (char *arg)
|
||||||
|
{
|
||||||
|
too_dangerous ("rename");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
com_stat (char *arg)
|
||||||
|
{
|
||||||
|
struct stat finfo;
|
||||||
|
|
||||||
|
if (!valid_argument ("stat", arg))
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
if (stat (arg, &finfo) == -1)
|
||||||
|
{
|
||||||
|
perror (arg);
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("Statistics for `%s':\n", arg);
|
||||||
|
|
||||||
|
printf ("%s has %d link%s, and is %d byte%s in length.\n", arg,
|
||||||
|
finfo.st_nlink,
|
||||||
|
(finfo.st_nlink == 1) ? "" : "s",
|
||||||
|
finfo.st_size,
|
||||||
|
(finfo.st_size == 1) ? "" : "s");
|
||||||
|
printf ("Inode Last Change at: %s", ctime (&finfo.st_ctime));
|
||||||
|
printf (" Last access at: %s", ctime (&finfo.st_atime));
|
||||||
|
printf (" Last modified at: %s", ctime (&finfo.st_mtime));
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
com_delete (char *arg)
|
||||||
|
{
|
||||||
|
too_dangerous ("delete");
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print out help for ARG, or for all of the commands if ARG is
|
||||||
|
not present. */
|
||||||
|
int
|
||||||
|
com_help (char *arg)
|
||||||
|
{
|
||||||
|
register int i;
|
||||||
|
int printed = 0;
|
||||||
|
|
||||||
|
for (i = 0; commands[i].name; i++)
|
||||||
|
{
|
||||||
|
if (!*arg || (strcmp (arg, commands[i].name) == 0))
|
||||||
|
{
|
||||||
|
printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc);
|
||||||
|
printed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!printed)
|
||||||
|
{
|
||||||
|
printf ("No commands match `%s'. Possibilties are:\n", arg);
|
||||||
|
|
||||||
|
for (i = 0; commands[i].name; i++)
|
||||||
|
{
|
||||||
|
/* Print in six columns. */
|
||||||
|
if (printed == 6)
|
||||||
|
{
|
||||||
|
printed = 0;
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("%s\t", commands[i].name);
|
||||||
|
printed++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (printed)
|
||||||
|
printf ("\n");
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Change to the directory ARG. */
|
||||||
|
int
|
||||||
|
com_cd (char *arg)
|
||||||
|
{
|
||||||
|
if (chdir (arg) == -1)
|
||||||
|
{
|
||||||
|
perror (arg);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
com_pwd ("");
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Print out the current working directory. */
|
||||||
|
int
|
||||||
|
com_pwd (char* ignore)
|
||||||
|
{
|
||||||
|
char dir[1024], *s;
|
||||||
|
|
||||||
|
s = (char*)getcwd(dir, sizeof(dir) - 1);
|
||||||
|
if (s == 0)
|
||||||
|
{
|
||||||
|
printf ("Error getting pwd: %s\n", dir);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf ("Current directory is %s\n", dir);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The user wishes to quit using this program. Just set DONE
|
||||||
|
non-zero. */
|
||||||
|
int
|
||||||
|
com_quit (char *arg)
|
||||||
|
{
|
||||||
|
done = 1;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Function which tells you that you can't do this. */
|
||||||
|
void
|
||||||
|
too_dangerous (char *caller)
|
||||||
|
{
|
||||||
|
fprintf (stderr,
|
||||||
|
"%s: Too dangerous for me to distribute.\n",
|
||||||
|
caller);
|
||||||
|
fprintf (stderr, "Write it yourself.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return non-zero if ARG is a valid argument for CALLER,
|
||||||
|
else print an error message and return zero. */
|
||||||
|
int
|
||||||
|
valid_argument (char *caller, char *arg)
|
||||||
|
{
|
||||||
|
if (!arg || !*arg)
|
||||||
|
{
|
||||||
|
fprintf (stderr, "%s: Argument required.\n", caller);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
xmalloc (size_t size)
|
||||||
|
{
|
||||||
|
register void *value = (void*)malloc(size);
|
||||||
|
if (value == 0)
|
||||||
|
fprintf(stderr, "virtual memory exhausted");
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,292 @@
|
||||||
|
/* $NetBSD: test.c,v 1.18 2005/06/01 11:37:52 lukem Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* test.c: A little test program
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
|
||||||
|
#include "histedit.h"
|
||||||
|
|
||||||
|
/* from src/sys/sys/cdefs.h */
|
||||||
|
#ifndef __UNCONST
|
||||||
|
# define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static int continuation = 0;
|
||||||
|
volatile sig_atomic_t gotsig = 0;
|
||||||
|
|
||||||
|
static unsigned char complete(EditLine *, int);
|
||||||
|
int main(int, char **);
|
||||||
|
static char *prompt(EditLine *);
|
||||||
|
static void sig(int);
|
||||||
|
|
||||||
|
static char *
|
||||||
|
prompt(EditLine *el)
|
||||||
|
{
|
||||||
|
static char a[] = "Edit$ ";
|
||||||
|
static char b[] = "Edit> ";
|
||||||
|
|
||||||
|
return (continuation ? b : a);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
sig(int i)
|
||||||
|
{
|
||||||
|
gotsig = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned char
|
||||||
|
complete(EditLine *el, int ch)
|
||||||
|
{
|
||||||
|
DIR *dd = opendir(".");
|
||||||
|
struct dirent *dp;
|
||||||
|
const char* ptr;
|
||||||
|
const LineInfo *lf = el_line(el);
|
||||||
|
int len;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find the last word
|
||||||
|
*/
|
||||||
|
for (ptr = lf->cursor - 1;
|
||||||
|
!isspace((unsigned char)*ptr) && ptr > lf->buffer; ptr--)
|
||||||
|
continue;
|
||||||
|
len = lf->cursor - ++ptr;
|
||||||
|
|
||||||
|
for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
|
||||||
|
if (len > strlen(dp->d_name))
|
||||||
|
continue;
|
||||||
|
if (strncmp(dp->d_name, ptr, len) == 0) {
|
||||||
|
closedir(dd);
|
||||||
|
if (el_insertstr(el, &dp->d_name[len]) == -1)
|
||||||
|
return (CC_ERROR);
|
||||||
|
else
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir(dd);
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
EditLine *el = NULL;
|
||||||
|
int num;
|
||||||
|
const char *buf;
|
||||||
|
Tokenizer *tok;
|
||||||
|
#if 0
|
||||||
|
int lastevent = 0;
|
||||||
|
#endif
|
||||||
|
int ncontinuation;
|
||||||
|
History *hist;
|
||||||
|
HistEvent ev;
|
||||||
|
|
||||||
|
(void) signal(SIGINT, sig);
|
||||||
|
(void) signal(SIGQUIT, sig);
|
||||||
|
(void) signal(SIGHUP, sig);
|
||||||
|
(void) signal(SIGTERM, sig);
|
||||||
|
|
||||||
|
hist = history_init(); /* Init the builtin history */
|
||||||
|
/* Remember 100 events */
|
||||||
|
history(hist, &ev, H_SETSIZE, 100);
|
||||||
|
|
||||||
|
tok = tok_init(NULL); /* Initialize the tokenizer */
|
||||||
|
|
||||||
|
/* Initialize editline */
|
||||||
|
el = el_init(*argv, stdin, stdout, stderr);
|
||||||
|
|
||||||
|
el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */
|
||||||
|
el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */
|
||||||
|
el_set(el, EL_PROMPT, prompt); /* Set the prompt function */
|
||||||
|
|
||||||
|
/* Tell editline to use this history interface */
|
||||||
|
el_set(el, EL_HIST, history, hist);
|
||||||
|
|
||||||
|
/* Add a user-defined function */
|
||||||
|
el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete);
|
||||||
|
|
||||||
|
/* Bind tab to it */
|
||||||
|
el_set(el, EL_BIND, "^I", "ed-complete", NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bind j, k in vi command mode to previous and next line, instead
|
||||||
|
* of previous and next history.
|
||||||
|
*/
|
||||||
|
el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL);
|
||||||
|
el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Source the user's defaults file.
|
||||||
|
*/
|
||||||
|
el_source(el, NULL);
|
||||||
|
|
||||||
|
while ((buf = el_gets(el, &num)) != NULL && num != 0) {
|
||||||
|
int ac, cc, co;
|
||||||
|
#ifdef DEBUG
|
||||||
|
int i;
|
||||||
|
#endif
|
||||||
|
const char **av;
|
||||||
|
const LineInfo *li;
|
||||||
|
li = el_line(el);
|
||||||
|
#ifdef DEBUG
|
||||||
|
(void) fprintf(stderr, "==> got %d %s", num, buf);
|
||||||
|
(void) fprintf(stderr, " > li `%.*s_%.*s'\n",
|
||||||
|
(li->cursor - li->buffer), li->buffer,
|
||||||
|
(li->lastchar - 1 - li->cursor),
|
||||||
|
(li->cursor >= li->lastchar) ? "" : li->cursor);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
if (gotsig) {
|
||||||
|
(void) fprintf(stderr, "Got signal %d.\n", gotsig);
|
||||||
|
gotsig = 0;
|
||||||
|
el_reset(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!continuation && num == 1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ac = cc = co = 0;
|
||||||
|
ncontinuation = tok_line(tok, li, &ac, &av, &cc, &co);
|
||||||
|
if (ncontinuation < 0) {
|
||||||
|
(void) fprintf(stderr, "Internal error\n");
|
||||||
|
continuation = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG
|
||||||
|
(void) fprintf(stderr, " > nc %d ac %d cc %d co %d\n",
|
||||||
|
ncontinuation, ac, cc, co);
|
||||||
|
#endif
|
||||||
|
#if 0
|
||||||
|
if (continuation) {
|
||||||
|
/*
|
||||||
|
* Append to the right event in case the user
|
||||||
|
* moved around in history.
|
||||||
|
*/
|
||||||
|
if (history(hist, &ev, H_SET, lastevent) == -1)
|
||||||
|
err(1, "%d: %s", lastevent, ev.str);
|
||||||
|
history(hist, &ev, H_ADD , buf);
|
||||||
|
} else {
|
||||||
|
history(hist, &ev, H_ENTER, buf);
|
||||||
|
lastevent = ev.num;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Simpler */
|
||||||
|
history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
continuation = ncontinuation;
|
||||||
|
ncontinuation = 0;
|
||||||
|
if (continuation)
|
||||||
|
continue;
|
||||||
|
#ifdef DEBUG
|
||||||
|
for (i = 0; i < ac; i++) {
|
||||||
|
(void) fprintf(stderr, " > arg# %2d ", i);
|
||||||
|
if (i != cc)
|
||||||
|
(void) fprintf(stderr, "`%s'\n", av[i]);
|
||||||
|
else
|
||||||
|
(void) fprintf(stderr, "`%.*s_%s'\n",
|
||||||
|
co, av[i], av[i] + co);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (strcmp(av[0], "history") == 0) {
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
switch (ac) {
|
||||||
|
case 1:
|
||||||
|
for (rv = history(hist, &ev, H_LAST); rv != -1;
|
||||||
|
rv = history(hist, &ev, H_PREV))
|
||||||
|
(void) fprintf(stdout, "%4d %s",
|
||||||
|
ev.num, ev.str);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
if (strcmp(av[1], "clear") == 0)
|
||||||
|
history(hist, &ev, H_CLEAR);
|
||||||
|
else
|
||||||
|
goto badhist;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
if (strcmp(av[1], "load") == 0)
|
||||||
|
history(hist, &ev, H_LOAD, av[2]);
|
||||||
|
else if (strcmp(av[1], "save") == 0)
|
||||||
|
history(hist, &ev, H_SAVE, av[2]);
|
||||||
|
break;
|
||||||
|
|
||||||
|
badhist:
|
||||||
|
default:
|
||||||
|
(void) fprintf(stderr,
|
||||||
|
"Bad history arguments\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (el_parse(el, ac, av) == -1) {
|
||||||
|
switch (fork()) {
|
||||||
|
case 0:
|
||||||
|
execvp(av[0], (char *const *)__UNCONST(av));
|
||||||
|
perror(av[0]);
|
||||||
|
_exit(1);
|
||||||
|
/*NOTREACHED*/
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
perror("fork");
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (wait(&num) == -1)
|
||||||
|
perror("wait");
|
||||||
|
(void) fprintf(stderr, "Exit %x\n", num);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tok_reset(tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
el_end(el);
|
||||||
|
tok_end(tok);
|
||||||
|
history_end(hist);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
|
@ -0,0 +1,12 @@
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: libedit
|
||||||
|
Description: command line editor library provides generic line editing, history, and tokenization functions.
|
||||||
|
Version: @VERSION@
|
||||||
|
Requires:
|
||||||
|
Libs: -L${libdir} -ledit -lcurses
|
||||||
|
Cflags: -I${includedir} -I${includedir}/editline
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
--- export/src/vis.h 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/vis.h 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -34,7 +34,7 @@
|
||||||
|
#ifndef _VIS_H_
|
||||||
|
#define _VIS_H_
|
||||||
|
|
||||||
|
-#include <sys/types.h>
|
||||||
|
+#include <config.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* to select alternate encoding format
|
||||||
|
@@ -72,8 +72,6 @@
|
||||||
|
*/
|
||||||
|
#define UNVIS_END 1 /* no more characters */
|
||||||
|
|
||||||
|
-#include <sys/cdefs.h>
|
||||||
|
-
|
||||||
|
__BEGIN_DECLS
|
||||||
|
char *vis(char *, int, int, int);
|
||||||
|
char *svis(char *, int, int, int, const char *);
|
||||||
|
@@ -84,7 +82,7 @@
|
||||||
|
int strunvis(char *, const char *);
|
||||||
|
int strunvisx(char *, const char *, int);
|
||||||
|
#ifndef __LIBC12_SOURCE__
|
||||||
|
-int unvis(char *, int, int *, int) __RENAME(__unvis13);
|
||||||
|
+int unvis(char *, int, int *, int);
|
||||||
|
#endif
|
||||||
|
__END_DECLS
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
--- export/src/term.c 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/term.c 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -51,19 +51,18 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
-#ifdef HAVE_TERMCAP_H
|
||||||
|
-#include <termcap.h>
|
||||||
|
-#endif
|
||||||
|
+
|
||||||
|
#ifdef HAVE_CURSES_H
|
||||||
|
-#include <curses.h>
|
||||||
|
-#endif
|
||||||
|
-#ifdef HAVE_NCURSES_H
|
||||||
|
-#include <ncurses.h>
|
||||||
|
+# include <curses.h>
|
||||||
|
+#elif HAVE_NCURSES_H
|
||||||
|
+# include <ncurses.h>
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
/* Solaris's term.h does horrid things. */
|
||||||
|
-#if (defined(HAVE_TERM_H) && !defined(SUNOS))
|
||||||
|
-#include <term.h>
|
||||||
|
+#if (defined(HAVE_TERM_H) && !defined(_SUNOS))
|
||||||
|
+# include <term.h>
|
||||||
|
#endif
|
||||||
|
+
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
--- export/src/el_term.h 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/el_term.h 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -81,6 +81,15 @@
|
||||||
|
#define A_K_EN 5
|
||||||
|
#define A_K_NKEYS 6
|
||||||
|
|
||||||
|
+#ifdef _SUNOS
|
||||||
|
+extern int tgetent(char *, const char *);
|
||||||
|
+extern int tgetflag(char *);
|
||||||
|
+extern int tgetnum(char *);
|
||||||
|
+extern int tputs(const char *, int, int (*)(int));
|
||||||
|
+extern char* tgoto(const char*, int, int);
|
||||||
|
+extern char* tgetstr(char*, char**);
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
protected void term_move_to_line(EditLine *, int);
|
||||||
|
protected void term_move_to_char(EditLine *, int);
|
||||||
|
protected void term_clear_EOL(EditLine *, int);
|
|
@ -0,0 +1,19 @@
|
||||||
|
--- export/src/unvis.c 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/unvis.c 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -29,7 +29,7 @@
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-#include <sys/cdefs.h>
|
||||||
|
+#include <config.h>
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
@@ -38,7 +38,6 @@
|
||||||
|
#endif
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
|
-#include "namespace.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
|
@ -0,0 +1,34 @@
|
||||||
|
--- export/src/strlcpy.c 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/strlcpy.c 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -17,19 +17,12 @@
|
||||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||||
|
-#if HAVE_NBTOOL_CONFIG_H
|
||||||
|
-#include "nbtool_config.h"
|
||||||
|
-#endif
|
||||||
|
+#include <config.h>
|
||||||
|
|
||||||
|
-#include <sys/cdefs.h>
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
__RCSID("$NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $");
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
|
-#ifdef _LIBC
|
||||||
|
-#include "namespace.h"
|
||||||
|
-#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
@@ -39,10 +32,6 @@
|
||||||
|
__weak_alias(strlcpy, _strlcpy)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
-#else
|
||||||
|
-#include <lib/libkern/libkern.h>
|
||||||
|
-#endif /* !_KERNEL && !_STANDALONE */
|
||||||
|
-
|
||||||
|
|
||||||
|
#if !HAVE_STRLCPY
|
||||||
|
/*
|
|
@ -0,0 +1,34 @@
|
||||||
|
--- export/src/strlcat.c 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/strlcat.c 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -17,19 +17,12 @@
|
||||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-#if !defined(_KERNEL) && !defined(_STANDALONE)
|
||||||
|
-#if HAVE_NBTOOL_CONFIG_H
|
||||||
|
-#include "nbtool_config.h"
|
||||||
|
-#endif
|
||||||
|
+#include <config.h>
|
||||||
|
|
||||||
|
-#include <sys/cdefs.h>
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
__RCSID("$NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $");
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
|
-#ifdef _LIBC
|
||||||
|
-#include "namespace.h"
|
||||||
|
-#endif
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
@@ -40,10 +33,6 @@
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
-#else
|
||||||
|
-#include <lib/libkern/libkern.h>
|
||||||
|
-#endif /* !_KERNEL && !_STANDALONE */
|
||||||
|
-
|
||||||
|
#if !HAVE_STRLCAT
|
||||||
|
/*
|
||||||
|
* Appends src to string dst of size siz (unlike strncat, siz is the
|
|
@ -0,0 +1,88 @@
|
||||||
|
--- export/src/readline.c 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/readline.c 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -32,7 +32,26 @@
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-#include "config.h"
|
||||||
|
+/* AIX requires this to be the first thing in the file. */
|
||||||
|
+#if defined (_AIX) && !defined (__GNUC__)
|
||||||
|
+ #pragma alloca
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#include <config.h>
|
||||||
|
+
|
||||||
|
+#ifdef __GNUC__
|
||||||
|
+# undef alloca
|
||||||
|
+# define alloca(n) __builtin_alloca (n)
|
||||||
|
+#else
|
||||||
|
+# ifdef HAVE_ALLOCA_H
|
||||||
|
+# include <alloca.h>
|
||||||
|
+# else
|
||||||
|
+# ifndef _AIX
|
||||||
|
+extern char *alloca ();
|
||||||
|
+# endif
|
||||||
|
+# endif
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
__RCSID("$NetBSD: readline.c,v 1.72 2007/08/12 07:41:51 christos Exp $");
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
@@ -50,20 +69,17 @@
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <setjmp.h>
|
||||||
|
-#ifdef HAVE_VIS_H
|
||||||
|
#include <vis.h>
|
||||||
|
-#else
|
||||||
|
-#include "np/vis.h"
|
||||||
|
-#endif
|
||||||
|
-#ifdef HAVE_ALLOCA_H
|
||||||
|
-#include <alloca.h>
|
||||||
|
-#endif
|
||||||
|
#include "el.h"
|
||||||
|
#include "fcns.h" /* for EL_NUM_FCNS */
|
||||||
|
#include "histedit.h"
|
||||||
|
-#include "readline/readline.h"
|
||||||
|
+#include "editline/readline.h"
|
||||||
|
#include "filecomplete.h"
|
||||||
|
|
||||||
|
+#if !defined(SIZE_T_MAX)
|
||||||
|
+# define SIZE_T_MAX (size_t)(-1)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
void rl_prep_terminal(int);
|
||||||
|
void rl_deprep_terminal(void);
|
||||||
|
|
||||||
|
@@ -198,7 +214,7 @@
|
||||||
|
return (HIST_ENTRY *) NULL;
|
||||||
|
|
||||||
|
rl_he.line = ev.str;
|
||||||
|
- rl_he.data = NULL;
|
||||||
|
+ rl_he.data = (histdata_t) &(ev.num);
|
||||||
|
|
||||||
|
return (&rl_he);
|
||||||
|
}
|
||||||
|
@@ -1440,8 +1456,7 @@
|
||||||
|
char *
|
||||||
|
username_completion_function(const char *text, int state)
|
||||||
|
{
|
||||||
|
- struct passwd *pwd, pwres;
|
||||||
|
- char pwbuf[1024];
|
||||||
|
+ struct passwd *pwd;
|
||||||
|
|
||||||
|
if (text[0] == '\0')
|
||||||
|
return (NULL);
|
||||||
|
@@ -1452,9 +1467,9 @@
|
||||||
|
if (state == 0)
|
||||||
|
setpwent();
|
||||||
|
|
||||||
|
- while (getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pwd) == 0
|
||||||
|
- && pwd != NULL && text[0] == pwd->pw_name[0]
|
||||||
|
- && strcmp(text, pwd->pw_name) == 0);
|
||||||
|
+ while ((pwd = getpwent())
|
||||||
|
+ && pwd != NULL && text[0] == pwd->pw_name[0]
|
||||||
|
+ && strcmp(text, pwd->pw_name) == 0);
|
||||||
|
|
||||||
|
if (pwd == NULL) {
|
||||||
|
endpwent();
|
|
@ -0,0 +1,37 @@
|
||||||
|
--- export/src/sys.h 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/sys.h 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -40,6 +40,8 @@
|
||||||
|
#ifndef _h_sys
|
||||||
|
#define _h_sys
|
||||||
|
|
||||||
|
+#include <config.h>
|
||||||
|
+
|
||||||
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#endif
|
||||||
|
@@ -48,6 +50,14 @@
|
||||||
|
# define __attribute__(A)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifndef __P
|
||||||
|
+# define __P(x) x
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifndef _DIAGASSERT
|
||||||
|
+# define _DIAGASSERT(x)
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#ifndef __BEGIN_DECLS
|
||||||
|
# ifdef __cplusplus
|
||||||
|
# define __BEGIN_DECLS extern "C" {
|
||||||
|
@@ -71,6 +81,10 @@
|
||||||
|
/* When we want to hide everything */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifndef HAVE_U_INT32_T
|
||||||
|
+typedef unsigned int u_int32_t;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#ifndef _PTR_T
|
||||||
|
# define _PTR_T
|
||||||
|
typedef void *ptr_t;
|
|
@ -0,0 +1,11 @@
|
||||||
|
--- export/src/el.h 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/el.h 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -96,7 +96,7 @@
|
||||||
|
#include "tty.h"
|
||||||
|
#include "prompt.h"
|
||||||
|
#include "key.h"
|
||||||
|
-#include "term.h"
|
||||||
|
+#include "el_term.h"
|
||||||
|
#include "refresh.h"
|
||||||
|
#include "chared.h"
|
||||||
|
#include "common.h"
|
|
@ -0,0 +1,10 @@
|
||||||
|
--- export/src/search.c 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/search.c 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -45,6 +45,7 @@
|
||||||
|
* search.c: History and character search functions
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
+#include <sys/types.h>
|
||||||
|
#if defined(REGEX)
|
||||||
|
#include <regex.h>
|
||||||
|
#elif defined(REGEXP)
|
|
@ -0,0 +1,24 @@
|
||||||
|
--- export/src/editline/readline.h 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/editline/readline.h 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -46,9 +46,11 @@
|
||||||
|
typedef char **CPPFunction(const char *, int, int);
|
||||||
|
typedef char *rl_compentry_func_t(const char *, int);
|
||||||
|
|
||||||
|
+typedef void *histdata_t;
|
||||||
|
+
|
||||||
|
typedef struct _hist_entry {
|
||||||
|
const char *line;
|
||||||
|
- const char *data;
|
||||||
|
+ histdata_t *data;
|
||||||
|
} HIST_ENTRY;
|
||||||
|
|
||||||
|
typedef struct _keymap_entry {
|
||||||
|
@@ -69,7 +71,7 @@
|
||||||
|
|
||||||
|
#ifndef CTRL
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
-#if !defined(__sun__) && !defined(__hpux__)
|
||||||
|
+#ifdef __GLIBC__
|
||||||
|
#include <sys/ttydefaults.h>
|
||||||
|
#endif
|
||||||
|
#ifndef CTRL
|
|
@ -0,0 +1,36 @@
|
||||||
|
--- export/src/el.c 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/el.c 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -473,12 +473,17 @@
|
||||||
|
|
||||||
|
fp = NULL;
|
||||||
|
if (fname == NULL) {
|
||||||
|
-#ifdef HAVE_ISSETUGID
|
||||||
|
static const char elpath[] = "/.editrc";
|
||||||
|
+#ifdef MAXPATHLEN
|
||||||
|
char path[MAXPATHLEN];
|
||||||
|
+#else
|
||||||
|
+ char path[4096];
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
+#ifdef HAVE_ISSETUGID
|
||||||
|
if (issetugid())
|
||||||
|
return (-1);
|
||||||
|
+#endif
|
||||||
|
if ((ptr = getenv("HOME")) == NULL)
|
||||||
|
return (-1);
|
||||||
|
if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
|
||||||
|
@@ -486,14 +491,6 @@
|
||||||
|
if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
|
||||||
|
return (-1);
|
||||||
|
fname = path;
|
||||||
|
-#else
|
||||||
|
- /*
|
||||||
|
- * If issetugid() is missing, always return an error, in order
|
||||||
|
- * to keep from inadvertently opening up the user to a security
|
||||||
|
- * hole.
|
||||||
|
- */
|
||||||
|
- return (-1);
|
||||||
|
-#endif
|
||||||
|
}
|
||||||
|
if (fp == NULL)
|
||||||
|
fp = fopen(fname, "r");
|
|
@ -0,0 +1,14 @@
|
||||||
|
--- export/src/history.c 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/history.c 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -47,11 +47,7 @@
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
-#ifdef HAVE_VIS_H
|
||||||
|
#include <vis.h>
|
||||||
|
-#else
|
||||||
|
-#include "np/vis.h"
|
||||||
|
-#endif
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
static const char hist_cookie[] = "_HiStOrY_V2_\n";
|
|
@ -0,0 +1,35 @@
|
||||||
|
--- export/src/vis.c 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/vis.c 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -58,12 +58,30 @@
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-#include <sys/cdefs.h>
|
||||||
|
+/* AIX requires this to be the first thing in the file. */
|
||||||
|
+#if defined (_AIX) && !defined (__GNUC__)
|
||||||
|
+ #pragma alloca
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#include <config.h>
|
||||||
|
+
|
||||||
|
+#ifdef __GNUC__
|
||||||
|
+# undef alloca
|
||||||
|
+# define alloca(n) __builtin_alloca (n)
|
||||||
|
+#else
|
||||||
|
+# ifdef HAVE_ALLOCA_H
|
||||||
|
+# include <alloca.h>
|
||||||
|
+# else
|
||||||
|
+# ifndef _AIX
|
||||||
|
+extern char *alloca ();
|
||||||
|
+# endif
|
||||||
|
+# endif
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
__RCSID("$NetBSD: vis.c,v 1.35 2006/08/28 20:42:12 christos Exp $");
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
|
-#include "namespace.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
|
@ -0,0 +1,10 @@
|
||||||
|
--- export/src/fgetln.c 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/fgetln.c 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -37,6 +37,7 @@
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_FGETLN
|
||||||
|
+#include <config.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifndef HAVE_NBTOOL_CONFIG_H
|
||||||
|
/* These headers are required, but included from nbtool_config.h */
|
|
@ -0,0 +1,98 @@
|
||||||
|
--- export/src/filecomplete.c 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../src/filecomplete.c 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -31,8 +31,27 @@
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
+
|
||||||
|
+/* AIX requires this to be the first thing in the file. */
|
||||||
|
+#if defined (_AIX) && !defined (__GNUC__)
|
||||||
|
+ #pragma alloca
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#include <config.h>
|
||||||
|
+
|
||||||
|
+#ifdef __GNUC__
|
||||||
|
+# undef alloca
|
||||||
|
+# define alloca(n) __builtin_alloca (n)
|
||||||
|
+#else
|
||||||
|
+# ifdef HAVE_ALLOCA_H
|
||||||
|
+# include <alloca.h>
|
||||||
|
+# else
|
||||||
|
+# ifndef _AIX
|
||||||
|
+extern char *alloca ();
|
||||||
|
+# endif
|
||||||
|
+# endif
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
-#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
__RCSID("$NetBSD: filecomplete.c,v 1.10 2006/11/09 16:58:38 christos Exp $");
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
@@ -49,14 +68,8 @@
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
-#ifdef HAVE_VIS_H
|
||||||
|
#include <vis.h>
|
||||||
|
-#else
|
||||||
|
-#include "np/vis.h"
|
||||||
|
-#endif
|
||||||
|
-#ifdef HAVE_ALLOCA_H
|
||||||
|
-#include <alloca.h>
|
||||||
|
-#endif
|
||||||
|
+
|
||||||
|
#include "el.h"
|
||||||
|
#include "fcns.h" /* for EL_NUM_FCNS */
|
||||||
|
#include "histedit.h"
|
||||||
|
@@ -101,11 +114,23 @@
|
||||||
|
temp[len - 2] = '\0';
|
||||||
|
}
|
||||||
|
if (temp[0] == 0) {
|
||||||
|
+#ifdef HAVE_GETPW_R_POSIX
|
||||||
|
if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
|
||||||
|
pass = NULL;
|
||||||
|
+#elif HAVE_GETPW_R_DRAFT
|
||||||
|
+ pass = getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf));
|
||||||
|
+#else
|
||||||
|
+ pass = getpwuid(getuid());
|
||||||
|
+#endif
|
||||||
|
} else {
|
||||||
|
+#ifdef HAVE_GETPW_R_POSIX
|
||||||
|
if (getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
|
||||||
|
pass = NULL;
|
||||||
|
+#elif HAVE_GETPW_R_DRAFT
|
||||||
|
+ pass = getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf));
|
||||||
|
+#else
|
||||||
|
+ pass = getpwnam(temp);
|
||||||
|
+#endif
|
||||||
|
}
|
||||||
|
free(temp); /* value no more needed */
|
||||||
|
if (pass == NULL)
|
||||||
|
@@ -211,11 +236,8 @@
|
||||||
|
/* otherwise, get first entry where first */
|
||||||
|
/* filename_len characters are equal */
|
||||||
|
if (entry->d_name[0] == filename[0]
|
||||||
|
-#if defined(__SVR4) || defined(__linux__)
|
||||||
|
+ /* Some dirents have d_namlen, but it is not portable. */
|
||||||
|
&& strlen(entry->d_name) >= filename_len
|
||||||
|
-#else
|
||||||
|
- && entry->d_namlen >= filename_len
|
||||||
|
-#endif
|
||||||
|
&& strncmp(entry->d_name, filename,
|
||||||
|
filename_len) == 0)
|
||||||
|
break;
|
||||||
|
@@ -223,12 +245,8 @@
|
||||||
|
|
||||||
|
if (entry) { /* match found */
|
||||||
|
|
||||||
|
-#if defined(__SVR4) || defined(__linux__)
|
||||||
|
+ /* Some dirents have d_namlen, but it is not portable. */
|
||||||
|
len = strlen(entry->d_name);
|
||||||
|
-#else
|
||||||
|
- len = entry->d_namlen;
|
||||||
|
-#endif
|
||||||
|
-
|
||||||
|
temp = malloc(strlen(dirname) + len + 1);
|
||||||
|
if (temp == NULL)
|
||||||
|
return NULL;
|
|
@ -0,0 +1,35 @@
|
||||||
|
--- export/examples/tc1.c 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../examples/tc1.c 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -32,20 +32,6 @@
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
-#include "config.h"
|
||||||
|
-#ifndef lint
|
||||||
|
-__COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
|
||||||
|
- The Regents of the University of California. All rights reserved.\n");
|
||||||
|
-#endif /* not lint */
|
||||||
|
-
|
||||||
|
-#if !defined(lint) && !defined(SCCSID)
|
||||||
|
-#if 0
|
||||||
|
-static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
-#else
|
||||||
|
-__RCSID("$NetBSD: tc1.c,v 1.1 2006/08/31 20:20:38 rpaulo Exp $");
|
||||||
|
-#endif
|
||||||
|
-#endif /* not lint && not SCCSID */
|
||||||
|
-
|
||||||
|
/*
|
||||||
|
* test.c: A little test program
|
||||||
|
*/
|
||||||
|
@@ -60,6 +46,11 @@
|
||||||
|
|
||||||
|
#include "histedit.h"
|
||||||
|
|
||||||
|
+/* from src/sys/sys/cdefs.h */
|
||||||
|
+#ifndef __UNCONST
|
||||||
|
+# define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
static int continuation = 0;
|
||||||
|
volatile sig_atomic_t gotsig = 0;
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
--- export/doc/editline.3.roff 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../doc/editline.3.roff 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -115,10 +115,11 @@
|
||||||
|
These functions are available in the
|
||||||
|
.Nm libedit
|
||||||
|
library (which needs the
|
||||||
|
-.Nm libtermcap
|
||||||
|
+.Nm libcurses
|
||||||
|
library).
|
||||||
|
Programs should be linked with
|
||||||
|
-.Fl ledit ltermcap .
|
||||||
|
+.Fl ledit
|
||||||
|
+.Fl lcurses .
|
||||||
|
.Sh LINE EDITING FUNCTIONS
|
||||||
|
The line editing functions use a common data structure,
|
||||||
|
.Fa EditLine ,
|
||||||
|
@@ -711,8 +712,10 @@
|
||||||
|
to be used by all other tokenizer functions.
|
||||||
|
.Fa IFS
|
||||||
|
contains the Input Field Separators, which defaults to
|
||||||
|
-.Aq space ,
|
||||||
|
-.Aq tab ,
|
||||||
|
+.Aq space
|
||||||
|
+,
|
||||||
|
+.Aq tab
|
||||||
|
+,
|
||||||
|
and
|
||||||
|
.Aq newline
|
||||||
|
if
|
|
@ -0,0 +1,34 @@
|
||||||
|
--- export/doc/editrc.5.roff 2007-08-31 00:02:46.000000000 +0200
|
||||||
|
+++ ../doc/editrc.5.roff 2007-08-31 00:03:08.000000000 +0200
|
||||||
|
@@ -157,7 +157,7 @@
|
||||||
|
.Ar command
|
||||||
|
can contain control characters of the form
|
||||||
|
.Sm off
|
||||||
|
-.Sq No ^ Ar character
|
||||||
|
+.Sq ^character
|
||||||
|
.Sm on
|
||||||
|
.Po
|
||||||
|
e.g.
|
||||||
|
@@ -183,7 +183,7 @@
|
||||||
|
.It Ic \ev
|
||||||
|
Vertical tab
|
||||||
|
.Sm off
|
||||||
|
-.It Sy \e Ar nnn
|
||||||
|
+.It Sy \ennn
|
||||||
|
.Sm on
|
||||||
|
The ASCII character corresponding to the octal number
|
||||||
|
.Ar nnn .
|
||||||
|
@@ -222,11 +222,11 @@
|
||||||
|
causing an error.
|
||||||
|
.Fl v
|
||||||
|
causes messages to be verbose.
|
||||||
|
-.It Ic edit Op Li on | Li off
|
||||||
|
+.It Ic edit Op on | off
|
||||||
|
Enable or disable the
|
||||||
|
.Nm editline
|
||||||
|
functionality in a program.
|
||||||
|
-.It Ic history Ar list | Ar size Dv n | Ar unique Dv n
|
||||||
|
+.It Ic history Ar list | Ar size n | Ar unique n
|
||||||
|
The
|
||||||
|
.Ar list
|
||||||
|
command lists all entries in the history.
|
|
@ -0,0 +1,62 @@
|
||||||
|
|
||||||
|
Files in this directory are used to update the source in this distribution with
|
||||||
|
updates from the FreeBSD CVS source.
|
||||||
|
|
||||||
|
|
||||||
|
1) cvs_export.sh - get the source from cvs (to ./export)
|
||||||
|
|
||||||
|
2) patches_apply.sh - try to patch ./export with current pathes.
|
||||||
|
|
||||||
|
3) patches_check.sh - check updated ./export against dist
|
||||||
|
|
||||||
|
4) update_dist.sh - update dist and version
|
||||||
|
|
||||||
|
If by hand:
|
||||||
|
|
||||||
|
*) copy ./export/* files to dist '""cp -rf export/* ..'
|
||||||
|
|
||||||
|
*) 'rm -rf export; cp -rf export.unpatched export' - get clean ./export hierarchy
|
||||||
|
|
||||||
|
*) patches_make.sh - make new patches to be distributed
|
||||||
|
|
||||||
|
*) update 'vi ../Makefile.am with' list ':r !./extra_dist_list.sh' (vim cmd)
|
||||||
|
|
||||||
|
*) update LT_VERSION in configure.ac according to the below Note
|
||||||
|
|
||||||
|
5) update ChangeLog
|
||||||
|
|
||||||
|
6) autoreconf && make distcheck!!!
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
http://developer.gnome.org/doc/books/WGA/dealing-with-libraries.html#AEN555 A
|
||||||
|
Note about Version Numbers
|
||||||
|
|
||||||
|
The three numbers stand for CURRENT:REVISION:AGE, or C:R:A for short. The
|
||||||
|
libtool script typically tacks these three numbers onto the end of the name of
|
||||||
|
the .so file it creates. The formula for calculating the file numbers on Linux
|
||||||
|
and Solaris is (C - A).(A).(R), so the example given here would create the
|
||||||
|
file libgrump.so.3.2.1. Other operating systems might use a different library
|
||||||
|
file name convention; libtool takes care of the details.
|
||||||
|
|
||||||
|
As you release new versions of your library, you will update the library's
|
||||||
|
C:R:A. Although the rules for changing these version numbers can quickly
|
||||||
|
become confusing, a few simple tips should help keep you on track. The libtool
|
||||||
|
documentation goes into greater depth.
|
||||||
|
|
||||||
|
In essence, every time you make a change to the library and release it, the
|
||||||
|
C:R:A should change. A new library should start with 0:0:0. Each time you
|
||||||
|
change the public interface (i.e., your installed header files), you should
|
||||||
|
increment the CURRENT number. This is called your interface number. The main
|
||||||
|
use of this interface number is to tag successive revisions of your API.
|
||||||
|
|
||||||
|
The AGE number is how many consecutive versions of the API the current
|
||||||
|
implementation supports. Thus if the CURRENT library API is the sixth
|
||||||
|
published version of the interface and it is also binary compatible with the
|
||||||
|
fourth and fifth versions (i.e., the last two), the C:R:A might be 6:0:2. When
|
||||||
|
you break binary compatibility, you need to set AGE to 0 and of course
|
||||||
|
increment CURRENT.
|
||||||
|
|
||||||
|
The REVISION marks a change in the source code of the library that doesn't
|
||||||
|
affect the interface-for example, a minor bug fix. Anytime you increment
|
||||||
|
CURRENT, you should set REVISION back to 0.
|
|
@ -0,0 +1,50 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
## export NetBSD source to ./export
|
||||||
|
|
||||||
|
rm -r export
|
||||||
|
rm -r export.unpatched
|
||||||
|
|
||||||
|
## cvs ... -dexport/src doesn't work
|
||||||
|
mkdir -p export
|
||||||
|
cd export
|
||||||
|
|
||||||
|
PSERV=:pserver:anoncvs@anoncvs.netbsd.org
|
||||||
|
|
||||||
|
## initial login (pw anoncvs)
|
||||||
|
##cvs -d :pserver:anoncvs@anoncvs.netbsd.org:/cvsroot login
|
||||||
|
|
||||||
|
for i in src/common/lib/libc/string/strlcat.c\
|
||||||
|
src/common/lib/libc/string/strlcpy.c\
|
||||||
|
src/lib/libc/gen/vis.c\
|
||||||
|
src/lib/libc/gen/unvis.c\
|
||||||
|
src/include/vis.h \
|
||||||
|
src/tools/compat/fgetln.c
|
||||||
|
do
|
||||||
|
echo $i
|
||||||
|
cvs -d $PSERV:/cvsroot export -Dnow -dsrc $i
|
||||||
|
done
|
||||||
|
|
||||||
|
cvs -d $PSERV:/cvsroot export -Dnow -dsrc src/lib/libedit
|
||||||
|
|
||||||
|
|
||||||
|
## hierarchy canges
|
||||||
|
|
||||||
|
rm src/readline/Makefile
|
||||||
|
rm src/TEST/Makefile
|
||||||
|
rm src/Makefile
|
||||||
|
rm src/config.h
|
||||||
|
|
||||||
|
mv src/TEST examples
|
||||||
|
|
||||||
|
mkdir doc
|
||||||
|
mv src/editline.3 doc/editline.3.roff
|
||||||
|
mv src/editrc.5 doc/editrc.5.roff
|
||||||
|
|
||||||
|
mv src/readline src/editline
|
||||||
|
mv src/term.h src/el_term.h
|
||||||
|
|
||||||
|
cd ..
|
||||||
|
date +"%Y%m%d" > timestamp.cvsexport
|
||||||
|
|
||||||
|
cp -rf export export.unpatched
|
|
@ -0,0 +1,30 @@
|
||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
## update EXTRA_DIST list in Makefile.am
|
||||||
|
|
||||||
|
f="Makefile.am"
|
||||||
|
""cd ..
|
||||||
|
|
||||||
|
## remove old list
|
||||||
|
ed $f <<EOF
|
||||||
|
/^## GENERATED BY SCRIPT/,\$d
|
||||||
|
w
|
||||||
|
EOF
|
||||||
|
|
||||||
|
## insert new list
|
||||||
|
echo "## GENERATED BY SCRIPT - DO NOT EDIT BELOW" >> $f
|
||||||
|
echo "" >> $f
|
||||||
|
|
||||||
|
echo "EXTRA_DIST += patches/README \\" >> $f
|
||||||
|
for i in $(ls -1 patches/*.patch);do printf '%*s%s \\\n' 13 ' ' $i >> $f;done
|
||||||
|
echo " patches/cvs_export.sh \\
|
||||||
|
patches/patches_make.sh \\
|
||||||
|
patches/patches_apply.sh \\
|
||||||
|
patches/patches_check.sh \\
|
||||||
|
patches/extra_dist_list.sh \\
|
||||||
|
patches/update_version.sh \\
|
||||||
|
patches/update_dist.sh \\
|
||||||
|
patches/timestamp.cvsexport" >> $f
|
||||||
|
|
||||||
|
echo "" >> $f
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
## apply patches to the ./export hierarchy
|
||||||
|
|
||||||
|
for patch in *.patch
|
||||||
|
do
|
||||||
|
patch -d export -p1 < $patch
|
||||||
|
done
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
## check updated ./export against dist, should be something like:
|
||||||
|
#Only in ../doc: Makefile.am
|
||||||
|
#Only in ../doc: Makefile.in
|
||||||
|
#Only in ../doc: mdoc2man.awk
|
||||||
|
#Only in ../examples: Makefile.am
|
||||||
|
#Only in ../examples: Makefile.in
|
||||||
|
#Only in ../examples: fileman.c
|
||||||
|
#Only in ../src: Makefile.am
|
||||||
|
#Only in ../src: Makefile.in
|
||||||
|
|
||||||
|
for dir in export/*
|
||||||
|
do
|
||||||
|
diff -aur $dir ../${dir#export/}
|
||||||
|
done
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
## make new patches after e.g. distributed ../src has been changed
|
||||||
|
|
||||||
|
rm *.patch
|
||||||
|
|
||||||
|
i=0
|
||||||
|
for file in $(find export -type f)
|
||||||
|
do
|
||||||
|
diff -q $file ../${file#export/} > /dev/null
|
||||||
|
res="$?"
|
||||||
|
if test 1 -eq "$res"
|
||||||
|
then
|
||||||
|
diff -au $file ../${file#export/} > $(printf '%02d' $i)-${file##*/}.patch
|
||||||
|
((i++))
|
||||||
|
fi
|
||||||
|
done
|
|
@ -0,0 +1 @@
|
||||||
|
20070831
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
|
||||||
|
## copy ./export/* files to dist
|
||||||
|
""cp -rf export/* ..
|
||||||
|
|
||||||
|
## get clean ./export hierarchy
|
||||||
|
""rm -rf export
|
||||||
|
""mv export.unpatched export
|
||||||
|
|
||||||
|
## make new patches to be distributed
|
||||||
|
./patches_make.sh
|
||||||
|
|
||||||
|
## update EXTRA_DIST list in Makefile.am
|
||||||
|
./extra_dist_list.sh
|
||||||
|
|
||||||
|
## increment LT_VERSION in ../configure.ac
|
||||||
|
./update_version.sh
|
|
@ -0,0 +1,17 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
## increment LT_VERSION in ../configure.ac
|
||||||
|
|
||||||
|
f=../configure.ac
|
||||||
|
|
||||||
|
grep LT_VERSION $f
|
||||||
|
|
||||||
|
i=$(awk '/LT_VERSION/ {n=gensub(/.*:([0-9]+):.*/,"\\1",1);print n}' $f)
|
||||||
|
((i++))
|
||||||
|
|
||||||
|
ed $f <<EOF
|
||||||
|
1,\$s/AC_SUBST(LT_VERSION, \[0:[0-9]*:0\])/AC_SUBST(LT_VERSION, \[0:$i:0\])/
|
||||||
|
w
|
||||||
|
EOF
|
||||||
|
|
||||||
|
grep LT_VERSION $f
|
|
@ -0,0 +1,46 @@
|
||||||
|
|
||||||
|
BUILT_SOURCES = vi.h emacs.h common.h fcns.h help.h fcns.c help.c
|
||||||
|
|
||||||
|
AHDR= vi.h emacs.h common.h
|
||||||
|
ASRC= $(srcdir)/vi.c $(srcdir)/emacs.c $(srcdir)/common.c
|
||||||
|
|
||||||
|
vi.h: Makefile $(srcdir)/vi.c
|
||||||
|
sh $(srcdir)/makelist -h $(srcdir)/vi.c > $@
|
||||||
|
|
||||||
|
emacs.h: Makefile $(srcdir)/emacs.c
|
||||||
|
sh $(srcdir)/makelist -h $(srcdir)/emacs.c > $@
|
||||||
|
|
||||||
|
common.h: Makefile $(srcdir)/common.c
|
||||||
|
sh $(srcdir)/makelist -h $(srcdir)/common.c > $@
|
||||||
|
|
||||||
|
fcns.h: Makefile $(AHDR)
|
||||||
|
sh $(srcdir)/makelist -fh $(AHDR) > $@
|
||||||
|
|
||||||
|
help.h: Makefile $(ASRC)
|
||||||
|
sh $(srcdir)/makelist -bh $(ASRC) > $@
|
||||||
|
|
||||||
|
fcns.c: Makefile $(AHDR)
|
||||||
|
sh $(srcdir)/makelist -fc $(AHDR) > $@
|
||||||
|
|
||||||
|
help.c: Makefile $(ASRC)
|
||||||
|
sh $(srcdir)/makelist -bc $(ASRC) > $@
|
||||||
|
|
||||||
|
|
||||||
|
CLEANFILES = $(BUILT_SOURCES)
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = libedit.la
|
||||||
|
libedit_la_SOURCES = chared.c common.c el.c emacs.c hist.c key.c map.c parse.c \
|
||||||
|
prompt.c read.c refresh.c search.c sig.c term.c tty.c vi.c \
|
||||||
|
fgetln.c strlcat.c strlcpy.c unvis.c vis.c tokenizer.c \
|
||||||
|
history.c filecomplete.c readline.c chared.h el.h hist.h \
|
||||||
|
histedit.h key.h map.h parse.h prompt.h read.h refresh.h \
|
||||||
|
search.h sig.h sys.h el_term.h tty.h vis.h filecomplete.h \
|
||||||
|
editline/readline.h
|
||||||
|
|
||||||
|
EXTRA_DIST = makelist shlib_version
|
||||||
|
nobase_include_HEADERS = histedit.h editline/readline.h
|
||||||
|
|
||||||
|
nodist_libedit_la_SOURCES = $(BUILT_SOURCES)
|
||||||
|
|
||||||
|
libedit_la_LDFLAGS = -no-undefined -version-info $(LT_VERSION)
|
||||||
|
|
|
@ -0,0 +1,777 @@
|
||||||
|
/* $NetBSD: chared.c,v 1.25 2005/08/08 01:41:30 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: chared.c,v 1.25 2005/08/08 01:41:30 christos Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* chared.c: Character editor utilities
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "el.h"
|
||||||
|
|
||||||
|
private void ch__clearmacro __P((EditLine *));
|
||||||
|
|
||||||
|
/* value to leave unused in line buffer */
|
||||||
|
#define EL_LEAVE 2
|
||||||
|
|
||||||
|
/* cv_undo():
|
||||||
|
* Handle state for the vi undo command
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
cv_undo(EditLine *el)
|
||||||
|
{
|
||||||
|
c_undo_t *vu = &el->el_chared.c_undo;
|
||||||
|
c_redo_t *r = &el->el_chared.c_redo;
|
||||||
|
unsigned int size;
|
||||||
|
|
||||||
|
/* Save entire line for undo */
|
||||||
|
size = el->el_line.lastchar - el->el_line.buffer;
|
||||||
|
vu->len = size;
|
||||||
|
vu->cursor = el->el_line.cursor - el->el_line.buffer;
|
||||||
|
memcpy(vu->buf, el->el_line.buffer, size);
|
||||||
|
|
||||||
|
/* save command info for redo */
|
||||||
|
r->count = el->el_state.doingarg ? el->el_state.argument : 0;
|
||||||
|
r->action = el->el_chared.c_vcmd.action;
|
||||||
|
r->pos = r->buf;
|
||||||
|
r->cmd = el->el_state.thiscmd;
|
||||||
|
r->ch = el->el_state.thisch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cv_yank():
|
||||||
|
* Save yank/delete data for paste
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
cv_yank(EditLine *el, const char *ptr, int size)
|
||||||
|
{
|
||||||
|
c_kill_t *k = &el->el_chared.c_kill;
|
||||||
|
|
||||||
|
memcpy(k->buf, ptr, size +0u);
|
||||||
|
k->last = k->buf + size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* c_insert():
|
||||||
|
* Insert num characters
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
c_insert(EditLine *el, int num)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
if (el->el_line.lastchar + num >= el->el_line.limit) {
|
||||||
|
if (!ch_enlargebufs(el, num +0u))
|
||||||
|
return; /* can't go past end of buffer */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (el->el_line.cursor < el->el_line.lastchar) {
|
||||||
|
/* if I must move chars */
|
||||||
|
for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--)
|
||||||
|
cp[num] = *cp;
|
||||||
|
}
|
||||||
|
el->el_line.lastchar += num;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* c_delafter():
|
||||||
|
* Delete num characters after the cursor
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
c_delafter(EditLine *el, int num)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (el->el_line.cursor + num > el->el_line.lastchar)
|
||||||
|
num = el->el_line.lastchar - el->el_line.cursor;
|
||||||
|
|
||||||
|
if (el->el_map.current != el->el_map.emacs) {
|
||||||
|
cv_undo(el);
|
||||||
|
cv_yank(el, el->el_line.cursor, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num > 0) {
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
|
||||||
|
*cp = cp[num];
|
||||||
|
|
||||||
|
el->el_line.lastchar -= num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* c_delafter1():
|
||||||
|
* Delete the character after the cursor, do not yank
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
c_delafter1(EditLine *el)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
|
||||||
|
*cp = cp[1];
|
||||||
|
|
||||||
|
el->el_line.lastchar--;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* c_delbefore():
|
||||||
|
* Delete num characters before the cursor
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
c_delbefore(EditLine *el, int num)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (el->el_line.cursor - num < el->el_line.buffer)
|
||||||
|
num = el->el_line.cursor - el->el_line.buffer;
|
||||||
|
|
||||||
|
if (el->el_map.current != el->el_map.emacs) {
|
||||||
|
cv_undo(el);
|
||||||
|
cv_yank(el, el->el_line.cursor - num, num);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (num > 0) {
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
for (cp = el->el_line.cursor - num;
|
||||||
|
cp <= el->el_line.lastchar;
|
||||||
|
cp++)
|
||||||
|
*cp = cp[num];
|
||||||
|
|
||||||
|
el->el_line.lastchar -= num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* c_delbefore1():
|
||||||
|
* Delete the character before the cursor, do not yank
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
c_delbefore1(EditLine *el)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
|
||||||
|
*cp = cp[1];
|
||||||
|
|
||||||
|
el->el_line.lastchar--;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ce__isword():
|
||||||
|
* Return if p is part of a word according to emacs
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
ce__isword(int p)
|
||||||
|
{
|
||||||
|
return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* cv__isword():
|
||||||
|
* Return if p is part of a word according to vi
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
cv__isword(int p)
|
||||||
|
{
|
||||||
|
if (isalnum(p) || p == '_')
|
||||||
|
return 1;
|
||||||
|
if (isgraph(p))
|
||||||
|
return 2;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* cv__isWord():
|
||||||
|
* Return if p is part of a big word according to vi
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
cv__isWord(int p)
|
||||||
|
{
|
||||||
|
return (!isspace(p));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* c__prev_word():
|
||||||
|
* Find the previous word
|
||||||
|
*/
|
||||||
|
protected char *
|
||||||
|
c__prev_word(char *p, char *low, int n, int (*wtest)(int))
|
||||||
|
{
|
||||||
|
p--;
|
||||||
|
|
||||||
|
while (n--) {
|
||||||
|
while ((p >= low) && !(*wtest)((unsigned char) *p))
|
||||||
|
p--;
|
||||||
|
while ((p >= low) && (*wtest)((unsigned char) *p))
|
||||||
|
p--;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cp now points to one character before the word */
|
||||||
|
p++;
|
||||||
|
if (p < low)
|
||||||
|
p = low;
|
||||||
|
/* cp now points where we want it */
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* c__next_word():
|
||||||
|
* Find the next word
|
||||||
|
*/
|
||||||
|
protected char *
|
||||||
|
c__next_word(char *p, char *high, int n, int (*wtest)(int))
|
||||||
|
{
|
||||||
|
while (n--) {
|
||||||
|
while ((p < high) && !(*wtest)((unsigned char) *p))
|
||||||
|
p++;
|
||||||
|
while ((p < high) && (*wtest)((unsigned char) *p))
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
if (p > high)
|
||||||
|
p = high;
|
||||||
|
/* p now points where we want it */
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* cv_next_word():
|
||||||
|
* Find the next word vi style
|
||||||
|
*/
|
||||||
|
protected char *
|
||||||
|
cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int))
|
||||||
|
{
|
||||||
|
int test;
|
||||||
|
|
||||||
|
while (n--) {
|
||||||
|
test = (*wtest)((unsigned char) *p);
|
||||||
|
while ((p < high) && (*wtest)((unsigned char) *p) == test)
|
||||||
|
p++;
|
||||||
|
/*
|
||||||
|
* vi historically deletes with cw only the word preserving the
|
||||||
|
* trailing whitespace! This is not what 'w' does..
|
||||||
|
*/
|
||||||
|
if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
|
||||||
|
while ((p < high) && isspace((unsigned char) *p))
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* p now points where we want it */
|
||||||
|
if (p > high)
|
||||||
|
return (high);
|
||||||
|
else
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* cv_prev_word():
|
||||||
|
* Find the previous word vi style
|
||||||
|
*/
|
||||||
|
protected char *
|
||||||
|
cv_prev_word(char *p, char *low, int n, int (*wtest)(int))
|
||||||
|
{
|
||||||
|
int test;
|
||||||
|
|
||||||
|
p--;
|
||||||
|
while (n--) {
|
||||||
|
while ((p > low) && isspace((unsigned char) *p))
|
||||||
|
p--;
|
||||||
|
test = (*wtest)((unsigned char) *p);
|
||||||
|
while ((p >= low) && (*wtest)((unsigned char) *p) == test)
|
||||||
|
p--;
|
||||||
|
}
|
||||||
|
p++;
|
||||||
|
|
||||||
|
/* p now points where we want it */
|
||||||
|
if (p < low)
|
||||||
|
return (low);
|
||||||
|
else
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef notdef
|
||||||
|
/* c__number():
|
||||||
|
* Ignore character p points to, return number appearing after that.
|
||||||
|
* A '$' by itself means a big number; "$-" is for negative; '^' means 1.
|
||||||
|
* Return p pointing to last char used.
|
||||||
|
*/
|
||||||
|
protected char *
|
||||||
|
c__number(
|
||||||
|
char *p, /* character position */
|
||||||
|
int *num, /* Return value */
|
||||||
|
int dval) /* dval is the number to subtract from like $-3 */
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int sign = 1;
|
||||||
|
|
||||||
|
if (*++p == '^') {
|
||||||
|
*num = 1;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
if (*p == '$') {
|
||||||
|
if (*++p != '-') {
|
||||||
|
*num = 0x7fffffff; /* Handle $ */
|
||||||
|
return (--p);
|
||||||
|
}
|
||||||
|
sign = -1; /* Handle $- */
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
|
||||||
|
continue;
|
||||||
|
*num = (sign < 0 ? dval - i : i);
|
||||||
|
return (--p);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* cv_delfini():
|
||||||
|
* Finish vi delete action
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
cv_delfini(EditLine *el)
|
||||||
|
{
|
||||||
|
int size;
|
||||||
|
int action = el->el_chared.c_vcmd.action;
|
||||||
|
|
||||||
|
if (action & INSERT)
|
||||||
|
el->el_map.current = el->el_map.key;
|
||||||
|
|
||||||
|
if (el->el_chared.c_vcmd.pos == 0)
|
||||||
|
/* sanity */
|
||||||
|
return;
|
||||||
|
|
||||||
|
size = el->el_line.cursor - el->el_chared.c_vcmd.pos;
|
||||||
|
if (size == 0)
|
||||||
|
size = 1;
|
||||||
|
el->el_line.cursor = el->el_chared.c_vcmd.pos;
|
||||||
|
if (action & YANK) {
|
||||||
|
if (size > 0)
|
||||||
|
cv_yank(el, el->el_line.cursor, size);
|
||||||
|
else
|
||||||
|
cv_yank(el, el->el_line.cursor + size, -size);
|
||||||
|
} else {
|
||||||
|
if (size > 0) {
|
||||||
|
c_delafter(el, size);
|
||||||
|
re_refresh_cursor(el);
|
||||||
|
} else {
|
||||||
|
c_delbefore(el, -size);
|
||||||
|
el->el_line.cursor += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
el->el_chared.c_vcmd.action = NOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef notdef
|
||||||
|
/* ce__endword():
|
||||||
|
* Go to the end of this word according to emacs
|
||||||
|
*/
|
||||||
|
protected char *
|
||||||
|
ce__endword(char *p, char *high, int n)
|
||||||
|
{
|
||||||
|
p++;
|
||||||
|
|
||||||
|
while (n--) {
|
||||||
|
while ((p < high) && isspace((unsigned char) *p))
|
||||||
|
p++;
|
||||||
|
while ((p < high) && !isspace((unsigned char) *p))
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
|
||||||
|
p--;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* cv__endword():
|
||||||
|
* Go to the end of this word according to vi
|
||||||
|
*/
|
||||||
|
protected char *
|
||||||
|
cv__endword(char *p, char *high, int n, int (*wtest)(int))
|
||||||
|
{
|
||||||
|
int test;
|
||||||
|
|
||||||
|
p++;
|
||||||
|
|
||||||
|
while (n--) {
|
||||||
|
while ((p < high) && isspace((unsigned char) *p))
|
||||||
|
p++;
|
||||||
|
|
||||||
|
test = (*wtest)((unsigned char) *p);
|
||||||
|
while ((p < high) && (*wtest)((unsigned char) *p) == test)
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
p--;
|
||||||
|
return (p);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ch_init():
|
||||||
|
* Initialize the character editor
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
ch_init(EditLine *el)
|
||||||
|
{
|
||||||
|
c_macro_t *ma = &el->el_chared.c_macro;
|
||||||
|
|
||||||
|
el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ);
|
||||||
|
if (el->el_line.buffer == NULL)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
(void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
|
||||||
|
el->el_line.cursor = el->el_line.buffer;
|
||||||
|
el->el_line.lastchar = el->el_line.buffer;
|
||||||
|
el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
|
||||||
|
|
||||||
|
el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ);
|
||||||
|
if (el->el_chared.c_undo.buf == NULL)
|
||||||
|
return (-1);
|
||||||
|
(void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
|
||||||
|
el->el_chared.c_undo.len = -1;
|
||||||
|
el->el_chared.c_undo.cursor = 0;
|
||||||
|
el->el_chared.c_redo.buf = (char *) el_malloc(EL_BUFSIZ);
|
||||||
|
if (el->el_chared.c_redo.buf == NULL)
|
||||||
|
return (-1);
|
||||||
|
el->el_chared.c_redo.pos = el->el_chared.c_redo.buf;
|
||||||
|
el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ;
|
||||||
|
el->el_chared.c_redo.cmd = ED_UNASSIGNED;
|
||||||
|
|
||||||
|
el->el_chared.c_vcmd.action = NOP;
|
||||||
|
el->el_chared.c_vcmd.pos = el->el_line.buffer;
|
||||||
|
|
||||||
|
el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ);
|
||||||
|
if (el->el_chared.c_kill.buf == NULL)
|
||||||
|
return (-1);
|
||||||
|
(void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ);
|
||||||
|
el->el_chared.c_kill.mark = el->el_line.buffer;
|
||||||
|
el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
|
||||||
|
|
||||||
|
el->el_map.current = el->el_map.key;
|
||||||
|
|
||||||
|
el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
|
||||||
|
el->el_state.doingarg = 0;
|
||||||
|
el->el_state.metanext = 0;
|
||||||
|
el->el_state.argument = 1;
|
||||||
|
el->el_state.lastcmd = ED_UNASSIGNED;
|
||||||
|
|
||||||
|
ma->level = -1;
|
||||||
|
ma->offset = 0;
|
||||||
|
ma->macro = (char **) el_malloc(EL_MAXMACRO * sizeof(char *));
|
||||||
|
if (ma->macro == NULL)
|
||||||
|
return (-1);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ch_reset():
|
||||||
|
* Reset the character editor
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
ch_reset(EditLine *el, int mclear)
|
||||||
|
{
|
||||||
|
el->el_line.cursor = el->el_line.buffer;
|
||||||
|
el->el_line.lastchar = el->el_line.buffer;
|
||||||
|
|
||||||
|
el->el_chared.c_undo.len = -1;
|
||||||
|
el->el_chared.c_undo.cursor = 0;
|
||||||
|
|
||||||
|
el->el_chared.c_vcmd.action = NOP;
|
||||||
|
el->el_chared.c_vcmd.pos = el->el_line.buffer;
|
||||||
|
|
||||||
|
el->el_chared.c_kill.mark = el->el_line.buffer;
|
||||||
|
|
||||||
|
el->el_map.current = el->el_map.key;
|
||||||
|
|
||||||
|
el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */
|
||||||
|
el->el_state.doingarg = 0;
|
||||||
|
el->el_state.metanext = 0;
|
||||||
|
el->el_state.argument = 1;
|
||||||
|
el->el_state.lastcmd = ED_UNASSIGNED;
|
||||||
|
|
||||||
|
el->el_history.eventno = 0;
|
||||||
|
|
||||||
|
if (mclear)
|
||||||
|
ch__clearmacro(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void
|
||||||
|
ch__clearmacro(el)
|
||||||
|
EditLine *el;
|
||||||
|
{
|
||||||
|
c_macro_t *ma = &el->el_chared.c_macro;
|
||||||
|
while (ma->level >= 0)
|
||||||
|
el_free((ptr_t)ma->macro[ma->level--]);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ch_enlargebufs():
|
||||||
|
* Enlarge line buffer to be able to hold twice as much characters.
|
||||||
|
* Returns 1 if successful, 0 if not.
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
ch_enlargebufs(el, addlen)
|
||||||
|
EditLine *el;
|
||||||
|
size_t addlen;
|
||||||
|
{
|
||||||
|
size_t sz, newsz;
|
||||||
|
char *newbuffer, *oldbuf, *oldkbuf;
|
||||||
|
|
||||||
|
sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE;
|
||||||
|
newsz = sz * 2;
|
||||||
|
/*
|
||||||
|
* If newly required length is longer than current buffer, we need
|
||||||
|
* to make the buffer big enough to hold both old and new stuff.
|
||||||
|
*/
|
||||||
|
if (addlen > sz) {
|
||||||
|
while(newsz - sz < addlen)
|
||||||
|
newsz *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reallocate line buffer.
|
||||||
|
*/
|
||||||
|
newbuffer = el_realloc(el->el_line.buffer, newsz);
|
||||||
|
if (!newbuffer)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* zero the newly added memory, leave old data in */
|
||||||
|
(void) memset(&newbuffer[sz], 0, newsz - sz);
|
||||||
|
|
||||||
|
oldbuf = el->el_line.buffer;
|
||||||
|
|
||||||
|
el->el_line.buffer = newbuffer;
|
||||||
|
el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf);
|
||||||
|
el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf);
|
||||||
|
/* don't set new size until all buffers are enlarged */
|
||||||
|
el->el_line.limit = &newbuffer[sz - EL_LEAVE];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reallocate kill buffer.
|
||||||
|
*/
|
||||||
|
newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz);
|
||||||
|
if (!newbuffer)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* zero the newly added memory, leave old data in */
|
||||||
|
(void) memset(&newbuffer[sz], 0, newsz - sz);
|
||||||
|
|
||||||
|
oldkbuf = el->el_chared.c_kill.buf;
|
||||||
|
|
||||||
|
el->el_chared.c_kill.buf = newbuffer;
|
||||||
|
el->el_chared.c_kill.last = newbuffer +
|
||||||
|
(el->el_chared.c_kill.last - oldkbuf);
|
||||||
|
el->el_chared.c_kill.mark = el->el_line.buffer +
|
||||||
|
(el->el_chared.c_kill.mark - oldbuf);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reallocate undo buffer.
|
||||||
|
*/
|
||||||
|
newbuffer = el_realloc(el->el_chared.c_undo.buf, newsz);
|
||||||
|
if (!newbuffer)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* zero the newly added memory, leave old data in */
|
||||||
|
(void) memset(&newbuffer[sz], 0, newsz - sz);
|
||||||
|
el->el_chared.c_undo.buf = newbuffer;
|
||||||
|
|
||||||
|
newbuffer = el_realloc(el->el_chared.c_redo.buf, newsz);
|
||||||
|
if (!newbuffer)
|
||||||
|
return 0;
|
||||||
|
el->el_chared.c_redo.pos = newbuffer +
|
||||||
|
(el->el_chared.c_redo.pos - el->el_chared.c_redo.buf);
|
||||||
|
el->el_chared.c_redo.lim = newbuffer +
|
||||||
|
(el->el_chared.c_redo.lim - el->el_chared.c_redo.buf);
|
||||||
|
el->el_chared.c_redo.buf = newbuffer;
|
||||||
|
|
||||||
|
if (!hist_enlargebuf(el, sz, newsz))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* Safe to set enlarged buffer size */
|
||||||
|
el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ch_end():
|
||||||
|
* Free the data structures used by the editor
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
ch_end(EditLine *el)
|
||||||
|
{
|
||||||
|
el_free((ptr_t) el->el_line.buffer);
|
||||||
|
el->el_line.buffer = NULL;
|
||||||
|
el->el_line.limit = NULL;
|
||||||
|
el_free((ptr_t) el->el_chared.c_undo.buf);
|
||||||
|
el->el_chared.c_undo.buf = NULL;
|
||||||
|
el_free((ptr_t) el->el_chared.c_redo.buf);
|
||||||
|
el->el_chared.c_redo.buf = NULL;
|
||||||
|
el->el_chared.c_redo.pos = NULL;
|
||||||
|
el->el_chared.c_redo.lim = NULL;
|
||||||
|
el->el_chared.c_redo.cmd = ED_UNASSIGNED;
|
||||||
|
el_free((ptr_t) el->el_chared.c_kill.buf);
|
||||||
|
el->el_chared.c_kill.buf = NULL;
|
||||||
|
ch_reset(el, 1);
|
||||||
|
el_free((ptr_t) el->el_chared.c_macro.macro);
|
||||||
|
el->el_chared.c_macro.macro = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_insertstr():
|
||||||
|
* Insert string at cursorI
|
||||||
|
*/
|
||||||
|
public int
|
||||||
|
el_insertstr(EditLine *el, const char *s)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if ((len = strlen(s)) == 0)
|
||||||
|
return (-1);
|
||||||
|
if (el->el_line.lastchar + len >= el->el_line.limit) {
|
||||||
|
if (!ch_enlargebufs(el, len))
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
c_insert(el, (int)len);
|
||||||
|
while (*s)
|
||||||
|
*el->el_line.cursor++ = *s++;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_deletestr():
|
||||||
|
* Delete num characters before the cursor
|
||||||
|
*/
|
||||||
|
public void
|
||||||
|
el_deletestr(EditLine *el, int n)
|
||||||
|
{
|
||||||
|
if (n <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (el->el_line.cursor < &el->el_line.buffer[n])
|
||||||
|
return;
|
||||||
|
|
||||||
|
c_delbefore(el, n); /* delete before dot */
|
||||||
|
el->el_line.cursor -= n;
|
||||||
|
if (el->el_line.cursor < el->el_line.buffer)
|
||||||
|
el->el_line.cursor = el->el_line.buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* c_gets():
|
||||||
|
* Get a string
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
c_gets(EditLine *el, char *buf, const char *prompt)
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
int len;
|
||||||
|
char *cp = el->el_line.buffer;
|
||||||
|
|
||||||
|
if (prompt) {
|
||||||
|
len = strlen(prompt);
|
||||||
|
memcpy(cp, prompt, len + 0u);
|
||||||
|
cp += len;
|
||||||
|
}
|
||||||
|
len = 0;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
el->el_line.cursor = cp;
|
||||||
|
*cp = ' ';
|
||||||
|
el->el_line.lastchar = cp + 1;
|
||||||
|
re_refresh(el);
|
||||||
|
|
||||||
|
if (el_getc(el, &ch) != 1) {
|
||||||
|
ed_end_of_file(el, 0);
|
||||||
|
len = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ch) {
|
||||||
|
|
||||||
|
case 0010: /* Delete and backspace */
|
||||||
|
case 0177:
|
||||||
|
if (len <= 0) {
|
||||||
|
len = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
cp--;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 0033: /* ESC */
|
||||||
|
case '\r': /* Newline */
|
||||||
|
case '\n':
|
||||||
|
buf[len] = ch;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
if (len >= EL_BUFSIZ - 16)
|
||||||
|
term_beep(el);
|
||||||
|
else {
|
||||||
|
buf[len++] = ch;
|
||||||
|
*cp++ = ch;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
el->el_line.buffer[0] = '\0';
|
||||||
|
el->el_line.lastchar = el->el_line.buffer;
|
||||||
|
el->el_line.cursor = el->el_line.buffer;
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* c_hpos():
|
||||||
|
* Return the current horizontal position of the cursor
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
c_hpos(EditLine *el)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find how many characters till the beginning of this line.
|
||||||
|
*/
|
||||||
|
if (el->el_line.cursor == el->el_line.buffer)
|
||||||
|
return (0);
|
||||||
|
else {
|
||||||
|
for (ptr = el->el_line.cursor - 1;
|
||||||
|
ptr >= el->el_line.buffer && *ptr != '\n';
|
||||||
|
ptr--)
|
||||||
|
continue;
|
||||||
|
return (el->el_line.cursor - ptr - 1);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,167 @@
|
||||||
|
/* $NetBSD: chared.h,v 1.17 2006/03/06 21:11:56 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)chared.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.chared.h: Character editor interface
|
||||||
|
*/
|
||||||
|
#ifndef _h_el_chared
|
||||||
|
#define _h_el_chared
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "histedit.h"
|
||||||
|
|
||||||
|
#define EL_MAXMACRO 10
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is an issue of basic "vi" look-and-feel. Defining VI_MOVE works
|
||||||
|
* like real vi: i.e. the transition from command<->insert modes moves
|
||||||
|
* the cursor.
|
||||||
|
*
|
||||||
|
* On the other hand we really don't want to move the cursor, because
|
||||||
|
* all the editing commands don't include the character under the cursor.
|
||||||
|
* Probably the best fix is to make all the editing commands aware of
|
||||||
|
* this fact.
|
||||||
|
*/
|
||||||
|
#define VI_MOVE
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct c_macro_t {
|
||||||
|
int level;
|
||||||
|
int offset;
|
||||||
|
char **macro;
|
||||||
|
} c_macro_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Undo information for vi - no undo in emacs (yet)
|
||||||
|
*/
|
||||||
|
typedef struct c_undo_t {
|
||||||
|
int len; /* length of saved line */
|
||||||
|
int cursor; /* position of saved cursor */
|
||||||
|
char *buf; /* full saved text */
|
||||||
|
} c_undo_t;
|
||||||
|
|
||||||
|
/* redo for vi */
|
||||||
|
typedef struct c_redo_t {
|
||||||
|
char *buf; /* redo insert key sequence */
|
||||||
|
char *pos;
|
||||||
|
char *lim;
|
||||||
|
el_action_t cmd; /* command to redo */
|
||||||
|
char ch; /* char that invoked it */
|
||||||
|
int count;
|
||||||
|
int action; /* from cv_action() */
|
||||||
|
} c_redo_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Current action information for vi
|
||||||
|
*/
|
||||||
|
typedef struct c_vcmd_t {
|
||||||
|
int action;
|
||||||
|
char *pos;
|
||||||
|
} c_vcmd_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Kill buffer for emacs
|
||||||
|
*/
|
||||||
|
typedef struct c_kill_t {
|
||||||
|
char *buf;
|
||||||
|
char *last;
|
||||||
|
char *mark;
|
||||||
|
} c_kill_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note that we use both data structures because the user can bind
|
||||||
|
* commands from both editors!
|
||||||
|
*/
|
||||||
|
typedef struct el_chared_t {
|
||||||
|
c_undo_t c_undo;
|
||||||
|
c_kill_t c_kill;
|
||||||
|
c_redo_t c_redo;
|
||||||
|
c_vcmd_t c_vcmd;
|
||||||
|
c_macro_t c_macro;
|
||||||
|
} el_chared_t;
|
||||||
|
|
||||||
|
|
||||||
|
#define STRQQ "\"\""
|
||||||
|
|
||||||
|
#define isglob(a) (strchr("*[]?", (a)) != NULL)
|
||||||
|
#define isword(a) (isprint(a))
|
||||||
|
|
||||||
|
#define NOP 0x00
|
||||||
|
#define DELETE 0x01
|
||||||
|
#define INSERT 0x02
|
||||||
|
#define YANK 0x04
|
||||||
|
|
||||||
|
#define CHAR_FWD (+1)
|
||||||
|
#define CHAR_BACK (-1)
|
||||||
|
|
||||||
|
#define MODE_INSERT 0
|
||||||
|
#define MODE_REPLACE 1
|
||||||
|
#define MODE_REPLACE_1 2
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
#include "vi.h"
|
||||||
|
#include "emacs.h"
|
||||||
|
#include "search.h"
|
||||||
|
#include "fcns.h"
|
||||||
|
|
||||||
|
|
||||||
|
protected int cv__isword(int);
|
||||||
|
protected int cv__isWord(int);
|
||||||
|
protected void cv_delfini(EditLine *);
|
||||||
|
protected char *cv__endword(char *, char *, int, int (*)(int));
|
||||||
|
protected int ce__isword(int);
|
||||||
|
protected void cv_undo(EditLine *);
|
||||||
|
protected void cv_yank(EditLine *, const char *, int);
|
||||||
|
protected char *cv_next_word(EditLine*, char *, char *, int, int (*)(int));
|
||||||
|
protected char *cv_prev_word(char *, char *, int, int (*)(int));
|
||||||
|
protected char *c__next_word(char *, char *, int, int (*)(int));
|
||||||
|
protected char *c__prev_word(char *, char *, int, int (*)(int));
|
||||||
|
protected void c_insert(EditLine *, int);
|
||||||
|
protected void c_delbefore(EditLine *, int);
|
||||||
|
protected void c_delbefore1(EditLine *);
|
||||||
|
protected void c_delafter(EditLine *, int);
|
||||||
|
protected void c_delafter1(EditLine *);
|
||||||
|
protected int c_gets(EditLine *, char *, const char *);
|
||||||
|
protected int c_hpos(EditLine *);
|
||||||
|
|
||||||
|
protected int ch_init(EditLine *);
|
||||||
|
protected void ch_reset(EditLine *, int);
|
||||||
|
protected int ch_enlargebufs(EditLine *, size_t);
|
||||||
|
protected void ch_end(EditLine *);
|
||||||
|
|
||||||
|
#endif /* _h_el_chared */
|
|
@ -0,0 +1,921 @@
|
||||||
|
/* $NetBSD: common.c,v 1.19 2006/03/06 21:11:56 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: common.c,v 1.19 2006/03/06 21:11:56 christos Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* common.c: Common Editor functions
|
||||||
|
*/
|
||||||
|
#include "el.h"
|
||||||
|
|
||||||
|
/* ed_end_of_file():
|
||||||
|
* Indicate end of file
|
||||||
|
* [^D]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_end_of_file(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
re_goto_bottom(el);
|
||||||
|
*el->el_line.lastchar = '\0';
|
||||||
|
return (CC_EOF);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_insert():
|
||||||
|
* Add character to the line
|
||||||
|
* Insert a character [bound to all insert keys]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
ed_insert(EditLine *el, int c)
|
||||||
|
{
|
||||||
|
int count = el->el_state.argument;
|
||||||
|
|
||||||
|
if (c == '\0')
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
if (el->el_line.lastchar + el->el_state.argument >=
|
||||||
|
el->el_line.limit) {
|
||||||
|
/* end of buffer space, try to allocate more */
|
||||||
|
if (!ch_enlargebufs(el, (size_t) count))
|
||||||
|
return CC_ERROR; /* error allocating more */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count == 1) {
|
||||||
|
if (el->el_state.inputmode == MODE_INSERT
|
||||||
|
|| el->el_line.cursor >= el->el_line.lastchar)
|
||||||
|
c_insert(el, 1);
|
||||||
|
|
||||||
|
*el->el_line.cursor++ = c;
|
||||||
|
re_fastaddc(el); /* fast refresh for one char. */
|
||||||
|
} else {
|
||||||
|
if (el->el_state.inputmode != MODE_REPLACE_1)
|
||||||
|
c_insert(el, el->el_state.argument);
|
||||||
|
|
||||||
|
while (count-- && el->el_line.cursor < el->el_line.lastchar)
|
||||||
|
*el->el_line.cursor++ = c;
|
||||||
|
re_refresh(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (el->el_state.inputmode == MODE_REPLACE_1)
|
||||||
|
return vi_command_mode(el, 0);
|
||||||
|
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_delete_prev_word():
|
||||||
|
* Delete from beginning of current word to cursor
|
||||||
|
* [M-^?] [^W]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *cp, *p, *kp;
|
||||||
|
|
||||||
|
if (el->el_line.cursor == el->el_line.buffer)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
|
||||||
|
el->el_state.argument, ce__isword);
|
||||||
|
|
||||||
|
for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++)
|
||||||
|
*kp++ = *p;
|
||||||
|
el->el_chared.c_kill.last = kp;
|
||||||
|
|
||||||
|
c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */
|
||||||
|
el->el_line.cursor = cp;
|
||||||
|
if (el->el_line.cursor < el->el_line.buffer)
|
||||||
|
el->el_line.cursor = el->el_line.buffer; /* bounds check */
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_delete_next_char():
|
||||||
|
* Delete character under cursor
|
||||||
|
* [^D] [x]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_delete_next_char(EditLine *el, int c)
|
||||||
|
{
|
||||||
|
#ifdef notdef /* XXX */
|
||||||
|
#define EL el->el_line
|
||||||
|
(void) fprintf(el->el_errlfile,
|
||||||
|
"\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n",
|
||||||
|
EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar,
|
||||||
|
EL.lastchar, EL.limit, EL.limit);
|
||||||
|
#endif
|
||||||
|
if (el->el_line.cursor == el->el_line.lastchar) {
|
||||||
|
/* if I'm at the end */
|
||||||
|
if (el->el_map.type == MAP_VI) {
|
||||||
|
if (el->el_line.cursor == el->el_line.buffer) {
|
||||||
|
/* if I'm also at the beginning */
|
||||||
|
#ifdef KSHVI
|
||||||
|
return (CC_ERROR);
|
||||||
|
#else
|
||||||
|
/* then do an EOF */
|
||||||
|
term_writechar(el, c);
|
||||||
|
return (CC_EOF);
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#ifdef KSHVI
|
||||||
|
el->el_line.cursor--;
|
||||||
|
#else
|
||||||
|
return (CC_ERROR);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (el->el_line.cursor != el->el_line.buffer)
|
||||||
|
el->el_line.cursor--;
|
||||||
|
else
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
c_delafter(el, el->el_state.argument); /* delete after dot */
|
||||||
|
if (el->el_line.cursor >= el->el_line.lastchar &&
|
||||||
|
el->el_line.cursor > el->el_line.buffer)
|
||||||
|
/* bounds check */
|
||||||
|
el->el_line.cursor = el->el_line.lastchar - 1;
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_kill_line():
|
||||||
|
* Cut to the end of line
|
||||||
|
* [^K] [^K]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_kill_line(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *kp, *cp;
|
||||||
|
|
||||||
|
cp = el->el_line.cursor;
|
||||||
|
kp = el->el_chared.c_kill.buf;
|
||||||
|
while (cp < el->el_line.lastchar)
|
||||||
|
*kp++ = *cp++; /* copy it */
|
||||||
|
el->el_chared.c_kill.last = kp;
|
||||||
|
/* zap! -- delete to end */
|
||||||
|
el->el_line.lastchar = el->el_line.cursor;
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_move_to_end():
|
||||||
|
* Move cursor to the end of line
|
||||||
|
* [^E] [^E]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_move_to_end(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_line.cursor = el->el_line.lastchar;
|
||||||
|
if (el->el_map.type == MAP_VI) {
|
||||||
|
#ifdef VI_MOVE
|
||||||
|
el->el_line.cursor--;
|
||||||
|
#endif
|
||||||
|
if (el->el_chared.c_vcmd.action != NOP) {
|
||||||
|
cv_delfini(el);
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (CC_CURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_move_to_beg():
|
||||||
|
* Move cursor to the beginning of line
|
||||||
|
* [^A] [^A]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_move_to_beg(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_line.cursor = el->el_line.buffer;
|
||||||
|
|
||||||
|
if (el->el_map.type == MAP_VI) {
|
||||||
|
/* We want FIRST non space character */
|
||||||
|
while (isspace((unsigned char) *el->el_line.cursor))
|
||||||
|
el->el_line.cursor++;
|
||||||
|
if (el->el_chared.c_vcmd.action != NOP) {
|
||||||
|
cv_delfini(el);
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (CC_CURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_transpose_chars():
|
||||||
|
* Exchange the character to the left of the cursor with the one under it
|
||||||
|
* [^T] [^T]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
ed_transpose_chars(EditLine *el, int c)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (el->el_line.cursor < el->el_line.lastchar) {
|
||||||
|
if (el->el_line.lastchar <= &el->el_line.buffer[1])
|
||||||
|
return (CC_ERROR);
|
||||||
|
else
|
||||||
|
el->el_line.cursor++;
|
||||||
|
}
|
||||||
|
if (el->el_line.cursor > &el->el_line.buffer[1]) {
|
||||||
|
/* must have at least two chars entered */
|
||||||
|
c = el->el_line.cursor[-2];
|
||||||
|
el->el_line.cursor[-2] = el->el_line.cursor[-1];
|
||||||
|
el->el_line.cursor[-1] = c;
|
||||||
|
return (CC_REFRESH);
|
||||||
|
} else
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_next_char():
|
||||||
|
* Move to the right one character
|
||||||
|
* [^F] [^F]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_next_char(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *lim = el->el_line.lastchar;
|
||||||
|
|
||||||
|
if (el->el_line.cursor >= lim ||
|
||||||
|
(el->el_line.cursor == lim - 1 &&
|
||||||
|
el->el_map.type == MAP_VI &&
|
||||||
|
el->el_chared.c_vcmd.action == NOP))
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
el->el_line.cursor += el->el_state.argument;
|
||||||
|
if (el->el_line.cursor > lim)
|
||||||
|
el->el_line.cursor = lim;
|
||||||
|
|
||||||
|
if (el->el_map.type == MAP_VI)
|
||||||
|
if (el->el_chared.c_vcmd.action != NOP) {
|
||||||
|
cv_delfini(el);
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
return (CC_CURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_prev_word():
|
||||||
|
* Move to the beginning of the current word
|
||||||
|
* [M-b] [b]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_prev_word(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (el->el_line.cursor == el->el_line.buffer)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
el->el_line.cursor = c__prev_word(el->el_line.cursor,
|
||||||
|
el->el_line.buffer,
|
||||||
|
el->el_state.argument,
|
||||||
|
ce__isword);
|
||||||
|
|
||||||
|
if (el->el_map.type == MAP_VI)
|
||||||
|
if (el->el_chared.c_vcmd.action != NOP) {
|
||||||
|
cv_delfini(el);
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
return (CC_CURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_prev_char():
|
||||||
|
* Move to the left one character
|
||||||
|
* [^B] [^B]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_prev_char(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (el->el_line.cursor > el->el_line.buffer) {
|
||||||
|
el->el_line.cursor -= el->el_state.argument;
|
||||||
|
if (el->el_line.cursor < el->el_line.buffer)
|
||||||
|
el->el_line.cursor = el->el_line.buffer;
|
||||||
|
|
||||||
|
if (el->el_map.type == MAP_VI)
|
||||||
|
if (el->el_chared.c_vcmd.action != NOP) {
|
||||||
|
cv_delfini(el);
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
return (CC_CURSOR);
|
||||||
|
} else
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_quoted_insert():
|
||||||
|
* Add the next character typed verbatim
|
||||||
|
* [^V] [^V]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
ed_quoted_insert(EditLine *el, int c)
|
||||||
|
{
|
||||||
|
int num;
|
||||||
|
char tc;
|
||||||
|
|
||||||
|
tty_quotemode(el);
|
||||||
|
num = el_getc(el, &tc);
|
||||||
|
c = (unsigned char) tc;
|
||||||
|
tty_noquotemode(el);
|
||||||
|
if (num == 1)
|
||||||
|
return (ed_insert(el, c));
|
||||||
|
else
|
||||||
|
return (ed_end_of_file(el, 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_digit():
|
||||||
|
* Adds to argument or enters a digit
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
ed_digit(EditLine *el, int c)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!isdigit(c))
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
if (el->el_state.doingarg) {
|
||||||
|
/* if doing an arg, add this in... */
|
||||||
|
if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT)
|
||||||
|
el->el_state.argument = c - '0';
|
||||||
|
else {
|
||||||
|
if (el->el_state.argument > 1000000)
|
||||||
|
return (CC_ERROR);
|
||||||
|
el->el_state.argument =
|
||||||
|
(el->el_state.argument * 10) + (c - '0');
|
||||||
|
}
|
||||||
|
return (CC_ARGHACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ed_insert(el, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_argument_digit():
|
||||||
|
* Digit that starts argument
|
||||||
|
* For ESC-n
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
ed_argument_digit(EditLine *el, int c)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (!isdigit(c))
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
if (el->el_state.doingarg) {
|
||||||
|
if (el->el_state.argument > 1000000)
|
||||||
|
return (CC_ERROR);
|
||||||
|
el->el_state.argument = (el->el_state.argument * 10) +
|
||||||
|
(c - '0');
|
||||||
|
} else { /* else starting an argument */
|
||||||
|
el->el_state.argument = c - '0';
|
||||||
|
el->el_state.doingarg = 1;
|
||||||
|
}
|
||||||
|
return (CC_ARGHACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_unassigned():
|
||||||
|
* Indicates unbound character
|
||||||
|
* Bound to keys that are not assigned
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_unassigned(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
** TTY key handling.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/* ed_tty_sigint():
|
||||||
|
* Tty interrupt character
|
||||||
|
* [^C]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_tty_sigint(EditLine *el __attribute__((__unused__)),
|
||||||
|
int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_tty_dsusp():
|
||||||
|
* Tty delayed suspend character
|
||||||
|
* [^Y]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
|
||||||
|
int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_tty_flush_output():
|
||||||
|
* Tty flush output characters
|
||||||
|
* [^O]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_tty_flush_output(EditLine *el __attribute__((__unused__)),
|
||||||
|
int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_tty_sigquit():
|
||||||
|
* Tty quit character
|
||||||
|
* [^\]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
|
||||||
|
int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_tty_sigtstp():
|
||||||
|
* Tty suspend character
|
||||||
|
* [^Z]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
|
||||||
|
int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_tty_stop_output():
|
||||||
|
* Tty disallow output characters
|
||||||
|
* [^S]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_tty_stop_output(EditLine *el __attribute__((__unused__)),
|
||||||
|
int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_tty_start_output():
|
||||||
|
* Tty allow output characters
|
||||||
|
* [^Q]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_tty_start_output(EditLine *el __attribute__((__unused__)),
|
||||||
|
int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_newline():
|
||||||
|
* Execute command
|
||||||
|
* [^J]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_newline(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
re_goto_bottom(el);
|
||||||
|
*el->el_line.lastchar++ = '\n';
|
||||||
|
*el->el_line.lastchar = '\0';
|
||||||
|
return (CC_NEWLINE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_delete_prev_char():
|
||||||
|
* Delete the character to the left of the cursor
|
||||||
|
* [^?]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (el->el_line.cursor <= el->el_line.buffer)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
c_delbefore(el, el->el_state.argument);
|
||||||
|
el->el_line.cursor -= el->el_state.argument;
|
||||||
|
if (el->el_line.cursor < el->el_line.buffer)
|
||||||
|
el->el_line.cursor = el->el_line.buffer;
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_clear_screen():
|
||||||
|
* Clear screen leaving current line at the top
|
||||||
|
* [^L]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_clear_screen(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
term_clear_screen(el); /* clear the whole real screen */
|
||||||
|
re_clear_display(el); /* reset everything */
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_redisplay():
|
||||||
|
* Redisplay everything
|
||||||
|
* ^R
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_redisplay(EditLine *el __attribute__((__unused__)),
|
||||||
|
int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
return (CC_REDISPLAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_start_over():
|
||||||
|
* Erase current line and start from scratch
|
||||||
|
* [^G]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_start_over(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
ch_reset(el, 0);
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_sequence_lead_in():
|
||||||
|
* First character in a bound sequence
|
||||||
|
* Placeholder for external keys
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
|
||||||
|
int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_prev_history():
|
||||||
|
* Move to the previous history line
|
||||||
|
* [^P] [k]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char beep = 0;
|
||||||
|
int sv_event = el->el_history.eventno;
|
||||||
|
|
||||||
|
el->el_chared.c_undo.len = -1;
|
||||||
|
*el->el_line.lastchar = '\0'; /* just in case */
|
||||||
|
|
||||||
|
if (el->el_history.eventno == 0) { /* save the current buffer
|
||||||
|
* away */
|
||||||
|
(void) strncpy(el->el_history.buf, el->el_line.buffer,
|
||||||
|
EL_BUFSIZ);
|
||||||
|
el->el_history.last = el->el_history.buf +
|
||||||
|
(el->el_line.lastchar - el->el_line.buffer);
|
||||||
|
}
|
||||||
|
el->el_history.eventno += el->el_state.argument;
|
||||||
|
|
||||||
|
if (hist_get(el) == CC_ERROR) {
|
||||||
|
if (el->el_map.type == MAP_VI) {
|
||||||
|
el->el_history.eventno = sv_event;
|
||||||
|
return CC_ERROR;
|
||||||
|
}
|
||||||
|
beep = 1;
|
||||||
|
/* el->el_history.eventno was fixed by first call */
|
||||||
|
(void) hist_get(el);
|
||||||
|
}
|
||||||
|
if (beep)
|
||||||
|
return CC_REFRESH_BEEP;
|
||||||
|
return CC_REFRESH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_next_history():
|
||||||
|
* Move to the next history line
|
||||||
|
* [^N] [j]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_next_history(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
el_action_t beep = CC_REFRESH, rval;
|
||||||
|
|
||||||
|
el->el_chared.c_undo.len = -1;
|
||||||
|
*el->el_line.lastchar = '\0'; /* just in case */
|
||||||
|
|
||||||
|
el->el_history.eventno -= el->el_state.argument;
|
||||||
|
|
||||||
|
if (el->el_history.eventno < 0) {
|
||||||
|
el->el_history.eventno = 0;
|
||||||
|
beep = CC_REFRESH_BEEP;
|
||||||
|
}
|
||||||
|
rval = hist_get(el);
|
||||||
|
if (rval == CC_REFRESH)
|
||||||
|
return beep;
|
||||||
|
return rval;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_search_prev_history():
|
||||||
|
* Search previous in history for a line matching the current
|
||||||
|
* next search history [M-P] [K]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
const char *hp;
|
||||||
|
int h;
|
||||||
|
bool_t found = 0;
|
||||||
|
|
||||||
|
el->el_chared.c_vcmd.action = NOP;
|
||||||
|
el->el_chared.c_undo.len = -1;
|
||||||
|
*el->el_line.lastchar = '\0'; /* just in case */
|
||||||
|
if (el->el_history.eventno < 0) {
|
||||||
|
#ifdef DEBUG_EDIT
|
||||||
|
(void) fprintf(el->el_errfile,
|
||||||
|
"e_prev_search_hist(): eventno < 0;\n");
|
||||||
|
#endif
|
||||||
|
el->el_history.eventno = 0;
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
if (el->el_history.eventno == 0) {
|
||||||
|
(void) strncpy(el->el_history.buf, el->el_line.buffer,
|
||||||
|
EL_BUFSIZ);
|
||||||
|
el->el_history.last = el->el_history.buf +
|
||||||
|
(el->el_line.lastchar - el->el_line.buffer);
|
||||||
|
}
|
||||||
|
if (el->el_history.ref == NULL)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
hp = HIST_FIRST(el);
|
||||||
|
if (hp == NULL)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
c_setpat(el); /* Set search pattern !! */
|
||||||
|
|
||||||
|
for (h = 1; h <= el->el_history.eventno; h++)
|
||||||
|
hp = HIST_NEXT(el);
|
||||||
|
|
||||||
|
while (hp != NULL) {
|
||||||
|
#ifdef SDEBUG
|
||||||
|
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
|
||||||
|
#endif
|
||||||
|
if ((strncmp(hp, el->el_line.buffer, (size_t)
|
||||||
|
(el->el_line.lastchar - el->el_line.buffer)) ||
|
||||||
|
hp[el->el_line.lastchar - el->el_line.buffer]) &&
|
||||||
|
c_hmatch(el, hp)) {
|
||||||
|
found++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
h++;
|
||||||
|
hp = HIST_NEXT(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
|
#ifdef SDEBUG
|
||||||
|
(void) fprintf(el->el_errfile, "not found\n");
|
||||||
|
#endif
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
el->el_history.eventno = h;
|
||||||
|
|
||||||
|
return (hist_get(el));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_search_next_history():
|
||||||
|
* Search next in history for a line matching the current
|
||||||
|
* [M-N] [J]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
const char *hp;
|
||||||
|
int h;
|
||||||
|
bool_t found = 0;
|
||||||
|
|
||||||
|
el->el_chared.c_vcmd.action = NOP;
|
||||||
|
el->el_chared.c_undo.len = -1;
|
||||||
|
*el->el_line.lastchar = '\0'; /* just in case */
|
||||||
|
|
||||||
|
if (el->el_history.eventno == 0)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
if (el->el_history.ref == NULL)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
hp = HIST_FIRST(el);
|
||||||
|
if (hp == NULL)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
c_setpat(el); /* Set search pattern !! */
|
||||||
|
|
||||||
|
for (h = 1; h < el->el_history.eventno && hp; h++) {
|
||||||
|
#ifdef SDEBUG
|
||||||
|
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
|
||||||
|
#endif
|
||||||
|
if ((strncmp(hp, el->el_line.buffer, (size_t)
|
||||||
|
(el->el_line.lastchar - el->el_line.buffer)) ||
|
||||||
|
hp[el->el_line.lastchar - el->el_line.buffer]) &&
|
||||||
|
c_hmatch(el, hp))
|
||||||
|
found = h;
|
||||||
|
hp = HIST_NEXT(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) { /* is it the current history number? */
|
||||||
|
if (!c_hmatch(el, el->el_history.buf)) {
|
||||||
|
#ifdef SDEBUG
|
||||||
|
(void) fprintf(el->el_errfile, "not found\n");
|
||||||
|
#endif
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
el->el_history.eventno = found;
|
||||||
|
|
||||||
|
return (hist_get(el));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_prev_line():
|
||||||
|
* Move up one line
|
||||||
|
* Could be [k] [^p]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
int nchars = c_hpos(el);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move to the line requested
|
||||||
|
*/
|
||||||
|
if (*(ptr = el->el_line.cursor) == '\n')
|
||||||
|
ptr--;
|
||||||
|
|
||||||
|
for (; ptr >= el->el_line.buffer; ptr--)
|
||||||
|
if (*ptr == '\n' && --el->el_state.argument <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (el->el_state.argument > 0)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move to the beginning of the line
|
||||||
|
*/
|
||||||
|
for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move to the character requested
|
||||||
|
*/
|
||||||
|
for (ptr++;
|
||||||
|
nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
|
||||||
|
ptr++)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
el->el_line.cursor = ptr;
|
||||||
|
return (CC_CURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_next_line():
|
||||||
|
* Move down one line
|
||||||
|
* Could be [j] [^n]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_next_line(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
int nchars = c_hpos(el);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move to the line requested
|
||||||
|
*/
|
||||||
|
for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++)
|
||||||
|
if (*ptr == '\n' && --el->el_state.argument <= 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (el->el_state.argument > 0)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Move to the character requested
|
||||||
|
*/
|
||||||
|
for (ptr++;
|
||||||
|
nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n';
|
||||||
|
ptr++)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
el->el_line.cursor = ptr;
|
||||||
|
return (CC_CURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ed_command():
|
||||||
|
* Editline extended command
|
||||||
|
* [M-X] [:]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
ed_command(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char tmpbuf[EL_BUFSIZ];
|
||||||
|
int tmplen;
|
||||||
|
|
||||||
|
tmplen = c_gets(el, tmpbuf, "\n: ");
|
||||||
|
term__putc('\n');
|
||||||
|
|
||||||
|
if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
|
||||||
|
term_beep(el);
|
||||||
|
|
||||||
|
el->el_map.current = el->el_map.key;
|
||||||
|
re_clear_display(el);
|
||||||
|
return CC_REFRESH;
|
||||||
|
}
|
|
@ -0,0 +1,204 @@
|
||||||
|
/* $NetBSD: readline.h,v 1.21 2007/08/12 07:41:51 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jaromir Dolecek.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef _READLINE_H_
|
||||||
|
#define _READLINE_H_
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
/* list of readline stuff supported by editline library's readline wrapper */
|
||||||
|
|
||||||
|
/* typedefs */
|
||||||
|
typedef int Function(const char *, int);
|
||||||
|
typedef void VFunction(void);
|
||||||
|
typedef void VCPFunction(char *);
|
||||||
|
typedef char *CPFunction(const char *, int);
|
||||||
|
typedef char **CPPFunction(const char *, int, int);
|
||||||
|
typedef char *rl_compentry_func_t(const char *, int);
|
||||||
|
|
||||||
|
typedef void *histdata_t;
|
||||||
|
|
||||||
|
typedef struct _hist_entry {
|
||||||
|
const char *line;
|
||||||
|
histdata_t *data;
|
||||||
|
} HIST_ENTRY;
|
||||||
|
|
||||||
|
typedef struct _keymap_entry {
|
||||||
|
char type;
|
||||||
|
#define ISFUNC 0
|
||||||
|
#define ISKMAP 1
|
||||||
|
#define ISMACR 2
|
||||||
|
Function *function;
|
||||||
|
} KEYMAP_ENTRY;
|
||||||
|
|
||||||
|
#define KEYMAP_SIZE 256
|
||||||
|
|
||||||
|
typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE];
|
||||||
|
typedef KEYMAP_ENTRY *Keymap;
|
||||||
|
|
||||||
|
#define control_character_threshold 0x20
|
||||||
|
#define control_character_bit 0x40
|
||||||
|
|
||||||
|
#ifndef CTRL
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#ifdef __GLIBC__
|
||||||
|
#include <sys/ttydefaults.h>
|
||||||
|
#endif
|
||||||
|
#ifndef CTRL
|
||||||
|
#define CTRL(c) ((c) & 037)
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#ifndef UNCTRL
|
||||||
|
#define UNCTRL(c) (((c) - 'a' + 'A')|control_character_bit)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define RUBOUT 0x7f
|
||||||
|
#define ABORT_CHAR CTRL('G')
|
||||||
|
|
||||||
|
/* global variables used by readline enabled applications */
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
extern const char *rl_library_version;
|
||||||
|
extern char *rl_readline_name;
|
||||||
|
extern FILE *rl_instream;
|
||||||
|
extern FILE *rl_outstream;
|
||||||
|
extern char *rl_line_buffer;
|
||||||
|
extern int rl_point, rl_end;
|
||||||
|
extern int history_base, history_length;
|
||||||
|
extern int max_input_history;
|
||||||
|
extern char *rl_basic_word_break_characters;
|
||||||
|
extern char *rl_completer_word_break_characters;
|
||||||
|
extern char *rl_completer_quote_characters;
|
||||||
|
extern Function *rl_completion_entry_function;
|
||||||
|
extern CPPFunction *rl_attempted_completion_function;
|
||||||
|
extern int rl_attempted_completion_over;
|
||||||
|
extern int rl_completion_type;
|
||||||
|
extern int rl_completion_query_items;
|
||||||
|
extern char *rl_special_prefixes;
|
||||||
|
extern int rl_completion_append_character;
|
||||||
|
extern int rl_inhibit_completion;
|
||||||
|
extern Function *rl_pre_input_hook;
|
||||||
|
extern Function *rl_startup_hook;
|
||||||
|
extern char *rl_terminal_name;
|
||||||
|
extern int rl_already_prompted;
|
||||||
|
extern char *rl_prompt;
|
||||||
|
/*
|
||||||
|
* The following is not implemented
|
||||||
|
*/
|
||||||
|
extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
|
||||||
|
emacs_meta_keymap,
|
||||||
|
emacs_ctlx_keymap;
|
||||||
|
extern int rl_filename_completion_desired;
|
||||||
|
extern int rl_ignore_completion_duplicates;
|
||||||
|
extern int (*rl_getc_function)(FILE *);
|
||||||
|
extern VFunction *rl_redisplay_function;
|
||||||
|
extern VFunction *rl_completion_display_matches_hook;
|
||||||
|
extern VFunction *rl_prep_term_function;
|
||||||
|
extern VFunction *rl_deprep_term_function;
|
||||||
|
extern int readline_echoing_p;
|
||||||
|
extern int _rl_print_completions_horizontally;
|
||||||
|
|
||||||
|
/* supported functions */
|
||||||
|
char *readline(const char *);
|
||||||
|
int rl_initialize(void);
|
||||||
|
|
||||||
|
void using_history(void);
|
||||||
|
int add_history(const char *);
|
||||||
|
void clear_history(void);
|
||||||
|
void stifle_history(int);
|
||||||
|
int unstifle_history(void);
|
||||||
|
int history_is_stifled(void);
|
||||||
|
int where_history(void);
|
||||||
|
HIST_ENTRY *current_history(void);
|
||||||
|
HIST_ENTRY *history_get(int);
|
||||||
|
HIST_ENTRY *remove_history(int);
|
||||||
|
int history_total_bytes(void);
|
||||||
|
int history_set_pos(int);
|
||||||
|
HIST_ENTRY *previous_history(void);
|
||||||
|
HIST_ENTRY *next_history(void);
|
||||||
|
int history_search(const char *, int);
|
||||||
|
int history_search_prefix(const char *, int);
|
||||||
|
int history_search_pos(const char *, int, int);
|
||||||
|
int read_history(const char *);
|
||||||
|
int write_history(const char *);
|
||||||
|
int history_expand(char *, char **);
|
||||||
|
char **history_tokenize(const char *);
|
||||||
|
const char *get_history_event(const char *, int *, int);
|
||||||
|
char *history_arg_extract(int, int, const char *);
|
||||||
|
|
||||||
|
char *tilde_expand(char *);
|
||||||
|
char *filename_completion_function(const char *, int);
|
||||||
|
char *username_completion_function(const char *, int);
|
||||||
|
int rl_complete(int, int);
|
||||||
|
int rl_read_key(void);
|
||||||
|
char **completion_matches(const char *, CPFunction *);
|
||||||
|
void rl_display_match_list(char **, int, int);
|
||||||
|
|
||||||
|
int rl_insert(int, int);
|
||||||
|
void rl_reset_terminal(const char *);
|
||||||
|
int rl_bind_key(int, int (*)(int, int));
|
||||||
|
int rl_newline(int, int);
|
||||||
|
void rl_callback_read_char(void);
|
||||||
|
void rl_callback_handler_install(const char *, VCPFunction *);
|
||||||
|
void rl_callback_handler_remove(void);
|
||||||
|
void rl_redisplay(void);
|
||||||
|
int rl_get_previous_history(int, int);
|
||||||
|
void rl_prep_terminal(int);
|
||||||
|
void rl_deprep_terminal(void);
|
||||||
|
int rl_read_init_file(const char *);
|
||||||
|
int rl_parse_and_bind(const char *);
|
||||||
|
int rl_variable_bind(const char *, const char *);
|
||||||
|
void rl_stuff_char(int);
|
||||||
|
int rl_add_defun(const char *, Function *, int);
|
||||||
|
void rl_get_screen_size(int *, int *);
|
||||||
|
void rl_set_screen_size(int, int);
|
||||||
|
char *rl_filename_completion_function (const char *, int);
|
||||||
|
int _rl_abort_internal(void);
|
||||||
|
int _rl_qsort_string_compare(char **, char **);
|
||||||
|
char **rl_completion_matches(const char *, rl_compentry_func_t *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The following are not implemented
|
||||||
|
*/
|
||||||
|
int rl_kill_text(int, int);
|
||||||
|
Keymap rl_get_keymap(void);
|
||||||
|
void rl_set_keymap(Keymap);
|
||||||
|
Keymap rl_make_bare_keymap(void);
|
||||||
|
int rl_generic_bind(int, const char *, const char *, Keymap);
|
||||||
|
int rl_bind_key_in_map(int, Function *, Keymap);
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _READLINE_H_ */
|
|
@ -0,0 +1,572 @@
|
||||||
|
/* $NetBSD: el.c,v 1.44 2006/12/15 22:13:33 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: el.c,v 1.44 2006/12/15 22:13:33 christos Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.c: EditLine interface functions
|
||||||
|
*/
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include "el.h"
|
||||||
|
|
||||||
|
/* el_init():
|
||||||
|
* Initialize editline and set default parameters.
|
||||||
|
*/
|
||||||
|
public EditLine *
|
||||||
|
el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
|
||||||
|
{
|
||||||
|
|
||||||
|
EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
|
||||||
|
|
||||||
|
if (el == NULL)
|
||||||
|
return (NULL);
|
||||||
|
|
||||||
|
memset(el, 0, sizeof(EditLine));
|
||||||
|
|
||||||
|
el->el_infile = fin;
|
||||||
|
el->el_outfile = fout;
|
||||||
|
el->el_errfile = ferr;
|
||||||
|
|
||||||
|
el->el_infd = fileno(fin);
|
||||||
|
|
||||||
|
if ((el->el_prog = el_strdup(prog)) == NULL) {
|
||||||
|
el_free(el);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize all the modules. Order is important!!!
|
||||||
|
*/
|
||||||
|
el->el_flags = 0;
|
||||||
|
|
||||||
|
if (term_init(el) == -1) {
|
||||||
|
el_free(el->el_prog);
|
||||||
|
el_free(el);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
(void) key_init(el);
|
||||||
|
(void) map_init(el);
|
||||||
|
if (tty_init(el) == -1)
|
||||||
|
el->el_flags |= NO_TTY;
|
||||||
|
(void) ch_init(el);
|
||||||
|
(void) search_init(el);
|
||||||
|
(void) hist_init(el);
|
||||||
|
(void) prompt_init(el);
|
||||||
|
(void) sig_init(el);
|
||||||
|
(void) read_init(el);
|
||||||
|
|
||||||
|
return (el);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_end():
|
||||||
|
* Clean up.
|
||||||
|
*/
|
||||||
|
public void
|
||||||
|
el_end(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (el == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
el_reset(el);
|
||||||
|
|
||||||
|
term_end(el);
|
||||||
|
key_end(el);
|
||||||
|
map_end(el);
|
||||||
|
tty_end(el);
|
||||||
|
ch_end(el);
|
||||||
|
search_end(el);
|
||||||
|
hist_end(el);
|
||||||
|
prompt_end(el);
|
||||||
|
sig_end(el);
|
||||||
|
|
||||||
|
el_free((ptr_t) el->el_prog);
|
||||||
|
el_free((ptr_t) el);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_reset():
|
||||||
|
* Reset the tty and the parser
|
||||||
|
*/
|
||||||
|
public void
|
||||||
|
el_reset(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
tty_cookedmode(el);
|
||||||
|
ch_reset(el, 0); /* XXX: Do we want that? */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_set():
|
||||||
|
* set the editline parameters
|
||||||
|
*/
|
||||||
|
public int
|
||||||
|
el_set(EditLine *el, int op, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int rv = 0;
|
||||||
|
|
||||||
|
if (el == NULL)
|
||||||
|
return (-1);
|
||||||
|
va_start(ap, op);
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case EL_PROMPT:
|
||||||
|
case EL_RPROMPT:
|
||||||
|
rv = prompt_set(el, va_arg(ap, el_pfunc_t), op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_TERMINAL:
|
||||||
|
rv = term_set(el, va_arg(ap, char *));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_EDITOR:
|
||||||
|
rv = map_set_editor(el, va_arg(ap, char *));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_SIGNAL:
|
||||||
|
if (va_arg(ap, int))
|
||||||
|
el->el_flags |= HANDLE_SIGNALS;
|
||||||
|
else
|
||||||
|
el->el_flags &= ~HANDLE_SIGNALS;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_BIND:
|
||||||
|
case EL_TELLTC:
|
||||||
|
case EL_SETTC:
|
||||||
|
case EL_GETTC:
|
||||||
|
case EL_ECHOTC:
|
||||||
|
case EL_SETTY:
|
||||||
|
{
|
||||||
|
const char *argv[20];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; i < 20; i++)
|
||||||
|
if ((argv[i] = va_arg(ap, char *)) == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case EL_BIND:
|
||||||
|
argv[0] = "bind";
|
||||||
|
rv = map_bind(el, i, argv);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_TELLTC:
|
||||||
|
argv[0] = "telltc";
|
||||||
|
rv = term_telltc(el, i, argv);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_SETTC:
|
||||||
|
argv[0] = "settc";
|
||||||
|
rv = term_settc(el, i, argv);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_ECHOTC:
|
||||||
|
argv[0] = "echotc";
|
||||||
|
rv = term_echotc(el, i, argv);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_SETTY:
|
||||||
|
argv[0] = "setty";
|
||||||
|
rv = tty_stty(el, i, argv);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
rv = -1;
|
||||||
|
EL_ABORT((el->el_errfile, "Bad op %d\n", op));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EL_ADDFN:
|
||||||
|
{
|
||||||
|
char *name = va_arg(ap, char *);
|
||||||
|
char *help = va_arg(ap, char *);
|
||||||
|
el_func_t func = va_arg(ap, el_func_t);
|
||||||
|
|
||||||
|
rv = map_addfunc(el, name, help, func);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EL_HIST:
|
||||||
|
{
|
||||||
|
hist_fun_t func = va_arg(ap, hist_fun_t);
|
||||||
|
ptr_t ptr = va_arg(ap, char *);
|
||||||
|
|
||||||
|
rv = hist_set(el, func, ptr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EL_EDITMODE:
|
||||||
|
if (va_arg(ap, int))
|
||||||
|
el->el_flags &= ~EDIT_DISABLED;
|
||||||
|
else
|
||||||
|
el->el_flags |= EDIT_DISABLED;
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_GETCFN:
|
||||||
|
{
|
||||||
|
el_rfunc_t rc = va_arg(ap, el_rfunc_t);
|
||||||
|
rv = el_read_setfn(el, rc);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EL_CLIENTDATA:
|
||||||
|
el->el_data = va_arg(ap, void *);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_UNBUFFERED:
|
||||||
|
rv = va_arg(ap, int);
|
||||||
|
if (rv && !(el->el_flags & UNBUFFERED)) {
|
||||||
|
el->el_flags |= UNBUFFERED;
|
||||||
|
read_prepare(el);
|
||||||
|
} else if (!rv && (el->el_flags & UNBUFFERED)) {
|
||||||
|
el->el_flags &= ~UNBUFFERED;
|
||||||
|
read_finish(el);
|
||||||
|
}
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_PREP_TERM:
|
||||||
|
rv = va_arg(ap, int);
|
||||||
|
if (rv)
|
||||||
|
(void) tty_rawmode(el);
|
||||||
|
else
|
||||||
|
(void) tty_cookedmode(el);
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_SETFP:
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
int what;
|
||||||
|
|
||||||
|
what = va_arg(ap, int);
|
||||||
|
fp = va_arg(ap, FILE *);
|
||||||
|
|
||||||
|
rv = 0;
|
||||||
|
switch (what) {
|
||||||
|
case 0:
|
||||||
|
el->el_infile = fp;
|
||||||
|
el->el_infd = fileno(fp);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
el->el_outfile = fp;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
el->el_errfile = fp;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rv = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
rv = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(ap);
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_get():
|
||||||
|
* retrieve the editline parameters
|
||||||
|
*/
|
||||||
|
public int
|
||||||
|
el_get(EditLine *el, int op, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
if (el == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
va_start(ap, op);
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case EL_PROMPT:
|
||||||
|
case EL_RPROMPT:
|
||||||
|
rv = prompt_get(el, va_arg(ap, el_pfunc_t *), op);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_EDITOR:
|
||||||
|
rv = map_get_editor(el, va_arg(ap, const char **));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_SIGNAL:
|
||||||
|
*va_arg(ap, int *) = (el->el_flags & HANDLE_SIGNALS);
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_EDITMODE:
|
||||||
|
*va_arg(ap, int *) = !(el->el_flags & EDIT_DISABLED);
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_TERMINAL:
|
||||||
|
term_get(el, va_arg(ap, const char **));
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_GETTC:
|
||||||
|
{
|
||||||
|
static char name[] = "gettc";
|
||||||
|
char *argv[20];
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; i < sizeof(argv) / sizeof(argv[0]); i++)
|
||||||
|
if ((argv[i] = va_arg(ap, char *)) == NULL)
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (op) {
|
||||||
|
case EL_GETTC:
|
||||||
|
argv[0] = name;
|
||||||
|
rv = term_gettc(el, i, argv);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
rv = -1;
|
||||||
|
EL_ABORT((el->el_errfile, "Bad op %d\n", op));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 /* XXX */
|
||||||
|
case EL_ADDFN:
|
||||||
|
{
|
||||||
|
char *name = va_arg(ap, char *);
|
||||||
|
char *help = va_arg(ap, char *);
|
||||||
|
el_func_t func = va_arg(ap, el_func_t);
|
||||||
|
|
||||||
|
rv = map_addfunc(el, name, help, func);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case EL_HIST:
|
||||||
|
{
|
||||||
|
hist_fun_t func = va_arg(ap, hist_fun_t);
|
||||||
|
ptr_t ptr = va_arg(ap, char *);
|
||||||
|
rv = hist_set(el, func, ptr);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif /* XXX */
|
||||||
|
|
||||||
|
case EL_GETCFN:
|
||||||
|
*va_arg(ap, el_rfunc_t *) = el_read_getfn(el);
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_CLIENTDATA:
|
||||||
|
*va_arg(ap, void **) = el->el_data;
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_UNBUFFERED:
|
||||||
|
*va_arg(ap, int *) = (!(el->el_flags & UNBUFFERED));
|
||||||
|
rv = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EL_GETFP:
|
||||||
|
{
|
||||||
|
int what;
|
||||||
|
FILE **fpp;
|
||||||
|
|
||||||
|
what = va_arg(ap, int);
|
||||||
|
fpp = va_arg(ap, FILE **);
|
||||||
|
rv = 0;
|
||||||
|
switch (what) {
|
||||||
|
case 0:
|
||||||
|
*fpp = el->el_infile;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
*fpp = el->el_outfile;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*fpp = el->el_errfile;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
rv = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
rv = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return (rv);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_line():
|
||||||
|
* Return editing info
|
||||||
|
*/
|
||||||
|
public const LineInfo *
|
||||||
|
el_line(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (const LineInfo *) (void *) &el->el_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_source():
|
||||||
|
* Source a file
|
||||||
|
*/
|
||||||
|
public int
|
||||||
|
el_source(EditLine *el, const char *fname)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
size_t len;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
fp = NULL;
|
||||||
|
if (fname == NULL) {
|
||||||
|
static const char elpath[] = "/.editrc";
|
||||||
|
#ifdef MAXPATHLEN
|
||||||
|
char path[MAXPATHLEN];
|
||||||
|
#else
|
||||||
|
char path[4096];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_ISSETUGID
|
||||||
|
if (issetugid())
|
||||||
|
return (-1);
|
||||||
|
#endif
|
||||||
|
if ((ptr = getenv("HOME")) == NULL)
|
||||||
|
return (-1);
|
||||||
|
if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
|
||||||
|
return (-1);
|
||||||
|
if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
|
||||||
|
return (-1);
|
||||||
|
fname = path;
|
||||||
|
}
|
||||||
|
if (fp == NULL)
|
||||||
|
fp = fopen(fname, "r");
|
||||||
|
if (fp == NULL)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
while ((ptr = fgetln(fp, &len)) != NULL) {
|
||||||
|
if (len > 0 && ptr[len - 1] == '\n')
|
||||||
|
--len;
|
||||||
|
ptr[len] = '\0';
|
||||||
|
if (parse_line(el, ptr) == -1) {
|
||||||
|
(void) fclose(fp);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
(void) fclose(fp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_resize():
|
||||||
|
* Called from program when terminal is resized
|
||||||
|
*/
|
||||||
|
public void
|
||||||
|
el_resize(EditLine *el)
|
||||||
|
{
|
||||||
|
int lins, cols;
|
||||||
|
sigset_t oset, nset;
|
||||||
|
|
||||||
|
(void) sigemptyset(&nset);
|
||||||
|
(void) sigaddset(&nset, SIGWINCH);
|
||||||
|
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||||
|
|
||||||
|
/* get the correct window size */
|
||||||
|
if (term_get_size(el, &lins, &cols))
|
||||||
|
term_change_size(el, lins, cols);
|
||||||
|
|
||||||
|
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_beep():
|
||||||
|
* Called from the program to beep
|
||||||
|
*/
|
||||||
|
public void
|
||||||
|
el_beep(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
term_beep(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_editmode()
|
||||||
|
* Set the state of EDIT_DISABLED from the `edit' command.
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
/*ARGSUSED*/
|
||||||
|
el_editmode(EditLine *el, int argc, const char **argv)
|
||||||
|
{
|
||||||
|
const char *how;
|
||||||
|
|
||||||
|
if (argv == NULL || argc != 2 || argv[1] == NULL)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
how = argv[1];
|
||||||
|
if (strcmp(how, "on") == 0) {
|
||||||
|
el->el_flags &= ~EDIT_DISABLED;
|
||||||
|
tty_rawmode(el);
|
||||||
|
} else if (strcmp(how, "off") == 0) {
|
||||||
|
tty_cookedmode(el);
|
||||||
|
el->el_flags |= EDIT_DISABLED;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
(void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
|
@ -0,0 +1,150 @@
|
||||||
|
/* $NetBSD: el.h,v 1.17 2006/12/15 22:13:33 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)el.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.h: Internal structures.
|
||||||
|
*/
|
||||||
|
#ifndef _h_el
|
||||||
|
#define _h_el
|
||||||
|
/*
|
||||||
|
* Local defaults
|
||||||
|
*/
|
||||||
|
#define KSHVI
|
||||||
|
#define VIDEFAULT
|
||||||
|
#define ANCHOR
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#define EL_BUFSIZ 1024 /* Maximum line size */
|
||||||
|
|
||||||
|
#define HANDLE_SIGNALS 0x01
|
||||||
|
#define NO_TTY 0x02
|
||||||
|
#define EDIT_DISABLED 0x04
|
||||||
|
#define UNBUFFERED 0x08
|
||||||
|
|
||||||
|
typedef int bool_t; /* True or not */
|
||||||
|
|
||||||
|
typedef unsigned char el_action_t; /* Index to command array */
|
||||||
|
|
||||||
|
typedef struct coord_t { /* Position on the screen */
|
||||||
|
int h;
|
||||||
|
int v;
|
||||||
|
} coord_t;
|
||||||
|
|
||||||
|
typedef struct el_line_t {
|
||||||
|
char *buffer; /* Input line */
|
||||||
|
char *cursor; /* Cursor position */
|
||||||
|
char *lastchar; /* Last character */
|
||||||
|
const char *limit; /* Max position */
|
||||||
|
} el_line_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Editor state
|
||||||
|
*/
|
||||||
|
typedef struct el_state_t {
|
||||||
|
int inputmode; /* What mode are we in? */
|
||||||
|
int doingarg; /* Are we getting an argument? */
|
||||||
|
int argument; /* Numeric argument */
|
||||||
|
int metanext; /* Is the next char a meta char */
|
||||||
|
el_action_t lastcmd; /* Previous command */
|
||||||
|
el_action_t thiscmd; /* this command */
|
||||||
|
char thisch; /* char that generated it */
|
||||||
|
} el_state_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Until we come up with something better...
|
||||||
|
*/
|
||||||
|
#define el_strdup(a) strdup(a)
|
||||||
|
#define el_malloc(a) malloc(a)
|
||||||
|
#define el_realloc(a,b) realloc(a, b)
|
||||||
|
#define el_free(a) free(a)
|
||||||
|
|
||||||
|
#include "tty.h"
|
||||||
|
#include "prompt.h"
|
||||||
|
#include "key.h"
|
||||||
|
#include "el_term.h"
|
||||||
|
#include "refresh.h"
|
||||||
|
#include "chared.h"
|
||||||
|
#include "common.h"
|
||||||
|
#include "search.h"
|
||||||
|
#include "hist.h"
|
||||||
|
#include "map.h"
|
||||||
|
#include "parse.h"
|
||||||
|
#include "sig.h"
|
||||||
|
#include "help.h"
|
||||||
|
#include "read.h"
|
||||||
|
|
||||||
|
struct editline {
|
||||||
|
char *el_prog; /* the program name */
|
||||||
|
FILE *el_infile; /* Stdio stuff */
|
||||||
|
FILE *el_outfile; /* Stdio stuff */
|
||||||
|
FILE *el_errfile; /* Stdio stuff */
|
||||||
|
int el_infd; /* Input file descriptor */
|
||||||
|
int el_flags; /* Various flags. */
|
||||||
|
coord_t el_cursor; /* Cursor location */
|
||||||
|
char **el_display; /* Real screen image = what is there */
|
||||||
|
char **el_vdisplay; /* Virtual screen image = what we see */
|
||||||
|
void *el_data; /* Client data */
|
||||||
|
el_line_t el_line; /* The current line information */
|
||||||
|
el_state_t el_state; /* Current editor state */
|
||||||
|
el_term_t el_term; /* Terminal dependent stuff */
|
||||||
|
el_tty_t el_tty; /* Tty dependent stuff */
|
||||||
|
el_refresh_t el_refresh; /* Refresh stuff */
|
||||||
|
el_prompt_t el_prompt; /* Prompt stuff */
|
||||||
|
el_prompt_t el_rprompt; /* Prompt stuff */
|
||||||
|
el_chared_t el_chared; /* Characted editor stuff */
|
||||||
|
el_map_t el_map; /* Key mapping stuff */
|
||||||
|
el_key_t el_key; /* Key binding stuff */
|
||||||
|
el_history_t el_history; /* History stuff */
|
||||||
|
el_search_t el_search; /* Search stuff */
|
||||||
|
el_signal_t el_signal; /* Signal handling stuff */
|
||||||
|
el_read_t el_read; /* Character reading stuff */
|
||||||
|
};
|
||||||
|
|
||||||
|
protected int el_editmode(EditLine *, int, const char **);
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
#define EL_ABORT(a) do { \
|
||||||
|
fprintf(el->el_errfile, "%s, %d: ", \
|
||||||
|
__FILE__, __LINE__); \
|
||||||
|
fprintf a; \
|
||||||
|
abort(); \
|
||||||
|
} while( /*CONSTCOND*/0);
|
||||||
|
#else
|
||||||
|
#define EL_ABORT(a) abort()
|
||||||
|
#endif
|
||||||
|
#endif /* _h_el */
|
|
@ -0,0 +1,134 @@
|
||||||
|
/* $NetBSD: term.h,v 1.18 2006/11/24 00:01:17 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)term.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.term.h: Termcap header
|
||||||
|
*/
|
||||||
|
#ifndef _h_el_term
|
||||||
|
#define _h_el_term
|
||||||
|
|
||||||
|
#include "histedit.h"
|
||||||
|
|
||||||
|
typedef struct { /* Symbolic function key bindings */
|
||||||
|
const char *name; /* name of the key */
|
||||||
|
int key; /* Index in termcap table */
|
||||||
|
key_value_t fun; /* Function bound to it */
|
||||||
|
int type; /* Type of function */
|
||||||
|
} fkey_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *t_name; /* the terminal name */
|
||||||
|
coord_t t_size; /* # lines and cols */
|
||||||
|
int t_flags;
|
||||||
|
#define TERM_CAN_INSERT 0x001 /* Has insert cap */
|
||||||
|
#define TERM_CAN_DELETE 0x002 /* Has delete cap */
|
||||||
|
#define TERM_CAN_CEOL 0x004 /* Has CEOL cap */
|
||||||
|
#define TERM_CAN_TAB 0x008 /* Can use tabs */
|
||||||
|
#define TERM_CAN_ME 0x010 /* Can turn all attrs. */
|
||||||
|
#define TERM_CAN_UP 0x020 /* Can move up */
|
||||||
|
#define TERM_HAS_META 0x040 /* Has a meta key */
|
||||||
|
#define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */
|
||||||
|
#define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */
|
||||||
|
char *t_buf; /* Termcap buffer */
|
||||||
|
int t_loc; /* location used */
|
||||||
|
char **t_str; /* termcap strings */
|
||||||
|
int *t_val; /* termcap values */
|
||||||
|
char *t_cap; /* Termcap buffer */
|
||||||
|
fkey_t *t_fkey; /* Array of keys */
|
||||||
|
} el_term_t;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* fKey indexes
|
||||||
|
*/
|
||||||
|
#define A_K_DN 0
|
||||||
|
#define A_K_UP 1
|
||||||
|
#define A_K_LT 2
|
||||||
|
#define A_K_RT 3
|
||||||
|
#define A_K_HO 4
|
||||||
|
#define A_K_EN 5
|
||||||
|
#define A_K_NKEYS 6
|
||||||
|
|
||||||
|
#ifdef _SUNOS
|
||||||
|
extern int tgetent(char *, const char *);
|
||||||
|
extern int tgetflag(char *);
|
||||||
|
extern int tgetnum(char *);
|
||||||
|
extern int tputs(const char *, int, int (*)(int));
|
||||||
|
extern char* tgoto(const char*, int, int);
|
||||||
|
extern char* tgetstr(char*, char**);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected void term_move_to_line(EditLine *, int);
|
||||||
|
protected void term_move_to_char(EditLine *, int);
|
||||||
|
protected void term_clear_EOL(EditLine *, int);
|
||||||
|
protected void term_overwrite(EditLine *, const char *, int);
|
||||||
|
protected void term_insertwrite(EditLine *, char *, int);
|
||||||
|
protected void term_deletechars(EditLine *, int);
|
||||||
|
protected void term_clear_screen(EditLine *);
|
||||||
|
protected void term_beep(EditLine *);
|
||||||
|
protected int term_change_size(EditLine *, int, int);
|
||||||
|
protected int term_get_size(EditLine *, int *, int *);
|
||||||
|
protected int term_init(EditLine *);
|
||||||
|
protected void term_bind_arrow(EditLine *);
|
||||||
|
protected void term_print_arrow(EditLine *, const char *);
|
||||||
|
protected int term_clear_arrow(EditLine *, const char *);
|
||||||
|
protected int term_set_arrow(EditLine *, const char *, key_value_t *, int);
|
||||||
|
protected void term_end(EditLine *);
|
||||||
|
protected void term_get(EditLine *, const char **);
|
||||||
|
protected int term_set(EditLine *, const char *);
|
||||||
|
protected int term_settc(EditLine *, int, const char **);
|
||||||
|
protected int term_gettc(EditLine *, int, char **);
|
||||||
|
protected int term_telltc(EditLine *, int, const char **);
|
||||||
|
protected int term_echotc(EditLine *, int, const char **);
|
||||||
|
protected void term_writec(EditLine *, int);
|
||||||
|
protected int term__putc(int);
|
||||||
|
protected void term__flush(void);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Easy access macros
|
||||||
|
*/
|
||||||
|
#define EL_FLAGS (el)->el_term.t_flags
|
||||||
|
|
||||||
|
#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT)
|
||||||
|
#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE)
|
||||||
|
#define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL)
|
||||||
|
#define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB)
|
||||||
|
#define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME)
|
||||||
|
#define EL_CAN_UP (EL_FLAGS & TERM_CAN_UP)
|
||||||
|
#define EL_HAS_META (EL_FLAGS & TERM_HAS_META)
|
||||||
|
#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS)
|
||||||
|
#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS)
|
||||||
|
|
||||||
|
#endif /* _h_el_term */
|
|
@ -0,0 +1,507 @@
|
||||||
|
/* $NetBSD: emacs.c,v 1.21 2006/03/06 21:11:56 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: emacs.c,v 1.21 2006/03/06 21:11:56 christos Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* emacs.c: Emacs functions
|
||||||
|
*/
|
||||||
|
#include "el.h"
|
||||||
|
|
||||||
|
/* em_delete_or_list():
|
||||||
|
* Delete character under cursor or list completions if at end of line
|
||||||
|
* [^D]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_delete_or_list(EditLine *el, int c)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (el->el_line.cursor == el->el_line.lastchar) {
|
||||||
|
/* if I'm at the end */
|
||||||
|
if (el->el_line.cursor == el->el_line.buffer) {
|
||||||
|
/* and the beginning */
|
||||||
|
term_writec(el, c); /* then do an EOF */
|
||||||
|
return (CC_EOF);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Here we could list completions, but it is an
|
||||||
|
* error right now
|
||||||
|
*/
|
||||||
|
term_beep(el);
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (el->el_state.doingarg)
|
||||||
|
c_delafter(el, el->el_state.argument);
|
||||||
|
else
|
||||||
|
c_delafter1(el);
|
||||||
|
if (el->el_line.cursor > el->el_line.lastchar)
|
||||||
|
el->el_line.cursor = el->el_line.lastchar;
|
||||||
|
/* bounds check */
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_delete_next_word():
|
||||||
|
* Cut from cursor to end of current word
|
||||||
|
* [M-d]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *cp, *p, *kp;
|
||||||
|
|
||||||
|
if (el->el_line.cursor == el->el_line.lastchar)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
|
||||||
|
el->el_state.argument, ce__isword);
|
||||||
|
|
||||||
|
for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++)
|
||||||
|
/* save the text */
|
||||||
|
*kp++ = *p;
|
||||||
|
el->el_chared.c_kill.last = kp;
|
||||||
|
|
||||||
|
c_delafter(el, cp - el->el_line.cursor); /* delete after dot */
|
||||||
|
if (el->el_line.cursor > el->el_line.lastchar)
|
||||||
|
el->el_line.cursor = el->el_line.lastchar;
|
||||||
|
/* bounds check */
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_yank():
|
||||||
|
* Paste cut buffer at cursor position
|
||||||
|
* [^Y]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_yank(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *kp, *cp;
|
||||||
|
|
||||||
|
if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
|
||||||
|
return (CC_NORM);
|
||||||
|
|
||||||
|
if (el->el_line.lastchar +
|
||||||
|
(el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
|
||||||
|
el->el_line.limit)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
el->el_chared.c_kill.mark = el->el_line.cursor;
|
||||||
|
cp = el->el_line.cursor;
|
||||||
|
|
||||||
|
/* open the space, */
|
||||||
|
c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
|
||||||
|
/* copy the chars */
|
||||||
|
for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
|
||||||
|
*cp++ = *kp;
|
||||||
|
|
||||||
|
/* if an arg, cursor at beginning else cursor at end */
|
||||||
|
if (el->el_state.argument == 1)
|
||||||
|
el->el_line.cursor = cp;
|
||||||
|
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_kill_line():
|
||||||
|
* Cut the entire line and save in cut buffer
|
||||||
|
* [^U]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_kill_line(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *kp, *cp;
|
||||||
|
|
||||||
|
cp = el->el_line.buffer;
|
||||||
|
kp = el->el_chared.c_kill.buf;
|
||||||
|
while (cp < el->el_line.lastchar)
|
||||||
|
*kp++ = *cp++; /* copy it */
|
||||||
|
el->el_chared.c_kill.last = kp;
|
||||||
|
/* zap! -- delete all of it */
|
||||||
|
el->el_line.lastchar = el->el_line.buffer;
|
||||||
|
el->el_line.cursor = el->el_line.buffer;
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_kill_region():
|
||||||
|
* Cut area between mark and cursor and save in cut buffer
|
||||||
|
* [^W]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_kill_region(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *kp, *cp;
|
||||||
|
|
||||||
|
if (!el->el_chared.c_kill.mark)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
if (el->el_chared.c_kill.mark > el->el_line.cursor) {
|
||||||
|
cp = el->el_line.cursor;
|
||||||
|
kp = el->el_chared.c_kill.buf;
|
||||||
|
while (cp < el->el_chared.c_kill.mark)
|
||||||
|
*kp++ = *cp++; /* copy it */
|
||||||
|
el->el_chared.c_kill.last = kp;
|
||||||
|
c_delafter(el, cp - el->el_line.cursor);
|
||||||
|
} else { /* mark is before cursor */
|
||||||
|
cp = el->el_chared.c_kill.mark;
|
||||||
|
kp = el->el_chared.c_kill.buf;
|
||||||
|
while (cp < el->el_line.cursor)
|
||||||
|
*kp++ = *cp++; /* copy it */
|
||||||
|
el->el_chared.c_kill.last = kp;
|
||||||
|
c_delbefore(el, cp - el->el_chared.c_kill.mark);
|
||||||
|
el->el_line.cursor = el->el_chared.c_kill.mark;
|
||||||
|
}
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_copy_region():
|
||||||
|
* Copy area between mark and cursor to cut buffer
|
||||||
|
* [M-W]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_copy_region(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *kp, *cp;
|
||||||
|
|
||||||
|
if (!el->el_chared.c_kill.mark)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
if (el->el_chared.c_kill.mark > el->el_line.cursor) {
|
||||||
|
cp = el->el_line.cursor;
|
||||||
|
kp = el->el_chared.c_kill.buf;
|
||||||
|
while (cp < el->el_chared.c_kill.mark)
|
||||||
|
*kp++ = *cp++; /* copy it */
|
||||||
|
el->el_chared.c_kill.last = kp;
|
||||||
|
} else {
|
||||||
|
cp = el->el_chared.c_kill.mark;
|
||||||
|
kp = el->el_chared.c_kill.buf;
|
||||||
|
while (cp < el->el_line.cursor)
|
||||||
|
*kp++ = *cp++; /* copy it */
|
||||||
|
el->el_chared.c_kill.last = kp;
|
||||||
|
}
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_gosmacs_transpose():
|
||||||
|
* Exchange the two characters before the cursor
|
||||||
|
* Gosling emacs transpose chars [^T]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
em_gosmacs_transpose(EditLine *el, int c)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (el->el_line.cursor > &el->el_line.buffer[1]) {
|
||||||
|
/* must have at least two chars entered */
|
||||||
|
c = el->el_line.cursor[-2];
|
||||||
|
el->el_line.cursor[-2] = el->el_line.cursor[-1];
|
||||||
|
el->el_line.cursor[-1] = c;
|
||||||
|
return (CC_REFRESH);
|
||||||
|
} else
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_next_word():
|
||||||
|
* Move next to end of current word
|
||||||
|
* [M-f]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_next_word(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
if (el->el_line.cursor == el->el_line.lastchar)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
el->el_line.cursor = c__next_word(el->el_line.cursor,
|
||||||
|
el->el_line.lastchar,
|
||||||
|
el->el_state.argument,
|
||||||
|
ce__isword);
|
||||||
|
|
||||||
|
if (el->el_map.type == MAP_VI)
|
||||||
|
if (el->el_chared.c_vcmd.action != NOP) {
|
||||||
|
cv_delfini(el);
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
return (CC_CURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_upper_case():
|
||||||
|
* Uppercase the characters from cursor to end of current word
|
||||||
|
* [M-u]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_upper_case(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *cp, *ep;
|
||||||
|
|
||||||
|
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
|
||||||
|
el->el_state.argument, ce__isword);
|
||||||
|
|
||||||
|
for (cp = el->el_line.cursor; cp < ep; cp++)
|
||||||
|
if (islower((unsigned char)*cp))
|
||||||
|
*cp = toupper((unsigned char)*cp);
|
||||||
|
|
||||||
|
el->el_line.cursor = ep;
|
||||||
|
if (el->el_line.cursor > el->el_line.lastchar)
|
||||||
|
el->el_line.cursor = el->el_line.lastchar;
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_capitol_case():
|
||||||
|
* Capitalize the characters from cursor to end of current word
|
||||||
|
* [M-c]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_capitol_case(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *cp, *ep;
|
||||||
|
|
||||||
|
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
|
||||||
|
el->el_state.argument, ce__isword);
|
||||||
|
|
||||||
|
for (cp = el->el_line.cursor; cp < ep; cp++) {
|
||||||
|
if (isalpha((unsigned char)*cp)) {
|
||||||
|
if (islower((unsigned char)*cp))
|
||||||
|
*cp = toupper((unsigned char)*cp);
|
||||||
|
cp++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (; cp < ep; cp++)
|
||||||
|
if (isupper((unsigned char)*cp))
|
||||||
|
*cp = tolower((unsigned char)*cp);
|
||||||
|
|
||||||
|
el->el_line.cursor = ep;
|
||||||
|
if (el->el_line.cursor > el->el_line.lastchar)
|
||||||
|
el->el_line.cursor = el->el_line.lastchar;
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_lower_case():
|
||||||
|
* Lowercase the characters from cursor to end of current word
|
||||||
|
* [M-l]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_lower_case(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *cp, *ep;
|
||||||
|
|
||||||
|
ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
|
||||||
|
el->el_state.argument, ce__isword);
|
||||||
|
|
||||||
|
for (cp = el->el_line.cursor; cp < ep; cp++)
|
||||||
|
if (isupper((unsigned char)*cp))
|
||||||
|
*cp = tolower((unsigned char)*cp);
|
||||||
|
|
||||||
|
el->el_line.cursor = ep;
|
||||||
|
if (el->el_line.cursor > el->el_line.lastchar)
|
||||||
|
el->el_line.cursor = el->el_line.lastchar;
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_set_mark():
|
||||||
|
* Set the mark at cursor
|
||||||
|
* [^@]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_set_mark(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_chared.c_kill.mark = el->el_line.cursor;
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_exchange_mark():
|
||||||
|
* Exchange the cursor and mark
|
||||||
|
* [^X^X]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_exchange_mark(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
cp = el->el_line.cursor;
|
||||||
|
el->el_line.cursor = el->el_chared.c_kill.mark;
|
||||||
|
el->el_chared.c_kill.mark = cp;
|
||||||
|
return (CC_CURSOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_universal_argument():
|
||||||
|
* Universal argument (argument times 4)
|
||||||
|
* [^U]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_universal_argument(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{ /* multiply current argument by 4 */
|
||||||
|
|
||||||
|
if (el->el_state.argument > 1000000)
|
||||||
|
return (CC_ERROR);
|
||||||
|
el->el_state.doingarg = 1;
|
||||||
|
el->el_state.argument *= 4;
|
||||||
|
return (CC_ARGHACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_meta_next():
|
||||||
|
* Add 8th bit to next character typed
|
||||||
|
* [<ESC>]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_meta_next(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_state.metanext = 1;
|
||||||
|
return (CC_ARGHACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_toggle_overwrite():
|
||||||
|
* Switch from insert to overwrite mode or vice versa
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
|
||||||
|
MODE_REPLACE : MODE_INSERT;
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_copy_prev_word():
|
||||||
|
* Copy current word to cursor
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_copy_prev_word(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
char *cp, *oldc, *dp;
|
||||||
|
|
||||||
|
if (el->el_line.cursor == el->el_line.buffer)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
oldc = el->el_line.cursor;
|
||||||
|
/* does a bounds check */
|
||||||
|
cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
|
||||||
|
el->el_state.argument, ce__isword);
|
||||||
|
|
||||||
|
c_insert(el, oldc - cp);
|
||||||
|
for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
|
||||||
|
*dp++ = *cp;
|
||||||
|
|
||||||
|
el->el_line.cursor = dp;/* put cursor at end */
|
||||||
|
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_inc_search_next():
|
||||||
|
* Emacs incremental next search
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_inc_search_next(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_search.patlen = 0;
|
||||||
|
return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_inc_search_prev():
|
||||||
|
* Emacs incremental reverse search
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_inc_search_prev(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_search.patlen = 0;
|
||||||
|
return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* em_delete_prev_char():
|
||||||
|
* Delete the character to the left of the cursor
|
||||||
|
* [^?]
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
/*ARGSUSED*/
|
||||||
|
em_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
|
||||||
|
if (el->el_line.cursor <= el->el_line.buffer)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
if (el->el_state.doingarg)
|
||||||
|
c_delbefore(el, el->el_state.argument);
|
||||||
|
else
|
||||||
|
c_delbefore1(el);
|
||||||
|
el->el_line.cursor -= el->el_state.argument;
|
||||||
|
if (el->el_line.cursor < el->el_line.buffer)
|
||||||
|
el->el_line.cursor = el->el_line.buffer;
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
|
@ -0,0 +1,110 @@
|
||||||
|
/* $NetBSD: fgetln.c,v 1.8 2006/10/18 15:17:38 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1998 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Christos Zoulas.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_NBTOOL_CONFIG_H
|
||||||
|
#include "nbtool_config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_FGETLN
|
||||||
|
#include <config.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#ifndef HAVE_NBTOOL_CONFIG_H
|
||||||
|
/* These headers are required, but included from nbtool_config.h */
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *
|
||||||
|
fgetln(FILE *fp, size_t *len)
|
||||||
|
{
|
||||||
|
static char *buf = NULL;
|
||||||
|
static size_t bufsiz = 0;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
|
||||||
|
if (buf == NULL) {
|
||||||
|
bufsiz = BUFSIZ;
|
||||||
|
if ((buf = malloc(bufsiz)) == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fgets(buf, bufsiz, fp) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
*len = 0;
|
||||||
|
while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
|
||||||
|
size_t nbufsiz = bufsiz + BUFSIZ;
|
||||||
|
char *nbuf = realloc(buf, nbufsiz);
|
||||||
|
|
||||||
|
if (nbuf == NULL) {
|
||||||
|
int oerrno = errno;
|
||||||
|
free(buf);
|
||||||
|
errno = oerrno;
|
||||||
|
buf = NULL;
|
||||||
|
return NULL;
|
||||||
|
} else
|
||||||
|
buf = nbuf;
|
||||||
|
|
||||||
|
if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) {
|
||||||
|
buf[bufsiz] = '\0';
|
||||||
|
*len = strlen(buf);
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
*len = bufsiz;
|
||||||
|
bufsiz = nbufsiz;
|
||||||
|
}
|
||||||
|
|
||||||
|
*len = (ptr - buf) + 1;
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef TEST
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
char *p;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
while ((p = fgetln(stdin, &len)) != NULL) {
|
||||||
|
(void)printf("%zu %s", len, p);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,561 @@
|
||||||
|
/* $NetBSD: filecomplete.c,v 1.10 2006/11/09 16:58:38 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jaromir Dolecek.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* AIX requires this to be the first thing in the file. */
|
||||||
|
#if defined (_AIX) && !defined (__GNUC__)
|
||||||
|
#pragma alloca
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# undef alloca
|
||||||
|
# define alloca(n) __builtin_alloca (n)
|
||||||
|
#else
|
||||||
|
# ifdef HAVE_ALLOCA_H
|
||||||
|
# include <alloca.h>
|
||||||
|
# else
|
||||||
|
# ifndef _AIX
|
||||||
|
extern char *alloca ();
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
__RCSID("$NetBSD: filecomplete.c,v 1.10 2006/11/09 16:58:38 christos Exp $");
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <vis.h>
|
||||||
|
|
||||||
|
#include "el.h"
|
||||||
|
#include "fcns.h" /* for EL_NUM_FCNS */
|
||||||
|
#include "histedit.h"
|
||||||
|
#include "filecomplete.h"
|
||||||
|
|
||||||
|
static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
|
||||||
|
'>', '<', '=', ';', '|', '&', '{', '(', '\0' };
|
||||||
|
|
||||||
|
|
||||||
|
/********************************/
|
||||||
|
/* completion functions */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* does tilde expansion of strings of type ``~user/foo''
|
||||||
|
* if ``user'' isn't valid user name or ``txt'' doesn't start
|
||||||
|
* w/ '~', returns pointer to strdup()ed copy of ``txt''
|
||||||
|
*
|
||||||
|
* it's callers's responsibility to free() returned string
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
fn_tilde_expand(const char *txt)
|
||||||
|
{
|
||||||
|
struct passwd pwres, *pass;
|
||||||
|
char *temp;
|
||||||
|
size_t len = 0;
|
||||||
|
char pwbuf[1024];
|
||||||
|
|
||||||
|
if (txt[0] != '~')
|
||||||
|
return (strdup(txt));
|
||||||
|
|
||||||
|
temp = strchr(txt + 1, '/');
|
||||||
|
if (temp == NULL) {
|
||||||
|
temp = strdup(txt + 1);
|
||||||
|
if (temp == NULL)
|
||||||
|
return NULL;
|
||||||
|
} else {
|
||||||
|
len = temp - txt + 1; /* text until string after slash */
|
||||||
|
temp = malloc(len);
|
||||||
|
if (temp == NULL)
|
||||||
|
return NULL;
|
||||||
|
(void)strncpy(temp, txt + 1, len - 2);
|
||||||
|
temp[len - 2] = '\0';
|
||||||
|
}
|
||||||
|
if (temp[0] == 0) {
|
||||||
|
#ifdef HAVE_GETPW_R_POSIX
|
||||||
|
if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
|
||||||
|
pass = NULL;
|
||||||
|
#elif HAVE_GETPW_R_DRAFT
|
||||||
|
pass = getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf));
|
||||||
|
#else
|
||||||
|
pass = getpwuid(getuid());
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#ifdef HAVE_GETPW_R_POSIX
|
||||||
|
if (getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
|
||||||
|
pass = NULL;
|
||||||
|
#elif HAVE_GETPW_R_DRAFT
|
||||||
|
pass = getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf));
|
||||||
|
#else
|
||||||
|
pass = getpwnam(temp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
free(temp); /* value no more needed */
|
||||||
|
if (pass == NULL)
|
||||||
|
return (strdup(txt));
|
||||||
|
|
||||||
|
/* update pointer txt to point at string immedially following */
|
||||||
|
/* first slash */
|
||||||
|
txt += len;
|
||||||
|
|
||||||
|
temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1);
|
||||||
|
if (temp == NULL)
|
||||||
|
return NULL;
|
||||||
|
(void)sprintf(temp, "%s/%s", pass->pw_dir, txt);
|
||||||
|
|
||||||
|
return (temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* return first found file name starting by the ``text'' or NULL if no
|
||||||
|
* such file can be found
|
||||||
|
* value of ``state'' is ignored
|
||||||
|
*
|
||||||
|
* it's caller's responsibility to free returned string
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
fn_filename_completion_function(const char *text, int state)
|
||||||
|
{
|
||||||
|
static DIR *dir = NULL;
|
||||||
|
static char *filename = NULL, *dirname = NULL, *dirpath = NULL;
|
||||||
|
static size_t filename_len = 0;
|
||||||
|
struct dirent *entry;
|
||||||
|
char *temp;
|
||||||
|
size_t len;
|
||||||
|
|
||||||
|
if (state == 0 || dir == NULL) {
|
||||||
|
temp = strrchr(text, '/');
|
||||||
|
if (temp) {
|
||||||
|
char *nptr;
|
||||||
|
temp++;
|
||||||
|
nptr = realloc(filename, strlen(temp) + 1);
|
||||||
|
if (nptr == NULL) {
|
||||||
|
free(filename);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
filename = nptr;
|
||||||
|
(void)strcpy(filename, temp);
|
||||||
|
len = temp - text; /* including last slash */
|
||||||
|
nptr = realloc(dirname, len + 1);
|
||||||
|
if (nptr == NULL) {
|
||||||
|
free(filename);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dirname = nptr;
|
||||||
|
(void)strncpy(dirname, text, len);
|
||||||
|
dirname[len] = '\0';
|
||||||
|
} else {
|
||||||
|
if (*text == 0)
|
||||||
|
filename = NULL;
|
||||||
|
else {
|
||||||
|
filename = strdup(text);
|
||||||
|
if (filename == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
dirname = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dir != NULL) {
|
||||||
|
(void)closedir(dir);
|
||||||
|
dir = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* support for ``~user'' syntax */
|
||||||
|
free(dirpath);
|
||||||
|
|
||||||
|
if (dirname == NULL && (dirname = strdup("./")) == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (*dirname == '~')
|
||||||
|
dirpath = fn_tilde_expand(dirname);
|
||||||
|
else
|
||||||
|
dirpath = strdup(dirname);
|
||||||
|
|
||||||
|
if (dirpath == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
dir = opendir(dirpath);
|
||||||
|
if (!dir)
|
||||||
|
return (NULL); /* cannot open the directory */
|
||||||
|
|
||||||
|
/* will be used in cycle */
|
||||||
|
filename_len = filename ? strlen(filename) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* find the match */
|
||||||
|
while ((entry = readdir(dir)) != NULL) {
|
||||||
|
/* skip . and .. */
|
||||||
|
if (entry->d_name[0] == '.' && (!entry->d_name[1]
|
||||||
|
|| (entry->d_name[1] == '.' && !entry->d_name[2])))
|
||||||
|
continue;
|
||||||
|
if (filename_len == 0)
|
||||||
|
break;
|
||||||
|
/* otherwise, get first entry where first */
|
||||||
|
/* filename_len characters are equal */
|
||||||
|
if (entry->d_name[0] == filename[0]
|
||||||
|
/* Some dirents have d_namlen, but it is not portable. */
|
||||||
|
&& strlen(entry->d_name) >= filename_len
|
||||||
|
&& strncmp(entry->d_name, filename,
|
||||||
|
filename_len) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (entry) { /* match found */
|
||||||
|
|
||||||
|
/* Some dirents have d_namlen, but it is not portable. */
|
||||||
|
len = strlen(entry->d_name);
|
||||||
|
temp = malloc(strlen(dirname) + len + 1);
|
||||||
|
if (temp == NULL)
|
||||||
|
return NULL;
|
||||||
|
(void)sprintf(temp, "%s%s", dirname, entry->d_name);
|
||||||
|
} else {
|
||||||
|
(void)closedir(dir);
|
||||||
|
dir = NULL;
|
||||||
|
temp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (temp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
append_char_function(const char *name)
|
||||||
|
{
|
||||||
|
struct stat stbuf;
|
||||||
|
char *expname = *name == '~' ? fn_tilde_expand(name) : NULL;
|
||||||
|
const char *rs = "";
|
||||||
|
|
||||||
|
if (stat(expname ? expname : name, &stbuf) == -1)
|
||||||
|
goto out;
|
||||||
|
if (S_ISDIR(stbuf.st_mode))
|
||||||
|
rs = "/";
|
||||||
|
out:
|
||||||
|
if (expname)
|
||||||
|
free(expname);
|
||||||
|
return rs;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* returns list of completions for text given
|
||||||
|
* non-static for readline.
|
||||||
|
*/
|
||||||
|
char ** completion_matches(const char *, char *(*)(const char *, int));
|
||||||
|
char **
|
||||||
|
completion_matches(const char *text, char *(*genfunc)(const char *, int))
|
||||||
|
{
|
||||||
|
char **match_list = NULL, *retstr, *prevstr;
|
||||||
|
size_t match_list_len, max_equal, which, i;
|
||||||
|
size_t matches;
|
||||||
|
|
||||||
|
matches = 0;
|
||||||
|
match_list_len = 1;
|
||||||
|
while ((retstr = (*genfunc) (text, (int)matches)) != NULL) {
|
||||||
|
/* allow for list terminator here */
|
||||||
|
if (matches + 3 >= match_list_len) {
|
||||||
|
char **nmatch_list;
|
||||||
|
while (matches + 3 >= match_list_len)
|
||||||
|
match_list_len <<= 1;
|
||||||
|
nmatch_list = realloc(match_list,
|
||||||
|
match_list_len * sizeof(char *));
|
||||||
|
if (nmatch_list == NULL) {
|
||||||
|
free(match_list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
match_list = nmatch_list;
|
||||||
|
|
||||||
|
}
|
||||||
|
match_list[++matches] = retstr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!match_list)
|
||||||
|
return NULL; /* nothing found */
|
||||||
|
|
||||||
|
/* find least denominator and insert it to match_list[0] */
|
||||||
|
which = 2;
|
||||||
|
prevstr = match_list[1];
|
||||||
|
max_equal = strlen(prevstr);
|
||||||
|
for (; which <= matches; which++) {
|
||||||
|
for (i = 0; i < max_equal &&
|
||||||
|
prevstr[i] == match_list[which][i]; i++)
|
||||||
|
continue;
|
||||||
|
max_equal = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
retstr = malloc(max_equal + 1);
|
||||||
|
if (retstr == NULL) {
|
||||||
|
free(match_list);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
(void)strncpy(retstr, match_list[1], max_equal);
|
||||||
|
retstr[max_equal] = '\0';
|
||||||
|
match_list[0] = retstr;
|
||||||
|
|
||||||
|
/* add NULL as last pointer to the array */
|
||||||
|
match_list[matches + 1] = (char *) NULL;
|
||||||
|
|
||||||
|
return (match_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sort function for qsort(). Just wrapper around strcasecmp().
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
_fn_qsort_string_compare(const void *i1, const void *i2)
|
||||||
|
{
|
||||||
|
const char *s1 = ((const char * const *)i1)[0];
|
||||||
|
const char *s2 = ((const char * const *)i2)[0];
|
||||||
|
|
||||||
|
return strcasecmp(s1, s2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Display list of strings in columnar format on readline's output stream.
|
||||||
|
* 'matches' is list of strings, 'len' is number of strings in 'matches',
|
||||||
|
* 'max' is maximum length of string in 'matches'.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
fn_display_match_list (EditLine *el, char **matches, int len, int max)
|
||||||
|
{
|
||||||
|
int i, idx, limit, count;
|
||||||
|
int screenwidth = el->el_term.t_size.h;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Find out how many entries can be put on one line, count
|
||||||
|
* with two spaces between strings.
|
||||||
|
*/
|
||||||
|
limit = screenwidth / (max + 2);
|
||||||
|
if (limit == 0)
|
||||||
|
limit = 1;
|
||||||
|
|
||||||
|
/* how many lines of output */
|
||||||
|
count = len / limit;
|
||||||
|
if (count * limit < len)
|
||||||
|
count++;
|
||||||
|
|
||||||
|
/* Sort the items if they are not already sorted. */
|
||||||
|
qsort(&matches[1], (size_t)(len - 1), sizeof(char *),
|
||||||
|
_fn_qsort_string_compare);
|
||||||
|
|
||||||
|
idx = 1;
|
||||||
|
for(; count > 0; count--) {
|
||||||
|
for(i = 0; i < limit && matches[idx]; i++, idx++)
|
||||||
|
(void)fprintf(el->el_outfile, "%-*s ", max,
|
||||||
|
matches[idx]);
|
||||||
|
(void)fprintf(el->el_outfile, "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Complete the word at or before point,
|
||||||
|
* 'what_to_do' says what to do with the completion.
|
||||||
|
* \t means do standard completion.
|
||||||
|
* `?' means list the possible completions.
|
||||||
|
* `*' means insert all of the possible completions.
|
||||||
|
* `!' means to do standard completion, and list all possible completions if
|
||||||
|
* there is more than one.
|
||||||
|
*
|
||||||
|
* Note: '*' support is not implemented
|
||||||
|
* '!' could never be invoked
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
fn_complete(EditLine *el,
|
||||||
|
char *(*complet_func)(const char *, int),
|
||||||
|
char **(*attempted_completion_function)(const char *, int, int),
|
||||||
|
const char *word_break, const char *special_prefixes,
|
||||||
|
const char *(*app_func)(const char *), int query_items,
|
||||||
|
int *completion_type, int *over, int *point, int *end)
|
||||||
|
{
|
||||||
|
const LineInfo *li;
|
||||||
|
char *temp, **matches;
|
||||||
|
const char *ctemp;
|
||||||
|
size_t len;
|
||||||
|
int what_to_do = '\t';
|
||||||
|
int retval = CC_NORM;
|
||||||
|
|
||||||
|
if (el->el_state.lastcmd == el->el_state.thiscmd)
|
||||||
|
what_to_do = '?';
|
||||||
|
|
||||||
|
/* readline's rl_complete() has to be told what we did... */
|
||||||
|
if (completion_type != NULL)
|
||||||
|
*completion_type = what_to_do;
|
||||||
|
|
||||||
|
if (!complet_func)
|
||||||
|
complet_func = fn_filename_completion_function;
|
||||||
|
if (!app_func)
|
||||||
|
app_func = append_char_function;
|
||||||
|
|
||||||
|
/* We now look backwards for the start of a filename/variable word */
|
||||||
|
li = el_line(el);
|
||||||
|
ctemp = (const char *) li->cursor;
|
||||||
|
while (ctemp > li->buffer
|
||||||
|
&& !strchr(word_break, ctemp[-1])
|
||||||
|
&& (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) )
|
||||||
|
ctemp--;
|
||||||
|
|
||||||
|
len = li->cursor - ctemp;
|
||||||
|
#if defined(__SSP__) || defined(__SSP_ALL__)
|
||||||
|
temp = malloc(len + 1);
|
||||||
|
#else
|
||||||
|
temp = alloca(len + 1);
|
||||||
|
#endif
|
||||||
|
(void)strncpy(temp, ctemp, len);
|
||||||
|
temp[len] = '\0';
|
||||||
|
|
||||||
|
/* these can be used by function called in completion_matches() */
|
||||||
|
/* or (*attempted_completion_function)() */
|
||||||
|
if (point != 0)
|
||||||
|
*point = li->cursor - li->buffer;
|
||||||
|
if (end != NULL)
|
||||||
|
*end = li->lastchar - li->buffer;
|
||||||
|
|
||||||
|
if (attempted_completion_function) {
|
||||||
|
int cur_off = li->cursor - li->buffer;
|
||||||
|
matches = (*attempted_completion_function) (temp,
|
||||||
|
(int)(cur_off - len), cur_off);
|
||||||
|
} else
|
||||||
|
matches = 0;
|
||||||
|
if (!attempted_completion_function ||
|
||||||
|
(over != NULL && !*over && !matches))
|
||||||
|
matches = completion_matches(temp, complet_func);
|
||||||
|
|
||||||
|
if (over != NULL)
|
||||||
|
*over = 0;
|
||||||
|
|
||||||
|
if (matches) {
|
||||||
|
int i;
|
||||||
|
int matches_num, maxlen, match_len, match_display=1;
|
||||||
|
|
||||||
|
retval = CC_REFRESH;
|
||||||
|
/*
|
||||||
|
* Only replace the completed string with common part of
|
||||||
|
* possible matches if there is possible completion.
|
||||||
|
*/
|
||||||
|
if (matches[0][0] != '\0') {
|
||||||
|
el_deletestr(el, (int) len);
|
||||||
|
el_insertstr(el, matches[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (what_to_do == '?')
|
||||||
|
goto display_matches;
|
||||||
|
|
||||||
|
if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) {
|
||||||
|
/*
|
||||||
|
* We found exact match. Add a space after
|
||||||
|
* it, unless we do filename completion and the
|
||||||
|
* object is a directory.
|
||||||
|
*/
|
||||||
|
el_insertstr(el, (*append_char_function)(matches[0]));
|
||||||
|
} else if (what_to_do == '!') {
|
||||||
|
display_matches:
|
||||||
|
/*
|
||||||
|
* More than one match and requested to list possible
|
||||||
|
* matches.
|
||||||
|
*/
|
||||||
|
|
||||||
|
for(i=1, maxlen=0; matches[i]; i++) {
|
||||||
|
match_len = strlen(matches[i]);
|
||||||
|
if (match_len > maxlen)
|
||||||
|
maxlen = match_len;
|
||||||
|
}
|
||||||
|
matches_num = i - 1;
|
||||||
|
|
||||||
|
/* newline to get on next line from command line */
|
||||||
|
(void)fprintf(el->el_outfile, "\n");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If there are too many items, ask user for display
|
||||||
|
* confirmation.
|
||||||
|
*/
|
||||||
|
if (matches_num > query_items) {
|
||||||
|
(void)fprintf(el->el_outfile,
|
||||||
|
"Display all %d possibilities? (y or n) ",
|
||||||
|
matches_num);
|
||||||
|
(void)fflush(el->el_outfile);
|
||||||
|
if (getc(stdin) != 'y')
|
||||||
|
match_display = 0;
|
||||||
|
(void)fprintf(el->el_outfile, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (match_display)
|
||||||
|
fn_display_match_list(el, matches, matches_num,
|
||||||
|
maxlen);
|
||||||
|
retval = CC_REDISPLAY;
|
||||||
|
} else if (matches[0][0]) {
|
||||||
|
/*
|
||||||
|
* There was some common match, but the name was
|
||||||
|
* not complete enough. Next tab will print possible
|
||||||
|
* completions.
|
||||||
|
*/
|
||||||
|
el_beep(el);
|
||||||
|
} else {
|
||||||
|
/* lcd is not a valid object - further specification */
|
||||||
|
/* is needed */
|
||||||
|
el_beep(el);
|
||||||
|
retval = CC_NORM;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free elements of array and the array itself */
|
||||||
|
for (i = 0; matches[i]; i++)
|
||||||
|
free(matches[i]);
|
||||||
|
free(matches);
|
||||||
|
matches = NULL;
|
||||||
|
}
|
||||||
|
#if defined(__SSP__) || defined(__SSP_ALL__)
|
||||||
|
free(temp);
|
||||||
|
#endif
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el-compatible wrapper around rl_complete; needed for key binding
|
||||||
|
*/
|
||||||
|
/* ARGSUSED */
|
||||||
|
unsigned char
|
||||||
|
_el_fn_complete(EditLine *el, int ch __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
return (unsigned char)fn_complete(el, NULL, NULL,
|
||||||
|
break_chars, NULL, NULL, 100,
|
||||||
|
NULL, NULL, NULL, NULL);
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/* $NetBSD: filecomplete.h,v 1.5 2006/08/21 12:45:30 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1997 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Jaromir Dolecek.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
#ifndef _FILECOMPLETE_H_
|
||||||
|
#define _FILECOMPLETE_H_
|
||||||
|
|
||||||
|
int fn_complete(EditLine *,
|
||||||
|
char *(*)(const char *, int),
|
||||||
|
char **(*)(const char *, int, int),
|
||||||
|
const char *, const char *, const char *(*)(const char *), int,
|
||||||
|
int *, int *, int *, int *);
|
||||||
|
|
||||||
|
void fn_display_match_list(EditLine *, char **, int, int);
|
||||||
|
char *fn_tilde_expand(const char *);
|
||||||
|
char *fn_filename_completion_function(const char *, int);
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,210 @@
|
||||||
|
/* $NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hist.c: History access functions
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "el.h"
|
||||||
|
|
||||||
|
/* hist_init():
|
||||||
|
* Initialization function.
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
hist_init(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_history.fun = NULL;
|
||||||
|
el->el_history.ref = NULL;
|
||||||
|
el->el_history.buf = (char *) el_malloc(EL_BUFSIZ);
|
||||||
|
el->el_history.sz = EL_BUFSIZ;
|
||||||
|
if (el->el_history.buf == NULL)
|
||||||
|
return (-1);
|
||||||
|
el->el_history.last = el->el_history.buf;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* hist_end():
|
||||||
|
* clean up history;
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
hist_end(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
el_free((ptr_t) el->el_history.buf);
|
||||||
|
el->el_history.buf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* hist_set():
|
||||||
|
* Set new history interface
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr)
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_history.ref = ptr;
|
||||||
|
el->el_history.fun = fun;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* hist_get():
|
||||||
|
* Get a history line and update it in the buffer.
|
||||||
|
* eventno tells us the event to get.
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
hist_get(EditLine *el)
|
||||||
|
{
|
||||||
|
const char *hp;
|
||||||
|
int h;
|
||||||
|
|
||||||
|
if (el->el_history.eventno == 0) { /* if really the current line */
|
||||||
|
(void) strncpy(el->el_line.buffer, el->el_history.buf,
|
||||||
|
el->el_history.sz);
|
||||||
|
el->el_line.lastchar = el->el_line.buffer +
|
||||||
|
(el->el_history.last - el->el_history.buf);
|
||||||
|
|
||||||
|
#ifdef KSHVI
|
||||||
|
if (el->el_map.type == MAP_VI)
|
||||||
|
el->el_line.cursor = el->el_line.buffer;
|
||||||
|
else
|
||||||
|
#endif /* KSHVI */
|
||||||
|
el->el_line.cursor = el->el_line.lastchar;
|
||||||
|
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
if (el->el_history.ref == NULL)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
hp = HIST_FIRST(el);
|
||||||
|
|
||||||
|
if (hp == NULL)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
for (h = 1; h < el->el_history.eventno; h++)
|
||||||
|
if ((hp = HIST_NEXT(el)) == NULL) {
|
||||||
|
el->el_history.eventno = h;
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
(void) strlcpy(el->el_line.buffer, hp,
|
||||||
|
(size_t)(el->el_line.limit - el->el_line.buffer));
|
||||||
|
el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer);
|
||||||
|
|
||||||
|
if (el->el_line.lastchar > el->el_line.buffer
|
||||||
|
&& el->el_line.lastchar[-1] == '\n')
|
||||||
|
el->el_line.lastchar--;
|
||||||
|
if (el->el_line.lastchar > el->el_line.buffer
|
||||||
|
&& el->el_line.lastchar[-1] == ' ')
|
||||||
|
el->el_line.lastchar--;
|
||||||
|
#ifdef KSHVI
|
||||||
|
if (el->el_map.type == MAP_VI)
|
||||||
|
el->el_line.cursor = el->el_line.buffer;
|
||||||
|
else
|
||||||
|
#endif /* KSHVI */
|
||||||
|
el->el_line.cursor = el->el_line.lastchar;
|
||||||
|
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* hist_command()
|
||||||
|
* process a history command
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
hist_command(EditLine *el, int argc, const char **argv)
|
||||||
|
{
|
||||||
|
const char *str;
|
||||||
|
int num;
|
||||||
|
HistEvent ev;
|
||||||
|
|
||||||
|
if (el->el_history.ref == NULL)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
if (argc == 1 || strcmp(argv[1], "list") == 0) {
|
||||||
|
/* List history entries */
|
||||||
|
|
||||||
|
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
|
||||||
|
(void) fprintf(el->el_outfile, "%d %s",
|
||||||
|
el->el_history.ev.num, str);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc != 3)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
num = (int)strtol(argv[2], NULL, 0);
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "size") == 0)
|
||||||
|
return history(el->el_history.ref, &ev, H_SETSIZE, num);
|
||||||
|
|
||||||
|
if (strcmp(argv[1], "unique") == 0)
|
||||||
|
return history(el->el_history.ref, &ev, H_SETUNIQUE, num);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* hist_enlargebuf()
|
||||||
|
* Enlarge history buffer to specified value. Called from el_enlargebufs().
|
||||||
|
* Return 0 for failure, 1 for success.
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
/*ARGSUSED*/
|
||||||
|
hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
|
||||||
|
{
|
||||||
|
char *newbuf;
|
||||||
|
|
||||||
|
newbuf = realloc(el->el_history.buf, newsz);
|
||||||
|
if (!newbuf)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
(void) memset(&newbuf[oldsz], '\0', newsz - oldsz);
|
||||||
|
|
||||||
|
el->el_history.last = newbuf +
|
||||||
|
(el->el_history.last - el->el_history.buf);
|
||||||
|
el->el_history.buf = newbuf;
|
||||||
|
el->el_history.sz = newsz;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
/* $NetBSD: hist.h,v 1.10 2003/08/07 16:44:31 agc Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)hist.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.hist.c: History functions
|
||||||
|
*/
|
||||||
|
#ifndef _h_el_hist
|
||||||
|
#define _h_el_hist
|
||||||
|
|
||||||
|
#include "histedit.h"
|
||||||
|
|
||||||
|
typedef int (*hist_fun_t)(ptr_t, HistEvent *, int, ...);
|
||||||
|
|
||||||
|
typedef struct el_history_t {
|
||||||
|
char *buf; /* The history buffer */
|
||||||
|
size_t sz; /* Size of history buffer */
|
||||||
|
char *last; /* The last character */
|
||||||
|
int eventno; /* Event we are looking for */
|
||||||
|
ptr_t ref; /* Argument for history fcns */
|
||||||
|
hist_fun_t fun; /* Event access */
|
||||||
|
HistEvent ev; /* Event cookie */
|
||||||
|
} el_history_t;
|
||||||
|
|
||||||
|
#define HIST_FUN(el, fn, arg) \
|
||||||
|
((((*(el)->el_history.fun) ((el)->el_history.ref, &(el)->el_history.ev, \
|
||||||
|
fn, arg)) == -1) ? NULL : (el)->el_history.ev.str)
|
||||||
|
|
||||||
|
#define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL)
|
||||||
|
#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL)
|
||||||
|
#define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL)
|
||||||
|
#define HIST_PREV(el) HIST_FUN(el, H_PREV, NULL)
|
||||||
|
#define HIST_SET(el, num) HIST_FUN(el, H_SET, num)
|
||||||
|
#define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname)
|
||||||
|
#define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname)
|
||||||
|
|
||||||
|
protected int hist_init(EditLine *);
|
||||||
|
protected void hist_end(EditLine *);
|
||||||
|
protected el_action_t hist_get(EditLine *);
|
||||||
|
protected int hist_set(EditLine *, hist_fun_t, ptr_t);
|
||||||
|
protected int hist_command(EditLine *, int, const char **);
|
||||||
|
protected int hist_enlargebuf(EditLine *, size_t, size_t);
|
||||||
|
|
||||||
|
#endif /* _h_el_hist */
|
|
@ -0,0 +1,227 @@
|
||||||
|
/* $NetBSD: histedit.h,v 1.32 2007/06/10 20:20:28 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)histedit.h 8.2 (Berkeley) 1/3/94
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* histedit.h: Line editor and history interface.
|
||||||
|
*/
|
||||||
|
#ifndef _HISTEDIT_H_
|
||||||
|
#define _HISTEDIT_H_
|
||||||
|
|
||||||
|
#define LIBEDIT_MAJOR 2
|
||||||
|
#define LIBEDIT_MINOR 10
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ==== Editing ====
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct editline EditLine;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For user-defined function interface
|
||||||
|
*/
|
||||||
|
typedef struct lineinfo {
|
||||||
|
const char *buffer;
|
||||||
|
const char *cursor;
|
||||||
|
const char *lastchar;
|
||||||
|
} LineInfo;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* EditLine editor function return codes.
|
||||||
|
* For user-defined function interface
|
||||||
|
*/
|
||||||
|
#define CC_NORM 0
|
||||||
|
#define CC_NEWLINE 1
|
||||||
|
#define CC_EOF 2
|
||||||
|
#define CC_ARGHACK 3
|
||||||
|
#define CC_REFRESH 4
|
||||||
|
#define CC_CURSOR 5
|
||||||
|
#define CC_ERROR 6
|
||||||
|
#define CC_FATAL 7
|
||||||
|
#define CC_REDISPLAY 8
|
||||||
|
#define CC_REFRESH_BEEP 9
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialization, cleanup, and resetting
|
||||||
|
*/
|
||||||
|
EditLine *el_init(const char *, FILE *, FILE *, FILE *);
|
||||||
|
void el_end(EditLine *);
|
||||||
|
void el_reset(EditLine *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Get a line, a character or push a string back in the input queue
|
||||||
|
*/
|
||||||
|
const char *el_gets(EditLine *, int *);
|
||||||
|
int el_getc(EditLine *, char *);
|
||||||
|
void el_push(EditLine *, char *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Beep!
|
||||||
|
*/
|
||||||
|
void el_beep(EditLine *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* High level function internals control
|
||||||
|
* Parses argc, argv array and executes builtin editline commands
|
||||||
|
*/
|
||||||
|
int el_parse(EditLine *, int, const char **);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Low level editline access functions
|
||||||
|
*/
|
||||||
|
int el_set(EditLine *, int, ...);
|
||||||
|
int el_get(EditLine *, int, ...);
|
||||||
|
unsigned char _el_fn_complete(EditLine *, int);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el_set/el_get parameters
|
||||||
|
*/
|
||||||
|
#define EL_PROMPT 0 /* , el_pfunc_t); */
|
||||||
|
#define EL_TERMINAL 1 /* , const char *); */
|
||||||
|
#define EL_EDITOR 2 /* , const char *); */
|
||||||
|
#define EL_SIGNAL 3 /* , int); */
|
||||||
|
#define EL_BIND 4 /* , const char *, ..., NULL); */
|
||||||
|
#define EL_TELLTC 5 /* , const char *, ..., NULL); */
|
||||||
|
#define EL_SETTC 6 /* , const char *, ..., NULL); */
|
||||||
|
#define EL_ECHOTC 7 /* , const char *, ..., NULL); */
|
||||||
|
#define EL_SETTY 8 /* , const char *, ..., NULL); */
|
||||||
|
#define EL_ADDFN 9 /* , const char *, const char * */
|
||||||
|
/* , el_func_t); */
|
||||||
|
#define EL_HIST 10 /* , hist_fun_t, const char *); */
|
||||||
|
#define EL_EDITMODE 11 /* , int); */
|
||||||
|
#define EL_RPROMPT 12 /* , el_pfunc_t); */
|
||||||
|
#define EL_GETCFN 13 /* , el_rfunc_t); */
|
||||||
|
#define EL_CLIENTDATA 14 /* , void *); */
|
||||||
|
#define EL_UNBUFFERED 15 /* , int); */
|
||||||
|
#define EL_PREP_TERM 16 /* , int); */
|
||||||
|
#define EL_GETTC 17 /* , const char *, ..., NULL); */
|
||||||
|
#define EL_GETFP 18 /* , int, FILE **) */
|
||||||
|
#define EL_SETFP 19 /* , int, FILE *) */
|
||||||
|
|
||||||
|
#define EL_BUILTIN_GETCFN (NULL)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Source named file or $PWD/.editrc or $HOME/.editrc
|
||||||
|
*/
|
||||||
|
int el_source(EditLine *, const char *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must be called when the terminal changes size; If EL_SIGNAL
|
||||||
|
* is set this is done automatically otherwise it is the responsibility
|
||||||
|
* of the application
|
||||||
|
*/
|
||||||
|
void el_resize(EditLine *);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* User-defined function interface.
|
||||||
|
*/
|
||||||
|
const LineInfo *el_line(EditLine *);
|
||||||
|
int el_insertstr(EditLine *, const char *);
|
||||||
|
void el_deletestr(EditLine *, int);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ==== History ====
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct history History;
|
||||||
|
|
||||||
|
typedef struct HistEvent {
|
||||||
|
int num;
|
||||||
|
const char *str;
|
||||||
|
} HistEvent;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* History access functions.
|
||||||
|
*/
|
||||||
|
History * history_init(void);
|
||||||
|
void history_end(History *);
|
||||||
|
|
||||||
|
int history(History *, HistEvent *, int, ...);
|
||||||
|
|
||||||
|
#define H_FUNC 0 /* , UTSL */
|
||||||
|
#define H_SETSIZE 1 /* , const int); */
|
||||||
|
#define H_GETSIZE 2 /* , void); */
|
||||||
|
#define H_FIRST 3 /* , void); */
|
||||||
|
#define H_LAST 4 /* , void); */
|
||||||
|
#define H_PREV 5 /* , void); */
|
||||||
|
#define H_NEXT 6 /* , void); */
|
||||||
|
#define H_CURR 8 /* , const int); */
|
||||||
|
#define H_SET 7 /* , int); */
|
||||||
|
#define H_ADD 9 /* , const char *); */
|
||||||
|
#define H_ENTER 10 /* , const char *); */
|
||||||
|
#define H_APPEND 11 /* , const char *); */
|
||||||
|
#define H_END 12 /* , void); */
|
||||||
|
#define H_NEXT_STR 13 /* , const char *); */
|
||||||
|
#define H_PREV_STR 14 /* , const char *); */
|
||||||
|
#define H_NEXT_EVENT 15 /* , const int); */
|
||||||
|
#define H_PREV_EVENT 16 /* , const int); */
|
||||||
|
#define H_LOAD 17 /* , const char *); */
|
||||||
|
#define H_SAVE 18 /* , const char *); */
|
||||||
|
#define H_CLEAR 19 /* , void); */
|
||||||
|
#define H_SETUNIQUE 20 /* , int); */
|
||||||
|
#define H_GETUNIQUE 21 /* , void); */
|
||||||
|
#define H_DEL 22 /* , int); */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ==== Tokenization ====
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct tokenizer Tokenizer;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* String tokenization functions, using simplified sh(1) quoting rules
|
||||||
|
*/
|
||||||
|
Tokenizer *tok_init(const char *);
|
||||||
|
void tok_end(Tokenizer *);
|
||||||
|
void tok_reset(Tokenizer *);
|
||||||
|
int tok_line(Tokenizer *, const LineInfo *,
|
||||||
|
int *, const char ***, int *, int *);
|
||||||
|
int tok_str(Tokenizer *, const char *,
|
||||||
|
int *, const char ***);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _HISTEDIT_H_ */
|
|
@ -0,0 +1,987 @@
|
||||||
|
/* $NetBSD: history.c,v 1.32 2006/09/28 13:52:51 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: history.c,v 1.32 2006/09/28 13:52:51 christos Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* hist.c: History access functions
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <vis.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
static const char hist_cookie[] = "_HiStOrY_V2_\n";
|
||||||
|
|
||||||
|
#include "histedit.h"
|
||||||
|
|
||||||
|
typedef int (*history_gfun_t)(ptr_t, HistEvent *);
|
||||||
|
typedef int (*history_efun_t)(ptr_t, HistEvent *, const char *);
|
||||||
|
typedef void (*history_vfun_t)(ptr_t, HistEvent *);
|
||||||
|
typedef int (*history_sfun_t)(ptr_t, HistEvent *, const int);
|
||||||
|
|
||||||
|
struct history {
|
||||||
|
ptr_t h_ref; /* Argument for history fcns */
|
||||||
|
int h_ent; /* Last entry point for history */
|
||||||
|
history_gfun_t h_first; /* Get the first element */
|
||||||
|
history_gfun_t h_next; /* Get the next element */
|
||||||
|
history_gfun_t h_last; /* Get the last element */
|
||||||
|
history_gfun_t h_prev; /* Get the previous element */
|
||||||
|
history_gfun_t h_curr; /* Get the current element */
|
||||||
|
history_sfun_t h_set; /* Set the current element */
|
||||||
|
history_sfun_t h_del; /* Set the given element */
|
||||||
|
history_vfun_t h_clear; /* Clear the history list */
|
||||||
|
history_efun_t h_enter; /* Add an element */
|
||||||
|
history_efun_t h_add; /* Append to an element */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define HNEXT(h, ev) (*(h)->h_next)((h)->h_ref, ev)
|
||||||
|
#define HFIRST(h, ev) (*(h)->h_first)((h)->h_ref, ev)
|
||||||
|
#define HPREV(h, ev) (*(h)->h_prev)((h)->h_ref, ev)
|
||||||
|
#define HLAST(h, ev) (*(h)->h_last)((h)->h_ref, ev)
|
||||||
|
#define HCURR(h, ev) (*(h)->h_curr)((h)->h_ref, ev)
|
||||||
|
#define HSET(h, ev, n) (*(h)->h_set)((h)->h_ref, ev, n)
|
||||||
|
#define HCLEAR(h, ev) (*(h)->h_clear)((h)->h_ref, ev)
|
||||||
|
#define HENTER(h, ev, str) (*(h)->h_enter)((h)->h_ref, ev, str)
|
||||||
|
#define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str)
|
||||||
|
#define HDEL(h, ev, n) (*(h)->h_del)((h)->h_ref, ev, n)
|
||||||
|
|
||||||
|
#define h_strdup(a) strdup(a)
|
||||||
|
#define h_malloc(a) malloc(a)
|
||||||
|
#define h_realloc(a, b) realloc((a), (b))
|
||||||
|
#define h_free(a) free(a)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int num;
|
||||||
|
char *str;
|
||||||
|
} HistEventPrivate;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private int history_setsize(History *, HistEvent *, int);
|
||||||
|
private int history_getsize(History *, HistEvent *);
|
||||||
|
private int history_setunique(History *, HistEvent *, int);
|
||||||
|
private int history_getunique(History *, HistEvent *);
|
||||||
|
private int history_set_fun(History *, History *);
|
||||||
|
private int history_load(History *, const char *);
|
||||||
|
private int history_save(History *, const char *);
|
||||||
|
private int history_prev_event(History *, HistEvent *, int);
|
||||||
|
private int history_next_event(History *, HistEvent *, int);
|
||||||
|
private int history_next_string(History *, HistEvent *, const char *);
|
||||||
|
private int history_prev_string(History *, HistEvent *, const char *);
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Builtin- history implementation
|
||||||
|
*/
|
||||||
|
typedef struct hentry_t {
|
||||||
|
HistEvent ev; /* What we return */
|
||||||
|
struct hentry_t *next; /* Next entry */
|
||||||
|
struct hentry_t *prev; /* Previous entry */
|
||||||
|
} hentry_t;
|
||||||
|
|
||||||
|
typedef struct history_t {
|
||||||
|
hentry_t list; /* Fake list header element */
|
||||||
|
hentry_t *cursor; /* Current element in the list */
|
||||||
|
int max; /* Maximum number of events */
|
||||||
|
int cur; /* Current number of events */
|
||||||
|
int eventid; /* For generation of unique event id */
|
||||||
|
int flags; /* History flags */
|
||||||
|
#define H_UNIQUE 1 /* Store only unique elements */
|
||||||
|
} history_t;
|
||||||
|
|
||||||
|
private int history_def_next(ptr_t, HistEvent *);
|
||||||
|
private int history_def_first(ptr_t, HistEvent *);
|
||||||
|
private int history_def_prev(ptr_t, HistEvent *);
|
||||||
|
private int history_def_last(ptr_t, HistEvent *);
|
||||||
|
private int history_def_curr(ptr_t, HistEvent *);
|
||||||
|
private int history_def_set(ptr_t, HistEvent *, const int);
|
||||||
|
private void history_def_clear(ptr_t, HistEvent *);
|
||||||
|
private int history_def_enter(ptr_t, HistEvent *, const char *);
|
||||||
|
private int history_def_add(ptr_t, HistEvent *, const char *);
|
||||||
|
private int history_def_del(ptr_t, HistEvent *, const int);
|
||||||
|
|
||||||
|
private int history_def_init(ptr_t *, HistEvent *, int);
|
||||||
|
private int history_def_insert(history_t *, HistEvent *, const char *);
|
||||||
|
private void history_def_delete(history_t *, HistEvent *, hentry_t *);
|
||||||
|
|
||||||
|
#define history_def_setsize(p, num)(void) (((history_t *)p)->max = (num))
|
||||||
|
#define history_def_getsize(p) (((history_t *)p)->cur)
|
||||||
|
#define history_def_getunique(p) (((((history_t *)p)->flags) & H_UNIQUE) != 0)
|
||||||
|
#define history_def_setunique(p, uni) \
|
||||||
|
if (uni) \
|
||||||
|
(((history_t *)p)->flags) |= H_UNIQUE; \
|
||||||
|
else \
|
||||||
|
(((history_t *)p)->flags) &= ~H_UNIQUE
|
||||||
|
|
||||||
|
#define he_strerror(code) he_errlist[code]
|
||||||
|
#define he_seterrev(evp, code) {\
|
||||||
|
evp->num = code;\
|
||||||
|
evp->str = he_strerror(code);\
|
||||||
|
}
|
||||||
|
|
||||||
|
/* error messages */
|
||||||
|
static const char *const he_errlist[] = {
|
||||||
|
"OK",
|
||||||
|
"unknown error",
|
||||||
|
"malloc() failed",
|
||||||
|
"first event not found",
|
||||||
|
"last event not found",
|
||||||
|
"empty list",
|
||||||
|
"no next event",
|
||||||
|
"no previous event",
|
||||||
|
"current event is invalid",
|
||||||
|
"event not found",
|
||||||
|
"can't read history from file",
|
||||||
|
"can't write history",
|
||||||
|
"required parameter(s) not supplied",
|
||||||
|
"history size negative",
|
||||||
|
"function not allowed with other history-functions-set the default",
|
||||||
|
"bad parameters"
|
||||||
|
};
|
||||||
|
/* error codes */
|
||||||
|
#define _HE_OK 0
|
||||||
|
#define _HE_UNKNOWN 1
|
||||||
|
#define _HE_MALLOC_FAILED 2
|
||||||
|
#define _HE_FIRST_NOTFOUND 3
|
||||||
|
#define _HE_LAST_NOTFOUND 4
|
||||||
|
#define _HE_EMPTY_LIST 5
|
||||||
|
#define _HE_END_REACHED 6
|
||||||
|
#define _HE_START_REACHED 7
|
||||||
|
#define _HE_CURR_INVALID 8
|
||||||
|
#define _HE_NOT_FOUND 9
|
||||||
|
#define _HE_HIST_READ 10
|
||||||
|
#define _HE_HIST_WRITE 11
|
||||||
|
#define _HE_PARAM_MISSING 12
|
||||||
|
#define _HE_SIZE_NEGATIVE 13
|
||||||
|
#define _HE_NOT_ALLOWED 14
|
||||||
|
#define _HE_BAD_PARAM 15
|
||||||
|
|
||||||
|
/* history_def_first():
|
||||||
|
* Default function to return the first event in the history.
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_def_first(ptr_t p, HistEvent *ev)
|
||||||
|
{
|
||||||
|
history_t *h = (history_t *) p;
|
||||||
|
|
||||||
|
h->cursor = h->list.next;
|
||||||
|
if (h->cursor != &h->list)
|
||||||
|
*ev = h->cursor->ev;
|
||||||
|
else {
|
||||||
|
he_seterrev(ev, _HE_FIRST_NOTFOUND);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_def_last():
|
||||||
|
* Default function to return the last event in the history.
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_def_last(ptr_t p, HistEvent *ev)
|
||||||
|
{
|
||||||
|
history_t *h = (history_t *) p;
|
||||||
|
|
||||||
|
h->cursor = h->list.prev;
|
||||||
|
if (h->cursor != &h->list)
|
||||||
|
*ev = h->cursor->ev;
|
||||||
|
else {
|
||||||
|
he_seterrev(ev, _HE_LAST_NOTFOUND);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_def_next():
|
||||||
|
* Default function to return the next event in the history.
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_def_next(ptr_t p, HistEvent *ev)
|
||||||
|
{
|
||||||
|
history_t *h = (history_t *) p;
|
||||||
|
|
||||||
|
if (h->cursor == &h->list) {
|
||||||
|
he_seterrev(ev, _HE_EMPTY_LIST);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h->cursor->next == &h->list) {
|
||||||
|
he_seterrev(ev, _HE_END_REACHED);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
h->cursor = h->cursor->next;
|
||||||
|
*ev = h->cursor->ev;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_def_prev():
|
||||||
|
* Default function to return the previous event in the history.
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_def_prev(ptr_t p, HistEvent *ev)
|
||||||
|
{
|
||||||
|
history_t *h = (history_t *) p;
|
||||||
|
|
||||||
|
if (h->cursor == &h->list) {
|
||||||
|
he_seterrev(ev,
|
||||||
|
(h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (h->cursor->prev == &h->list) {
|
||||||
|
he_seterrev(ev, _HE_START_REACHED);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
h->cursor = h->cursor->prev;
|
||||||
|
*ev = h->cursor->ev;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_def_curr():
|
||||||
|
* Default function to return the current event in the history.
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_def_curr(ptr_t p, HistEvent *ev)
|
||||||
|
{
|
||||||
|
history_t *h = (history_t *) p;
|
||||||
|
|
||||||
|
if (h->cursor != &h->list)
|
||||||
|
*ev = h->cursor->ev;
|
||||||
|
else {
|
||||||
|
he_seterrev(ev,
|
||||||
|
(h->cur > 0) ? _HE_CURR_INVALID : _HE_EMPTY_LIST);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_def_set():
|
||||||
|
* Default function to set the current event in the history to the
|
||||||
|
* given one.
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_def_set(ptr_t p, HistEvent *ev, const int n)
|
||||||
|
{
|
||||||
|
history_t *h = (history_t *) p;
|
||||||
|
|
||||||
|
if (h->cur == 0) {
|
||||||
|
he_seterrev(ev, _HE_EMPTY_LIST);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (h->cursor == &h->list || h->cursor->ev.num != n) {
|
||||||
|
for (h->cursor = h->list.next; h->cursor != &h->list;
|
||||||
|
h->cursor = h->cursor->next)
|
||||||
|
if (h->cursor->ev.num == n)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (h->cursor == &h->list) {
|
||||||
|
he_seterrev(ev, _HE_NOT_FOUND);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_def_add():
|
||||||
|
* Append string to element
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_def_add(ptr_t p, HistEvent *ev, const char *str)
|
||||||
|
{
|
||||||
|
history_t *h = (history_t *) p;
|
||||||
|
size_t len;
|
||||||
|
char *s;
|
||||||
|
HistEventPrivate *evp = (void *)&h->cursor->ev;
|
||||||
|
|
||||||
|
if (h->cursor == &h->list)
|
||||||
|
return (history_def_enter(p, ev, str));
|
||||||
|
len = strlen(evp->str) + strlen(str) + 1;
|
||||||
|
s = (char *) h_malloc(len);
|
||||||
|
if (s == NULL) {
|
||||||
|
he_seterrev(ev, _HE_MALLOC_FAILED);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
(void) strlcpy(s, h->cursor->ev.str, len);
|
||||||
|
(void) strlcat(s, str, len);
|
||||||
|
h_free((ptr_t)evp->str);
|
||||||
|
evp->str = s;
|
||||||
|
*ev = h->cursor->ev;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_def_del():
|
||||||
|
* Delete element hp of the h list
|
||||||
|
*/
|
||||||
|
/* ARGSUSED */
|
||||||
|
private int
|
||||||
|
history_def_del(ptr_t p, HistEvent *ev __attribute__((__unused__)),
|
||||||
|
const int num)
|
||||||
|
{
|
||||||
|
history_t *h = (history_t *) p;
|
||||||
|
if (history_def_set(h, ev, num) != 0)
|
||||||
|
return (-1);
|
||||||
|
ev->str = strdup(h->cursor->ev.str);
|
||||||
|
ev->num = h->cursor->ev.num;
|
||||||
|
history_def_delete(h, ev, h->cursor);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_def_delete():
|
||||||
|
* Delete element hp of the h list
|
||||||
|
*/
|
||||||
|
/* ARGSUSED */
|
||||||
|
private void
|
||||||
|
history_def_delete(history_t *h,
|
||||||
|
HistEvent *ev __attribute__((__unused__)), hentry_t *hp)
|
||||||
|
{
|
||||||
|
HistEventPrivate *evp = (void *)&hp->ev;
|
||||||
|
if (hp == &h->list)
|
||||||
|
abort();
|
||||||
|
if (h->cursor == hp)
|
||||||
|
h->cursor = hp->prev;
|
||||||
|
hp->prev->next = hp->next;
|
||||||
|
hp->next->prev = hp->prev;
|
||||||
|
h_free((ptr_t) evp->str);
|
||||||
|
h_free(hp);
|
||||||
|
h->cur--;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_def_insert():
|
||||||
|
* Insert element with string str in the h list
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_def_insert(history_t *h, HistEvent *ev, const char *str)
|
||||||
|
{
|
||||||
|
|
||||||
|
h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t));
|
||||||
|
if (h->cursor == NULL)
|
||||||
|
goto oomem;
|
||||||
|
if ((h->cursor->ev.str = h_strdup(str)) == NULL) {
|
||||||
|
h_free((ptr_t)h->cursor);
|
||||||
|
goto oomem;
|
||||||
|
}
|
||||||
|
h->cursor->ev.num = ++h->eventid;
|
||||||
|
h->cursor->next = h->list.next;
|
||||||
|
h->cursor->prev = &h->list;
|
||||||
|
h->list.next->prev = h->cursor;
|
||||||
|
h->list.next = h->cursor;
|
||||||
|
h->cur++;
|
||||||
|
|
||||||
|
*ev = h->cursor->ev;
|
||||||
|
return (0);
|
||||||
|
oomem:
|
||||||
|
he_seterrev(ev, _HE_MALLOC_FAILED);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_def_enter():
|
||||||
|
* Default function to enter an item in the history
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_def_enter(ptr_t p, HistEvent *ev, const char *str)
|
||||||
|
{
|
||||||
|
history_t *h = (history_t *) p;
|
||||||
|
|
||||||
|
if ((h->flags & H_UNIQUE) != 0 && h->list.next != &h->list &&
|
||||||
|
strcmp(h->list.next->ev.str, str) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
if (history_def_insert(h, ev, str) == -1)
|
||||||
|
return (-1); /* error, keep error message */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Always keep at least one entry.
|
||||||
|
* This way we don't have to check for the empty list.
|
||||||
|
*/
|
||||||
|
while (h->cur > h->max && h->cur > 0)
|
||||||
|
history_def_delete(h, ev, h->list.prev);
|
||||||
|
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_def_init():
|
||||||
|
* Default history initialization function
|
||||||
|
*/
|
||||||
|
/* ARGSUSED */
|
||||||
|
private int
|
||||||
|
history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n)
|
||||||
|
{
|
||||||
|
history_t *h = (history_t *) h_malloc(sizeof(history_t));
|
||||||
|
if (h == NULL)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (n <= 0)
|
||||||
|
n = 0;
|
||||||
|
h->eventid = 0;
|
||||||
|
h->cur = 0;
|
||||||
|
h->max = n;
|
||||||
|
h->list.next = h->list.prev = &h->list;
|
||||||
|
h->list.ev.str = NULL;
|
||||||
|
h->list.ev.num = 0;
|
||||||
|
h->cursor = &h->list;
|
||||||
|
h->flags = 0;
|
||||||
|
*p = (ptr_t) h;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_def_clear():
|
||||||
|
* Default history cleanup function
|
||||||
|
*/
|
||||||
|
private void
|
||||||
|
history_def_clear(ptr_t p, HistEvent *ev)
|
||||||
|
{
|
||||||
|
history_t *h = (history_t *) p;
|
||||||
|
|
||||||
|
while (h->list.prev != &h->list)
|
||||||
|
history_def_delete(h, ev, h->list.prev);
|
||||||
|
h->eventid = 0;
|
||||||
|
h->cur = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************************************/
|
||||||
|
|
||||||
|
/* history_init():
|
||||||
|
* Initialization function.
|
||||||
|
*/
|
||||||
|
public History *
|
||||||
|
history_init(void)
|
||||||
|
{
|
||||||
|
HistEvent ev;
|
||||||
|
History *h = (History *) h_malloc(sizeof(History));
|
||||||
|
if (h == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (history_def_init(&h->h_ref, &ev, 0) == -1) {
|
||||||
|
h_free((ptr_t)h);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
h->h_ent = -1;
|
||||||
|
h->h_next = history_def_next;
|
||||||
|
h->h_first = history_def_first;
|
||||||
|
h->h_last = history_def_last;
|
||||||
|
h->h_prev = history_def_prev;
|
||||||
|
h->h_curr = history_def_curr;
|
||||||
|
h->h_set = history_def_set;
|
||||||
|
h->h_clear = history_def_clear;
|
||||||
|
h->h_enter = history_def_enter;
|
||||||
|
h->h_add = history_def_add;
|
||||||
|
h->h_del = history_def_del;
|
||||||
|
|
||||||
|
return (h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_end():
|
||||||
|
* clean up history;
|
||||||
|
*/
|
||||||
|
public void
|
||||||
|
history_end(History *h)
|
||||||
|
{
|
||||||
|
HistEvent ev;
|
||||||
|
|
||||||
|
if (h->h_next == history_def_next)
|
||||||
|
history_def_clear(h->h_ref, &ev);
|
||||||
|
h_free(h->h_ref);
|
||||||
|
h_free(h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* history_setsize():
|
||||||
|
* Set history number of events
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_setsize(History *h, HistEvent *ev, int num)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (h->h_next != history_def_next) {
|
||||||
|
he_seterrev(ev, _HE_NOT_ALLOWED);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (num < 0) {
|
||||||
|
he_seterrev(ev, _HE_BAD_PARAM);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
history_def_setsize(h->h_ref, num);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_getsize():
|
||||||
|
* Get number of events currently in history
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_getsize(History *h, HistEvent *ev)
|
||||||
|
{
|
||||||
|
if (h->h_next != history_def_next) {
|
||||||
|
he_seterrev(ev, _HE_NOT_ALLOWED);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
ev->num = history_def_getsize(h->h_ref);
|
||||||
|
if (ev->num < -1) {
|
||||||
|
he_seterrev(ev, _HE_SIZE_NEGATIVE);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_setunique():
|
||||||
|
* Set if adjacent equal events should not be entered in history.
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_setunique(History *h, HistEvent *ev, int uni)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (h->h_next != history_def_next) {
|
||||||
|
he_seterrev(ev, _HE_NOT_ALLOWED);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
history_def_setunique(h->h_ref, uni);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_getunique():
|
||||||
|
* Get if adjacent equal events should not be entered in history.
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_getunique(History *h, HistEvent *ev)
|
||||||
|
{
|
||||||
|
if (h->h_next != history_def_next) {
|
||||||
|
he_seterrev(ev, _HE_NOT_ALLOWED);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
ev->num = history_def_getunique(h->h_ref);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_set_fun():
|
||||||
|
* Set history functions
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_set_fun(History *h, History *nh)
|
||||||
|
{
|
||||||
|
HistEvent ev;
|
||||||
|
|
||||||
|
if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL ||
|
||||||
|
nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == NULL ||
|
||||||
|
nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL ||
|
||||||
|
nh->h_del == NULL || nh->h_ref == NULL) {
|
||||||
|
if (h->h_next != history_def_next) {
|
||||||
|
history_def_init(&h->h_ref, &ev, 0);
|
||||||
|
h->h_first = history_def_first;
|
||||||
|
h->h_next = history_def_next;
|
||||||
|
h->h_last = history_def_last;
|
||||||
|
h->h_prev = history_def_prev;
|
||||||
|
h->h_curr = history_def_curr;
|
||||||
|
h->h_set = history_def_set;
|
||||||
|
h->h_clear = history_def_clear;
|
||||||
|
h->h_enter = history_def_enter;
|
||||||
|
h->h_add = history_def_add;
|
||||||
|
h->h_del = history_def_del;
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (h->h_next == history_def_next)
|
||||||
|
history_def_clear(h->h_ref, &ev);
|
||||||
|
|
||||||
|
h->h_ent = -1;
|
||||||
|
h->h_first = nh->h_first;
|
||||||
|
h->h_next = nh->h_next;
|
||||||
|
h->h_last = nh->h_last;
|
||||||
|
h->h_prev = nh->h_prev;
|
||||||
|
h->h_curr = nh->h_curr;
|
||||||
|
h->h_set = nh->h_set;
|
||||||
|
h->h_clear = nh->h_clear;
|
||||||
|
h->h_enter = nh->h_enter;
|
||||||
|
h->h_add = nh->h_add;
|
||||||
|
h->h_del = nh->h_del;
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_load():
|
||||||
|
* History load function
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_load(History *h, const char *fname)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
char *line;
|
||||||
|
size_t sz, max_size;
|
||||||
|
char *ptr;
|
||||||
|
int i = -1;
|
||||||
|
HistEvent ev;
|
||||||
|
|
||||||
|
if ((fp = fopen(fname, "r")) == NULL)
|
||||||
|
return (i);
|
||||||
|
|
||||||
|
if ((line = fgetln(fp, &sz)) == NULL)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
if (strncmp(line, hist_cookie, sz) != 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
ptr = h_malloc(max_size = 1024);
|
||||||
|
if (ptr == NULL)
|
||||||
|
goto done;
|
||||||
|
for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) {
|
||||||
|
char c = line[sz];
|
||||||
|
|
||||||
|
if (sz != 0 && line[sz - 1] == '\n')
|
||||||
|
line[--sz] = '\0';
|
||||||
|
else
|
||||||
|
line[sz] = '\0';
|
||||||
|
|
||||||
|
if (max_size < sz) {
|
||||||
|
char *nptr;
|
||||||
|
max_size = (sz + 1024) & ~1023;
|
||||||
|
nptr = h_realloc(ptr, max_size);
|
||||||
|
if (nptr == NULL) {
|
||||||
|
i = -1;
|
||||||
|
goto oomem;
|
||||||
|
}
|
||||||
|
ptr = nptr;
|
||||||
|
}
|
||||||
|
(void) strunvis(ptr, line);
|
||||||
|
line[sz] = c;
|
||||||
|
if (HENTER(h, &ev, ptr) == -1) {
|
||||||
|
h_free((ptr_t)ptr);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
oomem:
|
||||||
|
h_free((ptr_t)ptr);
|
||||||
|
done:
|
||||||
|
(void) fclose(fp);
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_save():
|
||||||
|
* History save function
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_save(History *h, const char *fname)
|
||||||
|
{
|
||||||
|
FILE *fp;
|
||||||
|
HistEvent ev;
|
||||||
|
int i = -1, retval;
|
||||||
|
size_t len, max_size;
|
||||||
|
char *ptr;
|
||||||
|
|
||||||
|
if ((fp = fopen(fname, "w")) == NULL)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1)
|
||||||
|
goto done;
|
||||||
|
if (fputs(hist_cookie, fp) == EOF)
|
||||||
|
goto done;
|
||||||
|
ptr = h_malloc(max_size = 1024);
|
||||||
|
if (ptr == NULL)
|
||||||
|
goto done;
|
||||||
|
for (i = 0, retval = HLAST(h, &ev);
|
||||||
|
retval != -1;
|
||||||
|
retval = HPREV(h, &ev), i++) {
|
||||||
|
len = strlen(ev.str) * 4;
|
||||||
|
if (len >= max_size) {
|
||||||
|
char *nptr;
|
||||||
|
max_size = (len + 1024) & ~1023;
|
||||||
|
nptr = h_realloc(ptr, max_size);
|
||||||
|
if (nptr == NULL) {
|
||||||
|
i = -1;
|
||||||
|
goto oomem;
|
||||||
|
}
|
||||||
|
ptr = nptr;
|
||||||
|
}
|
||||||
|
(void) strvis(ptr, ev.str, VIS_WHITE);
|
||||||
|
(void) fprintf(fp, "%s\n", ptr);
|
||||||
|
}
|
||||||
|
oomem:
|
||||||
|
h_free((ptr_t)ptr);
|
||||||
|
done:
|
||||||
|
(void) fclose(fp);
|
||||||
|
return (i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_prev_event():
|
||||||
|
* Find the previous event, with number given
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_prev_event(History *h, HistEvent *ev, int num)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
|
||||||
|
if (ev->num == num)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
he_seterrev(ev, _HE_NOT_FOUND);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_next_event():
|
||||||
|
* Find the next event, with number given
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_next_event(History *h, HistEvent *ev, int num)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
|
||||||
|
if (ev->num == num)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
he_seterrev(ev, _HE_NOT_FOUND);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_prev_string():
|
||||||
|
* Find the previous event beginning with string
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_prev_string(History *h, HistEvent *ev, const char *str)
|
||||||
|
{
|
||||||
|
size_t len = strlen(str);
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
|
||||||
|
if (strncmp(str, ev->str, len) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
he_seterrev(ev, _HE_NOT_FOUND);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history_next_string():
|
||||||
|
* Find the next event beginning with string
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
history_next_string(History *h, HistEvent *ev, const char *str)
|
||||||
|
{
|
||||||
|
size_t len = strlen(str);
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
|
||||||
|
if (strncmp(str, ev->str, len) == 0)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
he_seterrev(ev, _HE_NOT_FOUND);
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* history():
|
||||||
|
* User interface to history functions.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
history(History *h, HistEvent *ev, int fun, ...)
|
||||||
|
{
|
||||||
|
va_list va;
|
||||||
|
const char *str;
|
||||||
|
int retval;
|
||||||
|
|
||||||
|
va_start(va, fun);
|
||||||
|
|
||||||
|
he_seterrev(ev, _HE_OK);
|
||||||
|
|
||||||
|
switch (fun) {
|
||||||
|
case H_GETSIZE:
|
||||||
|
retval = history_getsize(h, ev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_SETSIZE:
|
||||||
|
retval = history_setsize(h, ev, va_arg(va, int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_GETUNIQUE:
|
||||||
|
retval = history_getunique(h, ev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_SETUNIQUE:
|
||||||
|
retval = history_setunique(h, ev, va_arg(va, int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_ADD:
|
||||||
|
str = va_arg(va, const char *);
|
||||||
|
retval = HADD(h, ev, str);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_DEL:
|
||||||
|
retval = HDEL(h, ev, va_arg(va, const int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_ENTER:
|
||||||
|
str = va_arg(va, const char *);
|
||||||
|
if ((retval = HENTER(h, ev, str)) != -1)
|
||||||
|
h->h_ent = ev->num;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_APPEND:
|
||||||
|
str = va_arg(va, const char *);
|
||||||
|
if ((retval = HSET(h, ev, h->h_ent)) != -1)
|
||||||
|
retval = HADD(h, ev, str);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_FIRST:
|
||||||
|
retval = HFIRST(h, ev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_NEXT:
|
||||||
|
retval = HNEXT(h, ev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_LAST:
|
||||||
|
retval = HLAST(h, ev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_PREV:
|
||||||
|
retval = HPREV(h, ev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_CURR:
|
||||||
|
retval = HCURR(h, ev);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_SET:
|
||||||
|
retval = HSET(h, ev, va_arg(va, const int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_CLEAR:
|
||||||
|
HCLEAR(h, ev);
|
||||||
|
retval = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_LOAD:
|
||||||
|
retval = history_load(h, va_arg(va, const char *));
|
||||||
|
if (retval == -1)
|
||||||
|
he_seterrev(ev, _HE_HIST_READ);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_SAVE:
|
||||||
|
retval = history_save(h, va_arg(va, const char *));
|
||||||
|
if (retval == -1)
|
||||||
|
he_seterrev(ev, _HE_HIST_WRITE);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_PREV_EVENT:
|
||||||
|
retval = history_prev_event(h, ev, va_arg(va, int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_NEXT_EVENT:
|
||||||
|
retval = history_next_event(h, ev, va_arg(va, int));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_PREV_STR:
|
||||||
|
retval = history_prev_string(h, ev, va_arg(va, const char *));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_NEXT_STR:
|
||||||
|
retval = history_next_string(h, ev, va_arg(va, const char *));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case H_FUNC:
|
||||||
|
{
|
||||||
|
History hf;
|
||||||
|
|
||||||
|
hf.h_ref = va_arg(va, ptr_t);
|
||||||
|
h->h_ent = -1;
|
||||||
|
hf.h_first = va_arg(va, history_gfun_t);
|
||||||
|
hf.h_next = va_arg(va, history_gfun_t);
|
||||||
|
hf.h_last = va_arg(va, history_gfun_t);
|
||||||
|
hf.h_prev = va_arg(va, history_gfun_t);
|
||||||
|
hf.h_curr = va_arg(va, history_gfun_t);
|
||||||
|
hf.h_set = va_arg(va, history_sfun_t);
|
||||||
|
hf.h_clear = va_arg(va, history_vfun_t);
|
||||||
|
hf.h_enter = va_arg(va, history_efun_t);
|
||||||
|
hf.h_add = va_arg(va, history_efun_t);
|
||||||
|
hf.h_del = va_arg(va, history_sfun_t);
|
||||||
|
|
||||||
|
if ((retval = history_set_fun(h, &hf)) == -1)
|
||||||
|
he_seterrev(ev, _HE_PARAM_MISSING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case H_END:
|
||||||
|
history_end(h);
|
||||||
|
retval = 0;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
retval = -1;
|
||||||
|
he_seterrev(ev, _HE_UNKNOWN);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
va_end(va);
|
||||||
|
return (retval);
|
||||||
|
}
|
|
@ -0,0 +1,706 @@
|
||||||
|
/* $NetBSD: key.c,v 1.19 2006/03/23 20:22:51 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: key.c,v 1.19 2006/03/23 20:22:51 christos Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* key.c: This module contains the procedures for maintaining
|
||||||
|
* the extended-key map.
|
||||||
|
*
|
||||||
|
* An extended-key (key) is a sequence of keystrokes introduced
|
||||||
|
* with a sequence introducer and consisting of an arbitrary
|
||||||
|
* number of characters. This module maintains a map (the el->el_key.map)
|
||||||
|
* to convert these extended-key sequences into input strs
|
||||||
|
* (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE).
|
||||||
|
*
|
||||||
|
* Warning:
|
||||||
|
* If key is a substr of some other keys, then the longer
|
||||||
|
* keys are lost!! That is, if the keys "abcd" and "abcef"
|
||||||
|
* are in el->el_key.map, adding the key "abc" will cause the first two
|
||||||
|
* definitions to be lost.
|
||||||
|
*
|
||||||
|
* Restrictions:
|
||||||
|
* -------------
|
||||||
|
* 1) It is not possible to have one key that is a
|
||||||
|
* substr of another.
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "el.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The Nodes of the el->el_key.map. The el->el_key.map is a linked list
|
||||||
|
* of these node elements
|
||||||
|
*/
|
||||||
|
struct key_node_t {
|
||||||
|
char ch; /* single character of key */
|
||||||
|
int type; /* node type */
|
||||||
|
key_value_t val; /* command code or pointer to str, */
|
||||||
|
/* if this is a leaf */
|
||||||
|
struct key_node_t *next; /* ptr to next char of this key */
|
||||||
|
struct key_node_t *sibling; /* ptr to another key with same prefix*/
|
||||||
|
};
|
||||||
|
|
||||||
|
private int node_trav(EditLine *, key_node_t *, char *,
|
||||||
|
key_value_t *);
|
||||||
|
private int node__try(EditLine *, key_node_t *, const char *,
|
||||||
|
key_value_t *, int);
|
||||||
|
private key_node_t *node__get(int);
|
||||||
|
private void node__free(key_node_t *);
|
||||||
|
private void node__put(EditLine *, key_node_t *);
|
||||||
|
private int node__delete(EditLine *, key_node_t **, const char *);
|
||||||
|
private int node_lookup(EditLine *, const char *, key_node_t *,
|
||||||
|
int);
|
||||||
|
private int node_enum(EditLine *, key_node_t *, int);
|
||||||
|
|
||||||
|
#define KEY_BUFSIZ EL_BUFSIZ
|
||||||
|
|
||||||
|
|
||||||
|
/* key_init():
|
||||||
|
* Initialize the key maps
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
key_init(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ);
|
||||||
|
if (el->el_key.buf == NULL)
|
||||||
|
return (-1);
|
||||||
|
el->el_key.map = NULL;
|
||||||
|
key_reset(el);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* key_end():
|
||||||
|
* Free the key maps
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
key_end(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
el_free((ptr_t) el->el_key.buf);
|
||||||
|
el->el_key.buf = NULL;
|
||||||
|
node__free(el->el_key.map);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* key_map_cmd():
|
||||||
|
* Associate cmd with a key value
|
||||||
|
*/
|
||||||
|
protected key_value_t *
|
||||||
|
key_map_cmd(EditLine *el, int cmd)
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_key.val.cmd = (el_action_t) cmd;
|
||||||
|
return (&el->el_key.val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* key_map_str():
|
||||||
|
* Associate str with a key value
|
||||||
|
*/
|
||||||
|
protected key_value_t *
|
||||||
|
key_map_str(EditLine *el, char *str)
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_key.val.str = str;
|
||||||
|
return (&el->el_key.val);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* key_reset():
|
||||||
|
* Takes all nodes on el->el_key.map and puts them on free list. Then
|
||||||
|
* initializes el->el_key.map with arrow keys
|
||||||
|
* [Always bind the ansi arrow keys?]
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
key_reset(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
node__put(el, el->el_key.map);
|
||||||
|
el->el_key.map = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* key_get():
|
||||||
|
* Calls the recursive function with entry point el->el_key.map
|
||||||
|
* Looks up *ch in map and then reads characters until a
|
||||||
|
* complete match is found or a mismatch occurs. Returns the
|
||||||
|
* type of the match found (XK_STR, XK_CMD, or XK_EXE).
|
||||||
|
* Returns NULL in val.str and XK_STR for no match.
|
||||||
|
* The last character read is returned in *ch.
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
key_get(EditLine *el, char *ch, key_value_t *val)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (node_trav(el, el->el_key.map, ch, val));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* key_add():
|
||||||
|
* Adds key to the el->el_key.map and associates the value in val with it.
|
||||||
|
* If key is already is in el->el_key.map, the new code is applied to the
|
||||||
|
* existing key. Ntype specifies if code is a command, an
|
||||||
|
* out str or a unix command.
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
key_add(EditLine *el, const char *key, key_value_t *val, int ntype)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (key[0] == '\0') {
|
||||||
|
(void) fprintf(el->el_errfile,
|
||||||
|
"key_add: Null extended-key not allowed.\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) {
|
||||||
|
(void) fprintf(el->el_errfile,
|
||||||
|
"key_add: sequence-lead-in command not allowed\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (el->el_key.map == NULL)
|
||||||
|
/* tree is initially empty. Set up new node to match key[0] */
|
||||||
|
el->el_key.map = node__get(key[0]);
|
||||||
|
/* it is properly initialized */
|
||||||
|
|
||||||
|
/* Now recurse through el->el_key.map */
|
||||||
|
(void) node__try(el, el->el_key.map, key, val, ntype);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* key_clear():
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
key_clear(EditLine *el, el_action_t *map, const char *in)
|
||||||
|
{
|
||||||
|
|
||||||
|
if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) &&
|
||||||
|
((map == el->el_map.key &&
|
||||||
|
el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) ||
|
||||||
|
(map == el->el_map.alt &&
|
||||||
|
el->el_map.key[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN)))
|
||||||
|
(void) key_delete(el, in);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* key_delete():
|
||||||
|
* Delete the key and all longer keys staring with key, if
|
||||||
|
* they exists.
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
key_delete(EditLine *el, const char *key)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (key[0] == '\0') {
|
||||||
|
(void) fprintf(el->el_errfile,
|
||||||
|
"key_delete: Null extended-key not allowed.\n");
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
if (el->el_key.map == NULL)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
(void) node__delete(el, &el->el_key.map, key);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* key_print():
|
||||||
|
* Print the binding associated with key key.
|
||||||
|
* Print entire el->el_key.map if null
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
key_print(EditLine *el, const char *key)
|
||||||
|
{
|
||||||
|
|
||||||
|
/* do nothing if el->el_key.map is empty and null key specified */
|
||||||
|
if (el->el_key.map == NULL && *key == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
el->el_key.buf[0] = '"';
|
||||||
|
if (node_lookup(el, key, el->el_key.map, 1) <= -1)
|
||||||
|
/* key is not bound */
|
||||||
|
(void) fprintf(el->el_errfile, "Unbound extended key \"%s\"\n",
|
||||||
|
key);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* node_trav():
|
||||||
|
* recursively traverses node in tree until match or mismatch is
|
||||||
|
* found. May read in more characters.
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
node_trav(EditLine *el, key_node_t *ptr, char *ch, key_value_t *val)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ptr->ch == *ch) {
|
||||||
|
/* match found */
|
||||||
|
if (ptr->next) {
|
||||||
|
/* key not complete so get next char */
|
||||||
|
if (el_getc(el, ch) != 1) { /* if EOF or error */
|
||||||
|
val->cmd = ED_END_OF_FILE;
|
||||||
|
return (XK_CMD);
|
||||||
|
/* PWP: Pretend we just read an end-of-file */
|
||||||
|
}
|
||||||
|
return (node_trav(el, ptr->next, ch, val));
|
||||||
|
} else {
|
||||||
|
*val = ptr->val;
|
||||||
|
if (ptr->type != XK_CMD)
|
||||||
|
*ch = '\0';
|
||||||
|
return (ptr->type);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* no match found here */
|
||||||
|
if (ptr->sibling) {
|
||||||
|
/* try next sibling */
|
||||||
|
return (node_trav(el, ptr->sibling, ch, val));
|
||||||
|
} else {
|
||||||
|
/* no next sibling -- mismatch */
|
||||||
|
val->str = NULL;
|
||||||
|
return (XK_STR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* node__try():
|
||||||
|
* Find a node that matches *str or allocate a new one
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int ntype)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (ptr->ch != *str) {
|
||||||
|
key_node_t *xm;
|
||||||
|
|
||||||
|
for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
|
||||||
|
if (xm->sibling->ch == *str)
|
||||||
|
break;
|
||||||
|
if (xm->sibling == NULL)
|
||||||
|
xm->sibling = node__get(*str); /* setup new node */
|
||||||
|
ptr = xm->sibling;
|
||||||
|
}
|
||||||
|
if (*++str == '\0') {
|
||||||
|
/* we're there */
|
||||||
|
if (ptr->next != NULL) {
|
||||||
|
node__put(el, ptr->next);
|
||||||
|
/* lose longer keys with this prefix */
|
||||||
|
ptr->next = NULL;
|
||||||
|
}
|
||||||
|
switch (ptr->type) {
|
||||||
|
case XK_CMD:
|
||||||
|
case XK_NOD:
|
||||||
|
break;
|
||||||
|
case XK_STR:
|
||||||
|
case XK_EXE:
|
||||||
|
if (ptr->val.str)
|
||||||
|
el_free((ptr_t) ptr->val.str);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n",
|
||||||
|
ptr->type));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (ptr->type = ntype) {
|
||||||
|
case XK_CMD:
|
||||||
|
ptr->val = *val;
|
||||||
|
break;
|
||||||
|
case XK_STR:
|
||||||
|
case XK_EXE:
|
||||||
|
if ((ptr->val.str = el_strdup(val->str)) == NULL)
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* still more chars to go */
|
||||||
|
if (ptr->next == NULL)
|
||||||
|
ptr->next = node__get(*str); /* setup new node */
|
||||||
|
(void) node__try(el, ptr->next, str, val, ntype);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* node__delete():
|
||||||
|
* Delete node that matches str
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
node__delete(EditLine *el, key_node_t **inptr, const char *str)
|
||||||
|
{
|
||||||
|
key_node_t *ptr;
|
||||||
|
key_node_t *prev_ptr = NULL;
|
||||||
|
|
||||||
|
ptr = *inptr;
|
||||||
|
|
||||||
|
if (ptr->ch != *str) {
|
||||||
|
key_node_t *xm;
|
||||||
|
|
||||||
|
for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
|
||||||
|
if (xm->sibling->ch == *str)
|
||||||
|
break;
|
||||||
|
if (xm->sibling == NULL)
|
||||||
|
return (0);
|
||||||
|
prev_ptr = xm;
|
||||||
|
ptr = xm->sibling;
|
||||||
|
}
|
||||||
|
if (*++str == '\0') {
|
||||||
|
/* we're there */
|
||||||
|
if (prev_ptr == NULL)
|
||||||
|
*inptr = ptr->sibling;
|
||||||
|
else
|
||||||
|
prev_ptr->sibling = ptr->sibling;
|
||||||
|
ptr->sibling = NULL;
|
||||||
|
node__put(el, ptr);
|
||||||
|
return (1);
|
||||||
|
} else if (ptr->next != NULL &&
|
||||||
|
node__delete(el, &ptr->next, str) == 1) {
|
||||||
|
if (ptr->next != NULL)
|
||||||
|
return (0);
|
||||||
|
if (prev_ptr == NULL)
|
||||||
|
*inptr = ptr->sibling;
|
||||||
|
else
|
||||||
|
prev_ptr->sibling = ptr->sibling;
|
||||||
|
ptr->sibling = NULL;
|
||||||
|
node__put(el, ptr);
|
||||||
|
return (1);
|
||||||
|
} else {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* node__put():
|
||||||
|
* Puts a tree of nodes onto free list using free(3).
|
||||||
|
*/
|
||||||
|
private void
|
||||||
|
node__put(EditLine *el, key_node_t *ptr)
|
||||||
|
{
|
||||||
|
if (ptr == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ptr->next != NULL) {
|
||||||
|
node__put(el, ptr->next);
|
||||||
|
ptr->next = NULL;
|
||||||
|
}
|
||||||
|
node__put(el, ptr->sibling);
|
||||||
|
|
||||||
|
switch (ptr->type) {
|
||||||
|
case XK_CMD:
|
||||||
|
case XK_NOD:
|
||||||
|
break;
|
||||||
|
case XK_EXE:
|
||||||
|
case XK_STR:
|
||||||
|
if (ptr->val.str != NULL)
|
||||||
|
el_free((ptr_t) ptr->val.str);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ptr->type));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
el_free((ptr_t) ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* node__get():
|
||||||
|
* Returns pointer to a key_node_t for ch.
|
||||||
|
*/
|
||||||
|
private key_node_t *
|
||||||
|
node__get(int ch)
|
||||||
|
{
|
||||||
|
key_node_t *ptr;
|
||||||
|
|
||||||
|
ptr = (key_node_t *) el_malloc((size_t) sizeof(key_node_t));
|
||||||
|
if (ptr == NULL)
|
||||||
|
return NULL;
|
||||||
|
ptr->ch = ch;
|
||||||
|
ptr->type = XK_NOD;
|
||||||
|
ptr->val.str = NULL;
|
||||||
|
ptr->next = NULL;
|
||||||
|
ptr->sibling = NULL;
|
||||||
|
return (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void
|
||||||
|
node__free(key_node_t *k)
|
||||||
|
{
|
||||||
|
if (k == NULL)
|
||||||
|
return;
|
||||||
|
node__free(k->sibling);
|
||||||
|
node__free(k->next);
|
||||||
|
el_free((ptr_t) k);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* node_lookup():
|
||||||
|
* look for the str starting at node ptr.
|
||||||
|
* Print if last node
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
|
||||||
|
{
|
||||||
|
int ncnt;
|
||||||
|
|
||||||
|
if (ptr == NULL)
|
||||||
|
return (-1); /* cannot have null ptr */
|
||||||
|
|
||||||
|
if (*str == 0) {
|
||||||
|
/* no more chars in str. node_enum from here. */
|
||||||
|
(void) node_enum(el, ptr, cnt);
|
||||||
|
return (0);
|
||||||
|
} else {
|
||||||
|
/* If match put this char into el->el_key.buf. Recurse */
|
||||||
|
if (ptr->ch == *str) {
|
||||||
|
/* match found */
|
||||||
|
ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt,
|
||||||
|
(unsigned char) ptr->ch);
|
||||||
|
if (ptr->next != NULL)
|
||||||
|
/* not yet at leaf */
|
||||||
|
return (node_lookup(el, str + 1, ptr->next,
|
||||||
|
ncnt + 1));
|
||||||
|
else {
|
||||||
|
/* next node is null so key should be complete */
|
||||||
|
if (str[1] == 0) {
|
||||||
|
el->el_key.buf[ncnt + 1] = '"';
|
||||||
|
el->el_key.buf[ncnt + 2] = '\0';
|
||||||
|
key_kprint(el, el->el_key.buf,
|
||||||
|
&ptr->val, ptr->type);
|
||||||
|
return (0);
|
||||||
|
} else
|
||||||
|
return (-1);
|
||||||
|
/* mismatch -- str still has chars */
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* no match found try sibling */
|
||||||
|
if (ptr->sibling)
|
||||||
|
return (node_lookup(el, str, ptr->sibling,
|
||||||
|
cnt));
|
||||||
|
else
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* node_enum():
|
||||||
|
* Traverse the node printing the characters it is bound in buffer
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
node_enum(EditLine *el, key_node_t *ptr, int cnt)
|
||||||
|
{
|
||||||
|
int ncnt;
|
||||||
|
|
||||||
|
if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */
|
||||||
|
el->el_key.buf[++cnt] = '"';
|
||||||
|
el->el_key.buf[++cnt] = '\0';
|
||||||
|
(void) fprintf(el->el_errfile,
|
||||||
|
"Some extended keys too long for internal print buffer");
|
||||||
|
(void) fprintf(el->el_errfile, " \"%s...\"\n", el->el_key.buf);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if (ptr == NULL) {
|
||||||
|
#ifdef DEBUG_EDIT
|
||||||
|
(void) fprintf(el->el_errfile,
|
||||||
|
"node_enum: BUG!! Null ptr passed\n!");
|
||||||
|
#endif
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
/* put this char at end of str */
|
||||||
|
ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt,
|
||||||
|
(unsigned char)ptr->ch);
|
||||||
|
if (ptr->next == NULL) {
|
||||||
|
/* print this key and function */
|
||||||
|
el->el_key.buf[ncnt + 1] = '"';
|
||||||
|
el->el_key.buf[ncnt + 2] = '\0';
|
||||||
|
key_kprint(el, el->el_key.buf, &ptr->val, ptr->type);
|
||||||
|
} else
|
||||||
|
(void) node_enum(el, ptr->next, ncnt + 1);
|
||||||
|
|
||||||
|
/* go to sibling if there is one */
|
||||||
|
if (ptr->sibling)
|
||||||
|
(void) node_enum(el, ptr->sibling, cnt);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* key_kprint():
|
||||||
|
* Print the specified key and its associated
|
||||||
|
* function specified by val
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
|
||||||
|
{
|
||||||
|
el_bindings_t *fp;
|
||||||
|
char unparsbuf[EL_BUFSIZ];
|
||||||
|
static const char fmt[] = "%-15s-> %s\n";
|
||||||
|
|
||||||
|
if (val != NULL)
|
||||||
|
switch (ntype) {
|
||||||
|
case XK_STR:
|
||||||
|
case XK_EXE:
|
||||||
|
(void) key__decode_str(val->str, unparsbuf,
|
||||||
|
sizeof(unparsbuf),
|
||||||
|
ntype == XK_STR ? "\"\"" : "[]");
|
||||||
|
(void) fprintf(el->el_outfile, fmt, key, unparsbuf);
|
||||||
|
break;
|
||||||
|
case XK_CMD:
|
||||||
|
for (fp = el->el_map.help; fp->name; fp++)
|
||||||
|
if (val->cmd == fp->func) {
|
||||||
|
(void) fprintf(el->el_outfile, fmt,
|
||||||
|
key, fp->name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef DEBUG_KEY
|
||||||
|
if (fp->name == NULL)
|
||||||
|
(void) fprintf(el->el_outfile,
|
||||||
|
"BUG! Command not found.\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
(void) fprintf(el->el_outfile, fmt, key, "no input");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define ADDC(c) \
|
||||||
|
if (b < eb) \
|
||||||
|
*b++ = c; \
|
||||||
|
else \
|
||||||
|
b++
|
||||||
|
/* key__decode_char():
|
||||||
|
* Put a printable form of char in buf.
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
key__decode_char(char *buf, int cnt, int off, int ch)
|
||||||
|
{
|
||||||
|
char *sb = buf + off;
|
||||||
|
char *eb = buf + cnt;
|
||||||
|
char *b = sb;
|
||||||
|
if (ch == 0) {
|
||||||
|
ADDC('^');
|
||||||
|
ADDC('@');
|
||||||
|
return b - sb;
|
||||||
|
}
|
||||||
|
if (iscntrl(ch)) {
|
||||||
|
ADDC('^');
|
||||||
|
if (ch == '\177')
|
||||||
|
ADDC('?');
|
||||||
|
else
|
||||||
|
ADDC(ch | 0100);
|
||||||
|
} else if (ch == '^') {
|
||||||
|
ADDC('\\');
|
||||||
|
ADDC('^');
|
||||||
|
} else if (ch == '\\') {
|
||||||
|
ADDC('\\');
|
||||||
|
ADDC('\\');
|
||||||
|
} else if (ch == ' ' || (isprint(ch) && !isspace(ch))) {
|
||||||
|
ADDC(ch);
|
||||||
|
} else {
|
||||||
|
ADDC('\\');
|
||||||
|
ADDC((((unsigned int) ch >> 6) & 7) + '0');
|
||||||
|
ADDC((((unsigned int) ch >> 3) & 7) + '0');
|
||||||
|
ADDC((ch & 7) + '0');
|
||||||
|
}
|
||||||
|
return b - sb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* key__decode_str():
|
||||||
|
* Make a printable version of the ey
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
key__decode_str(const char *str, char *buf, int len, const char *sep)
|
||||||
|
{
|
||||||
|
char *b = buf, *eb = b + len;
|
||||||
|
const char *p;
|
||||||
|
|
||||||
|
b = buf;
|
||||||
|
if (sep[0] != '\0') {
|
||||||
|
ADDC(sep[0]);
|
||||||
|
}
|
||||||
|
if (*str == '\0') {
|
||||||
|
ADDC('^');
|
||||||
|
ADDC('@');
|
||||||
|
if (sep[0] != '\0' && sep[1] != '\0') {
|
||||||
|
ADDC(sep[1]);
|
||||||
|
}
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
|
for (p = str; *p != 0; p++) {
|
||||||
|
if (iscntrl((unsigned char) *p)) {
|
||||||
|
ADDC('^');
|
||||||
|
if (*p == '\177') {
|
||||||
|
ADDC('?');
|
||||||
|
} else {
|
||||||
|
ADDC(*p | 0100);
|
||||||
|
}
|
||||||
|
} else if (*p == '^' || *p == '\\') {
|
||||||
|
ADDC('\\');
|
||||||
|
ADDC(*p);
|
||||||
|
} else if (*p == ' ' || (isprint((unsigned char) *p) &&
|
||||||
|
!isspace((unsigned char) *p))) {
|
||||||
|
ADDC(*p);
|
||||||
|
} else {
|
||||||
|
ADDC('\\');
|
||||||
|
ADDC((((unsigned int) *p >> 6) & 7) + '0');
|
||||||
|
ADDC((((unsigned int) *p >> 3) & 7) + '0');
|
||||||
|
ADDC((*p & 7) + '0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (sep[0] != '\0' && sep[1] != '\0') {
|
||||||
|
ADDC(sep[1]);
|
||||||
|
}
|
||||||
|
done:
|
||||||
|
ADDC('\0');
|
||||||
|
if (b - buf >= len)
|
||||||
|
buf[len - 1] = '\0';
|
||||||
|
return b - buf;
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/* $NetBSD: key.h,v 1.10 2006/03/23 20:22:51 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)key.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.key.h: Key macro header
|
||||||
|
*/
|
||||||
|
#ifndef _h_el_key
|
||||||
|
#define _h_el_key
|
||||||
|
|
||||||
|
typedef union key_value_t {
|
||||||
|
el_action_t cmd; /* If it is a command the # */
|
||||||
|
char *str; /* If it is a string... */
|
||||||
|
} key_value_t;
|
||||||
|
|
||||||
|
typedef struct key_node_t key_node_t;
|
||||||
|
|
||||||
|
typedef struct el_key_t {
|
||||||
|
char *buf; /* Key print buffer */
|
||||||
|
key_node_t *map; /* Key map */
|
||||||
|
key_value_t val; /* Local conversion buffer */
|
||||||
|
} el_key_t;
|
||||||
|
|
||||||
|
#define XK_CMD 0
|
||||||
|
#define XK_STR 1
|
||||||
|
#define XK_NOD 2
|
||||||
|
#define XK_EXE 3
|
||||||
|
|
||||||
|
#undef key_end
|
||||||
|
#undef key_clear
|
||||||
|
#undef key_print
|
||||||
|
|
||||||
|
protected int key_init(EditLine *);
|
||||||
|
protected void key_end(EditLine *);
|
||||||
|
protected key_value_t *key_map_cmd(EditLine *, int);
|
||||||
|
protected key_value_t *key_map_str(EditLine *, char *);
|
||||||
|
protected void key_reset(EditLine *);
|
||||||
|
protected int key_get(EditLine *, char *, key_value_t *);
|
||||||
|
protected void key_add(EditLine *, const char *, key_value_t *, int);
|
||||||
|
protected void key_clear(EditLine *, el_action_t *, const char *);
|
||||||
|
protected int key_delete(EditLine *, const char *);
|
||||||
|
protected void key_print(EditLine *, const char *);
|
||||||
|
protected void key_kprint(EditLine *, const char *, key_value_t *,
|
||||||
|
int);
|
||||||
|
protected int key__decode_str(const char *, char *, int,
|
||||||
|
const char *);
|
||||||
|
protected int key__decode_char(char *, int, int, int);
|
||||||
|
|
||||||
|
#endif /* _h_el_key */
|
|
@ -0,0 +1,249 @@
|
||||||
|
#!/bin/sh -
|
||||||
|
# $NetBSD: makelist,v 1.11 2005/10/22 16:45:03 christos Exp $
|
||||||
|
#
|
||||||
|
# Copyright (c) 1992, 1993
|
||||||
|
# The Regents of the University of California. All rights reserved.
|
||||||
|
#
|
||||||
|
# This code is derived from software contributed to Berkeley by
|
||||||
|
# Christos Zoulas of Cornell University.
|
||||||
|
#
|
||||||
|
# Redistribution and use in source and binary forms, with or without
|
||||||
|
# modification, are permitted provided that the following conditions
|
||||||
|
# are met:
|
||||||
|
# 1. Redistributions of source code must retain the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer.
|
||||||
|
# 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
# notice, this list of conditions and the following disclaimer in the
|
||||||
|
# documentation and/or other materials provided with the distribution.
|
||||||
|
# 3. Neither the name of the University nor the names of its contributors
|
||||||
|
# may be used to endorse or promote products derived from this software
|
||||||
|
# without specific prior written permission.
|
||||||
|
#
|
||||||
|
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
# SUCH DAMAGE.
|
||||||
|
#
|
||||||
|
# @(#)makelist 5.3 (Berkeley) 6/4/93
|
||||||
|
|
||||||
|
# makelist.sh: Automatically generate header files...
|
||||||
|
|
||||||
|
AWK=awk
|
||||||
|
USAGE="Usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
|
||||||
|
|
||||||
|
if [ "x$1" = "x" ]
|
||||||
|
then
|
||||||
|
echo $USAGE 1>&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
FLAG="$1"
|
||||||
|
shift
|
||||||
|
|
||||||
|
FILES="$@"
|
||||||
|
|
||||||
|
case $FLAG in
|
||||||
|
|
||||||
|
# generate foo.h file from foo.c
|
||||||
|
#
|
||||||
|
-h)
|
||||||
|
set - `echo $FILES | sed -e 's/\\./_/g'`
|
||||||
|
hdr="_h_`basename $1`"
|
||||||
|
cat $FILES | $AWK '
|
||||||
|
BEGIN {
|
||||||
|
printf("/* Automatically generated file, do not edit */\n");
|
||||||
|
printf("#ifndef %s\n#define %s\n", "'$hdr'", "'$hdr'");
|
||||||
|
}
|
||||||
|
/\(\):/ {
|
||||||
|
pr = substr($2, 1, 2);
|
||||||
|
if (pr == "vi" || pr == "em" || pr == "ed") {
|
||||||
|
name = substr($2, 1, length($2) - 3);
|
||||||
|
#
|
||||||
|
# XXX: need a space between name and prototype so that -fc and -fh
|
||||||
|
# parsing is much easier
|
||||||
|
#
|
||||||
|
printf("protected el_action_t\t%s (EditLine *, int);\n", name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
printf("#endif /* %s */\n", "'$hdr'");
|
||||||
|
}'
|
||||||
|
;;
|
||||||
|
|
||||||
|
# generate help.c from various .c files
|
||||||
|
#
|
||||||
|
-bc)
|
||||||
|
cat $FILES | $AWK '
|
||||||
|
BEGIN {
|
||||||
|
printf("/* Automatically generated file, do not edit */\n");
|
||||||
|
printf("#include \"sys.h\"\n#include \"el.h\"\n");
|
||||||
|
printf("private const struct el_bindings_t el_func_help[] = {\n");
|
||||||
|
low = "abcdefghijklmnopqrstuvwxyz_";
|
||||||
|
high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_";
|
||||||
|
for (i = 1; i <= length(low); i++)
|
||||||
|
tr[substr(low, i, 1)] = substr(high, i, 1);
|
||||||
|
}
|
||||||
|
/\(\):/ {
|
||||||
|
pr = substr($2, 1, 2);
|
||||||
|
if (pr == "vi" || pr == "em" || pr == "ed") {
|
||||||
|
name = substr($2, 1, length($2) - 3);
|
||||||
|
uname = "";
|
||||||
|
fname = "";
|
||||||
|
for (i = 1; i <= length(name); i++) {
|
||||||
|
s = substr(name, i, 1);
|
||||||
|
uname = uname tr[s];
|
||||||
|
if (s == "_")
|
||||||
|
s = "-";
|
||||||
|
fname = fname s;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(" { %-30.30s %-30.30s\n","\"" fname "\",", uname ",");
|
||||||
|
ok = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/^ \*/ {
|
||||||
|
if (ok) {
|
||||||
|
printf(" \"");
|
||||||
|
for (i = 2; i < NF; i++)
|
||||||
|
printf("%s ", $i);
|
||||||
|
printf("%s\" },\n", $i);
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
printf("};\n");
|
||||||
|
printf("\nprotected const el_bindings_t* help__get()");
|
||||||
|
printf("{ return el_func_help; }\n");
|
||||||
|
}'
|
||||||
|
;;
|
||||||
|
|
||||||
|
# generate help.h from various .c files
|
||||||
|
#
|
||||||
|
-bh)
|
||||||
|
$AWK '
|
||||||
|
BEGIN {
|
||||||
|
printf("/* Automatically generated file, do not edit */\n");
|
||||||
|
printf("#ifndef _h_help_c\n#define _h_help_c\n");
|
||||||
|
printf("protected const el_bindings_t *help__get(void);\n");
|
||||||
|
printf("#endif /* _h_help_c */\n");
|
||||||
|
}' /dev/null
|
||||||
|
;;
|
||||||
|
|
||||||
|
# generate fcns.h from various .h files
|
||||||
|
#
|
||||||
|
-fh)
|
||||||
|
cat $FILES | $AWK '/el_action_t/ { print $3 }' | \
|
||||||
|
sort | tr '[:lower:]' '[:upper:]' | $AWK '
|
||||||
|
BEGIN {
|
||||||
|
printf("/* Automatically generated file, do not edit */\n");
|
||||||
|
printf("#ifndef _h_fcns_c\n#define _h_fcns_c\n");
|
||||||
|
count = 0;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
printf("#define\t%-30.30s\t%3d\n", $1, count++);
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
printf("#define\t%-30.30s\t%3d\n", "EL_NUM_FCNS", count);
|
||||||
|
|
||||||
|
printf("typedef el_action_t (*el_func_t)(EditLine *, int);");
|
||||||
|
printf("\nprotected const el_func_t* func__get(void);\n");
|
||||||
|
printf("#endif /* _h_fcns_c */\n");
|
||||||
|
}'
|
||||||
|
;;
|
||||||
|
|
||||||
|
# generate fcns.c from various .h files
|
||||||
|
#
|
||||||
|
-fc)
|
||||||
|
cat $FILES | $AWK '/el_action_t/ { print $3 }' | sort | $AWK '
|
||||||
|
BEGIN {
|
||||||
|
printf("/* Automatically generated file, do not edit */\n");
|
||||||
|
printf("#include \"sys.h\"\n#include \"el.h\"\n");
|
||||||
|
printf("private const el_func_t el_func[] = {");
|
||||||
|
maxlen = 80;
|
||||||
|
needn = 1;
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
clen = 25 + 2;
|
||||||
|
len += clen;
|
||||||
|
if (len >= maxlen)
|
||||||
|
needn = 1;
|
||||||
|
if (needn) {
|
||||||
|
printf("\n ");
|
||||||
|
needn = 0;
|
||||||
|
len = 4 + clen;
|
||||||
|
}
|
||||||
|
s = $1 ",";
|
||||||
|
printf("%-26.26s ", s);
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
printf("\n};\n");
|
||||||
|
printf("\nprotected const el_func_t* func__get() { return el_func; }\n");
|
||||||
|
}'
|
||||||
|
;;
|
||||||
|
|
||||||
|
# generate editline.c from various .c files
|
||||||
|
#
|
||||||
|
-e)
|
||||||
|
echo "$FILES" | tr ' ' '\012' | $AWK '
|
||||||
|
BEGIN {
|
||||||
|
printf("/* Automatically generated file, do not edit */\n");
|
||||||
|
printf("#define protected static\n");
|
||||||
|
printf("#define SCCSID\n");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
printf("#include \"%s\"\n", $1);
|
||||||
|
}'
|
||||||
|
;;
|
||||||
|
|
||||||
|
# generate man page fragment from various .c files
|
||||||
|
#
|
||||||
|
-m)
|
||||||
|
cat $FILES | $AWK '
|
||||||
|
BEGIN {
|
||||||
|
printf(".\\\" Section automatically generated with makelist\n");
|
||||||
|
printf(".Bl -tag -width 4n\n");
|
||||||
|
}
|
||||||
|
/\(\):/ {
|
||||||
|
pr = substr($2, 1, 2);
|
||||||
|
if (pr == "vi" || pr == "em" || pr == "ed") {
|
||||||
|
name = substr($2, 1, length($2) - 3);
|
||||||
|
fname = "";
|
||||||
|
for (i = 1; i <= length(name); i++) {
|
||||||
|
s = substr(name, i, 1);
|
||||||
|
if (s == "_")
|
||||||
|
s = "-";
|
||||||
|
fname = fname s;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(".It Ic %s\n", fname);
|
||||||
|
ok = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/^ \*/ {
|
||||||
|
if (ok) {
|
||||||
|
for (i = 2; i < NF; i++)
|
||||||
|
printf("%s ", $i);
|
||||||
|
printf("%s.\n", $i);
|
||||||
|
ok = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
END {
|
||||||
|
printf(".El\n");
|
||||||
|
printf(".\\\" End of section automatically generated with makelist\n");
|
||||||
|
}'
|
||||||
|
;;
|
||||||
|
|
||||||
|
*)
|
||||||
|
echo $USAGE 1>&2
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
|
||||||
|
esac
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,75 @@
|
||||||
|
/* $NetBSD: map.h,v 1.8 2003/08/07 16:44:32 agc Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)map.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.map.h: Editor maps
|
||||||
|
*/
|
||||||
|
#ifndef _h_el_map
|
||||||
|
#define _h_el_map
|
||||||
|
|
||||||
|
typedef struct el_bindings_t { /* for the "bind" shell command */
|
||||||
|
const char *name; /* function name for bind command */
|
||||||
|
int func; /* function numeric value */
|
||||||
|
const char *description; /* description of function */
|
||||||
|
} el_bindings_t;
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct el_map_t {
|
||||||
|
el_action_t *alt; /* The current alternate key map */
|
||||||
|
el_action_t *key; /* The current normal key map */
|
||||||
|
el_action_t *current; /* The keymap we are using */
|
||||||
|
const el_action_t *emacs; /* The default emacs key map */
|
||||||
|
const el_action_t *vic; /* The vi command mode key map */
|
||||||
|
const el_action_t *vii; /* The vi insert mode key map */
|
||||||
|
int type; /* Emacs or vi */
|
||||||
|
el_bindings_t *help; /* The help for the editor functions */
|
||||||
|
el_func_t *func; /* List of available functions */
|
||||||
|
int nfunc; /* The number of functions/help items */
|
||||||
|
} el_map_t;
|
||||||
|
|
||||||
|
#define MAP_EMACS 0
|
||||||
|
#define MAP_VI 1
|
||||||
|
|
||||||
|
protected int map_bind(EditLine *, int, const char **);
|
||||||
|
protected int map_init(EditLine *);
|
||||||
|
protected void map_end(EditLine *);
|
||||||
|
protected void map_init_vi(EditLine *);
|
||||||
|
protected void map_init_emacs(EditLine *);
|
||||||
|
protected int map_set_editor(EditLine *, char *);
|
||||||
|
protected int map_get_editor(EditLine *, const char **);
|
||||||
|
protected int map_addfunc(EditLine *, const char *, const char *, el_func_t);
|
||||||
|
|
||||||
|
#endif /* _h_el_map */
|
|
@ -0,0 +1,263 @@
|
||||||
|
/* $NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* parse.c: parse an editline extended command
|
||||||
|
*
|
||||||
|
* commands are:
|
||||||
|
*
|
||||||
|
* bind
|
||||||
|
* echotc
|
||||||
|
* edit
|
||||||
|
* gettc
|
||||||
|
* history
|
||||||
|
* settc
|
||||||
|
* setty
|
||||||
|
*/
|
||||||
|
#include "el.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
private const struct {
|
||||||
|
const char *name;
|
||||||
|
int (*func)(EditLine *, int, const char **);
|
||||||
|
} cmds[] = {
|
||||||
|
{ "bind", map_bind },
|
||||||
|
{ "echotc", term_echotc },
|
||||||
|
{ "edit", el_editmode },
|
||||||
|
{ "history", hist_command },
|
||||||
|
{ "telltc", term_telltc },
|
||||||
|
{ "settc", term_settc },
|
||||||
|
{ "setty", tty_stty },
|
||||||
|
{ NULL, NULL }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* parse_line():
|
||||||
|
* Parse a line and dispatch it
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
parse_line(EditLine *el, const char *line)
|
||||||
|
{
|
||||||
|
const char **argv;
|
||||||
|
int argc;
|
||||||
|
Tokenizer *tok;
|
||||||
|
|
||||||
|
tok = tok_init(NULL);
|
||||||
|
tok_str(tok, line, &argc, &argv);
|
||||||
|
argc = el_parse(el, argc, argv);
|
||||||
|
tok_end(tok);
|
||||||
|
return (argc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_parse():
|
||||||
|
* Command dispatcher
|
||||||
|
*/
|
||||||
|
public int
|
||||||
|
el_parse(EditLine *el, int argc, const char *argv[])
|
||||||
|
{
|
||||||
|
const char *ptr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (argc < 1)
|
||||||
|
return (-1);
|
||||||
|
ptr = strchr(argv[0], ':');
|
||||||
|
if (ptr != NULL) {
|
||||||
|
char *tprog;
|
||||||
|
size_t l;
|
||||||
|
|
||||||
|
if (ptr == argv[0])
|
||||||
|
return (0);
|
||||||
|
l = ptr - argv[0] - 1;
|
||||||
|
tprog = (char *) el_malloc(l + 1);
|
||||||
|
if (tprog == NULL)
|
||||||
|
return (0);
|
||||||
|
(void) strncpy(tprog, argv[0], l);
|
||||||
|
tprog[l] = '\0';
|
||||||
|
ptr++;
|
||||||
|
l = el_match(el->el_prog, tprog);
|
||||||
|
el_free(tprog);
|
||||||
|
if (!l)
|
||||||
|
return (0);
|
||||||
|
} else
|
||||||
|
ptr = argv[0];
|
||||||
|
|
||||||
|
for (i = 0; cmds[i].name != NULL; i++)
|
||||||
|
if (strcmp(cmds[i].name, ptr) == 0) {
|
||||||
|
i = (*cmds[i].func) (el, argc, argv);
|
||||||
|
return (-i);
|
||||||
|
}
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* parse__escape():
|
||||||
|
* Parse a string of the form ^<char> \<odigit> \<char> and return
|
||||||
|
* the appropriate character or -1 if the escape is not valid
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
parse__escape(const char **ptr)
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
p = *ptr;
|
||||||
|
|
||||||
|
if (p[1] == 0)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
if (*p == '\\') {
|
||||||
|
p++;
|
||||||
|
switch (*p) {
|
||||||
|
case 'a':
|
||||||
|
c = '\007'; /* Bell */
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
c = '\010'; /* Backspace */
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
c = '\011'; /* Horizontal Tab */
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
c = '\012'; /* New Line */
|
||||||
|
break;
|
||||||
|
case 'v':
|
||||||
|
c = '\013'; /* Vertical Tab */
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
c = '\014'; /* Form Feed */
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
c = '\015'; /* Carriage Return */
|
||||||
|
break;
|
||||||
|
case 'e':
|
||||||
|
c = '\033'; /* Escape */
|
||||||
|
break;
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
{
|
||||||
|
int cnt, ch;
|
||||||
|
|
||||||
|
for (cnt = 0, c = 0; cnt < 3; cnt++) {
|
||||||
|
ch = *p++;
|
||||||
|
if (ch < '0' || ch > '7') {
|
||||||
|
p--;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
c = (c << 3) | (ch - '0');
|
||||||
|
}
|
||||||
|
if ((c & 0xffffff00) != 0)
|
||||||
|
return (-1);
|
||||||
|
--p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
c = *p;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (*p == '^') {
|
||||||
|
p++;
|
||||||
|
c = (*p == '?') ? '\177' : (*p & 0237);
|
||||||
|
} else
|
||||||
|
c = *p;
|
||||||
|
*ptr = ++p;
|
||||||
|
return (c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse__string():
|
||||||
|
* Parse the escapes from in and put the raw string out
|
||||||
|
*/
|
||||||
|
protected char *
|
||||||
|
parse__string(char *out, const char *in)
|
||||||
|
{
|
||||||
|
char *rv = out;
|
||||||
|
int n;
|
||||||
|
|
||||||
|
for (;;)
|
||||||
|
switch (*in) {
|
||||||
|
case '\0':
|
||||||
|
*out = '\0';
|
||||||
|
return (rv);
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
case '^':
|
||||||
|
if ((n = parse__escape(&in)) == -1)
|
||||||
|
return (NULL);
|
||||||
|
*out++ = n;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'M':
|
||||||
|
if (in[1] == '-' && in[2] != '\0') {
|
||||||
|
*out++ = '\033';
|
||||||
|
in += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/*FALLTHROUGH*/
|
||||||
|
|
||||||
|
default:
|
||||||
|
*out++ = *in++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* parse_cmd():
|
||||||
|
* Return the command number for the command string given
|
||||||
|
* or -1 if one is not found
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
parse_cmd(EditLine *el, const char *cmd)
|
||||||
|
{
|
||||||
|
el_bindings_t *b;
|
||||||
|
|
||||||
|
for (b = el->el_map.help; b->name != NULL; b++)
|
||||||
|
if (strcmp(b->name, cmd) == 0)
|
||||||
|
return (b->func);
|
||||||
|
return (-1);
|
||||||
|
}
|
|
@ -0,0 +1,48 @@
|
||||||
|
/* $NetBSD: parse.h,v 1.6 2005/05/29 04:58:15 lukem Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)parse.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.parse.h: Parser functions
|
||||||
|
*/
|
||||||
|
#ifndef _h_el_parse
|
||||||
|
#define _h_el_parse
|
||||||
|
|
||||||
|
protected int parse_line(EditLine *, const char *);
|
||||||
|
protected int parse__escape(const char **);
|
||||||
|
protected char *parse__string(char *, const char *);
|
||||||
|
protected int parse_cmd(EditLine *, const char *);
|
||||||
|
|
||||||
|
#endif /* _h_el_parse */
|
|
@ -0,0 +1,170 @@
|
||||||
|
/* $NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* prompt.c: Prompt printing functions
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "el.h"
|
||||||
|
|
||||||
|
private char *prompt_default(EditLine *);
|
||||||
|
private char *prompt_default_r(EditLine *);
|
||||||
|
|
||||||
|
/* prompt_default():
|
||||||
|
* Just a default prompt, in case the user did not provide one
|
||||||
|
*/
|
||||||
|
private char *
|
||||||
|
/*ARGSUSED*/
|
||||||
|
prompt_default(EditLine *el __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
static char a[3] = {'?', ' ', '\0'};
|
||||||
|
|
||||||
|
return (a);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* prompt_default_r():
|
||||||
|
* Just a default rprompt, in case the user did not provide one
|
||||||
|
*/
|
||||||
|
private char *
|
||||||
|
/*ARGSUSED*/
|
||||||
|
prompt_default_r(EditLine *el __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
static char a[1] = {'\0'};
|
||||||
|
|
||||||
|
return (a);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* prompt_print():
|
||||||
|
* Print the prompt and update the prompt position.
|
||||||
|
* We use an array of integers in case we want to pass
|
||||||
|
* literal escape sequences in the prompt and we want a
|
||||||
|
* bit to flag them
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
prompt_print(EditLine *el, int op)
|
||||||
|
{
|
||||||
|
el_prompt_t *elp;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (op == EL_PROMPT)
|
||||||
|
elp = &el->el_prompt;
|
||||||
|
else
|
||||||
|
elp = &el->el_rprompt;
|
||||||
|
p = (elp->p_func) (el);
|
||||||
|
while (*p)
|
||||||
|
re_putc(el, *p++, 1);
|
||||||
|
|
||||||
|
elp->p_pos.v = el->el_refresh.r_cursor.v;
|
||||||
|
elp->p_pos.h = el->el_refresh.r_cursor.h;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* prompt_init():
|
||||||
|
* Initialize the prompt stuff
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
prompt_init(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_prompt.p_func = prompt_default;
|
||||||
|
el->el_prompt.p_pos.v = 0;
|
||||||
|
el->el_prompt.p_pos.h = 0;
|
||||||
|
el->el_rprompt.p_func = prompt_default_r;
|
||||||
|
el->el_rprompt.p_pos.v = 0;
|
||||||
|
el->el_rprompt.p_pos.h = 0;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* prompt_end():
|
||||||
|
* Clean up the prompt stuff
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
/*ARGSUSED*/
|
||||||
|
prompt_end(EditLine *el __attribute__((__unused__)))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* prompt_set():
|
||||||
|
* Install a prompt printing function
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
prompt_set(EditLine *el, el_pfunc_t prf, int op)
|
||||||
|
{
|
||||||
|
el_prompt_t *p;
|
||||||
|
|
||||||
|
if (op == EL_PROMPT)
|
||||||
|
p = &el->el_prompt;
|
||||||
|
else
|
||||||
|
p = &el->el_rprompt;
|
||||||
|
if (prf == NULL) {
|
||||||
|
if (op == EL_PROMPT)
|
||||||
|
p->p_func = prompt_default;
|
||||||
|
else
|
||||||
|
p->p_func = prompt_default_r;
|
||||||
|
} else
|
||||||
|
p->p_func = prf;
|
||||||
|
p->p_pos.v = 0;
|
||||||
|
p->p_pos.h = 0;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* prompt_get():
|
||||||
|
* Retrieve the prompt printing function
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
prompt_get(EditLine *el, el_pfunc_t *prf, int op)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (prf == NULL)
|
||||||
|
return (-1);
|
||||||
|
if (op == EL_PROMPT)
|
||||||
|
*prf = el->el_prompt.p_func;
|
||||||
|
else
|
||||||
|
*prf = el->el_rprompt.p_func;
|
||||||
|
return (0);
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
/* $NetBSD: prompt.h,v 1.6 2003/08/07 16:44:32 agc Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)prompt.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.prompt.h: Prompt printing stuff
|
||||||
|
*/
|
||||||
|
#ifndef _h_el_prompt
|
||||||
|
#define _h_el_prompt
|
||||||
|
|
||||||
|
#include "histedit.h"
|
||||||
|
|
||||||
|
typedef char * (*el_pfunc_t)(EditLine*);
|
||||||
|
|
||||||
|
typedef struct el_prompt_t {
|
||||||
|
el_pfunc_t p_func; /* Function to return the prompt */
|
||||||
|
coord_t p_pos; /* position in the line after prompt */
|
||||||
|
} el_prompt_t;
|
||||||
|
|
||||||
|
protected void prompt_print(EditLine *, int);
|
||||||
|
protected int prompt_set(EditLine *, el_pfunc_t, int);
|
||||||
|
protected int prompt_get(EditLine *, el_pfunc_t *, int);
|
||||||
|
protected int prompt_init(EditLine *);
|
||||||
|
protected void prompt_end(EditLine *);
|
||||||
|
|
||||||
|
#endif /* _h_el_prompt */
|
|
@ -0,0 +1,628 @@
|
||||||
|
/* $NetBSD: read.c,v 1.40 2007/03/01 21:41:45 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: read.c,v 1.40 2007/03/01 21:41:45 christos Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* read.c: Clean this junk up! This is horrible code.
|
||||||
|
* Terminal read functions
|
||||||
|
*/
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "el.h"
|
||||||
|
|
||||||
|
#define OKCMD -1
|
||||||
|
|
||||||
|
private int read__fixio(int, int);
|
||||||
|
private int read_preread(EditLine *);
|
||||||
|
private int read_char(EditLine *, char *);
|
||||||
|
private int read_getcmd(EditLine *, el_action_t *, char *);
|
||||||
|
private void read_pop(c_macro_t *);
|
||||||
|
|
||||||
|
/* read_init():
|
||||||
|
* Initialize the read stuff
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
read_init(EditLine *el)
|
||||||
|
{
|
||||||
|
/* builtin read_char */
|
||||||
|
el->el_read.read_char = read_char;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_read_setfn():
|
||||||
|
* Set the read char function to the one provided.
|
||||||
|
* If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one.
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
el_read_setfn(EditLine *el, el_rfunc_t rc)
|
||||||
|
{
|
||||||
|
el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_read_getfn():
|
||||||
|
* return the current read char function, or EL_BUILTIN_GETCFN
|
||||||
|
* if it is the default one
|
||||||
|
*/
|
||||||
|
protected el_rfunc_t
|
||||||
|
el_read_getfn(EditLine *el)
|
||||||
|
{
|
||||||
|
return (el->el_read.read_char == read_char) ?
|
||||||
|
EL_BUILTIN_GETCFN : el->el_read.read_char;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef MIN
|
||||||
|
#define MIN(A,B) ((A) < (B) ? (A) : (B))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef DEBUG_EDIT
|
||||||
|
private void
|
||||||
|
read_debug(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (el->el_line.cursor > el->el_line.lastchar)
|
||||||
|
(void) fprintf(el->el_errfile, "cursor > lastchar\r\n");
|
||||||
|
if (el->el_line.cursor < el->el_line.buffer)
|
||||||
|
(void) fprintf(el->el_errfile, "cursor < buffer\r\n");
|
||||||
|
if (el->el_line.cursor > el->el_line.limit)
|
||||||
|
(void) fprintf(el->el_errfile, "cursor > limit\r\n");
|
||||||
|
if (el->el_line.lastchar > el->el_line.limit)
|
||||||
|
(void) fprintf(el->el_errfile, "lastchar > limit\r\n");
|
||||||
|
if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2])
|
||||||
|
(void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n");
|
||||||
|
}
|
||||||
|
#endif /* DEBUG_EDIT */
|
||||||
|
|
||||||
|
|
||||||
|
/* read__fixio():
|
||||||
|
* Try to recover from a read error
|
||||||
|
*/
|
||||||
|
/* ARGSUSED */
|
||||||
|
private int
|
||||||
|
read__fixio(int fd __attribute__((__unused__)), int e)
|
||||||
|
{
|
||||||
|
|
||||||
|
switch (e) {
|
||||||
|
case -1: /* Make sure that the code is reachable */
|
||||||
|
|
||||||
|
#ifdef EWOULDBLOCK
|
||||||
|
case EWOULDBLOCK:
|
||||||
|
#ifndef TRY_AGAIN
|
||||||
|
#define TRY_AGAIN
|
||||||
|
#endif
|
||||||
|
#endif /* EWOULDBLOCK */
|
||||||
|
|
||||||
|
#if defined(POSIX) && defined(EAGAIN)
|
||||||
|
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
|
||||||
|
case EAGAIN:
|
||||||
|
#ifndef TRY_AGAIN
|
||||||
|
#define TRY_AGAIN
|
||||||
|
#endif
|
||||||
|
#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
|
||||||
|
#endif /* POSIX && EAGAIN */
|
||||||
|
|
||||||
|
e = 0;
|
||||||
|
#ifdef TRY_AGAIN
|
||||||
|
#if defined(F_SETFL) && defined(O_NDELAY)
|
||||||
|
if ((e = fcntl(fd, F_GETFL, 0)) == -1)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
|
||||||
|
return (-1);
|
||||||
|
else
|
||||||
|
e = 1;
|
||||||
|
#endif /* F_SETFL && O_NDELAY */
|
||||||
|
|
||||||
|
#ifdef FIONBIO
|
||||||
|
{
|
||||||
|
int zero = 0;
|
||||||
|
|
||||||
|
if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1)
|
||||||
|
return (-1);
|
||||||
|
else
|
||||||
|
e = 1;
|
||||||
|
}
|
||||||
|
#endif /* FIONBIO */
|
||||||
|
|
||||||
|
#endif /* TRY_AGAIN */
|
||||||
|
return (e ? 0 : -1);
|
||||||
|
|
||||||
|
case EINTR:
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* read_preread():
|
||||||
|
* Try to read the stuff in the input queue;
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
read_preread(EditLine *el)
|
||||||
|
{
|
||||||
|
int chrs = 0;
|
||||||
|
|
||||||
|
if (el->el_tty.t_mode == ED_IO)
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
#ifdef FIONREAD
|
||||||
|
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
|
||||||
|
if (chrs > 0) {
|
||||||
|
char buf[EL_BUFSIZ];
|
||||||
|
|
||||||
|
chrs = read(el->el_infd, buf,
|
||||||
|
(size_t) MIN(chrs, EL_BUFSIZ - 1));
|
||||||
|
if (chrs > 0) {
|
||||||
|
buf[chrs] = '\0';
|
||||||
|
el_push(el, buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* FIONREAD */
|
||||||
|
|
||||||
|
return (chrs > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* el_push():
|
||||||
|
* Push a macro
|
||||||
|
*/
|
||||||
|
public void
|
||||||
|
el_push(EditLine *el, char *str)
|
||||||
|
{
|
||||||
|
c_macro_t *ma = &el->el_chared.c_macro;
|
||||||
|
|
||||||
|
if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
|
||||||
|
ma->level++;
|
||||||
|
if ((ma->macro[ma->level] = el_strdup(str)) != NULL)
|
||||||
|
return;
|
||||||
|
ma->level--;
|
||||||
|
}
|
||||||
|
term_beep(el);
|
||||||
|
term__flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* read_getcmd():
|
||||||
|
* Return next command from the input stream.
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
|
||||||
|
{
|
||||||
|
el_action_t cmd;
|
||||||
|
int num;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if ((num = el_getc(el, ch)) != 1) /* if EOF or error */
|
||||||
|
return (num);
|
||||||
|
|
||||||
|
#ifdef KANJI
|
||||||
|
if ((*ch & 0200)) {
|
||||||
|
el->el_state.metanext = 0;
|
||||||
|
cmd = CcViMap[' '];
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
#endif /* KANJI */
|
||||||
|
|
||||||
|
if (el->el_state.metanext) {
|
||||||
|
el->el_state.metanext = 0;
|
||||||
|
*ch |= 0200;
|
||||||
|
}
|
||||||
|
cmd = el->el_map.current[(unsigned char) *ch];
|
||||||
|
if (cmd == ED_SEQUENCE_LEAD_IN) {
|
||||||
|
key_value_t val;
|
||||||
|
switch (key_get(el, ch, &val)) {
|
||||||
|
case XK_CMD:
|
||||||
|
cmd = val.cmd;
|
||||||
|
break;
|
||||||
|
case XK_STR:
|
||||||
|
el_push(el, val.str);
|
||||||
|
break;
|
||||||
|
#ifdef notyet
|
||||||
|
case XK_EXE:
|
||||||
|
/* XXX: In the future to run a user function */
|
||||||
|
RunCommand(val.str);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
EL_ABORT((el->el_errfile, "Bad XK_ type \n"));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (el->el_map.alt == NULL)
|
||||||
|
el->el_map.current = el->el_map.key;
|
||||||
|
} while (cmd == ED_SEQUENCE_LEAD_IN);
|
||||||
|
*cmdnum = cmd;
|
||||||
|
return (OKCMD);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* read_char():
|
||||||
|
* Read a character from the tty.
|
||||||
|
*/
|
||||||
|
private int
|
||||||
|
read_char(EditLine *el, char *cp)
|
||||||
|
{
|
||||||
|
int num_read;
|
||||||
|
int tried = 0;
|
||||||
|
|
||||||
|
while ((num_read = read(el->el_infd, cp, 1)) == -1)
|
||||||
|
if (!tried && read__fixio(el->el_infd, errno) == 0)
|
||||||
|
tried = 1;
|
||||||
|
else {
|
||||||
|
*cp = '\0';
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (num_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* read_pop():
|
||||||
|
* Pop a macro from the stack
|
||||||
|
*/
|
||||||
|
private void
|
||||||
|
read_pop(c_macro_t *ma)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
el_free(ma->macro[0]);
|
||||||
|
for (i = ma->level--; i > 0; i--)
|
||||||
|
ma->macro[i - 1] = ma->macro[i];
|
||||||
|
ma->offset = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* el_getc():
|
||||||
|
* Read a character
|
||||||
|
*/
|
||||||
|
public int
|
||||||
|
el_getc(EditLine *el, char *cp)
|
||||||
|
{
|
||||||
|
int num_read;
|
||||||
|
c_macro_t *ma = &el->el_chared.c_macro;
|
||||||
|
|
||||||
|
term__flush();
|
||||||
|
for (;;) {
|
||||||
|
if (ma->level < 0) {
|
||||||
|
if (!read_preread(el))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ma->level < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (ma->macro[0][ma->offset] == '\0') {
|
||||||
|
read_pop(ma);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
*cp = ma->macro[0][ma->offset++] & 0377;
|
||||||
|
|
||||||
|
if (ma->macro[0][ma->offset] == '\0') {
|
||||||
|
/* Needed for QuoteMode On */
|
||||||
|
read_pop(ma);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef DEBUG_READ
|
||||||
|
(void) fprintf(el->el_errfile, "Turning raw mode on\n");
|
||||||
|
#endif /* DEBUG_READ */
|
||||||
|
if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
#ifdef DEBUG_READ
|
||||||
|
(void) fprintf(el->el_errfile, "Reading a character\n");
|
||||||
|
#endif /* DEBUG_READ */
|
||||||
|
num_read = (*el->el_read.read_char)(el, cp);
|
||||||
|
#ifdef DEBUG_READ
|
||||||
|
(void) fprintf(el->el_errfile, "Got it %c\n", *cp);
|
||||||
|
#endif /* DEBUG_READ */
|
||||||
|
return (num_read);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void
|
||||||
|
read_prepare(EditLine *el)
|
||||||
|
{
|
||||||
|
if (el->el_flags & HANDLE_SIGNALS)
|
||||||
|
sig_set(el);
|
||||||
|
if (el->el_flags & NO_TTY)
|
||||||
|
return;
|
||||||
|
if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED)
|
||||||
|
tty_rawmode(el);
|
||||||
|
|
||||||
|
/* This is relatively cheap, and things go terribly wrong if
|
||||||
|
we have the wrong size. */
|
||||||
|
el_resize(el);
|
||||||
|
re_clear_display(el); /* reset the display stuff */
|
||||||
|
ch_reset(el, 0);
|
||||||
|
re_refresh(el); /* print the prompt */
|
||||||
|
|
||||||
|
if (el->el_flags & UNBUFFERED)
|
||||||
|
term__flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void
|
||||||
|
read_finish(EditLine *el)
|
||||||
|
{
|
||||||
|
if ((el->el_flags & UNBUFFERED) == 0)
|
||||||
|
(void) tty_cookedmode(el);
|
||||||
|
if (el->el_flags & HANDLE_SIGNALS)
|
||||||
|
sig_clr(el);
|
||||||
|
}
|
||||||
|
|
||||||
|
public const char *
|
||||||
|
el_gets(EditLine *el, int *nread)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
el_action_t cmdnum = 0;
|
||||||
|
int num; /* how many chars we have read at NL */
|
||||||
|
char ch;
|
||||||
|
int crlf = 0;
|
||||||
|
#ifdef FIONREAD
|
||||||
|
c_macro_t *ma = &el->el_chared.c_macro;
|
||||||
|
#endif /* FIONREAD */
|
||||||
|
|
||||||
|
if (el->el_flags & NO_TTY) {
|
||||||
|
char *cp = el->el_line.buffer;
|
||||||
|
size_t idx;
|
||||||
|
|
||||||
|
while ((*el->el_read.read_char)(el, cp) == 1) {
|
||||||
|
/* make sure there is space for next character */
|
||||||
|
if (cp + 1 >= el->el_line.limit) {
|
||||||
|
idx = (cp - el->el_line.buffer);
|
||||||
|
if (!ch_enlargebufs(el, 2))
|
||||||
|
break;
|
||||||
|
cp = &el->el_line.buffer[idx];
|
||||||
|
}
|
||||||
|
cp++;
|
||||||
|
if (el->el_flags & UNBUFFERED)
|
||||||
|
break;
|
||||||
|
if (cp[-1] == '\r' || cp[-1] == '\n')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
el->el_line.cursor = el->el_line.lastchar = cp;
|
||||||
|
*cp = '\0';
|
||||||
|
if (nread)
|
||||||
|
*nread = el->el_line.cursor - el->el_line.buffer;
|
||||||
|
return (el->el_line.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef FIONREAD
|
||||||
|
if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
|
||||||
|
long chrs = 0;
|
||||||
|
|
||||||
|
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
|
||||||
|
if (chrs == 0) {
|
||||||
|
if (tty_rawmode(el) < 0) {
|
||||||
|
if (nread)
|
||||||
|
*nread = 0;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* FIONREAD */
|
||||||
|
|
||||||
|
if ((el->el_flags & UNBUFFERED) == 0)
|
||||||
|
read_prepare(el);
|
||||||
|
|
||||||
|
if (el->el_flags & EDIT_DISABLED) {
|
||||||
|
char *cp;
|
||||||
|
size_t idx;
|
||||||
|
if ((el->el_flags & UNBUFFERED) == 0)
|
||||||
|
cp = el->el_line.buffer;
|
||||||
|
else
|
||||||
|
cp = el->el_line.lastchar;
|
||||||
|
|
||||||
|
term__flush();
|
||||||
|
|
||||||
|
while ((*el->el_read.read_char)(el, cp) == 1) {
|
||||||
|
/* make sure there is space next character */
|
||||||
|
if (cp + 1 >= el->el_line.limit) {
|
||||||
|
idx = (cp - el->el_line.buffer);
|
||||||
|
if (!ch_enlargebufs(el, 2))
|
||||||
|
break;
|
||||||
|
cp = &el->el_line.buffer[idx];
|
||||||
|
}
|
||||||
|
if (*cp == 4) /* ought to be stty eof */
|
||||||
|
break;
|
||||||
|
cp++;
|
||||||
|
crlf = cp[-1] == '\r' || cp[-1] == '\n';
|
||||||
|
if (el->el_flags & UNBUFFERED)
|
||||||
|
break;
|
||||||
|
if (crlf)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
el->el_line.cursor = el->el_line.lastchar = cp;
|
||||||
|
*cp = '\0';
|
||||||
|
if (nread)
|
||||||
|
*nread = el->el_line.cursor - el->el_line.buffer;
|
||||||
|
return (el->el_line.buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (num = OKCMD; num == OKCMD;) { /* while still editing this
|
||||||
|
* line */
|
||||||
|
#ifdef DEBUG_EDIT
|
||||||
|
read_debug(el);
|
||||||
|
#endif /* DEBUG_EDIT */
|
||||||
|
/* if EOF or error */
|
||||||
|
if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) {
|
||||||
|
#ifdef DEBUG_READ
|
||||||
|
(void) fprintf(el->el_errfile,
|
||||||
|
"Returning from el_gets %d\n", num);
|
||||||
|
#endif /* DEBUG_READ */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ((unsigned int)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
|
||||||
|
#ifdef DEBUG_EDIT
|
||||||
|
(void) fprintf(el->el_errfile,
|
||||||
|
"ERROR: illegal command from key 0%o\r\n", ch);
|
||||||
|
#endif /* DEBUG_EDIT */
|
||||||
|
continue; /* try again */
|
||||||
|
}
|
||||||
|
/* now do the real command */
|
||||||
|
#ifdef DEBUG_READ
|
||||||
|
{
|
||||||
|
el_bindings_t *b;
|
||||||
|
for (b = el->el_map.help; b->name; b++)
|
||||||
|
if (b->func == cmdnum)
|
||||||
|
break;
|
||||||
|
if (b->name)
|
||||||
|
(void) fprintf(el->el_errfile,
|
||||||
|
"Executing %s\n", b->name);
|
||||||
|
else
|
||||||
|
(void) fprintf(el->el_errfile,
|
||||||
|
"Error command = %d\n", cmdnum);
|
||||||
|
}
|
||||||
|
#endif /* DEBUG_READ */
|
||||||
|
/* vi redo needs these way down the levels... */
|
||||||
|
el->el_state.thiscmd = cmdnum;
|
||||||
|
el->el_state.thisch = ch;
|
||||||
|
if (el->el_map.type == MAP_VI &&
|
||||||
|
el->el_map.current == el->el_map.key &&
|
||||||
|
el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
|
||||||
|
if (cmdnum == VI_DELETE_PREV_CHAR &&
|
||||||
|
el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
|
||||||
|
&& isprint((unsigned char)el->el_chared.c_redo.pos[-1]))
|
||||||
|
el->el_chared.c_redo.pos--;
|
||||||
|
else
|
||||||
|
*el->el_chared.c_redo.pos++ = ch;
|
||||||
|
}
|
||||||
|
retval = (*el->el_map.func[cmdnum]) (el, ch);
|
||||||
|
#ifdef DEBUG_READ
|
||||||
|
(void) fprintf(el->el_errfile,
|
||||||
|
"Returned state %d\n", retval );
|
||||||
|
#endif /* DEBUG_READ */
|
||||||
|
|
||||||
|
/* save the last command here */
|
||||||
|
el->el_state.lastcmd = cmdnum;
|
||||||
|
|
||||||
|
/* use any return value */
|
||||||
|
switch (retval) {
|
||||||
|
case CC_CURSOR:
|
||||||
|
re_refresh_cursor(el);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CC_REDISPLAY:
|
||||||
|
re_clear_lines(el);
|
||||||
|
re_clear_display(el);
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
|
case CC_REFRESH:
|
||||||
|
re_refresh(el);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CC_REFRESH_BEEP:
|
||||||
|
re_refresh(el);
|
||||||
|
term_beep(el);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CC_NORM: /* normal char */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CC_ARGHACK: /* Suggested by Rich Salz */
|
||||||
|
/* <rsalz@pineapple.bbn.com> */
|
||||||
|
continue; /* keep going... */
|
||||||
|
|
||||||
|
case CC_EOF: /* end of file typed */
|
||||||
|
if ((el->el_flags & UNBUFFERED) == 0)
|
||||||
|
num = 0;
|
||||||
|
else if (num == -1) {
|
||||||
|
*el->el_line.lastchar++ = CONTROL('d');
|
||||||
|
el->el_line.cursor = el->el_line.lastchar;
|
||||||
|
num = 1;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CC_NEWLINE: /* normal end of line */
|
||||||
|
num = el->el_line.lastchar - el->el_line.buffer;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CC_FATAL: /* fatal error, reset to known state */
|
||||||
|
#ifdef DEBUG_READ
|
||||||
|
(void) fprintf(el->el_errfile,
|
||||||
|
"*** editor fatal ERROR ***\r\n\n");
|
||||||
|
#endif /* DEBUG_READ */
|
||||||
|
/* put (real) cursor in a known place */
|
||||||
|
re_clear_display(el); /* reset the display stuff */
|
||||||
|
ch_reset(el, 1); /* reset the input pointers */
|
||||||
|
re_refresh(el); /* print the prompt again */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CC_ERROR:
|
||||||
|
default: /* functions we don't know about */
|
||||||
|
#ifdef DEBUG_READ
|
||||||
|
(void) fprintf(el->el_errfile,
|
||||||
|
"*** editor ERROR ***\r\n\n");
|
||||||
|
#endif /* DEBUG_READ */
|
||||||
|
term_beep(el);
|
||||||
|
term__flush();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
el->el_state.argument = 1;
|
||||||
|
el->el_state.doingarg = 0;
|
||||||
|
el->el_chared.c_vcmd.action = NOP;
|
||||||
|
if (el->el_flags & UNBUFFERED)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
term__flush(); /* flush any buffered output */
|
||||||
|
/* make sure the tty is set up correctly */
|
||||||
|
if ((el->el_flags & UNBUFFERED) == 0) {
|
||||||
|
read_finish(el);
|
||||||
|
if (nread)
|
||||||
|
*nread = num;
|
||||||
|
} else {
|
||||||
|
if (nread)
|
||||||
|
*nread = el->el_line.lastchar - el->el_line.buffer;
|
||||||
|
}
|
||||||
|
return (num ? el->el_line.buffer : NULL);
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/* $NetBSD: read.h,v 1.5 2006/08/21 12:45:30 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 2001 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to The NetBSD Foundation
|
||||||
|
* by Anthony Mallet.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.read.h: Character reading functions
|
||||||
|
*/
|
||||||
|
#ifndef _h_el_read
|
||||||
|
#define _h_el_read
|
||||||
|
|
||||||
|
typedef int (*el_rfunc_t)(EditLine *, char *);
|
||||||
|
|
||||||
|
typedef struct el_read_t {
|
||||||
|
el_rfunc_t read_char; /* Function to read a character */
|
||||||
|
} el_read_t;
|
||||||
|
|
||||||
|
protected int read_init(EditLine *);
|
||||||
|
protected void read_prepare(EditLine *);
|
||||||
|
protected void read_finish(EditLine *);
|
||||||
|
protected int el_read_setfn(EditLine *, el_rfunc_t);
|
||||||
|
protected el_rfunc_t el_read_getfn(EditLine *);
|
||||||
|
|
||||||
|
#endif /* _h_el_read */
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,59 @@
|
||||||
|
/* $NetBSD: refresh.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)refresh.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.refresh.h: Screen refresh functions
|
||||||
|
*/
|
||||||
|
#ifndef _h_el_refresh
|
||||||
|
#define _h_el_refresh
|
||||||
|
|
||||||
|
#include "histedit.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
coord_t r_cursor; /* Refresh cursor position */
|
||||||
|
int r_oldcv; /* Vertical locations */
|
||||||
|
int r_newcv;
|
||||||
|
} el_refresh_t;
|
||||||
|
|
||||||
|
protected void re_putc(EditLine *, int, int);
|
||||||
|
protected void re_clear_lines(EditLine *);
|
||||||
|
protected void re_clear_display(EditLine *);
|
||||||
|
protected void re_refresh(EditLine *);
|
||||||
|
protected void re_refresh_cursor(EditLine *);
|
||||||
|
protected void re_fastaddc(EditLine *);
|
||||||
|
protected void re_goto_bottom(EditLine *);
|
||||||
|
|
||||||
|
#endif /* _h_el_refresh */
|
|
@ -0,0 +1,634 @@
|
||||||
|
/* $NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* search.c: History and character search functions
|
||||||
|
*/
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#if defined(REGEX)
|
||||||
|
#include <regex.h>
|
||||||
|
#elif defined(REGEXP)
|
||||||
|
#include <regexp.h>
|
||||||
|
#endif
|
||||||
|
#include "el.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Adjust cursor in vi mode to include the character under it
|
||||||
|
*/
|
||||||
|
#define EL_CURSOR(el) \
|
||||||
|
((el)->el_line.cursor + (((el)->el_map.type == MAP_VI) && \
|
||||||
|
((el)->el_map.current == (el)->el_map.alt)))
|
||||||
|
|
||||||
|
/* search_init():
|
||||||
|
* Initialize the search stuff
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
search_init(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
el->el_search.patbuf = (char *) el_malloc(EL_BUFSIZ);
|
||||||
|
if (el->el_search.patbuf == NULL)
|
||||||
|
return (-1);
|
||||||
|
el->el_search.patlen = 0;
|
||||||
|
el->el_search.patdir = -1;
|
||||||
|
el->el_search.chacha = '\0';
|
||||||
|
el->el_search.chadir = CHAR_FWD;
|
||||||
|
el->el_search.chatflg = 0;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* search_end():
|
||||||
|
* Initialize the search stuff
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
search_end(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
el_free((ptr_t) el->el_search.patbuf);
|
||||||
|
el->el_search.patbuf = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef REGEXP
|
||||||
|
/* regerror():
|
||||||
|
* Handle regular expression errors
|
||||||
|
*/
|
||||||
|
public void
|
||||||
|
/*ARGSUSED*/
|
||||||
|
regerror(const char *msg)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* el_match():
|
||||||
|
* Return if string matches pattern
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
el_match(const char *str, const char *pat)
|
||||||
|
{
|
||||||
|
#if defined (REGEX)
|
||||||
|
regex_t re;
|
||||||
|
int rv;
|
||||||
|
#elif defined (REGEXP)
|
||||||
|
regexp *rp;
|
||||||
|
int rv;
|
||||||
|
#else
|
||||||
|
extern char *re_comp(const char *);
|
||||||
|
extern int re_exec(const char *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (strstr(str, pat) != NULL)
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
#if defined(REGEX)
|
||||||
|
if (regcomp(&re, pat, 0) == 0) {
|
||||||
|
rv = regexec(&re, str, 0, NULL, 0) == 0;
|
||||||
|
regfree(&re);
|
||||||
|
} else {
|
||||||
|
rv = 0;
|
||||||
|
}
|
||||||
|
return (rv);
|
||||||
|
#elif defined(REGEXP)
|
||||||
|
if ((re = regcomp(pat)) != NULL) {
|
||||||
|
rv = regexec(re, str);
|
||||||
|
free((ptr_t) re);
|
||||||
|
} else {
|
||||||
|
rv = 0;
|
||||||
|
}
|
||||||
|
return (rv);
|
||||||
|
#else
|
||||||
|
if (re_comp(pat) != NULL)
|
||||||
|
return (0);
|
||||||
|
else
|
||||||
|
return (re_exec(str) == 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* c_hmatch():
|
||||||
|
* return True if the pattern matches the prefix
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
c_hmatch(EditLine *el, const char *str)
|
||||||
|
{
|
||||||
|
#ifdef SDEBUG
|
||||||
|
(void) fprintf(el->el_errfile, "match `%s' with `%s'\n",
|
||||||
|
el->el_search.patbuf, str);
|
||||||
|
#endif /* SDEBUG */
|
||||||
|
|
||||||
|
return (el_match(str, el->el_search.patbuf));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* c_setpat():
|
||||||
|
* Set the history seatch pattern
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
c_setpat(EditLine *el)
|
||||||
|
{
|
||||||
|
if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY &&
|
||||||
|
el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) {
|
||||||
|
el->el_search.patlen = EL_CURSOR(el) - el->el_line.buffer;
|
||||||
|
if (el->el_search.patlen >= EL_BUFSIZ)
|
||||||
|
el->el_search.patlen = EL_BUFSIZ - 1;
|
||||||
|
if (el->el_search.patlen != 0) {
|
||||||
|
(void) strncpy(el->el_search.patbuf, el->el_line.buffer,
|
||||||
|
el->el_search.patlen);
|
||||||
|
el->el_search.patbuf[el->el_search.patlen] = '\0';
|
||||||
|
} else
|
||||||
|
el->el_search.patlen = strlen(el->el_search.patbuf);
|
||||||
|
}
|
||||||
|
#ifdef SDEBUG
|
||||||
|
(void) fprintf(el->el_errfile, "\neventno = %d\n",
|
||||||
|
el->el_history.eventno);
|
||||||
|
(void) fprintf(el->el_errfile, "patlen = %d\n", el->el_search.patlen);
|
||||||
|
(void) fprintf(el->el_errfile, "patbuf = \"%s\"\n",
|
||||||
|
el->el_search.patbuf);
|
||||||
|
(void) fprintf(el->el_errfile, "cursor %d lastchar %d\n",
|
||||||
|
EL_CURSOR(el) - el->el_line.buffer,
|
||||||
|
el->el_line.lastchar - el->el_line.buffer);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ce_inc_search():
|
||||||
|
* Emacs incremental search
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
ce_inc_search(EditLine *el, int dir)
|
||||||
|
{
|
||||||
|
static const char STRfwd[] = {'f', 'w', 'd', '\0'},
|
||||||
|
STRbck[] = {'b', 'c', 'k', '\0'};
|
||||||
|
static char pchar = ':';/* ':' = normal, '?' = failed */
|
||||||
|
static char endcmd[2] = {'\0', '\0'};
|
||||||
|
char ch, *ocursor = el->el_line.cursor, oldpchar = pchar;
|
||||||
|
const char *cp;
|
||||||
|
|
||||||
|
el_action_t ret = CC_NORM;
|
||||||
|
|
||||||
|
int ohisteventno = el->el_history.eventno;
|
||||||
|
int oldpatlen = el->el_search.patlen;
|
||||||
|
int newdir = dir;
|
||||||
|
int done, redo;
|
||||||
|
|
||||||
|
if (el->el_line.lastchar + sizeof(STRfwd) / sizeof(char) + 2 +
|
||||||
|
el->el_search.patlen >= el->el_line.limit)
|
||||||
|
return (CC_ERROR);
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
|
||||||
|
if (el->el_search.patlen == 0) { /* first round */
|
||||||
|
pchar = ':';
|
||||||
|
#ifdef ANCHOR
|
||||||
|
#define LEN 2
|
||||||
|
el->el_search.patbuf[el->el_search.patlen++] = '.';
|
||||||
|
el->el_search.patbuf[el->el_search.patlen++] = '*';
|
||||||
|
#else
|
||||||
|
#define LEN 0
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
done = redo = 0;
|
||||||
|
*el->el_line.lastchar++ = '\n';
|
||||||
|
for (cp = (newdir == ED_SEARCH_PREV_HISTORY) ? STRbck : STRfwd;
|
||||||
|
*cp; *el->el_line.lastchar++ = *cp++)
|
||||||
|
continue;
|
||||||
|
*el->el_line.lastchar++ = pchar;
|
||||||
|
for (cp = &el->el_search.patbuf[LEN];
|
||||||
|
cp < &el->el_search.patbuf[el->el_search.patlen];
|
||||||
|
*el->el_line.lastchar++ = *cp++)
|
||||||
|
continue;
|
||||||
|
*el->el_line.lastchar = '\0';
|
||||||
|
re_refresh(el);
|
||||||
|
|
||||||
|
if (el_getc(el, &ch) != 1)
|
||||||
|
return (ed_end_of_file(el, 0));
|
||||||
|
|
||||||
|
switch (el->el_map.current[(unsigned char) ch]) {
|
||||||
|
case ED_INSERT:
|
||||||
|
case ED_DIGIT:
|
||||||
|
if (el->el_search.patlen >= EL_BUFSIZ - LEN)
|
||||||
|
term_beep(el);
|
||||||
|
else {
|
||||||
|
el->el_search.patbuf[el->el_search.patlen++] =
|
||||||
|
ch;
|
||||||
|
*el->el_line.lastchar++ = ch;
|
||||||
|
*el->el_line.lastchar = '\0';
|
||||||
|
re_refresh(el);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EM_INC_SEARCH_NEXT:
|
||||||
|
newdir = ED_SEARCH_NEXT_HISTORY;
|
||||||
|
redo++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EM_INC_SEARCH_PREV:
|
||||||
|
newdir = ED_SEARCH_PREV_HISTORY;
|
||||||
|
redo++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case EM_DELETE_PREV_CHAR:
|
||||||
|
case ED_DELETE_PREV_CHAR:
|
||||||
|
if (el->el_search.patlen > LEN)
|
||||||
|
done++;
|
||||||
|
else
|
||||||
|
term_beep(el);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
switch (ch) {
|
||||||
|
case 0007: /* ^G: Abort */
|
||||||
|
ret = CC_ERROR;
|
||||||
|
done++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0027: /* ^W: Append word */
|
||||||
|
/* No can do if globbing characters in pattern */
|
||||||
|
for (cp = &el->el_search.patbuf[LEN];; cp++)
|
||||||
|
if (cp >= &el->el_search.patbuf[
|
||||||
|
el->el_search.patlen]) {
|
||||||
|
el->el_line.cursor +=
|
||||||
|
el->el_search.patlen - LEN - 1;
|
||||||
|
cp = c__next_word(el->el_line.cursor,
|
||||||
|
el->el_line.lastchar, 1,
|
||||||
|
ce__isword);
|
||||||
|
while (el->el_line.cursor < cp &&
|
||||||
|
*el->el_line.cursor != '\n') {
|
||||||
|
if (el->el_search.patlen >=
|
||||||
|
EL_BUFSIZ - LEN) {
|
||||||
|
term_beep(el);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
el->el_search.patbuf[el->el_search.patlen++] =
|
||||||
|
*el->el_line.cursor;
|
||||||
|
*el->el_line.lastchar++ =
|
||||||
|
*el->el_line.cursor++;
|
||||||
|
}
|
||||||
|
el->el_line.cursor = ocursor;
|
||||||
|
*el->el_line.lastchar = '\0';
|
||||||
|
re_refresh(el);
|
||||||
|
break;
|
||||||
|
} else if (isglob(*cp)) {
|
||||||
|
term_beep(el);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: /* Terminate and execute cmd */
|
||||||
|
endcmd[0] = ch;
|
||||||
|
el_push(el, endcmd);
|
||||||
|
/* FALLTHROUGH */
|
||||||
|
|
||||||
|
case 0033: /* ESC: Terminate */
|
||||||
|
ret = CC_REFRESH;
|
||||||
|
done++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (el->el_line.lastchar > el->el_line.buffer &&
|
||||||
|
*el->el_line.lastchar != '\n')
|
||||||
|
*el->el_line.lastchar-- = '\0';
|
||||||
|
*el->el_line.lastchar = '\0';
|
||||||
|
|
||||||
|
if (!done) {
|
||||||
|
|
||||||
|
/* Can't search if unmatched '[' */
|
||||||
|
for (cp = &el->el_search.patbuf[el->el_search.patlen-1],
|
||||||
|
ch = ']';
|
||||||
|
cp >= &el->el_search.patbuf[LEN];
|
||||||
|
cp--)
|
||||||
|
if (*cp == '[' || *cp == ']') {
|
||||||
|
ch = *cp;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (el->el_search.patlen > LEN && ch != '[') {
|
||||||
|
if (redo && newdir == dir) {
|
||||||
|
if (pchar == '?') { /* wrap around */
|
||||||
|
el->el_history.eventno =
|
||||||
|
newdir == ED_SEARCH_PREV_HISTORY ? 0 : 0x7fffffff;
|
||||||
|
if (hist_get(el) == CC_ERROR)
|
||||||
|
/* el->el_history.event
|
||||||
|
* no was fixed by
|
||||||
|
* first call */
|
||||||
|
(void) hist_get(el);
|
||||||
|
el->el_line.cursor = newdir ==
|
||||||
|
ED_SEARCH_PREV_HISTORY ?
|
||||||
|
el->el_line.lastchar :
|
||||||
|
el->el_line.buffer;
|
||||||
|
} else
|
||||||
|
el->el_line.cursor +=
|
||||||
|
newdir ==
|
||||||
|
ED_SEARCH_PREV_HISTORY ?
|
||||||
|
-1 : 1;
|
||||||
|
}
|
||||||
|
#ifdef ANCHOR
|
||||||
|
el->el_search.patbuf[el->el_search.patlen++] =
|
||||||
|
'.';
|
||||||
|
el->el_search.patbuf[el->el_search.patlen++] =
|
||||||
|
'*';
|
||||||
|
#endif
|
||||||
|
el->el_search.patbuf[el->el_search.patlen] =
|
||||||
|
'\0';
|
||||||
|
if (el->el_line.cursor < el->el_line.buffer ||
|
||||||
|
el->el_line.cursor > el->el_line.lastchar ||
|
||||||
|
(ret = ce_search_line(el, newdir))
|
||||||
|
== CC_ERROR) {
|
||||||
|
/* avoid c_setpat */
|
||||||
|
el->el_state.lastcmd =
|
||||||
|
(el_action_t) newdir;
|
||||||
|
ret = newdir == ED_SEARCH_PREV_HISTORY ?
|
||||||
|
ed_search_prev_history(el, 0) :
|
||||||
|
ed_search_next_history(el, 0);
|
||||||
|
if (ret != CC_ERROR) {
|
||||||
|
el->el_line.cursor = newdir ==
|
||||||
|
ED_SEARCH_PREV_HISTORY ?
|
||||||
|
el->el_line.lastchar :
|
||||||
|
el->el_line.buffer;
|
||||||
|
(void) ce_search_line(el,
|
||||||
|
newdir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
el->el_search.patlen -= LEN;
|
||||||
|
el->el_search.patbuf[el->el_search.patlen] =
|
||||||
|
'\0';
|
||||||
|
if (ret == CC_ERROR) {
|
||||||
|
term_beep(el);
|
||||||
|
if (el->el_history.eventno !=
|
||||||
|
ohisteventno) {
|
||||||
|
el->el_history.eventno =
|
||||||
|
ohisteventno;
|
||||||
|
if (hist_get(el) == CC_ERROR)
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
el->el_line.cursor = ocursor;
|
||||||
|
pchar = '?';
|
||||||
|
} else {
|
||||||
|
pchar = ':';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ret = ce_inc_search(el, newdir);
|
||||||
|
|
||||||
|
if (ret == CC_ERROR && pchar == '?' && oldpchar == ':')
|
||||||
|
/*
|
||||||
|
* break abort of failed search at last
|
||||||
|
* non-failed
|
||||||
|
*/
|
||||||
|
ret = CC_NORM;
|
||||||
|
|
||||||
|
}
|
||||||
|
if (ret == CC_NORM || (ret == CC_ERROR && oldpatlen == 0)) {
|
||||||
|
/* restore on normal return or error exit */
|
||||||
|
pchar = oldpchar;
|
||||||
|
el->el_search.patlen = oldpatlen;
|
||||||
|
if (el->el_history.eventno != ohisteventno) {
|
||||||
|
el->el_history.eventno = ohisteventno;
|
||||||
|
if (hist_get(el) == CC_ERROR)
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
el->el_line.cursor = ocursor;
|
||||||
|
if (ret == CC_ERROR)
|
||||||
|
re_refresh(el);
|
||||||
|
}
|
||||||
|
if (done || ret != CC_NORM)
|
||||||
|
return (ret);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* cv_search():
|
||||||
|
* Vi search.
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
cv_search(EditLine *el, int dir)
|
||||||
|
{
|
||||||
|
char ch;
|
||||||
|
char tmpbuf[EL_BUFSIZ];
|
||||||
|
int tmplen;
|
||||||
|
|
||||||
|
#ifdef ANCHOR
|
||||||
|
tmpbuf[0] = '.';
|
||||||
|
tmpbuf[1] = '*';
|
||||||
|
#endif
|
||||||
|
tmplen = LEN;
|
||||||
|
|
||||||
|
el->el_search.patdir = dir;
|
||||||
|
|
||||||
|
tmplen = c_gets(el, &tmpbuf[LEN],
|
||||||
|
dir == ED_SEARCH_PREV_HISTORY ? "\n/" : "\n?" );
|
||||||
|
if (tmplen == -1)
|
||||||
|
return CC_REFRESH;
|
||||||
|
|
||||||
|
tmplen += LEN;
|
||||||
|
ch = tmpbuf[tmplen];
|
||||||
|
tmpbuf[tmplen] = '\0';
|
||||||
|
|
||||||
|
if (tmplen == LEN) {
|
||||||
|
/*
|
||||||
|
* Use the old pattern, but wild-card it.
|
||||||
|
*/
|
||||||
|
if (el->el_search.patlen == 0) {
|
||||||
|
re_refresh(el);
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
#ifdef ANCHOR
|
||||||
|
if (el->el_search.patbuf[0] != '.' &&
|
||||||
|
el->el_search.patbuf[0] != '*') {
|
||||||
|
(void) strncpy(tmpbuf, el->el_search.patbuf,
|
||||||
|
sizeof(tmpbuf) - 1);
|
||||||
|
el->el_search.patbuf[0] = '.';
|
||||||
|
el->el_search.patbuf[1] = '*';
|
||||||
|
(void) strncpy(&el->el_search.patbuf[2], tmpbuf,
|
||||||
|
EL_BUFSIZ - 3);
|
||||||
|
el->el_search.patlen++;
|
||||||
|
el->el_search.patbuf[el->el_search.patlen++] = '.';
|
||||||
|
el->el_search.patbuf[el->el_search.patlen++] = '*';
|
||||||
|
el->el_search.patbuf[el->el_search.patlen] = '\0';
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
#ifdef ANCHOR
|
||||||
|
tmpbuf[tmplen++] = '.';
|
||||||
|
tmpbuf[tmplen++] = '*';
|
||||||
|
#endif
|
||||||
|
tmpbuf[tmplen] = '\0';
|
||||||
|
(void) strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
|
||||||
|
el->el_search.patlen = tmplen;
|
||||||
|
}
|
||||||
|
el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */
|
||||||
|
el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer;
|
||||||
|
if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) :
|
||||||
|
ed_search_next_history(el, 0)) == CC_ERROR) {
|
||||||
|
re_refresh(el);
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
if (ch == 0033) {
|
||||||
|
re_refresh(el);
|
||||||
|
return ed_newline(el, 0);
|
||||||
|
}
|
||||||
|
return (CC_REFRESH);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ce_search_line():
|
||||||
|
* Look for a pattern inside a line
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
ce_search_line(EditLine *el, int dir)
|
||||||
|
{
|
||||||
|
char *cp = el->el_line.cursor;
|
||||||
|
char *pattern = el->el_search.patbuf;
|
||||||
|
char oc, *ocp;
|
||||||
|
#ifdef ANCHOR
|
||||||
|
ocp = &pattern[1];
|
||||||
|
oc = *ocp;
|
||||||
|
*ocp = '^';
|
||||||
|
#else
|
||||||
|
ocp = pattern;
|
||||||
|
oc = *ocp;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (dir == ED_SEARCH_PREV_HISTORY) {
|
||||||
|
for (; cp >= el->el_line.buffer; cp--) {
|
||||||
|
if (el_match(cp, ocp)) {
|
||||||
|
*ocp = oc;
|
||||||
|
el->el_line.cursor = cp;
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ocp = oc;
|
||||||
|
return (CC_ERROR);
|
||||||
|
} else {
|
||||||
|
for (; *cp != '\0' && cp < el->el_line.limit; cp++) {
|
||||||
|
if (el_match(cp, ocp)) {
|
||||||
|
*ocp = oc;
|
||||||
|
el->el_line.cursor = cp;
|
||||||
|
return (CC_NORM);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ocp = oc;
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* cv_repeat_srch():
|
||||||
|
* Vi repeat search
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
cv_repeat_srch(EditLine *el, int c)
|
||||||
|
{
|
||||||
|
|
||||||
|
#ifdef SDEBUG
|
||||||
|
(void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n",
|
||||||
|
c, el->el_search.patlen, el->el_search.patbuf);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */
|
||||||
|
el->el_line.lastchar = el->el_line.buffer;
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case ED_SEARCH_NEXT_HISTORY:
|
||||||
|
return (ed_search_next_history(el, 0));
|
||||||
|
case ED_SEARCH_PREV_HISTORY:
|
||||||
|
return (ed_search_prev_history(el, 0));
|
||||||
|
default:
|
||||||
|
return (CC_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* cv_csearch():
|
||||||
|
* Vi character search
|
||||||
|
*/
|
||||||
|
protected el_action_t
|
||||||
|
cv_csearch(EditLine *el, int direction, int ch, int count, int tflag)
|
||||||
|
{
|
||||||
|
char *cp;
|
||||||
|
|
||||||
|
if (ch == 0)
|
||||||
|
return CC_ERROR;
|
||||||
|
|
||||||
|
if (ch == -1) {
|
||||||
|
char c;
|
||||||
|
if (el_getc(el, &c) != 1)
|
||||||
|
return ed_end_of_file(el, 0);
|
||||||
|
ch = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Save for ';' and ',' commands */
|
||||||
|
el->el_search.chacha = ch;
|
||||||
|
el->el_search.chadir = direction;
|
||||||
|
el->el_search.chatflg = tflag;
|
||||||
|
|
||||||
|
cp = el->el_line.cursor;
|
||||||
|
while (count--) {
|
||||||
|
if (*cp == ch)
|
||||||
|
cp += direction;
|
||||||
|
for (;;cp += direction) {
|
||||||
|
if (cp >= el->el_line.lastchar)
|
||||||
|
return CC_ERROR;
|
||||||
|
if (cp < el->el_line.buffer)
|
||||||
|
return CC_ERROR;
|
||||||
|
if (*cp == ch)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tflag)
|
||||||
|
cp -= direction;
|
||||||
|
|
||||||
|
el->el_line.cursor = cp;
|
||||||
|
|
||||||
|
if (el->el_chared.c_vcmd.action != NOP) {
|
||||||
|
if (direction > 0)
|
||||||
|
el->el_line.cursor++;
|
||||||
|
cv_delfini(el);
|
||||||
|
return CC_REFRESH;
|
||||||
|
}
|
||||||
|
return CC_CURSOR;
|
||||||
|
}
|
|
@ -0,0 +1,66 @@
|
||||||
|
/* $NetBSD: search.h,v 1.8 2003/10/18 23:27:36 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)search.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.search.h: Line and history searching utilities
|
||||||
|
*/
|
||||||
|
#ifndef _h_el_search
|
||||||
|
#define _h_el_search
|
||||||
|
|
||||||
|
#include "histedit.h"
|
||||||
|
|
||||||
|
typedef struct el_search_t {
|
||||||
|
char *patbuf; /* The pattern buffer */
|
||||||
|
size_t patlen; /* Length of the pattern buffer */
|
||||||
|
int patdir; /* Direction of the last search */
|
||||||
|
int chadir; /* Character search direction */
|
||||||
|
char chacha; /* Character we are looking for */
|
||||||
|
char chatflg; /* 0 if f, 1 if t */
|
||||||
|
} el_search_t;
|
||||||
|
|
||||||
|
|
||||||
|
protected int el_match(const char *, const char *);
|
||||||
|
protected int search_init(EditLine *);
|
||||||
|
protected void search_end(EditLine *);
|
||||||
|
protected int c_hmatch(EditLine *, const char *);
|
||||||
|
protected void c_setpat(EditLine *);
|
||||||
|
protected el_action_t ce_inc_search(EditLine *, int);
|
||||||
|
protected el_action_t cv_search(EditLine *, int);
|
||||||
|
protected el_action_t ce_search_line(EditLine *, int);
|
||||||
|
protected el_action_t cv_repeat_srch(EditLine *, int);
|
||||||
|
protected el_action_t cv_csearch(EditLine *, int, int, int, int);
|
||||||
|
|
||||||
|
#endif /* _h_el_search */
|
|
@ -0,0 +1,5 @@
|
||||||
|
# $NetBSD: shlib_version,v 1.16 2006/11/24 00:01:17 christos Exp $
|
||||||
|
# Remember to update distrib/sets/lists/base/shl.* when changing
|
||||||
|
#
|
||||||
|
major=2
|
||||||
|
minor=10
|
|
@ -0,0 +1,194 @@
|
||||||
|
/* $NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sig.c: Signal handling stuff.
|
||||||
|
* our policy is to trap all signals, set a good state
|
||||||
|
* and pass the ball to our caller.
|
||||||
|
*/
|
||||||
|
#include "el.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
private EditLine *sel = NULL;
|
||||||
|
|
||||||
|
private const int sighdl[] = {
|
||||||
|
#define _DO(a) (a),
|
||||||
|
ALLSIGS
|
||||||
|
#undef _DO
|
||||||
|
- 1
|
||||||
|
};
|
||||||
|
|
||||||
|
private void sig_handler(int);
|
||||||
|
|
||||||
|
/* sig_handler():
|
||||||
|
* This is the handler called for all signals
|
||||||
|
* XXX: we cannot pass any data so we just store the old editline
|
||||||
|
* state in a private variable
|
||||||
|
*/
|
||||||
|
private void
|
||||||
|
sig_handler(int signo)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
sigset_t nset, oset;
|
||||||
|
|
||||||
|
(void) sigemptyset(&nset);
|
||||||
|
(void) sigaddset(&nset, signo);
|
||||||
|
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||||
|
|
||||||
|
switch (signo) {
|
||||||
|
case SIGCONT:
|
||||||
|
tty_rawmode(sel);
|
||||||
|
if (ed_redisplay(sel, 0) == CC_REFRESH)
|
||||||
|
re_refresh(sel);
|
||||||
|
term__flush();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGWINCH:
|
||||||
|
el_resize(sel);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
tty_cookedmode(sel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; sighdl[i] != -1; i++)
|
||||||
|
if (signo == sighdl[i])
|
||||||
|
break;
|
||||||
|
|
||||||
|
(void) signal(signo, sel->el_signal[i]);
|
||||||
|
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||||
|
(void) kill(0, signo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* sig_init():
|
||||||
|
* Initialize all signal stuff
|
||||||
|
*/
|
||||||
|
protected int
|
||||||
|
sig_init(EditLine *el)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
sigset_t nset, oset;
|
||||||
|
|
||||||
|
(void) sigemptyset(&nset);
|
||||||
|
#define _DO(a) (void) sigaddset(&nset, a);
|
||||||
|
ALLSIGS
|
||||||
|
#undef _DO
|
||||||
|
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||||
|
|
||||||
|
#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(el_signalhandler_t))
|
||||||
|
|
||||||
|
el->el_signal = (el_signalhandler_t *) el_malloc(SIGSIZE);
|
||||||
|
if (el->el_signal == NULL)
|
||||||
|
return (-1);
|
||||||
|
for (i = 0; sighdl[i] != -1; i++)
|
||||||
|
el->el_signal[i] = SIG_ERR;
|
||||||
|
|
||||||
|
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||||
|
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* sig_end():
|
||||||
|
* Clear all signal stuff
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
sig_end(EditLine *el)
|
||||||
|
{
|
||||||
|
|
||||||
|
el_free((ptr_t) el->el_signal);
|
||||||
|
el->el_signal = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* sig_set():
|
||||||
|
* set all the signal handlers
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
sig_set(EditLine *el)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
sigset_t nset, oset;
|
||||||
|
|
||||||
|
(void) sigemptyset(&nset);
|
||||||
|
#define _DO(a) (void) sigaddset(&nset, a);
|
||||||
|
ALLSIGS
|
||||||
|
#undef _DO
|
||||||
|
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||||
|
|
||||||
|
for (i = 0; sighdl[i] != -1; i++) {
|
||||||
|
el_signalhandler_t s;
|
||||||
|
/* This could happen if we get interrupted */
|
||||||
|
if ((s = signal(sighdl[i], sig_handler)) != sig_handler)
|
||||||
|
el->el_signal[i] = s;
|
||||||
|
}
|
||||||
|
sel = el;
|
||||||
|
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* sig_clr():
|
||||||
|
* clear all the signal handlers
|
||||||
|
*/
|
||||||
|
protected void
|
||||||
|
sig_clr(EditLine *el)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
sigset_t nset, oset;
|
||||||
|
|
||||||
|
(void) sigemptyset(&nset);
|
||||||
|
#define _DO(a) (void) sigaddset(&nset, a);
|
||||||
|
ALLSIGS
|
||||||
|
#undef _DO
|
||||||
|
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
|
||||||
|
|
||||||
|
for (i = 0; sighdl[i] != -1; i++)
|
||||||
|
if (el->el_signal[i] != SIG_ERR)
|
||||||
|
(void) signal(sighdl[i], el->el_signal[i]);
|
||||||
|
|
||||||
|
sel = NULL; /* we are going to die if the handler is
|
||||||
|
* called */
|
||||||
|
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
/* $NetBSD: sig.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)sig.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.sig.h: Signal handling functions
|
||||||
|
*/
|
||||||
|
#ifndef _h_el_sig
|
||||||
|
#define _h_el_sig
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
|
||||||
|
#include "histedit.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Define here all the signals we are going to handle
|
||||||
|
* The _DO macro is used to iterate in the source code
|
||||||
|
*/
|
||||||
|
#define ALLSIGS \
|
||||||
|
_DO(SIGINT) \
|
||||||
|
_DO(SIGTSTP) \
|
||||||
|
_DO(SIGSTOP) \
|
||||||
|
_DO(SIGQUIT) \
|
||||||
|
_DO(SIGHUP) \
|
||||||
|
_DO(SIGTERM) \
|
||||||
|
_DO(SIGCONT) \
|
||||||
|
_DO(SIGWINCH)
|
||||||
|
|
||||||
|
typedef void (*el_signalhandler_t)(int);
|
||||||
|
typedef el_signalhandler_t *el_signal_t;
|
||||||
|
|
||||||
|
protected void sig_end(EditLine*);
|
||||||
|
protected int sig_init(EditLine*);
|
||||||
|
protected void sig_set(EditLine*);
|
||||||
|
protected void sig_clr(EditLine*);
|
||||||
|
|
||||||
|
#endif /* _h_el_sig */
|
|
@ -0,0 +1,74 @@
|
||||||
|
/* $NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */
|
||||||
|
/* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
|
||||||
|
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
|
||||||
|
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
__RCSID("$NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $");
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
# ifdef __weak_alias
|
||||||
|
__weak_alias(strlcat, _strlcat)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_STRLCAT
|
||||||
|
/*
|
||||||
|
* Appends src to string dst of size siz (unlike strncat, siz is the
|
||||||
|
* full size of dst, not space left). At most siz-1 characters
|
||||||
|
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
|
||||||
|
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
|
||||||
|
* If retval >= siz, truncation occurred.
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
strlcat(char *dst, const char *src, size_t siz)
|
||||||
|
{
|
||||||
|
char *d = dst;
|
||||||
|
const char *s = src;
|
||||||
|
size_t n = siz;
|
||||||
|
size_t dlen;
|
||||||
|
|
||||||
|
_DIAGASSERT(dst != NULL);
|
||||||
|
_DIAGASSERT(src != NULL);
|
||||||
|
|
||||||
|
/* Find the end of dst and adjust bytes left but don't go past end */
|
||||||
|
while (n-- != 0 && *d != '\0')
|
||||||
|
d++;
|
||||||
|
dlen = d - dst;
|
||||||
|
n = siz - dlen;
|
||||||
|
|
||||||
|
if (n == 0)
|
||||||
|
return(dlen + strlen(s));
|
||||||
|
while (*s != '\0') {
|
||||||
|
if (n != 1) {
|
||||||
|
*d++ = *s;
|
||||||
|
n--;
|
||||||
|
}
|
||||||
|
s++;
|
||||||
|
}
|
||||||
|
*d = '\0';
|
||||||
|
|
||||||
|
return(dlen + (s - src)); /* count does not include NUL */
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,70 @@
|
||||||
|
/* $NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */
|
||||||
|
/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
|
||||||
|
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
|
||||||
|
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
|
||||||
|
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
|
||||||
|
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
__RCSID("$NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $");
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#ifdef _LIBC
|
||||||
|
# ifdef __weak_alias
|
||||||
|
__weak_alias(strlcpy, _strlcpy)
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_STRLCPY
|
||||||
|
/*
|
||||||
|
* Copy src to string dst of size siz. At most siz-1 characters
|
||||||
|
* will be copied. Always NUL terminates (unless siz == 0).
|
||||||
|
* Returns strlen(src); if retval >= siz, truncation occurred.
|
||||||
|
*/
|
||||||
|
size_t
|
||||||
|
strlcpy(char *dst, const char *src, size_t siz)
|
||||||
|
{
|
||||||
|
char *d = dst;
|
||||||
|
const char *s = src;
|
||||||
|
size_t n = siz;
|
||||||
|
|
||||||
|
_DIAGASSERT(dst != NULL);
|
||||||
|
_DIAGASSERT(src != NULL);
|
||||||
|
|
||||||
|
/* Copy as many bytes as will fit */
|
||||||
|
if (n != 0 && --n != 0) {
|
||||||
|
do {
|
||||||
|
if ((*d++ = *s++) == 0)
|
||||||
|
break;
|
||||||
|
} while (--n != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Not enough room in dst, add NUL and traverse rest of src */
|
||||||
|
if (n == 0) {
|
||||||
|
if (siz != 0)
|
||||||
|
*d = '\0'; /* NUL-terminate dst */
|
||||||
|
while (*s++)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(s - src - 1); /* count does not include NUL */
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,154 @@
|
||||||
|
/* $NetBSD: sys.h,v 1.9 2004/01/17 17:57:40 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)sys.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sys.h: Put all the stupid compiler and system dependencies here...
|
||||||
|
*/
|
||||||
|
#ifndef _h_sys
|
||||||
|
#define _h_sys
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#ifdef HAVE_SYS_CDEFS_H
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
|
||||||
|
# define __attribute__(A)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __P
|
||||||
|
# define __P(x) x
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _DIAGASSERT
|
||||||
|
# define _DIAGASSERT(x)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __BEGIN_DECLS
|
||||||
|
# ifdef __cplusplus
|
||||||
|
# define __BEGIN_DECLS extern "C" {
|
||||||
|
# define __END_DECLS }
|
||||||
|
# else
|
||||||
|
# define __BEGIN_DECLS
|
||||||
|
# define __END_DECLS
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef public
|
||||||
|
# define public /* Externally visible functions/variables */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef private
|
||||||
|
# define private static /* Always hidden internals */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef protected
|
||||||
|
# define protected /* Redefined from elsewhere to "static" */
|
||||||
|
/* When we want to hide everything */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_U_INT32_T
|
||||||
|
typedef unsigned int u_int32_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _PTR_T
|
||||||
|
# define _PTR_T
|
||||||
|
typedef void *ptr_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _IOCTL_T
|
||||||
|
# define _IOCTL_T
|
||||||
|
typedef void *ioctl_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef HAVE_STRLCAT
|
||||||
|
#define strlcat libedit_strlcat
|
||||||
|
size_t strlcat(char *dst, const char *src, size_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_STRLCPY
|
||||||
|
#define strlcpy libedit_strlcpy
|
||||||
|
size_t strlcpy(char *dst, const char *src, size_t size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef HAVE_FGETLN
|
||||||
|
#define fgetln libedit_fgetln
|
||||||
|
char *fgetln(FILE *fp, size_t *len);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define REGEX /* Use POSIX.2 regular expression functions */
|
||||||
|
#undef REGEXP /* Use UNIX V8 regular expression functions */
|
||||||
|
|
||||||
|
#ifdef notdef
|
||||||
|
# undef REGEX
|
||||||
|
# undef REGEXP
|
||||||
|
# include <malloc.h>
|
||||||
|
# ifdef __GNUC__
|
||||||
|
/*
|
||||||
|
* Broken hdrs.
|
||||||
|
*/
|
||||||
|
extern int tgetent(const char *bp, char *name);
|
||||||
|
extern int tgetflag(const char *id);
|
||||||
|
extern int tgetnum(const char *id);
|
||||||
|
extern char *tgetstr(const char *id, char **area);
|
||||||
|
extern char *tgoto(const char *cap, int col, int row);
|
||||||
|
extern int tputs(const char *str, int affcnt, int (*putc)(int));
|
||||||
|
extern char *getenv(const char *);
|
||||||
|
extern int fprintf(FILE *, const char *, ...);
|
||||||
|
extern int sigsetmask(int);
|
||||||
|
extern int sigblock(int);
|
||||||
|
extern int fputc(int, FILE *);
|
||||||
|
extern int fgetc(FILE *);
|
||||||
|
extern int fflush(FILE *);
|
||||||
|
extern int tolower(int);
|
||||||
|
extern int toupper(int);
|
||||||
|
extern int errno, sys_nerr;
|
||||||
|
extern char *sys_errlist[];
|
||||||
|
extern void perror(const char *);
|
||||||
|
# include <string.h>
|
||||||
|
# define strerror(e) sys_errlist[e]
|
||||||
|
# endif
|
||||||
|
# ifdef SABER
|
||||||
|
extern ptr_t memcpy(ptr_t, const ptr_t, size_t);
|
||||||
|
extern ptr_t memset(ptr_t, int, size_t);
|
||||||
|
# endif
|
||||||
|
extern char *fgetline(FILE *, int *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _h_sys */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,447 @@
|
||||||
|
/* $NetBSD: tokenizer.c,v 1.14 2003/12/05 13:37:48 lukem Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "config.h"
|
||||||
|
#if !defined(lint) && !defined(SCCSID)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: tokenizer.c,v 1.14 2003/12/05 13:37:48 lukem Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* not lint && not SCCSID */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tokenize.c: Bourne shell like tokenizer
|
||||||
|
*/
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "histedit.h"
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
Q_none, Q_single, Q_double, Q_one, Q_doubleone
|
||||||
|
} quote_t;
|
||||||
|
|
||||||
|
#define IFS "\t \n"
|
||||||
|
|
||||||
|
#define TOK_KEEP 1
|
||||||
|
#define TOK_EAT 2
|
||||||
|
|
||||||
|
#define WINCR 20
|
||||||
|
#define AINCR 10
|
||||||
|
|
||||||
|
#define tok_strdup(a) strdup(a)
|
||||||
|
#define tok_malloc(a) malloc(a)
|
||||||
|
#define tok_free(a) free(a)
|
||||||
|
#define tok_realloc(a, b) realloc(a, b)
|
||||||
|
|
||||||
|
|
||||||
|
struct tokenizer {
|
||||||
|
char *ifs; /* In field separator */
|
||||||
|
int argc, amax; /* Current and maximum number of args */
|
||||||
|
char **argv; /* Argument list */
|
||||||
|
char *wptr, *wmax; /* Space and limit on the word buffer */
|
||||||
|
char *wstart; /* Beginning of next word */
|
||||||
|
char *wspace; /* Space of word buffer */
|
||||||
|
quote_t quote; /* Quoting state */
|
||||||
|
int flags; /* flags; */
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
private void tok_finish(Tokenizer *);
|
||||||
|
|
||||||
|
|
||||||
|
/* tok_finish():
|
||||||
|
* Finish a word in the tokenizer.
|
||||||
|
*/
|
||||||
|
private void
|
||||||
|
tok_finish(Tokenizer *tok)
|
||||||
|
{
|
||||||
|
|
||||||
|
*tok->wptr = '\0';
|
||||||
|
if ((tok->flags & TOK_KEEP) || tok->wptr != tok->wstart) {
|
||||||
|
tok->argv[tok->argc++] = tok->wstart;
|
||||||
|
tok->argv[tok->argc] = NULL;
|
||||||
|
tok->wstart = ++tok->wptr;
|
||||||
|
}
|
||||||
|
tok->flags &= ~TOK_KEEP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* tok_init():
|
||||||
|
* Initialize the tokenizer
|
||||||
|
*/
|
||||||
|
public Tokenizer *
|
||||||
|
tok_init(const char *ifs)
|
||||||
|
{
|
||||||
|
Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer));
|
||||||
|
|
||||||
|
if (tok == NULL)
|
||||||
|
return NULL;
|
||||||
|
tok->ifs = tok_strdup(ifs ? ifs : IFS);
|
||||||
|
if (tok->ifs == NULL) {
|
||||||
|
tok_free((ptr_t)tok);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tok->argc = 0;
|
||||||
|
tok->amax = AINCR;
|
||||||
|
tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax);
|
||||||
|
if (tok->argv == NULL) {
|
||||||
|
tok_free((ptr_t)tok->ifs);
|
||||||
|
tok_free((ptr_t)tok);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tok->argv[0] = NULL;
|
||||||
|
tok->wspace = (char *) tok_malloc(WINCR);
|
||||||
|
if (tok->wspace == NULL) {
|
||||||
|
tok_free((ptr_t)tok->argv);
|
||||||
|
tok_free((ptr_t)tok->ifs);
|
||||||
|
tok_free((ptr_t)tok);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
tok->wmax = tok->wspace + WINCR;
|
||||||
|
tok->wstart = tok->wspace;
|
||||||
|
tok->wptr = tok->wspace;
|
||||||
|
tok->flags = 0;
|
||||||
|
tok->quote = Q_none;
|
||||||
|
|
||||||
|
return (tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* tok_reset():
|
||||||
|
* Reset the tokenizer
|
||||||
|
*/
|
||||||
|
public void
|
||||||
|
tok_reset(Tokenizer *tok)
|
||||||
|
{
|
||||||
|
|
||||||
|
tok->argc = 0;
|
||||||
|
tok->wstart = tok->wspace;
|
||||||
|
tok->wptr = tok->wspace;
|
||||||
|
tok->flags = 0;
|
||||||
|
tok->quote = Q_none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* tok_end():
|
||||||
|
* Clean up
|
||||||
|
*/
|
||||||
|
public void
|
||||||
|
tok_end(Tokenizer *tok)
|
||||||
|
{
|
||||||
|
|
||||||
|
tok_free((ptr_t) tok->ifs);
|
||||||
|
tok_free((ptr_t) tok->wspace);
|
||||||
|
tok_free((ptr_t) tok->argv);
|
||||||
|
tok_free((ptr_t) tok);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* tok_line():
|
||||||
|
* Bourne shell (sh(1)) like tokenizing
|
||||||
|
* Arguments:
|
||||||
|
* tok current tokenizer state (setup with tok_init())
|
||||||
|
* line line to parse
|
||||||
|
* Returns:
|
||||||
|
* -1 Internal error
|
||||||
|
* 3 Quoted return
|
||||||
|
* 2 Unmatched double quote
|
||||||
|
* 1 Unmatched single quote
|
||||||
|
* 0 Ok
|
||||||
|
* Modifies (if return value is 0):
|
||||||
|
* argc number of arguments
|
||||||
|
* argv argument array
|
||||||
|
* cursorc if !NULL, argv element containing cursor
|
||||||
|
* cursorv if !NULL, offset in argv[cursorc] of cursor
|
||||||
|
*/
|
||||||
|
public int
|
||||||
|
tok_line(Tokenizer *tok, const LineInfo *line,
|
||||||
|
int *argc, const char ***argv, int *cursorc, int *cursoro)
|
||||||
|
{
|
||||||
|
const char *ptr;
|
||||||
|
int cc, co;
|
||||||
|
|
||||||
|
cc = co = -1;
|
||||||
|
ptr = line->buffer;
|
||||||
|
for (ptr = line->buffer; ;ptr++) {
|
||||||
|
if (ptr >= line->lastchar)
|
||||||
|
ptr = "";
|
||||||
|
if (ptr == line->cursor) {
|
||||||
|
cc = tok->argc;
|
||||||
|
co = tok->wptr - tok->wstart;
|
||||||
|
}
|
||||||
|
switch (*ptr) {
|
||||||
|
case '\'':
|
||||||
|
tok->flags |= TOK_KEEP;
|
||||||
|
tok->flags &= ~TOK_EAT;
|
||||||
|
switch (tok->quote) {
|
||||||
|
case Q_none:
|
||||||
|
tok->quote = Q_single; /* Enter single quote
|
||||||
|
* mode */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_single: /* Exit single quote mode */
|
||||||
|
tok->quote = Q_none;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_one: /* Quote this ' */
|
||||||
|
tok->quote = Q_none;
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_double: /* Stay in double quote mode */
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_doubleone: /* Quote this ' */
|
||||||
|
tok->quote = Q_double;
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '"':
|
||||||
|
tok->flags &= ~TOK_EAT;
|
||||||
|
tok->flags |= TOK_KEEP;
|
||||||
|
switch (tok->quote) {
|
||||||
|
case Q_none: /* Enter double quote mode */
|
||||||
|
tok->quote = Q_double;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_double: /* Exit double quote mode */
|
||||||
|
tok->quote = Q_none;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_one: /* Quote this " */
|
||||||
|
tok->quote = Q_none;
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_single: /* Stay in single quote mode */
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_doubleone: /* Quote this " */
|
||||||
|
tok->quote = Q_double;
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
tok->flags |= TOK_KEEP;
|
||||||
|
tok->flags &= ~TOK_EAT;
|
||||||
|
switch (tok->quote) {
|
||||||
|
case Q_none: /* Quote next character */
|
||||||
|
tok->quote = Q_one;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_double: /* Quote next character */
|
||||||
|
tok->quote = Q_doubleone;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_one: /* Quote this, restore state */
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
tok->quote = Q_none;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_single: /* Stay in single quote mode */
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_doubleone: /* Quote this \ */
|
||||||
|
tok->quote = Q_double;
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\n':
|
||||||
|
tok->flags &= ~TOK_EAT;
|
||||||
|
switch (tok->quote) {
|
||||||
|
case Q_none:
|
||||||
|
goto tok_line_outok;
|
||||||
|
|
||||||
|
case Q_single:
|
||||||
|
case Q_double:
|
||||||
|
*tok->wptr++ = *ptr; /* Add the return */
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_doubleone: /* Back to double, eat the '\n' */
|
||||||
|
tok->flags |= TOK_EAT;
|
||||||
|
tok->quote = Q_double;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_one: /* No quote, more eat the '\n' */
|
||||||
|
tok->flags |= TOK_EAT;
|
||||||
|
tok->quote = Q_none;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\0':
|
||||||
|
switch (tok->quote) {
|
||||||
|
case Q_none:
|
||||||
|
/* Finish word and return */
|
||||||
|
if (tok->flags & TOK_EAT) {
|
||||||
|
tok->flags &= ~TOK_EAT;
|
||||||
|
return (3);
|
||||||
|
}
|
||||||
|
goto tok_line_outok;
|
||||||
|
|
||||||
|
case Q_single:
|
||||||
|
return (1);
|
||||||
|
|
||||||
|
case Q_double:
|
||||||
|
return (2);
|
||||||
|
|
||||||
|
case Q_doubleone:
|
||||||
|
tok->quote = Q_double;
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_one:
|
||||||
|
tok->quote = Q_none;
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
tok->flags &= ~TOK_EAT;
|
||||||
|
switch (tok->quote) {
|
||||||
|
case Q_none:
|
||||||
|
if (strchr(tok->ifs, *ptr) != NULL)
|
||||||
|
tok_finish(tok);
|
||||||
|
else
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_single:
|
||||||
|
case Q_double:
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
|
case Q_doubleone:
|
||||||
|
*tok->wptr++ = '\\';
|
||||||
|
tok->quote = Q_double;
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Q_one:
|
||||||
|
tok->quote = Q_none;
|
||||||
|
*tok->wptr++ = *ptr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tok->wptr >= tok->wmax - 4) {
|
||||||
|
size_t size = tok->wmax - tok->wspace + WINCR;
|
||||||
|
char *s = (char *) tok_realloc(tok->wspace, size);
|
||||||
|
if (s == NULL)
|
||||||
|
return (-1);
|
||||||
|
|
||||||
|
if (s != tok->wspace) {
|
||||||
|
int i;
|
||||||
|
for (i = 0; i < tok->argc; i++) {
|
||||||
|
tok->argv[i] =
|
||||||
|
(tok->argv[i] - tok->wspace) + s;
|
||||||
|
}
|
||||||
|
tok->wptr = (tok->wptr - tok->wspace) + s;
|
||||||
|
tok->wstart = (tok->wstart - tok->wspace) + s;
|
||||||
|
tok->wspace = s;
|
||||||
|
}
|
||||||
|
tok->wmax = s + size;
|
||||||
|
}
|
||||||
|
if (tok->argc >= tok->amax - 4) {
|
||||||
|
char **p;
|
||||||
|
tok->amax += AINCR;
|
||||||
|
p = (char **) tok_realloc(tok->argv,
|
||||||
|
tok->amax * sizeof(char *));
|
||||||
|
if (p == NULL)
|
||||||
|
return (-1);
|
||||||
|
tok->argv = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tok_line_outok:
|
||||||
|
if (cc == -1 && co == -1) {
|
||||||
|
cc = tok->argc;
|
||||||
|
co = tok->wptr - tok->wstart;
|
||||||
|
}
|
||||||
|
if (cursorc != NULL)
|
||||||
|
*cursorc = cc;
|
||||||
|
if (cursoro != NULL)
|
||||||
|
*cursoro = co;
|
||||||
|
tok_finish(tok);
|
||||||
|
*argv = (const char **)tok->argv;
|
||||||
|
*argc = tok->argc;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* tok_str():
|
||||||
|
* Simpler version of tok_line, taking a NUL terminated line
|
||||||
|
* and splitting into words, ignoring cursor state.
|
||||||
|
*/
|
||||||
|
public int
|
||||||
|
tok_str(Tokenizer *tok, const char *line, int *argc, const char ***argv)
|
||||||
|
{
|
||||||
|
LineInfo li;
|
||||||
|
|
||||||
|
memset(&li, 0, sizeof(li));
|
||||||
|
li.buffer = line;
|
||||||
|
li.cursor = li.lastchar = strchr(line, '\0');
|
||||||
|
return (tok_line(tok, &li, argc, argv, NULL, NULL));
|
||||||
|
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,480 @@
|
||||||
|
/* $NetBSD: tty.h,v 1.11 2005/06/01 11:37:52 lukem Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1992, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* This code is derived from software contributed to Berkeley by
|
||||||
|
* Christos Zoulas of Cornell University.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)tty.h 8.1 (Berkeley) 6/4/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* el.tty.h: Local terminal header
|
||||||
|
*/
|
||||||
|
#ifndef _h_el_tty
|
||||||
|
#define _h_el_tty
|
||||||
|
|
||||||
|
#include "histedit.h"
|
||||||
|
#include <termios.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
/* Define our own since everyone gets it wrong! */
|
||||||
|
#define CONTROL(A) ((A) & 037)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Aix compatible names
|
||||||
|
*/
|
||||||
|
# if defined(VWERSE) && !defined(VWERASE)
|
||||||
|
# define VWERASE VWERSE
|
||||||
|
# endif /* VWERSE && !VWERASE */
|
||||||
|
|
||||||
|
# if defined(VDISCRD) && !defined(VDISCARD)
|
||||||
|
# define VDISCARD VDISCRD
|
||||||
|
# endif /* VDISCRD && !VDISCARD */
|
||||||
|
|
||||||
|
# if defined(VFLUSHO) && !defined(VDISCARD)
|
||||||
|
# define VDISCARD VFLUSHO
|
||||||
|
# endif /* VFLUSHO && VDISCARD */
|
||||||
|
|
||||||
|
# if defined(VSTRT) && !defined(VSTART)
|
||||||
|
# define VSTART VSTRT
|
||||||
|
# endif /* VSTRT && ! VSTART */
|
||||||
|
|
||||||
|
# if defined(VSTAT) && !defined(VSTATUS)
|
||||||
|
# define VSTATUS VSTAT
|
||||||
|
# endif /* VSTAT && ! VSTATUS */
|
||||||
|
|
||||||
|
# ifndef ONLRET
|
||||||
|
# define ONLRET 0
|
||||||
|
# endif /* ONLRET */
|
||||||
|
|
||||||
|
# ifndef TAB3
|
||||||
|
# ifdef OXTABS
|
||||||
|
# define TAB3 OXTABS
|
||||||
|
# else
|
||||||
|
# define TAB3 0
|
||||||
|
# endif /* OXTABS */
|
||||||
|
# endif /* !TAB3 */
|
||||||
|
|
||||||
|
# if defined(OXTABS) && !defined(XTABS)
|
||||||
|
# define XTABS OXTABS
|
||||||
|
# endif /* OXTABS && !XTABS */
|
||||||
|
|
||||||
|
# ifndef ONLCR
|
||||||
|
# define ONLCR 0
|
||||||
|
# endif /* ONLCR */
|
||||||
|
|
||||||
|
# ifndef IEXTEN
|
||||||
|
# define IEXTEN 0
|
||||||
|
# endif /* IEXTEN */
|
||||||
|
|
||||||
|
# ifndef ECHOCTL
|
||||||
|
# define ECHOCTL 0
|
||||||
|
# endif /* ECHOCTL */
|
||||||
|
|
||||||
|
# ifndef PARENB
|
||||||
|
# define PARENB 0
|
||||||
|
# endif /* PARENB */
|
||||||
|
|
||||||
|
# ifndef EXTPROC
|
||||||
|
# define EXTPROC 0
|
||||||
|
# endif /* EXTPROC */
|
||||||
|
|
||||||
|
# ifndef FLUSHO
|
||||||
|
# define FLUSHO 0
|
||||||
|
# endif /* FLUSHO */
|
||||||
|
|
||||||
|
|
||||||
|
# if defined(VDISABLE) && !defined(_POSIX_VDISABLE)
|
||||||
|
# define _POSIX_VDISABLE VDISABLE
|
||||||
|
# endif /* VDISABLE && ! _POSIX_VDISABLE */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Work around ISC's definition of IEXTEN which is
|
||||||
|
* XCASE!
|
||||||
|
*/
|
||||||
|
# ifdef ISC
|
||||||
|
# if defined(IEXTEN) && defined(XCASE)
|
||||||
|
# if IEXTEN == XCASE
|
||||||
|
# undef IEXTEN
|
||||||
|
# define IEXTEN 0
|
||||||
|
# endif /* IEXTEN == XCASE */
|
||||||
|
# endif /* IEXTEN && XCASE */
|
||||||
|
# if defined(IEXTEN) && !defined(XCASE)
|
||||||
|
# define XCASE IEXTEN
|
||||||
|
# undef IEXTEN
|
||||||
|
# define IEXTEN 0
|
||||||
|
# endif /* IEXTEN && !XCASE */
|
||||||
|
# endif /* ISC */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Work around convex weirdness where turning off IEXTEN makes us
|
||||||
|
* lose all postprocessing!
|
||||||
|
*/
|
||||||
|
#if defined(convex) || defined(__convex__)
|
||||||
|
# if defined(IEXTEN) && IEXTEN != 0
|
||||||
|
# undef IEXTEN
|
||||||
|
# define IEXTEN 0
|
||||||
|
# endif /* IEXTEN != 0 */
|
||||||
|
#endif /* convex || __convex__ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* So that we don't lose job control.
|
||||||
|
*/
|
||||||
|
#ifdef __SVR4
|
||||||
|
# undef CSWTCH
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _POSIX_VDISABLE
|
||||||
|
# define _POSIX_VDISABLE ((unsigned char) -1)
|
||||||
|
#endif /* _POSIX_VDISABLE */
|
||||||
|
|
||||||
|
#if !defined(CREPRINT) && defined(CRPRNT)
|
||||||
|
# define CREPRINT CRPRNT
|
||||||
|
#endif /* !CREPRINT && CRPRNT */
|
||||||
|
#if !defined(CDISCARD) && defined(CFLUSH)
|
||||||
|
# define CDISCARD CFLUSH
|
||||||
|
#endif /* !CDISCARD && CFLUSH */
|
||||||
|
|
||||||
|
#ifndef CINTR
|
||||||
|
# define CINTR CONTROL('c')
|
||||||
|
#endif /* CINTR */
|
||||||
|
#ifndef CQUIT
|
||||||
|
# define CQUIT 034 /* ^\ */
|
||||||
|
#endif /* CQUIT */
|
||||||
|
#ifndef CERASE
|
||||||
|
# define CERASE 0177 /* ^? */
|
||||||
|
#endif /* CERASE */
|
||||||
|
#ifndef CKILL
|
||||||
|
# define CKILL CONTROL('u')
|
||||||
|
#endif /* CKILL */
|
||||||
|
#ifndef CEOF
|
||||||
|
# define CEOF CONTROL('d')
|
||||||
|
#endif /* CEOF */
|
||||||
|
#ifndef CEOL
|
||||||
|
# define CEOL _POSIX_VDISABLE
|
||||||
|
#endif /* CEOL */
|
||||||
|
#ifndef CEOL2
|
||||||
|
# define CEOL2 _POSIX_VDISABLE
|
||||||
|
#endif /* CEOL2 */
|
||||||
|
#ifndef CSWTCH
|
||||||
|
# define CSWTCH _POSIX_VDISABLE
|
||||||
|
#endif /* CSWTCH */
|
||||||
|
#ifndef CDSWTCH
|
||||||
|
# define CDSWTCH _POSIX_VDISABLE
|
||||||
|
#endif /* CDSWTCH */
|
||||||
|
#ifndef CERASE2
|
||||||
|
# define CERASE2 _POSIX_VDISABLE
|
||||||
|
#endif /* CERASE2 */
|
||||||
|
#ifndef CSTART
|
||||||
|
# define CSTART CONTROL('q')
|
||||||
|
#endif /* CSTART */
|
||||||
|
#ifndef CSTOP
|
||||||
|
# define CSTOP CONTROL('s')
|
||||||
|
#endif /* CSTOP */
|
||||||
|
#ifndef CSUSP
|
||||||
|
# define CSUSP CONTROL('z')
|
||||||
|
#endif /* CSUSP */
|
||||||
|
#ifndef CDSUSP
|
||||||
|
# define CDSUSP CONTROL('y')
|
||||||
|
#endif /* CDSUSP */
|
||||||
|
|
||||||
|
#ifdef hpux
|
||||||
|
|
||||||
|
# ifndef CREPRINT
|
||||||
|
# define CREPRINT _POSIX_VDISABLE
|
||||||
|
# endif /* CREPRINT */
|
||||||
|
# ifndef CDISCARD
|
||||||
|
# define CDISCARD _POSIX_VDISABLE
|
||||||
|
# endif /* CDISCARD */
|
||||||
|
# ifndef CLNEXT
|
||||||
|
# define CLNEXT _POSIX_VDISABLE
|
||||||
|
# endif /* CLNEXT */
|
||||||
|
# ifndef CWERASE
|
||||||
|
# define CWERASE _POSIX_VDISABLE
|
||||||
|
# endif /* CWERASE */
|
||||||
|
|
||||||
|
#else /* !hpux */
|
||||||
|
|
||||||
|
# ifndef CREPRINT
|
||||||
|
# define CREPRINT CONTROL('r')
|
||||||
|
# endif /* CREPRINT */
|
||||||
|
# ifndef CDISCARD
|
||||||
|
# define CDISCARD CONTROL('o')
|
||||||
|
# endif /* CDISCARD */
|
||||||
|
# ifndef CLNEXT
|
||||||
|
# define CLNEXT CONTROL('v')
|
||||||
|
# endif /* CLNEXT */
|
||||||
|
# ifndef CWERASE
|
||||||
|
# define CWERASE CONTROL('w')
|
||||||
|
# endif /* CWERASE */
|
||||||
|
|
||||||
|
#endif /* hpux */
|
||||||
|
|
||||||
|
#ifndef CSTATUS
|
||||||
|
# define CSTATUS CONTROL('t')
|
||||||
|
#endif /* CSTATUS */
|
||||||
|
#ifndef CPAGE
|
||||||
|
# define CPAGE ' '
|
||||||
|
#endif /* CPAGE */
|
||||||
|
#ifndef CPGOFF
|
||||||
|
# define CPGOFF CONTROL('m')
|
||||||
|
#endif /* CPGOFF */
|
||||||
|
#ifndef CKILL2
|
||||||
|
# define CKILL2 _POSIX_VDISABLE
|
||||||
|
#endif /* CKILL2 */
|
||||||
|
#ifndef CBRK
|
||||||
|
# ifndef masscomp
|
||||||
|
# define CBRK 0377
|
||||||
|
# else
|
||||||
|
# define CBRK '\0'
|
||||||
|
# endif /* masscomp */
|
||||||
|
#endif /* CBRK */
|
||||||
|
#ifndef CMIN
|
||||||
|
# define CMIN CEOF
|
||||||
|
#endif /* CMIN */
|
||||||
|
#ifndef CTIME
|
||||||
|
# define CTIME CEOL
|
||||||
|
#endif /* CTIME */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Fix for sun inconsistency. On termio VSUSP and the rest of the
|
||||||
|
* ttychars > NCC are defined. So we undefine them.
|
||||||
|
*/
|
||||||
|
#if defined(TERMIO) || defined(POSIX)
|
||||||
|
# if defined(POSIX) && defined(NCCS)
|
||||||
|
# define NUMCC NCCS
|
||||||
|
# else
|
||||||
|
# ifdef NCC
|
||||||
|
# define NUMCC NCC
|
||||||
|
# endif /* NCC */
|
||||||
|
# endif /* POSIX && NCCS */
|
||||||
|
# ifdef NUMCC
|
||||||
|
# ifdef VINTR
|
||||||
|
# if NUMCC <= VINTR
|
||||||
|
# undef VINTR
|
||||||
|
# endif /* NUMCC <= VINTR */
|
||||||
|
# endif /* VINTR */
|
||||||
|
# ifdef VQUIT
|
||||||
|
# if NUMCC <= VQUIT
|
||||||
|
# undef VQUIT
|
||||||
|
# endif /* NUMCC <= VQUIT */
|
||||||
|
# endif /* VQUIT */
|
||||||
|
# ifdef VERASE
|
||||||
|
# if NUMCC <= VERASE
|
||||||
|
# undef VERASE
|
||||||
|
# endif /* NUMCC <= VERASE */
|
||||||
|
# endif /* VERASE */
|
||||||
|
# ifdef VKILL
|
||||||
|
# if NUMCC <= VKILL
|
||||||
|
# undef VKILL
|
||||||
|
# endif /* NUMCC <= VKILL */
|
||||||
|
# endif /* VKILL */
|
||||||
|
# ifdef VEOF
|
||||||
|
# if NUMCC <= VEOF
|
||||||
|
# undef VEOF
|
||||||
|
# endif /* NUMCC <= VEOF */
|
||||||
|
# endif /* VEOF */
|
||||||
|
# ifdef VEOL
|
||||||
|
# if NUMCC <= VEOL
|
||||||
|
# undef VEOL
|
||||||
|
# endif /* NUMCC <= VEOL */
|
||||||
|
# endif /* VEOL */
|
||||||
|
# ifdef VEOL2
|
||||||
|
# if NUMCC <= VEOL2
|
||||||
|
# undef VEOL2
|
||||||
|
# endif /* NUMCC <= VEOL2 */
|
||||||
|
# endif /* VEOL2 */
|
||||||
|
# ifdef VSWTCH
|
||||||
|
# if NUMCC <= VSWTCH
|
||||||
|
# undef VSWTCH
|
||||||
|
# endif /* NUMCC <= VSWTCH */
|
||||||
|
# endif /* VSWTCH */
|
||||||
|
# ifdef VDSWTCH
|
||||||
|
# if NUMCC <= VDSWTCH
|
||||||
|
# undef VDSWTCH
|
||||||
|
# endif /* NUMCC <= VDSWTCH */
|
||||||
|
# endif /* VDSWTCH */
|
||||||
|
# ifdef VERASE2
|
||||||
|
# if NUMCC <= VERASE2
|
||||||
|
# undef VERASE2
|
||||||
|
# endif /* NUMCC <= VERASE2 */
|
||||||
|
# endif /* VERASE2 */
|
||||||
|
# ifdef VSTART
|
||||||
|
# if NUMCC <= VSTART
|
||||||
|
# undef VSTART
|
||||||
|
# endif /* NUMCC <= VSTART */
|
||||||
|
# endif /* VSTART */
|
||||||
|
# ifdef VSTOP
|
||||||
|
# if NUMCC <= VSTOP
|
||||||
|
# undef VSTOP
|
||||||
|
# endif /* NUMCC <= VSTOP */
|
||||||
|
# endif /* VSTOP */
|
||||||
|
# ifdef VWERASE
|
||||||
|
# if NUMCC <= VWERASE
|
||||||
|
# undef VWERASE
|
||||||
|
# endif /* NUMCC <= VWERASE */
|
||||||
|
# endif /* VWERASE */
|
||||||
|
# ifdef VSUSP
|
||||||
|
# if NUMCC <= VSUSP
|
||||||
|
# undef VSUSP
|
||||||
|
# endif /* NUMCC <= VSUSP */
|
||||||
|
# endif /* VSUSP */
|
||||||
|
# ifdef VDSUSP
|
||||||
|
# if NUMCC <= VDSUSP
|
||||||
|
# undef VDSUSP
|
||||||
|
# endif /* NUMCC <= VDSUSP */
|
||||||
|
# endif /* VDSUSP */
|
||||||
|
# ifdef VREPRINT
|
||||||
|
# if NUMCC <= VREPRINT
|
||||||
|
# undef VREPRINT
|
||||||
|
# endif /* NUMCC <= VREPRINT */
|
||||||
|
# endif /* VREPRINT */
|
||||||
|
# ifdef VDISCARD
|
||||||
|
# if NUMCC <= VDISCARD
|
||||||
|
# undef VDISCARD
|
||||||
|
# endif /* NUMCC <= VDISCARD */
|
||||||
|
# endif /* VDISCARD */
|
||||||
|
# ifdef VLNEXT
|
||||||
|
# if NUMCC <= VLNEXT
|
||||||
|
# undef VLNEXT
|
||||||
|
# endif /* NUMCC <= VLNEXT */
|
||||||
|
# endif /* VLNEXT */
|
||||||
|
# ifdef VSTATUS
|
||||||
|
# if NUMCC <= VSTATUS
|
||||||
|
# undef VSTATUS
|
||||||
|
# endif /* NUMCC <= VSTATUS */
|
||||||
|
# endif /* VSTATUS */
|
||||||
|
# ifdef VPAGE
|
||||||
|
# if NUMCC <= VPAGE
|
||||||
|
# undef VPAGE
|
||||||
|
# endif /* NUMCC <= VPAGE */
|
||||||
|
# endif /* VPAGE */
|
||||||
|
# ifdef VPGOFF
|
||||||
|
# if NUMCC <= VPGOFF
|
||||||
|
# undef VPGOFF
|
||||||
|
# endif /* NUMCC <= VPGOFF */
|
||||||
|
# endif /* VPGOFF */
|
||||||
|
# ifdef VKILL2
|
||||||
|
# if NUMCC <= VKILL2
|
||||||
|
# undef VKILL2
|
||||||
|
# endif /* NUMCC <= VKILL2 */
|
||||||
|
# endif /* VKILL2 */
|
||||||
|
# ifdef VBRK
|
||||||
|
# if NUMCC <= VBRK
|
||||||
|
# undef VBRK
|
||||||
|
# endif /* NUMCC <= VBRK */
|
||||||
|
# endif /* VBRK */
|
||||||
|
# ifdef VMIN
|
||||||
|
# if NUMCC <= VMIN
|
||||||
|
# undef VMIN
|
||||||
|
# endif /* NUMCC <= VMIN */
|
||||||
|
# endif /* VMIN */
|
||||||
|
# ifdef VTIME
|
||||||
|
# if NUMCC <= VTIME
|
||||||
|
# undef VTIME
|
||||||
|
# endif /* NUMCC <= VTIME */
|
||||||
|
# endif /* VTIME */
|
||||||
|
# endif /* NUMCC */
|
||||||
|
#endif /* !POSIX */
|
||||||
|
|
||||||
|
#define C_INTR 0
|
||||||
|
#define C_QUIT 1
|
||||||
|
#define C_ERASE 2
|
||||||
|
#define C_KILL 3
|
||||||
|
#define C_EOF 4
|
||||||
|
#define C_EOL 5
|
||||||
|
#define C_EOL2 6
|
||||||
|
#define C_SWTCH 7
|
||||||
|
#define C_DSWTCH 8
|
||||||
|
#define C_ERASE2 9
|
||||||
|
#define C_START 10
|
||||||
|
#define C_STOP 11
|
||||||
|
#define C_WERASE 12
|
||||||
|
#define C_SUSP 13
|
||||||
|
#define C_DSUSP 14
|
||||||
|
#define C_REPRINT 15
|
||||||
|
#define C_DISCARD 16
|
||||||
|
#define C_LNEXT 17
|
||||||
|
#define C_STATUS 18
|
||||||
|
#define C_PAGE 19
|
||||||
|
#define C_PGOFF 20
|
||||||
|
#define C_KILL2 21
|
||||||
|
#define C_BRK 22
|
||||||
|
#define C_MIN 23
|
||||||
|
#define C_TIME 24
|
||||||
|
#define C_NCC 25
|
||||||
|
#define C_SH(A) (1 << (A))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Terminal dependend data structures
|
||||||
|
*/
|
||||||
|
#define EX_IO 0 /* while we are executing */
|
||||||
|
#define ED_IO 1 /* while we are editing */
|
||||||
|
#define TS_IO 2 /* new mode from terminal */
|
||||||
|
#define QU_IO 2 /* used only for quoted chars */
|
||||||
|
#define NN_IO 3 /* The number of entries */
|
||||||
|
|
||||||
|
#define MD_INP 0
|
||||||
|
#define MD_OUT 1
|
||||||
|
#define MD_CTL 2
|
||||||
|
#define MD_LIN 3
|
||||||
|
#define MD_CHAR 4
|
||||||
|
#define MD_NN 5
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *t_name;
|
||||||
|
unsigned int t_setmask;
|
||||||
|
unsigned int t_clrmask;
|
||||||
|
} ttyperm_t[NN_IO][MD_NN];
|
||||||
|
|
||||||
|
typedef unsigned char ttychar_t[NN_IO][C_NCC];
|
||||||
|
|
||||||
|
protected int tty_init(EditLine *);
|
||||||
|
protected void tty_end(EditLine *);
|
||||||
|
protected int tty_stty(EditLine *, int, const char **);
|
||||||
|
protected int tty_rawmode(EditLine *);
|
||||||
|
protected int tty_cookedmode(EditLine *);
|
||||||
|
protected int tty_quotemode(EditLine *);
|
||||||
|
protected int tty_noquotemode(EditLine *);
|
||||||
|
protected void tty_bind_char(EditLine *, int);
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
ttyperm_t t_t;
|
||||||
|
ttychar_t t_c;
|
||||||
|
struct termios t_ex, t_ed, t_ts;
|
||||||
|
int t_tabs;
|
||||||
|
int t_eight;
|
||||||
|
speed_t t_speed;
|
||||||
|
int t_mode;
|
||||||
|
unsigned char t_vdisable;
|
||||||
|
} el_tty_t;
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* _h_el_tty */
|
|
@ -0,0 +1,305 @@
|
||||||
|
/* $NetBSD: unvis.c,v 1.28 2005/09/13 01:44:09 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
#if 0
|
||||||
|
static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93";
|
||||||
|
#else
|
||||||
|
__RCSID("$NetBSD: unvis.c,v 1.28 2005/09/13 01:44:09 christos Exp $");
|
||||||
|
#endif
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <vis.h>
|
||||||
|
|
||||||
|
#ifdef __weak_alias
|
||||||
|
__weak_alias(strunvis,_strunvis)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_VIS
|
||||||
|
/*
|
||||||
|
* decode driven by state machine
|
||||||
|
*/
|
||||||
|
#define S_GROUND 0 /* haven't seen escape char */
|
||||||
|
#define S_START 1 /* start decoding special sequence */
|
||||||
|
#define S_META 2 /* metachar started (M) */
|
||||||
|
#define S_META1 3 /* metachar more, regular char (-) */
|
||||||
|
#define S_CTRL 4 /* control char started (^) */
|
||||||
|
#define S_OCTAL2 5 /* octal digit 2 */
|
||||||
|
#define S_OCTAL3 6 /* octal digit 3 */
|
||||||
|
#define S_HEX1 7 /* hex digit */
|
||||||
|
#define S_HEX2 8 /* hex digit 2 */
|
||||||
|
|
||||||
|
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
|
||||||
|
#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10))
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unvis - decode characters previously encoded by vis
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
unvis(cp, c, astate, flag)
|
||||||
|
char *cp;
|
||||||
|
int c;
|
||||||
|
int *astate, flag;
|
||||||
|
{
|
||||||
|
unsigned char uc = (unsigned char)c;
|
||||||
|
|
||||||
|
_DIAGASSERT(cp != NULL);
|
||||||
|
_DIAGASSERT(astate != NULL);
|
||||||
|
|
||||||
|
if (flag & UNVIS_END) {
|
||||||
|
if (*astate == S_OCTAL2 || *astate == S_OCTAL3
|
||||||
|
|| *astate == S_HEX2) {
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
}
|
||||||
|
return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (*astate) {
|
||||||
|
|
||||||
|
case S_GROUND:
|
||||||
|
*cp = 0;
|
||||||
|
if (c == '\\') {
|
||||||
|
*astate = S_START;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
if ((flag & VIS_HTTPSTYLE) && c == '%') {
|
||||||
|
*astate = S_HEX1;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
*cp = c;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
|
||||||
|
case S_START:
|
||||||
|
switch(c) {
|
||||||
|
case '\\':
|
||||||
|
*cp = c;
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
case '0': case '1': case '2': case '3':
|
||||||
|
case '4': case '5': case '6': case '7':
|
||||||
|
*cp = (c - '0');
|
||||||
|
*astate = S_OCTAL2;
|
||||||
|
return (0);
|
||||||
|
case 'M':
|
||||||
|
*cp = (char)0200;
|
||||||
|
*astate = S_META;
|
||||||
|
return (0);
|
||||||
|
case '^':
|
||||||
|
*astate = S_CTRL;
|
||||||
|
return (0);
|
||||||
|
case 'n':
|
||||||
|
*cp = '\n';
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
case 'r':
|
||||||
|
*cp = '\r';
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
case 'b':
|
||||||
|
*cp = '\b';
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
case 'a':
|
||||||
|
*cp = '\007';
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
case 'v':
|
||||||
|
*cp = '\v';
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
case 't':
|
||||||
|
*cp = '\t';
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
case 'f':
|
||||||
|
*cp = '\f';
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
case 's':
|
||||||
|
*cp = ' ';
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
case 'E':
|
||||||
|
*cp = '\033';
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
case '\n':
|
||||||
|
/*
|
||||||
|
* hidden newline
|
||||||
|
*/
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_NOCHAR);
|
||||||
|
case '$':
|
||||||
|
/*
|
||||||
|
* hidden marker
|
||||||
|
*/
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_NOCHAR);
|
||||||
|
}
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_SYNBAD);
|
||||||
|
|
||||||
|
case S_META:
|
||||||
|
if (c == '-')
|
||||||
|
*astate = S_META1;
|
||||||
|
else if (c == '^')
|
||||||
|
*astate = S_CTRL;
|
||||||
|
else {
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_SYNBAD);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
case S_META1:
|
||||||
|
*astate = S_GROUND;
|
||||||
|
*cp |= c;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
|
||||||
|
case S_CTRL:
|
||||||
|
if (c == '?')
|
||||||
|
*cp |= 0177;
|
||||||
|
else
|
||||||
|
*cp |= c & 037;
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
|
||||||
|
case S_OCTAL2: /* second possible octal digit */
|
||||||
|
if (isoctal(uc)) {
|
||||||
|
/*
|
||||||
|
* yes - and maybe a third
|
||||||
|
*/
|
||||||
|
*cp = (*cp << 3) + (c - '0');
|
||||||
|
*astate = S_OCTAL3;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* no - done with current sequence, push back passed char
|
||||||
|
*/
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALIDPUSH);
|
||||||
|
|
||||||
|
case S_OCTAL3: /* third possible octal digit */
|
||||||
|
*astate = S_GROUND;
|
||||||
|
if (isoctal(uc)) {
|
||||||
|
*cp = (*cp << 3) + (c - '0');
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* we were done, push back passed char
|
||||||
|
*/
|
||||||
|
return (UNVIS_VALIDPUSH);
|
||||||
|
|
||||||
|
case S_HEX1:
|
||||||
|
if (isxdigit(uc)) {
|
||||||
|
*cp = xtod(uc);
|
||||||
|
*astate = S_HEX2;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* no - done with current sequence, push back passed char
|
||||||
|
*/
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_VALIDPUSH);
|
||||||
|
|
||||||
|
case S_HEX2:
|
||||||
|
*astate = S_GROUND;
|
||||||
|
if (isxdigit(uc)) {
|
||||||
|
*cp = xtod(uc) | (*cp << 4);
|
||||||
|
return (UNVIS_VALID);
|
||||||
|
}
|
||||||
|
return (UNVIS_VALIDPUSH);
|
||||||
|
|
||||||
|
default:
|
||||||
|
/*
|
||||||
|
* decoder in unknown state - (probably uninitialized)
|
||||||
|
*/
|
||||||
|
*astate = S_GROUND;
|
||||||
|
return (UNVIS_SYNBAD);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* strunvis - decode src into dst
|
||||||
|
*
|
||||||
|
* Number of chars decoded into dst is returned, -1 on error.
|
||||||
|
* Dst is null terminated.
|
||||||
|
*/
|
||||||
|
|
||||||
|
int
|
||||||
|
strunvisx(dst, src, flag)
|
||||||
|
char *dst;
|
||||||
|
const char *src;
|
||||||
|
int flag;
|
||||||
|
{
|
||||||
|
char c;
|
||||||
|
char *start = dst;
|
||||||
|
int state = 0;
|
||||||
|
|
||||||
|
_DIAGASSERT(src != NULL);
|
||||||
|
_DIAGASSERT(dst != NULL);
|
||||||
|
|
||||||
|
while ((c = *src++) != '\0') {
|
||||||
|
again:
|
||||||
|
switch (unvis(dst, c, &state, flag)) {
|
||||||
|
case UNVIS_VALID:
|
||||||
|
dst++;
|
||||||
|
break;
|
||||||
|
case UNVIS_VALIDPUSH:
|
||||||
|
dst++;
|
||||||
|
goto again;
|
||||||
|
case 0:
|
||||||
|
case UNVIS_NOCHAR:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return (-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID)
|
||||||
|
dst++;
|
||||||
|
*dst = '\0';
|
||||||
|
return (dst - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
strunvis(dst, src)
|
||||||
|
char *dst;
|
||||||
|
const char *src;
|
||||||
|
{
|
||||||
|
return strunvisx(dst, src, 0);
|
||||||
|
}
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,405 @@
|
||||||
|
/* $NetBSD: vis.c,v 1.35 2006/08/28 20:42:12 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1989, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1999, 2005 The NetBSD Foundation, Inc.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of The NetBSD Foundation nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived
|
||||||
|
* from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||||
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||||
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
* POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* AIX requires this to be the first thing in the file. */
|
||||||
|
#if defined (_AIX) && !defined (__GNUC__)
|
||||||
|
#pragma alloca
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
#ifdef __GNUC__
|
||||||
|
# undef alloca
|
||||||
|
# define alloca(n) __builtin_alloca (n)
|
||||||
|
#else
|
||||||
|
# ifdef HAVE_ALLOCA_H
|
||||||
|
# include <alloca.h>
|
||||||
|
# else
|
||||||
|
# ifndef _AIX
|
||||||
|
extern char *alloca ();
|
||||||
|
# endif
|
||||||
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(LIBC_SCCS) && !defined(lint)
|
||||||
|
__RCSID("$NetBSD: vis.c,v 1.35 2006/08/28 20:42:12 christos Exp $");
|
||||||
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <vis.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#ifdef __weak_alias
|
||||||
|
__weak_alias(strsvis,_strsvis)
|
||||||
|
__weak_alias(strsvisx,_strsvisx)
|
||||||
|
__weak_alias(strvis,_strvis)
|
||||||
|
__weak_alias(strvisx,_strvisx)
|
||||||
|
__weak_alias(svis,_svis)
|
||||||
|
__weak_alias(vis,_vis)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_VIS || !HAVE_SVIS
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#undef BELL
|
||||||
|
#define BELL '\a'
|
||||||
|
|
||||||
|
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
|
||||||
|
#define iswhite(c) (c == ' ' || c == '\t' || c == '\n')
|
||||||
|
#define issafe(c) (c == '\b' || c == BELL || c == '\r')
|
||||||
|
#define xtoa(c) "0123456789abcdef"[c]
|
||||||
|
|
||||||
|
#define MAXEXTRAS 5
|
||||||
|
|
||||||
|
|
||||||
|
#define MAKEEXTRALIST(flag, extra, orig_str) \
|
||||||
|
do { \
|
||||||
|
const char *orig = orig_str; \
|
||||||
|
const char *o = orig; \
|
||||||
|
char *e; \
|
||||||
|
while (*o++) \
|
||||||
|
continue; \
|
||||||
|
extra = malloc((size_t)((o - orig) + MAXEXTRAS)); \
|
||||||
|
if (!extra) break; \
|
||||||
|
for (o = orig, e = extra; (*e++ = *o++) != '\0';) \
|
||||||
|
continue; \
|
||||||
|
e--; \
|
||||||
|
if (flag & VIS_SP) *e++ = ' '; \
|
||||||
|
if (flag & VIS_TAB) *e++ = '\t'; \
|
||||||
|
if (flag & VIS_NL) *e++ = '\n'; \
|
||||||
|
if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \
|
||||||
|
*e = '\0'; \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is HVIS, the macro of vis used to HTTP style (RFC 1808)
|
||||||
|
*/
|
||||||
|
#define HVIS(dst, c, flag, nextc, extra) \
|
||||||
|
do \
|
||||||
|
if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \
|
||||||
|
*dst++ = '%'; \
|
||||||
|
*dst++ = xtoa(((unsigned int)c >> 4) & 0xf); \
|
||||||
|
*dst++ = xtoa((unsigned int)c & 0xf); \
|
||||||
|
} else { \
|
||||||
|
SVIS(dst, c, flag, nextc, extra); \
|
||||||
|
} \
|
||||||
|
while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This is SVIS, the central macro of vis.
|
||||||
|
* dst: Pointer to the destination buffer
|
||||||
|
* c: Character to encode
|
||||||
|
* flag: Flag word
|
||||||
|
* nextc: The character following 'c'
|
||||||
|
* extra: Pointer to the list of extra characters to be
|
||||||
|
* backslash-protected.
|
||||||
|
*/
|
||||||
|
#define SVIS(dst, c, flag, nextc, extra) \
|
||||||
|
do { \
|
||||||
|
int isextra; \
|
||||||
|
isextra = strchr(extra, c) != NULL; \
|
||||||
|
if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \
|
||||||
|
((flag & VIS_SAFE) && issafe(c)))) { \
|
||||||
|
*dst++ = c; \
|
||||||
|
break; \
|
||||||
|
} \
|
||||||
|
if (flag & VIS_CSTYLE) { \
|
||||||
|
switch (c) { \
|
||||||
|
case '\n': \
|
||||||
|
*dst++ = '\\'; *dst++ = 'n'; \
|
||||||
|
continue; \
|
||||||
|
case '\r': \
|
||||||
|
*dst++ = '\\'; *dst++ = 'r'; \
|
||||||
|
continue; \
|
||||||
|
case '\b': \
|
||||||
|
*dst++ = '\\'; *dst++ = 'b'; \
|
||||||
|
continue; \
|
||||||
|
case BELL: \
|
||||||
|
*dst++ = '\\'; *dst++ = 'a'; \
|
||||||
|
continue; \
|
||||||
|
case '\v': \
|
||||||
|
*dst++ = '\\'; *dst++ = 'v'; \
|
||||||
|
continue; \
|
||||||
|
case '\t': \
|
||||||
|
*dst++ = '\\'; *dst++ = 't'; \
|
||||||
|
continue; \
|
||||||
|
case '\f': \
|
||||||
|
*dst++ = '\\'; *dst++ = 'f'; \
|
||||||
|
continue; \
|
||||||
|
case ' ': \
|
||||||
|
*dst++ = '\\'; *dst++ = 's'; \
|
||||||
|
continue; \
|
||||||
|
case '\0': \
|
||||||
|
*dst++ = '\\'; *dst++ = '0'; \
|
||||||
|
if (isoctal(nextc)) { \
|
||||||
|
*dst++ = '0'; \
|
||||||
|
*dst++ = '0'; \
|
||||||
|
} \
|
||||||
|
continue; \
|
||||||
|
default: \
|
||||||
|
if (isgraph(c)) { \
|
||||||
|
*dst++ = '\\'; *dst++ = c; \
|
||||||
|
continue; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \
|
||||||
|
*dst++ = '\\'; \
|
||||||
|
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; \
|
||||||
|
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; \
|
||||||
|
*dst++ = (c & 07) + '0'; \
|
||||||
|
} else { \
|
||||||
|
if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \
|
||||||
|
if (c & 0200) { \
|
||||||
|
c &= 0177; *dst++ = 'M'; \
|
||||||
|
} \
|
||||||
|
if (iscntrl(c)) { \
|
||||||
|
*dst++ = '^'; \
|
||||||
|
if (c == 0177) \
|
||||||
|
*dst++ = '?'; \
|
||||||
|
else \
|
||||||
|
*dst++ = c + '@'; \
|
||||||
|
} else { \
|
||||||
|
*dst++ = '-'; *dst++ = c; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
} while (/*CONSTCOND*/0)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* svis - visually encode characters, also encoding the characters
|
||||||
|
* pointed to by `extra'
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
svis(char *dst, int c, int flag, int nextc, const char *extra)
|
||||||
|
{
|
||||||
|
char *nextra = NULL;
|
||||||
|
|
||||||
|
_DIAGASSERT(dst != NULL);
|
||||||
|
_DIAGASSERT(extra != NULL);
|
||||||
|
MAKEEXTRALIST(flag, nextra, extra);
|
||||||
|
if (!nextra) {
|
||||||
|
*dst = '\0'; /* can't create nextra, return "" */
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
if (flag & VIS_HTTPSTYLE)
|
||||||
|
HVIS(dst, c, flag, nextc, nextra);
|
||||||
|
else
|
||||||
|
SVIS(dst, c, flag, nextc, nextra);
|
||||||
|
free(nextra);
|
||||||
|
*dst = '\0';
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* strsvis, strsvisx - visually encode characters from src into dst
|
||||||
|
*
|
||||||
|
* Extra is a pointer to a \0-terminated list of characters to
|
||||||
|
* be encoded, too. These functions are useful e. g. to
|
||||||
|
* encode strings in such a way so that they are not interpreted
|
||||||
|
* by a shell.
|
||||||
|
*
|
||||||
|
* Dst must be 4 times the size of src to account for possible
|
||||||
|
* expansion. The length of dst, not including the trailing NULL,
|
||||||
|
* is returned.
|
||||||
|
*
|
||||||
|
* Strsvisx encodes exactly len bytes from src into dst.
|
||||||
|
* This is useful for encoding a block of data.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
strsvis(char *dst, const char *csrc, int flag, const char *extra)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
char *start;
|
||||||
|
char *nextra = NULL;
|
||||||
|
const unsigned char *src = (const unsigned char *)csrc;
|
||||||
|
|
||||||
|
_DIAGASSERT(dst != NULL);
|
||||||
|
_DIAGASSERT(src != NULL);
|
||||||
|
_DIAGASSERT(extra != NULL);
|
||||||
|
MAKEEXTRALIST(flag, nextra, extra);
|
||||||
|
if (!nextra) {
|
||||||
|
*dst = '\0'; /* can't create nextra, return "" */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (flag & VIS_HTTPSTYLE) {
|
||||||
|
for (start = dst; (c = *src++) != '\0'; /* empty */)
|
||||||
|
HVIS(dst, c, flag, *src, nextra);
|
||||||
|
} else {
|
||||||
|
for (start = dst; (c = *src++) != '\0'; /* empty */)
|
||||||
|
SVIS(dst, c, flag, *src, nextra);
|
||||||
|
}
|
||||||
|
free(nextra);
|
||||||
|
*dst = '\0';
|
||||||
|
return (dst - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra)
|
||||||
|
{
|
||||||
|
unsigned char c;
|
||||||
|
char *start;
|
||||||
|
char *nextra = NULL;
|
||||||
|
const unsigned char *src = (const unsigned char *)csrc;
|
||||||
|
|
||||||
|
_DIAGASSERT(dst != NULL);
|
||||||
|
_DIAGASSERT(src != NULL);
|
||||||
|
_DIAGASSERT(extra != NULL);
|
||||||
|
MAKEEXTRALIST(flag, nextra, extra);
|
||||||
|
if (! nextra) {
|
||||||
|
*dst = '\0'; /* can't create nextra, return "" */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flag & VIS_HTTPSTYLE) {
|
||||||
|
for (start = dst; len > 0; len--) {
|
||||||
|
c = *src++;
|
||||||
|
HVIS(dst, c, flag, len ? *src : '\0', nextra);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (start = dst; len > 0; len--) {
|
||||||
|
c = *src++;
|
||||||
|
SVIS(dst, c, flag, len ? *src : '\0', nextra);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(nextra);
|
||||||
|
*dst = '\0';
|
||||||
|
return (dst - start);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !HAVE_VIS
|
||||||
|
/*
|
||||||
|
* vis - visually encode characters
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
vis(char *dst, int c, int flag, int nextc)
|
||||||
|
{
|
||||||
|
char *extra = NULL;
|
||||||
|
unsigned char uc = (unsigned char)c;
|
||||||
|
|
||||||
|
_DIAGASSERT(dst != NULL);
|
||||||
|
|
||||||
|
MAKEEXTRALIST(flag, extra, "");
|
||||||
|
if (! extra) {
|
||||||
|
*dst = '\0'; /* can't create extra, return "" */
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
if (flag & VIS_HTTPSTYLE)
|
||||||
|
HVIS(dst, uc, flag, nextc, extra);
|
||||||
|
else
|
||||||
|
SVIS(dst, uc, flag, nextc, extra);
|
||||||
|
free(extra);
|
||||||
|
*dst = '\0';
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* strvis, strvisx - visually encode characters from src into dst
|
||||||
|
*
|
||||||
|
* Dst must be 4 times the size of src to account for possible
|
||||||
|
* expansion. The length of dst, not including the trailing NULL,
|
||||||
|
* is returned.
|
||||||
|
*
|
||||||
|
* Strvisx encodes exactly len bytes from src into dst.
|
||||||
|
* This is useful for encoding a block of data.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
strvis(char *dst, const char *src, int flag)
|
||||||
|
{
|
||||||
|
char *extra = NULL;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
MAKEEXTRALIST(flag, extra, "");
|
||||||
|
if (!extra) {
|
||||||
|
*dst = '\0'; /* can't create extra, return "" */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
rv = strsvis(dst, src, flag, extra);
|
||||||
|
free(extra);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
strvisx(char *dst, const char *src, size_t len, int flag)
|
||||||
|
{
|
||||||
|
char *extra = NULL;
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
MAKEEXTRALIST(flag, extra, "");
|
||||||
|
if (!extra) {
|
||||||
|
*dst = '\0'; /* can't create extra, return "" */
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
rv = strsvisx(dst, src, len, flag, extra);
|
||||||
|
free(extra);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -0,0 +1,89 @@
|
||||||
|
/* $NetBSD: vis.h,v 1.16 2005/09/13 01:44:32 christos Exp $ */
|
||||||
|
|
||||||
|
/*-
|
||||||
|
* Copyright (c) 1990, 1993
|
||||||
|
* The Regents of the University of California. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the University nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* @(#)vis.h 8.1 (Berkeley) 6/2/93
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _VIS_H_
|
||||||
|
#define _VIS_H_
|
||||||
|
|
||||||
|
#include <config.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* to select alternate encoding format
|
||||||
|
*/
|
||||||
|
#define VIS_OCTAL 0x01 /* use octal \ddd format */
|
||||||
|
#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropiate */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* to alter set of characters encoded (default is to encode all
|
||||||
|
* non-graphic except space, tab, and newline).
|
||||||
|
*/
|
||||||
|
#define VIS_SP 0x04 /* also encode space */
|
||||||
|
#define VIS_TAB 0x08 /* also encode tab */
|
||||||
|
#define VIS_NL 0x10 /* also encode newline */
|
||||||
|
#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
|
||||||
|
#define VIS_SAFE 0x20 /* only encode "unsafe" characters */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* other
|
||||||
|
*/
|
||||||
|
#define VIS_NOSLASH 0x40 /* inhibit printing '\' */
|
||||||
|
#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unvis return codes
|
||||||
|
*/
|
||||||
|
#define UNVIS_VALID 1 /* character valid */
|
||||||
|
#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */
|
||||||
|
#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */
|
||||||
|
#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */
|
||||||
|
#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* unvis flags
|
||||||
|
*/
|
||||||
|
#define UNVIS_END 1 /* no more characters */
|
||||||
|
|
||||||
|
__BEGIN_DECLS
|
||||||
|
char *vis(char *, int, int, int);
|
||||||
|
char *svis(char *, int, int, int, const char *);
|
||||||
|
int strvis(char *, const char *, int);
|
||||||
|
int strsvis(char *, const char *, int, const char *);
|
||||||
|
int strvisx(char *, const char *, size_t, int);
|
||||||
|
int strsvisx(char *, const char *, size_t, int, const char *);
|
||||||
|
int strunvis(char *, const char *);
|
||||||
|
int strunvisx(char *, const char *, int);
|
||||||
|
#ifndef __LIBC12_SOURCE__
|
||||||
|
int unvis(char *, int, int *, int);
|
||||||
|
#endif
|
||||||
|
__END_DECLS
|
||||||
|
|
||||||
|
#endif /* !_VIS_H_ */
|
Loading…
Reference in New Issue