Updated libedit to NetBSD upstream

Note: This unconditionally assumes wchar_t support.  May need revision
if some platforms prove problematic.
This commit is contained in:
Viktor Dukhovni
2016-11-13 15:49:16 +11:00
parent e1c1cdb1b6
commit 77ff7185d7
55 changed files with 6113 additions and 4536 deletions

40
.gitignore vendored
View File

@@ -80,6 +80,7 @@ asn1_*.[cx]
/lib/libedit/src/emacs.h
/lib/libedit/src/fcns.c
/lib/libedit/src/fcns.h
/lib/libedit/src/func.h
/lib/libedit/src/help.c
/lib/libedit/src/help.h
/lib/libedit/src/vi.h
@@ -213,10 +214,6 @@ asn1_*.[cx]
/lib/com_err/parse.h
/lib/com_err/snprintf.c
/lib/com_err/strlcpy.c
/lib/editline/snprintf.c
/lib/editline/strdup.c
/lib/editline/strlcat.c
/lib/editline/testit
/lib/gssapi/gss
/lib/gssapi/gsstool
/lib/gssapi/krb5/gsskrb5-private.h
@@ -231,9 +228,36 @@ asn1_*.[cx]
/lib/gssapi/test_names
/lib/gssapi/test_ntlm
/lib/gssapi/test_oid
/lib/hcrypto/crypto-test
/lib/hcrypto/crypto-test2
/lib/hcrypto/destest
/lib/hcrypto/error
/lib/hcrypto/example_evp_cipher
/lib/hcrypto/hcrypto
/lib/hcrypto/hcrypto-link
/lib/hcrypto/mdtest
/lib/hcrypto/rc2test
/lib/hcrypto/rctest
/lib/hcrypto/test-out-1
/lib/hcrypto/test-out-15
/lib/hcrypto/test-out-16
/lib/hcrypto/test-out-17
/lib/hcrypto/test-out-31
/lib/hcrypto/test-out-32
/lib/hcrypto/test-out-33
/lib/hcrypto/test_bn
/lib/hcrypto/test_bulk
/lib/hcrypto/test_cipher
/lib/hcrypto/test_crypto
/lib/hcrypto/test_dh
/lib/hcrypto/test_engine_dso
/lib/hcrypto/test_hmac
/lib/hcrypto/test-out-7
/lib/hcrypto/test_pkcs12
/lib/hcrypto/test_pkcs5
/lib/hcrypto/test_rand
/lib/hcrypto/test_rsa
/lib/hcrypto/unix
/lib/roken/test-detach
/lib/hdb/hdb-protos.h
/lib/hdb/hdb-private.h
@@ -318,6 +342,7 @@ asn1_*.[cx]
/lib/krb5/krbhst-test
/lib/krb5/n-fold-test
/lib/krb5/parse-name-test
/lib/krb5/pseudo-random-test
/lib/krb5/store-test
/lib/krb5/string-to-key-test
/lib/krb5/test_acl
@@ -424,6 +449,7 @@ asn1_*.[cx]
/tests/can/check-can
/tests/can/current-db.db
/tests/can/krb5.conf
/tests/can/log
/tests/can/mit-pkinit-20070607.cf
/tests/can/test_can
/tests/db/add-modify-delete
@@ -438,8 +464,10 @@ asn1_*.[cx]
/tests/db/krb5.conf-lmdb
/tests/db/krb5.conf-sqlite
/tests/db/loaddump-db
/tests/db/log
/tests/db/tempfile
/tests/gss/barpassword
/tests/gss/check-basic
/tests/gss/check-context
/tests/gss/check-gss
/tests/gss/check-gssmask
@@ -449,6 +477,7 @@ asn1_*.[cx]
/tests/gss/foopassword
/tests/gss/krb5.conf
/tests/gss/krb5ccfile
/tests/gss/krb5ccfile2
/tests/gss/krb5ccfile-ds
/tests/gss/server.keytab
/tests/gss/tempfile
@@ -485,8 +514,10 @@ asn1_*.[cx]
/tests/kdc/check-tester
/tests/kdc/check-uu
/tests/kdc/current-db.db
/tests/kdc/current.log.save
/tests/kdc/current-db.sqlite3
/tests/kdc/foopassword
/tests/kdc/foopassword.rkpty
/tests/kdc/iprop-stats
/tests/kdc/iprop.keytab
/tests/kdc/ipropd.dumpfile
@@ -506,6 +537,7 @@ asn1_*.[cx]
/tests/kdc/krb5-cc.conf
/tests/kdc/krb5.conf.keys
/tests/kdc/localname
/tests/kdc/notfoopassword
/tests/kdc/o2cache.krb5
/tests/kdc/ocache.krb5
/tests/kdc/pkinit.crt

View File

@@ -64,22 +64,3 @@ AC_DEFUN([EL_GETPW_R_DRAFT],
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
])
dnl
dnl use option --enable-widec to turn on use of wide-character support
dnl
AC_DEFUN([EL_ENABLE_WIDEC],
[
AC_MSG_CHECKING(if you want wide-character code)
AC_ARG_ENABLE(widec,
[ --enable-widec compile with wide-char/UTF-8 code],
[with_widec=$enableval],
[with_widec=no])
AC_MSG_RESULT($with_widec)
if test "$with_widec" = yes ; then
AC_DEFINE(WIDECHAR, 1, [Define to 1 if you want wide-character code])
fi
AM_CONDITIONAL([WIDECHAR], [test "$with_widec" = yes])
])

View File

@@ -1,23 +1,5 @@
/* config.h.in. Generated from configure.ac by autoheader. */
/* Define to 1 if the `closedir' function returns void instead of `int'. */
#undef CLOSEDIR_VOID
/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
systems. This function is required for `alloca.c' support on those systems.
*/
#undef CRAY_STACKSEG_END
/* Define to 1 if using `alloca.c'. */
#undef C_ALLOCA
/* Define to 1 if you have `alloca', as a function or macro. */
#undef HAVE_ALLOCA
/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
*/
#undef HAVE_ALLOCA_H
/* Define to 1 if you have the <curses.h> header file. */
#undef HAVE_CURSES_H
@@ -28,15 +10,15 @@
/* Define to 1 if you have the <dlfcn.h> header file. */
#undef HAVE_DLFCN_H
/* Define to 1 if you have the `endpwent' function. */
#undef HAVE_ENDPWENT
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
/* Define to 1 if you have the `getline' function. */
#undef HAVE_GETLINE
/* Define to 1 if you have getpwnam_r and getpwuid_r that are draft POSIX.1
versions. */
#undef HAVE_GETPW_R_DRAFT
@@ -63,30 +45,15 @@
/* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H
/* Define to 1 if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define to 1 if you have the `memchr' function. */
#undef HAVE_MEMCHR
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* Define to 1 if you have the `memset' function. */
#undef HAVE_MEMSET
/* Define to 1 if you have the <ncurses.h> header file. */
#undef HAVE_NCURSES_H
/* Define to 1 if you have the <ndir.h> header file, and it defines `DIR'. */
#undef HAVE_NDIR_H
/* Define to 1 if you have the `regcomp' function. */
#undef HAVE_REGCOMP
/* Define to 1 if you have the `re_comp' function. */
#undef HAVE_RE_COMP
/* Define to 1 if `stat' has the bug that it succeeds when given the
zero-length file name argument. */
#undef HAVE_STAT_EMPTY_STRING_BUG
@@ -97,41 +64,14 @@
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the `strcasecmp' function. */
#undef HAVE_STRCASECMP
/* Define to 1 if you have the `strchr' function. */
#undef HAVE_STRCHR
/* Define to 1 if you have the `strcspn' function. */
#undef HAVE_STRCSPN
/* Define to 1 if you have the `strdup' function. */
#undef HAVE_STRDUP
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the `strlcat' function. */
#undef HAVE_STRLCAT
/* Define to 1 if you have the `strlcpy' function. */
#undef HAVE_STRLCPY
/* Define to 1 if you have the `strrchr' function. */
#undef HAVE_STRRCHR
/* Define to 1 if you have the `strstr' function. */
#undef HAVE_STRSTR
/* Define to 1 if you have the `strtol' function. */
#undef HAVE_STRTOL
/* Define to 1 if struct dirent has member d_namlen */
#undef HAVE_STRUCT_DIRENT_D_NAMLEN
/* Define to 1 if you have the <sys/cdefs.h> header file. */
#undef HAVE_SYS_CDEFS_H
@@ -214,14 +154,6 @@
/* Define as the return type of signal handlers (`int' or `void'). */
#undef RETSIGTYPE
/* If using the C implementation of alloca, define if you know the
direction of stack growth for your system; otherwise it will be
automatically deduced at runtime.
STACK_DIRECTION > 0 => grows toward higher addresses
STACK_DIRECTION < 0 => grows toward lower addresses
STACK_DIRECTION = 0 => direction of growth unknown */
#undef STACK_DIRECTION
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
@@ -250,9 +182,6 @@
/* Version number of package */
#undef VERSION
/* Define to 1 if you want wide-character code */
#undef WIDECHAR
/* Define to 1 if on MINIX. */
#undef _MINIX

View File

@@ -11,7 +11,7 @@
AC_PREREQ(2.61)
AC_INIT(libedit, [EL_RELEASE],, libedit-[EL_TIMESTAMP])
AC_CONFIG_SRCDIR([src/strlcat.c])
AC_CONFIG_SRCDIR([src/el.c])
AC_CONFIG_HEADER([config.h])
# features of Posix that are extensions to C (define _GNU_SOURCE)
@@ -38,15 +38,11 @@ AC_CHECK_LIB(curses, tgetent,,
[AC_MSG_ERROR([libcurses or libncurses are required!])] )] )
### use option --enable-widec to turn on use of wide-character support
EL_ENABLE_WIDEC
# Checks for header files.
AC_FUNC_ALLOCA
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_HEADER_SYS_WAIT
AC_CHECK_HEADERS([fcntl.h limits.h malloc.h stdlib.h string.h sys/ioctl.h sys/param.h unistd.h curses.h ncurses.h sys/cdefs.h])
AC_CHECK_HEADERS([fcntl.h limits.h stdlib.h string.h sys/ioctl.h sys/param.h unistd.h curses.h ncurses.h sys/cdefs.h])
AC_CHECK_HEADER([termios.h], [], [AC_MSG_ERROR([termios.h is required!])],[])
@@ -66,7 +62,6 @@ AC_TYPE_SIZE_T
AC_CHECK_TYPES([u_int32_t])
# Checks for library functions.
AC_FUNC_CLOSEDIR_VOID
AC_FUNC_FORK
AC_PROG_GCC_TRADITIONAL
## _AIX is offended by rpl_malloc and rpl_realloc
@@ -74,10 +69,17 @@ AC_PROG_GCC_TRADITIONAL
#AC_FUNC_REALLOC
AC_TYPE_SIGNAL
AC_FUNC_STAT
AC_CHECK_FUNCS([endpwent isascii memchr memset re_comp regcomp strcasecmp strchr strcspn strdup strlcpy strlcat strerror strrchr strstr strtol issetugid wcsdup])
AC_CHECK_FUNCS([getline isascii issetugid wcsdup])
EL_GETPW_R_POSIX
EL_GETPW_R_DRAFT
AC_CHECK_MEMBER(struct dirent.d_namlen,
AC_DEFINE([HAVE_STRUCT_DIRENT_D_NAMLEN],[1],
[Define to 1 if struct dirent has member d_namlen]),,
[#if HAVE_DIRENT_H
#include <dirent.h>
#endif
])
AH_BOTTOM([
#include "sys.h"

View File

@@ -1,52 +1,38 @@
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
BUILT_SOURCES = vi.h emacs.h common.h fcns.h help.h func.h
AHDR= vi.h emacs.h common.h
ASRC= $(srcdir)/vi.c $(srcdir)/emacs.c $(srcdir)/common.c
vi.h: Makefile $(srcdir)/vi.c
vi.h: Makefile $(srcdir)/makelist $(srcdir)/vi.c
AWK=$(AWK) sh $(srcdir)/makelist -h $(srcdir)/vi.c > $@
emacs.h: Makefile $(srcdir)/emacs.c
emacs.h: Makefile $(srcdir)/makelist $(srcdir)/emacs.c
AWK=$(AWK) sh $(srcdir)/makelist -h $(srcdir)/emacs.c > $@
common.h: Makefile $(srcdir)/common.c
common.h: Makefile $(srcdir)/makelist $(srcdir)/common.c
AWK=$(AWK) sh $(srcdir)/makelist -h $(srcdir)/common.c > $@
fcns.h: Makefile $(AHDR)
fcns.h: Makefile $(srcdir)/makelist $(AHDR)
AWK=$(AWK) sh $(srcdir)/makelist -fh $(AHDR) > $@
help.h: Makefile $(ASRC)
AWK=$(AWK) sh $(srcdir)/makelist -bh $(ASRC) > $@
fcns.c: Makefile $(AHDR)
func.h: Makefile $(srcdir)/makelist $(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 > $@
help.h: Makefile $(srcdir)/makelist $(ASRC)
AWK=$(AWK) sh $(srcdir)/makelist -bh $(ASRC) > $@
CLEANFILES = $(BUILT_SOURCES)
lib_LTLIBRARIES = libheimedit.la
libheimedit_la_SOURCES = chared.c common.c el.c emacs.c hist.c key.c map.c chartype.c parse.c \
prompt.c read.c refresh.c search.c sig.c term.c tty.c vi.c \
fgetln.c strlcat.c strlcpy.c unvis.c vis.c wcsdup.c tokenizer.c \
history.c filecomplete.c readline.c chared.h el.h hist.h \
histedit.h key.h map.h chartype.h parse.h prompt.h read.h refresh.h \
search.h sig.h sys.h el_term.h tty.h vis.h filecomplete.h \
editline/readline.h
if WIDECHAR
libheimedit_la_SOURCES += eln.c
endif
libheimedit_la_SOURCES = \
chared.c chartype.c common.c el.c eln.c emacs.c filecomplete.c hist.c \
history.c historyn.c keymacro.c map.c parse.c prompt.c read.c readline.c \
refresh.c search.c sig.c terminal.c tokenizer.c tokenizern.c tty.c \
unvis.c vi.c vis.c wcsdup.c \
chared.h chartype.h editline/readline.h el.h filecomplete.h \
histedit.h hist.h keymacro.h map.h parse.h prompt.h read.h \
refresh.h search.h sig.h sys.h terminal.h tty.h vis.h
EXTRA_DIST = makelist shlib_version
#nobase_include_HEADERS = histedit.h editline/readline.h

View File

@@ -1,4 +1,4 @@
/* $NetBSD: chared.c,v 1.29 2010/08/28 15:44:59 christos Exp $ */
/* $NetBSD: chared.c,v 1.56 2016/05/22 19:44:26 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,17 +37,20 @@
#if 0
static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: chared.c,v 1.29 2010/08/28 15:44:59 christos Exp $");
__RCSID("$NetBSD: chared.c,v 1.56 2016/05/22 19:44:26 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/*
* chared.c: Character editor utilities
*/
#include <ctype.h>
#include <stdlib.h>
#include "el.h"
#include <string.h>
private void ch__clearmacro (EditLine *);
#include "el.h"
#include "common.h"
#include "fcns.h"
/* value to leave unused in line buffer */
#define EL_LEAVE 2
@@ -55,7 +58,7 @@ private void ch__clearmacro (EditLine *);
/* cv_undo():
* Handle state for the vi undo command
*/
protected void
libedit_private void
cv_undo(EditLine *el)
{
c_undo_t *vu = &el->el_chared.c_undo;
@@ -63,8 +66,8 @@ cv_undo(EditLine *el)
size_t size;
/* Save entire line for undo */
size = el->el_line.lastchar - el->el_line.buffer;
vu->len = size;
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));
@@ -79,12 +82,12 @@ cv_undo(EditLine *el)
/* cv_yank():
* Save yank/delete data for paste
*/
protected void
cv_yank(EditLine *el, const Char *ptr, int size)
libedit_private void
cv_yank(EditLine *el, const wchar_t *ptr, int size)
{
c_kill_t *k = &el->el_chared.c_kill;
(void)memcpy(k->buf, ptr, size * sizeof(*k->buf));
(void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf));
k->last = k->buf + size;
}
@@ -92,10 +95,10 @@ cv_yank(EditLine *el, const Char *ptr, int size)
/* c_insert():
* Insert num characters
*/
protected void
libedit_private void
c_insert(EditLine *el, int num)
{
Char *cp;
wchar_t *cp;
if (el->el_line.lastchar + num >= el->el_line.limit) {
if (!ch_enlargebufs(el, (size_t)num))
@@ -114,7 +117,7 @@ c_insert(EditLine *el, int num)
/* c_delafter():
* Delete num characters after the cursor
*/
protected void
libedit_private void
c_delafter(EditLine *el, int num)
{
@@ -127,7 +130,7 @@ c_delafter(EditLine *el, int num)
}
if (num > 0) {
Char *cp;
wchar_t *cp;
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
*cp = cp[num];
@@ -140,10 +143,10 @@ c_delafter(EditLine *el, int num)
/* c_delafter1():
* Delete the character after the cursor, do not yank
*/
protected void
libedit_private void
c_delafter1(EditLine *el)
{
Char *cp;
wchar_t *cp;
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
*cp = cp[1];
@@ -155,7 +158,7 @@ c_delafter1(EditLine *el)
/* c_delbefore():
* Delete num characters before the cursor
*/
protected void
libedit_private void
c_delbefore(EditLine *el, int num)
{
@@ -168,7 +171,7 @@ c_delbefore(EditLine *el, int num)
}
if (num > 0) {
Char *cp;
wchar_t *cp;
for (cp = el->el_line.cursor - num;
cp <= el->el_line.lastchar;
@@ -183,10 +186,10 @@ c_delbefore(EditLine *el, int num)
/* c_delbefore1():
* Delete the character before the cursor, do not yank
*/
protected void
libedit_private void
c_delbefore1(EditLine *el)
{
Char *cp;
wchar_t *cp;
for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
*cp = cp[1];
@@ -198,22 +201,22 @@ c_delbefore1(EditLine *el)
/* ce__isword():
* Return if p is part of a word according to emacs
*/
protected int
ce__isword(Int p)
libedit_private int
ce__isword(wint_t p)
{
return (Isalnum(p) || Strchr(STR("*?_-.[]~="), p) != NULL);
return iswalnum(p) || wcschr(L"*?_-.[]~=", p) != NULL;
}
/* cv__isword():
* Return if p is part of a word according to vi
*/
protected int
cv__isword(Int p)
libedit_private int
cv__isword(wint_t p)
{
if (Isalnum(p) || p == '_')
if (iswalnum(p) || p == L'_')
return 1;
if (Isgraph(p))
if (iswgraph(p))
return 2;
return 0;
}
@@ -222,18 +225,18 @@ cv__isword(Int p)
/* cv__isWord():
* Return if p is part of a big word according to vi
*/
protected int
cv__isWord(Int p)
libedit_private int
cv__isWord(wint_t p)
{
return (!Isspace(p));
return !iswspace(p);
}
/* c__prev_word():
* Find the previous word
*/
protected Char *
c__prev_word(Char *p, Char *low, int n, int (*wtest)(Int))
libedit_private wchar_t *
c__prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
{
p--;
@@ -249,15 +252,15 @@ c__prev_word(Char *p, Char *low, int n, int (*wtest)(Int))
if (p < low)
p = low;
/* cp now points where we want it */
return (p);
return p;
}
/* c__next_word():
* Find the next word
*/
protected Char *
c__next_word(Char *p, Char *high, int n, int (*wtest)(Int))
libedit_private wchar_t *
c__next_word(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
{
while (n--) {
while ((p < high) && !(*wtest)(*p))
@@ -268,14 +271,15 @@ c__next_word(Char *p, Char *high, int n, int (*wtest)(Int))
if (p > high)
p = high;
/* p now points where we want it */
return (p);
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))
libedit_private wchar_t *
cv_next_word(EditLine *el, wchar_t *p, wchar_t *high, int n,
int (*wtest)(wint_t))
{
int test;
@@ -288,29 +292,29 @@ cv_next_word(EditLine *el, Char *p, Char *high, int n, int (*wtest)(Int))
* trailing whitespace! This is not what 'w' does..
*/
if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
while ((p < high) && Isspace(*p))
while ((p < high) && iswspace(*p))
p++;
}
/* p now points where we want it */
if (p > high)
return (high);
return high;
else
return (p);
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))
libedit_private wchar_t *
cv_prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
{
int test;
p--;
while (n--) {
while ((p > low) && Isspace(*p))
while ((p > low) && iswspace(*p))
p--;
test = (*wtest)(*p);
while ((p >= low) && (*wtest)(*p) == test)
@@ -320,51 +324,16 @@ cv_prev_word(Char *p, Char *low, int n, int (*wtest)(Int))
/* p now points where we want it */
if (p < low)
return (low);
return low;
else
return (p);
return p;
}
#ifdef notdef
/* c__number():
* Ignore character p points to, return number appearing after that.
* A '$' by itself means a big number; "$-" is for negative; '^' means 1.
* Return p pointing to last char used.
*/
protected Char *
c__number(
Char *p, /* character position */
int *num, /* Return value */
int dval) /* dval is the number to subtract from like $-3 */
{
int i;
int sign = 1;
if (*++p == '^') {
*num = 1;
return (p);
}
if (*p == '$') {
if (*++p != '-') {
*num = 0x7fffffff; /* Handle $ */
return (--p);
}
sign = -1; /* Handle $- */
++p;
}
/* XXX: this assumes ASCII compatible digits */
for (i = 0; Isdigit(*p); i = 10 * i + *p++ - '0')
continue;
*num = (sign < 0 ? dval - i : i);
return (--p);
}
#endif
/* cv_delfini():
* Finish vi delete action
*/
protected void
libedit_private void
cv_delfini(EditLine *el)
{
int size;
@@ -399,40 +368,18 @@ cv_delfini(EditLine *el)
}
#ifdef notdef
/* ce__endword():
* Go to the end of this word according to emacs
*/
protected Char *
ce__endword(Char *p, Char *high, int n)
{
p++;
while (n--) {
while ((p < high) && Isspace(*p))
p++;
while ((p < high) && !Isspace(*p))
p++;
}
p--;
return (p);
}
#endif
/* cv__endword():
* Go to the end of this word according to vi
*/
protected Char *
cv__endword(Char *p, Char *high, int n, int (*wtest)(Int))
libedit_private wchar_t *
cv__endword(wchar_t *p, wchar_t *high, int n, int (*wtest)(wint_t))
{
int test;
p++;
while (n--) {
while ((p < high) && Isspace(*p))
while ((p < high) && iswspace(*p))
p++;
test = (*wtest)(*p);
@@ -440,21 +387,19 @@ cv__endword(Char *p, Char *high, int n, int (*wtest)(Int))
p++;
}
p--;
return (p);
return p;
}
/* ch_init():
* Initialize the character editor
*/
protected int
libedit_private 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);
return -1;
(void) memset(el->el_line.buffer, 0, EL_BUFSIZ *
sizeof(*el->el_line.buffer));
@@ -465,7 +410,7 @@ ch_init(EditLine *el)
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);
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;
@@ -473,7 +418,7 @@ ch_init(EditLine *el)
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);
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;
@@ -484,13 +429,15 @@ ch_init(EditLine *el)
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);
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_chared.c_aliasfun = NULL;
el->el_chared.c_aliasarg = NULL;
el->el_map.current = el->el_map.key;
@@ -500,19 +447,14 @@ ch_init(EditLine *el)
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);
return 0;
}
/* ch_reset():
* Reset the character editor
*/
protected void
ch_reset(EditLine *el, int mclear)
libedit_private void
ch_reset(EditLine *el)
{
el->el_line.cursor = el->el_line.buffer;
el->el_line.lastchar = el->el_line.buffer;
@@ -534,30 +476,19 @@ ch_reset(EditLine *el, int mclear)
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((ptr_t)ma->macro[ma->level--]);
}
/* ch_enlargebufs():
* Enlarge line buffer to be able to hold twice as much characters.
* Returns 1 if successful, 0 if not.
*/
protected int
libedit_private int
ch_enlargebufs(EditLine *el, size_t addlen)
{
size_t sz, newsz;
Char *newbuffer, *oldbuf, *oldkbuf;
wchar_t *newbuffer, *oldbuf, *oldkbuf;
sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE;
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
@@ -589,7 +520,8 @@ ch_enlargebufs(EditLine *el, size_t addlen)
/*
* Reallocate kill buffer.
*/
newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz * sizeof(*newbuffer));
newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz *
sizeof(*newbuffer));
if (!newbuffer)
return 0;
@@ -639,53 +571,51 @@ ch_enlargebufs(EditLine *el, size_t addlen)
/* ch_end():
* Free the data structures used by the editor
*/
protected void
libedit_private void
ch_end(EditLine *el)
{
el_free((ptr_t) el->el_line.buffer);
el_free(el->el_line.buffer);
el->el_line.buffer = NULL;
el->el_line.limit = NULL;
el_free((ptr_t) el->el_chared.c_undo.buf);
el_free(el->el_chared.c_undo.buf);
el->el_chared.c_undo.buf = NULL;
el_free((ptr_t) el->el_chared.c_redo.buf);
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((ptr_t) el->el_chared.c_kill.buf);
el_free(el->el_chared.c_kill.buf);
el->el_chared.c_kill.buf = NULL;
ch_reset(el, 1);
el_free((ptr_t) el->el_chared.c_macro.macro);
el->el_chared.c_macro.macro = NULL;
ch_reset(el);
}
/* el_insertstr():
* Insert string at cursorI
*/
public int
FUN(el,insertstr)(EditLine *el, const Char *s)
int
el_winsertstr(EditLine *el, const wchar_t *s)
{
size_t len;
if ((len = Strlen(s)) == 0)
return (-1);
if (s == NULL || (len = wcslen(s)) == 0)
return -1;
if (el->el_line.lastchar + len >= el->el_line.limit) {
if (!ch_enlargebufs(el, len))
return (-1);
return -1;
}
c_insert(el, (int)len);
while (*s)
*el->el_line.cursor++ = *s++;
return (0);
return 0;
}
/* el_deletestr():
* Delete num characters before the cursor
*/
public void
void
el_deletestr(EditLine *el, int n)
{
if (n <= 0)
@@ -700,19 +630,37 @@ el_deletestr(EditLine *el, int n)
el->el_line.cursor = el->el_line.buffer;
}
/* el_cursor():
* Move the cursor to the left or the right of the current position
*/
int
el_cursor(EditLine *el, int n)
{
if (n == 0)
goto out;
el->el_line.cursor += n;
if (el->el_line.cursor < el->el_line.buffer)
el->el_line.cursor = el->el_line.buffer;
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
out:
return (int)(el->el_line.cursor - el->el_line.buffer);
}
/* c_gets():
* Get a string
*/
protected int
c_gets(EditLine *el, Char *buf, const Char *prompt)
libedit_private int
c_gets(EditLine *el, wchar_t *buf, const wchar_t *prompt)
{
Char ch;
ssize_t len;
Char *cp = el->el_line.buffer;
wchar_t *cp = el->el_line.buffer, ch;
if (prompt) {
len = Strlen(prompt);
(void)memcpy(cp, prompt, len * sizeof(*cp));
len = (ssize_t)wcslen(prompt);
(void)memcpy(cp, prompt, (size_t)len * sizeof(*cp));
cp += len;
}
len = 0;
@@ -723,7 +671,7 @@ c_gets(EditLine *el, Char *buf, const Char *prompt)
el->el_line.lastchar = cp + 1;
re_refresh(el);
if (FUN(el,getc)(el, &ch) != 1) {
if (el_wgetc(el, &ch) != 1) {
ed_end_of_file(el, 0);
len = -1;
break;
@@ -731,24 +679,25 @@ c_gets(EditLine *el, Char *buf, const Char *prompt)
switch (ch) {
case 0010: /* Delete and backspace */
case L'\b': /* Delete and backspace */
case 0177:
if (len == 0) {
len = -1;
break;
}
len--;
cp--;
continue;
case 0033: /* ESC */
case '\r': /* Newline */
case '\n':
case L'\r': /* Newline */
case L'\n':
buf[len] = ch;
break;
default:
if (len >= EL_BUFSIZ - 16)
term_beep(el);
if (len >= (ssize_t)(EL_BUFSIZ - 16))
terminal_beep(el);
else {
buf[len++] = ch;
*cp++ = ch;
@@ -768,16 +717,16 @@ c_gets(EditLine *el, Char *buf, const Char *prompt)
/* c_hpos():
* Return the current horizontal position of the cursor
*/
protected int
libedit_private int
c_hpos(EditLine *el)
{
Char *ptr;
wchar_t *ptr;
/*
* Find how many characters till the beginning of this line.
*/
if (el->el_line.cursor == el->el_line.buffer)
return (0);
return 0;
else {
for (ptr = el->el_line.cursor - 1;
ptr >= el->el_line.buffer && *ptr != '\n';
@@ -787,10 +736,18 @@ c_hpos(EditLine *el)
}
}
protected int
libedit_private 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;
}
libedit_private int
ch_aliasfun(EditLine *el, el_afunc_t f, void *a)
{
el->el_chared.c_aliasfun = f;
el->el_chared.c_aliasarg = a;
return 0;
}

View File

@@ -1,4 +1,4 @@
/* $NetBSD: chared.h,v 1.21 2010/08/28 15:44:59 christos Exp $ */
/* $NetBSD: chared.h,v 1.30 2016/05/22 19:44:26 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -40,13 +40,6 @@
#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
@@ -59,29 +52,22 @@
*/
#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 */
wchar_t *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;
wchar_t *buf; /* redo insert key sequence */
wchar_t *pos;
wchar_t *lim;
el_action_t cmd; /* command to redo */
Char ch; /* char that invoked it */
wchar_t ch; /* char that invoked it */
int count;
int action; /* from cv_action() */
} c_redo_t;
@@ -91,19 +77,20 @@ typedef struct c_redo_t {
*/
typedef struct c_vcmd_t {
int action;
Char *pos;
wchar_t *pos;
} c_vcmd_t;
/*
* Kill buffer for emacs
*/
typedef struct c_kill_t {
Char *buf;
Char *last;
Char *mark;
wchar_t *buf;
wchar_t *last;
wchar_t *mark;
} c_kill_t;
typedef void (*el_zfunc_t)(EditLine *, void *);
typedef const char *(*el_afunc_t)(void *, const char *);
/*
* Note that we use both data structures because the user can bind
@@ -114,9 +101,10 @@ typedef struct el_chared_t {
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;
el_afunc_t c_aliasfun;
void * c_resizearg;
void * c_aliasarg;
} el_chared_t;
@@ -136,36 +124,32 @@ typedef struct el_chared_t {
#define MODE_REPLACE 1
#define MODE_REPLACE_1 2
#include "common.h"
#include "vi.h"
#include "emacs.h"
#include "search.h"
#include "fcns.h"
libedit_private int cv__isword(wint_t);
libedit_private int cv__isWord(wint_t);
libedit_private void cv_delfini(EditLine *);
libedit_private wchar_t *cv__endword(wchar_t *, wchar_t *, int, int (*)(wint_t));
libedit_private int ce__isword(wint_t);
libedit_private void cv_undo(EditLine *);
libedit_private void cv_yank(EditLine *, const wchar_t *, int);
libedit_private wchar_t *cv_next_word(EditLine*, wchar_t *, wchar_t *, int,
int (*)(wint_t));
libedit_private wchar_t *cv_prev_word(wchar_t *, wchar_t *, int, int (*)(wint_t));
libedit_private wchar_t *c__next_word(wchar_t *, wchar_t *, int, int (*)(wint_t));
libedit_private wchar_t *c__prev_word(wchar_t *, wchar_t *, int, int (*)(wint_t));
libedit_private void c_insert(EditLine *, int);
libedit_private void c_delbefore(EditLine *, int);
libedit_private void c_delbefore1(EditLine *);
libedit_private void c_delafter(EditLine *, int);
libedit_private void c_delafter1(EditLine *);
libedit_private int c_gets(EditLine *, wchar_t *, const wchar_t *);
libedit_private int c_hpos(EditLine *);
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 *);
libedit_private int ch_init(EditLine *);
libedit_private void ch_reset(EditLine *);
libedit_private int ch_resizefun(EditLine *, el_zfunc_t, void *);
libedit_private int ch_aliasfun(EditLine *, el_afunc_t, void *);
libedit_private int ch_enlargebufs(EditLine *, size_t);
libedit_private void ch_end(EditLine *);
#endif /* _h_el_chared */

View File

@@ -1,4 +1,4 @@
/* $NetBSD: chartype.c,v 1.4 2010/04/15 00:55:57 christos Exp $ */
/* $NetBSD: chartype.c,v 1.30 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -12,13 +12,6 @@
* 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
@@ -38,122 +31,132 @@
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: chartype.c,v 1.4 2010/04/15 00:55:57 christos Exp $");
__RCSID("$NetBSD: chartype.c,v 1.30 2016/05/09 21:46:56 christos Exp $");
#endif /* not lint && not SCCSID */
#include "el.h"
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#define CT_BUFSIZ 1024
#include "el.h"
#ifdef WIDECHAR
protected void
ct_conv_buff_resize(ct_buffer_t *conv, size_t mincsize, size_t minwsize)
#define CT_BUFSIZ ((size_t)1024)
static int ct_conv_cbuff_resize(ct_buffer_t *, size_t);
static int ct_conv_wbuff_resize(ct_buffer_t *, size_t);
static int
ct_conv_cbuff_resize(ct_buffer_t *conv, size_t csize)
{
void *p;
if (mincsize > conv->csize) {
conv->csize = mincsize;
p = el_realloc(conv->cbuff, conv->csize);
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);
if (p == NULL) {
conv->wsize = 0;
el_free(conv->wbuff);
conv->wbuff = NULL;
} else
conv->wbuff = p;
if (csize <= conv->csize)
return 0;
conv->csize = csize;
p = el_realloc(conv->cbuff, conv->csize * sizeof(*conv->cbuff));
if (p == NULL) {
conv->csize = 0;
el_free(conv->cbuff);
conv->cbuff = NULL;
return -1;
}
conv->cbuff = p;
return 0;
}
static int
ct_conv_wbuff_resize(ct_buffer_t *conv, size_t wsize)
{
void *p;
if (wsize <= conv->wsize)
return 0;
conv->wsize = wsize;
p = el_realloc(conv->wbuff, conv->wsize * sizeof(*conv->wbuff));
if (p == NULL) {
conv->wsize = 0;
el_free(conv->wbuff);
conv->wbuff = NULL;
return -1;
}
conv->wbuff = p;
return 0;
}
public char *
ct_encode_string(const Char *s, ct_buffer_t *conv)
char *
ct_encode_string(const wchar_t *s, ct_buffer_t *conv)
{
char *dst;
ssize_t used = 0;
ssize_t used;
if (!s)
return NULL;
if (!conv->cbuff)
ct_conv_buff_resize(conv, CT_BUFSIZ, 0);
if (!conv->cbuff)
return NULL;
dst = conv->cbuff;
while (*s) {
used = ct_encode_char(dst, (int)(conv->csize -
(dst - conv->cbuff)), *s);
if (used == -1) { /* failed to encode, need more buffer space */
used = dst - conv->cbuff;
ct_conv_buff_resize(conv, conv->csize + CT_BUFSIZ, 0);
if (!conv->cbuff)
for (;;) {
used = (ssize_t)(dst - conv->cbuff);
if ((conv->csize - (size_t)used) < 5) {
if (ct_conv_cbuff_resize(conv,
conv->csize + CT_BUFSIZ) == -1)
return NULL;
dst = conv->cbuff + used;
/* don't increment s here - we want to retry it! */
}
else
++s;
if (!*s)
break;
used = ct_encode_char(dst, (size_t)5, *s);
if (used == -1) /* failed to encode, need more buffer space */
abort();
++s;
dst += used;
}
if (dst >= (conv->cbuff + conv->csize)) {
used = dst - conv->cbuff;
ct_conv_buff_resize(conv, conv->csize + 1, 0);
if (!conv->cbuff)
return NULL;
dst = conv->cbuff + used;
}
*dst = '\0';
return conv->cbuff;
}
public Char *
wchar_t *
ct_decode_string(const char *s, ct_buffer_t *conv)
{
size_t len = 0;
size_t len;
if (!s)
return NULL;
if (!conv->wbuff)
ct_conv_buff_resize(conv, 0, CT_BUFSIZ);
if (!conv->wbuff)
len = mbstowcs(NULL, s, (size_t)0);
if (len == (size_t)-1)
return NULL;
len = ct_mbstowcs(0, s, 0);
if (len > conv->wsize)
ct_conv_buff_resize(conv, 0, len + 1);
if (!conv->wbuff)
return NULL;
ct_mbstowcs(conv->wbuff, s, conv->wsize);
if (conv->wsize < ++len)
if (ct_conv_wbuff_resize(conv, len + CT_BUFSIZ) == -1)
return NULL;
mbstowcs(conv->wbuff, s, conv->wsize);
return conv->wbuff;
}
protected Char **
libedit_private wchar_t **
ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
{
size_t bufspace;
int i;
Char *p;
Char **wargv;
wchar_t *p;
wchar_t **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, 0, bufspace);
if (!conv->wsize)
return NULL;
if (conv->wsize < ++bufspace)
if (ct_conv_wbuff_resize(conv, bufspace + CT_BUFSIZ) == -1)
return NULL;
wargv = el_malloc(argc * sizeof(*wargv));
wargv = el_malloc((size_t)argc * sizeof(*wargv));
for (i = 0, p = conv->wbuff; i < argc; ++i) {
if (!argv[i]) { /* don't pass null pointers to mbstowcs */
@@ -161,14 +164,14 @@ ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
continue;
} else {
wargv[i] = p;
bytes = mbstowcs(p, argv[i], bufspace);
bytes = (ssize_t)mbstowcs(p, argv[i], bufspace);
}
if (bytes == -1) {
el_free(wargv);
return NULL;
} else
bytes++; /* include '\0' in the count */
bufspace -= bytes;
bufspace -= (size_t)bytes;
p += bytes;
}
@@ -176,8 +179,8 @@ ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
}
protected size_t
ct_enc_width(Char c)
libedit_private size_t
ct_enc_width(wchar_t c)
{
/* UTF-8 encoding specific values */
if (c < 0x80)
@@ -192,74 +195,66 @@ ct_enc_width(Char c)
return 0; /* not a valid codepoint */
}
protected ssize_t
ct_encode_char(char *dst, size_t len, Char c)
libedit_private ssize_t
ct_encode_char(char *dst, size_t len, wchar_t c)
{
ssize_t l = 0;
if (len < ct_enc_width(c))
return -1;
l = ct_wctomb(dst, c);
l = wctomb(dst, c);
if (l < 0) {
ct_wctomb_reset;
wctomb(NULL, L'\0');
l = 0;
}
return l;
}
#endif
protected const Char *
ct_visual_string(const Char *s)
libedit_private const wchar_t *
ct_visual_string(const wchar_t *s, ct_buffer_t *conv)
{
static Char *buff = NULL;
static size_t buffsize = 0;
void *p;
Char *dst;
ssize_t used = 0;
wchar_t *dst;
ssize_t used;
if (!s)
return NULL;
if (!buff) {
buffsize = CT_BUFSIZ;
buff = el_malloc(buffsize * sizeof(*buff));
}
dst = buff;
if (ct_conv_wbuff_resize(conv, CT_BUFSIZ) == -1)
return NULL;
used = 0;
dst = conv->wbuff;
while (*s) {
used = ct_visual_char(dst, buffsize - (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! */
used = ct_visual_char(dst,
conv->wsize - (size_t)(dst - conv->wbuff), *s);
if (used != -1) {
++s;
dst += used;
continue;
}
else
++s;
dst += used;
/* failed to encode, need more buffer space */
used = dst - conv->wbuff;
if (ct_conv_wbuff_resize(conv, conv->wsize + CT_BUFSIZ) == -1)
return NULL;
dst = conv->wbuff + 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;
if (dst >= (conv->wbuff + conv->wsize)) { /* sigh */
used = dst - conv->wbuff;
if (ct_conv_wbuff_resize(conv, conv->wsize + CT_BUFSIZ) == -1)
return NULL;
dst = conv->wbuff + used;
}
*dst = 0;
return buff;
out:
el_free(buff);
buffsize = 0;
return NULL;
*dst = L'\0';
return conv->wbuff;
}
protected int
ct_visual_width(Char c)
libedit_private int
ct_visual_width(wchar_t c)
{
int t = ct_chr_class(c);
switch (t) {
@@ -269,7 +264,6 @@ ct_visual_width(Char c)
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:
@@ -277,20 +271,14 @@ ct_visual_width(Char c)
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)
libedit_private ssize_t
ct_visual_char(wchar_t *dst, size_t len, wchar_t c)
{
int t = ct_chr_class(c);
switch (t) {
@@ -315,7 +303,6 @@ ct_visual_char(Char *dst, size_t len, Char c)
* so this is right */
if ((ssize_t)len < ct_visual_width(c))
return -1; /* insufficient space */
#ifdef WIDECHAR
*dst++ = '\\';
*dst++ = 'U';
*dst++ = '+';
@@ -326,14 +313,7 @@ ct_visual_char(Char *dst, size_t len, Char c)
*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
return c > 0xffff ? 8 : 7;
/*FALLTHROUGH*/
/* these two should be handled outside this function */
default: /* we should never hit the default */
@@ -344,16 +324,16 @@ ct_visual_char(Char *dst, size_t len, Char c)
protected int
ct_chr_class(Char c)
libedit_private int
ct_chr_class(wchar_t c)
{
if (c == '\t')
return CHTYPE_TAB;
else if (c == '\n')
return CHTYPE_NL;
else if (IsASCII(c) && Iscntrl(c))
else if (c < 0x100 && iswcntrl(c))
return CHTYPE_ASCIICTL;
else if (Isprint(c))
else if (iswprint(c))
return CHTYPE_PRINT;
else
return CHTYPE_NONPRINT;

View File

@@ -1,4 +1,4 @@
/* $NetBSD: chartype.h,v 1.7 2010/12/16 17:42:28 wiz Exp $ */
/* $NetBSD: chartype.h,v 1.34 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -12,13 +12,6 @@
* 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
@@ -36,15 +29,11 @@
#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__))
#if !defined(__NetBSD__) && !defined(__sun) && !(defined(__APPLE__) && defined(__MACH__)) && !defined(__OpenBSD__) && !defined(__FreeBSD__)
#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
@@ -60,175 +49,53 @@
#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,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)
#define Width(c) wcwidth(c)
#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;
wchar_t *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 *);
char *ct_encode_string(const wchar_t *, 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 *);
wchar_t *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 *);
libedit_private wchar_t **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
/* Encode a character into the destination buffer, provided there is sufficient
* 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). */
libedit_private ssize_t ct_encode_char(char *, size_t, wchar_t);
libedit_private size_t ct_enc_width(wchar_t);
/* The maximum buffer size to hold the most unwieldly visual representation,
/* The maximum buffer size to hold the most unwieldy visual representation,
* in this case \U+nnnnn. */
#define VISUAL_WIDTH_MAX 8
#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)
#define MB_FILL_CHAR ((wchar_t)-1)
/* Visual width of character c, taking into account ^? , \0177 and \U+nnnnn
* style visual expansions. */
protected int ct_visual_width(Char);
libedit_private int ct_visual_width(wchar_t);
/* 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);
* up, or -1 if insufficient space. Buffer length is in count of wchar_t's. */
libedit_private ssize_t ct_visual_char(wchar_t *, size_t, wchar_t);
/* 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 *);
libedit_private const wchar_t *ct_visual_string(const wchar_t *, ct_buffer_t *);
/* printable character, use ct_visual_width() to find out display width */
@@ -242,8 +109,6 @@ protected const Char *ct_visual_string(const Char *);
/* 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
libedit_private int ct_chr_class(wchar_t c);
#endif /* _chartype_f */

View File

@@ -1,4 +1,4 @@
/* $NetBSD: common.c,v 1.24 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: common.c,v 1.47 2016/05/22 19:44:26 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,27 +37,34 @@
#if 0
static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: common.c,v 1.24 2009/12/30 22:37:40 christos Exp $");
__RCSID("$NetBSD: common.c,v 1.47 2016/05/22 19:44:26 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/*
* common.c: Common Editor functions
*/
#include <ctype.h>
#include <string.h>
#include "el.h"
#include "common.h"
#include "fcns.h"
#include "parse.h"
#include "vi.h"
/* ed_end_of_file():
* Indicate end of file
* [^D]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_end_of_file(EditLine *el, Int c __attribute__((__unused__)))
ed_end_of_file(EditLine *el, wint_t c __attribute__((__unused__)))
{
re_goto_bottom(el);
*el->el_line.lastchar = '\0';
return (CC_EOF);
return CC_EOF;
}
@@ -65,13 +72,13 @@ ed_end_of_file(EditLine *el, Int c __attribute__((__unused__)))
* Add character to the line
* Insert a character [bound to all insert keys]
*/
protected el_action_t
ed_insert(EditLine *el, Int c)
libedit_private el_action_t
ed_insert(EditLine *el, wint_t c)
{
int count = el->el_state.argument;
if (c == '\0')
return (CC_ERROR);
return CC_ERROR;
if (el->el_line.lastchar + el->el_state.argument >=
el->el_line.limit) {
@@ -99,7 +106,7 @@ ed_insert(EditLine *el, Int c)
if (el->el_state.inputmode == MODE_REPLACE_1)
return vi_command_mode(el, 0);
return (CC_NORM);
return CC_NORM;
}
@@ -107,14 +114,14 @@ ed_insert(EditLine *el, Int c)
* Delete from beginning of current word to cursor
* [M-^?] [^W]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_delete_prev_word(EditLine *el, Int c __attribute__((__unused__)))
ed_delete_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *cp, *p, *kp;
wchar_t *cp, *p, *kp;
if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR);
return CC_ERROR;
cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
el->el_state.argument, ce__isword);
@@ -127,7 +134,7 @@ ed_delete_prev_word(EditLine *el, Int c __attribute__((__unused__)))
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);
return CC_REFRESH;
}
@@ -135,14 +142,14 @@ ed_delete_prev_word(EditLine *el, Int c __attribute__((__unused__)))
* Delete character under cursor
* [^D] [x]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_delete_next_char(EditLine *el, Int c)
ed_delete_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
{
#ifdef notdef /* XXX */
#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",
(void) fprintf(el->el_errfile,
"\nD(b: %p(%ls) c: %p(%ls) last: %p(%ls) limit: %p(%ls)\n",
EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar,
EL.lastchar, EL.limit, EL.limit);
#endif
@@ -152,32 +159,29 @@ ed_delete_next_char(EditLine *el, Int c)
if (el->el_line.cursor == el->el_line.buffer) {
/* if I'm also at the beginning */
#ifdef KSHVI
return (CC_ERROR);
return CC_ERROR;
#else
/* then do an EOF */
term_writec(el, c);
return (CC_EOF);
terminal_writec(el, c);
return CC_EOF;
#endif
} else {
#ifdef KSHVI
el->el_line.cursor--;
#else
return (CC_ERROR);
return CC_ERROR;
#endif
}
} else {
if (el->el_line.cursor != el->el_line.buffer)
el->el_line.cursor--;
else
return (CC_ERROR);
}
} else
return CC_ERROR;
}
c_delafter(el, el->el_state.argument); /* delete after dot */
if (el->el_line.cursor >= el->el_line.lastchar &&
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);
return CC_REFRESH;
}
@@ -185,11 +189,11 @@ ed_delete_next_char(EditLine *el, Int c)
* Cut to the end of line
* [^K] [^K]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_kill_line(EditLine *el, Int c __attribute__((__unused__)))
ed_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *kp, *cp;
wchar_t *kp, *cp;
cp = el->el_line.cursor;
kp = el->el_chared.c_kill.buf;
@@ -198,7 +202,7 @@ ed_kill_line(EditLine *el, Int c __attribute__((__unused__)))
el->el_chared.c_kill.last = kp;
/* zap! -- delete to end */
el->el_line.lastchar = el->el_line.cursor;
return (CC_REFRESH);
return CC_REFRESH;
}
@@ -206,22 +210,22 @@ ed_kill_line(EditLine *el, Int c __attribute__((__unused__)))
* Move cursor to the end of line
* [^E] [^E]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_move_to_end(EditLine *el, Int c __attribute__((__unused__)))
ed_move_to_end(EditLine *el, wint_t 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);
return CC_REFRESH;
}
#ifdef VI_MOVE
el->el_line.cursor--;
#endif
}
return (CC_CURSOR);
return CC_CURSOR;
}
@@ -229,23 +233,23 @@ ed_move_to_end(EditLine *el, Int c __attribute__((__unused__)))
* Move cursor to the beginning of line
* [^A] [^A]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_move_to_beg(EditLine *el, Int c __attribute__((__unused__)))
ed_move_to_beg(EditLine *el, wint_t 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))
while (iswspace(*el->el_line.cursor))
el->el_line.cursor++;
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
}
return (CC_CURSOR);
return CC_CURSOR;
}
@@ -253,13 +257,13 @@ ed_move_to_beg(EditLine *el, Int c __attribute__((__unused__)))
* 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)
libedit_private el_action_t
ed_transpose_chars(EditLine *el, wint_t c)
{
if (el->el_line.cursor < el->el_line.lastchar) {
if (el->el_line.lastchar <= &el->el_line.buffer[1])
return (CC_ERROR);
return CC_ERROR;
else
el->el_line.cursor++;
}
@@ -268,9 +272,9 @@ ed_transpose_chars(EditLine *el, Int c)
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);
return CC_REFRESH;
} else
return (CC_ERROR);
return CC_ERROR;
}
@@ -278,17 +282,17 @@ ed_transpose_chars(EditLine *el, Int c)
* Move to the right one character
* [^F] [^F]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_next_char(EditLine *el, Int c __attribute__((__unused__)))
ed_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *lim = el->el_line.lastchar;
wchar_t *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);
return CC_ERROR;
el->el_line.cursor += el->el_state.argument;
if (el->el_line.cursor > lim)
@@ -297,9 +301,9 @@ ed_next_char(EditLine *el, Int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
@@ -307,13 +311,13 @@ ed_next_char(EditLine *el, Int c __attribute__((__unused__)))
* Move to the beginning of the current word
* [M-b] [b]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_prev_word(EditLine *el, Int c __attribute__((__unused__)))
ed_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR);
return CC_ERROR;
el->el_line.cursor = c__prev_word(el->el_line.cursor,
el->el_line.buffer,
@@ -323,9 +327,9 @@ ed_prev_word(EditLine *el, Int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
@@ -333,9 +337,9 @@ ed_prev_word(EditLine *el, Int c __attribute__((__unused__)))
* Move to the left one character
* [^B] [^B]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_prev_char(EditLine *el, Int c __attribute__((__unused__)))
ed_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
{
if (el->el_line.cursor > el->el_line.buffer) {
@@ -346,11 +350,11 @@ ed_prev_char(EditLine *el, Int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
} else
return (CC_ERROR);
return CC_ERROR;
}
@@ -358,32 +362,30 @@ ed_prev_char(EditLine *el, Int c __attribute__((__unused__)))
* Add the next character typed verbatim
* [^V] [^V]
*/
protected el_action_t
ed_quoted_insert(EditLine *el, Int c)
libedit_private el_action_t
ed_quoted_insert(EditLine *el, wint_t c)
{
int num;
Char tc;
tty_quotemode(el);
num = FUN(el,getc)(el, &tc);
c = tc;
num = el_wgetc(el, &c);
tty_noquotemode(el);
if (num == 1)
return (ed_insert(el, c));
return ed_insert(el, c);
else
return (ed_end_of_file(el, 0));
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)
libedit_private el_action_t
ed_digit(EditLine *el, wint_t c)
{
if (!Isdigit(c))
return (CC_ERROR);
if (!iswdigit(c))
return CC_ERROR;
if (el->el_state.doingarg) {
/* if doing an arg, add this in... */
@@ -391,11 +393,11 @@ ed_digit(EditLine *el, Int c)
el->el_state.argument = c - '0';
else {
if (el->el_state.argument > 1000000)
return (CC_ERROR);
return CC_ERROR;
el->el_state.argument =
(el->el_state.argument * 10) + (c - '0');
}
return (CC_ARGHACK);
return CC_ARGHACK;
}
return ed_insert(el, c);
@@ -406,23 +408,23 @@ ed_digit(EditLine *el, Int c)
* Digit that starts argument
* For ESC-n
*/
protected el_action_t
ed_argument_digit(EditLine *el, Int c)
libedit_private el_action_t
ed_argument_digit(EditLine *el, wint_t c)
{
if (!Isdigit(c))
return (CC_ERROR);
if (!iswdigit(c))
return CC_ERROR;
if (el->el_state.doingarg) {
if (el->el_state.argument > 1000000)
return (CC_ERROR);
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);
return CC_ARGHACK;
}
@@ -430,114 +432,27 @@ ed_argument_digit(EditLine *el, Int c)
* Indicates unbound character
* Bound to keys that are not assigned
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_unassigned(EditLine *el, Int c __attribute__((__unused__)))
ed_unassigned(EditLine *el __attribute__((__unused__)),
wint_t c __attribute__((__unused__)))
{
return (CC_ERROR);
return CC_ERROR;
}
/**
** TTY key handling.
**/
/* ed_tty_sigint():
* Tty interrupt character
* [^C]
/* ed_ignore():
* Input characters that have no effect
* [^C ^O ^Q ^S ^Z ^\ ^]] [^C ^O ^Q ^S ^\]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_tty_sigint(EditLine *el __attribute__((__unused__)),
Int c __attribute__((__unused__)))
ed_ignore(EditLine *el __attribute__((__unused__)),
wint_t 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);
return CC_NORM;
}
@@ -545,15 +460,15 @@ ed_tty_start_output(EditLine *el __attribute__((__unused__)),
* Execute command
* [^J]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_newline(EditLine *el, Int c __attribute__((__unused__)))
ed_newline(EditLine *el, wint_t c __attribute__((__unused__)))
{
re_goto_bottom(el);
*el->el_line.lastchar++ = '\n';
*el->el_line.lastchar = '\0';
return (CC_NEWLINE);
return CC_NEWLINE;
}
@@ -561,19 +476,19 @@ ed_newline(EditLine *el, Int c __attribute__((__unused__)))
* Delete the character to the left of the cursor
* [^?]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
ed_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
{
if (el->el_line.cursor <= el->el_line.buffer)
return (CC_ERROR);
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);
return CC_REFRESH;
}
@@ -581,14 +496,14 @@ ed_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
* Clear screen leaving current line at the top
* [^L]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_clear_screen(EditLine *el, Int c __attribute__((__unused__)))
ed_clear_screen(EditLine *el, wint_t c __attribute__((__unused__)))
{
term_clear_screen(el); /* clear the whole real screen */
terminal_clear_screen(el); /* clear the whole real screen */
re_clear_display(el); /* reset everything */
return (CC_REFRESH);
return CC_REFRESH;
}
@@ -596,13 +511,13 @@ ed_clear_screen(EditLine *el, Int c __attribute__((__unused__)))
* Redisplay everything
* ^R
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_redisplay(EditLine *el __attribute__((__unused__)),
Int c __attribute__((__unused__)))
wint_t c __attribute__((__unused__)))
{
return (CC_REDISPLAY);
return CC_REDISPLAY;
}
@@ -610,13 +525,13 @@ ed_redisplay(EditLine *el __attribute__((__unused__)),
* Erase current line and start from scratch
* [^G]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_start_over(EditLine *el, Int c __attribute__((__unused__)))
ed_start_over(EditLine *el, wint_t c __attribute__((__unused__)))
{
ch_reset(el, 0);
return (CC_REFRESH);
ch_reset(el);
return CC_REFRESH;
}
@@ -624,13 +539,13 @@ ed_start_over(EditLine *el, Int c __attribute__((__unused__)))
* First character in a bound sequence
* Placeholder for external keys
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
Int c __attribute__((__unused__)))
wint_t c __attribute__((__unused__)))
{
return (CC_NORM);
return CC_NORM;
}
@@ -638,9 +553,9 @@ ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
* Move to the previous history line
* [^P] [k]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_prev_history(EditLine *el, Int c __attribute__((__unused__)))
ed_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
{
char beep = 0;
int sv_event = el->el_history.eventno;
@@ -650,7 +565,7 @@ ed_prev_history(EditLine *el, Int c __attribute__((__unused__)))
if (el->el_history.eventno == 0) { /* save the current buffer
* away */
(void) Strncpy(el->el_history.buf, el->el_line.buffer,
(void) wcsncpy(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);
@@ -660,7 +575,6 @@ ed_prev_history(EditLine *el, Int c __attribute__((__unused__)))
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 */
@@ -676,9 +590,9 @@ ed_prev_history(EditLine *el, Int c __attribute__((__unused__)))
* Move to the next history line
* [^N] [j]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_next_history(EditLine *el, Int c __attribute__((__unused__)))
ed_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
{
el_action_t beep = CC_REFRESH, rval;
@@ -703,13 +617,13 @@ ed_next_history(EditLine *el, Int c __attribute__((__unused__)))
* Search previous in history for a line matching the current
* next search history [M-P] [K]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_search_prev_history(EditLine *el, Int c __attribute__((__unused__)))
ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
{
const Char *hp;
const wchar_t *hp;
int h;
bool_t found = 0;
int found = 0;
el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_undo.len = -1;
@@ -720,20 +634,20 @@ ed_search_prev_history(EditLine *el, Int c __attribute__((__unused__)))
"e_prev_search_hist(): eventno < 0;\n");
#endif
el->el_history.eventno = 0;
return (CC_ERROR);
return CC_ERROR;
}
if (el->el_history.eventno == 0) {
(void) Strncpy(el->el_history.buf, el->el_line.buffer,
(void) wcsncpy(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);
return CC_ERROR;
hp = HIST_FIRST(el);
if (hp == NULL)
return (CC_ERROR);
return CC_ERROR;
c_setpat(el); /* Set search pattern !! */
@@ -744,11 +658,11 @@ ed_search_prev_history(EditLine *el, Int c __attribute__((__unused__)))
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
#endif
if ((Strncmp(hp, el->el_line.buffer, (size_t)
if ((wcsncmp(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++;
found = 1;
break;
}
h++;
@@ -759,11 +673,11 @@ ed_search_prev_history(EditLine *el, Int c __attribute__((__unused__)))
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "not found\n");
#endif
return (CC_ERROR);
return CC_ERROR;
}
el->el_history.eventno = h;
return (hist_get(el));
return hist_get(el);
}
@@ -771,27 +685,27 @@ ed_search_prev_history(EditLine *el, Int c __attribute__((__unused__)))
* Search next in history for a line matching the current
* [M-N] [J]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_search_next_history(EditLine *el, Int c __attribute__((__unused__)))
ed_search_next_history(EditLine *el, wint_t c __attribute__((__unused__)))
{
const Char *hp;
const wchar_t *hp;
int h;
bool_t found = 0;
int 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);
return CC_ERROR;
if (el->el_history.ref == NULL)
return (CC_ERROR);
return CC_ERROR;
hp = HIST_FIRST(el);
if (hp == NULL)
return (CC_ERROR);
return CC_ERROR;
c_setpat(el); /* Set search pattern !! */
@@ -799,7 +713,7 @@ ed_search_next_history(EditLine *el, Int c __attribute__((__unused__)))
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
#endif
if ((Strncmp(hp, el->el_line.buffer, (size_t)
if ((wcsncmp(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))
@@ -812,12 +726,12 @@ ed_search_next_history(EditLine *el, Int c __attribute__((__unused__)))
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "not found\n");
#endif
return (CC_ERROR);
return CC_ERROR;
}
}
el->el_history.eventno = found;
return (hist_get(el));
return hist_get(el);
}
@@ -825,11 +739,11 @@ ed_search_next_history(EditLine *el, Int c __attribute__((__unused__)))
* Move up one line
* Could be [k] [^p]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_prev_line(EditLine *el, Int c __attribute__((__unused__)))
ed_prev_line(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *ptr;
wchar_t *ptr;
int nchars = c_hpos(el);
/*
@@ -843,7 +757,7 @@ ed_prev_line(EditLine *el, Int c __attribute__((__unused__)))
break;
if (el->el_state.argument > 0)
return (CC_ERROR);
return CC_ERROR;
/*
* Move to the beginning of the line
@@ -860,7 +774,7 @@ ed_prev_line(EditLine *el, Int c __attribute__((__unused__)))
continue;
el->el_line.cursor = ptr;
return (CC_CURSOR);
return CC_CURSOR;
}
@@ -868,11 +782,11 @@ ed_prev_line(EditLine *el, Int c __attribute__((__unused__)))
* Move down one line
* Could be [j] [^n]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_next_line(EditLine *el, Int c __attribute__((__unused__)))
ed_next_line(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *ptr;
wchar_t *ptr;
int nchars = c_hpos(el);
/*
@@ -883,7 +797,7 @@ ed_next_line(EditLine *el, Int c __attribute__((__unused__)))
break;
if (el->el_state.argument > 0)
return (CC_ERROR);
return CC_ERROR;
/*
* Move to the character requested
@@ -894,7 +808,7 @@ ed_next_line(EditLine *el, Int c __attribute__((__unused__)))
continue;
el->el_line.cursor = ptr;
return (CC_CURSOR);
return CC_CURSOR;
}
@@ -902,18 +816,18 @@ ed_next_line(EditLine *el, Int c __attribute__((__unused__)))
* Editline extended command
* [M-X] [:]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_command(EditLine *el, Int c __attribute__((__unused__)))
ed_command(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char tmpbuf[EL_BUFSIZ];
wchar_t tmpbuf[EL_BUFSIZ];
int tmplen;
tmplen = c_gets(el, tmpbuf, STR("\n: "));
term__putc(el, '\n');
tmplen = c_gets(el, tmpbuf, L"\n: ");
terminal__putc(el, '\n');
if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
term_beep(el);
terminal_beep(el);
el->el_map.current = el->el_map.key;
re_clear_display(el);

997
lib/libedit/src/editline.3 Normal file
View File

@@ -0,0 +1,997 @@
.\" $NetBSD: editline.3,v 1.92 2016/05/22 23:54:20 christos Exp $
.\"
.\" Copyright (c) 1997-2014 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 May 22, 2016
.Dt EDITLINE 3
.Os
.Sh NAME
.Nm editline ,
.Nm el_init ,
.Nm el_init_fd ,
.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_cursor ,
.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 EditLine *
.Fn el_init_fd "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr" "int fdin" "int fdout" "int fderr"
.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 *wc"
.Ft void
.Fn el_push "EditLine *e" "const char *mbs"
.Ft void
.Fn el_wpush "EditLine *e" "const wchar_t *wcs"
.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 int
.Fn el_cursor "EditLine *e" "int count"
.Ft const LineInfo *
.Fn el_line "EditLine *e"
.Ft const LineInfoW *
.Fn el_wline "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 void
.Ft HistoryW *
.Fn history_winit void
.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 .
.Pp
The
.Nm
library respects the
.Ev LC_CTYPE
locale set by the application program and never uses
.Xr setlocale 3
to change the locale.
The only locales supported are UTF-8 and the default C or POSIX locale.
If any other locale is set, behaviour is undefined.
.Sh LINE EDITING FUNCTIONS
The line editing functions use a common data structure,
.Fa EditLine ,
which is created by
.Fn el_init
or
.Fn el_init_fd
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
Initialize the line editor, and return a data structure
to be used by all other line editing functions, or
.Dv NULL
on failure.
.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_init_fd
Like
.Fn el_init
but allows specifying file descriptors for the
.Xr stdio 3
corresponding streams, in case those were created with
.Xr funopen 3 .
.It Fn el_end
Clean up and finish with
.Fa e ,
assumed to have been created with
.Fn el_init
or
.Fn el_init_fd .
.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_wgetc
Read a wide character from the tty, respecting the current locale,
or from the input queue described in
.Xr editline 7
if that is not empty, and store it in
.Fa wc .
If an invalid or incomplete character is found, it is discarded,
.Va errno
is set to
.Er EILSEQ ,
and the next character is read and stored in
.Fa wc .
Returns 1 if a valid character was read, 0 on end of file, or \-1 on
.Xr read 2
failure.
In the latter case,
.Va errno
is set to indicate the error.
.It Fn el_getc
Read a wide character as described for
.Fn el_wgetc
and return 0 on end of file or \-1 on failure.
If the wide character can be represented as a single-byte character,
convert it with
.Xr wctob 3 ,
store the result in
.Fa ch ,
and return 1; otherwise, set
.Va errno
to
.Er ERANGE
and return \-1.
In the C or POSIX locale, this simply reads a byte, but for any other
locale, including UTF-8, this is rarely useful.
.It Fn el_wpush
Push the wide character string
.Fa wcs
back onto the input queue described in
.Xr editline 7 .
If the queue overflows, for example due to a recursive macro,
or if an error occurs, for example because
.Fa wcs
is
.Dv NULL
or memory allocation fails, the function beeps at the user,
but does not report the problem to the caller.
.It Fn el_push
Use the current locale to convert the multibyte string
.Fa mbs
to a wide character string, and pass the result to
.Fn el_wpush .
.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.
Returns 0 on success, \-1 on failure.
.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 "el_rfunc_t f"
Whenever reading a character, use the function
.Bd -ragged -offset indent -compact
.Ft int
.Fo f
.Fa "EditLine *e"
.Fa "wchar_t *wc"
.Fc
.Ed
which stores the character in
.Fa wc
and returns 1 on success, 0 on end of file, or \-1 on I/O or encoding
errors.
Functions internally using it include
.Fn el_wgets ,
.Fn el_wgetc ,
.Fn el_gets ,
and
.Fn el_getc .
Initially, a builtin function is installed, and replacing it
is discouraged because writing such a function is very error prone.
The builtin function can be restored at any time by passing the
special value
.Dv EL_BUILTIN_GETCFN
instead of a function pointer.
.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"
Set
.Fa f
to a pointer to the function that displays the prompt.
If
.Fa c
is not
.Dv NULL ,
set it to the start/stop literal prompt character.
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
Set
.Fa f
to a pointer to the function that displays the prompt.
If
.Fa c
is not
.Dv NULL ,
set it to the start/stop literal prompt character.
.It Dv EL_EDITOR , Fa "const char **n"
Set the name of the editor in
.Fa n ,
which will be one of
.Dq emacs
or
.Dq vi .
.It Dv EL_GETTC , Fa "const char *name" , Fa "void *value"
If
.Fa name
is a valid
.Xr termcap 5
capability set
.Fa value
to the current value of that capability.
.It Dv EL_SIGNAL , Fa "int *s"
Set
.Fa s
to non-zero if
.Nm
has installed private signal handlers (see
.Fn el_get
above).
.It Dv EL_EDITMODE , Fa "int *c"
Set
.Fa c
to non-zero if editing is enabled.
.It Dv EL_GETCFN , Fa "el_rfunc_t *f"
Set
.Fa f
to a pointer to the function that reads characters, or to
.Dv EL_BUILTIN_GETCFN
if the builtin function is in use.
.It Dv EL_CLIENTDATA , Fa "void **data"
Set
.Fa data
to the previously registered client data set by an
.Fn el_set
call.
.It Dv EL_UNBUFFERED , Fa "int *c"
Set
.Fa c
to non-zero if unbuffered mode is enabled.
.It Dv EL_GETFP , Fa "int fd", Fa "FILE **fp"
Set
.Fa fp
to 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
Initialize
.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 $HOME/.editrc .
Refer to
.Xr editrc 5
for details on the format of
.Fa file .
.Fn el_source
returns 0 on success and \-1 on error.
.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_cursor
Move the cursor to the right (if positive) or to the left (if negative)
.Fa count
characters.
Returns the resulting offset of the cursor from the beginning of the line.
.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
Initialize the history list, and return a data structure
to be used by all other history list functions, or
.Dv NULL
on failure.
.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 is newer than the current one.
.It Dv H_NEXT
Return the next element in the history.
It is older than the current one.
.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
has been called with a non-zero argument, 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_SAVE_FP , Fa "FILE *fp"
Save the history list to the opened
.Ft FILE
pointer
.Fa fp .
.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
Initialize 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 ,
.Xr editline 7
.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
.An -nosplit
The
.Nm
library was written by
.An Christos Zoulas .
.An Luke Mewburn
wrote this manual and implemented
.Dv CC_REDISPLAY ,
.Dv CC_REFRESH_BEEP ,
.Dv EL_EDITMODE ,
and
.Dv EL_RPROMPT .
.An Jaromir Dolecek
implemented the readline emulation.
.An 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.

935
lib/libedit/src/editline.7 Normal file
View File

@@ -0,0 +1,935 @@
.\" $NetBSD: editline.7,v 1.5 2016/05/09 21:27:55 christos Exp $
.\" $OpenBSD: editline.7,v 1.1 2016/04/20 01:11:45 schwarze Exp $
.\"
.\" Copyright (c) 2016 Ingo Schwarze <schwarze@openbsd.org>
.\"
.\" Permission to use, copy, modify, and distribute this software for any
.\" purpose with or without fee is hereby granted, provided that the above
.\" copyright notice and this permission notice appear in all copies.
.\"
.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
.Dd May 7, 2016
.Dt EDITLINE 7
.Os
.Sh NAME
.Nm editline
.Nd line editing user interface
.Sh DESCRIPTION
When a program using the
.Xr editline 3
library prompts for an input string using the function
.Xr el_wgets 3 ,
it reads characters from the terminal.
Invalid input bytes that do not form characters are silently
discarded.
For each character read, one editor command is executed.
The mapping of input characters to editor commands depends on the
editing mode.
There are three editing modes: vi insert mode, vi command mode,
and emacs mode.
The default is vi insert mode.
The program can switch the default to emacs mode by using the
.Xr el_set 3
or
.Xr el_parse 3
functions, and the user can switch to emacs mode either in the
.Xr editrc 5
configuration file or interactively with the
.Ic ed-command
editor command, in all three cases executing the
.Ic bind Fl e
builtin command.
.Pp
If trying to read from the terminal results in end of file or an
error, the library signals end of file to the program and does not
return a string.
.Ss Input character bindings
All default bindings described below can be overridden by individual
programs and can be changed with the
.Xr editrc 5
.Ic bind
builtin command.
.Pp
In the following tables,
.Sq Ctrl-
indicates a character with the bit 0x40 flipped, and
.Sq Meta-
indicates a character with the bit 0x80 set.
In vi insert mode and in emacs mode, all Meta-characters considered
printable by the current
.Xr locale 1
are bound to
.Ic ed-insert
instead of to the editor command listed below.
Consequently, in UTF-8 mode, most of the Meta-characters are not
directly accessible because their code points are occupied by
printable Unicode characters, and Meta-characters are usually input
using the
.Ic em-meta-next
editor command.
For example, to enter
.Sq Meta-B
in order to call the
.Ic ed-prev-word
editor command in emacs mode, call
.Ic em-meta-next
by pressing and releasing the escape key (or equivalently, Ctrl-[),
then press and release the
.Sq B
key.
If you have configured a Meta-key on your keyboard, for example
with
.Ql setxkbmap -option altwin:left_meta_win ,
the Ctrl-Meta-characters are directly accessible.
For example, to enter
.Sq Ctrl-Meta-H
in order to call the
.Ic ed-delete-prev-word
editor command in emacs mode, hold down the keys
.Sq Ctrl ,
.Sq Meta ,
and
.Sq H
at the same time.
Alternatively, press and release the escape key, then press and
release
.Sq Ctrl-H .
.Pp
In vi input mode, input characters are bound to the following editor
commands by default:
.Bl -column -offset indent "Ctrl-Z, TSTP" "ed-search-next-history"
.It Ctrl-D, EOF Ta Ic vi-list-or-eof
.It Ctrl-H, BS Ta Ic vi-delete-prev-char
.It Ctrl-J, LF Ta Ic ed-newline
.It Ctrl-M, CR Ta Ic ed-newline
.It Ctrl-Q Ta Ic ed-tty-start-output
.It Ctrl-S Ta Ic ed-tty-stop-output
.It Ctrl-U Ta Ic vi-kill-line-prev
.It Ctrl-V Ta Ic ed-quoted-insert
.It Ctrl-W Ta Ic ed-delete-prev-word
.It Ctrl-[, ESC Ta Ic vi-command-mode
.It Ctrl-\e, QUIT Ta Ic ed-tty-sigquit
.It Ctrl-?, DEL Ta Ic vi-delete-prev-char
.El
.Pp
All other input characters except the NUL character (Ctrl-@) are
bound to
.Ic ed-insert .
.Pp
In vi command mode, input characters are bound to the following
editor commands by default:
.Bl -column -offset indent "Ctrl-Z, TSTP" "ed-search-next-history"
.It Ctrl-A Ta Ic ed-move-to-beg
.It Ctrl-C, INT Ta Ic ed-tty-sigint
.It Ctrl-E Ta Ic ed-move-to-end
.It Ctrl-H, BS Ta Ic ed-delete-prev-char
.It Ctrl-J, LF Ta Ic ed-newline
.It Ctrl-K Ta Ic ed-kill-line
.It Ctrl-L, FF Ta Ic ed-clear-screen
.It Ctrl-M, CR Ta Ic ed-newline
.It Ctrl-N Ta Ic ed-next-history
.It Ctrl-O Ta Ic ed-tty-flush-output
.It Ctrl-P Ta Ic ed-prev-history
.It Ctrl-Q Ta Ic ed-tty-start-output
.It Ctrl-R Ta Ic ed-redisplay
.It Ctrl-S Ta Ic ed-tty-stop-output
.It Ctrl-U Ta Ic vi-kill-line-prev
.It Ctrl-W Ta Ic ed-delete-prev-word
.It Ctrl-[, ESC Ta Ic em-meta-next
.It Ctrl-\e, QUIT Ta Ic ed-tty-sigquit
.It Space Ta Ic ed-next-char
.It # Ta Ic vi-comment-out
.It $ Ta Ic ed-move-to-end
.It % Ta Ic vi-match
.It + Ta Ic ed-next-history
.It \&, Ta Ic vi-repeat-prev-char
.It - Ta Ic ed-prev-history
.It \&. Ta Ic vi-redo
.It / Ta Ic vi-search-prev
.It 0 Ta Ic vi-zero
.It 1 to 9 Ta Ic ed-argument-digit
.It \&: Ta Ic ed-command
.It \&; Ta Ic vi-repeat-next-char
.It \&? Ta Ic vi-search-next
.It @ Ta Ic vi-alias
.It A Ta Ic vi-add-at-eol
.It B Ta Ic vi-prev-big-word
.It C Ta Ic vi-change-to-eol
.It D Ta Ic ed-kill-line
.It E Ta Ic vi-end-big-word
.It F Ta Ic vi-prev-char
.It G Ta Ic vi-to-history-line
.It I Ta Ic vi-insert-at-bol
.It J Ta Ic ed-search-next-history
.It K Ta Ic ed-search-prev-history
.It N Ta Ic vi-repeat-search-prev
.It O Ta Ic ed-sequence-lead-in
.It P Ta Ic vi-paste-prev
.It R Ta Ic vi-replace-mode
.It S Ta Ic vi-substitute-line
.It T Ta Ic vi-to-prev-char
.It U Ta Ic vi-undo-line
.It W Ta Ic vi-next-big-word
.It X Ta Ic ed-delete-prev-char
.It Y Ta Ic vi-yank-end
.It \&[ Ta Ic ed-sequence-lead-in
.It ^ Ta Ic ed-move-to-beg
.It _ Ta Ic vi-history-word
.It a Ta Ic vi-add
.It b Ta Ic vi-prev-word
.It c Ta Ic vi-change-meta
.It d Ta Ic vi-delete-meta
.It e Ta Ic vi-end-word
.It f Ta Ic vi-next-char
.It h Ta Ic ed-prev-char
.It i Ta Ic vi-insert
.It j Ta Ic ed-next-history
.It k Ta Ic ed-prev-history
.It l Ta Ic ed-next-char
.It n Ta Ic vi-repeat-search-next
.It p Ta Ic vi-paste-next
.It r Ta Ic vi-replace-char
.It s Ta Ic vi-substitute-char
.It t Ta Ic vi-to-next-char
.It u Ta Ic vi-undo
.It v Ta Ic vi-histedit
.It w Ta Ic vi-next-word
.It x Ta Ic ed-delete-next-char
.It y Ta Ic vi-yank
.It \&| Ta Ic vi-to-column
.It ~ Ta Ic vi-change-case
.It Ctrl-?, DEL Ta Ic ed-delete-prev-char
.It Meta-O Ta Ic ed-sequence-lead-in
.It Meta-[ Ta Ic ed-sequence-lead-in
.El
.Pp
In emacs mode, input characters are bound to the following editor
commands by default:
.Bl -column -offset indent "Ctrl-Z, TSTP" "ed-search-next-history"
.It 0 to 9 Ta Ic ed-digit
.It Ctrl-@, NUL Ta Ic em-set-mark
.It Ctrl-A Ta Ic ed-move-to-beg
.It Ctrl-B Ta Ic ed-prev-char
.It Ctrl-C, INT Ta Ic ed-tty-sigint
.It Ctrl-D, EOF Ta Ic em-delete-or-list
.It Ctrl-E Ta Ic ed-move-to-end
.It Ctrl-F Ta Ic ed-next-char
.It Ctrl-H, BS Ta Ic em-delete-prev-char
.It Ctrl-J, LF Ta Ic ed-newline
.It Ctrl-K Ta Ic ed-kill-line
.It Ctrl-L, FF Ta Ic ed-clear-screen
.It Ctrl-M, CR Ta Ic ed-newline
.It Ctrl-N Ta Ic ed-next-history
.It Ctrl-O Ta Ic ed-tty-flush-output
.It Ctrl-P Ta Ic ed-prev-history
.It Ctrl-Q Ta Ic ed-tty-start-output
.It Ctrl-R Ta Ic ed-redisplay
.It Ctrl-S Ta Ic ed-tty-stop-output
.It Ctrl-T Ta Ic ed-transpose-chars
.It Ctrl-U Ta Ic ed-kill-line
.It Ctrl-V Ta Ic ed-quoted-insert
.It Ctrl-W Ta Ic em-kill-region
.It Ctrl-X Ta Ic ed-sequence-lead-in
.It Ctrl-Y Ta Ic em-yank
.It Ctrl-Z, TSTP Ta Ic ed-tty-sigtstp
.It Ctrl-[, ESC Ta Ic em-meta-next
.It Ctrl-\e, QUIT Ta Ic ed-tty-sigquit
.It Ctrl-] Ta Ic ed-tty-dsusp
.It Ctrl-?, DEL Ta Ic em-delete-prev-char
.It Ctrl-Meta-H Ta Ic ed-delete-prev-word
.It Ctrl-Meta-L Ta Ic ed-clear-screen
.It Ctrl-Meta-_ Ta Ic em-copy-prev-word
.It Meta-0 to 9 Ta Ic ed-argument-digit
.It Meta-B Ta Ic ed-prev-word
.It Meta-C Ta Ic em-capitol-case
.It Meta-D Ta Ic em-delete-next-word
.It Meta-F Ta Ic em-next-word
.It Meta-L Ta Ic em-lower-case
.It Meta-N Ta Ic ed-search-next-history
.It Meta-O Ta Ic ed-sequence-lead-in
.It Meta-P Ta Ic ed-search-prev-history
.It Meta-U Ta Ic em-upper-case
.It Meta-W Ta Ic em-copy-region
.It Meta-X Ta Ic ed-command
.It Meta-[ Ta Ic ed-sequence-lead-in
.It Meta-b Ta Ic ed-prev-word
.It Meta-c Ta Ic em-capitol-case
.It Meta-d Ta Ic em-delete-next-word
.It Meta-f Ta Ic em-next-word
.It Meta-l Ta Ic em-lower-case
.It Meta-n Ta Ic ed-search-next-history
.It Meta-p Ta Ic ed-search-prev-history
.It Meta-u Ta Ic em-upper-case
.It Meta-w Ta Ic em-copy-region
.It Meta-x Ta Ic ed-command
.It Ctrl-Meta-? Ta Ic ed-delete-prev-word
.El
.Pp
The remaining
.Xr ascii 7
characters in the range 0x20 to 0x7e are bound to
.Ic ed-insert .
.Pp
If standard output is not connected to a terminal device
or
.Xr el_set 3
was used to set
.Dv EL_EDITMODE
to 0, all input character bindings are disabled and all characters
typed are appended to the edit buffer.
In that case, the edit buffer is returned to the program after a
newline or carriage return character is typed, or after the first
character typed if
.Xr el_set 3
was used to set
.Dv EL_UNBUFFERED
to non-zero.
.Ss Editor commands
Most editor commands accept an optional argument.
The argument is entered by prefixing the editor command with one
or more of the editor commands
.Ic ed-argument-digit ,
.Ic ed-digit ,
.Ic em-universal-argument ,
or
.Ic vi-zero .
When an argument is not provided, it defaults to 1.
For most editor commands, the effect of an argument is to repeatedly
execute the command that number of times.
.Pp
When talking about a character string from a left character to a
right character, the left character is included in the string, while
the right character is not included.
.Pp
If an editor command causes an error, the input character is discarded,
no action occurs, and the terminal bell is rung.
In case of a non-fatal error, the terminal bell is also rung,
but the editor command takes effect anyway.
.Pp
In the following list, the default key bindings are listed after
each editor command.
.Bl -tag -width 4n
.It Ic ed-argument-digit Pq vi command: 1 to 9; emacs: Meta-0 to Meta-9
If in argument input mode, append the input digit to the argument
being read.
Otherwise, switch to argument input mode and use the input digit
as the most significant digit of the argument.
It is an error if the input character is not a digit or if the
existing argument is already greater than a million.
.It Ic ed-clear-screen Pq vi command: Ctrl-L; emacs: Ctrl-L, Ctrl-Meta-L
Clear the screen and display the edit buffer at the top.
Ignore any argument.
.It Ic ed-command Pq vi command: So \&: Sc ; emacs: Meta-X, Meta-x
Read a line from the terminal bypassing the normal line editing
functionality and execute that line as an
.Xr editrc 5
builtin command.
If in vi command mode, also switch back to vi insert mode.
Ignore any argument.
.It Ic ed-delete-next-char Pq vi command: x
Delete the character at the cursor position.
With an argument, delete that number of characters.
In emacs mode, it is an error if the cursor is at the end of the
edit buffer.
In vi mode, the last character in the edit buffer is deleted in
that case, and it is an error if the buffer is empty.
.It Ic ed-delete-prev-char Pq vi command: X, Ctrl-H, BS, Ctrl-?, DEL
Delete the character to the left of the cursor position.
With an argument, delete that number of characters.
It is an error if the cursor is at the beginning of the edit buffer.
.It Ic ed-delete-prev-word Pq vi: Ctrl-W; emacs: Ctrl-Meta-H, Ctrl-Meta-?
Move to the left to the closest beginning of a word, delete the
string from that position to the cursor, and save it to the cut
buffer.
With an argument, delete that number of words.
It is an error if the cursor is at the beginning of the edit buffer.
.It Ic ed-digit Pq emacs: 0 to 9
If in argument input mode, append the input digit to the argument
being read.
Otherwise, call
.Ic ed-insert .
It is an error if the input character is not a digit or if the
existing argument is already greater than a million.
.It Ic ed-end-of-file Pq not bound by default
Discard the edit buffer and indicate end of file to the program.
Ignore any argument.
.It Ic ed-ignore Pq various
Discard the input character and do nothing.
.It Ic ed-insert Pq vi input: almost all; emacs: printable characters
In insert mode, insert the input character left of the cursor
position.
In replace mode, overwrite the character at the cursor and move the
cursor to the right by one character position.
Accept an argument to do this repeatedly.
It is an error if the input character is the NUL character (Ctrl-@).
Failure to enlarge the edit buffer also results in an error.
.It Ic ed-kill-line Pq vi command: D, Ctrl-K; emacs: Ctrl-K, Ctrl-U
Delete the string from the cursor position to the end of the line
and save it to the cut buffer.
Ignore any argument.
.It Ic ed-move-to-beg Pq vi command: ^, Ctrl-A; emacs: Ctrl-A
In vi mode, move the cursor to the first non-space character in the
edit buffer.
In emacs mode, move the cursor to the beginning of the edit buffer.
Ignore any argument.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
.It Ic ed-move-to-end Pq vi command: $, Ctrl-E; emacs: Ctrl-E
Move the cursor to the end of the edit buffer.
Ignore any argument.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
.It Ic ed-newline Pq all modes: Ctrl-J, LF, Ctrl-M, CR
Append a newline character to the edit buffer and return the edit
buffer to the program.
Ignore any argument.
.It Ic ed-next-char Pq vi command: Space, l; emacs: Ctrl-F
Move the cursor one character position to the right.
With an argument, move by that number of characters.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
It is an error if the cursor is already at the end of the edit
buffer.
.It Ic ed-next-history Pq vi command: j, +, Ctrl-N; emacs: Ctrl-N
Replace the edit buffer with the next history line.
That line is older than the current line.
With an argument, go forward by that number of history lines.
It is a non-fatal error to advance by more lines than are available.
.It Ic ed-next-line Pq not bound by default
Move the cursor down one line.
With an argument, move down by that number of lines.
It is an error if the edit buffer does not contain enough newline
characters to the right of the cursor position.
.It Ic ed-prev-char Pq vi command: h; emacs: Ctrl-B
Move the cursor one character position to the left.
With an argument, move by that number of characters.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
It is an error if the cursor is already at the beginning of the
edit buffer.
.It Ic ed-prev-history Pq vi command: k, -, Ctrl-P; emacs: Ctrl-P
Replace the edit buffer with the previous history line.
That line is newer than the current line.
With an argument, go back by that number of lines.
It is a non-fatal error to back up by more lines than are available.
.It Ic ed-prev-line Pq not bound by default
Move the cursor up one line.
With an argument, move up by that number of lines.
It is an error if the edit buffer does not contain enough newline
characters to the left of the cursor position.
.It Ic ed-prev-word Pq emacs: Meta-B, Meta-b
Move the cursor to the left to the closest beginning of a word.
With an argument, repeat that number of times.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
It is an error if the cursor is already at the beginning of the
edit buffer.
.It Ic ed-quoted-insert Pq vi insert, emacs: Ctrl-V
Read one character from the terminal bypassing the normal line
editing functionality and call
.Ic ed-insert
on it.
If trying to read the character returns end of file or an error,
call
.Ic ed-end-of-file
instead.
.It Ic ed-redisplay Pq vi command, emacs: Ctrl-R
Redisplay everything.
Ignore any argument.
.It Ic ed-search-next-history Pq vi command: J; emacs: Meta-N, Meta-n
Replace the edit buffer with the next matching history entry.
.It Ic ed-search-prev-history Pq vi command: K; emacs: Meta-P, Meta-p
Replace the edit buffer with the previous matching history entry.
.It Ic ed-sequence-lead-in Pq vi cmd: O, \&[; emacs: Ctrl-X;\
both: Meta-O, Meta-[
Call a macro.
See the section about
.Sx Macros
below for details.
.It Ic ed-start-over Pq not bound by default
Discard the contents of the edit buffer and start from scratch.
Ignore any argument.
.It Ic ed-transpose-chars Pq emacs: Ctrl-T
Exchange the character at the cursor position with the one to the
left of it and move the cursor to the character to the right of the
two exchanged characters.
Ignore any argument.
It is an error if the cursor is at the beginning of the edit buffer
or if the edit buffer contains less than two characters.
.It Ic ed-unassigned Pq all characters not listed
This editor command always results in an error.
.It Ic em-capitol-case Pq emacs: Meta-C, Meta-c
Capitalize the string from the cursor to the end of the current
word.
That is, if it contains at least one alphabetic character, convert
the first alphabetic character to upper case, and convert all
characters to the right of it to lower case.
In any case, move the cursor to the next character after the end
of the current word.
.It Ic em-copy-prev-word Pq emacs: Ctrl-Meta-_
Copy the string from the beginning of the current word to the cursor
and insert it to the left of the cursor.
Move the cursor to the character after the inserted string.
It is an error if the cursor is at the beginning of the edit buffer.
.It Ic em-copy-region Pq emacs: Meta-W, Meta-w
Copy the string from the cursor to the mark to the cut buffer.
It is an error if the mark is not set.
.It Ic em-delete-next-word Pq emacs: Meta-D, Meta-d
Delete the string from the cursor to the end of the current word
and save it to the cut buffer.
It is an error if the cursor is at the end of the edit buffer.
.It Ic em-delete-or-list Pq emacs: Ctrl-D, EOF
If the cursor is not at the end of the line, delete the character
at the cursor.
If the edit buffer is empty, indicate end of file to the program.
It is an error if the cursor is at the end of the edit buffer and
the edit buffer is not empty.
.It Ic em-delete-prev-char Pq emacs: Ctrl-H, BS, Ctrl-?, DEL
Delete the character to the left of the cursor.
It is an error if the cursor is at the beginning of the edit buffer.
.It Ic em-exchange-mark Pq not bound by default
Exchange the cursor and the mark.
.It Ic em-gosmacs-transpose Pq not bound by default
Exchange the two characters to the left of the cursor.
It is an error if the cursor is on the first or second character
of the edit buffer.
.It Ic em-inc-search-next Pq not bound by default
Emacs incremental next search.
.It Ic em-inc-search-prev Pq not bound by default
Emacs incremental reverse search.
.It Ic em-kill-line Pq not bound by default
Delete the entire contents of the edit buffer and save it to the
cut buffer.
.It Ic em-kill-region Pq emacs: Ctrl-W
Delete the string from the cursor to the mark and save it to the
cut buffer.
It is an error if the mark is not set.
.It Ic em-lower-case Pq emacs: Meta-L, Meta-l
Convert the characters from the cursor to the end of the current
word to lower case.
.It Ic em-meta-next Pq vi command, emacs: Ctrl-[, ESC
Set the bit 0x80 on the next character typed.
Unless the resulting code point is printable, holding down the
.Sq Meta-
key while typing that character is a simpler way to achieve the
same effect.
.It Ic em-next-word Pq Meta-F, Meta-f
Move the cursor to the end of the current word.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
It is an error if the cursor is already at the end of the edit
buffer.
.It Ic em-set-mark Pq emacs: Ctrl-Q, NUL
Set the mark at the current cursor position.
.It Ic em-toggle-overwrite Pq not bound by default
Switch from insert to overwrite mode or vice versa.
.It Ic em-universal-argument Pq not bound by default
If in argument input mode, multiply the argument by 4.
Otherwise, switch to argument input mode and set the argument to 4.
It is an error if the existing argument is already greater than a
million.
.It Ic em-upper-case Pq emacs: Meta-U, Meta-u
Convert the characters from the cursor to the end of the current
word to upper case.
.It Ic em-yank Pq emacs: Ctrl-Y
Paste the cut buffer to the left of the cursor.
.It Ic vi-add Pq vi command: a
Switch to vi insert mode.
Unless the cursor is already at the end of the edit buffer, move
it one character position to the right.
.It Ic vi-add-at-eol Pq vi command: A
Switch to vi insert mode and move the cursor to the end of the edit
buffer.
.It Ic vi-alias Pq vi command: @
If an alias function was defined by calling the
.Xr el_set 3
or
.Xr el_wset 3
function with the argument
.Dv EL_ALIAS_TEXT ,
read one character from the terminal bypassing the normal line
editing functionality, call the alias function passing the argument that was specified with
.Dv EL_ALIAS_TEXT
as the first argument and the character read, with an underscore
prepended, as the second argument, and pass the string returned
from the alias function to
.Xr el_wpush 3 .
It is an error if no alias function is defined or if trying to read
the character results in end of file or an error.
.It Ic vi-change-case Pq vi command: ~
Change the case of the character at the cursor and move the cursor
one character position to the right.
It is an error if the cursor is already at the end of the edit
buffer.
.It Ic vi-change-meta Pq vi command: c
Delete the string from the cursor to the position specified by the
following movement command and save a copy of it to the cut buffer.
When given twice in a row, instead delete the whole contents of the
edit buffer and save a copy of it to the cut buffer.
In either case, switch to vi insert mode after that.
.It Ic vi-change-to-eol Pq vi command: C
Delete the string from the cursor position to the end of the line
and save it to the cut buffer, then switch to vi insert mode.
.It Ic vi-command-mode Pq vi insert: Ctrl-[, ESC
Discard pending actions and arguments and switch to vi command mode.
Unless the cursor is already at the beginning of the edit buffer,
move it to the left by one character position.
.It Ic vi-comment-out Pq vi command: #
Insert a
.Sq #
character at the beginning of the edit buffer and return the edit
buffer to the program.
.It Ic vi-delete-meta Pq vi command: d
Delete the string from the cursor to the position specified by the
following movement command and save a copy of it to the cut buffer.
When given twice in a row, instead delete the whole contents of the
edit buffer and save a copy of it to the cut buffer.
.It Ic vi-delete-prev-char Pq vi insert: Ctrl-H, BS, Ctrl-?, DEL
Delete the character to the left of the cursor.
It is an error if the cursor is already at the beginning of the
edit buffer.
.It Ic vi-end-big-word Pq vi command: E
Move the cursor to the end of the current space delimited word.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
It is an error if the cursor is already at the end of the edit
buffer.
.It Ic vi-end-word Pq vi command: e
Move the cursor to the end of the current word.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
It is an error if the cursor is already at the end of the edit
buffer.
.It Ic vi-history-word Pq vi command: _
Insert the first word from the most recent history entry after the
cursor, move the cursor after to the character after the inserted
word, and switch to vi insert mode.
It is an error if there is no history entry or the most recent
history entry is empty.
.It Ic vi-insert Pq vi command: i
Enter insert mode.
.It Ic vi-insert-at-bol Pq vi command: I
Move the cursor to the beginning of the edit buffer and switch to
vi insert mode.
.It Ic vi-kill-line-prev Pq vi: Ctrl-U
Delete the string from the beginning of the edit buffer to the
cursor and save it to the cut buffer.
.It Ic vi-list-or-eof Pq vi insert: Ctrl-D, EOF
If the edit buffer is empty, indicate end of file to the program.
It is an error if the edit buffer is not empty.
.It Ic vi-match Pq vi command: %
Consider opening and closing parentheses, braces, and brackets as
delimiters.
If the cursor is not at a delimiter, move it to the right until it
gets to one, then move it to the matching delimiter.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
It is an error if there is no delimiter at the cursor or in the
string to the right of the cursor, or if the first such delimiter
has no matching delimiter.
.It Ic vi-next-big-word Pq vi command: W
Move the cursor to the right to the beginning of the next space
delimited word.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
It is an error if the cursor is already at the end of the edit
buffer or on its last character.
.It Ic vi-next-char Pq vi command: f
Read one character from the terminal bypassing the normal line
editing functionality and move the cursor to the right to the next
instance of that character in the edit buffer.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
If trying to read the character results in end of file or an error,
call
.Ic ed-end-of-file
instead.
It is an error if the character is not found searching to the right
in the edit buffer.
.It Ic vi-next-word Pq vi command: w
Move the cursor to the right to the beginning of the next word.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
It is an error if the cursor is already at the end of the edit
buffer or on its last character.
.It Ic vi-paste-next Pq vi command: p
Insert a copy of the cut buffer to the right of the cursor.
It is an error if the cut buffer is empty.
.It Ic vi-paste-prev Pq vi command: P
Insert a copy of the cut buffer to the left of the cursor.
It is an error if the cut buffer is empty.
.It Ic vi-prev-big-word Pq vi command: B
Move the cursor to the left to the next beginning of a space delimited
word.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
It is an error if the cursor is already at the beginning of the
edit buffer.
.It Ic vi-prev-char Pq vi command: F
Read one character from the terminal bypassing the normal line
editing functionality and move the cursor to the left to the next
instance of that character in the edit buffer.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
If trying to read the character results in end of file or an error,
call
.Ic ed-end-of-file
instead.
It is an error if the character is not found searching to the left
in the edit buffer.
.It Ic vi-prev-word Pq vi command: b
Move the cursor to the left to the next beginning of a word.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
It is an error if the cursor is already at the beginning of the
edit buffer.
.It Ic vi-redo Pq vi command: Sq \&.
Redo the last non-motion command.
.It Ic vi-repeat-next-char Pq vi command: Sq \&;
Repeat the most recent character search in the same search direction.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
.It Ic vi-repeat-prev-char Pq vi command: Sq \&,
Repeat the most recent character search in the opposite search
direction.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
.It Ic vi-repeat-search-next Pq vi command: n
Repeat the most recent history search in the same search direction.
.It Ic vi-repeat-search-prev Pq vi command: N
Repeat the most recent history search in the opposite search
direction.
.It Ic vi-replace-char Pq vi command: r
Switch to vi replace mode, and automatically switch back to vi
command mode after the next character typed.
See
.Ic ed-insert
for a description of replace mode.
It is an error if the cursor is at the end of the edit buffer.
.It Ic vi-replace-mode Pq vi command: R
Switch to vi replace mode.
This is a variant of vi insert mode; see
.Ic ed-insert
for the difference.
.It Ic vi-search-next Pq vi command: \&?
Replace the edit buffer with the next matching history entry.
.It Ic vi-search-prev Pq vi command: /
Replace the edit buffer with the previous matching history entry.
.It Ic vi-substitute-char Pq vi command: s
Delete the character at the cursor and switch to vi insert mode.
.It Ic vi-substitute-line Pq vi command: S
Delete the entire contents of the edit buffer, save a copy of it
in the cut buffer, and enter vi insert mode.
.It Ic vi-to-column Pq vi command: \&|
Move the cursor to the column specified as the argument.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
.It Ic vi-to-history-line Pq vi command: G
Replace the edit buffer with the specified history entry.
.It Ic vi-to-next-char Pq vi command: t
Read one character from the terminal bypassing the normal line
editing functionality and move the cursor to the right to the
character before the next instance of that character in the edit
buffer.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
If trying to read the character results in end of file or an error,
call
.Ic ed-end-of-file
instead.
It is an error if the character is not found searching to the right
in the edit buffer.
.It Ic vi-to-prev-char Pq vi command: T
Read one character from the terminal bypassing the normal line
editing functionality and move the cursor to the left to the character
after the next instance of that character in the edit buffer.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
If trying to read the character results in end of file or an error,
call
.Ic ed-end-of-file
instead.
It is an error if the character is not found searching to the left
in the edit buffer.
.It Ic vi-undo Pq vi command: u
Undo the last change.
.It Ic vi-undo-line Pq vi command: U
Undo all changes to the edit buffer.
.It Ic vi-yank Pq vi command: y
Copy the string from the cursor to the position specified by the
following movement command to the cut buffer.
When given twice in a row, instead copy the whole contents of the
edit buffer to the cut buffer.
.It Ic vi-yank-end Pq vi command: Y
Copy the string from the cursor to the end of the edit buffer to
the cut buffer.
.It Ic vi-zero Pq vi command: 0
If in argument input mode, multiply the argument by ten.
Otherwise, move the cursor to the beginning of the edit buffer.
Can be used as a movement command after
.Ic vi_change_meta ,
.Ic vi_delete_meta ,
or
.Ic vi_yank .
.El
.Ss Macros
If an input character is bound to the editor command
.Ic ed-sequence-lead-in ,
.Nm
attempts to call a macro.
If the input character by itself forms the name of a macro, that
macro is executed.
Otherwise, additional input characters are read until the string
read forms the name of a macro, in which case that macro is executed,
or until the string read matches the beginning of none of the existing
macro names, in which case the string including the final, mismatching
character is discarded and the terminal bell is rung.
.Pp
There are two kinds of macros.
Command macros execute a single editor command.
Keyboard macros return a string of characters that is appended
as a new line to the
.Sx Input Queue .
.Pp
The following command macros are defined by default in vi command
mode and in emacs mode:
.Bl -column -offset indent "Esc O A, Esc O A" "em-exchange-mark"
.It Esc \&[ A, Esc O A Ta Ic ed-prev-history
.It Esc \&[ B, Esc O B Ta Ic ed-next-history
.It Esc \&[ C, Esc O C Ta Ic ed-next-char
.It Esc \&[ D, Esc O D Ta Ic ed-prev-char
.It Esc \&[ F, Esc O F Ta Ic ed-move-to-end
.It Esc \&[ H, Esc O H Ta Ic ed-move-to-beg
.El
.Pp
In vi command mode, they are also defined by default without the
initial escape character.
.Pp
In addition, the
.Nm
library tries to bind the strings generated by the arrow keys
as reported by the
.Xr terminfo 5
database to these editor commands, unless that would clobber
user settings.
.Pp
In emacs mode, the two-character string
.Dq Ctrl-X Ctrl-X
is bound to the
.Ic em-exchange-mark
editor command.
.Ss Input Queue
The
.Nm
library maintains an input queue operated in FIFO mode.
Whenever it needs an input character, it takes the first character
from the first line of the input queue.
When the queue is empty, it reads from the terminal.
.Pp
A line can be appended to the end of the input queue in several ways:
.Bl -dash -offset indent
.It
By calling one of the keyboard
.Sx Macros .
.It
By calling the editor command
.Ic vi-redo .
.It
By calling the editor command
.Ic vi-alias .
.It
By pressing a key in emacs incremental search mode that doesn't
have a special meaning in that mode but returns to normal emacs
mode.
.It
If an application program directly calls the functions
.Xr el_push 3
or
.Xr el_wpush 3 ,
it can provide additional, program-specific ways
of appending to the input queue.
.El
.Sh SEE ALSO
.Xr mg 1 ,
.Xr vi 1 ,
.Xr editline 3 ,
.Xr el_wgets 3 ,
.Xr el_wpush 3 ,
.Xr el_wset 3 ,
.Xr editrc 5
.Sh HISTORY
This manual page first appeared in
.Ox 6.0
and
.Nx 8 .
.Sh AUTHORS
.An -nosplit
This manual page was written by
.An Ingo Schwarze Aq Mt schwarze@openbsd.org .

317
lib/libedit/src/editrc.5 Normal file
View File

@@ -0,0 +1,317 @@
.\" $NetBSD: editrc.5,v 1.32 2016/05/22 23:54:20 christos Exp $
.\"
.\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\"
.\" 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 May 22, 2016
.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:
.Pp
.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 aeklrsv Oc Op Ar key Op Ar command
Without options and arguments, list all bound keys and macros, and
the editor command or input string to which each one is bound.
If only
.Ar key
is supplied, show the binding for that key or macro.
If
.Ar key command
is supplied, bind the editor
.Ar command
to that key or macro.
.Pp
The options are as follows:
.Bl -tag -width 4n
.It Fl a
List or change key bindings in the
.Xr vi 1
mode alternate (command mode) key map.
.It Fl e
Bind all keys to the standard GNU Emacs-like bindings.
.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 the binding of the key or macro
.Ar key .
.It Fl s
Define a keyboard macro rather than a key binding or command macro:
.Ar command
is taken as a literal string and appended to the input queue whenever
.Ar key
is typed.
Bound keys and macros in
.Ar command
are themselves reinterpreted, and this continues for ten levels of
interpretation.
.It Fl v
Bind all keys to the standard
.Xr vi 1 Ns -like
bindings.
.El
.Pp
The
.Xr editline 7
manual documents all editor commands and contains more information
about macros and the input queue.
.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 ... .
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 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 .
.It Ic telltc
List the values of all the terminal capabilities (see
.Xr termcap 5 ) .
.El
.Sh FILES
.Bl -tag -width "~/.editrcXXX"
.It Pa ~/.editrc
User configuration file for the
.Xr editline 3
library.
.El
.Sh SEE ALSO
.Xr editline 3 ,
.Xr regex 3 ,
.Xr termcap 5 ,
.Xr editline 7
.Sh AUTHORS
.An -nosplit
The
.Nm editline
library was written by
.An Christos Zoulas ,
and this manual was written by
.An Luke Mewburn ,
with some sections inspired by
.Xr tcsh 1 .

View File

@@ -1,4 +1,4 @@
/* $NetBSD: el.c,v 1.61 2011/01/27 23:11:40 christos Exp $ */
/* $NetBSD: el.c,v 1.92 2016/05/22 19:44:26 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,37 +37,44 @@
#if 0
static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
#else
__RCSID("$NetBSD: el.c,v 1.61 2011/01/27 23:11:40 christos Exp $");
__RCSID("$NetBSD: el.c,v 1.92 2016/05/22 19:44:26 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 <locale.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "el.h"
#include "parse.h"
#include "read.h"
/* el_init():
* Initialize editline and set default parameters.
*/
public EditLine *
EditLine *
el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
{
EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
return el_init_fd(prog, fin, fout, ferr, fileno(fin), fileno(fout),
fileno(ferr));
}
EditLine *
el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
int fdin, int fdout, int fderr)
{
EditLine *el = el_malloc(sizeof(*el));
if (el == NULL)
return (NULL);
return NULL;
memset(el, 0, sizeof(EditLine));
@@ -75,11 +82,11 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
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_infd = fdin;
el->el_outfd = fdout;
el->el_errfd = fderr;
el->el_prog = Strdup(ct_decode_string(prog, &el->el_scratch));
el->el_prog = wcsdup(ct_decode_string(prog, &el->el_scratch));
if (el->el_prog == NULL) {
el_free(el);
return NULL;
@@ -89,19 +96,17 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
* Initialize all the modules. Order is important!!!
*/
el->el_flags = 0;
#ifdef WIDECHAR
if (setlocale(LC_CTYPE, NULL) != NULL){
if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
el->el_flags |= CHARSET_IS_UTF8;
}
#endif
if (term_init(el) == -1) {
if (terminal_init(el) == -1) {
el_free(el->el_prog);
el_free(el);
return NULL;
}
(void) key_init(el);
(void) keymacro_init(el);
(void) map_init(el);
if (tty_init(el) == -1)
el->el_flags |= NO_TTY;
@@ -110,16 +115,18 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
(void) hist_init(el);
(void) prompt_init(el);
(void) sig_init(el);
(void) read_init(el);
return (el);
if (read_init(el) == -1) {
el_end(el);
return NULL;
}
return el;
}
/* el_end():
* Clean up.
*/
public void
void
el_end(EditLine *el)
{
@@ -128,50 +135,52 @@ el_end(EditLine *el)
el_reset(el);
term_end(el);
key_end(el);
terminal_end(el);
keymacro_end(el);
map_end(el);
tty_end(el);
if (!(el->el_flags & NO_TTY))
tty_end(el);
ch_end(el);
read_end(el->el_read);
search_end(el);
hist_end(el);
prompt_end(el);
sig_end(el);
el_free((ptr_t) el->el_prog);
el_free((ptr_t) el);
#ifdef WIDECHAR
el_free((ptr_t) el->el_scratch.cbuff);
el_free((ptr_t) el->el_scratch.wbuff);
el_free((ptr_t) el->el_lgcyconv.cbuff);
el_free((ptr_t) el->el_lgcyconv.wbuff);
#endif
el_free(el->el_prog);
el_free(el->el_visual.cbuff);
el_free(el->el_visual.wbuff);
el_free(el->el_scratch.cbuff);
el_free(el->el_scratch.wbuff);
el_free(el->el_lgcyconv.cbuff);
el_free(el->el_lgcyconv.wbuff);
el_free(el);
}
/* el_reset():
* Reset the tty and the parser
*/
public void
void
el_reset(EditLine *el)
{
tty_cookedmode(el);
ch_reset(el, 0); /* XXX: Do we want that? */
ch_reset(el); /* XXX: Do we want that? */
}
/* el_set():
* set the editline parameters
*/
public int
FUN(el,set)(EditLine *el, int op, ...)
int
el_wset(EditLine *el, int op, ...)
{
va_list ap;
int rv = 0;
if (el == NULL)
return (-1);
return -1;
va_start(ap, op);
switch (op) {
@@ -190,21 +199,28 @@ FUN(el,set)(EditLine *el, int op, ...)
break;
}
case EL_ALIAS_TEXT: {
el_afunc_t p = va_arg(ap, el_afunc_t);
void *arg = va_arg(ap, void *);
rv = ch_aliasfun(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);
rv = prompt_set(el, p, (wchar_t)c, op, 1);
break;
}
case EL_TERMINAL:
rv = term_set(el, va_arg(ap, char *));
rv = terminal_set(el, va_arg(ap, char *));
break;
case EL_EDITOR:
rv = map_set_editor(el, va_arg(ap, Char *));
rv = map_set_editor(el, va_arg(ap, wchar_t *));
break;
case EL_SIGNAL:
@@ -220,36 +236,36 @@ FUN(el,set)(EditLine *el, int op, ...)
case EL_ECHOTC:
case EL_SETTY:
{
const Char *argv[20];
const wchar_t *argv[20];
int i;
for (i = 1; i < 20; i++)
if ((argv[i] = va_arg(ap, Char *)) == NULL)
for (i = 1; i < (int)__arraycount(argv); i++)
if ((argv[i] = va_arg(ap, wchar_t *)) == NULL)
break;
switch (op) {
case EL_BIND:
argv[0] = STR("bind");
argv[0] = L"bind";
rv = map_bind(el, i, argv);
break;
case EL_TELLTC:
argv[0] = STR("telltc");
rv = term_telltc(el, i, argv);
argv[0] = L"telltc";
rv = terminal_telltc(el, i, argv);
break;
case EL_SETTC:
argv[0] = STR("settc");
rv = term_settc(el, i, argv);
argv[0] = L"settc";
rv = terminal_settc(el, i, argv);
break;
case EL_ECHOTC:
argv[0] = STR("echotc");
rv = term_echotc(el, i, argv);
argv[0] = L"echotc";
rv = terminal_echotc(el, i, argv);
break;
case EL_SETTY:
argv[0] = STR("setty");
argv[0] = L"setty";
rv = tty_stty(el, i, argv);
break;
@@ -263,8 +279,8 @@ FUN(el,set)(EditLine *el, int op, ...)
case EL_ADDFN:
{
Char *name = va_arg(ap, Char *);
Char *help = va_arg(ap, Char *);
wchar_t *name = va_arg(ap, wchar_t *);
wchar_t *help = va_arg(ap, wchar_t *);
el_func_t func = va_arg(ap, el_func_t);
rv = map_addfunc(el, name, help, func);
@@ -274,7 +290,7 @@ FUN(el,set)(EditLine *el, int op, ...)
case EL_HIST:
{
hist_fun_t func = va_arg(ap, hist_fun_t);
ptr_t ptr = va_arg(ap, ptr_t);
void *ptr = va_arg(ap, void *);
rv = hist_set(el, func, ptr);
if (!(el->el_flags & CHARSET_IS_UTF8))
@@ -293,8 +309,7 @@ FUN(el,set)(EditLine *el, int op, ...)
case EL_GETCFN:
{
el_rfunc_t rc = va_arg(ap, el_rfunc_t);
rv = el_read_setfn(el, rc);
el->el_flags &= ~NARROW_READ;
rv = el_read_setfn(el->el_read, rc);
break;
}
@@ -355,7 +370,7 @@ FUN(el,set)(EditLine *el, int op, ...)
case EL_REFRESH:
re_clear_display(el);
re_refresh(el);
term__flush(el);
terminal__flush(el);
break;
default:
@@ -364,15 +379,15 @@ FUN(el,set)(EditLine *el, int op, ...)
}
va_end(ap);
return (rv);
return rv;
}
/* el_get():
* retrieve the editline parameters
*/
public int
FUN(el,get)(EditLine *el, int op, ...)
int
el_wget(EditLine *el, int op, ...)
{
va_list ap;
int rv;
@@ -392,14 +407,14 @@ FUN(el,get)(EditLine *el, int op, ...)
case EL_PROMPT_ESC:
case EL_RPROMPT_ESC: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
Char *c = va_arg(ap, Char *);
wchar_t *c = va_arg(ap, wchar_t *);
rv = prompt_get(el, p, c, op);
break;
}
case EL_EDITOR:
rv = map_get_editor(el, va_arg(ap, const Char **));
rv = map_get_editor(el, va_arg(ap, const wchar_t **));
break;
case EL_SIGNAL:
@@ -413,7 +428,7 @@ FUN(el,get)(EditLine *el, int op, ...)
break;
case EL_TERMINAL:
term_get(el, va_arg(ap, const char **));
terminal_get(el, va_arg(ap, const char **));
rv = 0;
break;
@@ -423,26 +438,17 @@ FUN(el,get)(EditLine *el, int op, ...)
char *argv[20];
int i;
for (i = 1; i < (int)(sizeof(argv) / sizeof(argv[0])); i++)
for (i = 1; i < (int)__arraycount(argv); i++)
if ((argv[i] = va_arg(ap, char *)) == NULL)
break;
switch (op) {
case EL_GETTC:
argv[0] = name;
rv = term_gettc(el, i, argv);
break;
default:
rv = -1;
EL_ABORT((el->el_errfile, "Bad op %d\n", op));
break;
}
argv[0] = name;
rv = terminal_gettc(el, i, argv);
break;
}
case EL_GETCFN:
*va_arg(ap, el_rfunc_t *) = el_read_getfn(el);
*va_arg(ap, el_rfunc_t *) = el_read_getfn(el->el_read);
rv = 0;
break;
@@ -452,7 +458,7 @@ FUN(el,get)(EditLine *el, int op, ...)
break;
case EL_UNBUFFERED:
*va_arg(ap, int *) = (!(el->el_flags & UNBUFFERED));
*va_arg(ap, int *) = (el->el_flags & UNBUFFERED) != 0;
rv = 0;
break;
@@ -486,81 +492,97 @@ FUN(el,get)(EditLine *el, int op, ...)
}
va_end(ap);
return (rv);
return rv;
}
/* el_line():
* Return editing info
*/
public const TYPE(LineInfo) *
FUN(el,line)(EditLine *el)
const LineInfoW *
el_wline(EditLine *el)
{
return (const TYPE(LineInfo) *) (void *) &el->el_line;
return (const LineInfoW *)(void *)&el->el_line;
}
/* el_source():
* Source a file
*/
public int
int
el_source(EditLine *el, const char *fname)
{
FILE *fp;
size_t len;
ssize_t slen;
char *ptr;
char path[MAXPATHLEN];
const Char *dptr;
char *path = NULL;
const wchar_t *dptr;
int error = 0;
fp = NULL;
if (fname == NULL) {
static const char elpath[] = "/.editrc";
#ifdef HAVE_ISSETUGID
static const char elpath[] = "/.editrc";
size_t plen = sizeof(elpath);
if (issetugid())
return (-1);
#endif
return -1;
if ((ptr = getenv("HOME")) == NULL)
return (-1);
if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
return (-1);
if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
return (-1);
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)
return (-1);
if (fp == NULL) {
el_free(path);
return -1;
}
ptr = NULL;
len = 0;
while ((slen = getline(&ptr, &len, fp)) != -1) {
if (*ptr == '\n')
continue; /* Empty line. */
if (slen > 0 && ptr[--slen] == '\n')
ptr[slen] = '\0';
while ((ptr = fgetln(fp, &len)) != NULL) {
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))
while (*dptr != '\0' && iswspace(*dptr))
dptr++;
if (*dptr == '#')
continue; /* ignore, this is a comment line */
if (parse_line(el, dptr) == -1) {
(void) fclose(fp);
return (-1);
}
if ((error = parse_line(el, dptr)) == -1)
break;
}
free(ptr);
el_free(path);
(void) fclose(fp);
return (0);
return error;
}
/* el_resize():
* Called from program when terminal is resized
*/
public void
void
el_resize(EditLine *el)
{
int lins, cols;
@@ -571,8 +593,8 @@ el_resize(EditLine *el)
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
/* get the correct window size */
if (term_get_size(el, &lins, &cols))
term_change_size(el, lins, cols);
if (terminal_get_size(el, &lins, &cols))
terminal_change_size(el, lins, cols);
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
}
@@ -581,38 +603,38 @@ el_resize(EditLine *el)
/* el_beep():
* Called from the program to beep
*/
public void
void
el_beep(EditLine *el)
{
term_beep(el);
terminal_beep(el);
}
/* el_editmode()
* Set the state of EDIT_DISABLED from the `edit' command.
*/
protected int
libedit_private int
/*ARGSUSED*/
el_editmode(EditLine *el, int argc, const Char **argv)
el_editmode(EditLine *el, int argc, const wchar_t **argv)
{
const Char *how;
const wchar_t *how;
if (argv == NULL || argc != 2 || argv[1] == NULL)
return (-1);
return -1;
how = argv[1];
if (Strcmp(how, STR("on")) == 0) {
if (wcscmp(how, L"on") == 0) {
el->el_flags &= ~EDIT_DISABLED;
tty_rawmode(el);
} else if (Strcmp(how, STR("off")) == 0) {
} else if (wcscmp(how, L"off") == 0) {
tty_cookedmode(el);
el->el_flags |= EDIT_DISABLED;
}
else {
(void) fprintf(el->el_errfile, "edit: Bad value `" FSTR "'.\n",
(void) fprintf(el->el_errfile, "edit: Bad value `%ls'.\n",
how);
return (-1);
return -1;
}
return (0);
return 0;
}

View File

@@ -1,4 +1,4 @@
/* $NetBSD: el.h,v 1.22 2011/01/27 23:11:40 christos Exp $ */
/* $NetBSD: el.h,v 1.41 2016/05/24 15:00:45 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -48,21 +48,15 @@
#include "histedit.h"
#include "chartype.h"
#include <stdio.h>
#include <sys/types.h>
#define EL_BUFSIZ 1024 /* Maximum line size */
#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 */
@@ -72,10 +66,10 @@ typedef struct coord_t { /* Position on the screen */
} coord_t;
typedef struct el_line_t {
Char *buffer; /* Input line */
Char *cursor; /* Cursor position */
Char *lastchar; /* Last character */
const Char *limit; /* Max position */
wchar_t *buffer; /* Input line */
wchar_t *cursor; /* Cursor position */
wchar_t *lastchar; /* Last character */
const wchar_t *limit; /* Max position */
} el_line_t;
/*
@@ -87,8 +81,8 @@ typedef struct el_state_t {
int argument; /* Numeric argument */
int metanext; /* Is the next char a meta char */
el_action_t lastcmd; /* Previous command */
el_action_t thiscmd; /* this command */
Char thisch; /* char that generated it */
el_action_t thiscmd; /* this command */
wchar_t thisch; /* char that generated it */
} el_state_t;
/*
@@ -100,21 +94,19 @@ typedef struct el_state_t {
#include "tty.h"
#include "prompt.h"
#include "key.h"
#include "el_term.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 el_read_t;
struct editline {
Char *el_prog; /* the program name */
wchar_t *el_prog; /* the program name */
FILE *el_infile; /* Stdio stuff */
FILE *el_outfile; /* Stdio stuff */
FILE *el_errfile; /* Stdio stuff */
@@ -122,33 +114,31 @@ struct editline {
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 */
wchar_t **el_display; /* Real screen image = what is there */
wchar_t **el_vdisplay; /* Virtual screen image = what we see */
void *el_data; /* Client data */
el_line_t el_line; /* The current line information */
el_state_t el_state; /* Current editor state */
el_term_t el_term; /* Terminal dependent stuff */
el_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_key_t el_key; /* Key binding 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
struct el_read_t *el_read; /* Character reading stuff */
ct_buffer_t el_visual; /* Buffer for displayable str */
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 **);
libedit_private int el_editmode(EditLine *, int, const wchar_t **);
#ifdef DEBUG
#define EL_ABORT(a) do { \

View File

@@ -1,4 +1,4 @@
/* $NetBSD: eln.c,v 1.9 2010/11/04 13:53:12 christos Exp $ */
/* $NetBSD: eln.c,v 1.34 2016/05/09 21:37:34 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@@ -12,13 +12,6 @@
* 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
@@ -34,35 +27,38 @@
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: eln.c,v 1.9 2010/11/04 13:53:12 christos Exp $");
__RCSID("$NetBSD: eln.c,v 1.34 2016/05/09 21:37:34 christos Exp $");
#endif /* not lint && not SCCSID */
#include "histedit.h"
#include "el.h"
#include "read.h"
#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
public int
#include "el.h"
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 = (unsigned char)wc;
return num_read;
num_read = el_wgetc(el, &wc);
*cp = '\0';
if (num_read <= 0)
return num_read;
num_read = wctob(wc);
if (num_read == EOF) {
errno = ERANGE;
return -1;
} else {
*cp = (char)num_read;
return 1;
}
}
public void
void
el_push(EditLine *el, const char *str)
{
/* Using multibyte->wide string decoding works fine under single-byte
@@ -71,36 +67,41 @@ el_push(EditLine *el, const char *str)
}
public const char *
const char *
el_gets(EditLine *el, int *nread)
{
const wchar_t *tmp;
el->el_flags |= IGNORE_EXTCHARS;
tmp = el_wgets(el, nread);
el->el_flags &= ~IGNORE_EXTCHARS;
if (tmp != NULL) {
int i;
size_t nwread = 0;
for (i = 0; i < *nread; i++)
nwread += ct_enc_width(tmp[i]);
*nread = (int)nwread;
}
return ct_encode_string(tmp, &el->el_lgcyconv);
}
public int
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);
wargv = (void *)ct_decode_argv(argc, argv, &el->el_lgcyconv);
if (!wargv)
return -1;
ret = el_wparse(el, argc, wargv);
ct_free_argv(wargv);
el_free(wargv);
return ret;
}
public int
int
el_set(EditLine *el, int op, ...)
{
va_list ap;
@@ -125,6 +126,22 @@ el_set(EditLine *el, int op, ...)
break;
}
case EL_ALIAS_TEXT: {
el_afunc_t p = va_arg(ap, el_afunc_t);
void *arg = va_arg(ap, void *);
ret = ch_aliasfun(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);
ret = prompt_set(el, p, c, op, 0);
break;
}
case EL_TERMINAL: /* const char * */
ret = el_wset(el, op, va_arg(ap, char *));
break;
@@ -149,12 +166,11 @@ el_set(EditLine *el, int op, ...)
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)
for (i = 1; i < (int)__arraycount(argv) - 1; ++i)
if ((argv[i] = va_arg(ap, const char *)) == NULL)
break;
argv[0] = NULL;
wargv = (const wchar_t **)
ct_decode_argv(i, argv, &el->el_lgcyconv);
argv[0] = argv[i] = NULL;
wargv = (void *)ct_decode_argv(i + 1, argv, &el->el_lgcyconv);
if (!wargv) {
ret = -1;
goto out;
@@ -166,29 +182,29 @@ el_set(EditLine *el, int op, ...)
*/
switch (op) {
case EL_BIND:
wargv[0] = STR("bind");
wargv[0] = L"bind";
ret = map_bind(el, i, wargv);
break;
case EL_TELLTC:
wargv[0] = STR("telltc");
ret = term_telltc(el, i, wargv);
wargv[0] = L"telltc";
ret = terminal_telltc(el, i, wargv);
break;
case EL_SETTC:
wargv[0] = STR("settc");
ret = term_settc(el, i, wargv);
wargv[0] = L"settc";
ret = terminal_settc(el, i, wargv);
break;
case EL_ECHOTC:
wargv[0] = STR("echotc");
ret = term_echotc(el, i, wargv);
wargv[0] = L"echotc";
ret = terminal_echotc(el, i, wargv);
break;
case EL_SETTY:
wargv[0] = STR("setty");
wargv[0] = L"setty";
ret = tty_stty(el, i, wargv);
break;
default:
ret = -1;
}
ct_free_argv(wargv);
el_free(wargv);
break;
}
@@ -207,40 +223,42 @@ el_set(EditLine *el, int op, ...)
ret = -1;
goto out;
}
// XXX: The two strdup's leak
ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]),
/* XXX: The two strdup's leak */
ret = map_addfunc(el, wcsdup(wargv[0]), wcsdup(wargv[1]),
func);
ct_free_argv(wargv);
el_free(wargv);
break;
}
case EL_HIST: { /* hist_fun_t, const char * */
hist_fun_t fun = va_arg(ap, hist_fun_t);
ptr_t ptr = va_arg(ap, ptr_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 = va_arg(ap, int);
ret = prompt_set(el, p, c, op, 0);
case EL_REFRESH:
re_clear_display(el);
re_refresh(el);
terminal__flush(el);
ret = 0;
break;
}
default:
ret = -1;
break;
@@ -252,7 +270,7 @@ out:
}
public int
int
el_get(EditLine *el, int op, ...)
{
va_list ap;
@@ -275,9 +293,9 @@ el_get(EditLine *el, int op, ...)
case EL_RPROMPT_ESC: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
char *c = va_arg(ap, char *);
wchar_t wc;
wchar_t wc = 0;
ret = prompt_get(el, p, &wc, op);
*c = (unsigned char)wc;
*c = (char)wc;
break;
}
@@ -310,11 +328,10 @@ el_get(EditLine *el, int op, ...)
if ((argv[i] = va_arg(ap, char *)) == NULL)
break;
argv[0] = gettc;
ret = term_gettc(el, i, argv);
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;
@@ -346,7 +363,7 @@ el_line(EditLine *el)
const LineInfoW *winfo = el_wline(el);
LineInfo *info = &el->el_lgcylinfo;
size_t offset;
const Char *p;
const wchar_t *p;
info->buffer = ct_encode_string(winfo->buffer, &el->el_lgcyconv);

View File

@@ -1,4 +1,4 @@
/* $NetBSD: emacs.c,v 1.23 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: emacs.c,v 1.36 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,37 +37,41 @@
#if 0
static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: emacs.c,v 1.23 2009/12/30 22:37:40 christos Exp $");
__RCSID("$NetBSD: emacs.c,v 1.36 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/*
* emacs.c: Emacs functions
*/
#include <ctype.h>
#include "el.h"
#include "emacs.h"
#include "fcns.h"
/* em_delete_or_list():
* Delete character under cursor or list completions if at end of line
* [^D]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_delete_or_list(EditLine *el, Int c)
em_delete_or_list(EditLine *el, wint_t c)
{
if (el->el_line.cursor == el->el_line.lastchar) {
/* if I'm at the end */
if (el->el_line.cursor == el->el_line.buffer) {
/* and the beginning */
term_writec(el, c); /* then do an EOF */
return (CC_EOF);
terminal_writec(el, c); /* then do an EOF */
return CC_EOF;
} else {
/*
* Here we could list completions, but it is an
* error right now
*/
term_beep(el);
return (CC_ERROR);
terminal_beep(el);
return CC_ERROR;
}
} else {
if (el->el_state.doingarg)
@@ -77,7 +81,7 @@ em_delete_or_list(EditLine *el, Int c)
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
/* bounds check */
return (CC_REFRESH);
return CC_REFRESH;
}
}
@@ -86,14 +90,14 @@ em_delete_or_list(EditLine *el, Int c)
* Cut from cursor to end of current word
* [M-d]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_delete_next_word(EditLine *el, Int c __attribute__((__unused__)))
em_delete_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *cp, *p, *kp;
wchar_t *cp, *p, *kp;
if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR);
return CC_ERROR;
cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
el->el_state.argument, ce__isword);
@@ -107,7 +111,7 @@ em_delete_next_word(EditLine *el, Int c __attribute__((__unused__)))
if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar;
/* bounds check */
return (CC_REFRESH);
return CC_REFRESH;
}
@@ -115,19 +119,19 @@ em_delete_next_word(EditLine *el, Int c __attribute__((__unused__)))
* Paste cut buffer at cursor position
* [^Y]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_yank(EditLine *el, Int c __attribute__((__unused__)))
em_yank(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *kp, *cp;
wchar_t *kp, *cp;
if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
return (CC_NORM);
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);
return CC_ERROR;
el->el_chared.c_kill.mark = el->el_line.cursor;
cp = el->el_line.cursor;
@@ -143,7 +147,7 @@ em_yank(EditLine *el, Int c __attribute__((__unused__)))
if (el->el_state.argument == 1)
el->el_line.cursor = cp;
return (CC_REFRESH);
return CC_REFRESH;
}
@@ -151,11 +155,11 @@ em_yank(EditLine *el, Int c __attribute__((__unused__)))
* Cut the entire line and save in cut buffer
* [^U]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_kill_line(EditLine *el, Int c __attribute__((__unused__)))
em_kill_line(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *kp, *cp;
wchar_t *kp, *cp;
cp = el->el_line.buffer;
kp = el->el_chared.c_kill.buf;
@@ -165,7 +169,7 @@ em_kill_line(EditLine *el, Int c __attribute__((__unused__)))
/* zap! -- delete all of it */
el->el_line.lastchar = el->el_line.buffer;
el->el_line.cursor = el->el_line.buffer;
return (CC_REFRESH);
return CC_REFRESH;
}
@@ -173,14 +177,14 @@ em_kill_line(EditLine *el, Int c __attribute__((__unused__)))
* Cut area between mark and cursor and save in cut buffer
* [^W]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_kill_region(EditLine *el, Int c __attribute__((__unused__)))
em_kill_region(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *kp, *cp;
wchar_t *kp, *cp;
if (!el->el_chared.c_kill.mark)
return (CC_ERROR);
return CC_ERROR;
if (el->el_chared.c_kill.mark > el->el_line.cursor) {
cp = el->el_line.cursor;
@@ -198,7 +202,7 @@ em_kill_region(EditLine *el, Int c __attribute__((__unused__)))
c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
el->el_line.cursor = el->el_chared.c_kill.mark;
}
return (CC_REFRESH);
return CC_REFRESH;
}
@@ -206,14 +210,14 @@ em_kill_region(EditLine *el, Int c __attribute__((__unused__)))
* Copy area between mark and cursor to cut buffer
* [M-W]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_copy_region(EditLine *el, Int c __attribute__((__unused__)))
em_copy_region(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *kp, *cp;
wchar_t *kp, *cp;
if (!el->el_chared.c_kill.mark)
return (CC_ERROR);
return CC_ERROR;
if (el->el_chared.c_kill.mark > el->el_line.cursor) {
cp = el->el_line.cursor;
@@ -228,7 +232,7 @@ em_copy_region(EditLine *el, Int c __attribute__((__unused__)))
*kp++ = *cp++; /* copy it */
el->el_chared.c_kill.last = kp;
}
return (CC_NORM);
return CC_NORM;
}
@@ -236,8 +240,8 @@ em_copy_region(EditLine *el, Int c __attribute__((__unused__)))
* Exchange the two characters before the cursor
* Gosling emacs transpose chars [^T]
*/
protected el_action_t
em_gosmacs_transpose(EditLine *el, Int c)
libedit_private el_action_t
em_gosmacs_transpose(EditLine *el, wint_t c)
{
if (el->el_line.cursor > &el->el_line.buffer[1]) {
@@ -245,9 +249,9 @@ em_gosmacs_transpose(EditLine *el, Int c)
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);
return CC_REFRESH;
} else
return (CC_ERROR);
return CC_ERROR;
}
@@ -255,12 +259,12 @@ em_gosmacs_transpose(EditLine *el, Int c)
* Move next to end of current word
* [M-f]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_next_word(EditLine *el, Int c __attribute__((__unused__)))
em_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR);
return CC_ERROR;
el->el_line.cursor = c__next_word(el->el_line.cursor,
el->el_line.lastchar,
@@ -270,9 +274,9 @@ em_next_word(EditLine *el, Int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
return CC_REFRESH;
}
return (CC_CURSOR);
return CC_CURSOR;
}
@@ -280,23 +284,23 @@ em_next_word(EditLine *el, Int c __attribute__((__unused__)))
* Uppercase the characters from cursor to end of current word
* [M-u]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_upper_case(EditLine *el, Int c __attribute__((__unused__)))
em_upper_case(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *cp, *ep;
wchar_t *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);
if (iswlower(*cp))
*cp = towupper(*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);
return CC_REFRESH;
}
@@ -304,31 +308,31 @@ em_upper_case(EditLine *el, Int c __attribute__((__unused__)))
* Capitalize the characters from cursor to end of current word
* [M-c]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_capitol_case(EditLine *el, Int c __attribute__((__unused__)))
em_capitol_case(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *cp, *ep;
wchar_t *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);
if (iswalpha(*cp)) {
if (iswlower(*cp))
*cp = towupper(*cp);
cp++;
break;
}
}
for (; cp < ep; cp++)
if (Isupper(*cp))
*cp = Tolower(*cp);
if (iswupper(*cp))
*cp = towlower(*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);
return CC_REFRESH;
}
@@ -336,23 +340,23 @@ em_capitol_case(EditLine *el, Int c __attribute__((__unused__)))
* Lowercase the characters from cursor to end of current word
* [M-l]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_lower_case(EditLine *el, Int c __attribute__((__unused__)))
em_lower_case(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *cp, *ep;
wchar_t *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);
if (iswupper(*cp))
*cp = towlower(*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);
return CC_REFRESH;
}
@@ -360,13 +364,13 @@ em_lower_case(EditLine *el, Int c __attribute__((__unused__)))
* Set the mark at cursor
* [^@]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_set_mark(EditLine *el, Int c __attribute__((__unused__)))
em_set_mark(EditLine *el, wint_t c __attribute__((__unused__)))
{
el->el_chared.c_kill.mark = el->el_line.cursor;
return (CC_NORM);
return CC_NORM;
}
@@ -374,16 +378,16 @@ em_set_mark(EditLine *el, Int c __attribute__((__unused__)))
* Exchange the cursor and mark
* [^X^X]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_exchange_mark(EditLine *el, Int c __attribute__((__unused__)))
em_exchange_mark(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *cp;
wchar_t *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);
return CC_CURSOR;
}
@@ -391,16 +395,16 @@ em_exchange_mark(EditLine *el, Int c __attribute__((__unused__)))
* Universal argument (argument times 4)
* [^U]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_universal_argument(EditLine *el, Int c __attribute__((__unused__)))
em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__)))
{ /* multiply current argument by 4 */
if (el->el_state.argument > 1000000)
return (CC_ERROR);
return CC_ERROR;
el->el_state.doingarg = 1;
el->el_state.argument *= 4;
return (CC_ARGHACK);
return CC_ARGHACK;
}
@@ -408,41 +412,41 @@ em_universal_argument(EditLine *el, Int c __attribute__((__unused__)))
* Add 8th bit to next character typed
* [<ESC>]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_meta_next(EditLine *el, Int c __attribute__((__unused__)))
em_meta_next(EditLine *el, wint_t c __attribute__((__unused__)))
{
el->el_state.metanext = 1;
return (CC_ARGHACK);
return CC_ARGHACK;
}
/* em_toggle_overwrite():
* Switch from insert to overwrite mode or vice versa
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_toggle_overwrite(EditLine *el, Int c __attribute__((__unused__)))
em_toggle_overwrite(EditLine *el, wint_t c __attribute__((__unused__)))
{
el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
MODE_REPLACE : MODE_INSERT;
return (CC_NORM);
return CC_NORM;
}
/* em_copy_prev_word():
* Copy current word to cursor
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_copy_prev_word(EditLine *el, Int c __attribute__((__unused__)))
em_copy_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
{
Char *cp, *oldc, *dp;
wchar_t *cp, *oldc, *dp;
if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR);
return CC_ERROR;
oldc = el->el_line.cursor;
/* does a bounds check */
@@ -455,33 +459,33 @@ em_copy_prev_word(EditLine *el, Int c __attribute__((__unused__)))
el->el_line.cursor = dp;/* put cursor at end */
return (CC_REFRESH);
return CC_REFRESH;
}
/* em_inc_search_next():
* Emacs incremental next search
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_inc_search_next(EditLine *el, Int c __attribute__((__unused__)))
em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
{
el->el_search.patlen = 0;
return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY));
return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
}
/* em_inc_search_prev():
* Emacs incremental reverse search
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_inc_search_prev(EditLine *el, Int c __attribute__((__unused__)))
em_inc_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
{
el->el_search.patlen = 0;
return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
}
@@ -489,13 +493,13 @@ em_inc_search_prev(EditLine *el, Int c __attribute__((__unused__)))
* Delete the character to the left of the cursor
* [^?]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
em_delete_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
{
if (el->el_line.cursor <= el->el_line.buffer)
return (CC_ERROR);
return CC_ERROR;
if (el->el_state.doingarg)
c_delbefore(el, el->el_state.argument);
@@ -504,5 +508,5 @@ em_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
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);
return CC_REFRESH;
}

View File

@@ -1,107 +0,0 @@
/* $NetBSD: fgetln.c,v 1.9 2008/04/29 06:53:03 martin Exp $ */
/*-
* Copyright (c) 1998 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#endif
#if !HAVE_FGETLN
#include "config.h"
#include <stdlib.h>
#ifndef HAVE_NBTOOL_CONFIG_H
/* These headers are required, but included from nbtool_config.h */
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#endif
char *
fgetln(FILE *fp, size_t *len)
{
static char *buf = NULL;
static size_t bufsiz = 0;
char *ptr;
if (buf == NULL) {
bufsiz = BUFSIZ;
if ((buf = malloc(bufsiz)) == NULL)
return NULL;
}
if (fgets(buf, bufsiz, fp) == NULL)
return NULL;
*len = 0;
while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
size_t nbufsiz = bufsiz + BUFSIZ;
char *nbuf = realloc(buf, nbufsiz);
if (nbuf == NULL) {
int oerrno = errno;
free(buf);
errno = oerrno;
buf = NULL;
return NULL;
} else
buf = nbuf;
if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) {
buf[bufsiz] = '\0';
*len = strlen(buf);
return buf;
}
*len = bufsiz;
bufsiz = nbufsiz;
}
*len = (ptr - buf) + 1;
return buf;
}
#endif
#ifdef TEST
int
main(int argc, char *argv[])
{
char *p;
size_t len;
while ((p = fgetln(stdin, &len)) != NULL) {
(void)printf("%llu %s", (unsigned long long)len, p);
free(p);
}
return 0;
}
#endif

View File

@@ -1,4 +1,4 @@
/* $NetBSD: filecomplete.c,v 1.23 2010/12/06 00:05:38 dholland Exp $ */
/* $NetBSD: filecomplete.c,v 1.44 2016/10/31 17:46:32 abhinav Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -29,52 +29,27 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
/* AIX requires this to be the first thing in the file. */
#if defined (_AIX) && !defined (__GNUC__)
#pragma alloca
#endif
#include "config.h"
#ifdef __GNUC__
# undef alloca
# define alloca(n) __builtin_alloca (n)
#else
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifndef _AIX
extern char *alloca ();
# endif
# endif
#endif
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: filecomplete.c,v 1.23 2010/12/06 00:05:38 dholland Exp $");
__RCSID("$NetBSD: filecomplete.c,v 1.44 2016/10/31 17:46:32 abhinav Exp $");
#endif /* not lint && not SCCSID */
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <pwd.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <fcntl.h>
#include <vis.h>
#include <limits.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.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' };
static const wchar_t break_chars[] = L" \t\n\"\\'`@$><=;|&{(";
/********************************/
/* completion functions */
@@ -84,18 +59,21 @@ static const Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@',
* if ``user'' isn't valid user name or ``txt'' doesn't start
* w/ '~', returns pointer to strdup()ed copy of ``txt''
*
* it's callers's responsibility to free() returned string
* it's the caller's responsibility to free() the returned string
*/
char *
fn_tilde_expand(const char *txt)
{
struct passwd pwres, *pass;
#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;
char pwbuf[1024];
if (txt[0] != '~')
return (strdup(txt));
return strdup(txt);
temp = strchr(txt + 1, '/');
if (temp == NULL) {
@@ -103,8 +81,9 @@ fn_tilde_expand(const char *txt)
if (temp == NULL)
return NULL;
} else {
len = temp - txt + 1; /* text until string after slash */
temp = malloc(len);
/* 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);
@@ -112,12 +91,13 @@ fn_tilde_expand(const char *txt)
}
if (temp[0] == 0) {
#ifdef HAVE_GETPW_R_POSIX
if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
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());
pass = getpwuid(getuid());
#endif
} else {
#ifdef HAVE_GETPW_R_POSIX
@@ -129,20 +109,21 @@ fn_tilde_expand(const char *txt)
pass = getpwnam(temp);
#endif
}
free(temp); /* value no more needed */
el_free(temp); /* value no more needed */
if (pass == NULL)
return (strdup(txt));
return strdup(txt);
/* update pointer txt to point at string immedially following */
/* first slash */
txt += len;
temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1);
len = strlen(pass->pw_dir) + 1 + strlen(txt) + 1;
temp = el_malloc(len * sizeof(*temp));
if (temp == NULL)
return NULL;
(void)sprintf(temp, "%s/%s", pass->pw_dir, txt);
(void)snprintf(temp, len, "%s/%s", pass->pw_dir, txt);
return (temp);
return temp;
}
@@ -151,7 +132,7 @@ fn_tilde_expand(const char *txt)
* such file can be found
* value of ``state'' is ignored
*
* it's caller's responsibility to free returned string
* it's the caller's responsibility to free the returned string
*/
char *
fn_filename_completion_function(const char *text, int state)
@@ -168,19 +149,21 @@ fn_filename_completion_function(const char *text, int state)
if (temp) {
char *nptr;
temp++;
nptr = realloc(filename, strlen(temp) + 1);
nptr = el_realloc(filename, (strlen(temp) + 1) *
sizeof(*nptr));
if (nptr == NULL) {
free(filename);
el_free(filename);
filename = NULL;
return NULL;
}
filename = nptr;
(void)strcpy(filename, temp);
len = temp - text; /* including last slash */
len = (size_t)(temp - text); /* including last slash */
nptr = realloc(dirname, len + 1);
nptr = el_realloc(dirname, (len + 1) *
sizeof(*nptr));
if (nptr == NULL) {
free(dirname);
el_free(dirname);
dirname = NULL;
return NULL;
}
@@ -188,7 +171,7 @@ fn_filename_completion_function(const char *text, int state)
(void)strncpy(dirname, text, len);
dirname[len] = '\0';
} else {
free(filename);
el_free(filename);
if (*text == 0)
filename = NULL;
else {
@@ -196,7 +179,7 @@ fn_filename_completion_function(const char *text, int state)
if (filename == NULL)
return NULL;
}
free(dirname);
el_free(dirname);
dirname = NULL;
}
@@ -207,7 +190,7 @@ fn_filename_completion_function(const char *text, int state)
/* support for ``~user'' syntax */
free(dirpath);
el_free(dirpath);
dirpath = NULL;
if (dirname == NULL) {
if ((dirname = strdup("")) == NULL)
@@ -223,7 +206,7 @@ fn_filename_completion_function(const char *text, int state)
dir = opendir(dirpath);
if (!dir)
return (NULL); /* cannot open the directory */
return NULL; /* cannot open the directory */
/* will be used in cycle */
filename_len = filename ? strlen(filename) : 0;
@@ -240,8 +223,11 @@ fn_filename_completion_function(const char *text, int state)
/* otherwise, get first entry where first */
/* filename_len characters are equal */
if (entry->d_name[0] == filename[0]
/* Some dirents have d_namlen, but it is not portable. */
#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;
@@ -249,20 +235,24 @@ fn_filename_completion_function(const char *text, int state)
if (entry) { /* match found */
/* Some dirents have d_namlen, but it is not portable. */
#if HAVE_STRUCT_DIRENT_D_NAMLEN
len = entry->d_namlen;
#else
len = strlen(entry->d_name);
#endif
temp = malloc(strlen(dirname) + len + 1);
len = strlen(dirname) + len + 1;
temp = el_malloc(len * sizeof(*temp));
if (temp == NULL)
return NULL;
(void)sprintf(temp, "%s%s", dirname, entry->d_name);
(void)snprintf(temp, len, "%s%s", dirname, entry->d_name);
} else {
(void)closedir(dir);
dir = NULL;
temp = NULL;
}
return (temp);
return temp;
}
@@ -279,7 +269,7 @@ append_char_function(const char *name)
rs = "/";
out:
if (expname)
free(expname);
el_free(expname);
return rs;
}
/*
@@ -302,10 +292,10 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
char **nmatch_list;
while (matches + 3 >= match_list_len)
match_list_len <<= 1;
nmatch_list = realloc(match_list,
match_list_len * sizeof(char *));
nmatch_list = el_realloc(match_list,
match_list_len * sizeof(*nmatch_list));
if (nmatch_list == NULL) {
free(match_list);
el_free(match_list);
return NULL;
}
match_list = nmatch_list;
@@ -328,9 +318,9 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
max_equal = i;
}
retstr = malloc(max_equal + 1);
retstr = el_malloc((max_equal + 1) * sizeof(*retstr));
if (retstr == NULL) {
free(match_list);
el_free(match_list);
return NULL;
}
(void)strncpy(retstr, match_list[1], max_equal);
@@ -338,9 +328,9 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
match_list[0] = retstr;
/* add NULL as last pointer to the array */
match_list[matches + 1] = (char *) NULL;
match_list[matches + 1] = NULL;
return (match_list);
return match_list;
}
/*
@@ -367,7 +357,7 @@ 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_term.t_size.h;
int screenwidth = el->el_terminal.t_size.h;
/* Ignore matches[0]. Avoid 1-based array logic below. */
matches++;
@@ -377,7 +367,7 @@ fn_display_match_list (EditLine *el, char **matches, size_t num, size_t width)
* Find out how many entries can be put on one line; count
* with one space between strings the same way it's printed.
*/
cols = screenwidth / (width + 1);
cols = (size_t)screenwidth / (width + 1);
if (cols == 0)
cols = 1;
@@ -418,14 +408,14 @@ 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 wchar_t *word_break, const wchar_t *special_prefixes,
const char *(*app_func)(const char *), size_t query_items,
int *completion_type, int *over, int *point, int *end)
{
const TYPE(LineInfo) *li;
Char *temp;
const LineInfoW *li;
wchar_t *temp;
char **matches;
const Char *ctemp;
const wchar_t *ctemp;
size_t len;
int what_to_do = '\t';
int retval = CC_NORM;
@@ -443,38 +433,36 @@ fn_complete(EditLine *el,
app_func = append_char_function;
/* We now look backwards for the start of a filename/variable word */
li = FUN(el,line)(el);
li = el_wline(el);
ctemp = li->cursor;
while (ctemp > li->buffer
&& !Strchr(word_break, ctemp[-1])
&& (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) )
&& !wcschr(word_break, ctemp[-1])
&& (!special_prefixes || !wcschr(special_prefixes, ctemp[-1]) ) )
ctemp--;
len = li->cursor - ctemp;
#if defined(__SSP__) || defined(__SSP_ALL__)
temp = malloc(sizeof(*temp) * (len + 1));
#else
temp = alloca(sizeof(*temp) * (len + 1));
#endif
(void)Strncpy(temp, ctemp, len);
len = (size_t)(li->cursor - ctemp);
temp = el_malloc((len + 1) * sizeof(*temp));
(void)wcsncpy(temp, ctemp, len);
temp[len] = '\0';
/* these can be used by function called in completion_matches() */
/* or (*attempted_completion_function)() */
if (point != 0)
if (point != NULL)
*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) (ct_encode_string(temp, &el->el_scratch),
(int)(cur_off - len), cur_off);
matches = (*attempted_completion_function)(
ct_encode_string(temp, &el->el_scratch),
cur_off - (int)len, cur_off);
} else
matches = 0;
matches = NULL;
if (!attempted_completion_function ||
(over != NULL && !*over && !matches))
matches = completion_matches(ct_encode_string(temp, &el->el_scratch), complet_func);
matches = completion_matches(
ct_encode_string(temp, &el->el_scratch), complet_func);
if (over != NULL)
*over = 0;
@@ -490,24 +478,22 @@ fn_complete(EditLine *el,
*/
if (matches[0][0] != '\0') {
el_deletestr(el, (int) len);
FUN(el,insertstr)(el,
el_winsertstr(el,
ct_decode_string(matches[0], &el->el_scratch));
}
if (what_to_do == '?')
goto display_matches;
if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) {
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,
el_winsertstr(el,
ct_decode_string((*app_func)(matches[0]),
&el->el_scratch));
} else if (what_to_do == '!') {
display_matches:
} else if (what_to_do == '!' || what_to_do == '?') {
/*
* More than one match and requested to list possible
* matches.
@@ -519,7 +505,7 @@ fn_complete(EditLine *el,
maxlen = match_len;
}
/* matches[1] through matches[i-1] are available */
matches_num = i - 1;
matches_num = (size_t)(i - 1);
/* newline to get on next line from command line */
(void)fprintf(el->el_outfile, "\n");
@@ -530,8 +516,8 @@ fn_complete(EditLine *el,
*/
if (matches_num > query_items) {
(void)fprintf(el->el_outfile,
"Display all %llu possibilities? (y or n) ",
(unsigned long long)matches_num);
"Display all %zu possibilities? (y or n) ",
matches_num);
(void)fflush(el->el_outfile);
if (getc(stdin) != 'y')
match_display = 0;
@@ -566,13 +552,11 @@ fn_complete(EditLine *el,
/* free elements of array and the array itself */
for (i = 0; matches[i]; i++)
free(matches[i]);
free(matches);
el_free(matches[i]);
el_free(matches);
matches = NULL;
}
#if defined(__SSP__) || defined(__SSP_ALL__)
free(temp);
#endif
el_free(temp);
return retval;
}
@@ -584,6 +568,6 @@ unsigned char
_el_fn_complete(EditLine *el, int ch __attribute__((__unused__)))
{
return (unsigned char)fn_complete(el, NULL, NULL,
break_chars, NULL, NULL, 100,
break_chars, NULL, NULL, (size_t)100,
NULL, NULL, NULL, NULL);
}

View File

@@ -1,4 +1,4 @@
/* $NetBSD: filecomplete.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: filecomplete.h,v 1.10 2016/04/11 00:50:13 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
int fn_complete(EditLine *,
char *(*)(const char *, int),
char **(*)(const char *, int, int),
const Char *, const Char *, const char *(*)(const char *), size_t,
const wchar_t *, const wchar_t *, const char *(*)(const char *), size_t,
int *, int *, int *, int *);
void fn_display_match_list(EditLine *, char **, size_t, size_t);

View File

@@ -1,4 +1,4 @@
/* $NetBSD: hist.c,v 1.17 2009/12/30 23:54:52 christos Exp $ */
/* $NetBSD: hist.c,v 1.30 2016/11/07 15:30:18 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: hist.c,v 1.17 2009/12/30 23:54:52 christos Exp $");
__RCSID("$NetBSD: hist.c,v 1.30 2016/11/07 15:30:18 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@@ -45,12 +45,15 @@ __RCSID("$NetBSD: hist.c,v 1.17 2009/12/30 23:54:52 christos Exp $");
* hist.c: History access functions
*/
#include <stdlib.h>
#include <string.h>
#include <vis.h>
#include "el.h"
/* hist_init():
* Initialization function.
*/
protected int
libedit_private int
hist_init(EditLine *el)
{
@@ -59,20 +62,20 @@ hist_init(EditLine *el)
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);
return -1;
el->el_history.last = el->el_history.buf;
return (0);
return 0;
}
/* hist_end():
* clean up history;
*/
protected void
libedit_private void
hist_end(EditLine *el)
{
el_free((ptr_t) el->el_history.buf);
el_free(el->el_history.buf);
el->el_history.buf = NULL;
}
@@ -80,13 +83,13 @@ hist_end(EditLine *el)
/* hist_set():
* Set new history interface
*/
protected int
hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr)
libedit_private int
hist_set(EditLine *el, hist_fun_t fun, void *ptr)
{
el->el_history.ref = ptr;
el->el_history.fun = fun;
return (0);
return 0;
}
@@ -94,14 +97,14 @@ hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr)
* Get a history line and update it in the buffer.
* eventno tells us the event to get.
*/
protected el_action_t
libedit_private el_action_t
hist_get(EditLine *el)
{
const Char *hp;
const wchar_t *hp;
int h;
if (el->el_history.eventno == 0) { /* if really the current line */
(void) Strncpy(el->el_line.buffer, el->el_history.buf,
(void) wcsncpy(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);
@@ -113,25 +116,25 @@ hist_get(EditLine *el)
#endif /* KSHVI */
el->el_line.cursor = el->el_line.lastchar;
return (CC_REFRESH);
return CC_REFRESH;
}
if (el->el_history.ref == NULL)
return (CC_ERROR);
return CC_ERROR;
hp = HIST_FIRST(el);
if (hp == NULL)
return (CC_ERROR);
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);
return CC_ERROR;
}
(void) Strncpy(el->el_line.buffer, hp,
(void) wcsncpy(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);
el->el_line.lastchar = el->el_line.buffer + wcslen(el->el_line.buffer);
if (el->el_line.lastchar > el->el_line.buffer
&& el->el_line.lastchar[-1] == '\n')
@@ -146,42 +149,63 @@ hist_get(EditLine *el)
#endif /* KSHVI */
el->el_line.cursor = el->el_line.lastchar;
return (CC_REFRESH);
return CC_REFRESH;
}
/* hist_command()
* process a history command
*/
protected int
hist_command(EditLine *el, int argc, const Char **argv)
libedit_private int
hist_command(EditLine *el, int argc, const wchar_t **argv)
{
const Char *str;
const wchar_t *str;
int num;
HistEvent ev;
HistEventW ev;
if (el->el_history.ref == NULL)
return (-1);
return -1;
if (argc == 1 || Strcmp(argv[1], STR("list")) == 0) {
if (argc == 1 || wcscmp(argv[1], L"list") == 0) {
size_t maxlen = 0;
char *buf = NULL;
int hno = 1;
/* 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);
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el)) {
char *ptr =
ct_encode_string(str, &el->el_scratch);
size_t len = strlen(ptr);
if (len > 0 && ptr[len - 1] == '\n')
ptr[--len] = '\0';
len = len * 4 + 1;
if (len >= maxlen) {
maxlen = len + 1024;
char *nbuf = el_realloc(buf, maxlen);
if (nbuf == NULL) {
el_free(buf);
return -1;
}
buf = nbuf;
}
strvis(buf, ptr, VIS_NL);
(void) fprintf(el->el_outfile, "%d\t%s\n",
hno++, buf);
}
el_free(buf);
return 0;
}
if (argc != 3)
return (-1);
return -1;
num = (int)Strtol(argv[2], NULL, 0);
num = (int)wcstol(argv[2], NULL, 0);
if (Strcmp(argv[1], STR("size")) == 0)
return history(el->el_history.ref, &ev, H_SETSIZE, num);
if (wcscmp(argv[1], L"size") == 0)
return history_w(el->el_history.ref, &ev, H_SETSIZE, num);
if (Strcmp(argv[1], STR("unique")) == 0)
return history(el->el_history.ref, &ev, H_SETUNIQUE, num);
if (wcscmp(argv[1], L"unique") == 0)
return history_w(el->el_history.ref, &ev, H_SETUNIQUE, num);
return -1;
}
@@ -190,11 +214,11 @@ hist_command(EditLine *el, int argc, const Char **argv)
* Enlarge history buffer to specified value. Called from el_enlargebufs().
* Return 0 for failure, 1 for success.
*/
protected int
libedit_private int
/*ARGSUSED*/
hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
{
Char *newbuf;
wchar_t *newbuf;
newbuf = el_realloc(el->el_history.buf, newsz * sizeof(*newbuf));
if (!newbuf)
@@ -210,9 +234,8 @@ hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
return 1;
}
#ifdef WIDECHAR
protected wchar_t *
hist_convert(EditLine *el, int fn, ptr_t arg)
libedit_private 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)
@@ -220,4 +243,3 @@ hist_convert(EditLine *el, int fn, ptr_t arg)
return ct_decode_string((const char *)(const void *)ev.str,
&el->el_scratch);
}
#endif

View File

@@ -1,4 +1,4 @@
/* $NetBSD: hist.h,v 1.12 2009/12/30 23:54:52 christos Exp $ */
/* $NetBSD: hist.h,v 1.22 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -40,31 +40,24 @@
#ifndef _h_el_hist
#define _h_el_hist
#include "histedit.h"
typedef int (*hist_fun_t)(ptr_t, TYPE(HistEvent) *, int, ...);
typedef int (*hist_fun_t)(void *, HistEventW *, int, ...);
typedef struct el_history_t {
Char *buf; /* The history buffer */
size_t sz; /* Size of history buffer */
Char *last; /* The last character */
wchar_t *buf; /* The history buffer */
size_t sz; /* Size of history buffer */
wchar_t *last; /* The last character */
int eventno; /* Event we are looking for */
ptr_t ref; /* Argument for history fcns */
void *ref; /* Argument for history fcns */
hist_fun_t fun; /* Event access */
TYPE(HistEvent) ev; /* Event cookie */
HistEventW 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)
@@ -73,15 +66,14 @@ typedef struct el_history_t {
#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)
#define HIST_SAVE_FP(el, fp) HIST_FUN(el, H_SAVE_FP fp)
protected int hist_init(EditLine *);
protected void hist_end(EditLine *);
protected el_action_t hist_get(EditLine *);
protected int hist_set(EditLine *, hist_fun_t, ptr_t);
protected int hist_command(EditLine *, int, const Char **);
protected int hist_enlargebuf(EditLine *, size_t, size_t);
#ifdef WIDECHAR
protected wchar_t *hist_convert(EditLine *, int, ptr_t);
#endif
libedit_private int hist_init(EditLine *);
libedit_private void hist_end(EditLine *);
libedit_private el_action_t hist_get(EditLine *);
libedit_private int hist_set(EditLine *, hist_fun_t, void *);
libedit_private int hist_command(EditLine *, int, const wchar_t **);
libedit_private int hist_enlargebuf(EditLine *, size_t, size_t);
libedit_private wchar_t *hist_convert(EditLine *, int, void *);
#endif /* _h_el_hist */

View File

@@ -1,4 +1,4 @@
/* $NetBSD: histedit.h,v 1.47 2010/08/28 15:44:59 christos Exp $ */
/* $NetBSD: histedit.h,v 1.56 2016/04/19 19:50:53 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -43,10 +43,6 @@
#define LIBEDIT_MAJOR 2
#define LIBEDIT_MINOR 11
#ifdef HAVE_STDINT_H
#include <stdint.h>
#endif
#include <sys/types.h>
#include <stdio.h>
@@ -88,6 +84,8 @@ typedef struct lineinfo {
* Initialization, cleanup, and resetting
*/
EditLine *el_init(const char *, FILE *, FILE *, FILE *);
EditLine *el_init_fd(const char *, FILE *, FILE *, FILE *,
int, int, int);
void el_end(EditLine *);
void el_reset(EditLine *);
@@ -143,8 +141,8 @@ unsigned char _el_fn_complete(EditLine *, int);
#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 ptr_t); 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 */
@@ -158,6 +156,7 @@ unsigned char _el_fn_complete(EditLine *, int);
#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_ALIAS_TEXT 24 /* , el_afunc_t, void *); set */
#define EL_BUILTIN_GETCFN (NULL)
@@ -226,6 +225,7 @@ int history(History *, HistEvent *, 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); */
#define H_SAVE_FP 26 /* , FILE *); */
@@ -249,20 +249,9 @@ int tok_str(Tokenizer *, 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 ====
*/
@@ -272,6 +261,8 @@ typedef struct lineinfow {
const wchar_t *lastchar;
} LineInfoW;
typedef int (*el_rfunc_t)(EditLine *, wchar_t *);
const wchar_t *el_wgets(EditLine *, int *);
int el_wgetc(EditLine *, wchar_t *);
void el_wpush(EditLine *, const wchar_t *);
@@ -281,6 +272,7 @@ int el_wparse(EditLine *, int, const wchar_t **);
int el_wset(EditLine *, int, ...);
int el_wget(EditLine *, int, ...);
int el_cursor(EditLine *, int);
const LineInfoW *el_wline(EditLine *);
int el_winsertstr(EditLine *, const wchar_t *);
#define el_wdeletestr el_deletestr

View File

@@ -1,4 +1,4 @@
/* $NetBSD: history.c,v 1.38 2011/01/16 03:05:51 christos Exp $ */
/* $NetBSD: history.c,v 1.57 2016/04/11 18:56:31 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -32,39 +32,72 @@
* SUCH DAMAGE.
*/
#ifndef NARROWCHAR
#include "config.h"
#endif
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: history.c,v 1.38 2011/01/16 03:05:51 christos Exp $");
__RCSID("$NetBSD: history.c,v 1.57 2016/04/11 18:56:31 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/*
* hist.c: TYPE(History) access functions
*/
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <vis.h>
#include <sys/stat.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <vis.h>
static const char hist_cookie[] = "_HiStOrY_V2_\n";
#include "histedit.h"
#ifdef NARROWCHAR
#define Char char
#define FUN(prefix, rest) prefix ## _ ## rest
#define FUNW(type) type
#define TYPE(type) type
#define STR(x) x
#define Strlen(s) strlen(s)
#define Strdup(s) strdup(s)
#define Strcmp(d, s) strcmp(d, s)
#define Strncmp(d, s, n) strncmp(d, s, n)
#define Strncpy(d, s, n) strncpy(d, s, n)
#define Strncat(d, s, n) strncat(d, s, n)
#define ct_decode_string(s, b) (s)
#define ct_encode_string(s, b) (s)
#else
#include "chartype.h"
typedef int (*history_gfun_t)(ptr_t, TYPE(HistEvent) *);
typedef int (*history_efun_t)(ptr_t, TYPE(HistEvent) *, const Char *);
typedef void (*history_vfun_t)(ptr_t, TYPE(HistEvent) *);
typedef int (*history_sfun_t)(ptr_t, TYPE(HistEvent) *, const int);
#define Char wchar_t
#define FUN(prefix, rest) prefix ## _w ## rest
#define FUNW(type) type ## _w
#define TYPE(type) type ## W
#define STR(x) L ## x
#define Strlen(s) wcslen(s)
#define Strdup(s) wcsdup(s)
#define Strcmp(d, s) wcscmp(d, s)
#define Strncmp(d, s, n) wcsncmp(d, s, n)
#define Strncpy(d, s, n) wcsncpy(d, s, n)
#define Strncat(d, s, n) wcsncat(d, s, n)
#endif
typedef int (*history_gfun_t)(void *, TYPE(HistEvent) *);
typedef int (*history_efun_t)(void *, TYPE(HistEvent) *, const Char *);
typedef void (*history_vfun_t)(void *, TYPE(HistEvent) *);
typedef int (*history_sfun_t)(void *, TYPE(HistEvent) *, const int);
struct TYPE(history) {
ptr_t h_ref; /* Argument for history fcns */
void *h_ref; /* Argument for history fcns */
int h_ent; /* Last entry point for history */
history_gfun_t h_first; /* Get the first element */
history_gfun_t h_next; /* Get the next element */
@@ -100,18 +133,20 @@ typedef struct {
} HistEventPrivate;
private int history_setsize(TYPE(History) *, TYPE(HistEvent) *, int);
private int history_getsize(TYPE(History) *, TYPE(HistEvent) *);
private int history_setunique(TYPE(History) *, TYPE(HistEvent) *, int);
private int history_getunique(TYPE(History) *, TYPE(HistEvent) *);
private int history_set_fun(TYPE(History) *, TYPE(History) *);
private int history_load(TYPE(History) *, const char *);
private int history_save(TYPE(History) *, const char *);
private int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int);
private int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int);
private int history_next_string(TYPE(History) *, TYPE(HistEvent) *, const Char *);
private int history_prev_string(TYPE(History) *, TYPE(HistEvent) *, const Char *);
static int history_setsize(TYPE(History) *, TYPE(HistEvent) *, int);
static int history_getsize(TYPE(History) *, TYPE(HistEvent) *);
static int history_setunique(TYPE(History) *, TYPE(HistEvent) *, int);
static int history_getunique(TYPE(History) *, TYPE(HistEvent) *);
static int history_set_fun(TYPE(History) *, TYPE(History) *);
static int history_load(TYPE(History) *, const char *);
static int history_save(TYPE(History) *, const char *);
static int history_save_fp(TYPE(History) *, FILE *);
static int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int);
static int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int);
static int history_next_string(TYPE(History) *, TYPE(HistEvent) *,
const Char *);
static int history_prev_string(TYPE(History) *, TYPE(HistEvent) *,
const Char *);
/***********************************************************************/
@@ -136,23 +171,23 @@ typedef struct history_t {
#define H_UNIQUE 1 /* Store only unique elements */
} history_t;
private int history_def_next(ptr_t, TYPE(HistEvent) *);
private int history_def_first(ptr_t, TYPE(HistEvent) *);
private int history_def_prev(ptr_t, TYPE(HistEvent) *);
private int history_def_last(ptr_t, TYPE(HistEvent) *);
private int history_def_curr(ptr_t, TYPE(HistEvent) *);
private int history_def_set(ptr_t, TYPE(HistEvent) *, const int);
private void history_def_clear(ptr_t, TYPE(HistEvent) *);
private int history_def_enter(ptr_t, TYPE(HistEvent) *, const Char *);
private int history_def_add(ptr_t, TYPE(HistEvent) *, const Char *);
private int history_def_del(ptr_t, TYPE(HistEvent) *, const int);
static int history_def_next(void *, TYPE(HistEvent) *);
static int history_def_first(void *, TYPE(HistEvent) *);
static int history_def_prev(void *, TYPE(HistEvent) *);
static int history_def_last(void *, TYPE(HistEvent) *);
static int history_def_curr(void *, TYPE(HistEvent) *);
static int history_def_set(void *, TYPE(HistEvent) *, const int);
static void history_def_clear(void *, TYPE(HistEvent) *);
static int history_def_enter(void *, TYPE(HistEvent) *, const Char *);
static int history_def_add(void *, TYPE(HistEvent) *, const Char *);
static int history_def_del(void *, TYPE(HistEvent) *, const int);
private int history_def_init(ptr_t *, TYPE(HistEvent) *, int);
private int history_def_insert(history_t *, TYPE(HistEvent) *, const Char *);
private void history_def_delete(history_t *, TYPE(HistEvent) *, hentry_t *);
static int history_def_init(void **, TYPE(HistEvent) *, int);
static int history_def_insert(history_t *, TYPE(HistEvent) *, const Char *);
static void history_def_delete(history_t *, TYPE(HistEvent) *, hentry_t *);
private int history_deldata_nth(history_t *, TYPE(HistEvent) *, int, void **);
private int history_set_nth(ptr_t, TYPE(HistEvent) *, int);
static int history_deldata_nth(history_t *, TYPE(HistEvent) *, int, void **);
static int history_set_nth(void *, TYPE(HistEvent) *, int);
#define history_def_setsize(p, num)(void) (((history_t *)p)->max = (num))
#define history_def_getsize(p) (((history_t *)p)->cur)
@@ -209,8 +244,8 @@ static const Char *const he_errlist[] = {
/* history_def_first():
* Default function to return the first event in the history.
*/
private int
history_def_first(ptr_t p, TYPE(HistEvent) *ev)
static int
history_def_first(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@@ -219,18 +254,18 @@ history_def_first(ptr_t p, TYPE(HistEvent) *ev)
*ev = h->cursor->ev;
else {
he_seterrev(ev, _HE_FIRST_NOTFOUND);
return (-1);
return -1;
}
return (0);
return 0;
}
/* history_def_last():
* Default function to return the last event in the history.
*/
private int
history_def_last(ptr_t p, TYPE(HistEvent) *ev)
static int
history_def_last(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@@ -239,69 +274,69 @@ history_def_last(ptr_t p, TYPE(HistEvent) *ev)
*ev = h->cursor->ev;
else {
he_seterrev(ev, _HE_LAST_NOTFOUND);
return (-1);
return -1;
}
return (0);
return 0;
}
/* history_def_next():
* Default function to return the next event in the history.
*/
private int
history_def_next(ptr_t p, TYPE(HistEvent) *ev)
static int
history_def_next(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
if (h->cursor == &h->list) {
he_seterrev(ev, _HE_EMPTY_LIST);
return (-1);
return -1;
}
if (h->cursor->next == &h->list) {
he_seterrev(ev, _HE_END_REACHED);
return (-1);
return -1;
}
h->cursor = h->cursor->next;
*ev = h->cursor->ev;
return (0);
return 0;
}
/* history_def_prev():
* Default function to return the previous event in the history.
*/
private int
history_def_prev(ptr_t p, TYPE(HistEvent) *ev)
static int
history_def_prev(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
if (h->cursor == &h->list) {
he_seterrev(ev,
(h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST);
return (-1);
return -1;
}
if (h->cursor->prev == &h->list) {
he_seterrev(ev, _HE_START_REACHED);
return (-1);
return -1;
}
h->cursor = h->cursor->prev;
*ev = h->cursor->ev;
return (0);
return 0;
}
/* history_def_curr():
* Default function to return the current event in the history.
*/
private int
history_def_curr(ptr_t p, TYPE(HistEvent) *ev)
static int
history_def_curr(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@@ -310,10 +345,10 @@ history_def_curr(ptr_t p, TYPE(HistEvent) *ev)
else {
he_seterrev(ev,
(h->cur > 0) ? _HE_CURR_INVALID : _HE_EMPTY_LIST);
return (-1);
return -1;
}
return (0);
return 0;
}
@@ -321,14 +356,14 @@ history_def_curr(ptr_t p, TYPE(HistEvent) *ev)
* Default function to set the current event in the history to the
* given one.
*/
private int
history_def_set(ptr_t p, TYPE(HistEvent) *ev, const int n)
static int
history_def_set(void *p, TYPE(HistEvent) *ev, const int n)
{
history_t *h = (history_t *) p;
if (h->cur == 0) {
he_seterrev(ev, _HE_EMPTY_LIST);
return (-1);
return -1;
}
if (h->cursor == &h->list || h->cursor->ev.num != n) {
for (h->cursor = h->list.next; h->cursor != &h->list;
@@ -338,9 +373,9 @@ history_def_set(ptr_t p, TYPE(HistEvent) *ev, const int n)
}
if (h->cursor == &h->list) {
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
return (0);
return 0;
}
@@ -348,14 +383,14 @@ history_def_set(ptr_t p, TYPE(HistEvent) *ev, const int n)
* Default function to set the current event in the history to the
* n-th one.
*/
private int
history_set_nth(ptr_t p, TYPE(HistEvent) *ev, int n)
static int
history_set_nth(void *p, TYPE(HistEvent) *ev, int n)
{
history_t *h = (history_t *) p;
if (h->cur == 0) {
he_seterrev(ev, _HE_EMPTY_LIST);
return (-1);
return -1;
}
for (h->cursor = h->list.prev; h->cursor != &h->list;
h->cursor = h->cursor->prev)
@@ -363,17 +398,17 @@ history_set_nth(ptr_t p, TYPE(HistEvent) *ev, int n)
break;
if (h->cursor == &h->list) {
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
return (0);
return 0;
}
/* history_def_add():
* Append string to element
*/
private int
history_def_add(ptr_t p, TYPE(HistEvent) *ev, const Char *str)
static int
history_def_add(void *p, TYPE(HistEvent) *ev, const Char *str)
{
history_t *h = (history_t *) p;
size_t len;
@@ -381,38 +416,38 @@ history_def_add(ptr_t p, TYPE(HistEvent) *ev, const Char *str)
HistEventPrivate *evp = (void *)&h->cursor->ev;
if (h->cursor == &h->list)
return (history_def_enter(p, ev, str));
return history_def_enter(p, ev, str);
len = Strlen(evp->str) + Strlen(str) + 1;
s = h_malloc(len * sizeof(*s));
if (s == NULL) {
he_seterrev(ev, _HE_MALLOC_FAILED);
return (-1);
return -1;
}
(void) Strncpy(s, h->cursor->ev.str, len);
s[len - 1] = '\0';
(void) Strncat(s, str, len - Strlen(s) - 1);
h_free((ptr_t)evp->str);
h_free(evp->str);
evp->str = s;
*ev = h->cursor->ev;
return (0);
return 0;
}
private int
static int
history_deldata_nth(history_t *h, TYPE(HistEvent) *ev,
int num, void **data)
{
if (history_set_nth(h, ev, num) != 0)
return (-1);
return -1;
/* magic value to skip delete (just set to n-th history) */
if (data == (void **)-1)
return (0);
return 0;
ev->str = Strdup(h->cursor->ev.str);
ev->num = h->cursor->ev.num;
if (data)
*data = h->cursor->data;
history_def_delete(h, ev, h->cursor);
return (0);
return 0;
}
@@ -420,17 +455,17 @@ history_deldata_nth(history_t *h, TYPE(HistEvent) *ev,
* Delete element hp of the h list
*/
/* ARGSUSED */
private int
history_def_del(ptr_t p, TYPE(HistEvent) *ev __attribute__((__unused__)),
static int
history_def_del(void *p, TYPE(HistEvent) *ev __attribute__((__unused__)),
const int num)
{
history_t *h = (history_t *) p;
if (history_def_set(h, ev, num) != 0)
return (-1);
return -1;
ev->str = Strdup(h->cursor->ev.str);
ev->num = h->cursor->ev.num;
history_def_delete(h, ev, h->cursor);
return (0);
return 0;
}
@@ -438,7 +473,7 @@ history_def_del(ptr_t p, TYPE(HistEvent) *ev __attribute__((__unused__)),
* Delete element hp of the h list
*/
/* ARGSUSED */
private void
static void
history_def_delete(history_t *h,
TYPE(HistEvent) *ev __attribute__((__unused__)), hentry_t *hp)
{
@@ -452,7 +487,7 @@ history_def_delete(history_t *h,
}
hp->prev->next = hp->next;
hp->next->prev = hp->prev;
h_free((ptr_t) evp->str);
h_free(evp->str);
h_free(hp);
h->cur--;
}
@@ -461,47 +496,49 @@ history_def_delete(history_t *h,
/* history_def_insert():
* Insert element with string str in the h list
*/
private int
static int
history_def_insert(history_t *h, TYPE(HistEvent) *ev, const Char *str)
{
hentry_t *c;
h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t));
if (h->cursor == NULL)
c = h_malloc(sizeof(*c));
if (c == NULL)
goto oomem;
if ((h->cursor->ev.str = h_strdup(str)) == NULL) {
h_free((ptr_t)h->cursor);
if ((c->ev.str = h_strdup(str)) == NULL) {
h_free(c);
goto oomem;
}
h->cursor->data = NULL;
h->cursor->ev.num = ++h->eventid;
h->cursor->next = h->list.next;
h->cursor->prev = &h->list;
h->list.next->prev = h->cursor;
h->list.next = h->cursor;
c->data = NULL;
c->ev.num = ++h->eventid;
c->next = h->list.next;
c->prev = &h->list;
h->list.next->prev = c;
h->list.next = c;
h->cur++;
h->cursor = c;
*ev = h->cursor->ev;
return (0);
*ev = c->ev;
return 0;
oomem:
he_seterrev(ev, _HE_MALLOC_FAILED);
return (-1);
return -1;
}
/* history_def_enter():
* Default function to enter an item in the history
*/
private int
history_def_enter(ptr_t p, TYPE(HistEvent) *ev, const Char *str)
static int
history_def_enter(void *p, TYPE(HistEvent) *ev, const Char *str)
{
history_t *h = (history_t *) p;
if ((h->flags & H_UNIQUE) != 0 && h->list.next != &h->list &&
Strcmp(h->list.next->ev.str, str) == 0)
return (0);
return 0;
if (history_def_insert(h, ev, str) == -1)
return (-1); /* error, keep error message */
return -1; /* error, keep error message */
/*
* Always keep at least one entry.
@@ -510,7 +547,7 @@ history_def_enter(ptr_t p, TYPE(HistEvent) *ev, const Char *str)
while (h->cur > h->max && h->cur > 0)
history_def_delete(h, ev, h->list.prev);
return (1);
return 1;
}
@@ -518,10 +555,10 @@ history_def_enter(ptr_t p, TYPE(HistEvent) *ev, const Char *str)
* Default history initialization function
*/
/* ARGSUSED */
private int
history_def_init(ptr_t *p, TYPE(HistEvent) *ev __attribute__((__unused__)), int n)
static int
history_def_init(void **p, TYPE(HistEvent) *ev __attribute__((__unused__)), int n)
{
history_t *h = (history_t *) h_malloc(sizeof(history_t));
history_t *h = (history_t *) h_malloc(sizeof(*h));
if (h == NULL)
return -1;
@@ -535,7 +572,7 @@ history_def_init(ptr_t *p, TYPE(HistEvent) *ev __attribute__((__unused__)), int
h->list.ev.num = 0;
h->cursor = &h->list;
h->flags = 0;
*p = (ptr_t) h;
*p = h;
return 0;
}
@@ -543,13 +580,14 @@ history_def_init(ptr_t *p, TYPE(HistEvent) *ev __attribute__((__unused__)), int
/* history_def_clear():
* Default history cleanup function
*/
private void
history_def_clear(ptr_t p, TYPE(HistEvent) *ev)
static void
history_def_clear(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
while (h->list.prev != &h->list)
history_def_delete(h, ev, h->list.prev);
h->cursor = &h->list;
h->eventid = 0;
h->cur = 0;
}
@@ -562,16 +600,16 @@ history_def_clear(ptr_t p, TYPE(HistEvent) *ev)
/* history_init():
* Initialization function.
*/
public TYPE(History) *
TYPE(History) *
FUN(history,init)(void)
{
TYPE(HistEvent) ev;
TYPE(History) *h = (TYPE(History) *) h_malloc(sizeof(TYPE(History)));
TYPE(History) *h = (TYPE(History) *) h_malloc(sizeof(*h));
if (h == NULL)
return NULL;
if (history_def_init(&h->h_ref, &ev, 0) == -1) {
h_free((ptr_t)h);
h_free(h);
return NULL;
}
h->h_ent = -1;
@@ -586,14 +624,14 @@ FUN(history,init)(void)
h->h_add = history_def_add;
h->h_del = history_def_del;
return (h);
return h;
}
/* history_end():
* clean up history;
*/
public void
void
FUN(history,end)(TYPE(History) *h)
{
TYPE(HistEvent) ev;
@@ -609,77 +647,77 @@ FUN(history,end)(TYPE(History) *h)
/* history_setsize():
* Set history number of events
*/
private int
static int
history_setsize(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1);
return -1;
}
if (num < 0) {
he_seterrev(ev, _HE_BAD_PARAM);
return (-1);
return -1;
}
history_def_setsize(h->h_ref, num);
return (0);
return 0;
}
/* history_getsize():
* Get number of events currently in history
*/
private int
static int
history_getsize(TYPE(History) *h, TYPE(HistEvent) *ev)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1);
return -1;
}
ev->num = history_def_getsize(h->h_ref);
if (ev->num < -1) {
he_seterrev(ev, _HE_SIZE_NEGATIVE);
return (-1);
return -1;
}
return (0);
return 0;
}
/* history_setunique():
* Set if adjacent equal events should not be entered in history.
*/
private int
static int
history_setunique(TYPE(History) *h, TYPE(HistEvent) *ev, int uni)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1);
return -1;
}
history_def_setunique(h->h_ref, uni);
return (0);
return 0;
}
/* history_getunique():
* Get if adjacent equal events should not be entered in history.
*/
private int
static int
history_getunique(TYPE(History) *h, TYPE(HistEvent) *ev)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1);
return -1;
}
ev->num = history_def_getunique(h->h_ref);
return (0);
return 0;
}
/* history_set_fun():
* Set history functions
*/
private int
static int
history_set_fun(TYPE(History) *h, TYPE(History) *nh)
{
TYPE(HistEvent) ev;
@@ -689,7 +727,8 @@ history_set_fun(TYPE(History) *h, TYPE(History) *nh)
nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL ||
nh->h_del == NULL || nh->h_ref == NULL) {
if (h->h_next != history_def_next) {
history_def_init(&h->h_ref, &ev, 0);
if (history_def_init(&h->h_ref, &ev, 0) == -1)
return -1;
h->h_first = history_def_first;
h->h_next = history_def_next;
h->h_last = history_def_last;
@@ -701,7 +740,7 @@ history_set_fun(TYPE(History) *h, TYPE(History) *nh)
h->h_add = history_def_add;
h->h_del = history_def_del;
}
return (-1);
return -1;
}
if (h->h_next == history_def_next)
history_def_clear(h->h_ref, &ev);
@@ -718,50 +757,49 @@ history_set_fun(TYPE(History) *h, TYPE(History) *nh)
h->h_add = nh->h_add;
h->h_del = nh->h_del;
return (0);
return 0;
}
/* history_load():
* TYPE(History) load function
*/
private int
static int
history_load(TYPE(History) *h, const char *fname)
{
FILE *fp;
char *line;
size_t sz, max_size;
size_t llen;
ssize_t sz;
size_t max_size;
char *ptr;
int i = -1;
TYPE(HistEvent) ev;
#ifdef WIDECHAR
#ifndef NARROWCHAR
static ct_buffer_t conv;
#endif
if ((fp = fopen(fname, "r")) == NULL)
return (i);
return i;
if ((line = fgetln(fp, &sz)) == NULL)
line = NULL;
llen = 0;
if ((sz = getline(&line, &llen, fp)) == -1)
goto done;
if (strncmp(line, hist_cookie, sz) != 0)
if (strncmp(line, hist_cookie, (size_t)sz) != 0)
goto done;
ptr = h_malloc(max_size = 1024);
ptr = h_malloc((max_size = 1024) * sizeof(*ptr));
if (ptr == NULL)
goto done;
for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) {
char c = line[sz];
if (sz != 0 && line[sz - 1] == '\n')
for (i = 0; (sz = getline(&line, &llen, fp)) != -1; i++) {
if (sz > 0 && line[sz - 1] == '\n')
line[--sz] = '\0';
else
line[sz] = '\0';
if (max_size < sz) {
if (max_size < (size_t)sz) {
char *nptr;
max_size = (sz + 1024) & ~1023;
nptr = h_realloc(ptr, max_size);
max_size = ((size_t)sz + 1024) & (size_t)~1023;
nptr = h_realloc(ptr, max_size * sizeof(*ptr));
if (nptr == NULL) {
i = -1;
goto oomem;
@@ -769,88 +807,104 @@ history_load(TYPE(History) *h, const char *fname)
ptr = nptr;
}
(void) strunvis(ptr, line);
line[sz] = c;
if (HENTER(h, &ev, ct_decode_string(ptr, &conv)) == -1) {
i = -1;
goto oomem;
}
}
oomem:
h_free((ptr_t)ptr);
h_free(ptr);
done:
free(line);
(void) fclose(fp);
return (i);
return i;
}
/* history_save():
/* history_save_fp():
* TYPE(History) save function
*/
private int
history_save(TYPE(History) *h, const char *fname)
static int
history_save_fp(TYPE(History) *h, FILE *fp)
{
FILE *fp;
TYPE(HistEvent) ev;
int i = -1, retval;
size_t len, max_size;
char *ptr;
#ifdef WIDECHAR
const char *str;
#ifndef NARROWCHAR
static ct_buffer_t conv;
#endif
if ((fp = fopen(fname, "w")) == NULL)
return (-1);
if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1)
goto done;
if (fputs(hist_cookie, fp) == EOF)
goto done;
ptr = h_malloc(max_size = 1024);
ptr = h_malloc((max_size = 1024) * sizeof(*ptr));
if (ptr == NULL)
goto done;
for (i = 0, retval = HLAST(h, &ev);
retval != -1;
retval = HPREV(h, &ev), i++) {
len = Strlen(ev.str) * 4;
if (len >= max_size) {
str = ct_encode_string(ev.str, &conv);
len = strlen(str) * 4 + 1;
if (len > max_size) {
char *nptr;
max_size = (len + 1024) & ~1023;
nptr = h_realloc(ptr, max_size);
max_size = (len + 1024) & (size_t)~1023;
nptr = h_realloc(ptr, max_size * sizeof(*ptr));
if (nptr == NULL) {
i = -1;
goto oomem;
}
ptr = nptr;
}
(void) strvis(ptr, ct_encode_string(ev.str, &conv), VIS_WHITE);
(void) strvis(ptr, str, VIS_WHITE);
(void) fprintf(fp, "%s\n", ptr);
}
oomem:
h_free((ptr_t)ptr);
h_free(ptr);
done:
(void) fclose(fp);
return (i);
return i;
}
/* history_save():
* History save function
*/
static int
history_save(TYPE(History) *h, const char *fname)
{
FILE *fp;
int i;
if ((fp = fopen(fname, "w")) == NULL)
return -1;
i = history_save_fp(h, fp);
(void) fclose(fp);
return i;
}
/* history_prev_event():
* Find the previous event, with number given
*/
private int
static int
history_prev_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
{
int retval;
for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
if (ev->num == num)
return (0);
return 0;
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
private int
static int
history_next_evdata(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d)
{
int retval;
@@ -859,35 +913,35 @@ history_next_evdata(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d)
if (ev->num == num) {
if (d)
*d = ((history_t *)h->h_ref)->cursor->data;
return (0);
return 0;
}
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
/* history_next_event():
* Find the next event, with number given
*/
private int
static int
history_next_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
{
int retval;
for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
if (ev->num == num)
return (0);
return 0;
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
/* history_prev_string():
* Find the previous event beginning with string
*/
private int
static int
history_prev_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
{
size_t len = Strlen(str);
@@ -895,17 +949,17 @@ history_prev_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev))
if (Strncmp(str, ev->str, len) == 0)
return (0);
return 0;
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
/* history_next_string():
* Find the next event beginning with string
*/
private int
static int
history_next_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
{
size_t len = Strlen(str);
@@ -913,10 +967,10 @@ history_next_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
if (Strncmp(str, ev->str, len) == 0)
return (0);
return 0;
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
return -1;
}
@@ -1013,6 +1067,12 @@ FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...)
he_seterrev(ev, _HE_HIST_WRITE);
break;
case H_SAVE_FP:
retval = history_save_fp(h, va_arg(va, FILE *));
if (retval == -1)
he_seterrev(ev, _HE_HIST_WRITE);
break;
case H_PREV_EVENT:
retval = history_prev_event(h, ev, va_arg(va, int));
break;
@@ -1033,7 +1093,7 @@ FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...)
{
TYPE(History) hf;
hf.h_ref = va_arg(va, ptr_t);
hf.h_ref = va_arg(va, void *);
h->h_ent = -1;
hf.h_first = va_arg(va, history_gfun_t);
hf.h_next = va_arg(va, history_gfun_t);

View File

@@ -0,0 +1,3 @@
#include "config.h"
#define NARROWCHAR
#include "history.c"

View File

@@ -1,4 +1,4 @@
/* $NetBSD: key.c,v 1.23 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: keymacro.c,v 1.23 2016/05/24 15:00:45 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,286 +37,289 @@
#if 0
static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: key.c,v 1.23 2009/12/30 22:37:40 christos Exp $");
__RCSID("$NetBSD: keymacro.c,v 1.23 2016/05/24 15:00:45 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/*
* key.c: This module contains the procedures for maintaining
* the extended-key map.
* 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_key.map)
* 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).
* (XK_STR) or editor functions (XK_CMD).
*
* Warning:
* If key is a substr of some other keys, then the longer
* keys are lost!! That is, if the keys "abcd" and "abcef"
* are in el->el_key.map, adding the key "abc" will cause the first two
* definitions to be lost.
* 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 <string.h>
#include "el.h"
#include "fcns.h"
/*
* The Nodes of the el->el_key.map. The el->el_key.map is a linked list
* of these node elements
* The Nodes of the el->el_keymacro.map. The el->el_keymacro.map is a
* linked list of these node elements
*/
struct key_node_t {
Char ch; /* single character of key */
int type; /* node type */
key_value_t val; /* command code or pointer to str, */
/* if this is a leaf */
struct key_node_t *next; /* ptr to next char of this key */
struct key_node_t *sibling; /* ptr to another key with same prefix*/
struct keymacro_node_t {
wchar_t 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 *, key_node_t *, Char *,
key_value_t *);
private int node__try(EditLine *, key_node_t *, const Char *,
key_value_t *, int);
private key_node_t *node__get(Int);
private void node__free(key_node_t *);
private void node__put(EditLine *, key_node_t *);
private int node__delete(EditLine *, key_node_t **, const Char *);
private int node_lookup(EditLine *, const Char *, key_node_t *,
size_t);
private int node_enum(EditLine *, key_node_t *, size_t);
static int node_trav(EditLine *, keymacro_node_t *, wchar_t *,
keymacro_value_t *);
static int node__try(EditLine *, keymacro_node_t *,
const wchar_t *, keymacro_value_t *, int);
static keymacro_node_t *node__get(wint_t);
static void node__free(keymacro_node_t *);
static void node__put(EditLine *, keymacro_node_t *);
static int node__delete(EditLine *, keymacro_node_t **,
const wchar_t *);
static int node_lookup(EditLine *, const wchar_t *,
keymacro_node_t *, size_t);
static int node_enum(EditLine *, keymacro_node_t *, size_t);
#define KEY_BUFSIZ EL_BUFSIZ
/* key_init():
/* keymacro_init():
* Initialize the key maps
*/
protected int
key_init(EditLine *el)
libedit_private int
keymacro_init(EditLine *el)
{
el->el_key.buf = el_malloc(KEY_BUFSIZ * sizeof(*el->el_key.buf));
if (el->el_key.buf == NULL)
return (-1);
el->el_key.map = NULL;
key_reset(el);
return (0);
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;
}
/* key_end():
/* keymacro_end():
* Free the key maps
*/
protected void
key_end(EditLine *el)
libedit_private void
keymacro_end(EditLine *el)
{
el_free((ptr_t) el->el_key.buf);
el->el_key.buf = NULL;
node__free(el->el_key.map);
el_free(el->el_keymacro.buf);
el->el_keymacro.buf = NULL;
node__free(el->el_keymacro.map);
}
/* key_map_cmd():
/* keymacro_map_cmd():
* Associate cmd with a key value
*/
protected key_value_t *
key_map_cmd(EditLine *el, int cmd)
libedit_private keymacro_value_t *
keymacro_map_cmd(EditLine *el, int cmd)
{
el->el_key.val.cmd = (el_action_t) cmd;
return (&el->el_key.val);
el->el_keymacro.val.cmd = (el_action_t) cmd;
return &el->el_keymacro.val;
}
/* key_map_str():
/* keymacro_map_str():
* Associate str with a key value
*/
protected key_value_t *
key_map_str(EditLine *el, Char *str)
libedit_private keymacro_value_t *
keymacro_map_str(EditLine *el, wchar_t *str)
{
el->el_key.val.str = str;
return (&el->el_key.val);
el->el_keymacro.val.str = str;
return &el->el_keymacro.val;
}
/* key_reset():
* Takes all nodes on el->el_key.map and puts them on free list. Then
* initializes el->el_key.map with arrow keys
/* 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
key_reset(EditLine *el)
libedit_private void
keymacro_reset(EditLine *el)
{
node__put(el, el->el_key.map);
el->el_key.map = NULL;
node__put(el, el->el_keymacro.map);
el->el_keymacro.map = NULL;
return;
}
/* key_get():
* Calls the recursive function with entry point el->el_key.map
/* 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).
* type of the match found (XK_STR or XK_CMD).
* Returns NULL in val.str and XK_STR for no match.
* Returns XK_NOD for end of file or read error.
* The last character read is returned in *ch.
*/
protected int
key_get(EditLine *el, Char *ch, key_value_t *val)
libedit_private int
keymacro_get(EditLine *el, wchar_t *ch, keymacro_value_t *val)
{
return (node_trav(el, el->el_key.map, ch, val));
return node_trav(el, el->el_keymacro.map, ch, val);
}
/* key_add():
* Adds key to the el->el_key.map and associates the value in val with it.
* If key is already is in el->el_key.map, the new code is applied to the
* existing key. Ntype specifies if code is a command, an
* out str or a unix command.
/* 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
key_add(EditLine *el, const Char *key, key_value_t *val, int ntype)
libedit_private void
keymacro_add(EditLine *el, const wchar_t *key, keymacro_value_t *val,
int ntype)
{
if (key[0] == '\0') {
(void) fprintf(el->el_errfile,
"key_add: Null extended-key not allowed.\n");
"keymacro_add: Null extended-key not allowed.\n");
return;
}
if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) {
(void) fprintf(el->el_errfile,
"key_add: sequence-lead-in command not allowed\n");
"keymacro_add: sequence-lead-in command not allowed\n");
return;
}
if (el->el_key.map == NULL)
if (el->el_keymacro.map == NULL)
/* tree is initially empty. Set up new node to match key[0] */
el->el_key.map = node__get(key[0]);
el->el_keymacro.map = node__get(key[0]);
/* it is properly initialized */
/* Now recurse through el->el_key.map */
(void) node__try(el, el->el_key.map, key, val, ntype);
/* Now recurse through el->el_keymacro.map */
(void) node__try(el, el->el_keymacro.map, key, val, ntype);
return;
}
/* key_clear():
/* keymacro_clear():
*
*/
protected void
key_clear(EditLine *el, el_action_t *map, const Char *in)
libedit_private void
keymacro_clear(EditLine *el, el_action_t *map, const wchar_t *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) key_delete(el, in);
(void) keymacro_delete(el, in);
}
/* key_delete():
/* keymacro_delete():
* Delete the key and all longer keys staring with key, if
* they exists.
*/
protected int
key_delete(EditLine *el, const Char *key)
libedit_private int
keymacro_delete(EditLine *el, const wchar_t *key)
{
if (key[0] == '\0') {
(void) fprintf(el->el_errfile,
"key_delete: Null extended-key not allowed.\n");
return (-1);
"keymacro_delete: Null extended-key not allowed.\n");
return -1;
}
if (el->el_key.map == NULL)
return (0);
if (el->el_keymacro.map == NULL)
return 0;
(void) node__delete(el, &el->el_key.map, key);
return (0);
(void) node__delete(el, &el->el_keymacro.map, key);
return 0;
}
/* key_print():
/* keymacro_print():
* Print the binding associated with key key.
* Print entire el->el_key.map if null
* Print entire el->el_keymacro.map if null
*/
protected void
key_print(EditLine *el, const Char *key)
libedit_private void
keymacro_print(EditLine *el, const wchar_t *key)
{
/* do nothing if el->el_key.map is empty and null key specified */
if (el->el_key.map == NULL && *key == 0)
/* do nothing if el->el_keymacro.map is empty and null key specified */
if (el->el_keymacro.map == NULL && *key == 0)
return;
el->el_key.buf[0] = '"';
if (node_lookup(el, key, el->el_key.map, 1) <= -1)
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);
(void) fprintf(el->el_errfile, "Unbound extended key \"%ls"
"\"\n", key);
return;
}
/* node_trav():
* recursively traverses node in tree until match or mismatch is
* found. May read in more characters.
* found. May read in more characters.
*/
private int
node_trav(EditLine *el, key_node_t *ptr, Char *ch, key_value_t *val)
static int
node_trav(EditLine *el, keymacro_node_t *ptr, wchar_t *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));
if (el_wgetc(el, ch) != 1)
return XK_NOD;
return node_trav(el, ptr->next, ch, val);
} else {
*val = ptr->val;
if (ptr->type != XK_CMD)
*ch = '\0';
return (ptr->type);
return ptr->type;
}
} else {
/* no match found here */
if (ptr->sibling) {
/* try next sibling */
return (node_trav(el, ptr->sibling, ch, val));
return node_trav(el, ptr->sibling, ch, val);
} else {
/* no next sibling -- mismatch */
val->str = NULL;
return (XK_STR);
return XK_STR;
}
}
}
/* node__try():
* Find a node that matches *str or allocate a new one
* Find a node that matches *str or allocate a new one
*/
private int
node__try(EditLine *el, key_node_t *ptr, const Char *str, key_value_t *val, int ntype)
static int
node__try(EditLine *el, keymacro_node_t *ptr, const wchar_t *str,
keymacro_value_t *val, int ntype)
{
if (ptr->ch != *str) {
key_node_t *xm;
keymacro_node_t *xm;
for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
if (xm->sibling->ch == *str)
@@ -337,9 +340,8 @@ node__try(EditLine *el, key_node_t *ptr, const Char *str, key_value_t *val, int
case XK_NOD:
break;
case XK_STR:
case XK_EXE:
if (ptr->val.str)
el_free((ptr_t) ptr->val.str);
el_free(ptr->val.str);
break;
default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n",
@@ -352,8 +354,7 @@ node__try(EditLine *el, key_node_t *ptr, const Char *str, key_value_t *val, int
ptr->val = *val;
break;
case XK_STR:
case XK_EXE:
if ((ptr->val.str = Strdup(val->str)) == NULL)
if ((ptr->val.str = wcsdup(val->str)) == NULL)
return -1;
break;
default:
@@ -366,29 +367,29 @@ node__try(EditLine *el, key_node_t *ptr, const Char *str, key_value_t *val, int
ptr->next = node__get(*str); /* setup new node */
(void) node__try(el, ptr->next, str, val, ntype);
}
return (0);
return 0;
}
/* node__delete():
* Delete node that matches str
*/
private int
node__delete(EditLine *el, key_node_t **inptr, const Char *str)
static int
node__delete(EditLine *el, keymacro_node_t **inptr, const wchar_t *str)
{
key_node_t *ptr;
key_node_t *prev_ptr = NULL;
keymacro_node_t *ptr;
keymacro_node_t *prev_ptr = NULL;
ptr = *inptr;
if (ptr->ch != *str) {
key_node_t *xm;
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);
return 0;
prev_ptr = xm;
ptr = xm->sibling;
}
@@ -400,20 +401,20 @@ node__delete(EditLine *el, key_node_t **inptr, const Char *str)
prev_ptr->sibling = ptr->sibling;
ptr->sibling = NULL;
node__put(el, ptr);
return (1);
return 1;
} else if (ptr->next != NULL &&
node__delete(el, &ptr->next, str) == 1) {
if (ptr->next != NULL)
return (0);
return 0;
if (prev_ptr == NULL)
*inptr = ptr->sibling;
else
prev_ptr->sibling = ptr->sibling;
ptr->sibling = NULL;
node__put(el, ptr);
return (1);
return 1;
} else {
return (0);
return 0;
}
}
@@ -421,8 +422,8 @@ node__delete(EditLine *el, key_node_t **inptr, const Char *str)
/* node__put():
* Puts a tree of nodes onto free list using free(3).
*/
private void
node__put(EditLine *el, key_node_t *ptr)
static void
node__put(EditLine *el, keymacro_node_t *ptr)
{
if (ptr == NULL)
return;
@@ -437,28 +438,27 @@ node__put(EditLine *el, key_node_t *ptr)
case XK_CMD:
case XK_NOD:
break;
case XK_EXE:
case XK_STR:
if (ptr->val.str != NULL)
el_free((ptr_t) ptr->val.str);
el_free(ptr->val.str);
break;
default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ptr->type));
break;
}
el_free((ptr_t) ptr);
el_free(ptr);
}
/* node__get():
* Returns pointer to a key_node_t for ch.
* Returns pointer to a keymacro_node_t for ch.
*/
private key_node_t *
node__get(Int ch)
static keymacro_node_t *
node__get(wint_t ch)
{
key_node_t *ptr;
keymacro_node_t *ptr;
ptr = (key_node_t *) el_malloc((size_t) sizeof(key_node_t));
ptr = el_malloc(sizeof(*ptr));
if (ptr == NULL)
return NULL;
ptr->ch = ch;
@@ -466,57 +466,59 @@ node__get(Int ch)
ptr->val.str = NULL;
ptr->next = NULL;
ptr->sibling = NULL;
return (ptr);
return ptr;
}
private void
node__free(key_node_t *k)
static void
node__free(keymacro_node_t *k)
{
if (k == NULL)
return;
node__free(k->sibling);
node__free(k->next);
el_free((ptr_t) k);
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, key_node_t *ptr, size_t cnt)
static int
node_lookup(EditLine *el, const wchar_t *str, keymacro_node_t *ptr,
size_t cnt)
{
ssize_t used;
if (ptr == NULL)
return (-1); /* cannot have null ptr */
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);
return 0;
} else {
/* If match put this char into el->el_key.buf. Recurse */
/* If match put this char into el->el_keymacro.buf. Recurse */
if (ptr->ch == *str) {
/* match found */
used = ct_visual_char(el->el_key.buf + cnt,
used = ct_visual_char(el->el_keymacro.buf + cnt,
KEY_BUFSIZ - cnt, ptr->ch);
if (used == -1)
return (-1); /* ran out of buffer space */
return -1; /* ran out of buffer space */
if (ptr->next != NULL)
/* not yet at leaf */
return (node_lookup(el, str + 1, ptr->next,
used + cnt));
(size_t)used + cnt));
else {
/* next node is null so key should be complete */
if (str[1] == 0) {
el->el_key.buf[cnt + used ] = '"';
el->el_key.buf[cnt + used + 1] = '\0';
key_kprint(el, el->el_key.buf,
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);
return 0;
} else
return (-1);
return -1;
/* mismatch -- str still has chars */
}
} else {
@@ -525,7 +527,7 @@ node_lookup(EditLine *el, const Char *str, key_node_t *ptr, size_t cnt)
return (node_lookup(el, str, ptr->sibling,
cnt));
else
return (-1);
return -1;
}
}
}
@@ -534,49 +536,52 @@ node_lookup(EditLine *el, const Char *str, key_node_t *ptr, size_t cnt)
/* node_enum():
* Traverse the node printing the characters it is bound in buffer
*/
private int
node_enum(EditLine *el, key_node_t *ptr, size_t cnt)
static 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_key.buf[++cnt] = '"';
el->el_key.buf[++cnt] = '\0';
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_key.buf);
return (0);
(void) fprintf(el->el_errfile, " \"%ls...\"\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);
return -1;
}
/* put this char at end of str */
used = ct_visual_char(el->el_key.buf + cnt, KEY_BUFSIZ - cnt, ptr->ch);
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_key.buf[cnt + used ] = '"';
el->el_key.buf[cnt + used + 1] = '\0';
key_kprint(el, el->el_key.buf, &ptr->val, ptr->type);
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 + used);
(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);
return 0;
}
/* key_kprint():
/* keymacro_kprint():
* Print the specified key and its associated
* function specified by val
*/
protected void
key_kprint(EditLine *el, const Char *key, key_value_t *val, int ntype)
libedit_private void
keymacro_kprint(EditLine *el, const wchar_t *key, keymacro_value_t *val,
int ntype)
{
el_bindings_t *fp;
char unparsbuf[EL_BUFSIZ];
@@ -585,8 +590,7 @@ key_kprint(EditLine *el, const Char *key, key_value_t *val, int ntype)
if (val != NULL)
switch (ntype) {
case XK_STR:
case XK_EXE:
(void) key__decode_str(val->str, unparsbuf,
(void) keymacro__decode_str(val->str, unparsbuf,
sizeof(unparsbuf),
ntype == XK_STR ? "\"\"" : "[]");
(void) fprintf(el->el_outfile, fmt,
@@ -595,7 +599,7 @@ key_kprint(EditLine *el, const Char *key, key_value_t *val, int ntype)
case XK_CMD:
for (fp = el->el_map.help; fp->name; fp++)
if (val->cmd == fp->func) {
ct_wcstombs(unparsbuf, fp->name, sizeof(unparsbuf));
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);
@@ -623,14 +627,15 @@ key_kprint(EditLine *el, const Char *key, key_value_t *val, int ntype)
*b++ = c; \
else \
b++
/* key__decode_str():
/* keymacro__decode_str():
* Make a printable version of the ey
*/
protected size_t
key__decode_str(const Char *str, char *buf, size_t len, const char *sep)
libedit_private size_t
keymacro__decode_str(const wchar_t *str, char *buf, size_t len,
const char *sep)
{
char *b = buf, *eb = b + len;
const Char *p;
const wchar_t *p;
b = buf;
if (sep[0] != '\0') {
@@ -642,8 +647,8 @@ key__decode_str(const Char *str, char *buf, size_t len, const char *sep)
goto add_endsep;
}
for (p = str; *p != 0; p++) {
Char dbuf[VISUAL_WIDTH_MAX];
Char *p2 = dbuf;
wchar_t dbuf[VISUAL_WIDTH_MAX];
wchar_t *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++);
@@ -662,4 +667,3 @@ add_endsep:
buf[len - 1] = '\0';
return (size_t)(b - buf);
}

View File

@@ -1,4 +1,4 @@
/* $NetBSD: key.h,v 1.13 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: keymacro.h,v 1.6 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -35,46 +35,42 @@
*/
/*
* el.key.h: Key macro header
* el.keymacro.h: Key macro header
*/
#ifndef _h_el_key
#define _h_el_key
#ifndef _h_el_keymacro
#define _h_el_keymacro
typedef union key_value_t {
typedef union keymacro_value_t {
el_action_t cmd; /* If it is a command the # */
Char *str; /* If it is a string... */
} key_value_t;
wchar_t *str; /* If it is a string... */
} keymacro_value_t;
typedef struct key_node_t key_node_t;
typedef struct keymacro_node_t keymacro_node_t;
typedef struct el_key_t {
Char *buf; /* Key print buffer */
key_node_t *map; /* Key map */
key_value_t val; /* Local conversion buffer */
} el_key_t;
typedef struct el_keymacro_t {
wchar_t *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
#undef key_end
#undef key_clear
#undef key_print
protected int key_init(EditLine *);
protected void key_end(EditLine *);
protected key_value_t *key_map_cmd(EditLine *, int);
protected key_value_t *key_map_str(EditLine *, Char *);
protected void key_reset(EditLine *);
protected int key_get(EditLine *, Char *, key_value_t *);
protected void key_add(EditLine *, const Char *, key_value_t *, int);
protected void key_clear(EditLine *, el_action_t *, const Char *);
protected int key_delete(EditLine *, const Char *);
protected void key_print(EditLine *, const Char *);
protected void key_kprint(EditLine *, const Char *, key_value_t *,
int);
protected size_t key__decode_str(const Char *, char *, size_t,
libedit_private int keymacro_init(EditLine *);
libedit_private void keymacro_end(EditLine *);
libedit_private keymacro_value_t *keymacro_map_cmd(EditLine *, int);
libedit_private keymacro_value_t *keymacro_map_str(EditLine *, wchar_t *);
libedit_private void keymacro_reset(EditLine *);
libedit_private int keymacro_get(EditLine *, wchar_t *, keymacro_value_t *);
libedit_private void keymacro_add(EditLine *, const wchar_t *,
keymacro_value_t *, int);
libedit_private void keymacro_clear(EditLine *, el_action_t *, const wchar_t *);
libedit_private int keymacro_delete(EditLine *, const wchar_t *);
libedit_private void keymacro_print(EditLine *, const wchar_t *);
libedit_private void keymacro_kprint(EditLine *, const wchar_t *,
keymacro_value_t *, int);
libedit_private size_t keymacro__decode_str(const wchar_t *, char *, size_t,
const char *);
#endif /* _h_el_key */
#endif /* _h_el_keymacro */

View File

@@ -1,5 +1,5 @@
#!/bin/sh -
# $NetBSD: makelist,v 1.16 2010/04/18 21:17:05 christos Exp $
# $NetBSD: makelist,v 1.29 2016/05/09 21:46:56 christos Exp $
#
# Copyright (c) 1992, 1993
# The Regents of the University of California. All rights reserved.
@@ -35,7 +35,8 @@
# makelist.sh: Automatically generate header files...
USAGE="Usage: $0 -n|-h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
AWK=awk
USAGE="Usage: $0 -h|-fc|-fh|-bh <filenames>"
if [ "x$1" = "x" ]
then
@@ -50,17 +51,6 @@ 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`"
@@ -77,7 +67,8 @@ _EOF
# 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);
printf("libedit_private el_action_t\t%s (EditLine *, wint_t);\n",
name);
}
}
END {
@@ -85,15 +76,13 @@ _EOF
}'
;;
# generate help.c from various .c files
# generate help.h from various .c files
#
-bc)
-bh)
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");
printf("static const struct el_bindings_t el_func_help[] = {\n");
low = "abcdefghijklmnopqrstuvwxyz_";
high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_";
for (i = 1; i <= length(low); i++)
@@ -113,46 +102,31 @@ _EOF
fname = fname s;
}
printf(" { %-30.30s %-30.30s\n","STR(\"" fname "\"),", uname ",");
printf(" { %-30.30s %-30.30s\n","L\"" fname "\",", uname ",");
ok = 1;
}
}
/^ \*/ {
if (ok) {
printf(" STR(\"");
printf(" L\"");
for (i = 2; i < NF; i++)
printf("%s ", $i);
printf("%s\") },\n", $i);
printf("%s\" },\n", $i);
ok = 0;
}
}
END {
printf("};\n");
printf("\nprotected const el_bindings_t* help__get()");
printf("{ return el_func_help; }\n");
}'
;;
# generate help.h from various .c files
#
-bh)
$AWK '
BEGIN {
printf("/* Automatically generated file, do not edit */\n");
printf("#ifndef _h_help_c\n#define _h_help_c\n");
printf("protected const el_bindings_t *help__get(void);\n");
printf("#endif /* _h_help_c */\n");
}' /dev/null
;;
# generate fcns.h from various .h files
#
-fh)
cat $FILES | $AWK '/el_action_t/ { print $3 }' | \
sort | tr '[a-z]' '[A-Z]' | $AWK '
sort | tr '[:lower:]' '[:upper:]' | $AWK '
BEGIN {
printf("/* Automatically generated file, do not edit */\n");
printf("#ifndef _h_fcns_c\n#define _h_fcns_c\n");
count = 0;
}
{
@@ -160,21 +134,16 @@ _EOF
}
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
# generate func.h 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[] = {");
printf("static const el_func_t el_func[] = {");
maxlen = 80;
needn = 1;
len = 0;
@@ -194,59 +163,6 @@ _EOF
}
END {
printf("\n};\n");
printf("\nprotected const el_func_t* func__get() { return el_func; }\n");
}'
;;
# generate editline.c from various .c files
#
-e)
echo "$FILES" | tr ' ' '\012' | $AWK '
BEGIN {
printf("/* Automatically generated file, do not edit */\n");
printf("#define protected static\n");
printf("#define SCCSID\n");
}
{
printf("#include \"%s\"\n", $1);
}'
;;
# generate man page fragment from various .c files
#
-m)
cat $FILES | $AWK '
BEGIN {
printf(".\\\" Section automatically generated with makelist\n");
printf(".Bl -tag -width 4n\n");
}
/\(\):/ {
pr = substr($2, 1, 2);
if (pr == "vi" || pr == "em" || pr == "ed") {
name = substr($2, 1, length($2) - 3);
fname = "";
for (i = 1; i <= length(name); i++) {
s = substr(name, i, 1);
if (s == "_")
s = "-";
fname = fname s;
}
printf(".It Ic %s\n", fname);
ok = 1;
}
}
/^ \*/ {
if (ok) {
for (i = 2; i < NF; i++)
printf("%s ", $i);
printf("%s.\n", $i);
ok = 0;
}
}
END {
printf(".El\n");
printf(".\\\" End of section automatically generated with makelist\n");
}'
;;

View File

@@ -1,4 +1,4 @@
/* $NetBSD: map.c,v 1.25 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: map.c,v 1.51 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,30 +37,40 @@
#if 0
static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: map.c,v 1.25 2009/12/30 22:37:40 christos Exp $");
__RCSID("$NetBSD: map.c,v 1.51 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/*
* map.c: Editor function definitions
*/
#include <ctype.h>
#include <stdlib.h>
#include "el.h"
#include <string.h>
private void map_print_key(EditLine *, el_action_t *, const Char *);
private void map_print_some_keys(EditLine *, el_action_t *, Int, Int);
private void map_print_all_keys(EditLine *);
private void map_init_nls(EditLine *);
private void map_init_meta(EditLine *);
#include "el.h"
#include "common.h"
#include "emacs.h"
#include "vi.h"
#include "fcns.h"
#include "func.h"
#include "help.h"
#include "parse.h"
static void map_print_key(EditLine *, el_action_t *, const wchar_t *);
static void map_print_some_keys(EditLine *, el_action_t *, wint_t, wint_t);
static void map_print_all_keys(EditLine *);
static void map_init_nls(EditLine *);
static void map_init_meta(EditLine *);
/* keymap tables ; should be N_KEYS*sizeof(KEYCMD) bytes long */
private const el_action_t el_map_emacs[] = {
static const el_action_t el_map_emacs[] = {
/* 0 */ EM_SET_MARK, /* ^@ */
/* 1 */ ED_MOVE_TO_BEG, /* ^A */
/* 2 */ ED_PREV_CHAR, /* ^B */
/* 3 */ ED_TTY_SIGINT, /* ^C */
/* 3 */ ED_IGNORE, /* ^C */
/* 4 */ EM_DELETE_OR_LIST, /* ^D */
/* 5 */ ED_MOVE_TO_END, /* ^E */
/* 6 */ ED_NEXT_CHAR, /* ^F */
@@ -72,21 +82,21 @@ private const el_action_t el_map_emacs[] = {
/* 12 */ ED_CLEAR_SCREEN, /* ^L */
/* 13 */ ED_NEWLINE, /* ^M */
/* 14 */ ED_NEXT_HISTORY, /* ^N */
/* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */
/* 15 */ ED_IGNORE, /* ^O */
/* 16 */ ED_PREV_HISTORY, /* ^P */
/* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
/* 17 */ ED_IGNORE, /* ^Q */
/* 18 */ ED_REDISPLAY, /* ^R */
/* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
/* 19 */ ED_IGNORE, /* ^S */
/* 20 */ ED_TRANSPOSE_CHARS, /* ^T */
/* 21 */ EM_KILL_LINE, /* ^U */
/* 22 */ ED_QUOTED_INSERT, /* ^V */
/* 23 */ EM_KILL_REGION, /* ^W */
/* 24 */ ED_SEQUENCE_LEAD_IN, /* ^X */
/* 25 */ EM_YANK, /* ^Y */
/* 26 */ ED_TTY_SIGTSTP, /* ^Z */
/* 26 */ ED_IGNORE, /* ^Z */
/* 27 */ EM_META_NEXT, /* ^[ */
/* 28 */ ED_TTY_SIGQUIT, /* ^\ */
/* 29 */ ED_TTY_DSUSP, /* ^] */
/* 28 */ ED_IGNORE, /* ^\ */
/* 29 */ ED_IGNORE, /* ^] */
/* 30 */ ED_UNASSIGNED, /* ^^ */
/* 31 */ ED_UNASSIGNED, /* ^_ */
/* 32 */ ED_INSERT, /* SPACE */
@@ -323,7 +333,7 @@ private const el_action_t el_map_emacs[] = {
* insert mode characters are in the normal keymap, and command mode
* in the extended keymap.
*/
private const el_action_t el_map_vi_insert[] = {
static const el_action_t el_map_vi_insert[] = {
#ifdef KSHVI
/* 0 */ ED_UNASSIGNED, /* ^@ */
/* 1 */ ED_INSERT, /* ^A */
@@ -342,9 +352,9 @@ private const el_action_t el_map_vi_insert[] = {
/* 14 */ ED_INSERT, /* ^N */
/* 15 */ ED_INSERT, /* ^O */
/* 16 */ ED_INSERT, /* ^P */
/* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
/* 17 */ ED_IGNORE, /* ^Q */
/* 18 */ ED_INSERT, /* ^R */
/* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
/* 19 */ ED_IGNORE, /* ^S */
/* 20 */ ED_INSERT, /* ^T */
/* 21 */ VI_KILL_LINE_PREV, /* ^U */
/* 22 */ ED_QUOTED_INSERT, /* ^V */
@@ -354,7 +364,7 @@ private const el_action_t el_map_vi_insert[] = {
/* 25 */ ED_INSERT, /* ^Y */
/* 26 */ ED_INSERT, /* ^Z */
/* 27 */ VI_COMMAND_MODE, /* ^[ */ /* [ Esc ] key */
/* 28 */ ED_TTY_SIGQUIT, /* ^\ */
/* 28 */ ED_IGNORE, /* ^\ */
/* 29 */ ED_INSERT, /* ^] */
/* 30 */ ED_INSERT, /* ^^ */
/* 31 */ ED_INSERT, /* ^_ */
@@ -368,7 +378,7 @@ private const el_action_t el_map_vi_insert[] = {
/* 0 */ ED_UNASSIGNED, /* ^@ */
/* 1 */ ED_MOVE_TO_BEG, /* ^A */
/* 2 */ ED_PREV_CHAR, /* ^B */
/* 3 */ ED_TTY_SIGINT, /* ^C */
/* 3 */ ED_IGNORE, /* ^C */
/* 4 */ VI_LIST_OR_EOF, /* ^D */
/* 5 */ ED_MOVE_TO_END, /* ^E */
/* 6 */ ED_NEXT_CHAR, /* ^F */
@@ -380,20 +390,20 @@ private const el_action_t el_map_vi_insert[] = {
/* 12 */ ED_CLEAR_SCREEN, /* ^L */
/* 13 */ ED_NEWLINE, /* ^M */
/* 14 */ ED_NEXT_HISTORY, /* ^N */
/* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */
/* 15 */ ED_IGNORE, /* ^O */
/* 16 */ ED_PREV_HISTORY, /* ^P */
/* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
/* 17 */ ED_IGNORE, /* ^Q */
/* 18 */ ED_REDISPLAY, /* ^R */
/* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
/* 19 */ ED_IGNORE, /* ^S */
/* 20 */ ED_TRANSPOSE_CHARS, /* ^T */
/* 21 */ VI_KILL_LINE_PREV, /* ^U */
/* 22 */ ED_QUOTED_INSERT, /* ^V */
/* 23 */ ED_DELETE_PREV_WORD, /* ^W */
/* 24 */ ED_UNASSIGNED, /* ^X */
/* 25 */ ED_TTY_DSUSP, /* ^Y */
/* 26 */ ED_TTY_SIGTSTP, /* ^Z */
/* 25 */ ED_IGNORE, /* ^Y */
/* 26 */ ED_IGNORE, /* ^Z */
/* 27 */ VI_COMMAND_MODE, /* ^[ */
/* 28 */ ED_TTY_SIGQUIT, /* ^\ */
/* 28 */ ED_IGNORE, /* ^\ */
/* 29 */ ED_UNASSIGNED, /* ^] */
/* 30 */ ED_UNASSIGNED, /* ^^ */
/* 31 */ ED_UNASSIGNED, /* ^_ */
@@ -624,11 +634,11 @@ private const el_action_t el_map_vi_insert[] = {
/* 255 */ ED_INSERT /* M-^? */
};
private const el_action_t el_map_vi_command[] = {
static const el_action_t el_map_vi_command[] = {
/* 0 */ ED_UNASSIGNED, /* ^@ */
/* 1 */ ED_MOVE_TO_BEG, /* ^A */
/* 2 */ ED_UNASSIGNED, /* ^B */
/* 3 */ ED_TTY_SIGINT, /* ^C */
/* 3 */ ED_IGNORE, /* ^C */
/* 4 */ ED_UNASSIGNED, /* ^D */
/* 5 */ ED_MOVE_TO_END, /* ^E */
/* 6 */ ED_UNASSIGNED, /* ^F */
@@ -640,11 +650,11 @@ private const el_action_t el_map_vi_command[] = {
/* 12 */ ED_CLEAR_SCREEN, /* ^L */
/* 13 */ ED_NEWLINE, /* ^M */
/* 14 */ ED_NEXT_HISTORY, /* ^N */
/* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */
/* 15 */ ED_IGNORE, /* ^O */
/* 16 */ ED_PREV_HISTORY, /* ^P */
/* 17 */ ED_TTY_START_OUTPUT, /* ^Q */
/* 17 */ ED_IGNORE, /* ^Q */
/* 18 */ ED_REDISPLAY, /* ^R */
/* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */
/* 19 */ ED_IGNORE, /* ^S */
/* 20 */ ED_UNASSIGNED, /* ^T */
/* 21 */ VI_KILL_LINE_PREV, /* ^U */
/* 22 */ ED_UNASSIGNED, /* ^V */
@@ -653,7 +663,7 @@ private const el_action_t el_map_vi_command[] = {
/* 25 */ ED_UNASSIGNED, /* ^Y */
/* 26 */ ED_UNASSIGNED, /* ^Z */
/* 27 */ EM_META_NEXT, /* ^[ */
/* 28 */ ED_TTY_SIGQUIT, /* ^\ */
/* 28 */ ED_IGNORE, /* ^\ */
/* 29 */ ED_UNASSIGNED, /* ^] */
/* 30 */ ED_UNASSIGNED, /* ^^ */
/* 31 */ ED_UNASSIGNED, /* ^_ */
@@ -887,7 +897,7 @@ private const el_action_t el_map_vi_command[] = {
/* map_init():
* Initialize and allocate the maps
*/
protected int
libedit_private int
map_init(EditLine *el)
{
@@ -903,26 +913,25 @@ map_init(EditLine *el)
EL_ABORT((el->errfile, "Vi insert map incorrect\n"));
#endif
el->el_map.alt = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS);
el->el_map.alt = el_malloc(sizeof(*el->el_map.alt) * N_KEYS);
if (el->el_map.alt == NULL)
return (-1);
el->el_map.key = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS);
return -1;
el->el_map.key = el_malloc(sizeof(*el->el_map.key) * N_KEYS);
if (el->el_map.key == NULL)
return (-1);
return -1;
el->el_map.emacs = el_map_emacs;
el->el_map.vic = el_map_vi_command;
el->el_map.vii = el_map_vi_insert;
el->el_map.help = (el_bindings_t *) el_malloc(sizeof(el_bindings_t) *
EL_NUM_FCNS);
el->el_map.help = el_malloc(sizeof(*el->el_map.help) * EL_NUM_FCNS);
if (el->el_map.help == NULL)
return (-1);
(void) memcpy(el->el_map.help, help__get(),
sizeof(el_bindings_t) * EL_NUM_FCNS);
el->el_map.func = (el_func_t *)el_malloc(sizeof(el_func_t) *
EL_NUM_FCNS);
return -1;
(void) memcpy(el->el_map.help, el_func_help,
sizeof(*el->el_map.help) * EL_NUM_FCNS);
el->el_map.func = el_malloc(sizeof(*el->el_map.func) * EL_NUM_FCNS);
if (el->el_map.func == NULL)
return (-1);
memcpy(el->el_map.func, func__get(), sizeof(el_func_t) * EL_NUM_FCNS);
return -1;
memcpy(el->el_map.func, el_func, sizeof(*el->el_map.func)
* EL_NUM_FCNS);
el->el_map.nfunc = EL_NUM_FCNS;
#ifdef VIDEFAULT
@@ -930,27 +939,27 @@ map_init(EditLine *el)
#else
map_init_emacs(el);
#endif /* VIDEFAULT */
return (0);
return 0;
}
/* map_end():
* Free the space taken by the editor maps
*/
protected void
libedit_private void
map_end(EditLine *el)
{
el_free((ptr_t) el->el_map.alt);
el_free(el->el_map.alt);
el->el_map.alt = NULL;
el_free((ptr_t) el->el_map.key);
el_free(el->el_map.key);
el->el_map.key = NULL;
el->el_map.emacs = NULL;
el->el_map.vic = NULL;
el->el_map.vii = NULL;
el_free((ptr_t) el->el_map.help);
el_free(el->el_map.help);
el->el_map.help = NULL;
el_free((ptr_t) el->el_map.func);
el_free(el->el_map.func);
el->el_map.func = NULL;
}
@@ -958,7 +967,7 @@ map_end(EditLine *el)
/* map_init_nls():
* Find all the printable keys and bind them to self insert
*/
private void
static void
map_init_nls(EditLine *el)
{
int i;
@@ -966,7 +975,7 @@ map_init_nls(EditLine *el)
el_action_t *map = el->el_map.key;
for (i = 0200; i <= 0377; i++)
if (Isprint(i))
if (iswprint(i))
map[i] = ED_INSERT;
}
@@ -974,10 +983,10 @@ map_init_nls(EditLine *el)
/* map_init_meta():
* Bind all the meta keys to the appropriate ESC-<key> sequence
*/
private void
static void
map_init_meta(EditLine *el)
{
Char buf[3];
wchar_t buf[3];
int i;
el_action_t *map = el->el_map.key;
el_action_t *alt = el->el_map.alt;
@@ -995,7 +1004,7 @@ map_init_meta(EditLine *el)
} else
map = alt;
}
buf[0] = (Char) i;
buf[0] = (wchar_t)i;
buf[2] = 0;
for (i = 0200; i <= 0377; i++)
switch (map[i]) {
@@ -1005,7 +1014,7 @@ map_init_meta(EditLine *el)
break;
default:
buf[1] = i & 0177;
key_add(el, buf, key_map_cmd(el, (int) map[i]), XK_CMD);
keymacro_add(el, buf, keymacro_map_cmd(el, (int) map[i]), XK_CMD);
break;
}
map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN;
@@ -1015,7 +1024,7 @@ map_init_meta(EditLine *el)
/* map_init_vi():
* Initialize the vi bindings
*/
protected void
libedit_private void
map_init_vi(EditLine *el)
{
int i;
@@ -1027,7 +1036,7 @@ map_init_vi(EditLine *el)
el->el_map.type = MAP_VI;
el->el_map.current = el->el_map.key;
key_reset(el);
keymacro_reset(el);
for (i = 0; i < N_KEYS; i++) {
key[i] = vii[i];
@@ -1038,25 +1047,25 @@ map_init_vi(EditLine *el)
map_init_nls(el);
tty_bind_char(el, 1);
term_bind_arrow(el);
terminal_bind_arrow(el);
}
/* map_init_emacs():
* Initialize the emacs bindings
*/
protected void
libedit_private void
map_init_emacs(EditLine *el)
{
int i;
Char buf[3];
wchar_t buf[3];
el_action_t *key = el->el_map.key;
el_action_t *alt = el->el_map.alt;
const el_action_t *emacs = el->el_map.emacs;
el->el_map.type = MAP_EMACS;
el->el_map.current = el->el_map.key;
key_reset(el);
keymacro_reset(el);
for (i = 0; i < N_KEYS; i++) {
key[i] = emacs[i];
@@ -1069,84 +1078,84 @@ map_init_emacs(EditLine *el)
buf[0] = CONTROL('X');
buf[1] = CONTROL('X');
buf[2] = 0;
key_add(el, buf, key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
keymacro_add(el, buf, keymacro_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
tty_bind_char(el, 1);
term_bind_arrow(el);
terminal_bind_arrow(el);
}
/* map_set_editor():
* Set the editor
*/
protected int
map_set_editor(EditLine *el, Char *editor)
libedit_private int
map_set_editor(EditLine *el, wchar_t *editor)
{
if (Strcmp(editor, STR("emacs")) == 0) {
if (wcscmp(editor, L"emacs") == 0) {
map_init_emacs(el);
return (0);
return 0;
}
if (Strcmp(editor, STR("vi")) == 0) {
if (wcscmp(editor, L"vi") == 0) {
map_init_vi(el);
return (0);
return 0;
}
return (-1);
return -1;
}
/* map_get_editor():
* Retrieve the editor
*/
protected int
map_get_editor(EditLine *el, const Char **editor)
libedit_private int
map_get_editor(EditLine *el, const wchar_t **editor)
{
if (editor == NULL)
return (-1);
return -1;
switch (el->el_map.type) {
case MAP_EMACS:
*editor = STR("emacs");
return (0);
*editor = L"emacs";
return 0;
case MAP_VI:
*editor = STR("vi");
return (0);
*editor = L"vi";
return 0;
}
return (-1);
return -1;
}
/* map_print_key():
* Print the function description for 1 key
*/
private void
map_print_key(EditLine *el, el_action_t *map, const Char *in)
static void
map_print_key(EditLine *el, el_action_t *map, const wchar_t *in)
{
char outbuf[EL_BUFSIZ];
el_bindings_t *bp, *ep;
if (in[0] == '\0' || in[1] == '\0') {
(void) key__decode_str(in, outbuf, sizeof(outbuf), "");
(void) keymacro__decode_str(in, outbuf, sizeof(outbuf), "");
ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++)
if (bp->func == map[(unsigned char) *in]) {
(void) fprintf(el->el_outfile,
"%s\t->\t" FSTR "\n", outbuf, bp->name);
"%s\t->\t%ls\n", outbuf, bp->name);
return;
}
} else
key_print(el, in);
keymacro_print(el, in);
}
/* map_print_some_keys():
* Print keys from first to last
*/
private void
map_print_some_keys(EditLine *el, el_action_t *map, Int first, Int last)
static void
map_print_some_keys(EditLine *el, el_action_t *map, wint_t first, wint_t last)
{
el_bindings_t *bp, *ep;
Char firstbuf[2], lastbuf[2];
wchar_t firstbuf[2], lastbuf[2];
char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ];
firstbuf[0] = first;
@@ -1155,7 +1164,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, Int first, Int last)
lastbuf[1] = 0;
if (map[first] == ED_UNASSIGNED) {
if (first == last) {
(void) key__decode_str(firstbuf, unparsbuf,
(void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile,
"%-15s-> is undefined\n", unparsbuf);
@@ -1166,17 +1175,17 @@ map_print_some_keys(EditLine *el, el_action_t *map, Int first, Int last)
for (bp = el->el_map.help; bp < ep; bp++) {
if (bp->func == map[first]) {
if (first == last) {
(void) key__decode_str(firstbuf, unparsbuf,
(void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile, "%-15s-> " FSTR "\n",
(void) fprintf(el->el_outfile, "%-15s-> %ls\n",
unparsbuf, bp->name);
} else {
(void) key__decode_str(firstbuf, unparsbuf,
(void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) key__decode_str(lastbuf, extrabuf,
(void) keymacro__decode_str(lastbuf, extrabuf,
sizeof(extrabuf), STRQQ);
(void) fprintf(el->el_outfile,
"%-4s to %-7s-> " FSTR "\n",
"%-4s to %-7s-> %ls\n",
unparsbuf, extrabuf, bp->name);
}
return;
@@ -1184,14 +1193,14 @@ map_print_some_keys(EditLine *el, el_action_t *map, Int first, Int last)
}
#ifdef MAP_DEBUG
if (map == el->el_map.key) {
(void) key__decode_str(firstbuf, unparsbuf,
(void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile,
"BUG!!! %s isn't bound to anything.\n", unparsbuf);
(void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n",
first, el->el_map.key[first]);
} else {
(void) key__decode_str(firstbuf, unparsbuf,
(void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile,
"BUG!!! %s isn't bound to anything.\n", unparsbuf);
@@ -1206,7 +1215,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, Int first, Int last)
/* map_print_all_keys():
* Print the function description for all keys.
*/
private void
static void
map_print_all_keys(EditLine *el)
{
int prev, i;
@@ -1232,31 +1241,31 @@ map_print_all_keys(EditLine *el)
map_print_some_keys(el, el->el_map.alt, prev, i - 1);
(void) fprintf(el->el_outfile, "Multi-character bindings\n");
key_print(el, STR(""));
keymacro_print(el, L"");
(void) fprintf(el->el_outfile, "Arrow key bindings\n");
term_print_arrow(el, STR(""));
terminal_print_arrow(el, L"");
}
/* map_bind():
* Add/remove/change bindings
*/
protected int
map_bind(EditLine *el, int argc, const Char **argv)
libedit_private int
map_bind(EditLine *el, int argc, const wchar_t **argv)
{
el_action_t *map;
int ntype, rem;
const Char *p;
Char inbuf[EL_BUFSIZ];
Char outbuf[EL_BUFSIZ];
const Char *in = NULL;
Char *out = NULL;
const wchar_t *p;
wchar_t inbuf[EL_BUFSIZ];
wchar_t outbuf[EL_BUFSIZ];
const wchar_t *in = NULL;
wchar_t *out;
el_bindings_t *bp, *ep;
int cmd;
int key;
if (argv == NULL)
return (-1);
return -1;
map = el->el_map.key;
ntype = XK_CMD;
@@ -1271,11 +1280,6 @@ map_bind(EditLine *el, int argc, const Char **argv)
case 's':
ntype = XK_STR;
break;
#ifdef notyet
case 'c':
ntype = XK_EXE;
break;
#endif
case 'k':
key = 1;
break;
@@ -1286,136 +1290,138 @@ map_bind(EditLine *el, int argc, const Char **argv)
case 'v':
map_init_vi(el);
return (0);
return 0;
case 'e':
map_init_emacs(el);
return (0);
return 0;
case 'l':
ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++)
(void) fprintf(el->el_outfile,
"" FSTR "\n\t" FSTR "\n",
"%ls\n\t%ls\n",
bp->name, bp->description);
return (0);
return 0;
default:
(void) fprintf(el->el_errfile,
"" FSTR ": Invalid switch `%c'.\n",
argv[0], p[1]);
"%ls: Invalid switch `%lc'.\n",
argv[0], (wint_t)p[1]);
}
else
break;
if (argv[argc] == NULL) {
map_print_all_keys(el);
return (0);
return 0;
}
if (key)
in = argv[argc++];
else if ((in = parse__string(inbuf, argv[argc++])) == NULL) {
(void) fprintf(el->el_errfile,
"" FSTR ": Invalid \\ or ^ in instring.\n",
"%ls: Invalid \\ or ^ in instring.\n",
argv[0]);
return (-1);
return -1;
}
if (rem) {
if (key) {
(void) term_clear_arrow(el, in);
return (-1);
(void) terminal_clear_arrow(el, in);
return -1;
}
if (in[1])
(void) key_delete(el, in);
(void) keymacro_delete(el, in);
else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN)
(void) key_delete(el, in);
(void) keymacro_delete(el, in);
else
map[(unsigned char) *in] = ED_UNASSIGNED;
return (0);
return 0;
}
if (argv[argc] == NULL) {
if (key)
term_print_arrow(el, in);
terminal_print_arrow(el, in);
else
map_print_key(el, map, in);
return (0);
return 0;
}
#ifdef notyet
if (argv[argc + 1] != NULL) {
bindkey_usage();
return (-1);
bindkeymacro_usage();
return -1;
}
#endif
switch (ntype) {
case XK_STR:
case XK_EXE:
if ((out = parse__string(outbuf, argv[argc])) == NULL) {
(void) fprintf(el->el_errfile,
"" FSTR ": Invalid \\ or ^ in outstring.\n", argv[0]);
return (-1);
"%ls: Invalid \\ or ^ in outstring.\n", argv[0]);
return -1;
}
if (key)
term_set_arrow(el, in, key_map_str(el, out), ntype);
terminal_set_arrow(el, in, keymacro_map_str(el, out), ntype);
else
key_add(el, in, key_map_str(el, out), ntype);
keymacro_add(el, in, keymacro_map_str(el, out), ntype);
map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
break;
case XK_CMD:
if ((cmd = parse_cmd(el, argv[argc])) == -1) {
(void) fprintf(el->el_errfile,
"" FSTR ": Invalid command `" FSTR "'.\n",
"%ls: Invalid command `%ls'.\n",
argv[0], argv[argc]);
return (-1);
return -1;
}
if (key)
term_set_arrow(el, in, key_map_str(el, out), ntype);
terminal_set_arrow(el, in, keymacro_map_cmd(el, cmd), ntype);
else {
if (in[1]) {
key_add(el, in, key_map_cmd(el, cmd), ntype);
keymacro_add(el, in, keymacro_map_cmd(el, cmd), ntype);
map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
} else {
key_clear(el, map, in);
map[(unsigned char) *in] = cmd;
keymacro_clear(el, map, in);
map[(unsigned char) *in] = (el_action_t)cmd;
}
}
break;
/* coverity[dead_error_begin] */
default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
break;
}
return (0);
return 0;
}
/* map_addfunc():
* add a user defined function
*/
protected int
map_addfunc(EditLine *el, const Char *name, const Char *help, el_func_t func)
libedit_private int
map_addfunc(EditLine *el, const wchar_t *name, const wchar_t *help,
el_func_t func)
{
void *p;
int nf = el->el_map.nfunc + 1;
size_t nf = el->el_map.nfunc + 1;
if (name == NULL || help == NULL || func == NULL)
return (-1);
return -1;
if ((p = el_realloc(el->el_map.func, nf * sizeof(el_func_t))) == NULL)
return (-1);
el->el_map.func = (el_func_t *) p;
if ((p = el_realloc(el->el_map.help, nf * sizeof(el_bindings_t)))
if ((p = el_realloc(el->el_map.func, nf *
sizeof(*el->el_map.func))) == NULL)
return -1;
el->el_map.func = p;
if ((p = el_realloc(el->el_map.help, nf * sizeof(*el->el_map.help)))
== NULL)
return (-1);
el->el_map.help = (el_bindings_t *) p;
return -1;
el->el_map.help = p;
nf = el->el_map.nfunc;
nf = (size_t)el->el_map.nfunc;
el->el_map.func[nf] = func;
el->el_map.help[nf].name = name;
el->el_map.help[nf].func = nf;
el->el_map.help[nf].func = (int)nf;
el->el_map.help[nf].description = help;
el->el_map.nfunc++;
return (0);
return 0;
}

View File

@@ -1,4 +1,4 @@
/* $NetBSD: map.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: map.h,v 1.13 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -40,12 +40,13 @@
#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 el_action_t (*el_func_t)(EditLine *, wint_t);
typedef struct el_bindings_t { /* for the "bind" shell command */
const wchar_t *name; /* function name for bind command */
int func; /* function numeric value */
const wchar_t *description; /* description of function */
} el_bindings_t;
typedef struct el_map_t {
el_action_t *alt; /* The current alternate key map */
@@ -57,7 +58,7 @@ typedef struct el_map_t {
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 */
size_t nfunc; /* The number of functions/help items */
} el_map_t;
#define MAP_EMACS 0
@@ -65,13 +66,14 @@ typedef struct el_map_t {
#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);
libedit_private int map_bind(EditLine *, int, const wchar_t **);
libedit_private int map_init(EditLine *);
libedit_private void map_end(EditLine *);
libedit_private void map_init_vi(EditLine *);
libedit_private void map_init_emacs(EditLine *);
libedit_private int map_set_editor(EditLine *, wchar_t *);
libedit_private int map_get_editor(EditLine *, const wchar_t **);
libedit_private int map_addfunc(EditLine *, const wchar_t *, const wchar_t *,
el_func_t);
#endif /* _h_el_map */

View File

@@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.23 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: parse.c,v 1.40 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: parse.c,v 1.23 2009/12/30 22:37:40 christos Exp $");
__RCSID("$NetBSD: parse.c,v 1.40 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@@ -54,80 +54,83 @@ __RCSID("$NetBSD: parse.c,v 1.23 2009/12/30 22:37:40 christos Exp $");
* settc
* setty
*/
#include "el.h"
#include <stdlib.h>
#include <string.h>
private const struct {
const Char *name;
int (*func)(EditLine *, int, const Char **);
#include "el.h"
#include "parse.h"
static const struct {
const wchar_t *name;
int (*func)(EditLine *, int, const wchar_t **);
} cmds[] = {
{ STR("bind"), map_bind },
{ STR("echotc"), term_echotc },
{ STR("edit"), el_editmode },
{ STR("history"), hist_command },
{ STR("telltc"), term_telltc },
{ STR("settc"), term_settc },
{ STR("setty"), tty_stty },
{ NULL, NULL }
{ L"bind", map_bind },
{ L"echotc", terminal_echotc },
{ L"edit", el_editmode },
{ L"history", hist_command },
{ L"telltc", terminal_telltc },
{ L"settc", terminal_settc },
{ L"setty", tty_stty },
{ NULL, NULL }
};
/* parse_line():
* Parse a line and dispatch it
*/
protected int
parse_line(EditLine *el, const Char *line)
libedit_private int
parse_line(EditLine *el, const wchar_t *line)
{
const Char **argv;
const wchar_t **argv;
int argc;
TYPE(Tokenizer) *tok;
TokenizerW *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);
tok = tok_winit(NULL);
tok_wstr(tok, line, &argc, &argv);
argc = el_wparse(el, argc, argv);
tok_wend(tok);
return argc;
}
/* el_parse():
* Command dispatcher
*/
public int
FUN(el,parse)(EditLine *el, int argc, const Char *argv[])
int
el_wparse(EditLine *el, int argc, const wchar_t *argv[])
{
const Char *ptr;
const wchar_t *ptr;
int i;
if (argc < 1)
return (-1);
ptr = Strchr(argv[0], ':');
return -1;
ptr = wcschr(argv[0], L':');
if (ptr != NULL) {
Char *tprog;
wchar_t *tprog;
size_t l;
if (ptr == argv[0])
return (0);
l = ptr - argv[0] - 1;
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);
return 0;
(void) wcsncpy(tprog, argv[0], l);
tprog[l] = '\0';
ptr++;
l = el_match(el->el_prog, tprog);
l = (size_t)el_match(el->el_prog, tprog);
el_free(tprog);
if (!l)
return (0);
return 0;
} else
ptr = argv[0];
for (i = 0; cmds[i].name != NULL; i++)
if (Strcmp(cmds[i].name, ptr) == 0) {
if (wcscmp(cmds[i].name, ptr) == 0) {
i = (*cmds[i].func) (el, argc, argv);
return (-i);
return -i;
}
return (-1);
return -1;
}
@@ -135,16 +138,16 @@ FUN(el,parse)(EditLine *el, int argc, const Char *argv[])
* 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)
libedit_private int
parse__escape(const wchar_t **ptr)
{
const Char *p;
Int c;
const wchar_t *p;
wint_t c;
p = *ptr;
if (p[1] == 0)
return (-1);
return -1;
if (*p == '\\') {
p++;
@@ -173,28 +176,28 @@ parse__escape(const Char **ptr)
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);
case 'U': /* Unicode \U+xxxx or \U+xxxxx format */
{
int i;
const wchar_t hex[] = L"0123456789ABCDEF";
const wchar_t *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;
}
for (i = 0; i < 5; ++i) {
h = wcschr(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':
@@ -214,8 +217,8 @@ parse__escape(const Char **ptr)
}
c = (c << 3) | (ch - '0');
}
if ((c & 0xffffff00) != 0)
return (-1);
if ((c & (wint_t)0xffffff00) != (wint_t)0)
return -1;
--p;
break;
}
@@ -229,29 +232,29 @@ parse__escape(const Char **ptr)
} else
c = *p;
*ptr = ++p;
return (c);
return c;
}
/* parse__string():
* Parse the escapes from in and put the raw string out
*/
protected Char *
parse__string(Char *out, const Char *in)
libedit_private wchar_t *
parse__string(wchar_t *out, const wchar_t *in)
{
Char *rv = out;
wchar_t *rv = out;
int n;
for (;;)
switch (*in) {
case '\0':
*out = '\0';
return (rv);
return rv;
case '\\':
case '^':
if ((n = parse__escape(&in)) == -1)
return (NULL);
*out++ = n;
return NULL;
*out++ = (wchar_t)n;
break;
case 'M':
@@ -273,13 +276,14 @@ parse__string(Char *out, const Char *in)
* 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)
libedit_private int
parse_cmd(EditLine *el, const wchar_t *cmd)
{
el_bindings_t *b;
el_bindings_t *b = el->el_map.help;
size_t i;
for (b = el->el_map.help; b->name != NULL; b++)
if (Strcmp(b->name, cmd) == 0)
return (b->func);
return (-1);
for (i = 0; i < el->el_map.nfunc; i++)
if (wcscmp(b[i].name, cmd) == 0)
return b[i].func;
return -1;
}

View File

@@ -1,4 +1,4 @@
/* $NetBSD: parse.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: parse.h,v 1.9 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -40,9 +40,9 @@
#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 *);
libedit_private int parse_line(EditLine *, const wchar_t *);
libedit_private int parse__escape(const wchar_t **);
libedit_private wchar_t *parse__string(wchar_t *, const wchar_t *);
libedit_private int parse_cmd(EditLine *, const wchar_t *);
#endif /* _h_el_parse */

View File

@@ -1,4 +1,4 @@
/* $NetBSD: prompt.c,v 1.18 2009/12/31 15:58:26 christos Exp $ */
/* $NetBSD: prompt.c,v 1.26 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: prompt.c,v 1.18 2009/12/31 15:58:26 christos Exp $");
__RCSID("$NetBSD: prompt.c,v 1.26 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@@ -47,43 +47,43 @@ __RCSID("$NetBSD: prompt.c,v 1.18 2009/12/31 15:58:26 christos Exp $");
#include <stdio.h>
#include "el.h"
private Char *prompt_default(EditLine *);
private Char *prompt_default_r(EditLine *);
static wchar_t *prompt_default(EditLine *);
static wchar_t *prompt_default_r(EditLine *);
/* prompt_default():
* Just a default prompt, in case the user did not provide one
*/
private Char *
static wchar_t *
/*ARGSUSED*/
prompt_default(EditLine *el __attribute__((__unused__)))
{
static Char a[3] = {'?', ' ', '\0'};
static wchar_t a[3] = L"? ";
return (a);
return a;
}
/* prompt_default_r():
* Just a default rprompt, in case the user did not provide one
*/
private Char *
static wchar_t *
/*ARGSUSED*/
prompt_default_r(EditLine *el __attribute__((__unused__)))
{
static Char a[1] = {'\0'};
static wchar_t a[1] = L"";
return (a);
return a;
}
/* prompt_print():
* Print the prompt and update the prompt position.
*/
protected void
libedit_private void
prompt_print(EditLine *el, int op)
{
el_prompt_t *elp;
Char *p;
wchar_t *p;
int ignore = 0;
if (op == EL_PROMPT)
@@ -103,7 +103,7 @@ prompt_print(EditLine *el, int op)
continue;
}
if (ignore)
term__putc(el, *p);
terminal__putc(el, *p);
else
re_putc(el, *p, 1);
}
@@ -116,7 +116,7 @@ prompt_print(EditLine *el, int op)
/* prompt_init():
* Initialize the prompt stuff
*/
protected int
libedit_private int
prompt_init(EditLine *el)
{
@@ -135,7 +135,7 @@ prompt_init(EditLine *el)
/* prompt_end():
* Clean up the prompt stuff
*/
protected void
libedit_private void
/*ARGSUSED*/
prompt_end(EditLine *el __attribute__((__unused__)))
{
@@ -145,8 +145,8 @@ 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)
libedit_private int
prompt_set(EditLine *el, el_pfunc_t prf, wchar_t c, int op, int wide)
{
el_prompt_t *p;
@@ -177,8 +177,8 @@ prompt_set(EditLine *el, el_pfunc_t prf, Char c, int op, int wide)
/* prompt_get():
* Retrieve the prompt printing function
*/
protected int
prompt_get(EditLine *el, el_pfunc_t *prf, Char *c, int op)
libedit_private int
prompt_get(EditLine *el, el_pfunc_t *prf, wchar_t *c, int op)
{
el_prompt_t *p;

View File

@@ -1,4 +1,4 @@
/* $NetBSD: prompt.h,v 1.10 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: prompt.h,v 1.15 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -40,21 +40,19 @@
#ifndef _h_el_prompt
#define _h_el_prompt
#include "histedit.h"
typedef Char *(*el_pfunc_t)(EditLine *);
typedef wchar_t *(*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 */
Char p_ignore; /* character to start/end literal */
wchar_t p_ignore; /* character to start/end literal */
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 *);
libedit_private void prompt_print(EditLine *, int);
libedit_private int prompt_set(EditLine *, el_pfunc_t, wchar_t, int, int);
libedit_private int prompt_get(EditLine *, el_pfunc_t *, wchar_t *, int);
libedit_private int prompt_init(EditLine *);
libedit_private void prompt_end(EditLine *);
#endif /* _h_el_prompt */

View File

@@ -1,4 +1,4 @@
/* $NetBSD: read.c,v 1.58 2011/02/18 20:53:05 christos Exp $ */
/* $NetBSD: read.c,v 1.101 2016/05/25 13:01:11 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,49 +37,90 @@
#if 0
static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: read.c,v 1.58 2011/02/18 20:53:05 christos Exp $");
__RCSID("$NetBSD: read.c,v 1.101 2016/05/25 13:01:11 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/*
* read.c: Clean this junk up! This is horrible code.
* Terminal read functions
* read.c: Terminal read functions
*/
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "el.h"
#include "fcns.h"
#include "read.h"
#define OKCMD -1 /* must be -1! */
#define EL_MAXMACRO 10
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 *);
struct macros {
wchar_t **macro;
int level;
int offset;
};
struct el_read_t {
struct macros macros;
el_rfunc_t read_char; /* Function to read a character. */
int read_errno;
};
static int read__fixio(int, int);
static int read_char(EditLine *, wchar_t *);
static int read_getcmd(EditLine *, el_action_t *, wchar_t *);
static void read_clearmacros(struct macros *);
static void read_pop(struct macros *);
static const wchar_t *noedit_wgets(EditLine *, int *);
/* read_init():
* Initialize the read stuff
*/
protected int
libedit_private int
read_init(EditLine *el)
{
struct macros *ma;
if ((el->el_read = el_malloc(sizeof(*el->el_read))) == NULL)
return -1;
ma = &el->el_read->macros;
if ((ma->macro = el_malloc(EL_MAXMACRO *
sizeof(*ma->macro))) == NULL) {
free(el->el_read);
return -1;
}
ma->level = -1;
ma->offset = 0;
/* builtin read_char */
el->el_read.read_char = read_char;
el->el_read->read_char = read_char;
return 0;
}
/* el_read_end():
* Free the data structures used by the read stuff.
*/
libedit_private void
read_end(struct el_read_t *el_read)
{
read_clearmacros(&el_read->macros);
el_free(el_read->macros.macro);
el_read->macros.macro = NULL;
}
/* 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)
libedit_private int
el_read_setfn(struct el_read_t *el_read, el_rfunc_t rc)
{
el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc;
el_read->read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc;
return 0;
}
@@ -88,42 +129,19 @@ el_read_setfn(EditLine *el, el_rfunc_t rc)
* 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)
libedit_private el_rfunc_t
el_read_getfn(struct el_read_t *el_read)
{
return (el->el_read.read_char == read_char) ?
EL_BUILTIN_GETCFN : el->el_read.read_char;
return el_read->read_char == read_char ?
EL_BUILTIN_GETCFN : 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
static int
read__fixio(int fd __attribute__((__unused__)), int e)
{
@@ -133,7 +151,7 @@ read__fixio(int fd __attribute__((__unused__)), int e)
#ifdef EWOULDBLOCK
case EWOULDBLOCK:
#ifndef TRY_AGAIN
#define TRY_AGAIN
#define TRY_AGAIN
#endif
#endif /* EWOULDBLOCK */
@@ -141,7 +159,7 @@ read__fixio(int fd __attribute__((__unused__)), int e)
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EAGAIN:
#ifndef TRY_AGAIN
#define TRY_AGAIN
#define TRY_AGAIN
#endif
#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
#endif /* POSIX && EAGAIN */
@@ -150,10 +168,10 @@ read__fixio(int fd __attribute__((__unused__)), int e)
#ifdef TRY_AGAIN
#if defined(F_SETFL) && defined(O_NDELAY)
if ((e = fcntl(fd, F_GETFL, 0)) == -1)
return (-1);
return -1;
if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
return (-1);
return -1;
else
e = 1;
#endif /* F_SETFL && O_NDELAY */
@@ -162,95 +180,62 @@ read__fixio(int fd __attribute__((__unused__)), int e)
{
int zero = 0;
if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1)
return (-1);
if (ioctl(fd, FIONBIO, &zero) == -1)
return -1;
else
e = 1;
}
#endif /* FIONBIO */
#endif /* TRY_AGAIN */
return (e ? 0 : -1);
return e ? 0 : -1;
case EINTR:
return (0);
return 0;
default:
return (-1);
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, (ioctl_t) & chrs);
if (chrs > 0) {
char buf[EL_BUFSIZ];
chrs = read(el->el_infd, buf,
(size_t) MIN(chrs, EL_BUFSIZ - 1));
if (chrs > 0) {
buf[chrs] = '\0';
el_push(el, buf);
}
}
#endif /* FIONREAD */
#endif
return (chrs > 0);
}
/* el_push():
* Push a macro
*/
public void
FUN(el,push)(EditLine *el, const Char *str)
void
el_wpush(EditLine *el, const wchar_t *str)
{
c_macro_t *ma = &el->el_chared.c_macro;
struct macros *ma = &el->el_read->macros;
if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
ma->level++;
if ((ma->macro[ma->level] = Strdup(str)) != NULL)
if ((ma->macro[ma->level] = wcsdup(str)) != NULL)
return;
ma->level--;
}
term_beep(el);
term__flush(el);
terminal_beep(el);
terminal__flush(el);
}
/* read_getcmd():
* Return next command from the input stream.
* Get next command from the input stream,
* return 0 on success or -1 on EOF or error.
* Character values > 255 are not looked up in the map, but inserted.
*/
private int
read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
static int
read_getcmd(EditLine *el, el_action_t *cmdnum, wchar_t *ch)
{
static const wchar_t meta = (wchar_t)0x80;
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 (num);
}
if ((num = el_wgetc(el, ch)) != 1)
return -1;
#ifdef KANJI
if ((*ch & 0200)) {
if ((*ch & meta)) {
el->el_state.metanext = 0;
cmd = CcViMap[' '];
break;
@@ -259,71 +244,52 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
if (el->el_state.metanext) {
el->el_state.metanext = 0;
*ch |= 0200;
*ch |= meta;
}
#ifdef WIDECHAR
if (*ch >= N_KEYS)
cmd = ED_INSERT;
if (*ch >= N_KEYS)
cmd = ED_INSERT;
else
#endif
cmd = el->el_map.current[(unsigned char) *ch];
cmd = el->el_map.current[(unsigned char) *ch];
if (cmd == ED_SEQUENCE_LEAD_IN) {
key_value_t val;
switch (key_get(el, ch, &val)) {
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);
el_wpush(el, val.str);
break;
#ifdef notyet
case XK_EXE:
/* XXX: In the future to run a user function */
RunCommand(val.str);
break;
#endif
case XK_NOD:
return -1;
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);
return 0;
}
#ifdef WIDECHAR
/* utf8_islead():
* Test whether a byte is a leading byte of a UTF-8 sequence.
*/
private int
utf8_islead(unsigned char 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)
static int
read_char(EditLine *el, wchar_t *cp)
{
ssize_t num_read;
int tried = 0;
char cbuf[MB_LEN_MAX];
int cbp = 0;
int bytes = 0;
char cbuf[MB_LEN_MAX];
size_t cbp = 0;
int save_errno = errno;
again:
el->el_signal->sig_no = 0;
while ((num_read = read(el->el_infd, cbuf + cbp, 1)) == -1) {
while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) {
int e = errno;
switch (el->el_signal->sig_no) {
case SIGCONT:
el_set(el, EL_REFRESH);
el_wset(el, EL_REFRESH);
/*FALLTHROUGH*/
case SIGWINCH:
sig_set(el);
@@ -331,44 +297,69 @@ read_char(EditLine *el, Char *cp)
default:
break;
}
if (!tried && read__fixio(el->el_infd, errno) == 0)
if (!tried && read__fixio(el->el_infd, e) == 0) {
errno = save_errno;
tried = 1;
else {
*cp = '\0';
return (-1);
} else {
errno = e;
*cp = L'\0';
return -1;
}
}
#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 */
/* Test for EOF */
if (num_read == 0) {
*cp = L'\0';
return 0;
}
for (;;) {
mbstate_t mbs;
++cbp;
if ((bytes = ct_mbtowc(cp, cbuf, cbp)) == -1) {
ct_mbtowc_reset;
if (cbp >= MB_LEN_MAX) { /* "shouldn't happen" */
*cp = '\0';
return (-1);
/* This only works because UTF8 is stateless. */
memset(&mbs, 0, sizeof(mbs));
switch (mbrtowc(cp, cbuf, cbp, &mbs)) {
case (size_t)-1:
if (cbp > 1) {
/*
* Invalid sequence, discard all bytes
* except the last one.
*/
cbuf[0] = cbuf[cbp - 1];
cbp = 0;
break;
} else {
/* Invalid byte, discard it. */
cbp = 0;
goto again;
}
case (size_t)-2:
/*
* We don't support other multibyte charsets.
* The second condition shouldn't happen
* and is here merely for additional safety.
*/
if ((el->el_flags & CHARSET_IS_UTF8) == 0 ||
cbp >= MB_LEN_MAX) {
errno = EILSEQ;
*cp = L'\0';
return -1;
}
/* Incomplete sequence, read another byte. */
goto again;
default:
/* Valid character, process it. */
return 1;
}
} else /* we don't support other multibyte charsets */
#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)
static void
read_pop(struct macros *ma)
{
int i;
@@ -379,22 +370,25 @@ read_pop(c_macro_t *ma)
ma->offset = 0;
}
/* el_getc():
* Read a character
*/
public int
FUN(el,getc)(EditLine *el, Char *cp)
static void
read_clearmacros(struct macros *ma)
{
while (ma->level >= 0)
el_free(ma->macro[ma->level--]);
ma->offset = 0;
}
/* el_wgetc():
* Read a wide character
*/
int
el_wgetc(EditLine *el, wchar_t *cp)
{
struct macros *ma = &el->el_read->macros;
int num_read;
c_macro_t *ma = &el->el_chared.c_macro;
term__flush(el);
terminal__flush(el);
for (;;) {
if (ma->level < 0) {
if (!read_preread(el))
break;
}
if (ma->level < 0)
break;
@@ -410,30 +404,26 @@ FUN(el,getc)(EditLine *el, Char *cp)
read_pop(ma);
}
return (1);
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);
return 0;
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Reading a character\n");
#endif /* DEBUG_READ */
num_read = (*el->el_read.read_char)(el, cp);
#ifdef 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);
num_read = (*el->el_read->read_char)(el, cp);
/*
* Remember the original reason of a read failure
* such that el_wgets() can restore it after doing
* various cleanup operation that might change errno.
*/
if (num_read < 0)
el->el_read->read_errno = errno;
return num_read;
}
protected void
libedit_private void
read_prepare(EditLine *el)
{
if (el->el_flags & HANDLE_SIGNALS)
@@ -447,14 +437,14 @@ read_prepare(EditLine *el)
we have the wrong size. */
el_resize(el);
re_clear_display(el); /* reset the display stuff */
ch_reset(el, 0);
ch_reset(el);
re_refresh(el); /* print the prompt */
if (el->el_flags & UNBUFFERED)
term__flush(el);
terminal__flush(el);
}
protected void
libedit_private void
read_finish(EditLine *el)
{
if ((el->el_flags & UNBUFFERED) == 0)
@@ -463,61 +453,59 @@ read_finish(EditLine *el)
sig_clr(el);
}
public const Char *
FUN(el,gets)(EditLine *el, int *nread)
static const wchar_t *
noedit_wgets(EditLine *el, int *nread)
{
el_line_t *lp = &el->el_line;
int num;
while ((num = (*el->el_read->read_char)(el, lp->lastchar)) == 1) {
if (lp->lastchar + 1 >= lp->limit &&
!ch_enlargebufs(el, (size_t)2))
break;
lp->lastchar++;
if (el->el_flags & UNBUFFERED ||
lp->lastchar[-1] == '\r' ||
lp->lastchar[-1] == '\n')
break;
}
if (num == -1 && errno == EINTR)
lp->lastchar = lp->buffer;
lp->cursor = lp->lastchar;
*lp->lastchar = '\0';
*nread = (int)(lp->lastchar - lp->buffer);
return *nread ? lp->buffer : NULL;
}
const wchar_t *
el_wgets(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;
wchar_t ch;
int nrb;
#ifdef FIONREAD
c_macro_t *ma = &el->el_chared.c_macro;
#endif /* FIONREAD */
if (nread == NULL)
nread = &nrb;
*nread = 0;
el->el_read->read_errno = 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 = (cp - el->el_line.buffer);
if (!ch_enlargebufs(el, 2))
break;
cp = &el->el_line.buffer[idx];
}
cp++;
if (el->el_flags & UNBUFFERED)
break;
if (cp[-1] == '\r' || cp[-1] == '\n')
break;
}
if (num == -1) {
if (errno == EINTR)
cp = el->el_line.buffer;
el->el_errno = errno;
}
goto noedit;
el->el_line.lastchar = el->el_line.buffer;
return noedit_wgets(el, nread);
}
#ifdef FIONREAD
if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
long chrs = 0;
if (el->el_tty.t_mode == EX_IO && el->el_read->macros.level < 0) {
int chrs = 0;
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
(void) ioctl(el->el_infd, FIONREAD, &chrs);
if (chrs == 0) {
if (tty_rawmode(el) < 0) {
errno = 0;
*nread = 0;
return (NULL);
return NULL;
}
}
}
@@ -527,81 +515,19 @@ FUN(el,gets)(EditLine *el, int *nread)
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;
term__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 = (cp - el->el_line.buffer);
if (!ch_enlargebufs(el, 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;
}
goto noedit;
el->el_line.lastchar = el->el_line.buffer;
terminal__flush(el);
return noedit_wgets(el, nread);
}
for (num = OKCMD; num == OKCMD;) { /* while still editing this
* line */
#ifdef DEBUG_EDIT
read_debug(el);
#endif /* DEBUG_EDIT */
for (num = -1; num == -1;) { /* while still editing this line */
/* 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 (read_getcmd(el, &cmdnum, &ch) == -1)
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 */
if ((size_t)cmdnum >= el->el_map.nfunc) /* BUG CHECK command */
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;
@@ -610,16 +536,12 @@ FUN(el,gets)(EditLine *el, int *nread)
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]))
&& iswprint(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;
@@ -641,7 +563,7 @@ FUN(el,gets)(EditLine *el, int *nread)
case CC_REFRESH_BEEP:
re_refresh(el);
term_beep(el);
terminal_beep(el);
break;
case CC_NORM: /* normal char */
@@ -666,24 +588,17 @@ FUN(el,gets)(EditLine *el, int *nread)
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 */
ch_reset(el); /* reset the input pointers */
read_clearmacros(&el->el_read->macros);
re_refresh(el); /* print the prompt again */
break;
case CC_ERROR:
default: /* functions we don't know about */
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile,
"*** editor ERROR ***\r\n\n");
#endif /* DEBUG_READ */
term_beep(el);
term__flush(el);
terminal_beep(el);
terminal__flush(el);
break;
}
el->el_state.argument = 1;
@@ -693,24 +608,19 @@ FUN(el,gets)(EditLine *el, int *nread)
break;
}
term__flush(el); /* flush any buffered output */
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 {
} 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;
if (el->el_read->read_errno)
errno = el->el_read->read_errno;
}
return NULL;
} else

View File

@@ -1,4 +1,4 @@
/* $NetBSD: read.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: read.h,v 1.12 2016/05/22 19:44:26 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -35,16 +35,11 @@
#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 *);
libedit_private int read_init(EditLine *);
libedit_private void read_end(struct el_read_t *);
libedit_private void read_prepare(EditLine *);
libedit_private void read_finish(EditLine *);
libedit_private int el_read_setfn(struct el_read_t *, el_rfunc_t);
libedit_private el_rfunc_t el_read_getfn(struct el_read_t *);
#endif /* _h_el_read */

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $NetBSD: readline.h,v 1.32 2010/09/16 20:08:52 christos Exp $ */
/* $NetBSD: readline.h,v 1.41 2016/10/28 18:32:35 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -39,9 +39,8 @@
/* 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 void rl_vcpfunc_t(char *);
typedef char **rl_completion_func_t(const char *, int, int);
typedef char *rl_compentry_func_t(const char *, int);
typedef int rl_command_func_t(int, int);
@@ -54,7 +53,7 @@ typedef void *histdata_t;
typedef struct _hist_entry {
const char *line;
histdata_t data;
histdata_t data;
} HIST_ENTRY;
typedef struct _keymap_entry {
@@ -88,7 +87,7 @@ typedef KEYMAP_ENTRY *Keymap;
#define RUBOUT 0x7f
#define ABORT_CHAR CTRL('G')
#define RL_READLINE_VERSION 0x0402
#define RL_READLINE_VERSION 0x0402
#define RL_PROMPT_START_IGNORE '\1'
#define RL_PROMPT_END_IGNORE '\2'
@@ -97,7 +96,7 @@ typedef KEYMAP_ENTRY *Keymap;
extern "C" {
#endif
extern const char *rl_library_version;
extern int rl_readline_version;
extern int rl_readline_version;
extern char *rl_readline_name;
extern FILE *rl_instream;
extern FILE *rl_outstream;
@@ -108,8 +107,9 @@ extern int max_input_history;
extern char *rl_basic_word_break_characters;
extern char *rl_completer_word_break_characters;
extern char *rl_completer_quote_characters;
extern Function *rl_completion_entry_function;
extern CPPFunction *rl_attempted_completion_function;
extern rl_compentry_func_t *rl_completion_entry_function;
extern char *(*rl_completion_word_break_hook)(void);
extern rl_completion_func_t *rl_attempted_completion_function;
extern int rl_attempted_completion_over;
extern int rl_completion_type;
extern int rl_completion_query_items;
@@ -121,9 +121,12 @@ extern Function *rl_startup_hook;
extern char *rl_terminal_name;
extern int rl_already_prompted;
extern char *rl_prompt;
extern int rl_done;
/*
* The following is not implemented
*/
extern int rl_catch_signals;
extern int rl_catch_sigwinch;
extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
emacs_meta_keymap,
emacs_ctlx_keymap;
@@ -156,6 +159,7 @@ int history_total_bytes(void);
int history_set_pos(int);
HIST_ENTRY *previous_history(void);
HIST_ENTRY *next_history(void);
HIST_ENTRY **history_list(void);
int history_search(const char *, int);
int history_search_prefix(const char *, int);
int history_search_pos(const char *, int, int);
@@ -172,7 +176,7 @@ 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 *);
char **completion_matches(const char *, rl_compentry_func_t *);
void rl_display_match_list(char **, int, int);
int rl_insert(int, int);
@@ -181,7 +185,7 @@ 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_install(const char *, rl_vcpfunc_t *);
void rl_callback_handler_remove(void);
void rl_redisplay(void);
int rl_get_previous_history(int, int);
@@ -191,14 +195,14 @@ 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);
int rl_add_defun(const char *, rl_command_func_t *, 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);
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 *);
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);
@@ -214,6 +218,8 @@ 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);
int rl_set_keyboard_input_timeout(int);
#ifdef __cplusplus
}
#endif

View File

@@ -1,4 +1,4 @@
/* $NetBSD: refresh.c,v 1.35 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: refresh.c,v 1.51 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: refresh.c,v 1.35 2009/12/30 22:37:40 christos Exp $");
__RCSID("$NetBSD: refresh.c,v 1.51 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@@ -45,26 +45,25 @@ __RCSID("$NetBSD: refresh.c,v 1.35 2009/12/30 22:37:40 christos Exp $");
* refresh.c: Lower level screen refreshing functions
*/
#include <stdio.h>
#include <ctype.h>
#include <unistd.h>
#include <string.h>
#include <unistd.h>
#include "el.h"
private void re_nextline(EditLine *);
private void re_addc(EditLine *, Int);
private void re_update_line(EditLine *, Char *, Char *, int);
private void re_insert (EditLine *, Char *, int, int, Char *, int);
private void re_delete(EditLine *, Char *, int, int, int);
private void re_fastputc(EditLine *, Int);
private void re_clear_eol(EditLine *, int, int, int);
private void re__strncopy(Char *, Char *, size_t);
private void re__copy_and_pad(Char *, const Char *, size_t);
static void re_nextline(EditLine *);
static void re_addc(EditLine *, wint_t);
static void re_update_line(EditLine *, wchar_t *, wchar_t *, int);
static void re_insert (EditLine *, wchar_t *, int, int, wchar_t *, int);
static void re_delete(EditLine *, wchar_t *, int, int, int);
static void re_fastputc(EditLine *, wint_t);
static void re_clear_eol(EditLine *, int, int, int);
static void re__strncopy(wchar_t *, wchar_t *, size_t);
static void re__copy_and_pad(wchar_t *, const wchar_t *, size_t);
#ifdef DEBUG_REFRESH
private void re_printstr(EditLine *, const char *, char *, char *);
static void re_printstr(EditLine *, const char *, wchar_t *, wchar_t *);
#define __F el->el_errfile
#define ELRE_ASSERT(a, b, c) do \
#define ELRE_ASSERT(a, b, c) do \
if (/*CONSTCOND*/ a) { \
(void) fprintf b; \
c; \
@@ -75,8 +74,8 @@ private void re_printstr(EditLine *, const char *, char *, char *);
/* re_printstr():
* Print a string on the debugging pty
*/
private void
re_printstr(EditLine *el, const char *str, char *f, char *t)
static void
re_printstr(EditLine *el, const char *str, wchar_t *f, wchar_t *t)
{
ELRE_DEBUG(1, (__F, "%s:\"", str));
@@ -92,7 +91,7 @@ re_printstr(EditLine *el, const char *str, char *f, char *t)
/* re_nextline():
* Move to the next line or scroll
*/
private void
static void
re_nextline(EditLine *el)
{
el->el_refresh.r_cursor.h = 0; /* reset it. */
@@ -103,9 +102,9 @@ re_nextline(EditLine *el)
* We do this via pointer shuffling - it's safe in this case
* and we avoid memcpy().
*/
if (el->el_refresh.r_cursor.v + 1 >= el->el_term.t_size.v) {
int i, lins = el->el_term.t_size.v;
Char *firstline = el->el_vdisplay[0];
if (el->el_refresh.r_cursor.v + 1 >= el->el_terminal.t_size.v) {
int i, lins = el->el_terminal.t_size.v;
wchar_t *firstline = el->el_vdisplay[0];
for(i = 1; i < lins; i++)
el->el_vdisplay[i - 1] = el->el_vdisplay[i];
@@ -115,19 +114,19 @@ re_nextline(EditLine *el)
} else
el->el_refresh.r_cursor.v++;
ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_term.t_size.v,
ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_terminal.t_size.v,
(__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
el->el_refresh.r_cursor.v, el->el_term.t_size.v),
el->el_refresh.r_cursor.v, el->el_terminal.t_size.v),
abort());
}
/* re_addc():
* Draw c, expanding tabs, control chars etc.
*/
private void
re_addc(EditLine *el, Int c)
static void
re_addc(EditLine *el, wint_t c)
{
switch (ct_chr_class((Char)c)) {
switch (ct_chr_class(c)) {
case CHTYPE_TAB: /* expand the tab */
for (;;) {
re_putc(el, ' ', 1);
@@ -146,9 +145,9 @@ re_addc(EditLine *el, Int c)
re_putc(el, c, 1);
break;
default: {
Char visbuf[VISUAL_WIDTH_MAX];
wchar_t visbuf[VISUAL_WIDTH_MAX];
ssize_t i, n =
ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c);
for (i = 0; n-- > 0; ++i)
re_putc(el, visbuf[i], 1);
break;
@@ -160,13 +159,15 @@ re_addc(EditLine *el, Int c)
/* re_putc():
* Draw the character given
*/
protected void
re_putc(EditLine *el, Int c, int shift)
libedit_private void
re_putc(EditLine *el, wint_t c, int shift)
{
int i, w = Width(c);
ELRE_DEBUG(1, (__F, "printing %5x '%c'\r\n", c, c));
int i, w = wcwidth(c);
ELRE_DEBUG(1, (__F, "printing %5x '%lc'\r\n", c, c));
if (w == -1)
w = 0;
while (shift && (el->el_refresh.r_cursor.h + w > el->el_term.t_size.h))
while (shift && (el->el_refresh.r_cursor.h + w > el->el_terminal.t_size.h))
re_putc(el, ' ', 1);
el->el_vdisplay[el->el_refresh.r_cursor.v]
@@ -181,9 +182,9 @@ re_putc(EditLine *el, Int c, int shift)
return;
el->el_refresh.r_cursor.h += w; /* advance to next place */
if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) {
if (el->el_refresh.r_cursor.h >= el->el_terminal.t_size.h) {
/* assure end of line */
el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h]
el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_terminal.t_size.h]
= '\0';
re_nextline(el);
}
@@ -192,21 +193,21 @@ re_putc(EditLine *el, Int c, int shift)
/* re_refresh():
* draws the new virtual screen image from the current input
* line, then goes line-by-line changing the real image to the new
* line, then goes line-by-line changing the real image to the new
* virtual image. The routine to re-draw a line can be replaced
* easily in hopes of a smarter one being placed there.
*/
protected void
libedit_private void
re_refresh(EditLine *el)
{
int i, rhdiff;
Char *cp, *st;
wchar_t *cp, *st;
coord_t cur;
#ifdef notyet
size_t termsz;
#endif
ELRE_DEBUG(1, (__F, "el->el_line.buffer = :%s:\r\n",
ELRE_DEBUG(1, (__F, "el->el_line.buffer = :%ls:\r\n",
el->el_line.buffer));
/* reset the Drawing cursor */
@@ -235,7 +236,7 @@ re_refresh(EditLine *el)
/* draw the current input buffer */
#if notyet
termsz = el->el_term.t_size.h * el->el_term.t_size.v;
termsz = el->el_terminal.t_size.h * el->el_terminal.t_size.v;
if (el->el_line.lastchar - el->el_line.buffer > termsz) {
/*
* If line is longer than terminal, process only part
@@ -244,21 +245,21 @@ re_refresh(EditLine *el)
size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz;
st = el->el_line.lastchar - rem
- (termsz - (((rem / el->el_term.t_size.v) - 1)
* el->el_term.t_size.v));
- (termsz - (((rem / el->el_terminal.t_size.v) - 1)
* el->el_terminal.t_size.v));
} else
#endif
st = el->el_line.buffer;
for (cp = st; cp < el->el_line.lastchar; cp++) {
if (cp == el->el_line.cursor) {
int w = Width(*cp);
int w = wcwidth(*cp);
/* save for later */
cur.h = el->el_refresh.r_cursor.h;
cur.v = el->el_refresh.r_cursor.v;
/* handle being at a linebroken doublewidth char */
if (w > 1 && el->el_refresh.r_cursor.h + w >
el->el_term.t_size.h) {
el->el_terminal.t_size.h) {
cur.h = 0;
cur.v++;
}
@@ -270,7 +271,7 @@ re_refresh(EditLine *el)
cur.h = el->el_refresh.r_cursor.h;
cur.v = el->el_refresh.r_cursor.v;
}
rhdiff = el->el_term.t_size.h - el->el_refresh.r_cursor.h -
rhdiff = el->el_terminal.t_size.h - el->el_refresh.r_cursor.h -
el->el_rprompt.p_pos.h;
if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v &&
!el->el_refresh.r_cursor.v && rhdiff > 1) {
@@ -293,8 +294,9 @@ re_refresh(EditLine *el)
ELRE_DEBUG(1, (__F,
"term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
el->el_term.t_size.h, el->el_refresh.r_cursor.h,
el->el_refresh.r_cursor.v, ct_encode_string(el->el_vdisplay[0])));
el->el_terminal.t_size.h, el->el_refresh.r_cursor.h,
el->el_refresh.r_cursor.v, ct_encode_string(el->el_vdisplay[0],
&el->el_scratch)));
ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv));
for (i = 0; i <= el->el_refresh.r_newcv; i++) {
@@ -309,7 +311,7 @@ re_refresh(EditLine *el)
* leftover stuff.
*/
re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
(size_t) el->el_term.t_size.h);
(size_t) el->el_terminal.t_size.h);
}
ELRE_DEBUG(1, (__F,
"\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
@@ -317,12 +319,12 @@ re_refresh(EditLine *el)
if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
for (; i <= el->el_refresh.r_oldcv; i++) {
term_move_to_line(el, i);
term_move_to_char(el, 0);
/* This Strlen should be safe even with MB_FILL_CHARs */
term_clear_EOL(el, (int) Strlen(el->el_display[i]));
terminal_move_to_line(el, i);
terminal_move_to_char(el, 0);
/* This wcslen should be safe even with MB_FILL_CHARs */
terminal_clear_EOL(el, (int) wcslen(el->el_display[i]));
#ifdef DEBUG_REFRESH
term_overwrite(el, "C\b", (size_t)2);
terminal_overwrite(el, L"C\b", 2);
#endif /* DEBUG_REFRESH */
el->el_display[i][0] = '\0';
}
@@ -332,22 +334,22 @@ re_refresh(EditLine *el)
"\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
cur.h, cur.v));
term_move_to_line(el, cur.v); /* go to where the cursor is */
term_move_to_char(el, cur.h);
terminal_move_to_line(el, cur.v); /* go to where the cursor is */
terminal_move_to_char(el, cur.h);
}
/* re_goto_bottom():
* used to go to last used screen line
*/
protected void
libedit_private void
re_goto_bottom(EditLine *el)
{
term_move_to_line(el, el->el_refresh.r_oldcv);
term__putc(el, '\n');
terminal_move_to_line(el, el->el_refresh.r_oldcv);
terminal__putc(el, '\n');
re_clear_display(el);
term__flush(el);
terminal__flush(el);
}
@@ -355,12 +357,12 @@ re_goto_bottom(EditLine *el)
* insert num characters of s into d (in front of the character)
* at dat, maximum length of d is dlen
*/
private void
static void
/*ARGSUSED*/
re_insert(EditLine *el __attribute__((__unused__)),
Char *d, int dat, int dlen, Char *s, int num)
wchar_t *d, int dat, int dlen, wchar_t *s, int num)
{
Char *a, *b;
wchar_t *a, *b;
if (num <= 0)
return;
@@ -369,8 +371,9 @@ re_insert(EditLine *el __attribute__((__unused__)),
ELRE_DEBUG(1,
(__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, ct_encode_string(d)));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));
num, dat, dlen, ct_encode_string(d, &el->el_scratch)));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s,
&el->el_scratch)));
/* open up the space for num chars */
if (num > 0) {
@@ -383,8 +386,9 @@ re_insert(EditLine *el __attribute__((__unused__)),
ELRE_DEBUG(1, (__F,
"re_insert() after insert: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, ct_encode_string(d)));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));
num, dat, dlen, ct_encode_string(d, &el->el_scratch)));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s,
&el->el_scratch)));
/* copy the characters */
for (a = d + dat; (a < d + dlen) && (num > 0); num--)
@@ -404,12 +408,12 @@ re_insert(EditLine *el __attribute__((__unused__)),
/* re_delete():
* delete num characters d at dat, maximum length of d is dlen
*/
private void
static void
/*ARGSUSED*/
re_delete(EditLine *el __attribute__((__unused__)),
Char *d, int dat, int dlen, int num)
wchar_t *d, int dat, int dlen, int num)
{
Char *a, *b;
wchar_t *a, *b;
if (num <= 0)
return;
@@ -419,7 +423,7 @@ re_delete(EditLine *el __attribute__((__unused__)),
}
ELRE_DEBUG(1,
(__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, ct_encode_string(d)));
num, dat, dlen, ct_encode_string(d, &el->el_scratch)));
/* open up the space for num chars */
if (num > 0) {
@@ -431,15 +435,15 @@ re_delete(EditLine *el __attribute__((__unused__)),
}
ELRE_DEBUG(1,
(__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, ct_encode_string(d)));
num, dat, dlen, ct_encode_string(d, &el->el_scratch)));
}
/* re__strncopy():
* Like strncpy without padding.
*/
private void
re__strncopy(Char *a, Char *b, size_t n)
static void
re__strncopy(wchar_t *a, wchar_t *b, size_t n)
{
while (n-- && *b)
@@ -451,9 +455,9 @@ re__strncopy(Char *a, Char *b, size_t n)
* in order to make sure that we have cleared the previous contents of
* the line. fx and sx is the number of characters inserted or deleted
* in the first or second diff, diff is the difference between the
* number of characters between the new and old line.
* number of characters between the new and old line.
*/
private void
static void
re_clear_eol(EditLine *el, int fx, int sx, int diff)
{
@@ -470,7 +474,7 @@ re_clear_eol(EditLine *el, int fx, int sx, int diff)
diff = sx;
ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff));
term_clear_EOL(el, diff);
terminal_clear_EOL(el, diff);
}
/*****************************************************************
@@ -497,12 +501,12 @@ new: eddie> Oh, my little buggy says to me, as lurgid as
*/
#define MIN_END_KEEP 4
private void
re_update_line(EditLine *el, Char *old, Char *new, int i)
static void
re_update_line(EditLine *el, wchar_t *old, wchar_t *new, int i)
{
Char *o, *n, *p, c;
Char *ofd, *ols, *oe, *nfd, *nls, *ne;
Char *osb, *ose, *nsb, *nse;
wchar_t *o, *n, *p, c;
wchar_t *ofd, *ols, *oe, *nfd, *nls, *ne;
wchar_t *osb, *ose, *nsb, *nse;
int fx, sx;
size_t len;
@@ -559,7 +563,7 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
nls = ++n;
/*
* find same begining and same end
* find same beginning and same end
*/
osb = ols;
nsb = nls;
@@ -689,9 +693,9 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
sx = (int)((nls - nse) - (ols - ose));
ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx));
ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
ELRE_DEBUG(1, (__F, "ofd %td, osb %td, ose %td, ols %td, oe %td\n",
ofd - old, osb - old, ose - old, ols - old, oe - old));
ELRE_DEBUG(1, (__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n",
ELRE_DEBUG(1, (__F, "nfd %td, nsb %td, nse %td, nls %td, ne %td\n",
nfd - new, nsb - new, nse - new, nls - new, ne - new));
ELRE_DEBUG(1, (__F,
"xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n"));
@@ -717,7 +721,7 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
* don't have to change the line, we don't move to it. el_cursor.h to
* first diff char
*/
term_move_to_line(el, i);
terminal_move_to_line(el, i);
/*
* at this point we have something like this:
@@ -741,7 +745,7 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
* if we have a net insert on the first difference, AND inserting the
* net amount ((nsb-nfd) - (osb-ofd)) won't push the last useful
* character (which is ne if nls != ne, otherwise is nse) off the edge
* of the screen (el->el_term.t_size.h) else we do the deletes first
* of the screen (el->el_terminal.t_size.h) else we do the deletes first
* so that we keep everything we need to.
*/
@@ -763,13 +767,13 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
* No insert or delete
*/
if ((nsb != nfd) && fx > 0 &&
((p - old) + fx <= el->el_term.t_size.h)) {
((p - old) + fx <= el->el_terminal.t_size.h)) {
ELRE_DEBUG(1,
(__F, "first diff insert at %d...\r\n", nfd - new));
(__F, "first diff insert at %td...\r\n", nfd - new));
/*
* Move to the first char to insert, where the first diff is.
*/
term_move_to_char(el, (int)(nfd - new));
terminal_move_to_char(el, (int)(nfd - new));
/*
* Check if we have stuff to keep at end
*/
@@ -781,21 +785,21 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
if (fx > 0) {
ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in early first diff\n"));
term_insertwrite(el, nfd, fx);
terminal_insertwrite(el, nfd, fx);
re_insert(el, old, (int)(ofd - old),
el->el_term.t_size.h, nfd, fx);
el->el_terminal.t_size.h, nfd, fx);
}
/*
* write (nsb-nfd) - fx chars of new starting at
* (nfd + fx)
*/
len = (size_t) ((nsb - nfd) - fx);
term_overwrite(el, (nfd + fx), len);
terminal_overwrite(el, (nfd + fx), len);
re__strncopy(ofd + fx, nfd + fx, len);
} else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
len = (size_t)(nsb - nfd);
term_overwrite(el, nfd, len);
terminal_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
/*
* Done
@@ -804,11 +808,11 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
}
} else if (fx < 0) {
ELRE_DEBUG(1,
(__F, "first diff delete at %d...\r\n", ofd - old));
(__F, "first diff delete at %td...\r\n", ofd - old));
/*
* move to the first char to delete where the first diff is
*/
term_move_to_char(el, (int)(ofd - old));
terminal_move_to_char(el, (int)(ofd - old));
/*
* Check if we have stuff to save
*/
@@ -821,15 +825,15 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
if (fx < 0) {
ELRE_DEBUG(!EL_CAN_DELETE, (__F,
"ERROR: cannot delete in first diff\n"));
term_deletechars(el, -fx);
terminal_deletechars(el, -fx);
re_delete(el, old, (int)(ofd - old),
el->el_term.t_size.h, -fx);
el->el_terminal.t_size.h, -fx);
}
/*
* write (nsb-nfd) chars of new starting at nfd
*/
len = (size_t) (nsb - nfd);
term_overwrite(el, nfd, len);
terminal_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
} else {
@@ -838,7 +842,7 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
/*
* write (nsb-nfd) chars of new starting at nfd
*/
term_overwrite(el, nfd, (size_t)(nsb - nfd));
terminal_overwrite(el, nfd, (size_t)(nsb - nfd));
re_clear_eol(el, fx, sx,
(int)((oe - old) - (ne - new)));
/*
@@ -849,9 +853,9 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
} else
fx = 0;
if (sx < 0 && (ose - old) + fx < el->el_term.t_size.h) {
if (sx < 0 && (ose - old) + fx < el->el_terminal.t_size.h) {
ELRE_DEBUG(1, (__F,
"second diff delete at %d...\r\n", (ose - old) + fx));
"second diff delete at %td...\r\n", (ose - old) + fx));
/*
* Check if we have stuff to delete
*/
@@ -859,7 +863,7 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
* fx is the number of characters inserted (+) or deleted (-)
*/
term_move_to_char(el, (int)((ose - old) + fx));
terminal_move_to_char(el, (int)((ose - old) + fx));
/*
* Check if we have stuff to save
*/
@@ -871,16 +875,16 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
if (sx < 0) {
ELRE_DEBUG(!EL_CAN_DELETE, (__F,
"ERROR: cannot delete in second diff\n"));
term_deletechars(el, -sx);
terminal_deletechars(el, -sx);
}
/*
* write (nls-nse) chars of new starting at nse
*/
term_overwrite(el, nse, (size_t)(nls - nse));
terminal_overwrite(el, nse, (size_t)(nls - nse));
} else {
ELRE_DEBUG(1, (__F,
"but with nothing left to save\r\n"));
term_overwrite(el, nse, (size_t)(nls - nse));
terminal_overwrite(el, nse, (size_t)(nls - nse));
re_clear_eol(el, fx, sx,
(int)((oe - old) - (ne - new)));
}
@@ -889,10 +893,10 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
* if we have a first insert AND WE HAVEN'T ALREADY DONE IT...
*/
if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) {
ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n",
ELRE_DEBUG(1, (__F, "late first diff insert at %td...\r\n",
nfd - new));
term_move_to_char(el, (int)(nfd - new));
terminal_move_to_char(el, (int)(nfd - new));
/*
* Check if we have stuff to keep at the end
*/
@@ -910,21 +914,21 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
*/
ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in late first diff\n"));
term_insertwrite(el, nfd, fx);
terminal_insertwrite(el, nfd, fx);
re_insert(el, old, (int)(ofd - old),
el->el_term.t_size.h, nfd, fx);
el->el_terminal.t_size.h, nfd, fx);
}
/*
* write (nsb-nfd) - fx chars of new starting at
* (nfd + fx)
*/
len = (size_t) ((nsb - nfd) - fx);
term_overwrite(el, (nfd + fx), len);
terminal_overwrite(el, (nfd + fx), len);
re__strncopy(ofd + fx, nfd + fx, len);
} else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
len = (size_t) (nsb - nfd);
term_overwrite(el, nfd, len);
terminal_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
}
}
@@ -934,24 +938,24 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
if (sx >= 0) {
ELRE_DEBUG(1, (__F,
"second diff insert at %d...\r\n", (int)(nse - new)));
term_move_to_char(el, (int)(nse - new));
terminal_move_to_char(el, (int)(nse - new));
if (ols != oe) {
ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
if (sx > 0) {
/* insert sx chars of new starting at nse */
ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in second diff\n"));
term_insertwrite(el, nse, sx);
terminal_insertwrite(el, nse, sx);
}
/*
* write (nls-nse) - sx chars of new starting at
* (nse + sx)
*/
term_overwrite(el, (nse + sx),
terminal_overwrite(el, (nse + sx),
(size_t)((nls - nse) - sx));
} else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
term_overwrite(el, nse, (size_t)(nls - nse));
terminal_overwrite(el, nse, (size_t)(nls - nse));
/*
* No need to do a clear-to-end here because we were
@@ -967,8 +971,8 @@ re_update_line(EditLine *el, Char *old, Char *new, int i)
/* re__copy_and_pad():
* Copy string and pad with spaces
*/
private void
re__copy_and_pad(Char *dst, const Char *src, size_t width)
static void
re__copy_and_pad(wchar_t *dst, const wchar_t *src, size_t width)
{
size_t i;
@@ -988,10 +992,10 @@ re__copy_and_pad(Char *dst, const Char *src, size_t width)
/* re_refresh_cursor():
* Move to the new cursor position
*/
protected void
libedit_private void
re_refresh_cursor(EditLine *el)
{
Char *cp;
wchar_t *cp;
int h, v, th, w;
if (el->el_line.cursor >= el->el_line.lastchar) {
@@ -1005,7 +1009,7 @@ re_refresh_cursor(EditLine *el)
/* first we must find where the cursor is... */
h = el->el_prompt.p_pos.h;
v = el->el_prompt.p_pos.v;
th = el->el_term.t_size.h; /* optimize for speed */
th = el->el_terminal.t_size.h; /* optimize for speed */
/* do input buffer to el->el_line.cursor */
for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
@@ -1019,7 +1023,7 @@ re_refresh_cursor(EditLine *el)
continue;
break;
default:
w = Width(*cp);
w = wcwidth(*cp);
if (w > 1 && h + w > th) { /* won't fit on line */
h = 0;
v++;
@@ -1035,36 +1039,36 @@ re_refresh_cursor(EditLine *el)
}
/* if we have a next character, and it's a doublewidth one, we need to
* check whether we need to linebreak for it to fit */
if (cp < el->el_line.lastchar && (w = Width(*cp)) > 1)
if (cp < el->el_line.lastchar && (w = wcwidth(*cp)) > 1)
if (h + w > th) {
h = 0;
v++;
}
/* now go there */
term_move_to_line(el, v);
term_move_to_char(el, h);
term__flush(el);
terminal_move_to_line(el, v);
terminal_move_to_char(el, h);
terminal__flush(el);
}
/* re_fastputc():
* Add a character fast.
*/
private void
re_fastputc(EditLine *el, Int c)
static void
re_fastputc(EditLine *el, wint_t c)
{
int w = Width((Char)c);
while (w > 1 && el->el_cursor.h + w > el->el_term.t_size.h)
int w = wcwidth(c);
while (w > 1 && el->el_cursor.h + w > el->el_terminal.t_size.h)
re_fastputc(el, ' ');
term__putc(el, c);
terminal__putc(el, c);
el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
while (--w > 0)
el->el_display[el->el_cursor.v][el->el_cursor.h++]
= MB_FILL_CHAR;
if (el->el_cursor.h >= el->el_term.t_size.h) {
if (el->el_cursor.h >= el->el_terminal.t_size.h) {
/* if we must overflow */
el->el_cursor.h = 0;
@@ -1074,14 +1078,14 @@ re_fastputc(EditLine *el, Int c)
* We do this via pointer shuffling - it's safe in this case
* and we avoid memcpy().
*/
if (el->el_cursor.v + 1 >= el->el_term.t_size.v) {
int i, lins = el->el_term.t_size.v;
Char *firstline = el->el_display[0];
if (el->el_cursor.v + 1 >= el->el_terminal.t_size.v) {
int i, lins = el->el_terminal.t_size.v;
wchar_t *firstline = el->el_display[0];
for(i = 1; i < lins; i++)
el->el_display[i - 1] = el->el_display[i];
re__copy_and_pad(firstline, STR(""), 0);
re__copy_and_pad(firstline, L"", (size_t)0);
el->el_display[i - 1] = firstline;
} else {
el->el_cursor.v++;
@@ -1089,12 +1093,12 @@ re_fastputc(EditLine *el, Int c)
}
if (EL_HAS_AUTO_MARGINS) {
if (EL_HAS_MAGIC_MARGINS) {
term__putc(el, ' ');
term__putc(el, '\b');
terminal__putc(el, ' ');
terminal__putc(el, '\b');
}
} else {
term__putc(el, '\r');
term__putc(el, '\n');
terminal__putc(el, '\r');
terminal__putc(el, '\n');
}
}
}
@@ -1104,10 +1108,10 @@ re_fastputc(EditLine *el, Int c)
* we added just one char, handle it fast.
* Assumes that screen cursor == real cursor
*/
protected void
libedit_private void
re_fastaddc(EditLine *el)
{
Char c;
wchar_t c;
int rhdiff;
c = el->el_line.cursor[-1];
@@ -1116,7 +1120,7 @@ re_fastaddc(EditLine *el)
re_refresh(el); /* too hard to handle */
return;
}
rhdiff = el->el_term.t_size.h - el->el_cursor.h -
rhdiff = el->el_terminal.t_size.h - el->el_cursor.h -
el->el_rprompt.p_pos.h;
if (el->el_rprompt.p_pos.h && rhdiff < 3) {
re_refresh(el); /* clear out rprompt if less than 1 char gap */
@@ -1131,29 +1135,29 @@ re_fastaddc(EditLine *el)
break;
case CHTYPE_ASCIICTL:
case CHTYPE_NONPRINT: {
Char visbuf[VISUAL_WIDTH_MAX];
wchar_t visbuf[VISUAL_WIDTH_MAX];
ssize_t i, n =
ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c);
for (i = 0; n-- > 0; ++i)
re_fastputc(el, visbuf[i]);
break;
}
}
term__flush(el);
terminal__flush(el);
}
/* re_clear_display():
* clear the screen buffers so that new new prompt starts fresh.
*/
protected void
libedit_private void
re_clear_display(EditLine *el)
{
int i;
el->el_cursor.v = 0;
el->el_cursor.h = 0;
for (i = 0; i < el->el_term.t_size.v; i++)
for (i = 0; i < el->el_terminal.t_size.v; i++)
el->el_display[i][0] = '\0';
el->el_refresh.r_oldcv = 0;
}
@@ -1162,7 +1166,7 @@ re_clear_display(EditLine *el)
/* re_clear_lines():
* Make sure all lines are *really* blank
*/
protected void
libedit_private void
re_clear_lines(EditLine *el)
{
@@ -1170,14 +1174,14 @@ re_clear_lines(EditLine *el)
int i;
for (i = el->el_refresh.r_oldcv; i >= 0; i--) {
/* for each line on the screen */
term_move_to_line(el, i);
term_move_to_char(el, 0);
term_clear_EOL(el, el->el_term.t_size.h);
terminal_move_to_line(el, i);
terminal_move_to_char(el, 0);
terminal_clear_EOL(el, el->el_terminal.t_size.h);
}
} else {
term_move_to_line(el, el->el_refresh.r_oldcv);
terminal_move_to_line(el, el->el_refresh.r_oldcv);
/* go to last line */
term__putc(el, '\r'); /* go to BOL */
term__putc(el, '\n'); /* go to new line */
terminal__putc(el, '\r'); /* go to BOL */
terminal__putc(el, '\n'); /* go to new line */
}
}

View File

@@ -1,4 +1,4 @@
/* $NetBSD: refresh.h,v 1.6 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: refresh.h,v 1.10 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -40,20 +40,18 @@
#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 *);
libedit_private void re_putc(EditLine *, wint_t, int);
libedit_private void re_clear_lines(EditLine *);
libedit_private void re_clear_display(EditLine *);
libedit_private void re_refresh(EditLine *);
libedit_private void re_refresh_cursor(EditLine *);
libedit_private void re_fastaddc(EditLine *);
libedit_private void re_goto_bottom(EditLine *);
#endif /* _h_el_refresh */

View File

@@ -1,4 +1,4 @@
/* $NetBSD: search.c,v 1.24 2010/04/15 00:57:33 christos Exp $ */
/* $NetBSD: search.c,v 1.47 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: search.c,v 1.24 2010/04/15 00:57:33 christos Exp $");
__RCSID("$NetBSD: search.c,v 1.47 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@@ -45,13 +45,16 @@ __RCSID("$NetBSD: search.c,v 1.24 2010/04/15 00:57:33 christos Exp $");
* search.c: History and character search functions
*/
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#if defined(REGEX)
#include <regex.h>
#elif defined(REGEXP)
#include <regexp.h>
#endif
#include "el.h"
#include "common.h"
#include "fcns.h"
/*
* Adjust cursor in vi mode to include the character under it
@@ -63,31 +66,32 @@ __RCSID("$NetBSD: search.c,v 1.24 2010/04/15 00:57:33 christos Exp $");
/* search_init():
* Initialize the search stuff
*/
protected int
libedit_private 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);
return -1;
el->el_search.patbuf[0] = L'\0';
el->el_search.patlen = 0;
el->el_search.patdir = -1;
el->el_search.chacha = '\0';
el->el_search.chacha = L'\0';
el->el_search.chadir = CHAR_FWD;
el->el_search.chatflg = 0;
return (0);
return 0;
}
/* search_end():
* Initialize the search stuff
*/
protected void
libedit_private void
search_end(EditLine *el)
{
el_free((ptr_t) el->el_search.patbuf);
el_free(el->el_search.patbuf);
el->el_search.patbuf = NULL;
}
@@ -96,7 +100,7 @@ search_end(EditLine *el)
/* regerror():
* Handle regular expression errors
*/
public void
void
/*ARGSUSED*/
regerror(const char *msg)
{
@@ -107,12 +111,10 @@ regerror(const char *msg)
/* el_match():
* Return if string matches pattern
*/
protected int
el_match(const Char *str, const Char *pat)
libedit_private int
el_match(const wchar_t *str, const wchar_t *pat)
{
#ifdef WIDECHAR
static ct_buffer_t conv;
#endif
#if defined (REGEX)
regex_t re;
int rv;
@@ -124,30 +126,31 @@ el_match(const Char *str, const Char *pat)
extern int re_exec(const char *);
#endif
if (Strstr(str, pat) != 0)
return (1);
if (wcsstr(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), 0, NULL, 0) == 0;
rv = regexec(&re, ct_encode_string(str, &conv), (size_t)0, NULL,
0) == 0;
regfree(&re);
} else {
rv = 0;
}
return (rv);
return rv;
#elif defined(REGEXP)
if ((re = regcomp(ct_encode_string(pat, &conv))) != NULL) {
rv = regexec(re, ct_encode_string(str, &conv));
free((ptr_t) re);
el_free(re);
} else {
rv = 0;
}
return (rv);
return rv;
#else
if (re_comp(ct_encode_string(pat, &conv)) != NULL)
return (0);
return 0;
else
return (re_exec(ct_encode_string(str, &conv)) == 1);
return re_exec(ct_encode_string(str, &conv)) == 1;
#endif
}
@@ -155,35 +158,36 @@ el_match(const Char *str, const Char *pat)
/* c_hmatch():
* return True if the pattern matches the prefix
*/
protected int
c_hmatch(EditLine *el, const Char *str)
libedit_private int
c_hmatch(EditLine *el, const wchar_t *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));
return el_match(str, el->el_search.patbuf);
}
/* c_setpat():
* Set the history seatch pattern
*/
protected void
libedit_private void
c_setpat(EditLine *el)
{
if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY &&
el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) {
el->el_search.patlen = EL_CURSOR(el) - el->el_line.buffer;
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,
(void) wcsncpy(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);
el->el_search.patlen = wcslen(el->el_search.patbuf);
}
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "\neventno = %d\n",
@@ -201,15 +205,14 @@ c_setpat(EditLine *el)
/* ce_inc_search():
* Emacs incremental search
*/
protected el_action_t
libedit_private 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;
static const wchar_t STRfwd[] = L"fwd", STRbck[] = L"bck";
static wchar_t pchar = L':'; /* ':' = normal, '?' = failed */
static wchar_t endcmd[2] = {'\0', '\0'};
wchar_t *ocursor = el->el_line.cursor, oldpchar = pchar, ch;
const wchar_t *cp;
el_action_t ret = CC_NORM;
@@ -221,7 +224,7 @@ ce_inc_search(EditLine *el, int dir)
if (el->el_line.lastchar + sizeof(STRfwd) /
sizeof(*el->el_line.lastchar) + 2 +
el->el_search.patlen >= el->el_line.limit)
return (CC_ERROR);
return CC_ERROR;
for (;;) {
@@ -248,14 +251,14 @@ ce_inc_search(EditLine *el, int dir)
*el->el_line.lastchar = '\0';
re_refresh(el);
if (FUN(el,getc)(el, &ch) != 1)
return (ed_end_of_file(el, 0));
if (el_wgetc(el, &ch) != 1)
return ed_end_of_file(el, 0);
switch (el->el_map.current[(unsigned char) ch]) {
case ED_INSERT:
case ED_DIGIT:
if (el->el_search.patlen >= EL_BUFSIZ - LEN)
term_beep(el);
terminal_beep(el);
else {
el->el_search.patbuf[el->el_search.patlen++] =
ch;
@@ -280,7 +283,7 @@ ce_inc_search(EditLine *el, int dir)
if (el->el_search.patlen > LEN)
done++;
else
term_beep(el);
terminal_beep(el);
break;
default:
@@ -304,7 +307,7 @@ ce_inc_search(EditLine *el, int dir)
*el->el_line.cursor != '\n') {
if (el->el_search.patlen >=
EL_BUFSIZ - LEN) {
term_beep(el);
terminal_beep(el);
break;
}
el->el_search.patbuf[el->el_search.patlen++] =
@@ -317,14 +320,14 @@ ce_inc_search(EditLine *el, int dir)
re_refresh(el);
break;
} else if (isglob(*cp)) {
term_beep(el);
terminal_beep(el);
break;
}
break;
default: /* Terminate and execute cmd */
endcmd[0] = ch;
FUN(el,push)(el, endcmd);
el_wpush(el, endcmd);
/* FALLTHROUGH */
case 0033: /* ESC: Terminate */
@@ -344,14 +347,14 @@ ce_inc_search(EditLine *el, int dir)
/* Can't search if unmatched '[' */
for (cp = &el->el_search.patbuf[el->el_search.patlen-1],
ch = ']';
ch = L']';
cp >= &el->el_search.patbuf[LEN];
cp--)
if (*cp == '[' || *cp == ']') {
ch = *cp;
break;
}
if (el->el_search.patlen > LEN && ch != '[') {
if (el->el_search.patlen > LEN && ch != L'[') {
if (redo && newdir == dir) {
if (pchar == '?') { /* wrap around */
el->el_history.eventno =
@@ -386,9 +389,10 @@ ce_inc_search(EditLine *el, int dir)
/* avoid c_setpat */
el->el_state.lastcmd =
(el_action_t) newdir;
ret = newdir == ED_SEARCH_PREV_HISTORY ?
ret = (el_action_t)
(newdir == ED_SEARCH_PREV_HISTORY ?
ed_search_prev_history(el, 0) :
ed_search_next_history(el, 0);
ed_search_next_history(el, 0));
if (ret != CC_ERROR) {
el->el_line.cursor = newdir ==
ED_SEARCH_PREV_HISTORY ?
@@ -402,13 +406,13 @@ ce_inc_search(EditLine *el, int dir)
el->el_search.patbuf[el->el_search.patlen] =
'\0';
if (ret == CC_ERROR) {
term_beep(el);
terminal_beep(el);
if (el->el_history.eventno !=
ohisteventno) {
el->el_history.eventno =
ohisteventno;
if (hist_get(el) == CC_ERROR)
return (CC_ERROR);
return CC_ERROR;
}
el->el_line.cursor = ocursor;
pchar = '?';
@@ -433,14 +437,14 @@ ce_inc_search(EditLine *el, int dir)
if (el->el_history.eventno != ohisteventno) {
el->el_history.eventno = ohisteventno;
if (hist_get(el) == CC_ERROR)
return (CC_ERROR);
return CC_ERROR;
}
el->el_line.cursor = ocursor;
if (ret == CC_ERROR)
re_refresh(el);
}
if (done || ret != CC_NORM)
return (ret);
return ret;
}
}
@@ -448,12 +452,12 @@ ce_inc_search(EditLine *el, int dir)
/* cv_search():
* Vi search.
*/
protected el_action_t
libedit_private el_action_t
cv_search(EditLine *el, int dir)
{
Char ch;
Char tmpbuf[EL_BUFSIZ];
int tmplen;
wchar_t ch;
wchar_t tmpbuf[EL_BUFSIZ];
ssize_t tmplen;
#ifdef ANCHOR
tmpbuf[0] = '.';
@@ -464,7 +468,7 @@ cv_search(EditLine *el, int dir)
el->el_search.patdir = dir;
tmplen = c_gets(el, &tmpbuf[LEN],
dir == ED_SEARCH_PREV_HISTORY ? STR("\n/") : STR("\n?") );
dir == ED_SEARCH_PREV_HISTORY ? L"\n/" : L"\n?" );
if (tmplen == -1)
return CC_REFRESH;
@@ -478,16 +482,16 @@ cv_search(EditLine *el, int dir)
*/
if (el->el_search.patlen == 0) {
re_refresh(el);
return (CC_ERROR);
return CC_ERROR;
}
#ifdef ANCHOR
if (el->el_search.patbuf[0] != '.' &&
el->el_search.patbuf[0] != '*') {
(void) Strncpy(tmpbuf, el->el_search.patbuf,
(void) wcsncpy(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,
(void) wcsncpy(&el->el_search.patbuf[2], tmpbuf,
EL_BUFSIZ - 3);
el->el_search.patlen++;
el->el_search.patbuf[el->el_search.patlen++] = '.';
@@ -501,33 +505,33 @@ cv_search(EditLine *el, int dir)
tmpbuf[tmplen++] = '*';
#endif
tmpbuf[tmplen] = '\0';
(void) Strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
el->el_search.patlen = tmplen;
(void) wcsncpy(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);
return CC_ERROR;
}
if (ch == 0033) {
re_refresh(el);
return ed_newline(el, 0);
}
return (CC_REFRESH);
return CC_REFRESH;
}
/* ce_search_line():
* Look for a pattern inside a line
*/
protected el_action_t
libedit_private 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;
wchar_t *cp = el->el_line.cursor;
wchar_t *pattern = el->el_search.patbuf;
wchar_t oc, *ocp;
#ifdef ANCHOR
ocp = &pattern[1];
oc = *ocp;
@@ -542,21 +546,21 @@ ce_search_line(EditLine *el, int dir)
if (el_match(cp, ocp)) {
*ocp = oc;
el->el_line.cursor = cp;
return (CC_NORM);
return CC_NORM;
}
}
*ocp = oc;
return (CC_ERROR);
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);
return CC_NORM;
}
}
*ocp = oc;
return (CC_ERROR);
return CC_ERROR;
}
}
@@ -564,8 +568,8 @@ ce_search_line(EditLine *el, int dir)
/* cv_repeat_srch():
* Vi repeat search
*/
protected el_action_t
cv_repeat_srch(EditLine *el, Int c)
libedit_private el_action_t
cv_repeat_srch(EditLine *el, wint_t c)
{
#ifdef SDEBUG
@@ -578,11 +582,11 @@ cv_repeat_srch(EditLine *el, Int c)
switch (c) {
case ED_SEARCH_NEXT_HISTORY:
return (ed_search_next_history(el, 0));
return ed_search_next_history(el, 0);
case ED_SEARCH_PREV_HISTORY:
return (ed_search_prev_history(el, 0));
return ed_search_prev_history(el, 0);
default:
return (CC_ERROR);
return CC_ERROR;
}
}
@@ -590,36 +594,34 @@ cv_repeat_srch(EditLine *el, Int c)
/* cv_csearch():
* Vi character search
*/
protected el_action_t
cv_csearch(EditLine *el, int direction, Int ch, int count, int tflag)
libedit_private el_action_t
cv_csearch(EditLine *el, int direction, wint_t ch, int count, int tflag)
{
Char *cp;
wchar_t *cp;
if (ch == 0)
return CC_ERROR;
if (ch == -1) {
Char c;
if (FUN(el,getc)(el, &c) != 1)
if (ch == (wint_t)-1) {
if (el_wgetc(el, &ch) != 1)
return ed_end_of_file(el, 0);
ch = c;
}
/* Save for ';' and ',' commands */
el->el_search.chacha = ch;
el->el_search.chadir = direction;
el->el_search.chatflg = tflag;
el->el_search.chatflg = (char)tflag;
cp = el->el_line.cursor;
while (count--) {
if (*cp == ch)
if ((wint_t)*cp == ch)
cp += direction;
for (;;cp += direction) {
if (cp >= el->el_line.lastchar)
return CC_ERROR;
if (cp < el->el_line.buffer)
return CC_ERROR;
if (*cp == ch)
if ((wint_t)*cp == ch)
break;
}
}

View File

@@ -1,4 +1,4 @@
/* $NetBSD: search.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: search.h,v 1.14 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -40,27 +40,25 @@
#ifndef _h_el_search
#define _h_el_search
#include "histedit.h"
typedef struct el_search_t {
Char *patbuf; /* The pattern buffer */
wchar_t *patbuf; /* The pattern buffer */
size_t patlen; /* Length of the pattern buffer */
int patdir; /* Direction of the last search */
int chadir; /* Character search direction */
Char chacha; /* Character we are looking for */
wchar_t chacha; /* Character we are looking for */
char chatflg; /* 0 if f, 1 if t */
} el_search_t;
protected int el_match(const Char *, const Char *);
protected int search_init(EditLine *);
protected void search_end(EditLine *);
protected int c_hmatch(EditLine *, const Char *);
protected void c_setpat(EditLine *);
protected el_action_t ce_inc_search(EditLine *, int);
protected el_action_t cv_search(EditLine *, int);
protected el_action_t ce_search_line(EditLine *, int);
protected el_action_t cv_repeat_srch(EditLine *, Int);
protected el_action_t cv_csearch(EditLine *, int, Int, int, int);
libedit_private int el_match(const wchar_t *, const wchar_t *);
libedit_private int search_init(EditLine *);
libedit_private void search_end(EditLine *);
libedit_private int c_hmatch(EditLine *, const wchar_t *);
libedit_private void c_setpat(EditLine *);
libedit_private el_action_t ce_inc_search(EditLine *, int);
libedit_private el_action_t cv_search(EditLine *, int);
libedit_private el_action_t ce_search_line(EditLine *, int);
libedit_private el_action_t cv_repeat_srch(EditLine *, wint_t);
libedit_private el_action_t cv_csearch(EditLine *, int, wint_t, int, int);
#endif /* _h_el_search */

View File

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

View File

@@ -1,4 +1,4 @@
/* $NetBSD: sig.c,v 1.15 2009/02/19 15:20:22 christos Exp $ */
/* $NetBSD: sig.c,v 1.26 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: sig.c,v 1.15 2009/02/19 15:20:22 christos Exp $");
__RCSID("$NetBSD: sig.c,v 1.26 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@@ -46,31 +46,35 @@ __RCSID("$NetBSD: sig.c,v 1.15 2009/02/19 15:20:22 christos Exp $");
* our policy is to trap all signals, set a good state
* and pass the ball to our caller.
*/
#include "el.h"
#include <errno.h>
#include <stdlib.h>
private EditLine *sel = NULL;
#include "el.h"
#include "common.h"
private const int sighdl[] = {
static EditLine *sel = NULL;
static const int sighdl[] = {
#define _DO(a) (a),
ALLSIGS
#undef _DO
- 1
};
private void sig_handler(int);
static 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
static void
sig_handler(int signo)
{
int i;
int i, save_errno;
sigset_t nset, oset;
save_errno = errno;
(void) sigemptyset(&nset);
(void) sigaddset(&nset, signo);
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
@@ -82,7 +86,7 @@ sig_handler(int signo)
tty_rawmode(sel);
if (ed_redisplay(sel, 0) == CC_REFRESH)
re_refresh(sel);
term__flush(sel);
terminal__flush(sel);
break;
case SIGWINCH:
@@ -104,13 +108,14 @@ sig_handler(int signo)
sigemptyset(&sel->el_signal->sig_action[i].sa_mask);
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
(void) kill(0, signo);
errno = save_errno;
}
/* sig_init():
* Initialize all signal stuff
*/
protected int
libedit_private int
sig_init(EditLine *el)
{
size_t i;
@@ -142,11 +147,11 @@ sig_init(EditLine *el)
/* sig_end():
* Clear all signal stuff
*/
protected void
libedit_private void
sig_end(EditLine *el)
{
el_free((ptr_t) el->el_signal);
el_free(el->el_signal);
el->el_signal = NULL;
}
@@ -154,7 +159,7 @@ sig_end(EditLine *el)
/* sig_set():
* set all the signal handlers
*/
protected void
libedit_private void
sig_set(EditLine *el)
{
size_t i;
@@ -181,7 +186,7 @@ sig_set(EditLine *el)
/* sig_clr():
* clear all the signal handlers
*/
protected void
libedit_private void
sig_clr(EditLine *el)
{
size_t i;

View File

@@ -1,4 +1,4 @@
/* $NetBSD: sig.h,v 1.8 2009/02/19 15:20:22 christos Exp $ */
/* $NetBSD: sig.h,v 1.11 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -42,8 +42,6 @@
#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
@@ -64,9 +62,9 @@ typedef struct {
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*);
libedit_private void sig_end(EditLine*);
libedit_private int sig_init(EditLine*);
libedit_private void sig_set(EditLine*);
libedit_private void sig_clr(EditLine*);
#endif /* _h_el_sig */

View File

@@ -1,74 +0,0 @@
/* $NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */
/* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.h"
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <assert.h>
#include <string.h>
#ifdef _LIBC
# ifdef __weak_alias
__weak_alias(strlcat, _strlcat)
# endif
#endif
#if !HAVE_STRLCAT
/*
* Appends src to string dst of size siz (unlike strncat, siz is the
* full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(src) + MIN(siz, strlen(initial dst)).
* If retval >= siz, truncation occurred.
*/
size_t
strlcat(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
size_t dlen;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
/* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0')
d++;
dlen = d - dst;
n = siz - dlen;
if (n == 0)
return(dlen + strlen(s));
while (*s != '\0') {
if (n != 1) {
*d++ = *s;
n--;
}
s++;
}
*d = '\0';
return(dlen + (s - src)); /* count does not include NUL */
}
#endif

View File

@@ -1,70 +0,0 @@
/* $NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */
/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include "config.h"
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <assert.h>
#include <string.h>
#ifdef _LIBC
# ifdef __weak_alias
__weak_alias(strlcpy, _strlcpy)
# endif
#endif
#if !HAVE_STRLCPY
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
size_t
strlcpy(char *dst, const char *src, size_t siz)
{
char *d = dst;
const char *s = src;
size_t n = siz;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
/* Copy as many bytes as will fit */
if (n != 0 && --n != 0) {
do {
if ((*d++ = *s++) == 0)
break;
} while (--n != 0);
}
/* Not enough room in dst, add NUL and traverse rest of src */
if (n == 0) {
if (siz != 0)
*d = '\0'; /* NUL-terminate dst */
while (*s++)
;
}
return(s - src - 1); /* count does not include NUL */
}
#endif

View File

@@ -1,4 +1,4 @@
/* $NetBSD: sys.h,v 1.13 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: sys.h,v 1.27 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -48,10 +48,6 @@
# define __attribute__(A)
#endif
#ifndef _DIAGASSERT
# define _DIAGASSERT(x)
#endif
#ifndef __BEGIN_DECLS
# ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
@@ -62,37 +58,13 @@
# 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
/* If your compiler does not support this, define it to be empty. */
#define libedit_private __attribute__((__visibility__("hidden")))
#ifndef __arraycount
# define __arraycount(a) (sizeof(a) / sizeof(*(a)))
#endif
#ifndef HAVE_U_INT32_T
typedef unsigned int u_int32_t;
#endif
#ifndef _PTR_T
# define _PTR_T
typedef void *ptr_t;
#endif
#ifndef _IOCTL_T
# define _IOCTL_T
typedef void *ioctl_t;
#endif
#include <stdio.h>
#ifndef HAVE_STRLCAT
@@ -105,48 +77,37 @@ size_t strlcat(char *dst, const char *src, size_t size);
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);
#ifndef HAVE_GETLINE
#define getline libedit_getline
ssize_t getline(char **line, size_t *len, FILE *fp);
#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 HAVE_SIZE_MAX
#define SIZE_MAX ((size_t)-1)
#endif
#define REGEX /* Use POSIX.2 regular expression functions */
#undef REGEXP /* Use UNIX V8 regular expression functions */
#ifdef notdef
# undef REGEX
# undef REGEXP
# include <malloc.h>
# ifdef __GNUC__
/*
* Broken hdrs.
*/
extern int tgetent(const char *bp, char *name);
extern int tgetflag(const char *id);
extern int tgetnum(const char *id);
extern char *tgetstr(const char *id, char **area);
extern char *tgoto(const char *cap, int col, int row);
extern int tputs(const char *str, int affcnt, int (*putc)(int));
extern char *getenv(const char *);
extern int fprintf(FILE *, const char *, ...);
extern int sigsetmask(int);
extern int sigblock(int);
extern int fputc(int, FILE *);
extern int fgetc(FILE *);
extern int fflush(FILE *);
extern int tolower(int);
extern int toupper(int);
extern int errno, sys_nerr;
extern char *sys_errlist[];
extern void perror(const char *);
# include <string.h>
# define strerror(e) sys_errlist[e]
# endif
# ifdef SABER
extern ptr_t memcpy(ptr_t, const ptr_t, size_t);
extern ptr_t memset(ptr_t, int, size_t);
# endif
extern char *fgetline(FILE *, int *);
#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 */

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,4 @@
/* $NetBSD: term.h,v 1.21 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: terminal.h,v 1.9 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,17 +37,15 @@
/*
* el.term.h: Termcap header
*/
#ifndef _h_el_term
#define _h_el_term
#include "histedit.h"
#ifndef _h_el_terminal
#define _h_el_terminal
typedef struct { /* Symbolic function key bindings */
const Char *name; /* name of the key */
const wchar_t *name; /* name of the key */
int key; /* Index in termcap table */
key_value_t fun; /* Function bound to it */
keymacro_value_t fun; /* Function bound to it */
int type; /* Type of function */
} fkey_t;
} funckey_t;
typedef struct {
const char *t_name; /* the terminal name */
@@ -63,12 +61,12 @@ typedef struct {
#define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */
#define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */
char *t_buf; /* Termcap buffer */
int t_loc; /* location used */
size_t t_loc; /* location used */
char **t_str; /* termcap strings */
int *t_val; /* termcap values */
char *t_cap; /* Termcap buffer */
fkey_t *t_fkey; /* Array of keys */
} el_term_t;
funckey_t *t_fkey; /* Array of keys */
} el_terminal_t;
/*
* fKey indexes
@@ -79,38 +77,40 @@ typedef struct {
#define A_K_RT 3
#define A_K_HO 4
#define A_K_EN 5
#define A_K_NKEYS 6
#define A_K_DE 6
#define A_K_NKEYS 7
protected void term_move_to_line(EditLine *, int);
protected void term_move_to_char(EditLine *, int);
protected void term_clear_EOL(EditLine *, int);
protected void term_overwrite(EditLine *, const Char *, size_t);
protected void term_insertwrite(EditLine *, Char *, int);
protected void term_deletechars(EditLine *, int);
protected void term_clear_screen(EditLine *);
protected void term_beep(EditLine *);
protected int term_change_size(EditLine *, int, int);
protected int term_get_size(EditLine *, int *, int *);
protected int term_init(EditLine *);
protected void term_bind_arrow(EditLine *);
protected void term_print_arrow(EditLine *, const Char *);
protected int term_clear_arrow(EditLine *, const Char *);
protected int term_set_arrow(EditLine *, const Char *, key_value_t *, int);
protected void term_end(EditLine *);
protected void term_get(EditLine *, const char **);
protected int term_set(EditLine *, const char *);
protected int term_settc(EditLine *, int, const Char **);
protected int term_gettc(EditLine *, int, char **);
protected int term_telltc(EditLine *, int, const Char **);
protected int term_echotc(EditLine *, int, const Char **);
protected void term_writec(EditLine *, Int);
protected int term__putc(EditLine *, Int);
protected void term__flush(EditLine *);
libedit_private void terminal_move_to_line(EditLine *, int);
libedit_private void terminal_move_to_char(EditLine *, int);
libedit_private void terminal_clear_EOL(EditLine *, int);
libedit_private void terminal_overwrite(EditLine *, const wchar_t *, size_t);
libedit_private void terminal_insertwrite(EditLine *, wchar_t *, int);
libedit_private void terminal_deletechars(EditLine *, int);
libedit_private void terminal_clear_screen(EditLine *);
libedit_private void terminal_beep(EditLine *);
libedit_private int terminal_change_size(EditLine *, int, int);
libedit_private int terminal_get_size(EditLine *, int *, int *);
libedit_private int terminal_init(EditLine *);
libedit_private void terminal_bind_arrow(EditLine *);
libedit_private void terminal_print_arrow(EditLine *, const wchar_t *);
libedit_private int terminal_clear_arrow(EditLine *, const wchar_t *);
libedit_private int terminal_set_arrow(EditLine *, const wchar_t *,
keymacro_value_t *, int);
libedit_private void terminal_end(EditLine *);
libedit_private void terminal_get(EditLine *, const char **);
libedit_private int terminal_set(EditLine *, const char *);
libedit_private int terminal_settc(EditLine *, int, const wchar_t **);
libedit_private int terminal_gettc(EditLine *, int, char **);
libedit_private int terminal_telltc(EditLine *, int, const wchar_t **);
libedit_private int terminal_echotc(EditLine *, int, const wchar_t **);
libedit_private void terminal_writec(EditLine *, wint_t);
libedit_private int terminal__putc(EditLine *, wint_t);
libedit_private void terminal__flush(EditLine *);
/*
* Easy access macros
*/
#define EL_FLAGS (el)->el_term.t_flags
#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)
@@ -122,4 +122,4 @@ protected void term__flush(EditLine *);
#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS)
#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS)
#endif /* _h_el_term */
#endif /* _h_el_terminal */

View File

@@ -1,4 +1,4 @@
/* $NetBSD: tokenizer.c,v 1.18 2010/01/03 18:27:10 christos Exp $ */
/* $NetBSD: tokenizer.c,v 1.28 2016/04/11 18:56:31 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -32,15 +32,12 @@
* 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.18 2010/01/03 18:27:10 christos Exp $");
__RCSID("$NetBSD: tokenizer.c,v 1.28 2016/04/11 18:56:31 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@@ -48,10 +45,10 @@ __RCSID("$NetBSD: tokenizer.c,v 1.18 2010/01/03 18:27:10 christos Exp $");
/*
* tokenize.c: Bourne shell like tokenizer
*/
#include <string.h>
#include <stdlib.h>
#include <string.h>
#include "histedit.h"
#include "chartype.h"
typedef enum {
Q_none, Q_single, Q_double, Q_one, Q_doubleone
@@ -68,12 +65,26 @@ typedef enum {
#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)
#ifdef NARROWCHAR
#define Char char
#define FUN(prefix, rest) prefix ## _ ## rest
#define TYPE(type) type
#define STR(x) x
#define Strchr(s, c) strchr(s, c)
#define tok_strdup(s) strdup(s)
#else
#define Char wchar_t
#define FUN(prefix, rest) prefix ## _w ## rest
#define TYPE(type) type ## W
#define STR(x) L ## x
#define Strchr(s, c) wcschr(s, c)
#define tok_strdup(s) wcsdup(s)
#endif
struct TYPE(tokenizer) {
Char *ifs; /* In field separator */
int argc, amax; /* Current and maximum number of args */
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 */
@@ -83,13 +94,13 @@ struct TYPE(tokenizer) {
};
private void FUN(tok,finish)(TYPE(Tokenizer) *);
static void FUN(tok,finish)(TYPE(Tokenizer) *);
/* FUN(tok,finish)():
* Finish a word in the tokenizer.
*/
private void
static void
FUN(tok,finish)(TYPE(Tokenizer) *tok)
{
@@ -106,32 +117,32 @@ FUN(tok,finish)(TYPE(Tokenizer) *tok)
/* FUN(tok,init)():
* Initialize the tokenizer
*/
public TYPE(Tokenizer) *
TYPE(Tokenizer) *
FUN(tok,init)(const Char *ifs)
{
TYPE(Tokenizer) *tok = tok_malloc(sizeof(TYPE(Tokenizer)));
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((ptr_t)tok);
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((ptr_t)tok->ifs);
tok_free((ptr_t)tok);
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((ptr_t)tok->argv);
tok_free((ptr_t)tok->ifs);
tok_free((ptr_t)tok);
tok_free(tok->argv);
tok_free(tok->ifs);
tok_free(tok);
return NULL;
}
tok->wmax = tok->wspace + WINCR;
@@ -140,14 +151,14 @@ FUN(tok,init)(const Char *ifs)
tok->flags = 0;
tok->quote = Q_none;
return (tok);
return tok;
}
/* FUN(tok,reset)():
* Reset the tokenizer
*/
public void
void
FUN(tok,reset)(TYPE(Tokenizer) *tok)
{
@@ -162,14 +173,14 @@ FUN(tok,reset)(TYPE(Tokenizer) *tok)
/* FUN(tok,end)():
* Clean up
*/
public void
void
FUN(tok,end)(TYPE(Tokenizer) *tok)
{
tok_free((ptr_t) tok->ifs);
tok_free((ptr_t) tok->wspace);
tok_free((ptr_t) tok->argv);
tok_free((ptr_t) tok);
tok_free(tok->ifs);
tok_free(tok->wspace);
tok_free(tok->argv);
tok_free(tok);
}
@@ -191,7 +202,7 @@ FUN(tok,end)(TYPE(Tokenizer) *tok)
* cursorc if !NULL, argv element containing cursor
* cursorv if !NULL, offset in argv[cursorc] of cursor
*/
public int
int
FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
int *argc, const Char ***argv, int *cursorc, int *cursoro)
{
@@ -204,7 +215,7 @@ FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
if (ptr >= line->lastchar)
ptr = STR("");
if (ptr == line->cursor) {
cc = tok->argc;
cc = (int)tok->argc;
co = (int)(tok->wptr - tok->wstart);
}
switch (*ptr) {
@@ -236,7 +247,7 @@ FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
break;
default:
return (-1);
return -1;
}
break;
@@ -267,7 +278,7 @@ FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
break;
default:
return (-1);
return -1;
}
break;
@@ -298,7 +309,7 @@ FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
break;
default:
return (-1);
return -1;
}
break;
@@ -324,7 +335,7 @@ FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
break;
default:
return (0);
return 0;
}
break;
@@ -334,15 +345,15 @@ FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
/* Finish word and return */
if (tok->flags & TOK_EAT) {
tok->flags &= ~TOK_EAT;
return (3);
return 3;
}
goto tok_line_outok;
case Q_single:
return (1);
return 1;
case Q_double:
return (2);
return 2;
case Q_doubleone:
tok->quote = Q_double;
@@ -355,7 +366,7 @@ FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
break;
default:
return (-1);
return -1;
}
break;
@@ -387,21 +398,21 @@ FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
break;
default:
return (-1);
return -1;
}
break;
}
if (tok->wptr >= tok->wmax - 4) {
size_t size = tok->wmax - tok->wspace + WINCR;
size_t size = (size_t)(tok->wmax - tok->wspace + WINCR);
Char *s = tok_realloc(tok->wspace,
size * sizeof(*s));
if (s == NULL)
return (-1);
return -1;
if (s != tok->wspace) {
int i;
size_t i;
for (i = 0; i < tok->argc; i++) {
tok->argv[i] =
(tok->argv[i] - tok->wspace) + s;
@@ -416,14 +427,16 @@ FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
Char **p;
tok->amax += AINCR;
p = tok_realloc(tok->argv, tok->amax * sizeof(*p));
if (p == NULL)
return (-1);
if (p == NULL) {
tok->amax -= AINCR;
return -1;
}
tok->argv = p;
}
}
tok_line_outok:
if (cc == -1 && co == -1) {
cc = tok->argc;
cc = (int)tok->argc;
co = (int)(tok->wptr - tok->wstart);
}
if (cursorc != NULL)
@@ -432,15 +445,15 @@ FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
*cursoro = co;
FUN(tok,finish)(tok);
*argv = (const Char **)tok->argv;
*argc = tok->argc;
return (0);
*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
int
FUN(tok,str)(TYPE(Tokenizer) *tok, const Char *line, int *argc,
const Char ***argv)
{
@@ -449,5 +462,5 @@ FUN(tok,str)(TYPE(Tokenizer) *tok, const Char *line, int *argc,
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));
return FUN(tok,line)(tok, &li, argc, argv, NULL, NULL);
}

View File

@@ -0,0 +1,3 @@
#include "config.h"
#define NARROWCHAR
#include "tokenizer.c"

View File

@@ -1,4 +1,4 @@
/* $NetBSD: tty.c,v 1.35 2011/01/28 03:41:52 christos Exp $ */
/* $NetBSD: tty.c,v 1.65 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: tty.c,v 1.35 2011/01/28 03:41:52 christos Exp $");
__RCSID("$NetBSD: tty.c,v 1.65 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@@ -46,10 +46,14 @@ __RCSID("$NetBSD: tty.c,v 1.35 2011/01/28 03:41:52 christos Exp $");
*/
#include <assert.h>
#include <errno.h>
#include <unistd.h> /* for isatty */
#include <stdlib.h> /* for abort */
#include <string.h>
#include <strings.h> /* for ffs */
#include <unistd.h> /* for isatty */
#include "el.h"
#include "tty.h"
#include "fcns.h"
#include "parse.h"
typedef struct ttymodes_t {
const char *m_name;
@@ -58,12 +62,12 @@ typedef struct ttymodes_t {
} ttymodes_t;
typedef struct ttymap_t {
Int nch, och; /* Internal and termio rep of chars */
wint_t nch, och; /* Internal and termio rep of chars */
el_action_t bind[3]; /* emacs, vi, and vi-cmd */
} ttymap_t;
private const ttyperm_t ttyperm = {
static const ttyperm_t ttyperm = {
{
{"iflag:", ICRNL, (INLCR | IGNCR)},
{"oflag:", (OPOST | ONLCR), ONLRET},
@@ -91,7 +95,7 @@ private const ttyperm_t ttyperm = {
}
};
private const ttychar_t ttychar = {
static const ttychar_t ttychar = {
{
CINTR, CQUIT, CERASE, CKILL,
CEOF, CEOL, CEOL2, CSWTCH,
@@ -121,7 +125,7 @@ private const ttychar_t ttychar = {
}
};
private const ttymap_t tty_map[] = {
static const ttymap_t tty_map[] = {
#ifdef VERASE
{C_ERASE, VERASE,
{EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
@@ -154,11 +158,11 @@ private const ttymap_t tty_map[] = {
{C_LNEXT, VLNEXT,
{ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}},
#endif /* VLNEXT */
{-1, -1,
{(wint_t)-1, (wint_t)-1,
{ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}}
};
private const ttymodes_t ttymodes[] = {
static const ttymodes_t ttymodes[] = {
#ifdef IGNBRK
{"ignbrk", IGNBRK, MD_INP},
#endif /* IGNBRK */
@@ -452,20 +456,21 @@ private const ttymodes_t ttymodes[] = {
#define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
#define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
private int tty_getty(EditLine *, struct termios *);
private int tty_setty(EditLine *, int, const struct termios *);
private int tty__getcharindex(int);
private void tty__getchar(struct termios *, unsigned char *);
private void tty__setchar(struct termios *, unsigned char *);
private speed_t tty__getspeed(struct termios *);
private int tty_setup(EditLine *);
static int tty_getty(EditLine *, struct termios *);
static int tty_setty(EditLine *, int, const struct termios *);
static int tty__getcharindex(int);
static void tty__getchar(struct termios *, unsigned char *);
static void tty__setchar(struct termios *, unsigned char *);
static speed_t tty__getspeed(struct termios *);
static int tty_setup(EditLine *);
static void tty_setup_flags(EditLine *, struct termios *, int);
#define t_qu t_ts
/* tty_getty():
* Wrapper for tcgetattr to handle EINTR
*/
private int
static int
tty_getty(EditLine *el, struct termios *t)
{
int rv;
@@ -477,7 +482,7 @@ tty_getty(EditLine *el, struct termios *t)
/* tty_setty():
* Wrapper for tcsetattr to handle EINTR
*/
private int
static int
tty_setty(EditLine *el, int action, const struct termios *t)
{
int rv;
@@ -489,45 +494,38 @@ tty_setty(EditLine *el, int action, const struct termios *t)
/* tty_setup():
* Get the tty parameters and initialize the editing state
*/
private int
static int
tty_setup(EditLine *el)
{
int rst = 1;
if (el->el_flags & EDIT_DISABLED)
return (0);
return 0;
if (el->el_tty.t_initialized)
return -1;
if (!isatty(el->el_outfd)) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_setup: isatty: %s\n", strerror(errno));
(void) fprintf(el->el_errfile, "%s: isatty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
if (tty_getty(el, &el->el_tty.t_ed) == -1) {
if (tty_getty(el, &el->el_tty.t_or) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_setup: tty_getty: %s\n", strerror(errno));
(void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed = el->el_tty.t_or;
el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex);
el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex);
el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex);
el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
tty_setup_flags(el, &el->el_tty.t_ex, EX_IO);
/*
* Reset the tty chars to reasonable defaults
@@ -555,76 +553,73 @@ tty_setup(EditLine *el)
tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_setup: tty_setty: %s\n",
strerror(errno));
(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n",
__func__, strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
}
#ifdef notdef
else
tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
#endif
el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
tty_setup_flags(el, &el->el_tty.t_ed, ED_IO);
tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
tty_bind_char(el, 1);
return (0);
el->el_tty.t_initialized = 1;
return 0;
}
protected int
libedit_private int
tty_init(EditLine *el)
{
el->el_tty.t_mode = EX_IO;
el->el_tty.t_vdisable = _POSIX_VDISABLE;
el->el_tty.t_initialized = 0;
(void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
(void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
return (tty_setup(el));
return tty_setup(el);
}
/* tty_end():
* Restore the tty to its original settings
*/
protected void
libedit_private void
/*ARGSUSED*/
tty_end(EditLine *el __attribute__((__unused__)))
tty_end(EditLine *el)
{
if (el->el_flags & EDIT_DISABLED)
return;
/* XXX: Maybe reset to an initial state? */
if (!el->el_tty.t_initialized)
return;
if (tty_setty(el, TCSAFLUSH, &el->el_tty.t_or) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"%s: tty_setty: %s\n", __func__, strerror(errno));
#endif /* DEBUG_TTY */
}
}
/* tty__getspeed():
* Get the tty speed
*/
private speed_t
static speed_t
tty__getspeed(struct termios *td)
{
speed_t spd;
if ((spd = cfgetispeed(td)) == 0)
spd = cfgetospeed(td);
return (spd);
return spd;
}
/* tty__getspeed():
* Return the index of the asked char in the c_cc array
*/
private int
static int
tty__getcharindex(int i)
{
switch (i) {
@@ -732,7 +727,7 @@ tty__getcharindex(int i)
/* tty__getchar():
* Get the tty characters
*/
private void
static void
tty__getchar(struct termios *td, unsigned char *s)
{
@@ -814,7 +809,7 @@ tty__getchar(struct termios *td, unsigned char *s)
/* tty__setchar():
* Set the tty characters
*/
private void
static void
tty__setchar(struct termios *td, unsigned char *s)
{
@@ -896,13 +891,13 @@ tty__setchar(struct termios *td, unsigned char *s)
/* tty_bind_char():
* Rebind the editline functions
*/
protected void
libedit_private void
tty_bind_char(EditLine *el, int force)
{
unsigned char *t_n = el->el_tty.t_c[ED_IO];
unsigned char *t_o = el->el_tty.t_ed.c_cc;
Char new[2], old[2];
wchar_t new[2], old[2];
const ttymap_t *tp;
el_action_t *map, *alt;
const el_action_t *dmap, *dalt;
@@ -918,46 +913,100 @@ tty_bind_char(EditLine *el, int force)
dalt = NULL;
}
for (tp = tty_map; tp->nch != -1; tp++) {
new[0] = t_n[tp->nch];
old[0] = t_o[tp->och];
for (tp = tty_map; tp->nch != (wint_t)-1; tp++) {
new[0] = (wchar_t)t_n[tp->nch];
old[0] = (wchar_t)t_o[tp->och];
if (new[0] == old[0] && !force)
continue;
/* Put the old default binding back, and set the new binding */
key_clear(el, map, old);
map[UC(old[0])] = dmap[UC(old[0])];
key_clear(el, map, new);
keymacro_clear(el, map, old);
map[(unsigned char)old[0]] = dmap[(unsigned char)old[0]];
keymacro_clear(el, map, new);
/* MAP_VI == 1, MAP_EMACS == 0... */
map[UC(new[0])] = tp->bind[el->el_map.type];
map[(unsigned char)new[0]] = tp->bind[el->el_map.type];
if (dalt) {
key_clear(el, alt, old);
alt[UC(old[0])] = dalt[UC(old[0])];
key_clear(el, alt, new);
alt[UC(new[0])] = tp->bind[el->el_map.type + 1];
keymacro_clear(el, alt, old);
alt[(unsigned char)old[0]] =
dalt[(unsigned char)old[0]];
keymacro_clear(el, alt, new);
alt[(unsigned char)new[0]] =
tp->bind[el->el_map.type + 1];
}
}
}
static tcflag_t *
tty__get_flag(struct termios *t, int kind) {
switch (kind) {
case MD_INP:
return &t->c_iflag;
case MD_OUT:
return &t->c_oflag;
case MD_CTL:
return &t->c_cflag;
case MD_LIN:
return &t->c_lflag;
default:
abort();
/*NOTREACHED*/
}
}
static tcflag_t
tty_update_flag(EditLine *el, tcflag_t f, int mode, int kind)
{
f &= ~el->el_tty.t_t[mode][kind].t_clrmask;
f |= el->el_tty.t_t[mode][kind].t_setmask;
return f;
}
static void
tty_update_flags(EditLine *el, int kind)
{
tcflag_t *tt, *ed, *ex;
tt = tty__get_flag(&el->el_tty.t_ts, kind);
ed = tty__get_flag(&el->el_tty.t_ed, kind);
ex = tty__get_flag(&el->el_tty.t_ex, kind);
if (*tt != *ex && (kind != MD_CTL || *tt != *ed)) {
*ed = tty_update_flag(el, *tt, ED_IO, kind);
*ex = tty_update_flag(el, *tt, EX_IO, kind);
}
}
static void
tty_update_char(EditLine *el, int mode, int c) {
if (!((el->el_tty.t_t[mode][MD_CHAR].t_setmask & C_SH(c)))
&& (el->el_tty.t_c[TS_IO][c] != el->el_tty.t_c[EX_IO][c]))
el->el_tty.t_c[mode][c] = el->el_tty.t_c[TS_IO][c];
if (el->el_tty.t_t[mode][MD_CHAR].t_clrmask & C_SH(c))
el->el_tty.t_c[mode][c] = el->el_tty.t_vdisable;
}
/* tty_rawmode():
* Set terminal into 1 character at a time mode.
* Set terminal into 1 character at a time mode.
*/
protected int
libedit_private int
tty_rawmode(EditLine *el)
{
if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
return (0);
return 0;
if (el->el_flags & EDIT_DISABLED)
return (0);
return 0;
if (tty_getty(el, &el->el_tty.t_ts) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n",
(void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
/*
* We always keep up with the eight bit setting and the speed of the
@@ -974,225 +1023,145 @@ tty_rawmode(EditLine *el)
(void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed);
}
if (tty__cooked_mode(&el->el_tty.t_ts)) {
if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) {
el->el_tty.t_ex.c_cflag =
el->el_tty.t_ts.c_cflag;
el->el_tty.t_ex.c_cflag &=
~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask;
el->el_tty.t_ex.c_cflag |=
el->el_tty.t_t[EX_IO][MD_CTL].t_setmask;
int i;
el->el_tty.t_ed.c_cflag =
el->el_tty.t_ts.c_cflag;
el->el_tty.t_ed.c_cflag &=
~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask;
el->el_tty.t_ed.c_cflag |=
el->el_tty.t_t[ED_IO][MD_CTL].t_setmask;
}
if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) &&
(el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) {
el->el_tty.t_ex.c_lflag =
el->el_tty.t_ts.c_lflag;
el->el_tty.t_ex.c_lflag &=
~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask;
el->el_tty.t_ex.c_lflag |=
el->el_tty.t_t[EX_IO][MD_LIN].t_setmask;
for (i = MD_INP; i <= MD_LIN; i++)
tty_update_flags(el, i);
el->el_tty.t_ed.c_lflag =
el->el_tty.t_ts.c_lflag;
el->el_tty.t_ed.c_lflag &=
~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask;
el->el_tty.t_ed.c_lflag |=
el->el_tty.t_t[ED_IO][MD_LIN].t_setmask;
}
if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) &&
(el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) {
el->el_tty.t_ex.c_iflag =
el->el_tty.t_ts.c_iflag;
el->el_tty.t_ex.c_iflag &=
~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask;
el->el_tty.t_ex.c_iflag |=
el->el_tty.t_t[EX_IO][MD_INP].t_setmask;
el->el_tty.t_ed.c_iflag =
el->el_tty.t_ts.c_iflag;
el->el_tty.t_ed.c_iflag &=
~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
el->el_tty.t_ed.c_iflag |=
el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
}
if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) &&
(el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) {
el->el_tty.t_ex.c_oflag =
el->el_tty.t_ts.c_oflag;
el->el_tty.t_ex.c_oflag &=
~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask;
el->el_tty.t_ex.c_oflag |=
el->el_tty.t_t[EX_IO][MD_OUT].t_setmask;
el->el_tty.t_ed.c_oflag =
el->el_tty.t_ts.c_oflag;
el->el_tty.t_ed.c_oflag &=
~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask;
el->el_tty.t_ed.c_oflag |=
el->el_tty.t_t[ED_IO][MD_OUT].t_setmask;
}
if (tty__gettabs(&el->el_tty.t_ex) == 0)
el->el_tty.t_tabs = 0;
else
el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0;
{
int i;
tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
/*
* Check if the user made any changes.
* If he did, then propagate the changes to the
* edit and execute data structures.
*/
for (i = 0; i < C_NCC; i++)
if (el->el_tty.t_c[TS_IO][i] !=
el->el_tty.t_c[EX_IO][i])
break;
tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]);
if (i != C_NCC) {
/*
* Check if the user made any changes.
* If he did, then propagate the changes to the
* edit and execute data structures.
*/
* Propagate changes only to the unlibedit_private
* chars that have been modified just now.
*/
for (i = 0; i < C_NCC; i++)
if (el->el_tty.t_c[TS_IO][i] !=
el->el_tty.t_c[EX_IO][i])
break;
tty_update_char(el, ED_IO, i);
if (i != C_NCC) {
/*
* Propagate changes only to the unprotected
* chars that have been modified just now.
*/
for (i = 0; i < C_NCC; i++) {
if (!((el->el_tty.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i)))
&& (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i];
if (el->el_tty.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i))
el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable;
}
tty_bind_char(el, 0);
tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
tty_bind_char(el, 0);
tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
for (i = 0; i < C_NCC; i++) {
if (!((el->el_tty.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i)))
&& (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]))
el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i];
if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i))
el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable;
}
tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
}
for (i = 0; i < C_NCC; i++)
tty_update_char(el, EX_IO, i);
tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
}
}
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
el->el_tty.t_mode = ED_IO;
return (0);
return 0;
}
/* tty_cookedmode():
* Set the tty back to normal mode
*/
protected int
libedit_private int
tty_cookedmode(EditLine *el)
{ /* set tty in normal setup */
if (el->el_tty.t_mode == EX_IO)
return (0);
return 0;
if (el->el_flags & EDIT_DISABLED)
return (0);
return 0;
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_cookedmode: tty_setty: %s\n",
(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
el->el_tty.t_mode = EX_IO;
return (0);
return 0;
}
/* tty_quotemode():
* Turn on quote mode
*/
protected int
libedit_private int
tty_quotemode(EditLine *el)
{
if (el->el_tty.t_mode == QU_IO)
return (0);
return 0;
el->el_tty.t_qu = el->el_tty.t_ed;
el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask;
el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask;
el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask;
el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask;
el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask;
el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask;
el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask;
el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask;
tty_setup_flags(el, &el->el_tty.t_qu, QU_IO);
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
el->el_tty.t_mode = QU_IO;
return (0);
return 0;
}
/* tty_noquotemode():
* Turn off quote mode
*/
protected int
libedit_private int
tty_noquotemode(EditLine *el)
{
if (el->el_tty.t_mode != QU_IO)
return (0);
return 0;
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__,
strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
el->el_tty.t_mode = ED_IO;
return (0);
return 0;
}
/* tty_stty():
* Stty builtin
*/
protected int
libedit_private int
/*ARGSUSED*/
tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
tty_stty(EditLine *el, int argc __attribute__((__unused__)),
const wchar_t **argv)
{
const ttymodes_t *m;
char x;
int aflag = 0;
const Char *s, *d;
const wchar_t *s, *d;
char name[EL_BUFSIZ];
struct termios *tios = &el->el_tty.t_ex;
int z = EX_IO;
if (argv == NULL)
return (-1);
return -1;
strncpy(name, ct_encode_string(*argv++, &el->el_scratch), sizeof(name));
name[sizeof(name) - 1] = '\0';
@@ -1219,9 +1188,9 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
break;
default:
(void) fprintf(el->el_errfile,
"%s: Unknown switch `%c'.\n",
name, argv[0][1]);
return (-1);
"%s: Unknown switch `%lc'.\n",
name, (wint_t)argv[0][1]);
return -1;
}
if (!argv || !*argv) {
@@ -1239,8 +1208,9 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
if (i != -1) {
x = (el->el_tty.t_t[z][i].t_setmask & m->m_value)
? '+' : '\0';
x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
? '-' : x;
if (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
x = '-';
} else {
x = '\0';
}
@@ -1249,7 +1219,8 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
cu = strlen(m->m_name) + (x != '\0') + 1;
if (len + cu >= (size_t)el->el_term.t_size.h) {
if (len + cu >=
(size_t)el->el_terminal.t_size.h) {
(void) fprintf(el->el_outfile, "\n%*s",
(int)st, "");
len = st + cu;
@@ -1265,31 +1236,33 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
}
}
(void) fprintf(el->el_outfile, "\n");
return (0);
return 0;
}
while (argv && (s = *argv++)) {
const Char *p;
const wchar_t *p;
switch (*s) {
case '+':
case '-':
x = *s++;
x = (char)*s++;
break;
default:
x = '\0';
break;
}
d = s;
p = Strchr(s, '=');
p = wcschr(s, L'=');
for (m = ttymodes; m->m_name; m++)
if ((p ? strncmp(m->m_name, ct_encode_string(d, &el->el_scratch), (size_t)(p - d)) :
strcmp(m->m_name, ct_encode_string(d, &el->el_scratch))) == 0 &&
if ((p ? strncmp(m->m_name, ct_encode_string(d,
&el->el_scratch), (size_t)(p - d)) :
strcmp(m->m_name, ct_encode_string(d,
&el->el_scratch))) == 0 &&
(p == NULL || m->m_type == MD_CHAR))
break;
if (!m->m_name) {
(void) fprintf(el->el_errfile,
"%s: Invalid argument `" FSTR "'.\n", name, d);
return (-1);
"%s: Invalid argument `%ls'.\n", name, d);
return -1;
}
if (p) {
int c = ffs((int)m->m_value);
@@ -1299,7 +1272,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
c--;
c = tty__getcharindex(c);
assert(c != -1);
tios->c_cc[c] = v;
tios->c_cc[c] = (cc_t)v;
continue;
}
switch (x) {
@@ -1318,17 +1291,18 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
}
}
tty_setup_flags(el, tios, z);
if (el->el_tty.t_mode == z) {
if (tty_setty(el, TCSADRAIN, tios) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_stty: tty_setty: %s\n", strerror(errno));
(void) fprintf(el->el_errfile, "%s: tty_setty: %s\n",
__func__, strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
return -1;
}
}
return (0);
return 0;
}
@@ -1336,7 +1310,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
/* tty_printchar():
* DEbugging routine to print the tty characters
*/
private void
static void
tty_printchar(EditLine *el, unsigned char *s)
{
ttyperm_t *m;
@@ -1355,3 +1329,14 @@ tty_printchar(EditLine *el, unsigned char *s)
(void) fprintf(el->el_errfile, "\n");
}
#endif /* notyet */
static void
tty_setup_flags(EditLine *el, struct termios *tios, int mode)
{
int kind;
for (kind = MD_INP; kind <= MD_LIN; kind++) {
tcflag_t *f = tty__get_flag(tios, kind);
*f = tty_update_flag(el, *f, mode, kind);
}
}

View File

@@ -1,4 +1,4 @@
/* $NetBSD: tty.h,v 1.12 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: tty.h,v 1.21 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@@ -40,8 +40,6 @@
#ifndef _h_el_tty
#define _h_el_tty
#include "sys.h"
#include "histedit.h"
#include <termios.h>
#include <unistd.h>
@@ -431,7 +429,7 @@
#define C_MIN 23
#define C_TIME 24
#define C_NCC 25
#define C_SH(A) (1 << (A))
#define C_SH(A) ((unsigned int)(1 << (A)))
/*
* Terminal dependend data structures
@@ -442,6 +440,7 @@
#define QU_IO 2 /* used only for quoted chars */
#define NN_IO 3 /* The number of entries */
/* Don't re-order */
#define MD_INP 0
#define MD_OUT 1
#define MD_CTL 2
@@ -457,24 +456,25 @@ typedef struct {
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);
libedit_private int tty_init(EditLine *);
libedit_private void tty_end(EditLine *);
libedit_private int tty_stty(EditLine *, int, const wchar_t **);
libedit_private int tty_rawmode(EditLine *);
libedit_private int tty_cookedmode(EditLine *);
libedit_private int tty_quotemode(EditLine *);
libedit_private int tty_noquotemode(EditLine *);
libedit_private void tty_bind_char(EditLine *, int);
typedef struct {
ttyperm_t t_t;
ttychar_t t_c;
struct termios t_ex, t_ed, t_ts;
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_mode;
unsigned char t_vdisable;
unsigned char t_initialized;
} el_tty_t;

File diff suppressed because it is too large Load Diff