Move Source From Main Repo

Based on libedit-55
This commit is contained in:
Thomas A 2023-02-01 21:23:25 -08:00
commit 049914d031
74 changed files with 26441 additions and 0 deletions

62
CMakeLists.txt Normal file
View File

@ -0,0 +1,62 @@
project(libedit)
cmake_minimum_required(VERSION 3.10)
if(COMMAND cmake_policy)
cmake_policy(SET CMP0003 NEW)
endif(COMMAND cmake_policy)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -nostdinc -D__DARWIN_UNIX03 -fPIC -w")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -nostdlib")
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}/src)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/local)
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
set(edit_SRCS
src/chared.c
src/chartype.c
src/common.c
src/el.c
src/eln.c
src/emacs.c
src/filecomplete.c
src/hist.c
src/history.c
src/keymacro.c
src/map.c
src/parse.c
src/prompt.c
src/read.c
src/readline.c
src/refresh.c
src/search.c
src/sig.c
src/terminal.c
src/tokenizer.c
src/tty.c
src/unvis.c
src/vi.c
src/vis.c
src/wcsdup.c
local/fcns.c
local/help.c
local/historyn.c
local/tokenizern.c
)
set(DYLIB_INSTALL_NAME "/usr/lib/libedit.3.dylib")
set(DYLIB_COMPAT_VERSION "2.0.0")
set(DYLIB_CURRENT_VERSION "3.0.0")
add_darling_library(edit SHARED ${edit_SRCS})
make_fat(edit)
set_target_properties(edit PROPERTIES OUTPUT_NAME "edit.3")
target_link_libraries(edit PRIVATE system ncurses)
InstallSymlink("libedit.3.dylib" "${CMAKE_INSTALL_PREFIX}/libexec/darling/usr/lib/libedit.2.dylib")
InstallSymlink("libedit.3.dylib" "${CMAKE_INSTALL_PREFIX}/libexec/darling/usr/lib/libedit.dylib")
install(TARGETS edit DESTINATION libexec/darling/usr/lib)
install(FILES inputrc DESTINATION libexec/darling/etc)

71
UPDATING Normal file
View File

@ -0,0 +1,71 @@
1) Unpack the original tarball in a separate directory. Create a diff of the
original and the current src directory.
2) Unpack the new update in a separate directory. Overwrite the files in src
with the files from the update. Note that some filenames have been renamed:
key.c -> keymacro.c
key.h -> keymacro.h
term.c -> terminal.c
el_term.h -> terminal.h
Then manually apply the changes from the diff in 1) to the new files.
3) The patch-configure.ac file only deals with libtool-style versioning.
We had altered the version numbers so that the version number in the name
of the dylib matched the libedit version number, but this was the wrong
thing to do, and now we are stuck. For instance, original libtool-style
version number for a past version was 0:27:0. It was changed to 1:11:0 so
that libedit.2.11.dylib was created (1 is added to the major number, because
the libtool major number can be zero, but not the Mac OS X major number).
libedit 3.0 has a libtool version number of 0:35:0, meaning it is binary-
compatible with the 2.11 version. Since we now build with Xcode, we don't
care about the libtool versioning, *except* that it tells use the 3.0
version is binary compatible with libedit.2.dylib. So we can create a
libedit.3.dylib, plus the usual symlinks libedit.dylib, and libedit.3.0.dylib,
and also create a libedit.2.dylib symlink, *if* we remember to set the
compatibility version of libedit.3.dylib to 2.0.
4) Unpack the original tarball, make a darwin subdirectory at the top level,
and cd there. Then run:
% ../configure --help
Do the same for the new tarball. In this case, there are no new options.
5) Run in each of the darwin subdirectories:
% ../configure --disable-dependency-tracking --enable-shared --disable-static --enable-widec
% make
This will create config.h at the top level, and the nine auto-generated files:
common.h fcns.c help.c historyn.c vi.h
emacs.h fcns.h help.h tokenizern.c
in the src directory.
6) For the original files, copy the nine auto-generated files to a temp
directory, like /tmp/local:
% diff -r /tmp/local $libedit/local >/tmp/DIFF
(where $libedit is the path the the current version of the libedit project).
This create a diff of what has changed in those auto-generated files.
7) Overwrite the nine auto-generated files in $libedit/local from the new darwin/src directory.
Now manually apply the patches from /tmp/DIFF.
8) Diff the original config.h with the one in $libedit (in this case, no
differences).
9) Diff the original config.h with the new config.h to see what has changed.
Then overwrite the original config.h with the new config.h.
10) Global replace in libedit.xcodeproj/project.pbxproj, the filenames that
have changed with their new name.
11) Update the man pages in the doc directory,
12) Update the libedit.plist.

134
UPDATING-20100424 Normal file
View File

@ -0,0 +1,134 @@
0) Unpack the new update.
1) Examine each patchfile to determine if all or some patches may no longer be
needed, or needs to be applied differently (see 2 below for special-case
patch-configure.ac). Once patched are applied, update the patch files in
the applied-patched directory.
2) The patch-configure.ac file only deals with libtool-style versioning.
We had altered the version numbers so that the version number in the name
of the dylib matched the libedit version number, but this was the wrong
thing to do, and now we are stuck. For instance, original libtool-style
version number for a past version was 0:27:0. It was changed to 1:11:0 so
that libedit.2.11.dylib was created (1 is added to the major number, because
the libtool major number can be zero, but not the Mac OS X major number).
libedit 3.0 has a libtool version number of 0:35:0, meaning it is binary-
compatible with the 2.11 version. Since we now build with Xcode, we don't
care about the libtool versioning, *except* that it tells use the 3.0
version is binary compatible with libedit.2.dylib. So we can create a
libedit.3.dylib, plus the usual symlinks libedit.dylib, and libedit.3.0.dylib,
and also create a libedit.2.dylib symlink, *if* we remember to set the
compatibility version of libedit.3.dylib to 2.0.
3) We need to create config.h, which means we need to run configure. New
in libedit 3.0 is utf-8 support, which is enabled with the --enable-widec
option. To determine what what this option changes, we create two copies
of the patched directories, and run configure in both, one with the new
option, and one without.
3a) We compare the config.h from the two directories. In this case, a new
new #define is set (WIDECHAR).
3b) We compare the corresponding Makefiles, ignoring path differences due
to having two different directory names. Again, in this case, we see that
previously commented-out files are now enabled (this also tells us that if
we didn't enable the utf-8 support, those files would be unused, and probably
would have waste space if we blindly added those files to Xcode). There are
3 new .c files in this case:
eln.c historyn.c tokenizern.c
4) Compare the files in the src directory, between the old libedit and the
new. There are 3 new .c files and 1 new .h file:
chartype.c chartype.h eln.c wcsdup.c
So 1 of these new .c files (eln.c) is accounted for in 3b).
5) src/Makefile creates some of these new source files. These files (along
with others) are stored in the "local" directory in the libedit project, so we
will need to recreate them again:
cd src
echo 'my_local: $(BUILT_SOURCES)' >> Makefile
# the "am__configure_deps=" prevents trying to autoreconf
make my_local am__configure_deps=
In this case, the files:
vi.h emacs.h common.h fcns.h help.h fcns.c help.c tokenizern.c historyn.c
are created.
Two of these .c files were found in 3b) (tokenizern.c historyn.c).
6) From 4) and 5), the files from 3b) are accounted for. That leaves 2 .c
files found in 4) (chartype.c wcsdup.c) that are new and build by default
(which the Makefile confirms).
7) Copy the (unmodified) src directory to the src directory of the SVN copy.
Add the new files found in 4):
svn add chartype.c chartype.h eln.c wcsdup.c
8) Copy the files created in 5) to the local directory of the SVN copy, and
add the new files:
svn add tokenizern.c historyn.c
9) For completeness, copy libedit.pc (after running configure), to the local
directory.
10) Go into Xcode and add the files from 4) to the libedit and libedit-static
targets. When these files appear under the libedit group, move them into the
Source folder (sorting alphabetically to be nice).
11) Add the new files from 5) to the libedit and libedit-static targets. When
these files appear under the libedit group, move them into the local folder
(sorting alphabetically to be nice).
12) Modify the "make lists" script to add the two new file creations (for
historyn.c tokenizern.c). We also remove the "make list" build phase from each
of the libedit and libedit-static targets, since we should not be modifying
files (at build time) in SRCROOT. Besides, this would hide the fact that
the files in the local directory are out of date from what actually gets
built.
13) For the libedit target, change the "Current Library Version" from 2.11
to 3.0. Leave the "Compatibility Version" at 2. Change the "Product Name"
from "edit.2" to "edit.3".
14) Under the all target, modify the "install misc" script. Replace:
foreach l (libedit.2.11.dylib libedit.dylib libreadline.dylib) do
ln -s libedit.2.dylib $DSTROOT/usr/lib/$l
done
with:
foreach l (libedit.2.dylib libedit.3.0.dylib libedit.dylib libreadline.dylib) do
ln -s libedit.3.dylib $DSTROOT/usr/lib/$l
done
14) In the doc directory of the unpacked-and-configured copy, run:
touch ../config.status
echo 'my_man: $(EL_MANS)' >> Makefile
make my_man am__configure_deps=
Copy the two man pages (editline.3 editrc.5) to the doc subdirectory of the SVN
copy.
15) Update the libedit.plist file (in the local directory), with the current
information.
16) Add the tarball to SVN, so we have a copy of the original sources.
17) Because tokenizern.c and historyn.c are located in the local directory,
and because they expect to include the tokenizer.c and history.c files,
respectively, a new include directory needed to be added to Xcode (the "src"
directory). The -fpascal-strings option was removed as extraneous.
18) Build libedit and if testing finds bugs, fix the code, and update/create
the corresponding patch file.

296
config.h Normal file
View File

@ -0,0 +1,296 @@
/* config.h. Generated from config.h.in by configure. */
/* 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 1 if you have the <curses.h> header file. */
#define HAVE_CURSES_H 1
/* Define to 1 if you have the <dirent.h> header file, and it defines `DIR'.
*/
#define HAVE_DIRENT_H 1
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H 1
/* Define to 1 if you have the `endpwent' function. */
#define HAVE_ENDPWENT 1
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
/* Define to 1 if you have the `fgetln' function. */
#define HAVE_FGETLN 1
/* Define to 1 if you have the `fork' function. */
#define HAVE_FORK 1
/* 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. */
#define HAVE_GETPW_R_POSIX 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `isascii' function. */
#define HAVE_ISASCII 1
/* Define to 1 if you have the `issetugid' function. */
#define HAVE_ISSETUGID 1
/* 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 `termcap' library (-ltermcap). */
#define HAVE_LIBTERMCAP 1
/* Define to 1 if you have the `terminfo' library (-lterminfo). */
/* #undef HAVE_LIBTERMINFO */
/* Define to 1 if you have the `termlib' library (-ltermlib). */
/* #undef HAVE_LIBTERMLIB */
/* Define to 1 if you have the `tinfo' library (-ltinfo). */
/* #undef HAVE_LIBTINFO */
/* Define to 1 if you have the <limits.h> header file. */
#define HAVE_LIMITS_H 1
/* Define to 1 if you have the <malloc.h> header file. */
/* #undef HAVE_MALLOC_H */
/* Define to 1 if you have the `memchr' function. */
#define HAVE_MEMCHR 1
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the `memset' function. */
#define HAVE_MEMSET 1
/* Define to 1 if you have the <ncurses.h> header file. */
#define HAVE_NCURSES_H 1
/* 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. */
#define HAVE_REGCOMP 1
/* 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. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
/* Define to 1 if you have the `strcasecmp' function. */
#define HAVE_STRCASECMP 1
/* Define to 1 if you have the `strchr' function. */
#define HAVE_STRCHR 1
/* Define to 1 if you have the `strcspn' function. */
#define HAVE_STRCSPN 1
/* Define to 1 if you have the `strdup' function. */
#define HAVE_STRDUP 1
/* Define to 1 if you have the `strerror' function. */
#define HAVE_STRERROR 1
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H 1
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H 1
/* Define to 1 if you have the `strlcat' function. */
#define HAVE_STRLCAT 1
/* Define to 1 if you have the `strlcpy' function. */
#define HAVE_STRLCPY 1
/* Define to 1 if you have the `strrchr' function. */
#define HAVE_STRRCHR 1
/* Define to 1 if you have the `strstr' function. */
#define HAVE_STRSTR 1
/* Define to 1 if you have the `strtol' function. */
#define HAVE_STRTOL 1
/* Define to 1 if struct dirent has member d_namlen */
#define HAVE_STRUCT_DIRENT_D_NAMLEN 1
/* Define to 1 if you have the `strunvis' function. */
#define HAVE_STRUNVIS 1
/* Define to 1 if you have the `strvis' function. */
#define HAVE_STRVIS 1
/* Define to 1 if you have the <sys/cdefs.h> header file. */
#define HAVE_SYS_CDEFS_H 1
/* 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. */
#define HAVE_SYS_IOCTL_H 1
/* 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. */
#define HAVE_SYS_PARAM_H 1
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H 1
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
#define HAVE_SYS_WAIT_H 1
/* Define to 1 if you have the <termcap.h> header file. */
#define HAVE_TERMCAP_H 1
/* Define to 1 if you have the <term.h> header file. */
#define HAVE_TERM_H 1
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if the system has the type `u_int32_t'. */
#define HAVE_U_INT32_T 1
/* Define to 1 if you have the `vfork' function. */
#define HAVE_VFORK 1
/* Define to 1 if you have the <vfork.h> header file. */
/* #undef HAVE_VFORK_H */
/* Define to 1 if you have the `vis' function. */
#define HAVE_VIS 1
/* Define to 1 if you have the `wcsdup' function. */
#define HAVE_WCSDUP 1
/* Define to 1 if `fork' works. */
#define HAVE_WORKING_FORK 1
/* Define to 1 if `vfork' works. */
#define HAVE_WORKING_VFORK 1
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */
/* #undef LSTAT_FOLLOWS_SLASHED_SYMLINK */
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
#define LT_OBJDIR ".libs/"
/* Name of package */
#define PACKAGE "libedit-20121213"
/* Define to the address where bug reports for this package should be sent. */
#define PACKAGE_BUGREPORT ""
/* Define to the full name of this package. */
#define PACKAGE_NAME "libedit"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "libedit 3.0"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "libedit-20121213"
/* Define to the home page for this package. */
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "3.0"
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE void
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1
/* Enable extensions on AIX 3, Interix. */
#ifndef _ALL_SOURCE
# define _ALL_SOURCE 1
#endif
/* Enable GNU extensions on systems that have them. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
/* Enable threading extensions on Solaris. */
#ifndef _POSIX_PTHREAD_SEMANTICS
# define _POSIX_PTHREAD_SEMANTICS 1
#endif
/* Enable extensions on HP NonStop. */
#ifndef _TANDEM_SOURCE
# define _TANDEM_SOURCE 1
#endif
/* Enable general extensions on Solaris. */
#ifndef __EXTENSIONS__
# define __EXTENSIONS__ 1
#endif
/* Version number of package */
#define VERSION "3.0"
/* Define to 1 if you want wide-character code */
#define WIDECHAR 1
/* Define to 1 if on MINIX. */
/* #undef _MINIX */
/* Define to 2 if the system does not provide POSIX.1 features except with
this defined. */
/* #undef _POSIX_1_SOURCE */
/* Define to 1 if you need to in order for `stat' and other things to work. */
/* #undef _POSIX_SOURCE */
/* 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 */
/* 13150025 */
#define HAVE_FGETLN 1
#define HAVE_STRLCAT 1
#define HAVE_STRLCPY 1
#include "sys.h"
#define SCCSID
/* #undef LIBC_SCCS */
#define lint

BIN
config.log.gz Normal file

Binary file not shown.

BIN
config.status.gz Normal file

Binary file not shown.

891
doc/editline.3 Normal file
View File

@ -0,0 +1,891 @@
.\" $NetBSD: editline.3,v 1.77 2012/09/11 20:29:58 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.
.\"
.\" 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 September 11, 2012
.Dt EDITLINE 3
.Os
.Sh NAME
.Nm editline ,
.Nm el_init ,
.Nm el_end ,
.Nm el_reset ,
.Nm el_gets ,
.Nm el_wgets ,
.Nm el_getc ,
.Nm el_wgetc ,
.Nm el_push ,
.Nm el_wpush ,
.Nm el_parse ,
.Nm el_wparse ,
.Nm el_set ,
.Nm el_wset ,
.Nm el_get ,
.Nm el_wget ,
.Nm el_source ,
.Nm el_resize ,
.Nm el_line ,
.Nm el_wline ,
.Nm el_insertstr ,
.Nm el_winsertstr ,
.Nm el_deletestr ,
.Nm el_wdeletestr ,
.Nm history_init ,
.Nm history_winit ,
.Nm history_end ,
.Nm history_wend ,
.Nm history ,
.Nm history_w ,
.Nm tok_init ,
.Nm tok_winit ,
.Nm tok_end ,
.Nm tok_wend ,
.Nm tok_reset ,
.Nm tok_wreset ,
.Nm tok_line ,
.Nm tok_wline ,
.Nm tok_str
.Nm tok_wstr
.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 const wchar_t *
.Fn el_wgets "EditLine *e" "int *count"
.Ft int
.Fn el_getc "EditLine *e" "char *ch"
.Ft int
.Fn el_wgetc "EditLine *e" "wchar_t *ch"
.Ft void
.Fn el_push "EditLine *e" "const char *str"
.Ft void
.Fn el_wpush "EditLine *e" "const wchar_t *str"
.Ft int
.Fn el_parse "EditLine *e" "int argc" "const char *argv[]"
.Ft int
.Fn el_wparse "EditLine *e" "int argc" "const wchar_t *argv[]"
.Ft int
.Fn el_set "EditLine *e" "int op" "..."
.Ft int
.Fn el_wset "EditLine *e" "int op" "..."
.Ft int
.Fn el_get "EditLine *e" "int op" "..."
.Ft int
.Fn el_wget "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 int
.Fn el_winsertstr "EditLine *e" "const wchar_t *str"
.Ft void
.Fn el_deletestr "EditLine *e" "int count"
.Ft void
.Fn el_wdeletestr "EditLine *e" "int count"
.Ft History *
.Fn history_init
.Ft HistoryW *
.Fn history_winit
.Ft void
.Fn history_end "History *h"
.Ft void
.Fn history_wend "HistoryW *h"
.Ft int
.Fn history "History *h" "HistEvent *ev" "int op" "..."
.Ft int
.Fn history_w "HistoryW *h" "HistEventW *ev" "int op" "..."
.Ft Tokenizer *
.Fn tok_init "const char *IFS"
.Ft TokenizerW *
.Fn tok_winit "const wchar_t *IFS"
.Ft void
.Fn tok_end "Tokenizer *t"
.Ft void
.Fn tok_wend "TokenizerW *t"
.Ft void
.Fn tok_reset "Tokenizer *t"
.Ft void
.Fn tok_wreset "TokenizerW *t"
.Ft int
.Fn tok_line "Tokenizer *t" "const LineInfo *li" "int *argc" "const char **argv[]" "int *cursorc" "int *cursoro"
.Ft int
.Fn tok_wline "TokenizerW *t" "const LineInfoW *li" "int *argc" "const wchar_t **argv[]" "int *cursorc" "int *cursoro"
.Ft int
.Fn tok_str "Tokenizer *t" "const char *str" "int *argc" "const char **argv[]"
.Ft int
.Fn tok_wstr "TokenizerW *t" "const wchar_t *str" "int *argc" "const wchar_t **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 libtermcap
library).
Programs should be linked with
.Fl ledit ltermcap .
.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 wide-character functions behave the same way as their narrow
counterparts.
.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.
If an error occurred,
.Fa count
is set to \-1 and
.Dv errno
contains the error code that caused it.
The return value may not remain valid across calls to
.Fn el_gets
and must be copied if the data is to be retained.
.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,
in which case
.Dv errno
can be inspected for the cause.
.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_PROMPT_ESC , Fa "char *(*f)(EditLine *)" , Fa "char c"
Same as
.Dv EL_PROMPT ,
but the
.Fa c
argument indicates the start/stop literal prompt character.
.Pp
If a start/stop literal character is found in the prompt, the
character itself
is not printed, but characters after it are printed directly to the
terminal without affecting the state of the current line.
A subsequent second start/stop literal character ends this behavior.
This is typically used to embed literal escape sequences that change the
color/style of the terminal in the prompt.
.Dv 0
unsets it.
.It Dv EL_REFRESH
Re-display the current line on the next terminal line.
.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_RPROMPT_ESC , Fa "char *(*f)(EditLine *)" , Fa "char c"
Define the right prompt printing function but with a literal escape character.
.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 , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic bind
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_ECHOTC , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic echotc
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_SETTC , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic settc
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_SETTY , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic setty
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_TELLTC , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic telltc
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_ADDFN , Fa "const char *name" , Fa "const char *help" , \
Fa "unsigned char (*func)(EditLine *e, int ch)"
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 , Fa "History *(*func)(History *, int op, ...)" , \
Fa "const char *ptr"
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_UNBUFFERED , Fa "int flag"
If
.Fa flag
is zero,
unbuffered mode is disabled (the default).
In unbuffered mode,
.Fn el_gets
will return immediately after processing a single character.
.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
.Dq Dv 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 *)" , Fa "char *c"
Return a pointer to the function that displays the prompt in
.Fa f .
If
.Fa c
is not
.Dv NULL ,
return the start/stop literal prompt character in it.
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
Return a pointer to the function that displays the prompt in
.Fa f .
If
.Fa c
is not
.Dv NULL ,
return the start/stop literal prompt character in it.
.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
.Dq Dv 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"
Return non-zero if unbuffered mode is enabled.
.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 , 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"
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.
Johny Mattsson implemented wide-character support.
.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.

491
doc/editrc.5 Normal file
View File

@ -0,0 +1,491 @@
.\" $NetBSD: editrc.5,v 1.26 2012/06/02 14:19:20 njoly 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.
.\"
.\" 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
.Dt EDITRC 5
.Os
.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 Oo Fl a Oc Oo Fl e Oc Oo Fl k Oc Oo Fl l Oc Oo Fl r Oc \
Oo Fl s Oc Oo Fl v Oc Oo Ar key Oo Ar command Oc Oc
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 No ^ Ar 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 \e Ar nnn
.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 Oo Fl sv Oc Ar arg Ar ...
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 Li on | Li off
Enable or disable the
.Nm editline
functionality in a program.
.It Ic history Ar list | Ar size Dv n | Ar unique Dv 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 Oo Fl a Oc Oo Fl d Oc Oo Fl q Oc Oo Fl x Oc Oo Ar +mode Oc \
Oo Ar -mode Oc Oo Ar mode Oc Oo Ar char=c Oc
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 .

67
inputrc Normal file
View File

@ -0,0 +1,67 @@
# /etc/inputrc - global inputrc for libreadline
# See readline(3readline) and `info rluserman' for more information.
# Be 8 bit clean.
set input-meta on
set output-meta on
# To allow the use of 8bit-characters like the german umlauts, uncomment
# the line below. However this makes the meta key not work as a meta key,
# which is annoying to those which don't need to type in 8-bit characters.
# set convert-meta off
# try to enable the application keypad when it is called. Some systems
# need this to enable the arrow keys.
# set enable-keypad on
# see /usr/share/doc/bash/inputrc.arrows for other codes of arrow keys
# do not bell on tab-completion
# set bell-style none
# set bell-style visible
# some defaults / modifications for the emacs mode
$if mode=emacs
# allow the use of the Home/End keys
"\e[1~": beginning-of-line
"\e[4~": end-of-line
# allow the use of the Delete/Insert keys
"\e[3~": delete-char
"\e[2~": quoted-insert
# mappings for "page up" and "page down" to step to the beginning/end
# of the history
# "\e[5~": beginning-of-history
# "\e[6~": end-of-history
# alternate mappings for "page up" and "page down" to search the history
# "\e[5~": history-search-backward
# "\e[6~": history-search-forward
# mappings for Ctrl-left-arrow and Ctrl-right-arrow for word moving
"\e[1;5C": forward-word
"\e[1;5D": backward-word
"\e[5C": forward-word
"\e[5D": backward-word
"\e\e[C": forward-word
"\e\e[D": backward-word
$if term=rxvt
"\e[7~": beginning-of-line
"\e[8~": end-of-line
"\eOc": forward-word
"\eOd": backward-word
$endif
# for non RH/Debian xterm, can't hurt for RH/Debian xterm
# "\eOH": beginning-of-line
# "\eOF": end-of-line
# for freebsd console
# "\e[H": beginning-of-line
# "\e[F": end-of-line
$endif

BIN
libedit-20121213-3.0.tar.gz Normal file

Binary file not shown.

View File

@ -0,0 +1,689 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 45;
objects = {
/* Begin PBXAggregateTarget section */
4C615986104F1E8800BF0A10 /* all */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 4C61598F104F1EF300BF0A10 /* Build configuration list for PBXAggregateTarget "all" */;
buildPhases = (
4C615A221050668A00BF0A10 /* install misc */,
);
dependencies = (
4C61598A104F1E9000BF0A10 /* PBXTargetDependency */,
);
name = all;
productName = all;
};
4C6159C31050604600BF0A10 /* make lists */ = {
isa = PBXAggregateTarget;
buildConfigurationList = 4C6159CA1050608D00BF0A10 /* Build configuration list for PBXAggregateTarget "make lists" */;
buildPhases = (
4C6159C21050604600BF0A10 /* ShellScript */,
);
dependencies = (
);
name = "make lists";
productName = "make sources";
};
/* End PBXAggregateTarget section */
/* Begin PBXBuildFile section */
4C615952104F157800BF0A10 /* chared.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615922104F157800BF0A10 /* chared.c */; };
4C615953104F157800BF0A10 /* chared.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615923104F157800BF0A10 /* chared.h */; };
4C615954104F157800BF0A10 /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615924104F157800BF0A10 /* common.c */; };
4C615955104F157800BF0A10 /* readline.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615926104F157800BF0A10 /* readline.h */; };
4C615956104F157800BF0A10 /* terminal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615927104F157800BF0A10 /* terminal.h */; };
4C615957104F157800BF0A10 /* el.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615928104F157800BF0A10 /* el.c */; };
4C615958104F157800BF0A10 /* el.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615929104F157800BF0A10 /* el.h */; };
4C615959104F157800BF0A10 /* emacs.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61592A104F157800BF0A10 /* emacs.c */; };
4C61595B104F157800BF0A10 /* filecomplete.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61592C104F157800BF0A10 /* filecomplete.c */; };
4C61595C104F157800BF0A10 /* filecomplete.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61592D104F157800BF0A10 /* filecomplete.h */; };
4C61595D104F157800BF0A10 /* hist.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61592E104F157800BF0A10 /* hist.c */; };
4C61595E104F157800BF0A10 /* hist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61592F104F157800BF0A10 /* hist.h */; };
4C61595F104F157800BF0A10 /* histedit.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615930104F157800BF0A10 /* histedit.h */; };
4C615960104F157800BF0A10 /* history.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615931104F157800BF0A10 /* history.c */; };
4C615961104F157800BF0A10 /* keymacro.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615932104F157800BF0A10 /* keymacro.c */; };
4C615962104F157800BF0A10 /* keymacro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615933104F157800BF0A10 /* keymacro.h */; };
4C615963104F157800BF0A10 /* map.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615937104F157800BF0A10 /* map.c */; };
4C615964104F157800BF0A10 /* map.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615938104F157800BF0A10 /* map.h */; };
4C615965104F157800BF0A10 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615939104F157800BF0A10 /* parse.c */; };
4C615966104F157800BF0A10 /* parse.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61593A104F157800BF0A10 /* parse.h */; };
4C615967104F157800BF0A10 /* prompt.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61593B104F157800BF0A10 /* prompt.c */; };
4C615968104F157800BF0A10 /* prompt.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61593C104F157800BF0A10 /* prompt.h */; };
4C615969104F157800BF0A10 /* read.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61593D104F157800BF0A10 /* read.c */; };
4C61596A104F157800BF0A10 /* read.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61593E104F157800BF0A10 /* read.h */; };
4C61596B104F157800BF0A10 /* readline.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61593F104F157800BF0A10 /* readline.c */; };
4C61596C104F157800BF0A10 /* refresh.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615940104F157800BF0A10 /* refresh.c */; };
4C61596D104F157800BF0A10 /* refresh.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615941104F157800BF0A10 /* refresh.h */; };
4C61596E104F157800BF0A10 /* search.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615942104F157800BF0A10 /* search.c */; };
4C61596F104F157800BF0A10 /* search.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615943104F157800BF0A10 /* search.h */; };
4C615970104F157800BF0A10 /* sig.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615945104F157800BF0A10 /* sig.c */; };
4C615971104F157800BF0A10 /* sig.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615946104F157800BF0A10 /* sig.h */; };
4C615974104F157800BF0A10 /* sys.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615949104F157800BF0A10 /* sys.h */; };
4C615975104F157800BF0A10 /* terminal.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61594A104F157800BF0A10 /* terminal.c */; };
4C615976104F157800BF0A10 /* tokenizer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61594B104F157800BF0A10 /* tokenizer.c */; };
4C615977104F157800BF0A10 /* tty.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61594C104F157800BF0A10 /* tty.c */; };
4C615978104F157800BF0A10 /* tty.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61594D104F157800BF0A10 /* tty.h */; };
4C615979104F157800BF0A10 /* unvis.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61594E104F157800BF0A10 /* unvis.c */; };
4C61597A104F157800BF0A10 /* vi.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61594F104F157800BF0A10 /* vi.c */; };
4C61597B104F157800BF0A10 /* vis.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615950104F157800BF0A10 /* vis.c */; };
4C61597C104F157800BF0A10 /* vis.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615951104F157800BF0A10 /* vis.h */; };
4C615981104F15C700BF0A10 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615980104F15C700BF0A10 /* config.h */; };
4C6159A5104F203600BF0A10 /* common.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61599F104F203600BF0A10 /* common.h */; };
4C6159A6104F203600BF0A10 /* emacs.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6159A0104F203600BF0A10 /* emacs.h */; };
4C6159A7104F203600BF0A10 /* fcns.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6159A1104F203600BF0A10 /* fcns.c */; };
4C6159A8104F203600BF0A10 /* help.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6159A2104F203600BF0A10 /* help.c */; };
4C6159A9104F203600BF0A10 /* help.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6159A3104F203600BF0A10 /* help.h */; };
4C6159AA104F203600BF0A10 /* vi.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6159A4104F203600BF0A10 /* vi.h */; };
4C6159B8104F20F500BF0A10 /* fcns.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6159B7104F20F500BF0A10 /* fcns.h */; };
4C6159BD104F212400BF0A10 /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4C6159BC104F212400BF0A10 /* libncurses.dylib */; };
4C6159D41050615B00BF0A10 /* chared.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615922104F157800BF0A10 /* chared.c */; };
4C6159D51050615B00BF0A10 /* common.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615924104F157800BF0A10 /* common.c */; };
4C6159D61050615B00BF0A10 /* el.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615928104F157800BF0A10 /* el.c */; };
4C6159D71050615B00BF0A10 /* emacs.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61592A104F157800BF0A10 /* emacs.c */; };
4C6159D91050615B00BF0A10 /* filecomplete.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61592C104F157800BF0A10 /* filecomplete.c */; };
4C6159DA1050615B00BF0A10 /* hist.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61592E104F157800BF0A10 /* hist.c */; };
4C6159DB1050615B00BF0A10 /* history.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615931104F157800BF0A10 /* history.c */; };
4C6159DC1050615B00BF0A10 /* keymacro.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615932104F157800BF0A10 /* keymacro.c */; };
4C6159DD1050615B00BF0A10 /* map.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615937104F157800BF0A10 /* map.c */; };
4C6159DE1050615B00BF0A10 /* parse.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615939104F157800BF0A10 /* parse.c */; };
4C6159DF1050615B00BF0A10 /* prompt.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61593B104F157800BF0A10 /* prompt.c */; };
4C6159E01050615B00BF0A10 /* read.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61593D104F157800BF0A10 /* read.c */; };
4C6159E11050615B00BF0A10 /* readline.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61593F104F157800BF0A10 /* readline.c */; };
4C6159E21050615B00BF0A10 /* refresh.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615940104F157800BF0A10 /* refresh.c */; };
4C6159E31050615B00BF0A10 /* search.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615942104F157800BF0A10 /* search.c */; };
4C6159E41050615B00BF0A10 /* sig.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615945104F157800BF0A10 /* sig.c */; };
4C6159E71050615B00BF0A10 /* terminal.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61594A104F157800BF0A10 /* terminal.c */; };
4C6159E81050615B00BF0A10 /* tokenizer.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61594B104F157800BF0A10 /* tokenizer.c */; };
4C6159E91050615B00BF0A10 /* tty.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61594C104F157800BF0A10 /* tty.c */; };
4C6159EA1050615B00BF0A10 /* unvis.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61594E104F157800BF0A10 /* unvis.c */; };
4C6159EB1050615B00BF0A10 /* vi.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C61594F104F157800BF0A10 /* vi.c */; };
4C6159EC1050615B00BF0A10 /* vis.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C615950104F157800BF0A10 /* vis.c */; };
4C6159ED1050615B00BF0A10 /* fcns.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6159A1104F203600BF0A10 /* fcns.c */; };
4C6159EE1050615B00BF0A10 /* help.c in Sources */ = {isa = PBXBuildFile; fileRef = 4C6159A2104F203600BF0A10 /* help.c */; };
4C6159FD105061E200BF0A10 /* chared.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615923104F157800BF0A10 /* chared.h */; };
4C6159FE105061E200BF0A10 /* readline.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615926104F157800BF0A10 /* readline.h */; };
4C6159FF105061E200BF0A10 /* terminal.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615927104F157800BF0A10 /* terminal.h */; };
4C615A00105061E200BF0A10 /* el.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615929104F157800BF0A10 /* el.h */; };
4C615A01105061E200BF0A10 /* filecomplete.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61592D104F157800BF0A10 /* filecomplete.h */; };
4C615A02105061E200BF0A10 /* hist.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61592F104F157800BF0A10 /* hist.h */; };
4C615A03105061E200BF0A10 /* histedit.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615930104F157800BF0A10 /* histedit.h */; };
4C615A04105061E200BF0A10 /* keymacro.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615933104F157800BF0A10 /* keymacro.h */; };
4C615A05105061E200BF0A10 /* map.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615938104F157800BF0A10 /* map.h */; };
4C615A06105061E200BF0A10 /* parse.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61593A104F157800BF0A10 /* parse.h */; };
4C615A07105061E200BF0A10 /* prompt.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61593C104F157800BF0A10 /* prompt.h */; };
4C615A08105061E200BF0A10 /* read.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61593E104F157800BF0A10 /* read.h */; };
4C615A09105061E200BF0A10 /* refresh.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615941104F157800BF0A10 /* refresh.h */; };
4C615A0A105061E200BF0A10 /* search.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615943104F157800BF0A10 /* search.h */; };
4C615A0B105061E200BF0A10 /* sig.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615946104F157800BF0A10 /* sig.h */; };
4C615A0C105061E200BF0A10 /* sys.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615949104F157800BF0A10 /* sys.h */; };
4C615A0D105061E200BF0A10 /* tty.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61594D104F157800BF0A10 /* tty.h */; };
4C615A0E105061E200BF0A10 /* vis.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615951104F157800BF0A10 /* vis.h */; };
4C615A0F105061E200BF0A10 /* config.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C615980104F15C700BF0A10 /* config.h */; };
4C615A10105061E200BF0A10 /* common.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C61599F104F203600BF0A10 /* common.h */; };
4C615A11105061E200BF0A10 /* emacs.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6159A0104F203600BF0A10 /* emacs.h */; };
4C615A12105061E200BF0A10 /* help.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6159A3104F203600BF0A10 /* help.h */; };
4C615A13105061E200BF0A10 /* vi.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6159A4104F203600BF0A10 /* vi.h */; };
4C615A14105061E200BF0A10 /* fcns.h in Headers */ = {isa = PBXBuildFile; fileRef = 4C6159B7104F20F500BF0A10 /* fcns.h */; };
B1140F2B1188EEBE00188080 /* historyn.c in Sources */ = {isa = PBXBuildFile; fileRef = B1140F291188EEBE00188080 /* historyn.c */; };
B1140F2C1188EEBE00188080 /* tokenizern.c in Sources */ = {isa = PBXBuildFile; fileRef = B1140F2A1188EEBE00188080 /* tokenizern.c */; };
B1140F2D1188EEBE00188080 /* historyn.c in Sources */ = {isa = PBXBuildFile; fileRef = B1140F291188EEBE00188080 /* historyn.c */; };
B1140F2E1188EEBE00188080 /* tokenizern.c in Sources */ = {isa = PBXBuildFile; fileRef = B1140F2A1188EEBE00188080 /* tokenizern.c */; };
B18111981188D65A00EC8250 /* chartype.c in Sources */ = {isa = PBXBuildFile; fileRef = B18111941188D65A00EC8250 /* chartype.c */; };
B18111991188D65A00EC8250 /* chartype.h in Headers */ = {isa = PBXBuildFile; fileRef = B18111951188D65A00EC8250 /* chartype.h */; };
B181119A1188D65A00EC8250 /* eln.c in Sources */ = {isa = PBXBuildFile; fileRef = B18111961188D65A00EC8250 /* eln.c */; };
B181119B1188D65A00EC8250 /* wcsdup.c in Sources */ = {isa = PBXBuildFile; fileRef = B18111971188D65A00EC8250 /* wcsdup.c */; };
B181119C1188D65A00EC8250 /* chartype.c in Sources */ = {isa = PBXBuildFile; fileRef = B18111941188D65A00EC8250 /* chartype.c */; };
B181119D1188D65A00EC8250 /* chartype.h in Headers */ = {isa = PBXBuildFile; fileRef = B18111951188D65A00EC8250 /* chartype.h */; };
B181119E1188D65A00EC8250 /* eln.c in Sources */ = {isa = PBXBuildFile; fileRef = B18111961188D65A00EC8250 /* eln.c */; };
B181119F1188D65A00EC8250 /* wcsdup.c in Sources */ = {isa = PBXBuildFile; fileRef = B18111971188D65A00EC8250 /* wcsdup.c */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
4C615989104F1E9000BF0A10 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 08FB7793FE84155DC02AAC07 /* Project object */;
proxyType = 1;
remoteGlobalIDString = D2AAC0620554660B00DB518D;
remoteInfo = libedit;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
4C615922104F157800BF0A10 /* chared.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = chared.c; path = src/chared.c; sourceTree = "<group>"; };
4C615923104F157800BF0A10 /* chared.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = chared.h; path = src/chared.h; sourceTree = "<group>"; };
4C615924104F157800BF0A10 /* common.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = common.c; path = src/common.c; sourceTree = "<group>"; };
4C615926104F157800BF0A10 /* readline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = readline.h; sourceTree = "<group>"; };
4C615927104F157800BF0A10 /* terminal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = terminal.h; path = src/terminal.h; sourceTree = "<group>"; };
4C615928104F157800BF0A10 /* el.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = el.c; path = src/el.c; sourceTree = "<group>"; };
4C615929104F157800BF0A10 /* el.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = el.h; path = src/el.h; sourceTree = "<group>"; };
4C61592A104F157800BF0A10 /* emacs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = emacs.c; path = src/emacs.c; sourceTree = "<group>"; };
4C61592C104F157800BF0A10 /* filecomplete.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = filecomplete.c; path = src/filecomplete.c; sourceTree = "<group>"; };
4C61592D104F157800BF0A10 /* filecomplete.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = filecomplete.h; path = src/filecomplete.h; sourceTree = "<group>"; };
4C61592E104F157800BF0A10 /* hist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hist.c; path = src/hist.c; sourceTree = "<group>"; };
4C61592F104F157800BF0A10 /* hist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hist.h; path = src/hist.h; sourceTree = "<group>"; };
4C615930104F157800BF0A10 /* histedit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = histedit.h; path = src/histedit.h; sourceTree = "<group>"; };
4C615931104F157800BF0A10 /* history.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = history.c; path = src/history.c; sourceTree = "<group>"; };
4C615932104F157800BF0A10 /* keymacro.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = keymacro.c; path = src/keymacro.c; sourceTree = "<group>"; };
4C615933104F157800BF0A10 /* keymacro.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = keymacro.h; path = src/keymacro.h; sourceTree = "<group>"; };
4C615934104F157800BF0A10 /* Makefile.am */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Makefile.am; path = src/Makefile.am; sourceTree = "<group>"; };
4C615935104F157800BF0A10 /* Makefile.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = Makefile.in; path = src/Makefile.in; sourceTree = "<group>"; };
4C615936104F157800BF0A10 /* makelist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; name = makelist; path = src/makelist; sourceTree = "<group>"; };
4C615937104F157800BF0A10 /* map.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = map.c; path = src/map.c; sourceTree = "<group>"; };
4C615938104F157800BF0A10 /* map.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = map.h; path = src/map.h; sourceTree = "<group>"; };
4C615939104F157800BF0A10 /* parse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = parse.c; path = src/parse.c; sourceTree = "<group>"; };
4C61593A104F157800BF0A10 /* parse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = parse.h; path = src/parse.h; sourceTree = "<group>"; };
4C61593B104F157800BF0A10 /* prompt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = prompt.c; path = src/prompt.c; sourceTree = "<group>"; };
4C61593C104F157800BF0A10 /* prompt.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = prompt.h; path = src/prompt.h; sourceTree = "<group>"; };
4C61593D104F157800BF0A10 /* read.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = read.c; path = src/read.c; sourceTree = "<group>"; };
4C61593E104F157800BF0A10 /* read.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = read.h; path = src/read.h; sourceTree = "<group>"; };
4C61593F104F157800BF0A10 /* readline.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = readline.c; path = src/readline.c; sourceTree = "<group>"; };
4C615940104F157800BF0A10 /* refresh.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = refresh.c; path = src/refresh.c; sourceTree = "<group>"; };
4C615941104F157800BF0A10 /* refresh.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = refresh.h; path = src/refresh.h; sourceTree = "<group>"; };
4C615942104F157800BF0A10 /* search.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = search.c; path = src/search.c; sourceTree = "<group>"; };
4C615943104F157800BF0A10 /* search.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = search.h; path = src/search.h; sourceTree = "<group>"; };
4C615944104F157800BF0A10 /* shlib_version */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = shlib_version; path = src/shlib_version; sourceTree = "<group>"; };
4C615945104F157800BF0A10 /* sig.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = sig.c; path = src/sig.c; sourceTree = "<group>"; };
4C615946104F157800BF0A10 /* sig.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sig.h; path = src/sig.h; sourceTree = "<group>"; };
4C615949104F157800BF0A10 /* sys.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = sys.h; path = src/sys.h; sourceTree = "<group>"; };
4C61594A104F157800BF0A10 /* terminal.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = terminal.c; path = src/terminal.c; sourceTree = "<group>"; };
4C61594B104F157800BF0A10 /* tokenizer.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tokenizer.c; path = src/tokenizer.c; sourceTree = "<group>"; };
4C61594C104F157800BF0A10 /* tty.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tty.c; path = src/tty.c; sourceTree = "<group>"; };
4C61594D104F157800BF0A10 /* tty.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = tty.h; path = src/tty.h; sourceTree = "<group>"; };
4C61594E104F157800BF0A10 /* unvis.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = unvis.c; path = src/unvis.c; sourceTree = "<group>"; };
4C61594F104F157800BF0A10 /* vi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vi.c; path = src/vi.c; sourceTree = "<group>"; };
4C615950104F157800BF0A10 /* vis.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = vis.c; path = src/vis.c; sourceTree = "<group>"; };
4C615951104F157800BF0A10 /* vis.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vis.h; path = src/vis.h; sourceTree = "<group>"; };
4C615980104F15C700BF0A10 /* config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = config.h; sourceTree = "<group>"; };
4C61599F104F203600BF0A10 /* common.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = common.h; path = local/common.h; sourceTree = "<group>"; };
4C6159A0104F203600BF0A10 /* emacs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = emacs.h; path = local/emacs.h; sourceTree = "<group>"; };
4C6159A1104F203600BF0A10 /* fcns.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = fcns.c; path = local/fcns.c; sourceTree = "<group>"; };
4C6159A2104F203600BF0A10 /* help.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = help.c; path = local/help.c; sourceTree = "<group>"; };
4C6159A3104F203600BF0A10 /* help.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = help.h; path = local/help.h; sourceTree = "<group>"; };
4C6159A4104F203600BF0A10 /* vi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = vi.h; path = local/vi.h; sourceTree = "<group>"; };
4C6159B7104F20F500BF0A10 /* fcns.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fcns.h; path = local/fcns.h; sourceTree = "<group>"; };
4C6159BC104F212400BF0A10 /* libncurses.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.dylib; path = /usr/lib/libncurses.dylib; sourceTree = "<absolute>"; };
4C6159CF1050614000BF0A10 /* libedit.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libedit.a; sourceTree = BUILT_PRODUCTS_DIR; };
8128AE7C185DABB600F61B90 /* libedit.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = libedit.xcconfig; path = xcodescripts/libedit.xcconfig; sourceTree = "<group>"; };
B1140F291188EEBE00188080 /* historyn.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = historyn.c; path = local/historyn.c; sourceTree = "<group>"; };
B1140F2A1188EEBE00188080 /* tokenizern.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = tokenizern.c; path = local/tokenizern.c; sourceTree = "<group>"; };
B18111941188D65A00EC8250 /* chartype.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = chartype.c; path = src/chartype.c; sourceTree = "<group>"; };
B18111951188D65A00EC8250 /* chartype.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = chartype.h; path = src/chartype.h; sourceTree = "<group>"; };
B18111961188D65A00EC8250 /* eln.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = eln.c; path = src/eln.c; sourceTree = "<group>"; };
B18111971188D65A00EC8250 /* wcsdup.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = wcsdup.c; path = src/wcsdup.c; sourceTree = "<group>"; };
C903168F128A23B400BD42C3 /* install_misc.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = install_misc.sh; sourceTree = "<group>"; };
C9031690128A23B400BD42C3 /* make_lists.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = make_lists.sh; sourceTree = "<group>"; };
D2AAC0630554660B00DB518D /* libedit.3.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = libedit.3.dylib; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
4C6159CD1050614000BF0A10 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
D289988505E68E00004EDB86 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
4C6159BD104F212400BF0A10 /* libncurses.dylib in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
08FB7794FE84155DC02AAC07 /* libedit */ = {
isa = PBXGroup;
children = (
8128AE7C185DABB600F61B90 /* libedit.xcconfig */,
4C6159BC104F212400BF0A10 /* libncurses.dylib */,
4C61597F104F15A900BF0A10 /* local */,
08FB7795FE84155DC02AAC07 /* Source */,
1AB674ADFE9D54B511CA2CBB /* Products */,
C903168E128A23B400BD42C3 /* xcodescripts */,
);
name = libedit;
sourceTree = "<group>";
};
08FB7795FE84155DC02AAC07 /* Source */ = {
isa = PBXGroup;
children = (
4C615922104F157800BF0A10 /* chared.c */,
4C615923104F157800BF0A10 /* chared.h */,
B18111941188D65A00EC8250 /* chartype.c */,
B18111951188D65A00EC8250 /* chartype.h */,
4C615924104F157800BF0A10 /* common.c */,
4C615925104F157800BF0A10 /* editline */,
4C615927104F157800BF0A10 /* terminal.h */,
4C615928104F157800BF0A10 /* el.c */,
4C615929104F157800BF0A10 /* el.h */,
B18111961188D65A00EC8250 /* eln.c */,
4C61592A104F157800BF0A10 /* emacs.c */,
4C61592C104F157800BF0A10 /* filecomplete.c */,
4C61592D104F157800BF0A10 /* filecomplete.h */,
4C61592E104F157800BF0A10 /* hist.c */,
4C61592F104F157800BF0A10 /* hist.h */,
4C615930104F157800BF0A10 /* histedit.h */,
4C615931104F157800BF0A10 /* history.c */,
4C615932104F157800BF0A10 /* keymacro.c */,
4C615933104F157800BF0A10 /* keymacro.h */,
4C615934104F157800BF0A10 /* Makefile.am */,
4C615935104F157800BF0A10 /* Makefile.in */,
4C615936104F157800BF0A10 /* makelist */,
4C615937104F157800BF0A10 /* map.c */,
4C615938104F157800BF0A10 /* map.h */,
4C615939104F157800BF0A10 /* parse.c */,
4C61593A104F157800BF0A10 /* parse.h */,
4C61593B104F157800BF0A10 /* prompt.c */,
4C61593C104F157800BF0A10 /* prompt.h */,
4C61593D104F157800BF0A10 /* read.c */,
4C61593E104F157800BF0A10 /* read.h */,
4C61593F104F157800BF0A10 /* readline.c */,
4C615940104F157800BF0A10 /* refresh.c */,
4C615941104F157800BF0A10 /* refresh.h */,
4C615942104F157800BF0A10 /* search.c */,
4C615943104F157800BF0A10 /* search.h */,
4C615944104F157800BF0A10 /* shlib_version */,
4C615945104F157800BF0A10 /* sig.c */,
4C615946104F157800BF0A10 /* sig.h */,
4C615949104F157800BF0A10 /* sys.h */,
4C61594A104F157800BF0A10 /* terminal.c */,
4C61594B104F157800BF0A10 /* tokenizer.c */,
4C61594C104F157800BF0A10 /* tty.c */,
4C61594D104F157800BF0A10 /* tty.h */,
4C61594E104F157800BF0A10 /* unvis.c */,
4C61594F104F157800BF0A10 /* vi.c */,
4C615950104F157800BF0A10 /* vis.c */,
4C615951104F157800BF0A10 /* vis.h */,
B18111971188D65A00EC8250 /* wcsdup.c */,
);
name = Source;
sourceTree = "<group>";
};
1AB674ADFE9D54B511CA2CBB /* Products */ = {
isa = PBXGroup;
children = (
D2AAC0630554660B00DB518D /* libedit.3.dylib */,
4C6159CF1050614000BF0A10 /* libedit.a */,
);
name = Products;
sourceTree = "<group>";
};
4C615925104F157800BF0A10 /* editline */ = {
isa = PBXGroup;
children = (
4C615926104F157800BF0A10 /* readline.h */,
);
name = editline;
path = src/editline;
sourceTree = "<group>";
};
4C61597F104F15A900BF0A10 /* local */ = {
isa = PBXGroup;
children = (
4C6159B7104F20F500BF0A10 /* fcns.h */,
4C61599F104F203600BF0A10 /* common.h */,
4C6159A0104F203600BF0A10 /* emacs.h */,
4C6159A1104F203600BF0A10 /* fcns.c */,
4C6159A2104F203600BF0A10 /* help.c */,
4C6159A3104F203600BF0A10 /* help.h */,
B1140F291188EEBE00188080 /* historyn.c */,
B1140F2A1188EEBE00188080 /* tokenizern.c */,
4C6159A4104F203600BF0A10 /* vi.h */,
4C615980104F15C700BF0A10 /* config.h */,
);
name = local;
sourceTree = "<group>";
};
C903168E128A23B400BD42C3 /* xcodescripts */ = {
isa = PBXGroup;
children = (
C903168F128A23B400BD42C3 /* install_misc.sh */,
C9031690128A23B400BD42C3 /* make_lists.sh */,
);
path = xcodescripts;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
4C6159CB1050614000BF0A10 /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
4C6159FD105061E200BF0A10 /* chared.h in Headers */,
4C6159FE105061E200BF0A10 /* readline.h in Headers */,
4C6159FF105061E200BF0A10 /* terminal.h in Headers */,
4C615A00105061E200BF0A10 /* el.h in Headers */,
4C615A01105061E200BF0A10 /* filecomplete.h in Headers */,
4C615A02105061E200BF0A10 /* hist.h in Headers */,
4C615A03105061E200BF0A10 /* histedit.h in Headers */,
4C615A04105061E200BF0A10 /* keymacro.h in Headers */,
4C615A05105061E200BF0A10 /* map.h in Headers */,
4C615A06105061E200BF0A10 /* parse.h in Headers */,
4C615A07105061E200BF0A10 /* prompt.h in Headers */,
4C615A08105061E200BF0A10 /* read.h in Headers */,
4C615A09105061E200BF0A10 /* refresh.h in Headers */,
4C615A0A105061E200BF0A10 /* search.h in Headers */,
4C615A0B105061E200BF0A10 /* sig.h in Headers */,
4C615A0C105061E200BF0A10 /* sys.h in Headers */,
4C615A0D105061E200BF0A10 /* tty.h in Headers */,
4C615A0E105061E200BF0A10 /* vis.h in Headers */,
4C615A0F105061E200BF0A10 /* config.h in Headers */,
4C615A10105061E200BF0A10 /* common.h in Headers */,
4C615A11105061E200BF0A10 /* emacs.h in Headers */,
4C615A12105061E200BF0A10 /* help.h in Headers */,
4C615A13105061E200BF0A10 /* vi.h in Headers */,
4C615A14105061E200BF0A10 /* fcns.h in Headers */,
B181119D1188D65A00EC8250 /* chartype.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D2AAC0600554660B00DB518D /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
4C615953104F157800BF0A10 /* chared.h in Headers */,
4C615955104F157800BF0A10 /* readline.h in Headers */,
4C615956104F157800BF0A10 /* terminal.h in Headers */,
4C615958104F157800BF0A10 /* el.h in Headers */,
4C61595C104F157800BF0A10 /* filecomplete.h in Headers */,
4C61595E104F157800BF0A10 /* hist.h in Headers */,
4C61595F104F157800BF0A10 /* histedit.h in Headers */,
4C615962104F157800BF0A10 /* keymacro.h in Headers */,
4C615964104F157800BF0A10 /* map.h in Headers */,
4C615966104F157800BF0A10 /* parse.h in Headers */,
4C615968104F157800BF0A10 /* prompt.h in Headers */,
4C61596A104F157800BF0A10 /* read.h in Headers */,
4C61596D104F157800BF0A10 /* refresh.h in Headers */,
4C61596F104F157800BF0A10 /* search.h in Headers */,
4C615971104F157800BF0A10 /* sig.h in Headers */,
4C615974104F157800BF0A10 /* sys.h in Headers */,
4C615978104F157800BF0A10 /* tty.h in Headers */,
4C61597C104F157800BF0A10 /* vis.h in Headers */,
4C615981104F15C700BF0A10 /* config.h in Headers */,
4C6159A5104F203600BF0A10 /* common.h in Headers */,
4C6159A6104F203600BF0A10 /* emacs.h in Headers */,
4C6159A9104F203600BF0A10 /* help.h in Headers */,
4C6159AA104F203600BF0A10 /* vi.h in Headers */,
4C6159B8104F20F500BF0A10 /* fcns.h in Headers */,
B18111991188D65A00EC8250 /* chartype.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
4C6159CE1050614000BF0A10 /* libedit-static */ = {
isa = PBXNativeTarget;
buildConfigurationList = 4C6159F61050616A00BF0A10 /* Build configuration list for PBXNativeTarget "libedit-static" */;
buildPhases = (
4C6159CB1050614000BF0A10 /* Headers */,
4C6159CC1050614000BF0A10 /* Sources */,
4C6159CD1050614000BF0A10 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = "libedit-static";
productName = "libedit-static";
productReference = 4C6159CF1050614000BF0A10 /* libedit.a */;
productType = "com.apple.product-type.library.static";
};
D2AAC0620554660B00DB518D /* libedit */ = {
isa = PBXNativeTarget;
buildConfigurationList = 1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "libedit" */;
buildPhases = (
D2AAC0600554660B00DB518D /* Headers */,
D2AAC0610554660B00DB518D /* Sources */,
D289988505E68E00004EDB86 /* Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = libedit;
productName = libedit;
productReference = D2AAC0630554660B00DB518D /* libedit.3.dylib */;
productType = "com.apple.product-type.library.dynamic";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
08FB7793FE84155DC02AAC07 /* Project object */ = {
isa = PBXProject;
attributes = {
};
buildConfigurationList = 1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "libedit" */;
compatibilityVersion = "Xcode 3.1";
developmentRegion = English;
hasScannedForEncodings = 1;
knownRegions = (
English,
Japanese,
French,
German,
);
mainGroup = 08FB7794FE84155DC02AAC07 /* libedit */;
projectDirPath = "";
projectRoot = "";
targets = (
4C615986104F1E8800BF0A10 /* all */,
D2AAC0620554660B00DB518D /* libedit */,
4C6159C31050604600BF0A10 /* make lists */,
4C6159CE1050614000BF0A10 /* libedit-static */,
);
};
/* End PBXProject section */
/* Begin PBXShellScriptBuildPhase section */
4C6159C21050604600BF0A10 /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"$PROJECT_DIR\"/xcodescripts/make_lists.sh";
};
4C615A221050668A00BF0A10 /* install misc */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 8;
files = (
);
inputPaths = (
);
name = "install misc";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 1;
shellPath = /bin/sh;
shellScript = "\"$PROJECT_DIR\"/xcodescripts/install_misc.sh\n";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
4C6159CC1050614000BF0A10 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4C6159D41050615B00BF0A10 /* chared.c in Sources */,
4C6159D51050615B00BF0A10 /* common.c in Sources */,
4C6159D61050615B00BF0A10 /* el.c in Sources */,
4C6159D71050615B00BF0A10 /* emacs.c in Sources */,
4C6159D91050615B00BF0A10 /* filecomplete.c in Sources */,
4C6159DA1050615B00BF0A10 /* hist.c in Sources */,
4C6159DB1050615B00BF0A10 /* history.c in Sources */,
4C6159DC1050615B00BF0A10 /* keymacro.c in Sources */,
4C6159DD1050615B00BF0A10 /* map.c in Sources */,
4C6159DE1050615B00BF0A10 /* parse.c in Sources */,
4C6159DF1050615B00BF0A10 /* prompt.c in Sources */,
4C6159E01050615B00BF0A10 /* read.c in Sources */,
4C6159E11050615B00BF0A10 /* readline.c in Sources */,
4C6159E21050615B00BF0A10 /* refresh.c in Sources */,
4C6159E31050615B00BF0A10 /* search.c in Sources */,
4C6159E41050615B00BF0A10 /* sig.c in Sources */,
4C6159E71050615B00BF0A10 /* terminal.c in Sources */,
4C6159E81050615B00BF0A10 /* tokenizer.c in Sources */,
4C6159E91050615B00BF0A10 /* tty.c in Sources */,
4C6159EA1050615B00BF0A10 /* unvis.c in Sources */,
4C6159EB1050615B00BF0A10 /* vi.c in Sources */,
4C6159EC1050615B00BF0A10 /* vis.c in Sources */,
4C6159ED1050615B00BF0A10 /* fcns.c in Sources */,
4C6159EE1050615B00BF0A10 /* help.c in Sources */,
B181119C1188D65A00EC8250 /* chartype.c in Sources */,
B181119E1188D65A00EC8250 /* eln.c in Sources */,
B181119F1188D65A00EC8250 /* wcsdup.c in Sources */,
B1140F2D1188EEBE00188080 /* historyn.c in Sources */,
B1140F2E1188EEBE00188080 /* tokenizern.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
D2AAC0610554660B00DB518D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4C615952104F157800BF0A10 /* chared.c in Sources */,
4C615954104F157800BF0A10 /* common.c in Sources */,
4C615957104F157800BF0A10 /* el.c in Sources */,
4C615959104F157800BF0A10 /* emacs.c in Sources */,
4C61595B104F157800BF0A10 /* filecomplete.c in Sources */,
4C61595D104F157800BF0A10 /* hist.c in Sources */,
4C615960104F157800BF0A10 /* history.c in Sources */,
4C615961104F157800BF0A10 /* keymacro.c in Sources */,
4C615963104F157800BF0A10 /* map.c in Sources */,
4C615965104F157800BF0A10 /* parse.c in Sources */,
4C615967104F157800BF0A10 /* prompt.c in Sources */,
4C615969104F157800BF0A10 /* read.c in Sources */,
4C61596B104F157800BF0A10 /* readline.c in Sources */,
4C61596C104F157800BF0A10 /* refresh.c in Sources */,
4C61596E104F157800BF0A10 /* search.c in Sources */,
4C615970104F157800BF0A10 /* sig.c in Sources */,
4C615975104F157800BF0A10 /* terminal.c in Sources */,
4C615976104F157800BF0A10 /* tokenizer.c in Sources */,
4C615977104F157800BF0A10 /* tty.c in Sources */,
4C615979104F157800BF0A10 /* unvis.c in Sources */,
4C61597A104F157800BF0A10 /* vi.c in Sources */,
4C61597B104F157800BF0A10 /* vis.c in Sources */,
4C6159A7104F203600BF0A10 /* fcns.c in Sources */,
4C6159A8104F203600BF0A10 /* help.c in Sources */,
B18111981188D65A00EC8250 /* chartype.c in Sources */,
B181119A1188D65A00EC8250 /* eln.c in Sources */,
B181119B1188D65A00EC8250 /* wcsdup.c in Sources */,
B1140F2B1188EEBE00188080 /* historyn.c in Sources */,
B1140F2C1188EEBE00188080 /* tokenizern.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
4C61598A104F1E9000BF0A10 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = D2AAC0620554660B00DB518D /* libedit */;
targetProxy = 4C615989104F1E9000BF0A10 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
1DEB914C08733D8E0010E9CD /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 8128AE7C185DABB600F61B90 /* libedit.xcconfig */;
buildSettings = {
};
name = Release;
};
1DEB915008733D8E0010E9CD /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
4C615988104F1E8800BF0A10 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 8128AE7C185DABB600F61B90 /* libedit.xcconfig */;
buildSettings = {
PRODUCT_NAME = all;
};
name = Release;
};
4C6159C51050604600BF0A10 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = "make sources";
};
name = Release;
};
4C6159D11050614000BF0A10 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
GCC_ENABLE_PASCAL_STRINGS = NO;
INSTALL_PATH = /usr/local/lib;
"INSTALL_PATH[sdk=iphonesimulator*]" = "$(SDKROOT)/usr/local/lib";
PRODUCT_NAME = edit;
STRIP_INSTALLED_PRODUCT = YES;
STRIP_STYLE = "non-global";
USER_HEADER_SEARCH_PATHS = src;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
1DEB914A08733D8E0010E9CD /* Build configuration list for PBXNativeTarget "libedit" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB914C08733D8E0010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
1DEB914E08733D8E0010E9CD /* Build configuration list for PBXProject "libedit" */ = {
isa = XCConfigurationList;
buildConfigurations = (
1DEB915008733D8E0010E9CD /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4C61598F104F1EF300BF0A10 /* Build configuration list for PBXAggregateTarget "all" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4C615988104F1E8800BF0A10 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4C6159CA1050608D00BF0A10 /* Build configuration list for PBXAggregateTarget "make lists" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4C6159C51050604600BF0A10 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
4C6159F61050616A00BF0A10 /* Build configuration list for PBXNativeTarget "libedit-static" */ = {
isa = XCConfigurationList;
buildConfigurations = (
4C6159D11050614000BF0A10 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;
}

39
local/common.h Normal file
View File

@ -0,0 +1,39 @@
/* Automatically generated file, do not edit */
#ifndef _h_common_c
#define _h_common_c
protected el_action_t ed_end_of_file (EditLine *, Int);
protected el_action_t ed_insert (EditLine *, Int);
protected el_action_t ed_delete_prev_word (EditLine *, Int);
protected el_action_t ed_delete_next_char (EditLine *, Int);
protected el_action_t ed_kill_line (EditLine *, Int);
protected el_action_t ed_move_to_end (EditLine *, Int);
protected el_action_t ed_move_to_beg (EditLine *, Int);
protected el_action_t ed_transpose_chars (EditLine *, Int);
protected el_action_t ed_next_char (EditLine *, Int);
protected el_action_t ed_prev_word (EditLine *, Int);
protected el_action_t ed_prev_char (EditLine *, Int);
protected el_action_t ed_quoted_insert (EditLine *, Int);
protected el_action_t ed_digit (EditLine *, Int);
protected el_action_t ed_argument_digit (EditLine *, Int);
protected el_action_t ed_unassigned (EditLine *, Int);
protected el_action_t ed_tty_sigint (EditLine *, Int);
protected el_action_t ed_tty_dsusp (EditLine *, Int);
protected el_action_t ed_tty_flush_output (EditLine *, Int);
protected el_action_t ed_tty_sigquit (EditLine *, Int);
protected el_action_t ed_tty_sigtstp (EditLine *, Int);
protected el_action_t ed_tty_stop_output (EditLine *, Int);
protected el_action_t ed_tty_start_output (EditLine *, Int);
protected el_action_t ed_newline (EditLine *, Int);
protected el_action_t ed_delete_prev_char (EditLine *, Int);
protected el_action_t ed_clear_screen (EditLine *, Int);
protected el_action_t ed_redisplay (EditLine *, Int);
protected el_action_t ed_start_over (EditLine *, Int);
protected el_action_t ed_sequence_lead_in (EditLine *, Int);
protected el_action_t ed_prev_history (EditLine *, Int);
protected el_action_t ed_next_history (EditLine *, Int);
protected el_action_t ed_search_prev_history (EditLine *, Int);
protected el_action_t ed_search_next_history (EditLine *, Int);
protected el_action_t ed_prev_line (EditLine *, Int);
protected el_action_t ed_next_line (EditLine *, Int);
protected el_action_t ed_command (EditLine *, Int);
#endif /* _h_common_c */

24
local/emacs.h Normal file
View File

@ -0,0 +1,24 @@
/* Automatically generated file, do not edit */
#ifndef _h_emacs_c
#define _h_emacs_c
protected el_action_t em_delete_or_list (EditLine *, Int);
protected el_action_t em_delete_next_word (EditLine *, Int);
protected el_action_t em_yank (EditLine *, Int);
protected el_action_t em_kill_line (EditLine *, Int);
protected el_action_t em_kill_region (EditLine *, Int);
protected el_action_t em_copy_region (EditLine *, Int);
protected el_action_t em_gosmacs_transpose (EditLine *, Int);
protected el_action_t em_next_word (EditLine *, Int);
protected el_action_t em_upper_case (EditLine *, Int);
protected el_action_t em_capitol_case (EditLine *, Int);
protected el_action_t em_lower_case (EditLine *, Int);
protected el_action_t em_set_mark (EditLine *, Int);
protected el_action_t em_exchange_mark (EditLine *, Int);
protected el_action_t em_universal_argument (EditLine *, Int);
protected el_action_t em_meta_next (EditLine *, Int);
protected el_action_t em_toggle_overwrite (EditLine *, Int);
protected el_action_t em_copy_prev_word (EditLine *, Int);
protected el_action_t em_inc_search_next (EditLine *, Int);
protected el_action_t em_inc_search_prev (EditLine *, Int);
protected el_action_t em_delete_prev_char (EditLine *, Int);
#endif /* _h_emacs_c */

58
local/fcns.c Normal file
View File

@ -0,0 +1,58 @@
/* Automatically generated file, do not edit */
#include "config.h"
#include "el.h"
private const el_func_t el_func[] = {
ed_argument_digit, ed_clear_screen,
ed_command, ed_delete_next_char,
ed_delete_prev_char, ed_delete_prev_word,
ed_digit, ed_end_of_file,
ed_insert, ed_kill_line,
ed_move_to_beg, ed_move_to_end,
ed_newline, ed_next_char,
ed_next_history, ed_next_line,
ed_prev_char, ed_prev_history,
ed_prev_line, ed_prev_word,
ed_quoted_insert, ed_redisplay,
ed_search_next_history, ed_search_prev_history,
ed_sequence_lead_in, ed_start_over,
ed_transpose_chars, ed_tty_dsusp,
ed_tty_flush_output, ed_tty_sigint,
ed_tty_sigquit, ed_tty_sigtstp,
ed_tty_start_output, ed_tty_stop_output,
ed_unassigned, em_capitol_case,
em_copy_prev_word, em_copy_region,
em_delete_next_word, em_delete_or_list,
em_delete_prev_char, em_exchange_mark,
em_gosmacs_transpose, em_inc_search_next,
em_inc_search_prev, em_kill_line,
em_kill_region, em_lower_case,
em_meta_next, em_next_word,
em_set_mark, em_toggle_overwrite,
em_universal_argument, em_upper_case,
em_yank, vi_add,
vi_add_at_eol, vi_alias,
vi_change_case, vi_change_meta,
vi_change_to_eol, vi_command_mode,
vi_comment_out, vi_delete_meta,
vi_delete_prev_char, vi_end_big_word,
vi_end_word, vi_histedit,
vi_history_word, vi_insert,
vi_insert_at_bol, vi_kill_line_prev,
vi_list_or_eof, vi_match,
vi_next_big_word, vi_next_char,
vi_next_word, vi_paste_next,
vi_paste_prev, vi_prev_big_word,
vi_prev_char, vi_prev_word,
vi_redo, vi_repeat_next_char,
vi_repeat_prev_char, vi_repeat_search_next,
vi_repeat_search_prev, vi_replace_char,
vi_replace_mode, vi_search_next,
vi_search_prev, vi_substitute_char,
vi_substitute_line, vi_to_column,
vi_to_history_line, vi_to_next_char,
vi_to_prev_char, vi_undo,
vi_undo_line, vi_yank,
vi_yank_end, vi_zero,
};
protected const el_func_t* func__get(void) { return el_func; }

110
local/fcns.h Normal file
View File

@ -0,0 +1,110 @@
/* Automatically generated file, do not edit */
#ifndef _h_fcns_c
#define _h_fcns_c
#define ED_ARGUMENT_DIGIT 0
#define ED_CLEAR_SCREEN 1
#define ED_COMMAND 2
#define ED_DELETE_NEXT_CHAR 3
#define ED_DELETE_PREV_CHAR 4
#define ED_DELETE_PREV_WORD 5
#define ED_DIGIT 6
#define ED_END_OF_FILE 7
#define ED_INSERT 8
#define ED_KILL_LINE 9
#define ED_MOVE_TO_BEG 10
#define ED_MOVE_TO_END 11
#define ED_NEWLINE 12
#define ED_NEXT_CHAR 13
#define ED_NEXT_HISTORY 14
#define ED_NEXT_LINE 15
#define ED_PREV_CHAR 16
#define ED_PREV_HISTORY 17
#define ED_PREV_LINE 18
#define ED_PREV_WORD 19
#define ED_QUOTED_INSERT 20
#define ED_REDISPLAY 21
#define ED_SEARCH_NEXT_HISTORY 22
#define ED_SEARCH_PREV_HISTORY 23
#define ED_SEQUENCE_LEAD_IN 24
#define ED_START_OVER 25
#define ED_TRANSPOSE_CHARS 26
#define ED_TTY_DSUSP 27
#define ED_TTY_FLUSH_OUTPUT 28
#define ED_TTY_SIGINT 29
#define ED_TTY_SIGQUIT 30
#define ED_TTY_SIGTSTP 31
#define ED_TTY_START_OUTPUT 32
#define ED_TTY_STOP_OUTPUT 33
#define ED_UNASSIGNED 34
#define EM_CAPITOL_CASE 35
#define EM_COPY_PREV_WORD 36
#define EM_COPY_REGION 37
#define EM_DELETE_NEXT_WORD 38
#define EM_DELETE_OR_LIST 39
#define EM_DELETE_PREV_CHAR 40
#define EM_EXCHANGE_MARK 41
#define EM_GOSMACS_TRANSPOSE 42
#define EM_INC_SEARCH_NEXT 43
#define EM_INC_SEARCH_PREV 44
#define EM_KILL_LINE 45
#define EM_KILL_REGION 46
#define EM_LOWER_CASE 47
#define EM_META_NEXT 48
#define EM_NEXT_WORD 49
#define EM_SET_MARK 50
#define EM_TOGGLE_OVERWRITE 51
#define EM_UNIVERSAL_ARGUMENT 52
#define EM_UPPER_CASE 53
#define EM_YANK 54
#define VI_ADD 55
#define VI_ADD_AT_EOL 56
#define VI_ALIAS 57
#define VI_CHANGE_CASE 58
#define VI_CHANGE_META 59
#define VI_CHANGE_TO_EOL 60
#define VI_COMMAND_MODE 61
#define VI_COMMENT_OUT 62
#define VI_DELETE_META 63
#define VI_DELETE_PREV_CHAR 64
#define VI_END_BIG_WORD 65
#define VI_END_WORD 66
#define VI_HISTEDIT 67
#define VI_HISTORY_WORD 68
#define VI_INSERT 69
#define VI_INSERT_AT_BOL 70
#define VI_KILL_LINE_PREV 71
#define VI_LIST_OR_EOF 72
#define VI_MATCH 73
#define VI_NEXT_BIG_WORD 74
#define VI_NEXT_CHAR 75
#define VI_NEXT_WORD 76
#define VI_PASTE_NEXT 77
#define VI_PASTE_PREV 78
#define VI_PREV_BIG_WORD 79
#define VI_PREV_CHAR 80
#define VI_PREV_WORD 81
#define VI_REDO 82
#define VI_REPEAT_NEXT_CHAR 83
#define VI_REPEAT_PREV_CHAR 84
#define VI_REPEAT_SEARCH_NEXT 85
#define VI_REPEAT_SEARCH_PREV 86
#define VI_REPLACE_CHAR 87
#define VI_REPLACE_MODE 88
#define VI_SEARCH_NEXT 89
#define VI_SEARCH_PREV 90
#define VI_SUBSTITUTE_CHAR 91
#define VI_SUBSTITUTE_LINE 92
#define VI_TO_COLUMN 93
#define VI_TO_HISTORY_LINE 94
#define VI_TO_NEXT_CHAR 95
#define VI_TO_PREV_CHAR 96
#define VI_UNDO 97
#define VI_UNDO_LINE 98
#define VI_YANK 99
#define VI_YANK_END 100
#define VI_ZERO 101
#define EL_NUM_FCNS 102
#define EL_EOF 255
typedef el_action_t (*el_func_t)(EditLine *, Int);
protected const el_func_t* func__get(void);
#endif /* _h_fcns_c */

212
local/help.c Normal file
View File

@ -0,0 +1,212 @@
/* Automatically generated file, do not edit */
#include "config.h"
#include "el.h"
#include "chartype.h"
private const struct el_bindings_t el_func_help[] = {
{ STR("vi-paste-next"), VI_PASTE_NEXT,
STR("Vi paste previous deletion to the right of the cursor") },
{ STR("vi-paste-prev"), VI_PASTE_PREV,
STR("Vi paste previous deletion to the left of the cursor") },
{ STR("vi-prev-big-word"), VI_PREV_BIG_WORD,
STR("Vi move to the previous space delimited word") },
{ STR("vi-prev-word"), VI_PREV_WORD,
STR("Vi move to the previous word") },
{ STR("vi-next-big-word"), VI_NEXT_BIG_WORD,
STR("Vi move to the next space delimited word") },
{ STR("vi-next-word"), VI_NEXT_WORD,
STR("Vi move to the next word") },
{ STR("vi-change-case"), VI_CHANGE_CASE,
STR("Vi change case of character under the cursor and advance one character") },
{ STR("vi-change-meta"), VI_CHANGE_META,
STR("Vi change prefix command") },
{ STR("vi-insert-at-bol"), VI_INSERT_AT_BOL,
STR("Vi enter insert mode at the beginning of line") },
{ STR("vi-replace-char"), VI_REPLACE_CHAR,
STR("Vi replace character under the cursor with the next character typed") },
{ STR("vi-replace-mode"), VI_REPLACE_MODE,
STR("Vi enter replace mode") },
{ STR("vi-substitute-char"), VI_SUBSTITUTE_CHAR,
STR("Vi replace character under the cursor and enter insert mode") },
{ STR("vi-substitute-line"), VI_SUBSTITUTE_LINE,
STR("Vi substitute entire line") },
{ STR("vi-change-to-eol"), VI_CHANGE_TO_EOL,
STR("Vi change to end of line") },
{ STR("vi-insert"), VI_INSERT,
STR("Vi enter insert mode") },
{ STR("vi-add"), VI_ADD,
STR("Vi enter insert mode after the cursor") },
{ STR("vi-add-at-eol"), VI_ADD_AT_EOL,
STR("Vi enter insert mode at end of line") },
{ STR("vi-delete-meta"), VI_DELETE_META,
STR("Vi delete prefix command") },
{ STR("vi-end-big-word"), VI_END_BIG_WORD,
STR("Vi move to the end of the current space delimited word") },
{ STR("vi-end-word"), VI_END_WORD,
STR("Vi move to the end of the current word") },
{ STR("vi-undo"), VI_UNDO,
STR("Vi undo last change") },
{ STR("vi-command-mode"), VI_COMMAND_MODE,
STR("Vi enter command mode (use alternative key bindings)") },
{ STR("vi-zero"), VI_ZERO,
STR("Vi move to the beginning of line") },
{ STR("vi-delete-prev-char"), VI_DELETE_PREV_CHAR,
STR("Vi move to previous character (backspace)") },
{ STR("vi-list-or-eof"), VI_LIST_OR_EOF,
STR("Vi list choices for completion or indicate end of file if empty line") },
{ STR("vi-kill-line-prev"), VI_KILL_LINE_PREV,
STR("Vi cut from beginning of line to cursor") },
{ STR("vi-search-prev"), VI_SEARCH_PREV,
STR("Vi search history previous") },
{ STR("vi-search-next"), VI_SEARCH_NEXT,
STR("Vi search history next") },
{ STR("vi-repeat-search-next"), VI_REPEAT_SEARCH_NEXT,
STR("Vi repeat current search in the same search direction") },
{ STR("vi-repeat-search-prev"), VI_REPEAT_SEARCH_PREV,
STR("Vi repeat current search in the opposite search direction") },
{ STR("vi-next-char"), VI_NEXT_CHAR,
STR("Vi move to the character specified next") },
{ STR("vi-prev-char"), VI_PREV_CHAR,
STR("Vi move to the character specified previous") },
{ STR("vi-to-next-char"), VI_TO_NEXT_CHAR,
STR("Vi move up to the character specified next") },
{ STR("vi-to-prev-char"), VI_TO_PREV_CHAR,
STR("Vi move up to the character specified previous") },
{ STR("vi-repeat-next-char"), VI_REPEAT_NEXT_CHAR,
STR("Vi repeat current character search in the same search direction") },
{ STR("vi-repeat-prev-char"), VI_REPEAT_PREV_CHAR,
STR("Vi repeat current character search in the opposite search direction") },
{ STR("vi-match"), VI_MATCH,
STR("Vi go to matching () {} or []") },
{ STR("vi-undo-line"), VI_UNDO_LINE,
STR("Vi undo all changes to line") },
{ STR("vi-to-column"), VI_TO_COLUMN,
STR("Vi go to specified column") },
{ STR("vi-yank-end"), VI_YANK_END,
STR("Vi yank to end of line") },
{ STR("vi-yank"), VI_YANK,
STR("Vi yank") },
{ STR("vi-comment-out"), VI_COMMENT_OUT,
STR("Vi comment out current command") },
{ STR("vi-alias"), VI_ALIAS,
STR("Vi include shell alias") },
{ STR("vi-to-history-line"), VI_TO_HISTORY_LINE,
STR("Vi go to specified history file line.") },
{ STR("vi-histedit"), VI_HISTEDIT,
STR("Vi edit history line with vi") },
{ STR("vi-history-word"), VI_HISTORY_WORD,
STR("Vi append word from previous input line") },
{ STR("vi-redo"), VI_REDO,
STR("Vi redo last non-motion command") },
{ STR("em-delete-or-list"), EM_DELETE_OR_LIST,
STR("Delete character under cursor or list completions if at end of line") },
{ STR("em-delete-next-word"), EM_DELETE_NEXT_WORD,
STR("Cut from cursor to end of current word") },
{ STR("em-yank"), EM_YANK,
STR("Paste cut buffer at cursor position") },
{ STR("em-kill-line"), EM_KILL_LINE,
STR("Cut the entire line and save in cut buffer") },
{ STR("em-kill-region"), EM_KILL_REGION,
STR("Cut area between mark and cursor and save in cut buffer") },
{ STR("em-copy-region"), EM_COPY_REGION,
STR("Copy area between mark and cursor to cut buffer") },
{ STR("em-gosmacs-transpose"), EM_GOSMACS_TRANSPOSE,
STR("Exchange the two characters before the cursor") },
{ STR("em-next-word"), EM_NEXT_WORD,
STR("Move next to end of current word") },
{ STR("em-upper-case"), EM_UPPER_CASE,
STR("Uppercase the characters from cursor to end of current word") },
{ STR("em-capitol-case"), EM_CAPITOL_CASE,
STR("Capitalize the characters from cursor to end of current word") },
{ STR("em-lower-case"), EM_LOWER_CASE,
STR("Lowercase the characters from cursor to end of current word") },
{ STR("em-set-mark"), EM_SET_MARK,
STR("Set the mark at cursor") },
{ STR("em-exchange-mark"), EM_EXCHANGE_MARK,
STR("Exchange the cursor and mark") },
{ STR("em-universal-argument"), EM_UNIVERSAL_ARGUMENT,
STR("Universal argument (argument times 4)") },
{ STR("em-meta-next"), EM_META_NEXT,
STR("Add 8th bit to next character typed") },
{ STR("em-toggle-overwrite"), EM_TOGGLE_OVERWRITE,
STR("Switch from insert to overwrite mode or vice versa") },
{ STR("em-copy-prev-word"), EM_COPY_PREV_WORD,
STR("Copy current word to cursor") },
{ STR("em-inc-search-next"), EM_INC_SEARCH_NEXT,
STR("Emacs incremental next search") },
{ STR("em-inc-search-prev"), EM_INC_SEARCH_PREV,
STR("Emacs incremental reverse search") },
{ STR("em-delete-prev-char"), EM_DELETE_PREV_CHAR,
STR("Delete the character to the left of the cursor") },
{ STR("ed-end-of-file"), ED_END_OF_FILE,
STR("Indicate end of file") },
{ STR("ed-insert"), ED_INSERT,
STR("Add character to the line") },
{ STR("ed-delete-prev-word"), ED_DELETE_PREV_WORD,
STR("Delete from beginning of current word to cursor") },
{ STR("ed-delete-next-char"), ED_DELETE_NEXT_CHAR,
STR("Delete character under cursor") },
{ STR("ed-kill-line"), ED_KILL_LINE,
STR("Cut to the end of line") },
{ STR("ed-move-to-end"), ED_MOVE_TO_END,
STR("Move cursor to the end of line") },
{ STR("ed-move-to-beg"), ED_MOVE_TO_BEG,
STR("Move cursor to the beginning of line") },
{ STR("ed-transpose-chars"), ED_TRANSPOSE_CHARS,
STR("Exchange the character to the left of the cursor with the one under it") },
{ STR("ed-next-char"), ED_NEXT_CHAR,
STR("Move to the right one character") },
{ STR("ed-prev-word"), ED_PREV_WORD,
STR("Move to the beginning of the current word") },
{ STR("ed-prev-char"), ED_PREV_CHAR,
STR("Move to the left one character") },
{ STR("ed-quoted-insert"), ED_QUOTED_INSERT,
STR("Add the next character typed verbatim") },
{ STR("ed-digit"), ED_DIGIT,
STR("Adds to argument or enters a digit") },
{ STR("ed-argument-digit"), ED_ARGUMENT_DIGIT,
STR("Digit that starts argument") },
{ STR("ed-unassigned"), ED_UNASSIGNED,
STR("Indicates unbound character") },
{ STR("ed-tty-sigint"), ED_TTY_SIGINT,
STR("Tty interrupt character") },
{ STR("ed-tty-dsusp"), ED_TTY_DSUSP,
STR("Tty delayed suspend character") },
{ STR("ed-tty-flush-output"), ED_TTY_FLUSH_OUTPUT,
STR("Tty flush output characters") },
{ STR("ed-tty-sigquit"), ED_TTY_SIGQUIT,
STR("Tty quit character") },
{ STR("ed-tty-sigtstp"), ED_TTY_SIGTSTP,
STR("Tty suspend character") },
{ STR("ed-tty-stop-output"), ED_TTY_STOP_OUTPUT,
STR("Tty disallow output characters") },
{ STR("ed-tty-start-output"), ED_TTY_START_OUTPUT,
STR("Tty allow output characters") },
{ STR("ed-newline"), ED_NEWLINE,
STR("Execute command") },
{ STR("ed-delete-prev-char"), ED_DELETE_PREV_CHAR,
STR("Delete the character to the left of the cursor") },
{ STR("ed-clear-screen"), ED_CLEAR_SCREEN,
STR("Clear screen leaving current line at the top") },
{ STR("ed-redisplay"), ED_REDISPLAY,
STR("Redisplay everything") },
{ STR("ed-start-over"), ED_START_OVER,
STR("Erase current line and start from scratch") },
{ STR("ed-sequence-lead-in"), ED_SEQUENCE_LEAD_IN,
STR("First character in a bound sequence") },
{ STR("ed-prev-history"), ED_PREV_HISTORY,
STR("Move to the previous history line") },
{ STR("ed-next-history"), ED_NEXT_HISTORY,
STR("Move to the next history line") },
{ STR("ed-search-prev-history"), ED_SEARCH_PREV_HISTORY,
STR("Search previous in history for a line matching the current") },
{ STR("ed-search-next-history"), ED_SEARCH_NEXT_HISTORY,
STR("Search next in history for a line matching the current") },
{ STR("ed-prev-line"), ED_PREV_LINE,
STR("Move up one line") },
{ STR("ed-next-line"), ED_NEXT_LINE,
STR("Move down one line") },
{ STR("ed-command"), ED_COMMAND,
STR("Editline extended command") },
};
protected const el_bindings_t* help__get(void){ return el_func_help; }

5
local/help.h Normal file
View File

@ -0,0 +1,5 @@
/* Automatically generated file, do not edit */
#ifndef _h_help_c
#define _h_help_c
protected const el_bindings_t *help__get(void);
#endif /* _h_help_c */

4
local/historyn.c Normal file
View File

@ -0,0 +1,4 @@
#include "config.h"
#undef WIDECHAR
#define NARROWCHAR
#include "./history.c"

12
local/libedit.pc Normal file
View File

@ -0,0 +1,12 @@
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include
Name: libedit
Description: command line editor library provides generic line editing, history, and tokenization functions.
Version: 3.0
Requires:
Libs: -L${libdir} -ledit -lcurses
Cflags: -I${includedir} -I${includedir}/editline

30
local/libedit.plist Normal file
View File

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>OpenSourceProject</key>
<string>libedit</string>
<key>OpenSourceVersion</key>
<string>3.0</string>
<key>OpenSourceWebsiteURL</key>
<string>http://www.thrysoee.dk/editline/</string>
<key>OpenSourceURL</key>
<string>http://www.thrysoee.dk/editline/libedit-20121213-3.0.tar.gz</string>
<key>OpenSourceSHA1</key>
<string>2f20bc835c1282b6815c4c8e2f852d6fe4318f7a</string>
<key>OpenSourceImportDate</key>
<string>2012-01-15</string>
<key>OpenSourceLicense</key>
<string>BSD</string>
<key>OpenSourceLicenseFile</key>
<string>libedit.txt</string>
<key>OpenSourceModifications</key>
<array>
<string>Additional malloc fixes (7866382)</string>
<string>filecomplete.c: Fix rl_line_buffer (9869665)</string>
<string>filecomplete.c: Implement _el_fn_sh_complete (22276828)</string>
<string>filecomplete.c: Adjust dequoting_func types because of 9869665</string>
<string>filecomplete.c: Fix quoted_match leak</string>
</array>
</dict>
</plist>

4
local/tokenizern.c Normal file
View File

@ -0,0 +1,4 @@
#include "config.h"
#undef WIDECHAR
#define NARROWCHAR
#include "./tokenizer.c"

51
local/vi.h Normal file
View File

@ -0,0 +1,51 @@
/* Automatically generated file, do not edit */
#ifndef _h_vi_c
#define _h_vi_c
protected el_action_t vi_paste_next (EditLine *, Int);
protected el_action_t vi_paste_prev (EditLine *, Int);
protected el_action_t vi_prev_big_word (EditLine *, Int);
protected el_action_t vi_prev_word (EditLine *, Int);
protected el_action_t vi_next_big_word (EditLine *, Int);
protected el_action_t vi_next_word (EditLine *, Int);
protected el_action_t vi_change_case (EditLine *, Int);
protected el_action_t vi_change_meta (EditLine *, Int);
protected el_action_t vi_insert_at_bol (EditLine *, Int);
protected el_action_t vi_replace_char (EditLine *, Int);
protected el_action_t vi_replace_mode (EditLine *, Int);
protected el_action_t vi_substitute_char (EditLine *, Int);
protected el_action_t vi_substitute_line (EditLine *, Int);
protected el_action_t vi_change_to_eol (EditLine *, Int);
protected el_action_t vi_insert (EditLine *, Int);
protected el_action_t vi_add (EditLine *, Int);
protected el_action_t vi_add_at_eol (EditLine *, Int);
protected el_action_t vi_delete_meta (EditLine *, Int);
protected el_action_t vi_end_big_word (EditLine *, Int);
protected el_action_t vi_end_word (EditLine *, Int);
protected el_action_t vi_undo (EditLine *, Int);
protected el_action_t vi_command_mode (EditLine *, Int);
protected el_action_t vi_zero (EditLine *, Int);
protected el_action_t vi_delete_prev_char (EditLine *, Int);
protected el_action_t vi_list_or_eof (EditLine *, Int);
protected el_action_t vi_kill_line_prev (EditLine *, Int);
protected el_action_t vi_search_prev (EditLine *, Int);
protected el_action_t vi_search_next (EditLine *, Int);
protected el_action_t vi_repeat_search_next (EditLine *, Int);
protected el_action_t vi_repeat_search_prev (EditLine *, Int);
protected el_action_t vi_next_char (EditLine *, Int);
protected el_action_t vi_prev_char (EditLine *, Int);
protected el_action_t vi_to_next_char (EditLine *, Int);
protected el_action_t vi_to_prev_char (EditLine *, Int);
protected el_action_t vi_repeat_next_char (EditLine *, Int);
protected el_action_t vi_repeat_prev_char (EditLine *, Int);
protected el_action_t vi_match (EditLine *, Int);
protected el_action_t vi_undo_line (EditLine *, Int);
protected el_action_t vi_to_column (EditLine *, Int);
protected el_action_t vi_yank_end (EditLine *, Int);
protected el_action_t vi_yank (EditLine *, Int);
protected el_action_t vi_comment_out (EditLine *, Int);
protected el_action_t vi_alias (EditLine *, Int);
protected el_action_t vi_to_history_line (EditLine *, Int);
protected el_action_t vi_histedit (EditLine *, Int);
protected el_action_t vi_history_word (EditLine *, Int);
protected el_action_t vi_redo (EditLine *, Int);
#endif /* _h_vi_c */

57
src/Makefile.am Normal file
View File

@ -0,0 +1,57 @@
BUILT_SOURCES = vi.h emacs.h common.h fcns.h help.h fcns.c help.c
if WIDECHAR
BUILT_SOURCES += tokenizern.c historyn.c
endif
AHDR= vi.h emacs.h common.h
ASRC= $(srcdir)/vi.c $(srcdir)/emacs.c $(srcdir)/common.c
vi.h: Makefile $(srcdir)/vi.c
AWK=$(AWK) sh $(srcdir)/makelist -h $(srcdir)/vi.c > $@
emacs.h: Makefile $(srcdir)/emacs.c
AWK=$(AWK) sh $(srcdir)/makelist -h $(srcdir)/emacs.c > $@
common.h: Makefile $(srcdir)/common.c
AWK=$(AWK) sh $(srcdir)/makelist -h $(srcdir)/common.c > $@
fcns.h: Makefile $(AHDR)
AWK=$(AWK) sh $(srcdir)/makelist -fh $(AHDR) > $@
help.h: Makefile $(ASRC)
AWK=$(AWK) sh $(srcdir)/makelist -bh $(ASRC) > $@
fcns.c: Makefile $(AHDR)
AWK=$(AWK) sh $(srcdir)/makelist -fc $(AHDR) > $@
help.c: Makefile $(ASRC)
AWK=$(AWK) sh $(srcdir)/makelist -bc $(ASRC) > $@
tokenizern.c: Makefile $(srcdir)/tokenizer.c
AWK=$(AWK) sh $(srcdir)/makelist -n $(srcdir)/tokenizer.c > $@
historyn.c: Makefile $(srcdir)/history.c
AWK=$(AWK) sh $(srcdir)/makelist -n $(srcdir)/history.c > $@
CLEANFILES = $(BUILT_SOURCES)
lib_LTLIBRARIES = libedit.la
libedit_la_SOURCES = chared.c common.c el.c emacs.c hist.c keymacro.c map.c chartype.c parse.c \
prompt.c read.c refresh.c search.c sig.c terminal.c tty.c vi.c \
fgetln.c strlcat.c strlcpy.c unvis.c vis.c wcsdup.c tokenizer.c \
history.c filecomplete.c readline.c chared.h el.h hist.h \
histedit.h keymacro.h map.h chartype.h parse.h prompt.h read.h refresh.h \
search.h sig.h sys.h terminal.h tty.h vis.h filecomplete.h \
editline/readline.h
if WIDECHAR
libedit_la_SOURCES += eln.c
endif
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)

724
src/Makefile.in Normal file
View File

@ -0,0 +1,724 @@
# Makefile.in generated by automake 1.12.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2012 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@
VPATH = @srcdir@
am__make_dryrun = \
{ \
am__dry=no; \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
echo 'am--echo: ; @echo "AM" OK' | $(MAKE) -f - 2>/dev/null \
| grep '^AM OK$$' >/dev/null || am__dry=yes;; \
*) \
for am__flg in $$MAKEFLAGS; do \
case $$am__flg in \
*=*|--*) ;; \
*n*) am__dry=yes; break;; \
esac; \
done;; \
esac; \
test $$am__dry = yes; \
}
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
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@
@WIDECHAR_TRUE@am__append_1 = tokenizern.c historyn.c
@WIDECHAR_TRUE@am__append_2 = eln.c
subdir = src
DIST_COMMON = $(nobase_include_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(top_srcdir)/depcomp
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \
$(top_srcdir)/m4/ltoptions.m4 $(top_srcdir)/m4/ltsugar.m4 \
$(top_srcdir)/m4/ltversion.m4 $(top_srcdir)/m4/lt~obsolete.m4 \
$(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
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 = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libedit_la_LIBADD =
am__libedit_la_SOURCES_DIST = chared.c common.c el.c emacs.c hist.c \
keymacro.c map.c chartype.c parse.c prompt.c read.c refresh.c \
search.c sig.c terminal.c tty.c vi.c fgetln.c strlcat.c \
strlcpy.c unvis.c vis.c wcsdup.c tokenizer.c history.c \
filecomplete.c readline.c chared.h el.h hist.h histedit.h \
keymacro.h map.h chartype.h parse.h prompt.h read.h refresh.h \
search.h sig.h sys.h terminal.h tty.h vis.h filecomplete.h \
editline/readline.h eln.c
@WIDECHAR_TRUE@am__objects_1 = eln.lo
am_libedit_la_OBJECTS = chared.lo common.lo el.lo emacs.lo hist.lo \
keymacro.lo map.lo chartype.lo parse.lo prompt.lo read.lo \
refresh.lo search.lo sig.lo terminal.lo tty.lo vi.lo fgetln.lo \
strlcat.lo strlcpy.lo unvis.lo vis.lo wcsdup.lo tokenizer.lo \
history.lo filecomplete.lo readline.lo $(am__objects_1)
@WIDECHAR_TRUE@am__objects_2 = tokenizern.lo historyn.lo
am__objects_3 = fcns.lo help.lo $(am__objects_2)
nodist_libedit_la_OBJECTS = $(am__objects_3)
libedit_la_OBJECTS = $(am_libedit_la_OBJECTS) \
$(nodist_libedit_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libedit_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(libedit_la_LDFLAGS) $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libedit_la_SOURCES) $(nodist_libedit_la_SOURCES)
DIST_SOURCES = $(am__libedit_la_SOURCES_DIST)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
HEADERS = $(nobase_include_HEADERS)
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
LT_VERSION = @LT_VERSION@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MANTYPE = @MANTYPE@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
NROFF = @NROFF@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
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@
builddir = @builddir@
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@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
BUILT_SOURCES = vi.h emacs.h common.h fcns.h help.h fcns.c help.c \
$(am__append_1)
AHDR = vi.h emacs.h common.h
ASRC = $(srcdir)/vi.c $(srcdir)/emacs.c $(srcdir)/common.c
CLEANFILES = $(BUILT_SOURCES)
lib_LTLIBRARIES = libedit.la
libedit_la_SOURCES = chared.c common.c el.c emacs.c hist.c keymacro.c \
map.c chartype.c parse.c prompt.c read.c refresh.c search.c \
sig.c terminal.c tty.c vi.c fgetln.c strlcat.c strlcpy.c \
unvis.c vis.c wcsdup.c tokenizer.c history.c filecomplete.c \
readline.c chared.h el.h hist.h histedit.h keymacro.h map.h \
chartype.h parse.h prompt.h read.h refresh.h search.h sig.h \
sys.h terminal.h tty.h vis.h filecomplete.h \
editline/readline.h $(am__append_2)
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)
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .c .lo .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libedit.la: $(libedit_la_OBJECTS) $(libedit_la_DEPENDENCIES) $(EXTRA_libedit_la_DEPENDENCIES)
$(AM_V_CCLD)$(libedit_la_LINK) -rpath $(libdir) $(libedit_la_OBJECTS) $(libedit_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chared.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/chartype.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/el.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eln.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/emacs.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fcns.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fgetln.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/filecomplete.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/help.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hist.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/history.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/historyn.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keymacro.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parse.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prompt.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/readline.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/refresh.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/search.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sig.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strlcat.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/strlcpy.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/terminal.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tokenizer.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tokenizern.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tty.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unvis.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vi.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/vis.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/wcsdup.Plo@am__quote@
.c.o:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c `$(CYGPATH_W) '$<'`
.c.lo:
@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-nobase_includeHEADERS: $(nobase_include_HEADERS)
@$(NORMAL_INSTALL)
@list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(includedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(includedir)" || exit 1; \
fi; \
$(am__nobase_list) | while read dir files; do \
xfiles=; for file in $$files; do \
if test -f "$$file"; then xfiles="$$xfiles $$file"; \
else xfiles="$$xfiles $(srcdir)/$$file"; fi; done; \
test -z "$$xfiles" || { \
test "x$$dir" = x. || { \
echo " $(MKDIR_P) '$(DESTDIR)$(includedir)/$$dir'"; \
$(MKDIR_P) "$(DESTDIR)$(includedir)/$$dir"; }; \
echo " $(INSTALL_HEADER) $$xfiles '$(DESTDIR)$(includedir)/$$dir'"; \
$(INSTALL_HEADER) $$xfiles "$(DESTDIR)$(includedir)/$$dir" || exit $$?; }; \
done
uninstall-nobase_includeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(nobase_include_HEADERS)'; test -n "$(includedir)" || list=; \
$(am__nobase_strip_setup); files=`$(am__nobase_strip)`; \
dir='$(DESTDIR)$(includedir)'; $(am__uninstall_files_from_dir)
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; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
set x; \
here=`pwd`; \
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; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: CTAGS
CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
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; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: $(HEADERS) $(SOURCES) $(LISP)
list='$(SOURCES) $(HEADERS) $(LISP)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(includedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-nobase_includeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libLTLIBRARIES uninstall-nobase_includeHEADERS
.MAKE: all check install install-am install-strip
.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool cscopelist ctags distclean \
distclean-compile distclean-generic distclean-libtool \
distclean-tags distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-dvi \
install-dvi-am install-exec install-exec-am install-html \
install-html-am install-info install-info-am \
install-libLTLIBRARIES install-man \
install-nobase_includeHEADERS install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags uninstall uninstall-am uninstall-libLTLIBRARIES \
uninstall-nobase_includeHEADERS
vi.h: Makefile $(srcdir)/vi.c
AWK=$(AWK) sh $(srcdir)/makelist -h $(srcdir)/vi.c > $@
emacs.h: Makefile $(srcdir)/emacs.c
AWK=$(AWK) sh $(srcdir)/makelist -h $(srcdir)/emacs.c > $@
common.h: Makefile $(srcdir)/common.c
AWK=$(AWK) sh $(srcdir)/makelist -h $(srcdir)/common.c > $@
fcns.h: Makefile $(AHDR)
AWK=$(AWK) sh $(srcdir)/makelist -fh $(AHDR) > $@
help.h: Makefile $(ASRC)
AWK=$(AWK) sh $(srcdir)/makelist -bh $(ASRC) > $@
fcns.c: Makefile $(AHDR)
AWK=$(AWK) sh $(srcdir)/makelist -fc $(AHDR) > $@
help.c: Makefile $(ASRC)
AWK=$(AWK) sh $(srcdir)/makelist -bc $(ASRC) > $@
tokenizern.c: Makefile $(srcdir)/tokenizer.c
AWK=$(AWK) sh $(srcdir)/makelist -n $(srcdir)/tokenizer.c > $@
historyn.c: Makefile $(srcdir)/history.c
AWK=$(AWK) sh $(srcdir)/makelist -n $(srcdir)/history.c > $@
# 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:

740
src/chared.c Normal file
View File

@ -0,0 +1,740 @@
/* $NetBSD: chared.c,v 1.37 2012/07/18 17:12: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[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: chared.c,v 1.37 2012/07/18 17:12:39 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/*
* chared.c: Character editor utilities
*/
#include <stdlib.h>
#include "el.h"
private void ch__clearmacro (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;
size_t size;
/* Save entire line for undo */
size = (size_t)(el->el_line.lastchar - el->el_line.buffer);
vu->len = (ssize_t)size;
vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer);
(void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf));
/* 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;
(void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf));
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, (size_t)num))
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 = (int)(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 = (int)(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(STR("*?_-.[]~="), 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)(*p))
p--;
while ((p >= low) && (*wtest)(*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)(*p))
p++;
while ((p < high) && (*wtest)(*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)(*p);
while ((p < high) && (*wtest)(*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(*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(*p))
p--;
test = (*wtest)(*p);
while ((p >= low) && (*wtest)(*p) == test)
p--;
}
p++;
/* p now points where we want it */
if (p < low)
return low;
else
return p;
}
/* 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 = (int)(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;
}
/* 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(*p))
p++;
test = (*wtest)(*p);
while ((p < high) && (*wtest)(*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 = el_malloc(EL_BUFSIZ *
sizeof(*el->el_line.buffer));
if (el->el_line.buffer == NULL)
return -1;
(void) memset(el->el_line.buffer, 0, EL_BUFSIZ *
sizeof(*el->el_line.buffer));
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 = el_malloc(EL_BUFSIZ *
sizeof(*el->el_chared.c_undo.buf));
if (el->el_chared.c_undo.buf == NULL)
return -1;
(void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ *
sizeof(*el->el_chared.c_undo.buf));
el->el_chared.c_undo.len = -1;
el->el_chared.c_undo.cursor = 0;
el->el_chared.c_redo.buf = el_malloc(EL_BUFSIZ *
sizeof(*el->el_chared.c_redo.buf));
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 = el_malloc(EL_BUFSIZ *
sizeof(*el->el_chared.c_kill.buf));
if (el->el_chared.c_kill.buf == NULL)
return -1;
(void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ *
sizeof(*el->el_chared.c_kill.buf));
el->el_chared.c_kill.mark = el->el_line.buffer;
el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
el->el_chared.c_resizefun = NULL;
el->el_chared.c_resizearg = NULL;
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 = el_malloc(EL_MAXMACRO * sizeof(*ma->macro));
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(EditLine *el)
{
c_macro_t *ma = &el->el_chared.c_macro;
while (ma->level >= 0)
el_free(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(EditLine *el, size_t addlen)
{
size_t sz, newsz;
Char *newbuffer, *oldbuf, *oldkbuf;
sz = (size_t)(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 * sizeof(*newbuffer));
if (!newbuffer)
return 0;
/* zero the newly added memory, leave old data in */
(void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
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 *
sizeof(*newbuffer));
if (!newbuffer)
return 0;
/* zero the newly added memory, leave old data in */
(void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
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 * sizeof(*newbuffer));
if (!newbuffer)
return 0;
/* zero the newly added memory, leave old data in */
(void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
el->el_chared.c_undo.buf = newbuffer;
newbuffer = el_realloc(el->el_chared.c_redo.buf,
newsz * sizeof(*newbuffer));
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];
if (el->el_chared.c_resizefun)
(*el->el_chared.c_resizefun)(el, el->el_chared.c_resizearg);
return 1;
}
/* ch_end():
* Free the data structures used by the editor
*/
protected void
ch_end(EditLine *el)
{
el_free(el->el_line.buffer);
el->el_line.buffer = NULL;
el->el_line.limit = NULL;
el_free(el->el_chared.c_undo.buf);
el->el_chared.c_undo.buf = NULL;
el_free(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(el->el_chared.c_kill.buf);
el->el_chared.c_kill.buf = NULL;
ch_reset(el, 1);
el_free(el->el_chared.c_macro.macro);
el->el_chared.c_macro.macro = NULL;
}
/* el_insertstr():
* Insert string at cursorI
*/
public int
FUN(el,insertstr)(EditLine *el, const Char *s)
{
size_t len;
if (s == NULL || (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;
ssize_t len;
Char *cp = el->el_line.buffer;
if (prompt) {
len = (ssize_t)Strlen(prompt);
(void)memcpy(cp, prompt, (size_t)len * sizeof(*cp));
cp += len;
}
len = 0;
for (;;) {
el->el_line.cursor = cp;
*cp = ' ';
el->el_line.lastchar = cp + 1;
re_refresh(el);
if (FUN(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 >= (ssize_t)(EL_BUFSIZ - 16))
terminal_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 (int)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 (int)(el->el_line.cursor - ptr - 1);
}
}
protected int
ch_resizefun(EditLine *el, el_zfunc_t f, void *a)
{
el->el_chared.c_resizefun = f;
el->el_chared.c_resizearg = a;
return 0;
}

178
src/chared.h Normal file
View File

@ -0,0 +1,178 @@
/* $NetBSD: chared.h,v 1.21 2010/08/28 15:44:59 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 {
ssize_t 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 */
/*
* 8519376: Use an unnamed union to force the size of c_redo_t to
* be the same, independent of the size of Char.
*/
union {
Char ch; /* char that invoked it */
wchar_t dummy;
};
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;
typedef void (*el_zfunc_t)(EditLine *, void *);
/*
* 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_zfunc_t c_resizefun;
void * c_resizearg;
} el_chared_t;
#define STRQQ "\"\""
#define isglob(a) (strchr("*[]?", (a)) != NULL)
#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_resizefun(EditLine *, el_zfunc_t, void *);
protected int ch_enlargebufs(EditLine *, size_t);
protected void ch_end(EditLine *);
#endif /* _h_el_chared */

359
src/chartype.c Normal file
View File

@ -0,0 +1,359 @@
/* $NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $ */
/*-
* Copyright (c) 2009 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. 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.
*/
/*
* chartype.c: character classification and meta information
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $");
#endif /* not lint && not SCCSID */
#include "el.h"
#include <stdlib.h>
#define CT_BUFSIZ ((size_t)1024)
#ifdef WIDECHAR
protected void
ct_conv_buff_resize(ct_buffer_t *conv, size_t mincsize, size_t minwsize)
{
void *p;
if (mincsize > conv->csize) {
conv->csize = mincsize;
p = el_realloc(conv->cbuff, conv->csize * sizeof(*conv->cbuff));
if (p == NULL) {
conv->csize = 0;
el_free(conv->cbuff);
conv->cbuff = NULL;
} else
conv->cbuff = p;
}
if (minwsize > conv->wsize) {
conv->wsize = minwsize;
p = el_realloc(conv->wbuff, conv->wsize * sizeof(*conv->wbuff));
if (p == NULL) {
conv->wsize = 0;
el_free(conv->wbuff);
conv->wbuff = NULL;
} else
conv->wbuff = p;
}
}
public char *
ct_encode_string(const Char *s, ct_buffer_t *conv)
{
char *dst;
ssize_t used = 0;
if (!s)
return NULL;
if (!conv->cbuff)
ct_conv_buff_resize(conv, CT_BUFSIZ, (size_t)0);
if (!conv->cbuff)
return NULL;
dst = conv->cbuff;
while (*s) {
used = (ssize_t)(conv->csize - (size_t)(dst - conv->cbuff));
if (used < 5) {
used = dst - conv->cbuff;
ct_conv_buff_resize(conv, conv->csize + CT_BUFSIZ,
(size_t)0);
if (!conv->cbuff)
return NULL;
dst = conv->cbuff + used;
}
used = ct_encode_char(dst, (size_t)5, *s);
if (used == -1) /* failed to encode, need more buffer space */
abort();
++s;
dst += used;
}
*dst = '\0';
return conv->cbuff;
}
public Char *
ct_decode_string(const char *s, ct_buffer_t *conv)
{
size_t len = 0;
if (!s)
return NULL;
if (!conv->wbuff)
ct_conv_buff_resize(conv, (size_t)0, CT_BUFSIZ);
if (!conv->wbuff)
return NULL;
len = ct_mbstowcs(NULL, s, (size_t)0);
if (len == (size_t)-1)
return NULL;
if (len > conv->wsize)
ct_conv_buff_resize(conv, (size_t)0, len + 1);
if (!conv->wbuff)
return NULL;
ct_mbstowcs(conv->wbuff, s, conv->wsize);
return conv->wbuff;
}
protected Char **
ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
{
size_t bufspace;
int i;
Char *p;
Char **wargv;
ssize_t bytes;
/* Make sure we have enough space in the conversion buffer to store all
* the argv strings. */
for (i = 0, bufspace = 0; i < argc; ++i)
bufspace += argv[i] ? strlen(argv[i]) + 1 : 0;
ct_conv_buff_resize(conv, (size_t)0, bufspace);
if (!conv->wsize)
return NULL;
// radar:20968385 map_bind reads beyond the array
wargv = el_malloc((size_t)(argc + 1) * sizeof(*wargv));
wargv[argc] = NULL;
for (i = 0, p = conv->wbuff; i < argc; ++i) {
if (!argv[i]) { /* don't pass null pointers to mbstowcs */
wargv[i] = NULL;
continue;
} else {
wargv[i] = p;
bytes = (ssize_t)mbstowcs(p, argv[i], bufspace);
}
if (bytes == -1) {
el_free(wargv);
return NULL;
} else
bytes++; /* include '\0' in the count */
bufspace -= (size_t)bytes;
p += bytes;
}
return wargv;
}
protected size_t
ct_enc_width(Char c)
{
/* UTF-8 encoding specific values */
if (c < 0x80)
return 1;
else if (c < 0x0800)
return 2;
else if (c < 0x10000)
return 3;
else if (c < 0x110000)
return 4;
else
return 0; /* not a valid codepoint */
}
protected ssize_t
ct_encode_char(char *dst, size_t len, Char c)
{
ssize_t l = 0;
if (len < ct_enc_width(c))
return -1;
l = ct_wctomb(dst, c);
if (l < 0) {
ct_wctomb_reset;
l = 0;
}
return l;
}
#endif
protected const Char *
ct_visual_string(const Char *s)
{
static Char *buff = NULL;
static size_t buffsize = 0;
void *p;
Char *dst;
ssize_t used = 0;
if (!s)
return NULL;
if (!buff) {
buffsize = CT_BUFSIZ;
buff = el_malloc(buffsize * sizeof(*buff));
}
dst = buff;
while (*s) {
used = ct_visual_char(dst, buffsize - (size_t)(dst - buff), *s);
if (used == -1) { /* failed to encode, need more buffer space */
used = dst - buff;
buffsize += CT_BUFSIZ;
p = el_realloc(buff, buffsize * sizeof(*buff));
if (p == NULL)
goto out;
buff = p;
dst = buff + used;
/* don't increment s here - we want to retry it! */
continue;
}
else
++s;
dst += used;
}
if (dst >= (buff + buffsize)) { /* sigh */
buffsize += 1;
p = el_realloc(buff, buffsize * sizeof(*buff));
if (p == NULL)
goto out;
buff = p;
dst = buff + buffsize - 1;
}
*dst = 0;
return buff;
out:
el_free(buff);
buffsize = 0;
return NULL;
}
protected int
ct_visual_width(Char c)
{
int t = ct_chr_class(c);
switch (t) {
case CHTYPE_ASCIICTL:
return 2; /* ^@ ^? etc. */
case CHTYPE_TAB:
return 1; /* Hmm, this really need to be handled outside! */
case CHTYPE_NL:
return 0; /* Should this be 1 instead? */
#ifdef WIDECHAR
case CHTYPE_PRINT:
return wcwidth(c);
case CHTYPE_NONPRINT:
if (c > 0xffff) /* prefer standard 4-byte display over 5-byte */
return 8; /* \U+12345 */
else
return 7; /* \U+1234 */
#else
case CHTYPE_PRINT:
return 1;
case CHTYPE_NONPRINT:
return 4; /* \123 */
#endif
default:
return 0; /* should not happen */
}
}
protected ssize_t
ct_visual_char(Char *dst, size_t len, Char c)
{
int t = ct_chr_class(c);
switch (t) {
case CHTYPE_TAB:
case CHTYPE_NL:
case CHTYPE_ASCIICTL:
if (len < 2)
return -1; /* insufficient space */
*dst++ = '^';
if (c == '\177')
*dst = '?'; /* DEL -> ^? */
else
*dst = c | 0100; /* uncontrolify it */
return 2;
case CHTYPE_PRINT:
if (len < 1)
return -1; /* insufficient space */
*dst = c;
return 1;
case CHTYPE_NONPRINT:
/* we only use single-width glyphs for display,
* so this is right */
if ((ssize_t)len < ct_visual_width(c))
return -1; /* insufficient space */
#ifdef WIDECHAR
*dst++ = '\\';
*dst++ = 'U';
*dst++ = '+';
#define tohexdigit(v) "0123456789ABCDEF"[v]
if (c > 0xffff) /* prefer standard 4-byte display over 5-byte */
*dst++ = tohexdigit(((unsigned int) c >> 16) & 0xf);
*dst++ = tohexdigit(((unsigned int) c >> 12) & 0xf);
*dst++ = tohexdigit(((unsigned int) c >> 8) & 0xf);
*dst++ = tohexdigit(((unsigned int) c >> 4) & 0xf);
*dst = tohexdigit(((unsigned int) c ) & 0xf);
return c > 0xffff ? 8 : 7;
#else
*dst++ = '\\';
#define tooctaldigit(v) ((v) + '0')
*dst++ = tooctaldigit(((unsigned int) c >> 6) & 0x7);
*dst++ = tooctaldigit(((unsigned int) c >> 3) & 0x7);
*dst++ = tooctaldigit(((unsigned int) c ) & 0x7);
#endif
/*FALLTHROUGH*/
/* these two should be handled outside this function */
default: /* we should never hit the default */
return 0;
}
}
protected int
ct_chr_class(Char c)
{
if (c == '\t')
return CHTYPE_TAB;
else if (c == '\n')
return CHTYPE_NL;
else if (IsASCII(c) && Iscntrl(c))
return CHTYPE_ASCIICTL;
else if (Isprint(c))
return CHTYPE_PRINT;
else
return CHTYPE_NONPRINT;
}

254
src/chartype.h Normal file
View File

@ -0,0 +1,254 @@
/* $NetBSD: chartype.h,v 1.10 2011/11/16 01:45:10 christos Exp $ */
/*-
* Copyright (c) 2009 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. 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 _h_chartype_f
#define _h_chartype_f
#ifdef WIDECHAR
/* Ideally we should also test the value of the define to see if it
* supports non-BMP code points without requiring UTF-16, but nothing
* seems to actually advertise this properly, despite Unicode 3.1 having
* been around since 2001... */
#if !defined(__NetBSD__) && !defined(__sun) && !(defined(__APPLE__) && defined(__MACH__))
#ifndef __STDC_ISO_10646__
/* In many places it is assumed that the first 127 code points are ASCII
* compatible, so ensure wchar_t indeed does ISO 10646 and not some other
* funky encoding that could break us in weird and wonderful ways. */
#error wchar_t must store ISO 10646 characters
#endif
#endif
/* Oh for a <uchar.h> with char32_t and __STDC_UTF_32__ in it...
* ref: ISO/IEC DTR 19769
*/
#if WCHAR_MAX < INT32_MAX
#warning Build environment does not support non-BMP characters
#endif
#ifndef HAVE_WCSDUP
wchar_t *wcsdup(const wchar_t *s);
#endif
#define ct_mbtowc mbtowc
#define ct_mbtowc_reset mbtowc(0,0,(size_t)0)
#define ct_wctomb wctomb
#define ct_wctomb_reset wctomb(0,0)
#define ct_wcstombs wcstombs
#define ct_mbstowcs mbstowcs
#define Char wchar_t
#define Int wint_t
#define FUN(prefix,rest) prefix ## _w ## rest
#define FUNW(type) type ## _w
#define TYPE(type) type ## W
#define FSTR "%ls"
#define STR(x) L ## x
#define UC(c) c
#define Isalpha(x) iswalpha(x)
#define Isalnum(x) iswalnum(x)
#define Isgraph(x) iswgraph(x)
#define Isspace(x) iswspace(x)
#define Isdigit(x) iswdigit(x)
#define Iscntrl(x) iswcntrl(x)
#define Isprint(x) iswprint(x)
#define Isupper(x) iswupper(x)
#define Islower(x) iswlower(x)
#define Toupper(x) towupper(x)
#define Tolower(x) towlower(x)
#define IsASCII(x) (x < 0x100)
#define Strlen(x) wcslen(x)
#define Strchr(s,c) wcschr(s,c)
#define Strrchr(s,c) wcsrchr(s,c)
#define Strstr(s,v) wcsstr(s,v)
#define Strdup(x) wcsdup(x)
#define Strcpy(d,s) wcscpy(d,s)
#define Strncpy(d,s,n) wcsncpy(d,s,n)
#define Strncat(d,s,n) wcsncat(d,s,n)
#define Strcmp(s,v) wcscmp(s,v)
#define Strncmp(s,v,n) wcsncmp(s,v,n)
#define Strcspn(s,r) wcscspn(s,r)
#define Strtol(p,e,b) wcstol(p,e,b)
static inline int
Width(wchar_t c)
{
int w = wcwidth(c);
return w > 0 ? w : 1;
}
#else /* NARROW */
#define ct_mbtowc error
#define ct_mbtowc_reset
#define ct_wctomb error
#define ct_wctomb_reset
#define ct_wcstombs(a, b, c) (strncpy(a, b, c), strlen(a))
#define ct_mbstowcs(a, b, c) (strncpy(a, b, c), strlen(a))
#define Char char
#define Int int
#define FUN(prefix,rest) prefix ## _ ## rest
#define FUNW(type) type
#define TYPE(type) type
#define FSTR "%s"
#define STR(x) x
#define UC(c) (unsigned char)(c)
#define Isalpha(x) isalpha((unsigned char)x)
#define Isalnum(x) isalnum((unsigned char)x)
#define Isgraph(x) isgraph((unsigned char)x)
#define Isspace(x) isspace((unsigned char)x)
#define Isdigit(x) isdigit((unsigned char)x)
#define Iscntrl(x) iscntrl((unsigned char)x)
#define Isprint(x) isprint((unsigned char)x)
#define Isupper(x) isupper((unsigned char)x)
#define Islower(x) islower((unsigned char)x)
#define Toupper(x) toupper((unsigned char)x)
#define Tolower(x) tolower((unsigned char)x)
#define IsASCII(x) isascii((unsigned char)x)
#define Strlen(x) strlen(x)
#define Strchr(s,c) strchr(s,c)
#define Strrchr(s,c) strrchr(s,c)
#define Strstr(s,v) strstr(s,v)
#define Strdup(x) strdup(x)
#define Strcpy(d,s) strcpy(d,s)
#define Strncpy(d,s,n) strncpy(d,s,n)
#define Strncat(d,s,n) strncat(d,s,n)
#define Strcmp(s,v) strcmp(s,v)
#define Strncmp(s,v,n) strncmp(s,v,n)
#define Strcspn(s,r) strcspn(s,r)
#define Strtol(p,e,b) strtol(p,e,b)
#define Width(c) 1
#endif
#ifdef WIDECHAR
/*
* Conversion buffer
*/
typedef struct ct_buffer_t {
char *cbuff;
size_t csize;
Char *wbuff;
size_t wsize;
} ct_buffer_t;
#define ct_encode_string __ct_encode_string
/* Encode a wide-character string and return the UTF-8 encoded result. */
public char *ct_encode_string(const Char *, ct_buffer_t *);
#define ct_decode_string __ct_decode_string
/* Decode a (multi)?byte string and return the wide-character string result. */
public Char *ct_decode_string(const char *, ct_buffer_t *);
/* Decode a (multi)?byte argv string array.
* The pointer returned must be free()d when done. */
protected Char **ct_decode_argv(int, const char *[], ct_buffer_t *);
/* Resizes the conversion buffer(s) if needed. */
protected void ct_conv_buff_resize(ct_buffer_t *, size_t, size_t);
protected ssize_t ct_encode_char(char *, size_t, Char);
protected size_t ct_enc_width(Char);
#define ct_free_argv(s) el_free(s)
#else
#define ct_encode_string(s, b) (s)
#define ct_decode_string(s, b) (s)
#define ct_decode_argv(l, s, b) (s)
#define ct_conv_buff_resize(b, os, ns)
#define ct_encode_char(d, l, s) (*d = s, 1)
#define ct_free_argv(s)
#endif
#ifndef NARROWCHAR
/* Encode a characted into the destination buffer, provided there is sufficent
* buffer space available. Returns the number of bytes used up (zero if the
* character cannot be encoded, -1 if there was not enough space available). */
/* The maximum buffer size to hold the most unwieldly visual representation,
* in this case \U+nnnnn. */
#define VISUAL_WIDTH_MAX ((size_t)8)
/* The terminal is thought of in terms of X columns by Y lines. In the cases
* where a wide character takes up more than one column, the adjacent
* occupied column entries will contain this faux character. */
#define MB_FILL_CHAR ((Char)-1)
/* Visual width of character c, taking into account ^? , \0177 and \U+nnnnn
* style visual expansions. */
protected int ct_visual_width(Char);
/* Turn the given character into the appropriate visual format, matching
* the width given by ct_visual_width(). Returns the number of characters used
* up, or -1 if insufficient space. Buffer length is in count of Char's. */
protected ssize_t ct_visual_char(Char *, size_t, Char);
/* Convert the given string into visual format, using the ct_visual_char()
* function. Uses a static buffer, so not threadsafe. */
protected const Char *ct_visual_string(const Char *);
/* printable character, use ct_visual_width() to find out display width */
#define CHTYPE_PRINT ( 0)
/* control character found inside the ASCII portion of the charset */
#define CHTYPE_ASCIICTL (-1)
/* a \t */
#define CHTYPE_TAB (-2)
/* a \n */
#define CHTYPE_NL (-3)
/* non-printable character */
#define CHTYPE_NONPRINT (-4)
/* classification of character c, as one of the above defines */
protected int ct_chr_class(Char c);
#endif
#endif /* _chartype_f */

919
src/common.c Normal file
View File

@ -0,0 +1,919 @@
/* $NetBSD: common.c,v 1.29 2012/03/24 20:08:43 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.29 2012/03/24 20:08:43 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, (int)(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 __attribute__((__unused__)))
{
#ifdef DEBUG_EDIT
#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 */
terminal_writec(el, c);
return CC_EOF;
#endif
} else {
#ifdef KSHVI
el->el_line.cursor--;
#else
return CC_ERROR;
#endif
}
} else
return CC_ERROR;
}
c_delafter(el, el->el_state.argument); /* delete after dot */
if (el->el_map.type == MAP_VI &&
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) {
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return CC_REFRESH;
}
#ifdef VI_MOVE
el->el_line.cursor--;
#endif
}
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(*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 = FUN(el,getc)(el, &tc);
c = 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 __attribute__((__unused__)),
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__)))
{
terminal_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;
}
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, STR("\n: "));
terminal__putc(el, '\n');
if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
terminal_beep(el);
el->el_map.current = el->el_map.key;
re_clear_display(el);
return CC_REFRESH;
}

222
src/editline/readline.h Normal file
View File

@ -0,0 +1,222 @@
/* $NetBSD: readline.h,v 1.33 2012/05/15 17:30:04 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.
*
* 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>
#include <stdio.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 int rl_command_func_t(int, int);
/* only supports length */
typedef struct {
int length;
} HISTORY_STATE;
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>
#if !defined(__sun) && !defined(__hpux) && !defined(_AIX)
#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')
#define RL_READLINE_VERSION 0x0402
#define RL_PROMPT_START_IGNORE '\1'
#define RL_PROMPT_END_IGNORE '\2'
/* global variables used by readline enabled applications */
#ifdef __cplusplus
extern "C" {
#endif
extern const char *rl_library_version;
extern int rl_readline_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 char *(*rl_completion_word_break_hook)(void);
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);
HIST_ENTRY *replace_history_entry(int, const char *, histdata_t);
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_truncate_file (const char *, int);
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);
int rl_insert_text(const char *);
void rl_reset_terminal(const char *);
int rl_bind_key(int, rl_command_func_t *);
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);
HISTORY_STATE *history_get_history_state(void);
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 *);
void rl_forced_update_display(void);
int rl_set_prompt(const char *);
int rl_on_new_line(void);
/*
* 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, rl_command_func_t *, Keymap);
void rl_cleanup_after_signal(void);
void rl_free_line_state(void);
#ifdef __cplusplus
}
#endif
#endif /* _READLINE_H_ */

623
src/el.c Normal file
View File

@ -0,0 +1,623 @@
/* $NetBSD: el.c,v 1.71 2012/09/11 11:58:53 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.71 2012/09/11 11:58:53 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
#ifndef MAXPATHLEN
#define MAXPATHLEN 4096
#endif
/*
* el.c: EditLine interface functions
*/
#include <sys/types.h>
#include <sys/param.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <locale.h>
#include <langinfo.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 = el_malloc(sizeof(*el));
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);
el->el_outfd = fileno(fout);
el->el_errfd = fileno(ferr);
el->el_prog = Strdup(ct_decode_string(prog, &el->el_scratch));
if (el->el_prog == NULL) {
el_free(el);
return NULL;
}
/*
* Initialize all the modules. Order is important!!!
*/
el->el_flags = 0;
#ifdef WIDECHAR
char *loc = setlocale(LC_CTYPE, NULL);
if (loc != NULL && strcmp(loc, "C") == 0)
loc = setlocale(LC_CTYPE, "");
if (loc != NULL) {
if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
el->el_flags |= CHARSET_IS_UTF8;
}
#endif
if (terminal_init(el) == -1) {
el_free(el->el_prog);
el_free(el);
return NULL;
}
(void) keymacro_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);
terminal_end(el);
keymacro_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(el->el_prog);
#ifdef WIDECHAR
el_free(el->el_scratch.cbuff);
el_free(el->el_scratch.wbuff);
el_free(el->el_lgcyconv.cbuff);
el_free(el->el_lgcyconv.wbuff);
#endif
el_free(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
FUN(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: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
rv = prompt_set(el, p, 0, op, 1);
break;
}
case EL_RESIZE: {
el_zfunc_t p = va_arg(ap, el_zfunc_t);
void *arg = va_arg(ap, void *);
rv = ch_resizefun(el, p, arg);
break;
}
case EL_PROMPT_ESC:
case EL_RPROMPT_ESC: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
int c = va_arg(ap, int);
rv = prompt_set(el, p, c, op, 1);
break;
}
case EL_TERMINAL:
rv = terminal_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_ECHOTC:
case EL_SETTY:
{
const Char *argv[20];
int i;
for (i = 1; i < (int)__arraycount(argv); i++)
if ((argv[i] = va_arg(ap, Char *)) == NULL)
break;
switch (op) {
case EL_BIND:
argv[0] = STR("bind");
rv = map_bind(el, i, argv);
break;
case EL_TELLTC:
argv[0] = STR("telltc");
rv = terminal_telltc(el, i, argv);
break;
case EL_SETTC:
argv[0] = STR("settc");
rv = terminal_settc(el, i, argv);
break;
case EL_ECHOTC:
argv[0] = STR("echotc");
rv = terminal_echotc(el, i, argv);
break;
case EL_SETTY:
argv[0] = STR("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);
void *ptr = va_arg(ap, void *);
rv = hist_set(el, func, ptr);
el->el_flags &= ~NARROW_HISTORY;
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);
el->el_flags &= ~NARROW_READ;
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;
el->el_outfd = fileno(fp);
break;
case 2:
el->el_errfile = fp;
el->el_errfd = fileno(fp);
break;
default:
rv = -1;
break;
}
break;
}
case EL_REFRESH:
re_clear_display(el);
re_refresh(el);
terminal__flush(el);
break;
default:
rv = -1;
break;
}
va_end(ap);
return rv;
}
/* el_get():
* retrieve the editline parameters
*/
public int
FUN(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: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
rv = prompt_get(el, p, 0, op);
break;
}
case EL_PROMPT_ESC:
case EL_RPROMPT_ESC: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
Char *c = va_arg(ap, Char *);
rv = prompt_get(el, p, c, 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:
terminal_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 < (int)__arraycount(argv); i++)
if ((argv[i] = va_arg(ap, char *)) == NULL)
break;
argv[0] = name;
rv = terminal_gettc(el, i, argv);
break;
}
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) != 0;
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 TYPE(LineInfo) *
FUN(el,line)(EditLine *el)
{
return (const TYPE(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;
char *path = NULL;
const Char *dptr;
int error = 0;
fp = NULL;
if (fname == NULL) {
static const char elpath[] = "/.editrc";
size_t plen = sizeof(elpath);
#ifdef HAVE_ISSETUGID
if (issetugid())
return -1;
if ((ptr = getenv("HOME")) == NULL)
return -1;
plen += strlen(ptr);
if ((path = el_malloc(plen * sizeof(*path))) == NULL)
return -1;
(void)snprintf(path, plen, "%s%s", ptr, elpath);
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");
if (fp == NULL) {
el_free(path);
return -1;
}
while ((ptr = fgetln(fp, &len)) != NULL) {
if (*ptr == '\n')
continue; /* Empty line. */
dptr = ct_decode_string(ptr, &el->el_scratch);
if (!dptr)
continue;
if (len > 0 && dptr[len - 1] == '\n')
--len;
/* loop until first non-space char or EOL */
while (*dptr != '\0' && Isspace(*dptr))
dptr++;
if (*dptr == '#')
continue; /* ignore, this is a comment line */
if ((error = parse_line(el, dptr)) == -1)
break;
}
el_free(path);
(void) fclose(fp);
return error;
}
/* 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 (terminal_get_size(el, &lins, &cols))
terminal_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)
{
terminal_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, STR("on")) == 0) {
el->el_flags &= ~EDIT_DISABLED;
tty_rawmode(el);
} else if (Strcmp(how, STR("off")) == 0) {
tty_cookedmode(el);
el->el_flags |= EDIT_DISABLED;
}
else {
(void) fprintf(el->el_errfile, "edit: Bad value `" FSTR "'.\n",
how);
return -1;
}
return 0;
}

170
src/el.h Normal file
View File

@ -0,0 +1,170 @@
/* $NetBSD: el.h,v 1.25 2011/07/29 23:44:44 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 "histedit.h"
#include "chartype.h"
#include <stdio.h>
#include <sys/types.h>
#define EL_BUFSIZ ((size_t)1024) /* Maximum line size */
#define HANDLE_SIGNALS 0x01
#define NO_TTY 0x02
#define EDIT_DISABLED 0x04
#define UNBUFFERED 0x08
#define CHARSET_IS_UTF8 0x10
#define IGNORE_EXTCHARS 0x20 /* Ignore characters read > 0xff */
#define NARROW_HISTORY 0x40
#define NARROW_READ 0x80
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 */
/*
* 8519376: Use an unnamed union to force the size of el_state_t to
* be the same, independent of the size of Char.
*/
union {
Char thisch; /* char that generated it */
wchar_t dummy;
};
} el_state_t;
/*
* Until we come up with something better...
*/
#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 "keymacro.h"
#include "terminal.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_outfd; /* Output file descriptor */
int el_errfd; /* Error file descriptor */
int el_flags; /* Various flags. */
int el_errno; /* Local copy of errno */
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_terminal_t el_terminal; /* 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_keymacro_t el_keymacro; /* 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 */
#ifdef WIDECHAR
ct_buffer_t el_scratch; /* Scratch conversion buffer */
ct_buffer_t el_lgcyconv; /* Buffer for legacy wrappers */
LineInfo el_lgcylinfo; /* Legacy LineInfo buffer */
#endif
};
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 */

382
src/eln.c Normal file
View File

@ -0,0 +1,382 @@
/* $NetBSD: eln.c,v 1.14 2012/03/11 21:15:25 christos Exp $ */
/*-
* Copyright (c) 2009 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. 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.
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: eln.c,v 1.14 2012/03/11 21:15:25 christos Exp $");
#endif /* not lint && not SCCSID */
#include "histedit.h"
#include "el.h"
#include "read.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
public int
el_getc(EditLine *el, char *cp)
{
int num_read;
wchar_t wc = 0;
if (!(el->el_flags & CHARSET_IS_UTF8))
el->el_flags |= IGNORE_EXTCHARS;
num_read = el_wgetc (el, &wc);
if (!(el->el_flags & CHARSET_IS_UTF8))
el->el_flags &= ~IGNORE_EXTCHARS;
if (num_read > 0)
*cp = (char)wc;
return num_read;
}
public void
el_push(EditLine *el, const char *str)
{
/* Using multibyte->wide string decoding works fine under single-byte
* character sets too, and Does The Right Thing. */
el_wpush(el, ct_decode_string(str, &el->el_lgcyconv));
}
public const char *
el_gets(EditLine *el, int *nread)
{
const wchar_t *tmp;
const char *ret;
if (!(el->el_flags & CHARSET_IS_UTF8))
el->el_flags |= IGNORE_EXTCHARS;
tmp = el_wgets(el, nread);
if (!(el->el_flags & CHARSET_IS_UTF8))
el->el_flags &= ~IGNORE_EXTCHARS;
if (!tmp) return NULL;
ret = ct_encode_string(tmp, &el->el_lgcyconv);
if (ret)
*nread = strlen(ret);
return ret;
}
public int
el_parse(EditLine *el, int argc, const char *argv[])
{
int ret;
const wchar_t **wargv;
wargv = (const wchar_t **)
ct_decode_argv(argc, argv, &el->el_lgcyconv);
if (!wargv)
return -1;
ret = el_wparse(el, argc, wargv);
ct_free_argv(wargv);
return ret;
}
public int
el_set(EditLine *el, int op, ...)
{
va_list ap;
int ret;
if (!el)
return -1;
va_start(ap, op);
switch (op) {
case EL_PROMPT: /* el_pfunc_t */
case EL_RPROMPT: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
ret = prompt_set(el, p, 0, op, 0);
break;
}
case EL_RESIZE: {
el_zfunc_t p = va_arg(ap, el_zfunc_t);
void *arg = va_arg(ap, void *);
ret = ch_resizefun(el, p, arg);
break;
}
case EL_TERMINAL: /* const char * */
ret = el_wset(el, op, va_arg(ap, char *));
break;
case EL_EDITOR: /* const wchar_t * */
ret = el_wset(el, op, ct_decode_string(va_arg(ap, char *),
&el->el_lgcyconv));
break;
case EL_SIGNAL: /* int */
case EL_EDITMODE:
case EL_UNBUFFERED:
case EL_PREP_TERM:
ret = el_wset(el, op, va_arg(ap, int));
break;
case EL_BIND: /* const char * list -> const wchar_t * list */
case EL_TELLTC:
case EL_SETTC:
case EL_ECHOTC:
case EL_SETTY: {
const char *argv[20];
int i;
const wchar_t **wargv;
for (i = 1; i < (int)__arraycount(argv); ++i)
if ((argv[i] = va_arg(ap, char *)) == NULL)
break;
argv[0] = NULL;
wargv = (const wchar_t **)
ct_decode_argv(i + 1, argv, &el->el_lgcyconv);
if (!wargv) {
ret = -1;
goto out;
}
/*
* AFAIK we can't portably pass through our new wargv to
* el_wset(), so we have to reimplement the body of
* el_wset() for these ops.
*/
switch (op) {
case EL_BIND:
wargv[0] = STR("bind");
ret = map_bind(el, i, wargv);
break;
case EL_TELLTC:
wargv[0] = STR("telltc");
ret = terminal_telltc(el, i, wargv);
break;
case EL_SETTC:
wargv[0] = STR("settc");
ret = terminal_settc(el, i, wargv);
break;
case EL_ECHOTC:
wargv[0] = STR("echotc");
ret = terminal_echotc(el, i, wargv);
break;
case EL_SETTY:
wargv[0] = STR("setty");
ret = tty_stty(el, i, wargv);
break;
default:
ret = -1;
}
ct_free_argv(wargv);
break;
}
/* XXX: do we need to change el_func_t too? */
case EL_ADDFN: { /* const char *, const char *, el_func_t */
const char *args[2];
el_func_t func;
wchar_t **wargv;
args[0] = va_arg(ap, const char *);
args[1] = va_arg(ap, const char *);
func = va_arg(ap, el_func_t);
wargv = ct_decode_argv(2, args, &el->el_lgcyconv);
if (!wargv) {
ret = -1;
goto out;
}
// XXX: The two strdup's leak
ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]),
func);
ct_free_argv(wargv);
break;
}
case EL_HIST: { /* hist_fun_t, const char * */
hist_fun_t fun = va_arg(ap, hist_fun_t);
void *ptr = va_arg(ap, void *);
ret = hist_set(el, fun, ptr);
el->el_flags |= NARROW_HISTORY;
break;
}
/* XXX: do we need to change el_rfunc_t? */
case EL_GETCFN: /* el_rfunc_t */
ret = el_wset(el, op, va_arg(ap, el_rfunc_t));
el->el_flags |= NARROW_READ;
break;
case EL_CLIENTDATA: /* void * */
ret = el_wset(el, op, va_arg(ap, void *));
break;
case EL_SETFP: { /* int, FILE * */
int what = va_arg(ap, int);
FILE *fp = va_arg(ap, FILE *);
ret = el_wset(el, op, what, fp);
break;
}
case EL_PROMPT_ESC: /* el_pfunc_t, char */
case EL_RPROMPT_ESC: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
char c = (char)va_arg(ap, int);
ret = prompt_set(el, p, c, op, 0);
break;
}
case EL_REFRESH:
ret = el_wset(el, op);
break;
default:
ret = -1;
break;
}
out:
va_end(ap);
return ret;
}
public int
el_get(EditLine *el, int op, ...)
{
va_list ap;
int ret;
if (!el)
return -1;
va_start(ap, op);
switch (op) {
case EL_PROMPT: /* el_pfunc_t * */
case EL_RPROMPT: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
ret = prompt_get(el, p, 0, op);
break;
}
case EL_PROMPT_ESC: /* el_pfunc_t *, char **/
case EL_RPROMPT_ESC: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
char *c = va_arg(ap, char *);
wchar_t wc = 0;
ret = prompt_get(el, p, &wc, op);
*c = (char)wc;
break;
}
case EL_EDITOR: {
const char **p = va_arg(ap, const char **);
const wchar_t *pw;
ret = el_wget(el, op, &pw);
*p = ct_encode_string(pw, &el->el_lgcyconv);
if (!el->el_lgcyconv.csize)
ret = -1;
break;
}
case EL_TERMINAL: /* const char ** */
ret = el_wget(el, op, va_arg(ap, const char **));
break;
case EL_SIGNAL: /* int * */
case EL_EDITMODE:
case EL_UNBUFFERED:
case EL_PREP_TERM:
ret = el_wget(el, op, va_arg(ap, int *));
break;
case EL_GETTC: {
char *argv[20];
static char gettc[] = "gettc";
int i;
for (i = 1; i < (int)__arraycount(argv); ++i)
if ((argv[i] = va_arg(ap, char *)) == NULL)
break;
argv[0] = gettc;
ret = terminal_gettc(el, i, argv);
break;
}
/* XXX: do we need to change el_rfunc_t? */
case EL_GETCFN: /* el_rfunc_t */
ret = el_wget(el, op, va_arg(ap, el_rfunc_t *));
break;
case EL_CLIENTDATA: /* void ** */
ret = el_wget(el, op, va_arg(ap, void **));
break;
case EL_GETFP: { /* int, FILE ** */
int what = va_arg(ap, int);
FILE **fpp = va_arg(ap, FILE **);
ret = el_wget(el, op, what, fpp);
break;
}
default:
ret = -1;
break;
}
va_end(ap);
return ret;
}
const LineInfo *
el_line(EditLine *el)
{
const LineInfoW *winfo = el_wline(el);
LineInfo *info = &el->el_lgcylinfo;
size_t offset;
const Char *p;
info->buffer = ct_encode_string(winfo->buffer, &el->el_lgcyconv);
offset = 0;
for (p = winfo->buffer; p < winfo->cursor; p++)
offset += ct_enc_width(*p);
info->cursor = info->buffer + offset;
offset = 0;
for (p = winfo->buffer; p < winfo->lastchar; p++)
offset += ct_enc_width(*p);
info->lastchar = info->buffer + offset;
return info;
}
int
el_insertstr(EditLine *el, const char *str)
{
return el_winsertstr(el, ct_decode_string(str, &el->el_lgcyconv));
}

508
src/emacs.c Normal file
View File

@ -0,0 +1,508 @@
/* $NetBSD: emacs.c,v 1.25 2011/07/29 15:16: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[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: emacs.c,v 1.25 2011/07/29 15:16:33 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 */
terminal_writec(el, c); /* then do an EOF */
return CC_EOF;
} else {
/*
* Here we could list completions, but it is an
* error right now
*/
terminal_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, (int)(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,
(int)(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, (int)(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, (int)(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(*cp))
*cp = Toupper(*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(*cp)) {
if (Islower(*cp))
*cp = Toupper(*cp);
cp++;
break;
}
}
for (; cp < ep; cp++)
if (Isupper(*cp))
*cp = Tolower(*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(*cp))
*cp = Tolower(*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, (int)(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;
}

734
src/filecomplete.c Normal file
View File

@ -0,0 +1,734 @@
/* $NetBSD: filecomplete.c,v 1.34 2014/10/18 15:07:02 riz 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.
*
* 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.
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: filecomplete.c,v 1.34 2014/10/18 15:07:02 riz 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 "el.h"
#include "fcns.h" /* for EL_NUM_FCNS */
#include "histedit.h"
#include "filecomplete.h"
static const Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@',
'$', '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
/* Tilde is deliberately omitted here, we treat it specially. */
static const Char extra_quote_chars[] = { ')', '}', '*', '?', '[', '$', '\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 the caller's responsibility to free() the returned string
*/
char *
fn_tilde_expand(const char *txt)
{
#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
struct passwd pwres;
char pwbuf[1024];
#endif
struct passwd *pass;
char *temp;
size_t len = 0;
if (txt[0] != '~')
return strdup(txt);
temp = strchr(txt + 1, '/');
if (temp == NULL) {
temp = strdup(txt + 1);
if (temp == NULL)
return NULL;
} else {
/* text until string after slash */
len = (size_t)(temp - txt + 1);
temp = el_malloc(len * sizeof(*temp));
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
}
el_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;
len = strlen(pass->pw_dir) + 1 + strlen(txt) + 1;
temp = el_malloc(len * sizeof(*temp));
if (temp == NULL)
return NULL;
(void)snprintf(temp, len, "%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 the caller's responsibility to free the 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 = el_realloc(filename, (strlen(temp) + 1) *
sizeof(*nptr));
if (nptr == NULL) {
el_free(filename);
filename = NULL;
return NULL;
}
filename = nptr;
(void)strcpy(filename, temp);
len = (size_t)(temp - text); /* including last slash */
nptr = el_realloc(dirname, (len + 1) *
sizeof(*nptr));
if (nptr == NULL) {
el_free(dirname);
dirname = NULL;
return NULL;
}
dirname = nptr;
(void)strncpy(dirname, text, len);
dirname[len] = '\0';
} else {
el_free(filename);
if (*text == 0)
filename = NULL;
else {
filename = strdup(text);
if (filename == NULL)
return NULL;
}
el_free(dirname);
dirname = NULL;
}
if (dir != NULL) {
(void)closedir(dir);
dir = NULL;
}
/* support for ``~user'' syntax */
el_free(dirpath);
dirpath = NULL;
if (dirname == NULL) {
if ((dirname = strdup("")) == NULL)
return NULL;
dirpath = strdup("./");
} else 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]
#if HAVE_STRUCT_DIRENT_D_NAMLEN
&& entry->d_namlen >= filename_len
#else
&& strlen(entry->d_name) >= filename_len
#endif
&& strncmp(entry->d_name, filename,
filename_len) == 0)
break;
}
if (entry) { /* match found */
#if HAVE_STRUCT_DIRENT_D_NAMLEN
len = entry->d_namlen;
#else
len = strlen(entry->d_name);
#endif
len = strlen(dirname) + len + 1;
temp = el_malloc(len * sizeof(*temp));
if (temp == NULL)
return NULL;
(void)snprintf(temp, len, "%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)
el_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 = el_realloc(match_list,
match_list_len * sizeof(*nmatch_list));
if (nmatch_list == NULL) {
el_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 = el_malloc((max_equal + 1) * sizeof(*retstr));
if (retstr == NULL) {
el_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] = 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, 'num' is number of strings in 'matches',
* 'width' is maximum length of string in 'matches'.
*
* matches[0] is not one of the match strings, but it is counted in
* num, so the strings are matches[1] *through* matches[num-1].
*/
void
fn_display_match_list (EditLine *el, char **matches, size_t num, size_t width)
{
size_t line, lines, col, cols, thisguy;
int screenwidth = el->el_terminal.t_size.h;
/* Ignore matches[0]. Avoid 1-based array logic below. */
matches++;
num--;
/*
* Find out how many entries can be put on one line; count
* with one space between strings the same way it's printed.
*/
cols = (size_t)screenwidth / (width + 1);
if (cols == 0)
cols = 1;
/* how many lines of output, rounded up */
lines = (num + cols - 1) / cols;
/* Sort the items. */
qsort(matches, num, sizeof(char *), _fn_qsort_string_compare);
/*
* On the ith line print elements i, i+lines, i+lines*2, etc.
*/
for (line = 0; line < lines; line++) {
for (col = 0; col < cols; col++) {
thisguy = line + col * lines;
if (thisguy >= num)
break;
(void)fprintf(el->el_outfile, "%s%-*s",
col == 0 ? "" : " ", (int)width, matches[thisguy]);
}
(void)fprintf(el->el_outfile, "\n");
}
}
#ifdef WIDECHAR
/* This is ugly, but we need to set rl_line_buffer to the encoded buffer,
* which may get changed by realloc() in the el_line() call.
*/
extern char *rl_line_buffer;
#endif /* WIDECHAR */
/*
* 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 *), size_t query_items,
int *completion_type, int *over, int *point, int *end,
const Char *(*find_word_start_func)(const Char *, const Char *),
char *(*dequoting_func)(const char *),
char *(*quoting_func)(const char *))
{
const LineInfo *li;
#ifdef WIDECHAR
const LineInfoW *wli;
#endif /* WIDECHAR */
char *temp;
char *dequoted_temp;
char **matches;
const Char *ctemp;
size_t len;
#ifdef WIDECHAR
size_t ctemp_off;
#endif /* WIDECHAR */
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 */
#ifdef WIDECHAR
/* Map li to wli for the wide character version */
# define li wli
#endif /* WIDECHAR */
li = FUN(el,line)(el);
if (find_word_start_func)
ctemp = find_word_start_func(li->buffer, li->cursor);
else {
ctemp = li->cursor;
while (ctemp > li->buffer
&& !Strchr(word_break, ctemp[-1])
&& (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) )
ctemp--;
}
#ifdef WIDECHAR
/* Unmap li and convert wide character values */
# undef li
li = el_line(el);
{
const Char *p;
ctemp_off = 0;
for (p = wli->buffer; p < ctemp; p++)
ctemp_off += ct_enc_width(*p);
len = (li->cursor - li->buffer) - ctemp_off;
}
rl_line_buffer = li->buffer;
#else /* !WIDECHAR */
len = (size_t)(li->cursor - ctemp);
#endif /* !WIDECHAR */
temp = el_malloc((len + 1) * sizeof(*temp));
#ifdef WIDECHAR
(void)strncpy(temp, li->buffer + ctemp_off, len);
#else /* !WIDECHAR */
(void)strncpy(temp, ctemp, len);
#endif /* !WIDECHAR */
temp[len] = '\0';
if (dequoting_func) {
dequoted_temp = dequoting_func(temp);
if (dequoted_temp == NULL)
return retval;
} else
dequoted_temp = NULL;
/* these can be used by function called in completion_matches() */
/* or (*attempted_completion_function)() */
if (point != 0)
*point = (int)(li->cursor - li->buffer);
if (end != NULL)
*end = (int)(li->lastchar - li->buffer);
if (attempted_completion_function) {
int cur_off = (int)(li->cursor - li->buffer);
matches = (*attempted_completion_function)(
dequoted_temp ? dequoted_temp : temp,
cur_off - (int)len, cur_off);
} else
matches = 0;
if (!attempted_completion_function ||
(over != NULL && !*over && !matches))
matches = completion_matches(
dequoted_temp ? dequoted_temp : temp, complet_func);
if (over != NULL)
*over = 0;
if (matches) {
int i;
size_t 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') {
char *quoted_match;
if (quoting_func) {
quoted_match = quoting_func(matches[0]);
if (quoted_match == NULL)
goto free_matches;
} else
quoted_match = NULL;
#ifdef WIDECHAR
len = wli->cursor - ctemp;
#endif /* WIDECHAR */
el_deletestr(el, (int) len);
FUN(el,insertstr)(el,
ct_decode_string(quoted_match ? quoted_match :
matches[0] , &el->el_scratch));
free(quoted_match);
}
if (what_to_do == '?')
goto display_matches;
if (matches[2] == NULL &&
(matches[1] == 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.
*/
FUN(el,insertstr)(el,
ct_decode_string((*app_func)(matches[0]),
&el->el_scratch));
} 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[1] through matches[i-1] are available */
matches_num = (size_t)(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 %zu 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) {
/*
* Interface of this function requires the
* strings be matches[1..num-1] for compat.
* We have matches_num strings not counting
* the prefix in matches[0], so we need to
* add 1 to matches_num for the call.
*/
fn_display_match_list(el, matches,
matches_num+1, 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_matches:
/* free elements of array and the array itself */
for (i = 0; matches[i]; i++)
el_free(matches[i]);
el_free(matches);
matches = NULL;
}
free(dequoted_temp);
el_free(temp);
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, (size_t)100,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL);
}
static const Char *
sh_find_word_start(const Char *buffer, const Char *cursor)
{
const Char *word_start = buffer;
while (buffer < cursor) {
if (*buffer == '\\')
buffer++;
else if (Strchr(break_chars, *buffer))
word_start = buffer + 1;
buffer++;
}
return word_start;
}
static char *
sh_quote(const char *str)
{
const char *src;
int extra_len = 0;
char *quoted_str, *dst;
for (src = str; *src != '\0'; src++)
if (Strchr(break_chars, *src) ||
Strchr(extra_quote_chars, *src))
extra_len++;
quoted_str = malloc(sizeof(*quoted_str) *
(strlen(str) + extra_len + 1));
if (quoted_str == NULL)
return NULL;
dst = quoted_str;
for (src = str; *src != '\0'; src++) {
if (Strchr(break_chars, *src) ||
Strchr(extra_quote_chars, *src))
*dst++ = '\\';
*dst++ = *src;
}
*dst = '\0';
return quoted_str;
}
static char *
sh_dequote(const char *str)
{
char *dequoted_str, *dst;
/* save extra space to replace \~ with ./~ */
dequoted_str = malloc(sizeof(*dequoted_str) * (strlen(str) + 1 + 1));
if (dequoted_str == NULL)
return NULL;
dst = dequoted_str;
/* dequote \~ at start as ./~ */
if (*str == '\\' && str[1] == '~') {
str++;
*dst++ = '.';
*dst++ = '/';
}
while (*str) {
if (*str == '\\')
str++;
if (*str)
*dst++ = *str++;
}
*dst = '\0';
return dequoted_str;
}
/*
* completion function using sh quoting rules; for key binding
*/
/* ARGSUSED */
unsigned char
_el_fn_sh_complete(EditLine *el, int ch __attribute__((__unused__)))
{
return (unsigned char)fn_complete(el, NULL, NULL,
break_chars, NULL, NULL, 100,
NULL, NULL, NULL, NULL,
sh_find_word_start, sh_dequote, sh_quote);
}

47
src/filecomplete.h Normal file
View File

@ -0,0 +1,47 @@
/* $NetBSD: filecomplete.h,v 1.9 2009/12/30 22:37:40 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.
*
* 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 *), size_t,
int *, int *, int *, int *,
const Char *(*)(const Char *, const Char *),
char *(*)(const char *),
char *(*)(const char *));
void fn_display_match_list(EditLine *, char **, size_t, size_t);
char *fn_tilde_expand(const char *);
char *fn_filename_completion_function(const char *, int);
#endif

223
src/hist.c Normal file
View File

@ -0,0 +1,223 @@
/* $NetBSD: hist.c,v 1.20 2011/07/29 15:16: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[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: hist.c,v 1.20 2011/07/29 15:16:33 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 = el_malloc(EL_BUFSIZ * sizeof(*el->el_history.buf));
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(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, void *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) Strncpy(el->el_line.buffer, hp,
(size_t)(el->el_line.limit - el->el_line.buffer));
el->el_line.buffer[el->el_line.limit - el->el_line.buffer - 1] = '\0';
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;
TYPE(HistEvent) ev;
if (el->el_history.ref == NULL)
return -1;
if (argc == 1 || Strcmp(argv[1], STR("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, ct_encode_string(str, &el->el_scratch));
return 0;
}
if (argc != 3)
return -1;
num = (int)Strtol(argv[2], NULL, 0);
if (Strcmp(argv[1], STR("size")) == 0)
return FUNW(history)(el->el_history.ref, &ev, H_SETSIZE, num);
if (Strcmp(argv[1], STR("unique")) == 0)
return FUNW(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 = el_realloc(el->el_history.buf, newsz * sizeof(*newbuf));
if (!newbuf)
return 0;
(void) memset(&newbuf[oldsz], '\0', (newsz - oldsz) * sizeof(*newbuf));
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;
}
#ifdef WIDECHAR
protected wchar_t *
hist_convert(EditLine *el, int fn, void *arg)
{
HistEventW ev;
if ((*(el)->el_history.fun)((el)->el_history.ref, &ev, fn, arg) == -1)
return NULL;
return ct_decode_string((const char *)(const void *)ev.str,
&el->el_scratch);
}
#endif

87
src/hist.h Normal file
View File

@ -0,0 +1,87 @@
/* $NetBSD: hist.h,v 1.13 2011/07/28 20:50:55 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.
*
* @(#)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)(void *, TYPE(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 */
void * ref; /* Argument for history fcns */
hist_fun_t fun; /* Event access */
TYPE(HistEvent) ev; /* Event cookie */
} el_history_t;
#define HIST_FUN_INTERNAL(el, fn, arg) \
((((*(el)->el_history.fun) ((el)->el_history.ref, &(el)->el_history.ev, \
fn, arg)) == -1) ? NULL : (el)->el_history.ev.str)
#ifdef WIDECHAR
#define HIST_FUN(el, fn, arg) \
(((el)->el_flags & NARROW_HISTORY) ? hist_convert(el, fn, arg) : \
HIST_FUN_INTERNAL(el, fn, arg))
#else
#define HIST_FUN(el, fn, arg) HIST_FUN_INTERNAL(el, fn, arg)
#endif
#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, void *);
protected int hist_command(EditLine *, int, const Char **);
protected int hist_enlargebuf(EditLine *, size_t, size_t);
#ifdef WIDECHAR
protected wchar_t *hist_convert(EditLine *, int, void *);
#endif
#endif /* _h_el_hist */

318
src/histedit.h Normal file
View File

@ -0,0 +1,318 @@
/* $NetBSD: histedit.h,v 1.49 2012/05/31 13:16: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.
*
* @(#)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 11
#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 *, const 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);
unsigned char _el_fn_sh_complete(EditLine *, int);
/*
* el_set/el_get parameters
*
* When using el_wset/el_wget (as opposed to el_set/el_get):
* Char is wchar_t, otherwise it is char.
* prompt_func is el_wpfunc_t, otherwise it is el_pfunc_t .
* Prompt function prototypes are:
* typedef char *(*el_pfunct_t) (EditLine *);
* typedef wchar_t *(*el_wpfunct_t) (EditLine *);
*
* For operations that support set or set/get, the argument types listed are for
* the "set" operation. For "get", each listed type must be a pointer.
* E.g. EL_EDITMODE takes an int when set, but an int* when get.
*
* Operations that only support "get" have the correct argument types listed.
*/
#define EL_PROMPT 0 /* , prompt_func); set/get */
#define EL_TERMINAL 1 /* , const char *); set/get */
#define EL_EDITOR 2 /* , const Char *); set/get */
#define EL_SIGNAL 3 /* , int); set/get */
#define EL_BIND 4 /* , const Char *, ..., NULL); set */
#define EL_TELLTC 5 /* , const Char *, ..., NULL); set */
#define EL_SETTC 6 /* , const Char *, ..., NULL); set */
#define EL_ECHOTC 7 /* , const Char *, ..., NULL); set */
#define EL_SETTY 8 /* , const Char *, ..., NULL); set */
#define EL_ADDFN 9 /* , const Char *, const Char, set */
/* el_func_t); */
#define EL_HIST 10 /* , hist_fun_t, const void *); set */
#define EL_EDITMODE 11 /* , int); set/get */
#define EL_RPROMPT 12 /* , prompt_func); set/get */
#define EL_GETCFN 13 /* , el_rfunc_t); set/get */
#define EL_CLIENTDATA 14 /* , void *); set/get */
#define EL_UNBUFFERED 15 /* , int); set/get */
#define EL_PREP_TERM 16 /* , int); set */
#define EL_GETTC 17 /* , const Char *, ..., NULL); get */
#define EL_GETFP 18 /* , int, FILE **); get */
#define EL_SETFP 19 /* , int, FILE *); set */
#define EL_REFRESH 20 /* , void); set */
#define EL_PROMPT_ESC 21 /* , prompt_func, Char); set/get */
#define EL_RPROMPT_ESC 22 /* , prompt_func, Char); set/get */
#define EL_RESIZE 23 /* , el_zfunc_t, void *); set */
#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 /* , void); */
#define H_SET 7 /* , int); */
#define H_ADD 9 /* , const wchar_t *); */
#define H_ENTER 10 /* , const wchar_t *); */
#define H_APPEND 11 /* , const wchar_t *); */
#define H_END 12 /* , void); */
#define H_NEXT_STR 13 /* , const wchar_t *); */
#define H_PREV_STR 14 /* , const wchar_t *); */
#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); */
#define H_NEXT_EVDATA 23 /* , const int, histdata_t *); */
#define H_DELDATA 24 /* , int, histdata_t *);*/
#define H_REPLACE 25 /* , const char *, histdata_t); */
/*
* ==== 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 ***);
/*
* Begin Wide Character Support
*/
#ifdef __linux__
/* Apparently we need _GNU_SOURCE defined to get access to wcsdup on Linux */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#endif
#include <wchar.h>
#include <wctype.h>
/*
* Wide character versions
*/
/*
* ==== Editing ====
*/
typedef struct lineinfow {
const wchar_t *buffer;
const wchar_t *cursor;
const wchar_t *lastchar;
} LineInfoW;
const wchar_t *el_wgets(EditLine *, int *);
int el_wgetc(EditLine *, wchar_t *);
void el_wpush(EditLine *, const wchar_t *);
int el_wparse(EditLine *, int, const wchar_t **);
int el_wset(EditLine *, int, ...);
int el_wget(EditLine *, int, ...);
const LineInfoW *el_wline(EditLine *);
int el_winsertstr(EditLine *, const wchar_t *);
#define el_wdeletestr el_deletestr
/*
* ==== History ====
*/
typedef struct histeventW {
int num;
const wchar_t *str;
} HistEventW;
typedef struct historyW HistoryW;
HistoryW * history_winit(void);
void history_wend(HistoryW *);
int history_w(HistoryW *, HistEventW *, int, ...);
/*
* ==== Tokenization ====
*/
typedef struct tokenizerW TokenizerW;
/* Wide character tokenizer support */
TokenizerW *tok_winit(const wchar_t *);
void tok_wend(TokenizerW *);
void tok_wreset(TokenizerW *);
int tok_wline(TokenizerW *, const LineInfoW *,
int *, const wchar_t ***, int *, int *);
int tok_wstr(TokenizerW *, const wchar_t *,
int *, const wchar_t ***);
#ifdef __cplusplus
}
#endif
#endif /* _HISTEDIT_H_ */

1150
src/history.c Normal file

File diff suppressed because it is too large Load Diff

671
src/keymacro.c Normal file
View File

@ -0,0 +1,671 @@
/* $NetBSD: keymacro.c,v 1.7 2011/08/16 16:25:15 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: keymacro.c,v 1.7 2011/08/16 16:25:15 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/*
* keymacro.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_keymacro.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_keymacro.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_keymacro.map. The el->el_keymacro.map is a
* linked list of these node elements
*/
struct keymacro_node_t {
Char ch; /* single character of key */
int type; /* node type */
keymacro_value_t val; /* command code or pointer to str, */
/* if this is a leaf */
struct keymacro_node_t *next; /* ptr to next char of this key */
struct keymacro_node_t *sibling;/* ptr to another key with same prefix*/
};
private int node_trav(EditLine *, keymacro_node_t *, Char *,
keymacro_value_t *);
private int node__try(EditLine *, keymacro_node_t *, const Char *,
keymacro_value_t *, int);
private keymacro_node_t *node__get(Int);
private void node__free(keymacro_node_t *);
private void node__put(EditLine *, keymacro_node_t *);
private int node__delete(EditLine *, keymacro_node_t **,
const Char *);
private int node_lookup(EditLine *, const Char *,
keymacro_node_t *, size_t);
private int node_enum(EditLine *, keymacro_node_t *, size_t);
#define KEY_BUFSIZ EL_BUFSIZ
/* keymacro_init():
* Initialize the key maps
*/
protected int
keymacro_init(EditLine *el)
{
el->el_keymacro.buf = el_malloc(KEY_BUFSIZ *
sizeof(*el->el_keymacro.buf));
if (el->el_keymacro.buf == NULL)
return -1;
el->el_keymacro.map = NULL;
keymacro_reset(el);
return 0;
}
/* keymacro_end():
* Free the key maps
*/
protected void
keymacro_end(EditLine *el)
{
el_free(el->el_keymacro.buf);
el->el_keymacro.buf = NULL;
node__free(el->el_keymacro.map);
}
/* keymacro_map_cmd():
* Associate cmd with a key value
*/
protected keymacro_value_t *
keymacro_map_cmd(EditLine *el, int cmd)
{
el->el_keymacro.val.cmd = (el_action_t) cmd;
return &el->el_keymacro.val;
}
/* keymacro_map_str():
* Associate str with a key value
*/
protected keymacro_value_t *
keymacro_map_str(EditLine *el, Char *str)
{
el->el_keymacro.val.str = str;
return &el->el_keymacro.val;
}
/* keymacro_reset():
* Takes all nodes on el->el_keymacro.map and puts them on free list.
* Then initializes el->el_keymacro.map with arrow keys
* [Always bind the ansi arrow keys?]
*/
protected void
keymacro_reset(EditLine *el)
{
node__put(el, el->el_keymacro.map);
el->el_keymacro.map = NULL;
return;
}
/* keymacro_get():
* Calls the recursive function with entry point el->el_keymacro.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
keymacro_get(EditLine *el, Char *ch, keymacro_value_t *val)
{
return node_trav(el, el->el_keymacro.map, ch, val);
}
/* keymacro_add():
* Adds key to the el->el_keymacro.map and associates the value in
* val with it. If key is already is in el->el_keymacro.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
keymacro_add(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
{
if (key[0] == '\0') {
(void) fprintf(el->el_errfile,
"keymacro_add: Null extended-key not allowed.\n");
return;
}
if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) {
(void) fprintf(el->el_errfile,
"keymacro_add: sequence-lead-in command not allowed\n");
return;
}
if (el->el_keymacro.map == NULL)
/* tree is initially empty. Set up new node to match key[0] */
el->el_keymacro.map = node__get(key[0]);
/* it is properly initialized */
/* Now recurse through el->el_keymacro.map */
(void) node__try(el, el->el_keymacro.map, key, val, ntype);
return;
}
/* keymacro_clear():
*
*/
protected void
keymacro_clear(EditLine *el, el_action_t *map, const Char *in)
{
#ifdef WIDECHAR
if (*in > N_KEYS) /* can't be in the map */
return;
#endif
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) keymacro_delete(el, in);
}
/* keymacro_delete():
* Delete the key and all longer keys staring with key, if
* they exists.
*/
protected int
keymacro_delete(EditLine *el, const Char *key)
{
if (key[0] == '\0') {
(void) fprintf(el->el_errfile,
"keymacro_delete: Null extended-key not allowed.\n");
return -1;
}
if (el->el_keymacro.map == NULL)
return 0;
(void) node__delete(el, &el->el_keymacro.map, key);
return 0;
}
/* keymacro_print():
* Print the binding associated with key key.
* Print entire el->el_keymacro.map if null
*/
protected void
keymacro_print(EditLine *el, const Char *key)
{
/* do nothing if el->el_keymacro.map is empty and null key specified */
if (el->el_keymacro.map == NULL && *key == 0)
return;
el->el_keymacro.buf[0] = '"';
if (node_lookup(el, key, el->el_keymacro.map, (size_t)1) <= -1)
/* key is not bound */
(void) fprintf(el->el_errfile, "Unbound extended key \"" FSTR
"\"\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, keymacro_node_t *ptr, Char *ch, keymacro_value_t *val)
{
if (ptr->ch == *ch) {
/* match found */
if (ptr->next) {
/* key not complete so get next char */
if (FUN(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, keymacro_node_t *ptr, const Char *str,
keymacro_value_t *val, int ntype)
{
if (ptr->ch != *str) {
keymacro_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->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 = 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, keymacro_node_t **inptr, const Char *str)
{
keymacro_node_t *ptr;
keymacro_node_t *prev_ptr = NULL;
ptr = *inptr;
if (ptr->ch != *str) {
keymacro_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, keymacro_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->val.str);
break;
default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ptr->type));
break;
}
el_free(ptr);
}
/* node__get():
* Returns pointer to a keymacro_node_t for ch.
*/
private keymacro_node_t *
node__get(Int ch)
{
keymacro_node_t *ptr;
ptr = el_malloc(sizeof(*ptr));
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(keymacro_node_t *k)
{
if (k == NULL)
return;
node__free(k->sibling);
node__free(k->next);
el_free(k);
}
/* node_lookup():
* look for the str starting at node ptr.
* Print if last node
*/
private int
node_lookup(EditLine *el, const Char *str, keymacro_node_t *ptr, size_t cnt)
{
ssize_t used;
if (ptr == NULL)
return -1; /* cannot have null ptr */
if (!str || *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_keymacro.buf. Recurse */
if (ptr->ch == *str) {
/* match found */
used = ct_visual_char(el->el_keymacro.buf + cnt,
KEY_BUFSIZ - cnt, ptr->ch);
if (used == -1)
return -1; /* ran out of buffer space */
if (ptr->next != NULL)
/* not yet at leaf */
return (node_lookup(el, str + 1, ptr->next,
(size_t)used + cnt));
else {
/* next node is null so key should be complete */
if (str[1] == 0) {
size_t px = cnt + (size_t)used;
el->el_keymacro.buf[px] = '"';
el->el_keymacro.buf[px + 1] = '\0';
keymacro_kprint(el, el->el_keymacro.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, keymacro_node_t *ptr, size_t cnt)
{
ssize_t used;
if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */
el->el_keymacro.buf[++cnt] = '"';
el->el_keymacro.buf[++cnt] = '\0';
(void) fprintf(el->el_errfile,
"Some extended keys too long for internal print buffer");
(void) fprintf(el->el_errfile, " \"" FSTR "...\"\n",
el->el_keymacro.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 */
used = ct_visual_char(el->el_keymacro.buf + cnt, KEY_BUFSIZ - cnt,
ptr->ch);
if (ptr->next == NULL) {
/* print this key and function */
el->el_keymacro.buf[cnt + (size_t)used ] = '"';
el->el_keymacro.buf[cnt + (size_t)used + 1] = '\0';
keymacro_kprint(el, el->el_keymacro.buf, &ptr->val, ptr->type);
} else
(void) node_enum(el, ptr->next, cnt + (size_t)used);
/* go to sibling if there is one */
if (ptr->sibling)
(void) node_enum(el, ptr->sibling, cnt);
return 0;
}
/* keymacro_kprint():
* Print the specified key and its associated
* function specified by val
*/
protected void
keymacro_kprint(EditLine *el, const Char *key, keymacro_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) keymacro__decode_str(val->str, unparsbuf,
sizeof(unparsbuf),
ntype == XK_STR ? "\"\"" : "[]");
(void) fprintf(el->el_outfile, fmt,
ct_encode_string(key, &el->el_scratch), unparsbuf);
break;
case XK_CMD:
for (fp = el->el_map.help; fp->name; fp++)
if (val->cmd == fp->func) {
ct_wcstombs(unparsbuf, fp->name, sizeof(unparsbuf));
unparsbuf[sizeof(unparsbuf) -1] = '\0';
(void) fprintf(el->el_outfile, fmt,
ct_encode_string(key, &el->el_scratch), unparsbuf);
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, ct_encode_string(key,
&el->el_scratch), "no input");
}
#define ADDC(c) \
if (b < eb) \
*b++ = c; \
else \
b++
/* keymacro__decode_str():
* Make a printable version of the ey
*/
protected size_t
keymacro__decode_str(const Char *str, char *buf, size_t 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('@');
goto add_endsep;
}
for (p = str; *p != 0; p++) {
Char dbuf[VISUAL_WIDTH_MAX];
Char *p2 = dbuf;
ssize_t l = ct_visual_char(dbuf, VISUAL_WIDTH_MAX, *p);
while (l-- > 0) {
ssize_t n = ct_encode_char(b, (size_t)(eb - b), *p2++);
if (n == -1) /* ran out of space */
goto add_endsep;
else
b += n;
}
}
add_endsep:
if (sep[0] != '\0' && sep[1] != '\0') {
ADDC(sep[1]);
}
ADDC('\0');
if ((size_t)(b - buf) >= len)
buf[len - 1] = '\0';
return (size_t)(b - buf);
}

76
src/keymacro.h Normal file
View File

@ -0,0 +1,76 @@
/* $NetBSD: keymacro.h,v 1.2 2011/07/28 03:44: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.
*
* @(#)key.h 8.1 (Berkeley) 6/4/93
*/
/*
* el.keymacro.h: Key macro header
*/
#ifndef _h_el_keymacro
#define _h_el_keymacro
typedef union keymacro_value_t {
el_action_t cmd; /* If it is a command the # */
Char *str; /* If it is a string... */
} keymacro_value_t;
typedef struct keymacro_node_t keymacro_node_t;
typedef struct el_keymacromacro_t {
Char *buf; /* Key print buffer */
keymacro_node_t *map; /* Key map */
keymacro_value_t val; /* Local conversion buffer */
} el_keymacro_t;
#define XK_CMD 0
#define XK_STR 1
#define XK_NOD 2
#define XK_EXE 3
protected int keymacro_init(EditLine *);
protected void keymacro_end(EditLine *);
protected keymacro_value_t *keymacro_map_cmd(EditLine *, int);
protected keymacro_value_t *keymacro_map_str(EditLine *, Char *);
protected void keymacro_reset(EditLine *);
protected int keymacro_get(EditLine *, Char *, keymacro_value_t *);
protected void keymacro_add(EditLine *, const Char *, keymacro_value_t *, int);
protected void keymacro_clear(EditLine *, el_action_t *, const Char *);
protected int keymacro_delete(EditLine *, const Char *);
protected void keymacro_print(EditLine *, const Char *);
protected void keymacro_kprint(EditLine *, const Char *, keymacro_value_t *,
int);
protected size_t keymacro__decode_str(const Char *, char *, size_t,
const char *);
#endif /* _h_el_keymacro */

258
src/makelist Normal file
View File

@ -0,0 +1,258 @@
#!/bin/sh -
# $NetBSD: makelist,v 1.18 2012/03/21 05:34:54 matt 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...
USAGE="Usage: $0 -n|-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
#
-n)
cat << _EOF
#include "config.h"
#undef WIDECHAR
#define NARROWCHAR
#include "${FILES}"
_EOF
;;
-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 \"config.h\"\n#include \"el.h\"\n");
printf("#include \"chartype.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","STR(\"" fname "\"),", uname ",");
ok = 1;
}
}
/^ \*/ {
if (ok) {
printf(" STR(\"");
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(void)");
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 '[a-z]' '[A-Z]' | $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 \"config.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(void) { 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

1422
src/map.c Normal file

File diff suppressed because it is too large Load Diff

77
src/map.h Normal file
View File

@ -0,0 +1,77 @@
/* $NetBSD: map.h,v 1.9 2009/12/30 22:37: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.
*
* @(#)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
#define N_KEYS 256
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 */

286
src/parse.c Normal file
View File

@ -0,0 +1,286 @@
/* $NetBSD: parse.c,v 1.27 2014/07/06 18:15:34 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[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: parse.c,v 1.27 2014/07/06 18:15:34 christos 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[] = {
{ STR("bind"), map_bind },
{ STR("echotc"), terminal_echotc },
{ STR("edit"), el_editmode },
{ STR("history"), hist_command },
{ STR("telltc"), terminal_telltc },
{ STR("settc"), terminal_settc },
{ STR("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;
TYPE(Tokenizer) *tok;
tok = FUN(tok,init)(NULL);
FUN(tok,str)(tok, line, &argc, &argv);
argc = FUN(el,parse)(el, argc, argv);
FUN(tok,end)(tok);
return argc;
}
/* el_parse():
* Command dispatcher
*/
public int
FUN(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 = (size_t)(ptr - argv[0] - 1);
tprog = el_malloc((l + 1) * sizeof(*tprog));
if (tprog == NULL)
return 0;
(void) Strncpy(tprog, argv[0], l);
tprog[l] = '\0';
ptr++;
l = (size_t)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> \U+xxxx 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 'U': /* Unicode \U+xxxx or \U+xxxxx format */
{
int i;
const Char hex[] = STR("0123456789ABCDEF");
const Char *h;
++p;
if (*p++ != '+')
return -1;
c = 0;
for (i = 0; i < 5; ++i) {
h = Strchr(hex, *p++);
if (!h && i < 4)
return -1;
else if (h)
c = (c << 4) | ((int)(h - hex));
else
--p;
}
if (c > 0x10FFFF) /* outside valid character range */
return -1;
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 & (wint_t)0xffffff00) != (wint_t)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 = el->el_map.help;
size_t i;
for (i = 0; i < el->el_map.nfunc; i++)
if (Strcmp(b[i].name, cmd) == 0)
return b[i].func;
return -1;
}

48
src/parse.h Normal file
View File

@ -0,0 +1,48 @@
/* $NetBSD: parse.h,v 1.7 2009/12/30 22:37: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.
*
* @(#)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 */

199
src/prompt.c Normal file
View File

@ -0,0 +1,199 @@
/* $NetBSD: prompt.c,v 1.20 2011/07/29 15:16: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[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: prompt.c,v 1.20 2011/07/29 15:16:33 christos 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.
*/
protected void
prompt_print(EditLine *el, int op)
{
el_prompt_t *elp;
Char *p;
int ignore = 0;
if (op == EL_PROMPT)
elp = &el->el_prompt;
else
elp = &el->el_rprompt;
if (elp->p_wide)
p = (*elp->p_func)(el);
else
p = ct_decode_string((char *)(void *)(*elp->p_func)(el),
&el->el_scratch);
for (; *p; p++) {
if (elp->p_ignore == *p) {
ignore = !ignore;
continue;
}
if (ignore)
terminal__putc(el, *p);
else
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_prompt.p_ignore = '\0';
el->el_rprompt.p_func = prompt_default_r;
el->el_rprompt.p_pos.v = 0;
el->el_rprompt.p_pos.h = 0;
el->el_rprompt.p_ignore = '\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, Char c, int op, int wide)
{
el_prompt_t *p;
if (op == EL_PROMPT || op == EL_PROMPT_ESC)
p = &el->el_prompt;
else
p = &el->el_rprompt;
if (prf == NULL) {
if (op == EL_PROMPT || op == EL_PROMPT_ESC)
p->p_func = prompt_default;
else
p->p_func = prompt_default_r;
} else {
p->p_func = prf;
}
p->p_ignore = c;
p->p_pos.v = 0;
p->p_pos.h = 0;
p->p_wide = wide;
return 0;
}
/* prompt_get():
* Retrieve the prompt printing function
*/
protected int
prompt_get(EditLine *el, el_pfunc_t *prf, Char *c, int op)
{
el_prompt_t *p;
if (prf == NULL)
return -1;
if (op == EL_PROMPT)
p = &el->el_prompt;
else
p = &el->el_rprompt;
if (prf)
*prf = p->p_func;
if (c)
*c = p->p_ignore;
return 0;
}

67
src/prompt.h Normal file
View File

@ -0,0 +1,67 @@
/* $NetBSD: prompt.h,v 1.10 2009/12/30 22:37: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.
*
* @(#)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 */
/*
* 8519376: Use an unnamed union to force the size of el_prompt_t to
* be the same, independent of the size of Char.
*/
union {
Char p_ignore; /* character to start/end literal */
wchar_t dummy;
};
int p_wide;
} el_prompt_t;
protected void prompt_print(EditLine *, int);
protected int prompt_set(EditLine *, el_pfunc_t, Char, int, int);
protected int prompt_get(EditLine *, el_pfunc_t *, Char *, int);
protected int prompt_init(EditLine *);
protected void prompt_end(EditLine *);
#endif /* _h_el_prompt */

731
src/read.c Normal file
View File

@ -0,0 +1,731 @@
/* $NetBSD: read.c,v 1.69 2012/09/11 12:31:08 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.69 2012/09/11 12:31:08 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 <limits.h>
#include "el.h"
#define OKCMD -1 /* must be -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, &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;
#ifndef WIDECHAR
/* FIONREAD attempts to buffer up multiple bytes, and to make that work
* properly with partial wide/UTF-8 characters would need some careful work. */
#ifdef FIONREAD
(void) ioctl(el->el_infd, FIONREAD, &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 */
#endif
return chrs > 0;
}
/* el_push():
* Push a macro
*/
public void
FUN(el,push)(EditLine *el, const 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] = Strdup(str)) != NULL)
return;
ma->level--;
}
terminal_beep(el);
terminal__flush(el);
}
/* read_getcmd():
* Get next command from the input stream, return OKCMD on success.
* Character values > 255 are not looked up in the map, but inserted.
*/
private int
read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
{
el_action_t cmd;
int num;
el->el_errno = 0;
do {
if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */
el->el_errno = num == 0 ? 0 : errno;
return 0; /* not OKCMD */
}
#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;
}
#ifdef WIDECHAR
if (*ch >= N_KEYS)
cmd = ED_INSERT;
else
#endif
cmd = el->el_map.current[(unsigned char) *ch];
if (cmd == ED_SEQUENCE_LEAD_IN) {
keymacro_value_t val;
switch (keymacro_get(el, ch, &val)) {
case XK_CMD:
cmd = val.cmd;
break;
case XK_STR:
FUN(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;
}
#ifdef WIDECHAR
/* utf8_islead():
* Test whether a byte is a leading byte of a UTF-8 sequence.
*/
private int
utf8_islead(int c)
{
return c < 0x80 || /* single byte char */
(c >= 0xc2 && c <= 0xf4); /* start of multibyte sequence */
}
#endif
/* read_char():
* Read a character from the tty.
*/
private int
read_char(EditLine *el, Char *cp)
{
ssize_t num_read;
int tried = 0;
char cbuf[MB_LEN_MAX];
size_t cbp = 0;
int bytes = 0;
again:
el->el_signal->sig_no = 0;
while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) {
int e = errno;
switch (el->el_signal->sig_no) {
case SIGCONT:
FUN(el,set)(el, EL_REFRESH);
/*FALLTHROUGH*/
case SIGWINCH:
sig_set(el);
goto again;
default:
break;
}
if (!tried && read__fixio(el->el_infd, e) == 0)
tried = 1;
else {
errno = e;
*cp = '\0';
return -1;
}
}
if (num_read == 0) return 0;
#ifdef WIDECHAR
if (el->el_flags & CHARSET_IS_UTF8) {
if (!utf8_islead((unsigned char)cbuf[0]))
goto again; /* discard the byte we read and try again */
++cbp;
if ((bytes = ct_mbtowc(cp, cbuf, cbp)) == -1) {
ct_mbtowc_reset;
if (cbp >= MB_LEN_MAX) { /* "shouldn't happen" */
errno = EILSEQ;
*cp = '\0';
return -1;
}
goto again;
}
} else if (isascii((unsigned char)cbuf[0]) ||
/* we don't support other multibyte charsets */
++cbp != 1 ||
/* Try non-ASCII characters in a 8-bit character set */
(bytes = ct_mbtowc(cp, cbuf, cbp)) != 1)
#endif
*cp = (unsigned char)cbuf[0];
if ((el->el_flags & IGNORE_EXTCHARS) && bytes > 1) {
cbp = 0; /* skip this character */
goto again;
}
return (int)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 = 0; i < ma->level; i++)
ma->macro[i] = ma->macro[i + 1];
ma->level--;
ma->offset = 0;
}
/* el_getc():
* Read a character
*/
public int
FUN(el,getc)(EditLine *el, Char *cp)
{
int num_read;
c_macro_t *ma = &el->el_chared.c_macro;
terminal__flush(el);
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++];
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);
if (num_read < 0)
el->el_errno = errno;
#ifdef WIDECHAR
if (el->el_flags & NARROW_READ)
*cp = *(char *)(void *)cp;
#endif
#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)
terminal__flush(el);
}
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 *
FUN(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, *cp;
int crlf = 0;
int nrb;
#ifdef FIONREAD
c_macro_t *ma = &el->el_chared.c_macro;
#endif /* FIONREAD */
if (nread == NULL)
nread = &nrb;
*nread = 0;
if (el->el_flags & NO_TTY) {
size_t idx;
cp = el->el_line.buffer;
while ((num = (*el->el_read.read_char)(el, cp)) == 1) {
/* make sure there is space for next character */
if (cp + 1 >= el->el_line.limit) {
idx = (size_t)(cp - el->el_line.buffer);
if (!ch_enlargebufs(el, (size_t)2))
break;
cp = &el->el_line.buffer[idx];
}
cp++;
if (el->el_flags & UNBUFFERED)
break;
if (cp[-1] == '\r' || cp[-1] == '\n')
break;
}
if (num == -1) {
if (errno == EINTR)
cp = el->el_line.buffer;
el->el_errno = errno;
} else if (num == 0) el->el_state.thiscmd = EL_EOF;
goto noedit;
}
#ifdef FIONREAD
if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
long chrs = 0;
(void) ioctl(el->el_infd, FIONREAD, &chrs);
if (chrs == 0) {
if (tty_rawmode(el) < 0) {
errno = 0;
*nread = 0;
return NULL;
}
}
}
#endif /* FIONREAD */
if ((el->el_flags & UNBUFFERED) == 0)
read_prepare(el);
if (el->el_flags & EDIT_DISABLED) {
size_t idx;
if ((el->el_flags & UNBUFFERED) == 0)
cp = el->el_line.buffer;
else
cp = el->el_line.lastchar;
terminal__flush(el);
while ((num = (*el->el_read.read_char)(el, cp)) == 1) {
/* make sure there is space next character */
if (cp + 1 >= el->el_line.limit) {
idx = (size_t)(cp - el->el_line.buffer);
if (!ch_enlargebufs(el, (size_t)2))
break;
cp = &el->el_line.buffer[idx];
}
cp++;
crlf = cp[-1] == '\r' || cp[-1] == '\n';
if (el->el_flags & UNBUFFERED)
break;
if (crlf)
break;
}
if (num == -1) {
if (errno == EINTR)
cp = el->el_line.buffer;
el->el_errno = errno;
} else if (num == 0) el->el_state.thiscmd = EL_EOF;
goto noedit;
}
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 */
if (num == 0) el->el_state.thiscmd = EL_EOF;
break;
}
if (el->el_errno == EINTR) {
el->el_line.buffer[0] = '\0';
el->el_line.lastchar =
el->el_line.cursor = el->el_line.buffer;
break;
}
if ((unsigned int)cmdnum >= (unsigned int)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(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);
terminal_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 = (int)(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 */
terminal_beep(el);
terminal__flush(el);
break;
}
el->el_state.argument = 1;
el->el_state.doingarg = 0;
el->el_chared.c_vcmd.action = NOP;
if (el->el_flags & UNBUFFERED)
break;
}
terminal__flush(el); /* flush any buffered output */
/* make sure the tty is set up correctly */
if ((el->el_flags & UNBUFFERED) == 0) {
read_finish(el);
*nread = num != -1 ? num : 0;
} else {
*nread = (int)(el->el_line.lastchar - el->el_line.buffer);
}
goto done;
noedit:
el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0';
*nread = (int)(el->el_line.cursor - el->el_line.buffer);
done:
if (*nread == 0) {
if (num == -1) {
*nread = -1;
errno = el->el_errno;
}
return NULL;
} else {
el->el_line.buffer[*nread] = 0;
return el->el_line.buffer;
}
}

50
src/read.h Normal file
View File

@ -0,0 +1,50 @@
/* $NetBSD: read.h,v 1.7 2009/12/30 22:37:40 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.
*
* 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 */

2305
src/readline.c Normal file

File diff suppressed because it is too large Load Diff

1183
src/refresh.c Normal file

File diff suppressed because it is too large Load Diff

59
src/refresh.h Normal file
View File

@ -0,0 +1,59 @@
/* $NetBSD: refresh.h,v 1.6 2009/12/30 22:37: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.
*
* @(#)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 */

642
src/search.c Normal file
View File

@ -0,0 +1,642 @@
/* $NetBSD: search.c,v 1.30 2011/10/04 15:27:04 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.30 2011/10/04 15:27:04 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 = el_malloc(EL_BUFSIZ *
sizeof(*el->el_search.patbuf));
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(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)
{
#ifdef WIDECHAR
static ct_buffer_t conv;
#endif
#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) != 0)
return 1;
#if defined(REGEX)
if (regcomp(&re, ct_encode_string(pat, &conv), 0) == 0) {
rv = regexec(&re, ct_encode_string(str, &conv), (size_t)0, NULL,
0) == 0;
regfree(&re);
} else {
rv = 0;
}
return rv;
#elif defined(REGEXP)
if ((re = regcomp(ct_encode_string(pat, &conv))) != NULL) {
rv = regexec(re, ct_encode_string(str, &conv));
el_free(re);
} else {
rv = 0;
}
return rv;
#else
if (re_comp(ct_encode_string(pat, &conv)) != NULL)
return 0;
else
return re_exec(ct_encode_string(str, &conv) == 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 =
(size_t)(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;
size_t oldpatlen = el->el_search.patlen;
int newdir = dir;
int done, redo;
if (el->el_line.lastchar + sizeof(STRfwd) /
sizeof(*el->el_line.lastchar) + 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 (FUN(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)
terminal_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
terminal_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) {
terminal_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)) {
terminal_beep(el);
break;
}
break;
default: /* Terminate and execute cmd */
endcmd[0] = ch;
FUN(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 = (el_action_t)
(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) {
terminal_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];
ssize_t 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 ? STR("\n/") : STR("\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) / 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 = (size_t)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, ct_encode_string(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 == (Int)-1) {
Char c;
if (FUN(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 = (char)tflag;
cp = el->el_line.cursor;
while (count--) {
if ((Int)*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 ((Int)*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;
}

73
src/search.h Normal file
View File

@ -0,0 +1,73 @@
/* $NetBSD: search.h,v 1.9 2009/12/30 22:37: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.
*
* @(#)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 */
/*
* 8519376: Use an unnamed union to force the size of el_search_t to
* be the same, independent of the size of Char.
*/
union {
Char chacha; /* Character we are looking for */
wchar_t dummy;
};
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 */

5
src/shlib_version Normal file
View File

@ -0,0 +1,5 @@
# $NetBSD: shlib_version,v 1.18 2009/01/11 03:07:48 christos Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
major=3
minor=0

200
src/sig.c Normal file
View File

@ -0,0 +1,200 @@
/* $NetBSD: sig.c,v 1.17 2011/07/28 20:50:55 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[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: sig.c,v 1.17 2011/07/28 20:50:55 christos 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);
sel->el_signal->sig_no = signo;
switch (signo) {
case SIGCONT:
tty_rawmode(sel);
if (ed_redisplay(sel, 0) == CC_REFRESH)
re_refresh(sel);
terminal__flush(sel);
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) sigaction(signo, &sel->el_signal->sig_action[i], NULL);
sel->el_signal->sig_action[i].sa_handler = SIG_ERR;
sel->el_signal->sig_action[i].sa_flags = 0;
sigemptyset(&sel->el_signal->sig_action[i].sa_mask);
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
(void) kill(0, signo);
}
/* sig_init():
* Initialize all signal stuff
*/
protected int
sig_init(EditLine *el)
{
size_t i;
sigset_t *nset, oset;
el->el_signal = el_malloc(sizeof(*el->el_signal));
if (el->el_signal == NULL)
return -1;
nset = &el->el_signal->sig_set;
(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->el_signal->sig_action[i].sa_handler = SIG_ERR;
el->el_signal->sig_action[i].sa_flags = 0;
sigemptyset(&el->el_signal->sig_action[i].sa_mask);
}
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
return 0;
}
/* sig_end():
* Clear all signal stuff
*/
protected void
sig_end(EditLine *el)
{
el_free(el->el_signal);
el->el_signal = NULL;
}
/* sig_set():
* set all the signal handlers
*/
protected void
sig_set(EditLine *el)
{
size_t i;
sigset_t oset;
struct sigaction osa, nsa;
nsa.sa_handler = sig_handler;
nsa.sa_flags = 0;
sigemptyset(&nsa.sa_mask);
(void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
/* 13009629: set sel before signal handlers just in case */
sel = el;
for (i = 0; sighdl[i] != -1; i++) {
/* This could happen if we get interrupted */
if (sigaction(sighdl[i], &nsa, &osa) != -1 &&
osa.sa_handler != sig_handler)
el->el_signal->sig_action[i] = osa;
}
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
}
/* sig_clr():
* clear all the signal handlers
*/
protected void
sig_clr(EditLine *el)
{
size_t i;
sigset_t oset;
(void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
for (i = 0; sighdl[i] != -1; i++)
if (el->el_signal->sig_action[i].sa_handler != SIG_ERR)
(void)sigaction(sighdl[i],
&el->el_signal->sig_action[i], NULL);
/* 13009629: no longer clear sel, since a signal handler may still be running in another thread */
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
}

72
src/sig.h Normal file
View File

@ -0,0 +1,72 @@
/* $NetBSD: sig.h,v 1.8 2009/02/19 15:20:22 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.
*
* @(#)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(SIGQUIT) \
_DO(SIGHUP) \
_DO(SIGTERM) \
_DO(SIGCONT) \
_DO(SIGWINCH)
#define ALLSIGSNO 7
typedef struct {
struct sigaction sig_action[ALLSIGSNO];
sigset_t sig_set;
volatile sig_atomic_t sig_no;
} *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 */

142
src/sys.h Normal file
View File

@ -0,0 +1,142 @@
/* $NetBSD: sys.h,v 1.17 2011/09/28 14:08:04 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
#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 _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 __arraycount
# define __arraycount(a) (sizeof(a) / sizeof(*(a)))
#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
#ifndef HAVE_WCSDUP
#include <wchar.h>
wchar_t *wcsdup(const wchar_t *);
#endif
#ifndef _DIAGASSERT
#define _DIAGASSERT(x)
#endif
#ifndef __RCSID
#define __RCSID(x)
#endif
#ifndef HAVE_U_INT32_T
typedef unsigned int u_int32_t;
#endif
#ifndef SIZE_T_MAX
#define SIZE_T_MAX ((size_t)-1)
#endif
#define REGEX /* Use POSIX.2 regular expression functions */
#undef REGEXP /* Use UNIX V8 regular expression functions */
#if defined(__sun)
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
#endif /* _h_sys */

1673
src/terminal.c Normal file

File diff suppressed because it is too large Load Diff

135
src/terminal.h Normal file
View File

@ -0,0 +1,135 @@
/* $NetBSD: terminal.h,v 1.4 2012/03/24 20:09: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.
*
* @(#)term.h 8.1 (Berkeley) 6/4/93
*/
/*
* el.term.h: Termcap header
*/
#ifndef _h_el_terminal
#define _h_el_terminal
#include "histedit.h"
typedef struct { /* Symbolic function key bindings */
const Char *name; /* name of the key */
int key; /* Index in termcap table */
keymacro_value_t fun; /* Function bound to it */
int type; /* Type of function */
} funckey_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 */
size_t t_loc; /* location used */
char **t_str; /* termcap strings */
int *t_val; /* termcap values */
char *t_cap; /* Termcap buffer */
funckey_t *t_fkey; /* Array of keys */
} el_terminal_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_DE 6
#define A_K_NKEYS 7
#ifdef __sun
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 terminal_move_to_line(EditLine *, int);
protected void terminal_move_to_char(EditLine *, int);
protected void terminal_clear_EOL(EditLine *, int);
protected void terminal_overwrite(EditLine *, const Char *, size_t);
protected void terminal_insertwrite(EditLine *, Char *, int);
protected void terminal_deletechars(EditLine *, int);
protected void terminal_clear_screen(EditLine *);
protected void terminal_beep(EditLine *);
protected int terminal_change_size(EditLine *, int, int);
protected int terminal_get_size(EditLine *, int *, int *);
protected int terminal_init(EditLine *);
protected void terminal_bind_arrow(EditLine *);
protected void terminal_print_arrow(EditLine *, const Char *);
protected int terminal_clear_arrow(EditLine *, const Char *);
protected int terminal_set_arrow(EditLine *, const Char *, keymacro_value_t *, int);
protected void terminal_end(EditLine *);
protected void terminal_get(EditLine *, const char **);
protected int terminal_set(EditLine *, const char *);
protected int terminal_settc(EditLine *, int, const Char **);
protected int terminal_gettc(EditLine *, int, char **);
protected int terminal_telltc(EditLine *, int, const Char **);
protected int terminal_echotc(EditLine *, int, const Char **);
protected void terminal_writec(EditLine *, Int);
protected int terminal__putc(EditLine *, Int);
protected void terminal__flush(EditLine *);
/*
* Easy access macros
*/
#define EL_FLAGS (el)->el_terminal.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_terminal */

453
src/tokenizer.c Normal file
View File

@ -0,0 +1,453 @@
/* $NetBSD: tokenizer.c,v 1.21 2011/08/16 16:25:15 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.
*/
#ifndef NARROWCHAR
#include "config.h"
#endif
#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.21 2011/08/16 16:25:15 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/* We build this file twice, once as NARROW, once as WIDE. */
/*
* tokenize.c: Bourne shell like tokenizer
*/
#include <string.h>
#include <stdlib.h>
#include "histedit.h"
#include "chartype.h"
typedef enum {
Q_none, Q_single, Q_double, Q_one, Q_doubleone
} quote_t;
#define TOK_KEEP 1
#define TOK_EAT 2
#define WINCR 20
#define AINCR 10
#define IFS STR("\t \n")
#define tok_malloc(a) malloc(a)
#define tok_free(a) free(a)
#define tok_realloc(a, b) realloc(a, b)
#define tok_strdup(a) Strdup(a)
struct TYPE(tokenizer) {
Char *ifs; /* In field separator */
size_t 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 FUN(tok,finish)(TYPE(Tokenizer) *);
/* FUN(tok,finish)():
* Finish a word in the tokenizer.
*/
private void
FUN(tok,finish)(TYPE(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;
}
/* FUN(tok,init)():
* Initialize the tokenizer
*/
public TYPE(Tokenizer) *
FUN(tok,init)(const Char *ifs)
{
TYPE(Tokenizer) *tok = tok_malloc(sizeof(*tok));
if (tok == NULL)
return NULL;
tok->ifs = tok_strdup(ifs ? ifs : IFS);
if (tok->ifs == NULL) {
tok_free(tok);
return NULL;
}
tok->argc = 0;
tok->amax = AINCR;
tok->argv = tok_malloc(sizeof(*tok->argv) * tok->amax);
if (tok->argv == NULL) {
tok_free(tok->ifs);
tok_free(tok);
return NULL;
}
tok->argv[0] = NULL;
tok->wspace = tok_malloc(WINCR * sizeof(*tok->wspace));
if (tok->wspace == NULL) {
tok_free(tok->argv);
tok_free(tok->ifs);
tok_free(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;
}
/* FUN(tok,reset)():
* Reset the tokenizer
*/
public void
FUN(tok,reset)(TYPE(Tokenizer) *tok)
{
tok->argc = 0;
tok->wstart = tok->wspace;
tok->wptr = tok->wspace;
tok->flags = 0;
tok->quote = Q_none;
}
/* FUN(tok,end)():
* Clean up
*/
public void
FUN(tok,end)(TYPE(Tokenizer) *tok)
{
tok_free(tok->ifs);
tok_free(tok->wspace);
tok_free(tok->argv);
tok_free(tok);
}
/* FUN(tok,line)():
* Bourne shell (sh(1)) like tokenizing
* Arguments:
* tok current tokenizer state (setup with FUN(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
FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(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 = STR("");
if (ptr == line->cursor) {
cc = (int)tok->argc;
co = (int)(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)
FUN(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 = (size_t)(tok->wmax - tok->wspace + WINCR);
Char *s = tok_realloc(tok->wspace,
size * sizeof(*s));
if (s == NULL)
return -1;
if (s != tok->wspace) {
size_t 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 = tok_realloc(tok->argv, tok->amax * sizeof(*p));
if (p == NULL)
return -1;
tok->argv = p;
}
}
tok_line_outok:
if (cc == -1 && co == -1) {
cc = (int)tok->argc;
co = (int)(tok->wptr - tok->wstart);
}
if (cursorc != NULL)
*cursorc = cc;
if (cursoro != NULL)
*cursoro = co;
FUN(tok,finish)(tok);
*argv = (const Char **)tok->argv;
*argc = (int)tok->argc;
return 0;
}
/* FUN(tok,str)():
* Simpler version of tok_line, taking a NUL terminated line
* and splitting into words, ignoring cursor state.
*/
public int
FUN(tok,str)(TYPE(Tokenizer) *tok, const Char *line, int *argc,
const Char ***argv)
{
TYPE(LineInfo) li;
memset(&li, 0, sizeof(li));
li.buffer = line;
li.cursor = li.lastchar = Strchr(line, '\0');
return FUN(tok,line(tok, &li, argc, argv, NULL, NULL));
}

1404
src/tty.c Normal file

File diff suppressed because it is too large Load Diff

481
src/tty.h Normal file
View File

@ -0,0 +1,481 @@
/* $NetBSD: tty.h,v 1.14 2012/05/15 15:59:01 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.
*
* @(#)tty.h 8.1 (Berkeley) 6/4/93
*/
/*
* el.tty.h: Local terminal header
*/
#ifndef _h_el_tty
#define _h_el_tty
#include "sys.h"
#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) ((unsigned int)(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_or, 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 */

554
src/unvis.c Normal file
View File

@ -0,0 +1,554 @@
/* $NetBSD: unvis.c,v 1.39 2012/03/13 21:13:37 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.39 2012/03/13 21:13:37 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <stdio.h>
#include <errno.h>
#include <vis.h>
#ifdef __weak_alias
__weak_alias(strnunvisx,_strnunvisx)
#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_HEX 7 /* mandatory hex digit */
#define S_HEX1 8 /* http hex digit */
#define S_HEX2 9 /* http hex digit 2 */
#define S_MIME1 10 /* mime hex digit 1 */
#define S_MIME2 11 /* mime hex digit 2 */
#define S_EATCRNL 12 /* mime eating CRNL */
#define S_AMP 13 /* seen & */
#define S_NUMBER 14 /* collecting number */
#define S_STRING 15 /* collecting string */
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10))
#define XTOD(c) (isdigit(c) ? (c - '0') : ((c - 'A') + 10))
/*
* RFC 1866
*/
static const struct nv {
const char *name;
uint8_t value;
} nv[] = {
{ "AElig", 198 }, /* capital AE diphthong (ligature) */
{ "Aacute", 193 }, /* capital A, acute accent */
{ "Acirc", 194 }, /* capital A, circumflex accent */
{ "Agrave", 192 }, /* capital A, grave accent */
{ "Aring", 197 }, /* capital A, ring */
{ "Atilde", 195 }, /* capital A, tilde */
{ "Auml", 196 }, /* capital A, dieresis or umlaut mark */
{ "Ccedil", 199 }, /* capital C, cedilla */
{ "ETH", 208 }, /* capital Eth, Icelandic */
{ "Eacute", 201 }, /* capital E, acute accent */
{ "Ecirc", 202 }, /* capital E, circumflex accent */
{ "Egrave", 200 }, /* capital E, grave accent */
{ "Euml", 203 }, /* capital E, dieresis or umlaut mark */
{ "Iacute", 205 }, /* capital I, acute accent */
{ "Icirc", 206 }, /* capital I, circumflex accent */
{ "Igrave", 204 }, /* capital I, grave accent */
{ "Iuml", 207 }, /* capital I, dieresis or umlaut mark */
{ "Ntilde", 209 }, /* capital N, tilde */
{ "Oacute", 211 }, /* capital O, acute accent */
{ "Ocirc", 212 }, /* capital O, circumflex accent */
{ "Ograve", 210 }, /* capital O, grave accent */
{ "Oslash", 216 }, /* capital O, slash */
{ "Otilde", 213 }, /* capital O, tilde */
{ "Ouml", 214 }, /* capital O, dieresis or umlaut mark */
{ "THORN", 222 }, /* capital THORN, Icelandic */
{ "Uacute", 218 }, /* capital U, acute accent */
{ "Ucirc", 219 }, /* capital U, circumflex accent */
{ "Ugrave", 217 }, /* capital U, grave accent */
{ "Uuml", 220 }, /* capital U, dieresis or umlaut mark */
{ "Yacute", 221 }, /* capital Y, acute accent */
{ "aacute", 225 }, /* small a, acute accent */
{ "acirc", 226 }, /* small a, circumflex accent */
{ "acute", 180 }, /* acute accent */
{ "aelig", 230 }, /* small ae diphthong (ligature) */
{ "agrave", 224 }, /* small a, grave accent */
{ "amp", 38 }, /* ampersand */
{ "aring", 229 }, /* small a, ring */
{ "atilde", 227 }, /* small a, tilde */
{ "auml", 228 }, /* small a, dieresis or umlaut mark */
{ "brvbar", 166 }, /* broken (vertical) bar */
{ "ccedil", 231 }, /* small c, cedilla */
{ "cedil", 184 }, /* cedilla */
{ "cent", 162 }, /* cent sign */
{ "copy", 169 }, /* copyright sign */
{ "curren", 164 }, /* general currency sign */
{ "deg", 176 }, /* degree sign */
{ "divide", 247 }, /* divide sign */
{ "eacute", 233 }, /* small e, acute accent */
{ "ecirc", 234 }, /* small e, circumflex accent */
{ "egrave", 232 }, /* small e, grave accent */
{ "eth", 240 }, /* small eth, Icelandic */
{ "euml", 235 }, /* small e, dieresis or umlaut mark */
{ "frac12", 189 }, /* fraction one-half */
{ "frac14", 188 }, /* fraction one-quarter */
{ "frac34", 190 }, /* fraction three-quarters */
{ "gt", 62 }, /* greater than */
{ "iacute", 237 }, /* small i, acute accent */
{ "icirc", 238 }, /* small i, circumflex accent */
{ "iexcl", 161 }, /* inverted exclamation mark */
{ "igrave", 236 }, /* small i, grave accent */
{ "iquest", 191 }, /* inverted question mark */
{ "iuml", 239 }, /* small i, dieresis or umlaut mark */
{ "laquo", 171 }, /* angle quotation mark, left */
{ "lt", 60 }, /* less than */
{ "macr", 175 }, /* macron */
{ "micro", 181 }, /* micro sign */
{ "middot", 183 }, /* middle dot */
{ "nbsp", 160 }, /* no-break space */
{ "not", 172 }, /* not sign */
{ "ntilde", 241 }, /* small n, tilde */
{ "oacute", 243 }, /* small o, acute accent */
{ "ocirc", 244 }, /* small o, circumflex accent */
{ "ograve", 242 }, /* small o, grave accent */
{ "ordf", 170 }, /* ordinal indicator, feminine */
{ "ordm", 186 }, /* ordinal indicator, masculine */
{ "oslash", 248 }, /* small o, slash */
{ "otilde", 245 }, /* small o, tilde */
{ "ouml", 246 }, /* small o, dieresis or umlaut mark */
{ "para", 182 }, /* pilcrow (paragraph sign) */
{ "plusmn", 177 }, /* plus-or-minus sign */
{ "pound", 163 }, /* pound sterling sign */
{ "quot", 34 }, /* double quote */
{ "raquo", 187 }, /* angle quotation mark, right */
{ "reg", 174 }, /* registered sign */
{ "sect", 167 }, /* section sign */
{ "shy", 173 }, /* soft hyphen */
{ "sup1", 185 }, /* superscript one */
{ "sup2", 178 }, /* superscript two */
{ "sup3", 179 }, /* superscript three */
{ "szlig", 223 }, /* small sharp s, German (sz ligature) */
{ "thorn", 254 }, /* small thorn, Icelandic */
{ "times", 215 }, /* multiply sign */
{ "uacute", 250 }, /* small u, acute accent */
{ "ucirc", 251 }, /* small u, circumflex accent */
{ "ugrave", 249 }, /* small u, grave accent */
{ "uml", 168 }, /* umlaut (dieresis) */
{ "uuml", 252 }, /* small u, dieresis or umlaut mark */
{ "yacute", 253 }, /* small y, acute accent */
{ "yen", 165 }, /* yen sign */
{ "yuml", 255 }, /* small y, dieresis or umlaut mark */
};
/*
* unvis - decode characters previously encoded by vis
*/
int
unvis(char *cp, int c, int *astate, int flag)
{
unsigned char uc = (unsigned char)c;
unsigned char st, ia, is, lc;
/*
* Bottom 8 bits of astate hold the state machine state.
* Top 8 bits hold the current character in the http 1866 nv string decoding
*/
#define GS(a) ((a) & 0xff)
#define SS(a, b) (((uint32_t)(a) << 24) | (b))
#define GI(a) ((uint32_t)(a) >> 24)
_DIAGASSERT(cp != NULL);
_DIAGASSERT(astate != NULL);
st = GS(*astate);
if (flag & UNVIS_END) {
switch (st) {
case S_OCTAL2:
case S_OCTAL3:
case S_HEX2:
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case S_GROUND:
return UNVIS_NOCHAR;
default:
return UNVIS_SYNBAD;
}
}
switch (st) {
case S_GROUND:
*cp = 0;
if ((flag & VIS_NOESCAPE) == 0 && c == '\\') {
*astate = SS(0, S_START);
return UNVIS_NOCHAR;
}
if ((flag & VIS_HTTP1808) && c == '%') {
*astate = SS(0, S_HEX1);
return UNVIS_NOCHAR;
}
if ((flag & VIS_HTTP1866) && c == '&') {
*astate = SS(0, S_AMP);
return UNVIS_NOCHAR;
}
if ((flag & VIS_MIMESTYLE) && c == '=') {
*astate = SS(0, S_MIME1);
return UNVIS_NOCHAR;
}
*cp = c;
return UNVIS_VALID;
case S_START:
switch(c) {
case '\\':
*cp = c;
*astate = SS(0, 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 = SS(0, S_OCTAL2);
return UNVIS_NOCHAR;
case 'M':
*cp = (char)0200;
*astate = SS(0, S_META);
return UNVIS_NOCHAR;
case '^':
*astate = SS(0, S_CTRL);
return UNVIS_NOCHAR;
case 'n':
*cp = '\n';
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'r':
*cp = '\r';
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'b':
*cp = '\b';
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'a':
*cp = '\007';
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'v':
*cp = '\v';
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 't':
*cp = '\t';
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'f':
*cp = '\f';
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 's':
*cp = ' ';
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'E':
*cp = '\033';
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case 'x':
*astate = SS(0, S_HEX);
return UNVIS_NOCHAR;
case '\n':
/*
* hidden newline
*/
*astate = SS(0, S_GROUND);
return UNVIS_NOCHAR;
case '$':
/*
* hidden marker
*/
*astate = SS(0, S_GROUND);
return UNVIS_NOCHAR;
}
goto bad;
case S_META:
if (c == '-')
*astate = SS(0, S_META1);
else if (c == '^')
*astate = SS(0, S_CTRL);
else
goto bad;
return UNVIS_NOCHAR;
case S_META1:
*astate = SS(0, S_GROUND);
*cp |= c;
return UNVIS_VALID;
case S_CTRL:
if (c == '?')
*cp |= 0177;
else
*cp |= c & 037;
*astate = SS(0, 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 = SS(0, S_OCTAL3);
return UNVIS_NOCHAR;
}
/*
* no - done with current sequence, push back passed char
*/
*astate = SS(0, S_GROUND);
return UNVIS_VALIDPUSH;
case S_OCTAL3: /* third possible octal digit */
*astate = SS(0, 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_HEX:
if (!isxdigit(uc))
goto bad;
/*FALLTHROUGH*/
case S_HEX1:
if (isxdigit(uc)) {
*cp = xtod(uc);
*astate = SS(0, S_HEX2);
return UNVIS_NOCHAR;
}
/*
* no - done with current sequence, push back passed char
*/
*astate = SS(0, 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;
case S_MIME1:
if (uc == '\n' || uc == '\r') {
*astate = SS(0, S_EATCRNL);
return UNVIS_NOCHAR;
}
if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) {
*cp = XTOD(uc);
*astate = SS(0, S_MIME2);
return UNVIS_NOCHAR;
}
goto bad;
case S_MIME2:
if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) {
*astate = SS(0, S_GROUND);
*cp = XTOD(uc) | (*cp << 4);
return UNVIS_VALID;
}
goto bad;
case S_EATCRNL:
switch (uc) {
case '\r':
case '\n':
return UNVIS_NOCHAR;
case '=':
*astate = SS(0, S_MIME1);
return UNVIS_NOCHAR;
default:
*cp = uc;
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
}
case S_AMP:
*cp = 0;
if (uc == '#') {
*astate = SS(0, S_NUMBER);
return UNVIS_NOCHAR;
}
*astate = SS(0, S_STRING);
/*FALLTHROUGH*/
case S_STRING:
ia = *cp; /* index in the array */
is = GI(*astate); /* index in the string */
lc = is == 0 ? 0 : nv[ia].name[is - 1]; /* last character */
if (uc == ';')
uc = '\0';
for (; ia < __arraycount(nv); ia++) {
if (is != 0 && nv[ia].name[is - 1] != lc)
goto bad;
if (nv[ia].name[is] == uc)
break;
}
if (ia == __arraycount(nv))
goto bad;
if (uc != 0) {
*cp = ia;
*astate = SS(is + 1, S_STRING);
return UNVIS_NOCHAR;
}
*cp = nv[ia].value;
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case S_NUMBER:
if (uc == ';')
return UNVIS_VALID;
if (!isdigit(uc))
goto bad;
*cp += (*cp * 10) + uc - '0';
return UNVIS_NOCHAR;
default:
bad:
/*
* decoder in unknown state - (probably uninitialized)
*/
*astate = SS(0, S_GROUND);
return UNVIS_SYNBAD;
}
}
/*
* strnunvisx - decode src into dst
*
* Number of chars decoded into dst is returned, -1 on error.
* Dst is null terminated.
*/
int
strnunvisx(char *dst, size_t dlen, const char *src, int flag)
{
char c;
char t = '\0', *start = dst;
int state = 0;
_DIAGASSERT(src != NULL);
_DIAGASSERT(dst != NULL);
#define CHECKSPACE() \
do { \
if (dlen-- == 0) { \
errno = ENOSPC; \
return -1; \
} \
} while (/*CONSTCOND*/0)
while ((c = *src++) != '\0') {
again:
switch (unvis(&t, c, &state, flag)) {
case UNVIS_VALID:
CHECKSPACE();
*dst++ = t;
break;
case UNVIS_VALIDPUSH:
CHECKSPACE();
*dst++ = t;
goto again;
case 0:
case UNVIS_NOCHAR:
break;
case UNVIS_SYNBAD:
errno = EINVAL;
return -1;
default:
_DIAGASSERT(/*CONSTCOND*/0);
errno = EINVAL;
return -1;
}
}
if (unvis(&t, c, &state, UNVIS_END) == UNVIS_VALID) {
CHECKSPACE();
*dst++ = t;
}
CHECKSPACE();
*dst = '\0';
return (int)(dst - start);
}
int
strunvisx(char *dst, const char *src, int flag)
{
return strnunvisx(dst, (size_t)~0, src, flag);
}
int
strunvis(char *dst, const char *src)
{
return strnunvisx(dst, (size_t)~0, src, 0);
}
int
strnunvis(char *dst, size_t dlen, const char *src)
{
return strnunvisx(dst, dlen, src, 0);
}
#endif

1158
src/vi.c Normal file

File diff suppressed because it is too large Load Diff

574
src/vis.c Normal file
View File

@ -0,0 +1,574 @@
/* $NetBSD: vis.c,v 1.44 2011/03/12 19:52:48 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.
*
* 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.
*/
#include "config.h"
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: vis.c,v 1.44 2011/03/12 19:52:48 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <assert.h>
#include <vis.h>
#include <errno.h>
#include <stdlib.h>
#ifdef __weak_alias
__weak_alias(strvisx,_strvisx)
#endif
#if !HAVE_VIS || !HAVE_SVIS
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
static char *do_svis(char *, size_t *, int, int, int, const char *);
#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 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 do_hvis, for HTTP style (RFC 1808)
*/
static char *
do_hvis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra)
{
if ((isascii(c) && isalnum(c))
/* safe */
|| c == '$' || c == '-' || c == '_' || c == '.' || c == '+'
/* extra */
|| c == '!' || c == '*' || c == '\'' || c == '(' || c == ')'
|| c == ',') {
dst = do_svis(dst, dlen, c, flag, nextc, extra);
} else {
if (dlen) {
if (*dlen < 3)
return NULL;
*dlen -= 3;
}
*dst++ = '%';
*dst++ = xtoa(((unsigned int)c >> 4) & 0xf);
*dst++ = xtoa((unsigned int)c & 0xf);
}
return dst;
}
/*
* This is do_mvis, for Quoted-Printable MIME (RFC 2045)
* NB: No handling of long lines or CRLF.
*/
static char *
do_mvis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra)
{
if ((c != '\n') &&
/* Space at the end of the line */
((isspace(c) && (nextc == '\r' || nextc == '\n')) ||
/* Out of range */
(!isspace(c) && (c < 33 || (c > 60 && c < 62) || c > 126)) ||
/* Specific char to be escaped */
strchr("#$@[\\]^`{|}~", c) != NULL)) {
if (dlen) {
if (*dlen < 3)
return NULL;
*dlen -= 3;
}
*dst++ = '=';
*dst++ = XTOA(((unsigned int)c >> 4) & 0xf);
*dst++ = XTOA((unsigned int)c & 0xf);
} else {
dst = do_svis(dst, dlen, c, flag, nextc, extra);
}
return dst;
}
/*
* This is do_vis, the central code 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.
*/
static char *
do_svis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra)
{
int isextra;
size_t odlen = dlen ? *dlen : 0;
isextra = strchr(extra, c) != NULL;
#define HAVE(x) \
do { \
if (dlen) { \
if (*dlen < (x)) \
goto out; \
*dlen -= (x); \
} \
} while (/*CONSTCOND*/0)
if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) ||
((flag & VIS_SAFE) && issafe(c)))) {
HAVE(1);
*dst++ = c;
return dst;
}
if (flag & VIS_CSTYLE) {
HAVE(2);
switch (c) {
case '\n':
*dst++ = '\\'; *dst++ = 'n';
return dst;
case '\r':
*dst++ = '\\'; *dst++ = 'r';
return dst;
case '\b':
*dst++ = '\\'; *dst++ = 'b';
return dst;
case BELL:
*dst++ = '\\'; *dst++ = 'a';
return dst;
case '\v':
*dst++ = '\\'; *dst++ = 'v';
return dst;
case '\t':
*dst++ = '\\'; *dst++ = 't';
return dst;
case '\f':
*dst++ = '\\'; *dst++ = 'f';
return dst;
case ' ':
*dst++ = '\\'; *dst++ = 's';
return dst;
case '\0':
*dst++ = '\\'; *dst++ = '0';
if (isoctal(nextc)) {
HAVE(2);
*dst++ = '0';
*dst++ = '0';
}
return dst;
default:
if (isgraph(c)) {
*dst++ = '\\'; *dst++ = c;
return dst;
}
if (dlen)
*dlen = odlen;
}
}
if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
HAVE(4);
*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) {
HAVE(1);
*dst++ = '\\';
}
if (c & 0200) {
HAVE(1);
c &= 0177; *dst++ = 'M';
}
if (iscntrl(c)) {
HAVE(2);
*dst++ = '^';
if (c == 0177)
*dst++ = '?';
else
*dst++ = c + '@';
} else {
HAVE(2);
*dst++ = '-'; *dst++ = c;
}
}
return dst;
out:
*dlen = odlen;
return NULL;
}
typedef char *(*visfun_t)(char *, size_t *, int, int, int, const char *);
/*
* Return the appropriate encoding function depending on the flags given.
*/
static visfun_t
getvisfun(int flag)
{
if (flag & VIS_HTTPSTYLE)
return do_hvis;
if (flag & VIS_MIMESTYLE)
return do_mvis;
return do_svis;
}
/*
* isnvis - visually encode characters, also encoding the characters
* pointed to by `extra'
*/
static char *
isnvis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra)
{
char *nextra = NULL;
visfun_t f;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(extra != NULL);
MAKEEXTRALIST(flag, nextra, extra);
if (!nextra) {
if (dlen && *dlen == 0) {
errno = ENOSPC;
return NULL;
}
*dst = '\0'; /* can't create nextra, return "" */
return dst;
}
f = getvisfun(flag);
dst = (*f)(dst, dlen, c, flag, nextc, nextra);
free(nextra);
if (dst == NULL || (dlen && *dlen == 0)) {
errno = ENOSPC;
return NULL;
}
*dst = '\0';
return dst;
}
char *
svis(char *dst, int c, int flag, int nextc, const char *extra)
{
return isnvis(dst, NULL, c, flag, nextc, extra);
}
char *
snvis(char *dst, size_t dlen, int c, int flag, int nextc, const char *extra)
{
return isnvis(dst, &dlen, c, flag, nextc, extra);
}
/*
* 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.
*/
static int
istrsnvis(char *dst, size_t *dlen, const char *csrc, int flag, const char *extra)
{
int c;
char *start;
char *nextra = NULL;
const unsigned char *src = (const unsigned char *)csrc;
visfun_t f;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
_DIAGASSERT(extra != NULL);
MAKEEXTRALIST(flag, nextra, extra);
if (!nextra) {
*dst = '\0'; /* can't create nextra, return "" */
return 0;
}
f = getvisfun(flag);
for (start = dst; (c = *src++) != '\0'; /* empty */) {
dst = (*f)(dst, dlen, c, flag, *src, nextra);
if (dst == NULL) {
errno = ENOSPC;
return -1;
}
}
free(nextra);
if (dlen && *dlen == 0) {
errno = ENOSPC;
return -1;
}
*dst = '\0';
return (int)(dst - start);
}
int
strsvis(char *dst, const char *csrc, int flag, const char *extra)
{
return istrsnvis(dst, NULL, csrc, flag, extra);
}
int
strsnvis(char *dst, size_t dlen, const char *csrc, int flag, const char *extra)
{
return istrsnvis(dst, &dlen, csrc, flag, extra);
}
static int
istrsnvisx(char *dst, size_t *dlen, 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;
visfun_t f;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
_DIAGASSERT(extra != NULL);
MAKEEXTRALIST(flag, nextra, extra);
if (! nextra) {
if (dlen && *dlen == 0) {
errno = ENOSPC;
return -1;
}
*dst = '\0'; /* can't create nextra, return "" */
return 0;
}
f = getvisfun(flag);
for (start = dst; len > 0; len--) {
c = *src++;
dst = (*f)(dst, dlen, c, flag, len > 1 ? *src : '\0', nextra);
if (dst == NULL) {
errno = ENOSPC;
return -1;
}
}
free(nextra);
if (dlen && *dlen == 0) {
errno = ENOSPC;
return -1;
}
*dst = '\0';
return (int)(dst - start);
}
int
strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra)
{
return istrsnvisx(dst, NULL, csrc, len, flag, extra);
}
int
strsnvisx(char *dst, size_t dlen, const char *csrc, size_t len, int flag,
const char *extra)
{
return istrsnvisx(dst, &dlen, csrc, len, flag, extra);
}
#endif
#if !HAVE_VIS
/*
* vis - visually encode characters
*/
static char *
invis(char *dst, size_t *dlen, int c, int flag, int nextc)
{
char *extra = NULL;
unsigned char uc = (unsigned char)c;
visfun_t f;
_DIAGASSERT(dst != NULL);
MAKEEXTRALIST(flag, extra, "");
if (! extra) {
if (dlen && *dlen == 0) {
errno = ENOSPC;
return NULL;
}
*dst = '\0'; /* can't create extra, return "" */
return dst;
}
f = getvisfun(flag);
dst = (*f)(dst, dlen, uc, flag, nextc, extra);
free(extra);
if (dst == NULL || (dlen && *dlen == 0)) {
errno = ENOSPC;
return NULL;
}
*dst = '\0';
return dst;
}
char *
vis(char *dst, int c, int flag, int nextc)
{
return invis(dst, NULL, c, flag, nextc);
}
char *
nvis(char *dst, size_t dlen, int c, int flag, int nextc)
{
return invis(dst, &dlen, c, flag, nextc);
}
/*
* 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.
*/
static int
istrnvis(char *dst, size_t *dlen, const char *src, int flag)
{
char *extra = NULL;
int rv;
MAKEEXTRALIST(flag, extra, "");
if (!extra) {
if (dlen && *dlen == 0) {
errno = ENOSPC;
return -1;
}
*dst = '\0'; /* can't create extra, return "" */
return 0;
}
rv = istrsnvis(dst, dlen, src, flag, extra);
free(extra);
return rv;
}
int
strvis(char *dst, const char *src, int flag)
{
return istrnvis(dst, NULL, src, flag);
}
int
strnvis(char *dst, size_t dlen, const char *src, int flag)
{
return istrnvis(dst, &dlen, src, flag);
}
static int
istrnvisx(char *dst, size_t *dlen, const char *src, size_t len, int flag)
{
char *extra = NULL;
int rv;
MAKEEXTRALIST(flag, extra, "");
if (!extra) {
if (dlen && *dlen == 0) {
errno = ENOSPC;
return -1;
}
*dst = '\0'; /* can't create extra, return "" */
return 0;
}
rv = istrsnvisx(dst, dlen, src, len, flag, extra);
free(extra);
return rv;
}
int
strvisx(char *dst, const char *src, size_t len, int flag)
{
return istrnvisx(dst, NULL, src, len, flag);
}
int
strnvisx(char *dst, size_t dlen, const char *src, size_t len, int flag)
{
return istrnvisx(dst, &dlen, src, len, flag);
}
#endif

108
src/vis.h Normal file
View File

@ -0,0 +1,108 @@
/* $NetBSD: vis.h,v 1.19 2011/03/12 19:52:45 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_
/*
* to select alternate encoding format
*/
#define VIS_OCTAL 0x001 /* use octal \ddd format */
#define VIS_CSTYLE 0x002 /* 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 0x004 /* also encode space */
#define VIS_TAB 0x008 /* also encode tab */
#define VIS_NL 0x010 /* also encode newline */
#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
#define VIS_SAFE 0x020 /* only encode "unsafe" characters */
/*
* other
*/
#define VIS_NOSLASH 0x040 /* inhibit printing '\' */
#define VIS_HTTP1808 0x080 /* http-style escape % hex hex */
#define VIS_HTTPSTYLE 0x080 /* http-style escape % hex hex */
#define VIS_MIMESTYLE 0x100 /* mime-style escape = HEX HEX */
#define VIS_HTTP1866 0x200 /* http-style &#num; or &string; */
#define VIS_NOESCAPE 0x400 /* don't decode `\' */
#define _VIS_END 0x800 /* for unvis */
/*
* 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 _VIS_END /* no more characters */
__BEGIN_DECLS
char *vis(char *, int, int, int);
char *nvis(char *, size_t, int, int, int);
char *svis(char *, int, int, int, const char *);
char *snvis(char *, size_t, int, int, int, const char *);
int strvis(char *, const char *, int);
int strnvis(char *, size_t, const char *, int);
int strsvis(char *, const char *, int, const char *);
int strsnvis(char *, size_t, const char *, int, const char *);
int strvisx(char *, const char *, size_t, int);
int strnvisx(char *, size_t, const char *, size_t, int);
int strsvisx(char *, const char *, size_t, int, const char *);
int strsnvisx(char *, size_t, const char *, size_t, int, const char *);
int strunvis(char *, const char *);
int strnunvis(char *, size_t, const char *);
int strunvisx(char *, const char *, int);
int strnunvisx(char *, size_t, const char *, int);
#ifndef __LIBC12_SOURCE__
int unvis(char *, int, int *, int);
#endif
__END_DECLS
#endif /* !_VIS_H_ */

43
src/wcsdup.c Normal file
View File

@ -0,0 +1,43 @@
/* $NetBSD: wcsdup.c,v 1.3 2008/05/26 13:17:48 haad Exp $ */
/*
* Copyright (C) 2006 Aleksey Cheusov
*
* This material is provided "as is", with absolutely no warranty expressed
* or implied. Any use is at your own risk.
*
* Permission to use or copy this software for any purpose is hereby granted
* without fee. Permission to modify the code and to distribute modified
* code is also granted without any restrictions.
*/
#ifndef HAVE_WCSDUP
#include "config.h"
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: wcsdup.c,v 1.3 2008/05/26 13:17:48 haad Exp $");
#endif /* LIBC_SCCS and not lint */
#include <stdlib.h>
#include <assert.h>
#include <wchar.h>
wchar_t *
wcsdup(const wchar_t *str)
{
wchar_t *copy;
size_t len;
_DIAGASSERT(str != NULL);
len = wcslen(str) + 1;
copy = malloc(len * sizeof (wchar_t));
if (!copy)
return NULL;
return wmemcpy(copy, str, len);
}
#endif

255
unexports Normal file
View File

@ -0,0 +1,255 @@
___ct_decode_string
___ct_encode_string
___edit_3VersionNumber
___edit_3VersionString
_c__next_word
_c__prev_word
_c_delafter
_c_delafter1
_c_delbefore
_c_delbefore1
_c_gets
_c_hmatch
_c_hpos
_c_insert
_c_setpat
_ce__isword
_ce_inc_search
_ce_search_line
_ch_end
_ch_enlargebufs
_ch_init
_ch_reset
_ch_resizefun
_ct_chr_class
_ct_conv_buff_resize
_ct_decode_argv
_ct_enc_width
_ct_encode_char
_ct_visual_char
_ct_visual_string
_ct_visual_width
_cv__endword
_cv__isWord
_cv__isword
_cv_csearch
_cv_delfini
_cv_next_word
_cv_prev_word
_cv_repeat_srch
_cv_search
_cv_undo
_cv_yank
_ed_argument_digit
_ed_clear_screen
_ed_command
_ed_delete_next_char
_ed_delete_prev_char
_ed_delete_prev_word
_ed_digit
_ed_end_of_file
_ed_insert
_ed_kill_line
_ed_move_to_beg
_ed_move_to_end
_ed_newline
_ed_next_char
_ed_next_history
_ed_next_line
_ed_prev_char
_ed_prev_history
_ed_prev_line
_ed_prev_word
_ed_quoted_insert
_ed_redisplay
_ed_search_next_history
_ed_search_prev_history
_ed_sequence_lead_in
_ed_start_over
_ed_transpose_chars
_ed_tty_dsusp
_ed_tty_flush_output
_ed_tty_sigint
_ed_tty_sigquit
_ed_tty_sigtstp
_ed_tty_start_output
_ed_tty_stop_output
_ed_unassigned
_el_editmode
_el_match
_el_read_getfn
_el_read_setfn
_em_capitol_case
_em_copy_prev_word
_em_copy_region
_em_delete_next_word
_em_delete_or_list
_em_delete_prev_char
_em_exchange_mark
_em_gosmacs_transpose
_em_inc_search_next
_em_inc_search_prev
_em_kill_line
_em_kill_region
_em_lower_case
_em_meta_next
_em_next_word
_em_set_mark
_em_toggle_overwrite
_em_universal_argument
_em_upper_case
_em_yank
_fn_complete
_fn_display_match_list
_fn_filename_completion_function
_fn_tilde_expand
_func__get
_help__get
_hist_command
_hist_convert
_hist_end
_hist_enlargebuf
_hist_get
_hist_init
_hist_set
_history_expansion_char
_history_inhibit_expansion_function
_history_no_expand_chars
_history_subst_char
_keymacro__decode_str
_keymacro_add
_keymacro_clear
_keymacro_delete
_keymacro_end
_keymacro_get
_keymacro_init
_keymacro_kprint
_keymacro_map_cmd
_keymacro_map_str
_keymacro_print
_keymacro_reset
_map_addfunc
_map_bind
_map_end
_map_get_editor
_map_init
_map_init_emacs
_map_init_vi
_map_set_editor
_parse__escape
_parse__string
_parse_cmd
_parse_line
_prompt_end
_prompt_get
_prompt_init
_prompt_print
_prompt_set
_re_clear_display
_re_clear_lines
_re_fastaddc
_re_goto_bottom
_re_putc
_re_refresh
_re_refresh_cursor
_read_finish
_read_init
_read_prepare
_rl_catch_signals
_rl_done
_rl_event_hook
_rl_linefunc
_rl_startup1_hook
_search_end
_search_init
_sig_clr
_sig_end
_sig_init
_sig_set
_snvis
_strsnvis
_strsnvisx
_strsvis
_strsvisx
_svis
_terminal__flush
_terminal__putc
_terminal_beep
_terminal_bind_arrow
_terminal_change_size
_terminal_clear_EOL
_terminal_clear_arrow
_terminal_clear_screen
_terminal_deletechars
_terminal_echotc
_terminal_end
_terminal_get
_terminal_get_size
_terminal_gettc
_terminal_init
_terminal_insertwrite
_terminal_move_to_char
_terminal_move_to_line
_terminal_overwrite
_terminal_print_arrow
_terminal_set
_terminal_set_arrow
_terminal_settc
_terminal_telltc
_terminal_writec
_tty_bind_char
_tty_cookedmode
_tty_end
_tty_init
_tty_noquotemode
_tty_quotemode
_tty_rawmode
_tty_stty
_vi_add
_vi_add_at_eol
_vi_alias
_vi_change_case
_vi_change_meta
_vi_change_to_eol
_vi_command_mode
_vi_comment_out
_vi_delete_meta
_vi_delete_prev_char
_vi_end_big_word
_vi_end_word
_vi_histedit
_vi_history_word
_vi_insert
_vi_insert_at_bol
_vi_kill_line_prev
_vi_list_or_eof
_vi_match
_vi_next_big_word
_vi_next_char
_vi_next_word
_vi_paste_next
_vi_paste_prev
_vi_prev_big_word
_vi_prev_char
_vi_prev_word
_vi_redo
_vi_repeat_next_char
_vi_repeat_prev_char
_vi_repeat_search_next
_vi_repeat_search_prev
_vi_replace_char
_vi_replace_mode
_vi_search_next
_vi_search_prev
_vi_substitute_char
_vi_substitute_line
_vi_to_column
_vi_to_history_line
_vi_to_next_char
_vi_to_prev_char
_vi_undo
_vi_undo_line
_vi_yank
_vi_yank_end
_vi_zero
_wcsdup

View File

@ -0,0 +1,43 @@
#!/bin/sh
set -ex
mkdir -p $DSTROOT/usr/include/readline $DSTROOT/usr/include/editline
install -g $ALTERNATE_GROUP -o $ALTERNATE_OWNER -m $ALTERNATE_MODE $SRCROOT/src/histedit.h $DSTROOT/usr/include
install -g $ALTERNATE_GROUP -o $ALTERNATE_OWNER -m $ALTERNATE_MODE $SRCROOT/src/editline/readline.h $DSTROOT/usr/include/editline
for h in readline.h history.h ; do
ln -s -f ../editline/readline.h $DSTROOT/usr/include/readline/$h
done
[ "$ACTION" == "installhdrs" ] && exit 0
if [ "${RC_ProjectName%_Sim}" != "${RC_ProjectName}" ] ; then
[ -z "${DSTROOT}" ] && exit 1
# Don't keep static libraries for the simulator SDK
rm -rf ${DSTROOT}/usr/local/lib
fi
mkdir -p $DSTROOT/usr/lib
for l in libedit.2.tbd libedit.3.0.tbd libedit.tbd libreadline.tbd ; do
ln -s -f libedit.3.tbd $DSTROOT/usr/lib/$l
done
[ "$ACTION" == "installapi" ] && exit 0
for l in libedit.2.dylib libedit.3.0.dylib libedit.dylib libreadline.dylib ; do
ln -s -f libedit.3.dylib $DSTROOT/usr/lib/$l
done
if [ "${RC_ProjectName%_Sim}" == "${RC_ProjectName}" ] ; then
mkdir -p $DSTROOT/usr/share/man/man{3,5}
install -m 0644 $SRCROOT/doc/editrc.5 $DSTROOT/usr/share/man/man5
install -m 0644 $SRCROOT/doc/editline.3 $DSTROOT/usr/share/man/man3
for m in el_deletestr.3 el_end.3 el_get.3 el_getc.3 el_gets.3 el_history.3 el_history_end.3 el_history_init.3 el_init.3 el_insertstr.3 el_line.3 el_parse.3 el_push.3 el_reset.3 el_resize.3 el_set.3 el_source.3 el_tok_end.3 el_tok_init.3 el_tok_line.3 el_tok_reset.3 el_tok_str.3 ; do
ln -s -f editline.3 $DSTROOT/usr/share/man/man3/$m
done
fi
mkdir -p $DSTROOT/usr/local/OpenSource{Licenses,Versions}
install -g $ALTERNATE_GROUP -o $ALTERNATE_OWNER -m a=r $SRCROOT/local/libedit.plist $DSTROOT/usr/local/OpenSourceVersions
/usr/bin/sed -e '1,2d' -e '/^$/,$d' $SRCROOT/src/el.c >$DSTROOT/usr/local/OpenSourceLicenses/libedit.txt

View File

@ -0,0 +1,34 @@
#include "<DEVELOPER_DIR>/Makefiles/CoreOS/Xcode/BSD.xcconfig"
ARCHS = $(ARCHS_STANDARD_32_64_BIT)
ONLY_ACTIVE_ARCH = NO
DEBUG_INFORMATION_FORMAT = dwarf-with-dsym
CODE_SIGN_IDENTITY = -
INSTALL_PATH = /usr/lib
COPY_PHASE_STRIP = YES
STRIP_INSTALLED_PRODUCT = YES
STRIP_STYLE = non-global
DYLIB_COMPATIBILITY_VERSION = 2
DYLIB_CURRENT_VERSION = 3.0
DEAD_CODE_STRIPPING = YES
EXECUTABLE_PREFIX = lib
PRODUCT_NAME = edit.3
ALWAYS_SEARCH_USER_PATHS = NO
USER_HEADER_SEARCH_PATHS = src
CURRENT_PROJECT_VERSION = $(RC_ProjectSourceVersion)
VERSION_INFO_PREFIX = __
VERSIONING_SYSTEM = apple-generic
GCC_C_LANGUAGE_STANDARD = gnu99
GCC_ENABLE_BUILTIN_FUNCTIONS = YES
GCC_ENABLE_PASCAL_STRINGS = NO
GCC_WARN_ABOUT_RETURN_TYPE = YES
GCC_WARN_UNUSED_VARIABLE = YES
PREBINDING = NO
ZERO_LINK = NO
IS_ZIPPERED = YES
OTHER_LDFLAGS = $(inherited) -Wl,-unexported_symbols_list,$(SRCROOT)/unexports
SUPPORTS_TEXT_BASED_API = YES
TAPI_VERIFY_MODE = Pedantic
OTHER_TAPI_FLAGS = -extra-public-header $(SRCROOT)/src/editline/readline.h -extra-public-header $(SRCROOT)/src/histedit.h
INSTALLHDRS_COPY_PHASE = YES
INSTALLHDRS_SCRIPT_PHASE = YES

View File

@ -0,0 +1,15 @@
#!/bin/sh
set -x
cd local
S=$SRCROOT/src
sh $S/makelist -h $S/vi.c >vi.h
sh $S/makelist -h $S/emacs.c >emacs.h
sh $S/makelist -h $S/common.c >common.h
sh $S/makelist -bh $S/vi.c $S/emacs.c $S/common.c >help.h
sh $S/makelist -fc vi.h emacs.h common.h >fcns.c
sh $S/makelist -fh vi.h emacs.h common.h >fcns.h
sh $S/makelist -bc $S/vi.c $S/emacs.c $S/common.c >help.c
sh $S/makelist -n $S/tokenizer.c >tokenizern.c
sh $S/makelist -n $S/history.c >historyn.c