From 77ff7185d730bf489848302fd51e0090701dde35 Mon Sep 17 00:00:00 2001 From: Viktor Dukhovni Date: Sun, 13 Nov 2016 15:49:16 +1100 Subject: [PATCH] Updated libedit to NetBSD upstream Note: This unconditionally assumes wchar_t support. May need revision if some platforms prove problematic. --- .gitignore | 40 +- lib/libedit/acinclude.m4 | 19 - lib/libedit/config.h.in | 81 +- lib/libedit/configure.ac | 18 +- lib/libedit/src/Makefile.am | 46 +- lib/libedit/src/chared.c | 295 +++--- lib/libedit/src/chared.h | 96 +- lib/libedit/src/chartype.c | 270 +++--- lib/libedit/src/chartype.h | 169 +--- lib/libedit/src/common.c | 408 ++++----- lib/libedit/src/editline.3 | 997 ++++++++++++++++++++ lib/libedit/src/editline.7 | 935 +++++++++++++++++++ lib/libedit/src/editrc.5 | 317 +++++++ lib/libedit/src/el.c | 266 +++--- lib/libedit/src/el.h | 50 +- lib/libedit/src/eln.c | 143 +-- lib/libedit/src/emacs.c | 196 ++-- lib/libedit/src/fgetln.c | 107 --- lib/libedit/src/filecomplete.c | 196 ++-- lib/libedit/src/filecomplete.h | 4 +- lib/libedit/src/hist.c | 106 ++- lib/libedit/src/hist.h | 38 +- lib/libedit/src/histedit.h | 28 +- lib/libedit/src/history.c | 438 +++++---- lib/libedit/src/historyn.c | 3 + lib/libedit/src/{key.c => keymacro.c} | 384 ++++---- lib/libedit/src/{key.h => keymacro.h} | 60 +- lib/libedit/src/makelist | 112 +-- lib/libedit/src/map.c | 320 +++---- lib/libedit/src/map.h | 28 +- lib/libedit/src/parse.c | 164 ++-- lib/libedit/src/parse.h | 10 +- lib/libedit/src/prompt.c | 38 +- lib/libedit/src/prompt.h | 18 +- lib/libedit/src/read.c | 568 +++++------- lib/libedit/src/read.h | 19 +- lib/libedit/src/readline.c | 657 ++++++++------ lib/libedit/src/{editline => readline}/readline.h | 34 +- lib/libedit/src/refresh.c | 312 +++---- lib/libedit/src/refresh.h | 18 +- lib/libedit/src/search.c | 176 ++-- lib/libedit/src/search.h | 28 +- lib/libedit/src/shlib_version | 4 +- lib/libedit/src/sig.c | 33 +- lib/libedit/src/sig.h | 12 +- lib/libedit/src/strlcat.c | 74 -- lib/libedit/src/strlcpy.c | 70 -- lib/libedit/src/sys.h | 97 +- lib/libedit/src/{term.c => terminal.c} | 1003 ++++++++++----------- lib/libedit/src/{el_term.h => terminal.h} | 78 +- lib/libedit/src/tokenizer.c | 107 ++- lib/libedit/src/tokenizern.c | 3 + lib/libedit/src/tty.c | 469 +++++----- lib/libedit/src/tty.h | 28 +- lib/libedit/src/vi.c | 453 +++++----- 55 files changed, 6110 insertions(+), 4533 deletions(-) create mode 100644 lib/libedit/src/editline.3 create mode 100644 lib/libedit/src/editline.7 create mode 100644 lib/libedit/src/editrc.5 delete mode 100644 lib/libedit/src/fgetln.c create mode 100644 lib/libedit/src/historyn.c rename lib/libedit/src/{key.c => keymacro.c} (57%) rename lib/libedit/src/{key.h => keymacro.h} (58%) rename lib/libedit/src/{editline => readline}/readline.h (87%) delete mode 100644 lib/libedit/src/strlcat.c delete mode 100644 lib/libedit/src/strlcpy.c rename lib/libedit/src/{term.c => terminal.c} (61%) rename lib/libedit/src/{el_term.h => terminal.h} (62%) create mode 100644 lib/libedit/src/tokenizern.c diff --git a/.gitignore b/.gitignore index 73678830d..e74cd3a45 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/lib/libedit/acinclude.m4 b/lib/libedit/acinclude.m4 index 4a581894b..51b4ddb2c 100644 --- a/lib/libedit/acinclude.m4 +++ b/lib/libedit/acinclude.m4 @@ -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]) -]) - diff --git a/lib/libedit/config.h.in b/lib/libedit/config.h.in index 7daece669..06db50685 100644 --- a/lib/libedit/config.h.in +++ b/lib/libedit/config.h.in @@ -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 and it should be used (not on Ultrix). - */ -#undef HAVE_ALLOCA_H - /* Define to 1 if you have the header file. */ #undef HAVE_CURSES_H @@ -28,15 +10,15 @@ /* Define to 1 if you have the 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 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 header file. */ #undef HAVE_LIMITS_H -/* Define to 1 if you have the 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 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 header file. */ #undef HAVE_NCURSES_H /* Define to 1 if you have the 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 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 header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the 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 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 diff --git a/lib/libedit/configure.ac b/lib/libedit/configure.ac index 5e164b57b..e9ea85268 100644 --- a/lib/libedit/configure.ac +++ b/lib/libedit/configure.ac @@ -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 +#endif +]) AH_BOTTOM([ #include "sys.h" diff --git a/lib/libedit/src/Makefile.am b/lib/libedit/src/Makefile.am index 47e8a5026..027321ab3 100644 --- a/lib/libedit/src/Makefile.am +++ b/lib/libedit/src/Makefile.am @@ -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 diff --git a/lib/libedit/src/chared.c b/lib/libedit/src/chared.c index ec600a7bd..9d46ba68f 100644 --- a/lib/libedit/src/chared.c +++ b/lib/libedit/src/chared.c @@ -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 #include -#include "el.h" +#include -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; +} diff --git a/lib/libedit/src/chared.h b/lib/libedit/src/chared.h index 176475ac8..39f7d5173 100644 --- a/lib/libedit/src/chared.h +++ b/lib/libedit/src/chared.h @@ -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 -#include - -#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" - - -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 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 *); + +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 */ diff --git a/lib/libedit/src/chartype.c b/lib/libedit/src/chartype.c index a0adde6f6..f350dfd2d 100644 --- a/lib/libedit/src/chartype.c +++ b/lib/libedit/src/chartype.c @@ -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 #include +#include + +#include "el.h" -#define CT_BUFSIZ 1024 +#define CT_BUFSIZ ((size_t)1024) -#ifdef WIDECHAR -protected void -ct_conv_buff_resize(ct_buffer_t *conv, size_t mincsize, size_t minwsize) +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 (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; +} - 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; +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) - return NULL; - len = ct_mbstowcs(0, s, 0); - if (len > conv->wsize) - ct_conv_buff_resize(conv, 0, len + 1); - if (!conv->wbuff) + len = mbstowcs(NULL, s, (size_t)0); + if (len == (size_t)-1) 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; diff --git a/lib/libedit/src/chartype.h b/lib/libedit/src/chartype.h index df65b02c0..7f4b8d9d6 100644 --- a/lib/libedit/src/chartype.h +++ b/lib/libedit/src/chartype.h @@ -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 *); - -/* 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 +libedit_private wchar_t **ct_decode_argv(int, const char *[], ct_buffer_t *); -#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 */ diff --git a/lib/libedit/src/common.c b/lib/libedit/src/common.c index c4d21aa93..270860510 100644 --- a/lib/libedit/src/common.c +++ b/lib/libedit/src/common.c @@ -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 +#include + #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 -/*ARGSUSED*/ -ed_unassigned(EditLine *el, Int c __attribute__((__unused__))) -{ - - return (CC_ERROR); -} - - -/** - ** TTY key handling. - **/ - -/* ed_tty_sigint(): - * Tty interrupt character - * [^C] - */ -protected el_action_t -/*ARGSUSED*/ -ed_tty_sigint(EditLine *el __attribute__((__unused__)), - Int c __attribute__((__unused__))) -{ - - return (CC_NORM); -} - - -/* ed_tty_dsusp(): - * Tty delayed suspend character - * [^Y] - */ -protected el_action_t -/*ARGSUSED*/ -ed_tty_dsusp(EditLine *el __attribute__((__unused__)), - Int c __attribute__((__unused__))) -{ - - return (CC_NORM); -} - - -/* ed_tty_flush_output(): - * Tty flush output characters - * [^O] - */ -protected el_action_t -/*ARGSUSED*/ -ed_tty_flush_output(EditLine *el __attribute__((__unused__)), - Int c __attribute__((__unused__))) -{ - - return (CC_NORM); -} - - -/* ed_tty_sigquit(): - * Tty quit character - * [^\] - */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -ed_tty_sigquit(EditLine *el __attribute__((__unused__)), - Int c __attribute__((__unused__))) +ed_unassigned(EditLine *el __attribute__((__unused__)), + wint_t c __attribute__((__unused__))) { - return (CC_NORM); + return CC_ERROR; } -/* ed_tty_sigtstp(): - * Tty suspend character - * [^Z] +/* 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_sigtstp(EditLine *el __attribute__((__unused__)), - Int c __attribute__((__unused__))) +ed_ignore(EditLine *el __attribute__((__unused__)), + wint_t 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); diff --git a/lib/libedit/src/editline.3 b/lib/libedit/src/editline.3 new file mode 100644 index 000000000..bb5797220 --- /dev/null +++ b/lib/libedit/src/editline.3 @@ -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. diff --git a/lib/libedit/src/editline.7 b/lib/libedit/src/editline.7 new file mode 100644 index 000000000..863bab96d --- /dev/null +++ b/lib/libedit/src/editline.7 @@ -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 +.\" +.\" 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 . diff --git a/lib/libedit/src/editrc.5 b/lib/libedit/src/editrc.5 new file mode 100644 index 000000000..723cb9e71 --- /dev/null +++ b/lib/libedit/src/editrc.5 @@ -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 . diff --git a/lib/libedit/src/el.c b/lib/libedit/src/el.c index 168734cec..acde92942 100644 --- a/lib/libedit/src/el.c +++ b/lib/libedit/src/el.c @@ -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 #include -#include -#include -#include #include -#include #include +#include +#include +#include +#include + #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) { +#ifdef HAVE_ISSETUGID static const char elpath[] = "/.editrc"; + size_t plen = sizeof(elpath); -#ifdef HAVE_ISSETUGID 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; } diff --git a/lib/libedit/src/el.h b/lib/libedit/src/el.h index da07b3061..c281bc01b 100644 --- a/lib/libedit/src/el.h +++ b/lib/libedit/src/el.h @@ -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 -#include -#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 { \ diff --git a/lib/libedit/src/eln.c b/lib/libedit/src/eln.c index 04e992fba..aa0a5b565 100644 --- a/lib/libedit/src/eln.c +++ b/lib/libedit/src/eln.c @@ -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 #include #include #include -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); diff --git a/lib/libedit/src/emacs.c b/lib/libedit/src/emacs.c index 8fb6f4b50..0636c28b2 100644 --- a/lib/libedit/src/emacs.c +++ b/lib/libedit/src/emacs.c @@ -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 + #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 * [] */ -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; } diff --git a/lib/libedit/src/fgetln.c b/lib/libedit/src/fgetln.c deleted file mode 100644 index ea91a187d..000000000 --- a/lib/libedit/src/fgetln.c +++ /dev/null @@ -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 -#ifndef HAVE_NBTOOL_CONFIG_H -/* These headers are required, but included from nbtool_config.h */ -#include -#include -#include -#include -#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 diff --git a/lib/libedit/src/filecomplete.c b/lib/libedit/src/filecomplete.c index da13eff68..d1051f087 100644 --- a/lib/libedit/src/filecomplete.c +++ b/lib/libedit/src/filecomplete.c @@ -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 -# 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 #include -#include #include -#include +#include +#include +#include #include -#include +#include #include +#include #include -#include -#include -#include -#include #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); } diff --git a/lib/libedit/src/filecomplete.h b/lib/libedit/src/filecomplete.h index 971e6e059..7e93b9e36 100644 --- a/lib/libedit/src/filecomplete.h +++ b/lib/libedit/src/filecomplete.h @@ -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); diff --git a/lib/libedit/src/hist.c b/lib/libedit/src/hist.c index e12bfb9b9..4f01ade24 100644 --- a/lib/libedit/src/hist.c +++ b/lib/libedit/src/hist.c @@ -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 +#include +#include + #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 diff --git a/lib/libedit/src/hist.h b/lib/libedit/src/hist.h index 8c3af40bf..c58c5bfed 100644 --- a/lib/libedit/src/hist.h +++ b/lib/libedit/src/hist.h @@ -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 */ diff --git a/lib/libedit/src/histedit.h b/lib/libedit/src/histedit.h index bc95eaa64..9ea71899d 100644 --- a/lib/libedit/src/histedit.h +++ b/lib/libedit/src/histedit.h @@ -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 -#endif - #include #include @@ -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,21 +249,10 @@ 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 #include /* - * Wide character versions - */ - -/* * ==== Editing ==== */ typedef struct lineinfow { @@ -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 diff --git a/lib/libedit/src/history.c b/lib/libedit/src/history.c index 3ec16a77b..41d1014ca 100644 --- a/lib/libedit/src/history.c +++ b/lib/libedit/src/history.c @@ -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 -#include +#include #include +#include +#include #include -#include 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); diff --git a/lib/libedit/src/historyn.c b/lib/libedit/src/historyn.c new file mode 100644 index 000000000..59130dea3 --- /dev/null +++ b/lib/libedit/src/historyn.c @@ -0,0 +1,3 @@ +#include "config.h" +#define NARROWCHAR +#include "history.c" diff --git a/lib/libedit/src/key.c b/lib/libedit/src/keymacro.c similarity index 57% rename from lib/libedit/src/key.c rename to lib/libedit/src/keymacro.c index daf679fd5..13d208930 100644 --- a/lib/libedit/src/key.c +++ b/lib/libedit/src/keymacro.c @@ -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 #include +#include #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); } - diff --git a/lib/libedit/src/key.h b/lib/libedit/src/keymacro.h similarity index 58% rename from lib/libedit/src/key.h rename to lib/libedit/src/keymacro.h index 8f067a064..0653bbe3f 100644 --- a/lib/libedit/src/key.h +++ b/lib/libedit/src/keymacro.h @@ -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 */ diff --git a/lib/libedit/src/makelist b/lib/libedit/src/makelist index 662bc0704..c8f927651 100644 --- a/lib/libedit/src/makelist +++ b/lib/libedit/src/makelist @@ -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 " +AWK=awk +USAGE="Usage: $0 -h|-fc|-fh|-bh " 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"); }' ;; diff --git a/lib/libedit/src/map.c b/lib/libedit/src/map.c index e622060fa..f72d2724a 100644 --- a/lib/libedit/src/map.c +++ b/lib/libedit/src/map.c @@ -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 #include -#include "el.h" +#include -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- 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; } diff --git a/lib/libedit/src/map.h b/lib/libedit/src/map.h index 8e0c7e4ea..b4e4e2899 100644 --- a/lib/libedit/src/map.h +++ b/lib/libedit/src/map.h @@ -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,13 +40,14 @@ #ifndef _h_el_map #define _h_el_map +typedef el_action_t (*el_func_t)(EditLine *, wint_t); + typedef struct el_bindings_t { /* for the "bind" shell command */ - const Char *name; /* function name for bind command */ + const wchar_t *name; /* function name for bind command */ int func; /* function numeric value */ - const Char *description; /* description of function */ + const wchar_t *description; /* description of function */ } el_bindings_t; - typedef struct el_map_t { el_action_t *alt; /* The current alternate key map */ el_action_t *key; /* The current normal key map */ @@ -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 */ diff --git a/lib/libedit/src/parse.c b/lib/libedit/src/parse.c index 9983fa750..fdd0d847a 100644 --- a/lib/libedit/src/parse.c +++ b/lib/libedit/src/parse.c @@ -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 +#include + +#include "el.h" +#include "parse.h" -private const struct { - const Char *name; - int (*func)(EditLine *, int, const Char **); +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 ^ \ \ \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; } diff --git a/lib/libedit/src/parse.h b/lib/libedit/src/parse.h index ec04051bc..fe8eb4733 100644 --- a/lib/libedit/src/parse.h +++ b/lib/libedit/src/parse.h @@ -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 */ diff --git a/lib/libedit/src/prompt.c b/lib/libedit/src/prompt.c index acfb4372e..a3d9915ec 100644 --- a/lib/libedit/src/prompt.c +++ b/lib/libedit/src/prompt.c @@ -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 #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; diff --git a/lib/libedit/src/prompt.h b/lib/libedit/src/prompt.h index cde746285..2931428db 100644 --- a/lib/libedit/src/prompt.h +++ b/lib/libedit/src/prompt.h @@ -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 */ diff --git a/lib/libedit/src/read.c b/lib/libedit/src/read.c index 094977f72..cfab8206e 100644 --- a/lib/libedit/src/read.c +++ b/lib/libedit/src/read.c @@ -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 #include #include -#include -#include #include -#include "el.h" - -#define OKCMD -1 /* must be -1! */ +#include +#include +#include -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 *); +#include "el.h" +#include "fcns.h" +#include "read.h" + +#define EL_MAXMACRO 10 + +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); - } -} - - -/* 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); - } + return -1; } -#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); -} - -#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 */ + return 0; } -#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 +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 */ -public int -FUN(el,getc)(EditLine *el, Char *cp) +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); - -#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); + return 0; + + 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 diff --git a/lib/libedit/src/read.h b/lib/libedit/src/read.h index 1ded7c1cf..1acf5d676 100644 --- a/lib/libedit/src/read.h +++ b/lib/libedit/src/read.h @@ -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 */ diff --git a/lib/libedit/src/readline.c b/lib/libedit/src/readline.c index e3a27ad2d..fd25c0164 100644 --- a/lib/libedit/src/readline.c +++ b/lib/libedit/src/readline.c @@ -1,4 +1,4 @@ -/* $NetBSD: readline.c,v 1.92 2010/09/16 20:08:51 christos Exp $ */ +/* $NetBSD: readline.c,v 1.139 2016/10/28 18:32:26 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -31,33 +31,30 @@ #include "config.h" #if !defined(lint) && !defined(SCCSID) -__RCSID("$NetBSD: readline.c,v 1.92 2010/09/16 20:08:51 christos Exp $"); +__RCSID("$NetBSD: readline.c,v 1.139 2016/10/28 18:32:26 christos Exp $"); #endif /* not lint && not SCCSID */ #include #include -#include -#include -#include -#include #include -#include -#include -#include +#include #include #include +#include +#include #include +#include +#include +#include +#include +#include #include -#include "editline/readline.h" + +#include "readline/readline.h" #include "el.h" -#include "fcns.h" /* for EL_NUM_FCNS */ -#include "histedit.h" +#include "fcns.h" #include "filecomplete.h" -#if !defined(SIZE_T_MAX) -# define SIZE_T_MAX (size_t)(-1) -#endif - void rl_prep_terminal(int); void rl_deprep_terminal(void); @@ -81,15 +78,24 @@ FILE *rl_outstream = NULL; int rl_point = 0; int rl_end = 0; char *rl_line_buffer = NULL; -VCPFunction *rl_linefunc = NULL; +rl_vcpfunc_t *rl_linefunc = NULL; int rl_done = 0; VFunction *rl_event_hook = NULL; KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_meta_keymap, emacs_ctlx_keymap; +/* + * The following is not implemented; we always catch signals in the + * libedit fashion: set handlers on entry to el_gets() and clear them + * on the way out. This simplistic approach works for most cases; if + * it does not work for your application, please let us know. + */ +int rl_catch_signals = 1; +int rl_catch_sigwinch = 1; int history_base = 1; /* probably never subject to change */ int history_length = 0; +int history_offset = 0; int max_input_history = 0; char history_expansion_char = '!'; char history_subst_char = '^'; @@ -102,8 +108,9 @@ int rl_attempted_completion_over = 0; char *rl_basic_word_break_characters = break_chars; char *rl_completer_word_break_characters = NULL; char *rl_completer_quote_characters = NULL; -Function *rl_completion_entry_function = NULL; -CPPFunction *rl_attempted_completion_function = NULL; +rl_compentry_func_t *rl_completion_entry_function = NULL; +char *(*rl_completion_word_break_hook)(void) = NULL; +rl_completion_func_t *rl_attempted_completion_function = NULL; Function *rl_pre_input_hook = NULL; Function *rl_startup1_hook = NULL; int (*rl_getc_function)(FILE *) = NULL; @@ -111,7 +118,6 @@ char *rl_terminal_name = NULL; int rl_already_prompted = 0; int rl_filename_completion_desired = 0; int rl_ignore_completion_duplicates = 0; -int rl_catch_signals = 1; int readline_echoing_p = 1; int _rl_print_completions_horizontally = 0; VFunction *rl_redisplay_function = NULL; @@ -155,48 +161,29 @@ int rl_completion_append_character = ' '; static History *h = NULL; static EditLine *e = NULL; -static Function *map[256]; +static rl_command_func_t *map[256]; static jmp_buf topbuf; /* internal functions */ static unsigned char _el_rl_complete(EditLine *, int); static unsigned char _el_rl_tstp(EditLine *, int); static char *_get_prompt(EditLine *); -static int _getc_function(EditLine *, char *); -static HIST_ENTRY *_move_history(int); +static int _getc_function(EditLine *, wchar_t *); static int _history_expand_command(const char *, size_t, size_t, char **); static char *_rl_compat_sub(const char *, const char *, const char *, int); -static int _rl_event_read_char(EditLine *, char *); +static int _rl_event_read_char(EditLine *, wchar_t *); static void _rl_update_pos(void); +static HIST_ENTRY rl_he; /* ARGSUSED */ static char * _get_prompt(EditLine *el __attribute__((__unused__))) { rl_already_prompted = 1; - return (rl_prompt); -} - - -/* - * generic function for moving around history - */ -static HIST_ENTRY * -_move_history(int op) -{ - HistEvent ev; - static HIST_ENTRY rl_he; - - if (history(h, &ev, op) != 0) - return (HIST_ENTRY *) NULL; - - rl_he.line = ev.str; - rl_he.data = NULL; - - return (&rl_he); + return rl_prompt; } @@ -205,14 +192,14 @@ _move_history(int op) */ static int /*ARGSUSED*/ -_getc_function(EditLine *el, char *c) +_getc_function(EditLine *el __attribute__((__unused__)), wchar_t *c) { int i; - i = (*rl_getc_function)(NULL); + i = (*rl_getc_function)(rl_instream); if (i == -1) return 0; - *c = i; + *c = (wchar_t)i; return 1; } @@ -224,23 +211,27 @@ _resize_fun(EditLine *el, void *a) li = el_line(el); /* a cheesy way to get rid of const cast. */ - *ap = memchr(li->buffer, *li->buffer, 1); + *ap = memchr(li->buffer, *li->buffer, (size_t)1); } -static const char _dothistory[] = "/.history"; - static const char * _default_history_file(void) { struct passwd *p; - static char path[PATH_MAX]; + static char *path; + size_t len; - if (*path) + if (path) return path; + if ((p = getpwuid(getuid())) == NULL) return NULL; - strlcpy(path, p->pw_dir, PATH_MAX); - strlcat(path, _dothistory, PATH_MAX); + + len = strlen(p->pw_dir) + sizeof("/.history"); + if ((path = malloc(len)) == NULL) + return NULL; + + (void)snprintf(path, len, "%s/.history", p->pw_dir); return path; } @@ -261,7 +252,7 @@ rl_set_prompt(const char *prompt) if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0) return 0; if (rl_prompt) - free(rl_prompt); + el_free(rl_prompt); rl_prompt = strdup(prompt); if (rl_prompt == NULL) return -1; @@ -305,7 +296,7 @@ rl_initialize(void) h = history_init(); if (!e || !h) - return (-1); + return -1; history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */ history_length = 0; @@ -329,7 +320,7 @@ rl_initialize(void) el_set(e, EL_SIGNAL, rl_catch_signals); /* set default mode to "emacs"-style and read setting afterwards */ - /* so this can be overriden */ + /* so this can be overridden */ el_set(e, EL_EDITOR, "emacs"); if (rl_terminal_name != NULL) el_set(e, EL_TERMINAL, rl_terminal_name); @@ -353,6 +344,37 @@ rl_initialize(void) _el_rl_tstp); el_set(e, EL_BIND, "^Z", "rl_tstp", NULL); + /* + * Set some readline compatible key-bindings. + */ + el_set(e, EL_BIND, "^R", "em-inc-search-prev", NULL); + + /* + * Allow the use of Home/End keys. + */ + el_set(e, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL); + el_set(e, EL_BIND, "\\e[4~", "ed-move-to-end", NULL); + el_set(e, EL_BIND, "\\e[7~", "ed-move-to-beg", NULL); + el_set(e, EL_BIND, "\\e[8~", "ed-move-to-end", NULL); + el_set(e, EL_BIND, "\\e[H", "ed-move-to-beg", NULL); + el_set(e, EL_BIND, "\\e[F", "ed-move-to-end", NULL); + + /* + * Allow the use of the Delete/Insert keys. + */ + el_set(e, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL); + el_set(e, EL_BIND, "\\e[2~", "ed-quoted-insert", NULL); + + /* + * Ctrl-left-arrow and Ctrl-right-arrow for word moving. + */ + el_set(e, EL_BIND, "\\e[1;5C", "em-next-word", NULL); + el_set(e, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL); + el_set(e, EL_BIND, "\\e[5C", "em-next-word", NULL); + el_set(e, EL_BIND, "\\e[5D", "ed-prev-word", NULL); + el_set(e, EL_BIND, "\\e\\e[C", "em-next-word", NULL); + el_set(e, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL); + /* read settings from configuration file */ el_source(e, NULL); @@ -366,7 +388,7 @@ rl_initialize(void) if (rl_startup_hook) (*rl_startup_hook)(NULL, 0); - return (0); + return 0; } @@ -444,6 +466,7 @@ using_history(void) { if (h == NULL || e == NULL) rl_initialize(); + history_offset = history_length; } @@ -475,7 +498,7 @@ _rl_compat_sub(const char *str, const char *what, const char *with, } else s++; } - r = result = malloc(len + 1); + r = result = el_malloc((len + 1) * sizeof(*r)); if (result == NULL) return NULL; s = str; @@ -486,13 +509,13 @@ _rl_compat_sub(const char *str, const char *what, const char *with, s += what_len; if (!globally) { (void)strcpy(r, s); - return(result); + return result; } } else *r++ = *s++; } *r = '\0'; - return(result); + return result; } static char *last_search_pat; /* last !?pat[?] search pattern */ @@ -509,12 +532,12 @@ get_history_event(const char *cmd, int *cindex, int qchar) idx = *cindex; if (cmd[idx++] != history_expansion_char) - return(NULL); + return NULL; /* find out which event to take */ if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') { if (history(h, &ev, H_FIRST) != 0) - return(NULL); + return NULL; *cindex = cmd[idx]? (idx + 1):idx; return ev.str; } @@ -525,7 +548,7 @@ get_history_event(const char *cmd, int *cindex, int qchar) } if ('0' <= cmd[idx] && cmd[idx] <= '9') { - HIST_ENTRY *rl_he; + HIST_ENTRY *he; num = 0; while (cmd[idx] && '0' <= cmd[idx] && cmd[idx] <= '9') { @@ -535,11 +558,11 @@ get_history_event(const char *cmd, int *cindex, int qchar) if (sign) num = history_length - num + 1; - if (!(rl_he = history_get(num))) - return(NULL); + if (!(he = history_get(num))) + return NULL; *cindex = idx; - return(rl_he->line); + return he->line; } sub = 0; if (cmd[idx] == '?') { @@ -557,15 +580,15 @@ get_history_event(const char *cmd, int *cindex, int qchar) break; idx++; } - len = idx - begin; + len = (size_t)idx - (size_t)begin; if (sub && cmd[idx] == '?') idx++; if (sub && len == 0 && last_search_pat && *last_search_pat) pat = last_search_pat; else if (len == 0) - return(NULL); + return NULL; else { - if ((pat = malloc(len + 1)) == NULL) + if ((pat = el_malloc((len + 1) * sizeof(*pat))) == NULL) return NULL; (void)strncpy(pat, cmd + begin, len); pat[len] = '\0'; @@ -573,15 +596,15 @@ get_history_event(const char *cmd, int *cindex, int qchar) if (history(h, &ev, H_CURR) != 0) { if (pat != last_search_pat) - free(pat); - return (NULL); + el_free(pat); + return NULL; } num = ev.num; if (sub) { if (pat != last_search_pat) { if (last_search_pat) - free(last_search_pat); + el_free(last_search_pat); last_search_pat = pat; } ret = history_search(pat, -1); @@ -593,21 +616,21 @@ get_history_event(const char *cmd, int *cindex, int qchar) history(h, &ev, H_FIRST); (void)fprintf(rl_outstream, "%s: Event not found\n", pat); if (pat != last_search_pat) - free(pat); - return(NULL); + el_free(pat); + return NULL; } if (sub && len) { if (last_search_match && last_search_match != pat) - free(last_search_match); + el_free(last_search_match); last_search_match = pat; } if (pat != last_search_pat) - free(pat); + el_free(pat); if (history(h, &ev, H_CURR) != 0) - return(NULL); + return NULL; *cindex = idx; rptr = ev.str; @@ -625,7 +648,7 @@ get_history_event(const char *cmd, int *cindex, int qchar) * returns 0 if data was not modified, 1 if it was and 2 if the string * should be only printed and not executed; in case of error, * returns -1 and *result points to NULL - * it's callers responsibility to free() string returned in *result + * it's the caller's responsibility to free() the string returned in *result */ static int _history_expand_command(const char *command, size_t offs, size_t cmdlen, @@ -659,7 +682,8 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, } else { if (command[offs + 1] == '#') { /* use command so far */ - if ((aptr = malloc(offs + 1)) == NULL) + if ((aptr = el_malloc((offs + 1) * sizeof(*aptr))) + == NULL) return -1; (void)strncpy(aptr, command, offs); aptr[offs] = '\0'; @@ -670,19 +694,19 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, qchar = (offs > 0 && command[offs - 1] == '"')? '"':0; ptr = get_history_event(command + offs, &idx, qchar); } - has_mods = command[offs + idx] == ':'; + has_mods = command[offs + (size_t)idx] == ':'; } if (ptr == NULL && aptr == NULL) - return(-1); + return -1; if (!has_mods) { *result = strdup(aptr ? aptr : ptr); if (aptr) - free(aptr); + el_free(aptr); if (*result == NULL) return -1; - return(1); + return 1; } cmd = command + offs + idx + 1; @@ -727,18 +751,18 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, (void)fprintf(rl_outstream, "%s: Bad word specifier", command + offs + idx); if (aptr) - free(aptr); - return(-1); + el_free(aptr); + return -1; } } else tmp = strdup(aptr? aptr:ptr); if (aptr) - free(aptr); + el_free(aptr); if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) { *result = tmp; - return(1); + return 1; } for (; *cmd; cmd++) { @@ -750,7 +774,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, } else if (*cmd == 't') { /* remove leading path */ if ((aptr = strrchr(tmp, '/')) != NULL) { aptr = strdup(aptr + 1); - free(tmp); + el_free(tmp); tmp = aptr; } } else if (*cmd == 'r') { /* remove trailing suffix */ @@ -759,7 +783,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, } else if (*cmd == 'e') { /* remove all but suffix */ if ((aptr = strrchr(tmp, '.')) != NULL) { aptr = strdup(aptr); - free(tmp); + el_free(tmp); tmp = aptr; } } else if (*cmd == 'p') /* print only */ @@ -776,10 +800,10 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, else if (*cmd == 's') { delim = *(++cmd), cmd++; size = 16; - what = realloc(from, size); + what = el_realloc(from, size * sizeof(*what)); if (what == NULL) { - free(from); - free(tmp); + el_free(from); + el_free(tmp); return 0; } len = 0; @@ -788,11 +812,12 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, cmd++; if (len >= size) { char *nwhat; - nwhat = realloc(what, - (size <<= 1)); + nwhat = el_realloc(what, + (size <<= 1) * + sizeof(*nwhat)); if (nwhat == NULL) { - free(what); - free(tmp); + el_free(what); + el_free(tmp); return 0; } what = nwhat; @@ -802,17 +827,17 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, what[len] = '\0'; from = what; if (*what == '\0') { - free(what); + el_free(what); if (search) { from = strdup(search); if (from == NULL) { - free(tmp); + el_free(tmp); return 0; } } else { from = NULL; - free(tmp); - return (-1); + el_free(tmp); + return -1; } } cmd++; /* shift after delim */ @@ -820,10 +845,10 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, continue; size = 16; - with = realloc(to, size); + with = el_realloc(to, size * sizeof(*with)); if (with == NULL) { - free(to); - free(tmp); + el_free(to); + el_free(tmp); return -1; } len = 0; @@ -832,10 +857,11 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, if (len + from_len + 1 >= size) { char *nwith; size += from_len + 1; - nwith = realloc(with, size); + nwith = el_realloc(with, + size * sizeof(*nwith)); if (nwith == NULL) { - free(with); - free(tmp); + el_free(with); + el_free(tmp); return -1; } with = nwith; @@ -858,14 +884,14 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, aptr = _rl_compat_sub(tmp, from, to, g_on); if (aptr) { - free(tmp); + el_free(tmp); tmp = aptr; } g_on = 0; } } *result = tmp; - return (p_on? 2:1); + return p_on? 2:1; } @@ -884,13 +910,13 @@ history_expand(char *str, char **output) if (history_expansion_char == 0) { *output = strdup(str); - return(0); + return 0; } *output = NULL; if (str[0] == history_subst_char) { /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */ - *output = malloc(strlen(str) + 4 + 1); + *output = el_malloc((strlen(str) + 4 + 1) * sizeof(**output)); if (*output == NULL) return 0; (*output)[0] = (*output)[1] = history_expansion_char; @@ -907,11 +933,12 @@ history_expand(char *str, char **output) #define ADD_STRING(what, len, fr) \ { \ if (idx + len + 1 > size) { \ - char *nresult = realloc(result, (size += len + 1));\ + char *nresult = el_realloc(result, \ + (size += len + 1) * sizeof(*nresult)); \ if (nresult == NULL) { \ - free(*output); \ + el_free(*output); \ if (/*CONSTCOND*/fr) \ - free(tmp); \ + el_free(tmp); \ return 0; \ } \ result = nresult; \ @@ -935,7 +962,8 @@ loop: for (; str[j]; j++) { if (str[j] == '\\' && str[j + 1] == history_expansion_char) { - (void)strcpy(&str[j], &str[j + 1]); + len = strlen(&str[j + 1]) + 1; + memmove(&str[j], &str[j + 1], len); continue; } if (!loop_again) { @@ -978,7 +1006,7 @@ loop: ADD_STRING(tmp, len, 1); } if (tmp) { - free(tmp); + el_free(tmp); tmp = NULL; } i = j; @@ -995,10 +1023,10 @@ loop: ret = -1; #endif } - free(*output); + el_free(*output); *output = result; - return (ret); + return ret; } /* @@ -1033,14 +1061,14 @@ history_arg_extract(int start, int end, const char *str) (size_t)end > max || start > end) goto out; - for (i = start, len = 0; i <= (size_t)end; i++) + for (i = (size_t)start, len = 0; i <= (size_t)end; i++) len += strlen(arr[i]) + 1; len++; - result = malloc(len); + result = el_malloc(len * sizeof(*result)); if (result == NULL) goto out; - for (i = start, len = 0; i <= (size_t)end; i++) { + for (i = (size_t)start, len = 0; i <= (size_t)end; i++) { (void)strcpy(result + len, arr[i]); len += strlen(arr[i]); if (i < (size_t)end) @@ -1050,8 +1078,8 @@ history_arg_extract(int start, int end, const char *str) out: for (i = 0; arr[i]; i++) - free(arr[i]); - free(arr); + el_free(arr[i]); + el_free(arr); return result; } @@ -1090,19 +1118,19 @@ history_tokenize(const char *str) if (idx + 2 >= size) { char **nresult; size <<= 1; - nresult = realloc(result, size * sizeof(char *)); + nresult = el_realloc(result, (size_t)size * sizeof(*nresult)); if (nresult == NULL) { - free(result); + el_free(result); return NULL; } result = nresult; } - len = i - start; - temp = malloc(len + 1); + len = (size_t)i - (size_t)start; + temp = el_malloc((size_t)(len + 1) * sizeof(*temp)); if (temp == NULL) { for (i = 0; i < idx; i++) - free(result[i]); - free(result); + el_free(result[i]); + el_free(result); return NULL; } (void)strncpy(temp, &str[start], len); @@ -1112,7 +1140,7 @@ history_tokenize(const char *str) if (str[i]) i++; } - return (result); + return result; } @@ -1123,12 +1151,22 @@ void stifle_history(int max) { HistEvent ev; + HIST_ENTRY *he; if (h == NULL || e == NULL) rl_initialize(); - if (history(h, &ev, H_SETSIZE, max) == 0) + if (history(h, &ev, H_SETSIZE, max) == 0) { max_input_history = max; + if (history_length > max) + history_base = history_length - max; + while (history_length > max) { + he = remove_history(0); + el_free(he->data); + el_free((void *)(unsigned long)he->line); + el_free(he); + } + } } @@ -1144,7 +1182,7 @@ unstifle_history(void) history(h, &ev, H_SETSIZE, INT_MAX); omax = max_input_history; max_input_history = INT_MAX; - return (omax); /* some value _must_ be returned */ + return omax; /* some value _must_ be returned */ } @@ -1153,7 +1191,7 @@ history_is_stifled(void) { /* cannot return true answer */ - return (max_input_history != INT_MAX); + return max_input_history != INT_MAX; } static const char _history_tmp_template[] = "/tmp/.historyXXXXXX"; @@ -1188,7 +1226,7 @@ history_truncate_file (const char *filename, int nlines) } for(;;) { - if (fread(buf, sizeof(buf), 1, fp) != 1) { + if (fread(buf, sizeof(buf), (size_t)1, fp) != 1) { if (ferror(fp)) { ret = errno; break; @@ -1198,7 +1236,7 @@ history_truncate_file (const char *filename, int nlines) ret = errno; break; } - left = fread(buf, 1, sizeof(buf), fp); + left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), fp); if (ferror(fp)) { ret = errno; break; @@ -1206,14 +1244,15 @@ history_truncate_file (const char *filename, int nlines) if (left == 0) { count--; left = sizeof(buf); - } else if (fwrite(buf, (size_t)left, 1, tp) != 1) { + } else if (fwrite(buf, (size_t)left, (size_t)1, tp) + != 1) { ret = errno; break; } fflush(tp); break; } - if (fwrite(buf, sizeof(buf), 1, tp) != 1) { + if (fwrite(buf, sizeof(buf), (size_t)1, tp) != 1) { ret = errno; break; } @@ -1243,7 +1282,7 @@ history_truncate_file (const char *filename, int nlines) ret = errno; break; } - if (fread(buf, sizeof(buf), 1, tp) != 1) { + if (fread(buf, sizeof(buf), (size_t)1, tp) != 1) { if (ferror(tp)) { ret = errno; break; @@ -1257,7 +1296,7 @@ history_truncate_file (const char *filename, int nlines) if (ret || nlines > 0) goto out3; - if (fseeko(fp, 0, SEEK_SET) == (off_t)-1) { + if (fseeko(fp, (off_t)0, SEEK_SET) == (off_t)-1) { ret = errno; goto out3; } @@ -1269,12 +1308,12 @@ history_truncate_file (const char *filename, int nlines) } for(;;) { - if ((left = fread(buf, 1, sizeof(buf), tp)) == 0) { + if ((left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), tp)) == 0) { if (ferror(fp)) ret = errno; break; } - if (fwrite(buf, (size_t)left, 1, fp) != 1) { + if (fwrite(buf, (size_t)left, (size_t)1, fp) != 1) { ret = errno; break; } @@ -1305,8 +1344,8 @@ read_history(const char *filename) rl_initialize(); if (filename == NULL && (filename = _default_history_file()) == NULL) return errno; - return (history(h, &ev, H_LOAD, filename) == -1 ? - (errno ? errno : EINVAL) : 0); + return history(h, &ev, H_LOAD, filename) == -1 ? + (errno ? errno : EINVAL) : 0; } @@ -1322,8 +1361,8 @@ write_history(const char *filename) rl_initialize(); if (filename == NULL && (filename = _default_history_file()) == NULL) return errno; - return (history(h, &ev, H_SAVE, filename) == -1 ? - (errno ? errno : EINVAL) : 0); + return history(h, &ev, H_SAVE, filename) == -1 ? + (errno ? errno : EINVAL) : 0; } @@ -1342,25 +1381,37 @@ history_get(int num) if (h == NULL || e == NULL) rl_initialize(); + if (num < history_base) + return NULL; + /* save current position */ if (history(h, &ev, H_CURR) != 0) - return (NULL); + return NULL; curr_num = ev.num; - /* start from the oldest */ - if (history(h, &ev, H_LAST) != 0) - return (NULL); /* error */ - - /* look forwards for event matching specified offset */ - if (history(h, &ev, H_NEXT_EVDATA, num, &she.data)) - return (NULL); + /* + * use H_DELDATA to set to nth history (without delete) by passing + * (void **)-1 -- as in history_set_pos + */ + if (history(h, &ev, H_DELDATA, num - history_base, (void **)-1) != 0) + goto out; + /* get current entry */ + if (history(h, &ev, H_CURR) != 0) + goto out; + if (history(h, &ev, H_NEXT_EVDATA, ev.num, &she.data) != 0) + goto out; she.line = ev.str; /* restore pointer to where it was */ (void)history(h, &ev, H_SET, curr_num); - return (&she); + return &she; + +out: + /* restore pointer to where it was */ + (void)history(h, &ev, H_SET, curr_num); + return NULL; } @@ -1375,11 +1426,15 @@ add_history(const char *line) if (h == NULL || e == NULL) rl_initialize(); - (void)history(h, &ev, H_ENTER, line); - if (history(h, &ev, H_GETSIZE) == 0) - history_length = ev.num; + if (history(h, &ev, H_ENTER, line) == -1) + return 0; - return (!(history_length > 0)); /* return 0 if all is okay */ + (void)history(h, &ev, H_GETSIZE); + if (ev.num == history_length) + history_base++; + else + history_length = ev.num; + return 0; } @@ -1395,11 +1450,11 @@ remove_history(int num) if (h == NULL || e == NULL) rl_initialize(); - if ((he = malloc(sizeof(*he))) == NULL) + if ((he = el_malloc(sizeof(*he))) == NULL) return NULL; if (history(h, &ev, H_DELDATA, num, &he->data) != 0) { - free(he); + el_free(he); return NULL; } @@ -1433,7 +1488,7 @@ replace_history_entry(int num, const char *line, histdata_t data) if (history(h, &ev, H_LAST) != 0) return NULL; /* error */ - if ((he = malloc(sizeof(*he))) == NULL) + if ((he = el_malloc(sizeof(*he))) == NULL) return NULL; /* look forwards for event matching specified offset */ @@ -1453,7 +1508,7 @@ replace_history_entry(int num, const char *line, histdata_t data) return he; out: - free(he); + el_free(he); return NULL; } @@ -1465,8 +1520,11 @@ clear_history(void) { HistEvent ev; + if (h == NULL || e == NULL) + rl_initialize(); + (void)history(h, &ev, H_CLEAR); - history_length = 0; + history_offset = history_length = 0; } @@ -1476,21 +1534,42 @@ clear_history(void) int where_history(void) { + return history_offset; +} + +static HIST_ENTRY **_history_listp; +static HIST_ENTRY *_history_list; + +HIST_ENTRY ** +history_list(void) +{ HistEvent ev; - int curr_num, off; + HIST_ENTRY **nlp, *nl; + int i; - if (history(h, &ev, H_CURR) != 0) - return (0); - curr_num = ev.num; + if (history(h, &ev, H_LAST) != 0) + return NULL; - (void)history(h, &ev, H_FIRST); - off = 1; - while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0) - off++; + if ((nlp = el_realloc(_history_listp, + (size_t)history_length * sizeof(*nlp))) == NULL) + return NULL; + _history_listp = nlp; - return (off); -} + if ((nl = el_realloc(_history_list, + (size_t)history_length * sizeof(*nl))) == NULL) + return NULL; + _history_list = nl; + i = 0; + do { + _history_listp[i] = &_history_list[i]; + _history_list[i].line = ev.str; + _history_list[i].data = NULL; + if (i++ == history_length) + abort(); + } while (history(h, &ev, H_PREV) == 0); + return _history_listp; +} /* * returns current history event or NULL if there is no such event @@ -1498,8 +1577,14 @@ where_history(void) HIST_ENTRY * current_history(void) { + HistEvent ev; - return (_move_history(H_CURR)); + if (history(h, &ev, H_PREV_EVENT, history_offset + 1) != 0) + return NULL; + + rl_he.line = ev.str; + rl_he.data = NULL; + return &rl_he; } @@ -1514,7 +1599,7 @@ history_total_bytes(void) size_t size; if (history(h, &ev, H_CURR) != 0) - return (-1); + return -1; curr_num = ev.num; (void)history(h, &ev, H_FIRST); @@ -1526,7 +1611,7 @@ history_total_bytes(void) /* get to the same position as before */ history(h, &ev, H_PREV_EVENT, curr_num); - return (int)(size); + return (int)size; } @@ -1536,35 +1621,31 @@ history_total_bytes(void) int history_set_pos(int pos) { - HistEvent ev; - int curr_num; - if (pos >= history_length || pos < 0) - return (-1); - - (void)history(h, &ev, H_CURR); - curr_num = ev.num; + return 0; - /* - * use H_DELDATA to set to nth history (without delete) by passing - * (void **)-1 - */ - if (history(h, &ev, H_DELDATA, pos, (void **)-1)) { - (void)history(h, &ev, H_SET, curr_num); - return(-1); - } - return (0); + history_offset = pos; + return 1; } /* * returns previous event in history and shifts pointer accordingly + * Note that readline and editline define directions in opposite ways. */ HIST_ENTRY * previous_history(void) { + HistEvent ev; - return (_move_history(H_PREV)); + if (history_offset == 0) + return NULL; + + if (history(h, &ev, H_LAST) != 0) + return NULL; + + history_offset--; + return current_history(); } @@ -1574,8 +1655,16 @@ previous_history(void) HIST_ENTRY * next_history(void) { + HistEvent ev; + + if (history_offset >= history_length) + return NULL; + + if (history(h, &ev, H_LAST) != 0) + return NULL; - return (_move_history(H_NEXT)); + history_offset++; + return current_history(); } @@ -1590,17 +1679,17 @@ history_search(const char *str, int direction) int curr_num; if (history(h, &ev, H_CURR) != 0) - return (-1); + return -1; curr_num = ev.num; for (;;) { if ((strp = strstr(ev.str, str)) != NULL) - return (int) (strp - ev.str); + return (int)(strp - ev.str); if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0) break; } (void)history(h, &ev, H_SET, curr_num); - return (-1); + return -1; } @@ -1619,7 +1708,7 @@ history_search_prefix(const char *str, int direction) /* * search for event in history containing str, starting at offset - * labs(pos); continue backward, if pos<0, forward otherwise + * abs(pos); continue backward, if pos<0, forward otherwise */ /* ARGSUSED */ int @@ -1633,15 +1722,15 @@ history_search_pos(const char *str, pos = (pos > 0) ? 1 : -1; if (history(h, &ev, H_CURR) != 0) - return (-1); + return -1; curr_num = ev.num; - if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0) - return (-1); + if (!history_set_pos(off) || history(h, &ev, H_CURR) != 0) + return -1; for (;;) { if (strstr(ev.str, str)) - return (off); + return off; if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0) break; } @@ -1650,7 +1739,7 @@ history_search_pos(const char *str, (void)history(h, &ev, pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); - return (-1); + return -1; } @@ -1673,16 +1762,20 @@ filename_completion_function(const char *name, int state) * a completion generator for usernames; returns _first_ username * which starts with supplied text * text contains a partial username preceded by random character - * (usually '~'); state is ignored - * it's callers responsibility to free returned value + * (usually '~'); state resets search from start (??? should we do that anyway) + * it's the caller's responsibility to free the returned value */ char * username_completion_function(const char *text, int state) { - struct passwd *pwd; +#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT) + struct passwd pwres; + char pwbuf[1024]; +#endif + struct passwd *pass = NULL; if (text[0] == '\0') - return (NULL); + return NULL; if (*text == '~') text++; @@ -1690,15 +1783,21 @@ username_completion_function(const char *text, int state) if (state == 0) setpwent(); - while ((pwd = getpwent()) - && pwd != NULL && text[0] == pwd->pw_name[0] - && strcmp(text, pwd->pw_name) == 0); + while ( +#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT) + getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pass) == 0 && pass != NULL +#else + (pass = getpwent()) != NULL +#endif + && text[0] == pass->pw_name[0] + && strcmp(text, pass->pw_name) == 0) + continue; - if (pwd == NULL) { + if (pass == NULL) { endpwent(); return NULL; } - return strdup(pwd->pw_name); + return strdup(pass->pw_name); } @@ -1731,7 +1830,7 @@ _rl_completion_append_character_function(const char *dummy __attribute__((__unused__))) { static char buf[2]; - buf[0] = rl_completion_append_character; + buf[0] = (char)rl_completion_append_character; buf[1] = '\0'; return buf; } @@ -1744,9 +1843,8 @@ _rl_completion_append_character_function(const char *dummy int rl_complete(int ignore __attribute__((__unused__)), int invoking_key) { -#ifdef WIDECHAR static ct_buffer_t wbreak_conv, sprefix_conv; -#endif + char *breakchars; if (h == NULL || e == NULL) rl_initialize(); @@ -1756,15 +1854,22 @@ rl_complete(int ignore __attribute__((__unused__)), int invoking_key) arr[0] = (char)invoking_key; arr[1] = '\0'; el_insertstr(e, arr); - return (CC_REFRESH); + return CC_REFRESH; } + if (rl_completion_word_break_hook != NULL) + breakchars = (*rl_completion_word_break_hook)(); + else + breakchars = rl_basic_word_break_characters; + + _rl_update_pos(); + /* Just look at how many global variables modify this operation! */ return fn_complete(e, - (CPFunction *)rl_completion_entry_function, + (rl_compentry_func_t *)rl_completion_entry_function, rl_attempted_completion_function, ct_decode_string(rl_basic_word_break_characters, &wbreak_conv), - ct_decode_string(rl_special_prefixes, &sprefix_conv), + ct_decode_string(breakchars, &sprefix_conv), _rl_completion_append_character_function, (size_t)rl_completion_query_items, &rl_completion_type, &rl_attempted_completion_over, @@ -1801,7 +1906,7 @@ rl_bind_key(int c, rl_command_func_t *func) e->el_map.key[c] = ED_INSERT; retval = 0; } - return (retval); + return retval; } @@ -1817,7 +1922,7 @@ rl_read_key(void) if (e == NULL || h == NULL) rl_initialize(); - return (el_getc(e, fooarr)); + return el_getc(e, fooarr); } @@ -1847,32 +1952,33 @@ rl_insert(int count, int c) rl_initialize(); /* XXX - int -> char conversion can lose on multichars */ - arr[0] = c; + arr[0] = (char)c; arr[1] = '\0'; for (; count > 0; count--) el_push(e, arr); - return (0); + return 0; } int rl_insert_text(const char *text) { if (!text || *text == 0) - return (0); + return 0; if (h == NULL || e == NULL) rl_initialize(); if (el_insertstr(e, text) < 0) - return (0); + return 0; return (int)strlen(text); } /*ARGSUSED*/ int -rl_newline(int count, int c) +rl_newline(int count __attribute__((__unused__)), + int c __attribute__((__unused__))) { /* * Readline-4.0 appears to ignore the args. @@ -1882,14 +1988,14 @@ rl_newline(int count, int c) /*ARGSUSED*/ static unsigned char -rl_bind_wrapper(EditLine *el, unsigned char c) +rl_bind_wrapper(EditLine *el __attribute__((__unused__)), unsigned char c) { if (map[c] == NULL) return CC_ERROR; _rl_update_pos(); - (*map[c])(NULL, c); + (*map[c])(1, c); /* If rl_done was set by the above call, deal with it here */ if (rl_done) @@ -1899,7 +2005,7 @@ rl_bind_wrapper(EditLine *el, unsigned char c) } int -rl_add_defun(const char *name, Function *fun, int c) +rl_add_defun(const char *name, rl_command_func_t *fun, int c) { char dest[8]; if ((size_t)c >= sizeof(map) / sizeof(map[0]) || c < 0) @@ -1907,12 +2013,12 @@ rl_add_defun(const char *name, Function *fun, int c) map[(unsigned char)c] = fun; el_set(e, EL_ADDFN, name, name, rl_bind_wrapper); vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0); - el_set(e, EL_BIND, dest, name); + el_set(e, EL_BIND, dest, name, NULL); return 0; } void -rl_callback_read_char() +rl_callback_read_char(void) { int count = 0, done = 0; const char *buf = el_gets(e, &count); @@ -1933,12 +2039,12 @@ rl_callback_read_char() } else wbuf = NULL; (*(void (*)(const char *))rl_linefunc)(wbuf); - //el_set(e, EL_UNBUFFERED, 1); + el_set(e, EL_UNBUFFERED, 1); } } void -rl_callback_handler_install(const char *prompt, VCPFunction *linefunc) +rl_callback_handler_install(const char *prompt, rl_vcpfunc_t *linefunc) { if (e == NULL) { rl_initialize(); @@ -1959,7 +2065,7 @@ void rl_redisplay(void) { char a[2]; - a[0] = e->el_tty.t_c[TS_IO][C_REPRINT]; + a[0] = (char)e->el_tty.t_c[TS_IO][C_REPRINT]; a[1] = '\0'; el_push(e, a); } @@ -1968,7 +2074,7 @@ int rl_get_previous_history(int count, int key) { char a[2]; - a[0] = key; + a[0] = (char)key; a[1] = '\0'; while (count--) el_push(e, a); @@ -1977,7 +2083,7 @@ rl_get_previous_history(int count, int key) void /*ARGSUSED*/ -rl_prep_terminal(int meta_flag) +rl_prep_terminal(int meta_flag __attribute__((__unused__))) { el_set(e, EL_PREP_TERM, 1); } @@ -1991,7 +2097,7 @@ rl_deprep_terminal(void) int rl_read_init_file(const char *s) { - return(el_source(e, s)); + return el_source(e, s); } int @@ -2005,7 +2111,7 @@ rl_parse_and_bind(const char *line) tok_str(tok, line, &argc, &argv); argc = el_parse(e, argc, argv); tok_end(tok); - return (argc ? 1 : 0); + return argc ? 1 : 0; } int @@ -2015,7 +2121,7 @@ rl_variable_bind(const char *var, const char *value) * The proper return value is undocument, but this is what the * readline source seems to do. */ - return ((el_set(e, EL_BIND, "", var, value) == -1) ? 1 : 0); + return el_set(e, EL_BIND, "", var, value, NULL) == -1 ? 1 : 0; } void @@ -2023,41 +2129,43 @@ rl_stuff_char(int c) { char buf[2]; - buf[0] = c; + buf[0] = (char)c; buf[1] = '\0'; el_insertstr(e, buf); } static int -_rl_event_read_char(EditLine *el, char *cp) +_rl_event_read_char(EditLine *el, wchar_t *wc) { + char ch; int n; ssize_t num_read = 0; - *cp = '\0'; + ch = '\0'; + *wc = L'\0'; while (rl_event_hook) { (*rl_event_hook)(); #if defined(FIONREAD) if (ioctl(el->el_infd, FIONREAD, &n) < 0) - return(-1); + return -1; if (n) - num_read = read(el->el_infd, cp, 1); + num_read = read(el->el_infd, &ch, (size_t)1); else num_read = 0; #elif defined(F_SETFL) && defined(O_NDELAY) if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0) - return(-1); + return -1; if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0) - return(-1); - num_read = read(el->el_infd, cp, 1); + return -1; + num_read = read(el->el_infd, &ch, 1); if (fcntl(el->el_infd, F_SETFL, n)) - return(-1); + return -1; #else /* not non-blocking, but what you gonna do? */ - num_read = read(el->el_infd, cp, 1); - return(-1); + num_read = read(el->el_infd, &ch, 1); + return -1; #endif if (num_read < 0 && errno == EAGAIN) @@ -2068,6 +2176,7 @@ _rl_event_read_char(EditLine *el, char *cp) } if (!rl_event_hook) el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN); + *wc = (wchar_t)ch; return (int)num_read; } @@ -2084,9 +2193,9 @@ void rl_get_screen_size(int *rows, int *cols) { if (rows) - el_get(e, EL_GETTC, "li", rows); + el_get(e, EL_GETTC, "li", rows, (void *)0); if (cols) - el_get(e, EL_GETTC, "co", cols); + el_get(e, EL_GETTC, "co", cols, (void *)0); } void @@ -2094,9 +2203,9 @@ rl_set_screen_size(int rows, int cols) { char buf[64]; (void)snprintf(buf, sizeof(buf), "%d", rows); - el_set(e, EL_SETTC, "li", buf); + el_set(e, EL_SETTC, "li", buf, NULL); (void)snprintf(buf, sizeof(buf), "%d", cols); - el_set(e, EL_SETTC, "co", buf); + el_set(e, EL_SETTC, "co", buf, NULL); } char ** @@ -2107,7 +2216,7 @@ rl_completion_matches(const char *str, rl_compentry_func_t *fun) len = 1; max = 10; - if ((list = malloc(max * sizeof(*list))) == NULL) + if ((list = el_malloc(max * sizeof(*list))) == NULL) return NULL; while ((match = (*fun)(str, (int)(len - 1))) != NULL) { @@ -2115,7 +2224,7 @@ rl_completion_matches(const char *str, rl_compentry_func_t *fun) if (len == max) { char **nl; max += 10; - if ((nl = realloc(list, max * sizeof(*nl))) == NULL) + if ((nl = el_realloc(list, max * sizeof(*nl))) == NULL) goto out; list = nl; } @@ -2130,7 +2239,7 @@ rl_completion_matches(const char *str, rl_compentry_func_t *fun) } qsort(&list[1], len - 1, sizeof(*list), (int (*)(const void *, const void *)) strcmp); - min = SIZE_T_MAX; + min = SIZE_MAX; for (i = 1, a = list[i]; i < len - 1; i++, a = b) { b = list[i + 1]; for (j = 0; a[j] && a[j] == b[j]; j++) @@ -2142,7 +2251,7 @@ rl_completion_matches(const char *str, rl_compentry_func_t *fun) if ((list[0] = strdup(str)) == NULL) goto out; } else { - if ((list[0] = malloc(min + 1)) == NULL) + if ((list[0] = el_malloc((min + 1) * sizeof(*list[0]))) == NULL) goto out; (void)memcpy(list[0], list[1], min); list[0][min] = '\0'; @@ -2150,7 +2259,7 @@ rl_completion_matches(const char *str, rl_compentry_func_t *fun) return list; out: - free(list); + el_free(list); return NULL; } @@ -2185,15 +2294,16 @@ history_get_history_state(void) { HISTORY_STATE *hs; - if ((hs = malloc(sizeof(HISTORY_STATE))) == NULL) - return (NULL); + if ((hs = el_malloc(sizeof(*hs))) == NULL) + return NULL; hs->length = history_length; - return (hs); + return hs; } int /*ARGSUSED*/ -rl_kill_text(int from, int to) +rl_kill_text(int from __attribute__((__unused__)), + int to __attribute__((__unused__))) { return 0; } @@ -2212,20 +2322,25 @@ rl_get_keymap(void) void /*ARGSUSED*/ -rl_set_keymap(Keymap k) +rl_set_keymap(Keymap k __attribute__((__unused__))) { } int /*ARGSUSED*/ -rl_generic_bind(int type, const char * keyseq, const char * data, Keymap k) +rl_generic_bind(int type __attribute__((__unused__)), + const char * keyseq __attribute__((__unused__)), + const char * data __attribute__((__unused__)), + Keymap k __attribute__((__unused__))) { return 0; } int /*ARGSUSED*/ -rl_bind_key_in_map(int key, rl_command_func_t *fun, Keymap k) +rl_bind_key_in_map(int key __attribute__((__unused__)), + rl_command_func_t *fun __attribute__((__unused__)), + Keymap k __attribute__((__unused__))) { return 0; } @@ -2241,3 +2356,15 @@ rl_on_new_line(void) { return 0; } + +void +rl_free_line_state(void) +{ +} + +int +/*ARGSUSED*/ +rl_set_keyboard_input_timeout(int u __attribute__((__unused__))) +{ + return 0; +} diff --git a/lib/libedit/src/editline/readline.h b/lib/libedit/src/readline/readline.h similarity index 87% rename from lib/libedit/src/editline/readline.h rename to lib/libedit/src/readline/readline.h index b36d405e0..777a4c6f4 100644 --- a/lib/libedit/src/editline/readline.h +++ b/lib/libedit/src/readline/readline.h @@ -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 diff --git a/lib/libedit/src/refresh.c b/lib/libedit/src/refresh.c index 7f35ce153..e7775b0e4 100644 --- a/lib/libedit/src/refresh.c +++ b/lib/libedit/src/refresh.c @@ -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 -#include -#include #include +#include #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 */ } } diff --git a/lib/libedit/src/refresh.h b/lib/libedit/src/refresh.h index f80be4635..621c5691e 100644 --- a/lib/libedit/src/refresh.h +++ b/lib/libedit/src/refresh.h @@ -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 */ diff --git a/lib/libedit/src/search.c b/lib/libedit/src/search.c index 59bbd1add..5226cf5fa 100644 --- a/lib/libedit/src/search.c +++ b/lib/libedit/src/search.c @@ -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 -#include +#include #if defined(REGEX) #include #elif defined(REGEXP) #include #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; } } diff --git a/lib/libedit/src/search.h b/lib/libedit/src/search.h index d9f27e561..4ca39c4c0 100644 --- a/lib/libedit/src/search.h +++ b/lib/libedit/src/search.h @@ -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 */ diff --git a/lib/libedit/src/shlib_version b/lib/libedit/src/shlib_version index 778486cf3..303609d26 100644 --- a/lib/libedit/src/shlib_version +++ b/lib/libedit/src/shlib_version @@ -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 diff --git a/lib/libedit/src/sig.c b/lib/libedit/src/sig.c index 1ea319faa..83742a3d6 100644 --- a/lib/libedit/src/sig.c +++ b/lib/libedit/src/sig.c @@ -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 #include -private EditLine *sel = NULL; +#include "el.h" +#include "common.h" + +static EditLine *sel = NULL; -private const int sighdl[] = { +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; diff --git a/lib/libedit/src/sig.h b/lib/libedit/src/sig.h index c957cfdf5..5ee453fb6 100644 --- a/lib/libedit/src/sig.h +++ b/lib/libedit/src/sig.h @@ -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 -#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 */ diff --git a/lib/libedit/src/strlcat.c b/lib/libedit/src/strlcat.c deleted file mode 100644 index 1a92fc5fa..000000000 --- a/lib/libedit/src/strlcat.c +++ /dev/null @@ -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 - * - * 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 -#include -#include - -#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 diff --git a/lib/libedit/src/strlcpy.c b/lib/libedit/src/strlcpy.c deleted file mode 100644 index 8b3dfad21..000000000 --- a/lib/libedit/src/strlcpy.c +++ /dev/null @@ -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 - * - * 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 -#include -#include - -#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 diff --git a/lib/libedit/src/sys.h b/lib/libedit/src/sys.h index 6ce7fc678..dc0a8cb9a 100644 --- a/lib/libedit/src/sys.h +++ b/lib/libedit/src/sys.h @@ -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 #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 -# 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 -# 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 */ diff --git a/lib/libedit/src/term.c b/lib/libedit/src/terminal.c similarity index 61% rename from lib/libedit/src/term.c rename to lib/libedit/src/terminal.c index 3a1b5e739..26838e813 100644 --- a/lib/libedit/src/term.c +++ b/lib/libedit/src/terminal.c @@ -1,4 +1,4 @@ -/* $NetBSD: term.c,v 1.57 2009/12/30 22:37:40 christos Exp $ */ +/* $NetBSD: terminal.c,v 1.32 2016/05/09 21:46:56 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -37,21 +37,23 @@ #if 0 static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; #else -__RCSID("$NetBSD: term.c,v 1.57 2009/12/30 22:37:40 christos Exp $"); +__RCSID("$NetBSD: terminal.c,v 1.32 2016/05/09 21:46:56 christos Exp $"); #endif #endif /* not lint && not SCCSID */ /* - * term.c: Editor/termcap-curses interface - * We have to declare a static variable here, since the - * termcap putchar routine does not take an argument! + * terminal.c: Editor/termcap-curses interface + * We have to declare a static variable here, since the + * termcap putchar routine does not take an argument! */ -#include +#include +#include +#include #include -#include +#include #include +#include #include -#include #ifdef HAVE_TERMCAP_H #include #endif @@ -60,19 +62,18 @@ __RCSID("$NetBSD: term.c,v 1.57 2009/12/30 22:37:40 christos Exp $"); #elif HAVE_NCURSES_H #include #endif -/* Solaris's term.h does horrid things. */ -#if defined(HAVE_TERM_H) && !defined(__sun) +/* Solaris's term.h does horrid things. */ +#if defined(HAVE_TERM_H) && !defined(__sun) && !defined(HAVE_TERMCAP_H) #include #endif -#include -#include #ifdef _REENTRANT #include #endif #include "el.h" +#include "fcns.h" /* * IMPORTANT NOTE: these routines are allowed to look at the current screen @@ -81,86 +82,14 @@ __RCSID("$NetBSD: term.c,v 1.57 2009/12/30 22:37:40 christos Exp $"); * assumption... */ -#define TC_BUFSIZE 2048 +#define TC_BUFSIZE ((size_t)2048) -#define GoodStr(a) (el->el_term.t_str[a] != NULL && \ - el->el_term.t_str[a][0] != '\0') -#define Str(a) el->el_term.t_str[a] -#define Val(a) el->el_term.t_val[a] +#define GoodStr(a) (el->el_terminal.t_str[a] != NULL && \ + el->el_terminal.t_str[a][0] != '\0') +#define Str(a) el->el_terminal.t_str[a] +#define Val(a) el->el_terminal.t_val[a] -#ifdef notdef -private const struct { - const char *b_name; - int b_rate; -} baud_rate[] = { -#ifdef B0 - { "0", B0 }, -#endif -#ifdef B50 - { "50", B50 }, -#endif -#ifdef B75 - { "75", B75 }, -#endif -#ifdef B110 - { "110", B110 }, -#endif -#ifdef B134 - { "134", B134 }, -#endif -#ifdef B150 - { "150", B150 }, -#endif -#ifdef B200 - { "200", B200 }, -#endif -#ifdef B300 - { "300", B300 }, -#endif -#ifdef B600 - { "600", B600 }, -#endif -#ifdef B900 - { "900", B900 }, -#endif -#ifdef B1200 - { "1200", B1200 }, -#endif -#ifdef B1800 - { "1800", B1800 }, -#endif -#ifdef B2400 - { "2400", B2400 }, -#endif -#ifdef B3600 - { "3600", B3600 }, -#endif -#ifdef B4800 - { "4800", B4800 }, -#endif -#ifdef B7200 - { "7200", B7200 }, -#endif -#ifdef B9600 - { "9600", B9600 }, -#endif -#ifdef EXTA - { "19200", EXTA }, -#endif -#ifdef B19200 - { "19200", B19200 }, -#endif -#ifdef EXTB - { "38400", EXTB }, -#endif -#ifdef B38400 - { "38400", B38400 }, -#endif - { NULL, 0 } -}; -#endif - -private const struct termcapstr { +static const struct termcapstr { const char *name; const char *long_name; } tstr[] = { @@ -240,11 +169,13 @@ private const struct termcapstr { { "kh", "send cursor home" }, #define T_at7 37 { "@7", "send cursor end" }, -#define T_str 38 +#define T_kD 38 + { "kD", "send cursor delete" }, +#define T_str 39 { NULL, NULL } }; -private const struct termcapval { +static const struct termcapval { const char *name; const char *long_name; } tval[] = { @@ -269,27 +200,28 @@ private const struct termcapval { }; /* do two or more of the attributes use me */ -private void term_setflags(EditLine *); -private int term_rebuffer_display(EditLine *); -private void term_free_display(EditLine *); -private int term_alloc_display(EditLine *); -private void term_alloc(EditLine *, const struct termcapstr *, const char *); -private void term_init_arrow(EditLine *); -private void term_reset_arrow(EditLine *); -private int term_putc(int); -private void term_tputs(EditLine *, const char *, int); +static void terminal_setflags(EditLine *); +static int terminal_rebuffer_display(EditLine *); +static void terminal_free_display(EditLine *); +static int terminal_alloc_display(EditLine *); +static void terminal_alloc(EditLine *, const struct termcapstr *, + const char *); +static void terminal_init_arrow(EditLine *); +static void terminal_reset_arrow(EditLine *); +static int terminal_putc(int); +static void terminal_tputs(EditLine *, const char *, int); #ifdef _REENTRANT -private pthread_mutex_t term_mutex = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t terminal_mutex = PTHREAD_MUTEX_INITIALIZER; #endif -private FILE *term_outfile = NULL; +static FILE *terminal_outfile = NULL; -/* term_setflags(): +/* terminal_setflags(): * Set the terminal capability flags */ -private void -term_setflags(EditLine *el) +static void +terminal_setflags(EditLine *el) { EL_FLAGS = 0; if (el->el_tty.t_tabs) @@ -330,69 +262,91 @@ term_setflags(EditLine *el) #endif /* DEBUG_SCREEN */ } -/* term_init(): +/* terminal_init(): * Initialize the terminal stuff */ -protected int -term_init(EditLine *el) +libedit_private int +terminal_init(EditLine *el) { - el->el_term.t_buf = (char *) el_malloc(TC_BUFSIZE); - if (el->el_term.t_buf == NULL) - return (-1); - el->el_term.t_cap = (char *) el_malloc(TC_BUFSIZE); - if (el->el_term.t_cap == NULL) - return (-1); - el->el_term.t_fkey = (fkey_t *) el_malloc(A_K_NKEYS * sizeof(fkey_t)); - if (el->el_term.t_fkey == NULL) - return (-1); - el->el_term.t_loc = 0; - el->el_term.t_str = (char **) el_malloc(T_str * sizeof(char *)); - if (el->el_term.t_str == NULL) - return (-1); - (void) memset(el->el_term.t_str, 0, T_str * sizeof(char *)); - el->el_term.t_val = (int *) el_malloc(T_val * sizeof(int)); - if (el->el_term.t_val == NULL) - return (-1); - (void) memset(el->el_term.t_val, 0, T_val * sizeof(int)); - (void) term_set(el, NULL); - term_init_arrow(el); - return (0); + el->el_terminal.t_buf = el_malloc(TC_BUFSIZE * + sizeof(*el->el_terminal.t_buf)); + if (el->el_terminal.t_buf == NULL) + goto fail1; + el->el_terminal.t_cap = el_malloc(TC_BUFSIZE * + sizeof(*el->el_terminal.t_cap)); + if (el->el_terminal.t_cap == NULL) + goto fail2; + el->el_terminal.t_fkey = el_malloc(A_K_NKEYS * + sizeof(*el->el_terminal.t_fkey)); + if (el->el_terminal.t_fkey == NULL) + goto fail3; + el->el_terminal.t_loc = 0; + el->el_terminal.t_str = el_malloc(T_str * + sizeof(*el->el_terminal.t_str)); + if (el->el_terminal.t_str == NULL) + goto fail4; + (void) memset(el->el_terminal.t_str, 0, T_str * + sizeof(*el->el_terminal.t_str)); + el->el_terminal.t_val = el_malloc(T_val * + sizeof(*el->el_terminal.t_val)); + if (el->el_terminal.t_val == NULL) + goto fail5; + (void) memset(el->el_terminal.t_val, 0, T_val * + sizeof(*el->el_terminal.t_val)); + (void) terminal_set(el, NULL); + terminal_init_arrow(el); + return 0; +fail5: + free(el->el_terminal.t_str); + el->el_terminal.t_str = NULL; +fail4: + free(el->el_terminal.t_fkey); + el->el_terminal.t_fkey = NULL; +fail3: + free(el->el_terminal.t_cap); + el->el_terminal.t_cap = NULL; +fail2: + free(el->el_terminal.t_buf); + el->el_terminal.t_buf = NULL; +fail1: + return -1; } -/* term_end(): +/* terminal_end(): * Clean up the terminal stuff */ -protected void -term_end(EditLine *el) +libedit_private void +terminal_end(EditLine *el) { - el_free((ptr_t) el->el_term.t_buf); - el->el_term.t_buf = NULL; - el_free((ptr_t) el->el_term.t_cap); - el->el_term.t_cap = NULL; - el->el_term.t_loc = 0; - el_free((ptr_t) el->el_term.t_str); - el->el_term.t_str = NULL; - el_free((ptr_t) el->el_term.t_val); - el->el_term.t_val = NULL; - el_free((ptr_t) el->el_term.t_fkey); - el->el_term.t_fkey = NULL; - term_free_display(el); + el_free(el->el_terminal.t_buf); + el->el_terminal.t_buf = NULL; + el_free(el->el_terminal.t_cap); + el->el_terminal.t_cap = NULL; + el->el_terminal.t_loc = 0; + el_free(el->el_terminal.t_str); + el->el_terminal.t_str = NULL; + el_free(el->el_terminal.t_val); + el->el_terminal.t_val = NULL; + el_free(el->el_terminal.t_fkey); + el->el_terminal.t_fkey = NULL; + terminal_free_display(el); } -/* term_alloc(): +/* terminal_alloc(): * Maintain a string pool for termcap strings */ -private void -term_alloc(EditLine *el, const struct termcapstr *t, const char *cap) +static void +terminal_alloc(EditLine *el, const struct termcapstr *t, const char *cap) { char termbuf[TC_BUFSIZE]; size_t tlen, clen; - char **tlist = el->el_term.t_str; + char **tlist = el->el_terminal.t_str; char **tmp, **str = &tlist[t - tstr]; + (void) memset(termbuf, 0, sizeof(termbuf)); if (cap == NULL || *cap == '\0') { *str = NULL; return; @@ -412,11 +366,11 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap) /* * New string is longer; see if we have enough space to append */ - if (el->el_term.t_loc + 3 < TC_BUFSIZE) { + if (el->el_terminal.t_loc + 3 < TC_BUFSIZE) { /* XXX strcpy is safe */ - (void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], - cap); - el->el_term.t_loc += (int)clen + 1; /* one for \0 */ + (void) strcpy(*str = &el->el_terminal.t_buf[ + el->el_terminal.t_loc], cap); + el->el_terminal.t_loc += clen + 1; /* one for \0 */ return; } /* @@ -425,131 +379,135 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap) */ tlen = 0; for (tmp = tlist; tmp < &tlist[T_str]; tmp++) - if (*tmp != NULL && *tmp != '\0' && *tmp != *str) { + if (*tmp != NULL && **tmp != '\0' && *tmp != *str) { char *ptr; for (ptr = *tmp; *ptr != '\0'; termbuf[tlen++] = *ptr++) continue; termbuf[tlen++] = '\0'; } - memcpy(el->el_term.t_buf, termbuf, TC_BUFSIZE); - el->el_term.t_loc = (int)tlen; - if (el->el_term.t_loc + 3 >= TC_BUFSIZE) { + memcpy(el->el_terminal.t_buf, termbuf, TC_BUFSIZE); + el->el_terminal.t_loc = tlen; + if (el->el_terminal.t_loc + 3 >= TC_BUFSIZE) { (void) fprintf(el->el_errfile, "Out of termcap string space.\n"); return; } /* XXX strcpy is safe */ - (void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], cap); - el->el_term.t_loc += (int)clen + 1; /* one for \0 */ + (void) strcpy(*str = &el->el_terminal.t_buf[el->el_terminal.t_loc], + cap); + el->el_terminal.t_loc += (size_t)clen + 1; /* one for \0 */ return; } -/* term_rebuffer_display(): +/* terminal_rebuffer_display(): * Rebuffer the display after the screen changed size */ -private int -term_rebuffer_display(EditLine *el) +static int +terminal_rebuffer_display(EditLine *el) { - coord_t *c = &el->el_term.t_size; + coord_t *c = &el->el_terminal.t_size; - term_free_display(el); + terminal_free_display(el); c->h = Val(T_co); c->v = Val(T_li); - if (term_alloc_display(el) == -1) - return (-1); - return (0); + if (terminal_alloc_display(el) == -1) + return -1; + return 0; } -/* term_alloc_display(): +/* terminal_alloc_display(): * Allocate a new display. */ -private int -term_alloc_display(EditLine *el) +static int +terminal_alloc_display(EditLine *el) { int i; - Char **b; - coord_t *c = &el->el_term.t_size; + wchar_t **b; + coord_t *c = &el->el_terminal.t_size; - b = el_malloc(sizeof(*b) * (c->v + 1)); + b = el_malloc(sizeof(*b) * (size_t)(c->v + 1)); if (b == NULL) - return (-1); + goto done; for (i = 0; i < c->v; i++) { - b[i] = el_malloc(sizeof(**b) * (c->h + 1)); + b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1)); if (b[i] == NULL) { while (--i >= 0) - el_free((ptr_t) b[i]); - el_free((ptr_t) b); - return (-1); + el_free(b[i]); + el_free(b); + goto done; } } b[c->v] = NULL; el->el_display = b; - b = el_malloc(sizeof(*b) * (c->v + 1)); + b = el_malloc(sizeof(*b) * (size_t)(c->v + 1)); if (b == NULL) - return (-1); + goto done; for (i = 0; i < c->v; i++) { - b[i] = el_malloc(sizeof(**b) * (c->h + 1)); + b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1)); if (b[i] == NULL) { while (--i >= 0) - el_free((ptr_t) b[i]); - el_free((ptr_t) b); - return (-1); + el_free(b[i]); + el_free(b); + goto done; } } b[c->v] = NULL; el->el_vdisplay = b; - return (0); + return 0; +done: + terminal_free_display(el); + return -1; } -/* term_free_display(): +/* terminal_free_display(): * Free the display buffers */ -private void -term_free_display(EditLine *el) +static void +terminal_free_display(EditLine *el) { - Char **b; - Char **bufp; + wchar_t **b; + wchar_t **bufp; b = el->el_display; el->el_display = NULL; if (b != NULL) { for (bufp = b; *bufp != NULL; bufp++) - el_free((ptr_t) *bufp); - el_free((ptr_t) b); + el_free(*bufp); + el_free(b); } b = el->el_vdisplay; el->el_vdisplay = NULL; if (b != NULL) { for (bufp = b; *bufp != NULL; bufp++) - el_free((ptr_t) *bufp); - el_free((ptr_t) b); + el_free(*bufp); + el_free(b); } } -/* term_move_to_line(): +/* terminal_move_to_line(): * move to line (first line == 0) - * as efficiently as possible + * as efficiently as possible */ -protected void -term_move_to_line(EditLine *el, int where) +libedit_private void +terminal_move_to_line(EditLine *el, int where) { int del; if (where == el->el_cursor.v) return; - if (where > el->el_term.t_size.v) { + if (where > el->el_terminal.t_size.v) { #ifdef DEBUG_SCREEN (void) fprintf(el->el_errfile, - "term_move_to_line: where is ridiculous: %d\r\n", where); + "%s: where is ridiculous: %d\r\n", __func__, where); #endif /* DEBUG_SCREEN */ return; } @@ -557,30 +515,29 @@ term_move_to_line(EditLine *el, int where) while (del > 0) { if (EL_HAS_AUTO_MARGINS && el->el_display[el->el_cursor.v][0] != '\0') { - size_t h = el->el_term.t_size.h - 1; -#ifdef WIDECHAR + size_t h = (size_t) + (el->el_terminal.t_size.h - 1); for (; h > 0 && el->el_display[el->el_cursor.v][h] == MB_FILL_CHAR; h--) continue; -#endif /* move without newline */ - term_move_to_char(el, (int)h); - term_overwrite(el, &el->el_display + terminal_move_to_char(el, (int)h); + terminal_overwrite(el, &el->el_display [el->el_cursor.v][el->el_cursor.h], - (size_t)(el->el_term.t_size.h - + (size_t)(el->el_terminal.t_size.h - el->el_cursor.h)); /* updates Cursor */ del--; } else { if ((del > 1) && GoodStr(T_DO)) { - term_tputs(el, tgoto(Str(T_DO), del, + terminal_tputs(el, tgoto(Str(T_DO), del, del), del); del = 0; } else { for (; del > 0; del--) - term__putc(el, '\n'); + terminal__putc(el, '\n'); /* because the \n will become \r\n */ el->el_cursor.h = 0; } @@ -588,22 +545,22 @@ term_move_to_line(EditLine *el, int where) } } else { /* del < 0 */ if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up))) - term_tputs(el, tgoto(Str(T_UP), -del, -del), -del); + terminal_tputs(el, tgoto(Str(T_UP), -del, -del), -del); else { if (GoodStr(T_up)) for (; del < 0; del++) - term_tputs(el, Str(T_up), 1); + terminal_tputs(el, Str(T_up), 1); } } el->el_cursor.v = where;/* now where is here */ } -/* term_move_to_char(): +/* terminal_move_to_char(): * Move to the character position specified */ -protected void -term_move_to_char(EditLine *el, int where) +libedit_private void +terminal_move_to_char(EditLine *el, int where) { int del, i; @@ -611,15 +568,15 @@ mc_again: if (where == el->el_cursor.h) return; - if (where > el->el_term.t_size.h) { + if (where > el->el_terminal.t_size.h) { #ifdef DEBUG_SCREEN (void) fprintf(el->el_errfile, - "term_move_to_char: where is riduculous: %d\r\n", where); + "%s: where is ridiculous: %d\r\n", __func__, where); #endif /* DEBUG_SCREEN */ return; } if (!where) { /* if where is first column */ - term__putc(el, '\r'); /* do a CR */ + terminal__putc(el, '\r'); /* do a CR */ el->el_cursor.h = 0; return; } @@ -627,28 +584,28 @@ mc_again: if ((del < -4 || del > 4) && GoodStr(T_ch)) /* go there directly */ - term_tputs(el, tgoto(Str(T_ch), where, where), where); + terminal_tputs(el, tgoto(Str(T_ch), where, where), where); else { if (del > 0) { /* moving forward */ if ((del > 4) && GoodStr(T_RI)) - term_tputs(el, tgoto(Str(T_RI), del, del), del); + terminal_tputs(el, tgoto(Str(T_RI), del, del), + del); else { /* if I can do tabs, use them */ if (EL_CAN_TAB) { if ((el->el_cursor.h & 0370) != (where & ~0x7) -#ifdef WIDECHAR && (el->el_display[ el->el_cursor.v][where & 0370] != MB_FILL_CHAR) -#endif ) { /* if not within tab stop */ for (i = (el->el_cursor.h & 0370); i < (where & ~0x7); i += 8) - term__putc(el, '\t'); + terminal__putc(el, + '\t'); /* then tab over */ el->el_cursor.h = where & ~0x7; } @@ -658,17 +615,17 @@ mc_again: * chars, so we do. */ /* - * NOTE THAT term_overwrite() WILL CHANGE + * NOTE THAT terminal_overwrite() WILL CHANGE * el->el_cursor.h!!! */ - term_overwrite(el, &el->el_display[ + terminal_overwrite(el, &el->el_display[ el->el_cursor.v][el->el_cursor.h], (size_t)(where - el->el_cursor.h)); } } else { /* del < 0 := moving backward */ if ((-del > 4) && GoodStr(T_LE)) - term_tputs(el, tgoto(Str(T_LE), -del, -del), + terminal_tputs(el, tgoto(Str(T_LE), -del, -del), -del); else { /* can't go directly there */ /* @@ -680,12 +637,12 @@ mc_again: (((unsigned int) where >> 3) + (where & 07))) : (-del > where)) { - term__putc(el, '\r'); /* do a CR */ + terminal__putc(el, '\r');/* do a CR */ el->el_cursor.h = 0; goto mc_again; /* and try again */ } for (i = 0; i < -del; i++) - term__putc(el, '\b'); + terminal__putc(el, '\b'); } } } @@ -693,62 +650,60 @@ mc_again: } -/* term_overwrite(): +/* terminal_overwrite(): * Overstrike num characters * Assumes MB_FILL_CHARs are present to keep the column count correct */ -protected void -term_overwrite(EditLine *el, const Char *cp, size_t n) +libedit_private void +terminal_overwrite(EditLine *el, const wchar_t *cp, size_t n) { if (n == 0) return; - if (n > (size_t)el->el_term.t_size.h) { + if (n > (size_t)el->el_terminal.t_size.h) { #ifdef DEBUG_SCREEN (void) fprintf(el->el_errfile, - "term_overwrite: n is riduculous: %d\r\n", n); + "%s: n is ridiculous: %zu\r\n", __func__, n); #endif /* DEBUG_SCREEN */ return; } do { - /* term__putc() ignores any MB_FILL_CHARs */ - term__putc(el, *cp++); + /* terminal__putc() ignores any MB_FILL_CHARs */ + terminal__putc(el, *cp++); el->el_cursor.h++; } while (--n); - if (el->el_cursor.h >= el->el_term.t_size.h) { /* wrap? */ + if (el->el_cursor.h >= el->el_terminal.t_size.h) { /* wrap? */ if (EL_HAS_AUTO_MARGINS) { /* yes */ el->el_cursor.h = 0; el->el_cursor.v++; if (EL_HAS_MAGIC_MARGINS) { /* force the wrap to avoid the "magic" * situation */ - Char c; + wchar_t c; if ((c = el->el_display[el->el_cursor.v] [el->el_cursor.h]) != '\0') { - term_overwrite(el, &c, 1); -#ifdef WIDECHAR + terminal_overwrite(el, &c, (size_t)1); while (el->el_display[el->el_cursor.v] [el->el_cursor.h] == MB_FILL_CHAR) el->el_cursor.h++; -#endif } else { - term__putc(el, ' '); + terminal__putc(el, ' '); el->el_cursor.h = 1; } } } else /* no wrap, but cursor stays on screen */ - el->el_cursor.h = el->el_term.t_size.h - 1; + el->el_cursor.h = el->el_terminal.t_size.h - 1; } } -/* term_deletechars(): +/* terminal_deletechars(): * Delete num characters */ -protected void -term_deletechars(EditLine *el, int num) +libedit_private void +terminal_deletechars(EditLine *el, int num) { if (num <= 0) return; @@ -759,38 +714,38 @@ term_deletechars(EditLine *el, int num) #endif /* DEBUG_EDIT */ return; } - if (num > el->el_term.t_size.h) { + if (num > el->el_terminal.t_size.h) { #ifdef DEBUG_SCREEN (void) fprintf(el->el_errfile, - "term_deletechars: num is riduculous: %d\r\n", num); + "%s: num is ridiculous: %d\r\n", __func__, num); #endif /* DEBUG_SCREEN */ return; } if (GoodStr(T_DC)) /* if I have multiple delete */ if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more * expen. */ - term_tputs(el, tgoto(Str(T_DC), num, num), num); + terminal_tputs(el, tgoto(Str(T_DC), num, num), num); return; } if (GoodStr(T_dm)) /* if I have delete mode */ - term_tputs(el, Str(T_dm), 1); + terminal_tputs(el, Str(T_dm), 1); if (GoodStr(T_dc)) /* else do one at a time */ while (num--) - term_tputs(el, Str(T_dc), 1); + terminal_tputs(el, Str(T_dc), 1); if (GoodStr(T_ed)) /* if I have delete mode */ - term_tputs(el, Str(T_ed), 1); + terminal_tputs(el, Str(T_ed), 1); } -/* term_insertwrite(): +/* terminal_insertwrite(): * Puts terminal in insert character mode or inserts num * characters in the line * Assumes MB_FILL_CHARs are present to keep column count correct */ -protected void -term_insertwrite(EditLine *el, Char *cp, int num) +libedit_private void +terminal_insertwrite(EditLine *el, wchar_t *cp, int num) { if (num <= 0) return; @@ -800,130 +755,116 @@ term_insertwrite(EditLine *el, Char *cp, int num) #endif /* DEBUG_EDIT */ return; } - if (num > el->el_term.t_size.h) { + if (num > el->el_terminal.t_size.h) { #ifdef DEBUG_SCREEN (void) fprintf(el->el_errfile, - "StartInsert: num is riduculous: %d\r\n", num); + "%s: num is ridiculous: %d\r\n", __func__, num); #endif /* DEBUG_SCREEN */ return; } if (GoodStr(T_IC)) /* if I have multiple insert */ if ((num > 1) || !GoodStr(T_ic)) { /* if ic would be more expensive */ - term_tputs(el, tgoto(Str(T_IC), num, num), num); - term_overwrite(el, cp, (size_t)num); + terminal_tputs(el, tgoto(Str(T_IC), num, num), num); + terminal_overwrite(el, cp, (size_t)num); /* this updates el_cursor.h */ return; } if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */ - term_tputs(el, Str(T_im), 1); + terminal_tputs(el, Str(T_im), 1); el->el_cursor.h += num; do - term__putc(el, *cp++); + terminal__putc(el, *cp++); while (--num); if (GoodStr(T_ip)) /* have to make num chars insert */ - term_tputs(el, Str(T_ip), 1); + terminal_tputs(el, Str(T_ip), 1); - term_tputs(el, Str(T_ei), 1); + terminal_tputs(el, Str(T_ei), 1); return; } do { if (GoodStr(T_ic)) /* have to make num chars insert */ - term_tputs(el, Str(T_ic), 1); + terminal_tputs(el, Str(T_ic), 1); - term__putc(el, *cp++); + terminal__putc(el, *cp++); el->el_cursor.h++; if (GoodStr(T_ip)) /* have to make num chars insert */ - term_tputs(el, Str(T_ip), 1); + terminal_tputs(el, Str(T_ip), 1); /* pad the inserted char */ } while (--num); } -/* term_clear_EOL(): +/* terminal_clear_EOL(): * clear to end of line. There are num characters to clear */ -protected void -term_clear_EOL(EditLine *el, int num) +libedit_private void +terminal_clear_EOL(EditLine *el, int num) { int i; if (EL_CAN_CEOL && GoodStr(T_ce)) - term_tputs(el, Str(T_ce), 1); + terminal_tputs(el, Str(T_ce), 1); else { for (i = 0; i < num; i++) - term__putc(el, ' '); + terminal__putc(el, ' '); el->el_cursor.h += num; /* have written num spaces */ } } -/* term_clear_screen(): +/* terminal_clear_screen(): * Clear the screen */ -protected void -term_clear_screen(EditLine *el) +libedit_private void +terminal_clear_screen(EditLine *el) { /* clear the whole screen and home */ if (GoodStr(T_cl)) /* send the clear screen code */ - term_tputs(el, Str(T_cl), Val(T_li)); + terminal_tputs(el, Str(T_cl), Val(T_li)); else if (GoodStr(T_ho) && GoodStr(T_cd)) { - term_tputs(el, Str(T_ho), Val(T_li)); /* home */ + terminal_tputs(el, Str(T_ho), Val(T_li)); /* home */ /* clear to bottom of screen */ - term_tputs(el, Str(T_cd), Val(T_li)); + terminal_tputs(el, Str(T_cd), Val(T_li)); } else { - term__putc(el, '\r'); - term__putc(el, '\n'); + terminal__putc(el, '\r'); + terminal__putc(el, '\n'); } } -/* term_beep(): +/* terminal_beep(): * Beep the way the terminal wants us */ -protected void -term_beep(EditLine *el) +libedit_private void +terminal_beep(EditLine *el) { if (GoodStr(T_bl)) /* what termcap says we should use */ - term_tputs(el, Str(T_bl), 1); + terminal_tputs(el, Str(T_bl), 1); else - term__putc(el, '\007'); /* an ASCII bell; ^G */ + terminal__putc(el, '\007'); /* an ASCII bell; ^G */ } -#ifdef notdef -/* term_clear_to_bottom(): - * Clear to the bottom of the screen - */ -protected void -term_clear_to_bottom(EditLine *el) -{ - if (GoodStr(T_cd)) - term_tputs(el, Str(T_cd), Val(T_li)); - else if (GoodStr(T_ce)) - term_tputs(el, Str(T_ce), Val(T_li)); -} -#endif - -protected void -term_get(EditLine *el, const char **term) +libedit_private void +terminal_get(EditLine *el, const char **term) { - *term = el->el_term.t_name; + *term = el->el_terminal.t_name; } -/* term_set(): +/* terminal_set(): * Read in the terminal capabilities from the requested terminal */ -protected int -term_set(EditLine *el, const char *term) +libedit_private int +terminal_set(EditLine *el, const char *term) { int i; char buf[TC_BUFSIZE]; @@ -948,9 +889,9 @@ term_set(EditLine *el, const char *term) if (strcmp(term, "emacs") == 0) el->el_flags |= EDIT_DISABLED; - memset(el->el_term.t_cap, 0, TC_BUFSIZE); + (void) memset(el->el_terminal.t_cap, 0, TC_BUFSIZE); - i = tgetent(el->el_term.t_cap, term); + i = tgetent(el->el_terminal.t_cap, term); if (i <= 0) { if (i == -1) @@ -965,7 +906,7 @@ term_set(EditLine *el, const char *term) Val(T_pt) = Val(T_km) = Val(T_li) = 0; Val(T_xt) = Val(T_MT); for (t = tstr; t->name != NULL; t++) - term_alloc(el, t, NULL); + terminal_alloc(el, t, NULL); } else { /* auto/magic margins */ Val(T_am) = tgetflag("am"); @@ -981,7 +922,7 @@ term_set(EditLine *el, const char *term) Val(T_li) = tgetnum("li"); for (t = tstr; t->name != NULL; t++) { /* XXX: some systems' tgetstr needs non const */ - term_alloc(el, t, tgetstr(strchr(t->name, *t->name), + terminal_alloc(el, t, tgetstr(strchr(t->name, *t->name), &area)); } } @@ -991,28 +932,28 @@ term_set(EditLine *el, const char *term) if (Val(T_li) < 1) Val(T_li) = 24; - el->el_term.t_size.v = Val(T_co); - el->el_term.t_size.h = Val(T_li); + el->el_terminal.t_size.v = Val(T_co); + el->el_terminal.t_size.h = Val(T_li); - term_setflags(el); + terminal_setflags(el); /* get the correct window size */ - (void) term_get_size(el, &lins, &cols); - if (term_change_size(el, lins, cols) == -1) - return (-1); + (void) terminal_get_size(el, &lins, &cols); + if (terminal_change_size(el, lins, cols) == -1) + return -1; (void) sigprocmask(SIG_SETMASK, &oset, NULL); - term_bind_arrow(el); - el->el_term.t_name = term; - return (i <= 0 ? -1 : 0); + terminal_bind_arrow(el); + el->el_terminal.t_name = term; + return i <= 0 ? -1 : 0; } -/* term_get_size(): +/* terminal_get_size(): * Return the new window size in lines and cols, and * true if the size was changed. */ -protected int -term_get_size(EditLine *el, int *lins, int *cols) +libedit_private int +terminal_get_size(EditLine *el, int *lins, int *cols) { *cols = Val(T_co); @@ -1021,7 +962,7 @@ term_get_size(EditLine *el, int *lins, int *cols) #ifdef TIOCGWINSZ { struct winsize ws; - if (ioctl(el->el_infd, TIOCGWINSZ, (ioctl_t) & ws) != -1) { + if (ioctl(el->el_infd, TIOCGWINSZ, &ws) != -1) { if (ws.ws_col) *cols = ws.ws_col; if (ws.ws_row) @@ -1032,7 +973,7 @@ term_get_size(EditLine *el, int *lins, int *cols) #ifdef TIOCGSIZE { struct ttysize ts; - if (ioctl(el->el_infd, TIOCGSIZE, (ioctl_t) & ts) != -1) { + if (ioctl(el->el_infd, TIOCGSIZE, &ts) != -1) { if (ts.ts_cols) *cols = ts.ts_cols; if (ts.ts_lines) @@ -1040,15 +981,15 @@ term_get_size(EditLine *el, int *lins, int *cols) } } #endif - return (Val(T_co) != *cols || Val(T_li) != *lins); + return Val(T_co) != *cols || Val(T_li) != *lins; } -/* term_change_size(): +/* terminal_change_size(): * Change the size of the terminal */ -protected int -term_change_size(EditLine *el, int lins, int cols) +libedit_private int +terminal_change_size(EditLine *el, int lins, int cols) { /* * Just in case @@ -1057,184 +998,190 @@ term_change_size(EditLine *el, int lins, int cols) Val(T_li) = (lins < 1) ? 24 : lins; /* re-make display buffers */ - if (term_rebuffer_display(el) == -1) - return (-1); + if (terminal_rebuffer_display(el) == -1) + return -1; re_clear_display(el); - return (0); + return 0; } -/* term_init_arrow(): +/* terminal_init_arrow(): * Initialize the arrow key bindings from termcap */ -private void -term_init_arrow(EditLine *el) +static void +terminal_init_arrow(EditLine *el) { - fkey_t *arrow = el->el_term.t_fkey; + funckey_t *arrow = el->el_terminal.t_fkey; - arrow[A_K_DN].name = STR("down"); + arrow[A_K_DN].name = L"down"; arrow[A_K_DN].key = T_kd; arrow[A_K_DN].fun.cmd = ED_NEXT_HISTORY; arrow[A_K_DN].type = XK_CMD; - arrow[A_K_UP].name = STR("up"); + arrow[A_K_UP].name = L"up"; arrow[A_K_UP].key = T_ku; arrow[A_K_UP].fun.cmd = ED_PREV_HISTORY; arrow[A_K_UP].type = XK_CMD; - arrow[A_K_LT].name = STR("left"); + arrow[A_K_LT].name = L"left"; arrow[A_K_LT].key = T_kl; arrow[A_K_LT].fun.cmd = ED_PREV_CHAR; arrow[A_K_LT].type = XK_CMD; - arrow[A_K_RT].name = STR("right"); + arrow[A_K_RT].name = L"right"; arrow[A_K_RT].key = T_kr; arrow[A_K_RT].fun.cmd = ED_NEXT_CHAR; arrow[A_K_RT].type = XK_CMD; - arrow[A_K_HO].name = STR("home"); + arrow[A_K_HO].name = L"home"; arrow[A_K_HO].key = T_kh; arrow[A_K_HO].fun.cmd = ED_MOVE_TO_BEG; arrow[A_K_HO].type = XK_CMD; - arrow[A_K_EN].name = STR("end"); + arrow[A_K_EN].name = L"end"; arrow[A_K_EN].key = T_at7; arrow[A_K_EN].fun.cmd = ED_MOVE_TO_END; arrow[A_K_EN].type = XK_CMD; + + arrow[A_K_DE].name = L"delete"; + arrow[A_K_DE].key = T_kD; + arrow[A_K_DE].fun.cmd = ED_DELETE_NEXT_CHAR; + arrow[A_K_DE].type = XK_CMD; } -/* term_reset_arrow(): +/* terminal_reset_arrow(): * Reset arrow key bindings */ -private void -term_reset_arrow(EditLine *el) +static void +terminal_reset_arrow(EditLine *el) { - fkey_t *arrow = el->el_term.t_fkey; - static const Char strA[] = {033, '[', 'A', '\0'}; - static const Char strB[] = {033, '[', 'B', '\0'}; - static const Char strC[] = {033, '[', 'C', '\0'}; - static const Char strD[] = {033, '[', 'D', '\0'}; - static const Char strH[] = {033, '[', 'H', '\0'}; - static const Char strF[] = {033, '[', 'F', '\0'}; - static const Char stOA[] = {033, 'O', 'A', '\0'}; - static const Char stOB[] = {033, 'O', 'B', '\0'}; - static const Char stOC[] = {033, 'O', 'C', '\0'}; - static const Char stOD[] = {033, 'O', 'D', '\0'}; - static const Char stOH[] = {033, 'O', 'H', '\0'}; - static const Char stOF[] = {033, 'O', 'F', '\0'}; - - key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); - key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); - - if (el->el_map.type == MAP_VI) { - key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); - key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); - } + funckey_t *arrow = el->el_terminal.t_fkey; + static const wchar_t strA[] = L"\033[A"; + static const wchar_t strB[] = L"\033[B"; + static const wchar_t strC[] = L"\033[C"; + static const wchar_t strD[] = L"\033[D"; + static const wchar_t strH[] = L"\033[H"; + static const wchar_t strF[] = L"\033[F"; + static const wchar_t stOA[] = L"\033OA"; + static const wchar_t stOB[] = L"\033OB"; + static const wchar_t stOC[] = L"\033OC"; + static const wchar_t stOD[] = L"\033OD"; + static const wchar_t stOH[] = L"\033OH"; + static const wchar_t stOF[] = L"\033OF"; + + keymacro_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); + keymacro_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); + keymacro_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); + keymacro_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); + keymacro_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); + keymacro_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); + keymacro_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); + keymacro_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); + keymacro_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); + keymacro_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); + keymacro_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); + keymacro_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); + + if (el->el_map.type != MAP_VI) + return; + keymacro_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); + keymacro_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); + keymacro_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); + keymacro_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); + keymacro_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); + keymacro_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); + keymacro_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); + keymacro_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); + keymacro_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); + keymacro_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); + keymacro_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); + keymacro_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); } -/* term_set_arrow(): +/* terminal_set_arrow(): * Set an arrow key binding */ -protected int -term_set_arrow(EditLine *el, const Char *name, key_value_t *fun, int type) +libedit_private int +terminal_set_arrow(EditLine *el, const wchar_t *name, keymacro_value_t *fun, + int type) { - fkey_t *arrow = el->el_term.t_fkey; + funckey_t *arrow = el->el_terminal.t_fkey; int i; for (i = 0; i < A_K_NKEYS; i++) - if (Strcmp(name, arrow[i].name) == 0) { + if (wcscmp(name, arrow[i].name) == 0) { arrow[i].fun = *fun; arrow[i].type = type; - return (0); + return 0; } - return (-1); + return -1; } -/* term_clear_arrow(): +/* terminal_clear_arrow(): * Clear an arrow key binding */ -protected int -term_clear_arrow(EditLine *el, const Char *name) +libedit_private int +terminal_clear_arrow(EditLine *el, const wchar_t *name) { - fkey_t *arrow = el->el_term.t_fkey; + funckey_t *arrow = el->el_terminal.t_fkey; int i; for (i = 0; i < A_K_NKEYS; i++) - if (Strcmp(name, arrow[i].name) == 0) { + if (wcscmp(name, arrow[i].name) == 0) { arrow[i].type = XK_NOD; - return (0); + return 0; } - return (-1); + return -1; } -/* term_print_arrow(): +/* terminal_print_arrow(): * Print the arrow key bindings */ -protected void -term_print_arrow(EditLine *el, const Char *name) +libedit_private void +terminal_print_arrow(EditLine *el, const wchar_t *name) { int i; - fkey_t *arrow = el->el_term.t_fkey; + funckey_t *arrow = el->el_terminal.t_fkey; for (i = 0; i < A_K_NKEYS; i++) - if (*name == '\0' || Strcmp(name, arrow[i].name) == 0) + if (*name == '\0' || wcscmp(name, arrow[i].name) == 0) if (arrow[i].type != XK_NOD) - key_kprint(el, arrow[i].name, &arrow[i].fun, - arrow[i].type); + keymacro_kprint(el, arrow[i].name, + &arrow[i].fun, arrow[i].type); } -/* term_bind_arrow(): +/* terminal_bind_arrow(): * Bind the arrow keys */ -protected void -term_bind_arrow(EditLine *el) +libedit_private void +terminal_bind_arrow(EditLine *el) { el_action_t *map; const el_action_t *dmap; int i, j; char *p; - fkey_t *arrow = el->el_term.t_fkey; + funckey_t *arrow = el->el_terminal.t_fkey; /* Check if the components needed are initialized */ - if (el->el_term.t_buf == NULL || el->el_map.key == NULL) + if (el->el_terminal.t_buf == NULL || el->el_map.key == NULL) return; map = el->el_map.type == MAP_VI ? el->el_map.alt : el->el_map.key; dmap = el->el_map.type == MAP_VI ? el->el_map.vic : el->el_map.emacs; - term_reset_arrow(el); + terminal_reset_arrow(el); for (i = 0; i < A_K_NKEYS; i++) { - Char wt_str[VISUAL_WIDTH_MAX]; - Char *px; + wchar_t wt_str[VISUAL_WIDTH_MAX]; + wchar_t *px; size_t n; - p = el->el_term.t_str[arrow[i].key]; + p = el->el_terminal.t_str[arrow[i].key]; if (!p || !*p) continue; for (n = 0; n < VISUAL_WIDTH_MAX && p[n]; ++n) @@ -1254,97 +1201,99 @@ term_bind_arrow(EditLine *el) * unassigned key. */ if (arrow[i].type == XK_NOD) - key_clear(el, map, px); + keymacro_clear(el, map, px); else { if (p[1] && (dmap[j] == map[j] || map[j] == ED_SEQUENCE_LEAD_IN)) { - key_add(el, px, &arrow[i].fun, + keymacro_add(el, px, &arrow[i].fun, arrow[i].type); map[j] = ED_SEQUENCE_LEAD_IN; } else if (map[j] == ED_UNASSIGNED) { - key_clear(el, map, px); + keymacro_clear(el, map, px); if (arrow[i].type == XK_CMD) map[j] = arrow[i].fun.cmd; else - key_add(el, px, &arrow[i].fun, + keymacro_add(el, px, &arrow[i].fun, arrow[i].type); } } } } -/* term_putc(): +/* terminal_putc(): * Add a character */ -private int -term_putc(int c) +static int +terminal_putc(int c) { - if (term_outfile == NULL) + if (terminal_outfile == NULL) return -1; - return fputc(c, term_outfile); + return fputc(c, terminal_outfile); } -private void -term_tputs(EditLine *el, const char *cap, int affcnt) +static void +terminal_tputs(EditLine *el, const char *cap, int affcnt) { #ifdef _REENTRANT - pthread_mutex_lock(&term_mutex); + pthread_mutex_lock(&terminal_mutex); #endif - term_outfile = el->el_outfile; - (void)tputs(cap, affcnt, term_putc); + terminal_outfile = el->el_outfile; + (void)tputs(cap, affcnt, terminal_putc); #ifdef _REENTRANT - pthread_mutex_unlock(&term_mutex); + pthread_mutex_unlock(&terminal_mutex); #endif } -/* term__putc(): +/* terminal__putc(): * Add a character */ -protected int -term__putc(EditLine *el, Int c) +libedit_private int +terminal__putc(EditLine *el, wint_t c) { char buf[MB_LEN_MAX +1]; ssize_t i; - if (c == MB_FILL_CHAR) + if (c == (wint_t)MB_FILL_CHAR) return 0; - i = ct_encode_char(buf, MB_LEN_MAX, c); + i = ct_encode_char(buf, (size_t)MB_LEN_MAX, c); if (i <= 0) return (int)i; buf[i] = '\0'; return fputs(buf, el->el_outfile); } -/* term__flush(): +/* terminal__flush(): * Flush output */ -protected void -term__flush(EditLine *el) +libedit_private void +terminal__flush(EditLine *el) { (void) fflush(el->el_outfile); } -/* term_writec(): +/* terminal_writec(): * Write the given character out, in a human readable form */ -protected void -term_writec(EditLine *el, Int c) +libedit_private void +terminal_writec(EditLine *el, wint_t c) { - Char visbuf[VISUAL_WIDTH_MAX +1]; + wchar_t visbuf[VISUAL_WIDTH_MAX +1]; ssize_t vcnt = ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c); + if (vcnt < 0) + vcnt = 0; visbuf[vcnt] = '\0'; - term_overwrite(el, visbuf, (size_t)vcnt); - term__flush(el); + terminal_overwrite(el, visbuf, (size_t)vcnt); + terminal__flush(el); } -/* term_telltc(): +/* terminal_telltc(): * Print the current termcap characteristics */ -protected int +libedit_private int /*ARGSUSED*/ -term_telltc(EditLine *el, int argc __attribute__((__unused__)), - const Char **argv __attribute__((__unused__))) +terminal_telltc(EditLine *el, int argc __attribute__((__unused__)), + const wchar_t **argv __attribute__((__unused__))) { const struct termcapstr *t; char **ts; @@ -1363,12 +1312,12 @@ term_telltc(EditLine *el, int argc __attribute__((__unused__)), (void) fprintf(el->el_outfile, "\tIt %s magic margins\n", EL_HAS_MAGIC_MARGINS ? "has" : "does not have"); - for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++) { + for (t = tstr, ts = el->el_terminal.t_str; t->name != NULL; t++, ts++) { const char *ub; if (*ts && **ts) { ub = ct_encode_string(ct_visual_string( - ct_decode_string(*ts, &el->el_scratch)), - &el->el_scratch); + ct_decode_string(*ts, &el->el_scratch), + &el->el_visual), &el->el_scratch); } else { ub = "(empty)"; } @@ -1376,17 +1325,17 @@ term_telltc(EditLine *el, int argc __attribute__((__unused__)), t->long_name, t->name, ub); } (void) fputc('\n', el->el_outfile); - return (0); + return 0; } -/* term_settc(): +/* terminal_settc(): * Change the current terminal characteristics */ -protected int +libedit_private int /*ARGSUSED*/ -term_settc(EditLine *el, int argc __attribute__((__unused__)), - const Char **argv) +terminal_settc(EditLine *el, int argc __attribute__((__unused__)), + const wchar_t **argv) { const struct termcapstr *ts; const struct termcapval *tv; @@ -1408,8 +1357,8 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), break; if (ts->name != NULL) { - term_alloc(el, ts, how); - term_setflags(el); + terminal_alloc(el, ts, how); + terminal_setflags(el); return 0; } /* @@ -1425,16 +1374,16 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), if (tv == &tval[T_pt] || tv == &tval[T_km] || tv == &tval[T_am] || tv == &tval[T_xn]) { if (strcmp(how, "yes") == 0) - el->el_term.t_val[tv - tval] = 1; + el->el_terminal.t_val[tv - tval] = 1; else if (strcmp(how, "no") == 0) - el->el_term.t_val[tv - tval] = 0; + el->el_terminal.t_val[tv - tval] = 0; else { (void) fprintf(el->el_errfile, - "" FSTR ": Bad value `%s'.\n", argv[0], how); + "%ls: Bad value `%s'.\n", argv[0], how); return -1; } - term_setflags(el); - if (term_change_size(el, Val(T_li), Val(T_co)) == -1) + terminal_setflags(el); + if (terminal_change_size(el, Val(T_li), Val(T_co)) == -1) return -1; return 0; } else { @@ -1444,14 +1393,14 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), i = strtol(how, &ep, 10); if (*ep != '\0') { (void) fprintf(el->el_errfile, - "" FSTR ": Bad value `%s'.\n", argv[0], how); + "%ls: Bad value `%s'.\n", argv[0], how); return -1; } - el->el_term.t_val[tv - tval] = (int) i; - el->el_term.t_size.v = Val(T_co); - el->el_term.t_size.h = Val(T_li); + el->el_terminal.t_val[tv - tval] = (int) i; + el->el_terminal.t_size.v = Val(T_co); + el->el_terminal.t_size.h = Val(T_li); if (tv == &tval[T_co] || tv == &tval[T_li]) - if (term_change_size(el, Val(T_li), Val(T_co)) + if (terminal_change_size(el, Val(T_li), Val(T_co)) == -1) return -1; return 0; @@ -1459,12 +1408,12 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), } -/* term_gettc(): +/* terminal_gettc(): * Get the current terminal characteristics */ -protected int +libedit_private int /*ARGSUSED*/ -term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) +terminal_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) { const struct termcapstr *ts; const struct termcapval *tv; @@ -1472,7 +1421,7 @@ term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) void *how; if (argv == NULL || argv[1] == NULL || argv[2] == NULL) - return (-1); + return -1; what = argv[1]; how = argv[2]; @@ -1485,7 +1434,7 @@ term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) break; if (ts->name != NULL) { - *(char **)how = el->el_term.t_str[ts - tstr]; + *(char **)how = el->el_terminal.t_str[ts - tstr]; return 0; } /* @@ -1502,27 +1451,27 @@ term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) tv == &tval[T_am] || tv == &tval[T_xn]) { static char yes[] = "yes"; static char no[] = "no"; - if (el->el_term.t_val[tv - tval]) + if (el->el_terminal.t_val[tv - tval]) *(char **)how = yes; else *(char **)how = no; return 0; } else { - *(int *)how = el->el_term.t_val[tv - tval]; + *(int *)how = el->el_terminal.t_val[tv - tval]; return 0; } } -/* term_echotc(): +/* terminal_echotc(): * Print the termcap string out with variable substitution */ -protected int +libedit_private int /*ARGSUSED*/ -term_echotc(EditLine *el, int argc __attribute__((__unused__)), - const Char **argv) +terminal_echotc(EditLine *el, int argc __attribute__((__unused__)), + const wchar_t **argv) { char *cap, *scap; - Char *ep; + wchar_t *ep; int arg_need, arg_cols, arg_rows; int verbose = 0, silent = 0; char *area; @@ -1534,7 +1483,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), area = buf; if (argv == NULL || argv[1] == NULL) - return (-1); + return -1; argv++; if (argv[0][0] == '-') { @@ -1552,43 +1501,31 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), argv++; } if (!*argv || *argv[0] == '\0') - return (0); - if (Strcmp(*argv, STR("tabs")) == 0) { + return 0; + if (wcscmp(*argv, L"tabs") == 0) { (void) fprintf(el->el_outfile, fmts, EL_CAN_TAB ? "yes" : "no"); - return (0); - } else if (Strcmp(*argv, STR("meta")) == 0) { + return 0; + } else if (wcscmp(*argv, L"meta") == 0) { (void) fprintf(el->el_outfile, fmts, Val(T_km) ? "yes" : "no"); - return (0); - } else if (Strcmp(*argv, STR("xn")) == 0) { + return 0; + } else if (wcscmp(*argv, L"xn") == 0) { (void) fprintf(el->el_outfile, fmts, EL_HAS_MAGIC_MARGINS ? "yes" : "no"); - return (0); - } else if (Strcmp(*argv, STR("am")) == 0) { + return 0; + } else if (wcscmp(*argv, L"am") == 0) { (void) fprintf(el->el_outfile, fmts, EL_HAS_AUTO_MARGINS ? "yes" : "no"); - return (0); - } else if (Strcmp(*argv, STR("baud")) == 0) { -#ifdef notdef - int i; - - for (i = 0; baud_rate[i].b_name != NULL; i++) - if (el->el_tty.t_speed == baud_rate[i].b_rate) { - (void) fprintf(el->el_outfile, fmts, - baud_rate[i].b_name); - return (0); - } - (void) fprintf(el->el_outfile, fmtd, 0); -#else + return 0; + } else if (wcscmp(*argv, L"baud") == 0) { (void) fprintf(el->el_outfile, fmtd, (int)el->el_tty.t_speed); -#endif - return (0); - } else if (Strcmp(*argv, STR("rows")) == 0 || - Strcmp(*argv, STR("lines")) == 0) { + return 0; + } else if (wcscmp(*argv, L"rows") == 0 || + wcscmp(*argv, L"lines") == 0) { (void) fprintf(el->el_outfile, fmtd, Val(T_li)); - return (0); - } else if (Strcmp(*argv, STR("cols")) == 0) { + return 0; + } else if (wcscmp(*argv, L"cols") == 0) { (void) fprintf(el->el_outfile, fmtd, Val(T_co)); - return (0); + return 0; } /* * Try to use our local definition first @@ -1597,7 +1534,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), for (t = tstr; t->name != NULL; t++) if (strcmp(t->name, ct_encode_string(*argv, &el->el_scratch)) == 0) { - scap = el->el_term.t_str[t - tstr]; + scap = el->el_terminal.t_str[t - tstr]; break; } if (t->name == NULL) { @@ -1607,9 +1544,9 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), if (!scap || scap[0] == '\0') { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Termcap parameter `" FSTR "' not found.\n", + "echotc: Termcap parameter `%ls' not found.\n", *argv); - return (-1); + return -1; } /* * Count home many values we need for this capability. @@ -1650,11 +1587,11 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), if (*argv && *argv[0]) { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Warning: Extra argument `" FSTR "'.\n", + "echotc: Warning: Extra argument `%ls'.\n", *argv); - return (-1); + return -1; } - term_tputs(el, scap, 1); + terminal_tputs(el, scap, 1); break; case 1: argv++; @@ -1662,27 +1599,27 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), if (!silent) (void) fprintf(el->el_errfile, "echotc: Warning: Missing argument.\n"); - return (-1); + return -1; } arg_cols = 0; - i = Strtol(*argv, &ep, 10); + i = wcstol(*argv, &ep, 10); if (*ep != '\0' || i < 0) { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Bad value `" FSTR "' for rows.\n", + "echotc: Bad value `%ls' for rows.\n", *argv); - return (-1); + return -1; } arg_rows = (int) i; argv++; if (*argv && *argv[0]) { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Warning: Extra argument `" FSTR "'.\n", - *argv); - return (-1); + "echotc: Warning: Extra argument `%ls" + "'.\n", *argv); + return -1; } - term_tputs(el, tgoto(scap, arg_cols, arg_rows), 1); + terminal_tputs(el, tgoto(scap, arg_cols, arg_rows), 1); break; default: /* This is wrong, but I will ignore it... */ @@ -1697,15 +1634,15 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), if (!silent) (void) fprintf(el->el_errfile, "echotc: Warning: Missing argument.\n"); - return (-1); + return -1; } - i = Strtol(*argv, &ep, 10); + i = wcstol(*argv, &ep, 10); if (*ep != '\0' || i < 0) { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Bad value `" FSTR "' for cols.\n", + "echotc: Bad value `%ls' for cols.\n", *argv); - return (-1); + return -1; } arg_cols = (int) i; argv++; @@ -1713,33 +1650,33 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), if (!silent) (void) fprintf(el->el_errfile, "echotc: Warning: Missing argument.\n"); - return (-1); + return -1; } - i = Strtol(*argv, &ep, 10); + i = wcstol(*argv, &ep, 10); if (*ep != '\0' || i < 0) { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Bad value `" FSTR "' for rows.\n", + "echotc: Bad value `%ls' for rows.\n", *argv); - return (-1); + return -1; } arg_rows = (int) i; if (*ep != '\0') { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Bad value `" FSTR "'.\n", *argv); - return (-1); + "echotc: Bad value `%ls'.\n", *argv); + return -1; } argv++; if (*argv && *argv[0]) { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Warning: Extra argument `" FSTR "'.\n", - *argv); - return (-1); + "echotc: Warning: Extra argument `%ls" + "'.\n", *argv); + return -1; } - term_tputs(el, tgoto(scap, arg_cols, arg_rows), arg_rows); + terminal_tputs(el, tgoto(scap, arg_cols, arg_rows), arg_rows); break; } - return (0); + return 0; } diff --git a/lib/libedit/src/el_term.h b/lib/libedit/src/terminal.h similarity index 62% rename from lib/libedit/src/el_term.h rename to lib/libedit/src/terminal.h index de9157e8b..ae61beb1e 100644 --- a/lib/libedit/src/el_term.h +++ b/lib/libedit/src/terminal.h @@ -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 */ diff --git a/lib/libedit/src/tokenizer.c b/lib/libedit/src/tokenizer.c index b1d5278d2..18532240d 100644 --- a/lib/libedit/src/tokenizer.c +++ b/lib/libedit/src/tokenizer.c @@ -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 #include +#include + #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); } diff --git a/lib/libedit/src/tokenizern.c b/lib/libedit/src/tokenizern.c new file mode 100644 index 000000000..5846b6064 --- /dev/null +++ b/lib/libedit/src/tokenizern.c @@ -0,0 +1,3 @@ +#include "config.h" +#define NARROWCHAR +#include "tokenizer.c" diff --git a/lib/libedit/src/tty.c b/lib/libedit/src/tty.c index 94d23de23..f524da473 100644 --- a/lib/libedit/src/tty.c +++ b/lib/libedit/src/tty.c @@ -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 #include -#include /* for isatty */ +#include /* for abort */ +#include #include /* for ffs */ +#include /* 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; + + if (!el->el_tty.t_initialized) + return; - /* XXX: Maybe reset to an initial state? */ + 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; - - 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; - - 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; - } + int i; + + for (i = MD_INP; i <= MD_LIN; i++) + tty_update_flags(el, i); + 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; - - 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]); - - 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]); - } + tty_update_char(el, ED_IO, i); + + 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++) + 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); + } +} diff --git a/lib/libedit/src/tty.h b/lib/libedit/src/tty.h index f4b4d42a5..2603e1ad2 100644 --- a/lib/libedit/src/tty.h +++ b/lib/libedit/src/tty.h @@ -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 #include @@ -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; diff --git a/lib/libedit/src/vi.c b/lib/libedit/src/vi.c index fb8ee7203..0c37bfb9b 100644 --- a/lib/libedit/src/vi.c +++ b/lib/libedit/src/vi.c @@ -1,4 +1,4 @@ -/* $NetBSD: vi.c,v 1.34 2011/02/22 05:45:08 joerg Exp $ */ +/* $NetBSD: vi.c,v 1.62 2016/05/09 21:46:56 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -33,37 +33,43 @@ */ #include "config.h" -#include -#include -#include -#include - #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; #else -__RCSID("$NetBSD: vi.c,v 1.34 2011/02/22 05:45:08 joerg Exp $"); +__RCSID("$NetBSD: vi.c,v 1.62 2016/05/09 21:46:56 christos Exp $"); #endif #endif /* not lint && not SCCSID */ /* * vi.c: Vi mode commands. */ +#include +#include +#include +#include +#include +#include + #include "el.h" +#include "common.h" +#include "emacs.h" +#include "fcns.h" +#include "vi.h" -private el_action_t cv_action(EditLine *, Int); -private el_action_t cv_paste(EditLine *, Int); +static el_action_t cv_action(EditLine *, wint_t); +static el_action_t cv_paste(EditLine *, wint_t); /* cv_action(): * Handle vi actions. */ -private el_action_t -cv_action(EditLine *el, Int c) +static el_action_t +cv_action(EditLine *el, wint_t c) { if (el->el_chared.c_vcmd.action != NOP) { /* 'cc', 'dd' and (possibly) friends */ - if (c != el->el_chared.c_vcmd.action) + if (c != (wint_t)el->el_chared.c_vcmd.action) return CC_ERROR; if (!(c & YANK)) @@ -79,26 +85,27 @@ cv_action(EditLine *el, Int c) if (c & INSERT) el->el_map.current = el->el_map.key; - return (CC_REFRESH); + return CC_REFRESH; } el->el_chared.c_vcmd.pos = el->el_line.cursor; el->el_chared.c_vcmd.action = c; - return (CC_ARGHACK); + return CC_ARGHACK; } /* cv_paste(): * Paste previous deletion before or after the cursor */ -private el_action_t -cv_paste(EditLine *el, Int c) +static el_action_t +cv_paste(EditLine *el, wint_t c) { c_kill_t *k = &el->el_chared.c_kill; size_t len = (size_t)(k->last - k->buf); if (k->buf == NULL || len == 0) - return (CC_ERROR); + return CC_ERROR; #ifdef DEBUG_PASTE - (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", (int)len, k->buf); + (void) fprintf(el->el_errfile, "Paste: \"%.*ls\"\n", (int)len, + k->buf); #endif cv_undo(el); @@ -108,11 +115,11 @@ cv_paste(EditLine *el, Int c) c_insert(el, (int)len); if (el->el_line.cursor + len > el->el_line.lastchar) - return (CC_ERROR); + return CC_ERROR; (void) memcpy(el->el_line.cursor, k->buf, len * sizeof(*el->el_line.cursor)); - return (CC_REFRESH); + return CC_REFRESH; } @@ -120,12 +127,12 @@ cv_paste(EditLine *el, Int c) * Vi paste previous deletion to the right of the cursor * [p] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_paste_next(EditLine *el, Int c __attribute__((__unused__))) +vi_paste_next(EditLine *el, wint_t c __attribute__((__unused__))) { - return (cv_paste(el, 0)); + return cv_paste(el, 0); } @@ -133,12 +140,12 @@ vi_paste_next(EditLine *el, Int c __attribute__((__unused__))) * Vi paste previous deletion to the left of the cursor * [P] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_paste_prev(EditLine *el, Int c __attribute__((__unused__))) +vi_paste_prev(EditLine *el, wint_t c __attribute__((__unused__))) { - return (cv_paste(el, 1)); + return cv_paste(el, 1); } @@ -146,13 +153,13 @@ vi_paste_prev(EditLine *el, Int c __attribute__((__unused__))) * Vi move to the previous space delimited word * [B] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_prev_big_word(EditLine *el, Int c __attribute__((__unused__))) +vi_prev_big_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 = cv_prev_word(el->el_line.cursor, el->el_line.buffer, @@ -161,9 +168,9 @@ vi_prev_big_word(EditLine *el, Int c __attribute__((__unused__))) if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -171,13 +178,13 @@ vi_prev_big_word(EditLine *el, Int c __attribute__((__unused__))) * Vi move to the previous word * [b] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_prev_word(EditLine *el, Int c __attribute__((__unused__))) +vi_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 = cv_prev_word(el->el_line.cursor, el->el_line.buffer, @@ -186,9 +193,9 @@ vi_prev_word(EditLine *el, Int c __attribute__((__unused__))) if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -196,13 +203,13 @@ vi_prev_word(EditLine *el, Int c __attribute__((__unused__))) * Vi move to the next space delimited word * [W] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_next_big_word(EditLine *el, Int c __attribute__((__unused__))) +vi_next_big_word(EditLine *el, wint_t c __attribute__((__unused__))) { if (el->el_line.cursor >= el->el_line.lastchar - 1) - return (CC_ERROR); + return CC_ERROR; el->el_line.cursor = cv_next_word(el, el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, cv__isWord); @@ -210,9 +217,9 @@ vi_next_big_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; } @@ -220,13 +227,13 @@ vi_next_big_word(EditLine *el, Int c __attribute__((__unused__))) * Vi move to the next word * [w] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_next_word(EditLine *el, Int c __attribute__((__unused__))) +vi_next_word(EditLine *el, wint_t c __attribute__((__unused__))) { if (el->el_line.cursor >= el->el_line.lastchar - 1) - return (CC_ERROR); + return CC_ERROR; el->el_line.cursor = cv_next_word(el, el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, cv__isword); @@ -234,9 +241,9 @@ vi_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; } @@ -244,21 +251,21 @@ vi_next_word(EditLine *el, Int c __attribute__((__unused__))) * Vi change case of character under the cursor and advance one character * [~] */ -protected el_action_t -vi_change_case(EditLine *el, Int c) +libedit_private el_action_t +vi_change_case(EditLine *el, wint_t c) { int i; if (el->el_line.cursor >= el->el_line.lastchar) - return (CC_ERROR); + return CC_ERROR; cv_undo(el); for (i = 0; i < el->el_state.argument; i++) { c = *el->el_line.cursor; - if (Isupper(c)) - *el->el_line.cursor = Tolower(c); - else if (Islower(c)) - *el->el_line.cursor = Toupper(c); + if (iswupper(c)) + *el->el_line.cursor = towlower(c); + else if (iswlower(c)) + *el->el_line.cursor = towupper(c); if (++el->el_line.cursor >= el->el_line.lastchar) { el->el_line.cursor--; @@ -275,16 +282,16 @@ vi_change_case(EditLine *el, Int c) * Vi change prefix command * [c] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_change_meta(EditLine *el, Int c __attribute__((__unused__))) +vi_change_meta(EditLine *el, wint_t c __attribute__((__unused__))) { /* * Delete with insert == change: first we delete and then we leave in * insert mode. */ - return (cv_action(el, DELETE | INSERT)); + return cv_action(el, DELETE | INSERT); } @@ -292,15 +299,15 @@ vi_change_meta(EditLine *el, Int c __attribute__((__unused__))) * Vi enter insert mode at the beginning of line * [I] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_insert_at_bol(EditLine *el, Int c __attribute__((__unused__))) +vi_insert_at_bol(EditLine *el, wint_t c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; cv_undo(el); el->el_map.current = el->el_map.key; - return (CC_CURSOR); + return CC_CURSOR; } @@ -308,9 +315,9 @@ vi_insert_at_bol(EditLine *el, Int c __attribute__((__unused__))) * Vi replace character under the cursor with the next character typed * [r] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_replace_char(EditLine *el, Int c __attribute__((__unused__))) +vi_replace_char(EditLine *el, wint_t c __attribute__((__unused__))) { if (el->el_line.cursor >= el->el_line.lastchar) @@ -319,7 +326,7 @@ vi_replace_char(EditLine *el, Int c __attribute__((__unused__))) el->el_map.current = el->el_map.key; el->el_state.inputmode = MODE_REPLACE_1; cv_undo(el); - return (CC_ARGHACK); + return CC_ARGHACK; } @@ -327,15 +334,15 @@ vi_replace_char(EditLine *el, Int c __attribute__((__unused__))) * Vi enter replace mode * [R] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_replace_mode(EditLine *el, Int c __attribute__((__unused__))) +vi_replace_mode(EditLine *el, wint_t c __attribute__((__unused__))) { el->el_map.current = el->el_map.key; el->el_state.inputmode = MODE_REPLACE; cv_undo(el); - return (CC_NORM); + return CC_NORM; } @@ -343,14 +350,14 @@ vi_replace_mode(EditLine *el, Int c __attribute__((__unused__))) * Vi replace character under the cursor and enter insert mode * [s] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_substitute_char(EditLine *el, Int c __attribute__((__unused__))) +vi_substitute_char(EditLine *el, wint_t c __attribute__((__unused__))) { c_delafter(el, el->el_state.argument); el->el_map.current = el->el_map.key; - return (CC_REFRESH); + return CC_REFRESH; } @@ -358,9 +365,9 @@ vi_substitute_char(EditLine *el, Int c __attribute__((__unused__))) * Vi substitute entire line * [S] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_substitute_line(EditLine *el, Int c __attribute__((__unused__))) +vi_substitute_line(EditLine *el, wint_t c __attribute__((__unused__))) { cv_undo(el); @@ -368,7 +375,7 @@ vi_substitute_line(EditLine *el, Int c __attribute__((__unused__))) (int)(el->el_line.lastchar - el->el_line.buffer)); (void) em_kill_line(el, 0); el->el_map.current = el->el_map.key; - return (CC_REFRESH); + return CC_REFRESH; } @@ -376,9 +383,9 @@ vi_substitute_line(EditLine *el, Int c __attribute__((__unused__))) * Vi change to end of line * [C] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_change_to_eol(EditLine *el, Int c __attribute__((__unused__))) +vi_change_to_eol(EditLine *el, wint_t c __attribute__((__unused__))) { cv_undo(el); @@ -386,7 +393,7 @@ vi_change_to_eol(EditLine *el, Int c __attribute__((__unused__))) (int)(el->el_line.lastchar - el->el_line.cursor)); (void) ed_kill_line(el, 0); el->el_map.current = el->el_map.key; - return (CC_REFRESH); + return CC_REFRESH; } @@ -394,14 +401,14 @@ vi_change_to_eol(EditLine *el, Int c __attribute__((__unused__))) * Vi enter insert mode * [i] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_insert(EditLine *el, Int c __attribute__((__unused__))) +vi_insert(EditLine *el, wint_t c __attribute__((__unused__))) { el->el_map.current = el->el_map.key; cv_undo(el); - return (CC_NORM); + return CC_NORM; } @@ -409,9 +416,9 @@ vi_insert(EditLine *el, Int c __attribute__((__unused__))) * Vi enter insert mode after the cursor * [a] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_add(EditLine *el, Int c __attribute__((__unused__))) +vi_add(EditLine *el, wint_t c __attribute__((__unused__))) { int ret; @@ -426,7 +433,7 @@ vi_add(EditLine *el, Int c __attribute__((__unused__))) cv_undo(el); - return (ret); + return (el_action_t)ret; } @@ -434,15 +441,15 @@ vi_add(EditLine *el, Int c __attribute__((__unused__))) * Vi enter insert mode at end of line * [A] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_add_at_eol(EditLine *el, Int c __attribute__((__unused__))) +vi_add_at_eol(EditLine *el, wint_t c __attribute__((__unused__))) { el->el_map.current = el->el_map.key; el->el_line.cursor = el->el_line.lastchar; cv_undo(el); - return (CC_CURSOR); + return CC_CURSOR; } @@ -450,12 +457,12 @@ vi_add_at_eol(EditLine *el, Int c __attribute__((__unused__))) * Vi delete prefix command * [d] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_delete_meta(EditLine *el, Int c __attribute__((__unused__))) +vi_delete_meta(EditLine *el, wint_t c __attribute__((__unused__))) { - return (cv_action(el, DELETE)); + return cv_action(el, DELETE); } @@ -463,13 +470,13 @@ vi_delete_meta(EditLine *el, Int c __attribute__((__unused__))) * Vi move to the end of the current space delimited word * [E] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_end_big_word(EditLine *el, Int c) +vi_end_big_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 = cv__endword(el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, cv__isWord); @@ -477,9 +484,9 @@ vi_end_big_word(EditLine *el, Int c) if (el->el_chared.c_vcmd.action != NOP) { el->el_line.cursor++; cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -487,13 +494,13 @@ vi_end_big_word(EditLine *el, Int c) * Vi move to the end of the current word * [e] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_end_word(EditLine *el, Int c __attribute__((__unused__))) +vi_end_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 = cv__endword(el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, cv__isword); @@ -501,9 +508,9 @@ vi_end_word(EditLine *el, Int c __attribute__((__unused__))) if (el->el_chared.c_vcmd.action != NOP) { el->el_line.cursor++; cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -511,9 +518,9 @@ vi_end_word(EditLine *el, Int c __attribute__((__unused__))) * Vi undo last change * [u] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_undo(EditLine *el, Int c __attribute__((__unused__))) +vi_undo(EditLine *el, wint_t c __attribute__((__unused__))) { c_undo_t un = el->el_chared.c_undo; @@ -530,7 +537,7 @@ vi_undo(EditLine *el, Int c __attribute__((__unused__))) el->el_line.cursor = un.buf + un.cursor; el->el_line.lastchar = un.buf + un.len; - return (CC_REFRESH); + return CC_REFRESH; } @@ -538,9 +545,9 @@ vi_undo(EditLine *el, Int c __attribute__((__unused__))) * Vi enter command mode (use alternative key bindings) * [] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_command_mode(EditLine *el, Int c __attribute__((__unused__))) +vi_command_mode(EditLine *el, wint_t c __attribute__((__unused__))) { /* [Esc] cancels pending action */ @@ -555,7 +562,7 @@ vi_command_mode(EditLine *el, Int c __attribute__((__unused__))) if (el->el_line.cursor > el->el_line.buffer) el->el_line.cursor--; #endif - return (CC_CURSOR); + return CC_CURSOR; } @@ -563,8 +570,8 @@ vi_command_mode(EditLine *el, Int c __attribute__((__unused__))) * Vi move to the beginning of line * [0] */ -protected el_action_t -vi_zero(EditLine *el, Int c) +libedit_private el_action_t +vi_zero(EditLine *el, wint_t c) { if (el->el_state.doingarg) @@ -573,27 +580,27 @@ vi_zero(EditLine *el, Int c) el->el_line.cursor = el->el_line.buffer; if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } /* vi_delete_prev_char(): - * Vi move to previous character (backspace) + * Vi move to previous character (backspace) * [^H] in insert mode only */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_delete_prev_char(EditLine *el, Int c __attribute__((__unused__))) +vi_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_delbefore1(el); el->el_line.cursor--; - return (CC_REFRESH); + return CC_REFRESH; } @@ -601,34 +608,34 @@ vi_delete_prev_char(EditLine *el, Int c __attribute__((__unused__))) * Vi list choices for completion or indicate end of file if empty line * [^D] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_list_or_eof(EditLine *el, Int c) +vi_list_or_eof(EditLine *el, wint_t c) { if (el->el_line.cursor == el->el_line.lastchar) { if (el->el_line.cursor == el->el_line.buffer) { - term_writec(el, c); /* then do a EOF */ - return (CC_EOF); + terminal_writec(el, c); /* then do a 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 { #ifdef notyet re_goto_bottom(el); *el->el_line.lastchar = '\0'; /* just in case */ - return (CC_LIST_CHOICES); + return CC_LIST_CHOICES; #else /* * Just complain for now. */ - term_beep(el); - return (CC_ERROR); + terminal_beep(el); + return CC_ERROR; #endif } } @@ -638,11 +645,11 @@ vi_list_or_eof(EditLine *el, Int c) * Vi cut from beginning of line to cursor * [^U] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_kill_line_prev(EditLine *el, Int c __attribute__((__unused__))) +vi_kill_line_prev(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; @@ -651,7 +658,7 @@ vi_kill_line_prev(EditLine *el, Int c __attribute__((__unused__))) el->el_chared.c_kill.last = kp; c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer)); el->el_line.cursor = el->el_line.buffer; /* zap! */ - return (CC_REFRESH); + return CC_REFRESH; } @@ -659,12 +666,12 @@ vi_kill_line_prev(EditLine *el, Int c __attribute__((__unused__))) * Vi search history previous * [?] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_search_prev(EditLine *el, Int c __attribute__((__unused__))) +vi_search_prev(EditLine *el, wint_t c __attribute__((__unused__))) { - return (cv_search(el, ED_SEARCH_PREV_HISTORY)); + return cv_search(el, ED_SEARCH_PREV_HISTORY); } @@ -672,12 +679,12 @@ vi_search_prev(EditLine *el, Int c __attribute__((__unused__))) * Vi search history next * [/] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_search_next(EditLine *el, Int c __attribute__((__unused__))) +vi_search_next(EditLine *el, wint_t c __attribute__((__unused__))) { - return (cv_search(el, ED_SEARCH_NEXT_HISTORY)); + return cv_search(el, ED_SEARCH_NEXT_HISTORY); } @@ -685,15 +692,15 @@ vi_search_next(EditLine *el, Int c __attribute__((__unused__))) * Vi repeat current search in the same search direction * [n] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_repeat_search_next(EditLine *el, Int c __attribute__((__unused__))) +vi_repeat_search_next(EditLine *el, wint_t c __attribute__((__unused__))) { if (el->el_search.patlen == 0) - return (CC_ERROR); + return CC_ERROR; else - return (cv_repeat_srch(el, el->el_search.patdir)); + return cv_repeat_srch(el, el->el_search.patdir); } @@ -702,12 +709,12 @@ vi_repeat_search_next(EditLine *el, Int c __attribute__((__unused__))) * [N] */ /*ARGSUSED*/ -protected el_action_t -vi_repeat_search_prev(EditLine *el, Int c __attribute__((__unused__))) +libedit_private el_action_t +vi_repeat_search_prev(EditLine *el, wint_t c __attribute__((__unused__))) { if (el->el_search.patlen == 0) - return (CC_ERROR); + return CC_ERROR; else return (cv_repeat_srch(el, el->el_search.patdir == ED_SEARCH_PREV_HISTORY ? @@ -719,9 +726,9 @@ vi_repeat_search_prev(EditLine *el, Int c __attribute__((__unused__))) * Vi move to the character specified next * [f] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_next_char(EditLine *el, Int c __attribute__((__unused__))) +vi_next_char(EditLine *el, wint_t c __attribute__((__unused__))) { return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0); } @@ -731,9 +738,9 @@ vi_next_char(EditLine *el, Int c __attribute__((__unused__))) * Vi move to the character specified previous * [F] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_prev_char(EditLine *el, Int c __attribute__((__unused__))) +vi_prev_char(EditLine *el, wint_t c __attribute__((__unused__))) { return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0); } @@ -743,9 +750,9 @@ vi_prev_char(EditLine *el, Int c __attribute__((__unused__))) * Vi move up to the character specified next * [t] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_to_next_char(EditLine *el, Int c __attribute__((__unused__))) +vi_to_next_char(EditLine *el, wint_t c __attribute__((__unused__))) { return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1); } @@ -755,9 +762,9 @@ vi_to_next_char(EditLine *el, Int c __attribute__((__unused__))) * Vi move up to the character specified previous * [T] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_to_prev_char(EditLine *el, Int c __attribute__((__unused__))) +vi_to_prev_char(EditLine *el, wint_t c __attribute__((__unused__))) { return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1); } @@ -767,9 +774,9 @@ vi_to_prev_char(EditLine *el, Int c __attribute__((__unused__))) * Vi repeat current character search in the same search direction * [;] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_repeat_next_char(EditLine *el, Int c __attribute__((__unused__))) +vi_repeat_next_char(EditLine *el, wint_t c __attribute__((__unused__))) { return cv_csearch(el, el->el_search.chadir, el->el_search.chacha, @@ -781,9 +788,9 @@ vi_repeat_next_char(EditLine *el, Int c __attribute__((__unused__))) * Vi repeat current character search in the opposite search direction * [,] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_repeat_prev_char(EditLine *el, Int c __attribute__((__unused__))) +vi_repeat_prev_char(EditLine *el, wint_t c __attribute__((__unused__))) { el_action_t r; int dir = el->el_search.chadir; @@ -799,22 +806,22 @@ vi_repeat_prev_char(EditLine *el, Int c __attribute__((__unused__))) * Vi go to matching () {} or [] * [%] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_match(EditLine *el, Int c) +vi_match(EditLine *el, wint_t c __attribute__((__unused__))) { - const Char match_chars[] = STR("()[]{}"); - Char *cp; + const wchar_t match_chars[] = L"()[]{}"; + wchar_t *cp; size_t delta, i, count; - Char o_ch, c_ch; + wchar_t o_ch, c_ch; *el->el_line.lastchar = '\0'; /* just in case */ - i = Strcspn(el->el_line.cursor, match_chars); + i = wcscspn(el->el_line.cursor, match_chars); o_ch = el->el_line.cursor[i]; if (o_ch == 0) return CC_ERROR; - delta = Strchr(match_chars, o_ch) - match_chars; + delta = (size_t)(wcschr(match_chars, o_ch) - match_chars); c_ch = match_chars[delta ^ 1]; count = 1; delta = 1 - (delta & 1) * 2; @@ -837,18 +844,18 @@ vi_match(EditLine *el, Int c) if (delta > 0) el->el_line.cursor++; cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } /* vi_undo_line(): * Vi undo all changes to line * [U] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_undo_line(EditLine *el, Int c) +vi_undo_line(EditLine *el, wint_t c __attribute__((__unused__))) { cv_undo(el); @@ -860,9 +867,9 @@ vi_undo_line(EditLine *el, Int c) * [|] * NB netbsd vi goes to screen column 'n', posix says nth character */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_to_column(EditLine *el, Int c) +vi_to_column(EditLine *el, wint_t c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; @@ -874,9 +881,9 @@ vi_to_column(EditLine *el, Int c) * Vi yank to end of line * [Y] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_yank_end(EditLine *el, Int c) +vi_yank_end(EditLine *el, wint_t c __attribute__((__unused__))) { cv_yank(el, el->el_line.cursor, @@ -888,9 +895,9 @@ vi_yank_end(EditLine *el, Int c) * Vi yank * [y] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_yank(EditLine *el, Int c) +vi_yank(EditLine *el, wint_t c __attribute__((__unused__))) { return cv_action(el, YANK); @@ -900,9 +907,9 @@ vi_yank(EditLine *el, Int c) * Vi comment out current command * [#] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_comment_out(EditLine *el, Int c) +vi_comment_out(EditLine *el, wint_t c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; @@ -918,51 +925,42 @@ vi_comment_out(EditLine *el, Int c) * NB: posix implies that we should enter insert mode, however * this is against historical precedent... */ -#undef __weak_reference /* __weak_reference is different on freebsd */ -#ifdef __weak_reference -__weakref_visible char *my_get_alias_text(const char *) - __weak_reference(get_alias_text); -#endif -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_alias(EditLine *el, Int c) +vi_alias(EditLine *el, wint_t c __attribute__((__unused__))) { -#ifdef __weak_reference char alias_name[3]; - char *alias_text; + const char *alias_text; - if (my_get_alias_text == 0) { + if (el->el_chared.c_aliasfun == NULL) return CC_ERROR; - } alias_name[0] = '_'; alias_name[2] = 0; if (el_getc(el, &alias_name[1]) != 1) return CC_ERROR; - alias_text = my_get_alias_text(alias_name); + alias_text = (*el->el_chared.c_aliasfun)(el->el_chared.c_aliasarg, + alias_name); if (alias_text != NULL) - FUN(el,push)(el, ct_decode_string(alias_text, &el->el_scratch)); + el_wpush(el, ct_decode_string(alias_text, &el->el_scratch)); return CC_NORM; -#else - return CC_ERROR; -#endif } /* vi_to_history_line(): * Vi go to specified history file line. * [G] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_to_history_line(EditLine *el, Int c) +vi_to_history_line(EditLine *el, wint_t c __attribute__((__unused__))) { int sv_event_no = el->el_history.eventno; el_action_t rval; 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); @@ -998,18 +996,18 @@ vi_to_history_line(EditLine *el, Int c) * Vi edit history line with vi * [v] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_histedit(EditLine *el, Int c) +vi_histedit(EditLine *el, wint_t c __attribute__((__unused__))) { int fd; pid_t pid; ssize_t st; int status; char tempfile[] = "/tmp/histedit.XXXXXXXXXX"; - char *cp; + char *cp = NULL; size_t len; - Char *line; + wchar_t *line = NULL; if (el->el_state.doingarg) { if (vi_to_history_line(el, 0) == CC_ERROR) @@ -1021,32 +1019,23 @@ vi_histedit(EditLine *el, Int c) return CC_ERROR; len = (size_t)(el->el_line.lastchar - el->el_line.buffer); #define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX) - cp = el_malloc(TMP_BUFSIZ); - if (cp == NULL) { - unlink(tempfile); - close(fd); - return CC_ERROR; - } - line = el_malloc(len * sizeof(*line)); - if (line == NULL) { - el_free((ptr_t)cp); - return CC_ERROR; - } - Strncpy(line, el->el_line.buffer, len); + cp = el_malloc(TMP_BUFSIZ * sizeof(*cp)); + if (cp == NULL) + goto error; + line = el_malloc(len * sizeof(*line) + 1); + if (line == NULL) + goto error; + wcsncpy(line, el->el_line.buffer, len); line[len] = '\0'; - ct_wcstombs(cp, line, TMP_BUFSIZ - 1); + wcstombs(cp, line, TMP_BUFSIZ - 1); cp[TMP_BUFSIZ - 1] = '\0'; len = strlen(cp); write(fd, cp, len); - write(fd, "\n", 1); + write(fd, "\n", (size_t)1); pid = fork(); switch (pid) { case -1: - close(fd); - unlink(tempfile); - el_free(cp); - el_free(line); - return CC_ERROR; + goto error; case 0: close(fd); execlp("vi", "vi", tempfile, (char *)NULL); @@ -1056,12 +1045,12 @@ vi_histedit(EditLine *el, Int c) while (waitpid(pid, &status, 0) != pid) continue; lseek(fd, (off_t)0, SEEK_SET); - st = read(fd, cp, TMP_BUFSIZ); + st = read(fd, cp, TMP_BUFSIZ - 1); if (st > 0) { - len = (size_t)(el->el_line.lastchar - - el->el_line.buffer); - len = ct_mbstowcs(el->el_line.buffer, cp, len); - if (len > 0 && el->el_line.buffer[len -1] == '\n') + cp[st] = '\0'; + len = (size_t)(el->el_line.limit - el->el_line.buffer); + len = mbstowcs(el->el_line.buffer, cp, len); + if (len > 0 && el->el_line.buffer[len - 1] == '\n') --len; } else @@ -1077,6 +1066,12 @@ vi_histedit(EditLine *el, Int c) unlink(tempfile); /* return CC_REFRESH; */ return ed_newline(el, 0); +error: + el_free(line); + el_free(cp); + close(fd); + unlink(tempfile); + return CC_ERROR; } /* vi_history_word(): @@ -1085,33 +1080,33 @@ vi_histedit(EditLine *el, Int c) * Who knows where this one came from! * '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_' */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_history_word(EditLine *el, Int c) +vi_history_word(EditLine *el, wint_t c __attribute__((__unused__))) { - const Char *wp = HIST_FIRST(el); - const Char *wep, *wsp; + const wchar_t *wp = HIST_FIRST(el); + const wchar_t *wep, *wsp; int len; - Char *cp; - const Char *lim; + wchar_t *cp; + const wchar_t *lim; if (wp == NULL) return CC_ERROR; - wep = wsp = 0; + wep = wsp = NULL; do { - while (Isspace(*wp)) + while (iswspace(*wp)) wp++; if (*wp == 0) break; wsp = wp; - while (*wp && !Isspace(*wp)) + while (*wp && !iswspace(*wp)) wp++; wep = wp; } while ((!el->el_state.doingarg || --el->el_state.argument > 0) && *wp != 0); - if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0)) + if (wsp == NULL || (el->el_state.doingarg && el->el_state.argument != 0)) return CC_ERROR; cv_undo(el); @@ -1135,9 +1130,9 @@ vi_history_word(EditLine *el, Int c) * Vi redo last non-motion command * [.] */ -protected el_action_t +libedit_private el_action_t /*ARGSUSED*/ -vi_redo(EditLine *el, Int c) +vi_redo(EditLine *el, wint_t c __attribute__((__unused__))) { c_redo_t *r = &el->el_chared.c_redo; @@ -1153,10 +1148,10 @@ vi_redo(EditLine *el, Int c) /* sanity */ r->pos = r->lim - 1; r->pos[0] = 0; - FUN(el,push)(el, r->buf); + el_wpush(el, r->buf); } el->el_state.thiscmd = r->cmd; el->el_state.thisch = r->ch; - return (*el->el_map.func[r->cmd])(el, r->ch); + return (*el->el_map.func[r->cmd])(el, r->ch); } -- 2.11.4.GIT