Import libedit 2017-09-05

Obtained from:	NetBSD
This commit is contained in:
Pedro F. Giffuni 2017-09-13 15:57:58 +00:00
parent 70f1d4d70d
commit 8c36b0434c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/NetBSD/libedit/dist/; revision=323545
svn path=/vendor/NetBSD/libedit/2017-09-05/; revision=323546; tag=vendor/NetBSD/libedit/2017-09-05
51 changed files with 3087 additions and 2409 deletions

111
Makefile
View File

@ -1,9 +1,8 @@
# $NetBSD: Makefile,v 1.56 2016/03/02 19:24:20 christos Exp $
# $NetBSD: Makefile,v 1.65 2017/06/30 20:26:52 kre Exp $
# @(#)Makefile 8.1 (Berkeley) 6/4/93
USE_SHLIBDIR= yes
WIDECHAR ?= yes
WARNS?= 5
LIB= edit
@ -15,55 +14,80 @@ COPTS+= -Wunused-parameter
CWARNFLAGS.gcc+= -Wconversion
CWARNFLAGS.clang+= -Wno-cast-qual
OSRCS= chared.c common.c el.c eln.c emacs.c fcns.c filecomplete.c help.c \
hist.c keymacro.c map.c chartype.c \
parse.c prompt.c read.c refresh.c search.c sig.c terminal.c tty.c vi.c
SRCS = chared.c chartype.c common.c el.c eln.c emacs.c filecomplete.c \
hist.c history.c historyn.c keymacro.c literal.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 vi.c
MAN= editline.3 editrc.5
MAN= editline.3 editrc.5 editline.7
MLINKS= editline.3 el_init.3 editline.3 el_end.3 editline.3 el_reset.3 \
editline.3 el_gets.3 editline.3 el_getc.3 editline.3 el_push.3 \
editline.3 el_parse.3 editline.3 el_set.3 editline.3 el_get.3 \
editline.3 el_source.3 editline.3 el_resize.3 editline.3 el_line.3 \
editline.3 el_insertstr.3 editline.3 el_deletestr.3 \
editline.3 history_init.3 editline.3 history_end.3 \
editline.3 history.3 \
editline.3 tok_init.3 editline.3 tok_end.3 editline.3 tok_reset.3 \
editline.3 tok_line.3 editline.3 tok_str.3
MLINKS= \
editline.3 el_deletestr.3 \
editline.3 el_end.3 \
editline.3 el_get.3 \
editline.3 el_getc.3 \
editline.3 el_gets.3 \
editline.3 el_init.3 \
editline.3 el_init_fd.3 \
editline.3 el_insertstr.3 \
editline.3 el_line.3 \
editline.3 el_parse.3 \
editline.3 el_push.3 \
editline.3 el_reset.3 \
editline.3 el_resize.3 \
editline.3 el_set.3 \
editline.3 el_source.3 \
editline.3 history.3 \
editline.3 history_end.3 \
editline.3 history_init.3 \
editline.3 tok_end.3 \
editline.3 tok_init.3 \
editline.3 tok_line.3 \
editline.3 tok_reset.3 \
editline.3 tok_str.3
# For speed and debugging
#SRCS= ${OSRCS} readline.c tokenizer.c history.c
# For protection
SRCS= editline.c readline.c tokenizer.c history.c
.if ${WIDECHAR} == "yes"
SRCS += tokenizern.c historyn.c
CLEANFILES+=tokenizern.c.tmp tokenizern.c historyn.c.tmp historyn.c
CPPFLAGS+=-DWIDECHAR
.endif
MLINKS+= \
editline.3 el_wdeletestr.3 \
editline.3 el_wget.3 \
editline.3 el_wgetc.3 \
editline.3 el_wgets.3 \
editline.3 el_winsertstr.3 \
editline.3 el_wline.3 \
editline.3 el_wparse.3 \
editline.3 el_wpush.3 \
editline.3 el_wset.3 \
editline.3 history_w.3 \
editline.3 history_wend.3 \
editline.3 history_winit.3 \
editline.3 tok_wend.3 \
editline.3 tok_winit.3 \
editline.3 tok_wline.3 \
editline.3 tok_wreset.3 \
editline.3 tok_wstr.3
LIBEDITDIR?=${.CURDIR}
INCS= histedit.h
INCSDIR=/usr/include
CLEANFILES+=editline.c
CLEANFILES+=common.h.tmp editline.c.tmp emacs.h.tmp fcns.c.tmp fcns.h.tmp
CLEANFILES+=help.c.tmp help.h.tmp vi.h.tmp tc1.o tc1
CLEANFILES+=tokenizern.c.tmp tokenizern.c tokenizerw.c.tmp tokenizerw.c
CLEANFILES+=common.h.tmp emacs.h.tmp fcns.h.tmp func.h.tmp
CLEANFILES+=help.h.tmp vi.h.tmp tc1.o tc1 .depend
CPPFLAGS+=-I. -I${LIBEDITDIR}
CPPFLAGS+=-I. -I${.CURDIR}
#CPPFLAGS+=-DDEBUG_TTY -DDEBUG_KEY -DDEBUG_READ -DDEBUG -DDEBUG_REFRESH
#CPPFLAGS+=-DDEBUG_TTY -DDEBUG_KEY -DDEBUG -DDEBUG_REFRESH
#CPPFLAGS+=-DDEBUG_PASTE -DDEBUG_EDIT
AHDR=vi.h emacs.h common.h
ASRC=${LIBEDITDIR}/vi.c ${LIBEDITDIR}/emacs.c ${LIBEDITDIR}/common.c
DPSRCS+= ${AHDR} fcns.h help.h fcns.c help.c
CLEANFILES+= ${AHDR} fcns.h help.h fcns.c help.c
DPSRCS+= ${AHDR} fcns.h func.h help.h
CLEANFILES+= ${AHDR} fcns.h func.h help.h
SUBDIR= readline
.depend: ${AHDR} fcns.h func.h help.h
vi.h: vi.c makelist Makefile
${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/vi.c \
@ -87,36 +111,16 @@ fcns.h: ${AHDR} makelist Makefile
${HOST_SH} ${LIBEDITDIR}/makelist -fh ${AHDR} > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET}
fcns.c: ${AHDR} fcns.h help.h makelist Makefile
func.h: ${AHDR} makelist Makefile
${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -fc ${AHDR} > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET}
help.c: ${ASRC} makelist Makefile
${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -bc ${ASRC} > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET}
help.h: ${ASRC} makelist Makefile
${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -bh ${ASRC} > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET}
editline.c: ${OSRCS} makelist Makefile
${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -e ${OSRCS:T} > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET}
tokenizern.c: makelist Makefile
${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -n tokenizer.c > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET}
historyn.c: makelist Makefile
${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -n history.c > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET}
tc1.o: ${LIBEDITDIR}/TEST/tc1.c
tc1: libedit.a tc1.o
@ -129,6 +133,7 @@ tc1: libedit.a tc1.o
# XXX
.if defined(HAVE_GCC)
COPTS.editline.c+= -Wno-cast-qual
COPTS.literal.c+= -Wno-sign-conversion
COPTS.tokenizer.c+= -Wno-cast-qual
COPTS.tokenizern.c+= -Wno-cast-qual
.endif

View File

@ -1,6 +1,4 @@
# $NetBSD: Makefile,v 1.6 2016/02/15 21:38:07 christos Exp $
WIDECHAR ?= yes
# $NetBSD: Makefile,v 1.7 2016/03/23 22:27:48 christos Exp $
NOMAN=1
PROG=wtc1
@ -8,10 +6,6 @@ CPPFLAGS=-I${.CURDIR}/..
LDADD+=-ledit -ltermlib
DPADD+=${LIBEDIT} ${LIBTERMLIB}
.if "${WIDECHAR}" == "yes"
CPPFLAGS+=-DWIDECHAR
.endif
.ifdef DEBUG
CPPFLAGS+=-DDEBUG
.endif

140
chared.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: chared.c,v 1.49 2016/02/24 14:29:21 christos Exp $ */
/* $NetBSD: chared.c,v 1.56 2016/05/22 19:44:26 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: chared.c,v 1.49 2016/02/24 14:29:21 christos Exp $");
__RCSID("$NetBSD: chared.c,v 1.56 2016/05/22 19:44:26 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -50,8 +50,7 @@ __RCSID("$NetBSD: chared.c,v 1.49 2016/02/24 14:29:21 christos Exp $");
#include "el.h"
#include "common.h"
private void ch__clearmacro (EditLine *);
#include "fcns.h"
/* value to leave unused in line buffer */
#define EL_LEAVE 2
@ -59,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;
@ -83,8 +82,8 @@ 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;
@ -96,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))
@ -118,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)
{
@ -131,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];
@ -144,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];
@ -159,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)
{
@ -172,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;
@ -187,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];
@ -202,22 +201,22 @@ c_delbefore1(EditLine *el)
/* ce__isword():
* Return if p is part of a word according to emacs
*/
protected int
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
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;
}
@ -226,18 +225,18 @@ cv__isword(wint_t p)
/* cv__isWord():
* Return if p is part of a big word according to vi
*/
protected int
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)(wint_t))
libedit_private wchar_t *
c__prev_word(wchar_t *p, wchar_t *low, int n, int (*wtest)(wint_t))
{
p--;
@ -260,8 +259,8 @@ c__prev_word(Char *p, Char *low, int n, int (*wtest)(wint_t))
/* c__next_word():
* Find the next word
*/
protected Char *
c__next_word(Char *p, Char *high, int n, int (*wtest)(wint_t))
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))
@ -278,8 +277,9 @@ c__next_word(Char *p, Char *high, int n, int (*wtest)(wint_t))
/* cv_next_word():
* Find the next word vi style
*/
protected Char *
cv_next_word(EditLine *el, Char *p, Char *high, int n, int (*wtest)(wint_t))
libedit_private wchar_t *
cv_next_word(EditLine *el, wchar_t *p, wchar_t *high, int n,
int (*wtest)(wint_t))
{
int test;
@ -292,7 +292,7 @@ cv_next_word(EditLine *el, Char *p, Char *high, int n, int (*wtest)(wint_t))
* 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++;
}
@ -307,14 +307,14 @@ cv_next_word(EditLine *el, Char *p, Char *high, int n, int (*wtest)(wint_t))
/* cv_prev_word():
* Find the previous word vi style
*/
protected Char *
cv_prev_word(Char *p, Char *low, int n, int (*wtest)(wint_t))
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)
@ -333,7 +333,7 @@ cv_prev_word(Char *p, Char *low, int n, int (*wtest)(wint_t))
/* cv_delfini():
* Finish vi delete action
*/
protected void
libedit_private void
cv_delfini(EditLine *el)
{
int size;
@ -371,15 +371,15 @@ cv_delfini(EditLine *el)
/* cv__endword():
* Go to the end of this word according to vi
*/
protected Char *
cv__endword(Char *p, Char *high, int n, int (*wtest)(wint_t))
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);
@ -393,11 +393,9 @@ cv__endword(Char *p, Char *high, int n, int (*wtest)(wint_t))
/* 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)
@ -449,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;
}
/* 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;
@ -483,28 +476,17 @@ 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(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 = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE);
newsz = sz * 2;
@ -589,7 +571,7 @@ 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(el->el_line.buffer);
@ -604,21 +586,19 @@ ch_end(EditLine *el)
el->el_chared.c_redo.cmd = ED_UNASSIGNED;
el_free(el->el_chared.c_kill.buf);
el->el_chared.c_kill.buf = NULL;
ch_reset(el, 1);
el_free(el->el_chared.c_macro.macro);
el->el_chared.c_macro.macro = NULL;
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 (s == NULL || (len = Strlen(s)) == 0)
if (s == NULL || (len = wcslen(s)) == 0)
return -1;
if (el->el_line.lastchar + len >= el->el_line.limit) {
if (!ch_enlargebufs(el, len))
@ -635,7 +615,7 @@ FUN(el,insertstr)(EditLine *el, const Char *s)
/* el_deletestr():
* Delete num characters before the cursor
*/
public void
void
el_deletestr(EditLine *el, int n)
{
if (n <= 0)
@ -653,7 +633,7 @@ el_deletestr(EditLine *el, int n)
/* el_cursor():
* Move the cursor to the left or the right of the current position
*/
public int
int
el_cursor(EditLine *el, int n)
{
if (n == 0)
@ -672,15 +652,14 @@ el_cursor(EditLine *el, int n)
/* 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)
{
wchar_t wch;
ssize_t len;
Char *cp = el->el_line.buffer, ch;
wchar_t *cp = el->el_line.buffer, ch;
if (prompt) {
len = (ssize_t)Strlen(prompt);
len = (ssize_t)wcslen(prompt);
(void)memcpy(cp, prompt, (size_t)len * sizeof(*cp));
cp += len;
}
@ -692,12 +671,11 @@ c_gets(EditLine *el, Char *buf, const Char *prompt)
el->el_line.lastchar = cp + 1;
re_refresh(el);
if (el_wgetc(el, &wch) != 1) {
if (el_wgetc(el, &ch) != 1) {
ed_end_of_file(el, 0);
len = -1;
break;
}
ch = (Char)wch;
switch (ch) {
@ -739,10 +717,10 @@ 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.
@ -758,7 +736,7 @@ 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;
@ -766,7 +744,7 @@ ch_resizefun(EditLine *el, el_zfunc_t f, void *a)
return 0;
}
protected int
libedit_private int
ch_aliasfun(EditLine *el, el_afunc_t f, void *a)
{
el->el_chared.c_aliasfun = f;

View File

@ -1,4 +1,4 @@
/* $NetBSD: chared.h,v 1.27 2016/02/16 22:53:14 christos Exp $ */
/* $NetBSD: chared.h,v 1.30 2016/05/22 19:44:26 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -40,8 +40,6 @@
#ifndef _h_el_chared
#define _h_el_chared
#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
@ -54,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;
@ -86,16 +77,16 @@ 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 *);
@ -110,7 +101,6 @@ 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;
@ -135,30 +125,31 @@ typedef struct el_chared_t {
#define MODE_REPLACE_1 2
protected int cv__isword(wint_t);
protected int cv__isWord(wint_t);
protected void cv_delfini(EditLine *);
protected Char *cv__endword(Char *, Char *, int, int (*)(wint_t));
protected int ce__isword(wint_t);
protected void cv_undo(EditLine *);
protected void cv_yank(EditLine *, const Char *, int);
protected Char *cv_next_word(EditLine*, Char *, Char *, int, int (*)(wint_t));
protected Char *cv_prev_word(Char *, Char *, int, int (*)(wint_t));
protected Char *c__next_word(Char *, Char *, int, int (*)(wint_t));
protected Char *c__prev_word(Char *, Char *, int, int (*)(wint_t));
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 *);
libedit_private int cv__isword(wint_t);
libedit_private int cv__isWord(wint_t);
libedit_private void cv_delfini(EditLine *);
libedit_private wchar_t *cv__endword(wchar_t *, wchar_t *, int, int (*)(wint_t));
libedit_private int ce__isword(wint_t);
libedit_private void cv_undo(EditLine *);
libedit_private void cv_yank(EditLine *, const wchar_t *, int);
libedit_private wchar_t *cv_next_word(EditLine*, wchar_t *, wchar_t *, int,
int (*)(wint_t));
libedit_private wchar_t *cv_prev_word(wchar_t *, wchar_t *, int, int (*)(wint_t));
libedit_private wchar_t *c__next_word(wchar_t *, wchar_t *, int, int (*)(wint_t));
libedit_private wchar_t *c__prev_word(wchar_t *, wchar_t *, int, int (*)(wint_t));
libedit_private void c_insert(EditLine *, int);
libedit_private void c_delbefore(EditLine *, int);
libedit_private void c_delbefore1(EditLine *);
libedit_private void c_delafter(EditLine *, int);
libedit_private void c_delafter1(EditLine *);
libedit_private int c_gets(EditLine *, wchar_t *, const wchar_t *);
libedit_private int c_hpos(EditLine *);
protected int ch_init(EditLine *);
protected void ch_reset(EditLine *, int);
protected int ch_resizefun(EditLine *, el_zfunc_t, void *);
protected int ch_aliasfun(EditLine *, el_afunc_t, void *);
protected int ch_enlargebufs(EditLine *, size_t);
protected void ch_end(EditLine *);
libedit_private int ch_init(EditLine *);
libedit_private void ch_reset(EditLine *);
libedit_private int ch_resizefun(EditLine *, el_zfunc_t, void *);
libedit_private int ch_aliasfun(EditLine *, el_afunc_t, void *);
libedit_private int ch_enlargebufs(EditLine *, size_t);
libedit_private void ch_end(EditLine *);
#endif /* _h_el_chared */

View File

@ -1,4 +1,4 @@
/* $NetBSD: chartype.c,v 1.23 2016/02/28 23:02:24 christos Exp $ */
/* $NetBSD: chartype.c,v 1.31 2017/01/09 02:54:18 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: chartype.c,v 1.23 2016/02/28 23:02:24 christos Exp $");
__RCSID("$NetBSD: chartype.c,v 1.31 2017/01/09 02:54:18 christos Exp $");
#endif /* not lint && not SCCSID */
#include <ctype.h>
@ -42,8 +42,10 @@ __RCSID("$NetBSD: chartype.c,v 1.23 2016/02/28 23:02:24 christos Exp $");
#define CT_BUFSIZ ((size_t)1024)
#ifdef WIDECHAR
protected int
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;
@ -64,7 +66,7 @@ ct_conv_cbuff_resize(ct_buffer_t *conv, size_t csize)
return 0;
}
protected int
static int
ct_conv_wbuff_resize(ct_buffer_t *conv, size_t wsize)
{
void *p;
@ -86,8 +88,8 @@ ct_conv_wbuff_resize(ct_buffer_t *conv, size_t wsize)
}
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;
@ -116,7 +118,7 @@ ct_encode_string(const Char *s, ct_buffer_t *conv)
return conv->cbuff;
}
public Char *
wchar_t *
ct_decode_string(const char *s, ct_buffer_t *conv)
{
size_t len;
@ -124,7 +126,7 @@ ct_decode_string(const char *s, ct_buffer_t *conv)
if (!s)
return NULL;
len = ct_mbstowcs(NULL, s, (size_t)0);
len = mbstowcs(NULL, s, (size_t)0);
if (len == (size_t)-1)
return NULL;
@ -132,18 +134,18 @@ ct_decode_string(const char *s, ct_buffer_t *conv)
if (ct_conv_wbuff_resize(conv, len + CT_BUFSIZ) == -1)
return NULL;
ct_mbstowcs(conv->wbuff, s, conv->wsize);
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
@ -154,7 +156,7 @@ ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
if (ct_conv_wbuff_resize(conv, bufspace + CT_BUFSIZ) == -1)
return NULL;
wargv = el_malloc((size_t)argc * sizeof(*wargv));
wargv = el_malloc((size_t)(argc + 1) * sizeof(*wargv));
for (i = 0, p = conv->wbuff; i < argc; ++i) {
if (!argv[i]) { /* don't pass null pointers to mbstowcs */
@ -172,13 +174,14 @@ ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
bufspace -= (size_t)bytes;
p += bytes;
}
wargv[i] = NULL;
return wargv;
}
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)
@ -193,96 +196,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;
}
size_t
ct_mbrtowc(wchar_t *wc, const char *s, size_t n)
libedit_private const wchar_t *
ct_visual_string(const wchar_t *s, ct_buffer_t *conv)
{
mbstate_t mbs;
/* This only works because UTF-8 is stateless */
memset(&mbs, 0, sizeof(mbs));
return mbrtowc(wc, s, n, &mbs);
}
#else
size_t
ct_mbrtowc(wchar_t *wc, const char *s, size_t n)
if (s == NULL)
return 0;
if (n == 0)
return (size_t)-2;
if (wc != NULL)
*wc = *s;
return *s != '\0';
}
#endif
protected const Char *
ct_visual_string(const Char *s)
{
static Char *buff = NULL;
static size_t buffsize = 0;
void *p;
Char *dst;
ssize_t used = 0;
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 - (size_t)(dst - buff), *s);
if (used == -1) { /* failed to encode, need more buffer space */
used = dst - buff;
buffsize += CT_BUFSIZ;
p = el_realloc(buff, buffsize * sizeof(*buff));
if (p == NULL)
goto out;
buff = p;
dst = buff + used;
/* don't increment s here - we want to retry it! */
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) {
@ -292,7 +265,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:
@ -300,20 +272,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) {
@ -338,7 +304,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++ = '+';
@ -350,13 +315,6 @@ ct_visual_char(Char *dst, size_t len, Char c)
*dst++ = tohexdigit(((unsigned int) c >> 4) & 0xf);
*dst = tohexdigit(((unsigned int) c ) & 0xf);
return c > 0xffff ? 8 : 7;
#else
*dst++ = '\\';
#define tooctaldigit(v) (Char)((v) + '0')
*dst++ = tooctaldigit(((unsigned int) c >> 6) & 0x7);
*dst++ = tooctaldigit(((unsigned int) c >> 3) & 0x7);
*dst++ = tooctaldigit(((unsigned int) c ) & 0x7);
#endif
/*FALLTHROUGH*/
/* these two should be handled outside this function */
default: /* we should never hit the default */
@ -367,16 +325,16 @@ ct_visual_char(Char *dst, size_t len, Char c)
protected int
ct_chr_class(Char c)
libedit_private int
ct_chr_class(wchar_t c)
{
if (c == '\t')
return CHTYPE_TAB;
else if (c == '\n')
return CHTYPE_NL;
else if (IsASCII(c) && Iscntrl(c))
else if (c < 0x100 && iswcntrl(c))
return CHTYPE_ASCIICTL;
else if (Isprint(c))
else if (iswprint(c))
return CHTYPE_PRINT;
else
return CHTYPE_NONPRINT;

View File

@ -1,4 +1,4 @@
/* $NetBSD: chartype.h,v 1.25 2016/03/07 00:05:20 christos Exp $ */
/* $NetBSD: chartype.h,v 1.35 2017/05/22 19:16:25 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@ -29,14 +29,16 @@
#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__)) && !defined(__OpenBSD__) && !defined(__FreeBSD__)
#if !defined(__NetBSD__) && \
!defined(__sun) && \
!(defined(__APPLE__) && defined(__MACH__)) && \
!defined(__OpenBSD__) && \
!defined(__FreeBSD__) && \
!defined(__DragonFly__)
#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
@ -52,176 +54,53 @@
#warning Build environment does not support non-BMP characters
#endif
#define ct_wctob wctob
#define ct_wctomb wctomb
#define ct_wctomb_reset wctomb(0,0)
#define ct_wcstombs wcstombs
#define ct_mbstowcs mbstowcs
#define Char wchar_t
#define FUN(prefix,rest) prefix ## _w ## rest
#define FUNW(type) type ## _w
#define TYPE(type) type ## W
#define FSTR "%ls"
#define FSTARSTR "%.*ls"
#define STR(x) L ## x
#define UC(c) c
#define Isalpha(x) iswalpha(x)
#define Isalnum(x) iswalnum(x)
#define Isgraph(x) iswgraph(x)
#define Isspace(x) iswspace(x)
#define Isdigit(x) iswdigit(x)
#define Iscntrl(x) iswcntrl(x)
#define Isprint(x) iswprint(x)
#define Isupper(x) iswupper(x)
#define Islower(x) iswlower(x)
#define Toupper(x) towupper(x)
#define Tolower(x) towlower(x)
#define IsASCII(x) (x < 0x100)
#define Strlen(x) wcslen(x)
#define Strchr(s,c) wcschr(s,c)
#define Strrchr(s,c) wcsrchr(s,c)
#define Strstr(s,v) wcsstr(s,v)
#define Strdup(x) wcsdup(x)
#define Strcpy(d,s) wcscpy(d,s)
#define Strncpy(d,s,n) wcsncpy(d,s,n)
#define Strncat(d,s,n) wcsncat(d,s,n)
#define Strcmp(s,v) wcscmp(s,v)
#define Strncmp(s,v,n) wcsncmp(s,v,n)
#define Strcspn(s,r) wcscspn(s,r)
#define Strtol(p,e,b) wcstol(p,e,b)
static inline int
Width(wchar_t c)
{
int w = wcwidth(c);
return w < 0 ? 0 : w;
}
#else /* NARROW */
#define ct_wctob(w) ((int)(w))
#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 FUN(prefix,rest) prefix ## _ ## rest
#define FUNW(type) type
#define TYPE(type) type
#define FSTR "%s"
#define FSTARSTR "%.*s"
#define STR(x) x
#define UC(c) (unsigned char)(c)
#define Isalpha(x) isalpha((unsigned char)x)
#define Isalnum(x) isalnum((unsigned char)x)
#define Isgraph(x) isgraph((unsigned char)x)
#define Isspace(x) isspace((unsigned char)x)
#define Isdigit(x) isdigit((unsigned char)x)
#define Iscntrl(x) iscntrl((unsigned char)x)
#define Isprint(x) isprint((unsigned char)x)
#define Isupper(x) isupper((unsigned char)x)
#define Islower(x) islower((unsigned char)x)
#define Toupper(x) toupper((unsigned char)x)
#define Tolower(x) tolower((unsigned char)x)
#define IsASCII(x) isascii((unsigned char)x)
#define Strlen(x) strlen(x)
#define Strchr(s,c) strchr(s,c)
#define Strrchr(s,c) strrchr(s,c)
#define Strstr(s,v) strstr(s,v)
#define Strdup(x) strdup(x)
#define Strcpy(d,s) strcpy(d,s)
#define Strncpy(d,s,n) strncpy(d,s,n)
#define Strncat(d,s,n) strncat(d,s,n)
#define Strcmp(s,v) strcmp(s,v)
#define Strncmp(s,v,n) strncmp(s,v,n)
#define Strcspn(s,r) strcspn(s,r)
#define Strtol(p,e,b) strtol(p,e,b)
#define Width(c) 1
#endif
#ifdef WIDECHAR
/*
* Conversion buffer
*/
typedef struct ct_buffer_t {
char *cbuff;
size_t csize;
Char *wbuff;
wchar_t *wbuff;
size_t wsize;
} ct_buffer_t;
#define ct_encode_string __ct_encode_string
/* Encode a wide-character string and return the UTF-8 encoded result. */
public char *ct_encode_string(const Char *, ct_buffer_t *);
char *ct_encode_string(const wchar_t *, ct_buffer_t *);
#define ct_decode_string __ct_decode_string
/* Decode a (multi)?byte string and return the wide-character string result. */
public Char *ct_decode_string(const char *, ct_buffer_t *);
wchar_t *ct_decode_string(const char *, ct_buffer_t *);
/* Decode a (multi)?byte argv string array.
* The pointer returned must be free()d when done. */
protected Char **ct_decode_argv(int, const char *[], ct_buffer_t *);
libedit_private wchar_t **ct_decode_argv(int, const char *[], ct_buffer_t *);
/* Resizes the conversion buffer(s) if needed. */
protected int ct_conv_cbuff_resize(ct_buffer_t *, size_t);
protected int ct_conv_wbuff_resize(ct_buffer_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_cbuff_resize(b, s) ((s) == (0))
#define ct_conv_wbuff_resize(b, s) ((s) == (0))
#define ct_encode_char(d, l, s) (*d = s, 1)
#define ct_free_argv(s)
#endif
#ifndef NARROWCHAR
/* Encode a characted into the destination buffer, provided there is sufficent
/* Encode a character into the destination buffer, provided there is sufficient
* buffer space available. Returns the number of bytes used up (zero if the
* character cannot be encoded, -1 if there was not enough space available). */
libedit_private ssize_t ct_encode_char(char *, size_t, wchar_t);
libedit_private size_t ct_enc_width(wchar_t);
/* The maximum buffer size to hold the most unwieldly visual representation,
/* The maximum buffer size to hold the most unwieldy visual representation,
* in this case \U+nnnnn. */
#define VISUAL_WIDTH_MAX ((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 */
@ -235,10 +114,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
size_t ct_mbrtowc(wchar_t *, const char *, size_t);
libedit_private int ct_chr_class(wchar_t c);
#endif /* _chartype_f */

202
common.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: common.c,v 1.40 2016/03/02 19:24:20 christos Exp $ */
/* $NetBSD: common.c,v 1.47 2016/05/22 19:44:26 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: common.c,v 1.40 2016/03/02 19:24:20 christos Exp $");
__RCSID("$NetBSD: common.c,v 1.47 2016/05/22 19:44:26 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -49,6 +49,7 @@ __RCSID("$NetBSD: common.c,v 1.40 2016/03/02 19:24:20 christos Exp $");
#include "el.h"
#include "common.h"
#include "fcns.h"
#include "parse.h"
#include "vi.h"
@ -56,7 +57,7 @@ __RCSID("$NetBSD: common.c,v 1.40 2016/03/02 19:24:20 christos Exp $");
* Indicate end of file
* [^D]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_end_of_file(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -71,7 +72,7 @@ ed_end_of_file(EditLine *el, wint_t c __attribute__((__unused__)))
* Add character to the line
* Insert a character [bound to all insert keys]
*/
protected el_action_t
libedit_private el_action_t
ed_insert(EditLine *el, wint_t c)
{
int count = el->el_state.argument;
@ -91,14 +92,14 @@ ed_insert(EditLine *el, wint_t c)
|| el->el_line.cursor >= el->el_line.lastchar)
c_insert(el, 1);
*el->el_line.cursor++ = (Char)c;
*el->el_line.cursor++ = c;
re_fastaddc(el); /* fast refresh for one char. */
} else {
if (el->el_state.inputmode != MODE_REPLACE_1)
c_insert(el, el->el_state.argument);
while (count-- && el->el_line.cursor < el->el_line.lastchar)
*el->el_line.cursor++ = (Char)c;
*el->el_line.cursor++ = c;
re_refresh(el);
}
@ -113,11 +114,11 @@ ed_insert(EditLine *el, wint_t 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, 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;
@ -141,15 +142,14 @@ ed_delete_prev_word(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
#ifdef DEBUG_EDIT
#define EL el->el_line
(void) fprintf(el->el_errfile,
"\nD(b: %p(" FSTR ") c: %p(" FSTR ") last: %p(" FSTR
") limit: %p(" FSTR ")\n",
"\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
@ -189,11 +189,11 @@ ed_delete_next_char(EditLine *el, wint_t c __attribute__((__unused__)))
* Cut to the end of line
* [^K] [^K]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
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;
@ -210,7 +210,7 @@ ed_kill_line(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -233,7 +233,7 @@ ed_move_to_end(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -242,7 +242,7 @@ ed_move_to_beg(EditLine *el, wint_t c __attribute__((__unused__)))
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);
@ -257,7 +257,7 @@ ed_move_to_beg(EditLine *el, wint_t c __attribute__((__unused__)))
* Exchange the character to the left of the cursor with the one under it
* [^T] [^T]
*/
protected el_action_t
libedit_private el_action_t
ed_transpose_chars(EditLine *el, wint_t c)
{
@ -271,7 +271,7 @@ ed_transpose_chars(EditLine *el, wint_t c)
/* must have at least two chars entered */
c = el->el_line.cursor[-2];
el->el_line.cursor[-2] = el->el_line.cursor[-1];
el->el_line.cursor[-1] = (Char)c;
el->el_line.cursor[-1] = c;
return CC_REFRESH;
} else
return CC_ERROR;
@ -282,11 +282,11 @@ ed_transpose_chars(EditLine *el, wint_t c)
* Move to the right one character
* [^F] [^F]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
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 &&
@ -311,7 +311,7 @@ ed_next_char(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -337,7 +337,7 @@ ed_prev_word(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -362,7 +362,7 @@ ed_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
* Add the next character typed verbatim
* [^V] [^V]
*/
protected el_action_t
libedit_private el_action_t
ed_quoted_insert(EditLine *el, wint_t c)
{
int num;
@ -380,11 +380,11 @@ ed_quoted_insert(EditLine *el, wint_t c)
/* ed_digit():
* Adds to argument or enters a digit
*/
protected el_action_t
libedit_private el_action_t
ed_digit(EditLine *el, wint_t c)
{
if (!Isdigit(c))
if (!iswdigit(c))
return CC_ERROR;
if (el->el_state.doingarg) {
@ -408,11 +408,11 @@ ed_digit(EditLine *el, wint_t c)
* Digit that starts argument
* For ESC-n
*/
protected el_action_t
libedit_private el_action_t
ed_argument_digit(EditLine *el, wint_t c)
{
if (!Isdigit(c))
if (!iswdigit(c))
return CC_ERROR;
if (el->el_state.doingarg) {
@ -432,7 +432,7 @@ ed_argument_digit(EditLine *el, wint_t c)
* Indicates unbound character
* Bound to keys that are not assigned
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_unassigned(EditLine *el __attribute__((__unused__)),
wint_t c __attribute__((__unused__)))
@ -442,17 +442,13 @@ ed_unassigned(EditLine *el __attribute__((__unused__)),
}
/**
** TTY key handling.
**/
/* ed_tty_sigint():
* Tty interrupt character
* [^C]
/* ed_ignore():
* Input characters that have no effect
* [^C ^O ^Q ^S ^Z ^\ ^]] [^C ^O ^Q ^S ^\]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_tty_sigint(EditLine *el __attribute__((__unused__)),
ed_ignore(EditLine *el __attribute__((__unused__)),
wint_t c __attribute__((__unused__)))
{
@ -460,95 +456,11 @@ ed_tty_sigint(EditLine *el __attribute__((__unused__)),
}
/* ed_tty_dsusp():
* Tty delayed suspend character
* [^Y]
*/
protected el_action_t
/*ARGSUSED*/
ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
wint_t 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__)),
wint_t c __attribute__((__unused__)))
{
return CC_NORM;
}
/* ed_tty_sigquit():
* Tty quit character
* [^\]
*/
protected el_action_t
/*ARGSUSED*/
ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
wint_t c __attribute__((__unused__)))
{
return CC_NORM;
}
/* ed_tty_sigtstp():
* Tty suspend character
* [^Z]
*/
protected el_action_t
/*ARGSUSED*/
ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
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__)),
wint_t 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__)),
wint_t c __attribute__((__unused__)))
{
return CC_NORM;
}
/* ed_newline():
* Execute command
* [^J]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_newline(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -564,7 +476,7 @@ ed_newline(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -584,7 +496,7 @@ ed_delete_prev_char(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -599,7 +511,7 @@ ed_clear_screen(EditLine *el, wint_t c __attribute__((__unused__)))
* Redisplay everything
* ^R
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
ed_redisplay(EditLine *el __attribute__((__unused__)),
wint_t c __attribute__((__unused__)))
@ -613,12 +525,12 @@ 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, wint_t c __attribute__((__unused__)))
{
ch_reset(el, 0);
ch_reset(el);
return CC_REFRESH;
}
@ -627,7 +539,7 @@ ed_start_over(EditLine *el, wint_t 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__)),
wint_t c __attribute__((__unused__)))
@ -641,7 +553,7 @@ 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, wint_t c __attribute__((__unused__)))
{
@ -653,7 +565,7 @@ ed_prev_history(EditLine *el, wint_t 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);
@ -678,7 +590,7 @@ ed_prev_history(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -705,11 +617,11 @@ ed_next_history(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
const Char *hp;
const wchar_t *hp;
int h;
int found = 0;
@ -725,7 +637,7 @@ ed_search_prev_history(EditLine *el, wint_t c __attribute__((__unused__)))
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);
@ -746,7 +658,7 @@ ed_search_prev_history(EditLine *el, wint_t 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)) {
@ -773,11 +685,11 @@ ed_search_prev_history(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
const Char *hp;
const wchar_t *hp;
int h;
int found = 0;
@ -801,7 +713,7 @@ ed_search_next_history(EditLine *el, wint_t 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))
@ -827,11 +739,11 @@ ed_search_next_history(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
Char *ptr;
wchar_t *ptr;
int nchars = c_hpos(el);
/*
@ -870,11 +782,11 @@ ed_prev_line(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
Char *ptr;
wchar_t *ptr;
int nchars = c_hpos(el);
/*
@ -904,14 +816,14 @@ ed_next_line(EditLine *el, wint_t c __attribute__((__unused__)))
* Editline extended command
* [M-X] [:]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
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: "));
tmplen = c_gets(el, tmpbuf, L"\n: ");
terminal__putc(el, '\n');
if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)

View File

@ -256,9 +256,6 @@
/* Define to 1 if the system provides the SIZE_MAX constant */
#define HAVE_SIZE_MAX 1
/* Define to 1 if you want wide-character code */
/* #undef WIDECHAR */
/* Define to 1 if on MINIX. */
/* #undef _MINIX */

View File

@ -1,4 +1,4 @@
.\" $NetBSD: editline.3,v 1.88 2016/02/25 14:59:22 wiz Exp $
.\" $NetBSD: editline.3,v 1.98 2017/09/02 06:48:10 wiz Exp $
.\"
.\" Copyright (c) 1997-2014 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -26,7 +26,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd February 24, 2016
.Dd September 1, 2017
.Dt EDITLINE 3
.Os
.Sh NAME
@ -92,11 +92,11 @@
.Ft int
.Fn el_getc "EditLine *e" "char *ch"
.Ft int
.Fn el_wgetc "EditLine *e" "wchar_t *ch"
.Fn el_wgetc "EditLine *e" "wchar_t *wc"
.Ft void
.Fn el_push "EditLine *e" "const char *str"
.Fn el_push "EditLine *e" "const char *mbs"
.Ft void
.Fn el_wpush "EditLine *e" "const wchar_t *str"
.Fn el_wpush "EditLine *e" "const wchar_t *wcs"
.Ft int
.Fn el_parse "EditLine *e" "int argc" "const char *argv[]"
.Ft int
@ -113,7 +113,7 @@
.Fn el_source "EditLine *e" "const char *file"
.Ft void
.Fn el_resize "EditLine *e"
.Fn int
.Ft int
.Fn el_cursor "EditLine *e" "int count"
.Ft const LineInfo *
.Fn el_line "EditLine *e"
@ -250,18 +250,16 @@ The return value may not remain valid across calls to
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 stream written by
.Fn el_wpush
and
.Fn el_push
or from the input queue described in
.Xr editline 7
if that is not empty, and store it in
.Fa ch .
.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 ch .
.Fa wc .
Returns 1 if a valid character was read, 0 on end of file, or \-1 on
.Xr read 2
failure.
@ -284,17 +282,23 @@ to
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
Pushes
.Fa str
back onto the input stream.
This is used by the macro expansion mechanism.
Refer to the description of
.Ic bind
.Fl s
in
.Xr editrc 5
for more information.
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
@ -354,6 +358,8 @@ 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.
Note that the literal escape character cannot be the last character in the
prompt, as the escape sequence is attached to the next character in the prompt.
.Dv 0
unsets it.
.It Dv EL_REFRESH
@ -503,18 +509,31 @@ unbuffered mode is disabled (the default).
In unbuffered mode,
.Fn el_gets
will return immediately after processing a single character.
.It Dv EL_GETCFN , Fa "int (*f)(EditLine *, char *c)"
Define the character reading function as
.Fa f ,
which is to return the number of characters read and store them in
.Fa c .
This function is called internally by
.Fn el_gets
.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 .
The builtin function can be set or restored with the special function
name
.Dq Dv EL_BUILTIN_GETCFN .
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
@ -558,7 +577,7 @@ are supported, along with actual type of
.Bl -tag -width 4n
.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
Set
.Fa f .
.Fa f
to a pointer to the function that displays the prompt.
If
.Fa c
@ -567,7 +586,7 @@ is not
set it to the start/stop literal prompt character.
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
Set
.Fa f .
.Fa f
to a pointer to the function that displays the prompt.
If
.Fa c
@ -592,7 +611,7 @@ to the current value of that capability.
.It Dv EL_SIGNAL , Fa "int *s"
Set
.Fa s
to non zero if
to non-zero if
.Nm
has installed private signal handlers (see
.Fn el_get
@ -601,10 +620,12 @@ above).
Set
.Fa c
to non-zero if editing is enabled.
.It Dv EL_GETCFN , Fa "int (**f)(EditLine *, char *)"
Return a pointer to the function that read characters, which is equal to
.Dq Dv EL_BUILTIN_GETCFN
in the case of the default builtin function.
.It Dv EL_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
@ -648,6 +669,8 @@ If
is
.Dv NULL ,
try
.Pa $EDITRC
and if that is not set
.Pa $HOME/.editrc .
Refer to
.Xr editrc 5
@ -761,11 +784,13 @@ Return the first element in the history.
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
.It Dv H_SET , Fa "int position"
Set the cursor to point to the requested element.
.It Dv H_ADD , Fa "const char *str"
Append
@ -818,6 +843,13 @@ Save the history list to the opened
.Ft FILE
pointer
.Fa fp .
.It Dv H_NSAVE_FP , Fa "size_t n" , Fa "FILE *fp"
Save the last
.Ft n
history entries 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.
@ -828,14 +860,14 @@ be entered into the history.
Delete the event numbered
.Fa e .
This function is only provided for
.Xr readline 3
.Nm readline
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
returns >= 0 if the operation
.Fa op
succeeds.
Otherwise, \-1 is returned and
@ -921,7 +953,8 @@ is a NUL terminated string to tokenize.
.Xr signal 3 ,
.Xr termcap 3 ,
.Xr editrc 5 ,
.Xr termcap 5
.Xr termcap 5 ,
.Xr editline 7
.Sh HISTORY
The
.Nm

935
editline.7 Normal file
View File

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

259
editrc.5
View File

@ -1,4 +1,4 @@
.\" $NetBSD: editrc.5,v 1.29 2014/12/25 13:39:41 wiz Exp $
.\" $NetBSD: editrc.5,v 1.33 2017/06/27 01:22:58 kre Exp $
.\"
.\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -26,7 +26,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd December 25, 2014
.Dd May 22, 2016
.Dt EDITRC 5
.Os
.Sh NAME
@ -88,21 +88,19 @@ shell.
.Pp
The following builtin commands are available:
.Bl -tag -width 4n
.It Ic bind Oo Fl a Oc Oo Fl e Oc Oo Fl k Oc Oo Fl l Oc Oo Fl r Oc \
Oo Fl s Oc Oo Fl v Oc Oo Ar key Oo Ar command Oc Oc
Without options, list all bound keys, and the editor command to which
each is bound.
If
.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 bindings for
.Ar key .
is supplied, show the binding for that key or macro.
If
.Ar key command
is supplied, bind
is supplied, bind the editor
.Ar command
to
.Ar key .
Options include:
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
@ -121,13 +119,15 @@ or
.It Fl l
List all editor commands and a short description of each.
.It Fl r
Remove a key's binding.
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 treated as terminal input when
is taken as a literal string and appended to the input queue whenever
.Ar key
is typed.
Bound keys in
Bound keys and macros in
.Ar command
are themselves reinterpreted, and this continues for ten levels of
interpretation.
@ -137,10 +137,10 @@ Bind all keys to the standard
bindings.
.El
.Pp
.Ar command
may be one of the commands documented in
.Sx "EDITOR COMMANDS"
below, or another key.
The
.Xr editline 7
manual documents all editor commands and contains more information
about macros and the input queue.
.Pp
.Ar key
and
@ -293,225 +293,26 @@ then the character is set to
List the values of all the terminal capabilities (see
.Xr termcap 5 ) .
.El
.Sh EDITOR COMMANDS
The following editor commands are available for use in key bindings:
.\" Section automatically generated with makelist
.Bl -tag -width 4n
.It Ic vi-paste-next
Vi paste previous deletion to the right of the cursor.
.It Ic vi-paste-prev
Vi paste previous deletion to the left of the cursor.
.It Ic vi-prev-big-word
Vi move to the previous space delimited word.
.It Ic vi-prev-word
Vi move to the previous word.
.It Ic vi-next-big-word
Vi move to the next space delimited word.
.It Ic vi-next-word
Vi move to the next word.
.It Ic vi-change-case
Vi change case of character under the cursor and advance one character.
.It Ic vi-change-meta
Vi change prefix command.
.It Ic vi-insert-at-bol
Vi enter insert mode at the beginning of line.
.It Ic vi-replace-char
Vi replace character under the cursor with the next character typed.
.It Ic vi-replace-mode
Vi enter replace mode.
.It Ic vi-substitute-char
Vi replace character under the cursor and enter insert mode.
.It Ic vi-substitute-line
Vi substitute entire line.
.It Ic vi-change-to-eol
Vi change to end of line.
.It Ic vi-insert
Vi enter insert mode.
.It Ic vi-add
Vi enter insert mode after the cursor.
.It Ic vi-add-at-eol
Vi enter insert mode at end of line.
.It Ic vi-delete-meta
Vi delete prefix command.
.It Ic vi-end-big-word
Vi move to the end of the current space delimited word.
.It Ic vi-end-word
Vi move to the end of the current word.
.It Ic vi-undo
Vi undo last change.
.It Ic vi-command-mode
Vi enter command mode (use alternative key bindings).
.It Ic vi-zero
Vi move to the beginning of line.
.It Ic vi-delete-prev-char
Vi move to previous character (backspace).
.It Ic vi-list-or-eof
Vi list choices for completion or indicate end of file if empty line.
.It Ic vi-kill-line-prev
Vi cut from beginning of line to cursor.
.It Ic vi-search-prev
Vi search history previous.
.It Ic vi-search-next
Vi search history next.
.It Ic vi-repeat-search-next
Vi repeat current search in the same search direction.
.It Ic vi-repeat-search-prev
Vi repeat current search in the opposite search direction.
.It Ic vi-next-char
Vi move to the character specified next.
.It Ic vi-prev-char
Vi move to the character specified previous.
.It Ic vi-to-next-char
Vi move up to the character specified next.
.It Ic vi-to-prev-char
Vi move up to the character specified previous.
.It Ic vi-repeat-next-char
Vi repeat current character search in the same search direction.
.It Ic vi-repeat-prev-char
Vi repeat current character search in the opposite search direction.
.It Ic vi-match
Vi go to matching () {} or [].
.It Ic vi-undo-line
Vi undo all changes to line.
.It Ic vi-to-column
Vi go to specified column.
.It Ic vi-yank-end
Vi yank to end of line.
.It Ic vi-yank
Vi yank.
.It Ic vi-comment-out
Vi comment out current command.
.It Ic vi-alias
Vi include shell alias.
.It Ic vi-to-history-line
Vi go to specified history file line..
.It Ic vi-histedit
Vi edit history line with vi.
.It Ic vi-history-word
Vi append word from previous input line.
.It Ic vi-redo
Vi redo last non-motion command.
.It Ic em-delete-or-list
Delete character under cursor or list completions if at end of line.
.It Ic em-delete-next-word
Cut from cursor to end of current word.
.It Ic em-yank
Paste cut buffer at cursor position.
.It Ic em-kill-line
Cut the entire line and save in cut buffer.
.It Ic em-kill-region
Cut area between mark and cursor and save in cut buffer.
.It Ic em-copy-region
Copy area between mark and cursor to cut buffer.
.It Ic em-gosmacs-transpose
Exchange the two characters before the cursor.
.It Ic em-next-word
Move next to end of current word.
.It Ic em-upper-case
Uppercase the characters from cursor to end of current word.
.It Ic em-capitol-case
Capitalize the characters from cursor to end of current word.
.It Ic em-lower-case
Lowercase the characters from cursor to end of current word.
.It Ic em-set-mark
Set the mark at cursor.
.It Ic em-exchange-mark
Exchange the cursor and mark.
.It Ic em-universal-argument
Universal argument (argument times 4).
.It Ic em-meta-next
Add 8th bit to next character typed.
.It Ic em-toggle-overwrite
Switch from insert to overwrite mode or vice versa.
.It Ic em-copy-prev-word
Copy current word to cursor.
.It Ic em-inc-search-next
Emacs incremental next search.
.It Ic em-inc-search-prev
Emacs incremental reverse search.
.It Ic ed-end-of-file
Indicate end of file.
.It Ic ed-insert
Add character to the line.
.It Ic ed-delete-prev-word
Delete from beginning of current word to cursor.
.It Ic ed-delete-next-char
Delete character under cursor.
.It Ic ed-kill-line
Cut to the end of line.
.It Ic ed-move-to-end
Move cursor to the end of line.
.It Ic ed-move-to-beg
Move cursor to the beginning of line.
.It Ic ed-transpose-chars
Exchange the character to the left of the cursor with the one under it.
.It Ic ed-next-char
Move to the right one character.
.It Ic ed-prev-word
Move to the beginning of the current word.
.It Ic ed-prev-char
Move to the left one character.
.It Ic ed-quoted-insert
Add the next character typed verbatim.
.It Ic ed-digit
Adds to argument or enters a digit.
.It Ic ed-argument-digit
Digit that starts argument.
.It Ic ed-unassigned
Indicates unbound character.
.It Ic ed-tty-sigint
Tty interrupt character.
.It Ic ed-tty-dsusp
Tty delayed suspend character.
.It Ic ed-tty-flush-output
Tty flush output characters.
.It Ic ed-tty-sigquit
Tty quit character.
.It Ic ed-tty-sigtstp
Tty suspend character.
.It Ic ed-tty-stop-output
Tty disallow output characters.
.It Ic ed-tty-start-output
Tty allow output characters.
.It Ic ed-newline
Execute command.
.It Ic ed-delete-prev-char
Delete the character to the left of the cursor.
.It Ic ed-clear-screen
Clear screen leaving current line at the top.
.It Ic ed-redisplay
Redisplay everything.
.It Ic ed-start-over
Erase current line and start from scratch.
.It Ic ed-sequence-lead-in
First character in a bound sequence.
.It Ic ed-prev-history
Move to the previous history line.
.It Ic ed-next-history
Move to the next history line.
.It Ic ed-search-prev-history
Search previous in history for a line matching the current.
.It Ic ed-search-next-history
Search next in history for a line matching the current.
.It Ic ed-prev-line
Move up one line.
.It Ic ed-next-line
Move down one line.
.It Ic ed-command
Editline extended command.
.Sh ENVIRONMENT
.Bl -tag -width "~/.editrcXXX"
.It Ev EDITRC
Names the default configuration file for the
.Xr editline 3
library.
.El
.\" End of section automatically generated with makelist
.Sh FILES
.Bl -tag -width "~/.editrcXXX"
.It Pa ~/.editrc
User configuration file for the
Last resort, if no other file is specified,
user configuration file for the
.Xr editline 3
library.
.El
.Sh SEE ALSO
.Xr editline 3 ,
.Xr regex 3 ,
.Xr termcap 5
.Xr termcap 5 ,
.Xr editline 7
.Sh AUTHORS
.An -nosplit
The

141
el.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: el.c,v 1.83 2016/02/24 17:13:22 christos Exp $ */
/* $NetBSD: el.c,v 1.95 2017/09/05 18:07:59 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
#else
__RCSID("$NetBSD: el.c,v 1.83 2016/02/24 17:13:22 christos Exp $");
__RCSID("$NetBSD: el.c,v 1.95 2017/09/05 18:07:59 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -47,30 +47,29 @@ __RCSID("$NetBSD: el.c,v 1.83 2016/02/24 17:13:22 christos Exp $");
#include <sys/types.h>
#include <sys/param.h>
#include <ctype.h>
#include <langinfo.h>
#include <locale.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#ifdef WIDECHAR
#include <locale.h>
#include <langinfo.h>
#endif
#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)
{
return el_init_fd(prog, fin, fout, ferr, fileno(fin), fileno(fout),
fileno(ferr));
}
public EditLine *
el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
int fdin, int fdout, int fderr)
libedit_private EditLine *
el_init_internal(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
int fdin, int fdout, int fderr, int flags)
{
EditLine *el = el_malloc(sizeof(*el));
@ -87,7 +86,7 @@ el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
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;
@ -96,7 +95,7 @@ el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
/*
* Initialize all the modules. Order is important!!!
*/
el->el_flags = 0;
el->el_flags = flags;
if (setlocale(LC_CTYPE, NULL) != NULL){
if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
el->el_flags |= CHARSET_IS_UTF8;
@ -116,16 +115,25 @@ el_init_fd(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);
(void) literal_init(el);
if (read_init(el) == -1) {
el_end(el);
return NULL;
}
return el;
}
EditLine *
el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr,
int fdin, int fdout, int fderr)
{
return el_init_internal(prog, fin, fout, ferr, fdin, fdout, fderr, 0);
}
/* el_end():
* Clean up.
*/
public void
void
el_end(EditLine *el)
{
@ -140,18 +148,20 @@ el_end(EditLine *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);
literal_end(el);
el_free(el->el_prog);
#ifdef WIDECHAR
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);
#endif
el_free(el);
}
@ -159,20 +169,20 @@ el_end(EditLine *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;
@ -209,7 +219,7 @@ FUN(el,set)(EditLine *el, int op, ...)
el_pfunc_t p = va_arg(ap, el_pfunc_t);
int c = va_arg(ap, int);
rv = prompt_set(el, p, (Char)c, op, 1);
rv = prompt_set(el, p, (wchar_t)c, op, 1);
break;
}
@ -218,7 +228,7 @@ FUN(el,set)(EditLine *el, int op, ...)
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:
@ -234,36 +244,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 < (int)__arraycount(argv); i++)
if ((argv[i] = va_arg(ap, Char *)) == NULL)
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");
argv[0] = L"telltc";
rv = terminal_telltc(el, i, argv);
break;
case EL_SETTC:
argv[0] = STR("settc");
argv[0] = L"settc";
rv = terminal_settc(el, i, argv);
break;
case EL_ECHOTC:
argv[0] = STR("echotc");
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;
@ -277,8 +287,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);
@ -307,7 +317,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);
rv = el_read_setfn(el->el_read, rc);
break;
}
@ -384,8 +394,8 @@ FUN(el,set)(EditLine *el, int op, ...)
/* 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;
@ -405,14 +415,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:
@ -446,7 +456,7 @@ FUN(el,get)(EditLine *el, int op, ...)
}
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;
@ -497,18 +507,18 @@ FUN(el,get)(EditLine *el, int op, ...)
/* 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;
@ -516,24 +526,28 @@ el_source(EditLine *el, const char *fname)
ssize_t slen;
char *ptr;
char *path = NULL;
const Char *dptr;
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);
if (issetugid())
return -1;
if ((ptr = getenv("HOME")) == NULL)
return -1;
plen += strlen(ptr);
if ((path = el_malloc(plen * sizeof(*path))) == NULL)
return -1;
(void)snprintf(path, plen, "%s%s", ptr, elpath);
fname = path;
if ((fname = getenv("EDITRC")) == NULL) {
static const char elpath[] = "/.editrc";
size_t plen = sizeof(elpath);
if ((ptr = getenv("HOME")) == NULL)
return -1;
plen += strlen(ptr);
if ((path = el_malloc(plen * sizeof(*path))) == NULL)
return -1;
(void)snprintf(path, plen, "%s%s", ptr,
elpath + (*ptr == '\0'));
fname = path;
}
#else
/*
* If issetugid() is missing, always return an error, in order
@ -543,6 +557,9 @@ el_source(EditLine *el, const char *fname)
return -1;
#endif
}
if (fname[0] == '\0')
return -1;
if (fp == NULL)
fp = fopen(fname, "r");
if (fp == NULL) {
@ -562,7 +579,7 @@ el_source(EditLine *el, const char *fname)
if (!dptr)
continue;
/* 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 */
@ -580,7 +597,7 @@ el_source(EditLine *el, const char *fname)
/* el_resize():
* Called from program when terminal is resized
*/
public void
void
el_resize(EditLine *el)
{
int lins, cols;
@ -601,7 +618,7 @@ el_resize(EditLine *el)
/* el_beep():
* Called from the program to beep
*/
public void
void
el_beep(EditLine *el)
{
@ -612,25 +629,25 @@ el_beep(EditLine *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;
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;
}

35
el.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: el.h,v 1.34 2016/02/24 17:13:22 christos Exp $ */
/* $NetBSD: el.h,v 1.43 2017/09/05 18:07:59 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -57,6 +57,7 @@
#define UNBUFFERED 0x08
#define CHARSET_IS_UTF8 0x10
#define NARROW_HISTORY 0x40
#define NO_RESET 0x80
typedef unsigned char el_action_t; /* Index to command array */
@ -66,10 +67,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;
/*
@ -82,7 +83,7 @@ typedef struct el_state_t {
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 */
wchar_t thisch; /* char that generated it */
} el_state_t;
/*
@ -94,19 +95,20 @@ typedef struct el_state_t {
#include "tty.h"
#include "prompt.h"
#include "literal.h"
#include "keymacro.h"
#include "terminal.h"
#include "refresh.h"
#include "chared.h"
#include "search.h"
#include "hist.h"
#include "fcns.h" /* el_func_t is needed for map.h */
#include "map.h"
#include "sig.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 */
@ -114,10 +116,9 @@ 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 */
wint_t **el_display; /* Real screen image = what is there */
wint_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 */
@ -126,21 +127,23 @@ struct editline {
el_refresh_t el_refresh; /* Refresh stuff */
el_prompt_t el_prompt; /* Prompt stuff */
el_prompt_t el_rprompt; /* Prompt stuff */
el_literal_t el_literal; /* prompt literal bits */
el_chared_t el_chared; /* Characted editor stuff */
el_map_t el_map; /* Key mapping stuff */
el_keymacro_t el_keymacro; /* Key binding stuff */
el_history_t el_history; /* History stuff */
el_search_t el_search; /* Search stuff */
el_signal_t el_signal; /* Signal handling stuff */
el_read_t el_read; /* Character reading stuff */
#ifdef WIDECHAR
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 **);
libedit_private EditLine *el_init_internal(const char *, FILE *, FILE *,
FILE *, int, int, int, int);
#ifdef DEBUG
#define EL_ABORT(a) do { \

46
eln.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: eln.c,v 1.28 2016/02/28 23:02:24 christos Exp $ */
/* $NetBSD: eln.c,v 1.34 2016/05/09 21:37:34 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
@ -27,7 +27,7 @@
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: eln.c,v 1.28 2016/02/28 23:02:24 christos Exp $");
__RCSID("$NetBSD: eln.c,v 1.34 2016/05/09 21:37:34 christos Exp $");
#endif /* not lint && not SCCSID */
#include <errno.h>
@ -37,7 +37,7 @@ __RCSID("$NetBSD: eln.c,v 1.28 2016/02/28 23:02:24 christos Exp $");
#include "el.h"
public int
int
el_getc(EditLine *el, char *cp)
{
int num_read;
@ -47,7 +47,7 @@ el_getc(EditLine *el, char *cp)
*cp = '\0';
if (num_read <= 0)
return num_read;
num_read = ct_wctob(wc);
num_read = wctob(wc);
if (num_read == EOF) {
errno = ERANGE;
return -1;
@ -58,8 +58,7 @@ el_getc(EditLine *el, char *cp)
}
#ifdef WIDECHAR
public void
void
el_push(EditLine *el, const char *str)
{
/* Using multibyte->wide string decoding works fine under single-byte
@ -68,7 +67,7 @@ el_push(EditLine *el, const char *str)
}
public const char *
const char *
el_gets(EditLine *el, int *nread)
{
const wchar_t *tmp;
@ -86,24 +85,23 @@ el_gets(EditLine *el, int *nread)
}
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;
@ -172,8 +170,7 @@ el_set(EditLine *el, int op, ...)
if ((argv[i] = va_arg(ap, const char *)) == NULL)
break;
argv[0] = argv[i] = NULL;
wargv = (const wchar_t **)
ct_decode_argv(i + 1, argv, &el->el_lgcyconv);
wargv = (void *)ct_decode_argv(i + 1, argv, &el->el_lgcyconv);
if (!wargv) {
ret = -1;
goto out;
@ -185,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");
wargv[0] = L"telltc";
ret = terminal_telltc(el, i, wargv);
break;
case EL_SETTC:
wargv[0] = STR("settc");
wargv[0] = L"settc";
ret = terminal_settc(el, i, wargv);
break;
case EL_ECHOTC:
wargv[0] = STR("echotc");
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;
}
@ -227,9 +224,9 @@ el_set(EditLine *el, int op, ...)
goto out;
}
/* XXX: The two strdup's leak */
ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]),
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 * */
@ -273,7 +270,7 @@ el_set(EditLine *el, int op, ...)
}
public int
int
el_get(EditLine *el, int op, ...)
{
va_list ap;
@ -366,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);
@ -389,4 +386,3 @@ el_insertstr(EditLine *el, const char *str)
{
return el_winsertstr(el, ct_decode_string(str, &el->el_lgcyconv));
}
#endif /* WIDECHAR */

85
emacs.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: emacs.c,v 1.32 2016/02/16 22:53:14 christos Exp $ */
/* $NetBSD: emacs.c,v 1.36 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: emacs.c,v 1.32 2016/02/16 22:53:14 christos Exp $");
__RCSID("$NetBSD: emacs.c,v 1.36 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -48,12 +48,13 @@ __RCSID("$NetBSD: emacs.c,v 1.32 2016/02/16 22:53:14 christos Exp $");
#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, wint_t c)
{
@ -89,11 +90,11 @@ em_delete_or_list(EditLine *el, wint_t 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, 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;
@ -118,11 +119,11 @@ em_delete_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
* Paste cut buffer at cursor position
* [^Y]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
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;
@ -154,11 +155,11 @@ em_yank(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
Char *kp, *cp;
wchar_t *kp, *cp;
cp = el->el_line.buffer;
kp = el->el_chared.c_kill.buf;
@ -176,11 +177,11 @@ em_kill_line(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
Char *kp, *cp;
wchar_t *kp, *cp;
if (!el->el_chared.c_kill.mark)
return CC_ERROR;
@ -209,11 +210,11 @@ em_kill_region(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
Char *kp, *cp;
wchar_t *kp, *cp;
if (!el->el_chared.c_kill.mark)
return CC_ERROR;
@ -239,7 +240,7 @@ em_copy_region(EditLine *el, wint_t c __attribute__((__unused__)))
* Exchange the two characters before the cursor
* Gosling emacs transpose chars [^T]
*/
protected el_action_t
libedit_private el_action_t
em_gosmacs_transpose(EditLine *el, wint_t c)
{
@ -247,7 +248,7 @@ em_gosmacs_transpose(EditLine *el, wint_t c)
/* must have at least two chars entered */
c = el->el_line.cursor[-2];
el->el_line.cursor[-2] = el->el_line.cursor[-1];
el->el_line.cursor[-1] = (Char)c;
el->el_line.cursor[-1] = c;
return CC_REFRESH;
} else
return CC_ERROR;
@ -258,7 +259,7 @@ em_gosmacs_transpose(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -283,18 +284,18 @@ em_next_word(EditLine *el, wint_t 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, 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)
@ -307,26 +308,26 @@ em_upper_case(EditLine *el, wint_t 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, 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)
@ -339,18 +340,18 @@ em_capitol_case(EditLine *el, wint_t 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, 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)
@ -363,7 +364,7 @@ em_lower_case(EditLine *el, wint_t c __attribute__((__unused__)))
* Set the mark at cursor
* [^@]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_set_mark(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -377,11 +378,11 @@ em_set_mark(EditLine *el, wint_t 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, 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;
@ -394,7 +395,7 @@ em_exchange_mark(EditLine *el, wint_t c __attribute__((__unused__)))
* Universal argument (argument times 4)
* [^U]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__)))
{ /* multiply current argument by 4 */
@ -411,7 +412,7 @@ em_universal_argument(EditLine *el, wint_t c __attribute__((__unused__)))
* Add 8th bit to next character typed
* [<ESC>]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_meta_next(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -424,7 +425,7 @@ em_meta_next(EditLine *el, wint_t c __attribute__((__unused__)))
/* 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, wint_t c __attribute__((__unused__)))
{
@ -438,11 +439,11 @@ em_toggle_overwrite(EditLine *el, wint_t c __attribute__((__unused__)))
/* 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, 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;
@ -465,7 +466,7 @@ em_copy_prev_word(EditLine *el, wint_t c __attribute__((__unused__)))
/* em_inc_search_next():
* Emacs incremental next search
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -478,7 +479,7 @@ em_inc_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
/* em_inc_search_prev():
* Emacs incremental reverse search
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
em_inc_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -492,7 +493,7 @@ em_inc_search_prev(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: filecomplete.c,v 1.40 2016/02/17 19:47:49 christos Exp $ */
/* $NetBSD: filecomplete.c,v 1.45 2017/04/21 05:38:03 abhinav Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: filecomplete.c,v 1.40 2016/02/17 19:47:49 christos Exp $");
__RCSID("$NetBSD: filecomplete.c,v 1.45 2017/04/21 05:38:03 abhinav Exp $");
#endif /* not lint && not SCCSID */
#include <sys/types.h>
@ -49,9 +49,7 @@ __RCSID("$NetBSD: filecomplete.c,v 1.40 2016/02/17 19:47:49 christos Exp $");
#include "el.h"
#include "filecomplete.h"
static const Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@',
'$', '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
static const wchar_t break_chars[] = L" \t\n\"\\'`@$><=;|&{(";
/********************************/
/* completion functions */
@ -356,10 +354,13 @@ _fn_qsort_string_compare(const void *i1, const void *i2)
* num, so the strings are matches[1] *through* matches[num-1].
*/
void
fn_display_match_list (EditLine *el, char **matches, size_t num, size_t width)
fn_display_match_list(EditLine * el, char **matches, size_t num, size_t width,
const char *(*app_func) (const char *))
{
size_t line, lines, col, cols, thisguy;
int screenwidth = el->el_terminal.t_size.h;
if (app_func == NULL)
app_func = append_char_function;
/* Ignore matches[0]. Avoid 1-based array logic below. */
matches++;
@ -387,8 +388,11 @@ fn_display_match_list (EditLine *el, char **matches, size_t num, size_t width)
thisguy = line + col * lines;
if (thisguy >= num)
break;
(void)fprintf(el->el_outfile, "%s%-*s",
col == 0 ? "" : " ", (int)width, matches[thisguy]);
(void)fprintf(el->el_outfile, "%s%s%s",
col == 0 ? "" : " ", matches[thisguy],
append_char_function(matches[thisguy]));
(void)fprintf(el->el_outfile, "%-*s",
(int) (width - strlen(matches[thisguy])), "");
}
(void)fprintf(el->el_outfile, "\n");
}
@ -410,14 +414,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;
@ -435,21 +439,21 @@ 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 = (size_t)(li->cursor - ctemp);
temp = el_malloc((len + 1) * sizeof(*temp));
(void)Strncpy(temp, ctemp, len);
(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);
@ -460,7 +464,7 @@ fn_complete(EditLine *el,
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(
@ -480,12 +484,10 @@ 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 &&
(matches[1] == NULL || strcmp(matches[0], matches[1]) == 0)) {
@ -494,11 +496,10 @@ fn_complete(EditLine *el,
* 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.
@ -538,7 +539,7 @@ fn_complete(EditLine *el,
* add 1 to matches_num for the call.
*/
fn_display_match_list(el, matches,
matches_num+1, maxlen);
matches_num+1, maxlen, app_func);
}
retval = CC_REDISPLAY;
} else if (matches[0][0]) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: filecomplete.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
/* $NetBSD: filecomplete.h,v 1.11 2017/04/21 05:38:03 abhinav Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -34,10 +34,11 @@
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);
void fn_display_match_list(EditLine *, char **, size_t, size_t,
const char *(*)(const char *));
char *fn_tilde_expand(const char *);
char *fn_filename_completion_function(const char *, int);

95
hist.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: hist.c,v 1.24 2016/02/16 22:53:14 christos Exp $ */
/* $NetBSD: hist.c,v 1.32 2017/03/05 19:23:58 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.24 2016/02/16 22:53:14 christos Exp $");
__RCSID("$NetBSD: hist.c,v 1.32 2017/03/05 19:23:58 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -46,13 +46,14 @@ __RCSID("$NetBSD: hist.c,v 1.24 2016/02/16 22:53:14 christos Exp $");
*/
#include <stdlib.h>
#include <string.h>
#include <vis.h>
#include "el.h"
/* hist_init():
* Initialization function.
*/
protected int
libedit_private int
hist_init(EditLine *el)
{
@ -70,7 +71,7 @@ hist_init(EditLine *el)
/* hist_end():
* clean up history;
*/
protected void
libedit_private void
hist_end(EditLine *el)
{
@ -82,7 +83,7 @@ hist_end(EditLine *el)
/* hist_set():
* Set new history interface
*/
protected int
libedit_private int
hist_set(EditLine *el, hist_fun_t fun, void *ptr)
{
@ -96,14 +97,15 @@ hist_set(EditLine *el, hist_fun_t fun, void *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;
size_t blen, hlen;
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);
@ -126,14 +128,16 @@ hist_get(EditLine *el)
return CC_ERROR;
for (h = 1; h < el->el_history.eventno; h++)
if ((hp = HIST_NEXT(el)) == NULL) {
el->el_history.eventno = h;
return CC_ERROR;
}
(void) Strncpy(el->el_line.buffer, hp,
(size_t)(el->el_line.limit - el->el_line.buffer));
el->el_line.buffer[el->el_line.limit - el->el_line.buffer - 1] = '\0';
el->el_line.lastchar = el->el_line.buffer + Strlen(el->el_line.buffer);
if ((hp = HIST_NEXT(el)) == NULL)
goto out;
hlen = wcslen(hp) + 1;
blen = (size_t)(el->el_line.limit - el->el_line.buffer);
if (hlen > blen && !ch_enlargebufs(el, hlen))
goto out;
memcpy(el->el_line.buffer, hp, hlen * sizeof(*hp));
el->el_line.lastchar = el->el_line.buffer + hlen - 1;
if (el->el_line.lastchar > el->el_line.buffer
&& el->el_line.lastchar[-1] == '\n')
@ -149,41 +153,66 @@ hist_get(EditLine *el)
el->el_line.cursor = el->el_line.lastchar;
return CC_REFRESH;
out:
el->el_history.eventno = h;
return CC_ERROR;
}
/* 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;
TYPE(HistEvent) ev;
HistEventW ev;
if (el->el_history.ref == NULL)
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));
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;
num = (int)Strtol(argv[2], NULL, 0);
num = (int)wcstol(argv[2], NULL, 0);
if (Strcmp(argv[1], STR("size")) == 0)
return FUNW(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 FUNW(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;
}
@ -192,11 +221,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)
@ -212,8 +241,7 @@ hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
return 1;
}
#ifdef WIDECHAR
protected wchar_t *
libedit_private wchar_t *
hist_convert(EditLine *el, int fn, void *arg)
{
HistEventW ev;
@ -222,4 +250,3 @@ hist_convert(EditLine *el, int fn, void *arg)
return ct_decode_string((const char *)(const void *)ev.str,
&el->el_scratch);
}
#endif

48
hist.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: hist.h,v 1.18 2016/02/17 19:47:49 christos Exp $ */
/* $NetBSD: hist.h,v 1.23 2017/09/01 10:19:10 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -40,47 +40,41 @@
#ifndef _h_el_hist
#define _h_el_hist
typedef int (*hist_fun_t)(void *, TYPE(HistEvent) *, int, ...);
typedef int (*hist_fun_t)(void *, HistEventW *, int, ...);
typedef struct el_history_t {
Char *buf; /* The history buffer */
wchar_t *buf; /* The history buffer */
size_t sz; /* Size of history buffer */
Char *last; /* The last character */
wchar_t *last; /* The last character */
int eventno; /* Event we are looking for */
void *ref; /* Argument for history fcns */
hist_fun_t fun; /* Event access */
TYPE(HistEvent) ev; /* Event cookie */
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)
#define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL)
#define HIST_PREV(el) HIST_FUN(el, H_PREV, NULL)
#define HIST_SET(el, num) HIST_FUN(el, H_SET, num)
#define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname)
#define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname)
#define HIST_SAVE_FP(el, fp) HIST_FUN(el, H_SAVE_FP, fp)
#define HIST_NSAVE_FP(el, n, fp) HIST_FUN(el, H_NSAVE_FP, n, fp)
#define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL)
#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL)
#define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL)
#define HIST_PREV(el) HIST_FUN(el, H_PREV, NULL)
#define HIST_SET(el, num) HIST_FUN(el, H_SET, num)
#define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname)
#define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname)
#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, void *);
protected int hist_command(EditLine *, int, const Char **);
protected int hist_enlargebuf(EditLine *, size_t, size_t);
#ifdef WIDECHAR
protected wchar_t *hist_convert(EditLine *, int, void *);
#endif
libedit_private int hist_init(EditLine *);
libedit_private void hist_end(EditLine *);
libedit_private el_action_t hist_get(EditLine *);
libedit_private int hist_set(EditLine *, hist_fun_t, void *);
libedit_private int hist_command(EditLine *, int, const wchar_t **);
libedit_private int hist_enlargebuf(EditLine *, size_t, size_t);
libedit_private wchar_t *hist_convert(EditLine *, int, void *);
#endif /* _h_el_hist */

View File

@ -1,4 +1,4 @@
/* $NetBSD: histedit.h,v 1.55 2016/02/17 19:47:49 christos Exp $ */
/* $NetBSD: histedit.h,v 1.57 2017/09/01 10:19:10 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -226,6 +226,7 @@ int history(History *, HistEvent *, int, ...);
#define H_DELDATA 24 /* , int, histdata_t *);*/
#define H_REPLACE 25 /* , const char *, histdata_t); */
#define H_SAVE_FP 26 /* , FILE *); */
#define H_NSAVE_FP 27 /* , size_t, FILE *); */
@ -261,6 +262,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 *);

190
history.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: history.c,v 1.52 2016/02/17 19:47:49 christos Exp $ */
/* $NetBSD: history.c,v 1.58 2017/09/01 10:19:10 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: history.c,v 1.52 2016/02/17 19:47:49 christos Exp $");
__RCSID("$NetBSD: history.c,v 1.58 2017/09/01 10:19:10 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -53,8 +53,44 @@ __RCSID("$NetBSD: history.c,v 1.52 2016/02/17 19:47:49 christos Exp $");
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"
#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) *);
@ -97,19 +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_save_fp(TYPE(History) *, FILE *);
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) *, size_t, 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 *);
/***********************************************************************/
@ -134,23 +171,23 @@ typedef struct history_t {
#define H_UNIQUE 1 /* Store only unique elements */
} history_t;
private int history_def_next(void *, TYPE(HistEvent) *);
private int history_def_first(void *, TYPE(HistEvent) *);
private int history_def_prev(void *, TYPE(HistEvent) *);
private int history_def_last(void *, TYPE(HistEvent) *);
private int history_def_curr(void *, TYPE(HistEvent) *);
private int history_def_set(void *, TYPE(HistEvent) *, const int);
private void history_def_clear(void *, TYPE(HistEvent) *);
private int history_def_enter(void *, TYPE(HistEvent) *, const Char *);
private int history_def_add(void *, TYPE(HistEvent) *, const Char *);
private int history_def_del(void *, 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(void **, 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(void *, 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)
@ -207,7 +244,7 @@ static const Char *const he_errlist[] = {
/* history_def_first():
* Default function to return the first event in the history.
*/
private int
static int
history_def_first(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@ -227,7 +264,7 @@ history_def_first(void *p, TYPE(HistEvent) *ev)
/* history_def_last():
* Default function to return the last event in the history.
*/
private int
static int
history_def_last(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@ -247,7 +284,7 @@ history_def_last(void *p, TYPE(HistEvent) *ev)
/* history_def_next():
* Default function to return the next event in the history.
*/
private int
static int
history_def_next(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@ -272,7 +309,7 @@ history_def_next(void *p, TYPE(HistEvent) *ev)
/* history_def_prev():
* Default function to return the previous event in the history.
*/
private int
static int
history_def_prev(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@ -298,7 +335,7 @@ history_def_prev(void *p, TYPE(HistEvent) *ev)
/* history_def_curr():
* Default function to return the current event in the history.
*/
private int
static int
history_def_curr(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@ -319,7 +356,7 @@ history_def_curr(void *p, TYPE(HistEvent) *ev)
* Default function to set the current event in the history to the
* given one.
*/
private int
static int
history_def_set(void *p, TYPE(HistEvent) *ev, const int n)
{
history_t *h = (history_t *) p;
@ -346,7 +383,7 @@ history_def_set(void *p, TYPE(HistEvent) *ev, const int n)
* Default function to set the current event in the history to the
* n-th one.
*/
private int
static int
history_set_nth(void *p, TYPE(HistEvent) *ev, int n)
{
history_t *h = (history_t *) p;
@ -370,7 +407,7 @@ history_set_nth(void *p, TYPE(HistEvent) *ev, int n)
/* history_def_add():
* Append string to element
*/
private int
static int
history_def_add(void *p, TYPE(HistEvent) *ev, const Char *str)
{
history_t *h = (history_t *) p;
@ -396,7 +433,7 @@ history_def_add(void *p, TYPE(HistEvent) *ev, const Char *str)
}
private int
static int
history_deldata_nth(history_t *h, TYPE(HistEvent) *ev,
int num, void **data)
{
@ -418,7 +455,7 @@ history_deldata_nth(history_t *h, TYPE(HistEvent) *ev,
* Delete element hp of the h list
*/
/* ARGSUSED */
private int
static int
history_def_del(void *p, TYPE(HistEvent) *ev __attribute__((__unused__)),
const int num)
{
@ -436,7 +473,7 @@ history_def_del(void *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)
{
@ -459,7 +496,7 @@ 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;
@ -491,7 +528,7 @@ history_def_insert(history_t *h, TYPE(HistEvent) *ev, const Char *str)
/* history_def_enter():
* Default function to enter an item in the history
*/
private int
static int
history_def_enter(void *p, TYPE(HistEvent) *ev, const Char *str)
{
history_t *h = (history_t *) p;
@ -518,7 +555,7 @@ history_def_enter(void *p, TYPE(HistEvent) *ev, const Char *str)
* Default history initialization function
*/
/* ARGSUSED */
private int
static int
history_def_init(void **p, TYPE(HistEvent) *ev __attribute__((__unused__)), int n)
{
history_t *h = (history_t *) h_malloc(sizeof(*h));
@ -543,7 +580,7 @@ history_def_init(void **p, TYPE(HistEvent) *ev __attribute__((__unused__)), int
/* history_def_clear():
* Default history cleanup function
*/
private void
static void
history_def_clear(void *p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@ -563,7 +600,7 @@ history_def_clear(void *p, TYPE(HistEvent) *ev)
/* history_init():
* Initialization function.
*/
public TYPE(History) *
TYPE(History) *
FUN(history,init)(void)
{
TYPE(HistEvent) ev;
@ -594,7 +631,7 @@ FUN(history,init)(void)
/* history_end():
* clean up history;
*/
public void
void
FUN(history,end)(TYPE(History) *h)
{
TYPE(HistEvent) ev;
@ -610,7 +647,7 @@ 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)
{
@ -630,7 +667,7 @@ history_setsize(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
/* 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) {
@ -649,7 +686,7 @@ history_getsize(TYPE(History) *h, TYPE(HistEvent) *ev)
/* 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)
{
@ -665,7 +702,7 @@ history_setunique(TYPE(History) *h, TYPE(HistEvent) *ev, int uni)
/* 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) {
@ -680,7 +717,7 @@ history_getunique(TYPE(History) *h, TYPE(HistEvent) *ev)
/* history_set_fun():
* Set history functions
*/
private int
static int
history_set_fun(TYPE(History) *h, TYPE(History) *nh)
{
TYPE(HistEvent) ev;
@ -727,7 +764,7 @@ history_set_fun(TYPE(History) *h, TYPE(History) *nh)
/* history_load():
* TYPE(History) load function
*/
private int
static int
history_load(TYPE(History) *h, const char *fname)
{
FILE *fp;
@ -738,7 +775,7 @@ history_load(TYPE(History) *h, const char *fname)
char *ptr;
int i = -1;
TYPE(HistEvent) ev;
#ifdef WIDECHAR
#ifndef NARROWCHAR
static ct_buffer_t conv;
#endif
@ -787,28 +824,36 @@ history_load(TYPE(History) *h, const char *fname)
/* history_save_fp():
* TYPE(History) save function
*/
private int
history_save_fp(TYPE(History) *h, FILE *fp)
static int
history_save_fp(TYPE(History) *h, size_t nelem, FILE *fp)
{
TYPE(HistEvent) ev;
int i = -1, retval;
size_t len, max_size;
char *ptr;
const char *str;
#ifdef WIDECHAR
#ifndef NARROWCHAR
static ct_buffer_t conv;
#endif
if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1)
goto done;
if (fputs(hist_cookie, fp) == EOF)
if (ftell(fp) == 0 && fputs(hist_cookie, fp) == EOF)
goto done;
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++) {
if (nelem != (size_t)-1) {
for (retval = HFIRST(h, &ev); retval != -1 && nelem-- > 0;
retval = HNEXT(h, &ev))
continue;
} else
retval = -1;
if (retval == -1)
retval = HLAST(h, &ev);
for (i = 0; retval != -1; retval = HPREV(h, &ev), i++) {
str = ct_encode_string(ev.str, &conv);
len = strlen(str) * 4 + 1;
if (len > max_size) {
@ -834,7 +879,7 @@ history_save_fp(TYPE(History) *h, FILE *fp)
/* history_save():
* History save function
*/
private int
static int
history_save(TYPE(History) *h, const char *fname)
{
FILE *fp;
@ -843,7 +888,7 @@ history_save(TYPE(History) *h, const char *fname)
if ((fp = fopen(fname, "w")) == NULL)
return -1;
i = history_save_fp(h, fp);
i = history_save_fp(h, (size_t)-1, fp);
(void) fclose(fp);
return i;
@ -853,7 +898,7 @@ history_save(TYPE(History) *h, const char *fname)
/* 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;
@ -867,7 +912,7 @@ history_prev_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
}
private int
static int
history_next_evdata(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d)
{
int retval;
@ -887,7 +932,7 @@ history_next_evdata(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d)
/* 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;
@ -904,7 +949,7 @@ history_next_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
/* 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);
@ -922,7 +967,7 @@ history_prev_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
/* 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);
@ -1031,7 +1076,14 @@ FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...)
break;
case H_SAVE_FP:
retval = history_save_fp(h, va_arg(va, FILE *));
retval = history_save_fp(h, (size_t)-1, va_arg(va, FILE *));
if (retval == -1)
he_seterrev(ev, _HE_HIST_WRITE);
break;
case H_NSAVE_FP:
retval = history_save_fp(h, va_arg(va, size_t),
va_arg(va, FILE *));
if (retval == -1)
he_seterrev(ev, _HE_HIST_WRITE);
break;

3
historyn.c Normal file
View File

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

View File

@ -1,4 +1,4 @@
/* $NetBSD: keymacro.c,v 1.14 2016/02/24 14:25:38 christos Exp $ */
/* $NetBSD: keymacro.c,v 1.23 2016/05/24 15:00:45 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: keymacro.c,v 1.14 2016/02/24 14:25:38 christos Exp $");
__RCSID("$NetBSD: keymacro.c,v 1.23 2016/05/24 15:00:45 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -50,7 +50,7 @@ __RCSID("$NetBSD: keymacro.c,v 1.14 2016/02/24 14:25:38 christos Exp $");
* 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
@ -67,13 +67,14 @@ __RCSID("$NetBSD: keymacro.c,v 1.14 2016/02/24 14:25:38 christos Exp $");
#include <string.h>
#include "el.h"
#include "fcns.h"
/*
* The Nodes of the el->el_keymacro.map. The el->el_keymacro.map is a
* linked list of these node elements
*/
struct keymacro_node_t {
Char ch; /* single character of key */
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 */
@ -81,18 +82,18 @@ struct keymacro_node_t {
struct keymacro_node_t *sibling;/* ptr to another key with same prefix*/
};
private int node_trav(EditLine *, keymacro_node_t *, Char *,
static int node_trav(EditLine *, keymacro_node_t *, wchar_t *,
keymacro_value_t *);
private int node__try(EditLine *, keymacro_node_t *, const Char *,
keymacro_value_t *, int);
private keymacro_node_t *node__get(wint_t);
private void node__free(keymacro_node_t *);
private void node__put(EditLine *, keymacro_node_t *);
private int node__delete(EditLine *, keymacro_node_t **,
const Char *);
private int node_lookup(EditLine *, const Char *,
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);
private int node_enum(EditLine *, keymacro_node_t *, size_t);
static int node_enum(EditLine *, keymacro_node_t *, size_t);
#define KEY_BUFSIZ EL_BUFSIZ
@ -100,7 +101,7 @@ private int node_enum(EditLine *, keymacro_node_t *, size_t);
/* keymacro_init():
* Initialize the key maps
*/
protected int
libedit_private int
keymacro_init(EditLine *el)
{
@ -116,7 +117,7 @@ keymacro_init(EditLine *el)
/* keymacro_end():
* Free the key maps
*/
protected void
libedit_private void
keymacro_end(EditLine *el)
{
@ -129,7 +130,7 @@ keymacro_end(EditLine *el)
/* keymacro_map_cmd():
* Associate cmd with a key value
*/
protected keymacro_value_t *
libedit_private keymacro_value_t *
keymacro_map_cmd(EditLine *el, int cmd)
{
@ -141,8 +142,8 @@ keymacro_map_cmd(EditLine *el, int cmd)
/* keymacro_map_str():
* Associate str with a key value
*/
protected keymacro_value_t *
keymacro_map_str(EditLine *el, Char *str)
libedit_private keymacro_value_t *
keymacro_map_str(EditLine *el, wchar_t *str)
{
el->el_keymacro.val.str = str;
@ -155,7 +156,7 @@ keymacro_map_str(EditLine *el, Char *str)
* Then initializes el->el_keymacro.map with arrow keys
* [Always bind the ansi arrow keys?]
*/
protected void
libedit_private void
keymacro_reset(EditLine *el)
{
@ -169,12 +170,13 @@ keymacro_reset(EditLine *el)
* 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
keymacro_get(EditLine *el, Char *ch, keymacro_value_t *val)
libedit_private int
keymacro_get(EditLine *el, wchar_t *ch, keymacro_value_t *val)
{
return node_trav(el, el->el_keymacro.map, ch, val);
@ -187,8 +189,9 @@ keymacro_get(EditLine *el, Char *ch, keymacro_value_t *val)
* code is applied to the existing key. Ntype specifies if code is a
* command, an out str or a unix command.
*/
protected void
keymacro_add(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
libedit_private void
keymacro_add(EditLine *el, const wchar_t *key, keymacro_value_t *val,
int ntype)
{
if (key[0] == '\0') {
@ -215,13 +218,11 @@ keymacro_add(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
/* keymacro_clear():
*
*/
protected void
keymacro_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) ||
@ -235,8 +236,8 @@ keymacro_clear(EditLine *el, el_action_t *map, const Char *in)
* Delete the key and all longer keys staring with key, if
* they exists.
*/
protected int
keymacro_delete(EditLine *el, const Char *key)
libedit_private int
keymacro_delete(EditLine *el, const wchar_t *key)
{
if (key[0] == '\0') {
@ -256,8 +257,8 @@ keymacro_delete(EditLine *el, const Char *key)
* Print the binding associated with key key.
* Print entire el->el_keymacro.map if null
*/
protected void
keymacro_print(EditLine *el, const Char *key)
libedit_private void
keymacro_print(EditLine *el, const wchar_t *key)
{
/* do nothing if el->el_keymacro.map is empty and null key specified */
@ -267,7 +268,7 @@ keymacro_print(EditLine *el, const Char *key)
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
(void) fprintf(el->el_errfile, "Unbound extended key \"%ls"
"\"\n", key);
return;
}
@ -277,21 +278,17 @@ keymacro_print(EditLine *el, const Char *key)
* recursively traverses node in tree until match or mismatch is
* found. May read in more characters.
*/
private int
node_trav(EditLine *el, keymacro_node_t *ptr, Char *ch, keymacro_value_t *val)
static int
node_trav(EditLine *el, keymacro_node_t *ptr, wchar_t *ch,
keymacro_value_t *val)
{
wchar_t wc;
if (ptr->ch == *ch) {
/* match found */
if (ptr->next) {
/* key not complete so get next char */
if (el_wgetc(el, &wc) != 1) {/* if EOF or error */
val->cmd = ED_END_OF_FILE;
return XK_CMD;
/* PWP: Pretend we just read an end-of-file */
}
*ch = (Char)wc;
if (el_wgetc(el, ch) != 1)
return XK_NOD;
return node_trav(el, ptr->next, ch, val);
} else {
*val = ptr->val;
@ -316,8 +313,8 @@ node_trav(EditLine *el, keymacro_node_t *ptr, Char *ch, keymacro_value_t *val)
/* node__try():
* Find a node that matches *str or allocate a new one
*/
private int
node__try(EditLine *el, keymacro_node_t *ptr, const Char *str,
static int
node__try(EditLine *el, keymacro_node_t *ptr, const wchar_t *str,
keymacro_value_t *val, int ntype)
{
@ -343,7 +340,6 @@ node__try(EditLine *el, keymacro_node_t *ptr, const Char *str,
case XK_NOD:
break;
case XK_STR:
case XK_EXE:
if (ptr->val.str)
el_free(ptr->val.str);
break;
@ -358,8 +354,7 @@ node__try(EditLine *el, keymacro_node_t *ptr, const Char *str,
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:
@ -379,8 +374,8 @@ node__try(EditLine *el, keymacro_node_t *ptr, const Char *str,
/* node__delete():
* Delete node that matches str
*/
private int
node__delete(EditLine *el, keymacro_node_t **inptr, const Char *str)
static int
node__delete(EditLine *el, keymacro_node_t **inptr, const wchar_t *str)
{
keymacro_node_t *ptr;
keymacro_node_t *prev_ptr = NULL;
@ -427,7 +422,7 @@ node__delete(EditLine *el, keymacro_node_t **inptr, const Char *str)
/* node__put():
* Puts a tree of nodes onto free list using free(3).
*/
private void
static void
node__put(EditLine *el, keymacro_node_t *ptr)
{
if (ptr == NULL)
@ -443,7 +438,6 @@ node__put(EditLine *el, keymacro_node_t *ptr)
case XK_CMD:
case XK_NOD:
break;
case XK_EXE:
case XK_STR:
if (ptr->val.str != NULL)
el_free(ptr->val.str);
@ -459,7 +453,7 @@ node__put(EditLine *el, keymacro_node_t *ptr)
/* node__get():
* Returns pointer to a keymacro_node_t for ch.
*/
private keymacro_node_t *
static keymacro_node_t *
node__get(wint_t ch)
{
keymacro_node_t *ptr;
@ -467,7 +461,7 @@ node__get(wint_t ch)
ptr = el_malloc(sizeof(*ptr));
if (ptr == NULL)
return NULL;
ptr->ch = (Char)ch;
ptr->ch = ch;
ptr->type = XK_NOD;
ptr->val.str = NULL;
ptr->next = NULL;
@ -475,7 +469,7 @@ node__get(wint_t ch)
return ptr;
}
private void
static void
node__free(keymacro_node_t *k)
{
if (k == NULL)
@ -489,8 +483,9 @@ node__free(keymacro_node_t *k)
* look for the str starting at node ptr.
* Print if last node
*/
private int
node_lookup(EditLine *el, const Char *str, keymacro_node_t *ptr, size_t cnt)
static int
node_lookup(EditLine *el, const wchar_t *str, keymacro_node_t *ptr,
size_t cnt)
{
ssize_t used;
@ -541,7 +536,7 @@ node_lookup(EditLine *el, const Char *str, keymacro_node_t *ptr, size_t cnt)
/* node_enum():
* Traverse the node printing the characters it is bound in buffer
*/
private int
static int
node_enum(EditLine *el, keymacro_node_t *ptr, size_t cnt)
{
ssize_t used;
@ -551,7 +546,7 @@ node_enum(EditLine *el, keymacro_node_t *ptr, size_t 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",
(void) fprintf(el->el_errfile, " \"%ls...\"\n",
el->el_keymacro.buf);
return 0;
}
@ -584,8 +579,9 @@ node_enum(EditLine *el, keymacro_node_t *ptr, size_t cnt)
* Print the specified key and its associated
* function specified by val
*/
protected void
keymacro_kprint(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
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];
@ -594,7 +590,6 @@ keymacro_kprint(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
if (val != NULL)
switch (ntype) {
case XK_STR:
case XK_EXE:
(void) keymacro__decode_str(val->str, unparsbuf,
sizeof(unparsbuf),
ntype == XK_STR ? "\"\"" : "[]");
@ -604,7 +599,7 @@ keymacro_kprint(EditLine *el, const Char *key, keymacro_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);
@ -635,11 +630,12 @@ keymacro_kprint(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
/* keymacro__decode_str():
* Make a printable version of the ey
*/
protected size_t
keymacro__decode_str(const Char *str, char *buf, size_t len, const char *sep)
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') {
@ -651,8 +647,8 @@ keymacro__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++);

View File

@ -1,4 +1,4 @@
/* $NetBSD: keymacro.h,v 1.3 2016/01/29 19:59:11 christos Exp $ */
/* $NetBSD: keymacro.h,v 1.6 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -42,13 +42,13 @@
typedef union keymacro_value_t {
el_action_t cmd; /* If it is a command the # */
Char *str; /* If it is a string... */
wchar_t *str; /* If it is a string... */
} keymacro_value_t;
typedef struct keymacro_node_t keymacro_node_t;
typedef struct el_keymacro_t {
Char *buf; /* Key print buffer */
wchar_t *buf; /* Key print buffer */
keymacro_node_t *map; /* Key map */
keymacro_value_t val; /* Local conversion buffer */
} el_keymacro_t;
@ -56,21 +56,21 @@ typedef struct el_keymacro_t {
#define XK_CMD 0
#define XK_STR 1
#define XK_NOD 2
#define XK_EXE 3
protected int keymacro_init(EditLine *);
protected void keymacro_end(EditLine *);
protected keymacro_value_t *keymacro_map_cmd(EditLine *, int);
protected keymacro_value_t *keymacro_map_str(EditLine *, Char *);
protected void keymacro_reset(EditLine *);
protected int keymacro_get(EditLine *, Char *, keymacro_value_t *);
protected void keymacro_add(EditLine *, const Char *, keymacro_value_t *, int);
protected void keymacro_clear(EditLine *, el_action_t *, const Char *);
protected int keymacro_delete(EditLine *, const Char *);
protected void keymacro_print(EditLine *, const Char *);
protected void keymacro_kprint(EditLine *, const Char *, keymacro_value_t *,
int);
protected size_t keymacro__decode_str(const Char *, char *, size_t,
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_keymacro */

136
literal.c Normal file
View File

@ -0,0 +1,136 @@
/* $NetBSD: literal.c,v 1.3 2017/06/30 20:26:52 kre Exp $ */
/*-
* Copyright (c) 2017 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: literal.c,v 1.3 2017/06/30 20:26:52 kre Exp $");
#endif /* not lint && not SCCSID */
/*
* literal.c: Literal sequences handling.
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "el.h"
libedit_private void
literal_init(EditLine *el)
{
el_literal_t *l = &el->el_literal;
memset(l, 0, sizeof(*l));
}
libedit_private void
literal_end(EditLine *el)
{
literal_clear(el);
}
libedit_private void
literal_clear(EditLine *el)
{
el_literal_t *l = &el->el_literal;
size_t i;
if (l->l_len == 0)
return;
for (i = 0; i < l->l_idx; i++)
el_free(l->l_buf[i]);
el_free(l->l_buf);
l->l_buf = NULL;
l->l_len = 0;
l->l_idx = 0;
}
libedit_private wint_t
literal_add(EditLine *el, const wchar_t *buf, const wchar_t *end, int *wp)
{
el_literal_t *l = &el->el_literal;
size_t i, len;
ssize_t w, n;
char *b;
w = wcwidth(end[1]); /* column width of the visible char */
*wp = (int)w;
if (w <= 0) /* we require something to be printed */
return 0;
len = (size_t)(end - buf);
for (w = 0, i = 0; i < len; i++)
w += ct_enc_width(buf[i]);
w += ct_enc_width(end[1]);
b = el_malloc((size_t)(w + 1));
if (b == NULL)
return 0;
for (n = 0, i = 0; i < len; i++)
n += ct_encode_char(b + n, w - n, buf[i]);
n += ct_encode_char(b + n, w - n, end[1]);
b[n] = '\0';
/*
* Then save this literal string in the list of such strings,
* and return a "magic character" to put into the terminal buffer.
* When that magic char is 'printed' the saved string (which includes
* the char that belongs in that position) gets sent instead.
*/
if (l->l_idx == l->l_len) {
char **bp;
l->l_len += 4;
bp = el_realloc(l->l_buf, sizeof(*l->l_buf) * l->l_len);
if (bp == NULL) {
free(b);
l->l_len -= 4;
return 0;
}
l->l_buf = bp;
}
l->l_buf[l->l_idx++] = b;
return EL_LITERAL | (wint_t)(l->l_idx - 1);
}
libedit_private const char *
literal_get(EditLine *el, wint_t idx)
{
el_literal_t *l = &el->el_literal;
assert(idx & EL_LITERAL);
idx &= ~EL_LITERAL;
assert(l->l_idx > (size_t)idx);
return l->l_buf[idx];
}

53
literal.h Normal file
View File

@ -0,0 +1,53 @@
/* $NetBSD: literal.h,v 1.2 2017/06/30 20:26:52 kre Exp $ */
/*-
* Copyright (c) 2017 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* el.literal.h: Literal character
*/
#ifndef _h_el_literal
#define _h_el_literal
#define EL_LITERAL ((wint_t)0x80000000)
typedef struct el_literal_t {
char **l_buf; /* array of buffers */
size_t l_idx; /* max in use */
size_t l_len; /* max allocated */
} el_literal_t;
libedit_private void literal_init(EditLine *);
libedit_private void literal_end(EditLine *);
libedit_private void literal_clear(EditLine *);
libedit_private wint_t literal_add(EditLine *, const wchar_t *,
const wchar_t *, int *);
libedit_private const char *literal_get(EditLine *, wint_t);
#endif /* _h_el_literal */

111
makelist
View File

@ -1,5 +1,5 @@
#!/bin/sh -
# $NetBSD: makelist,v 1.24 2016/02/17 19:47:49 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.
@ -36,7 +36,7 @@
# makelist.sh: Automatically generate header files...
AWK=awk
USAGE="Usage: $0 -n|-h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
USAGE="Usage: $0 -h|-fc|-fh|-bh <filenames>"
if [ "x$1" = "x" ]
then
@ -51,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`"
@ -78,7 +67,7 @@ _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 *, wint_t);\n",
printf("libedit_private el_action_t\t%s (EditLine *, wint_t);\n",
name);
}
}
@ -87,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 \"help.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++)
@ -115,38 +102,24 @@ _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(void)");
printf("{ return el_func_help; }\n");
}'
;;
# generate help.h from various .c files
#
-bh)
$AWK '
BEGIN {
printf("/* Automatically generated file, do not edit */\n");
printf("#ifndef _h_help_c\n#define _h_help_c\n");
printf("protected const el_bindings_t *help__get(void);\n");
printf("#endif /* _h_help_c */\n");
}' /dev/null
;;
# generate fcns.h from various .h files
#
-fh)
@ -154,7 +127,6 @@ _EOF
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;
}
{
@ -162,24 +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 *, wint_t);");
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("#include \"common.h\"\n");
printf("#include \"emacs.h\"\n");
printf("#include \"vi.h\"\n");
printf("private const el_func_t el_func[] = {");
printf("static const el_func_t el_func[] = {");
maxlen = 80;
needn = 1;
len = 0;
@ -199,59 +163,6 @@ _EOF
}
END {
printf("\n};\n");
printf("\nprotected const el_func_t* func__get(void) { return el_func; }\n");
}'
;;
# generate editline.c from various .c files
#
-e)
echo "$FILES" | tr ' ' '\012' | $AWK '
BEGIN {
printf("/* Automatically generated file, do not edit */\n");
printf("#define protected static\n");
printf("#define SCCSID\n");
}
{
printf("#include \"%s\"\n", $1);
}'
;;
# generate man page fragment from various .c files
#
-m)
cat $FILES | $AWK '
BEGIN {
printf(".\\\" Section automatically generated with makelist\n");
printf(".Bl -tag -width 4n\n");
}
/\(\):/ {
pr = substr($2, 1, 2);
if (pr == "vi" || pr == "em" || pr == "ed") {
name = substr($2, 1, length($2) - 3);
fname = "";
for (i = 1; i <= length(name); i++) {
s = substr(name, i, 1);
if (s == "_")
s = "-";
fname = fname s;
}
printf(".It Ic %s\n", fname);
ok = 1;
}
}
/^ \*/ {
if (ok) {
for (i = 2; i < NF; i++)
printf("%s ", $i);
printf("%s.\n", $i);
ok = 0;
}
}
END {
printf(".El\n");
printf(".\\\" End of section automatically generated with makelist\n");
}'
;;

168
map.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: map.c,v 1.43 2016/02/17 19:47:49 christos Exp $ */
/* $NetBSD: map.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[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: map.c,v 1.43 2016/02/17 19:47:49 christos Exp $");
__RCSID("$NetBSD: map.c,v 1.51 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -49,23 +49,28 @@ __RCSID("$NetBSD: map.c,v 1.43 2016/02/17 19:47:49 christos Exp $");
#include <string.h>
#include "el.h"
#include "common.h"
#include "emacs.h"
#include "vi.h"
#include "fcns.h"
#include "func.h"
#include "help.h"
#include "parse.h"
private void map_print_key(EditLine *, el_action_t *, const Char *);
private void map_print_some_keys(EditLine *, el_action_t *, wint_t, wint_t);
private void map_print_all_keys(EditLine *);
private void map_init_nls(EditLine *);
private void map_init_meta(EditLine *);
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 */
@ -77,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 */
@ -328,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 */
@ -347,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 */
@ -359,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, /* ^_ */
@ -373,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 */
@ -385,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, /* ^_ */
@ -629,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 */
@ -645,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 */
@ -658,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, /* ^_ */
@ -892,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)
{
@ -920,12 +925,12 @@ map_init(EditLine *el)
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(),
(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->el_map.func)
memcpy(el->el_map.func, el_func, sizeof(*el->el_map.func)
* EL_NUM_FCNS);
el->el_map.nfunc = EL_NUM_FCNS;
@ -941,7 +946,7 @@ map_init(EditLine *el)
/* map_end():
* Free the space taken by the editor maps
*/
protected void
libedit_private void
map_end(EditLine *el)
{
@ -962,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;
@ -970,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;
}
@ -978,10 +983,10 @@ map_init_nls(EditLine *el)
/* map_init_meta():
* Bind all the meta keys to the appropriate ESC-<key> sequence
*/
private void
static void
map_init_meta(EditLine *el)
{
Char buf[3];
wchar_t buf[3];
int i;
el_action_t *map = el->el_map.key;
el_action_t *alt = el->el_map.alt;
@ -999,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]) {
@ -1019,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;
@ -1049,11 +1054,11 @@ map_init_vi(EditLine *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;
@ -1083,15 +1088,15 @@ map_init_emacs(EditLine *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;
}
if (Strcmp(editor, STR("vi")) == 0) {
if (wcscmp(editor, L"vi") == 0) {
map_init_vi(el);
return 0;
}
@ -1102,18 +1107,18 @@ map_set_editor(EditLine *el, Char *editor)
/* 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;
switch (el->el_map.type) {
case MAP_EMACS:
*editor = STR("emacs");
*editor = L"emacs";
return 0;
case MAP_VI:
*editor = STR("vi");
*editor = L"vi";
return 0;
}
return -1;
@ -1123,8 +1128,8 @@ map_get_editor(EditLine *el, const Char **editor)
/* 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;
@ -1135,7 +1140,7 @@ map_print_key(EditLine *el, el_action_t *map, const Char *in)
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
@ -1146,16 +1151,16 @@ map_print_key(EditLine *el, el_action_t *map, const Char *in)
/* map_print_some_keys():
* Print keys from first to last
*/
private void
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] = (Char)first;
firstbuf[0] = first;
firstbuf[1] = 0;
lastbuf[0] = (Char)last;
lastbuf[0] = last;
lastbuf[1] = 0;
if (map[first] == ED_UNASSIGNED) {
if (first == last) {
@ -1172,7 +1177,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, wint_t first, wint_t last)
if (first == last) {
(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) keymacro__decode_str(firstbuf, unparsbuf,
@ -1180,7 +1185,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, wint_t first, wint_t last)
(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;
@ -1210,7 +1215,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, wint_t first, wint_t 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;
@ -1236,25 +1241,25 @@ 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");
keymacro_print(el, STR(""));
keymacro_print(el, L"");
(void) fprintf(el->el_outfile, "Arrow key bindings\n");
terminal_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;
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;
@ -1275,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;
@ -1300,12 +1300,12 @@ map_bind(EditLine *el, int argc, const Char **argv)
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;
default:
(void) fprintf(el->el_errfile,
"" FSTR ": Invalid switch `%lc'.\n",
"%ls: Invalid switch `%lc'.\n",
argv[0], (wint_t)p[1]);
}
else
@ -1319,7 +1319,7 @@ map_bind(EditLine *el, int argc, const Char **argv)
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;
}
@ -1352,10 +1352,9 @@ map_bind(EditLine *el, int argc, const Char **argv)
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]);
"%ls: Invalid \\ or ^ in outstring.\n", argv[0]);
return -1;
}
if (key)
@ -1368,7 +1367,7 @@ map_bind(EditLine *el, int argc, const Char **argv)
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;
}
@ -1397,8 +1396,9 @@ map_bind(EditLine *el, int argc, const Char **argv)
/* 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;
size_t nf = el->el_map.nfunc + 1;

30
map.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: map.h,v 1.10 2014/07/06 18:15:34 christos Exp $ */
/* $NetBSD: map.h,v 1.13 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -40,12 +40,13 @@
#ifndef _h_el_map
#define _h_el_map
typedef struct el_bindings_t { /* for the "bind" shell command */
const Char *name; /* function name for bind command */
int func; /* function numeric value */
const Char *description; /* description of function */
} el_bindings_t;
typedef el_action_t (*el_func_t)(EditLine *, wint_t);
typedef struct el_bindings_t { /* for the "bind" shell command */
const wchar_t *name; /* function name for bind command */
int func; /* function numeric value */
const wchar_t *description; /* description of function */
} el_bindings_t;
typedef struct el_map_t {
el_action_t *alt; /* The current alternate key map */
@ -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 */

118
parse.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.35 2016/02/17 19:47:49 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.35 2016/02/17 19:47:49 christos Exp $");
__RCSID("$NetBSD: parse.c,v 1.40 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -60,35 +60,35 @@ __RCSID("$NetBSD: parse.c,v 1.35 2016/02/17 19:47:49 christos Exp $");
#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"), terminal_echotc },
{ STR("edit"), el_editmode },
{ STR("history"), hist_command },
{ STR("telltc"), terminal_telltc },
{ STR("settc"), terminal_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);
tok = tok_winit(NULL);
tok_wstr(tok, line, &argc, &argv);
argc = el_wparse(el, argc, argv);
tok_wend(tok);
return argc;
}
@ -96,17 +96,17 @@ parse_line(EditLine *el, const Char *line)
/* 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], ':');
ptr = wcschr(argv[0], L':');
if (ptr != NULL) {
Char *tprog;
wchar_t *tprog;
size_t l;
if (ptr == argv[0])
@ -115,7 +115,7 @@ FUN(el,parse)(EditLine *el, int argc, const Char *argv[])
tprog = el_malloc((l + 1) * sizeof(*tprog));
if (tprog == NULL)
return 0;
(void) Strncpy(tprog, argv[0], l);
(void) wcsncpy(tprog, argv[0], l);
tprog[l] = '\0';
ptr++;
l = (size_t)el_match(el->el_prog, tprog);
@ -126,7 +126,7 @@ FUN(el,parse)(EditLine *el, int argc, const Char *argv[])
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;
}
@ -138,10 +138,10 @@ FUN(el,parse)(EditLine *el, int argc, const Char *argv[])
* Parse a string of the form ^<char> \<odigit> \<char> \U+xxxx and return
* the appropriate character or -1 if the escape is not valid
*/
protected int
parse__escape(const Char **ptr)
libedit_private int
parse__escape(const wchar_t **ptr)
{
const Char *p;
const wchar_t *p;
wint_t c;
p = *ptr;
@ -176,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':
@ -238,10 +238,10 @@ parse__escape(const Char **ptr)
/* 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 (;;)
@ -254,7 +254,7 @@ parse__string(Char *out, const Char *in)
case '^':
if ((n = parse__escape(&in)) == -1)
return NULL;
*out++ = (Char)n;
*out++ = (wchar_t)n;
break;
case 'M':
@ -276,14 +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->el_map.help;
size_t i;
for (i = 0; i < el->el_map.nfunc; i++)
if (Strcmp(b[i].name, cmd) == 0)
if (wcscmp(b[i].name, cmd) == 0)
return b[i].func;
return -1;
}

10
parse.h
View File

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

View File

@ -1,4 +1,4 @@
/* $NetBSD: prompt.c,v 1.23 2016/02/16 15:53:48 christos Exp $ */
/* $NetBSD: prompt.c,v 1.27 2017/06/27 23:25:13 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.23 2016/02/16 15:53:48 christos Exp $");
__RCSID("$NetBSD: prompt.c,v 1.27 2017/06/27 23:25:13 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -47,17 +47,17 @@ __RCSID("$NetBSD: prompt.c,v 1.23 2016/02/16 15:53:48 christos Exp $");
#include <stdio.h>
#include "el.h"
private Char *prompt_default(EditLine *);
private Char *prompt_default_r(EditLine *);
static wchar_t *prompt_default(EditLine *);
static wchar_t *prompt_default_r(EditLine *);
/* prompt_default():
* Just a default prompt, in case the user did not provide one
*/
private Char *
static wchar_t *
/*ARGSUSED*/
prompt_default(EditLine *el __attribute__((__unused__)))
{
static Char a[3] = {'?', ' ', '\0'};
static wchar_t a[3] = L"? ";
return a;
}
@ -66,11 +66,11 @@ prompt_default(EditLine *el __attribute__((__unused__)))
/* 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;
}
@ -79,12 +79,11 @@ prompt_default_r(EditLine *el __attribute__((__unused__)))
/* 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;
int ignore = 0;
wchar_t *p;
if (op == EL_PROMPT)
elp = &el->el_prompt;
@ -99,13 +98,17 @@ prompt_print(EditLine *el, int op)
for (; *p; p++) {
if (elp->p_ignore == *p) {
ignore = !ignore;
wchar_t *litstart = ++p;
while (*p && *p != elp->p_ignore)
p++;
if (!*p || !p[1]) {
// XXX: We lose the last literal
break;
}
re_putliteral(el, litstart, p++);
continue;
}
if (ignore)
terminal__putc(el, *p);
else
re_putc(el, *p, 1);
re_putc(el, *p, 1);
}
elp->p_pos.v = el->el_refresh.r_cursor.v;
@ -116,7 +119,7 @@ prompt_print(EditLine *el, int op)
/* prompt_init():
* Initialize the prompt stuff
*/
protected int
libedit_private int
prompt_init(EditLine *el)
{
@ -135,7 +138,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 +148,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 +180,8 @@ prompt_set(EditLine *el, el_pfunc_t prf, Char c, int op, int wide)
/* prompt_get():
* Retrieve the prompt printing function
*/
protected int
prompt_get(EditLine *el, el_pfunc_t *prf, Char *c, int op)
libedit_private int
prompt_get(EditLine *el, el_pfunc_t *prf, wchar_t *c, int op)
{
el_prompt_t *p;

View File

@ -1,4 +1,4 @@
/* $NetBSD: prompt.h,v 1.13 2016/02/17 19:47:49 christos Exp $ */
/* $NetBSD: prompt.h,v 1.15 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -40,19 +40,19 @@
#ifndef _h_el_prompt
#define _h_el_prompt
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 */

405
read.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: read.c,v 1.86 2016/03/02 19:24:20 christos Exp $ */
/* $NetBSD: read.c,v 1.103 2017/06/27 23:24:19 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,13 +37,12 @@
#if 0
static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: read.c,v 1.86 2016/03/02 19:24:20 christos Exp $");
__RCSID("$NetBSD: read.c,v 1.103 2017/06/27 23:24:19 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/*
* read.c: Clean this junk up! This is horrible code.
* Terminal read functions
* read.c: Terminal read functions
*/
#include <ctype.h>
#include <errno.h>
@ -54,35 +53,75 @@ __RCSID("$NetBSD: read.c,v 1.86 2016/03/02 19:24:20 christos Exp $");
#include <unistd.h>
#include "el.h"
#include "fcns.h"
#include "read.h"
#define OKCMD -1 /* must be -1! */
#define EL_MAXMACRO 10
private int read__fixio(int, int);
private int read_preread(EditLine *);
private int read_char(EditLine *, wchar_t *);
private int read_getcmd(EditLine *, el_action_t *, Char *);
private void read_pop(c_macro_t *);
struct macros {
wchar_t **macro;
int level;
int offset;
};
struct el_read_t {
struct macros macros;
el_rfunc_t read_char; /* Function to read a character. */
int read_errno;
};
static int read__fixio(int, int);
static int read_char(EditLine *, wchar_t *);
static int read_getcmd(EditLine *, el_action_t *, wchar_t *);
static void read_clearmacros(struct macros *);
static void read_pop(struct macros *);
static const wchar_t *noedit_wgets(EditLine *, int *);
/* read_init():
* Initialize the read stuff
*/
protected int
libedit_private int
read_init(EditLine *el)
{
struct macros *ma;
if ((el->el_read = el_malloc(sizeof(*el->el_read))) == NULL)
return -1;
ma = &el->el_read->macros;
if ((ma->macro = el_malloc(EL_MAXMACRO *
sizeof(*ma->macro))) == NULL) {
free(el->el_read);
return -1;
}
ma->level = -1;
ma->offset = 0;
/* builtin read_char */
el->el_read.read_char = read_char;
el->el_read->read_char = read_char;
return 0;
}
/* el_read_end():
* Free the data structures used by the read stuff.
*/
libedit_private void
read_end(struct el_read_t *el_read)
{
read_clearmacros(&el_read->macros);
el_free(el_read->macros.macro);
el_read->macros.macro = NULL;
el_free(el_read);
}
/* 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;
}
@ -91,42 +130,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)
{
@ -184,49 +200,17 @@ read__fixio(int fd __attribute__((__unused__)), int e)
}
/* read_preread():
* Try to read the stuff in the input queue;
*/
private int
read_preread(EditLine *el)
{
int chrs = 0;
if (el->el_tty.t_mode == ED_IO)
return 0;
#ifndef WIDECHAR
/* FIONREAD attempts to buffer up multiple bytes, and to make that work
* properly with partial wide/UTF-8 characters would need some careful work. */
#ifdef FIONREAD
(void) ioctl(el->el_infd, FIONREAD, &chrs);
if (chrs > 0) {
char buf[EL_BUFSIZ];
chrs = read(el->el_infd, buf,
(size_t) MIN(chrs, EL_BUFSIZ - 1));
if (chrs > 0) {
buf[chrs] = '\0';
el_push(el, buf);
}
}
#endif /* FIONREAD */
#endif
return chrs > 0;
}
/* el_push():
* Push a macro
*/
public void
FUN(el,push)(EditLine *el, const Char *str)
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--;
}
@ -236,24 +220,19 @@ FUN(el,push)(EditLine *el, const Char *str)
/* read_getcmd():
* Get next command from the input stream, return OKCMD on success.
* 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 Char meta = (Char)0x80;
static const wchar_t meta = (wchar_t)0x80;
el_action_t cmd;
wchar_t wc;
int num;
el->el_errno = 0;
do {
if ((num = el_wgetc(el, &wc)) != 1) {/* if EOF or error */
el->el_errno = num == 0 ? 0 : errno;
return 0; /* not OKCMD */
}
*ch = (Char)wc;
if (el_wgetc(el, ch) != 1)
return -1;
#ifdef KANJI
if ((*ch & meta)) {
@ -267,11 +246,9 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
el->el_state.metanext = 0;
*ch |= meta;
}
#ifdef WIDECHAR
if (*ch >= N_KEYS)
cmd = ED_INSERT;
else
#endif
cmd = el->el_map.current[(unsigned char) *ch];
if (cmd == ED_SEQUENCE_LEAD_IN) {
keymacro_value_t val;
@ -280,30 +257,24 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
cmd = val.cmd;
break;
case XK_STR:
FUN(el,push)(el, val.str);
el_wpush(el, val.str);
break;
#ifdef notyet
case XK_EXE:
/* XXX: In the future to run a user function */
RunCommand(val.str);
break;
#endif
case XK_NOD:
return -1;
default:
EL_ABORT((el->el_errfile, "Bad XK_ type \n"));
break;
}
}
if (el->el_map.alt == NULL)
el->el_map.current = el->el_map.key;
} while (cmd == ED_SEQUENCE_LEAD_IN);
*cmdnum = cmd;
return OKCMD;
return 0;
}
/* read_char():
* Read a character from the tty.
*/
private int
static int
read_char(EditLine *el, wchar_t *cp)
{
ssize_t num_read;
@ -318,7 +289,7 @@ read_char(EditLine *el, wchar_t *cp)
int e = errno;
switch (el->el_signal->sig_no) {
case SIGCONT:
FUN(el,set)(el, EL_REFRESH);
el_wset(el, EL_REFRESH);
/*FALLTHROUGH*/
case SIGWINCH:
sig_set(el);
@ -343,9 +314,12 @@ read_char(EditLine *el, wchar_t *cp)
}
for (;;) {
mbstate_t mbs;
++cbp;
switch (ct_mbrtowc(cp, cbuf, cbp)) {
/* 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) {
/*
@ -384,8 +358,8 @@ read_char(EditLine *el, wchar_t *cp)
/* 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;
@ -396,22 +370,25 @@ read_pop(c_macro_t *ma)
ma->offset = 0;
}
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
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;
terminal__flush(el);
for (;;) {
if (ma->level < 0) {
if (!read_preread(el))
break;
}
if (ma->level < 0)
break;
@ -430,25 +407,23 @@ el_wgetc(EditLine *el, wchar_t *cp)
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);
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_errno = errno;
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Got it %lc\n", *cp);
#endif /* DEBUG_READ */
el->el_read->read_errno = errno;
return num_read;
}
protected void
libedit_private void
read_prepare(EditLine *el)
{
if (el->el_flags & HANDLE_SIGNALS)
@ -462,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)
terminal__flush(el);
}
protected void
libedit_private void
read_finish(EditLine *el)
{
if ((el->el_flags & UNBUFFERED) == 0)
@ -478,56 +453,52 @@ 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 */
wchar_t wc;
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, &wc)) == 1) {
*cp = (Char)wc;
/* make sure there is space for next character */
if (cp + 1 >= el->el_line.limit) {
idx = (size_t)(cp - el->el_line.buffer);
if (!ch_enlargebufs(el, (size_t)2))
break;
cp = &el->el_line.buffer[idx];
}
cp++;
if (el->el_flags & UNBUFFERED)
break;
if (cp[-1] == '\r' || cp[-1] == '\n')
break;
}
if (num == -1) {
if (errno == EINTR)
cp = el->el_line.buffer;
el->el_errno = errno;
}
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, &chrs);
if (chrs == 0) {
@ -544,83 +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;
el->el_line.lastchar = el->el_line.buffer;
terminal__flush(el);
while ((num = (*el->el_read.read_char)(el, &wc)) == 1) {
*cp = (Char)wc;
/* make sure there is space next character */
if (cp + 1 >= el->el_line.limit) {
idx = (size_t)(cp - el->el_line.buffer);
if (!ch_enlargebufs(el, (size_t)2))
break;
cp = &el->el_line.buffer[idx];
}
cp++;
crlf = cp[-1] == '\r' || cp[-1] == '\n';
if (el->el_flags & UNBUFFERED)
break;
if (crlf)
break;
}
if (num == -1) {
if (errno == EINTR)
cp = el->el_line.buffer;
el->el_errno = errno;
}
goto noedit;
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) {
num = -1;
#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 ((size_t)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
#ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile,
"ERROR: illegal command from key 0%o\r\n", ch);
#endif /* DEBUG_EDIT */
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 " FSTR "\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;
@ -629,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;
@ -685,22 +588,15 @@ 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 */
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 */
terminal_beep(el);
terminal__flush(el);
break;
@ -717,19 +613,14 @@ FUN(el,gets)(EditLine *el, int *nread)
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

19
read.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: read.h,v 1.9 2016/02/24 17:13:22 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 *, wchar_t *);
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 */

View File

@ -1,4 +1,4 @@
/* $NetBSD: readline.c,v 1.126 2016/02/24 17:13:22 christos Exp $ */
/* $NetBSD: readline.c,v 1.143 2017/09/05 18:07:59 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -31,7 +31,7 @@
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: readline.c,v 1.126 2016/02/24 17:13:22 christos Exp $");
__RCSID("$NetBSD: readline.c,v 1.143 2017/09/05 18:07:59 christos Exp $");
#endif /* not lint && not SCCSID */
#include <sys/types.h>
@ -52,6 +52,7 @@ __RCSID("$NetBSD: readline.c,v 1.126 2016/02/24 17:13:22 christos Exp $");
#include "readline/readline.h"
#include "el.h"
#include "fcns.h"
#include "filecomplete.h"
void rl_prep_terminal(int);
@ -94,6 +95,7 @@ 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 = '^';
@ -120,6 +122,7 @@ int readline_echoing_p = 1;
int _rl_print_completions_horizontally = 0;
VFunction *rl_redisplay_function = NULL;
Function *rl_startup_hook = NULL;
int rl_did_startup_hook = 0;
VFunction *rl_completion_display_matches_hook = NULL;
VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal;
VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal;
@ -167,7 +170,6 @@ 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 *, wchar_t *);
static HIST_ENTRY *_move_history(int);
static int _history_expand_command(const char *, size_t, size_t,
char **);
static char *_rl_compat_sub(const char *, const char *,
@ -175,6 +177,7 @@ static char *_rl_compat_sub(const char *, const char *,
static int _rl_event_read_char(EditLine *, wchar_t *);
static void _rl_update_pos(void);
static HIST_ENTRY rl_he;
/* ARGSUSED */
static char *
@ -185,25 +188,6 @@ _get_prompt(EditLine *el __attribute__((__unused__)))
}
/*
* 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 NULL;
rl_he.line = ev.str;
rl_he.data = NULL;
return &rl_he;
}
/*
* read one key from user defined input function
*/
@ -213,7 +197,7 @@ _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 = (wchar_t)i;
@ -306,7 +290,9 @@ rl_initialize(void)
if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0)
editmode = 0;
e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr);
e = el_init_internal(rl_readline_name, rl_instream, rl_outstream,
stderr, fileno(rl_instream), fileno(rl_outstream), fileno(stderr),
NO_RESET);
if (!editmode)
el_set(e, EL_EDITMODE, 0);
@ -402,8 +388,7 @@ rl_initialize(void)
_resize_fun(e, &rl_line_buffer);
_rl_update_pos();
if (rl_startup_hook)
(*rl_startup_hook)(NULL, 0);
tty_end(e);
return 0;
}
@ -425,14 +410,21 @@ readline(const char *p)
if (e == NULL || h == NULL)
rl_initialize();
if (rl_did_startup_hook == 0 && rl_startup_hook) {
rl_did_startup_hook = 1;
(*rl_startup_hook)(NULL, 0);
}
tty_init(e);
rl_done = 0;
(void)setjmp(topbuf);
buf = NULL;
/* update prompt accordingly to what has been passed */
if (rl_set_prompt(prompt) == -1)
return NULL;
goto out;
if (rl_pre_input_hook)
(*rl_pre_input_hook)(NULL, 0);
@ -457,7 +449,7 @@ readline(const char *p)
buf = strdup(ret);
if (buf == NULL)
return NULL;
goto out;
lastidx = count - 1;
if (buf[lastidx] == '\n')
buf[lastidx] = '\0';
@ -467,6 +459,8 @@ readline(const char *p)
history(h, &ev, H_GETSIZE);
history_length = ev.num;
out:
tty_end(e);
return buf;
}
@ -483,6 +477,7 @@ using_history(void)
{
if (h == NULL || e == NULL)
rl_initialize();
history_offset = history_length;
}
@ -564,7 +559,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') {
@ -572,13 +567,13 @@ get_history_event(const char *cmd, int *cindex, int qchar)
idx++;
}
if (sign)
num = history_length - num + 1;
num = history_length - num + history_base;
if (!(rl_he = history_get(num)))
if (!(he = history_get(num)))
return NULL;
*cindex = idx;
return rl_he->line;
return he->line;
}
sub = 0;
if (cmd[idx] == '?') {
@ -1167,12 +1162,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);
}
}
}
@ -1371,6 +1376,28 @@ write_history(const char *filename)
(errno ? errno : EINVAL) : 0;
}
int
append_history(int n, const char *filename)
{
HistEvent ev;
FILE *fp;
if (h == NULL || e == NULL)
rl_initialize();
if (filename == NULL && (filename = _default_history_file()) == NULL)
return errno;
if ((fp = fopen(filename, "a")) == NULL)
return errno;
if (history(h, &ev, H_NSAVE_FP, (size_t)n, fp) == -1) {
int serrno = errno ? errno : EINVAL;
fclose(fp);
return serrno;
}
fclose(fp);
return 0;
}
/*
* returns history ``num''th event
@ -1387,25 +1414,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;
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;
out:
/* restore pointer to where it was */
(void)history(h, &ev, H_SET, curr_num);
return NULL;
}
@ -1417,17 +1456,18 @@ add_history(const char *line)
{
HistEvent ev;
if (line == NULL)
return 0;
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;
}
@ -1517,7 +1557,7 @@ clear_history(void)
rl_initialize();
(void)history(h, &ev, H_CLEAR);
history_length = 0;
history_offset = history_length = 0;
}
@ -1527,21 +1567,42 @@ clear_history(void)
int
where_history(void)
{
HistEvent ev;
int curr_num, off;
if (history(h, &ev, H_CURR) != 0)
return 0;
curr_num = ev.num;
(void)history(h, &ev, H_FIRST);
off = 1;
while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0)
off++;
return off;
return history_offset;
}
static HIST_ENTRY **_history_listp;
static HIST_ENTRY *_history_list;
HIST_ENTRY **
history_list(void)
{
HistEvent ev;
HIST_ENTRY **nlp, *nl;
int i;
if (history(h, &ev, H_LAST) != 0)
return NULL;
if ((nlp = el_realloc(_history_listp,
(size_t)history_length * sizeof(*nlp))) == NULL)
return NULL;
_history_listp = nlp;
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
@ -1549,8 +1610,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;
}
@ -1587,35 +1654,31 @@ history_total_bytes(void)
int
history_set_pos(int pos)
{
HistEvent ev;
int curr_num;
if (pos >= history_length || pos < 0)
return -1;
return 0;
(void)history(h, &ev, H_CURR);
curr_num = ev.num;
/*
* 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();
}
@ -1625,8 +1688,16 @@ previous_history(void)
HIST_ENTRY *
next_history(void)
{
HistEvent ev;
return _move_history(H_NEXT);
if (history_offset >= history_length)
return NULL;
if (history(h, &ev, H_LAST) != 0)
return NULL;
history_offset++;
return current_history();
}
@ -1687,7 +1758,7 @@ history_search_pos(const char *str,
return -1;
curr_num = ev.num;
if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0)
if (!history_set_pos(off) || history(h, &ev, H_CURR) != 0)
return -1;
for (;;) {
@ -1774,18 +1845,6 @@ _el_rl_tstp(EditLine *el __attribute__((__unused__)), int ch __attribute__((__un
return CC_NORM;
}
/*
* Display list of strings in columnar format on readline's output stream.
* 'matches' is list of strings, 'len' is number of strings in 'matches',
* 'max' is maximum length of string in 'matches'.
*/
void
rl_display_match_list(char **matches, int len, int max)
{
fn_display_match_list(e, matches, (size_t)len, (size_t)max);
}
static const char *
/*ARGSUSED*/
_rl_completion_append_character_function(const char *dummy
@ -1798,6 +1857,19 @@ _rl_completion_append_character_function(const char *dummy
}
/*
* Display list of strings in columnar format on readline's output stream.
* 'matches' is list of strings, 'len' is number of strings in 'matches',
* 'max' is maximum length of string in 'matches'.
*/
void
rl_display_match_list(char **matches, int len, int max)
{
fn_display_match_list(e, matches, (size_t)len, (size_t)max,
_rl_completion_append_character_function);
}
/*
* complete word at current point
*/
@ -1805,9 +1877,7 @@ _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)
@ -2021,8 +2091,9 @@ rl_callback_handler_install(const char *prompt, rl_vcpfunc_t *linefunc)
void
rl_callback_handler_remove(void)
{
el_set(e, EL_UNBUFFERED, 0);
rl_linefunc = NULL;
el_end(e);
e = NULL;
}
void
@ -2332,3 +2403,9 @@ rl_set_keyboard_input_timeout(int u __attribute__((__unused__)))
{
return 0;
}
void
rl_resize_terminal(void)
{
el_resize(e);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: readline.h,v 1.39 2016/02/17 19:47:49 christos Exp $ */
/* $NetBSD: readline.h,v 1.42 2017/09/01 10:19:10 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -121,6 +121,7 @@ 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
*/
@ -146,6 +147,7 @@ int rl_initialize(void);
void using_history(void);
int add_history(const char *);
void clear_history(void);
int append_history(int, const char *);
void stifle_history(int);
int unstifle_history(void);
int history_is_stifled(void);
@ -158,6 +160,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);
@ -180,6 +183,7 @@ void rl_display_match_list(char **, int, int);
int rl_insert(int, int);
int rl_insert_text(const char *);
void rl_reset_terminal(const char *);
void rl_resize_terminal(void);
int rl_bind_key(int, rl_command_func_t *);
int rl_newline(int, int);
void rl_callback_read_char(void);

178
refresh.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: refresh.c,v 1.45 2016/03/02 19:24:20 christos Exp $ */
/* $NetBSD: refresh.c,v 1.54 2017/06/30 20:26:52 kre 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.45 2016/03/02 19:24:20 christos Exp $");
__RCSID("$NetBSD: refresh.c,v 1.54 2017/06/30 20:26:52 kre Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -50,18 +50,18 @@ __RCSID("$NetBSD: refresh.c,v 1.45 2016/03/02 19:24:20 christos Exp $");
#include "el.h"
private void re_nextline(EditLine *);
private void re_addc(EditLine *, wint_t);
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 *, wint_t);
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 \
if (/*CONSTCOND*/ a) { \
@ -74,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));
@ -91,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. */
@ -104,7 +104,7 @@ re_nextline(EditLine *el)
*/
if (el->el_refresh.r_cursor.v + 1 >= el->el_terminal.t_size.v) {
int i, lins = el->el_terminal.t_size.v;
Char *firstline = el->el_vdisplay[0];
wchar_t *firstline = el->el_vdisplay[0];
for(i = 1; i < lins; i++)
el->el_vdisplay[i - 1] = el->el_vdisplay[i];
@ -123,10 +123,10 @@ re_nextline(EditLine *el)
/* re_addc():
* Draw c, expanding tabs, control chars etc.
*/
private void
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);
@ -145,9 +145,9 @@ re_addc(EditLine *el, wint_t 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;
@ -155,35 +155,66 @@ re_addc(EditLine *el, wint_t c)
}
}
/* re_putliteral():
* Place the literal string given
*/
libedit_private void
re_putliteral(EditLine *el, const wchar_t *begin, const wchar_t *end)
{
coord_t *cur = &el->el_refresh.r_cursor;
wint_t c;
int sizeh = el->el_terminal.t_size.h;
int i, w;
c = literal_add(el, begin, end, &w);
if (c == 0 || w <= 0)
return;
el->el_vdisplay[cur->v][cur->h] = c;
i = w;
if (i > sizeh - cur->h) /* avoid overflow */
i = sizeh - cur->h;
while (--i > 0)
el->el_vdisplay[cur->v][cur->h + i] = MB_FILL_CHAR;
cur->h += w;
if (cur->h >= sizeh) {
/* assure end of line */
el->el_vdisplay[cur->v][sizeh] = '\0';
re_nextline(el);
}
}
/* re_putc():
* Draw the character given
*/
protected void
libedit_private void
re_putc(EditLine *el, wint_t c, int shift)
{
int i, w = Width(c);
ELRE_DEBUG(1, (__F, "printing %5x '%lc'\r\n", c, c));
coord_t *cur = &el->el_refresh.r_cursor;
int i, w = wcwidth(c);
int sizeh = el->el_terminal.t_size.h;
while (shift && (el->el_refresh.r_cursor.h + w > el->el_terminal.t_size.h))
ELRE_DEBUG(1, (__F, "printing %5x '%lc'\r\n", c, c));
if (w == -1)
w = 0;
while (shift && (cur->h + w > sizeh))
re_putc(el, ' ', 1);
el->el_vdisplay[el->el_refresh.r_cursor.v]
[el->el_refresh.r_cursor.h] = (Char)c;
el->el_vdisplay[cur->v][cur->h] = c;
/* assumes !shift is only used for single-column chars */
i = w;
while (--i > 0)
el->el_vdisplay[el->el_refresh.r_cursor.v]
[el->el_refresh.r_cursor.h + i] = MB_FILL_CHAR;
el->el_vdisplay[cur->v][cur->h + i] = MB_FILL_CHAR;
if (!shift)
return;
el->el_refresh.r_cursor.h += w; /* advance to next place */
if (el->el_refresh.r_cursor.h >= el->el_terminal.t_size.h) {
cur->h += w; /* advance to next place */
if (cur->h >= sizeh) {
/* assure end of line */
el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_terminal.t_size.h]
= '\0';
el->el_vdisplay[cur->v][sizeh] = '\0';
re_nextline(el);
}
}
@ -195,23 +226,26 @@ re_putc(EditLine *el, wint_t c, int shift)
* 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 = :" FSTR ":\r\n",
ELRE_DEBUG(1, (__F, "el->el_line.buffer = :%ls:\r\n",
el->el_line.buffer));
literal_clear(el);
/* reset the Drawing cursor */
el->el_refresh.r_cursor.h = 0;
el->el_refresh.r_cursor.v = 0;
terminal_move_to_char(el, 0);
/* temporarily draw rprompt to calculate its size */
prompt_print(el, EL_RPROMPT);
@ -251,7 +285,7 @@ re_refresh(EditLine *el)
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;
@ -319,10 +353,10 @@ re_refresh(EditLine *el)
for (; i <= el->el_refresh.r_oldcv; i++) {
terminal_move_to_line(el, i);
terminal_move_to_char(el, 0);
/* This Strlen should be safe even with MB_FILL_CHARs */
terminal_clear_EOL(el, (int) Strlen(el->el_display[i]));
/* This wcslen should be safe even with MB_FILL_CHARs */
terminal_clear_EOL(el, (int) wcslen(el->el_display[i]));
#ifdef DEBUG_REFRESH
terminal_overwrite(el, STR("C\b"), 2);
terminal_overwrite(el, L"C\b", 2);
#endif /* DEBUG_REFRESH */
el->el_display[i][0] = '\0';
}
@ -340,7 +374,7 @@ re_refresh(EditLine *el)
/* re_goto_bottom():
* used to go to last used screen line
*/
protected void
libedit_private void
re_goto_bottom(EditLine *el)
{
@ -355,12 +389,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;
@ -406,12 +440,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;
@ -440,8 +474,8 @@ re_delete(EditLine *el __attribute__((__unused__)),
/* 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)
@ -455,7 +489,7 @@ re__strncopy(Char *a, Char *b, size_t n)
* in the first or second diff, diff is the difference between the
* number of characters between the new and old line.
*/
private void
static void
re_clear_eol(EditLine *el, int fx, int sx, int diff)
{
@ -499,12 +533,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;
@ -561,7 +595,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;
@ -969,8 +1003,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;
@ -990,10 +1024,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) {
@ -1021,7 +1055,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++;
@ -1037,7 +1071,7 @@ 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++;
@ -1053,15 +1087,15 @@ re_refresh_cursor(EditLine *el)
/* re_fastputc():
* Add a character fast.
*/
private void
static void
re_fastputc(EditLine *el, wint_t c)
{
int w = Width((Char)c);
int w = wcwidth(c);
while (w > 1 && el->el_cursor.h + w > el->el_terminal.t_size.h)
re_fastputc(el, ' ');
terminal__putc(el, c);
el->el_display[el->el_cursor.v][el->el_cursor.h++] = (Char)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;
@ -1078,12 +1112,12 @@ re_fastputc(EditLine *el, wint_t c)
*/
if (el->el_cursor.v + 1 >= el->el_terminal.t_size.v) {
int i, lins = el->el_terminal.t_size.v;
Char *firstline = el->el_display[0];
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(""), (size_t)0);
re__copy_and_pad(firstline, L"", (size_t)0);
el->el_display[i - 1] = firstline;
} else {
el->el_cursor.v++;
@ -1106,10 +1140,10 @@ re_fastputc(EditLine *el, wint_t 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];
@ -1133,9 +1167,9 @@ 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;
@ -1148,7 +1182,7 @@ re_fastaddc(EditLine *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;
@ -1164,7 +1198,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)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: refresh.h,v 1.9 2016/02/16 15:53:48 christos Exp $ */
/* $NetBSD: refresh.h,v 1.11 2017/06/27 23:23:48 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -46,12 +46,14 @@ typedef struct {
int r_newcv;
} el_refresh_t;
protected void re_putc(EditLine *, wint_t, 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_putliteral(EditLine *, const wchar_t *,
const wchar_t *);
libedit_private void re_clear_lines(EditLine *);
libedit_private void re_clear_display(EditLine *);
libedit_private void re_refresh(EditLine *);
libedit_private void re_refresh_cursor(EditLine *);
libedit_private void re_fastaddc(EditLine *);
libedit_private void re_goto_bottom(EditLine *);
#endif /* _h_el_refresh */

View File

@ -1,4 +1,4 @@
/* $NetBSD: search.c,v 1.39 2016/02/24 14:25:38 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.39 2016/02/24 14:25:38 christos Exp $");
__RCSID("$NetBSD: search.c,v 1.47 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -54,6 +54,7 @@ __RCSID("$NetBSD: search.c,v 1.39 2016/02/24 14:25:38 christos Exp $");
#include "el.h"
#include "common.h"
#include "fcns.h"
/*
* Adjust cursor in vi mode to include the character under it
@ -65,7 +66,7 @@ __RCSID("$NetBSD: search.c,v 1.39 2016/02/24 14:25:38 christos Exp $");
/* search_init():
* Initialize the search stuff
*/
protected int
libedit_private int
search_init(EditLine *el)
{
@ -73,9 +74,10 @@ search_init(EditLine *el)
sizeof(*el->el_search.patbuf));
if (el->el_search.patbuf == NULL)
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;
@ -85,7 +87,7 @@ search_init(EditLine *el)
/* search_end():
* Initialize the search stuff
*/
protected void
libedit_private void
search_end(EditLine *el)
{
@ -98,7 +100,7 @@ search_end(EditLine *el)
/* regerror():
* Handle regular expression errors
*/
public void
void
/*ARGSUSED*/
regerror(const char *msg)
{
@ -109,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;
@ -126,7 +126,7 @@ el_match(const Char *str, const Char *pat)
extern int re_exec(const char *);
#endif
if (Strstr(str, pat) != 0)
if (wcsstr(str, pat) != 0)
return 1;
#if defined(REGEX)
@ -158,8 +158,8 @@ 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",
@ -173,7 +173,7 @@ c_hmatch(EditLine *el, const Char *str)
/* 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 &&
@ -183,11 +183,11 @@ c_setpat(EditLine *el)
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",
@ -205,16 +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 *ocursor = el->el_line.cursor, oldpchar = pchar, ch;
const Char *cp;
wchar_t wch;
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;
@ -253,11 +251,9 @@ ce_inc_search(EditLine *el, int dir)
*el->el_line.lastchar = '\0';
re_refresh(el);
if (el_wgetc(el, &wch) != 1)
if (el_wgetc(el, &ch) != 1)
return ed_end_of_file(el, 0);
ch = (Char)wch;
switch (el->el_map.current[(unsigned char) ch]) {
case ED_INSERT:
case ED_DIGIT:
@ -331,7 +327,7 @@ ce_inc_search(EditLine *el, int dir)
default: /* Terminate and execute cmd */
endcmd[0] = ch;
FUN(el,push)(el, endcmd);
el_wpush(el, endcmd);
/* FALLTHROUGH */
case 0033: /* ESC: Terminate */
@ -456,11 +452,11 @@ 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];
wchar_t ch;
wchar_t tmpbuf[EL_BUFSIZ];
ssize_t tmplen;
#ifdef ANCHOR
@ -472,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;
@ -491,11 +487,11 @@ cv_search(EditLine *el, int dir)
#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++] = '.';
@ -509,7 +505,7 @@ cv_search(EditLine *el, int dir)
tmpbuf[tmplen++] = '*';
#endif
tmpbuf[tmplen] = '\0';
(void) Strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
(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 */
@ -530,12 +526,12 @@ cv_search(EditLine *el, int dir)
/* 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;
@ -572,7 +568,7 @@ ce_search_line(EditLine *el, int dir)
/* cv_repeat_srch():
* Vi repeat search
*/
protected el_action_t
libedit_private el_action_t
cv_repeat_srch(EditLine *el, wint_t c)
{
@ -598,10 +594,10 @@ cv_repeat_srch(EditLine *el, wint_t c)
/* cv_csearch():
* Vi character search
*/
protected el_action_t
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;
@ -612,7 +608,7 @@ cv_csearch(EditLine *el, int direction, wint_t ch, int count, int tflag)
}
/* Save for ';' and ',' commands */
el->el_search.chacha = (Char)ch;
el->el_search.chacha = ch;
el->el_search.chadir = direction;
el->el_search.chatflg = (char)tflag;

View File

@ -1,4 +1,4 @@
/* $NetBSD: search.h,v 1.12 2016/02/16 15:53:48 christos Exp $ */
/* $NetBSD: search.h,v 1.14 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -41,24 +41,24 @@
#define _h_el_search
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 *, wint_t);
protected el_action_t cv_csearch(EditLine *, int, wint_t, 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 */

20
sig.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: sig.c,v 1.24 2016/02/16 19:08:41 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.24 2016/02/16 19:08:41 christos Exp $");
__RCSID("$NetBSD: sig.c,v 1.26 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -52,23 +52,23 @@ __RCSID("$NetBSD: sig.c,v 1.24 2016/02/16 19:08:41 christos Exp $");
#include "el.h"
#include "common.h"
private EditLine *sel = NULL;
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, save_errno;
@ -115,7 +115,7 @@ sig_handler(int signo)
/* sig_init():
* Initialize all signal stuff
*/
protected int
libedit_private int
sig_init(EditLine *el)
{
size_t i;
@ -147,7 +147,7 @@ sig_init(EditLine *el)
/* sig_end():
* Clear all signal stuff
*/
protected void
libedit_private void
sig_end(EditLine *el)
{
@ -159,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;
@ -186,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;

10
sig.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: sig.h,v 1.10 2016/02/16 15:53:48 christos Exp $ */
/* $NetBSD: sig.h,v 1.11 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -62,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 */

21
sys.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: sys.h,v 1.23 2016/02/17 19:47:49 christos Exp $ */
/* $NetBSD: sys.h,v 1.27 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -58,18 +58,8 @@
# 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)))
@ -111,11 +101,6 @@ typedef unsigned int u_int32_t;
#define REGEX /* Use POSIX.2 regular expression functions */
#undef REGEXP /* Use UNIX V8 regular expression functions */
#ifndef WIDECHAR
#define setlocale(c, l) /*LINTED*/NULL
#define nl_langinfo(i) ""
#endif
#if defined(__sun)
extern int tgetent(char *, const char *);
extern int tgetflag(char *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: terminal.c,v 1.24 2016/03/22 01:38:17 christos Exp $ */
/* $NetBSD: terminal.c,v 1.33 2017/06/27 23:23:09 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95";
#else
__RCSID("$NetBSD: terminal.c,v 1.24 2016/03/22 01:38:17 christos Exp $");
__RCSID("$NetBSD: terminal.c,v 1.33 2017/06/27 23:23:09 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -73,6 +73,7 @@ __RCSID("$NetBSD: terminal.c,v 1.24 2016/03/22 01:38:17 christos Exp $");
#endif
#include "el.h"
#include "fcns.h"
/*
* IMPORTANT NOTE: these routines are allowed to look at the current screen
@ -88,7 +89,7 @@ __RCSID("$NetBSD: terminal.c,v 1.24 2016/03/22 01:38:17 christos Exp $");
#define Str(a) el->el_terminal.t_str[a]
#define Val(a) el->el_terminal.t_val[a]
private const struct termcapstr {
static const struct termcapstr {
const char *name;
const char *long_name;
} tstr[] = {
@ -174,7 +175,7 @@ private const struct termcapstr {
{ NULL, NULL }
};
private const struct termcapval {
static const struct termcapval {
const char *name;
const char *long_name;
} tval[] = {
@ -199,27 +200,27 @@ private const struct termcapval {
};
/* do two or more of the attributes use me */
private void terminal_setflags(EditLine *);
private int terminal_rebuffer_display(EditLine *);
private void terminal_free_display(EditLine *);
private int terminal_alloc_display(EditLine *);
private void terminal_alloc(EditLine *, const struct termcapstr *,
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 *);
private void terminal_init_arrow(EditLine *);
private void terminal_reset_arrow(EditLine *);
private int terminal_putc(int);
private void terminal_tputs(EditLine *, const char *, int);
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 terminal_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t terminal_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
private FILE *terminal_outfile = NULL;
static FILE *terminal_outfile = NULL;
/* terminal_setflags():
* Set the terminal capability flags
*/
private void
static void
terminal_setflags(EditLine *el)
{
EL_FLAGS = 0;
@ -264,7 +265,7 @@ terminal_setflags(EditLine *el)
/* terminal_init():
* Initialize the terminal stuff
*/
protected int
libedit_private int
terminal_init(EditLine *el)
{
@ -315,7 +316,7 @@ terminal_init(EditLine *el)
/* terminal_end():
* Clean up the terminal stuff
*/
protected void
libedit_private void
terminal_end(EditLine *el)
{
@ -337,7 +338,7 @@ terminal_end(EditLine *el)
/* terminal_alloc():
* Maintain a string pool for termcap strings
*/
private void
static void
terminal_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
{
char termbuf[TC_BUFSIZE];
@ -403,7 +404,7 @@ terminal_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
/* terminal_rebuffer_display():
* Rebuffer the display after the screen changed size
*/
private int
static int
terminal_rebuffer_display(EditLine *el)
{
coord_t *c = &el->el_terminal.t_size;
@ -418,46 +419,58 @@ terminal_rebuffer_display(EditLine *el)
return 0;
}
static wchar_t **
terminal_alloc_buffer(EditLine *el)
{
wint_t **b;
coord_t *c = &el->el_terminal.t_size;
int i;
b = el_malloc(sizeof(*b) * (size_t)(c->v + 1));
if (b == NULL)
return NULL;
for (i = 0; i < c->v; i++) {
b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1));
if (b[i] == NULL) {
while (--i >= 0)
el_free(b[i]);
el_free(b);
return NULL;
}
}
b[c->v] = NULL;
return b;
}
static void
terminal_free_buffer(wint_t ***bp)
{
wint_t **b;
wint_t **bufp;
if (*bp == NULL)
return;
b = *bp;
*bp = NULL;
for (bufp = b; *bufp != NULL; bufp++)
el_free(*bufp);
el_free(b);
}
/* terminal_alloc_display():
* Allocate a new display.
*/
private int
static int
terminal_alloc_display(EditLine *el)
{
int i;
Char **b;
coord_t *c = &el->el_terminal.t_size;
b = el_malloc(sizeof(*b) * (size_t)(c->v + 1));
if (b == NULL)
el->el_display = terminal_alloc_buffer(el);
if (el->el_display == NULL)
goto done;
for (i = 0; i < c->v; i++) {
b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1));
if (b[i] == NULL) {
while (--i >= 0)
el_free(b[i]);
el_free(b);
goto done;
}
}
b[c->v] = NULL;
el->el_display = b;
b = el_malloc(sizeof(*b) * (size_t)(c->v + 1));
if (b == NULL)
el->el_vdisplay = terminal_alloc_buffer(el);
if (el->el_vdisplay == NULL)
goto done;
for (i = 0; i < c->v; i++) {
b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1));
if (b[i] == NULL) {
while (--i >= 0)
el_free(b[i]);
el_free(b);
goto done;
}
}
b[c->v] = NULL;
el->el_vdisplay = b;
return 0;
done:
terminal_free_display(el);
@ -468,26 +481,11 @@ terminal_alloc_display(EditLine *el)
/* terminal_free_display():
* Free the display buffers
*/
private void
static void
terminal_free_display(EditLine *el)
{
Char **b;
Char **bufp;
b = el->el_display;
el->el_display = NULL;
if (b != NULL) {
for (bufp = b; *bufp != NULL; bufp++)
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(*bufp);
el_free(b);
}
terminal_free_buffer(&el->el_display);
terminal_free_buffer(&el->el_vdisplay);
}
@ -495,7 +493,7 @@ terminal_free_display(EditLine *el)
* move to line <where> (first line == 0)
* as efficiently as possible
*/
protected void
libedit_private void
terminal_move_to_line(EditLine *el, int where)
{
int del;
@ -516,13 +514,11 @@ terminal_move_to_line(EditLine *el, int where)
el->el_display[el->el_cursor.v][0] != '\0') {
size_t h = (size_t)
(el->el_terminal.t_size.h - 1);
#ifdef WIDECHAR
for (; h > 0 &&
el->el_display[el->el_cursor.v][h] ==
MB_FILL_CHAR;
h--)
continue;
#endif
/* move without newline */
terminal_move_to_char(el, (int)h);
terminal_overwrite(el, &el->el_display
@ -560,7 +556,7 @@ terminal_move_to_line(EditLine *el, int where)
/* terminal_move_to_char():
* Move to the character position specified
*/
protected void
libedit_private void
terminal_move_to_char(EditLine *el, int where)
{
int del, i;
@ -596,11 +592,9 @@ terminal_move_to_char(EditLine *el, int where)
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 =
@ -657,8 +651,8 @@ terminal_move_to_char(EditLine *el, int where)
* Overstrike num characters
* Assumes MB_FILL_CHARs are present to keep the column count correct
*/
protected void
terminal_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;
@ -684,15 +678,13 @@ terminal_overwrite(EditLine *el, const Char *cp, size_t n)
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') {
terminal_overwrite(el, &c, (size_t)1);
#ifdef WIDECHAR
while (el->el_display[el->el_cursor.v]
[el->el_cursor.h] == MB_FILL_CHAR)
el->el_cursor.h++;
#endif
} else {
terminal__putc(el, ' ');
el->el_cursor.h = 1;
@ -707,7 +699,7 @@ terminal_overwrite(EditLine *el, const Char *cp, size_t n)
/* terminal_deletechars():
* Delete num characters
*/
protected void
libedit_private void
terminal_deletechars(EditLine *el, int num)
{
if (num <= 0)
@ -749,8 +741,8 @@ terminal_deletechars(EditLine *el, int num)
* characters in the line
* Assumes MB_FILL_CHARs are present to keep column count correct
*/
protected void
terminal_insertwrite(EditLine *el, Char *cp, int num)
libedit_private void
terminal_insertwrite(EditLine *el, wchar_t *cp, int num)
{
if (num <= 0)
return;
@ -808,7 +800,7 @@ terminal_insertwrite(EditLine *el, Char *cp, int num)
/* terminal_clear_EOL():
* clear to end of line. There are num characters to clear
*/
protected void
libedit_private void
terminal_clear_EOL(EditLine *el, int num)
{
int i;
@ -826,7 +818,7 @@ terminal_clear_EOL(EditLine *el, int num)
/* terminal_clear_screen():
* Clear the screen
*/
protected void
libedit_private void
terminal_clear_screen(EditLine *el)
{ /* clear the whole screen and home */
@ -847,7 +839,7 @@ terminal_clear_screen(EditLine *el)
/* terminal_beep():
* Beep the way the terminal wants us
*/
protected void
libedit_private void
terminal_beep(EditLine *el)
{
if (GoodStr(T_bl))
@ -858,7 +850,7 @@ terminal_beep(EditLine *el)
}
protected void
libedit_private void
terminal_get(EditLine *el, const char **term)
{
*term = el->el_terminal.t_name;
@ -868,7 +860,7 @@ terminal_get(EditLine *el, const char **term)
/* terminal_set():
* Read in the terminal capabilities from the requested terminal
*/
protected int
libedit_private int
terminal_set(EditLine *el, const char *term)
{
int i;
@ -957,7 +949,7 @@ terminal_set(EditLine *el, const char *term)
* Return the new window size in lines and cols, and
* true if the size was changed.
*/
protected int
libedit_private int
terminal_get_size(EditLine *el, int *lins, int *cols)
{
@ -993,7 +985,7 @@ terminal_get_size(EditLine *el, int *lins, int *cols)
/* terminal_change_size():
* Change the size of the terminal
*/
protected int
libedit_private int
terminal_change_size(EditLine *el, int lins, int cols)
{
/*
@ -1013,42 +1005,42 @@ terminal_change_size(EditLine *el, int lins, int cols)
/* terminal_init_arrow():
* Initialize the arrow key bindings from termcap
*/
private void
static void
terminal_init_arrow(EditLine *el)
{
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 = STR("delete");
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;
@ -1058,22 +1050,22 @@ terminal_init_arrow(EditLine *el)
/* terminal_reset_arrow():
* Reset arrow key bindings
*/
private void
static void
terminal_reset_arrow(EditLine *el)
{
funckey_t *arrow = el->el_terminal.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'};
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);
@ -1108,15 +1100,15 @@ terminal_reset_arrow(EditLine *el)
/* terminal_set_arrow():
* Set an arrow key binding
*/
protected int
terminal_set_arrow(EditLine *el, const Char *name, keymacro_value_t *fun,
libedit_private int
terminal_set_arrow(EditLine *el, const wchar_t *name, keymacro_value_t *fun,
int type)
{
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;
@ -1128,14 +1120,14 @@ terminal_set_arrow(EditLine *el, const Char *name, keymacro_value_t *fun,
/* terminal_clear_arrow():
* Clear an arrow key binding
*/
protected int
terminal_clear_arrow(EditLine *el, const Char *name)
libedit_private int
terminal_clear_arrow(EditLine *el, const wchar_t *name)
{
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;
}
@ -1146,14 +1138,14 @@ terminal_clear_arrow(EditLine *el, const Char *name)
/* terminal_print_arrow():
* Print the arrow key bindings
*/
protected void
terminal_print_arrow(EditLine *el, const Char *name)
libedit_private void
terminal_print_arrow(EditLine *el, const wchar_t *name)
{
int i;
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)
keymacro_kprint(el, arrow[i].name,
&arrow[i].fun, arrow[i].type);
@ -1163,7 +1155,7 @@ terminal_print_arrow(EditLine *el, const Char *name)
/* terminal_bind_arrow():
* Bind the arrow keys
*/
protected void
libedit_private void
terminal_bind_arrow(EditLine *el)
{
el_action_t *map;
@ -1182,8 +1174,8 @@ terminal_bind_arrow(EditLine *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_terminal.t_str[arrow[i].key];
@ -1228,7 +1220,7 @@ terminal_bind_arrow(EditLine *el)
/* terminal_putc():
* Add a character
*/
private int
static int
terminal_putc(int c)
{
if (terminal_outfile == NULL)
@ -1236,7 +1228,7 @@ terminal_putc(int c)
return fputc(c, terminal_outfile);
}
private void
static void
terminal_tputs(EditLine *el, const char *cap, int affcnt)
{
#ifdef _REENTRANT
@ -1252,14 +1244,16 @@ terminal_tputs(EditLine *el, const char *cap, int affcnt)
/* terminal__putc():
* Add a character
*/
protected int
libedit_private int
terminal__putc(EditLine *el, wint_t c)
{
char buf[MB_LEN_MAX +1];
ssize_t i;
if (c == (wint_t)MB_FILL_CHAR)
return 0;
i = ct_encode_char(buf, (size_t)MB_LEN_MAX, (Char)c);
if (c & EL_LITERAL)
return fputs(literal_get(el, c), el->el_outfile);
i = ct_encode_char(buf, (size_t)MB_LEN_MAX, c);
if (i <= 0)
return (int)i;
buf[i] = '\0';
@ -1269,7 +1263,7 @@ terminal__putc(EditLine *el, wint_t c)
/* terminal__flush():
* Flush output
*/
protected void
libedit_private void
terminal__flush(EditLine *el)
{
@ -1279,11 +1273,11 @@ terminal__flush(EditLine *el)
/* terminal_writec():
* Write the given character out, in a human readable form
*/
protected void
libedit_private void
terminal_writec(EditLine *el, wint_t c)
{
Char visbuf[VISUAL_WIDTH_MAX +1];
ssize_t vcnt = ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
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';
@ -1295,10 +1289,10 @@ terminal_writec(EditLine *el, wint_t c)
/* terminal_telltc():
* Print the current termcap characteristics
*/
protected int
libedit_private int
/*ARGSUSED*/
terminal_telltc(EditLine *el, int argc __attribute__((__unused__)),
const Char **argv __attribute__((__unused__)))
const wchar_t **argv __attribute__((__unused__)))
{
const struct termcapstr *t;
char **ts;
@ -1321,8 +1315,8 @@ terminal_telltc(EditLine *el, int argc __attribute__((__unused__)),
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)";
}
@ -1337,10 +1331,10 @@ terminal_telltc(EditLine *el, int argc __attribute__((__unused__)),
/* terminal_settc():
* Change the current terminal characteristics
*/
protected int
libedit_private int
/*ARGSUSED*/
terminal_settc(EditLine *el, int argc __attribute__((__unused__)),
const Char **argv)
const wchar_t **argv)
{
const struct termcapstr *ts;
const struct termcapval *tv;
@ -1384,7 +1378,7 @@ terminal_settc(EditLine *el, int argc __attribute__((__unused__)),
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;
}
terminal_setflags(el);
@ -1398,7 +1392,7 @@ terminal_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_terminal.t_val[tv - tval] = (int) i;
@ -1416,7 +1410,7 @@ terminal_settc(EditLine *el, int argc __attribute__((__unused__)),
/* terminal_gettc():
* Get the current terminal characteristics
*/
protected int
libedit_private int
/*ARGSUSED*/
terminal_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv)
{
@ -1470,13 +1464,13 @@ terminal_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv)
/* terminal_echotc():
* Print the termcap string out with variable substitution
*/
protected int
libedit_private int
/*ARGSUSED*/
terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
const Char **argv)
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;
@ -1507,28 +1501,28 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
}
if (!*argv || *argv[0] == '\0')
return 0;
if (Strcmp(*argv, STR("tabs")) == 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) {
} 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) {
} 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) {
} 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) {
} else if (wcscmp(*argv, L"baud") == 0) {
(void) fprintf(el->el_outfile, fmtd, (int)el->el_tty.t_speed);
return 0;
} else if (Strcmp(*argv, STR("rows")) == 0 ||
Strcmp(*argv, STR("lines")) == 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) {
} else if (wcscmp(*argv, L"cols") == 0) {
(void) fprintf(el->el_outfile, fmtd, Val(T_co));
return 0;
}
@ -1549,7 +1543,7 @@ terminal_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;
}
@ -1592,7 +1586,7 @@ terminal_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;
}
@ -1607,11 +1601,11 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
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;
}
@ -1620,7 +1614,7 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
if (*argv && *argv[0]) {
if (!silent)
(void) fprintf(el->el_errfile,
"echotc: Warning: Extra argument `" FSTR
"echotc: Warning: Extra argument `%ls"
"'.\n", *argv);
return -1;
}
@ -1641,11 +1635,11 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
"echotc: Warning: Missing argument.\n");
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;
}
@ -1657,11 +1651,11 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
"echotc: Warning: Missing argument.\n");
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;
}
@ -1669,14 +1663,14 @@ terminal_echotc(EditLine *el, int argc __attribute__((__unused__)),
if (*ep != '\0') {
if (!silent)
(void) fprintf(el->el_errfile,
"echotc: Bad value `" FSTR "'.\n", *argv);
"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
"echotc: Warning: Extra argument `%ls"
"'.\n", *argv);
return -1;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: terminal.h,v 1.7 2016/02/16 15:53:48 christos Exp $ */
/* $NetBSD: terminal.h,v 1.9 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -41,7 +41,7 @@
#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 */
keymacro_value_t fun; /* Function bound to it */
int type; /* Type of function */
@ -80,31 +80,32 @@ typedef struct {
#define A_K_DE 6
#define A_K_NKEYS 7
protected void terminal_move_to_line(EditLine *, int);
protected void terminal_move_to_char(EditLine *, int);
protected void terminal_clear_EOL(EditLine *, int);
protected void terminal_overwrite(EditLine *, const Char *, size_t);
protected void terminal_insertwrite(EditLine *, Char *, int);
protected void terminal_deletechars(EditLine *, int);
protected void terminal_clear_screen(EditLine *);
protected void terminal_beep(EditLine *);
protected int terminal_change_size(EditLine *, int, int);
protected int terminal_get_size(EditLine *, int *, int *);
protected int terminal_init(EditLine *);
protected void terminal_bind_arrow(EditLine *);
protected void terminal_print_arrow(EditLine *, const Char *);
protected int terminal_clear_arrow(EditLine *, const Char *);
protected int terminal_set_arrow(EditLine *, const Char *, keymacro_value_t *, int);
protected void terminal_end(EditLine *);
protected void terminal_get(EditLine *, const char **);
protected int terminal_set(EditLine *, const char *);
protected int terminal_settc(EditLine *, int, const Char **);
protected int terminal_gettc(EditLine *, int, char **);
protected int terminal_telltc(EditLine *, int, const Char **);
protected int terminal_echotc(EditLine *, int, const Char **);
protected void terminal_writec(EditLine *, wint_t);
protected int terminal__putc(EditLine *, wint_t);
protected void terminal__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

View File

@ -1,4 +1,4 @@
/* $NetBSD: tokenizer.c,v 1.24 2016/02/17 19:47:49 christos Exp $ */
/* $NetBSD: tokenizer.c,v 1.28 2016/04/11 18:56:31 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: tokenizer.c,v 1.24 2016/02/17 19:47:49 christos Exp $");
__RCSID("$NetBSD: tokenizer.c,v 1.28 2016/04/11 18:56:31 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -49,7 +49,6 @@ __RCSID("$NetBSD: tokenizer.c,v 1.24 2016/02/17 19:47:49 christos Exp $");
#include <string.h>
#include "histedit.h"
#include "chartype.h"
typedef enum {
Q_none, Q_single, Q_double, Q_one, Q_doubleone
@ -66,8 +65,22 @@ 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 */
@ -81,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)
{
@ -104,7 +117,7 @@ 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(*tok));
@ -145,7 +158,7 @@ FUN(tok,init)(const Char *ifs)
/* FUN(tok,reset)():
* Reset the tokenizer
*/
public void
void
FUN(tok,reset)(TYPE(Tokenizer) *tok)
{
@ -160,7 +173,7 @@ FUN(tok,reset)(TYPE(Tokenizer) *tok)
/* FUN(tok,end)():
* Clean up
*/
public void
void
FUN(tok,end)(TYPE(Tokenizer) *tok)
{
@ -189,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)
{
@ -440,7 +453,7 @@ FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
* 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)
{

3
tokenizern.c Normal file
View File

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

102
tty.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.c,v 1.59 2016/03/22 01:34:32 christos Exp $ */
/* $NetBSD: tty.c,v 1.66 2017/09/05 18:07:59 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.59 2016/03/22 01:34:32 christos Exp $");
__RCSID("$NetBSD: tty.c,v 1.66 2017/09/05 18:07:59 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -52,6 +52,7 @@ __RCSID("$NetBSD: tty.c,v 1.59 2016/03/22 01:34:32 christos Exp $");
#include <unistd.h> /* for isatty */
#include "el.h"
#include "fcns.h"
#include "parse.h"
typedef struct ttymodes_t {
@ -66,7 +67,7 @@ typedef struct ttymap_t {
} ttymap_t;
private const ttyperm_t ttyperm = {
static const ttyperm_t ttyperm = {
{
{"iflag:", ICRNL, (INLCR | IGNCR)},
{"oflag:", (OPOST | ONLCR), ONLRET},
@ -94,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,
@ -124,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}},
@ -161,7 +162,7 @@ private const ttymap_t tty_map[] = {
{ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}}
};
private const ttymodes_t ttymodes[] = {
static const ttymodes_t ttymodes[] = {
#ifdef IGNBRK
{"ignbrk", IGNBRK, MD_INP},
#endif /* IGNBRK */
@ -455,21 +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 *);
private void tty_setup_flags(EditLine *, struct termios *, int);
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;
@ -481,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;
@ -493,10 +494,10 @@ 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;
int rst = (el->el_flags & NO_RESET) == 0;
if (el->el_flags & EDIT_DISABLED)
return 0;
@ -567,7 +568,7 @@ tty_setup(EditLine *el)
return 0;
}
protected int
libedit_private int
tty_init(EditLine *el)
{
@ -583,7 +584,7 @@ tty_init(EditLine *el)
/* tty_end():
* Restore the tty to its original settings
*/
protected void
libedit_private void
/*ARGSUSED*/
tty_end(EditLine *el)
{
@ -605,7 +606,7 @@ tty_end(EditLine *el)
/* tty__getspeed():
* Get the tty speed
*/
private speed_t
static speed_t
tty__getspeed(struct termios *td)
{
speed_t spd;
@ -618,7 +619,7 @@ tty__getspeed(struct termios *td)
/* tty__getspeed():
* Return the index of the asked char in the c_cc array
*/
private int
static int
tty__getcharindex(int i)
{
switch (i) {
@ -726,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)
{
@ -808,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)
{
@ -890,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;
@ -913,27 +914,29 @@ tty_bind_char(EditLine *el, int force)
}
for (tp = tty_map; tp->nch != (wint_t)-1; tp++) {
new[0] = (Char)t_n[tp->nch];
old[0] = (Char)t_o[tp->och];
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 */
keymacro_clear(el, map, old);
map[UC(old[0])] = dmap[UC(old[0])];
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) {
keymacro_clear(el, alt, old);
alt[UC(old[0])] = dalt[UC(old[0])];
alt[(unsigned char)old[0]] =
dalt[(unsigned char)old[0]];
keymacro_clear(el, alt, new);
alt[UC(new[0])] = tp->bind[el->el_map.type + 1];
alt[(unsigned char)new[0]] =
tp->bind[el->el_map.type + 1];
}
}
}
private tcflag_t *
static tcflag_t *
tty__get_flag(struct termios *t, int kind) {
switch (kind) {
case MD_INP:
@ -951,7 +954,7 @@ tty__get_flag(struct termios *t, int kind) {
}
private tcflag_t
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;
@ -960,7 +963,7 @@ tty_update_flag(EditLine *el, tcflag_t f, int mode, int kind)
}
private void
static void
tty_update_flags(EditLine *el, int kind)
{
tcflag_t *tt, *ed, *ex;
@ -975,7 +978,7 @@ tty_update_flags(EditLine *el, int kind)
}
private void
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]))
@ -988,7 +991,7 @@ tty_update_char(EditLine *el, int mode, int c) {
/* tty_rawmode():
* Set terminal into 1 character at a time mode.
*/
protected int
libedit_private int
tty_rawmode(EditLine *el)
{
@ -1043,7 +1046,7 @@ tty_rawmode(EditLine *el)
if (i != C_NCC) {
/*
* Propagate changes only to the unprotected
* Propagate changes only to the unlibedit_private
* chars that have been modified just now.
*/
for (i = 0; i < C_NCC; i++)
@ -1073,7 +1076,7 @@ tty_rawmode(EditLine *el)
/* tty_cookedmode():
* Set the tty back to normal mode
*/
protected int
libedit_private int
tty_cookedmode(EditLine *el)
{ /* set tty in normal setup */
@ -1098,7 +1101,7 @@ tty_cookedmode(EditLine *el)
/* tty_quotemode():
* Turn on quote mode
*/
protected int
libedit_private int
tty_quotemode(EditLine *el)
{
if (el->el_tty.t_mode == QU_IO)
@ -1123,7 +1126,7 @@ tty_quotemode(EditLine *el)
/* tty_noquotemode():
* Turn off quote mode
*/
protected int
libedit_private int
tty_noquotemode(EditLine *el)
{
@ -1144,14 +1147,15 @@ tty_noquotemode(EditLine *el)
/* 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;
@ -1235,7 +1239,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
return 0;
}
while (argv && (s = *argv++)) {
const Char *p;
const wchar_t *p;
switch (*s) {
case '+':
case '-':
@ -1246,7 +1250,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
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)) :
@ -1257,7 +1261,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
if (!m->m_name) {
(void) fprintf(el->el_errfile,
"%s: Invalid argument `" FSTR "'.\n", name, d);
"%s: Invalid argument `%ls'.\n", name, d);
return -1;
}
if (p) {
@ -1306,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;
@ -1327,7 +1331,7 @@ tty_printchar(EditLine *el, unsigned char *s)
#endif /* notyet */
private void
static void
tty_setup_flags(EditLine *el, struct termios *tios, int mode)
{
int kind;

18
tty.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.h,v 1.19 2016/02/27 18:13:21 christos Exp $ */
/* $NetBSD: tty.h,v 1.21 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -456,14 +456,14 @@ 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;

159
vi.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: vi.c,v 1.55 2016/03/02 19:24:20 christos Exp $ */
/* $NetBSD: vi.c,v 1.62 2016/05/09 21:46:56 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: vi.c,v 1.55 2016/03/02 19:24:20 christos Exp $");
__RCSID("$NetBSD: vi.c,v 1.62 2016/05/09 21:46:56 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -54,15 +54,16 @@ __RCSID("$NetBSD: vi.c,v 1.55 2016/03/02 19:24:20 christos Exp $");
#include "el.h"
#include "common.h"
#include "emacs.h"
#include "fcns.h"
#include "vi.h"
private el_action_t cv_action(EditLine *, wint_t);
private el_action_t cv_paste(EditLine *, wint_t);
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
static el_action_t
cv_action(EditLine *el, wint_t c)
{
@ -94,7 +95,7 @@ cv_action(EditLine *el, wint_t c)
/* cv_paste():
* Paste previous deletion before or after the cursor
*/
private el_action_t
static el_action_t
cv_paste(EditLine *el, wint_t c)
{
c_kill_t *k = &el->el_chared.c_kill;
@ -103,7 +104,7 @@ cv_paste(EditLine *el, wint_t c)
if (k->buf == NULL || len == 0)
return CC_ERROR;
#ifdef DEBUG_PASTE
(void) fprintf(el->el_errfile, "Paste: \"" FSTARSTR "\"\n", (int)len,
(void) fprintf(el->el_errfile, "Paste: \"%.*ls\"\n", (int)len,
k->buf);
#endif
@ -126,7 +127,7 @@ cv_paste(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -139,7 +140,7 @@ vi_paste_next(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -152,7 +153,7 @@ vi_paste_prev(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -177,7 +178,7 @@ vi_prev_big_word(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -202,7 +203,7 @@ vi_prev_word(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -226,7 +227,7 @@ vi_next_big_word(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -250,7 +251,7 @@ vi_next_word(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi change case of character under the cursor and advance one character
* [~]
*/
protected el_action_t
libedit_private el_action_t
vi_change_case(EditLine *el, wint_t c)
{
int i;
@ -261,10 +262,10 @@ vi_change_case(EditLine *el, wint_t c)
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--;
@ -281,7 +282,7 @@ vi_change_case(EditLine *el, wint_t c)
* Vi change prefix command
* [c]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_change_meta(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -298,7 +299,7 @@ vi_change_meta(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -314,7 +315,7 @@ vi_insert_at_bol(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -333,7 +334,7 @@ vi_replace_char(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi enter replace mode
* [R]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_replace_mode(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -349,7 +350,7 @@ vi_replace_mode(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -364,7 +365,7 @@ vi_substitute_char(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi substitute entire line
* [S]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_substitute_line(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -382,7 +383,7 @@ vi_substitute_line(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -400,7 +401,7 @@ vi_change_to_eol(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi enter insert mode
* [i]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_insert(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -415,7 +416,7 @@ vi_insert(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -440,7 +441,7 @@ vi_add(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -456,7 +457,7 @@ vi_add_at_eol(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi delete prefix command
* [d]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_delete_meta(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -469,7 +470,7 @@ vi_delete_meta(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -493,7 +494,7 @@ vi_end_big_word(EditLine *el, wint_t c __attribute__((__unused__)))
* 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, wint_t c __attribute__((__unused__)))
{
@ -517,7 +518,7 @@ vi_end_word(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi undo last change
* [u]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_undo(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -544,7 +545,7 @@ vi_undo(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi enter command mode (use alternative key bindings)
* [<ESC>]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_command_mode(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -569,7 +570,7 @@ vi_command_mode(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi move to the beginning of line
* [0]
*/
protected el_action_t
libedit_private el_action_t
vi_zero(EditLine *el, wint_t c)
{
@ -589,7 +590,7 @@ vi_zero(EditLine *el, wint_t c)
* 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, wint_t c __attribute__((__unused__)))
{
@ -607,7 +608,7 @@ vi_delete_prev_char(EditLine *el, wint_t 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, wint_t c)
{
@ -644,11 +645,11 @@ vi_list_or_eof(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
Char *kp, *cp;
wchar_t *kp, *cp;
cp = el->el_line.buffer;
kp = el->el_chared.c_kill.buf;
@ -665,7 +666,7 @@ vi_kill_line_prev(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi search history previous
* [?]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -678,7 +679,7 @@ vi_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi search history next
* [/]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -691,7 +692,7 @@ vi_search_next(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -708,7 +709,7 @@ vi_repeat_search_next(EditLine *el, wint_t c __attribute__((__unused__)))
* [N]
*/
/*ARGSUSED*/
protected el_action_t
libedit_private el_action_t
vi_repeat_search_prev(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -725,7 +726,7 @@ vi_repeat_search_prev(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -737,7 +738,7 @@ vi_next_char(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -749,7 +750,7 @@ vi_prev_char(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -761,7 +762,7 @@ vi_to_next_char(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -773,7 +774,7 @@ vi_to_prev_char(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -787,7 +788,7 @@ vi_repeat_next_char(EditLine *el, wint_t 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, wint_t c __attribute__((__unused__)))
{
@ -805,22 +806,22 @@ vi_repeat_prev_char(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi go to matching () {} or []
* [%]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
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 = (size_t)(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;
@ -852,7 +853,7 @@ vi_match(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi undo all changes to line
* [U]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_undo_line(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -866,7 +867,7 @@ vi_undo_line(EditLine *el, wint_t c __attribute__((__unused__)))
* [|]
* 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, wint_t c __attribute__((__unused__)))
{
@ -880,7 +881,7 @@ vi_to_column(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi yank to end of line
* [Y]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_yank_end(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -894,7 +895,7 @@ vi_yank_end(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi yank
* [y]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_yank(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -906,7 +907,7 @@ vi_yank(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi comment out current command
* [#]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_comment_out(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -924,7 +925,7 @@ vi_comment_out(EditLine *el, wint_t c __attribute__((__unused__)))
* NB: posix implies that we should enter insert mode, however
* this is against historical precedent...
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_alias(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -942,7 +943,7 @@ vi_alias(EditLine *el, wint_t c __attribute__((__unused__)))
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;
}
@ -950,7 +951,7 @@ vi_alias(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi go to specified history file line.
* [G]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_to_history_line(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -959,7 +960,7 @@ vi_to_history_line(EditLine *el, wint_t c __attribute__((__unused__)))
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);
@ -995,7 +996,7 @@ vi_to_history_line(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi edit history line with vi
* [v]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -1006,7 +1007,7 @@ vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
char *cp = NULL;
size_t len;
Char *line = NULL;
wchar_t *line = NULL;
if (el->el_state.doingarg) {
if (vi_to_history_line(el, 0) == CC_ERROR)
@ -1024,9 +1025,9 @@ vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
line = el_malloc(len * sizeof(*line) + 1);
if (line == NULL)
goto error;
Strncpy(line, el->el_line.buffer, len);
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);
@ -1048,7 +1049,7 @@ vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
if (st > 0) {
cp[st] = '\0';
len = (size_t)(el->el_line.limit - el->el_line.buffer);
len = ct_mbstowcs(el->el_line.buffer, cp, len);
len = mbstowcs(el->el_line.buffer, cp, len);
if (len > 0 && el->el_line.buffer[len - 1] == '\n')
--len;
}
@ -1079,33 +1080,33 @@ vi_histedit(EditLine *el, wint_t c __attribute__((__unused__)))
* 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, 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);
@ -1129,7 +1130,7 @@ vi_history_word(EditLine *el, wint_t c __attribute__((__unused__)))
* Vi redo last non-motion command
* [.]
*/
protected el_action_t
libedit_private el_action_t
/*ARGSUSED*/
vi_redo(EditLine *el, wint_t c __attribute__((__unused__)))
{
@ -1147,7 +1148,7 @@ vi_redo(EditLine *el, wint_t c __attribute__((__unused__)))
/* 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;