Vendor import NetBSD's libedit of "2005/08/02 12:11:14 UTC".

Obtained from:	NetBSD
This commit is contained in:
David E. O'Brien 2011-03-31 01:13:05 +00:00
parent f592be44eb
commit 75d35a3703
47 changed files with 4022 additions and 2330 deletions

View File

@ -1,9 +1,15 @@
# $NetBSD: Makefile,v 1.20 2001/01/05 21:15:49 jdolecek Exp $ # $NetBSD: Makefile,v 1.34 2005/05/28 12:02:53 lukem Exp $
# @(#)Makefile 8.1 (Berkeley) 6/4/93 # @(#)Makefile 8.1 (Berkeley) 6/4/93
USE_SHLIBDIR= yes
WARNS= 3
LIB= edit LIB= edit
OSRCS= chared.c common.c el.c emacs.c fcns.c help.c hist.c key.c map.c \ LIBDPLIBS= termcap ${.CURDIR}/../libterm
OSRCS= chared.c common.c el.c emacs.c fcns.c filecomplete.c help.c hist.c \
key.c map.c \
parse.c prompt.c read.c refresh.c search.c sig.c term.c tty.c vi.c parse.c prompt.c read.c refresh.c search.c sig.c term.c tty.c vi.c
MAN= editline.3 editrc.5 MAN= editline.3 editrc.5
@ -13,75 +19,86 @@ MLINKS= editline.3 el_init.3 editline.3 el_end.3 editline.3 el_reset.3 \
editline.3 el_parse.3 editline.3 el_set.3 editline.3 el_get.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_source.3 editline.3 el_resize.3 editline.3 el_line.3 \
editline.3 el_insertstr.3 editline.3 el_deletestr.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 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
# For speed and debugging # For speed and debugging
#SRCS= ${OSRCS} tokenizer.c history.c readline.c #SRCS= ${OSRCS} tokenizer.c history.c readline.c
# For protection # For protection
SRCS= editline.c tokenizer.c history.c readline.c SRCS= editline.c tokenizer.c history.c readline.c
SRCS+= common.h emacs.h fcns.h help.h vi.h
LIBEDITDIR?=${.CURDIR} LIBEDITDIR?=${.CURDIR}
INCS= histedit.h INCS= histedit.h
INCSDIR=/usr/include INCSDIR=/usr/include
CLEANFILES+=common.h editline.c emacs.h fcns.c fcns.h help.c help.h vi.h CLEANFILES+=editline.c
CLEANFILES+=common.h.tmp editline.c.tmp emacs.h.tmp fcns.c.tmp fcns.h.tmp 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 CLEANFILES+=help.c.tmp help.h.tmp vi.h.tmp
CLEANFILES+=test.o test
CPPFLAGS+=-I. -I${LIBEDITDIR} CPPFLAGS+=-I. -I${LIBEDITDIR}
CPPFLAGS+=-I. -I${.CURDIR} CPPFLAGS+=-I. -I${.CURDIR}
CPPFLAGS+=#-DDEBUG_TTY -DDEBUG_KEY -DDEBUG_READ -DDEBUG -DDEBUG_REFRESH CPPFLAGS+=#-DDEBUG_TTY -DDEBUG_KEY -DDEBUG_READ -DDEBUG -DDEBUG_REFRESH
CPPFLAGS+=#-DDEBUG_PASTE CPPFLAGS+=#-DDEBUG_PASTE -DDEBUG_EDIT
AHDR=vi.h emacs.h common.h AHDR=vi.h emacs.h common.h
ASRC=${LIBEDITDIR}/vi.c ${LIBEDITDIR}/emacs.c ${LIBEDITDIR}/common.c 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
SUBDIR= readline SUBDIR= readline
vi.h: vi.c makelist vi.h: vi.c makelist Makefile
sh ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/vi.c > ${.TARGET}.tmp && \ ${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/vi.c \
> ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET} mv ${.TARGET}.tmp ${.TARGET}
emacs.h: emacs.c makelist emacs.h: emacs.c makelist Makefile
sh ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/emacs.c > ${.TARGET}.tmp && \ ${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/emacs.c \
> ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET} mv ${.TARGET}.tmp ${.TARGET}
common.h: common.c makelist common.h: common.c makelist Makefile
sh ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/common.c > ${.TARGET}.tmp && \ ${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/common.c \
> ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET} mv ${.TARGET}.tmp ${.TARGET}
fcns.h: ${AHDR} makelist fcns.h: ${AHDR} makelist Makefile
sh ${LIBEDITDIR}/makelist -fh ${AHDR} > ${.TARGET}.tmp && \ ${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -fh ${AHDR} > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET} mv ${.TARGET}.tmp ${.TARGET}
fcns.c: ${AHDR} fcns.h makelist fcns.c: ${AHDR} fcns.h help.h makelist Makefile
sh ${LIBEDITDIR}/makelist -fc ${AHDR} > ${.TARGET}.tmp && \ ${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -fc ${AHDR} > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET} mv ${.TARGET}.tmp ${.TARGET}
help.c: ${ASRC} makelist help.c: ${ASRC} makelist Makefile
sh ${LIBEDITDIR}/makelist -bc ${ASRC} > ${.TARGET}.tmp && \ ${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -bc ${ASRC} > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET} mv ${.TARGET}.tmp ${.TARGET}
help.h: ${ASRC} makelist help.h: ${ASRC} makelist Makefile
sh ${LIBEDITDIR}/makelist -bh ${ASRC} > ${.TARGET}.tmp && \ ${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -bh ${ASRC} > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET} mv ${.TARGET}.tmp ${.TARGET}
editline.c: ${OSRCS} editline.c: ${OSRCS} makelist Makefile
sh ${LIBEDITDIR}/makelist -e ${.ALLSRC:T} > ${.TARGET}.tmp && \ ${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -e ${OSRCS:T} > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET} mv ${.TARGET}.tmp ${.TARGET}
test.o: ${LIBEDITDIR}/TEST/test.c test.o: ${LIBEDITDIR}/TEST/test.c
test: libedit.a test.o test: libedit.a test.o
${_MKTARGET_LINK}
${CC} ${LDFLAGS} ${.ALLSRC} -o ${.TARGET} libedit.a ${LDADD} -ltermcap ${CC} ${LDFLAGS} ${.ALLSRC} -o ${.TARGET} libedit.a ${LDADD} -ltermcap
# minimal dependency to make "make depend" optional
editline.o editline.po editline.so editline.ln: \
common.h emacs.h fcns.c fcns.h help.c help.h vi.h
readline.o readline.po readline.so readline.ln: \
common.h emacs.h fcns.h help.h vi.h
.include <bsd.lib.mk> .include <bsd.lib.mk>
.include <bsd.subdir.mk> .include <bsd.subdir.mk>

13
TEST/Makefile Normal file
View File

@ -0,0 +1,13 @@
# $NetBSD: Makefile,v 1.2 2003/12/05 13:37:48 lukem Exp $
NOMAN=1
PROG=test
CPPFLAGS=-I${.CURDIR}/..
LDADD+=-ledit -ltermcap
DPADD+=${LIBEDIT} ${LIBTERMCAP}
.ifdef DEBUG
CPPFLAGS+=-DDEBUG
.endif
.include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $ */ /* $NetBSD: test.c,v 1.18 2005/06/01 11:37:52 lukem Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,7 +32,7 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#ifndef lint #ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\ __COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
The Regents of the University of California. All rights reserved.\n"); The Regents of the University of California. All rights reserved.\n");
@ -46,14 +42,13 @@ __COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
#if 0 #if 0
static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $"); __RCSID("$NetBSD: test.c,v 1.18 2005/06/01 11:37:52 lukem Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* test.c: A little test program * test.c: A little test program
*/ */
#include "sys.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <signal.h> #include <signal.h>
@ -64,12 +59,11 @@ __RCSID("$NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $");
#include <dirent.h> #include <dirent.h>
#include "histedit.h" #include "histedit.h"
#include "tokenizer.h"
static int continuation = 0; static int continuation = 0;
static EditLine *el = NULL; volatile sig_atomic_t gotsig = 0;
static u_char complete(EditLine *, int); static unsigned char complete(EditLine *, int);
int main(int, char **); int main(int, char **);
static char *prompt(EditLine *); static char *prompt(EditLine *);
static void sig(int); static void sig(int);
@ -77,8 +71,8 @@ static void sig(int);
static char * static char *
prompt(EditLine *el) prompt(EditLine *el)
{ {
static char a[] = "Edit$"; static char a[] = "Edit$ ";
static char b[] = "Edit>"; static char b[] = "Edit> ";
return (continuation ? b : a); return (continuation ? b : a);
} }
@ -86,9 +80,7 @@ prompt(EditLine *el)
static void static void
sig(int i) sig(int i)
{ {
gotsig = i;
(void) fprintf(stderr, "Got signal %d.\n", i);
el_reset(el);
} }
static unsigned char static unsigned char
@ -103,7 +95,8 @@ complete(EditLine *el, int ch)
/* /*
* Find the last word * Find the last word
*/ */
for (ptr = lf->cursor - 1; !isspace(*ptr) && ptr > lf->buffer; ptr--) for (ptr = lf->cursor - 1;
!isspace((unsigned char)*ptr) && ptr > lf->buffer; ptr--)
continue; continue;
len = lf->cursor - ++ptr; len = lf->cursor - ++ptr;
@ -126,10 +119,14 @@ complete(EditLine *el, int ch)
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
EditLine *el = NULL;
int num; int num;
const char *buf; const char *buf;
Tokenizer *tok; Tokenizer *tok;
int lastevent = 0, ncontinuation; #if 0
int lastevent = 0;
#endif
int ncontinuation;
History *hist; History *hist;
HistEvent ev; HistEvent ev;
@ -173,17 +170,41 @@ main(int argc, char *argv[])
el_source(el, NULL); el_source(el, NULL);
while ((buf = el_gets(el, &num)) != NULL && num != 0) { while ((buf = el_gets(el, &num)) != NULL && num != 0) {
int ac; int ac, cc, co;
char **av;
#ifdef DEBUG #ifdef DEBUG
(void) fprintf(stderr, "got %d %s", num, buf); int i;
#endif #endif
const char **av;
const LineInfo *li;
li = el_line(el);
#ifdef DEBUG
(void) fprintf(stderr, "==> got %d %s", num, buf);
(void) fprintf(stderr, " > li `%.*s_%.*s'\n",
(li->cursor - li->buffer), li->buffer,
(li->lastchar - 1 - li->cursor),
(li->cursor >= li->lastchar) ? "" : li->cursor);
#endif
if (gotsig) {
(void) fprintf(stderr, "Got signal %d.\n", gotsig);
gotsig = 0;
el_reset(el);
}
if (!continuation && num == 1) if (!continuation && num == 1)
continue; continue;
if (tok_line(tok, buf, &ac, &av) > 0) ac = cc = co = 0;
ncontinuation = 1; ncontinuation = tok_line(tok, li, &ac, &av, &cc, &co);
if (ncontinuation < 0) {
(void) fprintf(stderr, "Internal error\n");
continuation = 0;
continue;
}
#ifdef DEBUG
(void) fprintf(stderr, " > nc %d ac %d cc %d co %d\n",
ncontinuation, ac, cc, co);
#endif
#if 0 #if 0
if (continuation) { if (continuation) {
/* /*
@ -191,7 +212,7 @@ main(int argc, char *argv[])
* moved around in history. * moved around in history.
*/ */
if (history(hist, &ev, H_SET, lastevent) == -1) if (history(hist, &ev, H_SET, lastevent) == -1)
err(1, "%d: %s\n", lastevent, ev.str); err(1, "%d: %s", lastevent, ev.str);
history(hist, &ev, H_ADD , buf); history(hist, &ev, H_ADD , buf);
} else { } else {
history(hist, &ev, H_ENTER, buf); history(hist, &ev, H_ENTER, buf);
@ -204,6 +225,18 @@ main(int argc, char *argv[])
continuation = ncontinuation; continuation = ncontinuation;
ncontinuation = 0; ncontinuation = 0;
if (continuation)
continue;
#ifdef DEBUG
for (i = 0; i < ac; i++) {
(void) fprintf(stderr, " > arg# %2d ", i);
if (i != cc)
(void) fprintf(stderr, "`%s'\n", av[i]);
else
(void) fprintf(stderr, "`%.*s_%s'\n",
co, av[i], av[i] + co);
}
#endif
if (strcmp(av[0], "history") == 0) { if (strcmp(av[0], "history") == 0) {
int rv; int rv;
@ -239,7 +272,7 @@ main(int argc, char *argv[])
} else if (el_parse(el, ac, av) == -1) { } else if (el_parse(el, ac, av) == -1) {
switch (fork()) { switch (fork()) {
case 0: case 0:
execvp(av[0], av); execvp(av[0], (char *const *)__UNCONST(av));
perror(av[0]); perror(av[0]);
_exit(1); _exit(1);
/*NOTREACHED*/ /*NOTREACHED*/

342
chared.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: chared.c,v 1.14 2001/05/17 01:02:17 christos Exp $ */ /* $NetBSD: chared.c,v 1.24 2005/08/01 23:00:15 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,23 +32,23 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: chared.c,v 1.14 2001/05/17 01:02:17 christos Exp $"); __RCSID("$NetBSD: chared.c,v 1.24 2005/08/01 23:00:15 christos Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* chared.c: Character editor utilities * chared.c: Character editor utilities
*/ */
#include "sys.h"
#include <stdlib.h> #include <stdlib.h>
#include "el.h" #include "el.h"
private void ch__clearmacro __P((EditLine *));
/* value to leave unused in line buffer */ /* value to leave unused in line buffer */
#define EL_LEAVE 2 #define EL_LEAVE 2
@ -60,17 +56,36 @@ __RCSID("$NetBSD: chared.c,v 1.14 2001/05/17 01:02:17 christos Exp $");
* Handle state for the vi undo command * Handle state for the vi undo command
*/ */
protected void protected void
cv_undo(EditLine *el,int action, size_t size, char *ptr) cv_undo(EditLine *el)
{ {
c_undo_t *vu = &el->el_chared.c_undo; c_undo_t *vu = &el->el_chared.c_undo;
vu->action = action; c_redo_t *r = &el->el_chared.c_redo;
vu->ptr = ptr; unsigned int size;
vu->isize = size;
(void) memcpy(vu->buf, vu->ptr, size); /* Save entire line for undo */
#ifdef DEBUG_UNDO size = el->el_line.lastchar - el->el_line.buffer;
(void) fprintf(el->el_errfile, "Undo buffer \"%s\" size = +%d -%d\n", vu->len = size;
vu->ptr, vu->isize, vu->dsize); vu->cursor = el->el_line.cursor - el->el_line.buffer;
#endif memcpy(vu->buf, el->el_line.buffer, size);
/* save command info for redo */
r->count = el->el_state.doingarg ? el->el_state.argument : 0;
r->action = el->el_chared.c_vcmd.action;
r->pos = r->buf;
r->cmd = el->el_state.thiscmd;
r->ch = el->el_state.thisch;
}
/* cv_yank():
* Save yank/delete data for paste
*/
protected void
cv_yank(EditLine *el, const char *ptr, int size)
{
c_kill_t *k = &el->el_chared.c_kill;
memcpy(k->buf, ptr, size +0u);
k->last = k->buf + size;
} }
@ -82,8 +97,10 @@ c_insert(EditLine *el, int num)
{ {
char *cp; char *cp;
if (el->el_line.lastchar + num >= el->el_line.limit) if (el->el_line.lastchar + num >= el->el_line.limit) {
return; /* can't go past end of buffer */ if (!ch_enlargebufs(el, num +0u))
return; /* can't go past end of buffer */
}
if (el->el_line.cursor < el->el_line.lastchar) { if (el->el_line.cursor < el->el_line.lastchar) {
/* if I must move chars */ /* if I must move chars */
@ -104,12 +121,14 @@ c_delafter(EditLine *el, int num)
if (el->el_line.cursor + num > el->el_line.lastchar) if (el->el_line.cursor + num > el->el_line.lastchar)
num = el->el_line.lastchar - el->el_line.cursor; num = el->el_line.lastchar - el->el_line.cursor;
if (el->el_map.current != el->el_map.emacs) {
cv_undo(el);
cv_yank(el, el->el_line.cursor, num);
}
if (num > 0) { if (num > 0) {
char *cp; char *cp;
if (el->el_map.current != el->el_map.emacs)
cv_undo(el, INSERT, (size_t)num, el->el_line.cursor);
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
*cp = cp[num]; *cp = cp[num];
@ -118,6 +137,21 @@ c_delafter(EditLine *el, int num)
} }
/* c_delafter1():
* Delete the character after the cursor, do not yank
*/
protected void
c_delafter1(EditLine *el)
{
char *cp;
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
*cp = cp[1];
el->el_line.lastchar--;
}
/* c_delbefore(): /* c_delbefore():
* Delete num characters before the cursor * Delete num characters before the cursor
*/ */
@ -128,13 +162,14 @@ c_delbefore(EditLine *el, int num)
if (el->el_line.cursor - num < el->el_line.buffer) if (el->el_line.cursor - num < el->el_line.buffer)
num = el->el_line.cursor - el->el_line.buffer; num = el->el_line.cursor - el->el_line.buffer;
if (el->el_map.current != el->el_map.emacs) {
cv_undo(el);
cv_yank(el, el->el_line.cursor - num, num);
}
if (num > 0) { if (num > 0) {
char *cp; char *cp;
if (el->el_map.current != el->el_map.emacs)
cv_undo(el, INSERT, (size_t)num,
el->el_line.cursor - num);
for (cp = el->el_line.cursor - num; for (cp = el->el_line.cursor - num;
cp <= el->el_line.lastchar; cp <= el->el_line.lastchar;
cp++) cp++)
@ -145,13 +180,28 @@ c_delbefore(EditLine *el, int num)
} }
/* c_delbefore1():
* Delete the character before the cursor, do not yank
*/
protected void
c_delbefore1(EditLine *el)
{
char *cp;
for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
*cp = cp[1];
el->el_line.lastchar--;
}
/* ce__isword(): /* ce__isword():
* Return if p is part of a word according to emacs * Return if p is part of a word according to emacs
*/ */
protected int protected int
ce__isword(int p) ce__isword(int p)
{ {
return (isalpha(p) || isdigit(p) || strchr("*?_-.[]~=", p) != NULL); return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL);
} }
@ -160,6 +210,20 @@ ce__isword(int p)
*/ */
protected int protected int
cv__isword(int p) cv__isword(int p)
{
if (isalnum(p) || p == '_')
return 1;
if (isgraph(p))
return 2;
return 0;
}
/* cv__isWord():
* Return if p is part of a big word according to vi
*/
protected int
cv__isWord(int p)
{ {
return (!isspace(p)); return (!isspace(p));
} }
@ -223,7 +287,7 @@ cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int))
* vi historically deletes with cw only the word preserving the * vi historically deletes with cw only the word preserving the
* trailing whitespace! This is not what 'w' does.. * trailing whitespace! This is not what 'w' does..
*/ */
if (el->el_chared.c_vcmd.action != (DELETE|INSERT)) if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
while ((p < high) && isspace((unsigned char) *p)) while ((p < high) && isspace((unsigned char) *p))
p++; p++;
} }
@ -240,26 +304,19 @@ cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int))
* Find the previous word vi style * Find the previous word vi style
*/ */
protected char * protected char *
cv_prev_word(EditLine *el, char *p, char *low, int n, int (*wtest)(int)) cv_prev_word(char *p, char *low, int n, int (*wtest)(int))
{ {
int test; int test;
p--;
while (n--) { while (n--) {
p--; while ((p > low) && isspace((unsigned char) *p))
/* p--;
* vi historically deletes with cb only the word preserving the
* leading whitespace! This is not what 'b' does..
*/
if (el->el_chared.c_vcmd.action != (DELETE|INSERT))
while ((p > low) && isspace((unsigned char) *p))
p--;
test = (*wtest)((unsigned char) *p); test = (*wtest)((unsigned char) *p);
while ((p >= low) && (*wtest)((unsigned char) *p) == test) while ((p >= low) && (*wtest)((unsigned char) *p) == test)
p--; p--;
p++;
while (isspace((unsigned char) *p))
p++;
} }
p++;
/* p now points where we want it */ /* p now points where we want it */
if (p < low) if (p < low)
@ -310,47 +367,34 @@ protected void
cv_delfini(EditLine *el) cv_delfini(EditLine *el)
{ {
int size; int size;
int oaction; int action = el->el_chared.c_vcmd.action;
if (el->el_chared.c_vcmd.action & INSERT) if (action & INSERT)
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
oaction = el->el_chared.c_vcmd.action;
el->el_chared.c_vcmd.action = NOP;
if (el->el_chared.c_vcmd.pos == 0) if (el->el_chared.c_vcmd.pos == 0)
/* sanity */
return; return;
size = el->el_line.cursor - el->el_chared.c_vcmd.pos;
if (el->el_line.cursor > el->el_chared.c_vcmd.pos) { if (size == 0)
size = (int) (el->el_line.cursor - el->el_chared.c_vcmd.pos);
c_delbefore(el, size);
el->el_line.cursor = el->el_chared.c_vcmd.pos;
re_refresh_cursor(el);
} else if (el->el_line.cursor < el->el_chared.c_vcmd.pos) {
size = (int)(el->el_chared.c_vcmd.pos - el->el_line.cursor);
c_delafter(el, size);
} else {
size = 1; size = 1;
c_delafter(el, size); el->el_line.cursor = el->el_chared.c_vcmd.pos;
if (action & YANK) {
if (size > 0)
cv_yank(el, el->el_line.cursor, size);
else
cv_yank(el, el->el_line.cursor + size, -size);
} else {
if (size > 0) {
c_delafter(el, size);
re_refresh_cursor(el);
} else {
c_delbefore(el, -size);
el->el_line.cursor += size;
}
} }
switch (oaction) { el->el_chared.c_vcmd.action = NOP;
case DELETE|INSERT:
el->el_chared.c_undo.action = DELETE|INSERT;
break;
case DELETE:
el->el_chared.c_undo.action = INSERT;
break;
case NOP:
case INSERT:
default:
EL_ABORT((el->el_errfile, "Bad oaction %d\n", oaction));
break;
}
el->el_chared.c_undo.ptr = el->el_line.cursor;
el->el_chared.c_undo.dsize = size;
} }
@ -380,21 +424,19 @@ ce__endword(char *p, char *high, int n)
* Go to the end of this word according to vi * Go to the end of this word according to vi
*/ */
protected char * protected char *
cv__endword(char *p, char *high, int n) cv__endword(char *p, char *high, int n, int (*wtest)(int))
{ {
int test;
p++; p++;
while (n--) { while (n--) {
while ((p < high) && isspace((unsigned char) *p)) while ((p < high) && isspace((unsigned char) *p))
p++; p++;
if (isalnum((unsigned char) *p)) test = (*wtest)((unsigned char) *p);
while ((p < high) && isalnum((unsigned char) *p)) while ((p < high) && (*wtest)((unsigned char) *p) == test)
p++; p++;
else
while ((p < high) && !(isspace((unsigned char) *p) ||
isalnum((unsigned char) *p)))
p++;
} }
p--; p--;
return (p); return (p);
@ -406,6 +448,8 @@ cv__endword(char *p, char *high, int n)
protected int protected int
ch_init(EditLine *el) ch_init(EditLine *el)
{ {
c_macro_t *ma = &el->el_chared.c_macro;
el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ); el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ);
if (el->el_line.buffer == NULL) if (el->el_line.buffer == NULL)
return (-1); return (-1);
@ -413,20 +457,23 @@ ch_init(EditLine *el)
(void) memset(el->el_line.buffer, 0, EL_BUFSIZ); (void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
el->el_line.cursor = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer;
el->el_line.lastchar = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer;
el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - 2]; el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE];
el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ); el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ);
if (el->el_chared.c_undo.buf == NULL) if (el->el_chared.c_undo.buf == NULL)
return (-1); return (-1);
(void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ); (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
el->el_chared.c_undo.action = NOP; el->el_chared.c_undo.len = -1;
el->el_chared.c_undo.isize = 0; el->el_chared.c_undo.cursor = 0;
el->el_chared.c_undo.dsize = 0; el->el_chared.c_redo.buf = (char *) el_malloc(EL_BUFSIZ);
el->el_chared.c_undo.ptr = el->el_line.buffer; if (el->el_chared.c_redo.buf == NULL)
return (-1);
el->el_chared.c_redo.pos = el->el_chared.c_redo.buf;
el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ;
el->el_chared.c_redo.cmd = ED_UNASSIGNED;
el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_vcmd.pos = el->el_line.buffer; el->el_chared.c_vcmd.pos = el->el_line.buffer;
el->el_chared.c_vcmd.ins = el->el_line.buffer;
el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ); el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ);
if (el->el_chared.c_kill.buf == NULL) if (el->el_chared.c_kill.buf == NULL)
@ -443,11 +490,10 @@ ch_init(EditLine *el)
el->el_state.argument = 1; el->el_state.argument = 1;
el->el_state.lastcmd = ED_UNASSIGNED; el->el_state.lastcmd = ED_UNASSIGNED;
el->el_chared.c_macro.nline = NULL; ma->level = -1;
el->el_chared.c_macro.level = -1; ma->offset = 0;
el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO * ma->macro = (char **) el_malloc(EL_MAXMACRO * sizeof(char *));
sizeof(char *)); if (ma->macro == NULL)
if (el->el_chared.c_macro.macro == NULL)
return (-1); return (-1);
return (0); return (0);
} }
@ -456,19 +502,16 @@ ch_init(EditLine *el)
* Reset the character editor * Reset the character editor
*/ */
protected void protected void
ch_reset(EditLine *el) ch_reset(EditLine *el, int mclear)
{ {
el->el_line.cursor = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer;
el->el_line.lastchar = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer;
el->el_chared.c_undo.action = NOP; el->el_chared.c_undo.len = -1;
el->el_chared.c_undo.isize = 0; el->el_chared.c_undo.cursor = 0;
el->el_chared.c_undo.dsize = 0;
el->el_chared.c_undo.ptr = el->el_line.buffer;
el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_vcmd.pos = el->el_line.buffer; el->el_chared.c_vcmd.pos = el->el_line.buffer;
el->el_chared.c_vcmd.ins = el->el_line.buffer;
el->el_chared.c_kill.mark = el->el_line.buffer; el->el_chared.c_kill.mark = el->el_line.buffer;
@ -480,9 +523,17 @@ ch_reset(EditLine *el)
el->el_state.argument = 1; el->el_state.argument = 1;
el->el_state.lastcmd = ED_UNASSIGNED; el->el_state.lastcmd = ED_UNASSIGNED;
el->el_chared.c_macro.level = -1; if (mclear)
ch__clearmacro(el);
}
el->el_history.eventno = 0; private void
ch__clearmacro(el)
EditLine *el;
{
c_macro_t *ma = &el->el_chared.c_macro;
while (ma->level >= 0)
el_free((ptr_t)ma->macro[ma->level--]);
} }
/* ch_enlargebufs(): /* ch_enlargebufs():
@ -523,7 +574,8 @@ ch_enlargebufs(el, addlen)
el->el_line.buffer = newbuffer; el->el_line.buffer = newbuffer;
el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf); el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf);
el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf); el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf);
el->el_line.limit = &newbuffer[newsz - EL_LEAVE]; /* don't set new size until all buffers are enlarged */
el->el_line.limit = &newbuffer[sz - EL_LEAVE];
/* /*
* Reallocate kill buffer. * Reallocate kill buffer.
@ -552,14 +604,22 @@ ch_enlargebufs(el, addlen)
/* zero the newly added memory, leave old data in */ /* zero the newly added memory, leave old data in */
(void) memset(&newbuffer[sz], 0, newsz - sz); (void) memset(&newbuffer[sz], 0, newsz - sz);
el->el_chared.c_undo.ptr = el->el_line.buffer +
(el->el_chared.c_undo.ptr - oldbuf);
el->el_chared.c_undo.buf = newbuffer; el->el_chared.c_undo.buf = newbuffer;
newbuffer = el_realloc(el->el_chared.c_redo.buf, newsz);
if (!newbuffer)
return 0;
el->el_chared.c_redo.pos = newbuffer +
(el->el_chared.c_redo.pos - el->el_chared.c_redo.buf);
el->el_chared.c_redo.lim = newbuffer +
(el->el_chared.c_redo.lim - el->el_chared.c_redo.buf);
el->el_chared.c_redo.buf = newbuffer;
if (!hist_enlargebuf(el, sz, newsz)) if (!hist_enlargebuf(el, sz, newsz))
return 0; return 0;
/* Safe to set enlarged buffer size */
el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE];
return 1; return 1;
} }
@ -574,11 +634,16 @@ ch_end(EditLine *el)
el->el_line.limit = NULL; el->el_line.limit = NULL;
el_free((ptr_t) el->el_chared.c_undo.buf); el_free((ptr_t) el->el_chared.c_undo.buf);
el->el_chared.c_undo.buf = NULL; el->el_chared.c_undo.buf = NULL;
el_free((ptr_t) el->el_chared.c_redo.buf);
el->el_chared.c_redo.buf = NULL;
el->el_chared.c_redo.pos = NULL;
el->el_chared.c_redo.lim = NULL;
el->el_chared.c_redo.cmd = ED_UNASSIGNED;
el_free((ptr_t) el->el_chared.c_kill.buf); el_free((ptr_t) el->el_chared.c_kill.buf);
el->el_chared.c_kill.buf = NULL; el->el_chared.c_kill.buf = NULL;
ch_reset(el, 1);
el_free((ptr_t) el->el_chared.c_macro.macro); el_free((ptr_t) el->el_chared.c_macro.macro);
el->el_chared.c_macro.macro = NULL; el->el_chared.c_macro.macro = NULL;
ch_reset(el);
} }
@ -626,51 +691,64 @@ el_deletestr(EditLine *el, int n)
* Get a string * Get a string
*/ */
protected int protected int
c_gets(EditLine *el, char *buf) c_gets(EditLine *el, char *buf, const char *prompt)
{ {
char ch; char ch;
int len = 0; int len;
char *cp = el->el_line.buffer;
if (prompt) {
len = strlen(prompt);
memcpy(cp, prompt, len + 0u);
cp += len;
}
len = 0;
for (;;) {
el->el_line.cursor = cp;
*cp = ' ';
el->el_line.lastchar = cp + 1;
re_refresh(el);
if (el_getc(el, &ch) != 1) {
ed_end_of_file(el, 0);
len = -1;
break;
}
for (ch = 0; ch == 0;) {
if (el_getc(el, &ch) != 1)
return (ed_end_of_file(el, 0));
switch (ch) { switch (ch) {
case 0010: /* Delete and backspace */ case 0010: /* Delete and backspace */
case 0177: case 0177:
if (len > 1) { if (len <= 0) {
*el->el_line.cursor-- = '\0'; len = -1;
el->el_line.lastchar = el->el_line.cursor; break;
buf[len--] = '\0';
} else {
el->el_line.buffer[0] = '\0';
el->el_line.lastchar = el->el_line.buffer;
el->el_line.cursor = el->el_line.buffer;
return (CC_REFRESH);
} }
re_refresh(el); cp--;
ch = 0; continue;
break;
case 0033: /* ESC */ case 0033: /* ESC */
case '\r': /* Newline */ case '\r': /* Newline */
case '\n': case '\n':
buf[len] = ch;
break; break;
default: default:
if (len >= EL_BUFSIZ) if (len >= EL_BUFSIZ - 16)
term_beep(el); term_beep(el);
else { else {
buf[len++] = ch; buf[len++] = ch;
*el->el_line.cursor++ = ch; *cp++ = ch;
el->el_line.lastchar = el->el_line.cursor;
} }
re_refresh(el); continue;
ch = 0;
break;
} }
break;
} }
buf[len] = ch;
return (len); el->el_line.buffer[0] = '\0';
el->el_line.lastchar = el->el_line.buffer;
el->el_line.cursor = el->el_line.buffer;
return len;
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: chared.h,v 1.6 2001/01/10 07:45:41 jdolecek Exp $ */ /* $NetBSD: chared.h,v 1.15 2005/08/01 23:00:15 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -66,28 +62,36 @@
typedef struct c_macro_t { typedef struct c_macro_t {
int level; int level;
int offset;
char **macro; char **macro;
char *nline;
} c_macro_t; } c_macro_t;
/* /*
* Undo information for both vi and emacs * Undo information for vi - no undo in emacs (yet)
*/ */
typedef struct c_undo_t { typedef struct c_undo_t {
int action; int len; /* length of saved line */
size_t isize; int cursor; /* position of saved cursor */
size_t dsize; char *buf; /* full saved text */
char *ptr;
char *buf;
} c_undo_t; } c_undo_t;
/* redo for vi */
typedef struct c_redo_t {
char *buf; /* redo insert key sequence */
char *pos;
char *lim;
el_action_t cmd; /* command to redo */
char ch; /* char that invoked it */
int count;
int action; /* from cv_action() */
} c_redo_t;
/* /*
* Current action information for vi * Current action information for vi
*/ */
typedef struct c_vcmd_t { typedef struct c_vcmd_t {
int action; int action;
char *pos; char *pos;
char *ins;
} c_vcmd_t; } c_vcmd_t;
/* /*
@ -106,6 +110,7 @@ typedef struct c_kill_t {
typedef struct el_chared_t { typedef struct el_chared_t {
c_undo_t c_undo; c_undo_t c_undo;
c_kill_t c_kill; c_kill_t c_kill;
c_redo_t c_redo;
c_vcmd_t c_vcmd; c_vcmd_t c_vcmd;
c_macro_t c_macro; c_macro_t c_macro;
} el_chared_t; } el_chared_t;
@ -120,10 +125,10 @@ typedef struct el_chared_t {
#define NOP 0x00 #define NOP 0x00
#define DELETE 0x01 #define DELETE 0x01
#define INSERT 0x02 #define INSERT 0x02
#define CHANGE 0x04 #define YANK 0x04
#define CHAR_FWD 0 #define CHAR_FWD (+1)
#define CHAR_BACK 1 #define CHAR_BACK (-1)
#define MODE_INSERT 0 #define MODE_INSERT 0
#define MODE_REPLACE 1 #define MODE_REPLACE 1
@ -137,23 +142,27 @@ typedef struct el_chared_t {
protected int cv__isword(int); protected int cv__isword(int);
protected int cv__isWord(int);
protected void cv_delfini(EditLine *); protected void cv_delfini(EditLine *);
protected char *cv__endword(char *, char *, int); protected char *cv__endword(char *, char *, int, int (*)(int));
protected int ce__isword(int); protected int ce__isword(int);
protected void cv_undo(EditLine *, int, size_t, char *); protected void cv_undo(EditLine *);
protected void cv_yank(EditLine *, const char *, int);
protected char *cv_next_word(EditLine*, char *, char *, int, int (*)(int)); protected char *cv_next_word(EditLine*, char *, char *, int, int (*)(int));
protected char *cv_prev_word(EditLine*, char *, char *, int, int (*)(int)); protected char *cv_prev_word(char *, char *, int, int (*)(int));
protected char *c__next_word(char *, char *, int, int (*)(int)); protected char *c__next_word(char *, char *, int, int (*)(int));
protected char *c__prev_word(char *, char *, int, int (*)(int)); protected char *c__prev_word(char *, char *, int, int (*)(int));
protected void c_insert(EditLine *, int); protected void c_insert(EditLine *, int);
protected void c_delbefore(EditLine *, int); protected void c_delbefore(EditLine *, int);
protected void c_delbefore1(EditLine *);
protected void c_delafter(EditLine *, int); protected void c_delafter(EditLine *, int);
protected int c_gets(EditLine *, char *); protected void c_delafter1(EditLine *);
protected int c_gets(EditLine *, char *, const char *);
protected int c_hpos(EditLine *); protected int c_hpos(EditLine *);
protected int ch_init(EditLine *); protected int ch_init(EditLine *);
protected void ch_reset(EditLine *); protected void ch_reset(EditLine *, int);
protected int ch_enlargebufs __P((EditLine *, size_t)); protected int ch_enlargebufs(EditLine *, size_t);
protected void ch_end(EditLine *); protected void ch_end(EditLine *);
#endif /* _h_el_chared */ #endif /* _h_el_chared */

218
common.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: common.c,v 1.10 2001/01/10 07:45:41 jdolecek Exp $ */ /* $NetBSD: common.c,v 1.17 2005/08/01 23:00:15 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,19 +32,18 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: common.c,v 1.10 2001/01/10 07:45:41 jdolecek Exp $"); __RCSID("$NetBSD: common.c,v 1.17 2005/08/01 23:00:15 christos Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* common.c: Common Editor functions * common.c: Common Editor functions
*/ */
#include "sys.h"
#include "el.h" #include "el.h"
/* ed_end_of_file(): /* ed_end_of_file():
@ -57,7 +52,7 @@ __RCSID("$NetBSD: common.c,v 1.10 2001/01/10 07:45:41 jdolecek Exp $");
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_end_of_file(EditLine *el, int c) ed_end_of_file(EditLine *el, int c __attribute__((__unused__)))
{ {
re_goto_bottom(el); re_goto_bottom(el);
@ -73,7 +68,7 @@ ed_end_of_file(EditLine *el, int c)
protected el_action_t protected el_action_t
ed_insert(EditLine *el, int c) ed_insert(EditLine *el, int c)
{ {
int i; int count = el->el_state.argument;
if (c == '\0') if (c == '\0')
return (CC_ERROR); return (CC_ERROR);
@ -81,42 +76,28 @@ ed_insert(EditLine *el, int c)
if (el->el_line.lastchar + el->el_state.argument >= if (el->el_line.lastchar + el->el_state.argument >=
el->el_line.limit) { el->el_line.limit) {
/* end of buffer space, try to allocate more */ /* end of buffer space, try to allocate more */
if (!ch_enlargebufs(el, (size_t) el->el_state.argument)) if (!ch_enlargebufs(el, (size_t) count))
return CC_ERROR; /* error allocating more */ return CC_ERROR; /* error allocating more */
} }
if (el->el_state.argument == 1) { if (count == 1) {
if (el->el_state.inputmode != MODE_INSERT) { if (el->el_state.inputmode == MODE_INSERT
el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] = || el->el_line.cursor >= el->el_line.lastchar)
*el->el_line.cursor; c_insert(el, 1);
el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] =
'\0';
c_delafter(el, 1);
}
c_insert(el, 1);
*el->el_line.cursor++ = c; *el->el_line.cursor++ = c;
el->el_state.doingarg = 0; /* just in case */
re_fastaddc(el); /* fast refresh for one char. */ re_fastaddc(el); /* fast refresh for one char. */
} else { } else {
if (el->el_state.inputmode != MODE_INSERT) { if (el->el_state.inputmode != MODE_REPLACE_1)
for (i = 0; i < el->el_state.argument; i++) c_insert(el, el->el_state.argument);
el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
el->el_line.cursor[i];
el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = while (count-- && el->el_line.cursor < el->el_line.lastchar)
'\0';
c_delafter(el, el->el_state.argument);
}
c_insert(el, el->el_state.argument);
while (el->el_state.argument--)
*el->el_line.cursor++ = c; *el->el_line.cursor++ = c;
re_refresh(el); re_refresh(el);
} }
if (el->el_state.inputmode == MODE_REPLACE_1) if (el->el_state.inputmode == MODE_REPLACE_1)
(void) vi_command_mode(el, 0); return vi_command_mode(el, 0);
return (CC_NORM); return (CC_NORM);
} }
@ -128,7 +109,7 @@ ed_insert(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_delete_prev_word(EditLine *el, int c) ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
{ {
char *cp, *p, *kp; char *cp, *p, *kp;
@ -156,7 +137,7 @@ ed_delete_prev_word(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_delete_next_char(EditLine *el, int c) ed_delete_next_char(EditLine *el, int c __attribute__((__unused__)))
{ {
#ifdef notdef /* XXX */ #ifdef notdef /* XXX */
#define EL el->el_line #define EL el->el_line
@ -207,7 +188,7 @@ ed_delete_next_char(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_kill_line(EditLine *el, int c) ed_kill_line(EditLine *el, int c __attribute__((__unused__)))
{ {
char *kp, *cp; char *kp, *cp;
@ -228,7 +209,7 @@ ed_kill_line(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_move_to_end(EditLine *el, int c) ed_move_to_end(EditLine *el, int c __attribute__((__unused__)))
{ {
el->el_line.cursor = el->el_line.lastchar; el->el_line.cursor = el->el_line.lastchar;
@ -236,7 +217,7 @@ ed_move_to_end(EditLine *el, int c)
#ifdef VI_MOVE #ifdef VI_MOVE
el->el_line.cursor--; el->el_line.cursor--;
#endif #endif
if (el->el_chared.c_vcmd.action & DELETE) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return (CC_REFRESH);
} }
@ -251,7 +232,7 @@ ed_move_to_end(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_move_to_beg(EditLine *el, int c) ed_move_to_beg(EditLine *el, int c __attribute__((__unused__)))
{ {
el->el_line.cursor = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer;
@ -260,7 +241,7 @@ ed_move_to_beg(EditLine *el, int c)
/* We want FIRST non space character */ /* We want FIRST non space character */
while (isspace((unsigned char) *el->el_line.cursor)) while (isspace((unsigned char) *el->el_line.cursor))
el->el_line.cursor++; el->el_line.cursor++;
if (el->el_chared.c_vcmd.action & DELETE) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return (CC_REFRESH);
} }
@ -300,18 +281,22 @@ ed_transpose_chars(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_next_char(EditLine *el, int c) ed_next_char(EditLine *el, int c __attribute__((__unused__)))
{ {
char *lim = el->el_line.lastchar;
if (el->el_line.cursor >= el->el_line.lastchar) if (el->el_line.cursor >= lim ||
(el->el_line.cursor == lim - 1 &&
el->el_map.type == MAP_VI &&
el->el_chared.c_vcmd.action == NOP))
return (CC_ERROR); return (CC_ERROR);
el->el_line.cursor += el->el_state.argument; el->el_line.cursor += el->el_state.argument;
if (el->el_line.cursor > el->el_line.lastchar) if (el->el_line.cursor > lim)
el->el_line.cursor = el->el_line.lastchar; el->el_line.cursor = lim;
if (el->el_map.type == MAP_VI) if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action & DELETE) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return (CC_REFRESH);
} }
@ -325,7 +310,7 @@ ed_next_char(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_prev_word(EditLine *el, int c) ed_prev_word(EditLine *el, int c __attribute__((__unused__)))
{ {
if (el->el_line.cursor == el->el_line.buffer) if (el->el_line.cursor == el->el_line.buffer)
@ -337,7 +322,7 @@ ed_prev_word(EditLine *el, int c)
ce__isword); ce__isword);
if (el->el_map.type == MAP_VI) if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action & DELETE) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return (CC_REFRESH);
} }
@ -351,7 +336,7 @@ ed_prev_word(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_prev_char(EditLine *el, int c) ed_prev_char(EditLine *el, int c __attribute__((__unused__)))
{ {
if (el->el_line.cursor > el->el_line.buffer) { if (el->el_line.cursor > el->el_line.buffer) {
@ -360,7 +345,7 @@ ed_prev_char(EditLine *el, int c)
el->el_line.cursor = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer;
if (el->el_map.type == MAP_VI) if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action & DELETE) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return (CC_REFRESH);
} }
@ -412,25 +397,9 @@ ed_digit(EditLine *el, int c)
(el->el_state.argument * 10) + (c - '0'); (el->el_state.argument * 10) + (c - '0');
} }
return (CC_ARGHACK); return (CC_ARGHACK);
} else {
if (el->el_line.lastchar + 1 >= el->el_line.limit) {
if (!ch_enlargebufs(el, 1))
return (CC_ERROR);
}
if (el->el_state.inputmode != MODE_INSERT) {
el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] =
*el->el_line.cursor;
el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] =
'\0';
c_delafter(el, 1);
}
c_insert(el, 1);
*el->el_line.cursor++ = c;
el->el_state.doingarg = 0;
re_fastaddc(el);
} }
return (CC_NORM);
return ed_insert(el, c);
} }
@ -464,12 +433,10 @@ ed_argument_digit(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_unassigned(EditLine *el, int c) ed_unassigned(EditLine *el, int c __attribute__((__unused__)))
{ {
term_beep(el); return (CC_ERROR);
term__flush();
return (CC_NORM);
} }
@ -483,7 +450,8 @@ ed_unassigned(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_sigint(EditLine *el, int c) ed_tty_sigint(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
{ {
return (CC_NORM); return (CC_NORM);
@ -496,7 +464,8 @@ ed_tty_sigint(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_dsusp(EditLine *el, int c) ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
{ {
return (CC_NORM); return (CC_NORM);
@ -509,7 +478,8 @@ ed_tty_dsusp(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_flush_output(EditLine *el, int c) ed_tty_flush_output(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
{ {
return (CC_NORM); return (CC_NORM);
@ -522,7 +492,8 @@ ed_tty_flush_output(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_sigquit(EditLine *el, int c) ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
{ {
return (CC_NORM); return (CC_NORM);
@ -535,7 +506,8 @@ ed_tty_sigquit(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_sigtstp(EditLine *el, int c) ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
{ {
return (CC_NORM); return (CC_NORM);
@ -548,7 +520,8 @@ ed_tty_sigtstp(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_stop_output(EditLine *el, int c) ed_tty_stop_output(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
{ {
return (CC_NORM); return (CC_NORM);
@ -561,7 +534,8 @@ ed_tty_stop_output(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_start_output(EditLine *el, int c) ed_tty_start_output(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
{ {
return (CC_NORM); return (CC_NORM);
@ -574,14 +548,12 @@ ed_tty_start_output(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_newline(EditLine *el, int c) ed_newline(EditLine *el, int c __attribute__((__unused__)))
{ {
re_goto_bottom(el); re_goto_bottom(el);
*el->el_line.lastchar++ = '\n'; *el->el_line.lastchar++ = '\n';
*el->el_line.lastchar = '\0'; *el->el_line.lastchar = '\0';
if (el->el_map.type == MAP_VI)
el->el_chared.c_vcmd.ins = el->el_line.buffer;
return (CC_NEWLINE); return (CC_NEWLINE);
} }
@ -592,7 +564,7 @@ ed_newline(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_delete_prev_char(EditLine *el, int c) ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
{ {
if (el->el_line.cursor <= el->el_line.buffer) if (el->el_line.cursor <= el->el_line.buffer)
@ -612,7 +584,7 @@ ed_delete_prev_char(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_clear_screen(EditLine *el, int c) ed_clear_screen(EditLine *el, int c __attribute__((__unused__)))
{ {
term_clear_screen(el); /* clear the whole real screen */ term_clear_screen(el); /* clear the whole real screen */
@ -627,7 +599,8 @@ ed_clear_screen(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_redisplay(EditLine *el, int c) ed_redisplay(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
{ {
return (CC_REDISPLAY); return (CC_REDISPLAY);
@ -640,10 +613,10 @@ ed_redisplay(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_start_over(EditLine *el, int c) ed_start_over(EditLine *el, int c __attribute__((__unused__)))
{ {
ch_reset(el); ch_reset(el, 0);
return (CC_REFRESH); return (CC_REFRESH);
} }
@ -654,7 +627,8 @@ ed_start_over(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_sequence_lead_in(EditLine *el, int c) ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
{ {
return (CC_NORM); return (CC_NORM);
@ -667,11 +641,12 @@ ed_sequence_lead_in(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_prev_history(EditLine *el, int c) ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
{ {
char beep = 0; char beep = 0;
int sv_event = el->el_history.eventno;
el->el_chared.c_undo.action = NOP; el->el_chared.c_undo.len = -1;
*el->el_line.lastchar = '\0'; /* just in case */ *el->el_line.lastchar = '\0'; /* just in case */
if (el->el_history.eventno == 0) { /* save the current buffer if (el->el_history.eventno == 0) { /* save the current buffer
@ -684,15 +659,17 @@ ed_prev_history(EditLine *el, int c)
el->el_history.eventno += el->el_state.argument; el->el_history.eventno += el->el_state.argument;
if (hist_get(el) == CC_ERROR) { if (hist_get(el) == CC_ERROR) {
if (el->el_map.type == MAP_VI) {
el->el_history.eventno = sv_event;
return CC_ERROR;
}
beep = 1; beep = 1;
/* el->el_history.eventno was fixed by first call */ /* el->el_history.eventno was fixed by first call */
(void) hist_get(el); (void) hist_get(el);
} }
re_refresh(el);
if (beep) if (beep)
return (CC_ERROR); return CC_REFRESH_BEEP;
else return CC_REFRESH;
return (CC_NORM); /* was CC_UP_HIST */
} }
@ -702,19 +679,24 @@ ed_prev_history(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_next_history(EditLine *el, int c) ed_next_history(EditLine *el, int c __attribute__((__unused__)))
{ {
el_action_t beep = CC_REFRESH, rval;
el->el_chared.c_undo.action = NOP; el->el_chared.c_undo.len = -1;
*el->el_line.lastchar = '\0'; /* just in case */ *el->el_line.lastchar = '\0'; /* just in case */
el->el_history.eventno -= el->el_state.argument; el->el_history.eventno -= el->el_state.argument;
if (el->el_history.eventno < 0) { if (el->el_history.eventno < 0) {
el->el_history.eventno = 0; el->el_history.eventno = 0;
return (CC_ERROR);/* make it beep */ beep = CC_REFRESH_BEEP;
} }
return (hist_get(el)); rval = hist_get(el);
if (rval == CC_REFRESH)
return beep;
return rval;
} }
@ -724,14 +706,14 @@ ed_next_history(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_search_prev_history(EditLine *el, int c) ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
{ {
const char *hp; const char *hp;
int h; int h;
bool_t found = 0; bool_t found = 0;
el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_undo.action = NOP; el->el_chared.c_undo.len = -1;
*el->el_line.lastchar = '\0'; /* just in case */ *el->el_line.lastchar = '\0'; /* just in case */
if (el->el_history.eventno < 0) { if (el->el_history.eventno < 0) {
#ifdef DEBUG_EDIT #ifdef DEBUG_EDIT
@ -792,14 +774,14 @@ ed_search_prev_history(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_search_next_history(EditLine *el, int c) ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
{ {
const char *hp; const char *hp;
int h; int h;
bool_t found = 0; bool_t found = 0;
el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_undo.action = NOP; el->el_chared.c_undo.len = -1;
*el->el_line.lastchar = '\0'; /* just in case */ *el->el_line.lastchar = '\0'; /* just in case */
if (el->el_history.eventno == 0) if (el->el_history.eventno == 0)
@ -846,7 +828,7 @@ ed_search_next_history(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_prev_line(EditLine *el, int c) ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
{ {
char *ptr; char *ptr;
int nchars = c_hpos(el); int nchars = c_hpos(el);
@ -889,7 +871,7 @@ ed_prev_line(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_next_line(EditLine *el, int c) ed_next_line(EditLine *el, int c __attribute__((__unused__)))
{ {
char *ptr; char *ptr;
int nchars = c_hpos(el); int nchars = c_hpos(el);
@ -923,30 +905,18 @@ ed_next_line(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_command(EditLine *el, int c) ed_command(EditLine *el, int c __attribute__((__unused__)))
{ {
char tmpbuf[EL_BUFSIZ]; char tmpbuf[EL_BUFSIZ];
int tmplen; int tmplen;
el->el_line.buffer[0] = '\0'; tmplen = c_gets(el, tmpbuf, "\n: ");
el->el_line.lastchar = el->el_line.buffer; term__putc('\n');
el->el_line.cursor = el->el_line.buffer;
c_insert(el, 3); /* prompt + ": " */ if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
*el->el_line.cursor++ = '\n'; term_beep(el);
*el->el_line.cursor++ = ':';
*el->el_line.cursor++ = ' ';
re_refresh(el);
tmplen = c_gets(el, tmpbuf); el->el_map.current = el->el_map.key;
tmpbuf[tmplen] = '\0'; re_clear_display(el);
return CC_REFRESH;
el->el_line.buffer[0] = '\0';
el->el_line.lastchar = el->el_line.buffer;
el->el_line.cursor = el->el_line.buffer;
if (parse_line(el, tmpbuf) == -1)
return (CC_ERROR);
else
return (CC_REFRESH);
} }

18
config.h Normal file
View File

@ -0,0 +1,18 @@
/* config.h. Generated automatically by configure. */
/* #undef SUNOS */
#define HAVE_SYS_CDEFS_H 1
#define HAVE_TERMCAP_H 1
/* #undef HAVE_CURSES_H */
/* #undef HAVE_NCURSES_H */
/* #undef HAVE_TERM_H */
#define HAVE_VIS_H 1
#define HAVE_ISSETUGID 1
#define HAVE_STRLCAT 1
#define HAVE_STRLCPY 1
#define HAVE_FGETLN 1
#define HAVE_STRVIS 1
#define HAVE_STRUNVIS 1
#include "sys.h"

View File

@ -1,6 +1,6 @@
.\" $NetBSD: editline.3,v 1.22 2001/09/27 19:29:50 christos Exp $ .\" $NetBSD: editline.3,v 1.48 2005/07/14 15:02:37 wiz Exp $
.\" .\"
.\" Copyright (c) 1997-1999 The NetBSD Foundation, Inc. .\" Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
.\" All rights reserved. .\" All rights reserved.
.\" .\"
.\" This file was contributed to The NetBSD Foundation by Luke Mewburn. .\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
@ -33,7 +33,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE. .\" POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd November 12, 1999 .Dd July 14, 2005
.Os .Os
.Dt EDITLINE 3 .Dt EDITLINE 3
.Sh NAME .Sh NAME
@ -53,12 +53,17 @@
.Nm el_deletestr , .Nm el_deletestr ,
.Nm history_init , .Nm history_init ,
.Nm history_end , .Nm history_end ,
.Nm history .Nm history ,
.Nd line editor and history functions .Nm tok_init ,
.Nm tok_end ,
.Nm tok_reset ,
.Nm tok_line ,
.Nm tok_str
.Nd line editor, history and tokenization functions
.Sh LIBRARY .Sh LIBRARY
.Lb libedit .Lb libedit
.Sh SYNOPSIS .Sh SYNOPSIS
.Fd #include <histedit.h> .In histedit.h
.Ft EditLine * .Ft EditLine *
.Fn el_init "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr" .Fn el_init "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr"
.Ft void .Ft void
@ -72,7 +77,7 @@
.Ft void .Ft void
.Fn el_push "EditLine *e" "const char *str" .Fn el_push "EditLine *e" "const char *str"
.Ft int .Ft int
.Fn el_parse "EditLine *e" "int argc" "char *argv[]" .Fn el_parse "EditLine *e" "int argc" "const char *argv[]"
.Ft int .Ft int
.Fn el_set "EditLine *e" "int op" "..." .Fn el_set "EditLine *e" "int op" "..."
.Ft int .Ft int
@ -93,10 +98,20 @@
.Fn history_end "History *h" .Fn history_end "History *h"
.Ft int .Ft int
.Fn history "History *h" "HistEvent *ev" "int op" "..." .Fn history "History *h" "HistEvent *ev" "int op" "..."
.Ft Tokenizer *
.Fn tok_init "const char *IFS"
.Ft void
.Fn tok_end "Tokenizer *t"
.Ft void
.Fn tok_reset "Tokenizer *t"
.Ft int
.Fn tok_line "Tokenizer *t" "const LineInfo *li" "int *argc" "const char **argv[]" "int *cursorc" "int *cursoro"
.Ft int
.Fn tok_str "Tokenizer *t" "const char *str" "int *argc" "const char **argv[]"
.Sh DESCRIPTION .Sh DESCRIPTION
The The
.Nm .Nm
library provides generic line editing and history functions, library provides generic line editing, history and tokenization functions,
similar to those found in similar to those found in
.Xr sh 1 . .Xr sh 1 .
.Pp .Pp
@ -152,7 +167,7 @@ if no characters were read or if an error occurred.
Read a character from the tty. Read a character from the tty.
.Fa ch .Fa ch
is modified to contain the character read. is modified to contain the character read.
Returns the number of characters read if successful, -1 otherwise. Returns the number of characters read if successful, \-1 otherwise.
.It Fn el_push .It Fn el_push
Pushes Pushes
.Fa str .Fa str
@ -174,7 +189,7 @@ to execute builtin
.Nm .Nm
commands. commands.
If the command is prefixed with If the command is prefixed with
.Dq prog: .Dq prog :
then then
.Fn el_parse .Fn el_parse
will only execute the command if will only execute the command if
@ -184,7 +199,7 @@ matches the
argument supplied to argument supplied to
.Fn el_init . .Fn el_init .
The return value is The return value is
-1 if the command is unknown, \-1 if the command is unknown,
0 if there was no error or 0 if there was no error or
.Dq prog .Dq prog
didn't match, or didn't match, or
@ -303,7 +318,7 @@ for more information.
.It Dv EL_ADDFN , Xo .It Dv EL_ADDFN , Xo
.Fa "const char *name" , .Fa "const char *name" ,
.Fa "const char *help" , .Fa "const char *help" ,
.Fa "unsigned char (*func)(EditLine *e, int ch) .Fa "unsigned char (*func)(EditLine *e, int ch)"
.Xc .Xc
Add a user defined function, Add a user defined function,
.Fn func , .Fn func ,
@ -336,7 +351,7 @@ Refresh display.
Refresh display, and beep. Refresh display, and beep.
.It Dv CC_CURSOR .It Dv CC_CURSOR
Cursor moved, so update and perform Cursor moved, so update and perform
.Dv CC_REFRESH. .Dv CC_REFRESH .
.It Dv CC_REDISPLAY .It Dv CC_REDISPLAY
Redisplay entire input line. Redisplay entire input line.
This is useful if a key binding outputs extra information. This is useful if a key binding outputs extra information.
@ -362,7 +377,7 @@ is non-zero,
editing is enabled (the default). editing is enabled (the default).
Note that this is only an indication, and does not Note that this is only an indication, and does not
affect the operation of affect the operation of
.Nm "" . .Nm .
At this time, it is the caller's responsibility to At this time, it is the caller's responsibility to
check this check this
(using (using
@ -379,6 +394,13 @@ and
.Fn el_getc . .Fn el_getc .
The builtin function can be set or restored with the special function The builtin function can be set or restored with the special function
name ``EL_BUILTIN_GETCFN''. name ``EL_BUILTIN_GETCFN''.
.It Dv EL_CLIENTDATA , Fa "void *data"
Register
.Fa data
to be associated with this EditLine structure.
It can be retrieved with the corresponding
.Fn el_get
call.
.El .El
.It Fn el_get .It Fn el_get
Get Get
@ -387,6 +409,7 @@ parameters.
.Fa op .Fa op
determines which parameter to retrieve into determines which parameter to retrieve into
.Fa result . .Fa result .
Returns 0 if successful, \-1 otherwise.
.Pp .Pp
The following values for The following values for
.Fa op .Fa op
@ -413,6 +436,19 @@ Return non-zero if editing is enabled.
.It Dv EL_GETCFN, Fa "int (**f)(EditLine *, char *)" .It Dv EL_GETCFN, Fa "int (**f)(EditLine *, char *)"
Return a pointer to the function that read characters, which is equal to Return a pointer to the function that read characters, which is equal to
``EL_BUILTIN_GETCFN'' in the case of the default builtin function. ``EL_BUILTIN_GETCFN'' in the case of the default builtin function.
.It Dv EL_CLIENTDATA , Fa "void **data"
Retrieve
.Fa data
previously registered with the corresponding
.Fn el_set
call.
.It Dv EL_UNBUFFERED, Fa "int"
Sets or clears unbuffered mode.
In this mode,
.Fn el_gets
will return immediately after processing a single character.
.It Dv EL_PREP_TERM, Fa "int"
Sets or clears terminal editing mode.
.El .El
.It Fn el_source .It Fn el_source
Initialise Initialise
@ -455,11 +491,21 @@ typedef struct lineinfo {
const char *lastchar; /* address of last character */ const char *lastchar; /* address of last character */
} LineInfo; } LineInfo;
.Ed .Ed
.Pp
.Fa buffer
is not NUL terminated.
This function may be called after
.Fn el_gets
to obtain the
.Fa LineInfo
structure pertaining to line returned by that function,
and from within user defined functions added with
.Dv EL_ADDFN .
.It Fn el_insertstr .It Fn el_insertstr
Insert Insert
.Fa str .Fa str
into the line at the cursor. into the line at the cursor.
Returns -1 if Returns \-1 if
.Fa str .Fa str
is empty or won't fit, and 0 otherwise. is empty or won't fit, and 0 otherwise.
.It Fn el_deletestr .It Fn el_deletestr
@ -539,7 +585,11 @@ Set the cursor to point to the requested element.
.It Dv H_ADD , Fa "const char *str" .It Dv H_ADD , Fa "const char *str"
Append Append
.Fa str .Fa str
to the current element of the history, or create an element with to the current element of the history, or perform the
.Dv H_ENTER
operation with argument
.Fa str
if there is no current element.
.It Dv H_APPEND , Fa "const char *str" .It Dv H_APPEND , Fa "const char *str"
Append Append
.Fa str .Fa str
@ -549,6 +599,17 @@ Add
.Fa str .Fa str
as a new element to the history, and, if necessary, as a new element to the history, and, if necessary,
removing the oldest entry to keep the list to the created size. removing the oldest entry to keep the list to the created size.
If
.Dv H_SETUNIQUE
was has been called with a non-zero arguments, the element
will not be entered into the history if its contents match
the ones of the current history element.
If the element is entered
.Fn history
returns 1, if it is ignored as a duplicate returns 0.
Finally
.Fn history
returns \-1 if an error occurred.
.It Dv H_PREV_STR , Fa "const char *str" .It Dv H_PREV_STR , Fa "const char *str"
Return the closest previous event that starts with Return the closest previous event that starts with
.Fa str . .Fa str .
@ -567,22 +628,109 @@ Load the history list stored in
.It Dv H_SAVE , Fa "const char *file" .It Dv H_SAVE , Fa "const char *file"
Save the history list to Save the history list to
.Fa file . .Fa file .
.It Dv H_SETUNIQUE , Fa "int unique"
Set if the adjacent identical event strings should not be entered into
the history.
.It Dv H_GETUNIQUE
Retrieve the current setting if if adjacent elements should be entered into
the history.
.It Dv H_DEL , Fa "int num"
Delete the event numbered
.Fa e .
This function is only provided for
.Xr readline 3
compatibility.
The caller is responsible for free'ing the string in the returned
.Fa HistEvent .
.El .El
.Pp .Pp
.Fn history .Fn history
returns 0 if the operation returns \*[Gt]= 0 if the operation
.Fa op .Fa op
succeeds. Otherwise, -1 is returned and succeeds.
Otherwise, \-1 is returned and
.Fa ev .Fa ev
is updated to contain more details about the error. is updated to contain more details about the error.
.El .El
.Sh TOKENIZATION FUNCTIONS
The tokenization functions use a common data structure,
.Fa Tokenizer ,
which is created by
.Fn tok_init
and freed by
.Fn tok_end .
.Pp
The following functions are available:
.Bl -tag -width 4n
.It Fn tok_init
Initialise the tokenizer, and return a data structure
to be used by all other tokenizer functions.
.Fa IFS
contains the Input Field Separators, which defaults to
.Aq space ,
.Aq tab ,
and
.Aq newline
if
.Dv NULL .
.It Fn tok_end
Clean up and finish with
.Fa t ,
assumed to have been created with
.Fn tok_init .
.It Fn tok_reset
Reset the tokenizer state.
Use after a line has been successfully tokenized
by
.Fn tok_line
or
.Fn tok_str
and before a new line is to be tokenized.
.It Fn tok_line
Tokenize
.Fa li ,
If successful, modify:
.Fa argv
to contain the words,
.Fa argc
to contain the number of words,
.Fa cursorc
(if not
.Dv NULL )
to contain the index of the word containing the cursor,
and
.Fa cursoro
(if not
.Dv NULL )
to contain the offset within
.Fa argv[cursorc]
of the cursor.
.Pp
Returns
0 if successful,
\-1 for an internal error,
1 for an unmatched single quote,
2 for an unmatched double quote,
and
3 for a backslash quoted
.Aq newline .
A positive exit code indicates that another line should be read
and tokenization attempted again.
.
.It Fn tok_str
A simpler form of
.Fn tok_line ;
.Fa str
is a NUL terminated string to tokenize.
.El
.
.\"XXX.Sh EXAMPLES .\"XXX.Sh EXAMPLES
.\"XXX: provide some examples .\"XXX: provide some examples
.Sh SEE ALSO .Sh SEE ALSO
.Xr editrc 5 ,
.Xr sh 1 , .Xr sh 1 ,
.Xr signal 3 , .Xr signal 3 ,
.Xr termcap 3 .Xr termcap 3 ,
.Xr editrc 5
.Sh HISTORY .Sh HISTORY
The The
.Nm .Nm
@ -610,9 +758,6 @@ and
.Dv EL_RPROMPT . .Dv EL_RPROMPT .
Jaromir Dolecek implemented the readline emulation. Jaromir Dolecek implemented the readline emulation.
.Sh BUGS .Sh BUGS
The tokenization functions are not publically defined in
.Fd <histedit.h>.
.Pp
At this time, it is the responsibility of the caller to At this time, it is the responsibility of the caller to
check the result of the check the result of the
.Dv EL_EDITMODE .Dv EL_EDITMODE

View File

@ -1,4 +1,4 @@
.\" $NetBSD: editrc.5,v 1.11 2001/06/19 13:42:09 wiz Exp $ .\" $NetBSD: editrc.5,v 1.19 2003/11/01 23:35:33 christos Exp $
.\" .\"
.\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc. .\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
.\" All rights reserved. .\" All rights reserved.
@ -33,7 +33,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE. .\" POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd November 8, 2000 .Dd October 18, 2003
.Os .Os
.Dt EDITRC 5 .Dt EDITRC 5
.Sh NAME .Sh NAME
@ -62,7 +62,7 @@ for more information.
.Ar prog .Ar prog
is the program name string that a program defines when it calls is the program name string that a program defines when it calls
.Xr el_init 3 .Xr el_init 3
to setup to set up
.Xr editline 3 , .Xr editline 3 ,
which is usually which is usually
.Va argv[0] . .Va argv[0] .
@ -122,7 +122,7 @@ Options include:
Bind all keys to the standard GNU Emacs-like bindings. Bind all keys to the standard GNU Emacs-like bindings.
.It Fl v .It Fl v
Bind all keys to the standard Bind all keys to the standard
.Xr vi 1 -like .Xr vi 1 Ns -like
bindings. bindings.
.It Fl a .It Fl a
List or change key bindings in the List or change key bindings in the
@ -222,7 +222,7 @@ or
indicating that the terminal does or does not have that capability. indicating that the terminal does or does not have that capability.
.Pp .Pp
.Fl s .Fl s
returns an emptry string for non-existent capabilities, rather than returns an empty string for non-existent capabilities, rather than
causing an error. causing an error.
.Fl v .Fl v
causes messages to be verbose. causes messages to be verbose.
@ -230,11 +230,27 @@ causes messages to be verbose.
Enable or disable the Enable or disable the
.Nm editline .Nm editline
functionality in a program. functionality in a program.
.It Ic history .It Ic history Ar list | Ar size Dv n | Ar unique Dv n
List the history. The
.Ar list
command lists all entries in the history.
The
.Ar size
command sets the history size to
.Dv n
entries.
The
.Ar unique
command controls if history should keep duplicate entries.
If
.Dv n
is non zero, only keep unique history entries.
If
.Dv n
is zero, then keep all entries (the default).
.It Ic telltc .It Ic telltc
List the values of all the terminal capabilities (see List the values of all the terminal capabilities (see
.Xr termcap 5 ). .Xr termcap 5 ) .
.It Ic settc Ar cap Ar val .It Ic settc Ar cap Ar val
Set the terminal capability Set the terminal capability
.Ar cap .Ar cap
@ -251,6 +267,7 @@ No sanity checking is done.
.Op Ar +mode .Op Ar +mode
.Op Ar -mode .Op Ar -mode
.Op Ar mode .Op Ar mode
.Op Ar char=c
.Xc .Xc
Control which tty modes that Control which tty modes that
.Nm .Nm
@ -291,6 +308,15 @@ fixes
on or off or removes control of on or off or removes control of
.Ar mode .Ar mode
in the chosen set. in the chosen set.
.Pp
.Ic Setty
can also be used to set tty characters to particular values using
.Ar char=value .
If
.Ar value
is empty
then the character is set to
.Dv _POSIX_VDISABLE .
.El .El
.Sh EDITOR COMMANDS .Sh EDITOR COMMANDS
The following editor commands are available for use in key bindings: The following editor commands are available for use in key bindings:
@ -380,7 +406,7 @@ Cut the entire line and save in cut buffer.
Cut area between mark and cursor and save in cut buffer. Cut area between mark and cursor and save in cut buffer.
.It Ic em-copy-region .It Ic em-copy-region
Copy area between mark and cursor to cut buffer. Copy area between mark and cursor to cut buffer.
.It Ic em-gosmacs-traspose .It Ic em-gosmacs-transpose
Exchange the two characters before the cursor. Exchange the two characters before the cursor.
.It Ic em-next-word .It Ic em-next-word
Move next to end of current word. Move next to end of current word.

108
el.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: el.c,v 1.23 2001/09/27 19:29:50 christos Exp $ */ /* $NetBSD: el.c,v 1.40 2005/08/01 23:00:15 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,20 +32,18 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94"; static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
#else #else
__RCSID("$NetBSD: el.c,v 1.23 2001/09/27 19:29:50 christos Exp $"); __RCSID("$NetBSD: el.c,v 1.40 2005/08/01 23:00:15 christos Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* el.c: EditLine interface functions * el.c: EditLine interface functions
*/ */
#include "sys.h"
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
#include <string.h> #include <string.h>
@ -65,9 +59,6 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
{ {
EditLine *el = (EditLine *) el_malloc(sizeof(EditLine)); EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
#ifdef DEBUG
char *tty;
#endif
if (el == NULL) if (el == NULL)
return (NULL); return (NULL);
@ -77,14 +68,21 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
el->el_infd = fileno(fin); el->el_infd = fileno(fin);
el->el_outfile = fout; el->el_outfile = fout;
el->el_errfile = ferr; el->el_errfile = ferr;
el->el_prog = strdup(prog); if ((el->el_prog = el_strdup(prog)) == NULL) {
el_free(el);
return NULL;
}
/* /*
* Initialize all the modules. Order is important!!! * Initialize all the modules. Order is important!!!
*/ */
el->el_flags = 0; el->el_flags = 0;
(void) term_init(el); if (term_init(el) == -1) {
el_free(el->el_prog);
el_free(el);
return NULL;
}
(void) key_init(el); (void) key_init(el);
(void) map_init(el); (void) map_init(el);
if (tty_init(el) == -1) if (tty_init(el) == -1)
@ -135,7 +133,7 @@ el_reset(EditLine *el)
{ {
tty_cookedmode(el); tty_cookedmode(el);
ch_reset(el); /* XXX: Do we want that? */ ch_reset(el, 0); /* XXX: Do we want that? */
} }
@ -146,7 +144,7 @@ public int
el_set(EditLine *el, int op, ...) el_set(EditLine *el, int op, ...)
{ {
va_list va; va_list va;
int rv; int rv = 0;
if (el == NULL) if (el == NULL)
return (-1); return (-1);
@ -171,7 +169,6 @@ el_set(EditLine *el, int op, ...)
el->el_flags |= HANDLE_SIGNALS; el->el_flags |= HANDLE_SIGNALS;
else else
el->el_flags &= ~HANDLE_SIGNALS; el->el_flags &= ~HANDLE_SIGNALS;
rv = 0;
break; break;
case EL_BIND: case EL_BIND:
@ -180,7 +177,7 @@ el_set(EditLine *el, int op, ...)
case EL_ECHOTC: case EL_ECHOTC:
case EL_SETTY: case EL_SETTY:
{ {
char *argv[20]; const char *argv[20];
int i; int i;
for (i = 1; i < 20; i++) for (i = 1; i < 20; i++)
@ -255,8 +252,34 @@ el_set(EditLine *el, int op, ...)
break; break;
} }
case EL_CLIENTDATA:
el->el_data = va_arg(va, void *);
break;
case EL_UNBUFFERED:
rv = va_arg(va, int);
if (rv && !(el->el_flags & UNBUFFERED)) {
el->el_flags |= UNBUFFERED;
read_prepare(el);
} else if (!rv && (el->el_flags & UNBUFFERED)) {
el->el_flags &= ~UNBUFFERED;
read_finish(el);
}
rv = 0;
break;
case EL_PREP_TERM:
rv = va_arg(va, int);
if (rv)
(void) tty_rawmode(el);
else
(void) tty_cookedmode(el);
rv = 0;
break;
default: default:
rv = -1; rv = -1;
break;
} }
va_end(va); va_end(va);
@ -277,11 +300,11 @@ el_get(EditLine *el, int op, void *ret)
switch (op) { switch (op) {
case EL_PROMPT: case EL_PROMPT:
case EL_RPROMPT: case EL_RPROMPT:
rv = prompt_get(el, (el_pfunc_t *) & ret, op); rv = prompt_get(el, (void *) &ret, op);
break; break;
case EL_EDITOR: case EL_EDITOR:
rv = map_get_editor(el, (const char **) &ret); rv = map_get_editor(el, (void *) &ret);
break; break;
case EL_SIGNAL: case EL_SIGNAL:
@ -294,21 +317,22 @@ el_get(EditLine *el, int op, void *ret)
rv = 0; rv = 0;
break; break;
#if 0 /* XXX */
case EL_TERMINAL: case EL_TERMINAL:
rv = term_get(el, (const char *) &ret); term_get(el, (const char **)ret);
rv = 0;
break; break;
#if 0 /* XXX */
case EL_BIND: case EL_BIND:
case EL_TELLTC: case EL_TELLTC:
case EL_SETTC: case EL_SETTC:
case EL_ECHOTC: case EL_ECHOTC:
case EL_SETTY: case EL_SETTY:
{ {
char *argv[20]; const char *argv[20];
int i; int i;
for (i = 1; i < 20; i++) for (i = 1; i < sizeof(argv) / sizeof(argv[0]); i++)
if ((argv[i] = va_arg(va, char *)) == NULL) if ((argv[i] = va_arg(va, char *)) == NULL)
break; break;
@ -370,6 +394,16 @@ el_get(EditLine *el, int op, void *ret)
rv = 0; rv = 0;
break; break;
case EL_CLIENTDATA:
*((void **)ret) = el->el_data;
rv = 0;
break;
case EL_UNBUFFERED:
*((int *) ret) = (!(el->el_flags & UNBUFFERED));
rv = 0;
break;
default: default:
rv = -1; rv = -1;
} }
@ -388,7 +422,6 @@ el_line(EditLine *el)
return (const LineInfo *) (void *) &el->el_line; return (const LineInfo *) (void *) &el->el_line;
} }
static const char elpath[] = "/.editrc";
/* el_source(): /* el_source():
* Source a file * Source a file
@ -398,10 +431,14 @@ el_source(EditLine *el, const char *fname)
{ {
FILE *fp; FILE *fp;
size_t len; size_t len;
char *ptr, path[MAXPATHLEN]; char *ptr;
fp = NULL; fp = NULL;
if (fname == NULL) { if (fname == NULL) {
#ifdef HAVE_ISSETUGID
static const char elpath[] = "/.editrc";
char path[MAXPATHLEN];
if (issetugid()) if (issetugid())
return (-1); return (-1);
if ((ptr = getenv("HOME")) == NULL) if ((ptr = getenv("HOME")) == NULL)
@ -411,6 +448,14 @@ el_source(EditLine *el, const char *fname)
if (strlcat(path, elpath, sizeof(path)) >= sizeof(path)) if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
return (-1); return (-1);
fname = path; fname = path;
#else
/*
* If issetugid() is missing, always return an error, in order
* to keep from inadvertently opening up the user to a security
* hole.
*/
return (-1);
#endif
} }
if (fp == NULL) if (fp == NULL)
fp = fopen(fname, "r"); fp = fopen(fname, "r");
@ -469,7 +514,7 @@ el_beep(EditLine *el)
*/ */
protected int protected int
/*ARGSUSED*/ /*ARGSUSED*/
el_editmode(EditLine *el, int argc, char **argv) el_editmode(EditLine *el, int argc, const char **argv)
{ {
const char *how; const char *how;
@ -477,10 +522,13 @@ el_editmode(EditLine *el, int argc, char **argv)
return (-1); return (-1);
how = argv[1]; how = argv[1];
if (strcmp(how, "on") == 0) if (strcmp(how, "on") == 0) {
el->el_flags &= ~EDIT_DISABLED; el->el_flags &= ~EDIT_DISABLED;
else if (strcmp(how, "off") == 0) tty_rawmode(el);
} else if (strcmp(how, "off") == 0) {
tty_cookedmode(el);
el->el_flags |= EDIT_DISABLED; el->el_flags |= EDIT_DISABLED;
}
else { else {
(void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how); (void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how);
return (-1); return (-1);

31
el.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: el.h,v 1.9 2001/09/27 19:29:50 christos Exp $ */ /* $NetBSD: el.h,v 1.16 2003/10/18 23:48:42 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -55,9 +51,10 @@
#define EL_BUFSIZ 1024 /* Maximum line size */ #define EL_BUFSIZ 1024 /* Maximum line size */
#define HANDLE_SIGNALS 1<<0 #define HANDLE_SIGNALS 0x01
#define NO_TTY 1<<1 #define NO_TTY 0x02
#define EDIT_DISABLED 1<<2 #define EDIT_DISABLED 0x04
#define UNBUFFERED 0x08
typedef int bool_t; /* True or not */ typedef int bool_t; /* True or not */
@ -72,7 +69,7 @@ typedef struct el_line_t {
char *buffer; /* Input line */ char *buffer; /* Input line */
char *cursor; /* Cursor position */ char *cursor; /* Cursor position */
char *lastchar; /* Last character */ char *lastchar; /* Last character */
const char *limit; /* Max position */ const char *limit; /* Max position */
} el_line_t; } el_line_t;
/* /*
@ -84,11 +81,14 @@ typedef struct el_state_t {
int argument; /* Numeric argument */ int argument; /* Numeric argument */
int metanext; /* Is the next char a meta char */ int metanext; /* Is the next char a meta char */
el_action_t lastcmd; /* Previous command */ el_action_t lastcmd; /* Previous command */
el_action_t thiscmd; /* this command */
char thisch; /* char that generated it */
} el_state_t; } el_state_t;
/* /*
* Until we come up with something better... * Until we come up with something better...
*/ */
#define el_strdup(a) strdup(a)
#define el_malloc(a) malloc(a) #define el_malloc(a) malloc(a)
#define el_realloc(a,b) realloc(a, b) #define el_realloc(a,b) realloc(a, b)
#define el_free(a) free(a) #define el_free(a) free(a)
@ -117,6 +117,7 @@ struct editline {
coord_t el_cursor; /* Cursor location */ coord_t el_cursor; /* Cursor location */
char **el_display; /* Real screen image = what is there */ char **el_display; /* Real screen image = what is there */
char **el_vdisplay; /* Virtual screen image = what we see */ char **el_vdisplay; /* Virtual screen image = what we see */
void *el_data; /* Client data */
el_line_t el_line; /* The current line information */ el_line_t el_line; /* The current line information */
el_state_t el_state; /* Current editor state */ el_state_t el_state; /* Current editor state */
el_term_t el_term; /* Terminal dependent stuff */ el_term_t el_term; /* Terminal dependent stuff */
@ -133,11 +134,15 @@ struct editline {
el_read_t el_read; /* Character reading stuff */ el_read_t el_read; /* Character reading stuff */
}; };
protected int el_editmode(EditLine *, int, char **); protected int el_editmode(EditLine *, int, const char **);
#ifdef DEBUG #ifdef DEBUG
#define EL_ABORT(a) (void) (fprintf(el->el_errfile, "%s, %d: ", \ #define EL_ABORT(a) do { \
__FILE__, __LINE__), fprintf a, abort()) fprintf(el->el_errfile, "%s, %d: ", \
__FILE__, __LINE__); \
fprintf a; \
abort(); \
} while( /*CONSTCOND*/0);
#else #else
#define EL_ABORT(a) abort() #define EL_ABORT(a) abort()
#endif #endif

109
emacs.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: emacs.c,v 1.9 2001/01/10 07:45:41 jdolecek Exp $ */ /* $NetBSD: emacs.c,v 1.19 2004/10/28 21:14:52 dsl Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,19 +32,18 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: emacs.c,v 1.9 2001/01/10 07:45:41 jdolecek Exp $"); __RCSID("$NetBSD: emacs.c,v 1.19 2004/10/28 21:14:52 dsl Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* emacs.c: Emacs functions * emacs.c: Emacs functions
*/ */
#include "sys.h"
#include "el.h" #include "el.h"
/* em_delete_or_list(): /* em_delete_or_list():
@ -57,7 +52,7 @@ __RCSID("$NetBSD: emacs.c,v 1.9 2001/01/10 07:45:41 jdolecek Exp $");
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_delete_or_list(EditLine *el, int c) em_delete_or_list(EditLine *el, int c __attribute__((__unused__)))
{ {
if (el->el_line.cursor == el->el_line.lastchar) { if (el->el_line.cursor == el->el_line.lastchar) {
@ -76,7 +71,10 @@ em_delete_or_list(EditLine *el, int c)
return (CC_ERROR); return (CC_ERROR);
} }
} else { } else {
c_delafter(el, el->el_state.argument); /* delete after dot */ if (el->el_state.doingarg)
c_delafter(el, el->el_state.argument);
else
c_delafter1(el);
if (el->el_line.cursor > el->el_line.lastchar) if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar; el->el_line.cursor = el->el_line.lastchar;
/* bounds check */ /* bounds check */
@ -91,7 +89,7 @@ em_delete_or_list(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_delete_next_word(EditLine *el, int c) em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
{ {
char *cp, *p, *kp; char *cp, *p, *kp;
@ -120,14 +118,12 @@ em_delete_next_word(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_yank(EditLine *el, int c) em_yank(EditLine *el, int c __attribute__((__unused__)))
{ {
char *kp, *cp; char *kp, *cp;
if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) { if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
if (!ch_enlargebufs(el, 1)) return (CC_NORM);
return (CC_ERROR);
}
if (el->el_line.lastchar + if (el->el_line.lastchar +
(el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >= (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
@ -157,7 +153,7 @@ em_yank(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_kill_line(EditLine *el, int c) em_kill_line(EditLine *el, int c __attribute__((__unused__)))
{ {
char *kp, *cp; char *kp, *cp;
@ -179,7 +175,7 @@ em_kill_line(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_kill_region(EditLine *el, int c) em_kill_region(EditLine *el, int c __attribute__((__unused__)))
{ {
char *kp, *cp; char *kp, *cp;
@ -212,11 +208,11 @@ em_kill_region(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_copy_region(EditLine *el, int c) em_copy_region(EditLine *el, int c __attribute__((__unused__)))
{ {
char *kp, *cp; char *kp, *cp;
if (el->el_chared.c_kill.mark) if (!el->el_chared.c_kill.mark)
return (CC_ERROR); return (CC_ERROR);
if (el->el_chared.c_kill.mark > el->el_line.cursor) { if (el->el_chared.c_kill.mark > el->el_line.cursor) {
@ -236,12 +232,12 @@ em_copy_region(EditLine *el, int c)
} }
/* em_gosmacs_traspose(): /* em_gosmacs_transpose():
* Exchange the two characters before the cursor * Exchange the two characters before the cursor
* Gosling emacs transpose chars [^T] * Gosling emacs transpose chars [^T]
*/ */
protected el_action_t protected el_action_t
em_gosmacs_traspose(EditLine *el, int c) em_gosmacs_transpose(EditLine *el, int c)
{ {
if (el->el_line.cursor > &el->el_line.buffer[1]) { if (el->el_line.cursor > &el->el_line.buffer[1]) {
@ -261,7 +257,7 @@ em_gosmacs_traspose(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_next_word(EditLine *el, int c) em_next_word(EditLine *el, int c __attribute__((__unused__)))
{ {
if (el->el_line.cursor == el->el_line.lastchar) if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR); return (CC_ERROR);
@ -272,7 +268,7 @@ em_next_word(EditLine *el, int c)
ce__isword); ce__isword);
if (el->el_map.type == MAP_VI) if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action & DELETE) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return (CC_REFRESH);
} }
@ -286,7 +282,7 @@ em_next_word(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_upper_case(EditLine *el, int c) em_upper_case(EditLine *el, int c __attribute__((__unused__)))
{ {
char *cp, *ep; char *cp, *ep;
@ -294,8 +290,8 @@ em_upper_case(EditLine *el, int c)
el->el_state.argument, ce__isword); el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++) for (cp = el->el_line.cursor; cp < ep; cp++)
if (islower((unsigned char) *cp)) if (islower((unsigned char)*cp))
*cp = toupper(*cp); *cp = toupper((unsigned char)*cp);
el->el_line.cursor = ep; el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar) if (el->el_line.cursor > el->el_line.lastchar)
@ -310,7 +306,7 @@ em_upper_case(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_capitol_case(EditLine *el, int c) em_capitol_case(EditLine *el, int c __attribute__((__unused__)))
{ {
char *cp, *ep; char *cp, *ep;
@ -318,16 +314,16 @@ em_capitol_case(EditLine *el, int c)
el->el_state.argument, ce__isword); el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++) { for (cp = el->el_line.cursor; cp < ep; cp++) {
if (isalpha((unsigned char) *cp)) { if (isalpha((unsigned char)*cp)) {
if (islower((unsigned char) *cp)) if (islower((unsigned char)*cp))
*cp = toupper(*cp); *cp = toupper((unsigned char)*cp);
cp++; cp++;
break; break;
} }
} }
for (; cp < ep; cp++) for (; cp < ep; cp++)
if (isupper((unsigned char) *cp)) if (isupper((unsigned char)*cp))
*cp = tolower(*cp); *cp = tolower((unsigned char)*cp);
el->el_line.cursor = ep; el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar) if (el->el_line.cursor > el->el_line.lastchar)
@ -342,7 +338,7 @@ em_capitol_case(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_lower_case(EditLine *el, int c) em_lower_case(EditLine *el, int c __attribute__((__unused__)))
{ {
char *cp, *ep; char *cp, *ep;
@ -350,8 +346,8 @@ em_lower_case(EditLine *el, int c)
el->el_state.argument, ce__isword); el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++) for (cp = el->el_line.cursor; cp < ep; cp++)
if (isupper((unsigned char) *cp)) if (isupper((unsigned char)*cp))
*cp = tolower(*cp); *cp = tolower((unsigned char)*cp);
el->el_line.cursor = ep; el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar) if (el->el_line.cursor > el->el_line.lastchar)
@ -366,7 +362,7 @@ em_lower_case(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_set_mark(EditLine *el, int c) em_set_mark(EditLine *el, int c __attribute__((__unused__)))
{ {
el->el_chared.c_kill.mark = el->el_line.cursor; el->el_chared.c_kill.mark = el->el_line.cursor;
@ -380,7 +376,7 @@ em_set_mark(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_exchange_mark(EditLine *el, int c) em_exchange_mark(EditLine *el, int c __attribute__((__unused__)))
{ {
char *cp; char *cp;
@ -397,7 +393,7 @@ em_exchange_mark(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_universal_argument(EditLine *el, int c) em_universal_argument(EditLine *el, int c __attribute__((__unused__)))
{ /* multiply current argument by 4 */ { /* multiply current argument by 4 */
if (el->el_state.argument > 1000000) if (el->el_state.argument > 1000000)
@ -414,7 +410,7 @@ em_universal_argument(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_meta_next(EditLine *el, int c) em_meta_next(EditLine *el, int c __attribute__((__unused__)))
{ {
el->el_state.metanext = 1; el->el_state.metanext = 1;
@ -427,7 +423,7 @@ em_meta_next(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_toggle_overwrite(EditLine *el, int c) em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__)))
{ {
el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ? el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
@ -441,7 +437,7 @@ em_toggle_overwrite(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_copy_prev_word(EditLine *el, int c) em_copy_prev_word(EditLine *el, int c __attribute__((__unused__)))
{ {
char *cp, *oldc, *dp; char *cp, *oldc, *dp;
@ -468,7 +464,7 @@ em_copy_prev_word(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_inc_search_next(EditLine *el, int c) em_inc_search_next(EditLine *el, int c __attribute__((__unused__)))
{ {
el->el_search.patlen = 0; el->el_search.patlen = 0;
@ -481,9 +477,32 @@ em_inc_search_next(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_inc_search_prev(EditLine *el, int c) em_inc_search_prev(EditLine *el, int c __attribute__((__unused__)))
{ {
el->el_search.patlen = 0; el->el_search.patlen = 0;
return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY)); return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY));
} }
/* em_delete_prev_char():
* Delete the character to the left of the cursor
* [^?]
*/
protected el_action_t
/*ARGSUSED*/
em_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
{
if (el->el_line.cursor <= el->el_line.buffer)
return (CC_ERROR);
if (el->el_state.doingarg)
c_delbefore(el, el->el_state.argument);
else
c_delbefore1(el);
el->el_line.cursor -= el->el_state.argument;
if (el->el_line.cursor < el->el_line.buffer)
el->el_line.cursor = el->el_line.buffer;
return (CC_REFRESH);
}

539
filecomplete.c Normal file
View File

@ -0,0 +1,539 @@
/* $NetBSD: filecomplete.c,v 1.7 2005/06/11 18:18:59 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jaromir Dolecek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: filecomplete.c,v 1.7 2005/06/11 18:18:59 christos Exp $");
#endif /* not lint && not SCCSID */
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <pwd.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_VIS_H
#include <vis.h>
#else
#include "np/vis.h"
#endif
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif
#include "el.h"
#include "fcns.h" /* for EL_NUM_FCNS */
#include "histedit.h"
#include "filecomplete.h"
static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
'>', '<', '=', ';', '|', '&', '{', '(', '\0' };
/********************************/
/* completion functions */
/*
* does tilde expansion of strings of type ``~user/foo''
* if ``user'' isn't valid user name or ``txt'' doesn't start
* w/ '~', returns pointer to strdup()ed copy of ``txt''
*
* it's callers's responsibility to free() returned string
*/
char *
fn_tilde_expand(const char *txt)
{
struct passwd pwres, *pass;
char *temp;
size_t len = 0;
char pwbuf[1024];
if (txt[0] != '~')
return (strdup(txt));
temp = strchr(txt + 1, '/');
if (temp == NULL) {
temp = strdup(txt + 1);
if (temp == NULL)
return NULL;
} else {
len = temp - txt + 1; /* text until string after slash */
temp = malloc(len);
if (temp == NULL)
return NULL;
(void)strncpy(temp, txt + 1, len - 2);
temp[len - 2] = '\0';
}
if (temp[0] == 0) {
if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
pass = NULL;
} else {
if (getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
pass = NULL;
}
free(temp); /* value no more needed */
if (pass == NULL)
return (strdup(txt));
/* update pointer txt to point at string immedially following */
/* first slash */
txt += len;
temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1);
if (temp == NULL)
return NULL;
(void)sprintf(temp, "%s/%s", pass->pw_dir, txt);
return (temp);
}
/*
* return first found file name starting by the ``text'' or NULL if no
* such file can be found
* value of ``state'' is ignored
*
* it's caller's responsibility to free returned string
*/
char *
fn_filename_completion_function(const char *text, int state)
{
static DIR *dir = NULL;
static char *filename = NULL, *dirname = NULL, *dirpath = NULL;
static size_t filename_len = 0;
struct dirent *entry;
char *temp;
size_t len;
if (state == 0 || dir == NULL) {
temp = strrchr(text, '/');
if (temp) {
char *nptr;
temp++;
nptr = realloc(filename, strlen(temp) + 1);
if (nptr == NULL) {
free(filename);
return NULL;
}
filename = nptr;
(void)strcpy(filename, temp);
len = temp - text; /* including last slash */
nptr = realloc(dirname, len + 1);
if (nptr == NULL) {
free(filename);
return NULL;
}
dirname = nptr;
(void)strncpy(dirname, text, len);
dirname[len] = '\0';
} else {
if (*text == 0)
filename = NULL;
else {
filename = strdup(text);
if (filename == NULL)
return NULL;
}
dirname = NULL;
}
if (dir != NULL) {
(void)closedir(dir);
dir = NULL;
}
/* support for ``~user'' syntax */
free(dirpath);
if (dirname == NULL && (dirname = strdup("./")) == NULL)
return NULL;
if (*dirname == '~')
dirpath = fn_tilde_expand(dirname);
else
dirpath = strdup(dirname);
if (dirpath == NULL)
return NULL;
dir = opendir(dirpath);
if (!dir)
return (NULL); /* cannot open the directory */
/* will be used in cycle */
filename_len = filename ? strlen(filename) : 0;
}
/* find the match */
while ((entry = readdir(dir)) != NULL) {
/* skip . and .. */
if (entry->d_name[0] == '.' && (!entry->d_name[1]
|| (entry->d_name[1] == '.' && !entry->d_name[2])))
continue;
if (filename_len == 0)
break;
/* otherwise, get first entry where first */
/* filename_len characters are equal */
if (entry->d_name[0] == filename[0]
#if defined(__SVR4) || defined(__linux__)
&& strlen(entry->d_name) >= filename_len
#else
&& entry->d_namlen >= filename_len
#endif
&& strncmp(entry->d_name, filename,
filename_len) == 0)
break;
}
if (entry) { /* match found */
#if defined(__SVR4) || defined(__linux__)
len = strlen(entry->d_name);
#else
len = entry->d_namlen;
#endif
temp = malloc(strlen(dirname) + len + 1);
if (temp == NULL)
return NULL;
(void)sprintf(temp, "%s%s", dirname, entry->d_name);
} else {
(void)closedir(dir);
dir = NULL;
temp = NULL;
}
return (temp);
}
static const char *
append_char_function(const char *name)
{
struct stat stbuf;
char *expname = *name == '~' ? fn_tilde_expand(name) : NULL;
const char *rs = "";
if (stat(expname ? expname : name, &stbuf) == -1)
goto out;
if (S_ISDIR(stbuf.st_mode))
rs = "/";
out:
if (expname)
free(expname);
return rs;
}
/*
* returns list of completions for text given
* non-static for readline.
*/
char ** completion_matches(const char *, char *(*)(const char *, int));
char **
completion_matches(const char *text, char *(*genfunc)(const char *, int))
{
char **match_list = NULL, *retstr, *prevstr;
size_t match_list_len, max_equal, which, i;
size_t matches;
matches = 0;
match_list_len = 1;
while ((retstr = (*genfunc) (text, (int)matches)) != NULL) {
/* allow for list terminator here */
if (matches + 3 >= match_list_len) {
char **nmatch_list;
while (matches + 3 >= match_list_len)
match_list_len <<= 1;
nmatch_list = realloc(match_list,
match_list_len * sizeof(char *));
if (nmatch_list == NULL) {
free(match_list);
return NULL;
}
match_list = nmatch_list;
}
match_list[++matches] = retstr;
}
if (!match_list)
return NULL; /* nothing found */
/* find least denominator and insert it to match_list[0] */
which = 2;
prevstr = match_list[1];
max_equal = strlen(prevstr);
for (; which <= matches; which++) {
for (i = 0; i < max_equal &&
prevstr[i] == match_list[which][i]; i++)
continue;
max_equal = i;
}
retstr = malloc(max_equal + 1);
if (retstr == NULL) {
free(match_list);
return NULL;
}
(void)strncpy(retstr, match_list[1], max_equal);
retstr[max_equal] = '\0';
match_list[0] = retstr;
/* add NULL as last pointer to the array */
match_list[matches + 1] = (char *) NULL;
return (match_list);
}
/*
* Sort function for qsort(). Just wrapper around strcasecmp().
*/
static int
_fn_qsort_string_compare(const void *i1, const void *i2)
{
const char *s1 = ((const char * const *)i1)[0];
const char *s2 = ((const char * const *)i2)[0];
return strcasecmp(s1, s2);
}
/*
* Display list of strings in columnar format on readline's output stream.
* 'matches' is list of strings, 'len' is number of strings in 'matches',
* 'max' is maximum length of string in 'matches'.
*/
void
fn_display_match_list (EditLine *el, char **matches, int len, int max)
{
int i, idx, limit, count;
int screenwidth = el->el_term.t_size.h;
/*
* Find out how many entries can be put on one line, count
* with two spaces between strings.
*/
limit = screenwidth / (max + 2);
if (limit == 0)
limit = 1;
/* how many lines of output */
count = len / limit;
if (count * limit < len)
count++;
/* Sort the items if they are not already sorted. */
qsort(&matches[1], (size_t)(len - 1), sizeof(char *),
_fn_qsort_string_compare);
idx = 1;
for(; count > 0; count--) {
for(i = 0; i < limit && matches[idx]; i++, idx++)
(void)fprintf(el->el_outfile, "%-*s ", max,
matches[idx]);
(void)fprintf(el->el_outfile, "\n");
}
}
/*
* Complete the word at or before point,
* 'what_to_do' says what to do with the completion.
* \t means do standard completion.
* `?' means list the possible completions.
* `*' means insert all of the possible completions.
* `!' means to do standard completion, and list all possible completions if
* there is more than one.
*
* Note: '*' support is not implemented
* '!' could never be invoked
*/
int
fn_complete(EditLine *el,
char *(*complet_func)(const char *, int),
char **(*attempted_completion_function)(const char *, int, int),
const char *word_break, const char *special_prefixes,
const char *(*app_func)(const char *), int query_items,
int *completion_type, int *over, int *point, int *end)
{
const LineInfo *li;
char *temp, **matches;
const char *ctemp;
size_t len;
int what_to_do = '\t';
if (el->el_state.lastcmd == el->el_state.thiscmd)
what_to_do = '?';
/* readline's rl_complete() has to be told what we did... */
if (completion_type != NULL)
*completion_type = what_to_do;
if (!complet_func)
complet_func = fn_filename_completion_function;
if (!app_func)
app_func = append_char_function;
/* We now look backwards for the start of a filename/variable word */
li = el_line(el);
ctemp = (const char *) li->cursor;
while (ctemp > li->buffer
&& !strchr(word_break, ctemp[-1])
&& (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) )
ctemp--;
len = li->cursor - ctemp;
temp = alloca(len + 1);
(void)strncpy(temp, ctemp, len);
temp[len] = '\0';
/* these can be used by function called in completion_matches() */
/* or (*attempted_completion_function)() */
if (point != 0)
*point = li->cursor - li->buffer;
if (end != NULL)
*end = li->lastchar - li->buffer;
if (attempted_completion_function) {
int cur_off = li->cursor - li->buffer;
matches = (*attempted_completion_function) (temp,
(int)(cur_off - len), cur_off);
} else
matches = 0;
if (!attempted_completion_function ||
(over != NULL && *over && !matches))
matches = completion_matches(temp, complet_func);
if (over != NULL)
*over = 0;
if (matches) {
int i, retval = CC_REFRESH;
int matches_num, maxlen, match_len, match_display=1;
/*
* Only replace the completed string with common part of
* possible matches if there is possible completion.
*/
if (matches[0][0] != '\0') {
el_deletestr(el, (int) len);
el_insertstr(el, matches[0]);
}
if (what_to_do == '?')
goto display_matches;
if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) {
/*
* We found exact match. Add a space after
* it, unless we do filename completion and the
* object is a directory.
*/
el_insertstr(el, (*append_char_function)(matches[0]));
} else if (what_to_do == '!') {
display_matches:
/*
* More than one match and requested to list possible
* matches.
*/
for(i=1, maxlen=0; matches[i]; i++) {
match_len = strlen(matches[i]);
if (match_len > maxlen)
maxlen = match_len;
}
matches_num = i - 1;
/* newline to get on next line from command line */
(void)fprintf(el->el_outfile, "\n");
/*
* If there are too many items, ask user for display
* confirmation.
*/
if (matches_num > query_items) {
(void)fprintf(el->el_outfile,
"Display all %d possibilities? (y or n) ",
matches_num);
(void)fflush(el->el_outfile);
if (getc(stdin) != 'y')
match_display = 0;
(void)fprintf(el->el_outfile, "\n");
}
if (match_display)
fn_display_match_list(el, matches, matches_num,
maxlen);
retval = CC_REDISPLAY;
} else if (matches[0][0]) {
/*
* There was some common match, but the name was
* not complete enough. Next tab will print possible
* completions.
*/
el_beep(el);
} else {
/* lcd is not a valid object - further specification */
/* is needed */
el_beep(el);
retval = CC_NORM;
}
/* free elements of array and the array itself */
for (i = 0; matches[i]; i++)
free(matches[i]);
free(matches), matches = NULL;
return (retval);
}
return (CC_NORM);
}
/*
* el-compatible wrapper around rl_complete; needed for key binding
*/
/* ARGSUSED */
unsigned char
_el_fn_complete(EditLine *el, int ch __attribute__((__unused__)))
{
return (unsigned char)fn_complete(el, NULL, NULL,
break_chars, NULL, NULL, 100,
NULL, NULL, NULL, NULL);
}

51
filecomplete.h Normal file
View File

@ -0,0 +1,51 @@
/* $NetBSD: filecomplete.h,v 1.4 2005/06/11 18:18:59 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jaromir Dolecek.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _FILECOMPLETE_H_
#define _FILECOMPLETE_H_
int fn_complete(EditLine *,
char *(*)(const char *, int),
char **(*)(const char *, int, int),
const char *, const char *, const char *(*)(const char *), int,
int *, int *, int *, int *);
void fn_display_match_list(EditLine *, char **, int, int);
char *fn_tilde_expand(const char *);
char *fn_filename_completion_function(const char *, int);
#endif

64
hist.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: hist.c,v 1.9 2001/05/17 01:02:17 christos Exp $ */ /* $NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,19 +32,18 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: hist.c,v 1.9 2001/05/17 01:02:17 christos Exp $"); __RCSID("$NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* hist.c: History access functions * hist.c: History access functions
*/ */
#include "sys.h"
#include <stdlib.h> #include <stdlib.h>
#include "el.h" #include "el.h"
@ -133,18 +128,16 @@ hist_get(EditLine *el)
el->el_history.eventno = h; el->el_history.eventno = h;
return (CC_ERROR); return (CC_ERROR);
} }
(void) strncpy(el->el_line.buffer, hp, (void) strlcpy(el->el_line.buffer, hp,
(size_t)(el->el_line.limit - el->el_line.buffer)); (size_t)(el->el_line.limit - el->el_line.buffer));
el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer); el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer);
if (el->el_line.lastchar > el->el_line.buffer) { if (el->el_line.lastchar > el->el_line.buffer
if (el->el_line.lastchar[-1] == '\n') && el->el_line.lastchar[-1] == '\n')
el->el_line.lastchar--; el->el_line.lastchar--;
if (el->el_line.lastchar[-1] == ' ') if (el->el_line.lastchar > el->el_line.buffer
el->el_line.lastchar--; && el->el_line.lastchar[-1] == ' ')
if (el->el_line.lastchar < el->el_line.buffer) el->el_line.lastchar--;
el->el_line.lastchar = el->el_line.buffer;
}
#ifdef KSHVI #ifdef KSHVI
if (el->el_map.type == MAP_VI) if (el->el_map.type == MAP_VI)
el->el_line.cursor = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer;
@ -156,21 +149,40 @@ hist_get(EditLine *el)
} }
/* hist_list() /* hist_command()
* List history entries * process a history command
*/ */
protected int protected int
/*ARGSUSED*/ hist_command(EditLine *el, int argc, const char **argv)
hist_list(EditLine *el, int argc, char **argv)
{ {
const char *str; const char *str;
int num;
HistEvent ev;
if (el->el_history.ref == NULL) if (el->el_history.ref == NULL)
return (-1); return (-1);
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
(void) fprintf(el->el_outfile, "%d %s", if (argc == 1 || strcmp(argv[1], "list") == 0) {
el->el_history.ev.num, str); /* List history entries */
return (0);
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
(void) fprintf(el->el_outfile, "%d %s",
el->el_history.ev.num, str);
return (0);
}
if (argc != 3)
return (-1);
num = (int)strtol(argv[2], NULL, 0);
if (strcmp(argv[1], "size") == 0)
return history(el->el_history.ref, &ev, H_SETSIZE, num);
if (strcmp(argv[1], "unique") == 0)
return history(el->el_history.ref, &ev, H_SETUNIQUE, num);
return -1;
} }
/* hist_enlargebuf() /* hist_enlargebuf()

12
hist.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: hist.h,v 1.6 2001/01/10 07:45:41 jdolecek Exp $ */ /* $NetBSD: hist.h,v 1.10 2003/08/07 16:44:31 agc Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -66,7 +62,7 @@ typedef struct el_history_t {
#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL) #define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL)
#define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL) #define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL)
#define HIST_PREV(el) HIST_FUN(el, H_PREV, NULL) #define HIST_PREV(el) HIST_FUN(el, H_PREV, NULL)
#define HIST_EVENT(el, num) HIST_FUN(el, H_EVENT, num) #define HIST_SET(el, num) HIST_FUN(el, H_SET, num)
#define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname) #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(el, fname) HIST_FUN(el, H_SAVE fname)
@ -74,7 +70,7 @@ protected int hist_init(EditLine *);
protected void hist_end(EditLine *); protected void hist_end(EditLine *);
protected el_action_t hist_get(EditLine *); protected el_action_t hist_get(EditLine *);
protected int hist_set(EditLine *, hist_fun_t, ptr_t); protected int hist_set(EditLine *, hist_fun_t, ptr_t);
protected int hist_list(EditLine *, int, char **); protected int hist_command(EditLine *, int, const char **);
protected int hist_enlargebuf(EditLine *, size_t, size_t); protected int hist_enlargebuf(EditLine *, size_t, size_t);
#endif /* _h_el_hist */ #endif /* _h_el_hist */

View File

@ -1,4 +1,4 @@
/* $NetBSD: histedit.h,v 1.17 2001/09/27 19:29:50 christos Exp $ */ /* $NetBSD: histedit.h,v 1.28 2005/07/14 15:00:58 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -44,12 +40,20 @@
#ifndef _HISTEDIT_H_ #ifndef _HISTEDIT_H_
#define _HISTEDIT_H_ #define _HISTEDIT_H_
#define LIBEDIT_MAJOR 2
#define LIBEDIT_MINOR 9
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h> #include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/* /*
* ==== Editing ==== * ==== Editing ====
*/ */
typedef struct editline EditLine; typedef struct editline EditLine;
/* /*
@ -61,7 +65,6 @@ typedef struct lineinfo {
const char *lastchar; const char *lastchar;
} LineInfo; } LineInfo;
/* /*
* EditLine editor function return codes. * EditLine editor function return codes.
* For user-defined function interface * For user-defined function interface
@ -81,16 +84,15 @@ typedef struct lineinfo {
* Initialization, cleanup, and resetting * Initialization, cleanup, and resetting
*/ */
EditLine *el_init(const char *, FILE *, FILE *, FILE *); EditLine *el_init(const char *, FILE *, FILE *, FILE *);
void el_reset(EditLine *);
void el_end(EditLine *); void el_end(EditLine *);
void el_reset(EditLine *);
/* /*
* Get a line, a character or push a string back in the input queue * Get a line, a character or push a string back in the input queue
*/ */
const char *el_gets(EditLine *, int *); const char *el_gets(EditLine *, int *);
int el_getc(EditLine *, char *); int el_getc(EditLine *, char *);
void el_push(EditLine *, const char *); void el_push(EditLine *, char *);
/* /*
* Beep! * Beep!
@ -101,13 +103,14 @@ void el_beep(EditLine *);
* High level function internals control * High level function internals control
* Parses argc, argv array and executes builtin editline commands * Parses argc, argv array and executes builtin editline commands
*/ */
int el_parse(EditLine *, int, char **); int el_parse(EditLine *, int, const char **);
/* /*
* Low level editline access functions * Low level editline access functions
*/ */
int el_set(EditLine *, int, ...); int el_set(EditLine *, int, ...);
int el_get(EditLine *, int, void *); int el_get(EditLine *, int, void *);
unsigned char _el_fn_complete(EditLine *, int);
/* /*
* el_set/el_get parameters * el_set/el_get parameters
@ -127,6 +130,9 @@ int el_get(EditLine *, int, void *);
#define EL_EDITMODE 11 /* , int); */ #define EL_EDITMODE 11 /* , int); */
#define EL_RPROMPT 12 /* , el_pfunc_t); */ #define EL_RPROMPT 12 /* , el_pfunc_t); */
#define EL_GETCFN 13 /* , el_rfunc_t); */ #define EL_GETCFN 13 /* , el_rfunc_t); */
#define EL_CLIENTDATA 14 /* , void *); */
#define EL_UNBUFFERED 15 /* , int); */
#define EL_PREP_TERM 16 /* , int); */
#define EL_BUILTIN_GETCFN (NULL) #define EL_BUILTIN_GETCFN (NULL)
@ -142,7 +148,6 @@ int el_source(EditLine *, const char *);
*/ */
void el_resize(EditLine *); void el_resize(EditLine *);
/* /*
* User-defined function interface. * User-defined function interface.
*/ */
@ -150,6 +155,7 @@ const LineInfo *el_line(EditLine *);
int el_insertstr(EditLine *, const char *); int el_insertstr(EditLine *, const char *);
void el_deletestr(EditLine *, int); void el_deletestr(EditLine *, int);
/* /*
* ==== History ==== * ==== History ====
*/ */
@ -177,7 +183,7 @@ int history(History *, HistEvent *, int, ...);
#define H_PREV 5 /* , void); */ #define H_PREV 5 /* , void); */
#define H_NEXT 6 /* , void); */ #define H_NEXT 6 /* , void); */
#define H_CURR 8 /* , const int); */ #define H_CURR 8 /* , const int); */
#define H_SET 7 /* , void); */ #define H_SET 7 /* , int); */
#define H_ADD 9 /* , const char *); */ #define H_ADD 9 /* , const char *); */
#define H_ENTER 10 /* , const char *); */ #define H_ENTER 10 /* , const char *); */
#define H_APPEND 11 /* , const char *); */ #define H_APPEND 11 /* , const char *); */
@ -189,5 +195,30 @@ int history(History *, HistEvent *, int, ...);
#define H_LOAD 17 /* , const char *); */ #define H_LOAD 17 /* , const char *); */
#define H_SAVE 18 /* , const char *); */ #define H_SAVE 18 /* , const char *); */
#define H_CLEAR 19 /* , void); */ #define H_CLEAR 19 /* , void); */
#define H_SETUNIQUE 20 /* , int); */
#define H_GETUNIQUE 21 /* , void); */
#define H_DEL 22 /* , int); */
/*
* ==== Tokenization ====
*/
typedef struct tokenizer Tokenizer;
/*
* String tokenization functions, using simplified sh(1) quoting rules
*/
Tokenizer *tok_init(const char *);
void tok_end(Tokenizer *);
void tok_reset(Tokenizer *);
int tok_line(Tokenizer *, const LineInfo *,
int *, const char ***, int *, int *);
int tok_str(Tokenizer *, const char *,
int *, const char ***);
#ifdef __cplusplus
}
#endif
#endif /* _HISTEDIT_H_ */ #endif /* _HISTEDIT_H_ */

268
history.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: history.c,v 1.18 2001/09/29 17:52:10 jdolecek Exp $ */ /* $NetBSD: history.c,v 1.31 2005/08/01 14:34:06 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,24 +32,26 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: history.c,v 1.18 2001/09/29 17:52:10 jdolecek Exp $"); __RCSID("$NetBSD: history.c,v 1.31 2005/08/01 14:34:06 christos Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* hist.c: History access functions * hist.c: History access functions
*/ */
#include "sys.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#ifdef HAVE_VIS_H
#include <vis.h> #include <vis.h>
#else
#include "np/vis.h"
#endif
#include <sys/stat.h> #include <sys/stat.h>
static const char hist_cookie[] = "_HiStOrY_V2_\n"; static const char hist_cookie[] = "_HiStOrY_V2_\n";
@ -74,10 +72,12 @@ struct history {
history_gfun_t h_prev; /* Get the previous element */ history_gfun_t h_prev; /* Get the previous element */
history_gfun_t h_curr; /* Get the current element */ history_gfun_t h_curr; /* Get the current element */
history_sfun_t h_set; /* Set the current element */ history_sfun_t h_set; /* Set the current element */
history_sfun_t h_del; /* Set the given element */
history_vfun_t h_clear; /* Clear the history list */ history_vfun_t h_clear; /* Clear the history list */
history_efun_t h_enter; /* Add an element */ history_efun_t h_enter; /* Add an element */
history_efun_t h_add; /* Append to an element */ history_efun_t h_add; /* Append to an element */
}; };
#define HNEXT(h, ev) (*(h)->h_next)((h)->h_ref, ev) #define HNEXT(h, ev) (*(h)->h_next)((h)->h_ref, ev)
#define HFIRST(h, ev) (*(h)->h_first)((h)->h_ref, ev) #define HFIRST(h, ev) (*(h)->h_first)((h)->h_ref, ev)
#define HPREV(h, ev) (*(h)->h_prev)((h)->h_ref, ev) #define HPREV(h, ev) (*(h)->h_prev)((h)->h_ref, ev)
@ -87,14 +87,24 @@ struct history {
#define HCLEAR(h, ev) (*(h)->h_clear)((h)->h_ref, ev) #define HCLEAR(h, ev) (*(h)->h_clear)((h)->h_ref, ev)
#define HENTER(h, ev, str) (*(h)->h_enter)((h)->h_ref, ev, str) #define HENTER(h, ev, str) (*(h)->h_enter)((h)->h_ref, ev, str)
#define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str) #define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str)
#define HDEL(h, ev, n) (*(h)->h_del)((h)->h_ref, ev, n)
#define h_strdup(a) strdup(a)
#define h_malloc(a) malloc(a) #define h_malloc(a) malloc(a)
#define h_realloc(a, b) realloc((a), (b)) #define h_realloc(a, b) realloc((a), (b))
#define h_free(a) free(a) #define h_free(a) free(a)
typedef struct {
int num;
char *str;
} HistEventPrivate;
private int history_setsize(History *, HistEvent *, int); private int history_setsize(History *, HistEvent *, int);
private int history_getsize(History *, HistEvent *); private int history_getsize(History *, HistEvent *);
private int history_setunique(History *, HistEvent *, int);
private int history_getunique(History *, HistEvent *);
private int history_set_fun(History *, History *); private int history_set_fun(History *, History *);
private int history_load(History *, const char *); private int history_load(History *, const char *);
private int history_save(History *, const char *); private int history_save(History *, const char *);
@ -113,31 +123,41 @@ typedef struct hentry_t {
HistEvent ev; /* What we return */ HistEvent ev; /* What we return */
struct hentry_t *next; /* Next entry */ struct hentry_t *next; /* Next entry */
struct hentry_t *prev; /* Previous entry */ struct hentry_t *prev; /* Previous entry */
} hentry_t; } hentry_t;
typedef struct history_t { typedef struct history_t {
hentry_t list; /* Fake list header element */ hentry_t list; /* Fake list header element */
hentry_t *cursor; /* Current element in the list */ hentry_t *cursor; /* Current element in the list */
int max; /* Maximum number of events */ int max; /* Maximum number of events */
int cur; /* Current number of events */ int cur; /* Current number of events */
int eventid; /* For generation of unique event id */ int eventid; /* For generation of unique event id */
} history_t; int flags; /* History flags */
#define H_UNIQUE 1 /* Store only unique elements */
} history_t;
private int history_def_first(ptr_t, HistEvent *);
private int history_def_last(ptr_t, HistEvent *);
private int history_def_next(ptr_t, HistEvent *); private int history_def_next(ptr_t, HistEvent *);
private int history_def_first(ptr_t, HistEvent *);
private int history_def_prev(ptr_t, HistEvent *); private int history_def_prev(ptr_t, HistEvent *);
private int history_def_last(ptr_t, HistEvent *);
private int history_def_curr(ptr_t, HistEvent *); private int history_def_curr(ptr_t, HistEvent *);
private int history_def_set(ptr_t, HistEvent *, const int n); private int history_def_set(ptr_t, HistEvent *, const int);
private void history_def_clear(ptr_t, HistEvent *);
private int history_def_enter(ptr_t, HistEvent *, const char *); private int history_def_enter(ptr_t, HistEvent *, const char *);
private int history_def_add(ptr_t, HistEvent *, const char *); private int history_def_add(ptr_t, HistEvent *, const char *);
private void history_def_init(ptr_t *, HistEvent *, int); private int history_def_del(ptr_t, HistEvent *, const int);
private void history_def_clear(ptr_t, HistEvent *);
private int history_def_init(ptr_t *, HistEvent *, int);
private int history_def_insert(history_t *, HistEvent *, const char *); private int history_def_insert(history_t *, HistEvent *, const char *);
private void history_def_delete(history_t *, HistEvent *, hentry_t *); private void history_def_delete(history_t *, HistEvent *, hentry_t *);
#define history_def_setsize(p, num)(void) (((history_t *) p)->max = (num)) #define history_def_setsize(p, num)(void) (((history_t *)p)->max = (num))
#define history_def_getsize(p) (((history_t *) p)->cur) #define history_def_getsize(p) (((history_t *)p)->cur)
#define history_def_getunique(p) (((((history_t *)p)->flags) & H_UNIQUE) != 0)
#define history_def_setunique(p, uni) \
if (uni) \
(((history_t *)p)->flags) |= H_UNIQUE; \
else \
(((history_t *)p)->flags) &= ~H_UNIQUE
#define he_strerror(code) he_errlist[code] #define he_strerror(code) he_errlist[code]
#define he_seterrev(evp, code) {\ #define he_seterrev(evp, code) {\
@ -230,20 +250,19 @@ history_def_next(ptr_t p, HistEvent *ev)
{ {
history_t *h = (history_t *) p; history_t *h = (history_t *) p;
if (h->cursor != &h->list) if (h->cursor == &h->list) {
h->cursor = h->cursor->next;
else {
he_seterrev(ev, _HE_EMPTY_LIST); he_seterrev(ev, _HE_EMPTY_LIST);
return (-1); return (-1);
} }
if (h->cursor != &h->list) if (h->cursor->next == &h->list) {
*ev = h->cursor->ev;
else {
he_seterrev(ev, _HE_END_REACHED); he_seterrev(ev, _HE_END_REACHED);
return (-1); return (-1);
} }
h->cursor = h->cursor->next;
*ev = h->cursor->ev;
return (0); return (0);
} }
@ -256,21 +275,20 @@ history_def_prev(ptr_t p, HistEvent *ev)
{ {
history_t *h = (history_t *) p; history_t *h = (history_t *) p;
if (h->cursor != &h->list) if (h->cursor == &h->list) {
h->cursor = h->cursor->prev;
else {
he_seterrev(ev, he_seterrev(ev,
(h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST); (h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST);
return (-1); return (-1);
} }
if (h->cursor != &h->list) if (h->cursor->prev == &h->list) {
*ev = h->cursor->ev;
else {
he_seterrev(ev, _HE_START_REACHED); he_seterrev(ev, _HE_START_REACHED);
return (-1); return (-1);
} }
h->cursor = h->cursor->prev;
*ev = h->cursor->ev;
return (0); return (0);
} }
@ -331,39 +349,59 @@ history_def_add(ptr_t p, HistEvent *ev, const char *str)
history_t *h = (history_t *) p; history_t *h = (history_t *) p;
size_t len; size_t len;
char *s; char *s;
HistEventPrivate *evp = (void *)&h->cursor->ev;
if (h->cursor == &h->list) if (h->cursor == &h->list)
return (history_def_enter(p, ev, str)); return (history_def_enter(p, ev, str));
len = strlen(h->cursor->ev.str) + strlen(str) + 1; len = strlen(evp->str) + strlen(str) + 1;
s = (char *) h_malloc(len); s = (char *) h_malloc(len);
if (!s) { if (s == NULL) {
he_seterrev(ev, _HE_MALLOC_FAILED); he_seterrev(ev, _HE_MALLOC_FAILED);
return (-1); return (-1);
} }
(void) strlcpy(s, h->cursor->ev.str, len); (void) strlcpy(s, h->cursor->ev.str, len);
(void) strlcat(s, str, len); (void) strlcat(s, str, len);
/* LINTED const cast */ h_free((ptr_t)evp->str);
h_free((ptr_t) h->cursor->ev.str); evp->str = s;
h->cursor->ev.str = s;
*ev = h->cursor->ev; *ev = h->cursor->ev;
return (0); return (0);
} }
/* history_def_del():
* Delete element hp of the h list
*/
/* ARGSUSED */
private int
history_def_del(ptr_t p, HistEvent *ev __attribute__((__unused__)),
const int num)
{
history_t *h = (history_t *) p;
if (history_def_set(h, ev, num) != 0)
return (-1);
ev->str = strdup(h->cursor->ev.str);
ev->num = h->cursor->ev.num;
history_def_delete(h, ev, h->cursor);
return (0);
}
/* history_def_delete(): /* history_def_delete():
* Delete element hp of the h list * Delete element hp of the h list
*/ */
/* ARGSUSED */ /* ARGSUSED */
private void private void
history_def_delete(history_t *h, HistEvent *ev, hentry_t *hp) history_def_delete(history_t *h,
HistEvent *ev __attribute__((__unused__)), hentry_t *hp)
{ {
HistEventPrivate *evp = (void *)&hp->ev;
if (hp == &h->list) if (hp == &h->list)
abort(); abort();
if (h->cursor == hp)
h->cursor = hp->prev;
hp->prev->next = hp->next; hp->prev->next = hp->next;
hp->next->prev = hp->prev; hp->next->prev = hp->prev;
/* LINTED const cast */ h_free((ptr_t) evp->str);
h_free((ptr_t) hp->ev.str);
h_free(hp); h_free(hp);
h->cur--; h->cur--;
} }
@ -377,11 +415,11 @@ history_def_insert(history_t *h, HistEvent *ev, const char *str)
{ {
h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t)); h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t));
if (h->cursor) if (h->cursor == NULL)
h->cursor->ev.str = strdup(str); goto oomem;
if (!h->cursor || !h->cursor->ev.str) { if ((h->cursor->ev.str = h_strdup(str)) == NULL) {
he_seterrev(ev, _HE_MALLOC_FAILED); h_free((ptr_t)h->cursor);
return (-1); goto oomem;
} }
h->cursor->ev.num = ++h->eventid; h->cursor->ev.num = ++h->eventid;
h->cursor->next = h->list.next; h->cursor->next = h->list.next;
@ -392,6 +430,9 @@ history_def_insert(history_t *h, HistEvent *ev, const char *str)
*ev = h->cursor->ev; *ev = h->cursor->ev;
return (0); return (0);
oomem:
he_seterrev(ev, _HE_MALLOC_FAILED);
return (-1);
} }
@ -403,6 +444,10 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str)
{ {
history_t *h = (history_t *) p; history_t *h = (history_t *) p;
if ((h->flags & H_UNIQUE) != 0 && h->list.next != &h->list &&
strcmp(h->list.next->ev.str, str) == 0)
return (0);
if (history_def_insert(h, ev, str) == -1) if (history_def_insert(h, ev, str) == -1)
return (-1); /* error, keep error message */ return (-1); /* error, keep error message */
@ -413,7 +458,7 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str)
while (h->cur > h->max && h->cur > 0) while (h->cur > h->max && h->cur > 0)
history_def_delete(h, ev, h->list.prev); history_def_delete(h, ev, h->list.prev);
return (0); return (1);
} }
@ -421,10 +466,12 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str)
* Default history initialization function * Default history initialization function
*/ */
/* ARGSUSED */ /* ARGSUSED */
private void private int
history_def_init(ptr_t *p, HistEvent *ev, int n) history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n)
{ {
history_t *h = (history_t *) h_malloc(sizeof(history_t)); history_t *h = (history_t *) h_malloc(sizeof(history_t));
if (h == NULL)
return -1;
if (n <= 0) if (n <= 0)
n = 0; n = 0;
@ -435,7 +482,9 @@ history_def_init(ptr_t *p, HistEvent *ev, int n)
h->list.ev.str = NULL; h->list.ev.str = NULL;
h->list.ev.num = 0; h->list.ev.num = 0;
h->cursor = &h->list; h->cursor = &h->list;
h->flags = 0;
*p = (ptr_t) h; *p = (ptr_t) h;
return 0;
} }
@ -464,10 +513,15 @@ history_def_clear(ptr_t p, HistEvent *ev)
public History * public History *
history_init(void) history_init(void)
{ {
History *h = (History *) h_malloc(sizeof(History));
HistEvent ev; HistEvent ev;
History *h = (History *) h_malloc(sizeof(History));
if (h == NULL)
return NULL;
history_def_init(&h->h_ref, &ev, 0); if (history_def_init(&h->h_ref, &ev, 0) == -1) {
h_free((ptr_t)h);
return NULL;
}
h->h_ent = -1; h->h_ent = -1;
h->h_next = history_def_next; h->h_next = history_def_next;
h->h_first = history_def_first; h->h_first = history_def_first;
@ -478,6 +532,7 @@ history_init(void)
h->h_clear = history_def_clear; h->h_clear = history_def_clear;
h->h_enter = history_def_enter; h->h_enter = history_def_enter;
h->h_add = history_def_add; h->h_add = history_def_add;
h->h_del = history_def_del;
return (h); return (h);
} }
@ -493,6 +548,7 @@ history_end(History *h)
if (h->h_next == history_def_next) if (h->h_next == history_def_next)
history_def_clear(h->h_ref, &ev); history_def_clear(h->h_ref, &ev);
h_free(h);
} }
@ -523,18 +579,46 @@ history_setsize(History *h, HistEvent *ev, int num)
private int private int
history_getsize(History *h, HistEvent *ev) history_getsize(History *h, HistEvent *ev)
{ {
int retval = 0; if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1);
}
ev->num = history_def_getsize(h->h_ref);
if (ev->num < -1) {
he_seterrev(ev, _HE_SIZE_NEGATIVE);
return (-1);
}
return (0);
}
/* history_setunique():
* Set if adjacent equal events should not be entered in history.
*/
private int
history_setunique(History *h, HistEvent *ev, int uni)
{
if (h->h_next != history_def_next) { if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED); he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1); return (-1);
} }
retval = history_def_getsize(h->h_ref); history_def_setunique(h->h_ref, uni);
if (retval < -1) { return (0);
he_seterrev(ev, _HE_SIZE_NEGATIVE); }
/* history_getunique():
* Get if adjacent equal events should not be entered in history.
*/
private int
history_getunique(History *h, HistEvent *ev)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
return (-1); return (-1);
} }
ev->num = retval; ev->num = history_def_getunique(h->h_ref);
return (0); return (0);
} }
@ -550,7 +634,7 @@ history_set_fun(History *h, History *nh)
if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL || if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL ||
nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == NULL || nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == NULL ||
nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL || nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL ||
nh->h_ref == NULL) { nh->h_del == NULL || nh->h_ref == NULL) {
if (h->h_next != history_def_next) { if (h->h_next != history_def_next) {
history_def_init(&h->h_ref, &ev, 0); history_def_init(&h->h_ref, &ev, 0);
h->h_first = history_def_first; h->h_first = history_def_first;
@ -562,6 +646,7 @@ history_set_fun(History *h, History *nh)
h->h_clear = history_def_clear; h->h_clear = history_def_clear;
h->h_enter = history_def_enter; h->h_enter = history_def_enter;
h->h_add = history_def_add; h->h_add = history_def_add;
h->h_del = history_def_del;
} }
return (-1); return (-1);
} }
@ -578,6 +663,7 @@ history_set_fun(History *h, History *nh)
h->h_clear = nh->h_clear; h->h_clear = nh->h_clear;
h->h_enter = nh->h_enter; h->h_enter = nh->h_enter;
h->h_add = nh->h_add; h->h_add = nh->h_add;
h->h_del = nh->h_del;
return (0); return (0);
} }
@ -606,6 +692,8 @@ history_load(History *h, const char *fname)
goto done; goto done;
ptr = h_malloc(max_size = 1024); ptr = h_malloc(max_size = 1024);
if (ptr == NULL)
goto done;
for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) { for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) {
char c = line[sz]; char c = line[sz];
@ -615,15 +703,24 @@ history_load(History *h, const char *fname)
line[sz] = '\0'; line[sz] = '\0';
if (max_size < sz) { if (max_size < sz) {
max_size = (sz + 1023) & ~1023; char *nptr;
ptr = h_realloc(ptr, max_size); max_size = (sz + 1024) & ~1023;
nptr = h_realloc(ptr, max_size);
if (nptr == NULL) {
i = -1;
goto oomem;
}
ptr = nptr;
} }
(void) strunvis(ptr, line); (void) strunvis(ptr, line);
line[sz] = c; line[sz] = c;
HENTER(h, &ev, ptr); if (HENTER(h, &ev, ptr) == -1) {
h_free((ptr_t)ptr);
return -1;
}
} }
h_free(ptr); oomem:
h_free((ptr_t)ptr);
done: done:
(void) fclose(fp); (void) fclose(fp);
return (i); return (i);
@ -638,28 +735,40 @@ history_save(History *h, const char *fname)
{ {
FILE *fp; FILE *fp;
HistEvent ev; HistEvent ev;
int i = 0, retval; int i = -1, retval;
size_t len, max_size; size_t len, max_size;
char *ptr; char *ptr;
if ((fp = fopen(fname, "w")) == NULL) if ((fp = fopen(fname, "w")) == NULL)
return (-1); return (-1);
(void) fchmod(fileno(fp), S_IRUSR|S_IWUSR); if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1)
(void) fputs(hist_cookie, fp); goto done;
if (fputs(hist_cookie, fp) == EOF)
goto done;
ptr = h_malloc(max_size = 1024); ptr = h_malloc(max_size = 1024);
for (retval = HLAST(h, &ev); if (ptr == NULL)
goto done;
for (i = 0, retval = HLAST(h, &ev);
retval != -1; retval != -1;
retval = HPREV(h, &ev), i++) { retval = HPREV(h, &ev), i++) {
len = strlen(ev.str) * 4; len = strlen(ev.str) * 4;
if (len >= max_size) { if (len >= max_size) {
max_size = (len + 1023) & 1023; char *nptr;
ptr = h_realloc(ptr, max_size); max_size = (len + 1024) & ~1023;
nptr = h_realloc(ptr, max_size);
if (nptr == NULL) {
i = -1;
goto oomem;
}
ptr = nptr;
} }
(void) strvis(ptr, ev.str, VIS_WHITE); (void) strvis(ptr, ev.str, VIS_WHITE);
(void) fprintf(fp, "%s\n", ev.str); (void) fprintf(fp, "%s\n", ptr);
} }
h_free(ptr); oomem:
h_free((ptr_t)ptr);
done:
(void) fclose(fp); (void) fclose(fp);
return (i); return (i);
} }
@ -758,11 +867,23 @@ history(History *h, HistEvent *ev, int fun, ...)
retval = history_setsize(h, ev, va_arg(va, int)); retval = history_setsize(h, ev, va_arg(va, int));
break; break;
case H_GETUNIQUE:
retval = history_getunique(h, ev);
break;
case H_SETUNIQUE:
retval = history_setunique(h, ev, va_arg(va, int));
break;
case H_ADD: case H_ADD:
str = va_arg(va, const char *); str = va_arg(va, const char *);
retval = HADD(h, ev, str); retval = HADD(h, ev, str);
break; break;
case H_DEL:
retval = HDEL(h, ev, va_arg(va, const int));
break;
case H_ENTER: case H_ENTER:
str = va_arg(va, const char *); str = va_arg(va, const char *);
if ((retval = HENTER(h, ev, str)) != -1) if ((retval = HENTER(h, ev, str)) != -1)
@ -847,6 +968,7 @@ history(History *h, HistEvent *ev, int fun, ...)
hf.h_clear = va_arg(va, history_vfun_t); hf.h_clear = va_arg(va, history_vfun_t);
hf.h_enter = va_arg(va, history_efun_t); hf.h_enter = va_arg(va, history_efun_t);
hf.h_add = va_arg(va, history_efun_t); hf.h_add = va_arg(va, history_efun_t);
hf.h_del = va_arg(va, history_sfun_t);
if ((retval = history_set_fun(h, &hf)) == -1) if ((retval = history_set_fun(h, &hf)) == -1)
he_seterrev(ev, _HE_PARAM_MISSING); he_seterrev(ev, _HE_PARAM_MISSING);

53
key.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: key.c,v 1.12 2001/05/17 01:02:17 christos Exp $ */ /* $NetBSD: key.c,v 1.16 2005/07/06 21:13:02 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,12 +32,12 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: key.c,v 1.12 2001/05/17 01:02:17 christos Exp $"); __RCSID("$NetBSD: key.c,v 1.16 2005/07/06 21:13:02 christos Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
@ -66,7 +62,6 @@ __RCSID("$NetBSD: key.c,v 1.12 2001/05/17 01:02:17 christos Exp $");
* 1) It is not possible to have one key that is a * 1) It is not possible to have one key that is a
* substr of another. * substr of another.
*/ */
#include "sys.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
@ -90,9 +85,11 @@ private int node_trav(EditLine *, key_node_t *, char *,
private int node__try(EditLine *, key_node_t *, const char *, private int node__try(EditLine *, key_node_t *, const char *,
key_value_t *, int); key_value_t *, int);
private key_node_t *node__get(int); private key_node_t *node__get(int);
private void node__free(key_node_t *);
private void node__put(EditLine *, key_node_t *); private void node__put(EditLine *, key_node_t *);
private int node__delete(EditLine *, key_node_t **, char *); private int node__delete(EditLine *, key_node_t **, const char *);
private int node_lookup(EditLine *, char *, key_node_t *, int); private int node_lookup(EditLine *, const char *, key_node_t *,
int);
private int node_enum(EditLine *, key_node_t *, int); private int node_enum(EditLine *, key_node_t *, int);
private int key__decode_char(char *, int, int); private int key__decode_char(char *, int, int);
@ -114,7 +111,6 @@ key_init(EditLine *el)
return (0); return (0);
} }
/* key_end(): /* key_end():
* Free the key maps * Free the key maps
*/ */
@ -124,8 +120,7 @@ key_end(EditLine *el)
el_free((ptr_t) el->el_key.buf); el_free((ptr_t) el->el_key.buf);
el->el_key.buf = NULL; el->el_key.buf = NULL;
/* XXX: provide a function to clear the keys */ node__free(el->el_key.map);
el->el_key.map = NULL;
} }
@ -219,7 +214,7 @@ key_add(EditLine *el, const char *key, key_value_t *val, int ntype)
* *
*/ */
protected void protected void
key_clear(EditLine *el, el_action_t *map, char *in) key_clear(EditLine *el, el_action_t *map, const char *in)
{ {
if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) && if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) &&
@ -236,7 +231,7 @@ key_clear(EditLine *el, el_action_t *map, char *in)
* they exists. * they exists.
*/ */
protected int protected int
key_delete(EditLine *el, char *key) key_delete(EditLine *el, const char *key)
{ {
if (key[0] == '\0') { if (key[0] == '\0') {
@ -257,7 +252,7 @@ key_delete(EditLine *el, char *key)
* Print entire el->el_key.map if null * Print entire el->el_key.map if null
*/ */
protected void protected void
key_print(EditLine *el, char *key) key_print(EditLine *el, const char *key)
{ {
/* do nothing if el->el_key.map is empty and null key specified */ /* do nothing if el->el_key.map is empty and null key specified */
@ -356,7 +351,8 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
break; break;
case XK_STR: case XK_STR:
case XK_EXE: case XK_EXE:
ptr->val.str = strdup(val->str); if ((ptr->val.str = el_strdup(val->str)) == NULL)
return -1;
break; break;
default: default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
@ -376,7 +372,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
* Delete node that matches str * Delete node that matches str
*/ */
private int private int
node__delete(EditLine *el, key_node_t **inptr, char *str) node__delete(EditLine *el, key_node_t **inptr, const char *str)
{ {
key_node_t *ptr; key_node_t *ptr;
key_node_t *prev_ptr = NULL; key_node_t *prev_ptr = NULL;
@ -471,14 +467,22 @@ node__get(int ch)
return (ptr); return (ptr);
} }
private void
node__free(key_node_t *k)
{
if (k == NULL)
return;
node__free(k->sibling);
node__free(k->next);
el_free((ptr_t) k);
}
/* node_lookup(): /* node_lookup():
* look for the str starting at node ptr. * look for the str starting at node ptr.
* Print if last node * Print if last node
*/ */
private int private int
node_lookup(EditLine *el, char *str, key_node_t *ptr, int cnt) node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
{ {
int ncnt; int ncnt;
@ -568,7 +572,7 @@ node_enum(EditLine *el, key_node_t *ptr, int cnt)
* function specified by val * function specified by val
*/ */
protected void protected void
key_kprint(EditLine *el, char *key, key_value_t *val, int ntype) key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
{ {
el_bindings_t *fp; el_bindings_t *fp;
char unparsbuf[EL_BUFSIZ]; char unparsbuf[EL_BUFSIZ];
@ -644,9 +648,10 @@ key__decode_char(char *buf, int cnt, int ch)
* Make a printable version of the ey * Make a printable version of the ey
*/ */
protected char * protected char *
key__decode_str(char *str, char *buf, char *sep) key__decode_str(const char *str, char *buf, const char *sep)
{ {
char *b, *p; char *b;
const char *p;
b = buf; b = buf;
if (sep[0] != '\0') if (sep[0] != '\0')

23
key.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: key.h,v 1.5 2001/01/23 15:55:30 jdolecek Exp $ */ /* $NetBSD: key.h,v 1.8 2003/08/07 16:44:32 agc Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -62,6 +58,10 @@ typedef struct el_key_t {
#define XK_NOD 2 #define XK_NOD 2
#define XK_EXE 3 #define XK_EXE 3
#undef key_end
#undef key_clear
#undef key_print
protected int key_init(EditLine *); protected int key_init(EditLine *);
protected void key_end(EditLine *); protected void key_end(EditLine *);
protected key_value_t *key_map_cmd(EditLine *, int); protected key_value_t *key_map_cmd(EditLine *, int);
@ -69,10 +69,11 @@ protected key_value_t *key_map_str(EditLine *, char *);
protected void key_reset(EditLine *); protected void key_reset(EditLine *);
protected int key_get(EditLine *, char *, key_value_t *); protected int key_get(EditLine *, char *, key_value_t *);
protected void key_add(EditLine *, const char *, key_value_t *, int); protected void key_add(EditLine *, const char *, key_value_t *, int);
protected void key_clear(EditLine *, el_action_t *, char *); protected void key_clear(EditLine *, el_action_t *, const char *);
protected int key_delete(EditLine *, char *); protected int key_delete(EditLine *, const char *);
protected void key_print(EditLine *, char *); protected void key_print(EditLine *, const char *);
protected void key_kprint(EditLine *, char *, key_value_t *, int); protected void key_kprint(EditLine *, const char *, key_value_t *,
protected char *key__decode_str(char *, char *, char *); int);
protected char *key__decode_str(const char *, char *, const char *);
#endif /* _h_el_key */ #endif /* _h_el_key */

View File

@ -1,5 +1,5 @@
#!/bin/sh - #!/bin/sh -
# $NetBSD: makelist,v 1.7 2001/01/09 19:22:31 jdolecek Exp $ # $NetBSD: makelist,v 1.9 2005/05/16 13:14:43 lukem Exp $
# #
# Copyright (c) 1992, 1993 # Copyright (c) 1992, 1993
# The Regents of the University of California. All rights reserved. # The Regents of the University of California. All rights reserved.
@ -15,11 +15,7 @@
# 2. Redistributions in binary form must reproduce the above copyright # 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the # notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution. # documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software # 3. Neither the name of the University nor the names of its contributors
# must display the following acknowledgement:
# This product includes software developed by the University of
# California, Berkeley and its contributors.
# 4. Neither the name of the University nor the names of its contributors
# may be used to endorse or promote products derived from this software # may be used to endorse or promote products derived from this software
# without specific prior written permission. # without specific prior written permission.
# #
@ -39,7 +35,7 @@
# makelist.sh: Automatically generate header files... # makelist.sh: Automatically generate header files...
AWK=/usr/bin/awk AWK=awk
USAGE="Usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m <filenames>" USAGE="Usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
if [ "x$1" = "x" ] if [ "x$1" = "x" ]

317
map.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: map.c,v 1.14 2001/01/09 17:22:09 jdolecek Exp $ */ /* $NetBSD: map.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,25 +32,24 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: map.c,v 1.14 2001/01/09 17:22:09 jdolecek Exp $"); __RCSID("$NetBSD: map.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* map.c: Editor function definitions * map.c: Editor function definitions
*/ */
#include "sys.h"
#include <stdlib.h> #include <stdlib.h>
#include "el.h" #include "el.h"
#define N_KEYS 256 #define N_KEYS 256
private void map_print_key(EditLine *, el_action_t *, char *); private void map_print_key(EditLine *, el_action_t *, const char *);
private void map_print_some_keys(EditLine *, el_action_t *, int, int); private void map_print_some_keys(EditLine *, el_action_t *, int, int);
private void map_print_all_keys(EditLine *); private void map_print_all_keys(EditLine *);
private void map_init_nls(EditLine *); private void map_init_nls(EditLine *);
@ -72,7 +67,7 @@ private const el_action_t el_map_emacs[] = {
/* 5 */ ED_MOVE_TO_END, /* ^E */ /* 5 */ ED_MOVE_TO_END, /* ^E */
/* 6 */ ED_NEXT_CHAR, /* ^F */ /* 6 */ ED_NEXT_CHAR, /* ^F */
/* 7 */ ED_UNASSIGNED, /* ^G */ /* 7 */ ED_UNASSIGNED, /* ^G */
/* 8 */ ED_DELETE_PREV_CHAR, /* ^H */ /* 8 */ EM_DELETE_PREV_CHAR, /* ^H */
/* 9 */ ED_UNASSIGNED, /* ^I */ /* 9 */ ED_UNASSIGNED, /* ^I */
/* 10 */ ED_NEWLINE, /* ^J */ /* 10 */ ED_NEWLINE, /* ^J */
/* 11 */ ED_KILL_LINE, /* ^K */ /* 11 */ ED_KILL_LINE, /* ^K */
@ -191,7 +186,7 @@ private const el_action_t el_map_emacs[] = {
/* 124 */ ED_INSERT, /* | */ /* 124 */ ED_INSERT, /* | */
/* 125 */ ED_INSERT, /* } */ /* 125 */ ED_INSERT, /* } */
/* 126 */ ED_INSERT, /* ~ */ /* 126 */ ED_INSERT, /* ~ */
/* 127 */ ED_DELETE_PREV_CHAR, /* ^? */ /* 127 */ EM_DELETE_PREV_CHAR, /* ^? */
/* 128 */ ED_UNASSIGNED, /* M-^@ */ /* 128 */ ED_UNASSIGNED, /* M-^@ */
/* 129 */ ED_UNASSIGNED, /* M-^A */ /* 129 */ ED_UNASSIGNED, /* M-^A */
/* 130 */ ED_UNASSIGNED, /* M-^B */ /* 130 */ ED_UNASSIGNED, /* M-^B */
@ -380,7 +375,7 @@ private const el_action_t el_map_vi_insert[] = {
/* 5 */ ED_MOVE_TO_END, /* ^E */ /* 5 */ ED_MOVE_TO_END, /* ^E */
/* 6 */ ED_NEXT_CHAR, /* ^F */ /* 6 */ ED_NEXT_CHAR, /* ^F */
/* 7 */ ED_UNASSIGNED, /* ^G */ /* 7 */ ED_UNASSIGNED, /* ^G */
/* 8 */ ED_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */ /* 8 */ VI_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */
/* 9 */ ED_UNASSIGNED, /* ^I */ /* Tab Key */ /* 9 */ ED_UNASSIGNED, /* ^I */ /* Tab Key */
/* 10 */ ED_NEWLINE, /* ^J */ /* 10 */ ED_NEWLINE, /* ^J */
/* 11 */ ED_KILL_LINE, /* ^K */ /* 11 */ ED_KILL_LINE, /* ^K */
@ -500,135 +495,135 @@ private const el_action_t el_map_vi_insert[] = {
/* 124 */ ED_INSERT, /* | */ /* 124 */ ED_INSERT, /* | */
/* 125 */ ED_INSERT, /* } */ /* 125 */ ED_INSERT, /* } */
/* 126 */ ED_INSERT, /* ~ */ /* 126 */ ED_INSERT, /* ~ */
/* 127 */ ED_DELETE_PREV_CHAR, /* ^? */ /* 127 */ VI_DELETE_PREV_CHAR, /* ^? */
/* 128 */ ED_UNASSIGNED, /* M-^@ */ /* 128 */ ED_INSERT, /* M-^@ */
/* 129 */ ED_UNASSIGNED, /* M-^A */ /* 129 */ ED_INSERT, /* M-^A */
/* 130 */ ED_UNASSIGNED, /* M-^B */ /* 130 */ ED_INSERT, /* M-^B */
/* 131 */ ED_UNASSIGNED, /* M-^C */ /* 131 */ ED_INSERT, /* M-^C */
/* 132 */ ED_UNASSIGNED, /* M-^D */ /* 132 */ ED_INSERT, /* M-^D */
/* 133 */ ED_UNASSIGNED, /* M-^E */ /* 133 */ ED_INSERT, /* M-^E */
/* 134 */ ED_UNASSIGNED, /* M-^F */ /* 134 */ ED_INSERT, /* M-^F */
/* 135 */ ED_UNASSIGNED, /* M-^G */ /* 135 */ ED_INSERT, /* M-^G */
/* 136 */ ED_UNASSIGNED, /* M-^H */ /* 136 */ ED_INSERT, /* M-^H */
/* 137 */ ED_UNASSIGNED, /* M-^I */ /* 137 */ ED_INSERT, /* M-^I */
/* 138 */ ED_UNASSIGNED, /* M-^J */ /* 138 */ ED_INSERT, /* M-^J */
/* 139 */ ED_UNASSIGNED, /* M-^K */ /* 139 */ ED_INSERT, /* M-^K */
/* 140 */ ED_UNASSIGNED, /* M-^L */ /* 140 */ ED_INSERT, /* M-^L */
/* 141 */ ED_UNASSIGNED, /* M-^M */ /* 141 */ ED_INSERT, /* M-^M */
/* 142 */ ED_UNASSIGNED, /* M-^N */ /* 142 */ ED_INSERT, /* M-^N */
/* 143 */ ED_UNASSIGNED, /* M-^O */ /* 143 */ ED_INSERT, /* M-^O */
/* 144 */ ED_UNASSIGNED, /* M-^P */ /* 144 */ ED_INSERT, /* M-^P */
/* 145 */ ED_UNASSIGNED, /* M-^Q */ /* 145 */ ED_INSERT, /* M-^Q */
/* 146 */ ED_UNASSIGNED, /* M-^R */ /* 146 */ ED_INSERT, /* M-^R */
/* 147 */ ED_UNASSIGNED, /* M-^S */ /* 147 */ ED_INSERT, /* M-^S */
/* 148 */ ED_UNASSIGNED, /* M-^T */ /* 148 */ ED_INSERT, /* M-^T */
/* 149 */ ED_UNASSIGNED, /* M-^U */ /* 149 */ ED_INSERT, /* M-^U */
/* 150 */ ED_UNASSIGNED, /* M-^V */ /* 150 */ ED_INSERT, /* M-^V */
/* 151 */ ED_UNASSIGNED, /* M-^W */ /* 151 */ ED_INSERT, /* M-^W */
/* 152 */ ED_UNASSIGNED, /* M-^X */ /* 152 */ ED_INSERT, /* M-^X */
/* 153 */ ED_UNASSIGNED, /* M-^Y */ /* 153 */ ED_INSERT, /* M-^Y */
/* 154 */ ED_UNASSIGNED, /* M-^Z */ /* 154 */ ED_INSERT, /* M-^Z */
/* 155 */ ED_UNASSIGNED, /* M-^[ */ /* 155 */ ED_INSERT, /* M-^[ */
/* 156 */ ED_UNASSIGNED, /* M-^\ */ /* 156 */ ED_INSERT, /* M-^\ */
/* 157 */ ED_UNASSIGNED, /* M-^] */ /* 157 */ ED_INSERT, /* M-^] */
/* 158 */ ED_UNASSIGNED, /* M-^^ */ /* 158 */ ED_INSERT, /* M-^^ */
/* 159 */ ED_UNASSIGNED, /* M-^_ */ /* 159 */ ED_INSERT, /* M-^_ */
/* 160 */ ED_UNASSIGNED, /* M-SPACE */ /* 160 */ ED_INSERT, /* M-SPACE */
/* 161 */ ED_UNASSIGNED, /* M-! */ /* 161 */ ED_INSERT, /* M-! */
/* 162 */ ED_UNASSIGNED, /* M-" */ /* 162 */ ED_INSERT, /* M-" */
/* 163 */ ED_UNASSIGNED, /* M-# */ /* 163 */ ED_INSERT, /* M-# */
/* 164 */ ED_UNASSIGNED, /* M-$ */ /* 164 */ ED_INSERT, /* M-$ */
/* 165 */ ED_UNASSIGNED, /* M-% */ /* 165 */ ED_INSERT, /* M-% */
/* 166 */ ED_UNASSIGNED, /* M-& */ /* 166 */ ED_INSERT, /* M-& */
/* 167 */ ED_UNASSIGNED, /* M-' */ /* 167 */ ED_INSERT, /* M-' */
/* 168 */ ED_UNASSIGNED, /* M-( */ /* 168 */ ED_INSERT, /* M-( */
/* 169 */ ED_UNASSIGNED, /* M-) */ /* 169 */ ED_INSERT, /* M-) */
/* 170 */ ED_UNASSIGNED, /* M-* */ /* 170 */ ED_INSERT, /* M-* */
/* 171 */ ED_UNASSIGNED, /* M-+ */ /* 171 */ ED_INSERT, /* M-+ */
/* 172 */ ED_UNASSIGNED, /* M-, */ /* 172 */ ED_INSERT, /* M-, */
/* 173 */ ED_UNASSIGNED, /* M-- */ /* 173 */ ED_INSERT, /* M-- */
/* 174 */ ED_UNASSIGNED, /* M-. */ /* 174 */ ED_INSERT, /* M-. */
/* 175 */ ED_UNASSIGNED, /* M-/ */ /* 175 */ ED_INSERT, /* M-/ */
/* 176 */ ED_UNASSIGNED, /* M-0 */ /* 176 */ ED_INSERT, /* M-0 */
/* 177 */ ED_UNASSIGNED, /* M-1 */ /* 177 */ ED_INSERT, /* M-1 */
/* 178 */ ED_UNASSIGNED, /* M-2 */ /* 178 */ ED_INSERT, /* M-2 */
/* 179 */ ED_UNASSIGNED, /* M-3 */ /* 179 */ ED_INSERT, /* M-3 */
/* 180 */ ED_UNASSIGNED, /* M-4 */ /* 180 */ ED_INSERT, /* M-4 */
/* 181 */ ED_UNASSIGNED, /* M-5 */ /* 181 */ ED_INSERT, /* M-5 */
/* 182 */ ED_UNASSIGNED, /* M-6 */ /* 182 */ ED_INSERT, /* M-6 */
/* 183 */ ED_UNASSIGNED, /* M-7 */ /* 183 */ ED_INSERT, /* M-7 */
/* 184 */ ED_UNASSIGNED, /* M-8 */ /* 184 */ ED_INSERT, /* M-8 */
/* 185 */ ED_UNASSIGNED, /* M-9 */ /* 185 */ ED_INSERT, /* M-9 */
/* 186 */ ED_UNASSIGNED, /* M-: */ /* 186 */ ED_INSERT, /* M-: */
/* 187 */ ED_UNASSIGNED, /* M-; */ /* 187 */ ED_INSERT, /* M-; */
/* 188 */ ED_UNASSIGNED, /* M-< */ /* 188 */ ED_INSERT, /* M-< */
/* 189 */ ED_UNASSIGNED, /* M-= */ /* 189 */ ED_INSERT, /* M-= */
/* 190 */ ED_UNASSIGNED, /* M-> */ /* 190 */ ED_INSERT, /* M-> */
/* 191 */ ED_UNASSIGNED, /* M-? */ /* 191 */ ED_INSERT, /* M-? */
/* 192 */ ED_UNASSIGNED, /* M-@ */ /* 192 */ ED_INSERT, /* M-@ */
/* 193 */ ED_UNASSIGNED, /* M-A */ /* 193 */ ED_INSERT, /* M-A */
/* 194 */ ED_UNASSIGNED, /* M-B */ /* 194 */ ED_INSERT, /* M-B */
/* 195 */ ED_UNASSIGNED, /* M-C */ /* 195 */ ED_INSERT, /* M-C */
/* 196 */ ED_UNASSIGNED, /* M-D */ /* 196 */ ED_INSERT, /* M-D */
/* 197 */ ED_UNASSIGNED, /* M-E */ /* 197 */ ED_INSERT, /* M-E */
/* 198 */ ED_UNASSIGNED, /* M-F */ /* 198 */ ED_INSERT, /* M-F */
/* 199 */ ED_UNASSIGNED, /* M-G */ /* 199 */ ED_INSERT, /* M-G */
/* 200 */ ED_UNASSIGNED, /* M-H */ /* 200 */ ED_INSERT, /* M-H */
/* 201 */ ED_UNASSIGNED, /* M-I */ /* 201 */ ED_INSERT, /* M-I */
/* 202 */ ED_UNASSIGNED, /* M-J */ /* 202 */ ED_INSERT, /* M-J */
/* 203 */ ED_UNASSIGNED, /* M-K */ /* 203 */ ED_INSERT, /* M-K */
/* 204 */ ED_UNASSIGNED, /* M-L */ /* 204 */ ED_INSERT, /* M-L */
/* 205 */ ED_UNASSIGNED, /* M-M */ /* 205 */ ED_INSERT, /* M-M */
/* 206 */ ED_UNASSIGNED, /* M-N */ /* 206 */ ED_INSERT, /* M-N */
/* 207 */ ED_UNASSIGNED, /* M-O */ /* 207 */ ED_INSERT, /* M-O */
/* 208 */ ED_UNASSIGNED, /* M-P */ /* 208 */ ED_INSERT, /* M-P */
/* 209 */ ED_UNASSIGNED, /* M-Q */ /* 209 */ ED_INSERT, /* M-Q */
/* 210 */ ED_UNASSIGNED, /* M-R */ /* 210 */ ED_INSERT, /* M-R */
/* 211 */ ED_UNASSIGNED, /* M-S */ /* 211 */ ED_INSERT, /* M-S */
/* 212 */ ED_UNASSIGNED, /* M-T */ /* 212 */ ED_INSERT, /* M-T */
/* 213 */ ED_UNASSIGNED, /* M-U */ /* 213 */ ED_INSERT, /* M-U */
/* 214 */ ED_UNASSIGNED, /* M-V */ /* 214 */ ED_INSERT, /* M-V */
/* 215 */ ED_UNASSIGNED, /* M-W */ /* 215 */ ED_INSERT, /* M-W */
/* 216 */ ED_UNASSIGNED, /* M-X */ /* 216 */ ED_INSERT, /* M-X */
/* 217 */ ED_UNASSIGNED, /* M-Y */ /* 217 */ ED_INSERT, /* M-Y */
/* 218 */ ED_UNASSIGNED, /* M-Z */ /* 218 */ ED_INSERT, /* M-Z */
/* 219 */ ED_UNASSIGNED, /* M-[ */ /* 219 */ ED_INSERT, /* M-[ */
/* 220 */ ED_UNASSIGNED, /* M-\ */ /* 220 */ ED_INSERT, /* M-\ */
/* 221 */ ED_UNASSIGNED, /* M-] */ /* 221 */ ED_INSERT, /* M-] */
/* 222 */ ED_UNASSIGNED, /* M-^ */ /* 222 */ ED_INSERT, /* M-^ */
/* 223 */ ED_UNASSIGNED, /* M-_ */ /* 223 */ ED_INSERT, /* M-_ */
/* 224 */ ED_UNASSIGNED, /* M-` */ /* 224 */ ED_INSERT, /* M-` */
/* 225 */ ED_UNASSIGNED, /* M-a */ /* 225 */ ED_INSERT, /* M-a */
/* 226 */ ED_UNASSIGNED, /* M-b */ /* 226 */ ED_INSERT, /* M-b */
/* 227 */ ED_UNASSIGNED, /* M-c */ /* 227 */ ED_INSERT, /* M-c */
/* 228 */ ED_UNASSIGNED, /* M-d */ /* 228 */ ED_INSERT, /* M-d */
/* 229 */ ED_UNASSIGNED, /* M-e */ /* 229 */ ED_INSERT, /* M-e */
/* 230 */ ED_UNASSIGNED, /* M-f */ /* 230 */ ED_INSERT, /* M-f */
/* 231 */ ED_UNASSIGNED, /* M-g */ /* 231 */ ED_INSERT, /* M-g */
/* 232 */ ED_UNASSIGNED, /* M-h */ /* 232 */ ED_INSERT, /* M-h */
/* 233 */ ED_UNASSIGNED, /* M-i */ /* 233 */ ED_INSERT, /* M-i */
/* 234 */ ED_UNASSIGNED, /* M-j */ /* 234 */ ED_INSERT, /* M-j */
/* 235 */ ED_UNASSIGNED, /* M-k */ /* 235 */ ED_INSERT, /* M-k */
/* 236 */ ED_UNASSIGNED, /* M-l */ /* 236 */ ED_INSERT, /* M-l */
/* 237 */ ED_UNASSIGNED, /* M-m */ /* 237 */ ED_INSERT, /* M-m */
/* 238 */ ED_UNASSIGNED, /* M-n */ /* 238 */ ED_INSERT, /* M-n */
/* 239 */ ED_UNASSIGNED, /* M-o */ /* 239 */ ED_INSERT, /* M-o */
/* 240 */ ED_UNASSIGNED, /* M-p */ /* 240 */ ED_INSERT, /* M-p */
/* 241 */ ED_UNASSIGNED, /* M-q */ /* 241 */ ED_INSERT, /* M-q */
/* 242 */ ED_UNASSIGNED, /* M-r */ /* 242 */ ED_INSERT, /* M-r */
/* 243 */ ED_UNASSIGNED, /* M-s */ /* 243 */ ED_INSERT, /* M-s */
/* 244 */ ED_UNASSIGNED, /* M-t */ /* 244 */ ED_INSERT, /* M-t */
/* 245 */ ED_UNASSIGNED, /* M-u */ /* 245 */ ED_INSERT, /* M-u */
/* 246 */ ED_UNASSIGNED, /* M-v */ /* 246 */ ED_INSERT, /* M-v */
/* 247 */ ED_UNASSIGNED, /* M-w */ /* 247 */ ED_INSERT, /* M-w */
/* 248 */ ED_UNASSIGNED, /* M-x */ /* 248 */ ED_INSERT, /* M-x */
/* 249 */ ED_UNASSIGNED, /* M-y */ /* 249 */ ED_INSERT, /* M-y */
/* 250 */ ED_UNASSIGNED, /* M-z */ /* 250 */ ED_INSERT, /* M-z */
/* 251 */ ED_UNASSIGNED, /* M-{ */ /* 251 */ ED_INSERT, /* M-{ */
/* 252 */ ED_UNASSIGNED, /* M-| */ /* 252 */ ED_INSERT, /* M-| */
/* 253 */ ED_UNASSIGNED, /* M-} */ /* 253 */ ED_INSERT, /* M-} */
/* 254 */ ED_UNASSIGNED, /* M-~ */ /* 254 */ ED_INSERT, /* M-~ */
/* 255 */ ED_UNASSIGNED /* M-^? */ /* 255 */ ED_INSERT /* M-^? */
}; };
private const el_action_t el_map_vi_command[] = { private const el_action_t el_map_vi_command[] = {
@ -640,7 +635,7 @@ private const el_action_t el_map_vi_command[] = {
/* 5 */ ED_MOVE_TO_END, /* ^E */ /* 5 */ ED_MOVE_TO_END, /* ^E */
/* 6 */ ED_UNASSIGNED, /* ^F */ /* 6 */ ED_UNASSIGNED, /* ^F */
/* 7 */ ED_UNASSIGNED, /* ^G */ /* 7 */ ED_UNASSIGNED, /* ^G */
/* 8 */ ED_PREV_CHAR, /* ^H */ /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */
/* 9 */ ED_UNASSIGNED, /* ^I */ /* 9 */ ED_UNASSIGNED, /* ^I */
/* 10 */ ED_NEWLINE, /* ^J */ /* 10 */ ED_NEWLINE, /* ^J */
/* 11 */ ED_KILL_LINE, /* ^K */ /* 11 */ ED_KILL_LINE, /* ^K */
@ -667,9 +662,9 @@ private const el_action_t el_map_vi_command[] = {
/* 32 */ ED_NEXT_CHAR, /* SPACE */ /* 32 */ ED_NEXT_CHAR, /* SPACE */
/* 33 */ ED_UNASSIGNED, /* ! */ /* 33 */ ED_UNASSIGNED, /* ! */
/* 34 */ ED_UNASSIGNED, /* " */ /* 34 */ ED_UNASSIGNED, /* " */
/* 35 */ ED_UNASSIGNED, /* # */ /* 35 */ VI_COMMENT_OUT, /* # */
/* 36 */ ED_MOVE_TO_END, /* $ */ /* 36 */ ED_MOVE_TO_END, /* $ */
/* 37 */ ED_UNASSIGNED, /* % */ /* 37 */ VI_MATCH, /* % */
/* 38 */ ED_UNASSIGNED, /* & */ /* 38 */ ED_UNASSIGNED, /* & */
/* 39 */ ED_UNASSIGNED, /* ' */ /* 39 */ ED_UNASSIGNED, /* ' */
/* 40 */ ED_UNASSIGNED, /* ( */ /* 40 */ ED_UNASSIGNED, /* ( */
@ -678,7 +673,7 @@ private const el_action_t el_map_vi_command[] = {
/* 43 */ ED_NEXT_HISTORY, /* + */ /* 43 */ ED_NEXT_HISTORY, /* + */
/* 44 */ VI_REPEAT_PREV_CHAR, /* , */ /* 44 */ VI_REPEAT_PREV_CHAR, /* , */
/* 45 */ ED_PREV_HISTORY, /* - */ /* 45 */ ED_PREV_HISTORY, /* - */
/* 46 */ ED_UNASSIGNED, /* . */ /* 46 */ VI_REDO, /* . */
/* 47 */ VI_SEARCH_PREV, /* / */ /* 47 */ VI_SEARCH_PREV, /* / */
/* 48 */ VI_ZERO, /* 0 */ /* 48 */ VI_ZERO, /* 0 */
/* 49 */ ED_ARGUMENT_DIGIT, /* 1 */ /* 49 */ ED_ARGUMENT_DIGIT, /* 1 */
@ -696,14 +691,14 @@ private const el_action_t el_map_vi_command[] = {
/* 61 */ ED_UNASSIGNED, /* = */ /* 61 */ ED_UNASSIGNED, /* = */
/* 62 */ ED_UNASSIGNED, /* > */ /* 62 */ ED_UNASSIGNED, /* > */
/* 63 */ VI_SEARCH_NEXT, /* ? */ /* 63 */ VI_SEARCH_NEXT, /* ? */
/* 64 */ ED_UNASSIGNED, /* @ */ /* 64 */ VI_ALIAS, /* @ */
/* 65 */ VI_ADD_AT_EOL, /* A */ /* 65 */ VI_ADD_AT_EOL, /* A */
/* 66 */ VI_PREV_SPACE_WORD, /* B */ /* 66 */ VI_PREV_BIG_WORD, /* B */
/* 67 */ VI_CHANGE_TO_EOL, /* C */ /* 67 */ VI_CHANGE_TO_EOL, /* C */
/* 68 */ ED_KILL_LINE, /* D */ /* 68 */ ED_KILL_LINE, /* D */
/* 69 */ VI_TO_END_WORD, /* E */ /* 69 */ VI_END_BIG_WORD, /* E */
/* 70 */ VI_PREV_CHAR, /* F */ /* 70 */ VI_PREV_CHAR, /* F */
/* 71 */ ED_UNASSIGNED, /* G */ /* 71 */ VI_TO_HISTORY_LINE, /* G */
/* 72 */ ED_UNASSIGNED, /* H */ /* 72 */ ED_UNASSIGNED, /* H */
/* 73 */ VI_INSERT_AT_BOL, /* I */ /* 73 */ VI_INSERT_AT_BOL, /* I */
/* 74 */ ED_SEARCH_NEXT_HISTORY, /* J */ /* 74 */ ED_SEARCH_NEXT_HISTORY, /* J */
@ -717,17 +712,17 @@ private const el_action_t el_map_vi_command[] = {
/* 82 */ VI_REPLACE_MODE, /* R */ /* 82 */ VI_REPLACE_MODE, /* R */
/* 83 */ VI_SUBSTITUTE_LINE, /* S */ /* 83 */ VI_SUBSTITUTE_LINE, /* S */
/* 84 */ VI_TO_PREV_CHAR, /* T */ /* 84 */ VI_TO_PREV_CHAR, /* T */
/* 85 */ ED_UNASSIGNED, /* U */ /* 85 */ VI_UNDO_LINE, /* U */
/* 86 */ ED_UNASSIGNED, /* V */ /* 86 */ ED_UNASSIGNED, /* V */
/* 87 */ VI_NEXT_SPACE_WORD, /* W */ /* 87 */ VI_NEXT_BIG_WORD, /* W */
/* 88 */ ED_DELETE_PREV_CHAR, /* X */ /* 88 */ ED_DELETE_PREV_CHAR, /* X */
/* 89 */ ED_UNASSIGNED, /* Y */ /* 89 */ VI_YANK_END, /* Y */
/* 90 */ ED_UNASSIGNED, /* Z */ /* 90 */ ED_UNASSIGNED, /* Z */
/* 91 */ ED_SEQUENCE_LEAD_IN, /* [ */ /* 91 */ ED_SEQUENCE_LEAD_IN, /* [ */
/* 92 */ ED_UNASSIGNED, /* \ */ /* 92 */ ED_UNASSIGNED, /* \ */
/* 93 */ ED_UNASSIGNED, /* ] */ /* 93 */ ED_UNASSIGNED, /* ] */
/* 94 */ ED_MOVE_TO_BEG, /* ^ */ /* 94 */ ED_MOVE_TO_BEG, /* ^ */
/* 95 */ ED_UNASSIGNED, /* _ */ /* 95 */ VI_HISTORY_WORD, /* _ */
/* 96 */ ED_UNASSIGNED, /* ` */ /* 96 */ ED_UNASSIGNED, /* ` */
/* 97 */ VI_ADD, /* a */ /* 97 */ VI_ADD, /* a */
/* 98 */ VI_PREV_WORD, /* b */ /* 98 */ VI_PREV_WORD, /* b */
@ -750,13 +745,13 @@ private const el_action_t el_map_vi_command[] = {
/* 115 */ VI_SUBSTITUTE_CHAR, /* s */ /* 115 */ VI_SUBSTITUTE_CHAR, /* s */
/* 116 */ VI_TO_NEXT_CHAR, /* t */ /* 116 */ VI_TO_NEXT_CHAR, /* t */
/* 117 */ VI_UNDO, /* u */ /* 117 */ VI_UNDO, /* u */
/* 118 */ ED_UNASSIGNED, /* v */ /* 118 */ VI_HISTEDIT, /* v */
/* 119 */ VI_NEXT_WORD, /* w */ /* 119 */ VI_NEXT_WORD, /* w */
/* 120 */ ED_DELETE_NEXT_CHAR, /* x */ /* 120 */ ED_DELETE_NEXT_CHAR, /* x */
/* 121 */ ED_UNASSIGNED, /* y */ /* 121 */ VI_YANK, /* y */
/* 122 */ ED_UNASSIGNED, /* z */ /* 122 */ ED_UNASSIGNED, /* z */
/* 123 */ ED_UNASSIGNED, /* { */ /* 123 */ ED_UNASSIGNED, /* { */
/* 124 */ ED_UNASSIGNED, /* | */ /* 124 */ VI_TO_COLUMN, /* | */
/* 125 */ ED_UNASSIGNED, /* } */ /* 125 */ ED_UNASSIGNED, /* } */
/* 126 */ VI_CHANGE_CASE, /* ~ */ /* 126 */ VI_CHANGE_CASE, /* ~ */
/* 127 */ ED_DELETE_PREV_CHAR, /* ^? */ /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */
@ -1127,7 +1122,7 @@ map_get_editor(EditLine *el, const char **editor)
* Print the function description for 1 key * Print the function description for 1 key
*/ */
private void private void
map_print_key(EditLine *el, el_action_t *map, char *in) map_print_key(EditLine *el, el_action_t *map, const char *in)
{ {
char outbuf[EL_BUFSIZ]; char outbuf[EL_BUFSIZ];
el_bindings_t *bp; el_bindings_t *bp;
@ -1240,14 +1235,14 @@ map_print_all_keys(EditLine *el)
* Add/remove/change bindings * Add/remove/change bindings
*/ */
protected int protected int
map_bind(EditLine *el, int argc, char **argv) map_bind(EditLine *el, int argc, const char **argv)
{ {
el_action_t *map; el_action_t *map;
int ntype, rem; int ntype, rem;
char *p; const char *p;
char inbuf[EL_BUFSIZ]; char inbuf[EL_BUFSIZ];
char outbuf[EL_BUFSIZ]; char outbuf[EL_BUFSIZ];
char *in = NULL; const char *in = NULL;
char *out = NULL; char *out = NULL;
el_bindings_t *bp; el_bindings_t *bp;
int cmd; int cmd;

10
map.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: map.h,v 1.6 2001/01/09 17:22:09 jdolecek Exp $ */ /* $NetBSD: map.h,v 1.8 2003/08/07 16:44:32 agc Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -67,7 +63,7 @@ typedef struct el_map_t {
#define MAP_EMACS 0 #define MAP_EMACS 0
#define MAP_VI 1 #define MAP_VI 1
protected int map_bind(EditLine *, int, char **); protected int map_bind(EditLine *, int, const char **);
protected int map_init(EditLine *); protected int map_init(EditLine *);
protected void map_end(EditLine *); protected void map_end(EditLine *);
protected void map_init_vi(EditLine *); protected void map_init_vi(EditLine *);

41
parse.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.14 2001/01/23 15:55:30 jdolecek Exp $ */ /* $NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,12 +32,12 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: parse.c,v 1.14 2001/01/23 15:55:30 jdolecek Exp $"); __RCSID("$NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
@ -58,19 +54,17 @@ __RCSID("$NetBSD: parse.c,v 1.14 2001/01/23 15:55:30 jdolecek Exp $");
* settc * settc
* setty * setty
*/ */
#include "sys.h"
#include "el.h" #include "el.h"
#include "tokenizer.h"
#include <stdlib.h> #include <stdlib.h>
private const struct { private const struct {
char *name; const char *name;
int (*func)(EditLine *, int, char **); int (*func)(EditLine *, int, const char **);
} cmds[] = { } cmds[] = {
{ "bind", map_bind }, { "bind", map_bind },
{ "echotc", term_echotc }, { "echotc", term_echotc },
{ "edit", el_editmode }, { "edit", el_editmode },
{ "history", hist_list }, { "history", hist_command },
{ "telltc", term_telltc }, { "telltc", term_telltc },
{ "settc", term_settc }, { "settc", term_settc },
{ "setty", tty_stty }, { "setty", tty_stty },
@ -84,12 +78,12 @@ private const struct {
protected int protected int
parse_line(EditLine *el, const char *line) parse_line(EditLine *el, const char *line)
{ {
char **argv; const char **argv;
int argc; int argc;
Tokenizer *tok; Tokenizer *tok;
tok = tok_init(NULL); tok = tok_init(NULL);
tok_line(tok, line, &argc, &argv); tok_str(tok, line, &argc, &argv);
argc = el_parse(el, argc, argv); argc = el_parse(el, argc, argv);
tok_end(tok); tok_end(tok);
return (argc); return (argc);
@ -100,9 +94,9 @@ parse_line(EditLine *el, const char *line)
* Command dispatcher * Command dispatcher
*/ */
public int public int
el_parse(EditLine *el, int argc, char *argv[]) el_parse(EditLine *el, int argc, const char *argv[])
{ {
char *ptr; const char *ptr;
int i; int i;
if (argc < 1) if (argc < 1)
@ -142,7 +136,7 @@ el_parse(EditLine *el, int argc, char *argv[])
* the appropriate character or -1 if the escape is not valid * the appropriate character or -1 if the escape is not valid
*/ */
protected int protected int
parse__escape(const char **const ptr) parse__escape(const char **ptr)
{ {
const char *p; const char *p;
int c; int c;
@ -207,7 +201,7 @@ parse__escape(const char **const ptr)
c = *p; c = *p;
break; break;
} }
} else if (*p == '^' && isalpha((unsigned char) p[1])) { } else if (*p == '^') {
p++; p++;
c = (*p == '?') ? '\177' : (*p & 0237); c = (*p == '?') ? '\177' : (*p & 0237);
} else } else
@ -215,6 +209,7 @@ parse__escape(const char **const ptr)
*ptr = ++p; *ptr = ++p;
return (c); return (c);
} }
/* parse__string(): /* parse__string():
* Parse the escapes from in and put the raw string out * Parse the escapes from in and put the raw string out
*/ */
@ -237,6 +232,14 @@ parse__string(char *out, const char *in)
*out++ = n; *out++ = n;
break; break;
case 'M':
if (in[1] == '-' && in[2] != '\0') {
*out++ = '\033';
in += 2;
break;
}
/*FALLTHROUGH*/
default: default:
*out++ = *in++; *out++ = *in++;
break; break;

10
parse.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.h,v 1.4 2000/09/04 22:06:31 lukem Exp $ */ /* $NetBSD: parse.h,v 1.6 2005/05/29 04:58:15 lukem Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -45,7 +41,7 @@
#define _h_el_parse #define _h_el_parse
protected int parse_line(EditLine *, const char *); protected int parse_line(EditLine *, const char *);
protected int parse__escape(const char ** const); protected int parse__escape(const char **);
protected char *parse__string(char *, const char *); protected char *parse__string(char *, const char *);
protected int parse_cmd(EditLine *, const char *); protected int parse_cmd(EditLine *, const char *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: prompt.c,v 1.8 2001/01/10 07:45:41 jdolecek Exp $ */ /* $NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,19 +32,18 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: prompt.c,v 1.8 2001/01/10 07:45:41 jdolecek Exp $"); __RCSID("$NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* prompt.c: Prompt printing functions * prompt.c: Prompt printing functions
*/ */
#include "sys.h"
#include <stdio.h> #include <stdio.h>
#include "el.h" #include "el.h"
@ -60,7 +55,7 @@ private char *prompt_default_r(EditLine *);
*/ */
private char * private char *
/*ARGSUSED*/ /*ARGSUSED*/
prompt_default(EditLine *el) prompt_default(EditLine *el __attribute__((__unused__)))
{ {
static char a[3] = {'?', ' ', '\0'}; static char a[3] = {'?', ' ', '\0'};
@ -73,7 +68,7 @@ prompt_default(EditLine *el)
*/ */
private char * private char *
/*ARGSUSED*/ /*ARGSUSED*/
prompt_default_r(EditLine *el) prompt_default_r(EditLine *el __attribute__((__unused__)))
{ {
static char a[1] = {'\0'}; static char a[1] = {'\0'};
@ -128,7 +123,7 @@ prompt_init(EditLine *el)
*/ */
protected void protected void
/*ARGSUSED*/ /*ARGSUSED*/
prompt_end(EditLine *el) prompt_end(EditLine *el __attribute__((__unused__)))
{ {
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: prompt.h,v 1.5 2000/09/04 22:06:31 lukem Exp $ */ /* $NetBSD: prompt.h,v 1.6 2003/08/07 16:44:32 agc Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *

177
read.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: read.c,v 1.20 2001/09/27 19:29:50 christos Exp $ */ /* $NetBSD: read.c,v 1.39 2005/08/02 12:11:14 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,12 +32,12 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: read.c,v 1.20 2001/09/27 19:29:50 christos Exp $"); __RCSID("$NetBSD: read.c,v 1.39 2005/08/02 12:11:14 christos Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
@ -49,8 +45,8 @@ __RCSID("$NetBSD: read.c,v 1.20 2001/09/27 19:29:50 christos Exp $");
* read.c: Clean this junk up! This is horrible code. * read.c: Clean this junk up! This is horrible code.
* Terminal read functions * Terminal read functions
*/ */
#include "sys.h"
#include <errno.h> #include <errno.h>
#include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include "el.h" #include "el.h"
@ -98,6 +94,10 @@ el_read_getfn(EditLine *el)
} }
#ifndef MIN
#define MIN(A,B) ((A) < (B) ? (A) : (B))
#endif
#ifdef DEBUG_EDIT #ifdef DEBUG_EDIT
private void private void
read_debug(EditLine *el) read_debug(EditLine *el)
@ -122,7 +122,7 @@ read_debug(EditLine *el)
*/ */
/* ARGSUSED */ /* ARGSUSED */
private int private int
read__fixio(int fd, int e) read__fixio(int fd __attribute__((__unused__)), int e)
{ {
switch (e) { switch (e) {
@ -187,10 +187,6 @@ read_preread(EditLine *el)
{ {
int chrs = 0; int chrs = 0;
if (el->el_chared.c_macro.nline) {
el_free((ptr_t) el->el_chared.c_macro.nline);
el->el_chared.c_macro.nline = NULL;
}
if (el->el_tty.t_mode == ED_IO) if (el->el_tty.t_mode == ED_IO)
return (0); return (0);
@ -203,8 +199,7 @@ read_preread(EditLine *el)
(size_t) MIN(chrs, EL_BUFSIZ - 1)); (size_t) MIN(chrs, EL_BUFSIZ - 1));
if (chrs > 0) { if (chrs > 0) {
buf[chrs] = '\0'; buf[chrs] = '\0';
el->el_chared.c_macro.nline = strdup(buf); el_push(el, buf);
el_push(el, el->el_chared.c_macro.nline);
} }
} }
#endif /* FIONREAD */ #endif /* FIONREAD */
@ -217,18 +212,18 @@ read_preread(EditLine *el)
* Push a macro * Push a macro
*/ */
public void public void
el_push(EditLine *el, const char *str) el_push(EditLine *el, char *str)
{ {
c_macro_t *ma = &el->el_chared.c_macro; c_macro_t *ma = &el->el_chared.c_macro;
if (str != NULL && ma->level + 1 < EL_MAXMACRO) { if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
ma->level++; ma->level++;
/* LINTED const cast */ if ((ma->macro[ma->level] = el_strdup(str)) != NULL)
ma->macro[ma->level] = (char *) str; return;
} else { ma->level--;
term_beep(el);
term__flush();
} }
term_beep(el);
term__flush();
} }
@ -238,10 +233,10 @@ el_push(EditLine *el, const char *str)
private int private int
read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
{ {
el_action_t cmd = ED_UNASSIGNED; el_action_t cmd;
int num; int num;
while (cmd == ED_UNASSIGNED || cmd == ED_SEQUENCE_LEAD_IN) { do {
if ((num = el_getc(el, ch)) != 1) /* if EOF or error */ if ((num = el_getc(el, ch)) != 1) /* if EOF or error */
return (num); return (num);
@ -280,7 +275,7 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
} }
if (el->el_map.alt == NULL) if (el->el_map.alt == NULL)
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
} } while (cmd == ED_SEQUENCE_LEAD_IN);
*cmdnum = cmd; *cmdnum = cmd;
return (OKCMD); return (OKCMD);
} }
@ -325,14 +320,16 @@ el_getc(EditLine *el, char *cp)
if (ma->level < 0) if (ma->level < 0)
break; break;
if (*ma->macro[ma->level] == 0) { if (ma->macro[ma->level][ma->offset] == '\0') {
ma->level--; el_free(ma->macro[ma->level--]);
ma->offset = 0;
continue; continue;
} }
*cp = *ma->macro[ma->level]++ & 0377; *cp = ma->macro[ma->level][ma->offset++] & 0377;
if (*ma->macro[ma->level] == 0) { /* Needed for QuoteMode if (ma->macro[ma->level][ma->offset] == '\0') {
* On */ /* Needed for QuoteMode On */
ma->level--; el_free(ma->macro[ma->level--]);
ma->offset = 0;
} }
return (1); return (1);
} }
@ -353,6 +350,35 @@ el_getc(EditLine *el, char *cp)
return (num_read); return (num_read);
} }
protected void
read_prepare(EditLine *el)
{
if (el->el_flags & HANDLE_SIGNALS)
sig_set(el);
if (el->el_flags & NO_TTY)
return;
if ((el->el_flags & (UNBUFFERED|EDIT_DISABLED)) == UNBUFFERED)
tty_rawmode(el);
/* This is relatively cheap, and things go terribly wrong if
we have the wrong size. */
el_resize(el);
re_clear_display(el); /* reset the display stuff */
ch_reset(el, 0);
re_refresh(el); /* print the prompt */
if (el->el_flags & UNBUFFERED)
term__flush();
}
protected void
read_finish(EditLine *el)
{
if ((el->el_flags & UNBUFFERED) == 0)
(void) tty_cookedmode(el);
if (el->el_flags & HANDLE_SIGNALS)
sig_clr(el);
}
public const char * public const char *
el_gets(EditLine *el, int *nread) el_gets(EditLine *el, int *nread)
@ -361,13 +387,11 @@ el_gets(EditLine *el, int *nread)
el_action_t cmdnum = 0; el_action_t cmdnum = 0;
int num; /* how many chars we have read at NL */ int num; /* how many chars we have read at NL */
char ch; char ch;
int crlf = 0;
#ifdef FIONREAD #ifdef FIONREAD
c_macro_t *ma = &el->el_chared.c_macro; c_macro_t *ma = &el->el_chared.c_macro;
#endif /* FIONREAD */ #endif /* FIONREAD */
if (el->el_flags & HANDLE_SIGNALS)
sig_set(el);
if (el->el_flags & NO_TTY) { if (el->el_flags & NO_TTY) {
char *cp = el->el_line.buffer; char *cp = el->el_line.buffer;
size_t idx; size_t idx;
@ -381,6 +405,8 @@ el_gets(EditLine *el, int *nread)
cp = &el->el_line.buffer[idx]; cp = &el->el_line.buffer[idx];
} }
cp++; cp++;
if (el->el_flags & UNBUFFERED)
break;
if (cp[-1] == '\r' || cp[-1] == '\n') if (cp[-1] == '\r' || cp[-1] == '\n')
break; break;
} }
@ -391,8 +417,7 @@ el_gets(EditLine *el, int *nread)
*nread = el->el_line.cursor - el->el_line.buffer; *nread = el->el_line.cursor - el->el_line.buffer;
return (el->el_line.buffer); return (el->el_line.buffer);
} }
re_clear_display(el); /* reset the display stuff */
ch_reset(el);
#ifdef FIONREAD #ifdef FIONREAD
if (el->el_tty.t_mode == EX_IO && ma->level < 0) { if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
@ -409,11 +434,16 @@ el_gets(EditLine *el, int *nread)
} }
#endif /* FIONREAD */ #endif /* FIONREAD */
re_refresh(el); /* print the prompt */ if ((el->el_flags & UNBUFFERED) == 0)
read_prepare(el);
if (el->el_flags & EDIT_DISABLED) { if (el->el_flags & EDIT_DISABLED) {
char *cp = el->el_line.buffer; char *cp;
size_t idx; size_t idx;
if ((el->el_flags & UNBUFFERED) == 0)
cp = el->el_line.buffer;
else
cp = el->el_line.lastchar;
term__flush(); term__flush();
@ -425,8 +455,13 @@ el_gets(EditLine *el, int *nread)
break; break;
cp = &el->el_line.buffer[idx]; cp = &el->el_line.buffer[idx];
} }
if (*cp == 4) /* ought to be stty eof */
break;
cp++; cp++;
if (cp[-1] == '\r' || cp[-1] == '\n') crlf = cp[-1] == '\r' || cp[-1] == '\n';
if (el->el_flags & UNBUFFERED)
break;
if (crlf)
break; break;
} }
@ -436,6 +471,7 @@ el_gets(EditLine *el, int *nread)
*nread = el->el_line.cursor - el->el_line.buffer; *nread = el->el_line.cursor - el->el_line.buffer;
return (el->el_line.buffer); return (el->el_line.buffer);
} }
for (num = OKCMD; num == OKCMD;) { /* while still editing this for (num = OKCMD; num == OKCMD;) { /* while still editing this
* line */ * line */
#ifdef DEBUG_EDIT #ifdef DEBUG_EDIT
@ -449,7 +485,7 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
break; break;
} }
if ((int) cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ if ((unsigned int)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
#ifdef DEBUG_EDIT #ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"ERROR: illegal command from key 0%o\r\n", ch); "ERROR: illegal command from key 0%o\r\n", ch);
@ -471,7 +507,24 @@ el_gets(EditLine *el, int *nread)
"Error command = %d\n", cmdnum); "Error command = %d\n", cmdnum);
} }
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
/* vi redo needs these way down the levels... */
el->el_state.thiscmd = cmdnum;
el->el_state.thisch = ch;
if (el->el_map.type == MAP_VI &&
el->el_map.current == el->el_map.key &&
el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
if (cmdnum == VI_DELETE_PREV_CHAR &&
el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
&& isprint((unsigned char)el->el_chared.c_redo.pos[-1]))
el->el_chared.c_redo.pos--;
else
*el->el_chared.c_redo.pos++ = ch;
}
retval = (*el->el_map.func[cmdnum]) (el, ch); 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 */ /* save the last command here */
el->el_state.lastcmd = cmdnum; el->el_state.lastcmd = cmdnum;
@ -479,8 +532,6 @@ el_gets(EditLine *el, int *nread)
/* use any return value */ /* use any return value */
switch (retval) { switch (retval) {
case CC_CURSOR: case CC_CURSOR:
el->el_state.argument = 1;
el->el_state.doingarg = 0;
re_refresh_cursor(el); re_refresh_cursor(el);
break; break;
@ -490,29 +541,29 @@ el_gets(EditLine *el, int *nread)
/* FALLTHROUGH */ /* FALLTHROUGH */
case CC_REFRESH: case CC_REFRESH:
el->el_state.argument = 1;
el->el_state.doingarg = 0;
re_refresh(el); re_refresh(el);
break; break;
case CC_REFRESH_BEEP: case CC_REFRESH_BEEP:
el->el_state.argument = 1;
el->el_state.doingarg = 0;
re_refresh(el); re_refresh(el);
term_beep(el); term_beep(el);
break; break;
case CC_NORM: /* normal char */ case CC_NORM: /* normal char */
el->el_state.argument = 1;
el->el_state.doingarg = 0;
break; break;
case CC_ARGHACK: /* Suggested by Rich Salz */ case CC_ARGHACK: /* Suggested by Rich Salz */
/* <rsalz@pineapple.bbn.com> */ /* <rsalz@pineapple.bbn.com> */
break; /* keep going... */ continue; /* keep going... */
case CC_EOF: /* end of file typed */ case CC_EOF: /* end of file typed */
num = 0; if ((el->el_flags & UNBUFFERED) == 0)
num = 0;
else if (num == -1) {
*el->el_line.lastchar++ = CONTROL('d');
el->el_line.cursor = el->el_line.lastchar;
num = 1;
}
break; break;
case CC_NEWLINE: /* normal end of line */ case CC_NEWLINE: /* normal end of line */
@ -526,10 +577,8 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
/* put (real) cursor in a known place */ /* put (real) cursor in a known place */
re_clear_display(el); /* reset the display stuff */ re_clear_display(el); /* reset the display stuff */
ch_reset(el); /* reset the input pointers */ ch_reset(el, 1); /* reset the input pointers */
re_refresh(el); /* print the prompt again */ re_refresh(el); /* print the prompt again */
el->el_state.argument = 1;
el->el_state.doingarg = 0;
break; break;
case CC_ERROR: case CC_ERROR:
@ -538,20 +587,26 @@ el_gets(EditLine *el, int *nread)
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"*** editor ERROR ***\r\n\n"); "*** editor ERROR ***\r\n\n");
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
el->el_state.argument = 1;
el->el_state.doingarg = 0;
term_beep(el); term_beep(el);
term__flush(); term__flush();
break; break;
} }
el->el_state.argument = 1;
el->el_state.doingarg = 0;
el->el_chared.c_vcmd.action = NOP;
if (el->el_flags & UNBUFFERED)
break;
} }
/* make sure the tty is set up correctly */
(void) tty_cookedmode(el);
term__flush(); /* flush any buffered output */ term__flush(); /* flush any buffered output */
if (el->el_flags & HANDLE_SIGNALS) /* make sure the tty is set up correctly */
sig_clr(el); if ((el->el_flags & UNBUFFERED) == 0) {
if (nread) read_finish(el);
*nread = num; if (nread)
*nread = num;
} else {
if (nread)
*nread = el->el_line.lastchar - el->el_line.buffer;
}
return (num ? el->el_line.buffer : NULL); return (num ? el->el_line.buffer : NULL);
} }

4
read.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: read.h,v 1.1 2001/09/27 19:29:50 christos Exp $ */ /* $NetBSD: read.h,v 1.4 2004/02/27 14:52:18 christos Exp $ */
/*- /*-
* Copyright (c) 2001 The NetBSD Foundation, Inc. * Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -49,6 +49,8 @@ typedef struct el_read_t {
} el_read_t; } el_read_t;
protected int read_init(EditLine *); 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 int el_read_setfn(EditLine *, el_rfunc_t);
protected el_rfunc_t el_read_getfn(EditLine *); protected el_rfunc_t el_read_getfn(EditLine *);

1625
readline.c

File diff suppressed because it is too large Load Diff

View File

@ -1,13 +1,13 @@
# $NetBSD: Makefile,v 1.4 2001/05/16 07:09:26 enami Exp $ # $NetBSD: Makefile,v 1.7 2003/08/03 09:23:15 lukem Exp $
.PATH: ${CURDIR}/.. NOOBJ= # defined
.include <bsd.own.mk>
.PATH: ${NETBSDSRCDIR}/lib/libedit
INCS= readline.h INCS= readline.h
INCSDIR= /usr/include/readline INCSDIR= /usr/include/readline
SYMLINKS= readline.h ${INCSDIR}/history.h INCSYMLINKS= readline.h ${INCSDIR}/history.h
MKOBJ= no
incinstall:: linksinstall
.include <bsd.prog.mk> .include <bsd.prog.mk>

View File

@ -1,4 +1,4 @@
/* $NetBSD: readline.h,v 1.1 2001/01/05 21:15:50 jdolecek Exp $ */ /* $NetBSD: readline.h,v 1.17 2005/07/14 15:00:58 christos Exp $ */
/*- /*-
* Copyright (c) 1997 The NetBSD Foundation, Inc. * Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -36,7 +36,7 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _READLINE_H_ #ifndef _READLINE_H_
#define _READLINE_H_ #define _READLINE_H_
#include <sys/types.h> #include <sys/types.h>
@ -45,6 +45,7 @@
/* typedefs */ /* typedefs */
typedef int Function(const char *, int); typedef int Function(const char *, int);
typedef void VFunction(void); typedef void VFunction(void);
typedef void VCPFunction(char *);
typedef char *CPFunction(const char *, int); typedef char *CPFunction(const char *, int);
typedef char **CPPFunction(const char *, int, int); typedef char **CPPFunction(const char *, int, int);
@ -53,8 +54,42 @@ typedef struct _hist_entry {
const char *data; const char *data;
} HIST_ENTRY; } HIST_ENTRY;
typedef struct _keymap_entry {
char type;
#define ISFUNC 0
#define ISKMAP 1
#define ISMACR 2
Function *function;
} KEYMAP_ENTRY;
#define KEYMAP_SIZE 256
typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE];
typedef KEYMAP_ENTRY *Keymap;
#define control_character_threshold 0x20
#define control_character_bit 0x40
#ifndef CTRL
#include <sys/ioctl.h>
#if !defined(__sun__) && !defined(__hpux__)
#include <sys/ttydefaults.h>
#endif
#ifndef CTRL
#define CTRL(c) ((c) & 037)
#endif
#endif
#ifndef UNCTRL
#define UNCTRL(c) (((c) - 'a' + 'A')|control_character_bit)
#endif
#define RUBOUT 0x7f
#define ABORT_CHAR CTRL('G')
/* global variables used by readline enabled applications */ /* global variables used by readline enabled applications */
__BEGIN_DECLS #ifdef __cplusplus
extern "C" {
#endif
extern const char *rl_library_version; extern const char *rl_library_version;
extern char *rl_readline_name; extern char *rl_readline_name;
extern FILE *rl_instream; extern FILE *rl_instream;
@ -66,12 +101,32 @@ extern int max_input_history;
extern char *rl_basic_word_break_characters; extern char *rl_basic_word_break_characters;
extern char *rl_completer_word_break_characters; extern char *rl_completer_word_break_characters;
extern char *rl_completer_quote_characters; extern char *rl_completer_quote_characters;
extern CPFunction *rl_completion_entry_function; extern Function *rl_completion_entry_function;
extern CPPFunction *rl_attempted_completion_function; extern CPPFunction *rl_attempted_completion_function;
extern int rl_attempted_completion_over;
extern int rl_completion_type; extern int rl_completion_type;
extern int rl_completion_query_items; extern int rl_completion_query_items;
extern char *rl_special_prefixes; extern char *rl_special_prefixes;
extern int rl_completion_append_character; extern int rl_completion_append_character;
extern int rl_inhibit_completion;
extern Function *rl_pre_input_hook;
extern Function *rl_startup_hook;
extern char *rl_terminal_name;
extern int rl_already_prompted;
extern char *rl_prompt;
/*
* The following is not implemented
*/
extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
emacs_meta_keymap,
emacs_ctlx_keymap;
extern int rl_filename_completion_desired;
extern int rl_ignore_completion_duplicates;
extern Function *rl_getc_function;
extern VFunction *rl_redisplay_function;
extern VFunction *rl_completion_display_matches_hook;
extern VFunction *rl_prep_term_function;
extern VFunction *rl_deprep_term_function;
/* supported functions */ /* supported functions */
char *readline(const char *); char *readline(const char *);
@ -86,6 +141,7 @@ int history_is_stifled(void);
int where_history(void); int where_history(void);
HIST_ENTRY *current_history(void); HIST_ENTRY *current_history(void);
HIST_ENTRY *history_get(int); HIST_ENTRY *history_get(int);
HIST_ENTRY *remove_history(int);
int history_total_bytes(void); int history_total_bytes(void);
int history_set_pos(int); int history_set_pos(int);
HIST_ENTRY *previous_history(void); HIST_ENTRY *previous_history(void);
@ -97,6 +153,8 @@ int read_history(const char *);
int write_history(const char *); int write_history(const char *);
int history_expand(char *, char **); int history_expand(char *, char **);
char **history_tokenize(const char *); char **history_tokenize(const char *);
const char *get_history_event(const char *, int *, int);
char *history_arg_extract(int, int, const char *);
char *tilde_expand(char *); char *tilde_expand(char *);
char *filename_completion_function(const char *, int); char *filename_completion_function(const char *, int);
@ -109,6 +167,29 @@ void rl_display_match_list(char **, int, int);
int rl_insert(int, int); int rl_insert(int, int);
void rl_reset_terminal(const char *); void rl_reset_terminal(const char *);
int rl_bind_key(int, int (*)(int, int)); int rl_bind_key(int, int (*)(int, int));
__END_DECLS int rl_newline(int, int);
void rl_callback_read_char(void);
void rl_callback_handler_install(const char *, VCPFunction *);
void rl_callback_handler_remove(void);
void rl_redisplay(void);
int rl_get_previous_history(int, int);
void rl_prep_terminal(int);
void rl_deprep_terminal(void);
int rl_read_init_file(const char *);
int rl_parse_and_bind(const char *);
int rl_variable_bind(const char *, const char *);
void rl_stuff_char(int);
int rl_add_defun(const char *, Function *, int);
/*
* The following are not implemented
*/
Keymap rl_get_keymap(void);
Keymap rl_make_bare_keymap(void);
int rl_generic_bind(int, const char *, const char *, Keymap);
int rl_bind_key_in_map(int, Function *, Keymap);
#ifdef __cplusplus
}
#endif
#endif /* _READLINE_H_ */ #endif /* _READLINE_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: refresh.c,v 1.17 2001/04/13 00:53:11 lukem Exp $ */ /* $NetBSD: refresh.c,v 1.26 2003/08/07 16:44:33 agc Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,19 +32,18 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: refresh.c,v 1.17 2001/04/13 00:53:11 lukem Exp $"); __RCSID("$NetBSD: refresh.c,v 1.26 2003/08/07 16:44:33 agc Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* refresh.c: Lower level screen refreshing functions * refresh.c: Lower level screen refreshing functions
*/ */
#include "sys.h"
#include <stdio.h> #include <stdio.h>
#include <ctype.h> #include <ctype.h>
#include <unistd.h> #include <unistd.h>
@ -62,24 +57,24 @@ private void re_insert (EditLine *, char *, int, int, char *, int);
private void re_delete(EditLine *, char *, int, int, int); private void re_delete(EditLine *, char *, int, int, int);
private void re_fastputc(EditLine *, int); private void re_fastputc(EditLine *, int);
private void re__strncopy(char *, char *, size_t); private void re__strncopy(char *, char *, size_t);
private void re__copy_and_pad(char *, char *, size_t); private void re__copy_and_pad(char *, const char *, size_t);
#ifdef DEBUG_REFRESH #ifdef DEBUG_REFRESH
private void re_printstr(EditLine *, char *, char *, char *); private void re_printstr(EditLine *, const char *, char *, char *);
#define __F el->el_errfile #define __F el->el_errfile
#define ELRE_ASSERT(a, b, c) do \ #define ELRE_ASSERT(a, b, c) do \
if (a) { \ if (/*CONSTCOND*/ a) { \
(void) fprintf b; \ (void) fprintf b; \
c; \ c; \
} \ } \
while (0) while (/*CONSTCOND*/0)
#define ELRE_DEBUG(a, b) ELRE_ASSERT(a,b,;) #define ELRE_DEBUG(a, b) ELRE_ASSERT(a,b,;)
/* re_printstr(): /* re_printstr():
* Print a string on the debugging pty * Print a string on the debugging pty
*/ */
private void private void
re_printstr(EditLine *el, char *str, char *f, char *t) re_printstr(EditLine *el, const char *str, char *f, char *t)
{ {
ELRE_DEBUG(1, (__F, "%s:\"", str)); ELRE_DEBUG(1, (__F, "%s:\"", str));
@ -210,6 +205,14 @@ re_refresh(EditLine *el)
el->el_refresh.r_cursor.h = 0; el->el_refresh.r_cursor.h = 0;
el->el_refresh.r_cursor.v = 0; el->el_refresh.r_cursor.v = 0;
if (el->el_line.cursor >= el->el_line.lastchar) {
if (el->el_map.current == el->el_map.alt
&& el->el_line.lastchar != el->el_line.buffer)
el->el_line.cursor = el->el_line.lastchar - 1;
else
el->el_line.cursor = el->el_line.lastchar;
}
cur.h = -1; /* set flag in case I'm not set */ cur.h = -1; /* set flag in case I'm not set */
cur.v = 0; cur.v = 0;
@ -319,7 +322,6 @@ re_goto_bottom(EditLine *el)
{ {
term_move_to_line(el, el->el_refresh.r_oldcv); term_move_to_line(el, el->el_refresh.r_oldcv);
term__putc('\r');
term__putc('\n'); term__putc('\n');
re_clear_display(el); re_clear_display(el);
term__flush(); term__flush();
@ -332,7 +334,8 @@ re_goto_bottom(EditLine *el)
*/ */
private void private void
/*ARGSUSED*/ /*ARGSUSED*/
re_insert(EditLine *el, char *d, int dat, int dlen, char *s, int num) re_insert(EditLine *el __attribute__((__unused__)),
char *d, int dat, int dlen, char *s, int num)
{ {
char *a, *b; char *a, *b;
@ -375,7 +378,8 @@ re_insert(EditLine *el, char *d, int dat, int dlen, char *s, int num)
*/ */
private void private void
/*ARGSUSED*/ /*ARGSUSED*/
re_delete(EditLine *el, char *d, int dat, int dlen, int num) re_delete(EditLine *el __attribute__((__unused__)),
char *d, int dat, int dlen, int num)
{ {
char *a, *b; char *a, *b;
@ -908,9 +912,9 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* Copy string and pad with spaces * Copy string and pad with spaces
*/ */
private void private void
re__copy_and_pad(char *dst, char *src, size_t width) re__copy_and_pad(char *dst, const char *src, size_t width)
{ {
int i; size_t i;
for (i = 0; i < width; i++) { for (i = 0; i < width; i++) {
if (*src == '\0') if (*src == '\0')
@ -934,6 +938,14 @@ re_refresh_cursor(EditLine *el)
char *cp, c; char *cp, c;
int h, v, th; int h, v, th;
if (el->el_line.cursor >= el->el_line.lastchar) {
if (el->el_map.current == el->el_map.alt
&& el->el_line.lastchar != el->el_line.buffer)
el->el_line.cursor = el->el_line.lastchar - 1;
else
el->el_line.cursor = el->el_line.lastchar;
}
/* first we must find where the cursor is... */ /* first we must find where the cursor is... */
h = el->el_prompt.p_pos.h; h = el->el_prompt.p_pos.h;
v = el->el_prompt.p_pos.v; v = el->el_prompt.p_pos.v;
@ -1056,8 +1068,8 @@ re_fastaddc(EditLine *el)
re_fastputc(el, c); re_fastputc(el, c);
} else { } else {
re_fastputc(el, '\\'); re_fastputc(el, '\\');
re_fastputc(el, (int) ((((unsigned int) c >> 6) & 7) + '0')); re_fastputc(el, (int)(((((unsigned int)c) >> 6) & 3) + '0'));
re_fastputc(el, (int) ((((unsigned int) c >> 3) & 7) + '0')); re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0'));
re_fastputc(el, (c & 7) + '0'); re_fastputc(el, (c & 7) + '0');
} }
term__flush(); term__flush();

View File

@ -1,4 +1,4 @@
/* $NetBSD: refresh.h,v 1.4 2001/01/10 07:45:42 jdolecek Exp $ */ /* $NetBSD: refresh.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *

207
search.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: search.c,v 1.11 2001/01/23 15:55:31 jdolecek Exp $ */ /* $NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,19 +32,18 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: search.c,v 1.11 2001/01/23 15:55:31 jdolecek Exp $"); __RCSID("$NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* search.c: History and character search functions * search.c: History and character search functions
*/ */
#include "sys.h"
#include <stdlib.h> #include <stdlib.h>
#if defined(REGEX) #if defined(REGEX)
#include <regex.h> #include <regex.h>
@ -77,7 +72,8 @@ search_init(EditLine *el)
el->el_search.patlen = 0; el->el_search.patlen = 0;
el->el_search.patdir = -1; el->el_search.patdir = -1;
el->el_search.chacha = '\0'; el->el_search.chacha = '\0';
el->el_search.chadir = -1; el->el_search.chadir = CHAR_FWD;
el->el_search.chatflg = 0;
return (0); return (0);
} }
@ -226,8 +222,11 @@ ce_inc_search(EditLine *el, int dir)
if (el->el_search.patlen == 0) { /* first round */ if (el->el_search.patlen == 0) { /* first round */
pchar = ':'; pchar = ':';
#ifdef ANCHOR #ifdef ANCHOR
#define LEN 2
el->el_search.patbuf[el->el_search.patlen++] = '.'; el->el_search.patbuf[el->el_search.patlen++] = '.';
el->el_search.patbuf[el->el_search.patlen++] = '*'; el->el_search.patbuf[el->el_search.patlen++] = '*';
#else
#define LEN 0
#endif #endif
} }
done = redo = 0; done = redo = 0;
@ -236,7 +235,7 @@ ce_inc_search(EditLine *el, int dir)
*cp; *el->el_line.lastchar++ = *cp++) *cp; *el->el_line.lastchar++ = *cp++)
continue; continue;
*el->el_line.lastchar++ = pchar; *el->el_line.lastchar++ = pchar;
for (cp = &el->el_search.patbuf[1]; for (cp = &el->el_search.patbuf[LEN];
cp < &el->el_search.patbuf[el->el_search.patlen]; cp < &el->el_search.patbuf[el->el_search.patlen];
*el->el_line.lastchar++ = *cp++) *el->el_line.lastchar++ = *cp++)
continue; continue;
@ -249,7 +248,7 @@ ce_inc_search(EditLine *el, int dir)
switch (el->el_map.current[(unsigned char) ch]) { switch (el->el_map.current[(unsigned char) ch]) {
case ED_INSERT: case ED_INSERT:
case ED_DIGIT: case ED_DIGIT:
if (el->el_search.patlen > EL_BUFSIZ - 3) if (el->el_search.patlen >= EL_BUFSIZ - LEN)
term_beep(el); term_beep(el);
else { else {
el->el_search.patbuf[el->el_search.patlen++] = el->el_search.patbuf[el->el_search.patlen++] =
@ -270,8 +269,9 @@ ce_inc_search(EditLine *el, int dir)
redo++; redo++;
break; break;
case EM_DELETE_PREV_CHAR:
case ED_DELETE_PREV_CHAR: case ED_DELETE_PREV_CHAR:
if (el->el_search.patlen > 1) if (el->el_search.patlen > LEN)
done++; done++;
else else
term_beep(el); term_beep(el);
@ -286,17 +286,18 @@ ce_inc_search(EditLine *el, int dir)
case 0027: /* ^W: Append word */ case 0027: /* ^W: Append word */
/* No can do if globbing characters in pattern */ /* No can do if globbing characters in pattern */
for (cp = &el->el_search.patbuf[1];; cp++) for (cp = &el->el_search.patbuf[LEN];; cp++)
if (cp >= &el->el_search.patbuf[el->el_search.patlen]) { if (cp >= &el->el_search.patbuf[
el->el_search.patlen]) {
el->el_line.cursor += el->el_line.cursor +=
el->el_search.patlen - 1; el->el_search.patlen - LEN - 1;
cp = c__next_word(el->el_line.cursor, cp = c__next_word(el->el_line.cursor,
el->el_line.lastchar, 1, el->el_line.lastchar, 1,
ce__isword); ce__isword);
while (el->el_line.cursor < cp && while (el->el_line.cursor < cp &&
*el->el_line.cursor != '\n') { *el->el_line.cursor != '\n') {
if (el->el_search.patlen > if (el->el_search.patlen >=
EL_BUFSIZ - 3) { EL_BUFSIZ - LEN) {
term_beep(el); term_beep(el);
break; break;
} }
@ -338,13 +339,13 @@ ce_inc_search(EditLine *el, int dir)
/* Can't search if unmatched '[' */ /* Can't search if unmatched '[' */
for (cp = &el->el_search.patbuf[el->el_search.patlen-1], for (cp = &el->el_search.patbuf[el->el_search.patlen-1],
ch = ']'; ch = ']';
cp > el->el_search.patbuf; cp >= &el->el_search.patbuf[LEN];
cp--) cp--)
if (*cp == '[' || *cp == ']') { if (*cp == '[' || *cp == ']') {
ch = *cp; ch = *cp;
break; break;
} }
if (el->el_search.patlen > 1 && ch != '[') { if (el->el_search.patlen > LEN && ch != '[') {
if (redo && newdir == dir) { if (redo && newdir == dir) {
if (pchar == '?') { /* wrap around */ if (pchar == '?') { /* wrap around */
el->el_history.eventno = el->el_history.eventno =
@ -374,9 +375,8 @@ ce_inc_search(EditLine *el, int dir)
'\0'; '\0';
if (el->el_line.cursor < el->el_line.buffer || if (el->el_line.cursor < el->el_line.buffer ||
el->el_line.cursor > el->el_line.lastchar || el->el_line.cursor > el->el_line.lastchar ||
(ret = ce_search_line(el, (ret = ce_search_line(el, newdir))
&el->el_search.patbuf[1], == CC_ERROR) {
newdir)) == CC_ERROR) {
/* avoid c_setpat */ /* avoid c_setpat */
el->el_state.lastcmd = el->el_state.lastcmd =
(el_action_t) newdir; (el_action_t) newdir;
@ -389,11 +389,11 @@ ce_inc_search(EditLine *el, int dir)
el->el_line.lastchar : el->el_line.lastchar :
el->el_line.buffer; el->el_line.buffer;
(void) ce_search_line(el, (void) ce_search_line(el,
&el->el_search.patbuf[1],
newdir); newdir);
} }
} }
el->el_search.patbuf[--el->el_search.patlen] = el->el_search.patlen -= LEN;
el->el_search.patbuf[el->el_search.patlen] =
'\0'; '\0';
if (ret == CC_ERROR) { if (ret == CC_ERROR) {
term_beep(el); term_beep(el);
@ -449,29 +449,20 @@ cv_search(EditLine *el, int dir)
char tmpbuf[EL_BUFSIZ]; char tmpbuf[EL_BUFSIZ];
int tmplen; int tmplen;
tmplen = 0;
#ifdef ANCHOR #ifdef ANCHOR
tmpbuf[tmplen++] = '.'; tmpbuf[0] = '.';
tmpbuf[tmplen++] = '*'; tmpbuf[1] = '*';
#endif #endif
tmplen = LEN;
el->el_line.buffer[0] = '\0';
el->el_line.lastchar = el->el_line.buffer;
el->el_line.cursor = el->el_line.buffer;
el->el_search.patdir = dir; el->el_search.patdir = dir;
c_insert(el, 2); /* prompt + '\n' */ tmplen = c_gets(el, &tmpbuf[LEN],
*el->el_line.cursor++ = '\n'; dir == ED_SEARCH_PREV_HISTORY ? "\n/" : "\n?" );
*el->el_line.cursor++ = dir == ED_SEARCH_PREV_HISTORY ? '/' : '?'; if (tmplen == -1)
re_refresh(el); return CC_REFRESH;
#ifdef ANCHOR tmplen += LEN;
#define LEN 2
#else
#define LEN 0
#endif
tmplen = c_gets(el, &tmpbuf[LEN]) + LEN;
ch = tmpbuf[tmplen]; ch = tmpbuf[tmplen];
tmpbuf[tmplen] = '\0'; tmpbuf[tmplen] = '\0';
@ -480,9 +471,6 @@ cv_search(EditLine *el, int dir)
* Use the old pattern, but wild-card it. * Use the old pattern, but wild-card it.
*/ */
if (el->el_search.patlen == 0) { if (el->el_search.patlen == 0) {
el->el_line.buffer[0] = '\0';
el->el_line.lastchar = el->el_line.buffer;
el->el_line.cursor = el->el_line.buffer;
re_refresh(el); re_refresh(el);
return (CC_ERROR); return (CC_ERROR);
} }
@ -513,19 +501,15 @@ cv_search(EditLine *el, int dir)
el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */ el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */
el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer; el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer;
if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) : if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) :
ed_search_next_history(el, 0)) == CC_ERROR) { ed_search_next_history(el, 0)) == CC_ERROR) {
re_refresh(el); re_refresh(el);
return (CC_ERROR); return (CC_ERROR);
} else {
if (ch == 0033) {
re_refresh(el);
*el->el_line.lastchar++ = '\n';
*el->el_line.lastchar = '\0';
re_goto_bottom(el);
return (CC_NEWLINE);
} else
return (CC_REFRESH);
} }
if (ch == 0033) {
re_refresh(el);
return ed_newline(el, 0);
}
return (CC_REFRESH);
} }
@ -533,24 +517,39 @@ cv_search(EditLine *el, int dir)
* Look for a pattern inside a line * Look for a pattern inside a line
*/ */
protected el_action_t protected el_action_t
ce_search_line(EditLine *el, char *pattern, int dir) ce_search_line(EditLine *el, int dir)
{ {
char *cp; char *cp = el->el_line.cursor;
char *pattern = el->el_search.patbuf;
char oc, *ocp;
#ifdef ANCHOR
ocp = &pattern[1];
oc = *ocp;
*ocp = '^';
#else
ocp = pattern;
oc = *ocp;
#endif
if (dir == ED_SEARCH_PREV_HISTORY) { if (dir == ED_SEARCH_PREV_HISTORY) {
for (cp = el->el_line.cursor; cp >= el->el_line.buffer; cp--) for (; cp >= el->el_line.buffer; cp--) {
if (el_match(cp, pattern)) { if (el_match(cp, ocp)) {
*ocp = oc;
el->el_line.cursor = cp; el->el_line.cursor = cp;
return (CC_NORM); return (CC_NORM);
} }
}
*ocp = oc;
return (CC_ERROR); return (CC_ERROR);
} else { } else {
for (cp = el->el_line.cursor; *cp != '\0' && for (; *cp != '\0' && cp < el->el_line.limit; cp++) {
cp < el->el_line.limit; cp++) if (el_match(cp, ocp)) {
if (el_match(cp, pattern)) { *ocp = oc;
el->el_line.cursor = cp; el->el_line.cursor = cp;
return (CC_NORM); return (CC_NORM);
} }
}
*ocp = oc;
return (CC_ERROR); return (CC_ERROR);
} }
} }
@ -582,69 +581,53 @@ cv_repeat_srch(EditLine *el, int c)
} }
/* cv_csearch_back(): /* cv_csearch():
* Vi character search reverse * Vi character search
*/ */
protected el_action_t protected el_action_t
cv_csearch_back(EditLine *el, int ch, int count, int tflag) cv_csearch(EditLine *el, int direction, int ch, int count, int tflag)
{ {
char *cp; char *cp;
if (ch == 0)
return CC_ERROR;
if (ch == -1) {
char c;
if (el_getc(el, &c) != 1)
return ed_end_of_file(el, 0);
ch = c;
}
/* Save for ';' and ',' commands */
el->el_search.chacha = ch;
el->el_search.chadir = direction;
el->el_search.chatflg = tflag;
cp = el->el_line.cursor; cp = el->el_line.cursor;
while (count--) { while (count--) {
if (*cp == ch) if (*cp == ch)
cp--; cp += direction;
while (cp > el->el_line.buffer && *cp != ch) for (;;cp += direction) {
cp--; if (cp >= el->el_line.lastchar)
return CC_ERROR;
if (cp < el->el_line.buffer)
return CC_ERROR;
if (*cp == ch)
break;
}
} }
if (cp < el->el_line.buffer || (cp == el->el_line.buffer && *cp != ch)) if (tflag)
return (CC_ERROR); cp -= direction;
if (*cp == ch && tflag)
cp++;
el->el_line.cursor = cp; el->el_line.cursor = cp;
if (el->el_chared.c_vcmd.action & DELETE) { if (el->el_chared.c_vcmd.action != NOP) {
el->el_line.cursor++; if (direction > 0)
el->el_line.cursor++;
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
re_refresh_cursor(el); return CC_CURSOR;
return (CC_NORM);
}
/* cv_csearch_fwd():
* Vi character search forward
*/
protected el_action_t
cv_csearch_fwd(EditLine *el, int ch, int count, int tflag)
{
char *cp;
cp = el->el_line.cursor;
while (count--) {
if (*cp == ch)
cp++;
while (cp < el->el_line.lastchar && *cp != ch)
cp++;
}
if (cp >= el->el_line.lastchar)
return (CC_ERROR);
if (*cp == ch && tflag)
cp--;
el->el_line.cursor = cp;
if (el->el_chared.c_vcmd.action & DELETE) {
el->el_line.cursor++;
cv_delfini(el);
return (CC_REFRESH);
}
re_refresh_cursor(el);
return (CC_NORM);
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: search.h,v 1.5 2000/09/04 22:06:32 lukem Exp $ */ /* $NetBSD: search.h,v 1.8 2003/10/18 23:27:36 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -52,6 +48,7 @@ typedef struct el_search_t {
int patdir; /* Direction of the last search */ int patdir; /* Direction of the last search */
int chadir; /* Character search direction */ int chadir; /* Character search direction */
char chacha; /* Character we are looking for */ char chacha; /* Character we are looking for */
char chatflg; /* 0 if f, 1 if t */
} el_search_t; } el_search_t;
@ -62,9 +59,8 @@ protected int c_hmatch(EditLine *, const char *);
protected void c_setpat(EditLine *); protected void c_setpat(EditLine *);
protected el_action_t ce_inc_search(EditLine *, int); protected el_action_t ce_inc_search(EditLine *, int);
protected el_action_t cv_search(EditLine *, int); protected el_action_t cv_search(EditLine *, int);
protected el_action_t ce_search_line(EditLine *, char *, int); protected el_action_t ce_search_line(EditLine *, int);
protected el_action_t cv_repeat_srch(EditLine *, int); protected el_action_t cv_repeat_srch(EditLine *, int);
protected el_action_t cv_csearch_back(EditLine *, int, int, int); protected el_action_t cv_csearch(EditLine *, int, int, int, int);
protected el_action_t cv_csearch_fwd(EditLine *, int, int, int);
#endif /* _h_el_search */ #endif /* _h_el_search */

View File

@ -1,5 +1,5 @@
# $NetBSD: shlib_version,v 1.11 2001/01/01 15:54:07 jdolecek Exp $ # $NetBSD: shlib_version,v 1.15 2003/12/05 13:37:48 lukem Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing # Remember to update distrib/sets/lists/base/shl.* when changing
# #
major=2 major=2
minor=5 minor=9

19
sig.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: sig.c,v 1.8 2001/01/09 17:31:04 jdolecek Exp $ */ /* $NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,12 +32,12 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: sig.c,v 1.8 2001/01/09 17:31:04 jdolecek Exp $"); __RCSID("$NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
@ -50,7 +46,6 @@ __RCSID("$NetBSD: sig.c,v 1.8 2001/01/09 17:31:04 jdolecek Exp $");
* our policy is to trap all signals, set a good state * our policy is to trap all signals, set a good state
* and pass the ball to our caller. * and pass the ball to our caller.
*/ */
#include "sys.h"
#include "el.h" #include "el.h"
#include <stdlib.h> #include <stdlib.h>
@ -122,9 +117,9 @@ sig_init(EditLine *el)
#undef _DO #undef _DO
(void) sigprocmask(SIG_BLOCK, &nset, &oset); (void) sigprocmask(SIG_BLOCK, &nset, &oset);
#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(sig_t)) #define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(el_signalhandler_t))
el->el_signal = (sig_t *) el_malloc(SIGSIZE); el->el_signal = (el_signalhandler_t *) el_malloc(SIGSIZE);
if (el->el_signal == NULL) if (el->el_signal == NULL)
return (-1); return (-1);
for (i = 0; sighdl[i] != -1; i++) for (i = 0; sighdl[i] != -1; i++)
@ -164,7 +159,7 @@ sig_set(EditLine *el)
(void) sigprocmask(SIG_BLOCK, &nset, &oset); (void) sigprocmask(SIG_BLOCK, &nset, &oset);
for (i = 0; sighdl[i] != -1; i++) { for (i = 0; sighdl[i] != -1; i++) {
sig_t s; el_signalhandler_t s;
/* This could happen if we get interrupted */ /* This could happen if we get interrupted */
if ((s = signal(sighdl[i], sig_handler)) != sig_handler) if ((s = signal(sighdl[i], sig_handler)) != sig_handler)
el->el_signal[i] = s; el->el_signal[i] = s;

11
sig.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: sig.h,v 1.3 2000/09/04 22:06:32 lukem Exp $ */ /* $NetBSD: sig.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -62,7 +58,8 @@
_DO(SIGCONT) \ _DO(SIGCONT) \
_DO(SIGWINCH) _DO(SIGWINCH)
typedef sig_t *el_signal_t; typedef void (*el_signalhandler_t)(int);
typedef el_signalhandler_t *el_signal_t;
protected void sig_end(EditLine*); protected void sig_end(EditLine*);
protected int sig_init(EditLine*); protected int sig_init(EditLine*);

54
sys.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: sys.h,v 1.4 2000/09/04 22:06:32 lukem Exp $ */ /* $NetBSD: sys.h,v 1.9 2004/01/17 17:57:40 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -44,6 +40,24 @@
#ifndef _h_sys #ifndef _h_sys
#define _h_sys #define _h_sys
#ifdef HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
# define __attribute__(A)
#endif
#ifndef __BEGIN_DECLS
# ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
# else
# define __BEGIN_DECLS
# define __END_DECLS
# endif
#endif
#ifndef public #ifndef public
# define public /* Externally visible functions/variables */ # define public /* Externally visible functions/variables */
#endif #endif
@ -57,8 +71,6 @@
/* When we want to hide everything */ /* When we want to hide everything */
#endif #endif
#include <sys/cdefs.h>
#ifndef _PTR_T #ifndef _PTR_T
# define _PTR_T # define _PTR_T
typedef void *ptr_t; typedef void *ptr_t;
@ -71,23 +83,42 @@ typedef void *ioctl_t;
#include <stdio.h> #include <stdio.h>
#ifndef HAVE_STRLCAT
#define strlcat libedit_strlcat
size_t strlcat(char *dst, const char *src, size_t size);
#endif
#ifndef HAVE_STRLCPY
#define strlcpy libedit_strlcpy
size_t strlcpy(char *dst, const char *src, size_t size);
#endif
#ifndef HAVE_FGETLN
#define fgetln libedit_fgetln
char *fgetln(FILE *fp, size_t *len);
#endif
#define REGEX /* Use POSIX.2 regular expression functions */ #define REGEX /* Use POSIX.2 regular expression functions */
#undef REGEXP /* Use UNIX V8 regular expression functions */ #undef REGEXP /* Use UNIX V8 regular expression functions */
#ifdef SUNOS #ifdef notdef
# undef REGEX # undef REGEX
# undef REGEXP # undef REGEXP
# include <malloc.h> # include <malloc.h>
typedef void (*sig_t)(int);
# ifdef __GNUC__ # ifdef __GNUC__
/* /*
* Broken hdrs. * Broken hdrs.
*/ */
extern int tgetent(const char *bp, char *name);
extern int tgetflag(const char *id);
extern int tgetnum(const char *id);
extern char *tgetstr(const char *id, char **area);
extern char *tgoto(const char *cap, int col, int row);
extern int tputs(const char *str, int affcnt, int (*putc)(int));
extern char *getenv(const char *); extern char *getenv(const char *);
extern int fprintf(FILE *, const char *, ...); extern int fprintf(FILE *, const char *, ...);
extern int sigsetmask(int); extern int sigsetmask(int);
extern int sigblock(int); extern int sigblock(int);
extern int ioctl(int, int, void *);
extern int fputc(int, FILE *); extern int fputc(int, FILE *);
extern int fgetc(FILE *); extern int fgetc(FILE *);
extern int fflush(FILE *); extern int fflush(FILE *);
@ -96,7 +127,6 @@ extern int toupper(int);
extern int errno, sys_nerr; extern int errno, sys_nerr;
extern char *sys_errlist[]; extern char *sys_errlist[];
extern void perror(const char *); extern void perror(const char *);
extern int read(int, const char*, int);
# include <string.h> # include <string.h>
# define strerror(e) sys_errlist[e] # define strerror(e) sys_errlist[e]
# endif # endif

81
term.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: term.c,v 1.32 2001/01/23 15:55:31 jdolecek Exp $ */ /* $NetBSD: term.c,v 1.40 2004/05/22 23:21:28 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,12 +32,12 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95";
#else #else
__RCSID("$NetBSD: term.c,v 1.32 2001/01/23 15:55:31 jdolecek Exp $"); __RCSID("$NetBSD: term.c,v 1.40 2004/05/22 23:21:28 christos Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
@ -50,13 +46,24 @@ __RCSID("$NetBSD: term.c,v 1.32 2001/01/23 15:55:31 jdolecek Exp $");
* We have to declare a static variable here, since the * We have to declare a static variable here, since the
* termcap putchar routine does not take an argument! * termcap putchar routine does not take an argument!
*/ */
#include "sys.h"
#include <stdio.h> #include <stdio.h>
#include <signal.h> #include <signal.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#ifdef HAVE_TERMCAP_H
#include <termcap.h> #include <termcap.h>
#endif
#ifdef HAVE_CURSES_H
#include <curses.h>
#endif
#ifdef HAVE_NCURSES_H
#include <ncurses.h>
#endif
/* Solaris's term.h does horrid things. */
#if (defined(HAVE_TERM_H) && !defined(SUNOS))
#include <term.h>
#endif
#include <sys/types.h> #include <sys/types.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@ -261,7 +268,7 @@ private void term_setflags(EditLine *);
private int term_rebuffer_display(EditLine *); private int term_rebuffer_display(EditLine *);
private void term_free_display(EditLine *); private void term_free_display(EditLine *);
private int term_alloc_display(EditLine *); private int term_alloc_display(EditLine *);
private void term_alloc(EditLine *, const struct termcapstr *, char *); private void term_alloc(EditLine *, const struct termcapstr *, const char *);
private void term_init_arrow(EditLine *); private void term_init_arrow(EditLine *);
private void term_reset_arrow(EditLine *); private void term_reset_arrow(EditLine *);
@ -341,11 +348,11 @@ term_init(EditLine *el)
return (-1); return (-1);
(void) memset(el->el_term.t_val, 0, T_val * sizeof(int)); (void) memset(el->el_term.t_val, 0, T_val * sizeof(int));
term_outfile = el->el_outfile; term_outfile = el->el_outfile;
if (term_set(el, NULL) == -1) (void) term_set(el, NULL);
return (-1);
term_init_arrow(el); term_init_arrow(el);
return (0); return (0);
} }
/* term_end(): /* term_end():
* Clean up the terminal stuff * Clean up the terminal stuff
*/ */
@ -362,6 +369,8 @@ term_end(EditLine *el)
el->el_term.t_str = NULL; el->el_term.t_str = NULL;
el_free((ptr_t) el->el_term.t_val); el_free((ptr_t) el->el_term.t_val);
el->el_term.t_val = NULL; el->el_term.t_val = NULL;
el_free((ptr_t) el->el_term.t_fkey);
el->el_term.t_fkey = NULL;
term_free_display(el); term_free_display(el);
} }
@ -370,7 +379,7 @@ term_end(EditLine *el)
* Maintain a string pool for termcap strings * Maintain a string pool for termcap strings
*/ */
private void private void
term_alloc(EditLine *el, const struct termcapstr *t, char *cap) term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
{ {
char termbuf[TC_BUFSIZE]; char termbuf[TC_BUFSIZE];
int tlen, clen; int tlen, clen;
@ -638,7 +647,8 @@ term_move_to_char(EditLine *el, int where)
* from col 0 * from col 0
*/ */
if (EL_CAN_TAB ? if (EL_CAN_TAB ?
(-del > (((unsigned int) where >> 3) + ((unsigned int)-del >
(((unsigned int) where >> 3) +
(where & 07))) (where & 07)))
: (-del > where)) { : (-del > where)) {
term__putc('\r'); /* do a CR */ term__putc('\r'); /* do a CR */
@ -658,7 +668,7 @@ term_move_to_char(EditLine *el, int where)
* Overstrike num characters * Overstrike num characters
*/ */
protected void protected void
term_overwrite(EditLine *el, char *cp, int n) term_overwrite(EditLine *el, const char *cp, int n)
{ {
if (n <= 0) if (n <= 0)
return; /* catch bugs */ return; /* catch bugs */
@ -866,12 +876,18 @@ term_clear_to_bottom(EditLine *el)
} }
#endif #endif
protected void
term_get(EditLine *el, const char **term)
{
*term = el->el_term.t_name;
}
/* term_set(): /* term_set():
* Read in the terminal capabilities from the requested terminal * Read in the terminal capabilities from the requested terminal
*/ */
protected int protected int
term_set(EditLine *el, char *term) term_set(EditLine *el, const char *term)
{ {
int i; int i;
char buf[TC_BUFSIZE]; char buf[TC_BUFSIZE];
@ -927,8 +943,11 @@ term_set(EditLine *el, char *term)
/* Get the size */ /* Get the size */
Val(T_co) = tgetnum("co"); Val(T_co) = tgetnum("co");
Val(T_li) = tgetnum("li"); Val(T_li) = tgetnum("li");
for (t = tstr; t->name != NULL; t++) for (t = tstr; t->name != NULL; t++) {
term_alloc(el, t, tgetstr(t->name, &area)); /* XXX: some systems tgetstr needs non const */
term_alloc(el, t, tgetstr(strchr(t->name, *t->name),
&area));
}
} }
if (Val(T_co) < 2) if (Val(T_co) < 2)
@ -947,6 +966,7 @@ term_set(EditLine *el, char *term)
return (-1); return (-1);
(void) sigprocmask(SIG_SETMASK, &oset, NULL); (void) sigprocmask(SIG_SETMASK, &oset, NULL);
term_bind_arrow(el); term_bind_arrow(el);
el->el_term.t_name = term;
return (i <= 0 ? -1 : 0); return (i <= 0 ? -1 : 0);
} }
@ -1102,7 +1122,7 @@ term_reset_arrow(EditLine *el)
* Set an arrow key binding * Set an arrow key binding
*/ */
protected int protected int
term_set_arrow(EditLine *el, char *name, key_value_t *fun, int type) term_set_arrow(EditLine *el, const char *name, key_value_t *fun, int type)
{ {
fkey_t *arrow = el->el_term.t_fkey; fkey_t *arrow = el->el_term.t_fkey;
int i; int i;
@ -1121,7 +1141,7 @@ term_set_arrow(EditLine *el, char *name, key_value_t *fun, int type)
* Clear an arrow key binding * Clear an arrow key binding
*/ */
protected int protected int
term_clear_arrow(EditLine *el, char *name) term_clear_arrow(EditLine *el, const char *name)
{ {
fkey_t *arrow = el->el_term.t_fkey; fkey_t *arrow = el->el_term.t_fkey;
int i; int i;
@ -1139,7 +1159,7 @@ term_clear_arrow(EditLine *el, char *name)
* Print the arrow key bindings * Print the arrow key bindings
*/ */
protected void protected void
term_print_arrow(EditLine *el, char *name) term_print_arrow(EditLine *el, const char *name)
{ {
int i; int i;
fkey_t *arrow = el->el_term.t_fkey; fkey_t *arrow = el->el_term.t_fkey;
@ -1236,7 +1256,8 @@ term__flush(void)
*/ */
protected int protected int
/*ARGSUSED*/ /*ARGSUSED*/
term_telltc(EditLine *el, int argc, char **argv) term_telltc(EditLine *el, int argc __attribute__((__unused__)),
const char **argv __attribute__((__unused__)))
{ {
const struct termcapstr *t; const struct termcapstr *t;
char **ts; char **ts;
@ -1271,11 +1292,12 @@ term_telltc(EditLine *el, int argc, char **argv)
*/ */
protected int protected int
/*ARGSUSED*/ /*ARGSUSED*/
term_settc(EditLine *el, int argc, char **argv) term_settc(EditLine *el, int argc __attribute__((__unused__)),
const char **argv)
{ {
const struct termcapstr *ts; const struct termcapstr *ts;
const struct termcapval *tv; const struct termcapval *tv;
char *what, *how; const char *what, *how;
if (argv == NULL || argv[1] == NULL || argv[2] == NULL) if (argv == NULL || argv[1] == NULL || argv[2] == NULL)
return (-1); return (-1);
@ -1347,7 +1369,8 @@ term_settc(EditLine *el, int argc, char **argv)
*/ */
protected int protected int
/*ARGSUSED*/ /*ARGSUSED*/
term_echotc(EditLine *el, int argc, char **argv) term_echotc(EditLine *el, int argc __attribute__((__unused__)),
const char **argv)
{ {
char *cap, *scap, *ep; char *cap, *scap, *ep;
int arg_need, arg_cols, arg_rows; int arg_need, arg_cols, arg_rows;
@ -1406,7 +1429,7 @@ term_echotc(EditLine *el, int argc, char **argv)
} }
(void) fprintf(el->el_outfile, fmtd, 0); (void) fprintf(el->el_outfile, fmtd, 0);
#else #else
(void) fprintf(el->el_outfile, fmtd, el->el_tty.t_speed); (void) fprintf(el->el_outfile, fmtd, (int)el->el_tty.t_speed);
#endif #endif
return (0); return (0);
} else if (strcmp(*argv, "rows") == 0 || strcmp(*argv, "lines") == 0) { } else if (strcmp(*argv, "rows") == 0 || strcmp(*argv, "lines") == 0) {
@ -1425,8 +1448,10 @@ term_echotc(EditLine *el, int argc, char **argv)
scap = el->el_term.t_str[t - tstr]; scap = el->el_term.t_str[t - tstr];
break; break;
} }
if (t->name == NULL) if (t->name == NULL) {
scap = tgetstr(*argv, &area); /* XXX: some systems tgetstr needs non const */
scap = tgetstr(strchr(*argv, **argv), &area);
}
if (!scap || scap[0] == '\0') { if (!scap || scap[0] == '\0') {
if (!silent) if (!silent)
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,

29
term.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: term.h,v 1.12 2001/01/04 15:56:32 christos Exp $ */ /* $NetBSD: term.h,v 1.16 2005/03/15 00:10:40 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -47,13 +43,14 @@
#include "histedit.h" #include "histedit.h"
typedef struct { /* Symbolic function key bindings */ typedef struct { /* Symbolic function key bindings */
char *name; /* name of the key */ const char *name; /* name of the key */
int key; /* Index in termcap table */ int key; /* Index in termcap table */
key_value_t fun; /* Function bound to it */ key_value_t fun; /* Function bound to it */
int type; /* Type of function */ int type; /* Type of function */
} fkey_t; } fkey_t;
typedef struct { typedef struct {
const char *t_name; /* the terminal name */
coord_t t_size; /* # lines and cols */ coord_t t_size; /* # lines and cols */
int t_flags; int t_flags;
#define TERM_CAN_INSERT 0x001 /* Has insert cap */ #define TERM_CAN_INSERT 0x001 /* Has insert cap */
@ -87,7 +84,7 @@ typedef struct {
protected void term_move_to_line(EditLine *, int); protected void term_move_to_line(EditLine *, int);
protected void term_move_to_char(EditLine *, int); protected void term_move_to_char(EditLine *, int);
protected void term_clear_EOL(EditLine *, int); protected void term_clear_EOL(EditLine *, int);
protected void term_overwrite(EditLine *, char *, int); protected void term_overwrite(EditLine *, const char *, int);
protected void term_insertwrite(EditLine *, char *, int); protected void term_insertwrite(EditLine *, char *, int);
protected void term_deletechars(EditLine *, int); protected void term_deletechars(EditLine *, int);
protected void term_clear_screen(EditLine *); protected void term_clear_screen(EditLine *);
@ -96,14 +93,15 @@ protected int term_change_size(EditLine *, int, int);
protected int term_get_size(EditLine *, int *, int *); protected int term_get_size(EditLine *, int *, int *);
protected int term_init(EditLine *); protected int term_init(EditLine *);
protected void term_bind_arrow(EditLine *); protected void term_bind_arrow(EditLine *);
protected void term_print_arrow(EditLine *, char *); protected void term_print_arrow(EditLine *, const char *);
protected int term_clear_arrow(EditLine *, char *); protected int term_clear_arrow(EditLine *, const char *);
protected int term_set_arrow(EditLine *, char *, key_value_t *, int); protected int term_set_arrow(EditLine *, const char *, key_value_t *, int);
protected void term_end(EditLine *); protected void term_end(EditLine *);
protected int term_set(EditLine *, char *); protected void term_get(EditLine *, const char **);
protected int term_settc(EditLine *, int, char **); protected int term_set(EditLine *, const char *);
protected int term_telltc(EditLine *, int, char **); protected int term_settc(EditLine *, int, const char **);
protected int term_echotc(EditLine *, int, char **); protected int term_telltc(EditLine *, int, const char **);
protected int term_echotc(EditLine *, int, const char **);
protected int term__putc(int); protected int term__putc(int);
protected void term__flush(void); protected void term__flush(void);
@ -117,6 +115,7 @@ protected void term__flush(void);
#define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL) #define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL)
#define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB) #define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB)
#define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME) #define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME)
#define EL_CAN_UP (EL_FLAGS & TERM_CAN_UP)
#define EL_HAS_META (EL_FLAGS & TERM_HAS_META) #define EL_HAS_META (EL_FLAGS & TERM_HAS_META)
#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS) #define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS)
#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS) #define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS)

View File

@ -1,4 +1,4 @@
/* $NetBSD: tokenizer.c,v 1.7 2001/01/04 15:56:32 christos Exp $ */ /* $NetBSD: tokenizer.c,v 1.14 2003/12/05 13:37:48 lukem Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,22 +32,21 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: tokenizer.c,v 1.7 2001/01/04 15:56:32 christos Exp $"); __RCSID("$NetBSD: tokenizer.c,v 1.14 2003/12/05 13:37:48 lukem Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* tokenize.c: Bourne shell like tokenizer * tokenize.c: Bourne shell like tokenizer
*/ */
#include "sys.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "tokenizer.h" #include "histedit.h"
typedef enum { typedef enum {
Q_none, Q_single, Q_double, Q_one, Q_doubleone Q_none, Q_single, Q_double, Q_one, Q_doubleone
@ -65,6 +60,7 @@ typedef enum {
#define WINCR 20 #define WINCR 20
#define AINCR 10 #define AINCR 10
#define tok_strdup(a) strdup(a)
#define tok_malloc(a) malloc(a) #define tok_malloc(a) malloc(a)
#define tok_free(a) free(a) #define tok_free(a) free(a)
#define tok_realloc(a, b) realloc(a, b) #define tok_realloc(a, b) realloc(a, b)
@ -110,16 +106,29 @@ tok_init(const char *ifs)
{ {
Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer)); Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer));
tok->ifs = strdup(ifs ? ifs : IFS); if (tok == NULL)
return NULL;
tok->ifs = tok_strdup(ifs ? ifs : IFS);
if (tok->ifs == NULL) {
tok_free((ptr_t)tok);
return NULL;
}
tok->argc = 0; tok->argc = 0;
tok->amax = AINCR; tok->amax = AINCR;
tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax); tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax);
if (tok->argv == NULL) if (tok->argv == NULL) {
return (NULL); tok_free((ptr_t)tok->ifs);
tok_free((ptr_t)tok);
return NULL;
}
tok->argv[0] = NULL; tok->argv[0] = NULL;
tok->wspace = (char *) tok_malloc(WINCR); tok->wspace = (char *) tok_malloc(WINCR);
if (tok->wspace == NULL) if (tok->wspace == NULL) {
return (NULL); tok_free((ptr_t)tok->argv);
tok_free((ptr_t)tok->ifs);
tok_free((ptr_t)tok);
return NULL;
}
tok->wmax = tok->wspace + WINCR; tok->wmax = tok->wspace + WINCR;
tok->wstart = tok->wspace; tok->wstart = tok->wspace;
tok->wptr = tok->wspace; tok->wptr = tok->wspace;
@ -161,21 +170,39 @@ tok_end(Tokenizer *tok)
/* tok_line(): /* tok_line():
* Bourne shell like tokenizing * Bourne shell (sh(1)) like tokenizing
* Return: * Arguments:
* -1: Internal error * tok current tokenizer state (setup with tok_init())
* 3: Quoted return * line line to parse
* 2: Unmatched double quote * Returns:
* 1: Unmatched single quote * -1 Internal error
* 0: Ok * 3 Quoted return
* 2 Unmatched double quote
* 1 Unmatched single quote
* 0 Ok
* Modifies (if return value is 0):
* argc number of arguments
* argv argument array
* cursorc if !NULL, argv element containing cursor
* cursorv if !NULL, offset in argv[cursorc] of cursor
*/ */
public int public int
tok_line(Tokenizer *tok, const char *line, int *argc, char ***argv) tok_line(Tokenizer *tok, const LineInfo *line,
int *argc, const char ***argv, int *cursorc, int *cursoro)
{ {
const char *ptr; const char *ptr;
int cc, co;
for (;;) { cc = co = -1;
switch (*(ptr = line++)) { ptr = line->buffer;
for (ptr = line->buffer; ;ptr++) {
if (ptr >= line->lastchar)
ptr = "";
if (ptr == line->cursor) {
cc = tok->argc;
co = tok->wptr - tok->wstart;
}
switch (*ptr) {
case '\'': case '\'':
tok->flags |= TOK_KEEP; tok->flags |= TOK_KEEP;
tok->flags &= ~TOK_EAT; tok->flags &= ~TOK_EAT;
@ -274,10 +301,7 @@ tok_line(Tokenizer *tok, const char *line, int *argc, char ***argv)
tok->flags &= ~TOK_EAT; tok->flags &= ~TOK_EAT;
switch (tok->quote) { switch (tok->quote) {
case Q_none: case Q_none:
tok_finish(tok); goto tok_line_outok;
*argv = tok->argv;
*argc = tok->argc;
return (0);
case Q_single: case Q_single:
case Q_double: case Q_double:
@ -307,10 +331,7 @@ tok_line(Tokenizer *tok, const char *line, int *argc, char ***argv)
tok->flags &= ~TOK_EAT; tok->flags &= ~TOK_EAT;
return (3); return (3);
} }
tok_finish(tok); goto tok_line_outok;
*argv = tok->argv;
*argc = tok->argc;
return (0);
case Q_single: case Q_single:
return (1); return (1);
@ -370,20 +391,20 @@ tok_line(Tokenizer *tok, const char *line, int *argc, char ***argv)
if (tok->wptr >= tok->wmax - 4) { if (tok->wptr >= tok->wmax - 4) {
size_t size = tok->wmax - tok->wspace + WINCR; size_t size = tok->wmax - tok->wspace + WINCR;
char *s = (char *) tok_realloc(tok->wspace, size); char *s = (char *) tok_realloc(tok->wspace, size);
/* SUPPRESS 22 */
int offs = s - tok->wspace;
if (s == NULL) if (s == NULL)
return (-1); return (-1);
if (offs != 0) { if (s != tok->wspace) {
int i; int i;
for (i = 0; i < tok->argc; i++) for (i = 0; i < tok->argc; i++) {
tok->argv[i] = tok->argv[i] + offs; tok->argv[i] =
tok->wptr = tok->wptr + offs; (tok->argv[i] - tok->wspace) + s;
tok->wstart = tok->wstart + offs; }
tok->wmax = s + size; tok->wptr = (tok->wptr - tok->wspace) + s;
tok->wstart = (tok->wstart - tok->wspace) + s;
tok->wspace = s; tok->wspace = s;
} }
tok->wmax = s + size;
} }
if (tok->argc >= tok->amax - 4) { if (tok->argc >= tok->amax - 4) {
char **p; char **p;
@ -395,4 +416,32 @@ tok_line(Tokenizer *tok, const char *line, int *argc, char ***argv)
tok->argv = p; tok->argv = p;
} }
} }
tok_line_outok:
if (cc == -1 && co == -1) {
cc = tok->argc;
co = tok->wptr - tok->wstart;
}
if (cursorc != NULL)
*cursorc = cc;
if (cursoro != NULL)
*cursoro = co;
tok_finish(tok);
*argv = (const char **)tok->argv;
*argc = tok->argc;
return (0);
}
/* tok_str():
* Simpler version of tok_line, taking a NUL terminated line
* and splitting into words, ignoring cursor state.
*/
public int
tok_str(Tokenizer *tok, const char *line, int *argc, const char ***argv)
{
LineInfo li;
memset(&li, 0, sizeof(li));
li.buffer = line;
li.cursor = li.lastchar = strchr(line, '\0');
return (tok_line(tok, &li, argc, argv, NULL, NULL));
} }

View File

@ -1,54 +0,0 @@
/* $NetBSD: tokenizer.h,v 1.4 2000/09/04 22:06:33 lukem Exp $ */
/*-
* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Christos Zoulas of Cornell University.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)tokenizer.h 8.1 (Berkeley) 6/4/93
*/
/*
* tokenizer.h: Header file for tokenizer routines
*/
#ifndef _h_tokenizer
#define _h_tokenizer
typedef struct tokenizer Tokenizer;
Tokenizer *tok_init(const char *);
void tok_reset(Tokenizer *);
void tok_end(Tokenizer *);
int tok_line(Tokenizer *, const char *, int *, char ***);
#endif /* _h_tokenizer */

160
tty.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.c,v 1.15 2001/05/17 01:02:17 christos Exp $ */ /* $NetBSD: tty.c,v 1.23 2005/06/01 11:37:52 lukem Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -36,32 +32,32 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <sys/cdefs.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
#if 0 #if 0
static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: tty.c,v 1.15 2001/05/17 01:02:17 christos Exp $"); __RCSID("$NetBSD: tty.c,v 1.23 2005/06/01 11:37:52 lukem Exp $");
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* tty.c: tty interface stuff * tty.c: tty interface stuff
*/ */
#include "sys.h" #include <assert.h>
#include "tty.h" #include "tty.h"
#include "el.h" #include "el.h"
typedef struct ttymodes_t { typedef struct ttymodes_t {
const char *m_name; const char *m_name;
u_int m_value; unsigned int m_value;
int m_type; int m_type;
} ttymodes_t; } ttymodes_t;
typedef struct ttymap_t { typedef struct ttymap_t {
int nch, och; /* Internal and termio rep of chars */ int nch, och; /* Internal and termio rep of chars */
el_action_t bind[3]; /* emacs, vi, and vi-cmd */ el_action_t bind[3]; /* emacs, vi, and vi-cmd */
} ttymap_t; } ttymap_t;
private const ttyperm_t ttyperm = { private const ttyperm_t ttyperm = {
@ -125,11 +121,11 @@ private const ttychar_t ttychar = {
private const ttymap_t tty_map[] = { private const ttymap_t tty_map[] = {
#ifdef VERASE #ifdef VERASE
{C_ERASE, VERASE, {C_ERASE, VERASE,
{ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
#endif /* VERASE */ #endif /* VERASE */
#ifdef VERASE2 #ifdef VERASE2
{C_ERASE2, VERASE2, {C_ERASE2, VERASE2,
{ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, {EM_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}},
#endif /* VERASE2 */ #endif /* VERASE2 */
#ifdef VKILL #ifdef VKILL
{C_KILL, VKILL, {C_KILL, VKILL,
@ -456,6 +452,7 @@ private const ttymodes_t ttymodes[] = {
#define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8) #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
#define tty__cooked_mode(td) ((td)->c_lflag & ICANON) #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
private int tty__getcharindex(int);
private void tty__getchar(struct termios *, unsigned char *); private void tty__getchar(struct termios *, unsigned char *);
private void tty__setchar(struct termios *, unsigned char *); private void tty__setchar(struct termios *, unsigned char *);
private speed_t tty__getspeed(struct termios *); private speed_t tty__getspeed(struct termios *);
@ -569,7 +566,7 @@ tty_init(EditLine *el)
*/ */
protected void protected void
/*ARGSUSED*/ /*ARGSUSED*/
tty_end(EditLine *el) tty_end(EditLine *el __attribute__((__unused__)))
{ {
/* XXX: Maybe reset to an initial state? */ /* XXX: Maybe reset to an initial state? */
@ -589,6 +586,113 @@ tty__getspeed(struct termios *td)
return (spd); return (spd);
} }
/* tty__getspeed():
* Return the index of the asked char in the c_cc array
*/
private int
tty__getcharindex(int i)
{
switch (i) {
#ifdef VINTR
case C_INTR:
return VINTR;
#endif /* VINTR */
#ifdef VQUIT
case C_QUIT:
return VQUIT;
#endif /* VQUIT */
#ifdef VERASE
case C_ERASE:
return VERASE;
#endif /* VERASE */
#ifdef VKILL
case C_KILL:
return VKILL;
#endif /* VKILL */
#ifdef VEOF
case C_EOF:
return VEOF;
#endif /* VEOF */
#ifdef VEOL
case C_EOL:
return VEOL;
#endif /* VEOL */
#ifdef VEOL2
case C_EOL2:
return VEOL2;
#endif /* VEOL2 */
#ifdef VSWTCH
case C_SWTCH:
return VSWTCH;
#endif /* VSWTCH */
#ifdef VDSWTCH
case C_DSWTCH:
return VDSWTCH;
#endif /* VDSWTCH */
#ifdef VERASE2
case C_ERASE2:
return VERASE2;
#endif /* VERASE2 */
#ifdef VSTART
case C_START:
return VSTART;
#endif /* VSTART */
#ifdef VSTOP
case C_STOP:
return VSTOP;
#endif /* VSTOP */
#ifdef VWERASE
case C_WERASE:
return VWERASE;
#endif /* VWERASE */
#ifdef VSUSP
case C_SUSP:
return VSUSP;
#endif /* VSUSP */
#ifdef VDSUSP
case C_DSUSP:
return VDSUSP;
#endif /* VDSUSP */
#ifdef VREPRINT
case C_REPRINT:
return VREPRINT;
#endif /* VREPRINT */
#ifdef VDISCARD
case C_DISCARD:
return VDISCARD;
#endif /* VDISCARD */
#ifdef VLNEXT
case C_LNEXT:
return VLNEXT;
#endif /* VLNEXT */
#ifdef VSTATUS
case C_STATUS:
return VSTATUS;
#endif /* VSTATUS */
#ifdef VPAGE
case C_PAGE:
return VPAGE;
#endif /* VPAGE */
#ifdef VPGOFF
case C_PGOFF:
return VPGOFF;
#endif /* VPGOFF */
#ifdef VKILL2
case C_KILL2:
return VKILL2;
#endif /* KILL2 */
#ifdef VMIN
case C_MIN:
return VMIN;
#endif /* VMIN */
#ifdef VTIME
case C_TIME:
return VTIME;
#endif /* VTIME */
default:
return -1;
}
}
/* tty__getchar(): /* tty__getchar():
* Get the tty characters * Get the tty characters
@ -1042,13 +1146,14 @@ tty_noquotemode(EditLine *el)
*/ */
protected int protected int
/*ARGSUSED*/ /*ARGSUSED*/
tty_stty(EditLine *el, int argc, char **argv) tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
{ {
const ttymodes_t *m; const ttymodes_t *m;
char x, *d; char x;
int aflag = 0; int aflag = 0;
char *s; const char *s, *d;
char *name; const char *name;
struct termios *tios = &el->el_tty.t_ex;
int z = EX_IO; int z = EX_IO;
if (argv == NULL) if (argv == NULL)
@ -1063,14 +1168,17 @@ tty_stty(EditLine *el, int argc, char **argv)
break; break;
case 'd': case 'd':
argv++; argv++;
tios = &el->el_tty.t_ed;
z = ED_IO; z = ED_IO;
break; break;
case 'x': case 'x':
argv++; argv++;
tios = &el->el_tty.t_ex;
z = EX_IO; z = EX_IO;
break; break;
case 'q': case 'q':
argv++; argv++;
tios = &el->el_tty.t_ts;
z = QU_IO; z = QU_IO;
break; break;
default: default:
@ -1120,6 +1228,7 @@ tty_stty(EditLine *el, int argc, char **argv)
return (0); return (0);
} }
while (argv && (s = *argv++)) { while (argv && (s = *argv++)) {
const char *p;
switch (*s) { switch (*s) {
case '+': case '+':
case '-': case '-':
@ -1130,8 +1239,11 @@ tty_stty(EditLine *el, int argc, char **argv)
break; break;
} }
d = s; d = s;
p = strchr(s, '=');
for (m = ttymodes; m->m_name; m++) for (m = ttymodes; m->m_name; m++)
if (strcmp(m->m_name, d) == 0) if ((p ? strncmp(m->m_name, d, (size_t)(p - d)) :
strcmp(m->m_name, d)) == 0 &&
(p == NULL || m->m_type == MD_CHAR))
break; break;
if (!m->m_name) { if (!m->m_name) {
@ -1139,6 +1251,16 @@ tty_stty(EditLine *el, int argc, char **argv)
"%s: Invalid argument `%s'.\n", name, d); "%s: Invalid argument `%s'.\n", name, d);
return (-1); return (-1);
} }
if (p) {
int c = ffs((int)m->m_value);
int v = *++p ? parse__escape((const char **) &p) :
el->el_tty.t_vdisable;
assert(c-- != 0);
c = tty__getcharindex(c);
assert(c != -1);
tios->c_cc[c] = v;
continue;
}
switch (x) { switch (x) {
case '+': case '+':
el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value; el->el_tty.t_t[z][m->m_type].t_setmask |= m->m_value;

16
tty.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.h,v 1.8 2000/09/04 22:06:33 lukem Exp $ */ /* $NetBSD: tty.h,v 1.11 2005/06/01 11:37:52 lukem Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -15,11 +15,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -453,16 +449,16 @@
#define MD_NN 5 #define MD_NN 5
typedef struct { typedef struct {
char *t_name; const char *t_name;
u_int t_setmask; unsigned int t_setmask;
u_int t_clrmask; unsigned int t_clrmask;
} ttyperm_t[NN_IO][MD_NN]; } ttyperm_t[NN_IO][MD_NN];
typedef unsigned char ttychar_t[NN_IO][C_NCC]; typedef unsigned char ttychar_t[NN_IO][C_NCC];
protected int tty_init(EditLine *); protected int tty_init(EditLine *);
protected void tty_end(EditLine *); protected void tty_end(EditLine *);
protected int tty_stty(EditLine *, int, char**); protected int tty_stty(EditLine *, int, const char **);
protected int tty_rawmode(EditLine *); protected int tty_rawmode(EditLine *);
protected int tty_cookedmode(EditLine *); protected int tty_cookedmode(EditLine *);
protected int tty_quotemode(EditLine *); protected int tty_quotemode(EditLine *);

826
vi.c

File diff suppressed because it is too large Load Diff