diff options
author | obrien <obrien@FreeBSD.org> | 2011-03-31 01:00:31 +0000 |
---|---|---|
committer | obrien <obrien@FreeBSD.org> | 2011-03-31 01:00:31 +0000 |
commit | ed52965c2a5e99270584af6409a9b60c2dfab73c (patch) | |
tree | 2b8f5136c8ef8ae631042f124fe7b50a0c885ad1 | |
parent | ac93027e6dd0829aafab8696805a10ad49b06ab3 (diff) | |
download | FreeBSD-src-ed52965c2a5e99270584af6409a9b60c2dfab73c.zip FreeBSD-src-ed52965c2a5e99270584af6409a9b60c2dfab73c.tar.gz |
Vendor import NetBSD's libedit of "2001/09/29 17:52:10 UTC".
Obtained from: NetBSD
-rw-r--r-- | dist/Makefile | 60 | ||||
-rw-r--r-- | dist/TEST/test.c | 338 | ||||
-rw-r--r-- | dist/chared.c | 838 | ||||
-rw-r--r-- | dist/chared.h | 113 | ||||
-rw-r--r-- | dist/common.c | 1108 | ||||
-rw-r--r-- | dist/editline.3 | 191 | ||||
-rw-r--r-- | dist/editrc.5 | 227 | ||||
-rw-r--r-- | dist/el.c | 552 | ||||
-rw-r--r-- | dist/el.h | 95 | ||||
-rw-r--r-- | dist/emacs.c | 495 | ||||
-rw-r--r-- | dist/hist.c | 174 | ||||
-rw-r--r-- | dist/hist.h | 37 | ||||
-rw-r--r-- | dist/histedit.h | 125 | ||||
-rw-r--r-- | dist/history.c | 1066 | ||||
-rw-r--r-- | dist/key.c | 878 | ||||
-rw-r--r-- | dist/key.h | 50 | ||||
-rw-r--r-- | dist/makelist | 117 | ||||
-rw-r--r-- | dist/map.c | 2430 | ||||
-rw-r--r-- | dist/map.h | 50 | ||||
-rw-r--r-- | dist/parse.c | 309 | ||||
-rw-r--r-- | dist/parse.h | 12 | ||||
-rw-r--r-- | dist/prompt.c | 124 | ||||
-rw-r--r-- | dist/prompt.h | 19 | ||||
-rw-r--r-- | dist/read.c | 689 | ||||
-rw-r--r-- | dist/read.h | 55 | ||||
-rw-r--r-- | dist/readline.c | 1664 | ||||
-rw-r--r-- | dist/readline/Makefile | 13 | ||||
-rw-r--r-- | dist/readline/readline.h | 114 | ||||
-rw-r--r-- | dist/refresh.c | 1652 | ||||
-rw-r--r-- | dist/refresh.h | 23 | ||||
-rw-r--r-- | dist/search.c | 860 | ||||
-rw-r--r-- | dist/search.h | 38 | ||||
-rw-r--r-- | dist/shlib_version | 7 | ||||
-rw-r--r-- | dist/sig.c | 192 | ||||
-rw-r--r-- | dist/sig.h | 32 | ||||
-rw-r--r-- | dist/sys.h | 48 | ||||
-rw-r--r-- | dist/term.c | 2174 | ||||
-rw-r--r-- | dist/term.h | 120 | ||||
-rw-r--r-- | dist/termcap.h | 54 | ||||
-rw-r--r-- | dist/tokenizer.c | 567 | ||||
-rw-r--r-- | dist/tokenizer.h | 13 | ||||
-rw-r--r-- | dist/tty.c | 1915 | ||||
-rw-r--r-- | dist/tty.h | 113 | ||||
-rw-r--r-- | dist/vi.c | 1014 |
44 files changed, 11819 insertions, 8946 deletions
diff --git a/dist/Makefile b/dist/Makefile index fadbddf..837ed0e 100644 --- a/dist/Makefile +++ b/dist/Makefile @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.8 1997/05/09 07:50:14 mycroft Exp $ +# $NetBSD: Makefile,v 1.20 2001/01/05 21:15:49 jdolecek Exp $ # @(#)Makefile 8.1 (Berkeley) 6/4/93 LIB= edit @@ -10,54 +10,78 @@ MAN= editline.3 editrc.5 MLINKS= editline.3 el_init.3 editline.3 el_end.3 editline.3 el_reset.3 \ editline.3 el_gets.3 editline.3 el_getc.3 editline.3 el_push.3 \ - editline.3 el_parse.3 editline.3 el_set.3 editline.3 el_source.3 \ - editline.3 el_resize.3 editline.3 el_line.3 \ + editline.3 el_parse.3 editline.3 el_set.3 editline.3 el_get.3 \ + editline.3 el_source.3 editline.3 el_resize.3 editline.3 el_line.3 \ editline.3 el_insertstr.3 editline.3 el_deletestr.3 \ editline.3 history_init.3 editline.3 history_end.3 editline.3 history.3 # For speed and debugging -#SRCS= ${OSRCS} tokenizer.c history.c +#SRCS= ${OSRCS} tokenizer.c history.c readline.c # For protection -SRCS= editline.c tokenizer.c history.c +SRCS= editline.c tokenizer.c history.c readline.c SRCS+= common.h emacs.h fcns.h help.h vi.h +LIBEDITDIR?=${.CURDIR} + INCS= histedit.h INCSDIR=/usr/include CLEANFILES+=common.h editline.c emacs.h fcns.c fcns.h help.c help.h vi.h -CFLAGS+=-I. -I${.CURDIR} -CFLAGS+=#-DDEBUG_TTY -DDEBUG_KEY -DDEBUG_READ -DDEBUG -DDEBUG_REFRESH -CFLAGS+=#-DDEBUG_PASTE +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 +CPPFLAGS+=-I. -I${LIBEDITDIR} +CPPFLAGS+=-I. -I${.CURDIR} +CPPFLAGS+=#-DDEBUG_TTY -DDEBUG_KEY -DDEBUG_READ -DDEBUG -DDEBUG_REFRESH +CPPFLAGS+=#-DDEBUG_PASTE AHDR=vi.h emacs.h common.h -ASRC=${.CURDIR}/vi.c ${.CURDIR}/emacs.c ${.CURDIR}/common.c +ASRC=${LIBEDITDIR}/vi.c ${LIBEDITDIR}/emacs.c ${LIBEDITDIR}/common.c + +SUBDIR= readline vi.h: vi.c makelist - sh ${.CURDIR}/makelist -h ${.CURDIR}/vi.c > ${.TARGET} + sh ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/vi.c > ${.TARGET}.tmp && \ + mv ${.TARGET}.tmp ${.TARGET} emacs.h: emacs.c makelist - sh ${.CURDIR}/makelist -h ${.CURDIR}/emacs.c > ${.TARGET} + sh ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/emacs.c > ${.TARGET}.tmp && \ + mv ${.TARGET}.tmp ${.TARGET} common.h: common.c makelist - sh ${.CURDIR}/makelist -h ${.CURDIR}/common.c > ${.TARGET} + sh ${LIBEDITDIR}/makelist -h ${LIBEDITDIR}/common.c > ${.TARGET}.tmp && \ + mv ${.TARGET}.tmp ${.TARGET} fcns.h: ${AHDR} makelist - sh ${.CURDIR}/makelist -fh ${AHDR} > ${.TARGET} + sh ${LIBEDITDIR}/makelist -fh ${AHDR} > ${.TARGET}.tmp && \ + mv ${.TARGET}.tmp ${.TARGET} fcns.c: ${AHDR} fcns.h makelist - sh ${.CURDIR}/makelist -fc ${AHDR} > ${.TARGET} + sh ${LIBEDITDIR}/makelist -fc ${AHDR} > ${.TARGET}.tmp && \ + mv ${.TARGET}.tmp ${.TARGET} help.c: ${ASRC} makelist - sh ${.CURDIR}/makelist -bc ${ASRC} > ${.TARGET} + sh ${LIBEDITDIR}/makelist -bc ${ASRC} > ${.TARGET}.tmp && \ + mv ${.TARGET}.tmp ${.TARGET} help.h: ${ASRC} makelist - sh ${.CURDIR}/makelist -bh ${ASRC} > ${.TARGET} + sh ${LIBEDITDIR}/makelist -bh ${ASRC} > ${.TARGET}.tmp && \ + mv ${.TARGET}.tmp ${.TARGET} editline.c: ${OSRCS} - sh ${.CURDIR}/makelist -e ${.ALLSRC:T} > ${.TARGET} + sh ${LIBEDITDIR}/makelist -e ${.ALLSRC:T} > ${.TARGET}.tmp && \ + mv ${.TARGET}.tmp ${.TARGET} +test.o: ${LIBEDITDIR}/TEST/test.c + test: libedit.a test.o - ${CC} ${CFLAGS} ${.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.subdir.mk> diff --git a/dist/TEST/test.c b/dist/TEST/test.c index cc2202d..267cccf 100644 --- a/dist/TEST/test.c +++ b/dist/TEST/test.c @@ -1,4 +1,4 @@ -/* $NetBSD */ +/* $NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,17 +36,17 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #ifndef lint -static char copyright[] = -"@(#) Copyright (c) 1992, 1993\n\ - The Regents of the University of California. All rights reserved.\n"; +__COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\ + The Regents of the University of California. All rights reserved.\n"); #endif /* not lint */ #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD"; +__RCSID("$NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -69,182 +69,200 @@ static char rcsid[] = "$NetBSD"; static int continuation = 0; static EditLine *el = NULL; +static u_char complete(EditLine *, int); + int main(int, char **); +static char *prompt(EditLine *); +static void sig(int); + static char * -/*ARGSUSED*/ -prompt(el) - EditLine *el; +prompt(EditLine *el) { - static char a[] = "Edit$"; - static char b[] = "Edit>"; - return continuation ? b : a; + static char a[] = "Edit$"; + static char b[] = "Edit>"; + + return (continuation ? b : a); } static void -sig(i) - int i; +sig(int i) { - (void) fprintf(stderr, "Got signal %d.\n", i); - el_reset(el); + + (void) fprintf(stderr, "Got signal %d.\n", i); + el_reset(el); } static unsigned char -/*ARGSUSED*/ -complete(el, ch) - EditLine *el; - int ch; +complete(EditLine *el, int ch) { - DIR *dd = opendir("."); - struct dirent *dp; - const char* ptr; - const LineInfo *lf = el_line(el); - int len; - - /* - * Find the last word - */ - for (ptr = lf->cursor - 1; !isspace(*ptr) && ptr > lf->buffer; ptr--) - continue; - len = lf->cursor - ++ptr; - - for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) { - if (len > strlen(dp->d_name)) - continue; - if (strncmp(dp->d_name, ptr, len) == 0) { - closedir(dd); - if (el_insertstr(el, &dp->d_name[len]) == -1) - return CC_ERROR; - else - return CC_REFRESH; + DIR *dd = opendir("."); + struct dirent *dp; + const char* ptr; + const LineInfo *lf = el_line(el); + int len; + + /* + * Find the last word + */ + for (ptr = lf->cursor - 1; !isspace(*ptr) && ptr > lf->buffer; ptr--) + continue; + len = lf->cursor - ++ptr; + + for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) { + if (len > strlen(dp->d_name)) + continue; + if (strncmp(dp->d_name, ptr, len) == 0) { + closedir(dd); + if (el_insertstr(el, &dp->d_name[len]) == -1) + return (CC_ERROR); + else + return (CC_REFRESH); + } } - } - closedir(dd); - return CC_ERROR; + closedir(dd); + return (CC_ERROR); } int -/*ARGSUSED*/ -main(argc, argv) - int argc; - char *argv[]; +main(int argc, char *argv[]) { - int num; - const char *buf; - Tokenizer *tok; - History *hist; - - (void) signal(SIGINT, sig); - (void) signal(SIGQUIT, sig); - (void) signal(SIGHUP, sig); - (void) signal(SIGTERM, sig); - - hist = history_init(); /* Init the builtin history */ - history(hist, H_EVENT, 100); /* Remember 100 events */ - - tok = tok_init(NULL); /* Initialize the tokenizer */ - - el = el_init(*argv, stdin, stdout); /* Initialize editline */ - - el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */ - el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */ - el_set(el, EL_PROMPT, prompt); /* Set the prompt function */ - - /* Tell editline to use this history interface */ - el_set(el, EL_HIST, history, hist); - - /* Add a user-defined function */ - el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete); - - el_set(el, EL_BIND, "^I", "ed-complete", NULL);/* Bind tab to it */ - - /* - * Bind j, k in vi command mode to previous and next line, instead - * of previous and next history. - */ - el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL); - el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL); - - /* - * Source the user's defaults file. - */ - el_source(el, NULL); - - while ((buf = el_gets(el, &num)) != NULL && num != 0) { - int ac; - char **av; + int num; + const char *buf; + Tokenizer *tok; + int lastevent = 0, ncontinuation; + History *hist; + HistEvent ev; + + (void) signal(SIGINT, sig); + (void) signal(SIGQUIT, sig); + (void) signal(SIGHUP, sig); + (void) signal(SIGTERM, sig); + + hist = history_init(); /* Init the builtin history */ + /* Remember 100 events */ + history(hist, &ev, H_SETSIZE, 100); + + tok = tok_init(NULL); /* Initialize the tokenizer */ + + /* Initialize editline */ + el = el_init(*argv, stdin, stdout, stderr); + + el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */ + el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */ + el_set(el, EL_PROMPT, prompt); /* Set the prompt function */ + + /* Tell editline to use this history interface */ + el_set(el, EL_HIST, history, hist); + + /* Add a user-defined function */ + el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete); + + /* Bind tab to it */ + el_set(el, EL_BIND, "^I", "ed-complete", NULL); + + /* + * Bind j, k in vi command mode to previous and next line, instead + * of previous and next history. + */ + el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL); + el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL); + + /* + * Source the user's defaults file. + */ + el_source(el, NULL); + + while ((buf = el_gets(el, &num)) != NULL && num != 0) { + int ac; + char **av; #ifdef DEBUG - (void) fprintf(stderr, "got %d %s", num, buf); + (void) fprintf(stderr, "got %d %s", num, buf); #endif - if (!continuation && num == 1) - continue; + if (!continuation && num == 1) + continue; - if (tok_line(tok, buf, &ac, &av) > 0) { - history(hist, continuation ? H_ADD : H_ENTER, buf); - continuation = 1; - continue; - } + if (tok_line(tok, buf, &ac, &av) > 0) + ncontinuation = 1; - history(hist, continuation ? H_ADD : H_ENTER, buf); - - continuation = 0; - - if (strcmp(av[0], "history") == 0) { - const struct HistEvent *he; - - switch (ac) { - case 1: - for (he = history(hist, H_LAST); he; - he = history(hist, H_PREV)) - (void) fprintf(stdout, "%4d %s", he->num, he->str); - break; - - case 2: - if (strcmp(av[1], "clear") == 0) - history(hist, H_CLEAR); - else - goto badhist; - break; - - case 3: - if (strcmp(av[1], "load") == 0) - history(hist, H_LOAD, av[2]); - else if (strcmp(av[1], "save") == 0) - history(hist, H_SAVE, av[2]); - break; - - badhist: - default: - (void) fprintf(stderr, "Bad history arguments\n"); - break; - } - } - else if (el_parse(el, ac, av) == -1) { - switch (fork()) { - case 0: - execvp(av[0], av); - perror(av[0]); - _exit(1); - /*NOTREACHED*/ - break; - - case -1: - perror("fork"); - break; - - default: - if (wait(&num) == -1) - perror("wait"); - (void) fprintf(stderr, "Exit %x\n", num); - break; - } - } +#if 0 + if (continuation) { + /* + * Append to the right event in case the user + * moved around in history. + */ + if (history(hist, &ev, H_SET, lastevent) == -1) + err(1, "%d: %s\n", lastevent, ev.str); + history(hist, &ev, H_ADD , buf); + } else { + history(hist, &ev, H_ENTER, buf); + lastevent = ev.num; + } +#else + /* Simpler */ + history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf); +#endif - tok_reset(tok); - } + continuation = ncontinuation; + ncontinuation = 0; + + if (strcmp(av[0], "history") == 0) { + int rv; + + switch (ac) { + case 1: + for (rv = history(hist, &ev, H_LAST); rv != -1; + rv = history(hist, &ev, H_PREV)) + (void) fprintf(stdout, "%4d %s", + ev.num, ev.str); + break; + + case 2: + if (strcmp(av[1], "clear") == 0) + history(hist, &ev, H_CLEAR); + else + goto badhist; + break; + + case 3: + if (strcmp(av[1], "load") == 0) + history(hist, &ev, H_LOAD, av[2]); + else if (strcmp(av[1], "save") == 0) + history(hist, &ev, H_SAVE, av[2]); + break; + + badhist: + default: + (void) fprintf(stderr, + "Bad history arguments\n"); + break; + } + } else if (el_parse(el, ac, av) == -1) { + switch (fork()) { + case 0: + execvp(av[0], av); + perror(av[0]); + _exit(1); + /*NOTREACHED*/ + break; + + case -1: + perror("fork"); + break; + + default: + if (wait(&num) == -1) + perror("wait"); + (void) fprintf(stderr, "Exit %x\n", num); + break; + } + } + + tok_reset(tok); + } - el_end(el); - tok_end(tok); - history_end(hist); + el_end(el); + tok_end(tok); + history_end(hist); - return 0; + return (0); } diff --git a/dist/chared.c b/dist/chared.c index 82aa089..790f8ff 100644 --- a/dist/chared.c +++ b/dist/chared.c @@ -1,4 +1,4 @@ -/* $NetBSD: chared.c,v 1.2 1997/01/11 06:47:48 lukem Exp $ */ +/* $NetBSD: chared.c,v 1.14 2001/05/17 01:02:17 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,15 +36,16 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: chared.c,v 1.2 1997/01/11 06:47:48 lukem Exp $"; +__RCSID("$NetBSD: chared.c,v 1.14 2001/05/17 01:02:17 christos Exp $"); #endif #endif /* not lint && not SCCSID */ -/* +/* * chared.c: Character editor utilities */ #include "sys.h" @@ -52,72 +53,68 @@ static char rcsid[] = "$NetBSD: chared.c,v 1.2 1997/01/11 06:47:48 lukem Exp $"; #include <stdlib.h> #include "el.h" +/* value to leave unused in line buffer */ +#define EL_LEAVE 2 + /* cv_undo(): * Handle state for the vi undo command */ protected void -cv_undo(el, action, size, ptr) - EditLine *el; - int action, size; - char *ptr; +cv_undo(EditLine *el,int action, size_t size, char *ptr) { - c_undo_t *vu = &el->el_chared.c_undo; - vu->action = action; - vu->ptr = ptr; - vu->isize = size; - (void) memcpy(vu->buf, vu->ptr, size); + c_undo_t *vu = &el->el_chared.c_undo; + vu->action = action; + vu->ptr = ptr; + vu->isize = size; + (void) memcpy(vu->buf, vu->ptr, size); #ifdef DEBUG_UNDO - (void) fprintf(el->el_errfile, "Undo buffer \"%s\" size = +%d -%d\n", - vu->ptr, vu->isize, vu->dsize); + (void) fprintf(el->el_errfile, "Undo buffer \"%s\" size = +%d -%d\n", + vu->ptr, vu->isize, vu->dsize); #endif } -/* c_insert(): +/* c_insert(): * Insert num characters */ protected void -c_insert(el, num) - EditLine *el; - int num; +c_insert(EditLine *el, int num) { - char *cp; + char *cp; - if (el->el_line.lastchar + num >= el->el_line.limit) - return; /* can't go past end of buffer */ + if (el->el_line.lastchar + num >= el->el_line.limit) + return; /* can't go past end of buffer */ - if (el->el_line.cursor < el->el_line.lastchar) { - /* if I must move chars */ - for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--) - cp[num] = *cp; - } - el->el_line.lastchar += num; -} /* end c_insert */ + if (el->el_line.cursor < el->el_line.lastchar) { + /* if I must move chars */ + for (cp = el->el_line.lastchar; cp >= el->el_line.cursor; cp--) + cp[num] = *cp; + } + el->el_line.lastchar += num; +} /* c_delafter(): * Delete num characters after the cursor */ protected void -c_delafter(el, num) - EditLine *el; - int num; +c_delafter(EditLine *el, int num) { - if (el->el_line.cursor + num > el->el_line.lastchar) - num = el->el_line.lastchar - el->el_line.cursor; + if (el->el_line.cursor + num > el->el_line.lastchar) + num = el->el_line.lastchar - el->el_line.cursor; - if (num > 0) { - char *cp; + if (num > 0) { + char *cp; - if (el->el_map.current != el->el_map.emacs) - cv_undo(el, INSERT, num, el->el_line.cursor); + 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++) - *cp = cp[num]; + for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) + *cp = cp[num]; - el->el_line.lastchar -= num; - } + el->el_line.lastchar -= num; + } } @@ -125,25 +122,26 @@ c_delafter(el, num) * Delete num characters before the cursor */ protected void -c_delbefore(el, num) - EditLine *el; - int num; +c_delbefore(EditLine *el, int num) { - if (el->el_line.cursor - num < el->el_line.buffer) - num = el->el_line.cursor - el->el_line.buffer; + if (el->el_line.cursor - num < el->el_line.buffer) + num = el->el_line.cursor - el->el_line.buffer; - if (num > 0) { - char *cp; + if (num > 0) { + char *cp; - if (el->el_map.current != el->el_map.emacs) - cv_undo(el, INSERT, num, el->el_line.cursor - num); + 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; cp <= el->el_line.lastchar; cp++) - *cp = cp[num]; + for (cp = el->el_line.cursor - num; + cp <= el->el_line.lastchar; + cp++) + *cp = cp[num]; - el->el_line.lastchar -= num; - } + el->el_line.lastchar -= num; + } } @@ -151,10 +149,9 @@ c_delbefore(el, num) * Return if p is part of a word according to emacs */ protected int -ce__isword(p) - int p; +ce__isword(int p) { - return isalpha(p) || isdigit(p) || strchr("*?_-.[]~=", p) != NULL; + return (isalpha(p) || isdigit(p) || strchr("*?_-.[]~=", p) != NULL); } @@ -162,10 +159,9 @@ ce__isword(p) * Return if p is part of a word according to vi */ protected int -cv__isword(p) - int p; +cv__isword(int p) { - return !isspace(p); + return (!isspace(p)); } @@ -173,26 +169,23 @@ cv__isword(p) * Find the previous word */ protected char * -c__prev_word(p, low, n, wtest) - register char *p, *low; - register int n; - int (*wtest) __P((int)); +c__prev_word(char *p, char *low, int n, int (*wtest)(int)) { - p--; - - while (n--) { - while ((p >= low) && !(*wtest)((unsigned char) *p)) - p--; - while ((p >= low) && (*wtest)((unsigned char) *p)) - p--; - } - - /* cp now points to one character before the word */ - p++; - if (p < low) - p = low; - /* cp now points where we want it */ - return p; + p--; + + while (n--) { + while ((p >= low) && !(*wtest)((unsigned char) *p)) + p--; + while ((p >= low) && (*wtest)((unsigned char) *p)) + p--; + } + + /* cp now points to one character before the word */ + p++; + if (p < low) + p = low; + /* cp now points where we want it */ + return (p); } @@ -200,53 +193,46 @@ c__prev_word(p, low, n, wtest) * Find the next word */ protected char * -c__next_word(p, high, n, wtest) - register char *p, *high; - register int n; - int (*wtest) __P((int)); +c__next_word(char *p, char *high, int n, int (*wtest)(int)) { - while (n--) { - while ((p < high) && !(*wtest)((unsigned char) *p)) - p++; - while ((p < high) && (*wtest)((unsigned char) *p)) - p++; - } - if (p > high) - p = high; - /* p now points where we want it */ - return p; + while (n--) { + while ((p < high) && !(*wtest)((unsigned char) *p)) + p++; + while ((p < high) && (*wtest)((unsigned char) *p)) + p++; + } + if (p > high) + p = high; + /* p now points where we want it */ + return (p); } /* cv_next_word(): * Find the next word vi style */ protected char * -cv_next_word(el, p, high, n, wtest) - EditLine *el; - register char *p, *high; - register int n; - int (*wtest) __P((int)); +cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int)) { - int test; - - while (n--) { - test = (*wtest)((unsigned char) *p); - while ((p < high) && (*wtest)((unsigned char) *p) == test) - p++; - /* - * vi historically deletes with cw only the word preserving the - * trailing whitespace! This is not what 'w' does.. - */ - if (el->el_chared.c_vcmd.action != (DELETE|INSERT)) - while ((p < high) && isspace((unsigned char) *p)) - p++; - } + int test; + + while (n--) { + test = (*wtest)((unsigned char) *p); + while ((p < high) && (*wtest)((unsigned char) *p) == test) + p++; + /* + * vi historically deletes with cw only the word preserving the + * trailing whitespace! This is not what 'w' does.. + */ + if (el->el_chared.c_vcmd.action != (DELETE|INSERT)) + while ((p < high) && isspace((unsigned char) *p)) + p++; + } - /* p now points where we want it */ - if (p > high) - return high; - else - return p; + /* p now points where we want it */ + if (p > high) + return (high); + else + return (p); } @@ -254,36 +240,32 @@ cv_next_word(el, p, high, n, wtest) * Find the previous word vi style */ protected char * -cv_prev_word(el, p, low, n, wtest) - EditLine *el; - register char *p, *low; - register int n; - int (*wtest) __P((int)); +cv_prev_word(EditLine *el, char *p, char *low, int n, int (*wtest)(int)) { - int test; + int test; - while (n--) { - 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)) + while (n--) { p--; - test = (*wtest)((unsigned char) *p); - while ((p >= low) && (*wtest)((unsigned char) *p) == test) - p--; - p++; - while (isspace((unsigned char) *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); + while ((p >= low) && (*wtest)((unsigned char) *p) == test) + p--; p++; - } + while (isspace((unsigned char) *p)) + p++; + } - /* p now points where we want it */ - if (p < low) - return low; - else - return p; + /* p now points where we want it */ + if (p < low) + return (low); + else + return (p); } @@ -294,30 +276,30 @@ cv_prev_word(el, p, low, n, wtest) * Return p pointing to last char used. */ protected char * -c__number(p, num, dval) - char *p; /* character position */ - int *num; /* Return value */ - int dval; /* dval is the number to subtract from like $-3 */ +c__number( + char *p, /* character position */ + int *num, /* Return value */ + int dval) /* dval is the number to subtract from like $-3 */ { - register int i; - register int sign = 1; - - if (*++p == '^') { - *num = 1; - return p; - } - if (*p == '$') { - if (*++p != '-') { - *num = 0x7fffffff; /* Handle $ */ - return --p; + int i; + int sign = 1; + + if (*++p == '^') { + *num = 1; + return (p); + } + if (*p == '$') { + if (*++p != '-') { + *num = 0x7fffffff; /* Handle $ */ + return (--p); + } + sign = -1; /* Handle $- */ + ++p; } - sign = -1; /* Handle $- */ - ++p; - } - for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0') - continue; - *num = (sign < 0 ? dval - i : i); - return --p; + for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0') + continue; + *num = (sign < 0 ? dval - i : i); + return (--p); } #endif @@ -325,53 +307,50 @@ c__number(p, num, dval) * Finish vi delete action */ protected void -cv_delfini(el) - EditLine *el; +cv_delfini(EditLine *el) { - register int size; - int oaction; - - if (el->el_chared.c_vcmd.action & INSERT) - 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) - return; - - - if (el->el_line.cursor > el->el_chared.c_vcmd.pos) { - 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; - c_delafter(el, size); - } - switch (oaction) { - 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: - abort(); - break; - } - + int size; + int oaction; + + if (el->el_chared.c_vcmd.action & INSERT) + 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) + return; + + + if (el->el_line.cursor > el->el_chared.c_vcmd.pos) { + 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; + c_delafter(el, size); + } + switch (oaction) { + 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; + el->el_chared.c_undo.ptr = el->el_line.cursor; + el->el_chared.c_undo.dsize = size; } @@ -380,21 +359,19 @@ cv_delfini(el) * Go to the end of this word according to emacs */ protected char * -ce__endword(p, high, n) - char *p, *high; - int n; +ce__endword(char *p, char *high, int n) { - p++; + p++; - while (n--) { - while ((p < high) && isspace((unsigned char) *p)) - p++; - while ((p < high) && !isspace((unsigned char) *p)) - p++; - } + while (n--) { + while ((p < high) && isspace((unsigned char) *p)) + p++; + while ((p < high) && !isspace((unsigned char) *p)) + p++; + } - p--; - return p; + p--; + return (p); } #endif @@ -403,124 +380,205 @@ ce__endword(p, high, n) * Go to the end of this word according to vi */ protected char * -cv__endword(p, high, n) - char *p, *high; - int n; +cv__endword(char *p, char *high, int n) { - p++; - - while (n--) { - while ((p < high) && isspace((unsigned char) *p)) - p++; + p++; - if (isalnum((unsigned char) *p)) - while ((p < high) && isalnum((unsigned char) *p)) - p++; - else - while ((p < high) && !(isspace((unsigned char) *p) || - isalnum((unsigned char) *p))) - p++; - } - p--; - return p; + while (n--) { + while ((p < high) && isspace((unsigned char) *p)) + p++; + + if (isalnum((unsigned char) *p)) + while ((p < high) && isalnum((unsigned char) *p)) + p++; + else + while ((p < high) && !(isspace((unsigned char) *p) || + isalnum((unsigned char) *p))) + p++; + } + p--; + return (p); } /* ch_init(): * Initialize the character editor */ protected int -ch_init(el) - EditLine *el; +ch_init(EditLine *el) { - el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ); - (void) memset(el->el_line.buffer, 0, EL_BUFSIZ); - el->el_line.cursor = el->el_line.buffer; - el->el_line.lastchar = el->el_line.buffer; - el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - 2]; - - el->el_chared.c_undo.buf = (char *) el_malloc(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.isize = 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.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); - (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ); - el->el_chared.c_kill.mark = el->el_line.buffer; - el->el_chared.c_kill.last = el->el_chared.c_kill.buf; - - el->el_map.current = el->el_map.key; - - el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */ - el->el_state.doingarg = 0; - el->el_state.metanext = 0; - el->el_state.argument = 1; - el->el_state.lastcmd = ED_UNASSIGNED; - - el->el_chared.c_macro.nline = NULL; - el->el_chared.c_macro.level = -1; - el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO * - sizeof(char *)); - return 0; + el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ); + if (el->el_line.buffer == NULL) + return (-1); + + (void) memset(el->el_line.buffer, 0, EL_BUFSIZ); + el->el_line.cursor = el->el_line.buffer; + el->el_line.lastchar = el->el_line.buffer; + el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - 2]; + + el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ); + if (el->el_chared.c_undo.buf == NULL) + return (-1); + (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ); + el->el_chared.c_undo.action = NOP; + el->el_chared.c_undo.isize = 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.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); + if (el->el_chared.c_kill.buf == NULL) + return (-1); + (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ); + el->el_chared.c_kill.mark = el->el_line.buffer; + el->el_chared.c_kill.last = el->el_chared.c_kill.buf; + + el->el_map.current = el->el_map.key; + + el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */ + el->el_state.doingarg = 0; + el->el_state.metanext = 0; + el->el_state.argument = 1; + el->el_state.lastcmd = ED_UNASSIGNED; + + el->el_chared.c_macro.nline = NULL; + el->el_chared.c_macro.level = -1; + el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO * + sizeof(char *)); + if (el->el_chared.c_macro.macro == NULL) + return (-1); + return (0); } /* ch_reset(): * Reset the character editor */ protected void -ch_reset(el) - EditLine *el; +ch_reset(EditLine *el) { - el->el_line.cursor = el->el_line.buffer; - el->el_line.lastchar = el->el_line.buffer; + el->el_line.cursor = el->el_line.buffer; + el->el_line.lastchar = el->el_line.buffer; - el->el_chared.c_undo.action = NOP; - el->el_chared.c_undo.isize = 0; - el->el_chared.c_undo.dsize = 0; - el->el_chared.c_undo.ptr = el->el_line.buffer; + el->el_chared.c_undo.action = NOP; + el->el_chared.c_undo.isize = 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.pos = el->el_line.buffer; - el->el_chared.c_vcmd.ins = el->el_line.buffer; + el->el_chared.c_vcmd.action = NOP; + 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; - el->el_map.current = el->el_map.key; + el->el_map.current = el->el_map.key; - el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */ - el->el_state.doingarg = 0; - el->el_state.metanext = 0; - el->el_state.argument = 1; - el->el_state.lastcmd = ED_UNASSIGNED; + el->el_state.inputmode = MODE_INSERT; /* XXX: save a default */ + el->el_state.doingarg = 0; + el->el_state.metanext = 0; + el->el_state.argument = 1; + el->el_state.lastcmd = ED_UNASSIGNED; - el->el_chared.c_macro.level = -1; + el->el_chared.c_macro.level = -1; - el->el_history.eventno = 0; + el->el_history.eventno = 0; } +/* ch_enlargebufs(): + * Enlarge line buffer to be able to hold twice as much characters. + * Returns 1 if successful, 0 if not. + */ +protected int +ch_enlargebufs(el, addlen) + EditLine *el; + size_t addlen; +{ + size_t sz, newsz; + char *newbuffer, *oldbuf, *oldkbuf; + + sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE; + newsz = sz * 2; + /* + * If newly required length is longer than current buffer, we need + * to make the buffer big enough to hold both old and new stuff. + */ + if (addlen > sz) { + while(newsz - sz < addlen) + newsz *= 2; + } + + /* + * Reallocate line buffer. + */ + newbuffer = el_realloc(el->el_line.buffer, newsz); + if (!newbuffer) + return 0; + + /* zero the newly added memory, leave old data in */ + (void) memset(&newbuffer[sz], 0, newsz - sz); + + oldbuf = el->el_line.buffer; + + el->el_line.buffer = newbuffer; + el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf); + el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf); + el->el_line.limit = &newbuffer[newsz - EL_LEAVE]; + + /* + * Reallocate kill buffer. + */ + newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz); + if (!newbuffer) + return 0; + + /* zero the newly added memory, leave old data in */ + (void) memset(&newbuffer[sz], 0, newsz - sz); + + oldkbuf = el->el_chared.c_kill.buf; + + el->el_chared.c_kill.buf = newbuffer; + el->el_chared.c_kill.last = newbuffer + + (el->el_chared.c_kill.last - oldkbuf); + el->el_chared.c_kill.mark = el->el_line.buffer + + (el->el_chared.c_kill.mark - oldbuf); + + /* + * Reallocate undo buffer. + */ + newbuffer = el_realloc(el->el_chared.c_undo.buf, newsz); + if (!newbuffer) + return 0; + + /* zero the newly added memory, leave old data in */ + (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; + + if (!hist_enlargebuf(el, sz, newsz)) + return 0; + + return 1; +} /* ch_end(): * Free the data structures used by the editor */ protected void -ch_end(el) - EditLine *el; +ch_end(EditLine *el) { - el_free((ptr_t) el->el_line.buffer); - el->el_line.buffer = NULL; - el->el_line.limit = NULL; - el_free((ptr_t) el->el_chared.c_undo.buf); - el->el_chared.c_undo.buf = NULL; - el_free((ptr_t) el->el_chared.c_kill.buf); - el->el_chared.c_kill.buf = NULL; - el_free((ptr_t) el->el_chared.c_macro.macro); - el->el_chared.c_macro.macro = NULL; - ch_reset(el); + el_free((ptr_t) el->el_line.buffer); + el->el_line.buffer = NULL; + el->el_line.limit = NULL; + el_free((ptr_t) el->el_chared.c_undo.buf); + el->el_chared.c_undo.buf = NULL; + el_free((ptr_t) el->el_chared.c_kill.buf); + el->el_chared.c_kill.buf = NULL; + el_free((ptr_t) el->el_chared.c_macro.macro); + el->el_chared.c_macro.macro = NULL; + ch_reset(el); } @@ -528,21 +586,21 @@ ch_end(el) * Insert string at cursorI */ public int -el_insertstr(el, s) - EditLine *el; - char *s; +el_insertstr(EditLine *el, const char *s) { - int len; + size_t len; - if ((len = strlen(s)) == 0) - return -1; - if (el->el_line.lastchar + len >= el->el_line.limit) - return -1; + if ((len = strlen(s)) == 0) + return (-1); + if (el->el_line.lastchar + len >= el->el_line.limit) { + if (!ch_enlargebufs(el, len)) + return (-1); + } - c_insert(el, len); - while (*s) - *el->el_line.cursor++ = *s++; - return 0; + c_insert(el, (int)len); + while (*s) + *el->el_line.cursor++ = *s++; + return (0); } @@ -550,74 +608,69 @@ el_insertstr(el, s) * Delete num characters before the cursor */ public void -el_deletestr(el, n) - EditLine *el; - int n; +el_deletestr(EditLine *el, int n) { - if (n <= 0) - return; + if (n <= 0) + return; - if (el->el_line.cursor < &el->el_line.buffer[n]) - return; + if (el->el_line.cursor < &el->el_line.buffer[n]) + return; - c_delbefore(el, n); /* delete before dot */ - el->el_line.cursor -= n; - if (el->el_line.cursor < el->el_line.buffer) - el->el_line.cursor = el->el_line.buffer; + c_delbefore(el, n); /* delete before dot */ + el->el_line.cursor -= n; + if (el->el_line.cursor < el->el_line.buffer) + el->el_line.cursor = el->el_line.buffer; } /* c_gets(): * Get a string */ protected int -c_gets(el, buf) - EditLine *el; - char *buf; +c_gets(EditLine *el, char *buf) { - char ch; - int len = 0; - - for (ch = 0; ch == 0;) { - if (el_getc(el, &ch) != 1) - return ed_end_of_file(el, 0); - switch (ch) { - case 0010: /* Delete and backspace */ - case 0177: - if (len > 1) { - *el->el_line.cursor-- = '\0'; - el->el_line.lastchar = el->el_line.cursor; - 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); - ch = 0; - break; - - case 0033: /* ESC */ - case '\r': /* Newline */ - case '\n': - break; - - default: - if (len >= EL_BUFSIZ) - term_beep(el); - else { - buf[len++] = ch; - *el->el_line.cursor++ = ch; - el->el_line.lastchar = el->el_line.cursor; - } - re_refresh(el); - ch = 0; - break; + char ch; + int len = 0; + + for (ch = 0; ch == 0;) { + if (el_getc(el, &ch) != 1) + return (ed_end_of_file(el, 0)); + switch (ch) { + case 0010: /* Delete and backspace */ + case 0177: + if (len > 1) { + *el->el_line.cursor-- = '\0'; + el->el_line.lastchar = el->el_line.cursor; + 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); + ch = 0; + break; + + case 0033: /* ESC */ + case '\r': /* Newline */ + case '\n': + break; + + default: + if (len >= EL_BUFSIZ) + term_beep(el); + else { + buf[len++] = ch; + *el->el_line.cursor++ = ch; + el->el_line.lastchar = el->el_line.cursor; + } + re_refresh(el); + ch = 0; + break; + } } - } - buf[len] = ch; - return len; + buf[len] = ch; + return (len); } @@ -625,21 +678,20 @@ c_gets(el, buf) * Return the current horizontal position of the cursor */ protected int -c_hpos(el) - EditLine *el; +c_hpos(EditLine *el) { - char *ptr; - - /* - * Find how many characters till the beginning of this line. - */ - if (el->el_line.cursor == el->el_line.buffer) - return 0; - else { - for (ptr = el->el_line.cursor - 1; - ptr >= el->el_line.buffer && *ptr != '\n'; - ptr--) - continue; - return el->el_line.cursor - ptr - 1; - } + char *ptr; + + /* + * Find how many characters till the beginning of this line. + */ + if (el->el_line.cursor == el->el_line.buffer) + return (0); + else { + for (ptr = el->el_line.cursor - 1; + ptr >= el->el_line.buffer && *ptr != '\n'; + ptr--) + continue; + return (el->el_line.cursor - ptr - 1); + } } diff --git a/dist/chared.h b/dist/chared.h index 4e7c285..2eb9ad3 100644 --- a/dist/chared.h +++ b/dist/chared.h @@ -1,4 +1,4 @@ -/* $NetBSD: chared.h,v 1.2 1997/01/11 06:47:49 lukem Exp $ */ +/* $NetBSD: chared.h,v 1.6 2001/01/10 07:45:41 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,61 +42,61 @@ * el.chared.h: Character editor interface */ #ifndef _h_el_chared -#define _h_el_chared +#define _h_el_chared #include <ctype.h> #include <string.h> #include "histedit.h" -#define EL_MAXMACRO 10 +#define EL_MAXMACRO 10 /* * This is a issue of basic "vi" look-and-feel. Defining VI_MOVE works * like real vi: i.e. the transition from command<->insert modes moves * the cursor. * - * On the other hand we really don't want to move the cursor, because + * On the other hand we really don't want to move the cursor, because * all the editing commands don't include the character under the cursor. * Probably the best fix is to make all the editing commands aware of * this fact. */ -#define VI_MOVE +#define VI_MOVE typedef struct c_macro_t { - int level; - char **macro; - char *nline; + int level; + char **macro; + char *nline; } c_macro_t; -/* +/* * Undo information for both vi and emacs */ typedef struct c_undo_t { - int action; - int isize; - int dsize; - char *ptr; - char *buf; + int action; + size_t isize; + size_t dsize; + char *ptr; + char *buf; } c_undo_t; /* * Current action information for vi */ typedef struct c_vcmd_t { - int action; - char *pos; - char *ins; + int action; + char *pos; + char *ins; } c_vcmd_t; /* * Kill buffer for emacs */ typedef struct c_kill_t { - char *buf; - char *last; - char *mark; + char *buf; + char *last; + char *mark; } c_kill_t; /* @@ -104,30 +104,30 @@ typedef struct c_kill_t { * commands from both editors! */ typedef struct el_chared_t { - c_undo_t c_undo; - c_kill_t c_kill; - c_vcmd_t c_vcmd; - c_macro_t c_macro; + c_undo_t c_undo; + c_kill_t c_kill; + c_vcmd_t c_vcmd; + c_macro_t c_macro; } el_chared_t; -#define STReof "^D\b\b" -#define STRQQ "\"\"" +#define STReof "^D\b\b" +#define STRQQ "\"\"" -#define isglob(a) (strchr("*[]?", (a)) != NULL) -#define isword(a) (isprint(a)) +#define isglob(a) (strchr("*[]?", (a)) != NULL) +#define isword(a) (isprint(a)) -#define NOP 0x00 -#define DELETE 0x01 -#define INSERT 0x02 -#define CHANGE 0x04 +#define NOP 0x00 +#define DELETE 0x01 +#define INSERT 0x02 +#define CHANGE 0x04 -#define CHAR_FWD 0 -#define CHAR_BACK 1 +#define CHAR_FWD 0 +#define CHAR_BACK 1 -#define MODE_INSERT 0 -#define MODE_REPLACE 1 -#define MODE_REPLACE_1 2 +#define MODE_INSERT 0 +#define MODE_REPLACE 1 +#define MODE_REPLACE_1 2 #include "common.h" #include "vi.h" @@ -136,25 +136,24 @@ typedef struct el_chared_t { #include "fcns.h" -protected int cv__isword __P((int)); -protected void cv_delfini __P((EditLine *)); -protected char *cv__endword __P((char *, char *, int)); -protected int ce__isword __P((int)); -protected void cv_undo __P((EditLine *, int, int, char *)); -protected char *cv_next_word __P((EditLine*, char *, char *, int, - int (*)(int))); -protected char *cv_prev_word __P((EditLine*, char *, char *, int, - int (*)(int))); -protected char *c__next_word __P((char *, char *, int, int (*)(int))); -protected char *c__prev_word __P((char *, char *, int, int (*)(int))); -protected void c_insert __P((EditLine *, int)); -protected void c_delbefore __P((EditLine *, int)); -protected void c_delafter __P((EditLine *, int)); -protected int c_gets __P((EditLine *, char *)); -protected int c_hpos __P((EditLine *)); - -protected int ch_init __P((EditLine *)); -protected void ch_reset __P((EditLine *)); -protected void ch_end __P((EditLine *)); +protected int cv__isword(int); +protected void cv_delfini(EditLine *); +protected char *cv__endword(char *, char *, int); +protected int ce__isword(int); +protected void cv_undo(EditLine *, int, size_t, char *); +protected char *cv_next_word(EditLine*, char *, char *, int, int (*)(int)); +protected char *cv_prev_word(EditLine*, char *, char *, int, int (*)(int)); +protected char *c__next_word(char *, char *, int, int (*)(int)); +protected char *c__prev_word(char *, char *, int, int (*)(int)); +protected void c_insert(EditLine *, int); +protected void c_delbefore(EditLine *, int); +protected void c_delafter(EditLine *, int); +protected int c_gets(EditLine *, char *); +protected int c_hpos(EditLine *); + +protected int ch_init(EditLine *); +protected void ch_reset(EditLine *); +protected int ch_enlargebufs __P((EditLine *, size_t)); +protected void ch_end(EditLine *); #endif /* _h_el_chared */ diff --git a/dist/common.c b/dist/common.c index a0636cb..dfb8a71 100644 --- a/dist/common.c +++ b/dist/common.c @@ -1,4 +1,4 @@ -/* $NetBSD: common.c,v 1.3 1997/01/14 04:17:22 lukem Exp $ */ +/* $NetBSD: common.c,v 1.10 2001/01/10 07:45:41 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,11 +36,12 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: common.c,v 1.3 1997/01/14 04:17:22 lukem Exp $"; +__RCSID("$NetBSD: common.c,v 1.10 2001/01/10 07:45:41 jdolecek Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -50,442 +51,425 @@ static char rcsid[] = "$NetBSD: common.c,v 1.3 1997/01/14 04:17:22 lukem Exp $"; #include "sys.h" #include "el.h" -/* ed_end_of_file(): +/* ed_end_of_file(): * Indicate end of file * [^D] */ protected el_action_t /*ARGSUSED*/ -ed_end_of_file(el, c) - EditLine *el; - int c; +ed_end_of_file(EditLine *el, int c) { - re_goto_bottom(el); - *el->el_line.lastchar = '\0'; - return CC_EOF; + + re_goto_bottom(el); + *el->el_line.lastchar = '\0'; + return (CC_EOF); } -/* ed_insert(): +/* ed_insert(): * Add character to the line * Insert a character [bound to all insert keys] */ protected el_action_t -ed_insert(el, c) - EditLine *el; - int c; +ed_insert(EditLine *el, int c) { - int i; - - if (c == '\0') - return CC_ERROR; - - if (el->el_line.lastchar + el->el_state.argument >= - el->el_line.limit) - return CC_ERROR; /* end of buffer space */ - - if (el->el_state.argument == 1) { - 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; /* just in case */ - re_fastaddc(el); /* fast refresh for one char. */ - } - else { - if (el->el_state.inputmode != MODE_INSERT) { + int i; - for(i = 0;i < el->el_state.argument; i++) - el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] = - el->el_line.cursor[i]; + if (c == '\0') + return (CC_ERROR); - el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = '\0'; - c_delafter(el, el->el_state.argument); - } - - c_insert(el, el->el_state.argument); + if (el->el_line.lastchar + el->el_state.argument >= + el->el_line.limit) { + /* end of buffer space, try to allocate more */ + if (!ch_enlargebufs(el, (size_t) el->el_state.argument)) + return CC_ERROR; /* error allocating more */ + } - while (el->el_state.argument--) - *el->el_line.cursor++ = c; - re_refresh(el); - } + if (el->el_state.argument == 1) { + 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; /* just in case */ + re_fastaddc(el); /* fast refresh for one char. */ + } else { + if (el->el_state.inputmode != MODE_INSERT) { + for (i = 0; i < el->el_state.argument; i++) + 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] = + '\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; + re_refresh(el); + } - if (el->el_state.inputmode == MODE_REPLACE_1) - (void) vi_command_mode(el, 0); + if (el->el_state.inputmode == MODE_REPLACE_1) + (void) vi_command_mode(el, 0); - return CC_NORM; + return (CC_NORM); } -/* ed_delete_prev_word(): +/* ed_delete_prev_word(): * Delete from beginning of current word to cursor * [M-^?] [^W] */ protected el_action_t /*ARGSUSED*/ -ed_delete_prev_word(el, c) - EditLine *el; - int c; +ed_delete_prev_word(EditLine *el, int c) { - char *cp, *p, *kp; + char *cp, *p, *kp; - if (el->el_line.cursor == el->el_line.buffer) - return CC_ERROR; + if (el->el_line.cursor == el->el_line.buffer) + return (CC_ERROR); - cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, - el->el_state.argument, ce__isword); + cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, + el->el_state.argument, ce__isword); - for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++) - *kp++ = *p; - el->el_chared.c_kill.last = kp; + for (p = cp, kp = el->el_chared.c_kill.buf; p < el->el_line.cursor; p++) + *kp++ = *p; + el->el_chared.c_kill.last = kp; - c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */ - el->el_line.cursor = cp; - if (el->el_line.cursor < el->el_line.buffer) - el->el_line.cursor = el->el_line.buffer; /* bounds check */ - return CC_REFRESH; + c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */ + el->el_line.cursor = cp; + if (el->el_line.cursor < el->el_line.buffer) + el->el_line.cursor = el->el_line.buffer; /* bounds check */ + return (CC_REFRESH); } -/* ed_delete_next_char(): +/* ed_delete_next_char(): * Delete character under cursor * [^D] [x] */ protected el_action_t /*ARGSUSED*/ -ed_delete_next_char(el, c) - EditLine *el; - int c; -{ -#ifdef notdef /* XXX */ -#define EL el->el_line -fprintf(stderr, "\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n", - EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar, EL.lastchar, EL.limit, EL.limit); +ed_delete_next_char(EditLine *el, int c) +{ +#ifdef notdef /* XXX */ +#define EL el->el_line + (void) fprintf(el->el_errlfile, + "\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n", + EL.buffer, EL.buffer, EL.cursor, EL.cursor, EL.lastchar, + EL.lastchar, EL.limit, EL.limit); #endif - if (el->el_line.cursor == el->el_line.lastchar) {/* if I'm at the end */ - if (el->el_map.type == MAP_VI) { - if (el->el_line.cursor == el->el_line.buffer) { - /* if I'm also at the beginning */ + if (el->el_line.cursor == el->el_line.lastchar) { + /* if I'm at the end */ + if (el->el_map.type == MAP_VI) { + if (el->el_line.cursor == el->el_line.buffer) { + /* if I'm also at the beginning */ #ifdef KSHVI - return CC_ERROR; + return (CC_ERROR); #else - term_overwrite(el, STReof, 4);/* then do a EOF */ - term__flush(); - return CC_EOF; + term_overwrite(el, STReof, 4); + /* then do a EOF */ + term__flush(); + return (CC_EOF); #endif - } - else { + } else { #ifdef KSHVI - el->el_line.cursor--; + el->el_line.cursor--; #else - return CC_ERROR; + return (CC_ERROR); #endif - } - } - else { - if (el->el_line.cursor != el->el_line.buffer) - el->el_line.cursor--; - else - return CC_ERROR; + } + } else { + if (el->el_line.cursor != el->el_line.buffer) + el->el_line.cursor--; + else + return (CC_ERROR); + } } - } - c_delafter(el, el->el_state.argument); /* delete after dot */ - if (el->el_line.cursor >= el->el_line.lastchar && el->el_line.cursor > el->el_line.buffer) - el->el_line.cursor = el->el_line.lastchar - 1; /* bounds check */ - return CC_REFRESH; + c_delafter(el, el->el_state.argument); /* delete after dot */ + if (el->el_line.cursor >= el->el_line.lastchar && + el->el_line.cursor > el->el_line.buffer) + /* bounds check */ + el->el_line.cursor = el->el_line.lastchar - 1; + return (CC_REFRESH); } -/* ed_kill_line(): +/* ed_kill_line(): * Cut to the end of line * [^K] [^K] */ protected el_action_t /*ARGSUSED*/ -ed_kill_line(el, c) - EditLine *el; - int c; +ed_kill_line(EditLine *el, int c) { - char *kp, *cp; + char *kp, *cp; - cp = el->el_line.cursor; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_line.lastchar) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - el->el_line.lastchar = el->el_line.cursor; /* zap! -- delete to end */ - return CC_REFRESH; + cp = el->el_line.cursor; + kp = el->el_chared.c_kill.buf; + while (cp < el->el_line.lastchar) + *kp++ = *cp++; /* copy it */ + el->el_chared.c_kill.last = kp; + /* zap! -- delete to end */ + el->el_line.lastchar = el->el_line.cursor; + return (CC_REFRESH); } -/* ed_move_to_end(): +/* ed_move_to_end(): * Move cursor to the end of line * [^E] [^E] */ protected el_action_t /*ARGSUSED*/ -ed_move_to_end(el, c) - EditLine *el; - int c; +ed_move_to_end(EditLine *el, int c) { - el->el_line.cursor = el->el_line.lastchar; - if (el->el_map.type == MAP_VI) { + + el->el_line.cursor = el->el_line.lastchar; + if (el->el_map.type == MAP_VI) { #ifdef VI_MOVE - el->el_line.cursor--; + el->el_line.cursor--; #endif - if (el->el_chared.c_vcmd.action & DELETE) { - cv_delfini(el); - return CC_REFRESH; + if (el->el_chared.c_vcmd.action & DELETE) { + cv_delfini(el); + return (CC_REFRESH); + } } - } - return CC_CURSOR; + return (CC_CURSOR); } -/* ed_move_to_beg(): +/* ed_move_to_beg(): * Move cursor to the beginning of line * [^A] [^A] */ protected el_action_t /*ARGSUSED*/ -ed_move_to_beg(el, c) - EditLine *el; - int c; -{ - el->el_line.cursor = el->el_line.buffer; - - if (el->el_map.type == MAP_VI) { - /* We want FIRST non space character */ - while (isspace(*el->el_line.cursor)) - el->el_line.cursor++; - if (el->el_chared.c_vcmd.action & DELETE) { - cv_delfini(el); - return CC_REFRESH; - } - } +ed_move_to_beg(EditLine *el, int c) +{ - return CC_CURSOR; + el->el_line.cursor = el->el_line.buffer; + + if (el->el_map.type == MAP_VI) { + /* We want FIRST non space character */ + while (isspace((unsigned char) *el->el_line.cursor)) + el->el_line.cursor++; + if (el->el_chared.c_vcmd.action & DELETE) { + cv_delfini(el); + return (CC_REFRESH); + } + } + return (CC_CURSOR); } -/* ed_transpose_chars(): +/* ed_transpose_chars(): * Exchange the character to the left of the cursor with the one under it * [^T] [^T] */ protected el_action_t -ed_transpose_chars(el, c) - EditLine *el; - int c; +ed_transpose_chars(EditLine *el, int c) { - if (el->el_line.cursor < el->el_line.lastchar) { - if (el->el_line.lastchar <= &el->el_line.buffer[1]) - return CC_ERROR; - else - el->el_line.cursor++; - } - if (el->el_line.cursor > &el->el_line.buffer[1]) { - /* must have at least two chars entered */ - c = el->el_line.cursor[-2]; - el->el_line.cursor[-2] = el->el_line.cursor[-1]; - el->el_line.cursor[-1] = c; - return CC_REFRESH; - } - else - return CC_ERROR; + + if (el->el_line.cursor < el->el_line.lastchar) { + if (el->el_line.lastchar <= &el->el_line.buffer[1]) + return (CC_ERROR); + else + el->el_line.cursor++; + } + if (el->el_line.cursor > &el->el_line.buffer[1]) { + /* must have at least two chars entered */ + c = el->el_line.cursor[-2]; + el->el_line.cursor[-2] = el->el_line.cursor[-1]; + el->el_line.cursor[-1] = c; + return (CC_REFRESH); + } else + return (CC_ERROR); } -/* ed_next_char(): +/* ed_next_char(): * Move to the right one character * [^F] [^F] */ protected el_action_t /*ARGSUSED*/ -ed_next_char(el, c) - EditLine *el; - int c; +ed_next_char(EditLine *el, int c) { - if (el->el_line.cursor >= el->el_line.lastchar) - return CC_ERROR; - el->el_line.cursor += el->el_state.argument; - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; + if (el->el_line.cursor >= el->el_line.lastchar) + return (CC_ERROR); - if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action & DELETE) { - cv_delfini(el); - return CC_REFRESH; - } + el->el_line.cursor += el->el_state.argument; + if (el->el_line.cursor > el->el_line.lastchar) + el->el_line.cursor = el->el_line.lastchar; - return CC_CURSOR; + if (el->el_map.type == MAP_VI) + if (el->el_chared.c_vcmd.action & DELETE) { + cv_delfini(el); + return (CC_REFRESH); + } + return (CC_CURSOR); } -/* ed_prev_word(): +/* ed_prev_word(): * Move to the beginning of the current word * [M-b] [b] */ protected el_action_t /*ARGSUSED*/ -ed_prev_word(el, c) - EditLine *el; - int c; +ed_prev_word(EditLine *el, int c) { - if (el->el_line.cursor == el->el_line.buffer) - return CC_ERROR; - el->el_line.cursor = c__prev_word(el->el_line.cursor, el->el_line.buffer, - el->el_state.argument, - ce__isword); + if (el->el_line.cursor == el->el_line.buffer) + return (CC_ERROR); - if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action & DELETE) { - cv_delfini(el); - return CC_REFRESH; - } + el->el_line.cursor = c__prev_word(el->el_line.cursor, + el->el_line.buffer, + el->el_state.argument, + ce__isword); - return CC_CURSOR; + if (el->el_map.type == MAP_VI) + if (el->el_chared.c_vcmd.action & DELETE) { + cv_delfini(el); + return (CC_REFRESH); + } + return (CC_CURSOR); } -/* ed_prev_char(): +/* ed_prev_char(): * Move to the left one character * [^B] [^B] */ protected el_action_t /*ARGSUSED*/ -ed_prev_char(el, c) - EditLine *el; - int c; +ed_prev_char(EditLine *el, int c) { - if (el->el_line.cursor > el->el_line.buffer) { - el->el_line.cursor -= el->el_state.argument; - if (el->el_line.cursor < el->el_line.buffer) - el->el_line.cursor = el->el_line.buffer; - if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action & DELETE) { - cv_delfini(el); - return CC_REFRESH; - } + if (el->el_line.cursor > el->el_line.buffer) { + el->el_line.cursor -= el->el_state.argument; + if (el->el_line.cursor < el->el_line.buffer) + el->el_line.cursor = el->el_line.buffer; - return CC_CURSOR; - } - else - return CC_ERROR; + if (el->el_map.type == MAP_VI) + if (el->el_chared.c_vcmd.action & DELETE) { + cv_delfini(el); + return (CC_REFRESH); + } + return (CC_CURSOR); + } else + return (CC_ERROR); } -/* ed_quoted_insert(): +/* ed_quoted_insert(): * Add the next character typed verbatim * [^V] [^V] */ protected el_action_t -ed_quoted_insert(el, c) - EditLine *el; - int c; +ed_quoted_insert(EditLine *el, int c) { - int num; - char tc; + int num; + char tc; - tty_quotemode(el); - num = el_getc(el, &tc); - c = (unsigned char) tc; - tty_noquotemode(el); - if (num == 1) - return ed_insert(el, c); - else - return ed_end_of_file(el, 0); + tty_quotemode(el); + num = el_getc(el, &tc); + c = (unsigned char) tc; + tty_noquotemode(el); + if (num == 1) + return (ed_insert(el, c)); + else + return (ed_end_of_file(el, 0)); } -/* ed_digit(): +/* ed_digit(): * Adds to argument or enters a digit */ protected el_action_t -ed_digit(el, c) - EditLine *el; - int c; -{ - if (!isdigit(c)) - return CC_ERROR; - - if (el->el_state.doingarg) { - /* if doing an arg, add this in... */ - if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT) - el->el_state.argument = c - '0'; - else { - if (el->el_state.argument > 1000000) - return CC_ERROR; - el->el_state.argument = - (el->el_state.argument * 10) + (c - '0'); +ed_digit(EditLine *el, int c) +{ + + if (!isdigit(c)) + return (CC_ERROR); + + if (el->el_state.doingarg) { + /* if doing an arg, add this in... */ + if (el->el_state.lastcmd == EM_UNIVERSAL_ARGUMENT) + el->el_state.argument = c - '0'; + else { + if (el->el_state.argument > 1000000) + return (CC_ERROR); + el->el_state.argument = + (el->el_state.argument * 10) + (c - '0'); + } + return (CC_ARGHACK); + } 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_ARGHACK; - } - else { - if (el->el_line.lastchar + 1 >= el->el_line.limit) - 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; -} - - -/* ed_argument_digit(): + return (CC_NORM); +} + + +/* ed_argument_digit(): * Digit that starts argument * For ESC-n */ protected el_action_t -ed_argument_digit(el, c) - EditLine *el; - register int c; +ed_argument_digit(EditLine *el, int c) { - if (!isdigit(c)) - return CC_ERROR; - if (el->el_state.doingarg) { - if (el->el_state.argument > 1000000) - return CC_ERROR; - el->el_state.argument = (el->el_state.argument * 10) + (c - '0'); - } - else { /* else starting an argument */ - el->el_state.argument = c - '0'; - el->el_state.doingarg = 1; - } - return CC_ARGHACK; + if (!isdigit(c)) + return (CC_ERROR); + + if (el->el_state.doingarg) { + if (el->el_state.argument > 1000000) + return (CC_ERROR); + el->el_state.argument = (el->el_state.argument * 10) + + (c - '0'); + } else { /* else starting an argument */ + el->el_state.argument = c - '0'; + el->el_state.doingarg = 1; + } + return (CC_ARGHACK); } -/* ed_unassigned(): +/* ed_unassigned(): * Indicates unbound character * Bound to keys that are not assigned */ protected el_action_t /*ARGSUSED*/ -ed_unassigned(el, c) - EditLine *el; - int c; +ed_unassigned(EditLine *el, int c) { - term_beep(el); - term__flush(); - return CC_NORM; + + term_beep(el); + term__flush(); + return (CC_NORM); } @@ -493,390 +477,366 @@ ed_unassigned(el, c) ** TTY key handling. **/ -/* ed_tty_sigint(): +/* ed_tty_sigint(): * Tty interrupt character * [^C] */ protected el_action_t /*ARGSUSED*/ -ed_tty_sigint(el, c) - EditLine *el; - int c; -{ - return CC_NORM; +ed_tty_sigint(EditLine *el, int c) +{ + + return (CC_NORM); } -/* ed_tty_dsusp(): +/* ed_tty_dsusp(): * Tty delayed suspend character * [^Y] */ protected el_action_t /*ARGSUSED*/ -ed_tty_dsusp(el, c) - EditLine *el; - int c; +ed_tty_dsusp(EditLine *el, int c) { - return CC_NORM; + + return (CC_NORM); } -/* ed_tty_flush_output(): +/* ed_tty_flush_output(): * Tty flush output characters * [^O] */ protected el_action_t /*ARGSUSED*/ -ed_tty_flush_output(el, c) - EditLine *el; - int c; +ed_tty_flush_output(EditLine *el, int c) { - return CC_NORM; + + return (CC_NORM); } -/* ed_tty_sigquit(): +/* ed_tty_sigquit(): * Tty quit character * [^\] */ protected el_action_t /*ARGSUSED*/ -ed_tty_sigquit(el, c) - EditLine *el; - int c; +ed_tty_sigquit(EditLine *el, int c) { - return CC_NORM; + + return (CC_NORM); } -/* ed_tty_sigtstp(): +/* ed_tty_sigtstp(): * Tty suspend character * [^Z] */ protected el_action_t /*ARGSUSED*/ -ed_tty_sigtstp(el, c) - EditLine *el; - int c; +ed_tty_sigtstp(EditLine *el, int c) { - return CC_NORM; + + return (CC_NORM); } -/* ed_tty_stop_output(): +/* ed_tty_stop_output(): * Tty disallow output characters * [^S] */ protected el_action_t /*ARGSUSED*/ -ed_tty_stop_output(el, c) - EditLine *el; - int c; +ed_tty_stop_output(EditLine *el, int c) { - return CC_NORM; + + return (CC_NORM); } -/* ed_tty_start_output(): +/* ed_tty_start_output(): * Tty allow output characters * [^Q] */ protected el_action_t /*ARGSUSED*/ -ed_tty_start_output(el, c) - EditLine *el; - int c; +ed_tty_start_output(EditLine *el, int c) { - return CC_NORM; + + return (CC_NORM); } -/* ed_newline(): +/* ed_newline(): * Execute command * [^J] */ protected el_action_t /*ARGSUSED*/ -ed_newline(el, c) - EditLine *el; - int c; +ed_newline(EditLine *el, int c) { - re_goto_bottom(el); - *el->el_line.lastchar++ = '\n'; - *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; + + re_goto_bottom(el); + *el->el_line.lastchar++ = '\n'; + *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); } -/* ed_delete_prev_char(): +/* ed_delete_prev_char(): * Delete the character to the left of the cursor * [^?] */ protected el_action_t /*ARGSUSED*/ -ed_delete_prev_char(el, c) - EditLine *el; - int c; +ed_delete_prev_char(EditLine *el, int c) { - if (el->el_line.cursor <= el->el_line.buffer) - return CC_ERROR; - c_delbefore(el, el->el_state.argument); - el->el_line.cursor -= el->el_state.argument; - if (el->el_line.cursor < el->el_line.buffer) - el->el_line.cursor = el->el_line.buffer; - return CC_REFRESH; + if (el->el_line.cursor <= el->el_line.buffer) + return (CC_ERROR); + + c_delbefore(el, el->el_state.argument); + el->el_line.cursor -= el->el_state.argument; + if (el->el_line.cursor < el->el_line.buffer) + el->el_line.cursor = el->el_line.buffer; + return (CC_REFRESH); } -/* ed_clear_screen(): +/* ed_clear_screen(): * Clear screen leaving current line at the top * [^L] */ protected el_action_t /*ARGSUSED*/ -ed_clear_screen(el, c) - EditLine *el; - int c; +ed_clear_screen(EditLine *el, int c) { - term_clear_screen(el); /* clear the whole real screen */ - re_clear_display(el); /* reset everything */ - return CC_REFRESH; + + term_clear_screen(el); /* clear the whole real screen */ + re_clear_display(el); /* reset everything */ + return (CC_REFRESH); } -/* ed_redisplay(): +/* ed_redisplay(): * Redisplay everything * ^R */ protected el_action_t /*ARGSUSED*/ -ed_redisplay(el, c) - EditLine *el; - int c; +ed_redisplay(EditLine *el, int c) { - return CC_REDISPLAY; + + return (CC_REDISPLAY); } -/* ed_start_over(): +/* ed_start_over(): * Erase current line and start from scratch * [^G] */ protected el_action_t /*ARGSUSED*/ -ed_start_over(el, c) - EditLine *el; - int c; +ed_start_over(EditLine *el, int c) { - ch_reset(el); - return CC_REFRESH; + + ch_reset(el); + return (CC_REFRESH); } -/* ed_sequence_lead_in(): +/* ed_sequence_lead_in(): * First character in a bound sequence * Placeholder for external keys */ protected el_action_t /*ARGSUSED*/ -ed_sequence_lead_in(el, c) - EditLine *el; - int c; +ed_sequence_lead_in(EditLine *el, int c) { - return CC_NORM; + + return (CC_NORM); } -/* ed_prev_history(): +/* ed_prev_history(): * Move to the previous history line * [^P] [k] */ protected el_action_t /*ARGSUSED*/ -ed_prev_history(el, c) - EditLine *el; - int c; +ed_prev_history(EditLine *el, int c) { - char beep = 0; - - el->el_chared.c_undo.action = NOP; - *el->el_line.lastchar = '\0'; /* just in case */ - - if (el->el_history.eventno == 0) { /* save the current buffer away */ - (void) strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ); - el->el_history.last = el->el_history.buf + - (el->el_line.lastchar - el->el_line.buffer); - } + char beep = 0; - el->el_history.eventno += el->el_state.argument; + el->el_chared.c_undo.action = NOP; + *el->el_line.lastchar = '\0'; /* just in case */ - if (hist_get(el) == CC_ERROR) { - beep = 1; - /* el->el_history.eventno was fixed by first call */ - (void) hist_get(el); - } + if (el->el_history.eventno == 0) { /* save the current buffer + * away */ + (void) strncpy(el->el_history.buf, el->el_line.buffer, + EL_BUFSIZ); + el->el_history.last = el->el_history.buf + + (el->el_line.lastchar - el->el_line.buffer); + } + el->el_history.eventno += el->el_state.argument; - re_refresh(el); - if (beep) - return CC_ERROR; - else - return CC_NORM; /* was CC_UP_HIST */ + if (hist_get(el) == CC_ERROR) { + beep = 1; + /* el->el_history.eventno was fixed by first call */ + (void) hist_get(el); + } + re_refresh(el); + if (beep) + return (CC_ERROR); + else + return (CC_NORM); /* was CC_UP_HIST */ } -/* ed_next_history(): +/* ed_next_history(): * Move to the next history line * [^N] [j] */ protected el_action_t /*ARGSUSED*/ -ed_next_history(el, c) - EditLine *el; - int c; +ed_next_history(EditLine *el, int c) { - el->el_chared.c_undo.action = NOP; - *el->el_line.lastchar = '\0'; /* just in case */ - el->el_history.eventno -= el->el_state.argument; + el->el_chared.c_undo.action = NOP; + *el->el_line.lastchar = '\0'; /* just in case */ - if (el->el_history.eventno < 0) { - el->el_history.eventno = 0; - return CC_ERROR; /* make it beep */ - } + el->el_history.eventno -= el->el_state.argument; - return hist_get(el); + if (el->el_history.eventno < 0) { + el->el_history.eventno = 0; + return (CC_ERROR);/* make it beep */ + } + return (hist_get(el)); } -/* ed_search_prev_history(): +/* ed_search_prev_history(): * Search previous in history for a line matching the current * next search history [M-P] [K] */ protected el_action_t /*ARGSUSED*/ -ed_search_prev_history(el, c) - EditLine *el; - int c; -{ - const char *hp; - int h; - bool_t found = 0; - - el->el_chared.c_vcmd.action = NOP; - el->el_chared.c_undo.action = NOP; - *el->el_line.lastchar = '\0'; /* just in case */ - if (el->el_history.eventno < 0) { +ed_search_prev_history(EditLine *el, int c) +{ + const char *hp; + int h; + bool_t found = 0; + + el->el_chared.c_vcmd.action = NOP; + el->el_chared.c_undo.action = NOP; + *el->el_line.lastchar = '\0'; /* just in case */ + if (el->el_history.eventno < 0) { #ifdef DEBUG_EDIT - (void) fprintf(el->el_errfile, "e_prev_search_hist(): eventno < 0;\n"); + (void) fprintf(el->el_errfile, + "e_prev_search_hist(): eventno < 0;\n"); #endif - el->el_history.eventno = 0; - return CC_ERROR; - } - - if (el->el_history.eventno == 0) { - (void) strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ); - el->el_history.last = el->el_history.buf + - (el->el_line.lastchar - el->el_line.buffer); - } - - - if (el->el_history.ref == NULL) - return CC_ERROR; + el->el_history.eventno = 0; + return (CC_ERROR); + } + if (el->el_history.eventno == 0) { + (void) strncpy(el->el_history.buf, el->el_line.buffer, + EL_BUFSIZ); + el->el_history.last = el->el_history.buf + + (el->el_line.lastchar - el->el_line.buffer); + } + if (el->el_history.ref == NULL) + return (CC_ERROR); - hp = HIST_FIRST(el); - if (hp == NULL) - return CC_ERROR; + hp = HIST_FIRST(el); + if (hp == NULL) + return (CC_ERROR); - c_setpat(el); /* Set search pattern !! */ + c_setpat(el); /* Set search pattern !! */ - for (h = 1; h <= el->el_history.eventno; h++) - hp = HIST_NEXT(el); + for (h = 1; h <= el->el_history.eventno; h++) + hp = HIST_NEXT(el); - while (hp != NULL) { + while (hp != NULL) { #ifdef SDEBUG - (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); + (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); #endif - if ((strncmp(hp, el->el_line.buffer, - el->el_line.lastchar - el->el_line.buffer) || - hp[el->el_line.lastchar-el->el_line.buffer]) && - c_hmatch(el, hp)) { - found++; - break; + if ((strncmp(hp, el->el_line.buffer, (size_t) + (el->el_line.lastchar - el->el_line.buffer)) || + hp[el->el_line.lastchar - el->el_line.buffer]) && + c_hmatch(el, hp)) { + found++; + break; + } + h++; + hp = HIST_NEXT(el); } - h++; - hp = HIST_NEXT(el); - } - if (!found) { + if (!found) { #ifdef SDEBUG - (void) fprintf(el->el_errfile, "not found\n"); + (void) fprintf(el->el_errfile, "not found\n"); #endif - return CC_ERROR; - } - - el->el_history.eventno = h; + return (CC_ERROR); + } + el->el_history.eventno = h; - return hist_get(el); + return (hist_get(el)); } -/* ed_search_next_history(): +/* ed_search_next_history(): * Search next in history for a line matching the current * [M-N] [J] */ protected el_action_t /*ARGSUSED*/ -ed_search_next_history(el, c) - EditLine *el; - int c; +ed_search_next_history(EditLine *el, int c) { - const char *hp; - int h; - bool_t found = 0; + const char *hp; + int h; + bool_t found = 0; - el->el_chared.c_vcmd.action = NOP; - el->el_chared.c_undo.action = NOP; - *el->el_line.lastchar = '\0'; /* just in case */ + el->el_chared.c_vcmd.action = NOP; + el->el_chared.c_undo.action = NOP; + *el->el_line.lastchar = '\0'; /* just in case */ - if (el->el_history.eventno == 0) - return CC_ERROR; + if (el->el_history.eventno == 0) + return (CC_ERROR); - if (el->el_history.ref == NULL) - return CC_ERROR; + if (el->el_history.ref == NULL) + return (CC_ERROR); - hp = HIST_FIRST(el); - if (hp == NULL) - return CC_ERROR; + hp = HIST_FIRST(el); + if (hp == NULL) + return (CC_ERROR); - c_setpat(el); /* Set search pattern !! */ + c_setpat(el); /* Set search pattern !! */ - for (h = 1; h < el->el_history.eventno && hp; h++) { + for (h = 1; h < el->el_history.eventno && hp; h++) { #ifdef SDEBUG - (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); + (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); #endif - if ((strncmp(hp, el->el_line.buffer, - el->el_line.lastchar - el->el_line.buffer) || - hp[el->el_line.lastchar-el->el_line.buffer]) && - c_hmatch(el, hp)) - found = h; - hp = HIST_NEXT(el); - } - - if (!found) { /* is it the current history number? */ - if (!c_hmatch(el, el->el_history.buf)) { + if ((strncmp(hp, el->el_line.buffer, (size_t) + (el->el_line.lastchar - el->el_line.buffer)) || + hp[el->el_line.lastchar - el->el_line.buffer]) && + c_hmatch(el, hp)) + found = h; + hp = HIST_NEXT(el); + } + + if (!found) { /* is it the current history number? */ + if (!c_hmatch(el, el->el_history.buf)) { #ifdef SDEBUG - (void) fprintf(el->el_errfile, "not found\n"); + (void) fprintf(el->el_errfile, "not found\n"); #endif - return CC_ERROR; + return (CC_ERROR); + } } - } + el->el_history.eventno = found; - el->el_history.eventno = found; - - return hist_get(el); + return (hist_get(el)); } @@ -886,42 +846,40 @@ ed_search_next_history(el, c) */ protected el_action_t /*ARGSUSED*/ -ed_prev_line(el, c) - EditLine *el; - int c; -{ - char *ptr; - int nchars = c_hpos(el); - - /* - * Move to the line requested - */ - if (*(ptr = el->el_line.cursor) == '\n') - ptr--; - - for (; ptr >= el->el_line.buffer; ptr--) - if (*ptr == '\n' && --el->el_state.argument <= 0) - break; - - if (el->el_state.argument > 0) - return CC_ERROR; - - /* - * Move to the beginning of the line - */ - for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--) - continue; - - /* - * Move to the character requested - */ - for (ptr++; - nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n'; - ptr++) - continue; - - el->el_line.cursor = ptr; - return CC_CURSOR; +ed_prev_line(EditLine *el, int c) +{ + char *ptr; + int nchars = c_hpos(el); + + /* + * Move to the line requested + */ + if (*(ptr = el->el_line.cursor) == '\n') + ptr--; + + for (; ptr >= el->el_line.buffer; ptr--) + if (*ptr == '\n' && --el->el_state.argument <= 0) + break; + + if (el->el_state.argument > 0) + return (CC_ERROR); + + /* + * Move to the beginning of the line + */ + for (ptr--; ptr >= el->el_line.buffer && *ptr != '\n'; ptr--) + continue; + + /* + * Move to the character requested + */ + for (ptr++; + nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n'; + ptr++) + continue; + + el->el_line.cursor = ptr; + return (CC_CURSOR); } @@ -931,68 +889,64 @@ ed_prev_line(el, c) */ protected el_action_t /*ARGSUSED*/ -ed_next_line(el, c) - EditLine *el; - int c; +ed_next_line(EditLine *el, int c) { - char *ptr; - int nchars = c_hpos(el); + char *ptr; + int nchars = c_hpos(el); + + /* + * Move to the line requested + */ + for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++) + if (*ptr == '\n' && --el->el_state.argument <= 0) + break; - /* - * Move to the line requested - */ - for (ptr = el->el_line.cursor; ptr < el->el_line.lastchar; ptr++) - if (*ptr == '\n' && --el->el_state.argument <= 0) - break; + if (el->el_state.argument > 0) + return (CC_ERROR); - if (el->el_state.argument > 0) - return CC_ERROR; + /* + * Move to the character requested + */ + for (ptr++; + nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n'; + ptr++) + continue; - /* - * Move to the character requested - */ - for (ptr++; - nchars-- > 0 && ptr < el->el_line.lastchar && *ptr != '\n'; - ptr++) - continue; - - el->el_line.cursor = ptr; - return CC_CURSOR; + el->el_line.cursor = ptr; + return (CC_CURSOR); } -/* ed_command(): +/* ed_command(): * Editline extended command * [M-X] [:] */ protected el_action_t /*ARGSUSED*/ -ed_command(el, c) - EditLine *el; - int c; -{ - char tmpbuf[EL_BUFSIZ]; - int tmplen; - - el->el_line.buffer[0] = '\0'; - el->el_line.lastchar = el->el_line.buffer; - el->el_line.cursor = el->el_line.buffer; - - c_insert(el, 3); /* prompt + ": " */ - *el->el_line.cursor++ = '\n'; - *el->el_line.cursor++ = ':'; - *el->el_line.cursor++ = ' '; - re_refresh(el); - - tmplen = c_gets(el, tmpbuf); - tmpbuf[tmplen] = '\0'; - - 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; +ed_command(EditLine *el, int c) +{ + char tmpbuf[EL_BUFSIZ]; + int tmplen; + + el->el_line.buffer[0] = '\0'; + el->el_line.lastchar = el->el_line.buffer; + el->el_line.cursor = el->el_line.buffer; + + c_insert(el, 3); /* prompt + ": " */ + *el->el_line.cursor++ = '\n'; + *el->el_line.cursor++ = ':'; + *el->el_line.cursor++ = ' '; + re_refresh(el); + + tmplen = c_gets(el, tmpbuf); + tmpbuf[tmplen] = '\0'; + + 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); } diff --git a/dist/editline.3 b/dist/editline.3 index b2858f6..f748491 100644 --- a/dist/editline.3 +++ b/dist/editline.3 @@ -1,6 +1,6 @@ -.\" $NetBSD: editline.3,v 1.4 1997/01/14 04:17:23 lukem Exp $ +.\" $NetBSD: editline.3,v 1.22 2001/09/27 19:29:50 christos Exp $ .\" -.\" Copyright (c) 1997 The NetBSD Foundation, Inc. +.\" Copyright (c) 1997-1999 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This file was contributed to The NetBSD Foundation by Luke Mewburn. @@ -24,8 +24,8 @@ .\" 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 REGENTS OR CONTRIBUTORS BE -.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" 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 @@ -33,8 +33,8 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 11, 1997 -.Os BSD 4.4 +.Dd November 12, 1999 +.Os .Dt EDITLINE 3 .Sh NAME .Nm editline , @@ -55,10 +55,12 @@ .Nm history_end , .Nm history .Nd line editor and history functions +.Sh LIBRARY +.Lb libedit .Sh SYNOPSIS .Fd #include <histedit.h> .Ft EditLine * -.Fn el_init "const char *prog" "FILE *fin" "FILE *fout" +.Fn el_init "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr" .Ft void .Fn el_end "EditLine *e" .Ft void @@ -74,21 +76,23 @@ .Ft int .Fn el_set "EditLine *e" "int op" "..." .Ft int +.Fn el_get "EditLine *e" "int op" "void *result" +.Ft int .Fn el_source "EditLine *e" "const char *file" .Ft void .Fn el_resize "EditLine *e" .Ft const LineInfo * .Fn el_line "EditLine *e" .Ft int -.Fn el_insertstr "EditLine *e" "char *str" +.Fn el_insertstr "EditLine *e" "const char *str" .Ft void .Fn el_deletestr "EditLine *e" "int count" .Ft History * .Fn history_init .Ft void .Fn history_end "History *h" -.Ft HistEvent * -.Fn history "History h" "int op" "..." +.Ft int +.Fn history "History *h" "HistEvent *ev" "int op" "..." .Sh DESCRIPTION The .Nm @@ -120,10 +124,11 @@ to be used by all other line editing functions. is the name of the invoking program, used when reading the .Xr editrc 5 file to determine which settings to use. -.Fa fin -and +.Fa fin , .Fa fout -are the input and output streams (respectively) to use. +and +.Fa ferr +are the input, output, and error streams (respectively) to use. In this documentation, references to .Dq the tty are actually to this input/output stream combination. @@ -187,19 +192,6 @@ didn't match, or Refer to .Xr editrc 5 for more information. -.Pp -.Em NOTE: -.Va argv[0] -may be modified by -.Fn el_parse . -The colon between -.Dq prog -and the command, -.Ar command , -will be replaced with a NUL -.Po -.Dq \e0 -.Pc . .It Fn el_set Set .Nm @@ -216,6 +208,10 @@ are supported, along with the required argument list: Define prompt printing function as .Fa f , which is to return a string that contains the prompt. +.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" +Define right side prompt printing function as +.Fa f , +which is to return a string that contains the prompt. .It Dv EL_TERMINAL , Fa "const char *type" Define terminal type of the tty to be .Fa type , @@ -257,7 +253,7 @@ Otherwise, the current signal handlers will be used. Perform the .Ic bind builtin command. -Refer to +Refer to .Xr editrc 5 for more information. .It Dv EL_ECHOTC , Xo @@ -268,7 +264,7 @@ for more information. Perform the .Ic echotc builtin command. -Refer to +Refer to .Xr editrc 5 for more information. .It Dv EL_SETTC , Xo @@ -279,7 +275,7 @@ for more information. Perform the .Ic settc builtin command. -Refer to +Refer to .Xr editrc 5 for more information. .It Dv EL_SETTY , Xo @@ -290,7 +286,7 @@ for more information. Perform the .Ic setty builtin command. -Refer to +Refer to .Xr editrc 5 for more information. .It Dv EL_TELLTC , Xo @@ -301,7 +297,7 @@ for more information. Perform the .Ic telltc builtin command. -Refer to +Refer to .Xr editrc 5 for more information. .It Dv EL_ADDFN , Xo @@ -336,6 +332,8 @@ EOF was entered. Expecting further command input as arguments, do nothing visually. .It Dv CC_REFRESH Refresh display. +.It Dv CC_REFRESH_BEEP +Refresh display, and beep. .It Dv CC_CURSOR Cursor moved, so update and perform .Dv CC_REFRESH. @@ -357,11 +355,69 @@ Defines which history function to use, which is usually .Fa ptr should be the value returned by .Fn history_init . +.It Dv EL_EDITMODE , Fa "int flag" +If +.Fa flag +is non-zero, +editing is enabled (the default). +Note that this is only an indication, and does not +affect the operation of +.Nm "" . +At this time, it is the caller's responsibility to +check this +(using +.Fn el_get ) +to determine if editing should be enabled or not. +.It Dv EL_GETCFN , Fa "int (*f)(EditLine *, char *c)" +Define the character reading function as +.Fa f , +which is to return the number of characters read and store them in +.Fa c . +This function is called internally by +.Fn el_gets +and +.Fn el_getc . +The builtin function can be set or restored with the special function +name ``EL_BUILTIN_GETCFN''. +.El +.It Fn el_get +Get +.Nm +parameters. +.Fa op +determines which parameter to retrieve into +.Fa result . +.Pp +The following values for +.Fa op +are supported, along with actual type of +.Fa result : +.Bl -tag -width 4n +.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)" +Return a pointer to the function that displays the prompt. +.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" +Return a pointer to the function that displays the rightside prompt. +.It Dv EL_EDITOR , Fa "const char *" +Return the name of the editor, which will be one of +.Dq emacs +or +.Dq vi . +.It Dv EL_SIGNAL , Fa "int *" +Return non-zero if +.Nm +has installed private signal handlers (see +.Fn el_get +above). +.It Dv EL_EDITMODE, Fa "int *" +Return non-zero if editing is enabled. +.It Dv EL_GETCFN, Fa "int (**f)(EditLine *, char *)" +Return a pointer to the function that read characters, which is equal to +``EL_BUILTIN_GETCFN'' in the case of the default builtin function. .El .It Fn el_source Initialise .Nm -by reading the contents of +by reading the contents of .Fa file . .Fn el_parse is called for each line in @@ -434,14 +490,18 @@ Perform operation .Fa op on the history list, with optional arguments as needed by the operation. +.Fa ev +is changed accordingly to operation. The following values for .Fa op are supported, along with the required argument list: .Bl -tag -width 4n -.It Dv H_EVENT , Fa "int size" +.It Dv H_SETSIZE , Fa "int size" Set size of history to .Fa size elements. +.It Dv H_GETSIZE +Get number of events currently in history. .It Dv H_END Cleans up and finishes with .Fa h , @@ -456,6 +516,7 @@ Clear the history. .Fa "history_gfun_t last" , .Fa "history_gfun_t prev" , .Fa "history_gfun_t curr" , +.Fa "history_sfun_t set" , .Fa "history_vfun_t clear" , .Fa "history_efun_t enter" , .Fa "history_efun_t add" @@ -473,16 +534,20 @@ Return the previous element in the history. Return the next element in the history. .It Dv H_CURR Return the current element in the history. +.It Dv H_SET +Set the cursor to point to the requested element. .It Dv H_ADD , Fa "const char *str" Append .Fa str to the current element of the history, or create an element with -.Dv H_ENTER -if there isn't one. +.It Dv H_APPEND , Fa "const char *str" +Append +.Fa str +to the last new element of the history. .It Dv H_ENTER , Fa "const char *str" Add .Fa str -as a new element to the history, and, if necessary, +as a new element to the history, and, if necessary, removing the oldest entry to keep the list to the created size. .It Dv H_PREV_STR , Fa "const char *str" Return the closest previous event that starts with @@ -503,6 +568,13 @@ Load the history list stored in Save the history list to .Fa file . .El +.Pp +.Fn history +returns 0 if the operation +.Fa op +succeeds. Otherwise, -1 is returned and +.Fa ev +is updated to contain more details about the error. .El .\"XXX.Sh EXAMPLES .\"XXX: provide some examples @@ -516,17 +588,46 @@ The .Nm library first appeared in .Bx 4.4 . +.Dv CC_REDISPLAY +appeared in +.Nx 1.3 . +.Dv CC_REFRESH_BEEP , +.Dv EL_EDITMODE +and the readline emulation appeared in +.Nx 1.4 . +.Dv EL_RPROMPT +appeared in +.Nx 1.5 . .Sh AUTHORS The .Nm -library was written by Christos Zoulas, -and this manual was written by Luke Mewburn. +library was written by Christos Zoulas. +Luke Mewburn wrote this manual and implemented +.Dv CC_REDISPLAY , +.Dv CC_REFRESH_BEEP , +.Dv EL_EDITMODE , +and +.Dv EL_RPROMPT . +Jaromir Dolecek implemented the readline emulation. .Sh BUGS -This documentation is probably incomplete. -.Pp -.Fn el_parse -should not modify the supplied -.Va argv[0] . -.Pp The tokenization functions are not publically defined in -.Fd <histedit.h> +.Fd <histedit.h>. +.Pp +At this time, it is the responsibility of the caller to +check the result of the +.Dv EL_EDITMODE +operation of +.Fn el_get +(after an +.Fn el_source +or +.Fn el_parse ) +to determine if +.Nm +should be used for further input. +I.e., +.Dv EL_EDITMODE +is purely an indication of the result of the most recent +.Xr editrc 5 +.Ic edit +command. diff --git a/dist/editrc.5 b/dist/editrc.5 index e9b2992..b112261 100644 --- a/dist/editrc.5 +++ b/dist/editrc.5 @@ -1,6 +1,6 @@ -.\" $NetBSD: editrc.5,v 1.4 1997/04/24 20:20:31 christos Exp $ +.\" $NetBSD: editrc.5,v 1.11 2001/06/19 13:42:09 wiz Exp $ .\" -.\" Copyright (c) 1997 The NetBSD Foundation, Inc. +.\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This file was contributed to The NetBSD Foundation by Luke Mewburn. @@ -24,8 +24,8 @@ .\" 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 REGENTS OR CONTRIBUTORS BE -.\" LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +.\" 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 @@ -33,8 +33,8 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd January 11, 1997 -.Os BSD 4.4 +.Dd November 8, 2000 +.Os .Dt EDITRC 5 .Sh NAME .Nm editrc @@ -48,10 +48,8 @@ file defines various settings to be used by the .Xr editline 3 library. .Pp -The format of each line is either: -.Dl prog:command [arg [...]] -or -.Dl command [arg [...]] +The format of each line is: +.Dl [prog:]command [arg [...]] .Pp .Ar command is one of the @@ -61,7 +59,7 @@ Refer to .Sx BUILTIN COMMANDS for more information. .Pp -.Ar prog +.Ar prog is the program name string that a program defines when it calls .Xr el_init 3 to setup @@ -79,6 +77,12 @@ style regular expression, in which case .Ar command will be executed for any program that matches the regular expression. +.Pp +If +.Ar prog +is absent, +.Ar command +is executed for all programs. .Sh BUILTIN COMMANDS The .Nm editline @@ -117,11 +121,11 @@ Options include: .It Fl e Bind all keys to the standard GNU Emacs-like bindings. .It Fl v -Bind all keys to the standard +Bind all keys to the standard .Xr vi 1 -like bindings. .It Fl a -List or change key bindings in the +List or change key bindings in the .Xr vi 1 mode alternate (command mode) key map. .It Fl k @@ -147,6 +151,11 @@ are themselves reinterpreted, and this continues for ten levels of interpretation. .El .Pp +.Ar command +may be one of the commands documented in +.Sx "EDITOR COMMANDS" +below, or another key. +.Pp .Ar key and .Ar command @@ -213,10 +222,14 @@ or indicating that the terminal does or does not have that capability. .Pp .Fl s -returns an emptry string for non-existant capabilities, rather than +returns an emptry string for non-existent capabilities, rather than causing an error. .Fl v causes messages to be verbose. +.It Ic edit Op Li on | Li off +Enable or disable the +.Nm editline +functionality in a program. .It Ic history List the history. .It Ic telltc @@ -279,6 +292,192 @@ on or off or removes control of .Ar mode in the chosen set. .El +.Sh EDITOR COMMANDS +The following editor commands are available for use in key bindings: +.\" Section automatically generated with makelist +.Bl -tag -width 4n +.It Ic vi-paste-next +Vi paste previous deletion to the right of the cursor. +.It Ic vi-paste-prev +Vi paste previous deletion to the left of the cursor. +.It Ic vi-prev-space-word +Vi move to the previous space delimited word. +.It Ic vi-prev-word +Vi move to the previous word. +.It Ic vi-next-space-word +Vi move to the next space delimited word. +.It Ic vi-next-word +Vi move to the next word. +.It Ic vi-change-case +Vi change case of character under the cursor and advance one character. +.It Ic vi-change-meta +Vi change prefix command. +.It Ic vi-insert-at-bol +Vi enter insert mode at the beginning of line. +.It Ic vi-replace-char +Vi replace character under the cursor with the next character typed. +.It Ic vi-replace-mode +Vi enter replace mode. +.It Ic vi-substitute-char +Vi replace character under the cursor and enter insert mode. +.It Ic vi-substitute-line +Vi substitute entire line. +.It Ic vi-change-to-eol +Vi change to end of line. +.It Ic vi-insert +Vi enter insert mode. +.It Ic vi-add +Vi enter insert mode after the cursor. +.It Ic vi-add-at-eol +Vi enter insert mode at end of line. +.It Ic vi-delete-meta +Vi delete prefix command. +.It Ic vi-end-word +Vi move to the end of the current space delimited word. +.It Ic vi-to-end-word +Vi move to the end of the current word. +.It Ic vi-undo +Vi undo last change. +.It Ic vi-command-mode +Vi enter command mode (use alternative key bindings). +.It Ic vi-zero +Vi move to the beginning of line. +.It Ic vi-delete-prev-char +Vi move to previous character (backspace). +.It Ic vi-list-or-eof +Vi list choices for completion or indicate end of file if empty line. +.It Ic vi-kill-line-prev +Vi cut from beginning of line to cursor. +.It Ic vi-search-prev +Vi search history previous. +.It Ic vi-search-next +Vi search history next. +.It Ic vi-repeat-search-next +Vi repeat current search in the same search direction. +.It Ic vi-repeat-search-prev +Vi repeat current search in the opposite search direction. +.It Ic vi-next-char +Vi move to the character specified next. +.It Ic vi-prev-char +Vi move to the character specified previous. +.It Ic vi-to-next-char +Vi move up to the character specified next. +.It Ic vi-to-prev-char +Vi move up to the character specified previous. +.It Ic vi-repeat-next-char +Vi repeat current character search in the same search direction. +.It Ic vi-repeat-prev-char +Vi repeat current character search in the opposite search direction. +.It Ic em-delete-or-list +Delete character under cursor or list completions if at end of line. +.It Ic em-delete-next-word +Cut from cursor to end of current word. +.It Ic em-yank +Paste cut buffer at cursor position. +.It Ic em-kill-line +Cut the entire line and save in cut buffer. +.It Ic em-kill-region +Cut area between mark and cursor and save in cut buffer. +.It Ic em-copy-region +Copy area between mark and cursor to cut buffer. +.It Ic em-gosmacs-traspose +Exchange the two characters before the cursor. +.It Ic em-next-word +Move next to end of current word. +.It Ic em-upper-case +Uppercase the characters from cursor to end of current word. +.It Ic em-capitol-case +Capitalize the characters from cursor to end of current word. +.It Ic em-lower-case +Lowercase the characters from cursor to end of current word. +.It Ic em-set-mark +Set the mark at cursor. +.It Ic em-exchange-mark +Exchange the cursor and mark. +.It Ic em-universal-argument +Universal argument (argument times 4). +.It Ic em-meta-next +Add 8th bit to next character typed. +.It Ic em-toggle-overwrite +Switch from insert to overwrite mode or vice versa. +.It Ic em-copy-prev-word +Copy current word to cursor. +.It Ic em-inc-search-next +Emacs incremental next search. +.It Ic em-inc-search-prev +Emacs incremental reverse search. +.It Ic ed-end-of-file +Indicate end of file. +.It Ic ed-insert +Add character to the line. +.It Ic ed-delete-prev-word +Delete from beginning of current word to cursor. +.It Ic ed-delete-next-char +Delete character under cursor. +.It Ic ed-kill-line +Cut to the end of line. +.It Ic ed-move-to-end +Move cursor to the end of line. +.It Ic ed-move-to-beg +Move cursor to the beginning of line. +.It Ic ed-transpose-chars +Exchange the character to the left of the cursor with the one under it. +.It Ic ed-next-char +Move to the right one character. +.It Ic ed-prev-word +Move to the beginning of the current word. +.It Ic ed-prev-char +Move to the left one character. +.It Ic ed-quoted-insert +Add the next character typed verbatim. +.It Ic ed-digit +Adds to argument or enters a digit. +.It Ic ed-argument-digit +Digit that starts argument. +.It Ic ed-unassigned +Indicates unbound character. +.It Ic ed-tty-sigint +Tty interrupt character. +.It Ic ed-tty-dsusp +Tty delayed suspend character. +.It Ic ed-tty-flush-output +Tty flush output characters. +.It Ic ed-tty-sigquit +Tty quit character. +.It Ic ed-tty-sigtstp +Tty suspend character. +.It Ic ed-tty-stop-output +Tty disallow output characters. +.It Ic ed-tty-start-output +Tty allow output characters. +.It Ic ed-newline +Execute command. +.It Ic ed-delete-prev-char +Delete the character to the left of the cursor. +.It Ic ed-clear-screen +Clear screen leaving current line at the top. +.It Ic ed-redisplay +Redisplay everything. +.It Ic ed-start-over +Erase current line and start from scratch. +.It Ic ed-sequence-lead-in +First character in a bound sequence. +.It Ic ed-prev-history +Move to the previous history line. +.It Ic ed-next-history +Move to the next history line. +.It Ic ed-search-prev-history +Search previous in history for a line matching the current. +.It Ic ed-search-next-history +Search next in history for a line matching the current. +.It Ic ed-prev-line +Move up one line. +.It Ic ed-next-line +Move down one line. +.It Ic ed-command +Editline extended command. +.El +.\" End of section automatically generated with makelist .Sh SEE ALSO .Xr editline 3 , .Xr regex 3 , @@ -1,4 +1,4 @@ -/* $NetBSD: el.c,v 1.6 1997/04/24 18:54:16 christos Exp $ */ +/* $NetBSD: el.c,v 1.23 2001/09/27 19:29:50 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,11 +36,12 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94"; #else -static char rcsid[] = "$NetBSD: el.c,v 1.6 1997/04/24 18:54:16 christos Exp $"; +__RCSID("$NetBSD: el.c,v 1.23 2001/09/27 19:29:50 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -53,103 +54,88 @@ static char rcsid[] = "$NetBSD: el.c,v 1.6 1997/04/24 18:54:16 christos Exp $"; #include <sys/param.h> #include <string.h> #include <stdlib.h> -#ifdef __STDC__ -# include <stdarg.h> -#else -# include <varargs.h> -#endif +#include <stdarg.h> #include "el.h" /* el_init(): * Initialize editline and set default parameters. */ public EditLine * -el_init(prog, fin, fout) - const char *prog; - FILE *fin, *fout; +el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) { - EditLine *el = (EditLine *) el_malloc(sizeof(EditLine)); -#ifdef DEBUG - char *tty; -#endif - - if (el == NULL) - return NULL; - - memset(el, 0, sizeof(EditLine)); - - el->el_infd = fileno(fin); - el->el_outfile = fout; - el->el_prog = strdup(prog); + EditLine *el = (EditLine *) el_malloc(sizeof(EditLine)); #ifdef DEBUG - if ((tty = getenv("DEBUGTTY")) != NULL) { - el->el_errfile = fopen(tty, "w"); - if (el->el_errfile == NULL) { - extern errno; - (void) fprintf(stderr, "Cannot open %s (%s).\n", - tty, strerror(errno)); - return NULL; - } - } - else + char *tty; #endif - el->el_errfile = stderr; - - /* - * Initialize all the modules. Order is important!!! - */ - (void) term_init(el); - (void) tty_init(el); - (void) key_init(el); - (void) map_init(el); - (void) ch_init(el); - (void) search_init(el); - (void) hist_init(el); - (void) prompt_init(el); - (void) sig_init(el); - el->el_flags = 0; - - return el; -} /* end el_init */ + + if (el == NULL) + return (NULL); + + memset(el, 0, sizeof(EditLine)); + + el->el_infd = fileno(fin); + el->el_outfile = fout; + el->el_errfile = ferr; + el->el_prog = strdup(prog); + + /* + * Initialize all the modules. Order is important!!! + */ + el->el_flags = 0; + + (void) term_init(el); + (void) key_init(el); + (void) map_init(el); + if (tty_init(el) == -1) + el->el_flags |= NO_TTY; + (void) ch_init(el); + (void) search_init(el); + (void) hist_init(el); + (void) prompt_init(el); + (void) sig_init(el); + (void) read_init(el); + + return (el); +} /* el_end(): * Clean up. */ public void -el_end(el) - EditLine *el; +el_end(EditLine *el) { - if (el == NULL) - return; - el_reset(el); + if (el == NULL) + return; - term_end(el); - tty_end(el); - key_end(el); - map_end(el); - ch_end(el); - search_end(el); - hist_end(el); - prompt_end(el); - sig_end(el); + el_reset(el); - el_free((ptr_t) el->el_prog); - el_free((ptr_t) el); -} /* end el_end */ + term_end(el); + key_end(el); + map_end(el); + tty_end(el); + ch_end(el); + search_end(el); + hist_end(el); + prompt_end(el); + sig_end(el); + + el_free((ptr_t) el->el_prog); + el_free((ptr_t) el); +} /* el_reset(): * Reset the tty and the parser */ public void -el_reset(el) - EditLine *el; +el_reset(EditLine *el) { - tty_cookedmode(el); - ch_reset(el); /* XXX: Do we want that? */ + + tty_cookedmode(el); + ch_reset(el); /* XXX: Do we want that? */ } @@ -157,127 +143,249 @@ el_reset(el) * set the editline parameters */ public int -#ifdef __STDC__ el_set(EditLine *el, int op, ...) -#else -el_set(va_alist) - va_dcl -#endif { - va_list va; - int rv; -#ifdef __STDC__ - va_start(va, op); -#else - EditLine *el; - int op; + va_list va; + int rv; - va_start(va); - el = va_arg(va, EditLine *); - op = va_arg(va, int); -#endif - - switch (op) { - case EL_PROMPT: - rv = prompt_set(el, va_arg(va, el_pfunc_t)); - break; - - case EL_TERMINAL: - rv = term_set(el, va_arg(va, char *)); - break; - - case EL_EDITOR: - rv = map_set_editor(el, va_arg(va, char *)); - break; - - case EL_SIGNAL: - if (va_arg(va, int)) - el->el_flags |= HANDLE_SIGNALS; - else - el->el_flags &= ~HANDLE_SIGNALS; - rv = 0; - break; - - case EL_BIND: - case EL_TELLTC: - case EL_SETTC: - case EL_ECHOTC: - case EL_SETTY: + if (el == NULL) + return (-1); + va_start(va, op); + + switch (op) { + case EL_PROMPT: + case EL_RPROMPT: + rv = prompt_set(el, va_arg(va, el_pfunc_t), op); + break; + + case EL_TERMINAL: + rv = term_set(el, va_arg(va, char *)); + break; + + case EL_EDITOR: + rv = map_set_editor(el, va_arg(va, char *)); + break; + + case EL_SIGNAL: + if (va_arg(va, int)) + el->el_flags |= HANDLE_SIGNALS; + else + el->el_flags &= ~HANDLE_SIGNALS; + rv = 0; + break; + + case EL_BIND: + case EL_TELLTC: + case EL_SETTC: + case EL_ECHOTC: + case EL_SETTY: { - char *argv[20]; - int i; - for (i = 1; i < 20; i++) - if ((argv[i] = va_arg(va, char *)) == NULL) - break; - - switch (op) { - case EL_BIND: - argv[0] = "bind"; - rv = map_bind(el, i, argv); + char *argv[20]; + int i; + + for (i = 1; i < 20; i++) + if ((argv[i] = va_arg(va, char *)) == NULL) + break; + + switch (op) { + case EL_BIND: + argv[0] = "bind"; + rv = map_bind(el, i, argv); + break; + + case EL_TELLTC: + argv[0] = "telltc"; + rv = term_telltc(el, i, argv); + break; + + case EL_SETTC: + argv[0] = "settc"; + rv = term_settc(el, i, argv); + break; + + case EL_ECHOTC: + argv[0] = "echotc"; + rv = term_echotc(el, i, argv); + break; + + case EL_SETTY: + argv[0] = "setty"; + rv = tty_stty(el, i, argv); + break; + + default: + rv = -1; + EL_ABORT((el->el_errfile, "Bad op %d\n", op)); + break; + } break; + } - case EL_TELLTC: - argv[0] = "telltc"; - rv = term_telltc(el, i, argv); + case EL_ADDFN: + { + char *name = va_arg(va, char *); + char *help = va_arg(va, char *); + el_func_t func = va_arg(va, el_func_t); + + rv = map_addfunc(el, name, help, func); break; + } - case EL_SETTC: - argv[0] = "settc"; - rv = term_settc(el, i, argv); + case EL_HIST: + { + hist_fun_t func = va_arg(va, hist_fun_t); + ptr_t ptr = va_arg(va, char *); + + rv = hist_set(el, func, ptr); break; + } - case EL_ECHOTC: - argv[0] = "echotc"; - rv = term_echotc(el, i, argv); + case EL_EDITMODE: + if (va_arg(va, int)) + el->el_flags &= ~EDIT_DISABLED; + else + el->el_flags |= EDIT_DISABLED; + rv = 0; break; - case EL_SETTY: - argv[0] = "setty"; - rv = tty_stty(el, i, argv); + case EL_GETCFN: + { + el_rfunc_t rc = va_arg(va, el_rfunc_t); + rv = el_read_setfn(el, rc); break; + } - default: + default: rv = -1; - abort(); - break; - } } - break; - - case EL_ADDFN: + + va_end(va); + return (rv); +} + + +/* el_get(): + * retrieve the editline parameters + */ +public int +el_get(EditLine *el, int op, void *ret) +{ + int rv; + + if (el == NULL || ret == NULL) + return (-1); + switch (op) { + case EL_PROMPT: + case EL_RPROMPT: + rv = prompt_get(el, (el_pfunc_t *) & ret, op); + break; + + case EL_EDITOR: + rv = map_get_editor(el, (const char **) &ret); + break; + + case EL_SIGNAL: + *((int *) ret) = (el->el_flags & HANDLE_SIGNALS); + rv = 0; + break; + + case EL_EDITMODE: + *((int *) ret) = (!(el->el_flags & EDIT_DISABLED)); + rv = 0; + break; + +#if 0 /* XXX */ + case EL_TERMINAL: + rv = term_get(el, (const char *) &ret); + break; + + case EL_BIND: + case EL_TELLTC: + case EL_SETTC: + case EL_ECHOTC: + case EL_SETTY: { - char *name = va_arg(va, char *); - char *help = va_arg(va, char *); - el_func_t func = va_arg(va, el_func_t); - rv = map_addfunc(el, name, help, func); + char *argv[20]; + int i; + + for (i = 1; i < 20; i++) + if ((argv[i] = va_arg(va, char *)) == NULL) + break; + + switch (op) { + case EL_BIND: + argv[0] = "bind"; + rv = map_bind(el, i, argv); + break; + + case EL_TELLTC: + argv[0] = "telltc"; + rv = term_telltc(el, i, argv); + break; + + case EL_SETTC: + argv[0] = "settc"; + rv = term_settc(el, i, argv); + break; + + case EL_ECHOTC: + argv[0] = "echotc"; + rv = term_echotc(el, i, argv); + break; + + case EL_SETTY: + argv[0] = "setty"; + rv = tty_stty(el, i, argv); + break; + + default: + rv = -1; + EL_ABORT((el->errfile, "Bad op %d\n", op)); + break; + } + break; } - break; - case EL_HIST: + case EL_ADDFN: { - hist_fun_t func = va_arg(va, hist_fun_t); - ptr_t ptr = va_arg(va, char *); - rv = hist_set(el, func, ptr); + char *name = va_arg(va, char *); + char *help = va_arg(va, char *); + el_func_t func = va_arg(va, el_func_t); + + rv = map_addfunc(el, name, help, func); + break; } - break; - default: - rv = -1; - } + case EL_HIST: + { + hist_fun_t func = va_arg(va, hist_fun_t); + ptr_t ptr = va_arg(va, char *); + rv = hist_set(el, func, ptr); + } + break; +#endif /* XXX */ - va_end(va); - return rv; -} /* end el_set */ + case EL_GETCFN: + *((el_rfunc_t *)ret) = el_read_getfn(el); + rv = 0; + break; + + default: + rv = -1; + } + + return (rv); +} /* el_line(): * Return editing info */ public const LineInfo * -el_line(el) - EditLine *el; +el_line(EditLine *el) { - return (const LineInfo *) &el->el_line; + + return (const LineInfo *) (void *) &el->el_line; } static const char elpath[] = "/.editrc"; @@ -286,39 +394,41 @@ static const char elpath[] = "/.editrc"; * Source a file */ public int -el_source(el, fname) - EditLine *el; - const char *fname; +el_source(EditLine *el, const char *fname) { - FILE *fp; - size_t len; - char *ptr, path[MAXPATHLEN]; - - if (fname == NULL) { - fname = &elpath[1]; - if ((fp = fopen(fname, "r")) == NULL) { - if ((ptr = getenv("HOME")) == NULL) - return -1; - (void)snprintf(path, sizeof(path), "%s%s", ptr, elpath); - fname = path; + FILE *fp; + size_t len; + char *ptr, path[MAXPATHLEN]; + + fp = NULL; + if (fname == NULL) { + if (issetugid()) + return (-1); + if ((ptr = getenv("HOME")) == NULL) + return (-1); + if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path)) + return (-1); + if (strlcat(path, elpath, sizeof(path)) >= sizeof(path)) + return (-1); + fname = path; } - } - - if ((fp = fopen(fname, "r")) == NULL) - return -1; - - while ((ptr = fgetln(fp, &len)) != NULL) { - if (ptr[len - 1] == '\n') - --len; - ptr[len] = '\0'; - if (parse_line(el, ptr) == -1) { - (void) fclose(fp); - return -1; + if (fp == NULL) + fp = fopen(fname, "r"); + if (fp == NULL) + return (-1); + + while ((ptr = fgetln(fp, &len)) != NULL) { + if (len > 0 && ptr[len - 1] == '\n') + --len; + ptr[len] = '\0'; + if (parse_line(el, ptr) == -1) { + (void) fclose(fp); + return (-1); + } } - } - (void) fclose(fp); - return 0; + (void) fclose(fp); + return (0); } @@ -326,18 +436,54 @@ el_source(el, fname) * Called from program when terminal is resized */ public void -el_resize(el) - EditLine *el; +el_resize(EditLine *el) { - int lins, cols; - sigset_t oset, nset; - (void) sigemptyset(&nset); - (void) sigaddset(&nset, SIGWINCH); - (void) sigprocmask(SIG_BLOCK, &nset, &oset); + int lins, cols; + sigset_t oset, nset; - /* get the correct window size */ - if (term_get_size(el, &lins, &cols)) - term_change_size(el, lins, cols); + (void) sigemptyset(&nset); + (void) sigaddset(&nset, SIGWINCH); + (void) sigprocmask(SIG_BLOCK, &nset, &oset); - (void) sigprocmask(SIG_SETMASK, &oset, NULL); + /* get the correct window size */ + if (term_get_size(el, &lins, &cols)) + term_change_size(el, lins, cols); + + (void) sigprocmask(SIG_SETMASK, &oset, NULL); +} + + +/* el_beep(): + * Called from the program to beep + */ +public void +el_beep(EditLine *el) +{ + + term_beep(el); +} + + +/* el_editmode() + * Set the state of EDIT_DISABLED from the `edit' command. + */ +protected int +/*ARGSUSED*/ +el_editmode(EditLine *el, int argc, char **argv) +{ + const char *how; + + if (argv == NULL || argc != 2 || argv[1] == NULL) + return (-1); + + how = argv[1]; + if (strcmp(how, "on") == 0) + el->el_flags &= ~EDIT_DISABLED; + else if (strcmp(how, "off") == 0) + el->el_flags |= EDIT_DISABLED; + else { + (void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how); + return (-1); + } + return (0); } @@ -1,4 +1,4 @@ -/* $NetBSD: el.h,v 1.2 1997/01/11 06:47:53 lukem Exp $ */ +/* $NetBSD: el.h,v 1.9 2001/09/27 19:29:50 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,53 +42,56 @@ * el.h: Internal structures. */ #ifndef _h_el -#define _h_el +#define _h_el /* * Local defaults */ -#define KSHVI -#define VIDEFAULT -#define ANCHOR +#define KSHVI +#define VIDEFAULT +#define ANCHOR #include <stdio.h> #include <sys/types.h> -#define EL_BUFSIZ 1024 /* Maximum line size */ +#define EL_BUFSIZ 1024 /* Maximum line size */ -#define HANDLE_SIGNALS 1 +#define HANDLE_SIGNALS 1<<0 +#define NO_TTY 1<<1 +#define EDIT_DISABLED 1<<2 typedef int bool_t; /* True or not */ typedef unsigned char el_action_t; /* Index to command array */ typedef struct coord_t { /* Position on the screen */ - int h, v; + int h; + int v; } coord_t; typedef struct el_line_t { - char *buffer, /* Input line */ - *cursor, /* Cursor position */ - *lastchar, /* Last character */ - *limit; /* Max position */ + char *buffer; /* Input line */ + char *cursor; /* Cursor position */ + char *lastchar; /* Last character */ + const char *limit; /* Max position */ } el_line_t; /* * Editor state */ typedef struct el_state_t { - int inputmode; /* What mode are we in? */ - int doingarg; /* Are we getting an argument? */ - int argument; /* Numeric argument */ - int metanext; /* Is the next char a meta char */ - el_action_t lastcmd; /* Previous command */ + int inputmode; /* What mode are we in? */ + int doingarg; /* Are we getting an argument? */ + int argument; /* Numeric argument */ + int metanext; /* Is the next char a meta char */ + el_action_t lastcmd; /* Previous command */ } el_state_t; /* * Until we come up with something better... */ -#define el_malloc(a) malloc(a) -#define el_realloc(a,b) realloc(a, b) -#define el_free(a) free(a) +#define el_malloc(a) malloc(a) +#define el_realloc(a,b) realloc(a, b) +#define el_free(a) free(a) #include "tty.h" #include "prompt.h" @@ -103,29 +106,39 @@ typedef struct el_state_t { #include "parse.h" #include "sig.h" #include "help.h" +#include "read.h" struct editline { - char *el_prog; /* the program name */ - FILE *el_outfile; /* Stdio stuff */ - FILE *el_errfile; /* Stdio stuff */ - int el_infd; /* Input file descriptor */ - int el_flags; /* Various flags. */ - coord_t el_cursor; /* Cursor location */ - char **el_display, /* Real screen image = what is there */ - **el_vdisplay; /* Virtual screen image = what we see */ - - el_line_t el_line; /* The current line information */ - el_state_t el_state; /* Current editor state */ - el_term_t el_term; /* Terminal dependent stuff */ - el_tty_t el_tty; /* Tty dependent stuff */ - el_refresh_t el_refresh; /* Refresh stuff */ - el_prompt_t el_prompt; /* Prompt stuff */ - el_chared_t el_chared; /* Characted editor stuff */ - el_map_t el_map; /* Key mapping stuff */ - el_key_t el_key; /* Key binding stuff */ - el_history_t el_history; /* History stuff */ - el_search_t el_search; /* Search stuff */ - el_signal_t el_signal; /* Signal handling stuff */ + char *el_prog; /* the program name */ + FILE *el_outfile; /* Stdio stuff */ + FILE *el_errfile; /* Stdio stuff */ + int el_infd; /* Input file descriptor */ + int el_flags; /* Various flags. */ + coord_t el_cursor; /* Cursor location */ + char **el_display; /* Real screen image = what is there */ + char **el_vdisplay; /* Virtual screen image = what we see */ + el_line_t el_line; /* The current line information */ + el_state_t el_state; /* Current editor state */ + el_term_t el_term; /* Terminal dependent stuff */ + el_tty_t el_tty; /* Tty dependent stuff */ + el_refresh_t el_refresh; /* Refresh stuff */ + el_prompt_t el_prompt; /* Prompt stuff */ + el_prompt_t el_rprompt; /* Prompt stuff */ + el_chared_t el_chared; /* Characted editor stuff */ + el_map_t el_map; /* Key mapping stuff */ + el_key_t el_key; /* Key binding stuff */ + el_history_t el_history; /* History stuff */ + el_search_t el_search; /* Search stuff */ + el_signal_t el_signal; /* Signal handling stuff */ + el_read_t el_read; /* Character reading stuff */ }; +protected int el_editmode(EditLine *, int, char **); + +#ifdef DEBUG +#define EL_ABORT(a) (void) (fprintf(el->el_errfile, "%s, %d: ", \ + __FILE__, __LINE__), fprintf a, abort()) +#else +#define EL_ABORT(a) abort() +#endif #endif /* _h_el */ diff --git a/dist/emacs.c b/dist/emacs.c index a1f84c2..cc18411 100644 --- a/dist/emacs.c +++ b/dist/emacs.c @@ -1,4 +1,4 @@ -/* $NetBSD: emacs.c,v 1.3 1997/01/11 06:47:54 lukem Exp $ */ +/* $NetBSD: emacs.c,v 1.9 2001/01/10 07:45:41 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,15 +36,16 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: emacs.c,v 1.3 1997/01/11 06:47:54 lukem Exp $"; +__RCSID("$NetBSD: emacs.c,v 1.9 2001/01/10 07:45:41 jdolecek Exp $"); #endif #endif /* not lint && not SCCSID */ -/* +/* * emacs.c: Emacs functions */ #include "sys.h" @@ -56,28 +57,31 @@ static char rcsid[] = "$NetBSD: emacs.c,v 1.3 1997/01/11 06:47:54 lukem Exp $"; */ protected el_action_t /*ARGSUSED*/ -em_delete_or_list(el, c) - EditLine *el; - int c; +em_delete_or_list(EditLine *el, int c) { - if (el->el_line.cursor == el->el_line.lastchar) { /* if I'm at the end */ - if (el->el_line.cursor == el->el_line.buffer) { /* and the beginning */ - term_overwrite(el, STReof, 4);/* then do a EOF */ - term__flush(); - return CC_EOF; - } - else { - /* Here we could list completions, but it is an error right now */ - term_beep(el); - return CC_ERROR; + + if (el->el_line.cursor == el->el_line.lastchar) { + /* if I'm at the end */ + if (el->el_line.cursor == el->el_line.buffer) { + /* and the beginning */ + term_overwrite(el, STReof, 4); /* then do a EOF */ + term__flush(); + return (CC_EOF); + } else { + /* + * Here we could list completions, but it is an + * error right now + */ + term_beep(el); + return (CC_ERROR); + } + } else { + c_delafter(el, el->el_state.argument); /* delete after dot */ + if (el->el_line.cursor > el->el_line.lastchar) + el->el_line.cursor = el->el_line.lastchar; + /* bounds check */ + return (CC_REFRESH); } - } - else { - c_delafter(el, el->el_state.argument); /* delete after dot */ - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; /* bounds check */ - return CC_REFRESH; - } } @@ -87,27 +91,26 @@ em_delete_or_list(el, c) */ protected el_action_t /*ARGSUSED*/ -em_delete_next_word(el, c) - EditLine *el; - int c; +em_delete_next_word(EditLine *el, int c) { - char *cp, *p, *kp; + char *cp, *p, *kp; - if (el->el_line.cursor == el->el_line.lastchar) - return CC_ERROR; + if (el->el_line.cursor == el->el_line.lastchar) + return (CC_ERROR); - cp = c__next_word(el->el_line.cursor, el->el_line.lastchar, - el->el_state.argument, ce__isword); + cp = c__next_word(el->el_line.cursor, el->el_line.lastchar, + el->el_state.argument, ce__isword); - for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++) - /* save the text */ - *kp++ = *p; - el->el_chared.c_kill.last = kp; + for (p = el->el_line.cursor, kp = el->el_chared.c_kill.buf; p < cp; p++) + /* save the text */ + *kp++ = *p; + el->el_chared.c_kill.last = kp; - c_delafter(el, cp - el->el_line.cursor); /* delete after dot */ - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; /* bounds check */ - return CC_REFRESH; + c_delafter(el, cp - el->el_line.cursor); /* delete after dot */ + if (el->el_line.cursor > el->el_line.lastchar) + el->el_line.cursor = el->el_line.lastchar; + /* bounds check */ + return (CC_REFRESH); } @@ -117,34 +120,34 @@ em_delete_next_word(el, c) */ protected el_action_t /*ARGSUSED*/ -em_yank(el, c) - EditLine *el; - int c; +em_yank(EditLine *el, int c) { - char *kp, *cp; + char *kp, *cp; - if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) - return CC_ERROR; + if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) { + if (!ch_enlargebufs(el, 1)) + return (CC_ERROR); + } - if (el->el_line.lastchar + - (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >= - el->el_line.limit) - return CC_ERROR; + if (el->el_line.lastchar + + (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >= + el->el_line.limit) + return (CC_ERROR); - el->el_chared.c_kill.mark = el->el_line.cursor; - cp = el->el_line.cursor; + el->el_chared.c_kill.mark = el->el_line.cursor; + cp = el->el_line.cursor; - /* open the space, */ - c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf); - /* copy the chars */ - for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++) - *cp++ = *kp; + /* open the space, */ + c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf); + /* copy the chars */ + for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++) + *cp++ = *kp; - /* if an arg, cursor at beginning else cursor at end */ - if (el->el_state.argument == 1) - el->el_line.cursor = cp; + /* if an arg, cursor at beginning else cursor at end */ + if (el->el_state.argument == 1) + el->el_line.cursor = cp; - return CC_REFRESH; + return (CC_REFRESH); } @@ -154,20 +157,19 @@ em_yank(el, c) */ protected el_action_t /*ARGSUSED*/ -em_kill_line(el, c) - EditLine *el; - int c; +em_kill_line(EditLine *el, int c) { - char *kp, *cp; - - cp = el->el_line.buffer; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_line.lastchar) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - el->el_line.lastchar = el->el_line.buffer; /* zap! -- delete all of it */ - el->el_line.cursor = el->el_line.buffer; - return CC_REFRESH; + char *kp, *cp; + + cp = el->el_line.buffer; + kp = el->el_chared.c_kill.buf; + while (cp < el->el_line.lastchar) + *kp++ = *cp++; /* copy it */ + el->el_chared.c_kill.last = kp; + /* zap! -- delete all of it */ + el->el_line.lastchar = el->el_line.buffer; + el->el_line.cursor = el->el_line.buffer; + return (CC_REFRESH); } @@ -177,33 +179,30 @@ em_kill_line(el, c) */ protected el_action_t /*ARGSUSED*/ -em_kill_region(el, c) - EditLine *el; - int c; +em_kill_region(EditLine *el, int c) { - char *kp, *cp; - - if (!el->el_chared.c_kill.mark) - return CC_ERROR; - - if (el->el_chared.c_kill.mark > el->el_line.cursor) { - cp = el->el_line.cursor; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_chared.c_kill.mark) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - c_delafter(el, cp - el->el_line.cursor); - } - else { /* mark is before cursor */ - cp = el->el_chared.c_kill.mark; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_line.cursor) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - c_delbefore(el, cp - el->el_chared.c_kill.mark); - el->el_line.cursor = el->el_chared.c_kill.mark; - } - return CC_REFRESH; + char *kp, *cp; + + if (!el->el_chared.c_kill.mark) + return (CC_ERROR); + + if (el->el_chared.c_kill.mark > el->el_line.cursor) { + cp = el->el_line.cursor; + kp = el->el_chared.c_kill.buf; + while (cp < el->el_chared.c_kill.mark) + *kp++ = *cp++; /* copy it */ + el->el_chared.c_kill.last = kp; + c_delafter(el, cp - el->el_line.cursor); + } else { /* mark is before cursor */ + cp = el->el_chared.c_kill.mark; + kp = el->el_chared.c_kill.buf; + while (cp < el->el_line.cursor) + *kp++ = *cp++; /* copy it */ + el->el_chared.c_kill.last = kp; + c_delbefore(el, cp - el->el_chared.c_kill.mark); + el->el_line.cursor = el->el_chared.c_kill.mark; + } + return (CC_REFRESH); } @@ -213,30 +212,27 @@ em_kill_region(el, c) */ protected el_action_t /*ARGSUSED*/ -em_copy_region(el, c) - EditLine *el; - int c; +em_copy_region(EditLine *el, int c) { - char *kp, *cp; - - if (el->el_chared.c_kill.mark) - return CC_ERROR; - - if (el->el_chared.c_kill.mark > el->el_line.cursor) { - cp = el->el_line.cursor; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_chared.c_kill.mark) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - } - else { - cp = el->el_chared.c_kill.mark; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_line.cursor) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - } - return CC_NORM; + char *kp, *cp; + + if (el->el_chared.c_kill.mark) + return (CC_ERROR); + + if (el->el_chared.c_kill.mark > el->el_line.cursor) { + cp = el->el_line.cursor; + kp = el->el_chared.c_kill.buf; + while (cp < el->el_chared.c_kill.mark) + *kp++ = *cp++; /* copy it */ + el->el_chared.c_kill.last = kp; + } else { + cp = el->el_chared.c_kill.mark; + kp = el->el_chared.c_kill.buf; + while (cp < el->el_line.cursor) + *kp++ = *cp++; /* copy it */ + el->el_chared.c_kill.last = kp; + } + return (CC_NORM); } @@ -245,20 +241,17 @@ em_copy_region(el, c) * Gosling emacs transpose chars [^T] */ protected el_action_t -em_gosmacs_traspose(el, c) - EditLine *el; - int c; +em_gosmacs_traspose(EditLine *el, int c) { - if (el->el_line.cursor > &el->el_line.buffer[1]) { - /* must have at least two chars entered */ - c = el->el_line.cursor[-2]; - el->el_line.cursor[-2] = el->el_line.cursor[-1]; - el->el_line.cursor[-1] = c; - return CC_REFRESH; - } - else - return CC_ERROR; + if (el->el_line.cursor > &el->el_line.buffer[1]) { + /* must have at least two chars entered */ + c = el->el_line.cursor[-2]; + el->el_line.cursor[-2] = el->el_line.cursor[-1]; + el->el_line.cursor[-1] = c; + return (CC_REFRESH); + } else + return (CC_ERROR); } @@ -268,49 +261,46 @@ em_gosmacs_traspose(el, c) */ protected el_action_t /*ARGSUSED*/ -em_next_word(el, c) - EditLine *el; - int c; +em_next_word(EditLine *el, int c) { - if (el->el_line.cursor == el->el_line.lastchar) - return CC_ERROR; - - el->el_line.cursor = c__next_word(el->el_line.cursor, el->el_line.lastchar, - el->el_state.argument, - ce__isword); - - if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action & DELETE) { - cv_delfini(el); - return CC_REFRESH; - } - - return CC_CURSOR; + if (el->el_line.cursor == el->el_line.lastchar) + return (CC_ERROR); + + el->el_line.cursor = c__next_word(el->el_line.cursor, + el->el_line.lastchar, + el->el_state.argument, + ce__isword); + + if (el->el_map.type == MAP_VI) + if (el->el_chared.c_vcmd.action & DELETE) { + cv_delfini(el); + return (CC_REFRESH); + } + return (CC_CURSOR); } + /* em_upper_case(): * Uppercase the characters from cursor to end of current word * [M-u] */ protected el_action_t /*ARGSUSED*/ -em_upper_case(el, c) - EditLine *el; - int c; +em_upper_case(EditLine *el, int c) { - char *cp, *ep; + char *cp, *ep; - ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, - el->el_state.argument, ce__isword); + ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, + el->el_state.argument, ce__isword); - for (cp = el->el_line.cursor; cp < ep; cp++) - if (islower(*cp)) - *cp = toupper(*cp); + for (cp = el->el_line.cursor; cp < ep; cp++) + if (islower((unsigned char) *cp)) + *cp = toupper(*cp); - el->el_line.cursor = ep; - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; - return CC_REFRESH; + el->el_line.cursor = ep; + if (el->el_line.cursor > el->el_line.lastchar) + el->el_line.cursor = el->el_line.lastchar; + return (CC_REFRESH); } @@ -320,56 +310,53 @@ em_upper_case(el, c) */ protected el_action_t /*ARGSUSED*/ -em_capitol_case(el, c) - EditLine *el; - int c; +em_capitol_case(EditLine *el, int c) { - char *cp, *ep; - - ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, - el->el_state.argument, ce__isword); - - for (cp = el->el_line.cursor; cp < ep; cp++) { - if (isalpha(*cp)) { - if (islower(*cp)) - *cp = toupper(*cp); - cp++; - break; + char *cp, *ep; + + ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, + el->el_state.argument, ce__isword); + + for (cp = el->el_line.cursor; cp < ep; cp++) { + if (isalpha((unsigned char) *cp)) { + if (islower((unsigned char) *cp)) + *cp = toupper(*cp); + cp++; + break; + } } - } - for (; cp < ep; cp++) - if (isupper(*cp)) - *cp = tolower(*cp); - - el->el_line.cursor = ep; - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; - return CC_REFRESH; + for (; cp < ep; cp++) + if (isupper((unsigned char) *cp)) + *cp = tolower(*cp); + + el->el_line.cursor = ep; + if (el->el_line.cursor > el->el_line.lastchar) + el->el_line.cursor = el->el_line.lastchar; + return (CC_REFRESH); } + /* em_lower_case(): * Lowercase the characters from cursor to end of current word * [M-l] */ protected el_action_t /*ARGSUSED*/ -em_lower_case(el, c) - EditLine *el; - int c; +em_lower_case(EditLine *el, int c) { - char *cp, *ep; + char *cp, *ep; - ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, - el->el_state.argument, ce__isword); + ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, + el->el_state.argument, ce__isword); - for (cp = el->el_line.cursor; cp < ep; cp++) - if (isupper(*cp)) - *cp = tolower(*cp); + for (cp = el->el_line.cursor; cp < ep; cp++) + if (isupper((unsigned char) *cp)) + *cp = tolower(*cp); - el->el_line.cursor = ep; - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; - return CC_REFRESH; + el->el_line.cursor = ep; + if (el->el_line.cursor > el->el_line.lastchar) + el->el_line.cursor = el->el_line.lastchar; + return (CC_REFRESH); } @@ -379,62 +366,59 @@ em_lower_case(el, c) */ protected el_action_t /*ARGSUSED*/ -em_set_mark(el, c) - EditLine *el; - int c; +em_set_mark(EditLine *el, int c) { - el->el_chared.c_kill.mark = el->el_line.cursor; - return CC_NORM; + + el->el_chared.c_kill.mark = el->el_line.cursor; + return (CC_NORM); } /* em_exchange_mark(): - * Exchange the cursor and mark + * Exchange the cursor and mark * [^X^X] */ protected el_action_t /*ARGSUSED*/ -em_exchange_mark(el, c) - EditLine *el; - int c; +em_exchange_mark(EditLine *el, int c) { - register char *cp; + char *cp; - cp = el->el_line.cursor; - el->el_line.cursor = el->el_chared.c_kill.mark; - el->el_chared.c_kill.mark = cp; - return CC_CURSOR; + cp = el->el_line.cursor; + el->el_line.cursor = el->el_chared.c_kill.mark; + el->el_chared.c_kill.mark = cp; + return (CC_CURSOR); } + /* em_universal_argument(): * Universal argument (argument times 4) * [^U] */ protected el_action_t /*ARGSUSED*/ -em_universal_argument(el, c) - EditLine *el; - int c; +em_universal_argument(EditLine *el, int c) { /* multiply current argument by 4 */ - if (el->el_state.argument > 1000000) - return CC_ERROR; - el->el_state.doingarg = 1; - el->el_state.argument *= 4; - return CC_ARGHACK; + + if (el->el_state.argument > 1000000) + return (CC_ERROR); + el->el_state.doingarg = 1; + el->el_state.argument *= 4; + return (CC_ARGHACK); } + /* em_meta_next(): * Add 8th bit to next character typed * [<ESC>] */ protected el_action_t /*ARGSUSED*/ -em_meta_next(el, c) - EditLine *el; - int c; +em_meta_next(EditLine *el, int c) { - el->el_state.metanext = 1; - return CC_ARGHACK; + + el->el_state.metanext = 1; + return (CC_ARGHACK); } @@ -443,13 +427,12 @@ em_meta_next(el, c) */ protected el_action_t /*ARGSUSED*/ -em_toggle_overwrite(el, c) - EditLine *el; - int c; +em_toggle_overwrite(EditLine *el, int c) { - el->el_state.inputmode = - (el->el_state.inputmode == MODE_INSERT) ? MODE_REPLACE : MODE_INSERT; - return CC_NORM; + + el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ? + MODE_REPLACE : MODE_INSERT; + return (CC_NORM); } @@ -458,27 +441,25 @@ em_toggle_overwrite(el, c) */ protected el_action_t /*ARGSUSED*/ -em_copy_prev_word(el, c) - EditLine *el; - int c; +em_copy_prev_word(EditLine *el, int c) { - char *cp, *oldc, *dp; + char *cp, *oldc, *dp; - if (el->el_line.cursor == el->el_line.buffer) - return CC_ERROR; + if (el->el_line.cursor == el->el_line.buffer) + return (CC_ERROR); - oldc = el->el_line.cursor; - /* does a bounds check */ - cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, - el->el_state.argument, ce__isword); + oldc = el->el_line.cursor; + /* does a bounds check */ + cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, + el->el_state.argument, ce__isword); - c_insert(el, oldc - cp); - for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++) - *dp++ = *cp; + c_insert(el, oldc - cp); + for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++) + *dp++ = *cp; - el->el_line.cursor = dp; /* put cursor at end */ + el->el_line.cursor = dp;/* put cursor at end */ - return CC_REFRESH; + return (CC_REFRESH); } @@ -487,12 +468,11 @@ em_copy_prev_word(el, c) */ protected el_action_t /*ARGSUSED*/ -em_inc_search_next(el, c) - EditLine *el; - int c; +em_inc_search_next(EditLine *el, int c) { - el->el_search.patlen = 0; - return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY); + + el->el_search.patlen = 0; + return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY)); } @@ -501,10 +481,9 @@ em_inc_search_next(el, c) */ protected el_action_t /*ARGSUSED*/ -em_inc_search_prev(el, c) - EditLine *el; - int c; +em_inc_search_prev(EditLine *el, int c) { - el->el_search.patlen = 0; - return ce_inc_search(el, ED_SEARCH_PREV_HISTORY); + + el->el_search.patlen = 0; + return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY)); } diff --git a/dist/hist.c b/dist/hist.c index 7e46a48..31589b8 100644 --- a/dist/hist.c +++ b/dist/hist.c @@ -1,4 +1,4 @@ -/* $NetBSD: hist.c,v 1.2 1997/01/11 06:47:55 lukem Exp $ */ +/* $NetBSD: hist.c,v 1.9 2001/05/17 01:02:17 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,11 +36,12 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: hist.c,v 1.2 1997/01/11 06:47:55 lukem Exp $"; +__RCSID("$NetBSD: hist.c,v 1.9 2001/05/17 01:02:17 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -55,14 +56,17 @@ static char rcsid[] = "$NetBSD: hist.c,v 1.2 1997/01/11 06:47:55 lukem Exp $"; * Initialization function. */ protected int -hist_init(el) - EditLine *el; +hist_init(EditLine *el) { - el->el_history.fun = NULL; - el->el_history.ref = NULL; - el->el_history.buf = (char *) el_malloc(EL_BUFSIZ); - el->el_history.last = el->el_history.buf; - return 0; + + el->el_history.fun = NULL; + el->el_history.ref = NULL; + el->el_history.buf = (char *) el_malloc(EL_BUFSIZ); + el->el_history.sz = EL_BUFSIZ; + if (el->el_history.buf == NULL) + return (-1); + el->el_history.last = el->el_history.buf; + return (0); } @@ -70,11 +74,11 @@ hist_init(el) * clean up history; */ protected void -hist_end(el) - EditLine *el; +hist_end(EditLine *el) { - el_free((ptr_t) el->el_history.buf); - el->el_history.buf = NULL; + + el_free((ptr_t) el->el_history.buf); + el->el_history.buf = NULL; } @@ -82,15 +86,12 @@ hist_end(el) * Set new history interface */ protected int -hist_set(el, fun, ptr) - EditLine *el; - hist_fun_t fun; - ptr_t ptr; - +hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr) { - el->el_history.ref = ptr; - el->el_history.fun = fun; - return 0; + + el->el_history.ref = ptr; + el->el_history.fun = fun; + return (0); } @@ -99,78 +100,99 @@ hist_set(el, fun, ptr) * eventno tells us the event to get. */ protected el_action_t -hist_get(el) - EditLine *el; +hist_get(EditLine *el) { - const char *hp; - int h; + const char *hp; + int h; - if (el->el_history.eventno == 0) { /* if really the current line */ - (void) strncpy(el->el_line.buffer, el->el_history.buf, EL_BUFSIZ); - el->el_line.lastchar = el->el_line.buffer + - (el->el_history.last - el->el_history.buf); + if (el->el_history.eventno == 0) { /* if really the current line */ + (void) strncpy(el->el_line.buffer, el->el_history.buf, + el->el_history.sz); + el->el_line.lastchar = el->el_line.buffer + + (el->el_history.last - el->el_history.buf); #ifdef KSHVI - if (el->el_map.type == MAP_VI) - el->el_line.cursor = el->el_line.buffer; - else + if (el->el_map.type == MAP_VI) + el->el_line.cursor = el->el_line.buffer; + else #endif /* KSHVI */ - el->el_line.cursor = el->el_line.lastchar; - - return CC_REFRESH; - } - - if (el->el_history.ref == NULL) - return CC_ERROR; + el->el_line.cursor = el->el_line.lastchar; - hp = HIST_FIRST(el); - - if (hp == NULL) - return CC_ERROR; - - for (h = 1; h < el->el_history.eventno; h++) - if ((hp = HIST_NEXT(el)) == NULL) { - el->el_history.eventno = h; - return CC_ERROR; + return (CC_REFRESH); + } + if (el->el_history.ref == NULL) + return (CC_ERROR); + + hp = HIST_FIRST(el); + + if (hp == NULL) + return (CC_ERROR); + + for (h = 1; h < el->el_history.eventno; h++) + if ((hp = HIST_NEXT(el)) == NULL) { + el->el_history.eventno = h; + return (CC_ERROR); + } + (void) strncpy(el->el_line.buffer, hp, + (size_t)(el->el_line.limit - el->el_line.buffer)); + el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer); + + if (el->el_line.lastchar > el->el_line.buffer) { + if (el->el_line.lastchar[-1] == '\n') + el->el_line.lastchar--; + if (el->el_line.lastchar[-1] == ' ') + el->el_line.lastchar--; + if (el->el_line.lastchar < el->el_line.buffer) + el->el_line.lastchar = el->el_line.buffer; } - - (void) strncpy(el->el_line.buffer, hp, EL_BUFSIZ); - 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[-1] == '\n') - el->el_line.lastchar--; - if (el->el_line.lastchar[-1] == ' ') - el->el_line.lastchar--; - if (el->el_line.lastchar < el->el_line.buffer) - el->el_line.lastchar = el->el_line.buffer; - } - #ifdef KSHVI - if (el->el_map.type == MAP_VI) - el->el_line.cursor = el->el_line.buffer; - else + if (el->el_map.type == MAP_VI) + el->el_line.cursor = el->el_line.buffer; + else #endif /* KSHVI */ - el->el_line.cursor = el->el_line.lastchar; + el->el_line.cursor = el->el_line.lastchar; - return CC_REFRESH; + return (CC_REFRESH); } + /* hist_list() * List history entries */ protected int /*ARGSUSED*/ -hist_list(el, argc, argv) - EditLine *el; - int argc; - char **argv; +hist_list(EditLine *el, int argc, char **argv) { - const char *str; + const char *str; + + if (el->el_history.ref == NULL) + return (-1); + 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); +} + +/* hist_enlargebuf() + * Enlarge history buffer to specified value. Called from el_enlargebufs(). + * Return 0 for failure, 1 for success. + */ +protected int +/*ARGSUSED*/ +hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz) +{ + char *newbuf; + + newbuf = realloc(el->el_history.buf, newsz); + if (!newbuf) + return 0; + + (void) memset(&newbuf[oldsz], '\0', newsz - oldsz); + + el->el_history.last = newbuf + + (el->el_history.last - el->el_history.buf); + el->el_history.buf = newbuf; + el->el_history.sz = newsz; - if (el->el_history.ref == NULL) - return -1; - 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; + return 1; } diff --git a/dist/hist.h b/dist/hist.h index af6d649..9023e61 100644 --- a/dist/hist.h +++ b/dist/hist.h @@ -1,4 +1,4 @@ -/* $NetBSD: hist.h,v 1.3 1997/01/11 06:47:56 lukem Exp $ */ +/* $NetBSD: hist.h,v 1.6 2001/01/10 07:45:41 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,25 +42,25 @@ * el.hist.c: History functions */ #ifndef _h_el_hist -#define _h_el_hist +#define _h_el_hist #include "histedit.h" -typedef const HistEvent * (*hist_fun_t) __P((ptr_t, int, ...)); +typedef int (*hist_fun_t)(ptr_t, HistEvent *, int, ...); typedef struct el_history_t { - char *buf; /* The history buffer */ - char *last; /* The last character */ - int eventno; /* Event we are looking for */ - ptr_t ref; /* Argument for history fcns */ - hist_fun_t fun; /* Event access */ - const HistEvent *ev; /* Event cookie */ + char *buf; /* The history buffer */ + size_t sz; /* Size of history buffer */ + char *last; /* The last character */ + int eventno; /* Event we are looking for */ + ptr_t ref; /* Argument for history fcns */ + hist_fun_t fun; /* Event access */ + HistEvent ev; /* Event cookie */ } el_history_t; -#define HIST_FUN(el, fn, arg) \ - ((((el)->el_history.ev = \ - (*(el)->el_history.fun)((el)->el_history.ref, fn, arg)) == NULL) ? \ - NULL : (el)->el_history.ev->str) +#define HIST_FUN(el, fn, arg) \ + ((((*(el)->el_history.fun) ((el)->el_history.ref, &(el)->el_history.ev, \ + fn, arg)) == -1) ? NULL : (el)->el_history.ev.str) #define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL) #define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL) @@ -70,10 +70,11 @@ typedef struct el_history_t { #define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname) #define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname) -protected int hist_init __P((EditLine *)); -protected void hist_end __P((EditLine *)); -protected el_action_t hist_get __P((EditLine *)); -protected int hist_set __P((EditLine *, hist_fun_t, ptr_t)); -protected int hist_list __P((EditLine *, int, char **)); +protected int hist_init(EditLine *); +protected void hist_end(EditLine *); +protected el_action_t hist_get(EditLine *); +protected int hist_set(EditLine *, hist_fun_t, ptr_t); +protected int hist_list(EditLine *, int, char **); +protected int hist_enlargebuf(EditLine *, size_t, size_t); #endif /* _h_el_hist */ diff --git a/dist/histedit.h b/dist/histedit.h index 3e138d6..9c3a2dc 100644 --- a/dist/histedit.h +++ b/dist/histedit.h @@ -1,4 +1,4 @@ -/* $NetBSD: histedit.h,v 1.5 1997/04/11 17:52:45 christos Exp $ */ +/* $NetBSD: histedit.h,v 1.17 2001/09/27 19:29:50 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -41,8 +41,8 @@ /* * histedit.h: Line editor and history interface. */ -#ifndef _h_editline -#define _h_editline +#ifndef _HISTEDIT_H_ +#define _HISTEDIT_H_ #include <sys/types.h> #include <stdio.h> @@ -56,9 +56,9 @@ typedef struct editline EditLine; * For user-defined function interface */ typedef struct lineinfo { - const char *buffer; - const char *cursor; - const char *lastchar; + const char *buffer; + const char *cursor; + const char *lastchar; } LineInfo; @@ -69,46 +69,53 @@ typedef struct lineinfo { #define CC_NORM 0 #define CC_NEWLINE 1 #define CC_EOF 2 -#define CC_ARGHACK 3 -#define CC_REFRESH 4 +#define CC_ARGHACK 3 +#define CC_REFRESH 4 #define CC_CURSOR 5 #define CC_ERROR 6 -#define CC_FATAL 7 -#define CC_REDISPLAY 8 +#define CC_FATAL 7 +#define CC_REDISPLAY 8 +#define CC_REFRESH_BEEP 9 /* * Initialization, cleanup, and resetting */ -EditLine *el_init __P((const char *, FILE *, FILE *)); -void el_reset __P((EditLine *)); -void el_end __P((EditLine *)); +EditLine *el_init(const char *, FILE *, FILE *, FILE *); +void el_reset(EditLine *); +void el_end(EditLine *); /* * Get a line, a character or push a string back in the input queue */ -const char *el_gets __P((EditLine *, int *)); -int el_getc __P((EditLine *, char *)); -void el_push __P((EditLine *, const char *)); +const char *el_gets(EditLine *, int *); +int el_getc(EditLine *, char *); +void el_push(EditLine *, const char *); + +/* + * Beep! + */ +void el_beep(EditLine *); /* * High level function internals control * Parses argc, argv array and executes builtin editline commands */ -int el_parse __P((EditLine *, int, char **)); +int el_parse(EditLine *, int, char **); /* - * Low level editline access function + * Low level editline access functions */ -int el_set __P((EditLine *, int, ...)); +int el_set(EditLine *, int, ...); +int el_get(EditLine *, int, void *); /* * el_set/el_get parameters */ -#define EL_PROMPT 0 /* , el_pfunc_t); */ -#define EL_TERMINAL 1 /* , const char *); */ -#define EL_EDITOR 2 /* , const char *); */ -#define EL_SIGNAL 3 /* , int); */ +#define EL_PROMPT 0 /* , el_pfunc_t); */ +#define EL_TERMINAL 1 /* , const char *); */ +#define EL_EDITOR 2 /* , const char *); */ +#define EL_SIGNAL 3 /* , int); */ #define EL_BIND 4 /* , const char *, ..., NULL); */ #define EL_TELLTC 5 /* , const char *, ..., NULL); */ #define EL_SETTC 6 /* , const char *, ..., NULL); */ @@ -116,27 +123,32 @@ int el_set __P((EditLine *, int, ...)); #define EL_SETTY 8 /* , const char *, ..., NULL); */ #define EL_ADDFN 9 /* , const char *, const char * */ /* , el_func_t); */ -#define EL_HIST 10 /* , hist_fun_t, const char *); */ +#define EL_HIST 10 /* , hist_fun_t, const char *); */ +#define EL_EDITMODE 11 /* , int); */ +#define EL_RPROMPT 12 /* , el_pfunc_t); */ +#define EL_GETCFN 13 /* , el_rfunc_t); */ + +#define EL_BUILTIN_GETCFN (NULL) /* * Source named file or $PWD/.editrc or $HOME/.editrc */ -int el_source __P((EditLine *, const char *)); +int el_source(EditLine *, const char *); /* * Must be called when the terminal changes size; If EL_SIGNAL * is set this is done automatically otherwise it is the responsibility * of the application */ -void el_resize __P((EditLine *)); +void el_resize(EditLine *); /* * User-defined function interface. */ -const LineInfo *el_line __P((EditLine *)); -int el_insertstr __P((EditLine *, char *)); -void el_deletestr __P((EditLine *, int)); +const LineInfo *el_line(EditLine *); +int el_insertstr(EditLine *, const char *); +void el_deletestr(EditLine *, int); /* * ==== History ==== @@ -145,34 +157,37 @@ void el_deletestr __P((EditLine *, int)); typedef struct history History; typedef struct HistEvent { - int num; - const char *str; + int num; + const char *str; } HistEvent; /* * History access functions. */ -History * history_init __P((void)); -void history_end __P((History *)); - -const HistEvent * history __P((History *, int, ...)); - -#define H_FUNC 0 /* , UTSL */ -#define H_EVENT 1 /* , const int); */ -#define H_FIRST 2 /* , void); */ -#define H_LAST 3 /* , void); */ -#define H_PREV 4 /* , void); */ -#define H_NEXT 5 /* , void); */ -#define H_CURR 6 /* , void); */ -#define H_ADD 7 /* , const char*); */ -#define H_ENTER 8 /* , const char*); */ -#define H_END 9 /* , void); */ -#define H_NEXT_STR 10 /* , const char*); */ -#define H_PREV_STR 11 /* , const char*); */ -#define H_NEXT_EVENT 12 /* , const int); */ -#define H_PREV_EVENT 13 /* , const int); */ -#define H_LOAD 14 /* , const char *); */ -#define H_SAVE 15 /* , const char *); */ -#define H_CLEAR 16 /* , void); */ - -#endif /* _h_editline */ +History * history_init(void); +void history_end(History *); + +int history(History *, HistEvent *, int, ...); + +#define H_FUNC 0 /* , UTSL */ +#define H_SETSIZE 1 /* , const int); */ +#define H_GETSIZE 2 /* , void); */ +#define H_FIRST 3 /* , void); */ +#define H_LAST 4 /* , void); */ +#define H_PREV 5 /* , void); */ +#define H_NEXT 6 /* , void); */ +#define H_CURR 8 /* , const int); */ +#define H_SET 7 /* , void); */ +#define H_ADD 9 /* , const char *); */ +#define H_ENTER 10 /* , const char *); */ +#define H_APPEND 11 /* , const char *); */ +#define H_END 12 /* , void); */ +#define H_NEXT_STR 13 /* , const char *); */ +#define H_PREV_STR 14 /* , const char *); */ +#define H_NEXT_EVENT 15 /* , const int); */ +#define H_PREV_EVENT 16 /* , const int); */ +#define H_LOAD 17 /* , const char *); */ +#define H_SAVE 18 /* , const char *); */ +#define H_CLEAR 19 /* , void); */ + +#endif /* _HISTEDIT_H_ */ diff --git a/dist/history.c b/dist/history.c index fed1572..d048898 100644 --- a/dist/history.c +++ b/dist/history.c @@ -1,4 +1,4 @@ -/* $NetBSD: history.c,v 1.5 1997/04/11 17:52:46 christos Exp $ */ +/* $NetBSD: history.c,v 1.18 2001/09/29 17:52:10 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,8 +36,13 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) +#if 0 static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: history.c,v 1.18 2001/09/29 17:52:10 jdolecek Exp $"); +#endif #endif /* not lint && not SCCSID */ /* @@ -47,53 +52,56 @@ static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; #include <string.h> #include <stdlib.h> -#ifdef __STDC__ #include <stdarg.h> -#else -#include <varargs.h> -#endif +#include <vis.h> +#include <sys/stat.h> -static const char hist_cookie[] = "_HiStOrY_V1_\n"; +static const char hist_cookie[] = "_HiStOrY_V2_\n"; #include "histedit.h" -typedef const HistEvent * (*history_gfun_t) __P((ptr_t)); -typedef const HistEvent * (*history_efun_t) __P((ptr_t, const char *)); -typedef void (*history_vfun_t) __P((ptr_t)); +typedef int (*history_gfun_t)(ptr_t, HistEvent *); +typedef int (*history_efun_t)(ptr_t, HistEvent *, const char *); +typedef void (*history_vfun_t)(ptr_t, HistEvent *); +typedef int (*history_sfun_t)(ptr_t, HistEvent *, const int); struct history { - ptr_t h_ref; /* Argument for history fcns */ - history_gfun_t h_first; /* Get the first element */ - history_gfun_t h_next; /* Get the next element */ - history_gfun_t h_last; /* Get the last element */ - history_gfun_t h_prev; /* Get the previous element */ - history_gfun_t h_curr; /* Get the current element */ - history_vfun_t h_clear; /* Clear the history list */ - history_efun_t h_enter; /* Add an element */ - history_efun_t h_add; /* Append to an element */ + ptr_t h_ref; /* Argument for history fcns */ + int h_ent; /* Last entry point for history */ + history_gfun_t h_first; /* Get the first element */ + history_gfun_t h_next; /* Get the next element */ + history_gfun_t h_last; /* Get the last element */ + history_gfun_t h_prev; /* Get the previous element */ + history_gfun_t h_curr; /* Get the current element */ + history_sfun_t h_set; /* Set the current element */ + history_vfun_t h_clear; /* Clear the history list */ + history_efun_t h_enter; /* Add an element */ + history_efun_t h_add; /* Append to an element */ }; - -#define HNEXT(h) (*(h)->h_next)((h)->h_ref) -#define HFIRST(h) (*(h)->h_first)((h)->h_ref) -#define HPREV(h) (*(h)->h_prev)((h)->h_ref) -#define HLAST(h) (*(h)->h_last)((h)->h_ref) -#define HCURR(h) (*(h)->h_curr)((h)->h_ref) -#define HCLEAR(h) (*(h)->h_clear)((h)->h_ref) -#define HENTER(h, str) (*(h)->h_enter)((h)->h_ref, str) -#define HADD(h, str) (*(h)->h_add)((h)->h_ref, str) - -#define h_malloc(a) malloc(a) -#define h_free(a) free(a) - - -private int history_set_num __P((History *, int)); -private int history_set_fun __P((History *, History *)); -private int history_load __P((History *, const char *)); -private int history_save __P((History *, const char *)); -private const HistEvent *history_prev_event __P((History *, int)); -private const HistEvent *history_next_event __P((History *, int)); -private const HistEvent *history_next_string __P((History *, const char *)); -private const HistEvent *history_prev_string __P((History *, const char *)); +#define HNEXT(h, ev) (*(h)->h_next)((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 HLAST(h, ev) (*(h)->h_last)((h)->h_ref, ev) +#define HCURR(h, ev) (*(h)->h_curr)((h)->h_ref, ev) +#define HSET(h, ev, n) (*(h)->h_set)((h)->h_ref, ev, n) +#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 HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str) + +#define h_malloc(a) malloc(a) +#define h_realloc(a, b) realloc((a), (b)) +#define h_free(a) free(a) + + +private int history_setsize(History *, HistEvent *, int); +private int history_getsize(History *, HistEvent *); +private int history_set_fun(History *, History *); +private int history_load(History *, const char *); +private int history_save(History *, const char *); +private int history_prev_event(History *, HistEvent *, int); +private int history_next_event(History *, HistEvent *, int); +private int history_next_string(History *, HistEvent *, const char *); +private int history_prev_string(History *, HistEvent *, const char *); /***********************************************************************/ @@ -102,227 +110,332 @@ private const HistEvent *history_prev_string __P((History *, const char *)); * Builtin- history implementation */ typedef struct hentry_t { - HistEvent ev; /* What we return */ - struct hentry_t *next; /* Next entry */ - struct hentry_t *prev; /* Previous entry */ -} hentry_t; + HistEvent ev; /* What we return */ + struct hentry_t *next; /* Next entry */ + struct hentry_t *prev; /* Previous entry */ +} hentry_t; typedef struct history_t { - hentry_t list; /* Fake list header element */ - hentry_t *cursor; /* Current element in the list */ - int max; /* Maximum number of events */ - int cur; /* Current number of events */ - int eventno; /* Current event number */ -} history_t; - -private const HistEvent *history_def_first __P((ptr_t)); -private const HistEvent *history_def_last __P((ptr_t)); -private const HistEvent *history_def_next __P((ptr_t)); -private const HistEvent *history_def_prev __P((ptr_t)); -private const HistEvent *history_def_curr __P((ptr_t)); -private const HistEvent *history_def_enter __P((ptr_t, const char *)); -private const HistEvent *history_def_add __P((ptr_t, const char *)); -private void history_def_init __P((ptr_t *, int)); -private void history_def_clear __P((ptr_t)); -private const HistEvent *history_def_insert __P((history_t *, const char *)); -private void history_def_delete __P((history_t *, hentry_t *)); - -#define history_def_set(p, num) (void) (((history_t *) p)->max = (num)) - + hentry_t list; /* Fake list header element */ + hentry_t *cursor; /* Current element in the list */ + int max; /* Maximum number of events */ + int cur; /* Current number of events */ + int eventid; /* For generation of unique event id */ +} 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_prev(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_enter(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 void history_def_clear(ptr_t, HistEvent *); +private int history_def_insert(history_t *, HistEvent *, const char *); +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_getsize(p) (((history_t *) p)->cur) + +#define he_strerror(code) he_errlist[code] +#define he_seterrev(evp, code) {\ + evp->num = code;\ + evp->str = he_strerror(code);\ + } + +/* error messages */ +static const char *const he_errlist[] = { + "OK", + "unknown error", + "malloc() failed", + "first event not found", + "last event not found", + "empty list", + "no next event", + "no previous event", + "current event is invalid", + "event not found", + "can't read history from file", + "can't write history", + "required parameter(s) not supplied", + "history size negative", + "function not allowed with other history-functions-set the default", + "bad parameters" +}; +/* error codes */ +#define _HE_OK 0 +#define _HE_UNKNOWN 1 +#define _HE_MALLOC_FAILED 2 +#define _HE_FIRST_NOTFOUND 3 +#define _HE_LAST_NOTFOUND 4 +#define _HE_EMPTY_LIST 5 +#define _HE_END_REACHED 6 +#define _HE_START_REACHED 7 +#define _HE_CURR_INVALID 8 +#define _HE_NOT_FOUND 9 +#define _HE_HIST_READ 10 +#define _HE_HIST_WRITE 11 +#define _HE_PARAM_MISSING 12 +#define _HE_SIZE_NEGATIVE 13 +#define _HE_NOT_ALLOWED 14 +#define _HE_BAD_PARAM 15 /* history_def_first(): * Default function to return the first event in the history. */ -private const HistEvent * -history_def_first(p) - ptr_t p; +private int +history_def_first(ptr_t p, HistEvent *ev) { - history_t *h = (history_t *) p; - h->cursor = h->list.next; - if (h->cursor != &h->list) - return &h->cursor->ev; - else - return NULL; + history_t *h = (history_t *) p; + + h->cursor = h->list.next; + if (h->cursor != &h->list) + *ev = h->cursor->ev; + else { + he_seterrev(ev, _HE_FIRST_NOTFOUND); + return (-1); + } + + return (0); } + /* history_def_last(): * Default function to return the last event in the history. */ -private const HistEvent * -history_def_last(p) - ptr_t p; +private int +history_def_last(ptr_t p, HistEvent *ev) { - history_t *h = (history_t *) p; - h->cursor = h->list.prev; - if (h->cursor != &h->list) - return &h->cursor->ev; - else - return NULL; + history_t *h = (history_t *) p; + + h->cursor = h->list.prev; + if (h->cursor != &h->list) + *ev = h->cursor->ev; + else { + he_seterrev(ev, _HE_LAST_NOTFOUND); + return (-1); + } + + return (0); } + /* history_def_next(): * Default function to return the next event in the history. */ -private const HistEvent * -history_def_next(p) - ptr_t p; +private int +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) - h->cursor = h->cursor->next; - else - return NULL; + if (h->cursor != &h->list) + h->cursor = h->cursor->next; + else { + he_seterrev(ev, _HE_EMPTY_LIST); + return (-1); + } + + if (h->cursor != &h->list) + *ev = h->cursor->ev; + else { + he_seterrev(ev, _HE_END_REACHED); + return (-1); + } - if (h->cursor != &h->list) - return &h->cursor->ev; - else - return NULL; + return (0); } /* history_def_prev(): * Default function to return the previous event in the history. */ -private const HistEvent * -history_def_prev(p) - ptr_t p; +private int +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) + h->cursor = h->cursor->prev; + else { + he_seterrev(ev, + (h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST); + return (-1); + } - if (h->cursor != &h->list) - h->cursor = h->cursor->prev; - else - return NULL; + if (h->cursor != &h->list) + *ev = h->cursor->ev; + else { + he_seterrev(ev, _HE_START_REACHED); + return (-1); + } - if (h->cursor != &h->list) - return &h->cursor->ev; - else - return NULL; + return (0); } /* history_def_curr(): * Default function to return the current event in the history. */ -private const HistEvent * -history_def_curr(p) - ptr_t p; +private int +history_def_curr(ptr_t p, HistEvent *ev) +{ + history_t *h = (history_t *) p; + + if (h->cursor != &h->list) + *ev = h->cursor->ev; + else { + he_seterrev(ev, + (h->cur > 0) ? _HE_CURR_INVALID : _HE_EMPTY_LIST); + return (-1); + } + + return (0); +} + + +/* history_def_set(): + * Default function to set the current event in the history to the + * given one. + */ +private int +history_def_set(ptr_t p, HistEvent *ev, const int n) { - history_t *h = (history_t *) p; + history_t *h = (history_t *) p; - if (h->cursor != &h->list) - return &h->cursor->ev; - else - return NULL; + if (h->cur == 0) { + he_seterrev(ev, _HE_EMPTY_LIST); + return (-1); + } + if (h->cursor == &h->list || h->cursor->ev.num != n) { + for (h->cursor = h->list.next; h->cursor != &h->list; + h->cursor = h->cursor->next) + if (h->cursor->ev.num == n) + break; + } + if (h->cursor == &h->list) { + he_seterrev(ev, _HE_NOT_FOUND); + return (-1); + } + return (0); } + /* history_def_add(): * Append string to element */ -private const HistEvent * -history_def_add(p, str) - ptr_t p; - const char *str; +private int +history_def_add(ptr_t p, HistEvent *ev, const char *str) { - history_t *h = (history_t *) p; - size_t len; - char *s; - - if (h->cursor == &h->list) - return (history_def_enter(p, str)); - len = strlen(h->cursor->ev.str) + strlen(str) + 1; - s = (char *) h_malloc(len); - (void)strcpy(s, h->cursor->ev.str); /* XXX strcpy is safe */ - (void)strcat(s, str); /* XXX strcat is safe */ - h_free((ptr_t) h->cursor->ev.str); - h->cursor->ev.str = s; - return &h->cursor->ev; + history_t *h = (history_t *) p; + size_t len; + char *s; + + if (h->cursor == &h->list) + return (history_def_enter(p, ev, str)); + len = strlen(h->cursor->ev.str) + strlen(str) + 1; + s = (char *) h_malloc(len); + if (!s) { + he_seterrev(ev, _HE_MALLOC_FAILED); + return (-1); + } + (void) strlcpy(s, h->cursor->ev.str, len); + (void) strlcat(s, str, len); + /* LINTED const cast */ + h_free((ptr_t) h->cursor->ev.str); + h->cursor->ev.str = s; + *ev = h->cursor->ev; + return (0); } /* history_def_delete(): * Delete element hp of the h list */ +/* ARGSUSED */ private void -history_def_delete(h, hp) - history_t *h; - hentry_t *hp; +history_def_delete(history_t *h, HistEvent *ev, hentry_t *hp) { - if (hp == &h->list) - abort(); - hp->prev->next = hp->next; - hp->next->prev = hp->prev; - h_free((ptr_t) hp->ev.str); - h_free(hp); - h->cur--; + + if (hp == &h->list) + abort(); + hp->prev->next = hp->next; + hp->next->prev = hp->prev; + /* LINTED const cast */ + h_free((ptr_t) hp->ev.str); + h_free(hp); + h->cur--; } /* history_def_insert(): * Insert element with string str in the h list */ -private const HistEvent * -history_def_insert(h, str) - history_t *h; - const char *str; +private int +history_def_insert(history_t *h, HistEvent *ev, const char *str) { - h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t)); - h->cursor->ev.str = strdup(str); - h->cursor->next = h->list.next; - h->cursor->prev = &h->list; - h->list.next->prev = h->cursor; - h->list.next = h->cursor; - h->cur++; - - return &h->cursor->ev; + + h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t)); + if (h->cursor) + h->cursor->ev.str = strdup(str); + if (!h->cursor || !h->cursor->ev.str) { + he_seterrev(ev, _HE_MALLOC_FAILED); + return (-1); + } + h->cursor->ev.num = ++h->eventid; + h->cursor->next = h->list.next; + h->cursor->prev = &h->list; + h->list.next->prev = h->cursor; + h->list.next = h->cursor; + h->cur++; + + *ev = h->cursor->ev; + return (0); } /* history_def_enter(): * Default function to enter an item in the history */ -private const HistEvent * -history_def_enter(p, str) - ptr_t p; - const char *str; +private int +history_def_enter(ptr_t p, HistEvent *ev, const char *str) { - history_t *h = (history_t *) p; - const HistEvent *ev; + history_t *h = (history_t *) p; + if (history_def_insert(h, ev, str) == -1) + return (-1); /* error, keep error message */ - ev = history_def_insert(h, str); - ((HistEvent*) ev)->num = ++h->eventno; + /* + * Always keep at least one entry. + * This way we don't have to check for the empty list. + */ + while (h->cur > h->max && h->cur > 0) + history_def_delete(h, ev, h->list.prev); - /* - * Always keep at least one entry. - * This way we don't have to check for the empty list. - */ - while (h->cur > h->max + 1) - history_def_delete(h, h->list.prev); - return ev; + return (0); } /* history_def_init(): * Default history initialization function */ +/* ARGSUSED */ private void -history_def_init(p, n) - ptr_t *p; - int n; +history_def_init(ptr_t *p, HistEvent *ev, int n) { - history_t *h = (history_t *) h_malloc(sizeof(history_t)); - if (n <= 0) - n = 0; - h->eventno = 0; - h->cur = 0; - h->max = n; - h->list.next = h->list.prev = &h->list; - h->list.ev.str = NULL; - h->list.ev.num = 0; - h->cursor = &h->list; - *p = (ptr_t) h; + history_t *h = (history_t *) h_malloc(sizeof(history_t)); + + if (n <= 0) + n = 0; + h->eventid = 0; + h->cur = 0; + h->max = n; + h->list.next = h->list.prev = &h->list; + h->list.ev.str = NULL; + h->list.ev.num = 0; + h->cursor = &h->list; + *p = (ptr_t) h; } @@ -330,15 +443,14 @@ history_def_init(p, n) * Default history cleanup function */ private void -history_def_clear(p) - ptr_t p; +history_def_clear(ptr_t p, HistEvent *ev) { - history_t *h = (history_t *) p; + history_t *h = (history_t *) p; - while (h->list.prev != &h->list) - history_def_delete(h, h->list.prev); - h->eventno = 0; - h->cur = 0; + while (h->list.prev != &h->list) + history_def_delete(h, ev, h->list.prev); + h->eventid = 0; + h->cur = 0; } @@ -350,22 +462,24 @@ history_def_clear(p) * Initialization function. */ public History * -history_init() +history_init(void) { - History *h = (History *) h_malloc(sizeof(History)); - - history_def_init(&h->h_ref, 0); - - h->h_next = history_def_next; - h->h_first = history_def_first; - h->h_last = history_def_last; - h->h_prev = history_def_prev; - h->h_curr = history_def_curr; - h->h_clear = history_def_clear; - h->h_enter = history_def_enter; - h->h_add = history_def_add; - - return h; + History *h = (History *) h_malloc(sizeof(History)); + HistEvent ev; + + history_def_init(&h->h_ref, &ev, 0); + h->h_ent = -1; + h->h_next = history_def_next; + h->h_first = history_def_first; + h->h_last = history_def_last; + h->h_prev = history_def_prev; + h->h_curr = history_def_curr; + h->h_set = history_def_set; + h->h_clear = history_def_clear; + h->h_enter = history_def_enter; + h->h_add = history_def_add; + + return (h); } @@ -373,27 +487,55 @@ history_init() * clean up history; */ public void -history_end(h) - History *h; +history_end(History *h) { - if (h->h_next == history_def_next) - history_def_clear(h->h_ref); + HistEvent ev; + + if (h->h_next == history_def_next) + history_def_clear(h->h_ref, &ev); } -/* history_set_num(): +/* history_setsize(): * Set history number of events */ private int -history_set_num(h, num) - History *h; - int num; +history_setsize(History *h, HistEvent *ev, int num) +{ + + if (h->h_next != history_def_next) { + he_seterrev(ev, _HE_NOT_ALLOWED); + return (-1); + } + if (num < 0) { + he_seterrev(ev, _HE_BAD_PARAM); + return (-1); + } + history_def_setsize(h->h_ref, num); + return (0); +} + + +/* history_getsize(): + * Get number of events currently in history + */ +private int +history_getsize(History *h, HistEvent *ev) { - if (h->h_next != history_def_next || num < 0) - return -1; - history_def_set(h->h_ref, num); - return 0; + int retval = 0; + + if (h->h_next != history_def_next) { + he_seterrev(ev, _HE_NOT_ALLOWED); + return (-1); + } + retval = history_def_getsize(h->h_ref); + if (retval < -1) { + he_seterrev(ev, _HE_SIZE_NEGATIVE); + return (-1); + } + ev->num = retval; + return (0); } @@ -401,40 +543,43 @@ history_set_num(h, num) * Set history functions */ private int -history_set_fun(h, nh) - History *h, *nh; +history_set_fun(History *h, History *nh) { - if (nh->h_first == NULL || nh->h_next == NULL || - nh->h_last == NULL || nh->h_prev == NULL || nh->h_curr == NULL || - nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL || - nh->h_ref == NULL) { - if (h->h_next != history_def_next) { - history_def_init(&h->h_ref, 0); - h->h_first = history_def_first; - h->h_next = history_def_next; - h->h_last = history_def_last; - h->h_prev = history_def_prev; - h->h_curr = history_def_curr; - h->h_clear = history_def_clear; - h->h_enter = history_def_enter; - h->h_add = history_def_add; + HistEvent ev; + + 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_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL || + nh->h_ref == NULL) { + if (h->h_next != history_def_next) { + history_def_init(&h->h_ref, &ev, 0); + h->h_first = history_def_first; + h->h_next = history_def_next; + h->h_last = history_def_last; + h->h_prev = history_def_prev; + h->h_curr = history_def_curr; + h->h_set = history_def_set; + h->h_clear = history_def_clear; + h->h_enter = history_def_enter; + h->h_add = history_def_add; + } + return (-1); } - return -1; - } - - if (h->h_next == history_def_next) - history_def_clear(h->h_ref); - - h->h_first = nh->h_first; - h->h_next = nh->h_next; - h->h_last = nh->h_last; - h->h_prev = nh->h_prev; - h->h_curr = nh->h_curr; - h->h_clear = nh->h_clear; - h->h_enter = nh->h_enter; - h->h_add = nh->h_add; - - return 0; + if (h->h_next == history_def_next) + history_def_clear(h->h_ref, &ev); + + h->h_ent = -1; + h->h_first = nh->h_first; + h->h_next = nh->h_next; + h->h_last = nh->h_last; + h->h_prev = nh->h_prev; + h->h_curr = nh->h_curr; + h->h_set = nh->h_set; + h->h_clear = nh->h_clear; + h->h_enter = nh->h_enter; + h->h_add = nh->h_add; + + return (0); } @@ -442,34 +587,46 @@ history_set_fun(h, nh) * History load function */ private int -history_load(h, fname) - History *h; - const char *fname; +history_load(History *h, const char *fname) { - FILE *fp; - char *line; - size_t sz; - int i = -1; - - if ((fp = fopen(fname, "r")) == NULL) - return i; - - if ((line = fgetln(fp, &sz)) == NULL) - goto done; - - if (strncmp(line, hist_cookie, sz) != 0) - goto done; - - for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) { - char c = line[sz]; - line[sz] = '\0'; - HENTER(h, line); - line[sz] = c; - } + FILE *fp; + char *line; + size_t sz, max_size; + char *ptr; + int i = -1; + HistEvent ev; + + if ((fp = fopen(fname, "r")) == NULL) + return (i); + + if ((line = fgetln(fp, &sz)) == NULL) + goto done; + + if (strncmp(line, hist_cookie, sz) != 0) + goto done; + + ptr = h_malloc(max_size = 1024); + for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) { + char c = line[sz]; + + if (sz != 0 && line[sz - 1] == '\n') + line[--sz] = '\0'; + else + line[sz] = '\0'; + + if (max_size < sz) { + max_size = (sz + 1023) & ~1023; + ptr = h_realloc(ptr, max_size); + } + (void) strunvis(ptr, line); + line[sz] = c; + HENTER(h, &ev, ptr); + } + h_free(ptr); done: - (void) fclose(fp); - return i; + (void) fclose(fp); + return (i); } @@ -477,216 +634,235 @@ done: * History save function */ private int -history_save(h, fname) - History *h; - const char *fname; +history_save(History *h, const char *fname) { - FILE *fp; - const HistEvent *ev; - int i = 0; - - if ((fp = fopen(fname, "w")) == NULL) - return -1; - - (void) fputs(hist_cookie, fp); - for (ev = HLAST(h); ev != NULL; ev = HPREV(h), i++) - (void) fprintf(fp, "%s", ev->str); - (void) fclose(fp); - return i; + FILE *fp; + HistEvent ev; + int i = 0, retval; + size_t len, max_size; + char *ptr; + + if ((fp = fopen(fname, "w")) == NULL) + return (-1); + + (void) fchmod(fileno(fp), S_IRUSR|S_IWUSR); + (void) fputs(hist_cookie, fp); + ptr = h_malloc(max_size = 1024); + for (retval = HLAST(h, &ev); + retval != -1; + retval = HPREV(h, &ev), i++) { + len = strlen(ev.str) * 4; + if (len >= max_size) { + max_size = (len + 1023) & 1023; + ptr = h_realloc(ptr, max_size); + } + (void) strvis(ptr, ev.str, VIS_WHITE); + (void) fprintf(fp, "%s\n", ev.str); + } + h_free(ptr); + (void) fclose(fp); + return (i); } /* history_prev_event(): * Find the previous event, with number given */ -private const HistEvent * -history_prev_event(h, num) - History *h; - int num; +private int +history_prev_event(History *h, HistEvent *ev, int num) { - const HistEvent *ev; - for (ev = HCURR(h); ev != NULL; ev = HPREV(h)) - if (ev->num == num) - return ev; - return NULL; + int retval; + + for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) + if (ev->num == num) + return (0); + + he_seterrev(ev, _HE_NOT_FOUND); + return (-1); } /* history_next_event(): * Find the next event, with number given */ -private const HistEvent * -history_next_event(h, num) - History *h; - int num; +private int +history_next_event(History *h, HistEvent *ev, int num) { - const HistEvent *ev; - for (ev = HCURR(h); ev != NULL; ev = HNEXT(h)) - if (ev->num == num) - return ev; - return NULL; + int retval; + + for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev)) + if (ev->num == num) + return (0); + + he_seterrev(ev, _HE_NOT_FOUND); + return (-1); } /* history_prev_string(): * Find the previous event beginning with string */ -private const HistEvent * -history_prev_string(h, str) - History *h; - const char* str; +private int +history_prev_string(History *h, HistEvent *ev, const char *str) { - const HistEvent *ev; - size_t len = strlen(str); - - for (ev = HCURR(h); ev != NULL; ev = HNEXT(h)) - if (strncmp(str, ev->str, len) == 0) - return ev; - return NULL; -} + size_t len = strlen(str); + int retval; + for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev)) + if (strncmp(str, ev->str, len) == 0) + return (0); + he_seterrev(ev, _HE_NOT_FOUND); + return (-1); +} /* history_next_string(): * Find the next event beginning with string */ -private const HistEvent * -history_next_string(h, str) - History *h; - const char* str; +private int +history_next_string(History *h, HistEvent *ev, const char *str) { - const HistEvent *ev; - size_t len = strlen(str); + size_t len = strlen(str); + int retval; - for (ev = HCURR(h); ev != NULL; ev = HPREV(h)) - if (strncmp(str, ev->str, len) == 0) - return ev; - return NULL; + for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) + if (strncmp(str, ev->str, len) == 0) + return (0); + + he_seterrev(ev, _HE_NOT_FOUND); + return (-1); } /* history(): * User interface to history functions. */ -const HistEvent * -#ifdef __STDC__ -history(History *h, int fun, ...) -#else -history(va_alist) - va_dcl -#endif +int +history(History *h, HistEvent *ev, int fun, ...) { - va_list va; - const HistEvent *ev = NULL; - const char *str; - static HistEvent sev = { 0, "" }; - -#ifdef __STDC__ - va_start(va, fun); -#else - History *h; - int fun; - va_start(va); - h = va_arg(va, History *); - fun = va_arg(va, int); -#endif - - switch (fun) { - case H_ADD: - str = va_arg(va, const char *); - ev = HADD(h, str); - break; - - case H_ENTER: - str = va_arg(va, const char *); - ev = HENTER(h, str); - break; - - case H_FIRST: - ev = HFIRST(h); - break; - - case H_NEXT: - ev = HNEXT(h); - break; - - case H_LAST: - ev = HLAST(h); - break; - - case H_PREV: - ev = HPREV(h); - break; - - case H_CURR: - ev = HCURR(h); - break; - - case H_CLEAR: - HCLEAR(h); - break; - - case H_LOAD: - sev.num = history_load(h, va_arg(va, const char *)); - ev = &sev; - break; - - case H_SAVE: - sev.num = history_save(h, va_arg(va, const char *)); - ev = &sev; - break; - - case H_PREV_EVENT: - ev = history_prev_event(h, va_arg(va, int)); - break; - - case H_NEXT_EVENT: - ev = history_next_event(h, va_arg(va, int)); - break; - - case H_PREV_STR: - ev = history_prev_string(h, va_arg(va, const char*)); - break; - - case H_NEXT_STR: - ev = history_next_string(h, va_arg(va, const char*)); - break; - - case H_EVENT: - if (history_set_num(h, va_arg(va, int)) == 0) { - sev.num = -1; - ev = &sev; - } - break; - - case H_FUNC: + va_list va; + const char *str; + int retval; + + va_start(va, fun); + + he_seterrev(ev, _HE_OK); + + switch (fun) { + case H_GETSIZE: + retval = history_getsize(h, ev); + break; + + case H_SETSIZE: + retval = history_setsize(h, ev, va_arg(va, int)); + break; + + case H_ADD: + str = va_arg(va, const char *); + retval = HADD(h, ev, str); + break; + + case H_ENTER: + str = va_arg(va, const char *); + if ((retval = HENTER(h, ev, str)) != -1) + h->h_ent = ev->num; + break; + + case H_APPEND: + str = va_arg(va, const char *); + if ((retval = HSET(h, ev, h->h_ent)) != -1) + retval = HADD(h, ev, str); + break; + + case H_FIRST: + retval = HFIRST(h, ev); + break; + + case H_NEXT: + retval = HNEXT(h, ev); + break; + + case H_LAST: + retval = HLAST(h, ev); + break; + + case H_PREV: + retval = HPREV(h, ev); + break; + + case H_CURR: + retval = HCURR(h, ev); + break; + + case H_SET: + retval = HSET(h, ev, va_arg(va, const int)); + break; + + case H_CLEAR: + HCLEAR(h, ev); + retval = 0; + break; + + case H_LOAD: + retval = history_load(h, va_arg(va, const char *)); + if (retval == -1) + he_seterrev(ev, _HE_HIST_READ); + break; + + case H_SAVE: + retval = history_save(h, va_arg(va, const char *)); + if (retval == -1) + he_seterrev(ev, _HE_HIST_WRITE); + break; + + case H_PREV_EVENT: + retval = history_prev_event(h, ev, va_arg(va, int)); + break; + + case H_NEXT_EVENT: + retval = history_next_event(h, ev, va_arg(va, int)); + break; + + case H_PREV_STR: + retval = history_prev_string(h, ev, va_arg(va, const char *)); + break; + + case H_NEXT_STR: + retval = history_next_string(h, ev, va_arg(va, const char *)); + break; + + case H_FUNC: { - History hf; - hf.h_ref = va_arg(va, ptr_t); - hf.h_first = va_arg(va, history_gfun_t); - hf.h_next = va_arg(va, history_gfun_t); - hf.h_last = va_arg(va, history_gfun_t); - hf.h_prev = va_arg(va, history_gfun_t); - hf.h_curr = va_arg(va, history_gfun_t); - hf.h_clear = va_arg(va, history_vfun_t); - hf.h_enter = va_arg(va, history_efun_t); - hf.h_add = va_arg(va, history_efun_t); - - if (history_set_fun(h, &hf) == 0) { - sev.num = -1; - ev = &sev; - } + History hf; + + hf.h_ref = va_arg(va, ptr_t); + h->h_ent = -1; + hf.h_first = va_arg(va, history_gfun_t); + hf.h_next = va_arg(va, history_gfun_t); + hf.h_last = va_arg(va, history_gfun_t); + hf.h_prev = va_arg(va, history_gfun_t); + hf.h_curr = va_arg(va, history_gfun_t); + hf.h_set = va_arg(va, history_sfun_t); + hf.h_clear = va_arg(va, history_vfun_t); + hf.h_enter = va_arg(va, history_efun_t); + hf.h_add = va_arg(va, history_efun_t); + + if ((retval = history_set_fun(h, &hf)) == -1) + he_seterrev(ev, _HE_PARAM_MISSING); + break; } - break; - case H_END: - history_end(h); - break; + case H_END: + history_end(h); + retval = 0; + break; - default: - break; - } - va_end(va); - return ev; + default: + retval = -1; + he_seterrev(ev, _HE_UNKNOWN); + break; + } + va_end(va); + return (retval); } @@ -1,4 +1,4 @@ -/* $NetBSD: key.c,v 1.2 1997/01/11 06:47:58 lukem Exp $ */ +/* $NetBSD: key.c,v 1.12 2001/05/17 01:02:17 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,11 +36,12 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: key.c,v 1.2 1997/01/11 06:47:58 lukem Exp $"; +__RCSID("$NetBSD: key.c,v 1.12 2001/05/17 01:02:17 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -48,10 +49,10 @@ static char rcsid[] = "$NetBSD: key.c,v 1.2 1997/01/11 06:47:58 lukem Exp $"; * key.c: This module contains the procedures for maintaining * the extended-key map. * - * An extended-key (key) is a sequence of keystrokes introduced - * with an sequence introducer and consisting of an arbitrary - * number of characters. This module maintains a map (the el->el_key.map) - * to convert these extended-key sequences into input strs + * An extended-key (key) is a sequence of keystrokes introduced + * with an sequence introducer and consisting of an arbitrary + * number of characters. This module maintains a map (the el->el_key.map) + * to convert these extended-key sequences into input strs * (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE). * * Warning: @@ -71,72 +72,72 @@ static char rcsid[] = "$NetBSD: key.c,v 1.2 1997/01/11 06:47:58 lukem Exp $"; #include "el.h" -/* - * The Nodes of the el->el_key.map. The el->el_key.map is a linked list +/* + * The Nodes of the el->el_key.map. The el->el_key.map is a linked list * of these node elements */ struct key_node_t { - char ch; /* single character of key */ - int type; /* node type */ - key_value_t val; /* command code or pointer to str, */ - /* if this is a leaf */ - struct key_node_t *next; /* ptr to next char of this key */ - struct key_node_t *sibling; /* ptr to another key with same prefix */ + char ch; /* single character of key */ + int type; /* node type */ + key_value_t val; /* command code or pointer to str, */ + /* if this is a leaf */ + struct key_node_t *next; /* ptr to next char of this key */ + struct key_node_t *sibling; /* ptr to another key with same prefix*/ }; -private int node_trav __P((EditLine *, key_node_t *, char *, - key_value_t *)); -private int node__try __P((key_node_t *, char *, - key_value_t *, int)); -private key_node_t *node__get __P((int)); -private void node__put __P((key_node_t *)); -private int node__delete __P((key_node_t **, char *)); -private int node_lookup __P((EditLine *, char *, key_node_t *, - int)); -private int node_enum __P((EditLine *, key_node_t *, int)); -private int key__decode_char __P((char *, int, int)); +private int node_trav(EditLine *, key_node_t *, char *, + key_value_t *); +private int node__try(EditLine *, key_node_t *, const char *, + key_value_t *, int); +private key_node_t *node__get(int); +private void node__put(EditLine *, key_node_t *); +private int node__delete(EditLine *, key_node_t **, char *); +private int node_lookup(EditLine *, char *, key_node_t *, int); +private int node_enum(EditLine *, key_node_t *, int); +private int key__decode_char(char *, int, int); -#define KEY_BUFSIZ EL_BUFSIZ +#define KEY_BUFSIZ EL_BUFSIZ /* key_init(): * Initialize the key maps */ protected int -key_init(el) - EditLine *el; +key_init(EditLine *el) { - el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ); - el->el_key.map = NULL; - key_reset(el); - return 0; -} + + el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ); + if (el->el_key.buf == NULL) + return (-1); + el->el_key.map = NULL; + key_reset(el); + return (0); +} /* key_end(): * Free the key maps */ protected void -key_end(el) - EditLine *el; +key_end(EditLine *el) { - el_free((ptr_t) el->el_key.buf); - el->el_key.buf = NULL; - /* XXX: provide a function to clear the keys */ - el->el_key.map = NULL; -} + + el_free((ptr_t) el->el_key.buf); + el->el_key.buf = NULL; + /* XXX: provide a function to clear the keys */ + el->el_key.map = NULL; +} /* key_map_cmd(): * Associate cmd with a key value */ protected key_value_t * -key_map_cmd(el, cmd) - EditLine *el; - int cmd; +key_map_cmd(EditLine *el, int cmd) { - el->el_key.val.cmd = (el_action_t) cmd; - return &el->el_key.val; + + el->el_key.val.cmd = (el_action_t) cmd; + return (&el->el_key.val); } @@ -144,12 +145,11 @@ key_map_cmd(el, cmd) * Associate str with a key value */ protected key_value_t * -key_map_str(el, str) - EditLine *el; - char *str; +key_map_str(EditLine *el, char *str) { - el->el_key.val.str = str; - return &el->el_key.val; + + el->el_key.val.str = str; + return (&el->el_key.val); } @@ -159,12 +159,12 @@ key_map_str(el, str) * [Always bind the ansi arrow keys?] */ protected void -key_reset(el) - EditLine *el; +key_reset(EditLine *el) { - node__put(el->el_key.map); - el->el_key.map = NULL; - return; + + node__put(el, el->el_key.map); + el->el_key.map = NULL; + return; } @@ -173,18 +173,15 @@ key_reset(el) * Looks up *ch in map and then reads characters until a * complete match is found or a mismatch occurs. Returns the * type of the match found (XK_STR, XK_CMD, or XK_EXE). - * Returns NULL in val.str and XK_STR for no match. + * Returns NULL in val.str and XK_STR for no match. * The last character read is returned in *ch. */ protected int -key_get(el, ch, val) - EditLine *el; - char *ch; - key_value_t *val; +key_get(EditLine *el, char *ch, key_value_t *val) { - return node_trav(el, el->el_key.map, ch, val); -} + return (node_trav(el, el->el_key.map, ch, val)); +} /* key_add(): @@ -194,31 +191,27 @@ key_get(el, ch, val) * out str or a unix command. */ protected void -key_add(el, key, val, ntype) - EditLine *el; - char *key; - key_value_t *val; - int ntype; +key_add(EditLine *el, const char *key, key_value_t *val, int ntype) { - if (key[0] == '\0') { - (void) fprintf(el->el_errfile, - "key_add: Null extended-key not allowed.\n"); - return; - } - if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) { - (void) fprintf(el->el_errfile, - "key_add: sequence-lead-in command not allowed\n"); - return; - } - - if (el->el_key.map == NULL) - /* tree is initially empty. Set up new node to match key[0] */ - el->el_key.map = node__get(key[0]); /* it is properly initialized */ + if (key[0] == '\0') { + (void) fprintf(el->el_errfile, + "key_add: Null extended-key not allowed.\n"); + return; + } + if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) { + (void) fprintf(el->el_errfile, + "key_add: sequence-lead-in command not allowed\n"); + return; + } + if (el->el_key.map == NULL) + /* tree is initially empty. Set up new node to match key[0] */ + el->el_key.map = node__get(key[0]); + /* it is properly initialized */ - /* Now recurse through el->el_key.map */ - (void) node__try(el->el_key.map, key, val, ntype); - return; + /* Now recurse through el->el_key.map */ + (void) node__try(el, el->el_key.map, key, val, ntype); + return; } @@ -226,17 +219,15 @@ key_add(el, key, val, ntype) * */ protected void -key_clear(el, map, in) - EditLine *el; - el_action_t *map; - char *in; +key_clear(EditLine *el, el_action_t *map, char *in) { - if ((map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN) && - ((map == el->el_map.key && - el->el_map.alt[(unsigned char) *in] != ED_SEQUENCE_LEAD_IN) || - (map == el->el_map.alt && - el->el_map.key[(unsigned char) *in] != ED_SEQUENCE_LEAD_IN))) - (void) key_delete(el, in); + + if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) && + ((map == el->el_map.key && + el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) || + (map == el->el_map.alt && + el->el_map.key[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN))) + (void) key_delete(el, in); } @@ -245,21 +236,19 @@ key_clear(el, map, in) * they exists. */ protected int -key_delete(el, key) - EditLine *el; - char *key; +key_delete(EditLine *el, char *key) { - if (key[0] == '\0') { - (void) fprintf(el->el_errfile, - "key_delete: Null extended-key not allowed.\n"); - return -1; - } - if (el->el_key.map == NULL) - return 0; + if (key[0] == '\0') { + (void) fprintf(el->el_errfile, + "key_delete: Null extended-key not allowed.\n"); + return (-1); + } + if (el->el_key.map == NULL) + return (0); - (void) node__delete(&el->el_key.map, key); - return 0; + (void) node__delete(el, &el->el_key.map, key); + return (0); } @@ -268,19 +257,19 @@ key_delete(el, key) * Print entire el->el_key.map if null */ protected void -key_print(el, key) - EditLine *el; - char *key; +key_print(EditLine *el, char *key) { - /* do nothing if el->el_key.map is empty and null key specified */ - if (el->el_key.map == NULL && *key == 0) - return; - el->el_key.buf[0] = '"'; - if (node_lookup(el, key, el->el_key.map, 1) <= -1) - /* key is not bound */ - (void) fprintf(el->el_errfile, "Unbound extended key \"%s\"\n", key); - return; + /* do nothing if el->el_key.map is empty and null key specified */ + if (el->el_key.map == NULL && *key == 0) + return; + + el->el_key.buf[0] = '"'; + if (node_lookup(el, key, el->el_key.map, 1) <= -1) + /* key is not bound */ + (void) fprintf(el->el_errfile, "Unbound extended key \"%s\"\n", + key); + return; } @@ -289,41 +278,36 @@ key_print(el, key) * found. May read in more characters. */ private int -node_trav(el, ptr, ch, val) - EditLine *el; - key_node_t *ptr; - char *ch; - key_value_t *val; +node_trav(EditLine *el, key_node_t *ptr, char *ch, key_value_t *val) { - if (ptr->ch == *ch) { - /* match found */ - if (ptr->next) { - /* key not complete so get next char */ - if (el_getc(el, ch) != 1) { /* if EOF or error */ - val->cmd = ED_END_OF_FILE; - return XK_CMD;/* PWP: Pretend we just read an end-of-file */ - } - return node_trav(el, ptr->next, ch, val); - } - else { - *val = ptr->val; - if (ptr->type != XK_CMD) - *ch = '\0'; - return ptr->type; - } - } - else { - /* no match found here */ - if (ptr->sibling) { - /* try next sibling */ - return node_trav(el, ptr->sibling, ch, val); - } - else { - /* no next sibling -- mismatch */ - val->str = NULL; - return XK_STR; + + if (ptr->ch == *ch) { + /* match found */ + if (ptr->next) { + /* key not complete so get next char */ + if (el_getc(el, ch) != 1) { /* if EOF or error */ + val->cmd = ED_END_OF_FILE; + return (XK_CMD); + /* PWP: Pretend we just read an end-of-file */ + } + return (node_trav(el, ptr->next, ch, val)); + } else { + *val = ptr->val; + if (ptr->type != XK_CMD) + *ch = '\0'; + return (ptr->type); + } + } else { + /* no match found here */ + if (ptr->sibling) { + /* try next sibling */ + return (node_trav(el, ptr->sibling, ch, val)); + } else { + /* no next sibling -- mismatch */ + val->str = NULL; + return (XK_STR); + } } - } } @@ -331,63 +315,60 @@ node_trav(el, ptr, ch, val) * Find a node that matches *str or allocate a new one */ private int -node__try(ptr, str, val, ntype) - key_node_t *ptr; - char *str; - key_value_t *val; - int ntype; +node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int ntype) { - if (ptr->ch != *str) { - key_node_t *xm; - for (xm = ptr; xm->sibling != NULL; xm = xm->sibling) - if (xm->sibling->ch == *str) - break; - if (xm->sibling == NULL) - xm->sibling = node__get(*str); /* setup new node */ - ptr = xm->sibling; - } + if (ptr->ch != *str) { + key_node_t *xm; - if (*++str == '\0') { - /* we're there */ - if (ptr->next != NULL) { - node__put(ptr->next); /* lose longer keys with this prefix */ - ptr->next = NULL; - } - switch (ptr->type) { - case XK_CMD: - case XK_NOD: - break; - case XK_STR: - case XK_EXE: - if (ptr->val.str) - el_free((ptr_t) ptr->val.str); - break; - default: - abort(); - break; + for (xm = ptr; xm->sibling != NULL; xm = xm->sibling) + if (xm->sibling->ch == *str) + break; + if (xm->sibling == NULL) + xm->sibling = node__get(*str); /* setup new node */ + ptr = xm->sibling; } + if (*++str == '\0') { + /* we're there */ + if (ptr->next != NULL) { + node__put(el, ptr->next); + /* lose longer keys with this prefix */ + ptr->next = NULL; + } + switch (ptr->type) { + case XK_CMD: + case XK_NOD: + break; + case XK_STR: + case XK_EXE: + if (ptr->val.str) + el_free((ptr_t) ptr->val.str); + break; + default: + EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", + ptr->type)); + break; + } - switch (ptr->type = ntype) { - case XK_CMD: - ptr->val = *val; - break; - case XK_STR: - case XK_EXE: - ptr->val.str = strdup(val->str); - break; - default: - abort(); - break; + switch (ptr->type = ntype) { + case XK_CMD: + ptr->val = *val; + break; + case XK_STR: + case XK_EXE: + ptr->val.str = strdup(val->str); + break; + default: + EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); + break; + } + } else { + /* still more chars to go */ + if (ptr->next == NULL) + ptr->next = node__get(*str); /* setup new node */ + (void) node__try(el, ptr->next, str, val, ntype); } - } - else { - /* still more chars to go */ - if (ptr->next == NULL) - ptr->next = node__get(*str); /* setup new node */ - (void) node__try(ptr->next, str, val, ntype); - } - return 0; + return (0); } @@ -395,84 +376,79 @@ node__try(ptr, str, val, ntype) * Delete node that matches str */ private int -node__delete(inptr, str) - key_node_t **inptr; - char *str; +node__delete(EditLine *el, key_node_t **inptr, char *str) { - key_node_t *ptr; - key_node_t *prev_ptr = NULL; + key_node_t *ptr; + key_node_t *prev_ptr = NULL; - ptr = *inptr; + ptr = *inptr; - if (ptr->ch != *str) { - key_node_t *xm; + if (ptr->ch != *str) { + key_node_t *xm; - for (xm = ptr; xm->sibling != NULL; xm = xm->sibling) - if (xm->sibling->ch == *str) - break; - if (xm->sibling == NULL) - return 0; - prev_ptr = xm; - ptr = xm->sibling; - } - - if (*++str == '\0') { - /* we're there */ - if (prev_ptr == NULL) - *inptr = ptr->sibling; - else - prev_ptr->sibling = ptr->sibling; - ptr->sibling = NULL; - node__put(ptr); - return 1; - } - else if (ptr->next != NULL && node__delete(&ptr->next, str) == 1) { - if (ptr->next != NULL) - return 0; - if (prev_ptr == NULL) - *inptr = ptr->sibling; - else - prev_ptr->sibling = ptr->sibling; - ptr->sibling = NULL; - node__put(ptr); - return 1; - } - else { - return 0; - } + for (xm = ptr; xm->sibling != NULL; xm = xm->sibling) + if (xm->sibling->ch == *str) + break; + if (xm->sibling == NULL) + return (0); + prev_ptr = xm; + ptr = xm->sibling; + } + if (*++str == '\0') { + /* we're there */ + if (prev_ptr == NULL) + *inptr = ptr->sibling; + else + prev_ptr->sibling = ptr->sibling; + ptr->sibling = NULL; + node__put(el, ptr); + return (1); + } else if (ptr->next != NULL && + node__delete(el, &ptr->next, str) == 1) { + if (ptr->next != NULL) + return (0); + if (prev_ptr == NULL) + *inptr = ptr->sibling; + else + prev_ptr->sibling = ptr->sibling; + ptr->sibling = NULL; + node__put(el, ptr); + return (1); + } else { + return (0); + } } + /* node__put(): * Puts a tree of nodes onto free list using free(3). */ private void -node__put(ptr) - key_node_t *ptr; +node__put(EditLine *el, key_node_t *ptr) { - if (ptr == NULL) - return; + if (ptr == NULL) + return; - if (ptr->next != NULL) { - node__put(ptr->next); - ptr->next = NULL; - } - - node__put(ptr->sibling); - - switch (ptr->type) { - case XK_CMD: - case XK_NOD: - break; - case XK_EXE: - case XK_STR: - if (ptr->val.str != NULL) - el_free((ptr_t) ptr->val.str); - break; - default: - abort(); - break; - } - el_free((ptr_t) ptr); + if (ptr->next != NULL) { + node__put(el, ptr->next); + ptr->next = NULL; + } + node__put(el, ptr->sibling); + + switch (ptr->type) { + case XK_CMD: + case XK_NOD: + break; + case XK_EXE: + case XK_STR: + if (ptr->val.str != NULL) + el_free((ptr_t) ptr->val.str); + break; + default: + EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ptr->type)); + break; + } + el_free((ptr_t) ptr); } @@ -480,18 +456,19 @@ node__put(ptr) * Returns pointer to an key_node_t for ch. */ private key_node_t * -node__get(ch) - int ch; +node__get(int ch) { - key_node_t *ptr; - - ptr = (key_node_t *) el_malloc((size_t) sizeof(key_node_t)); - ptr->ch = ch; - ptr->type = XK_NOD; - ptr->val.str = NULL; - ptr->next = NULL; - ptr->sibling = NULL; - return ptr; + key_node_t *ptr; + + ptr = (key_node_t *) el_malloc((size_t) sizeof(key_node_t)); + if (ptr == NULL) + return NULL; + ptr->ch = ch; + ptr->type = XK_NOD; + ptr->val.str = NULL; + ptr->next = NULL; + ptr->sibling = NULL; + return (ptr); } @@ -501,51 +478,48 @@ node__get(ch) * Print if last node */ private int -node_lookup(el, str, ptr, cnt) - EditLine *el; - char *str; - key_node_t *ptr; - int cnt; +node_lookup(EditLine *el, char *str, key_node_t *ptr, int cnt) { - int ncnt; - - if (ptr == NULL) - return -1; /* cannot have null ptr */ - - if (*str == 0) { - /* no more chars in str. node_enum from here. */ - (void) node_enum(el, ptr, cnt); - return 0; - } - else { - /* If match put this char into el->el_key.buf. Recurse */ - if (ptr->ch == *str) { - /* match found */ - ncnt = key__decode_char(el->el_key.buf, cnt, - (unsigned char) ptr->ch); - if (ptr->next != NULL) - /* not yet at leaf */ - return node_lookup(el, str + 1, ptr->next, ncnt + 1); - else { - /* next node is null so key should be complete */ - if (str[1] == 0) { - el->el_key.buf[ncnt + 1] = '"'; - el->el_key.buf[ncnt + 2] = '\0'; - key_kprint(el, el->el_key.buf, &ptr->val, ptr->type); - return 0; + int ncnt; + + if (ptr == NULL) + return (-1); /* cannot have null ptr */ + + if (*str == 0) { + /* no more chars in str. node_enum from here. */ + (void) node_enum(el, ptr, cnt); + return (0); + } else { + /* If match put this char into el->el_key.buf. Recurse */ + if (ptr->ch == *str) { + /* match found */ + ncnt = key__decode_char(el->el_key.buf, cnt, + (unsigned char) ptr->ch); + if (ptr->next != NULL) + /* not yet at leaf */ + return (node_lookup(el, str + 1, ptr->next, + ncnt + 1)); + else { + /* next node is null so key should be complete */ + if (str[1] == 0) { + el->el_key.buf[ncnt + 1] = '"'; + el->el_key.buf[ncnt + 2] = '\0'; + key_kprint(el, el->el_key.buf, + &ptr->val, ptr->type); + return (0); + } else + return (-1); + /* mismatch -- str still has chars */ + } + } else { + /* no match found try sibling */ + if (ptr->sibling) + return (node_lookup(el, str, ptr->sibling, + cnt)); + else + return (-1); } - else - return -1;/* mismatch -- str still has chars */ - } - } - else { - /* no match found try sibling */ - if (ptr->sibling) - return node_lookup(el, str, ptr->sibling, cnt); - else - return -1; } - } } @@ -553,44 +527,39 @@ node_lookup(el, str, ptr, cnt) * Traverse the node printing the characters it is bound in buffer */ private int -node_enum(el, ptr, cnt) - EditLine *el; - key_node_t *ptr; - int cnt; +node_enum(EditLine *el, key_node_t *ptr, int cnt) { - int ncnt; + int ncnt; - if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */ - el->el_key.buf[++cnt] = '"'; - el->el_key.buf[++cnt] = '\0'; - (void) fprintf(el->el_errfile, + if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */ + el->el_key.buf[++cnt] = '"'; + el->el_key.buf[++cnt] = '\0'; + (void) fprintf(el->el_errfile, "Some extended keys too long for internal print buffer"); - (void) fprintf(el->el_errfile, " \"%s...\"\n", el->el_key.buf); - return 0; - } - - if (ptr == NULL) { + (void) fprintf(el->el_errfile, " \"%s...\"\n", el->el_key.buf); + return (0); + } + if (ptr == NULL) { #ifdef DEBUG_EDIT - (void) fprintf(el->el_errfile, "node_enum: BUG!! Null ptr passed\n!"); + (void) fprintf(el->el_errfile, + "node_enum: BUG!! Null ptr passed\n!"); #endif - return -1; - } - - /* put this char at end of str */ - ncnt = key__decode_char(el->el_key.buf, cnt, (unsigned char) ptr->ch); - if (ptr->next == NULL) { - /* print this key and function */ - el->el_key.buf[ncnt + 1] = '"'; - el->el_key.buf[ncnt + 2] = '\0'; - key_kprint(el, el->el_key.buf, &ptr->val, ptr->type); - } - else - (void) node_enum(el, ptr->next, ncnt + 1); - - /* go to sibling if there is one */ - if (ptr->sibling) - (void) node_enum(el, ptr->sibling, cnt); - return 0; + return (-1); + } + /* put this char at end of str */ + ncnt = key__decode_char(el->el_key.buf, cnt, (unsigned char) ptr->ch); + if (ptr->next == NULL) { + /* print this key and function */ + el->el_key.buf[ncnt + 1] = '"'; + el->el_key.buf[ncnt + 2] = '\0'; + key_kprint(el, el->el_key.buf, &ptr->val, ptr->type); + } else + (void) node_enum(el, ptr->next, ncnt + 1); + + /* go to sibling if there is one */ + if (ptr->sibling) + (void) node_enum(el, ptr->sibling, cnt); + return (0); } @@ -599,42 +568,40 @@ node_enum(el, ptr, cnt) * function specified by val */ protected void -key_kprint(el, key, val, ntype) - EditLine *el; - char *key; - key_value_t *val; - int ntype; +key_kprint(EditLine *el, char *key, key_value_t *val, int ntype) { - el_bindings_t *fp; - char unparsbuf[EL_BUFSIZ]; - static char *fmt = "%-15s-> %s\n"; - - if (val != NULL) - switch (ntype) { - case XK_STR: - case XK_EXE: - (void) fprintf(el->el_errfile, fmt, key, - key__decode_str(val->str, unparsbuf, - ntype == XK_STR ? "\"\"" : "[]")); - break; - case XK_CMD: - for (fp = el->el_map.help; fp->name; fp++) - if (val->cmd == fp->func) { - (void) fprintf(el->el_errfile, fmt, key, fp->name); - break; - } + el_bindings_t *fp; + char unparsbuf[EL_BUFSIZ]; + static const char fmt[] = "%-15s-> %s\n"; + + if (val != NULL) + switch (ntype) { + case XK_STR: + case XK_EXE: + (void) fprintf(el->el_outfile, fmt, key, + key__decode_str(val->str, unparsbuf, + ntype == XK_STR ? "\"\"" : "[]")); + break; + case XK_CMD: + for (fp = el->el_map.help; fp->name; fp++) + if (val->cmd == fp->func) { + (void) fprintf(el->el_outfile, fmt, + key, fp->name); + break; + } #ifdef DEBUG_KEY - if (fp->name == NULL) - (void) fprintf(el->el_errfile, "BUG! Command not found.\n"); + if (fp->name == NULL) + (void) fprintf(el->el_outfile, + "BUG! Command not found.\n"); #endif - break; - default: - abort(); - break; - } - else - (void) fprintf(el->el_errfile, fmt, key, "no input"); + break; + default: + EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); + break; + } + else + (void) fprintf(el->el_outfile, fmt, key, "no input"); } @@ -642,91 +609,78 @@ key_kprint(el, key, val, ntype) * Put a printable form of char in buf. */ private int -key__decode_char(buf, cnt, ch) - char *buf; - int cnt, ch; +key__decode_char(char *buf, int cnt, int ch) { - if (ch == 0) { - buf[cnt++] = '^'; - buf[cnt] = '@'; - return cnt; - } - - if (iscntrl(ch)) { - buf[cnt++] = '^'; - if (ch == '\177') - buf[cnt] = '?'; - else - buf[cnt] = ch | 0100; - } - else if (ch == '^') { - buf[cnt++] = '\\'; - buf[cnt] = '^'; - } - else if (ch == '\\') { - buf[cnt++] = '\\'; - buf[cnt] = '\\'; - } - else if (ch == ' ' || (isprint(ch) && !isspace(ch))) { - buf[cnt] = ch; - } - else { - buf[cnt++] = '\\'; - buf[cnt++] = ((ch >> 6) & 7) + '0'; - buf[cnt++] = ((ch >> 3) & 7) + '0'; - buf[cnt] = (ch & 7) + '0'; - } - return cnt; + if (ch == 0) { + buf[cnt++] = '^'; + buf[cnt] = '@'; + return (cnt); + } + if (iscntrl(ch)) { + buf[cnt++] = '^'; + if (ch == '\177') + buf[cnt] = '?'; + else + buf[cnt] = ch | 0100; + } else if (ch == '^') { + buf[cnt++] = '\\'; + buf[cnt] = '^'; + } else if (ch == '\\') { + buf[cnt++] = '\\'; + buf[cnt] = '\\'; + } else if (ch == ' ' || (isprint(ch) && !isspace(ch))) { + buf[cnt] = ch; + } else { + buf[cnt++] = '\\'; + buf[cnt++] = (((unsigned int) ch >> 6) & 7) + '0'; + buf[cnt++] = (((unsigned int) ch >> 3) & 7) + '0'; + buf[cnt] = (ch & 7) + '0'; + } + return (cnt); } + /* key__decode_str(): * Make a printable version of the ey */ protected char * -key__decode_str(str, buf, sep) - char *str; - char *buf; - char *sep; +key__decode_str(char *str, char *buf, char *sep) { - char *b, *p; - - b = buf; - if (sep[0] != '\0') - *b++ = sep[0]; - if (*str == 0) { - *b++ = '^'; - *b++ = '@'; - if (sep[0] != '\0' && sep[1] != '\0') - *b++ = sep[1]; - *b++ = 0; - return buf; - } - - for (p = str; *p != 0; p++) { - if (iscntrl((unsigned char) *p)) { - *b++ = '^'; - if (*p == '\177') - *b++ = '?'; - else - *b++ = *p | 0100; - } - else if (*p == '^' || *p == '\\') { - *b++ = '\\'; - *b++ = *p; - } - else if (*p == ' ' || (isprint((unsigned char) *p) && - !isspace((unsigned char) *p))) { - *b++ = *p; + char *b, *p; + + b = buf; + if (sep[0] != '\0') + *b++ = sep[0]; + if (*str == 0) { + *b++ = '^'; + *b++ = '@'; + if (sep[0] != '\0' && sep[1] != '\0') + *b++ = sep[1]; + *b++ = 0; + return (buf); } - else { - *b++ = '\\'; - *b++ = ((*p >> 6) & 7) + '0'; - *b++ = ((*p >> 3) & 7) + '0'; - *b++ = (*p & 7) + '0'; + for (p = str; *p != 0; p++) { + if (iscntrl((unsigned char) *p)) { + *b++ = '^'; + if (*p == '\177') + *b++ = '?'; + else + *b++ = *p | 0100; + } else if (*p == '^' || *p == '\\') { + *b++ = '\\'; + *b++ = *p; + } else if (*p == ' ' || (isprint((unsigned char) *p) && + !isspace((unsigned char) *p))) { + *b++ = *p; + } else { + *b++ = '\\'; + *b++ = (((unsigned int) *p >> 6) & 7) + '0'; + *b++ = (((unsigned int) *p >> 3) & 7) + '0'; + *b++ = (*p & 7) + '0'; + } } - } - if (sep[0] != '\0' && sep[1] != '\0') - *b++ = sep[1]; - *b++ = 0; - return buf; /* should check for overflow */ + if (sep[0] != '\0' && sep[1] != '\0') + *b++ = sep[1]; + *b++ = 0; + return (buf); /* should check for overflow */ } @@ -1,4 +1,4 @@ -/* $NetBSD: key.h,v 1.2 1997/01/11 06:47:59 lukem Exp $ */ +/* $NetBSD: key.h,v 1.5 2001/01/23 15:55:30 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,41 +42,37 @@ * el.key.h: Key macro header */ #ifndef _h_el_key -#define _h_el_key +#define _h_el_key typedef union key_value_t { - el_action_t cmd; /* If it is a command the # */ - char *str; /* If it is a string... */ + el_action_t cmd; /* If it is a command the # */ + char *str; /* If it is a string... */ } key_value_t; typedef struct key_node_t key_node_t; typedef struct el_key_t { - char *buf; /* Key print buffer */ - key_node_t *map; /* Key map */ - key_value_t val; /* Local conversion buffer */ + char *buf; /* Key print buffer */ + key_node_t *map; /* Key map */ + key_value_t val; /* Local conversion buffer */ } el_key_t; -#define XK_CMD 0 -#define XK_STR 1 -#define XK_NOD 2 -#define XK_EXE 3 +#define XK_CMD 0 +#define XK_STR 1 +#define XK_NOD 2 +#define XK_EXE 3 -protected int key_init __P((EditLine *)); -protected void key_end __P((EditLine *)); -protected key_value_t * key_map_cmd __P((EditLine *, int)); -protected key_value_t * key_map_str __P((EditLine *, char *)); -protected void key_reset __P((EditLine *)); -protected int key_get __P((EditLine *, char *, - key_value_t *)); -protected void key_add __P((EditLine *, char *, key_value_t *, - int)); -protected void key_clear __P((EditLine *, el_action_t *, - char *)); -protected int key_delete __P((EditLine *, char *)); -protected void key_print __P((EditLine *, char *)); -protected void key_kprint __P((EditLine *, char *, - key_value_t *, int)); -protected char *key__decode_str __P((char *, char *, char *)); +protected int key_init(EditLine *); +protected void key_end(EditLine *); +protected key_value_t *key_map_cmd(EditLine *, int); +protected key_value_t *key_map_str(EditLine *, char *); +protected void key_reset(EditLine *); +protected int key_get(EditLine *, char *, key_value_t *); +protected void key_add(EditLine *, const char *, key_value_t *, int); +protected void key_clear(EditLine *, el_action_t *, char *); +protected int key_delete(EditLine *, char *); +protected void key_print(EditLine *, char *); +protected void key_kprint(EditLine *, char *, key_value_t *, int); +protected char *key__decode_str(char *, char *, char *); #endif /* _h_el_key */ diff --git a/dist/makelist b/dist/makelist index 5073648..8e98353 100644 --- a/dist/makelist +++ b/dist/makelist @@ -1,5 +1,5 @@ #!/bin/sh - -# $NetBSD: makelist,v 1.3 1997/01/11 06:48:00 lukem Exp $ +# $NetBSD: makelist,v 1.7 2001/01/09 19:22:31 jdolecek Exp $ # # Copyright (c) 1992, 1993 # The Regents of the University of California. All rights reserved. @@ -40,7 +40,7 @@ # makelist.sh: Automatically generate header files... AWK=/usr/bin/awk -USAGE="Usage: $0 -h|-e|-fc|-fh|-bc|-bh <filenames>" +USAGE="Usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m <filenames>" if [ "x$1" = "x" ] then @@ -54,6 +54,9 @@ shift FILES="$@" case $FLAG in + +# generate foo.h file from foo.c +# -h) set - `echo $FILES | sed -e 's/\\./_/g'` hdr="_h_`basename $1`" @@ -66,18 +69,26 @@ case $FLAG in pr = substr($2, 1, 2); if (pr == "vi" || pr == "em" || pr == "ed") { name = substr($2, 1, length($2) - 3); - printf("protected el_action_t\t%-25.25s __P((EditLine *, int));\n", name); +# +# XXX: need a space between name and prototype so that -fc and -fh +# parsing is much easier +# + printf("protected el_action_t\t%s (EditLine *, int);\n", name); } } END { printf("#endif /* %s */\n", "'$hdr'"); - }';; + }' + ;; + +# generate help.c from various .c files +# -bc) cat $FILES | $AWK ' BEGIN { printf("/* Automatically generated file, do not edit */\n"); printf("#include \"sys.h\"\n#include \"el.h\"\n"); - printf("private struct el_bindings_t el_func_help[] = {\n"); + printf("private const struct el_bindings_t el_func_help[] = {\n"); low = "abcdefghijklmnopqrstuvwxyz_"; high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"; for (i = 1; i <= length(low); i++) @@ -96,9 +107,9 @@ case $FLAG in s = "-"; fname = fname s; } - + printf(" { %-30.30s %-30.30s\n","\"" fname "\",", uname ","); - ok = 1; + ok = 1; } } /^ \*/ { @@ -113,41 +124,53 @@ case $FLAG in END { printf(" { NULL, 0, NULL }\n"); printf("};\n"); - printf("\nprotected el_bindings_t* help__get()"); + printf("\nprotected const el_bindings_t* help__get()"); printf("{ return el_func_help; }\n"); - }';; + }' + ;; + +# generate help.h from various .c files +# -bh) $AWK ' - BEGIN { + BEGIN { printf("/* Automatically generated file, do not edit */\n"); printf("#ifndef _h_help_c\n#define _h_help_c\n"); - printf("protected el_bindings_t *help__get\t__P((void));\n"); + printf("protected const el_bindings_t *help__get(void);\n"); printf("#endif /* _h_help_c */\n"); - }' /dev/null;; + }' /dev/null + ;; + +# generate fcns.h from various .h files +# -fh) cat $FILES | $AWK '/el_action_t/ { print $3 }' | \ sort | tr '[a-z]' '[A-Z]' | $AWK ' - BEGIN { + BEGIN { printf("/* Automatically generated file, do not edit */\n"); printf("#ifndef _h_fcns_c\n#define _h_fcns_c\n"); - count = 0; + count = 0; } - { + { printf("#define\t%-30.30s\t%3d\n", $1, count++); } END { printf("#define\t%-30.30s\t%3d\n", "EL_NUM_FCNS", count); - printf("typedef el_action_t (*el_func_t) __P((EditLine *, int));"); - printf("\nprotected el_func_t* func__get __P((void));\n"); + printf("typedef el_action_t (*el_func_t)(EditLine *, int);"); + printf("\nprotected const el_func_t* func__get(void);\n"); printf("#endif /* _h_fcns_c */\n"); - }';; + }' + ;; + +# generate fcns.c from various .h files +# -fc) cat $FILES | $AWK '/el_action_t/ { print $3 }' | sort | $AWK ' BEGIN { printf("/* Automatically generated file, do not edit */\n"); printf("#include \"sys.h\"\n#include \"el.h\"\n"); - printf("private el_func_t el_func[] = {"); + printf("private const el_func_t el_func[] = {"); maxlen = 80; needn = 1; len = 0; @@ -155,7 +178,7 @@ case $FLAG in { clen = 25 + 2; len += clen; - if (len >= maxlen) + if (len >= maxlen) needn = 1; if (needn) { printf("\n "); @@ -167,8 +190,12 @@ case $FLAG in } END { printf("\n};\n"); - printf("\nprotected el_func_t* func__get() { return el_func; }\n"); - }';; + printf("\nprotected const el_func_t* func__get() { return el_func; }\n"); + }' + ;; + +# generate editline.c from various .c files +# -e) echo "$FILES" | tr ' ' '\012' | $AWK ' BEGIN { @@ -178,8 +205,50 @@ case $FLAG in } { printf("#include \"%s\"\n", $1); - }';; + }' + ;; + +# generate man page fragment from various .c files +# +-m) + cat $FILES | $AWK ' + BEGIN { + printf(".\\\" Section automatically generated with makelist\n"); + printf(".Bl -tag -width 4n\n"); + } + /\(\):/ { + pr = substr($2, 1, 2); + if (pr == "vi" || pr == "em" || pr == "ed") { + name = substr($2, 1, length($2) - 3); + fname = ""; + for (i = 1; i <= length(name); i++) { + s = substr(name, i, 1); + if (s == "_") + s = "-"; + fname = fname s; + } + + printf(".It Ic %s\n", fname); + ok = 1; + } + } + /^ \*/ { + if (ok) { + for (i = 2; i < NF; i++) + printf("%s ", $i); + printf("%s.\n", $i); + ok = 0; + } + } + END { + printf(".El\n"); + printf(".\\\" End of section automatically generated with makelist\n"); + }' + ;; + *) echo $USAGE 1>&2 - exit 1;; + exit 1 + ;; + esac @@ -1,4 +1,4 @@ -/* $NetBSD: map.c,v 1.3 1997/01/11 06:48:00 lukem Exp $ */ +/* $NetBSD: map.c,v 1.14 2001/01/09 17:22:09 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,848 +36,858 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: map.c,v 1.3 1997/01/11 06:48:00 lukem Exp $"; +__RCSID("$NetBSD: map.c,v 1.14 2001/01/09 17:22:09 jdolecek Exp $"); #endif #endif /* not lint && not SCCSID */ /* - * map.c: Editor function definitions + * map.c: Editor function definitions */ #include "sys.h" #include <stdlib.h> #include "el.h" -#define N_KEYS 256 +#define N_KEYS 256 -private void map_print_key __P((EditLine *, el_action_t *, char *)); -private void map_print_some_keys __P((EditLine *, el_action_t *, int, int)); -private void map_print_all_keys __P((EditLine *)); -private void map_init_nls __P((EditLine *)); -private void map_init_meta __P((EditLine *)); +private void map_print_key(EditLine *, el_action_t *, char *); +private void map_print_some_keys(EditLine *, el_action_t *, int, int); +private void map_print_all_keys(EditLine *); +private void map_init_nls(EditLine *); +private void map_init_meta(EditLine *); /* keymap tables ; should be N_KEYS*sizeof(KEYCMD) bytes long */ -private el_action_t el_map_emacs[] = { - /* 0 */ EM_SET_MARK, /* ^@ */ - /* 1 */ ED_MOVE_TO_BEG, /* ^A */ - /* 2 */ ED_PREV_CHAR, /* ^B */ - /* 3 */ ED_TTY_SIGINT, /* ^C */ - /* 4 */ EM_DELETE_OR_LIST, /* ^D */ - /* 5 */ ED_MOVE_TO_END, /* ^E */ - /* 6 */ ED_NEXT_CHAR, /* ^F */ - /* 7 */ ED_UNASSIGNED, /* ^G */ - /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */ - /* 9 */ ED_UNASSIGNED, /* ^I */ - /* 10 */ ED_NEWLINE, /* ^J */ - /* 11 */ ED_KILL_LINE, /* ^K */ - /* 12 */ ED_CLEAR_SCREEN, /* ^L */ - /* 13 */ ED_NEWLINE, /* ^M */ - /* 14 */ ED_NEXT_HISTORY, /* ^N */ - /* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */ - /* 16 */ ED_PREV_HISTORY, /* ^P */ - /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */ - /* 18 */ ED_REDISPLAY, /* ^R */ - /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */ - /* 20 */ ED_TRANSPOSE_CHARS, /* ^T */ - /* 21 */ EM_KILL_LINE, /* ^U */ - /* 22 */ ED_QUOTED_INSERT, /* ^V */ - /* 23 */ EM_KILL_REGION, /* ^W */ - /* 24 */ ED_SEQUENCE_LEAD_IN, /* ^X */ - /* 25 */ EM_YANK, /* ^Y */ - /* 26 */ ED_TTY_SIGTSTP, /* ^Z */ - /* 27 */ EM_META_NEXT, /* ^[ */ - /* 28 */ ED_TTY_SIGQUIT, /* ^\ */ - /* 29 */ ED_TTY_DSUSP, /* ^] */ - /* 30 */ ED_UNASSIGNED, /* ^^ */ - /* 31 */ ED_UNASSIGNED, /* ^_ */ - /* 32 */ ED_INSERT, /* SPACE */ - /* 33 */ ED_INSERT, /* ! */ - /* 34 */ ED_INSERT, /* " */ - /* 35 */ ED_INSERT, /* # */ - /* 36 */ ED_INSERT, /* $ */ - /* 37 */ ED_INSERT, /* % */ - /* 38 */ ED_INSERT, /* & */ - /* 39 */ ED_INSERT, /* ' */ - /* 40 */ ED_INSERT, /* ( */ - /* 41 */ ED_INSERT, /* ) */ - /* 42 */ ED_INSERT, /* * */ - /* 43 */ ED_INSERT, /* + */ - /* 44 */ ED_INSERT, /* , */ - /* 45 */ ED_INSERT, /* - */ - /* 46 */ ED_INSERT, /* . */ - /* 47 */ ED_INSERT, /* / */ - /* 48 */ ED_DIGIT, /* 0 */ - /* 49 */ ED_DIGIT, /* 1 */ - /* 50 */ ED_DIGIT, /* 2 */ - /* 51 */ ED_DIGIT, /* 3 */ - /* 52 */ ED_DIGIT, /* 4 */ - /* 53 */ ED_DIGIT, /* 5 */ - /* 54 */ ED_DIGIT, /* 6 */ - /* 55 */ ED_DIGIT, /* 7 */ - /* 56 */ ED_DIGIT, /* 8 */ - /* 57 */ ED_DIGIT, /* 9 */ - /* 58 */ ED_INSERT, /* : */ - /* 59 */ ED_INSERT, /* ; */ - /* 60 */ ED_INSERT, /* < */ - /* 61 */ ED_INSERT, /* = */ - /* 62 */ ED_INSERT, /* > */ - /* 63 */ ED_INSERT, /* ? */ - /* 64 */ ED_INSERT, /* @ */ - /* 65 */ ED_INSERT, /* A */ - /* 66 */ ED_INSERT, /* B */ - /* 67 */ ED_INSERT, /* C */ - /* 68 */ ED_INSERT, /* D */ - /* 69 */ ED_INSERT, /* E */ - /* 70 */ ED_INSERT, /* F */ - /* 71 */ ED_INSERT, /* G */ - /* 72 */ ED_INSERT, /* H */ - /* 73 */ ED_INSERT, /* I */ - /* 74 */ ED_INSERT, /* J */ - /* 75 */ ED_INSERT, /* K */ - /* 76 */ ED_INSERT, /* L */ - /* 77 */ ED_INSERT, /* M */ - /* 78 */ ED_INSERT, /* N */ - /* 79 */ ED_INSERT, /* O */ - /* 80 */ ED_INSERT, /* P */ - /* 81 */ ED_INSERT, /* Q */ - /* 82 */ ED_INSERT, /* R */ - /* 83 */ ED_INSERT, /* S */ - /* 84 */ ED_INSERT, /* T */ - /* 85 */ ED_INSERT, /* U */ - /* 86 */ ED_INSERT, /* V */ - /* 87 */ ED_INSERT, /* W */ - /* 88 */ ED_INSERT, /* X */ - /* 89 */ ED_INSERT, /* Y */ - /* 90 */ ED_INSERT, /* Z */ - /* 91 */ ED_INSERT, /* [ */ - /* 92 */ ED_INSERT, /* \ */ - /* 93 */ ED_INSERT, /* ] */ - /* 94 */ ED_INSERT, /* ^ */ - /* 95 */ ED_INSERT, /* _ */ - /* 96 */ ED_INSERT, /* ` */ - /* 97 */ ED_INSERT, /* a */ - /* 98 */ ED_INSERT, /* b */ - /* 99 */ ED_INSERT, /* c */ - /* 100 */ ED_INSERT, /* d */ - /* 101 */ ED_INSERT, /* e */ - /* 102 */ ED_INSERT, /* f */ - /* 103 */ ED_INSERT, /* g */ - /* 104 */ ED_INSERT, /* h */ - /* 105 */ ED_INSERT, /* i */ - /* 106 */ ED_INSERT, /* j */ - /* 107 */ ED_INSERT, /* k */ - /* 108 */ ED_INSERT, /* l */ - /* 109 */ ED_INSERT, /* m */ - /* 110 */ ED_INSERT, /* n */ - /* 111 */ ED_INSERT, /* o */ - /* 112 */ ED_INSERT, /* p */ - /* 113 */ ED_INSERT, /* q */ - /* 114 */ ED_INSERT, /* r */ - /* 115 */ ED_INSERT, /* s */ - /* 116 */ ED_INSERT, /* t */ - /* 117 */ ED_INSERT, /* u */ - /* 118 */ ED_INSERT, /* v */ - /* 119 */ ED_INSERT, /* w */ - /* 120 */ ED_INSERT, /* x */ - /* 121 */ ED_INSERT, /* y */ - /* 122 */ ED_INSERT, /* z */ - /* 123 */ ED_INSERT, /* { */ - /* 124 */ ED_INSERT, /* | */ - /* 125 */ ED_INSERT, /* } */ - /* 126 */ ED_INSERT, /* ~ */ - /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */ - /* 128 */ ED_UNASSIGNED, /* M-^@ */ - /* 129 */ ED_UNASSIGNED, /* M-^A */ - /* 130 */ ED_UNASSIGNED, /* M-^B */ - /* 131 */ ED_UNASSIGNED, /* M-^C */ - /* 132 */ ED_UNASSIGNED, /* M-^D */ - /* 133 */ ED_UNASSIGNED, /* M-^E */ - /* 134 */ ED_UNASSIGNED, /* M-^F */ - /* 135 */ ED_UNASSIGNED, /* M-^G */ - /* 136 */ ED_DELETE_PREV_WORD, /* M-^H */ - /* 137 */ ED_UNASSIGNED, /* M-^I */ - /* 138 */ ED_UNASSIGNED, /* M-^J */ - /* 139 */ ED_UNASSIGNED, /* M-^K */ - /* 140 */ ED_CLEAR_SCREEN, /* M-^L */ - /* 141 */ ED_UNASSIGNED, /* M-^M */ - /* 142 */ ED_UNASSIGNED, /* M-^N */ - /* 143 */ ED_UNASSIGNED, /* M-^O */ - /* 144 */ ED_UNASSIGNED, /* M-^P */ - /* 145 */ ED_UNASSIGNED, /* M-^Q */ - /* 146 */ ED_UNASSIGNED, /* M-^R */ - /* 147 */ ED_UNASSIGNED, /* M-^S */ - /* 148 */ ED_UNASSIGNED, /* M-^T */ - /* 149 */ ED_UNASSIGNED, /* M-^U */ - /* 150 */ ED_UNASSIGNED, /* M-^V */ - /* 151 */ ED_UNASSIGNED, /* M-^W */ - /* 152 */ ED_UNASSIGNED, /* M-^X */ - /* 153 */ ED_UNASSIGNED, /* M-^Y */ - /* 154 */ ED_UNASSIGNED, /* M-^Z */ - /* 155 */ ED_UNASSIGNED, /* M-^[ */ - /* 156 */ ED_UNASSIGNED, /* M-^\ */ - /* 157 */ ED_UNASSIGNED, /* M-^] */ - /* 158 */ ED_UNASSIGNED, /* M-^^ */ - /* 159 */ EM_COPY_PREV_WORD, /* M-^_ */ - /* 160 */ ED_UNASSIGNED, /* M-SPACE */ - /* 161 */ ED_UNASSIGNED, /* M-! */ - /* 162 */ ED_UNASSIGNED, /* M-" */ - /* 163 */ ED_UNASSIGNED, /* M-# */ - /* 164 */ ED_UNASSIGNED, /* M-$ */ - /* 165 */ ED_UNASSIGNED, /* M-% */ - /* 166 */ ED_UNASSIGNED, /* M-& */ - /* 167 */ ED_UNASSIGNED, /* M-' */ - /* 168 */ ED_UNASSIGNED, /* M-( */ - /* 169 */ ED_UNASSIGNED, /* M-) */ - /* 170 */ ED_UNASSIGNED, /* M-* */ - /* 171 */ ED_UNASSIGNED, /* M-+ */ - /* 172 */ ED_UNASSIGNED, /* M-, */ - /* 173 */ ED_UNASSIGNED, /* M-- */ - /* 174 */ ED_UNASSIGNED, /* M-. */ - /* 175 */ ED_UNASSIGNED, /* M-/ */ - /* 176 */ ED_ARGUMENT_DIGIT, /* M-0 */ - /* 177 */ ED_ARGUMENT_DIGIT, /* M-1 */ - /* 178 */ ED_ARGUMENT_DIGIT, /* M-2 */ - /* 179 */ ED_ARGUMENT_DIGIT, /* M-3 */ - /* 180 */ ED_ARGUMENT_DIGIT, /* M-4 */ - /* 181 */ ED_ARGUMENT_DIGIT, /* M-5 */ - /* 182 */ ED_ARGUMENT_DIGIT, /* M-6 */ - /* 183 */ ED_ARGUMENT_DIGIT, /* M-7 */ - /* 184 */ ED_ARGUMENT_DIGIT, /* M-8 */ - /* 185 */ ED_ARGUMENT_DIGIT, /* M-9 */ - /* 186 */ ED_UNASSIGNED, /* M-: */ - /* 187 */ ED_UNASSIGNED, /* M-; */ - /* 188 */ ED_UNASSIGNED, /* M-< */ - /* 189 */ ED_UNASSIGNED, /* M-= */ - /* 190 */ ED_UNASSIGNED, /* M-> */ - /* 191 */ ED_UNASSIGNED, /* M-? */ - /* 192 */ ED_UNASSIGNED, /* M-@ */ - /* 193 */ ED_UNASSIGNED, /* M-A */ - /* 194 */ ED_PREV_WORD, /* M-B */ - /* 195 */ EM_CAPITOL_CASE, /* M-C */ - /* 196 */ EM_DELETE_NEXT_WORD, /* M-D */ - /* 197 */ ED_UNASSIGNED, /* M-E */ - /* 198 */ EM_NEXT_WORD, /* M-F */ - /* 199 */ ED_UNASSIGNED, /* M-G */ - /* 200 */ ED_UNASSIGNED, /* M-H */ - /* 201 */ ED_UNASSIGNED, /* M-I */ - /* 202 */ ED_UNASSIGNED, /* M-J */ - /* 203 */ ED_UNASSIGNED, /* M-K */ - /* 204 */ EM_LOWER_CASE, /* M-L */ - /* 205 */ ED_UNASSIGNED, /* M-M */ - /* 206 */ ED_SEARCH_NEXT_HISTORY, /* M-N */ - /* 207 */ ED_SEQUENCE_LEAD_IN, /* M-O */ - /* 208 */ ED_SEARCH_PREV_HISTORY, /* M-P */ - /* 209 */ ED_UNASSIGNED, /* M-Q */ - /* 210 */ ED_UNASSIGNED, /* M-R */ - /* 211 */ ED_UNASSIGNED, /* M-S */ - /* 212 */ ED_UNASSIGNED, /* M-T */ - /* 213 */ EM_UPPER_CASE, /* M-U */ - /* 214 */ ED_UNASSIGNED, /* M-V */ - /* 215 */ EM_COPY_REGION, /* M-W */ - /* 216 */ ED_COMMAND, /* M-X */ - /* 217 */ ED_UNASSIGNED, /* M-Y */ - /* 218 */ ED_UNASSIGNED, /* M-Z */ - /* 219 */ ED_SEQUENCE_LEAD_IN, /* M-[ */ - /* 220 */ ED_UNASSIGNED, /* M-\ */ - /* 221 */ ED_UNASSIGNED, /* M-] */ - /* 222 */ ED_UNASSIGNED, /* M-^ */ - /* 223 */ ED_UNASSIGNED, /* M-_ */ - /* 223 */ ED_UNASSIGNED, /* M-` */ - /* 224 */ ED_UNASSIGNED, /* M-a */ - /* 225 */ ED_PREV_WORD, /* M-b */ - /* 226 */ EM_CAPITOL_CASE, /* M-c */ - /* 227 */ EM_DELETE_NEXT_WORD, /* M-d */ - /* 228 */ ED_UNASSIGNED, /* M-e */ - /* 229 */ EM_NEXT_WORD, /* M-f */ - /* 230 */ ED_UNASSIGNED, /* M-g */ - /* 231 */ ED_UNASSIGNED, /* M-h */ - /* 232 */ ED_UNASSIGNED, /* M-i */ - /* 233 */ ED_UNASSIGNED, /* M-j */ - /* 234 */ ED_UNASSIGNED, /* M-k */ - /* 235 */ EM_LOWER_CASE, /* M-l */ - /* 236 */ ED_UNASSIGNED, /* M-m */ - /* 237 */ ED_SEARCH_NEXT_HISTORY, /* M-n */ - /* 238 */ ED_UNASSIGNED, /* M-o */ - /* 239 */ ED_SEARCH_PREV_HISTORY, /* M-p */ - /* 240 */ ED_UNASSIGNED, /* M-q */ - /* 241 */ ED_UNASSIGNED, /* M-r */ - /* 242 */ ED_UNASSIGNED, /* M-s */ - /* 243 */ ED_UNASSIGNED, /* M-t */ - /* 244 */ EM_UPPER_CASE, /* M-u */ - /* 245 */ ED_UNASSIGNED, /* M-v */ - /* 246 */ EM_COPY_REGION, /* M-w */ - /* 247 */ ED_COMMAND, /* M-x */ - /* 248 */ ED_UNASSIGNED, /* M-y */ - /* 249 */ ED_UNASSIGNED, /* M-z */ - /* 250 */ ED_UNASSIGNED, /* M-{ */ - /* 251 */ ED_UNASSIGNED, /* M-| */ - /* 252 */ ED_UNASSIGNED, /* M-} */ - /* 253 */ ED_UNASSIGNED, /* M-~ */ - /* 254 */ ED_DELETE_PREV_WORD /* M-^? */ - /* 255 */ + +private const el_action_t el_map_emacs[] = { + /* 0 */ EM_SET_MARK, /* ^@ */ + /* 1 */ ED_MOVE_TO_BEG, /* ^A */ + /* 2 */ ED_PREV_CHAR, /* ^B */ + /* 3 */ ED_TTY_SIGINT, /* ^C */ + /* 4 */ EM_DELETE_OR_LIST, /* ^D */ + /* 5 */ ED_MOVE_TO_END, /* ^E */ + /* 6 */ ED_NEXT_CHAR, /* ^F */ + /* 7 */ ED_UNASSIGNED, /* ^G */ + /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */ + /* 9 */ ED_UNASSIGNED, /* ^I */ + /* 10 */ ED_NEWLINE, /* ^J */ + /* 11 */ ED_KILL_LINE, /* ^K */ + /* 12 */ ED_CLEAR_SCREEN, /* ^L */ + /* 13 */ ED_NEWLINE, /* ^M */ + /* 14 */ ED_NEXT_HISTORY, /* ^N */ + /* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */ + /* 16 */ ED_PREV_HISTORY, /* ^P */ + /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */ + /* 18 */ ED_REDISPLAY, /* ^R */ + /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */ + /* 20 */ ED_TRANSPOSE_CHARS, /* ^T */ + /* 21 */ EM_KILL_LINE, /* ^U */ + /* 22 */ ED_QUOTED_INSERT, /* ^V */ + /* 23 */ EM_KILL_REGION, /* ^W */ + /* 24 */ ED_SEQUENCE_LEAD_IN, /* ^X */ + /* 25 */ EM_YANK, /* ^Y */ + /* 26 */ ED_TTY_SIGTSTP, /* ^Z */ + /* 27 */ EM_META_NEXT, /* ^[ */ + /* 28 */ ED_TTY_SIGQUIT, /* ^\ */ + /* 29 */ ED_TTY_DSUSP, /* ^] */ + /* 30 */ ED_UNASSIGNED, /* ^^ */ + /* 31 */ ED_UNASSIGNED, /* ^_ */ + /* 32 */ ED_INSERT, /* SPACE */ + /* 33 */ ED_INSERT, /* ! */ + /* 34 */ ED_INSERT, /* " */ + /* 35 */ ED_INSERT, /* # */ + /* 36 */ ED_INSERT, /* $ */ + /* 37 */ ED_INSERT, /* % */ + /* 38 */ ED_INSERT, /* & */ + /* 39 */ ED_INSERT, /* ' */ + /* 40 */ ED_INSERT, /* ( */ + /* 41 */ ED_INSERT, /* ) */ + /* 42 */ ED_INSERT, /* * */ + /* 43 */ ED_INSERT, /* + */ + /* 44 */ ED_INSERT, /* , */ + /* 45 */ ED_INSERT, /* - */ + /* 46 */ ED_INSERT, /* . */ + /* 47 */ ED_INSERT, /* / */ + /* 48 */ ED_DIGIT, /* 0 */ + /* 49 */ ED_DIGIT, /* 1 */ + /* 50 */ ED_DIGIT, /* 2 */ + /* 51 */ ED_DIGIT, /* 3 */ + /* 52 */ ED_DIGIT, /* 4 */ + /* 53 */ ED_DIGIT, /* 5 */ + /* 54 */ ED_DIGIT, /* 6 */ + /* 55 */ ED_DIGIT, /* 7 */ + /* 56 */ ED_DIGIT, /* 8 */ + /* 57 */ ED_DIGIT, /* 9 */ + /* 58 */ ED_INSERT, /* : */ + /* 59 */ ED_INSERT, /* ; */ + /* 60 */ ED_INSERT, /* < */ + /* 61 */ ED_INSERT, /* = */ + /* 62 */ ED_INSERT, /* > */ + /* 63 */ ED_INSERT, /* ? */ + /* 64 */ ED_INSERT, /* @ */ + /* 65 */ ED_INSERT, /* A */ + /* 66 */ ED_INSERT, /* B */ + /* 67 */ ED_INSERT, /* C */ + /* 68 */ ED_INSERT, /* D */ + /* 69 */ ED_INSERT, /* E */ + /* 70 */ ED_INSERT, /* F */ + /* 71 */ ED_INSERT, /* G */ + /* 72 */ ED_INSERT, /* H */ + /* 73 */ ED_INSERT, /* I */ + /* 74 */ ED_INSERT, /* J */ + /* 75 */ ED_INSERT, /* K */ + /* 76 */ ED_INSERT, /* L */ + /* 77 */ ED_INSERT, /* M */ + /* 78 */ ED_INSERT, /* N */ + /* 79 */ ED_INSERT, /* O */ + /* 80 */ ED_INSERT, /* P */ + /* 81 */ ED_INSERT, /* Q */ + /* 82 */ ED_INSERT, /* R */ + /* 83 */ ED_INSERT, /* S */ + /* 84 */ ED_INSERT, /* T */ + /* 85 */ ED_INSERT, /* U */ + /* 86 */ ED_INSERT, /* V */ + /* 87 */ ED_INSERT, /* W */ + /* 88 */ ED_INSERT, /* X */ + /* 89 */ ED_INSERT, /* Y */ + /* 90 */ ED_INSERT, /* Z */ + /* 91 */ ED_INSERT, /* [ */ + /* 92 */ ED_INSERT, /* \ */ + /* 93 */ ED_INSERT, /* ] */ + /* 94 */ ED_INSERT, /* ^ */ + /* 95 */ ED_INSERT, /* _ */ + /* 96 */ ED_INSERT, /* ` */ + /* 97 */ ED_INSERT, /* a */ + /* 98 */ ED_INSERT, /* b */ + /* 99 */ ED_INSERT, /* c */ + /* 100 */ ED_INSERT, /* d */ + /* 101 */ ED_INSERT, /* e */ + /* 102 */ ED_INSERT, /* f */ + /* 103 */ ED_INSERT, /* g */ + /* 104 */ ED_INSERT, /* h */ + /* 105 */ ED_INSERT, /* i */ + /* 106 */ ED_INSERT, /* j */ + /* 107 */ ED_INSERT, /* k */ + /* 108 */ ED_INSERT, /* l */ + /* 109 */ ED_INSERT, /* m */ + /* 110 */ ED_INSERT, /* n */ + /* 111 */ ED_INSERT, /* o */ + /* 112 */ ED_INSERT, /* p */ + /* 113 */ ED_INSERT, /* q */ + /* 114 */ ED_INSERT, /* r */ + /* 115 */ ED_INSERT, /* s */ + /* 116 */ ED_INSERT, /* t */ + /* 117 */ ED_INSERT, /* u */ + /* 118 */ ED_INSERT, /* v */ + /* 119 */ ED_INSERT, /* w */ + /* 120 */ ED_INSERT, /* x */ + /* 121 */ ED_INSERT, /* y */ + /* 122 */ ED_INSERT, /* z */ + /* 123 */ ED_INSERT, /* { */ + /* 124 */ ED_INSERT, /* | */ + /* 125 */ ED_INSERT, /* } */ + /* 126 */ ED_INSERT, /* ~ */ + /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */ + /* 128 */ ED_UNASSIGNED, /* M-^@ */ + /* 129 */ ED_UNASSIGNED, /* M-^A */ + /* 130 */ ED_UNASSIGNED, /* M-^B */ + /* 131 */ ED_UNASSIGNED, /* M-^C */ + /* 132 */ ED_UNASSIGNED, /* M-^D */ + /* 133 */ ED_UNASSIGNED, /* M-^E */ + /* 134 */ ED_UNASSIGNED, /* M-^F */ + /* 135 */ ED_UNASSIGNED, /* M-^G */ + /* 136 */ ED_DELETE_PREV_WORD, /* M-^H */ + /* 137 */ ED_UNASSIGNED, /* M-^I */ + /* 138 */ ED_UNASSIGNED, /* M-^J */ + /* 139 */ ED_UNASSIGNED, /* M-^K */ + /* 140 */ ED_CLEAR_SCREEN, /* M-^L */ + /* 141 */ ED_UNASSIGNED, /* M-^M */ + /* 142 */ ED_UNASSIGNED, /* M-^N */ + /* 143 */ ED_UNASSIGNED, /* M-^O */ + /* 144 */ ED_UNASSIGNED, /* M-^P */ + /* 145 */ ED_UNASSIGNED, /* M-^Q */ + /* 146 */ ED_UNASSIGNED, /* M-^R */ + /* 147 */ ED_UNASSIGNED, /* M-^S */ + /* 148 */ ED_UNASSIGNED, /* M-^T */ + /* 149 */ ED_UNASSIGNED, /* M-^U */ + /* 150 */ ED_UNASSIGNED, /* M-^V */ + /* 151 */ ED_UNASSIGNED, /* M-^W */ + /* 152 */ ED_UNASSIGNED, /* M-^X */ + /* 153 */ ED_UNASSIGNED, /* M-^Y */ + /* 154 */ ED_UNASSIGNED, /* M-^Z */ + /* 155 */ ED_UNASSIGNED, /* M-^[ */ + /* 156 */ ED_UNASSIGNED, /* M-^\ */ + /* 157 */ ED_UNASSIGNED, /* M-^] */ + /* 158 */ ED_UNASSIGNED, /* M-^^ */ + /* 159 */ EM_COPY_PREV_WORD, /* M-^_ */ + /* 160 */ ED_UNASSIGNED, /* M-SPACE */ + /* 161 */ ED_UNASSIGNED, /* M-! */ + /* 162 */ ED_UNASSIGNED, /* M-" */ + /* 163 */ ED_UNASSIGNED, /* M-# */ + /* 164 */ ED_UNASSIGNED, /* M-$ */ + /* 165 */ ED_UNASSIGNED, /* M-% */ + /* 166 */ ED_UNASSIGNED, /* M-& */ + /* 167 */ ED_UNASSIGNED, /* M-' */ + /* 168 */ ED_UNASSIGNED, /* M-( */ + /* 169 */ ED_UNASSIGNED, /* M-) */ + /* 170 */ ED_UNASSIGNED, /* M-* */ + /* 171 */ ED_UNASSIGNED, /* M-+ */ + /* 172 */ ED_UNASSIGNED, /* M-, */ + /* 173 */ ED_UNASSIGNED, /* M-- */ + /* 174 */ ED_UNASSIGNED, /* M-. */ + /* 175 */ ED_UNASSIGNED, /* M-/ */ + /* 176 */ ED_ARGUMENT_DIGIT, /* M-0 */ + /* 177 */ ED_ARGUMENT_DIGIT, /* M-1 */ + /* 178 */ ED_ARGUMENT_DIGIT, /* M-2 */ + /* 179 */ ED_ARGUMENT_DIGIT, /* M-3 */ + /* 180 */ ED_ARGUMENT_DIGIT, /* M-4 */ + /* 181 */ ED_ARGUMENT_DIGIT, /* M-5 */ + /* 182 */ ED_ARGUMENT_DIGIT, /* M-6 */ + /* 183 */ ED_ARGUMENT_DIGIT, /* M-7 */ + /* 184 */ ED_ARGUMENT_DIGIT, /* M-8 */ + /* 185 */ ED_ARGUMENT_DIGIT, /* M-9 */ + /* 186 */ ED_UNASSIGNED, /* M-: */ + /* 187 */ ED_UNASSIGNED, /* M-; */ + /* 188 */ ED_UNASSIGNED, /* M-< */ + /* 189 */ ED_UNASSIGNED, /* M-= */ + /* 190 */ ED_UNASSIGNED, /* M-> */ + /* 191 */ ED_UNASSIGNED, /* M-? */ + /* 192 */ ED_UNASSIGNED, /* M-@ */ + /* 193 */ ED_UNASSIGNED, /* M-A */ + /* 194 */ ED_PREV_WORD, /* M-B */ + /* 195 */ EM_CAPITOL_CASE, /* M-C */ + /* 196 */ EM_DELETE_NEXT_WORD, /* M-D */ + /* 197 */ ED_UNASSIGNED, /* M-E */ + /* 198 */ EM_NEXT_WORD, /* M-F */ + /* 199 */ ED_UNASSIGNED, /* M-G */ + /* 200 */ ED_UNASSIGNED, /* M-H */ + /* 201 */ ED_UNASSIGNED, /* M-I */ + /* 202 */ ED_UNASSIGNED, /* M-J */ + /* 203 */ ED_UNASSIGNED, /* M-K */ + /* 204 */ EM_LOWER_CASE, /* M-L */ + /* 205 */ ED_UNASSIGNED, /* M-M */ + /* 206 */ ED_SEARCH_NEXT_HISTORY, /* M-N */ + /* 207 */ ED_SEQUENCE_LEAD_IN, /* M-O */ + /* 208 */ ED_SEARCH_PREV_HISTORY, /* M-P */ + /* 209 */ ED_UNASSIGNED, /* M-Q */ + /* 210 */ ED_UNASSIGNED, /* M-R */ + /* 211 */ ED_UNASSIGNED, /* M-S */ + /* 212 */ ED_UNASSIGNED, /* M-T */ + /* 213 */ EM_UPPER_CASE, /* M-U */ + /* 214 */ ED_UNASSIGNED, /* M-V */ + /* 215 */ EM_COPY_REGION, /* M-W */ + /* 216 */ ED_COMMAND, /* M-X */ + /* 217 */ ED_UNASSIGNED, /* M-Y */ + /* 218 */ ED_UNASSIGNED, /* M-Z */ + /* 219 */ ED_SEQUENCE_LEAD_IN, /* M-[ */ + /* 220 */ ED_UNASSIGNED, /* M-\ */ + /* 221 */ ED_UNASSIGNED, /* M-] */ + /* 222 */ ED_UNASSIGNED, /* M-^ */ + /* 223 */ ED_UNASSIGNED, /* M-_ */ + /* 223 */ ED_UNASSIGNED, /* M-` */ + /* 224 */ ED_UNASSIGNED, /* M-a */ + /* 225 */ ED_PREV_WORD, /* M-b */ + /* 226 */ EM_CAPITOL_CASE, /* M-c */ + /* 227 */ EM_DELETE_NEXT_WORD, /* M-d */ + /* 228 */ ED_UNASSIGNED, /* M-e */ + /* 229 */ EM_NEXT_WORD, /* M-f */ + /* 230 */ ED_UNASSIGNED, /* M-g */ + /* 231 */ ED_UNASSIGNED, /* M-h */ + /* 232 */ ED_UNASSIGNED, /* M-i */ + /* 233 */ ED_UNASSIGNED, /* M-j */ + /* 234 */ ED_UNASSIGNED, /* M-k */ + /* 235 */ EM_LOWER_CASE, /* M-l */ + /* 236 */ ED_UNASSIGNED, /* M-m */ + /* 237 */ ED_SEARCH_NEXT_HISTORY, /* M-n */ + /* 238 */ ED_UNASSIGNED, /* M-o */ + /* 239 */ ED_SEARCH_PREV_HISTORY, /* M-p */ + /* 240 */ ED_UNASSIGNED, /* M-q */ + /* 241 */ ED_UNASSIGNED, /* M-r */ + /* 242 */ ED_UNASSIGNED, /* M-s */ + /* 243 */ ED_UNASSIGNED, /* M-t */ + /* 244 */ EM_UPPER_CASE, /* M-u */ + /* 245 */ ED_UNASSIGNED, /* M-v */ + /* 246 */ EM_COPY_REGION, /* M-w */ + /* 247 */ ED_COMMAND, /* M-x */ + /* 248 */ ED_UNASSIGNED, /* M-y */ + /* 249 */ ED_UNASSIGNED, /* M-z */ + /* 250 */ ED_UNASSIGNED, /* M-{ */ + /* 251 */ ED_UNASSIGNED, /* M-| */ + /* 252 */ ED_UNASSIGNED, /* M-} */ + /* 253 */ ED_UNASSIGNED, /* M-~ */ + /* 254 */ ED_DELETE_PREV_WORD /* M-^? */ + /* 255 */ }; + /* * keymap table for vi. Each index into above tbl; should be * N_KEYS entries long. Vi mode uses a sticky-extend to do command mode: * insert mode characters are in the normal keymap, and command mode * in the extended keymap. */ -private el_action_t el_map_vi_insert[] = { +private const el_action_t el_map_vi_insert[] = { #ifdef KSHVI - /* 0 */ ED_UNASSIGNED, /* ^@ */ - /* 1 */ ED_INSERT, /* ^A */ - /* 2 */ ED_INSERT, /* ^B */ - /* 3 */ ED_INSERT, /* ^C */ - /* 4 */ VI_LIST_OR_EOF, /* ^D */ - /* 5 */ ED_INSERT, /* ^E */ - /* 6 */ ED_INSERT, /* ^F */ - /* 7 */ ED_INSERT, /* ^G */ - /* 8 */ VI_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */ - /* 9 */ ED_INSERT, /* ^I */ /* Tab Key */ - /* 10 */ ED_NEWLINE, /* ^J */ - /* 11 */ ED_INSERT, /* ^K */ - /* 12 */ ED_INSERT, /* ^L */ - /* 13 */ ED_NEWLINE, /* ^M */ - /* 14 */ ED_INSERT, /* ^N */ - /* 15 */ ED_INSERT, /* ^O */ - /* 16 */ ED_INSERT, /* ^P */ - /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */ - /* 18 */ ED_INSERT, /* ^R */ - /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */ - /* 20 */ ED_INSERT, /* ^T */ - /* 21 */ VI_KILL_LINE_PREV, /* ^U */ - /* 22 */ ED_QUOTED_INSERT, /* ^V */ - /* 23 */ ED_DELETE_PREV_WORD, /* ^W */ /* Only until strt edit pos */ - /* 24 */ ED_INSERT, /* ^X */ - /* 25 */ ED_INSERT, /* ^Y */ - /* 26 */ ED_INSERT, /* ^Z */ - /* 27 */ VI_COMMAND_MODE, /* ^[ */ /* [ Esc ] key */ - /* 28 */ ED_TTY_SIGQUIT, /* ^\ */ - /* 29 */ ED_INSERT, /* ^] */ - /* 30 */ ED_INSERT, /* ^^ */ - /* 31 */ ED_INSERT, /* ^_ */ + /* 0 */ ED_UNASSIGNED, /* ^@ */ + /* 1 */ ED_INSERT, /* ^A */ + /* 2 */ ED_INSERT, /* ^B */ + /* 3 */ ED_INSERT, /* ^C */ + /* 4 */ VI_LIST_OR_EOF, /* ^D */ + /* 5 */ ED_INSERT, /* ^E */ + /* 6 */ ED_INSERT, /* ^F */ + /* 7 */ ED_INSERT, /* ^G */ + /* 8 */ VI_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */ + /* 9 */ ED_INSERT, /* ^I */ /* Tab Key */ + /* 10 */ ED_NEWLINE, /* ^J */ + /* 11 */ ED_INSERT, /* ^K */ + /* 12 */ ED_INSERT, /* ^L */ + /* 13 */ ED_NEWLINE, /* ^M */ + /* 14 */ ED_INSERT, /* ^N */ + /* 15 */ ED_INSERT, /* ^O */ + /* 16 */ ED_INSERT, /* ^P */ + /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */ + /* 18 */ ED_INSERT, /* ^R */ + /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */ + /* 20 */ ED_INSERT, /* ^T */ + /* 21 */ VI_KILL_LINE_PREV, /* ^U */ + /* 22 */ ED_QUOTED_INSERT, /* ^V */ + /* 23 */ ED_DELETE_PREV_WORD, /* ^W */ + /* ED_DELETE_PREV_WORD: Only until strt edit pos */ + /* 24 */ ED_INSERT, /* ^X */ + /* 25 */ ED_INSERT, /* ^Y */ + /* 26 */ ED_INSERT, /* ^Z */ + /* 27 */ VI_COMMAND_MODE, /* ^[ */ /* [ Esc ] key */ + /* 28 */ ED_TTY_SIGQUIT, /* ^\ */ + /* 29 */ ED_INSERT, /* ^] */ + /* 30 */ ED_INSERT, /* ^^ */ + /* 31 */ ED_INSERT, /* ^_ */ #else /* !KSHVI */ - /* 0 */ ED_UNASSIGNED, /* ^@ */ /* NOTE: These mappings do */ - /* 1 */ ED_MOVE_TO_BEG, /* ^A */ /* NOT Correspond well to */ - /* 2 */ ED_PREV_CHAR, /* ^B */ /* the KSH VI editing as- */ - /* 3 */ ED_TTY_SIGINT, /* ^C */ /* signments. On the other */ - /* 4 */ VI_LIST_OR_EOF, /* ^D */ /* hand they are convenient*/ - /* 5 */ ED_MOVE_TO_END, /* ^E */ /* and many people have */ - /* 6 */ ED_NEXT_CHAR, /* ^F */ /* have gotten used to them*/ - /* 7 */ ED_UNASSIGNED, /* ^G */ - /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */ - /* 9 */ ED_UNASSIGNED, /* ^I */ /* Tab Key */ - /* 10 */ ED_NEWLINE, /* ^J */ - /* 11 */ ED_KILL_LINE, /* ^K */ - /* 12 */ ED_CLEAR_SCREEN, /* ^L */ - /* 13 */ ED_NEWLINE, /* ^M */ - /* 14 */ ED_NEXT_HISTORY, /* ^N */ - /* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */ - /* 16 */ ED_PREV_HISTORY, /* ^P */ - /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */ - /* 18 */ ED_REDISPLAY, /* ^R */ - /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */ - /* 20 */ ED_TRANSPOSE_CHARS, /* ^T */ - /* 21 */ VI_KILL_LINE_PREV, /* ^U */ - /* 22 */ ED_QUOTED_INSERT, /* ^V */ - /* 23 */ ED_DELETE_PREV_WORD, /* ^W */ - /* 24 */ ED_UNASSIGNED, /* ^X */ - /* 25 */ ED_TTY_DSUSP, /* ^Y */ - /* 26 */ ED_TTY_SIGTSTP, /* ^Z */ - /* 27 */ VI_COMMAND_MODE, /* ^[ */ - /* 28 */ ED_TTY_SIGQUIT, /* ^\ */ - /* 29 */ ED_UNASSIGNED, /* ^] */ - /* 30 */ ED_UNASSIGNED, /* ^^ */ - /* 31 */ ED_UNASSIGNED, /* ^_ */ + /* + * NOTE: These mappings do NOT Correspond well + * to the KSH VI editing assignments. + * On the other and they are convenient and + * many people have have gotten used to them. + */ + /* 0 */ ED_UNASSIGNED, /* ^@ */ + /* 1 */ ED_MOVE_TO_BEG, /* ^A */ + /* 2 */ ED_PREV_CHAR, /* ^B */ + /* 3 */ ED_TTY_SIGINT, /* ^C */ + /* 4 */ VI_LIST_OR_EOF, /* ^D */ + /* 5 */ ED_MOVE_TO_END, /* ^E */ + /* 6 */ ED_NEXT_CHAR, /* ^F */ + /* 7 */ ED_UNASSIGNED, /* ^G */ + /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */ + /* 9 */ ED_UNASSIGNED, /* ^I */ /* Tab Key */ + /* 10 */ ED_NEWLINE, /* ^J */ + /* 11 */ ED_KILL_LINE, /* ^K */ + /* 12 */ ED_CLEAR_SCREEN, /* ^L */ + /* 13 */ ED_NEWLINE, /* ^M */ + /* 14 */ ED_NEXT_HISTORY, /* ^N */ + /* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */ + /* 16 */ ED_PREV_HISTORY, /* ^P */ + /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */ + /* 18 */ ED_REDISPLAY, /* ^R */ + /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */ + /* 20 */ ED_TRANSPOSE_CHARS, /* ^T */ + /* 21 */ VI_KILL_LINE_PREV, /* ^U */ + /* 22 */ ED_QUOTED_INSERT, /* ^V */ + /* 23 */ ED_DELETE_PREV_WORD, /* ^W */ + /* 24 */ ED_UNASSIGNED, /* ^X */ + /* 25 */ ED_TTY_DSUSP, /* ^Y */ + /* 26 */ ED_TTY_SIGTSTP, /* ^Z */ + /* 27 */ VI_COMMAND_MODE, /* ^[ */ + /* 28 */ ED_TTY_SIGQUIT, /* ^\ */ + /* 29 */ ED_UNASSIGNED, /* ^] */ + /* 30 */ ED_UNASSIGNED, /* ^^ */ + /* 31 */ ED_UNASSIGNED, /* ^_ */ #endif /* KSHVI */ - /* 32 */ ED_INSERT, /* SPACE */ - /* 33 */ ED_INSERT, /* ! */ - /* 34 */ ED_INSERT, /* " */ - /* 35 */ ED_INSERT, /* # */ - /* 36 */ ED_INSERT, /* $ */ - /* 37 */ ED_INSERT, /* % */ - /* 38 */ ED_INSERT, /* & */ - /* 39 */ ED_INSERT, /* ' */ - /* 40 */ ED_INSERT, /* ( */ - /* 41 */ ED_INSERT, /* ) */ - /* 42 */ ED_INSERT, /* * */ - /* 43 */ ED_INSERT, /* + */ - /* 44 */ ED_INSERT, /* , */ - /* 45 */ ED_INSERT, /* - */ - /* 46 */ ED_INSERT, /* . */ - /* 47 */ ED_INSERT, /* / */ - /* 48 */ ED_INSERT, /* 0 */ - /* 49 */ ED_INSERT, /* 1 */ - /* 50 */ ED_INSERT, /* 2 */ - /* 51 */ ED_INSERT, /* 3 */ - /* 52 */ ED_INSERT, /* 4 */ - /* 53 */ ED_INSERT, /* 5 */ - /* 54 */ ED_INSERT, /* 6 */ - /* 55 */ ED_INSERT, /* 7 */ - /* 56 */ ED_INSERT, /* 8 */ - /* 57 */ ED_INSERT, /* 9 */ - /* 58 */ ED_INSERT, /* : */ - /* 59 */ ED_INSERT, /* ; */ - /* 60 */ ED_INSERT, /* < */ - /* 61 */ ED_INSERT, /* = */ - /* 62 */ ED_INSERT, /* > */ - /* 63 */ ED_INSERT, /* ? */ - /* 64 */ ED_INSERT, /* @ */ - /* 65 */ ED_INSERT, /* A */ - /* 66 */ ED_INSERT, /* B */ - /* 67 */ ED_INSERT, /* C */ - /* 68 */ ED_INSERT, /* D */ - /* 69 */ ED_INSERT, /* E */ - /* 70 */ ED_INSERT, /* F */ - /* 71 */ ED_INSERT, /* G */ - /* 72 */ ED_INSERT, /* H */ - /* 73 */ ED_INSERT, /* I */ - /* 74 */ ED_INSERT, /* J */ - /* 75 */ ED_INSERT, /* K */ - /* 76 */ ED_INSERT, /* L */ - /* 77 */ ED_INSERT, /* M */ - /* 78 */ ED_INSERT, /* N */ - /* 79 */ ED_INSERT, /* O */ - /* 80 */ ED_INSERT, /* P */ - /* 81 */ ED_INSERT, /* Q */ - /* 82 */ ED_INSERT, /* R */ - /* 83 */ ED_INSERT, /* S */ - /* 84 */ ED_INSERT, /* T */ - /* 85 */ ED_INSERT, /* U */ - /* 86 */ ED_INSERT, /* V */ - /* 87 */ ED_INSERT, /* W */ - /* 88 */ ED_INSERT, /* X */ - /* 89 */ ED_INSERT, /* Y */ - /* 90 */ ED_INSERT, /* Z */ - /* 91 */ ED_INSERT, /* [ */ - /* 92 */ ED_INSERT, /* \ */ - /* 93 */ ED_INSERT, /* ] */ - /* 94 */ ED_INSERT, /* ^ */ - /* 95 */ ED_INSERT, /* _ */ - /* 96 */ ED_INSERT, /* ` */ - /* 97 */ ED_INSERT, /* a */ - /* 98 */ ED_INSERT, /* b */ - /* 99 */ ED_INSERT, /* c */ - /* 100 */ ED_INSERT, /* d */ - /* 101 */ ED_INSERT, /* e */ - /* 102 */ ED_INSERT, /* f */ - /* 103 */ ED_INSERT, /* g */ - /* 104 */ ED_INSERT, /* h */ - /* 105 */ ED_INSERT, /* i */ - /* 106 */ ED_INSERT, /* j */ - /* 107 */ ED_INSERT, /* k */ - /* 108 */ ED_INSERT, /* l */ - /* 109 */ ED_INSERT, /* m */ - /* 110 */ ED_INSERT, /* n */ - /* 111 */ ED_INSERT, /* o */ - /* 112 */ ED_INSERT, /* p */ - /* 113 */ ED_INSERT, /* q */ - /* 114 */ ED_INSERT, /* r */ - /* 115 */ ED_INSERT, /* s */ - /* 116 */ ED_INSERT, /* t */ - /* 117 */ ED_INSERT, /* u */ - /* 118 */ ED_INSERT, /* v */ - /* 119 */ ED_INSERT, /* w */ - /* 120 */ ED_INSERT, /* x */ - /* 121 */ ED_INSERT, /* y */ - /* 122 */ ED_INSERT, /* z */ - /* 123 */ ED_INSERT, /* { */ - /* 124 */ ED_INSERT, /* | */ - /* 125 */ ED_INSERT, /* } */ - /* 126 */ ED_INSERT, /* ~ */ - /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */ - /* 128 */ ED_UNASSIGNED, /* M-^@ */ - /* 129 */ ED_UNASSIGNED, /* M-^A */ - /* 130 */ ED_UNASSIGNED, /* M-^B */ - /* 131 */ ED_UNASSIGNED, /* M-^C */ - /* 132 */ ED_UNASSIGNED, /* M-^D */ - /* 133 */ ED_UNASSIGNED, /* M-^E */ - /* 134 */ ED_UNASSIGNED, /* M-^F */ - /* 135 */ ED_UNASSIGNED, /* M-^G */ - /* 136 */ ED_UNASSIGNED, /* M-^H */ - /* 137 */ ED_UNASSIGNED, /* M-^I */ - /* 138 */ ED_UNASSIGNED, /* M-^J */ - /* 139 */ ED_UNASSIGNED, /* M-^K */ - /* 140 */ ED_UNASSIGNED, /* M-^L */ - /* 141 */ ED_UNASSIGNED, /* M-^M */ - /* 142 */ ED_UNASSIGNED, /* M-^N */ - /* 143 */ ED_UNASSIGNED, /* M-^O */ - /* 144 */ ED_UNASSIGNED, /* M-^P */ - /* 145 */ ED_UNASSIGNED, /* M-^Q */ - /* 146 */ ED_UNASSIGNED, /* M-^R */ - /* 147 */ ED_UNASSIGNED, /* M-^S */ - /* 148 */ ED_UNASSIGNED, /* M-^T */ - /* 149 */ ED_UNASSIGNED, /* M-^U */ - /* 150 */ ED_UNASSIGNED, /* M-^V */ - /* 151 */ ED_UNASSIGNED, /* M-^W */ - /* 152 */ ED_UNASSIGNED, /* M-^X */ - /* 153 */ ED_UNASSIGNED, /* M-^Y */ - /* 154 */ ED_UNASSIGNED, /* M-^Z */ - /* 155 */ ED_UNASSIGNED, /* M-^[ */ - /* 156 */ ED_UNASSIGNED, /* M-^\ */ - /* 157 */ ED_UNASSIGNED, /* M-^] */ - /* 158 */ ED_UNASSIGNED, /* M-^^ */ - /* 159 */ ED_UNASSIGNED, /* M-^_ */ - /* 160 */ ED_UNASSIGNED, /* M-SPACE */ - /* 161 */ ED_UNASSIGNED, /* M-! */ - /* 162 */ ED_UNASSIGNED, /* M-" */ - /* 163 */ ED_UNASSIGNED, /* M-# */ - /* 164 */ ED_UNASSIGNED, /* M-$ */ - /* 165 */ ED_UNASSIGNED, /* M-% */ - /* 166 */ ED_UNASSIGNED, /* M-& */ - /* 167 */ ED_UNASSIGNED, /* M-' */ - /* 168 */ ED_UNASSIGNED, /* M-( */ - /* 169 */ ED_UNASSIGNED, /* M-) */ - /* 170 */ ED_UNASSIGNED, /* M-* */ - /* 171 */ ED_UNASSIGNED, /* M-+ */ - /* 172 */ ED_UNASSIGNED, /* M-, */ - /* 173 */ ED_UNASSIGNED, /* M-- */ - /* 174 */ ED_UNASSIGNED, /* M-. */ - /* 175 */ ED_UNASSIGNED, /* M-/ */ - /* 176 */ ED_UNASSIGNED, /* M-0 */ - /* 177 */ ED_UNASSIGNED, /* M-1 */ - /* 178 */ ED_UNASSIGNED, /* M-2 */ - /* 179 */ ED_UNASSIGNED, /* M-3 */ - /* 180 */ ED_UNASSIGNED, /* M-4 */ - /* 181 */ ED_UNASSIGNED, /* M-5 */ - /* 182 */ ED_UNASSIGNED, /* M-6 */ - /* 183 */ ED_UNASSIGNED, /* M-7 */ - /* 184 */ ED_UNASSIGNED, /* M-8 */ - /* 185 */ ED_UNASSIGNED, /* M-9 */ - /* 186 */ ED_UNASSIGNED, /* M-: */ - /* 187 */ ED_UNASSIGNED, /* M-; */ - /* 188 */ ED_UNASSIGNED, /* M-< */ - /* 189 */ ED_UNASSIGNED, /* M-= */ - /* 190 */ ED_UNASSIGNED, /* M-> */ - /* 191 */ ED_UNASSIGNED, /* M-? */ - /* 192 */ ED_UNASSIGNED, /* M-@ */ - /* 193 */ ED_UNASSIGNED, /* M-A */ - /* 194 */ ED_UNASSIGNED, /* M-B */ - /* 195 */ ED_UNASSIGNED, /* M-C */ - /* 196 */ ED_UNASSIGNED, /* M-D */ - /* 197 */ ED_UNASSIGNED, /* M-E */ - /* 198 */ ED_UNASSIGNED, /* M-F */ - /* 199 */ ED_UNASSIGNED, /* M-G */ - /* 200 */ ED_UNASSIGNED, /* M-H */ - /* 201 */ ED_UNASSIGNED, /* M-I */ - /* 202 */ ED_UNASSIGNED, /* M-J */ - /* 203 */ ED_UNASSIGNED, /* M-K */ - /* 204 */ ED_UNASSIGNED, /* M-L */ - /* 205 */ ED_UNASSIGNED, /* M-M */ - /* 206 */ ED_UNASSIGNED, /* M-N */ - /* 207 */ ED_UNASSIGNED, /* M-O */ - /* 208 */ ED_UNASSIGNED, /* M-P */ - /* 209 */ ED_UNASSIGNED, /* M-Q */ - /* 210 */ ED_UNASSIGNED, /* M-R */ - /* 211 */ ED_UNASSIGNED, /* M-S */ - /* 212 */ ED_UNASSIGNED, /* M-T */ - /* 213 */ ED_UNASSIGNED, /* M-U */ - /* 214 */ ED_UNASSIGNED, /* M-V */ - /* 215 */ ED_UNASSIGNED, /* M-W */ - /* 216 */ ED_UNASSIGNED, /* M-X */ - /* 217 */ ED_UNASSIGNED, /* M-Y */ - /* 218 */ ED_UNASSIGNED, /* M-Z */ - /* 219 */ ED_UNASSIGNED, /* M-[ */ - /* 220 */ ED_UNASSIGNED, /* M-\ */ - /* 221 */ ED_UNASSIGNED, /* M-] */ - /* 222 */ ED_UNASSIGNED, /* M-^ */ - /* 223 */ ED_UNASSIGNED, /* M-_ */ - /* 224 */ ED_UNASSIGNED, /* M-` */ - /* 225 */ ED_UNASSIGNED, /* M-a */ - /* 226 */ ED_UNASSIGNED, /* M-b */ - /* 227 */ ED_UNASSIGNED, /* M-c */ - /* 228 */ ED_UNASSIGNED, /* M-d */ - /* 229 */ ED_UNASSIGNED, /* M-e */ - /* 230 */ ED_UNASSIGNED, /* M-f */ - /* 231 */ ED_UNASSIGNED, /* M-g */ - /* 232 */ ED_UNASSIGNED, /* M-h */ - /* 233 */ ED_UNASSIGNED, /* M-i */ - /* 234 */ ED_UNASSIGNED, /* M-j */ - /* 235 */ ED_UNASSIGNED, /* M-k */ - /* 236 */ ED_UNASSIGNED, /* M-l */ - /* 237 */ ED_UNASSIGNED, /* M-m */ - /* 238 */ ED_UNASSIGNED, /* M-n */ - /* 239 */ ED_UNASSIGNED, /* M-o */ - /* 240 */ ED_UNASSIGNED, /* M-p */ - /* 241 */ ED_UNASSIGNED, /* M-q */ - /* 242 */ ED_UNASSIGNED, /* M-r */ - /* 243 */ ED_UNASSIGNED, /* M-s */ - /* 244 */ ED_UNASSIGNED, /* M-t */ - /* 245 */ ED_UNASSIGNED, /* M-u */ - /* 246 */ ED_UNASSIGNED, /* M-v */ - /* 247 */ ED_UNASSIGNED, /* M-w */ - /* 248 */ ED_UNASSIGNED, /* M-x */ - /* 249 */ ED_UNASSIGNED, /* M-y */ - /* 250 */ ED_UNASSIGNED, /* M-z */ - /* 251 */ ED_UNASSIGNED, /* M-{ */ - /* 252 */ ED_UNASSIGNED, /* M-| */ - /* 253 */ ED_UNASSIGNED, /* M-} */ - /* 254 */ ED_UNASSIGNED, /* M-~ */ - /* 255 */ ED_UNASSIGNED /* M-^? */ + /* 32 */ ED_INSERT, /* SPACE */ + /* 33 */ ED_INSERT, /* ! */ + /* 34 */ ED_INSERT, /* " */ + /* 35 */ ED_INSERT, /* # */ + /* 36 */ ED_INSERT, /* $ */ + /* 37 */ ED_INSERT, /* % */ + /* 38 */ ED_INSERT, /* & */ + /* 39 */ ED_INSERT, /* ' */ + /* 40 */ ED_INSERT, /* ( */ + /* 41 */ ED_INSERT, /* ) */ + /* 42 */ ED_INSERT, /* * */ + /* 43 */ ED_INSERT, /* + */ + /* 44 */ ED_INSERT, /* , */ + /* 45 */ ED_INSERT, /* - */ + /* 46 */ ED_INSERT, /* . */ + /* 47 */ ED_INSERT, /* / */ + /* 48 */ ED_INSERT, /* 0 */ + /* 49 */ ED_INSERT, /* 1 */ + /* 50 */ ED_INSERT, /* 2 */ + /* 51 */ ED_INSERT, /* 3 */ + /* 52 */ ED_INSERT, /* 4 */ + /* 53 */ ED_INSERT, /* 5 */ + /* 54 */ ED_INSERT, /* 6 */ + /* 55 */ ED_INSERT, /* 7 */ + /* 56 */ ED_INSERT, /* 8 */ + /* 57 */ ED_INSERT, /* 9 */ + /* 58 */ ED_INSERT, /* : */ + /* 59 */ ED_INSERT, /* ; */ + /* 60 */ ED_INSERT, /* < */ + /* 61 */ ED_INSERT, /* = */ + /* 62 */ ED_INSERT, /* > */ + /* 63 */ ED_INSERT, /* ? */ + /* 64 */ ED_INSERT, /* @ */ + /* 65 */ ED_INSERT, /* A */ + /* 66 */ ED_INSERT, /* B */ + /* 67 */ ED_INSERT, /* C */ + /* 68 */ ED_INSERT, /* D */ + /* 69 */ ED_INSERT, /* E */ + /* 70 */ ED_INSERT, /* F */ + /* 71 */ ED_INSERT, /* G */ + /* 72 */ ED_INSERT, /* H */ + /* 73 */ ED_INSERT, /* I */ + /* 74 */ ED_INSERT, /* J */ + /* 75 */ ED_INSERT, /* K */ + /* 76 */ ED_INSERT, /* L */ + /* 77 */ ED_INSERT, /* M */ + /* 78 */ ED_INSERT, /* N */ + /* 79 */ ED_INSERT, /* O */ + /* 80 */ ED_INSERT, /* P */ + /* 81 */ ED_INSERT, /* Q */ + /* 82 */ ED_INSERT, /* R */ + /* 83 */ ED_INSERT, /* S */ + /* 84 */ ED_INSERT, /* T */ + /* 85 */ ED_INSERT, /* U */ + /* 86 */ ED_INSERT, /* V */ + /* 87 */ ED_INSERT, /* W */ + /* 88 */ ED_INSERT, /* X */ + /* 89 */ ED_INSERT, /* Y */ + /* 90 */ ED_INSERT, /* Z */ + /* 91 */ ED_INSERT, /* [ */ + /* 92 */ ED_INSERT, /* \ */ + /* 93 */ ED_INSERT, /* ] */ + /* 94 */ ED_INSERT, /* ^ */ + /* 95 */ ED_INSERT, /* _ */ + /* 96 */ ED_INSERT, /* ` */ + /* 97 */ ED_INSERT, /* a */ + /* 98 */ ED_INSERT, /* b */ + /* 99 */ ED_INSERT, /* c */ + /* 100 */ ED_INSERT, /* d */ + /* 101 */ ED_INSERT, /* e */ + /* 102 */ ED_INSERT, /* f */ + /* 103 */ ED_INSERT, /* g */ + /* 104 */ ED_INSERT, /* h */ + /* 105 */ ED_INSERT, /* i */ + /* 106 */ ED_INSERT, /* j */ + /* 107 */ ED_INSERT, /* k */ + /* 108 */ ED_INSERT, /* l */ + /* 109 */ ED_INSERT, /* m */ + /* 110 */ ED_INSERT, /* n */ + /* 111 */ ED_INSERT, /* o */ + /* 112 */ ED_INSERT, /* p */ + /* 113 */ ED_INSERT, /* q */ + /* 114 */ ED_INSERT, /* r */ + /* 115 */ ED_INSERT, /* s */ + /* 116 */ ED_INSERT, /* t */ + /* 117 */ ED_INSERT, /* u */ + /* 118 */ ED_INSERT, /* v */ + /* 119 */ ED_INSERT, /* w */ + /* 120 */ ED_INSERT, /* x */ + /* 121 */ ED_INSERT, /* y */ + /* 122 */ ED_INSERT, /* z */ + /* 123 */ ED_INSERT, /* { */ + /* 124 */ ED_INSERT, /* | */ + /* 125 */ ED_INSERT, /* } */ + /* 126 */ ED_INSERT, /* ~ */ + /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */ + /* 128 */ ED_UNASSIGNED, /* M-^@ */ + /* 129 */ ED_UNASSIGNED, /* M-^A */ + /* 130 */ ED_UNASSIGNED, /* M-^B */ + /* 131 */ ED_UNASSIGNED, /* M-^C */ + /* 132 */ ED_UNASSIGNED, /* M-^D */ + /* 133 */ ED_UNASSIGNED, /* M-^E */ + /* 134 */ ED_UNASSIGNED, /* M-^F */ + /* 135 */ ED_UNASSIGNED, /* M-^G */ + /* 136 */ ED_UNASSIGNED, /* M-^H */ + /* 137 */ ED_UNASSIGNED, /* M-^I */ + /* 138 */ ED_UNASSIGNED, /* M-^J */ + /* 139 */ ED_UNASSIGNED, /* M-^K */ + /* 140 */ ED_UNASSIGNED, /* M-^L */ + /* 141 */ ED_UNASSIGNED, /* M-^M */ + /* 142 */ ED_UNASSIGNED, /* M-^N */ + /* 143 */ ED_UNASSIGNED, /* M-^O */ + /* 144 */ ED_UNASSIGNED, /* M-^P */ + /* 145 */ ED_UNASSIGNED, /* M-^Q */ + /* 146 */ ED_UNASSIGNED, /* M-^R */ + /* 147 */ ED_UNASSIGNED, /* M-^S */ + /* 148 */ ED_UNASSIGNED, /* M-^T */ + /* 149 */ ED_UNASSIGNED, /* M-^U */ + /* 150 */ ED_UNASSIGNED, /* M-^V */ + /* 151 */ ED_UNASSIGNED, /* M-^W */ + /* 152 */ ED_UNASSIGNED, /* M-^X */ + /* 153 */ ED_UNASSIGNED, /* M-^Y */ + /* 154 */ ED_UNASSIGNED, /* M-^Z */ + /* 155 */ ED_UNASSIGNED, /* M-^[ */ + /* 156 */ ED_UNASSIGNED, /* M-^\ */ + /* 157 */ ED_UNASSIGNED, /* M-^] */ + /* 158 */ ED_UNASSIGNED, /* M-^^ */ + /* 159 */ ED_UNASSIGNED, /* M-^_ */ + /* 160 */ ED_UNASSIGNED, /* M-SPACE */ + /* 161 */ ED_UNASSIGNED, /* M-! */ + /* 162 */ ED_UNASSIGNED, /* M-" */ + /* 163 */ ED_UNASSIGNED, /* M-# */ + /* 164 */ ED_UNASSIGNED, /* M-$ */ + /* 165 */ ED_UNASSIGNED, /* M-% */ + /* 166 */ ED_UNASSIGNED, /* M-& */ + /* 167 */ ED_UNASSIGNED, /* M-' */ + /* 168 */ ED_UNASSIGNED, /* M-( */ + /* 169 */ ED_UNASSIGNED, /* M-) */ + /* 170 */ ED_UNASSIGNED, /* M-* */ + /* 171 */ ED_UNASSIGNED, /* M-+ */ + /* 172 */ ED_UNASSIGNED, /* M-, */ + /* 173 */ ED_UNASSIGNED, /* M-- */ + /* 174 */ ED_UNASSIGNED, /* M-. */ + /* 175 */ ED_UNASSIGNED, /* M-/ */ + /* 176 */ ED_UNASSIGNED, /* M-0 */ + /* 177 */ ED_UNASSIGNED, /* M-1 */ + /* 178 */ ED_UNASSIGNED, /* M-2 */ + /* 179 */ ED_UNASSIGNED, /* M-3 */ + /* 180 */ ED_UNASSIGNED, /* M-4 */ + /* 181 */ ED_UNASSIGNED, /* M-5 */ + /* 182 */ ED_UNASSIGNED, /* M-6 */ + /* 183 */ ED_UNASSIGNED, /* M-7 */ + /* 184 */ ED_UNASSIGNED, /* M-8 */ + /* 185 */ ED_UNASSIGNED, /* M-9 */ + /* 186 */ ED_UNASSIGNED, /* M-: */ + /* 187 */ ED_UNASSIGNED, /* M-; */ + /* 188 */ ED_UNASSIGNED, /* M-< */ + /* 189 */ ED_UNASSIGNED, /* M-= */ + /* 190 */ ED_UNASSIGNED, /* M-> */ + /* 191 */ ED_UNASSIGNED, /* M-? */ + /* 192 */ ED_UNASSIGNED, /* M-@ */ + /* 193 */ ED_UNASSIGNED, /* M-A */ + /* 194 */ ED_UNASSIGNED, /* M-B */ + /* 195 */ ED_UNASSIGNED, /* M-C */ + /* 196 */ ED_UNASSIGNED, /* M-D */ + /* 197 */ ED_UNASSIGNED, /* M-E */ + /* 198 */ ED_UNASSIGNED, /* M-F */ + /* 199 */ ED_UNASSIGNED, /* M-G */ + /* 200 */ ED_UNASSIGNED, /* M-H */ + /* 201 */ ED_UNASSIGNED, /* M-I */ + /* 202 */ ED_UNASSIGNED, /* M-J */ + /* 203 */ ED_UNASSIGNED, /* M-K */ + /* 204 */ ED_UNASSIGNED, /* M-L */ + /* 205 */ ED_UNASSIGNED, /* M-M */ + /* 206 */ ED_UNASSIGNED, /* M-N */ + /* 207 */ ED_UNASSIGNED, /* M-O */ + /* 208 */ ED_UNASSIGNED, /* M-P */ + /* 209 */ ED_UNASSIGNED, /* M-Q */ + /* 210 */ ED_UNASSIGNED, /* M-R */ + /* 211 */ ED_UNASSIGNED, /* M-S */ + /* 212 */ ED_UNASSIGNED, /* M-T */ + /* 213 */ ED_UNASSIGNED, /* M-U */ + /* 214 */ ED_UNASSIGNED, /* M-V */ + /* 215 */ ED_UNASSIGNED, /* M-W */ + /* 216 */ ED_UNASSIGNED, /* M-X */ + /* 217 */ ED_UNASSIGNED, /* M-Y */ + /* 218 */ ED_UNASSIGNED, /* M-Z */ + /* 219 */ ED_UNASSIGNED, /* M-[ */ + /* 220 */ ED_UNASSIGNED, /* M-\ */ + /* 221 */ ED_UNASSIGNED, /* M-] */ + /* 222 */ ED_UNASSIGNED, /* M-^ */ + /* 223 */ ED_UNASSIGNED, /* M-_ */ + /* 224 */ ED_UNASSIGNED, /* M-` */ + /* 225 */ ED_UNASSIGNED, /* M-a */ + /* 226 */ ED_UNASSIGNED, /* M-b */ + /* 227 */ ED_UNASSIGNED, /* M-c */ + /* 228 */ ED_UNASSIGNED, /* M-d */ + /* 229 */ ED_UNASSIGNED, /* M-e */ + /* 230 */ ED_UNASSIGNED, /* M-f */ + /* 231 */ ED_UNASSIGNED, /* M-g */ + /* 232 */ ED_UNASSIGNED, /* M-h */ + /* 233 */ ED_UNASSIGNED, /* M-i */ + /* 234 */ ED_UNASSIGNED, /* M-j */ + /* 235 */ ED_UNASSIGNED, /* M-k */ + /* 236 */ ED_UNASSIGNED, /* M-l */ + /* 237 */ ED_UNASSIGNED, /* M-m */ + /* 238 */ ED_UNASSIGNED, /* M-n */ + /* 239 */ ED_UNASSIGNED, /* M-o */ + /* 240 */ ED_UNASSIGNED, /* M-p */ + /* 241 */ ED_UNASSIGNED, /* M-q */ + /* 242 */ ED_UNASSIGNED, /* M-r */ + /* 243 */ ED_UNASSIGNED, /* M-s */ + /* 244 */ ED_UNASSIGNED, /* M-t */ + /* 245 */ ED_UNASSIGNED, /* M-u */ + /* 246 */ ED_UNASSIGNED, /* M-v */ + /* 247 */ ED_UNASSIGNED, /* M-w */ + /* 248 */ ED_UNASSIGNED, /* M-x */ + /* 249 */ ED_UNASSIGNED, /* M-y */ + /* 250 */ ED_UNASSIGNED, /* M-z */ + /* 251 */ ED_UNASSIGNED, /* M-{ */ + /* 252 */ ED_UNASSIGNED, /* M-| */ + /* 253 */ ED_UNASSIGNED, /* M-} */ + /* 254 */ ED_UNASSIGNED, /* M-~ */ + /* 255 */ ED_UNASSIGNED /* M-^? */ }; -private el_action_t el_map_vi_command[] = { - /* 0 */ ED_UNASSIGNED, /* ^@ */ - /* 1 */ ED_MOVE_TO_BEG, /* ^A */ - /* 2 */ ED_UNASSIGNED, /* ^B */ - /* 3 */ ED_TTY_SIGINT, /* ^C */ - /* 4 */ ED_UNASSIGNED, /* ^D */ - /* 5 */ ED_MOVE_TO_END, /* ^E */ - /* 6 */ ED_UNASSIGNED, /* ^F */ - /* 7 */ ED_UNASSIGNED, /* ^G */ - /* 8 */ ED_PREV_CHAR, /* ^H */ - /* 9 */ ED_UNASSIGNED, /* ^I */ - /* 10 */ ED_NEWLINE, /* ^J */ - /* 11 */ ED_KILL_LINE, /* ^K */ - /* 12 */ ED_CLEAR_SCREEN, /* ^L */ - /* 13 */ ED_NEWLINE, /* ^M */ - /* 14 */ ED_NEXT_HISTORY, /* ^N */ - /* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */ - /* 16 */ ED_PREV_HISTORY, /* ^P */ - /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */ - /* 18 */ ED_REDISPLAY, /* ^R */ - /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */ - /* 20 */ ED_UNASSIGNED, /* ^T */ - /* 21 */ VI_KILL_LINE_PREV, /* ^U */ - /* 22 */ ED_UNASSIGNED, /* ^V */ - /* 23 */ ED_DELETE_PREV_WORD, /* ^W */ - /* 24 */ ED_UNASSIGNED, /* ^X */ - /* 25 */ ED_UNASSIGNED, /* ^Y */ - /* 26 */ ED_UNASSIGNED, /* ^Z */ - /* 27 */ EM_META_NEXT, /* ^[ */ - /* 28 */ ED_TTY_SIGQUIT, /* ^\ */ - /* 29 */ ED_UNASSIGNED, /* ^] */ - /* 30 */ ED_UNASSIGNED, /* ^^ */ - /* 31 */ ED_UNASSIGNED, /* ^_ */ - /* 32 */ ED_NEXT_CHAR, /* SPACE */ - /* 33 */ ED_UNASSIGNED, /* ! */ - /* 34 */ ED_UNASSIGNED, /* " */ - /* 35 */ ED_UNASSIGNED, /* # */ - /* 36 */ ED_MOVE_TO_END, /* $ */ - /* 37 */ ED_UNASSIGNED, /* % */ - /* 38 */ ED_UNASSIGNED, /* & */ - /* 39 */ ED_UNASSIGNED, /* ' */ - /* 40 */ ED_UNASSIGNED, /* ( */ - /* 41 */ ED_UNASSIGNED, /* ) */ - /* 42 */ ED_UNASSIGNED, /* * */ - /* 43 */ ED_NEXT_HISTORY, /* + */ - /* 44 */ VI_REPEAT_PREV_CHAR, /* , */ - /* 45 */ ED_PREV_HISTORY, /* - */ - /* 46 */ ED_UNASSIGNED, /* . */ - /* 47 */ VI_SEARCH_PREV, /* / */ - /* 48 */ VI_ZERO, /* 0 */ - /* 49 */ ED_ARGUMENT_DIGIT, /* 1 */ - /* 50 */ ED_ARGUMENT_DIGIT, /* 2 */ - /* 51 */ ED_ARGUMENT_DIGIT, /* 3 */ - /* 52 */ ED_ARGUMENT_DIGIT, /* 4 */ - /* 53 */ ED_ARGUMENT_DIGIT, /* 5 */ - /* 54 */ ED_ARGUMENT_DIGIT, /* 6 */ - /* 55 */ ED_ARGUMENT_DIGIT, /* 7 */ - /* 56 */ ED_ARGUMENT_DIGIT, /* 8 */ - /* 57 */ ED_ARGUMENT_DIGIT, /* 9 */ - /* 58 */ ED_COMMAND, /* : */ - /* 59 */ VI_REPEAT_NEXT_CHAR, /* ; */ - /* 60 */ ED_UNASSIGNED, /* < */ - /* 61 */ ED_UNASSIGNED, /* = */ - /* 62 */ ED_UNASSIGNED, /* > */ - /* 63 */ VI_SEARCH_NEXT, /* ? */ - /* 64 */ ED_UNASSIGNED, /* @ */ - /* 65 */ VI_ADD_AT_EOL, /* A */ - /* 66 */ VI_PREV_SPACE_WORD, /* B */ - /* 67 */ VI_CHANGE_TO_EOL, /* C */ - /* 68 */ ED_KILL_LINE, /* D */ - /* 69 */ VI_TO_END_WORD, /* E */ - /* 70 */ VI_PREV_CHAR, /* F */ - /* 71 */ ED_UNASSIGNED, /* G */ - /* 72 */ ED_UNASSIGNED, /* H */ - /* 73 */ VI_INSERT_AT_BOL, /* I */ - /* 74 */ ED_SEARCH_NEXT_HISTORY, /* J */ - /* 75 */ ED_SEARCH_PREV_HISTORY, /* K */ - /* 76 */ ED_UNASSIGNED, /* L */ - /* 77 */ ED_UNASSIGNED, /* M */ - /* 78 */ VI_REPEAT_SEARCH_PREV, /* N */ - /* 79 */ ED_SEQUENCE_LEAD_IN, /* O */ - /* 80 */ VI_PASTE_PREV, /* P */ - /* 81 */ ED_UNASSIGNED, /* Q */ - /* 82 */ VI_REPLACE_MODE, /* R */ - /* 83 */ VI_SUBSTITUTE_LINE, /* S */ - /* 84 */ VI_TO_PREV_CHAR, /* T */ - /* 85 */ ED_UNASSIGNED, /* U */ - /* 86 */ ED_UNASSIGNED, /* V */ - /* 87 */ VI_NEXT_SPACE_WORD, /* W */ - /* 88 */ ED_DELETE_PREV_CHAR, /* X */ - /* 89 */ ED_UNASSIGNED, /* Y */ - /* 90 */ ED_UNASSIGNED, /* Z */ - /* 91 */ ED_SEQUENCE_LEAD_IN, /* [ */ - /* 92 */ ED_UNASSIGNED, /* \ */ - /* 93 */ ED_UNASSIGNED, /* ] */ - /* 94 */ ED_MOVE_TO_BEG, /* ^ */ - /* 95 */ ED_UNASSIGNED, /* _ */ - /* 96 */ ED_UNASSIGNED, /* ` */ - /* 97 */ VI_ADD, /* a */ - /* 98 */ VI_PREV_WORD, /* b */ - /* 99 */ VI_CHANGE_META, /* c */ - /* 100 */ VI_DELETE_META, /* d */ - /* 101 */ VI_END_WORD, /* e */ - /* 102 */ VI_NEXT_CHAR, /* f */ - /* 103 */ ED_UNASSIGNED, /* g */ - /* 104 */ ED_PREV_CHAR, /* h */ - /* 105 */ VI_INSERT, /* i */ - /* 106 */ ED_NEXT_HISTORY, /* j */ - /* 107 */ ED_PREV_HISTORY, /* k */ - /* 108 */ ED_NEXT_CHAR, /* l */ - /* 109 */ ED_UNASSIGNED, /* m */ - /* 110 */ VI_REPEAT_SEARCH_NEXT, /* n */ - /* 111 */ ED_UNASSIGNED, /* o */ - /* 112 */ VI_PASTE_NEXT, /* p */ - /* 113 */ ED_UNASSIGNED, /* q */ - /* 114 */ VI_REPLACE_CHAR, /* r */ - /* 115 */ VI_SUBSTITUTE_CHAR, /* s */ - /* 116 */ VI_TO_NEXT_CHAR, /* t */ - /* 117 */ VI_UNDO, /* u */ - /* 118 */ ED_UNASSIGNED, /* v */ - /* 119 */ VI_NEXT_WORD, /* w */ - /* 120 */ ED_DELETE_NEXT_CHAR, /* x */ - /* 121 */ ED_UNASSIGNED, /* y */ - /* 122 */ ED_UNASSIGNED, /* z */ - /* 123 */ ED_UNASSIGNED, /* { */ - /* 124 */ ED_UNASSIGNED, /* | */ - /* 125 */ ED_UNASSIGNED, /* } */ - /* 126 */ VI_CHANGE_CASE, /* ~ */ - /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */ - /* 128 */ ED_UNASSIGNED, /* M-^@ */ - /* 129 */ ED_UNASSIGNED, /* M-^A */ - /* 130 */ ED_UNASSIGNED, /* M-^B */ - /* 131 */ ED_UNASSIGNED, /* M-^C */ - /* 132 */ ED_UNASSIGNED, /* M-^D */ - /* 133 */ ED_UNASSIGNED, /* M-^E */ - /* 134 */ ED_UNASSIGNED, /* M-^F */ - /* 135 */ ED_UNASSIGNED, /* M-^G */ - /* 136 */ ED_UNASSIGNED, /* M-^H */ - /* 137 */ ED_UNASSIGNED, /* M-^I */ - /* 138 */ ED_UNASSIGNED, /* M-^J */ - /* 139 */ ED_UNASSIGNED, /* M-^K */ - /* 140 */ ED_UNASSIGNED, /* M-^L */ - /* 141 */ ED_UNASSIGNED, /* M-^M */ - /* 142 */ ED_UNASSIGNED, /* M-^N */ - /* 143 */ ED_UNASSIGNED, /* M-^O */ - /* 144 */ ED_UNASSIGNED, /* M-^P */ - /* 145 */ ED_UNASSIGNED, /* M-^Q */ - /* 146 */ ED_UNASSIGNED, /* M-^R */ - /* 147 */ ED_UNASSIGNED, /* M-^S */ - /* 148 */ ED_UNASSIGNED, /* M-^T */ - /* 149 */ ED_UNASSIGNED, /* M-^U */ - /* 150 */ ED_UNASSIGNED, /* M-^V */ - /* 151 */ ED_UNASSIGNED, /* M-^W */ - /* 152 */ ED_UNASSIGNED, /* M-^X */ - /* 153 */ ED_UNASSIGNED, /* M-^Y */ - /* 154 */ ED_UNASSIGNED, /* M-^Z */ - /* 155 */ ED_UNASSIGNED, /* M-^[ */ - /* 156 */ ED_UNASSIGNED, /* M-^\ */ - /* 157 */ ED_UNASSIGNED, /* M-^] */ - /* 158 */ ED_UNASSIGNED, /* M-^^ */ - /* 159 */ ED_UNASSIGNED, /* M-^_ */ - /* 160 */ ED_UNASSIGNED, /* M-SPACE */ - /* 161 */ ED_UNASSIGNED, /* M-! */ - /* 162 */ ED_UNASSIGNED, /* M-" */ - /* 163 */ ED_UNASSIGNED, /* M-# */ - /* 164 */ ED_UNASSIGNED, /* M-$ */ - /* 165 */ ED_UNASSIGNED, /* M-% */ - /* 166 */ ED_UNASSIGNED, /* M-& */ - /* 167 */ ED_UNASSIGNED, /* M-' */ - /* 168 */ ED_UNASSIGNED, /* M-( */ - /* 169 */ ED_UNASSIGNED, /* M-) */ - /* 170 */ ED_UNASSIGNED, /* M-* */ - /* 171 */ ED_UNASSIGNED, /* M-+ */ - /* 172 */ ED_UNASSIGNED, /* M-, */ - /* 173 */ ED_UNASSIGNED, /* M-- */ - /* 174 */ ED_UNASSIGNED, /* M-. */ - /* 175 */ ED_UNASSIGNED, /* M-/ */ - /* 176 */ ED_UNASSIGNED, /* M-0 */ - /* 177 */ ED_UNASSIGNED, /* M-1 */ - /* 178 */ ED_UNASSIGNED, /* M-2 */ - /* 179 */ ED_UNASSIGNED, /* M-3 */ - /* 180 */ ED_UNASSIGNED, /* M-4 */ - /* 181 */ ED_UNASSIGNED, /* M-5 */ - /* 182 */ ED_UNASSIGNED, /* M-6 */ - /* 183 */ ED_UNASSIGNED, /* M-7 */ - /* 184 */ ED_UNASSIGNED, /* M-8 */ - /* 185 */ ED_UNASSIGNED, /* M-9 */ - /* 186 */ ED_UNASSIGNED, /* M-: */ - /* 187 */ ED_UNASSIGNED, /* M-; */ - /* 188 */ ED_UNASSIGNED, /* M-< */ - /* 189 */ ED_UNASSIGNED, /* M-= */ - /* 190 */ ED_UNASSIGNED, /* M-> */ - /* 191 */ ED_UNASSIGNED, /* M-? */ - /* 192 */ ED_UNASSIGNED, /* M-@ */ - /* 193 */ ED_UNASSIGNED, /* M-A */ - /* 194 */ ED_UNASSIGNED, /* M-B */ - /* 195 */ ED_UNASSIGNED, /* M-C */ - /* 196 */ ED_UNASSIGNED, /* M-D */ - /* 197 */ ED_UNASSIGNED, /* M-E */ - /* 198 */ ED_UNASSIGNED, /* M-F */ - /* 199 */ ED_UNASSIGNED, /* M-G */ - /* 200 */ ED_UNASSIGNED, /* M-H */ - /* 201 */ ED_UNASSIGNED, /* M-I */ - /* 202 */ ED_UNASSIGNED, /* M-J */ - /* 203 */ ED_UNASSIGNED, /* M-K */ - /* 204 */ ED_UNASSIGNED, /* M-L */ - /* 205 */ ED_UNASSIGNED, /* M-M */ - /* 206 */ ED_UNASSIGNED, /* M-N */ - /* 207 */ ED_SEQUENCE_LEAD_IN, /* M-O */ - /* 208 */ ED_UNASSIGNED, /* M-P */ - /* 209 */ ED_UNASSIGNED, /* M-Q */ - /* 210 */ ED_UNASSIGNED, /* M-R */ - /* 211 */ ED_UNASSIGNED, /* M-S */ - /* 212 */ ED_UNASSIGNED, /* M-T */ - /* 213 */ ED_UNASSIGNED, /* M-U */ - /* 214 */ ED_UNASSIGNED, /* M-V */ - /* 215 */ ED_UNASSIGNED, /* M-W */ - /* 216 */ ED_UNASSIGNED, /* M-X */ - /* 217 */ ED_UNASSIGNED, /* M-Y */ - /* 218 */ ED_UNASSIGNED, /* M-Z */ - /* 219 */ ED_SEQUENCE_LEAD_IN, /* M-[ */ - /* 220 */ ED_UNASSIGNED, /* M-\ */ - /* 221 */ ED_UNASSIGNED, /* M-] */ - /* 222 */ ED_UNASSIGNED, /* M-^ */ - /* 223 */ ED_UNASSIGNED, /* M-_ */ - /* 224 */ ED_UNASSIGNED, /* M-` */ - /* 225 */ ED_UNASSIGNED, /* M-a */ - /* 226 */ ED_UNASSIGNED, /* M-b */ - /* 227 */ ED_UNASSIGNED, /* M-c */ - /* 228 */ ED_UNASSIGNED, /* M-d */ - /* 229 */ ED_UNASSIGNED, /* M-e */ - /* 230 */ ED_UNASSIGNED, /* M-f */ - /* 231 */ ED_UNASSIGNED, /* M-g */ - /* 232 */ ED_UNASSIGNED, /* M-h */ - /* 233 */ ED_UNASSIGNED, /* M-i */ - /* 234 */ ED_UNASSIGNED, /* M-j */ - /* 235 */ ED_UNASSIGNED, /* M-k */ - /* 236 */ ED_UNASSIGNED, /* M-l */ - /* 237 */ ED_UNASSIGNED, /* M-m */ - /* 238 */ ED_UNASSIGNED, /* M-n */ - /* 239 */ ED_UNASSIGNED, /* M-o */ - /* 240 */ ED_UNASSIGNED, /* M-p */ - /* 241 */ ED_UNASSIGNED, /* M-q */ - /* 242 */ ED_UNASSIGNED, /* M-r */ - /* 243 */ ED_UNASSIGNED, /* M-s */ - /* 244 */ ED_UNASSIGNED, /* M-t */ - /* 245 */ ED_UNASSIGNED, /* M-u */ - /* 246 */ ED_UNASSIGNED, /* M-v */ - /* 247 */ ED_UNASSIGNED, /* M-w */ - /* 248 */ ED_UNASSIGNED, /* M-x */ - /* 249 */ ED_UNASSIGNED, /* M-y */ - /* 250 */ ED_UNASSIGNED, /* M-z */ - /* 251 */ ED_UNASSIGNED, /* M-{ */ - /* 252 */ ED_UNASSIGNED, /* M-| */ - /* 253 */ ED_UNASSIGNED, /* M-} */ - /* 254 */ ED_UNASSIGNED, /* M-~ */ - /* 255 */ ED_UNASSIGNED /* M-^? */ +private const el_action_t el_map_vi_command[] = { + /* 0 */ ED_UNASSIGNED, /* ^@ */ + /* 1 */ ED_MOVE_TO_BEG, /* ^A */ + /* 2 */ ED_UNASSIGNED, /* ^B */ + /* 3 */ ED_TTY_SIGINT, /* ^C */ + /* 4 */ ED_UNASSIGNED, /* ^D */ + /* 5 */ ED_MOVE_TO_END, /* ^E */ + /* 6 */ ED_UNASSIGNED, /* ^F */ + /* 7 */ ED_UNASSIGNED, /* ^G */ + /* 8 */ ED_PREV_CHAR, /* ^H */ + /* 9 */ ED_UNASSIGNED, /* ^I */ + /* 10 */ ED_NEWLINE, /* ^J */ + /* 11 */ ED_KILL_LINE, /* ^K */ + /* 12 */ ED_CLEAR_SCREEN, /* ^L */ + /* 13 */ ED_NEWLINE, /* ^M */ + /* 14 */ ED_NEXT_HISTORY, /* ^N */ + /* 15 */ ED_TTY_FLUSH_OUTPUT, /* ^O */ + /* 16 */ ED_PREV_HISTORY, /* ^P */ + /* 17 */ ED_TTY_START_OUTPUT, /* ^Q */ + /* 18 */ ED_REDISPLAY, /* ^R */ + /* 19 */ ED_TTY_STOP_OUTPUT, /* ^S */ + /* 20 */ ED_UNASSIGNED, /* ^T */ + /* 21 */ VI_KILL_LINE_PREV, /* ^U */ + /* 22 */ ED_UNASSIGNED, /* ^V */ + /* 23 */ ED_DELETE_PREV_WORD, /* ^W */ + /* 24 */ ED_UNASSIGNED, /* ^X */ + /* 25 */ ED_UNASSIGNED, /* ^Y */ + /* 26 */ ED_UNASSIGNED, /* ^Z */ + /* 27 */ EM_META_NEXT, /* ^[ */ + /* 28 */ ED_TTY_SIGQUIT, /* ^\ */ + /* 29 */ ED_UNASSIGNED, /* ^] */ + /* 30 */ ED_UNASSIGNED, /* ^^ */ + /* 31 */ ED_UNASSIGNED, /* ^_ */ + /* 32 */ ED_NEXT_CHAR, /* SPACE */ + /* 33 */ ED_UNASSIGNED, /* ! */ + /* 34 */ ED_UNASSIGNED, /* " */ + /* 35 */ ED_UNASSIGNED, /* # */ + /* 36 */ ED_MOVE_TO_END, /* $ */ + /* 37 */ ED_UNASSIGNED, /* % */ + /* 38 */ ED_UNASSIGNED, /* & */ + /* 39 */ ED_UNASSIGNED, /* ' */ + /* 40 */ ED_UNASSIGNED, /* ( */ + /* 41 */ ED_UNASSIGNED, /* ) */ + /* 42 */ ED_UNASSIGNED, /* * */ + /* 43 */ ED_NEXT_HISTORY, /* + */ + /* 44 */ VI_REPEAT_PREV_CHAR, /* , */ + /* 45 */ ED_PREV_HISTORY, /* - */ + /* 46 */ ED_UNASSIGNED, /* . */ + /* 47 */ VI_SEARCH_PREV, /* / */ + /* 48 */ VI_ZERO, /* 0 */ + /* 49 */ ED_ARGUMENT_DIGIT, /* 1 */ + /* 50 */ ED_ARGUMENT_DIGIT, /* 2 */ + /* 51 */ ED_ARGUMENT_DIGIT, /* 3 */ + /* 52 */ ED_ARGUMENT_DIGIT, /* 4 */ + /* 53 */ ED_ARGUMENT_DIGIT, /* 5 */ + /* 54 */ ED_ARGUMENT_DIGIT, /* 6 */ + /* 55 */ ED_ARGUMENT_DIGIT, /* 7 */ + /* 56 */ ED_ARGUMENT_DIGIT, /* 8 */ + /* 57 */ ED_ARGUMENT_DIGIT, /* 9 */ + /* 58 */ ED_COMMAND, /* : */ + /* 59 */ VI_REPEAT_NEXT_CHAR, /* ; */ + /* 60 */ ED_UNASSIGNED, /* < */ + /* 61 */ ED_UNASSIGNED, /* = */ + /* 62 */ ED_UNASSIGNED, /* > */ + /* 63 */ VI_SEARCH_NEXT, /* ? */ + /* 64 */ ED_UNASSIGNED, /* @ */ + /* 65 */ VI_ADD_AT_EOL, /* A */ + /* 66 */ VI_PREV_SPACE_WORD, /* B */ + /* 67 */ VI_CHANGE_TO_EOL, /* C */ + /* 68 */ ED_KILL_LINE, /* D */ + /* 69 */ VI_TO_END_WORD, /* E */ + /* 70 */ VI_PREV_CHAR, /* F */ + /* 71 */ ED_UNASSIGNED, /* G */ + /* 72 */ ED_UNASSIGNED, /* H */ + /* 73 */ VI_INSERT_AT_BOL, /* I */ + /* 74 */ ED_SEARCH_NEXT_HISTORY, /* J */ + /* 75 */ ED_SEARCH_PREV_HISTORY, /* K */ + /* 76 */ ED_UNASSIGNED, /* L */ + /* 77 */ ED_UNASSIGNED, /* M */ + /* 78 */ VI_REPEAT_SEARCH_PREV, /* N */ + /* 79 */ ED_SEQUENCE_LEAD_IN, /* O */ + /* 80 */ VI_PASTE_PREV, /* P */ + /* 81 */ ED_UNASSIGNED, /* Q */ + /* 82 */ VI_REPLACE_MODE, /* R */ + /* 83 */ VI_SUBSTITUTE_LINE, /* S */ + /* 84 */ VI_TO_PREV_CHAR, /* T */ + /* 85 */ ED_UNASSIGNED, /* U */ + /* 86 */ ED_UNASSIGNED, /* V */ + /* 87 */ VI_NEXT_SPACE_WORD, /* W */ + /* 88 */ ED_DELETE_PREV_CHAR, /* X */ + /* 89 */ ED_UNASSIGNED, /* Y */ + /* 90 */ ED_UNASSIGNED, /* Z */ + /* 91 */ ED_SEQUENCE_LEAD_IN, /* [ */ + /* 92 */ ED_UNASSIGNED, /* \ */ + /* 93 */ ED_UNASSIGNED, /* ] */ + /* 94 */ ED_MOVE_TO_BEG, /* ^ */ + /* 95 */ ED_UNASSIGNED, /* _ */ + /* 96 */ ED_UNASSIGNED, /* ` */ + /* 97 */ VI_ADD, /* a */ + /* 98 */ VI_PREV_WORD, /* b */ + /* 99 */ VI_CHANGE_META, /* c */ + /* 100 */ VI_DELETE_META, /* d */ + /* 101 */ VI_END_WORD, /* e */ + /* 102 */ VI_NEXT_CHAR, /* f */ + /* 103 */ ED_UNASSIGNED, /* g */ + /* 104 */ ED_PREV_CHAR, /* h */ + /* 105 */ VI_INSERT, /* i */ + /* 106 */ ED_NEXT_HISTORY, /* j */ + /* 107 */ ED_PREV_HISTORY, /* k */ + /* 108 */ ED_NEXT_CHAR, /* l */ + /* 109 */ ED_UNASSIGNED, /* m */ + /* 110 */ VI_REPEAT_SEARCH_NEXT, /* n */ + /* 111 */ ED_UNASSIGNED, /* o */ + /* 112 */ VI_PASTE_NEXT, /* p */ + /* 113 */ ED_UNASSIGNED, /* q */ + /* 114 */ VI_REPLACE_CHAR, /* r */ + /* 115 */ VI_SUBSTITUTE_CHAR, /* s */ + /* 116 */ VI_TO_NEXT_CHAR, /* t */ + /* 117 */ VI_UNDO, /* u */ + /* 118 */ ED_UNASSIGNED, /* v */ + /* 119 */ VI_NEXT_WORD, /* w */ + /* 120 */ ED_DELETE_NEXT_CHAR, /* x */ + /* 121 */ ED_UNASSIGNED, /* y */ + /* 122 */ ED_UNASSIGNED, /* z */ + /* 123 */ ED_UNASSIGNED, /* { */ + /* 124 */ ED_UNASSIGNED, /* | */ + /* 125 */ ED_UNASSIGNED, /* } */ + /* 126 */ VI_CHANGE_CASE, /* ~ */ + /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */ + /* 128 */ ED_UNASSIGNED, /* M-^@ */ + /* 129 */ ED_UNASSIGNED, /* M-^A */ + /* 130 */ ED_UNASSIGNED, /* M-^B */ + /* 131 */ ED_UNASSIGNED, /* M-^C */ + /* 132 */ ED_UNASSIGNED, /* M-^D */ + /* 133 */ ED_UNASSIGNED, /* M-^E */ + /* 134 */ ED_UNASSIGNED, /* M-^F */ + /* 135 */ ED_UNASSIGNED, /* M-^G */ + /* 136 */ ED_UNASSIGNED, /* M-^H */ + /* 137 */ ED_UNASSIGNED, /* M-^I */ + /* 138 */ ED_UNASSIGNED, /* M-^J */ + /* 139 */ ED_UNASSIGNED, /* M-^K */ + /* 140 */ ED_UNASSIGNED, /* M-^L */ + /* 141 */ ED_UNASSIGNED, /* M-^M */ + /* 142 */ ED_UNASSIGNED, /* M-^N */ + /* 143 */ ED_UNASSIGNED, /* M-^O */ + /* 144 */ ED_UNASSIGNED, /* M-^P */ + /* 145 */ ED_UNASSIGNED, /* M-^Q */ + /* 146 */ ED_UNASSIGNED, /* M-^R */ + /* 147 */ ED_UNASSIGNED, /* M-^S */ + /* 148 */ ED_UNASSIGNED, /* M-^T */ + /* 149 */ ED_UNASSIGNED, /* M-^U */ + /* 150 */ ED_UNASSIGNED, /* M-^V */ + /* 151 */ ED_UNASSIGNED, /* M-^W */ + /* 152 */ ED_UNASSIGNED, /* M-^X */ + /* 153 */ ED_UNASSIGNED, /* M-^Y */ + /* 154 */ ED_UNASSIGNED, /* M-^Z */ + /* 155 */ ED_UNASSIGNED, /* M-^[ */ + /* 156 */ ED_UNASSIGNED, /* M-^\ */ + /* 157 */ ED_UNASSIGNED, /* M-^] */ + /* 158 */ ED_UNASSIGNED, /* M-^^ */ + /* 159 */ ED_UNASSIGNED, /* M-^_ */ + /* 160 */ ED_UNASSIGNED, /* M-SPACE */ + /* 161 */ ED_UNASSIGNED, /* M-! */ + /* 162 */ ED_UNASSIGNED, /* M-" */ + /* 163 */ ED_UNASSIGNED, /* M-# */ + /* 164 */ ED_UNASSIGNED, /* M-$ */ + /* 165 */ ED_UNASSIGNED, /* M-% */ + /* 166 */ ED_UNASSIGNED, /* M-& */ + /* 167 */ ED_UNASSIGNED, /* M-' */ + /* 168 */ ED_UNASSIGNED, /* M-( */ + /* 169 */ ED_UNASSIGNED, /* M-) */ + /* 170 */ ED_UNASSIGNED, /* M-* */ + /* 171 */ ED_UNASSIGNED, /* M-+ */ + /* 172 */ ED_UNASSIGNED, /* M-, */ + /* 173 */ ED_UNASSIGNED, /* M-- */ + /* 174 */ ED_UNASSIGNED, /* M-. */ + /* 175 */ ED_UNASSIGNED, /* M-/ */ + /* 176 */ ED_UNASSIGNED, /* M-0 */ + /* 177 */ ED_UNASSIGNED, /* M-1 */ + /* 178 */ ED_UNASSIGNED, /* M-2 */ + /* 179 */ ED_UNASSIGNED, /* M-3 */ + /* 180 */ ED_UNASSIGNED, /* M-4 */ + /* 181 */ ED_UNASSIGNED, /* M-5 */ + /* 182 */ ED_UNASSIGNED, /* M-6 */ + /* 183 */ ED_UNASSIGNED, /* M-7 */ + /* 184 */ ED_UNASSIGNED, /* M-8 */ + /* 185 */ ED_UNASSIGNED, /* M-9 */ + /* 186 */ ED_UNASSIGNED, /* M-: */ + /* 187 */ ED_UNASSIGNED, /* M-; */ + /* 188 */ ED_UNASSIGNED, /* M-< */ + /* 189 */ ED_UNASSIGNED, /* M-= */ + /* 190 */ ED_UNASSIGNED, /* M-> */ + /* 191 */ ED_UNASSIGNED, /* M-? */ + /* 192 */ ED_UNASSIGNED, /* M-@ */ + /* 193 */ ED_UNASSIGNED, /* M-A */ + /* 194 */ ED_UNASSIGNED, /* M-B */ + /* 195 */ ED_UNASSIGNED, /* M-C */ + /* 196 */ ED_UNASSIGNED, /* M-D */ + /* 197 */ ED_UNASSIGNED, /* M-E */ + /* 198 */ ED_UNASSIGNED, /* M-F */ + /* 199 */ ED_UNASSIGNED, /* M-G */ + /* 200 */ ED_UNASSIGNED, /* M-H */ + /* 201 */ ED_UNASSIGNED, /* M-I */ + /* 202 */ ED_UNASSIGNED, /* M-J */ + /* 203 */ ED_UNASSIGNED, /* M-K */ + /* 204 */ ED_UNASSIGNED, /* M-L */ + /* 205 */ ED_UNASSIGNED, /* M-M */ + /* 206 */ ED_UNASSIGNED, /* M-N */ + /* 207 */ ED_SEQUENCE_LEAD_IN, /* M-O */ + /* 208 */ ED_UNASSIGNED, /* M-P */ + /* 209 */ ED_UNASSIGNED, /* M-Q */ + /* 210 */ ED_UNASSIGNED, /* M-R */ + /* 211 */ ED_UNASSIGNED, /* M-S */ + /* 212 */ ED_UNASSIGNED, /* M-T */ + /* 213 */ ED_UNASSIGNED, /* M-U */ + /* 214 */ ED_UNASSIGNED, /* M-V */ + /* 215 */ ED_UNASSIGNED, /* M-W */ + /* 216 */ ED_UNASSIGNED, /* M-X */ + /* 217 */ ED_UNASSIGNED, /* M-Y */ + /* 218 */ ED_UNASSIGNED, /* M-Z */ + /* 219 */ ED_SEQUENCE_LEAD_IN, /* M-[ */ + /* 220 */ ED_UNASSIGNED, /* M-\ */ + /* 221 */ ED_UNASSIGNED, /* M-] */ + /* 222 */ ED_UNASSIGNED, /* M-^ */ + /* 223 */ ED_UNASSIGNED, /* M-_ */ + /* 224 */ ED_UNASSIGNED, /* M-` */ + /* 225 */ ED_UNASSIGNED, /* M-a */ + /* 226 */ ED_UNASSIGNED, /* M-b */ + /* 227 */ ED_UNASSIGNED, /* M-c */ + /* 228 */ ED_UNASSIGNED, /* M-d */ + /* 229 */ ED_UNASSIGNED, /* M-e */ + /* 230 */ ED_UNASSIGNED, /* M-f */ + /* 231 */ ED_UNASSIGNED, /* M-g */ + /* 232 */ ED_UNASSIGNED, /* M-h */ + /* 233 */ ED_UNASSIGNED, /* M-i */ + /* 234 */ ED_UNASSIGNED, /* M-j */ + /* 235 */ ED_UNASSIGNED, /* M-k */ + /* 236 */ ED_UNASSIGNED, /* M-l */ + /* 237 */ ED_UNASSIGNED, /* M-m */ + /* 238 */ ED_UNASSIGNED, /* M-n */ + /* 239 */ ED_UNASSIGNED, /* M-o */ + /* 240 */ ED_UNASSIGNED, /* M-p */ + /* 241 */ ED_UNASSIGNED, /* M-q */ + /* 242 */ ED_UNASSIGNED, /* M-r */ + /* 243 */ ED_UNASSIGNED, /* M-s */ + /* 244 */ ED_UNASSIGNED, /* M-t */ + /* 245 */ ED_UNASSIGNED, /* M-u */ + /* 246 */ ED_UNASSIGNED, /* M-v */ + /* 247 */ ED_UNASSIGNED, /* M-w */ + /* 248 */ ED_UNASSIGNED, /* M-x */ + /* 249 */ ED_UNASSIGNED, /* M-y */ + /* 250 */ ED_UNASSIGNED, /* M-z */ + /* 251 */ ED_UNASSIGNED, /* M-{ */ + /* 252 */ ED_UNASSIGNED, /* M-| */ + /* 253 */ ED_UNASSIGNED, /* M-} */ + /* 254 */ ED_UNASSIGNED, /* M-~ */ + /* 255 */ ED_UNASSIGNED /* M-^? */ }; @@ -885,41 +895,49 @@ private el_action_t el_map_vi_command[] = { * Initialize and allocate the maps */ protected int -map_init(el) - EditLine *el; +map_init(EditLine *el) { - - /* - * Make sure those are correct before starting. - */ + + /* + * Make sure those are correct before starting. + */ #ifdef MAP_DEBUG - if (sizeof(el_map_emacs) != N_KEYS * sizeof(el_action_t)) - abort(); - if (sizeof(el_map_vi_command) != N_KEYS * sizeof(el_action_t)) - abort(); - if (sizeof(el_map_vi_insert) != N_KEYS * sizeof(el_action_t)) - abort(); + if (sizeof(el_map_emacs) != N_KEYS * sizeof(el_action_t)) + EL_ABORT((el->errfile, "Emacs map incorrect\n")); + if (sizeof(el_map_vi_command) != N_KEYS * sizeof(el_action_t)) + EL_ABORT((el->errfile, "Vi command map incorrect\n")); + if (sizeof(el_map_vi_insert) != N_KEYS * sizeof(el_action_t)) + EL_ABORT((el->errfile, "Vi insert map incorrect\n")); #endif - el->el_map.alt = (el_action_t *) el_malloc(sizeof(el_action_t) * N_KEYS); - el->el_map.key = (el_action_t *) el_malloc(sizeof(el_action_t) * N_KEYS); - el->el_map.emacs = el_map_emacs; - el->el_map.vic = el_map_vi_command; - el->el_map.vii = el_map_vi_insert; - el->el_map.help = (el_bindings_t *) el_malloc(sizeof(el_bindings_t) * - EL_NUM_FCNS); - (void) memcpy(el->el_map.help, help__get(), - sizeof(el_bindings_t) * EL_NUM_FCNS); - el->el_map.func = (el_func_t *) el_malloc(sizeof(el_func_t) * EL_NUM_FCNS); - memcpy(el->el_map.func, func__get(), sizeof(el_func_t) * EL_NUM_FCNS); - el->el_map.nfunc = EL_NUM_FCNS; + el->el_map.alt = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS); + if (el->el_map.alt == NULL) + return (-1); + el->el_map.key = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS); + if (el->el_map.key == NULL) + return (-1); + el->el_map.emacs = el_map_emacs; + el->el_map.vic = el_map_vi_command; + el->el_map.vii = el_map_vi_insert; + el->el_map.help = (el_bindings_t *) el_malloc(sizeof(el_bindings_t) * + EL_NUM_FCNS); + if (el->el_map.help == NULL) + return (-1); + (void) memcpy(el->el_map.help, help__get(), + sizeof(el_bindings_t) * EL_NUM_FCNS); + el->el_map.func = (el_func_t *)el_malloc(sizeof(el_func_t) * + EL_NUM_FCNS); + if (el->el_map.func == NULL) + return (-1); + memcpy(el->el_map.func, func__get(), sizeof(el_func_t) * EL_NUM_FCNS); + el->el_map.nfunc = EL_NUM_FCNS; #ifdef VIDEFAULT - map_init_vi(el); + map_init_vi(el); #else - map_init_emacs(el); + map_init_emacs(el); #endif /* VIDEFAULT */ - return 0; + return (0); } @@ -927,20 +945,20 @@ map_init(el) * Free the space taken by the editor maps */ protected void -map_end(el) - EditLine *el; +map_end(EditLine *el) { - el_free((ptr_t) el->el_map.alt); - el->el_map.alt = NULL; - el_free((ptr_t) el->el_map.key); - el->el_map.key = NULL; - el->el_map.emacs = NULL; - el->el_map.vic = NULL; - el->el_map.vii = NULL; - el_free((ptr_t) el->el_map.help); - el->el_map.help = NULL; - el_free((ptr_t) el->el_map.func); - el->el_map.func = NULL; + + el_free((ptr_t) el->el_map.alt); + el->el_map.alt = NULL; + el_free((ptr_t) el->el_map.key); + el->el_map.key = NULL; + el->el_map.emacs = NULL; + el->el_map.vic = NULL; + el->el_map.vii = NULL; + el_free((ptr_t) el->el_map.help); + el->el_map.help = NULL; + el_free((ptr_t) el->el_map.func); + el->el_map.func = NULL; } @@ -948,15 +966,15 @@ map_end(el) * Find all the printable keys and bind them to self insert */ private void -map_init_nls(el) - EditLine *el; +map_init_nls(EditLine *el) { - int i; - el_action_t *map = el->el_map.key; + int i; + + el_action_t *map = el->el_map.key; - for (i = 0200; i <= 0377; i++) - if (isprint(i)) - map[i] = ED_INSERT; + for (i = 0200; i <= 0377; i++) + if (isprint(i)) + map[i] = ED_INSERT; } @@ -964,42 +982,40 @@ map_init_nls(el) * Bind all the meta keys to the appropriate ESC-<key> sequence */ private void -map_init_meta(el) - EditLine *el; +map_init_meta(EditLine *el) { - char buf[3]; - register int i; - el_action_t *map = el->el_map.key; - el_action_t *alt = el->el_map.alt; + char buf[3]; + int i; + el_action_t *map = el->el_map.key; + el_action_t *alt = el->el_map.alt; - for (i = 0; i <= 0377 && map[i] != EM_META_NEXT; i++) - continue; + for (i = 0; i <= 0377 && map[i] != EM_META_NEXT; i++) + continue; - if (i > 0377) { - for (i = 0; i <= 0377 && alt[i] != EM_META_NEXT; i++) - continue; if (i > 0377) { - i = 033; - if (el->el_map.type == MAP_VI) - map = alt; + for (i = 0; i <= 0377 && alt[i] != EM_META_NEXT; i++) + continue; + if (i > 0377) { + i = 033; + if (el->el_map.type == MAP_VI) + map = alt; + } else + map = alt; } - else - map = alt; - } - buf[0] = (char) i; - buf[2] = 0; - for (i = 0200; i <= 0377; i++) - switch (map[i]) { - case ED_INSERT: - case ED_UNASSIGNED: - case ED_SEQUENCE_LEAD_IN: - break; - default: - buf[1] = i & 0177; - key_add(el, buf, key_map_cmd(el, (int) map[i]), XK_CMD); - break; - } - map[buf[0]] = ED_SEQUENCE_LEAD_IN; + buf[0] = (char) i; + buf[2] = 0; + for (i = 0200; i <= 0377; i++) + switch (map[i]) { + case ED_INSERT: + case ED_UNASSIGNED: + case ED_SEQUENCE_LEAD_IN: + break; + default: + buf[1] = i & 0177; + key_add(el, buf, key_map_cmd(el, (int) map[i]), XK_CMD); + break; + } + map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN; } @@ -1007,33 +1023,29 @@ map_init_meta(el) * Initialize the vi bindings */ protected void -map_init_vi(el) - EditLine *el; +map_init_vi(EditLine *el) { - register int i; - el_action_t *key = el->el_map.key; - el_action_t *alt = el->el_map.alt; - el_action_t *vii = el->el_map.vii; - el_action_t *vic = el->el_map.vic; + int i; + el_action_t *key = el->el_map.key; + el_action_t *alt = el->el_map.alt; + const el_action_t *vii = el->el_map.vii; + const el_action_t *vic = el->el_map.vic; - el->el_map.type = MAP_VI; - el->el_map.current = el->el_map.key; + el->el_map.type = MAP_VI; + el->el_map.current = el->el_map.key; - key_reset(el); + key_reset(el); - for (i = 0; i < N_KEYS; i++) { - key[i] = vii[i]; - alt[i] = vic[i]; - } + for (i = 0; i < N_KEYS; i++) { + key[i] = vii[i]; + alt[i] = vic[i]; + } - map_init_meta(el); -#ifdef notyet - if (0 /* XXX: USER has set LC_CTYPE */) + map_init_meta(el); map_init_nls(el); -#endif - tty_bind_char(el, 1); - term_bind_arrow(el); + tty_bind_char(el, 1); + term_bind_arrow(el); } @@ -1041,58 +1053,73 @@ map_init_vi(el) * Initialize the emacs bindings */ protected void -map_init_emacs(el) - EditLine *el; +map_init_emacs(EditLine *el) { - int i; - char buf[3]; - el_action_t *key = el->el_map.key; - el_action_t *alt = el->el_map.alt; - el_action_t *emacs = el->el_map.emacs; - - el->el_map.type = MAP_EMACS; - el->el_map.current = el->el_map.key; - key_reset(el); - - for (i = 0; i < N_KEYS; i++) { - key[i] = emacs[i]; - alt[i] = ED_UNASSIGNED; - } - - map_init_meta(el); -#ifdef notyet - if (0 /* XXX: USER has set LC_CTYPE */) + int i; + char buf[3]; + el_action_t *key = el->el_map.key; + el_action_t *alt = el->el_map.alt; + const el_action_t *emacs = el->el_map.emacs; + + el->el_map.type = MAP_EMACS; + el->el_map.current = el->el_map.key; + key_reset(el); + + for (i = 0; i < N_KEYS; i++) { + key[i] = emacs[i]; + alt[i] = ED_UNASSIGNED; + } + + map_init_meta(el); map_init_nls(el); -#endif - map_init_nls(el); - - buf[0] = CONTROL('X'); - buf[1] = CONTROL('X'); - buf[2] = 0; - key_add(el, buf, key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD); - - tty_bind_char(el, 1); - term_bind_arrow(el); + + buf[0] = CONTROL('X'); + buf[1] = CONTROL('X'); + buf[2] = 0; + key_add(el, buf, key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD); + + tty_bind_char(el, 1); + term_bind_arrow(el); } /* map_set_editor(): - * Set the editor + * Set the editor */ protected int -map_set_editor(el, editor) - EditLine *el; - char *editor; +map_set_editor(EditLine *el, char *editor) { - if (strcmp(editor, "emacs") == 0) { - map_init_emacs(el); - return 0; - } - if (strcmp(editor, "vi") == 0) { - map_init_vi(el); - return 0; - } - return -1; + + if (strcmp(editor, "emacs") == 0) { + map_init_emacs(el); + return (0); + } + if (strcmp(editor, "vi") == 0) { + map_init_vi(el); + return (0); + } + return (-1); +} + + +/* map_get_editor(): + * Retrieve the editor + */ +protected int +map_get_editor(EditLine *el, const char **editor) +{ + + if (editor == NULL) + return (-1); + switch (el->el_map.type) { + case MAP_EMACS: + *editor = "emacs"; + return (0); + case MAP_VI: + *editor = "vi"; + return (0); + } + return (-1); } @@ -1100,25 +1127,21 @@ map_set_editor(el, editor) * Print the function description for 1 key */ private void -map_print_key(el, map, in) - EditLine *el; - el_action_t *map; - char *in; +map_print_key(EditLine *el, el_action_t *map, char *in) { - char outbuf[EL_BUFSIZ]; - el_bindings_t *bp; - - if (in[0] == '\0' || in[1] == '\0') { - (void) key__decode_str(in, outbuf, ""); - for (bp = el->el_map.help; bp->name != NULL; bp++) - if (bp->func == map[(unsigned char) *in]) { - (void) fprintf(el->el_outfile, - "%s\t->\t%s\n", outbuf, bp->name); - return; - } - } - else - key_print(el, in); + char outbuf[EL_BUFSIZ]; + el_bindings_t *bp; + + if (in[0] == '\0' || in[1] == '\0') { + (void) key__decode_str(in, outbuf, ""); + for (bp = el->el_map.help; bp->name != NULL; bp++) + if (bp->func == map[(unsigned char) *in]) { + (void) fprintf(el->el_outfile, + "%s\t->\t%s\n", outbuf, bp->name); + return; + } + } else + key_print(el, in); } @@ -1126,57 +1149,55 @@ map_print_key(el, map, in) * Print keys from first to last */ private void -map_print_some_keys(el, map, first, last) - EditLine *el; - el_action_t *map; - int first, last; +map_print_some_keys(EditLine *el, el_action_t *map, int first, int last) { - el_bindings_t *bp; - char firstbuf[2], lastbuf[2]; - char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ]; - - firstbuf[0] = first; - firstbuf[1] = 0; - lastbuf[0] = last; - lastbuf[1] = 0; - if (map[first] == ED_UNASSIGNED) { - if (first == last) - (void) fprintf(el->el_outfile, "%-15s-> is undefined\n", - key__decode_str(firstbuf, unparsbuf, STRQQ)); - return; - } - - for (bp = el->el_map.help; bp->name != NULL; bp++) { - if (bp->func == map[first]) { - if (first == last) { - (void) fprintf(el->el_outfile, "%-15s-> %s\n", - key__decode_str(firstbuf, unparsbuf, STRQQ), - bp->name); - } - else { - (void) fprintf(el->el_outfile, "%-4s to %-7s-> %s\n", - key__decode_str(firstbuf, unparsbuf, STRQQ), - key__decode_str(lastbuf, extrabuf, STRQQ), - bp->name); - } - return; + el_bindings_t *bp; + char firstbuf[2], lastbuf[2]; + char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ]; + + firstbuf[0] = first; + firstbuf[1] = 0; + lastbuf[0] = last; + lastbuf[1] = 0; + if (map[first] == ED_UNASSIGNED) { + if (first == last) + (void) fprintf(el->el_outfile, + "%-15s-> is undefined\n", + key__decode_str(firstbuf, unparsbuf, STRQQ)); + return; + } + for (bp = el->el_map.help; bp->name != NULL; bp++) { + if (bp->func == map[first]) { + if (first == last) { + (void) fprintf(el->el_outfile, "%-15s-> %s\n", + key__decode_str(firstbuf, unparsbuf, STRQQ), + bp->name); + } else { + (void) fprintf(el->el_outfile, + "%-4s to %-7s-> %s\n", + key__decode_str(firstbuf, unparsbuf, STRQQ), + key__decode_str(lastbuf, extrabuf, STRQQ), + bp->name); + } + return; + } } - } #ifdef MAP_DEBUG - if (map == el->el_map.key) { - (void) fprintf(el->el_outfile, "BUG!!! %s isn't bound to anything.\n", - key__decode_str(firstbuf, unparsbuf, STRQQ)); - (void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n", - first, el->el_map.key[first]); - } - else { - (void) fprintf(el->el_outfile, "BUG!!! %s isn't bound to anything.\n", - key__decode_str(firstbuf, unparsbuf, STRQQ)); - (void) fprintf(el->el_outfile, "el->el_map.alt[%d] == %d\n", - first, el->el_map.alt[first]); - } + if (map == el->el_map.key) { + (void) fprintf(el->el_outfile, + "BUG!!! %s isn't bound to anything.\n", + key__decode_str(firstbuf, unparsbuf, STRQQ)); + (void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n", + first, el->el_map.key[first]); + } else { + (void) fprintf(el->el_outfile, + "BUG!!! %s isn't bound to anything.\n", + key__decode_str(firstbuf, unparsbuf, STRQQ)); + (void) fprintf(el->el_outfile, "el->el_map.alt[%d] == %d\n", + first, el->el_map.alt[first]); + } #endif - abort(); + EL_ABORT((el->el_errfile, "Error printing keys\n")); } @@ -1184,35 +1205,34 @@ map_print_some_keys(el, map, first, last) * Print the function description for all keys. */ private void -map_print_all_keys(el) - EditLine *el; +map_print_all_keys(EditLine *el) { - int prev, i; - - (void) fprintf(el->el_outfile, "Standard key bindings\n"); - prev = 0; - for (i = 0; i < N_KEYS; i++) { - if (el->el_map.key[prev] == el->el_map.key[i]) - continue; + int prev, i; + + (void) fprintf(el->el_outfile, "Standard key bindings\n"); + prev = 0; + for (i = 0; i < N_KEYS; i++) { + if (el->el_map.key[prev] == el->el_map.key[i]) + continue; + map_print_some_keys(el, el->el_map.key, prev, i - 1); + prev = i; + } map_print_some_keys(el, el->el_map.key, prev, i - 1); - prev = i; - } - map_print_some_keys(el, el->el_map.key, prev, i - 1); - - (void) fprintf(el->el_outfile, "Alternative key bindings\n"); - prev = 0; - for (i = 0; i < N_KEYS; i++) { - if (el->el_map.alt[prev] == el->el_map.alt[i]) - continue; + + (void) fprintf(el->el_outfile, "Alternative key bindings\n"); + prev = 0; + for (i = 0; i < N_KEYS; i++) { + if (el->el_map.alt[prev] == el->el_map.alt[i]) + continue; + map_print_some_keys(el, el->el_map.alt, prev, i - 1); + prev = i; + } map_print_some_keys(el, el->el_map.alt, prev, i - 1); - prev = i; - } - map_print_some_keys(el, el->el_map.alt, prev, i - 1); - - (void) fprintf(el->el_outfile, "Multi-character bindings\n"); - key_print(el, ""); - (void) fprintf(el->el_outfile, "Arrow key bindings\n"); - term_print_arrow(el, ""); + + (void) fprintf(el->el_outfile, "Multi-character bindings\n"); + key_print(el, ""); + (void) fprintf(el->el_outfile, "Arrow key bindings\n"); + term_print_arrow(el, ""); } @@ -1220,154 +1240,149 @@ map_print_all_keys(el) * Add/remove/change bindings */ protected int -map_bind(el, argc, argv) - EditLine *el; - int argc; - char **argv; +map_bind(EditLine *el, int argc, char **argv) { - el_action_t *map; - int ntype, remove; - char *p; - char inbuf[EL_BUFSIZ]; - char outbuf[EL_BUFSIZ]; - char *in = NULL; - char *out = NULL; - el_bindings_t *bp; - int cmd; - int key; - - if (argv == NULL) - return -1; - - map = el->el_map.key; - ntype = XK_CMD; - key = remove = 0; - for (argc = 1; (p = argv[argc]) != NULL; argc++) - if (p[0] == '-') - switch (p[1]) { - case 'a': - map = el->el_map.alt; - break; - - case 's': - ntype = XK_STR; - break; + el_action_t *map; + int ntype, rem; + char *p; + char inbuf[EL_BUFSIZ]; + char outbuf[EL_BUFSIZ]; + char *in = NULL; + char *out = NULL; + el_bindings_t *bp; + int cmd; + int key; + + if (argv == NULL) + return (-1); + + map = el->el_map.key; + ntype = XK_CMD; + key = rem = 0; + for (argc = 1; (p = argv[argc]) != NULL; argc++) + if (p[0] == '-') + switch (p[1]) { + case 'a': + map = el->el_map.alt; + break; + + case 's': + ntype = XK_STR; + break; #ifdef notyet - case 'c': - ntype = XK_EXE; - break; + case 'c': + ntype = XK_EXE; + break; #endif - case 'k': - key = 1; - break; - - case 'r': - remove = 1; - break; - - case 'v': - map_init_vi(el); - return 0; - - case 'e': - map_init_emacs(el); - return 0; - - case 'l': - for (bp = el->el_map.help; bp->name != NULL; bp++) - (void) fprintf(el->el_outfile, "%s\n\t%s\n", - bp->name, bp->description); - return 0; - default: - (void) fprintf(el->el_errfile, "%s: Invalid switch `%c'.\n", - argv[0], p[1]); - } - else - break; - - if (argv[argc] == NULL) { - map_print_all_keys(el); - return 0; - } - - if (key) - in = argv[argc++]; - else - if ((in = parse__string(inbuf, argv[argc++])) == NULL) { - (void) fprintf(el->el_errfile, "%s: Invalid \\ or ^ in instring.\n", - argv[0]); - return -1; + case 'k': + key = 1; + break; + + case 'r': + rem = 1; + break; + + case 'v': + map_init_vi(el); + return (0); + + case 'e': + map_init_emacs(el); + return (0); + + case 'l': + for (bp = el->el_map.help; bp->name != NULL; + bp++) + (void) fprintf(el->el_outfile, + "%s\n\t%s\n", + bp->name, bp->description); + return (0); + default: + (void) fprintf(el->el_errfile, + "%s: Invalid switch `%c'.\n", + argv[0], p[1]); + } + else + break; + + if (argv[argc] == NULL) { + map_print_all_keys(el); + return (0); } - - if (remove) { - if (key) { - (void) term_clear_arrow(el, in); - return -1; - } - if (in[1]) - (void) key_delete(el, in); - else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN) - (void) key_delete(el, in); - else - map[(unsigned char) *in] = ED_UNASSIGNED; - return 0; - } - - if (argv[argc] == NULL) { if (key) - term_print_arrow(el, in); - else - map_print_key(el, map, in); - return 0; - } - + in = argv[argc++]; + else if ((in = parse__string(inbuf, argv[argc++])) == NULL) { + (void) fprintf(el->el_errfile, + "%s: Invalid \\ or ^ in instring.\n", + argv[0]); + return (-1); + } + if (rem) { + if (key) { + (void) term_clear_arrow(el, in); + return (-1); + } + if (in[1]) + (void) key_delete(el, in); + else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN) + (void) key_delete(el, in); + else + map[(unsigned char) *in] = ED_UNASSIGNED; + return (0); + } + if (argv[argc] == NULL) { + if (key) + term_print_arrow(el, in); + else + map_print_key(el, map, in); + return (0); + } #ifdef notyet - if (argv[argc + 1] != NULL) { - bindkey_usage(); - return -1; - } + if (argv[argc + 1] != NULL) { + bindkey_usage(); + return (-1); + } #endif - switch (ntype) { - case XK_STR: - case XK_EXE: - if ((out = parse__string(outbuf, argv[argc])) == NULL) { - (void) fprintf(el->el_errfile, - "%s: Invalid \\ or ^ in outstring.\n", argv[0]); - return -1; - } - if (key) - term_set_arrow(el, in, key_map_str(el, out), ntype); - else - key_add(el, in, key_map_str(el, out), ntype); - map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN; - break; - - case XK_CMD: - if ((cmd = parse_cmd(el, argv[argc])) == -1) { - (void) fprintf(el->el_errfile, - "%s: Invalid command `%s'.\n", argv[0], argv[argc]); - return -1; - } - if (key) - term_set_arrow(el, in, key_map_str(el, out), ntype); - else { - if (in[1]) { - key_add(el, in, key_map_cmd(el, cmd), ntype); + switch (ntype) { + case XK_STR: + case XK_EXE: + if ((out = parse__string(outbuf, argv[argc])) == NULL) { + (void) fprintf(el->el_errfile, + "%s: Invalid \\ or ^ in outstring.\n", argv[0]); + return (-1); + } + if (key) + term_set_arrow(el, in, key_map_str(el, out), ntype); + else + key_add(el, in, key_map_str(el, out), ntype); map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN; - } - else { - key_clear(el, map, in); - map[(unsigned char) *in] = cmd; - } - } - break; + break; - default: - abort(); - break; - } - return 0; + case XK_CMD: + if ((cmd = parse_cmd(el, argv[argc])) == -1) { + (void) fprintf(el->el_errfile, + "%s: Invalid command `%s'.\n", argv[0], argv[argc]); + return (-1); + } + if (key) + term_set_arrow(el, in, key_map_str(el, out), ntype); + else { + if (in[1]) { + key_add(el, in, key_map_cmd(el, cmd), ntype); + map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN; + } else { + key_clear(el, map, in); + map[(unsigned char) *in] = cmd; + } + } + break; + + default: + EL_ABORT((el->el_errfile, "Bad XK_ type\n", ntype)); + break; + } + return (0); } @@ -1375,29 +1390,30 @@ map_bind(el, argc, argv) * add a user defined function */ protected int -map_addfunc(el, name, help, func) - EditLine *el; - const char *name; - const char *help; - el_func_t func; +map_addfunc(EditLine *el, const char *name, const char *help, el_func_t func) { - int nf = el->el_map.nfunc + 2; - if (name == NULL || help == NULL || func == NULL) - return -1; - - el->el_map.func = (el_func_t *) - el_realloc(el->el_map.func, nf * sizeof(el_func_t)); - el->el_map.help = (el_bindings_t *) - el_realloc(el->el_map.help, nf * sizeof(el_bindings_t)); - - nf = el->el_map.nfunc; - el->el_map.func[nf] = func; - - el->el_map.help[nf].name = name; - el->el_map.help[nf].func = nf; - el->el_map.help[nf].description = help; - el->el_map.help[++nf].name = NULL; - el->el_map.nfunc++; - - return 0; + void *p; + int nf = el->el_map.nfunc + 2; + + if (name == NULL || help == NULL || func == NULL) + return (-1); + + if ((p = el_realloc(el->el_map.func, nf * sizeof(el_func_t))) == NULL) + return (-1); + el->el_map.func = (el_func_t *) p; + if ((p = el_realloc(el->el_map.help, nf * sizeof(el_bindings_t))) + == NULL) + return (-1); + el->el_map.help = (el_bindings_t *) p; + + nf = el->el_map.nfunc; + el->el_map.func[nf] = func; + + el->el_map.help[nf].name = name; + el->el_map.help[nf].func = nf; + el->el_map.help[nf].description = help; + el->el_map.help[++nf].name = NULL; + el->el_map.nfunc++; + + return (0); } @@ -1,4 +1,4 @@ -/* $NetBSD: map.h,v 1.2 1997/01/11 06:48:01 lukem Exp $ */ +/* $NetBSD: map.h,v 1.6 2001/01/09 17:22:09 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,38 +42,38 @@ * el.map.h: Editor maps */ #ifndef _h_el_map -#define _h_el_map +#define _h_el_map typedef struct el_bindings_t { /* for the "bind" shell command */ - const char *name; /* function name for bind command */ - int func; /* function numeric value */ - const char *description; /* description of function */ + const char *name; /* function name for bind command */ + int func; /* function numeric value */ + const char *description; /* description of function */ } el_bindings_t; typedef struct el_map_t { - el_action_t *alt; /* The current alternate key map */ - el_action_t *key; /* The current normal key map */ - el_action_t *current; /* The keymap we are using */ - el_action_t *emacs; /* The default emacs key map */ - el_action_t *vic; /* The vi command mode key map */ - el_action_t *vii; /* The vi insert mode key map */ - int type; /* Emacs or vi */ - el_bindings_t *help; /* The help for the editor functions */ - el_func_t *func; /* List of available functions */ - int nfunc; /* The number of functions/help items */ + el_action_t *alt; /* The current alternate key map */ + el_action_t *key; /* The current normal key map */ + el_action_t *current; /* The keymap we are using */ + const el_action_t *emacs; /* The default emacs key map */ + const el_action_t *vic; /* The vi command mode key map */ + const el_action_t *vii; /* The vi insert mode key map */ + int type; /* Emacs or vi */ + el_bindings_t *help; /* The help for the editor functions */ + el_func_t *func; /* List of available functions */ + int nfunc; /* The number of functions/help items */ } el_map_t; -#define MAP_EMACS 0 -#define MAP_VI 1 +#define MAP_EMACS 0 +#define MAP_VI 1 -protected int map_bind __P((EditLine *, int, char **)); -protected int map_init __P((EditLine *)); -protected void map_end __P((EditLine *)); -protected void map_init_vi __P((EditLine *)); -protected void map_init_emacs __P((EditLine *)); -protected int map_set_editor __P((EditLine *, char *)); -protected int map_addfunc __P((EditLine *, const char *, - const char *, el_func_t)); +protected int map_bind(EditLine *, int, char **); +protected int map_init(EditLine *); +protected void map_end(EditLine *); +protected void map_init_vi(EditLine *); +protected void map_init_emacs(EditLine *); +protected int map_set_editor(EditLine *, char *); +protected int map_get_editor(EditLine *, const char **); +protected int map_addfunc(EditLine *, const char *, const char *, el_func_t); #endif /* _h_el_map */ diff --git a/dist/parse.c b/dist/parse.c index ee37c14..3beeb1b 100644 --- a/dist/parse.c +++ b/dist/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.5 1997/01/11 09:57:08 lukem Exp $ */ +/* $NetBSD: parse.c,v 1.14 2001/01/23 15:55:30 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,11 +36,12 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: parse.c,v 1.5 1997/01/11 09:57:08 lukem Exp $"; +__RCSID("$NetBSD: parse.c,v 1.14 2001/01/23 15:55:30 jdolecek Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -51,6 +52,7 @@ static char rcsid[] = "$NetBSD: parse.c,v 1.5 1997/01/11 09:57:08 lukem Exp $"; * * bind * echotc + * edit * gettc * history * settc @@ -59,18 +61,20 @@ static char rcsid[] = "$NetBSD: parse.c,v 1.5 1997/01/11 09:57:08 lukem Exp $"; #include "sys.h" #include "el.h" #include "tokenizer.h" +#include <stdlib.h> -private struct { - char *name; - int (*func) __P((EditLine *, int, char **)); +private const struct { + char *name; + int (*func)(EditLine *, int, char **); } cmds[] = { - { "bind", map_bind }, - { "echotc", term_echotc }, - { "history", hist_list }, - { "telltc", term_telltc }, - { "settc", term_settc }, - { "setty", tty_stty }, - { NULL, NULL } + { "bind", map_bind }, + { "echotc", term_echotc }, + { "edit", el_editmode }, + { "history", hist_list }, + { "telltc", term_telltc }, + { "settc", term_settc }, + { "setty", tty_stty }, + { NULL, NULL } }; @@ -78,51 +82,58 @@ private struct { * Parse a line and dispatch it */ protected int -parse_line(el, line) - EditLine *el; - const char *line; +parse_line(EditLine *el, const char *line) { - char **argv; - int argc; - Tokenizer *tok; - - tok = tok_init(NULL); - tok_line(tok, line, &argc, &argv); - argc = el_parse(el, argc, argv); - tok_end(tok); - return argc; + char **argv; + int argc; + Tokenizer *tok; + + tok = tok_init(NULL); + tok_line(tok, line, &argc, &argv); + argc = el_parse(el, argc, argv); + tok_end(tok); + return (argc); } + /* el_parse(): * Command dispatcher */ public int -el_parse(el, argc, argv) - EditLine *el; - int argc; - char *argv[]; +el_parse(EditLine *el, int argc, char *argv[]) { - char *ptr; - int i; - - if (argc < 1) - return -1; - ptr = strchr(argv[0], ':'); - if (ptr != NULL) { - *ptr++ = '\0'; - if (! el_match(el->el_prog, argv[0])) - return 0; - } - else - ptr = argv[0]; - - for (i = 0; cmds[i].name != NULL; i++) - if (strcmp(cmds[i].name, ptr) == 0) { - i = (*cmds[i].func)(el, argc, argv); - return -i; - } - - return -1; + char *ptr; + int i; + + if (argc < 1) + return (-1); + ptr = strchr(argv[0], ':'); + if (ptr != NULL) { + char *tprog; + size_t l; + + if (ptr == argv[0]) + return (0); + l = ptr - argv[0] - 1; + tprog = (char *) el_malloc(l + 1); + if (tprog == NULL) + return (0); + (void) strncpy(tprog, argv[0], l); + tprog[l] = '\0'; + ptr++; + l = el_match(el->el_prog, tprog); + el_free(tprog); + if (!l) + return (0); + } else + ptr = argv[0]; + + for (i = 0; cmds[i].name != NULL; i++) + if (strcmp(cmds[i].name, ptr) == 0) { + i = (*cmds[i].func) (el, argc, argv); + return (-i); + } + return (-1); } @@ -131,125 +142,119 @@ el_parse(el, argc, argv) * the appropriate character or -1 if the escape is not valid */ protected int -parse__escape(ptr) - const char ** const ptr; +parse__escape(const char **const ptr) { - const char *p; - int c; - - p = *ptr; - - if (p[1] == 0) - return -1; - - if (*p == '\\') { - p++; - switch (*p) { - case 'a': - c = '\007'; /* Bell */ - break; - case 'b': - c = '\010'; /* Backspace */ - break; - case 't': - c = '\011'; /* Horizontal Tab */ - break; - case 'n': - c = '\012'; /* New Line */ - break; - case 'v': - c = '\013'; /* Vertical Tab */ - break; - case 'f': - c = '\014'; /* Form Feed */ - break; - case 'r': - c = '\015'; /* Carriage Return */ - break; - case 'e': - c = '\033'; /* Escape */ - break; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - { - int cnt, ch; - - for (cnt = 0, c = 0; cnt < 3; cnt++) { - ch = *p++; - if (ch < '0' || ch > '7') { - p--; + const char *p; + int c; + + p = *ptr; + + if (p[1] == 0) + return (-1); + + if (*p == '\\') { + p++; + switch (*p) { + case 'a': + c = '\007'; /* Bell */ + break; + case 'b': + c = '\010'; /* Backspace */ + break; + case 't': + c = '\011'; /* Horizontal Tab */ + break; + case 'n': + c = '\012'; /* New Line */ + break; + case 'v': + c = '\013'; /* Vertical Tab */ + break; + case 'f': + c = '\014'; /* Form Feed */ + break; + case 'r': + c = '\015'; /* Carriage Return */ + break; + case 'e': + c = '\033'; /* Escape */ + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + int cnt, ch; + + for (cnt = 0, c = 0; cnt < 3; cnt++) { + ch = *p++; + if (ch < '0' || ch > '7') { + p--; + break; + } + c = (c << 3) | (ch - '0'); + } + if ((c & 0xffffff00) != 0) + return (-1); + --p; break; - } - c = (c << 3) | (ch - '0'); } - if ((c & 0xffffff00) != 0) - return -1; - --p; - } - break; - default: - c = *p; - break; - } - } - else if (*p == '^' && isalpha((unsigned char) p[1])) { - p++; - c = (*p == '?') ? '\177' : (*p & 0237); - } - else - c = *p; - *ptr = ++p; - return c; + default: + c = *p; + break; + } + } else if (*p == '^' && isalpha((unsigned char) p[1])) { + p++; + c = (*p == '?') ? '\177' : (*p & 0237); + } else + c = *p; + *ptr = ++p; + return (c); } - /* parse__string(): * Parse the escapes from in and put the raw string out */ protected char * -parse__string(out, in) - char *out; - const char *in; +parse__string(char *out, const char *in) { - char *rv = out; - int n; - for (;;) - switch (*in) { - case '\0': - *out = '\0'; - return rv; - - case '\\': - case '^': - if ((n = parse__escape(&in)) == -1) - return NULL; - *out++ = n; - break; - - default: - *out++ = *in++; - break; - } + char *rv = out; + int n; + + for (;;) + switch (*in) { + case '\0': + *out = '\0'; + return (rv); + + case '\\': + case '^': + if ((n = parse__escape(&in)) == -1) + return (NULL); + *out++ = n; + break; + + default: + *out++ = *in++; + break; + } } + /* parse_cmd(): * Return the command number for the command string given * or -1 if one is not found */ protected int -parse_cmd(el, cmd) - EditLine *el; - const char *cmd; +parse_cmd(EditLine *el, const char *cmd) { - el_bindings_t *b; + el_bindings_t *b; - for (b = el->el_map.help; b->name != NULL; b++) - if (strcmp(b->name, cmd) == 0) - return b->func; - return -1; + for (b = el->el_map.help; b->name != NULL; b++) + if (strcmp(b->name, cmd) == 0) + return (b->func); + return (-1); } diff --git a/dist/parse.h b/dist/parse.h index 76fddf2..4aaef2f 100644 --- a/dist/parse.h +++ b/dist/parse.h @@ -1,4 +1,4 @@ -/* $NetBSD: parse.h,v 1.2 1997/01/11 06:48:03 lukem Exp $ */ +/* $NetBSD: parse.h,v 1.4 2000/09/04 22:06:31 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,11 +42,11 @@ * el.parse.h: Parser functions */ #ifndef _h_el_parse -#define _h_el_parse +#define _h_el_parse -protected int parse_line __P((EditLine *, const char *)); -protected int parse__escape __P((const char ** const)); -protected char * parse__string __P((char *, const char *)); -protected int parse_cmd __P((EditLine *, const char *)); +protected int parse_line(EditLine *, const char *); +protected int parse__escape(const char ** const); +protected char *parse__string(char *, const char *); +protected int parse_cmd(EditLine *, const char *); #endif /* _h_el_parse */ diff --git a/dist/prompt.c b/dist/prompt.c index 8999c14..b41ac5b 100644 --- a/dist/prompt.c +++ b/dist/prompt.c @@ -1,4 +1,4 @@ -/* $NetBSD: prompt.c,v 1.2 1997/01/11 06:48:04 lukem Exp $ */ +/* $NetBSD: prompt.c,v 1.8 2001/01/10 07:45:41 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,11 +36,12 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: prompt.c,v 1.2 1997/01/11 06:48:04 lukem Exp $"; +__RCSID("$NetBSD: prompt.c,v 1.8 2001/01/10 07:45:41 jdolecek Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -51,18 +52,32 @@ static char rcsid[] = "$NetBSD: prompt.c,v 1.2 1997/01/11 06:48:04 lukem Exp $"; #include <stdio.h> #include "el.h" -private char *prompt_default __P((EditLine *)); +private char *prompt_default(EditLine *); +private char *prompt_default_r(EditLine *); /* prompt_default(): * Just a default prompt, in case the user did not provide one */ private char * /*ARGSUSED*/ -prompt_default(el) - EditLine *el; +prompt_default(EditLine *el) { - static char a[3] = { '?', ' ', '\0' }; - return a; + static char a[3] = {'?', ' ', '\0'}; + + return (a); +} + + +/* prompt_default_r(): + * Just a default rprompt, in case the user did not provide one + */ +private char * +/*ARGSUSED*/ +prompt_default_r(EditLine *el) +{ + static char a[1] = {'\0'}; + + return (a); } @@ -73,57 +88,88 @@ prompt_default(el) * bit to flag them */ protected void -prompt_print(el) - EditLine *el; +prompt_print(EditLine *el, int op) { - char *p = (*el->el_prompt.p_func)(el); - while (*p) - re_putc(el, *p++); + el_prompt_t *elp; + char *p; - el->el_prompt.p_pos.v = el->el_refresh.r_cursor.v; - el->el_prompt.p_pos.h = el->el_refresh.r_cursor.h; + if (op == EL_PROMPT) + elp = &el->el_prompt; + else + elp = &el->el_rprompt; + p = (elp->p_func) (el); + while (*p) + re_putc(el, *p++, 1); -} /* end prompt_print */ + elp->p_pos.v = el->el_refresh.r_cursor.v; + elp->p_pos.h = el->el_refresh.r_cursor.h; +} /* prompt_init(): * Initialize the prompt stuff */ -protected int -prompt_init(el) - EditLine *el; +protected int +prompt_init(EditLine *el) { - el->el_prompt.p_func = prompt_default; - el->el_prompt.p_pos.v = 0; - el->el_prompt.p_pos.h = 0; - return 0; -} /* end prompt_init */ + + el->el_prompt.p_func = prompt_default; + el->el_prompt.p_pos.v = 0; + el->el_prompt.p_pos.h = 0; + el->el_rprompt.p_func = prompt_default_r; + el->el_rprompt.p_pos.v = 0; + el->el_rprompt.p_pos.h = 0; + return (0); +} /* prompt_end(): * Clean up the prompt stuff */ protected void -/*ARGSUSED*/ -prompt_end(el) - EditLine *el; +/*ARGSUSED*/ +prompt_end(EditLine *el) { -} /* end prompt_end */ +} /* prompt_set(): * Install a prompt printing function */ -protected int -prompt_set(el, prf) - EditLine *el; - el_pfunc_t prf; +protected int +prompt_set(EditLine *el, el_pfunc_t prf, int op) { - if (prf == NULL) - el->el_prompt.p_func = prompt_default; - else - el->el_prompt.p_func = prf; - el->el_prompt.p_pos.v = 0; - el->el_prompt.p_pos.h = 0; - return 0; -} /* end prompt_set */ + el_prompt_t *p; + + if (op == EL_PROMPT) + p = &el->el_prompt; + else + p = &el->el_rprompt; + if (prf == NULL) { + if (op == EL_PROMPT) + p->p_func = prompt_default; + else + p->p_func = prompt_default_r; + } else + p->p_func = prf; + p->p_pos.v = 0; + p->p_pos.h = 0; + return (0); +} + + +/* prompt_get(): + * Retrieve the prompt printing function + */ +protected int +prompt_get(EditLine *el, el_pfunc_t *prf, int op) +{ + + if (prf == NULL) + return (-1); + if (op == EL_PROMPT) + *prf = el->el_prompt.p_func; + else + *prf = el->el_rprompt.p_func; + return (0); +} diff --git a/dist/prompt.h b/dist/prompt.h index 4734ae1..08810e2 100644 --- a/dist/prompt.h +++ b/dist/prompt.h @@ -1,4 +1,4 @@ -/* $NetBSD: prompt.h,v 1.2 1997/01/11 06:48:05 lukem Exp $ */ +/* $NetBSD: prompt.h,v 1.5 2000/09/04 22:06:31 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,20 +42,21 @@ * el.prompt.h: Prompt printing stuff */ #ifndef _h_el_prompt -#define _h_el_prompt +#define _h_el_prompt #include "histedit.h" -typedef char * (*el_pfunc_t) __P((EditLine*)); +typedef char * (*el_pfunc_t)(EditLine*); typedef struct el_prompt_t { - el_pfunc_t p_func; /* Function to return the prompt */ - coord_t p_pos; /* position in the line after prompt */ + el_pfunc_t p_func; /* Function to return the prompt */ + coord_t p_pos; /* position in the line after prompt */ } el_prompt_t; -protected void prompt_print __P((EditLine *)); -protected int prompt_set __P((EditLine *, el_pfunc_t)); -protected int prompt_init __P((EditLine *)); -protected void prompt_end __P((EditLine *)); +protected void prompt_print(EditLine *, int); +protected int prompt_set(EditLine *, el_pfunc_t, int); +protected int prompt_get(EditLine *, el_pfunc_t *, int); +protected int prompt_init(EditLine *); +protected void prompt_end(EditLine *); #endif /* _h_el_prompt */ diff --git a/dist/read.c b/dist/read.c index 46d08cc..0103fb3 100644 --- a/dist/read.c +++ b/dist/read.c @@ -1,4 +1,4 @@ -/* $NetBSD: read.c,v 1.4 1997/04/11 17:52:47 christos Exp $ */ +/* $NetBSD: read.c,v 1.20 2001/09/27 19:29:50 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,11 +36,12 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: read.c,v 1.4 1997/04/11 17:52:47 christos Exp $"; +__RCSID("$NetBSD: read.c,v 1.20 2001/09/27 19:29:50 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -49,91 +50,132 @@ static char rcsid[] = "$NetBSD: read.c,v 1.4 1997/04/11 17:52:47 christos Exp $" * Terminal read functions */ #include "sys.h" -#include <sys/errno.h> +#include <errno.h> #include <unistd.h> #include <stdlib.h> -extern int errno; #include "el.h" -#define OKCMD -1 +#define OKCMD -1 + +private int read__fixio(int, int); +private int read_preread(EditLine *); +private int read_char(EditLine *, char *); +private int read_getcmd(EditLine *, el_action_t *, char *); + +/* read_init(): + * Initialize the read stuff + */ +protected int +read_init(EditLine *el) +{ + /* builtin read_char */ + el->el_read.read_char = read_char; + return 0; +} + + +/* el_read_setfn(): + * Set the read char function to the one provided. + * If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one. + */ +protected int +el_read_setfn(EditLine *el, el_rfunc_t rc) +{ + el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc; + return 0; +} + + +/* el_read_getfn(): + * return the current read char function, or EL_BUILTIN_GETCFN + * if it is the default one + */ +protected el_rfunc_t +el_read_getfn(EditLine *el) +{ + return (el->el_read.read_char == read_char) ? + EL_BUILTIN_GETCFN : el->el_read.read_char; +} -private int read__fixio __P((int, int)); -private int read_preread __P((EditLine *)); -private int read_getcmd __P((EditLine *, el_action_t *, char *)); #ifdef DEBUG_EDIT private void -read_debug(el) - EditLine *el; +read_debug(EditLine *el) { - if (el->el_line.cursor > el->el_line.lastchar) - (void) fprintf(el->el_errfile, "cursor > lastchar\r\n"); - if (el->el_line.cursor < el->el_line.buffer) - (void) fprintf(el->el_errfile, "cursor < buffer\r\n"); - if (el->el_line.cursor > el->el_line.limit) - (void) fprintf(el->el_errfile, "cursor > limit\r\n"); - if (el->el_line.lastchar > el->el_line.limit) - (void) fprintf(el->el_errfile, "lastchar > limit\r\n"); - if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2]) - (void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n"); + if (el->el_line.cursor > el->el_line.lastchar) + (void) fprintf(el->el_errfile, "cursor > lastchar\r\n"); + if (el->el_line.cursor < el->el_line.buffer) + (void) fprintf(el->el_errfile, "cursor < buffer\r\n"); + if (el->el_line.cursor > el->el_line.limit) + (void) fprintf(el->el_errfile, "cursor > limit\r\n"); + if (el->el_line.lastchar > el->el_line.limit) + (void) fprintf(el->el_errfile, "lastchar > limit\r\n"); + if (el->el_line.limit != &el->el_line.buffer[EL_BUFSIZ - 2]) + (void) fprintf(el->el_errfile, "limit != &buffer[EL_BUFSIZ-2]\r\n"); } #endif /* DEBUG_EDIT */ + /* read__fixio(): * Try to recover from a read error */ +/* ARGSUSED */ private int -read__fixio(fd, e) - int fd, e; +read__fixio(int fd, int e) { - switch (e) { - case -1: /* Make sure that the code is reachable */ + + switch (e) { + case -1: /* Make sure that the code is reachable */ #ifdef EWOULDBLOCK - case EWOULDBLOCK: -# ifndef TRY_AGAIN -# define TRY_AGAIN -# endif + case EWOULDBLOCK: +#ifndef TRY_AGAIN +#define TRY_AGAIN +#endif #endif /* EWOULDBLOCK */ #if defined(POSIX) && defined(EAGAIN) -# if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN - case EAGAIN: -# ifndef TRY_AGAIN -# define TRY_AGAIN -# endif -# endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */ +#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN + case EAGAIN: +#ifndef TRY_AGAIN +#define TRY_AGAIN +#endif +#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */ #endif /* POSIX && EAGAIN */ - e = 0; + e = 0; #ifdef TRY_AGAIN -# if defined(F_SETFL) && defined(O_NDELAY) - if ((e = fcntl(fd, F_GETFL, 0)) == -1) - return -1; - - if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1) - return -1; - else - e = 1; -# endif /* F_SETFL && O_NDELAY */ - -# ifdef FIONBIO - if (ioctl(fd, FIONBIO, (ioctl_t) &e) == -1) - return -1; - else - e = 1; -# endif /* FIONBIO */ +#if defined(F_SETFL) && defined(O_NDELAY) + if ((e = fcntl(fd, F_GETFL, 0)) == -1) + return (-1); + + if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1) + return (-1); + else + e = 1; +#endif /* F_SETFL && O_NDELAY */ + +#ifdef FIONBIO + { + int zero = 0; + + if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1) + return (-1); + else + e = 1; + } +#endif /* FIONBIO */ #endif /* TRY_AGAIN */ - return e ? 0 : -1; + return (e ? 0 : -1); - case EINTR: - return 0; + case EINTR: + return (0); - default: - return -1; - } + default: + return (-1); + } } @@ -141,34 +183,33 @@ read__fixio(fd, e) * Try to read the stuff in the input queue; */ private int -read_preread(el) - EditLine *el; +read_preread(EditLine *el) { - 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; - } + int chrs = 0; - if (el->el_tty.t_mode == ED_IO) - return 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) + return (0); #ifdef FIONREAD - (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) &chrs); - if (chrs > 0) { - char buf[EL_BUFSIZ]; - - chrs = read(el->el_infd, buf, (size_t) MIN(chrs, EL_BUFSIZ - 1)); + (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); if (chrs > 0) { - buf[chrs] = '\0'; - el->el_chared.c_macro.nline = strdup(buf); - el_push(el->el_chared.c_macro.nline); + char buf[EL_BUFSIZ]; + + chrs = read(el->el_infd, buf, + (size_t) MIN(chrs, EL_BUFSIZ - 1)); + if (chrs > 0) { + buf[chrs] = '\0'; + el->el_chared.c_macro.nline = strdup(buf); + el_push(el, el->el_chared.c_macro.nline); + } } - } -#endif /* FIONREAD */ +#endif /* FIONREAD */ - return chrs > 0; + return (chrs > 0); } @@ -176,20 +217,18 @@ read_preread(el) * Push a macro */ public void -el_push(el, str) - EditLine *el; - const char *str; +el_push(EditLine *el, const char *str) { - c_macro_t *ma = &el->el_chared.c_macro; - - if (str != NULL && ma->level + 1 < EL_MAXMACRO) { - ma->level++; - ma->macro[ma->level] = (char *) str; - } - else { - term_beep(el); - term__flush(); - } + c_macro_t *ma = &el->el_chared.c_macro; + + if (str != NULL && ma->level + 1 < EL_MAXMACRO) { + ma->level++; + /* LINTED const cast */ + ma->macro[ma->level] = (char *) str; + } else { + term_beep(el); + term__flush(); + } } @@ -197,57 +236,74 @@ el_push(el, str) * Return next command from the input stream. */ private int -read_getcmd(el, cmdnum, ch) - EditLine *el; - el_action_t *cmdnum; - char *ch; +read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) { - el_action_t cmd = 0; - int num; + el_action_t cmd = ED_UNASSIGNED; + int num; - while (cmd == 0 || cmd == ED_SEQUENCE_LEAD_IN) { - if ((num = el_getc(el, ch)) != 1) /* if EOF or error */ - return num; + while (cmd == ED_UNASSIGNED || cmd == ED_SEQUENCE_LEAD_IN) { + if ((num = el_getc(el, ch)) != 1) /* if EOF or error */ + return (num); #ifdef KANJI - if ((*ch & 0200)) { - el->el_state.metanext = 0; - cmd = CcViMap[' ']; - break; - } - else + if ((*ch & 0200)) { + el->el_state.metanext = 0; + cmd = CcViMap[' ']; + break; + } else #endif /* KANJI */ - if (el->el_state.metanext) { - el->el_state.metanext = 0; - *ch |= 0200; - } - cmd = el->el_map.current[(unsigned char) *ch]; - if (cmd == ED_SEQUENCE_LEAD_IN) { - key_value_t val; - switch (key_get(el, ch, &val)) { - case XK_CMD: - cmd = val.cmd; - break; - case XK_STR: - el_push(el, val.str); - break; + if (el->el_state.metanext) { + el->el_state.metanext = 0; + *ch |= 0200; + } + cmd = el->el_map.current[(unsigned char) *ch]; + if (cmd == ED_SEQUENCE_LEAD_IN) { + key_value_t val; + switch (key_get(el, ch, &val)) { + case XK_CMD: + cmd = val.cmd; + break; + case XK_STR: + el_push(el, val.str); + break; #ifdef notyet - case XK_EXE: - /* XXX: In the future to run a user function */ - RunCommand(val.str); - break; + case XK_EXE: + /* XXX: In the future to run a user function */ + RunCommand(val.str); + break; #endif - default: - abort(); - break; - } + default: + EL_ABORT((el->el_errfile, "Bad XK_ type \n")); + break; + } + } + if (el->el_map.alt == NULL) + el->el_map.current = el->el_map.key; } - if (el->el_map.alt == NULL) - el->el_map.current = el->el_map.key; - } - *cmdnum = cmd; - return OKCMD; + *cmdnum = cmd; + return (OKCMD); +} + + +/* read_char(): + * Read a character from the tty. + */ +private int +read_char(EditLine *el, char *cp) +{ + int num_read; + int tried = 0; + + while ((num_read = read(el->el_infd, cp, 1)) == -1) + if (!tried && read__fixio(el->el_infd, errno) == 0) + tried = 1; + else { + *cp = '\0'; + return (-1); + } + + return (num_read); } @@ -255,198 +311,247 @@ read_getcmd(el, cmdnum, ch) * Read a character */ public int -el_getc(el, cp) - EditLine *el; - char *cp; +el_getc(EditLine *el, char *cp) { - int num_read; - unsigned char tcp; - int tried = 0; - - c_macro_t *ma = &el->el_chared.c_macro; + int num_read; + c_macro_t *ma = &el->el_chared.c_macro; - term__flush(); - for (;;) { - if (ma->level < 0) { - if (!read_preread(el)) - break; - } - if (ma->level < 0) - break; - - if (*ma->macro[ma->level] == 0) { - ma->level--; - continue; - } - *cp = *ma->macro[ma->level]++ & 0377; - if (*ma->macro[ma->level] == 0) { /* Needed for QuoteMode On */ - ma->level--; + term__flush(); + for (;;) { + if (ma->level < 0) { + if (!read_preread(el)) + break; + } + if (ma->level < 0) + break; + + if (*ma->macro[ma->level] == 0) { + ma->level--; + continue; + } + *cp = *ma->macro[ma->level]++ & 0377; + if (*ma->macro[ma->level] == 0) { /* Needed for QuoteMode + * On */ + ma->level--; + } + return (1); } - return 1; - } #ifdef DEBUG_READ - (void) fprintf(el->el_errfile, "Turning raw mode on\n"); + (void) fprintf(el->el_errfile, "Turning raw mode on\n"); #endif /* DEBUG_READ */ - if (tty_rawmode(el) < 0) /* make sure the tty is set up correctly */ - return 0; + if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */ + return (0); #ifdef DEBUG_READ - (void) fprintf(el->el_errfile, "Reading a character\n"); + (void) fprintf(el->el_errfile, "Reading a character\n"); #endif /* DEBUG_READ */ - while ((num_read = read(el->el_infd, (char *) &tcp, 1)) == -1) - if (!tried && read__fixio(el->el_infd, errno) == 0) - tried = 1; - else { - *cp = '\0'; - return -1; - } + num_read = (*el->el_read.read_char)(el, cp); #ifdef DEBUG_READ - (void) fprintf(el->el_errfile, "Got it %c\n", tcp); + (void) fprintf(el->el_errfile, "Got it %c\n", *cp); #endif /* DEBUG_READ */ - *cp = tcp; - return num_read; + return (num_read); } - public const char * -el_gets(el, nread) - EditLine *el; - int *nread; +el_gets(EditLine *el, int *nread) { - int retval; - el_action_t cmdnum = 0; - int num; /* how many chars we have read at NL */ - char ch; - - if (el->el_flags & HANDLE_SIGNALS) - sig_set(el); - - re_clear_display(el); /* reset the display stuff */ - ch_reset(el); - + int retval; + el_action_t cmdnum = 0; + int num; /* how many chars we have read at NL */ + char ch; #ifdef FIONREAD - if (el->el_tty.t_mode == EX_IO && ma->level < 0) { - long chrs = 0; + c_macro_t *ma = &el->el_chared.c_macro; +#endif /* FIONREAD */ - (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) &chrs); - if (chrs == 0) { - if (tty_rawmode(el) < 0) { + if (el->el_flags & HANDLE_SIGNALS) + sig_set(el); + + if (el->el_flags & NO_TTY) { + char *cp = el->el_line.buffer; + size_t idx; + + while ((*el->el_read.read_char)(el, cp) == 1) { + /* make sure there is space for next character */ + if (cp + 1 >= el->el_line.limit) { + idx = (cp - el->el_line.buffer); + if (!ch_enlargebufs(el, 2)) + break; + cp = &el->el_line.buffer[idx]; + } + cp++; + if (cp[-1] == '\r' || cp[-1] == '\n') + break; + } + + el->el_line.cursor = el->el_line.lastchar = cp; + *cp = '\0'; if (nread) - *nread = 0; - return NULL; - } + *nread = el->el_line.cursor - el->el_line.buffer; + return (el->el_line.buffer); } - } -#endif /* FIONREAD */ + re_clear_display(el); /* reset the display stuff */ + ch_reset(el); - re_refresh(el); /* print the prompt */ +#ifdef FIONREAD + if (el->el_tty.t_mode == EX_IO && ma->level < 0) { + long chrs = 0; + + (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); + if (chrs == 0) { + if (tty_rawmode(el) < 0) { + if (nread) + *nread = 0; + return (NULL); + } + } + } +#endif /* FIONREAD */ - for (num = OKCMD; num == OKCMD;) { /* while still editing this line */ + re_refresh(el); /* print the prompt */ + + if (el->el_flags & EDIT_DISABLED) { + char *cp = el->el_line.buffer; + size_t idx; + + term__flush(); + + while ((*el->el_read.read_char)(el, cp) == 1) { + /* make sure there is space next character */ + if (cp + 1 >= el->el_line.limit) { + idx = (cp - el->el_line.buffer); + if (!ch_enlargebufs(el, 2)) + break; + cp = &el->el_line.buffer[idx]; + } + cp++; + if (cp[-1] == '\r' || cp[-1] == '\n') + break; + } + + el->el_line.cursor = el->el_line.lastchar = cp; + *cp = '\0'; + if (nread) + *nread = el->el_line.cursor - el->el_line.buffer; + return (el->el_line.buffer); + } + for (num = OKCMD; num == OKCMD;) { /* while still editing this + * line */ #ifdef DEBUG_EDIT - read_debug(el); + read_debug(el); #endif /* DEBUG_EDIT */ - /* if EOF or error */ - if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) { + /* if EOF or error */ + if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) { #ifdef DEBUG_READ - (void) fprintf(el->el_errfile, "Returning from el_gets %d\n", num); + (void) fprintf(el->el_errfile, + "Returning from el_gets %d\n", num); #endif /* DEBUG_READ */ - break; - } - - if (cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ + break; + } + if ((int) cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ #ifdef DEBUG_EDIT - (void) fprintf(el->el_errfile, - "ERROR: illegal command from key 0%o\r\n", ch); + (void) fprintf(el->el_errfile, + "ERROR: illegal command from key 0%o\r\n", ch); #endif /* DEBUG_EDIT */ - continue; /* try again */ - } - - /* now do the real command */ + continue; /* try again */ + } + /* now do the real command */ #ifdef DEBUG_READ - { - el_bindings_t *b; - for (b = el->el_map.help; b->name; b++) - if (b->func == cmdnum) - break; - if (b->name) - (void) fprintf(el->el_errfile, "Executing %s\n", b->name); - else - (void) fprintf(el->el_errfile, "Error command = %d\n", cmdnum); - } + { + el_bindings_t *b; + for (b = el->el_map.help; b->name; b++) + if (b->func == cmdnum) + break; + if (b->name) + (void) fprintf(el->el_errfile, + "Executing %s\n", b->name); + else + (void) fprintf(el->el_errfile, + "Error command = %d\n", cmdnum); + } #endif /* DEBUG_READ */ - retval = (*el->el_map.func[cmdnum])(el, ch); - - /* save the last command here */ - el->el_state.lastcmd = cmdnum; - - /* use any return value */ - switch (retval) { - case CC_CURSOR: - el->el_state.argument = 1; - el->el_state.doingarg = 0; - re_refresh_cursor(el); - break; - - case CC_REDISPLAY: - re_clear_lines(el); - re_clear_display(el); - /* FALLTHROUGH */ - - case CC_REFRESH: - el->el_state.argument = 1; - el->el_state.doingarg = 0; - re_refresh(el); - break; - - case CC_NORM: /* normal char */ - el->el_state.argument = 1; - el->el_state.doingarg = 0; - break; - - case CC_ARGHACK: /* Suggested by Rich Salz */ - /* <rsalz@pineapple.bbn.com> */ - break; /* keep going... */ - - case CC_EOF: /* end of file typed */ - num = 0; - break; - - case CC_NEWLINE: /* normal end of line */ - num = el->el_line.lastchar - el->el_line.buffer; - break; - - case CC_FATAL: /* fatal error, reset to known state */ + retval = (*el->el_map.func[cmdnum]) (el, ch); + + /* save the last command here */ + el->el_state.lastcmd = cmdnum; + + /* use any return value */ + switch (retval) { + case CC_CURSOR: + el->el_state.argument = 1; + el->el_state.doingarg = 0; + re_refresh_cursor(el); + break; + + case CC_REDISPLAY: + re_clear_lines(el); + re_clear_display(el); + /* FALLTHROUGH */ + + case CC_REFRESH: + el->el_state.argument = 1; + el->el_state.doingarg = 0; + re_refresh(el); + break; + + case CC_REFRESH_BEEP: + el->el_state.argument = 1; + el->el_state.doingarg = 0; + re_refresh(el); + term_beep(el); + break; + + case CC_NORM: /* normal char */ + el->el_state.argument = 1; + el->el_state.doingarg = 0; + break; + + case CC_ARGHACK: /* Suggested by Rich Salz */ + /* <rsalz@pineapple.bbn.com> */ + break; /* keep going... */ + + case CC_EOF: /* end of file typed */ + num = 0; + break; + + case CC_NEWLINE: /* normal end of line */ + num = el->el_line.lastchar - el->el_line.buffer; + break; + + case CC_FATAL: /* fatal error, reset to known state */ #ifdef DEBUG_READ - (void) fprintf(el->el_errfile, "*** editor fatal ERROR ***\r\n\n"); + (void) fprintf(el->el_errfile, + "*** editor fatal ERROR ***\r\n\n"); #endif /* DEBUG_READ */ - /* put (real) cursor in a known place */ - re_clear_display(el); /* reset the display stuff */ - ch_reset(el); /* reset the input pointers */ - re_refresh(el); /* print the prompt again */ - el->el_state.argument = 1; - el->el_state.doingarg = 0; - break; - - case CC_ERROR: - default: /* functions we don't know about */ + /* put (real) cursor in a known place */ + re_clear_display(el); /* reset the display stuff */ + ch_reset(el); /* reset the input pointers */ + re_refresh(el); /* print the prompt again */ + el->el_state.argument = 1; + el->el_state.doingarg = 0; + break; + + case CC_ERROR: + default: /* functions we don't know about */ #ifdef DEBUG_READ - (void) fprintf(el->el_errfile, "*** editor ERROR ***\r\n\n"); + (void) fprintf(el->el_errfile, + "*** editor ERROR ***\r\n\n"); #endif /* DEBUG_READ */ - el->el_state.argument = 1; - el->el_state.doingarg = 0; - term_beep(el); - term__flush(); - break; + el->el_state.argument = 1; + el->el_state.doingarg = 0; + term_beep(el); + term__flush(); + break; + } } - } - - (void) tty_cookedmode(el); /* make sure the tty is set up correctly */ - term__flush(); /* flush any buffered output */ - if (el->el_flags & HANDLE_SIGNALS) - sig_clr(el); - if (nread) - *nread = num; - return num ? el->el_line.buffer : NULL; + + /* make sure the tty is set up correctly */ + (void) tty_cookedmode(el); + term__flush(); /* flush any buffered output */ + if (el->el_flags & HANDLE_SIGNALS) + sig_clr(el); + if (nread) + *nread = num; + return (num ? el->el_line.buffer : NULL); } diff --git a/dist/read.h b/dist/read.h new file mode 100644 index 0000000..b01e77d --- /dev/null +++ b/dist/read.h @@ -0,0 +1,55 @@ +/* $NetBSD: read.h,v 1.1 2001/09/27 19:29:50 christos Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Anthony Mallet. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 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. + */ + +/* + * el.read.h: Character reading functions + */ +#ifndef _h_el_read +#define _h_el_read + +typedef int (*el_rfunc_t)(EditLine *, char *); + +typedef struct el_read_t { + el_rfunc_t read_char; /* Function to read a character */ +} el_read_t; + +protected int read_init(EditLine *); +protected int el_read_setfn(EditLine *, el_rfunc_t); +protected el_rfunc_t el_read_getfn(EditLine *); + +#endif /* _h_el_read */ diff --git a/dist/readline.c b/dist/readline.c new file mode 100644 index 0000000..6606976 --- /dev/null +++ b/dist/readline.c @@ -0,0 +1,1664 @@ +/* $NetBSD: readline.c,v 1.19 2001/01/10 08:10:45 jdolecek 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 <sys/cdefs.h> +#if !defined(lint) && !defined(SCCSID) +__RCSID("$NetBSD: readline.c,v 1.19 2001/01/10 08:10:45 jdolecek 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 "histedit.h" +#include "readline/readline.h" +#include "sys.h" +#include "el.h" +#include "fcns.h" /* for EL_NUM_FCNS */ + +/* for rl_complete() */ +#define TAB '\r' + +/* see comment at the #ifdef for sense of this */ +#define GDB_411_HACK + +/* readline compatibility stuff - look at readline sources/documentation */ +/* to see what these variables mean */ +const char *rl_library_version = "EditLine wrapper"; +char *rl_readline_name = ""; +FILE *rl_instream = NULL; +FILE *rl_outstream = NULL; +int rl_point = 0; +int rl_end = 0; +char *rl_line_buffer = NULL; + +int history_base = 1; /* probably never subject to change */ +int history_length = 0; +int max_input_history = 0; +char history_expansion_char = '!'; +char history_subst_char = '^'; +char *history_no_expand_chars = " \t\n=("; +Function *history_inhibit_expansion_function = NULL; + +int rl_inhibit_completion = 0; +int rl_attempted_completion_over = 0; +char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; +char *rl_completer_word_break_characters = NULL; +char *rl_completer_quote_characters = NULL; +CPFunction *rl_completion_entry_function = NULL; +CPPFunction *rl_attempted_completion_function = NULL; + +/* + * This is set to character indicating type of completion being done by + * rl_complete_internal(); this is available for application completion + * functions. + */ +int rl_completion_type = 0; + +/* + * If more than this number of items results from query for possible + * completions, we ask user if they are sure to really display the list. + */ +int rl_completion_query_items = 100; + +/* + * List of characters which are word break characters, but should be left + * in the parsed text when it is passed to the completion function. + * Shell uses this to help determine what kind of completing to do. + */ +char *rl_special_prefixes = (char *)NULL; + +/* + * This is the character appended to the completed words if at the end of + * the line. Default is ' ' (a space). + */ +int rl_completion_append_character = ' '; + +/* stuff below is used internally by libedit for readline emulation */ + +/* if not zero, non-unique completions always show list of possible matches */ +static int _rl_complete_show_all = 0; + +static History *h = NULL; +static EditLine *e = NULL; +static int el_rl_complete_cmdnum = 0; + +/* internal functions */ +static unsigned char _el_rl_complete(EditLine *, int); +static char *_get_prompt(EditLine *); +static HIST_ENTRY *_move_history(int); +static int _history_search_gen(const char *, int, int); +static int _history_expand_command(const char *, size_t, char **); +static char *_rl_compat_sub(const char *, const char *, + const char *, int); +static int rl_complete_internal(int); +static int _rl_qsort_string_compare(const void *, const void *); + +/* + * needed for prompt switching in readline() + */ +static char *el_rl_prompt = NULL; + + +/* ARGSUSED */ +static char * +_get_prompt(EditLine *el) +{ + return (el_rl_prompt); +} + + +/* + * generic function for moving around history + */ +static HIST_ENTRY * +_move_history(int op) +{ + HistEvent ev; + static HIST_ENTRY rl_he; + + if (history(h, &ev, op) != 0) + return (HIST_ENTRY *) NULL; + + rl_he.line = ev.str; + rl_he.data = ""; + + return (&rl_he); +} + + +/* + * READLINE compatibility stuff + */ + +/* + * initialize rl compat stuff + */ +int +rl_initialize(void) +{ + HistEvent ev; + const LineInfo *li; + int i; + int editmode = 1; + struct termios t; + + if (e != NULL) + el_end(e); + if (h != NULL) + history_end(h); + + if (!rl_instream) + rl_instream = stdin; + if (!rl_outstream) + rl_outstream = stdout; + + /* + * See if we don't really want to run the editor + */ + if (tcgetattr(fileno(rl_instream), &t) != -1 && (t.c_lflag & ECHO) == 0) + editmode = 0; + + e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr); + + if (!editmode) + el_set(e, EL_EDITMODE, 0); + + h = history_init(); + if (!e || !h) + return (-1); + + history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */ + history_length = 0; + max_input_history = INT_MAX; + el_set(e, EL_HIST, history, h); + + /* for proper prompt printing in readline() */ + el_rl_prompt = strdup(""); + el_set(e, EL_PROMPT, _get_prompt); + el_set(e, EL_SIGNAL, 1); + + /* set default mode to "emacs"-style and read setting afterwards */ + /* so this can be overriden */ + el_set(e, EL_EDITOR, "emacs"); + + /* + * Word completition - this has to go AFTER rebinding keys + * to emacs-style. + */ + el_set(e, EL_ADDFN, "rl_complete", + "ReadLine compatible completition function", + _el_rl_complete); + el_set(e, EL_BIND, "^I", "rl_complete", NULL); + + /* + * Find out where the rl_complete function was added; this is + * used later to detect that lastcmd was also rl_complete. + */ + for(i=EL_NUM_FCNS; i < e->el_map.nfunc; i++) { + if (e->el_map.func[i] == _el_rl_complete) { + el_rl_complete_cmdnum = i; + break; + } + } + + /* read settings from configuration file */ + el_source(e, NULL); + + /* + * Unfortunately, some applications really do use rl_point + * and rl_line_buffer directly. + */ + li = el_line(e); + /* LINTED const cast */ + rl_line_buffer = (char *) li->buffer; + rl_point = rl_end = 0; + + return (0); +} + + +/* + * read one line from input stream and return it, chomping + * trailing newline (if there is any) + */ +char * +readline(const char *prompt) +{ + HistEvent ev; + int count; + const char *ret; + + if (e == NULL || h == NULL) + rl_initialize(); + + /* update prompt accordingly to what has been passed */ + if (!prompt) + prompt = ""; + if (strcmp(el_rl_prompt, prompt) != 0) { + free(el_rl_prompt); + el_rl_prompt = strdup(prompt); + } + /* get one line from input stream */ + ret = el_gets(e, &count); + + if (ret && count > 0) { + char *foo; + int lastidx; + + foo = strdup(ret); + lastidx = count - 1; + if (foo[lastidx] == '\n') + foo[lastidx] = '\0'; + + ret = foo; + } else + ret = NULL; + + history(h, &ev, H_GETSIZE); + history_length = ev.num; + + /* LINTED const cast */ + return (char *) ret; +} + +/* + * history functions + */ + +/* + * is normally called before application starts to use + * history expansion functions + */ +void +using_history(void) +{ + if (h == NULL || e == NULL) + rl_initialize(); +} + + +/* + * substitute ``what'' with ``with'', returning resulting string; if + * globally == 1, substitutes all occurences of what, otherwise only the + * first one + */ +static char * +_rl_compat_sub(const char *str, const char *what, const char *with, + int globally) +{ + char *result; + const char *temp, *new; + int len, with_len, what_len, add; + size_t size, i; + + result = malloc((size = 16)); + temp = str; + with_len = strlen(with); + what_len = strlen(what); + len = 0; + do { + new = strstr(temp, what); + if (new) { + i = new - temp; + add = i + with_len; + if (i + add + 1 >= size) { + size += add + 1; + result = realloc(result, size); + } + (void) strncpy(&result[len], temp, i); + len += i; + (void) strcpy(&result[len], with); /* safe */ + len += with_len; + temp = new + what_len; + } else { + add = strlen(temp); + if (len + add + 1 >= size) { + size += add + 1; + result = realloc(result, size); + } + (void) strcpy(&result[len], temp); /* safe */ + len += add; + temp = NULL; + } + } while (temp && globally); + result[len] = '\0'; + + return (result); +} + + +/* + * the real function doing history expansion - takes as argument command + * to do and data upon which the command should be executed + * does expansion the way I've understood readline documentation + * word designator ``%'' isn't supported (yet ?) + * + * returns 0 if data was not modified, 1 if it was and 2 if the string + * should be only printed and not executed; in case of error, + * returns -1 and *result points to NULL + * it's callers responsibility to free() string returned in *result + */ +static int +_history_expand_command(const char *command, size_t cmdlen, char **result) +{ + char **arr, *tempcmd, *line, *search = NULL, *cmd; + const char *event_data = NULL; + static char *from = NULL, *to = NULL; + int start = -1, end = -1, max, i, idx; + int h_on = 0, t_on = 0, r_on = 0, e_on = 0, p_on = 0, g_on = 0; + int event_num = 0, retval; + size_t cmdsize; + + *result = NULL; + + cmd = alloca(cmdlen + 1); + (void) strncpy(cmd, command, cmdlen); + cmd[cmdlen] = 0; + + idx = 1; + /* find out which event to take */ + if (cmd[idx] == history_expansion_char) { + event_num = history_length; + idx++; + } else { + int off, num; + size_t len; + off = idx; + while (cmd[off] && !strchr(":^$*-%", cmd[off])) + off++; + num = atoi(&cmd[idx]); + if (num != 0) { + event_num = num; + if (num < 0) + event_num += history_length + 1; + } else { + int prefix = 1, curr_num; + HistEvent ev; + + len = off - idx; + if (cmd[idx] == '?') { + idx++, len--; + if (cmd[off - 1] == '?') + len--; + else if (cmd[off] != '\n' && cmd[off] != '\0') + return (-1); + prefix = 0; + } + search = alloca(len + 1); + (void) strncpy(search, &cmd[idx], len); + search[len] = '\0'; + + if (history(h, &ev, H_CURR) != 0) + return (-1); + curr_num = ev.num; + + if (prefix) + retval = history_search_prefix(search, -1); + else + retval = history_search(search, -1); + + if (retval == -1) { + fprintf(rl_outstream, "%s: Event not found\n", + search); + return (-1); + } + if (history(h, &ev, H_CURR) != 0) + return (-1); + event_data = ev.str; + + /* roll back to original position */ + history(h, &ev, H_NEXT_EVENT, curr_num); + } + idx = off; + } + + if (!event_data && event_num >= 0) { + HIST_ENTRY *rl_he; + rl_he = history_get(event_num); + if (!rl_he) + return (0); + event_data = rl_he->line; + } else + return (-1); + + if (cmd[idx] != ':') + return (-1); + cmd += idx + 1; + + /* recognize cmd */ + if (*cmd == '^') + start = end = 1, cmd++; + else if (*cmd == '$') + start = end = -1, cmd++; + else if (*cmd == '*') + start = 1, end = -1, cmd++; + else if (isdigit((unsigned char) *cmd)) { + const char *temp; + int shifted = 0; + + start = atoi(cmd); + temp = cmd; + for (; isdigit((unsigned char) *cmd); cmd++); + if (temp != cmd) + shifted = 1; + if (shifted && *cmd == '-') { + if (!isdigit((unsigned char) *(cmd + 1))) + end = -2; + else { + end = atoi(cmd + 1); + for (; isdigit((unsigned char) *cmd); cmd++); + } + } else if (shifted && *cmd == '*') + end = -1, cmd++; + else if (shifted) + end = start; + } + if (*cmd == ':') + cmd++; + + line = strdup(event_data); + for (; *cmd; cmd++) { + if (*cmd == ':') + continue; + else if (*cmd == 'h') + h_on = 1 | g_on, g_on = 0; + else if (*cmd == 't') + t_on = 1 | g_on, g_on = 0; + else if (*cmd == 'r') + r_on = 1 | g_on, g_on = 0; + else if (*cmd == 'e') + e_on = 1 | g_on, g_on = 0; + else if (*cmd == 'p') + p_on = 1 | g_on, g_on = 0; + else if (*cmd == 'g') + g_on = 2; + else if (*cmd == 's' || *cmd == '&') { + char *what, *with, delim; + int len, from_len; + size_t size; + + if (*cmd == '&' && (from == NULL || to == NULL)) + continue; + else if (*cmd == 's') { + delim = *(++cmd), cmd++; + size = 16; + what = realloc(from, size); + len = 0; + for (; *cmd && *cmd != delim; cmd++) { + if (*cmd == '\\' + && *(cmd + 1) == delim) + cmd++; + if (len >= size) + what = realloc(what, + (size <<= 1)); + what[len++] = *cmd; + } + what[len] = '\0'; + from = what; + if (*what == '\0') { + free(what); + if (search) + from = strdup(search); + else { + from = NULL; + return (-1); + } + } + cmd++; /* shift after delim */ + if (!*cmd) + continue; + + size = 16; + with = realloc(to, size); + len = 0; + from_len = strlen(from); + for (; *cmd && *cmd != delim; cmd++) { + if (len + from_len + 1 >= size) { + size += from_len + 1; + with = realloc(with, size); + } + if (*cmd == '&') { + /* safe */ + (void) strcpy(&with[len], from); + len += from_len; + continue; + } + if (*cmd == '\\' + && (*(cmd + 1) == delim + || *(cmd + 1) == '&')) + cmd++; + with[len++] = *cmd; + } + with[len] = '\0'; + to = with; + + tempcmd = _rl_compat_sub(line, from, to, + (g_on) ? 1 : 0); + free(line); + line = tempcmd; + g_on = 0; + } + } + } + + arr = history_tokenize(line); + free(line); /* no more needed */ + if (arr && *arr == NULL) + free(arr), arr = NULL; + if (!arr) + return (-1); + + /* find out max valid idx to array of array */ + max = 0; + for (i = 0; arr[i]; i++) + max++; + max--; + + /* set boundaries to something relevant */ + if (start < 0) + start = 1; + if (end < 0) + end = max - ((end < -1) ? 1 : 0); + + /* check boundaries ... */ + if (start > max || end > max || start > end) + return (-1); + + for (i = 0; i <= max; i++) { + char *temp; + if (h_on && (i == 1 || h_on > 1) && + (temp = strrchr(arr[i], '/'))) + *(temp + 1) = '\0'; + if (t_on && (i == 1 || t_on > 1) && + (temp = strrchr(arr[i], '/'))) + (void) strcpy(arr[i], temp + 1); + if (r_on && (i == 1 || r_on > 1) && + (temp = strrchr(arr[i], '.'))) + *temp = '\0'; + if (e_on && (i == 1 || e_on > 1) && + (temp = strrchr(arr[i], '.'))) + (void) strcpy(arr[i], temp); + } + + cmdsize = 1, cmdlen = 0; + tempcmd = malloc(cmdsize); + for (i = start; start <= i && i <= end; i++) { + int arr_len; + + arr_len = strlen(arr[i]); + if (cmdlen + arr_len + 1 >= cmdsize) { + cmdsize += arr_len + 1; + tempcmd = realloc(tempcmd, cmdsize); + } + (void) strcpy(&tempcmd[cmdlen], arr[i]); /* safe */ + cmdlen += arr_len; + tempcmd[cmdlen++] = ' '; /* add a space */ + } + while (cmdlen > 0 && isspace((unsigned char) tempcmd[cmdlen - 1])) + cmdlen--; + tempcmd[cmdlen] = '\0'; + + *result = tempcmd; + + for (i = 0; i <= max; i++) + free(arr[i]); + free(arr), arr = (char **) NULL; + return (p_on) ? 2 : 1; +} + + +/* + * csh-style history expansion + */ +int +history_expand(char *str, char **output) +{ + int i, retval = 0, idx; + size_t size; + char *temp, *result; + + if (h == NULL || e == NULL) + rl_initialize(); + + *output = strdup(str); /* do it early */ + + if (str[0] == history_subst_char) { + /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */ + temp = alloca(4 + strlen(str) + 1); + temp[0] = temp[1] = history_expansion_char; + temp[2] = ':'; + temp[3] = 's'; + (void) strcpy(temp + 4, str); + str = temp; + } +#define ADD_STRING(what, len) \ + { \ + if (idx + len + 1 > size) \ + result = realloc(result, (size += len + 1)); \ + (void)strncpy(&result[idx], what, len); \ + idx += len; \ + result[idx] = '\0'; \ + } + + result = NULL; + size = idx = 0; + for (i = 0; str[i];) { + int start, j, loop_again; + size_t len; + + loop_again = 1; + start = j = i; +loop: + for (; str[j]; j++) { + if (str[j] == '\\' && + str[j + 1] == history_expansion_char) { + (void) strcpy(&str[j], &str[j + 1]); + continue; + } + if (!loop_again) { + if (str[j] == '?') { + while (str[j] && str[++j] != '?'); + if (str[j] == '?') + j++; + } else if (isspace((unsigned char) str[j])) + break; + } + if (str[j] == history_expansion_char + && !strchr(history_no_expand_chars, str[j + 1]) + && (!history_inhibit_expansion_function || + (*history_inhibit_expansion_function)(str, j) == 0)) + break; + } + + if (str[j] && str[j + 1] != '#' && loop_again) { + i = j; + j++; + if (str[j] == history_expansion_char) + j++; + loop_again = 0; + goto loop; + } + len = i - start; + temp = &str[start]; + ADD_STRING(temp, len); + + if (str[i] == '\0' || str[i] != history_expansion_char + || str[i + 1] == '#') { + len = j - i; + temp = &str[i]; + ADD_STRING(temp, len); + if (start == 0) + retval = 0; + else + retval = 1; + break; + } + retval = _history_expand_command(&str[i], (size_t) (j - i), + &temp); + if (retval != -1) { + len = strlen(temp); + ADD_STRING(temp, len); + } + i = j; + } /* for(i ...) */ + + if (retval == 2) { + add_history(temp); +#ifdef GDB_411_HACK + /* gdb 4.11 has been shipped with readline, where */ + /* history_expand() returned -1 when the line */ + /* should not be executed; in readline 2.1+ */ + /* it should return 2 in such a case */ + retval = -1; +#endif + } + free(*output); + *output = result; + + return (retval); +} + + +/* + * Parse the string into individual tokens, similarily to how shell would do it. + */ +char ** +history_tokenize(const char *str) +{ + int size = 1, result_idx = 0, i, start; + size_t len; + char **result = NULL, *temp, delim = '\0'; + + for (i = 0; str[i]; i++) { + while (isspace((unsigned char) str[i])) + i++; + start = i; + for (; str[i]; i++) { + if (str[i] == '\\') { + if (str[i+1] != '\0') + i++; + } else if (str[i] == delim) + delim = '\0'; + else if (!delim && + (isspace((unsigned char) str[i]) || + strchr("()<>;&|$", str[i]))) + break; + else if (!delim && strchr("'`\"", str[i])) + delim = str[i]; + } + + if (result_idx + 2 >= size) { + size <<= 1; + result = realloc(result, size * sizeof(char *)); + } + len = i - start; + temp = malloc(len + 1); + (void) strncpy(temp, &str[start], len); + temp[len] = '\0'; + result[result_idx++] = temp; + result[result_idx] = NULL; + } + + return (result); +} + + +/* + * limit size of history record to ``max'' events + */ +void +stifle_history(int max) +{ + HistEvent ev; + + if (h == NULL || e == NULL) + rl_initialize(); + + if (history(h, &ev, H_SETSIZE, max) == 0) + max_input_history = max; +} + + +/* + * "unlimit" size of history - set the limit to maximum allowed int value + */ +int +unstifle_history(void) +{ + HistEvent ev; + int omax; + + history(h, &ev, H_SETSIZE, INT_MAX); + omax = max_input_history; + max_input_history = INT_MAX; + return (omax); /* some value _must_ be returned */ +} + + +int +history_is_stifled(void) +{ + + /* cannot return true answer */ + return (max_input_history != INT_MAX); +} + + +/* + * read history from a file given + */ +int +read_history(const char *filename) +{ + HistEvent ev; + + if (h == NULL || e == NULL) + rl_initialize(); + return (history(h, &ev, H_LOAD, filename)); +} + + +/* + * write history to a file given + */ +int +write_history(const char *filename) +{ + HistEvent ev; + + if (h == NULL || e == NULL) + rl_initialize(); + return (history(h, &ev, H_SAVE, filename)); +} + + +/* + * returns history ``num''th event + * + * returned pointer points to static variable + */ +HIST_ENTRY * +history_get(int num) +{ + static HIST_ENTRY she; + HistEvent ev; + int i = 1, curr_num; + + if (h == NULL || e == NULL) + rl_initialize(); + + /* rewind to beginning */ + if (history(h, &ev, H_CURR) != 0) + return (NULL); + curr_num = ev.num; + if (history(h, &ev, H_LAST) != 0) + return (NULL); /* error */ + while (i < num && history(h, &ev, H_PREV) == 0) + i++; + if (i != num) + return (NULL); /* not so many entries */ + + she.line = ev.str; + she.data = NULL; + + /* rewind history to the same event it was before */ + (void) history(h, &ev, H_FIRST); + (void) history(h, &ev, H_NEXT_EVENT, curr_num); + + return (&she); +} + + +/* + * add the line to history table + */ +int +add_history(const char *line) +{ + HistEvent ev; + + if (h == NULL || e == NULL) + rl_initialize(); + + (void) history(h, &ev, H_ENTER, line); + if (history(h, &ev, H_GETSIZE) == 0) + history_length = ev.num; + + return (!(history_length > 0)); /* return 0 if all is okay */ +} + + +/* + * clear the history list - delete all entries + */ +void +clear_history(void) +{ + HistEvent ev; + + history(h, &ev, H_CLEAR); +} + + +/* + * returns offset of the current history event + */ +int +where_history(void) +{ + HistEvent ev; + int curr_num, off; + + if (history(h, &ev, H_CURR) != 0) + return (0); + curr_num = ev.num; + + history(h, &ev, H_FIRST); + off = 1; + while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0) + off++; + + return (off); +} + + +/* + * returns current history event or NULL if there is no such event + */ +HIST_ENTRY * +current_history(void) +{ + + return (_move_history(H_CURR)); +} + + +/* + * returns total number of bytes history events' data are using + */ +int +history_total_bytes(void) +{ + HistEvent ev; + int curr_num, size; + + if (history(h, &ev, H_CURR) != 0) + return (-1); + curr_num = ev.num; + + history(h, &ev, H_FIRST); + size = 0; + do + size += strlen(ev.str); + while (history(h, &ev, H_NEXT) == 0); + + /* get to the same position as before */ + history(h, &ev, H_PREV_EVENT, curr_num); + + return (size); +} + + +/* + * sets the position in the history list to ``pos'' + */ +int +history_set_pos(int pos) +{ + HistEvent ev; + int off, curr_num; + + if (pos > history_length || pos < 0) + return (-1); + + history(h, &ev, H_CURR); + curr_num = ev.num; + history(h, &ev, H_FIRST); + off = 0; + while (off < pos && history(h, &ev, H_NEXT) == 0) + off++; + + if (off != pos) { /* do a rollback in case of error */ + history(h, &ev, H_FIRST); + history(h, &ev, H_NEXT_EVENT, curr_num); + return (-1); + } + return (0); +} + + +/* + * returns previous event in history and shifts pointer accordingly + */ +HIST_ENTRY * +previous_history(void) +{ + + return (_move_history(H_PREV)); +} + + +/* + * returns next event in history and shifts pointer accordingly + */ +HIST_ENTRY * +next_history(void) +{ + + return (_move_history(H_NEXT)); +} + + +/* + * generic history search function + */ +static int +_history_search_gen(const char *str, int direction, int pos) +{ + HistEvent ev; + const char *strp; + int curr_num; + + if (history(h, &ev, H_CURR) != 0) + return (-1); + curr_num = ev.num; + + for (;;) { + strp = strstr(ev.str, str); + if (strp && (pos < 0 || &ev.str[pos] == strp)) + return (int) (strp - ev.str); + if (history(h, &ev, direction < 0 ? H_PREV : H_NEXT) != 0) + break; + } + + history(h, &ev, direction < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); + + return (-1); +} + + +/* + * searches for first history event containing the str + */ +int +history_search(const char *str, int direction) +{ + + return (_history_search_gen(str, direction, -1)); +} + + +/* + * searches for first history event beginning with str + */ +int +history_search_prefix(const char *str, int direction) +{ + + return (_history_search_gen(str, direction, 0)); +} + + +/* + * search for event in history containing str, starting at offset + * abs(pos); continue backward, if pos<0, forward otherwise + */ +/* ARGSUSED */ +int +history_search_pos(const char *str, int direction, int pos) +{ + HistEvent ev; + int curr_num, off; + + off = (pos > 0) ? pos : -pos; + pos = (pos > 0) ? 1 : -1; + + if (history(h, &ev, H_CURR) != 0) + return (-1); + curr_num = ev.num; + + if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0) + return (-1); + + + for (;;) { + if (strstr(ev.str, str)) + return (off); + if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0) + break; + } + + /* set "current" pointer back to previous state */ + history(h, &ev, (pos < 0) ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); + + return (-1); +} + + +/********************************/ +/* completition 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 * +tilde_expand(char *txt) +{ + struct passwd *pass; + char *temp; + size_t len = 0; + + if (txt[0] != '~') + return (strdup(txt)); + + temp = strchr(txt + 1, '/'); + if (temp == NULL) + temp = strdup(txt + 1); + else { + len = temp - txt + 1; /* text until string after slash */ + temp = malloc(len); + (void) strncpy(temp, txt + 1, len - 2); + temp[len - 2] = '\0'; + } + pass = getpwnam(temp); + 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); + (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 * +filename_completion_function(const char *text, int state) +{ + static DIR *dir = NULL; + static char *filename = NULL, *dirname = NULL; + static size_t filename_len = 0; + struct dirent *entry; + char *temp; + size_t len; + + if (state == 0 || dir == NULL) { + if (dir != NULL) { + closedir(dir); + dir = NULL; + } + temp = strrchr(text, '/'); + if (temp) { + temp++; + filename = realloc(filename, strlen(temp) + 1); + (void) strcpy(filename, temp); + len = temp - text; /* including last slash */ + dirname = realloc(dirname, len + 1); + (void) strncpy(dirname, text, len); + dirname[len] = '\0'; + } else { + filename = strdup(text); + dirname = NULL; + } + + /* support for ``~user'' syntax */ + if (dirname && *dirname == '~') { + temp = tilde_expand(dirname); + dirname = realloc(dirname, strlen(temp) + 1); + (void) strcpy(dirname, temp); /* safe */ + free(temp); /* no longer needed */ + } + /* will be used in cycle */ + filename_len = strlen(filename); + if (filename_len == 0) + return (NULL); /* no expansion possible */ + + dir = opendir(dirname ? dirname : "."); + if (!dir) + return (NULL); /* cannot open the directory */ + } + /* find the match */ + while ((entry = readdir(dir)) != NULL) { + /* 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 */ + + struct stat stbuf; +#if defined(__SVR4) || defined(__linux__) + len = strlen(entry->d_name) + +#else + len = entry->d_namlen + +#endif + ((dirname) ? strlen(dirname) : 0) + 1 + 1; + temp = malloc(len); + (void) sprintf(temp, "%s%s", + dirname ? dirname : "", entry->d_name); /* safe */ + + /* test, if it's directory */ + if (stat(temp, &stbuf) == 0 && S_ISDIR(stbuf.st_mode)) + strcat(temp, "/"); /* safe */ + } else + temp = NULL; + + return (temp); +} + + +/* + * a completion generator for usernames; returns _first_ username + * which starts with supplied text + * text contains a partial username preceded by random character + * (usually '~'); state is ignored + * it's callers responsibility to free returned value + */ +char * +username_completion_function(const char *text, int state) +{ + struct passwd *pwd; + + if (text[0] == '\0') + return (NULL); + + if (*text == '~') + text++; + + if (state == 0) + setpwent(); + + while ((pwd = getpwent()) && text[0] == pwd->pw_name[0] + && strcmp(text, pwd->pw_name) == 0); + + if (pwd == NULL) { + endpwent(); + return (NULL); + } + return (strdup(pwd->pw_name)); +} + + +/* + * el-compatible wrapper around rl_complete; needed for key binding + */ +/* ARGSUSED */ +static unsigned char +_el_rl_complete(EditLine *el, int ch) +{ + return (unsigned char) rl_complete(0, ch); +} + + +/* + * returns list of completitions for text given + */ +char ** +completion_matches(const char *text, CPFunction *genfunc) +{ + char **match_list = NULL, *retstr, *prevstr; + size_t match_list_len, max_equal, which, i; + int matches; + + if (h == NULL || e == NULL) + rl_initialize(); + + matches = 0; + match_list_len = 1; + while ((retstr = (*genfunc) (text, matches)) != NULL) { + if (matches + 1 >= match_list_len) { + match_list_len <<= 1; + match_list = realloc(match_list, + match_list_len * sizeof(char *)); + } + match_list[++matches] = retstr; + } + + if (!match_list) + return (char **) 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); + (void) strncpy(retstr, match_list[1], max_equal); + retstr[max_equal] = '\0'; + match_list[0] = retstr; + + /* add NULL as last pointer to the array */ + if (matches + 1 >= match_list_len) + match_list = realloc(match_list, + (match_list_len + 1) * sizeof(char *)); + match_list[matches + 1] = (char *) NULL; + + return (match_list); +} + +/* + * Sort function for qsort(). Just wrapper around strcasecmp(). + */ +static int +_rl_qsort_string_compare(i1, i2) + const void *i1, *i2; +{ + /*LINTED const castaway*/ + const char *s1 = ((const char **)i1)[0]; + /*LINTED const castaway*/ + const char *s2 = ((const char **)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 +rl_display_match_list (matches, len, max) + char **matches; + int len, max; +{ + int i, idx, limit, count; + int screenwidth = e->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 *), + _rl_qsort_string_compare); + + idx = 1; + for(; count > 0; count--) { + for(i=0; i < limit && matches[idx]; i++, idx++) + fprintf(e->el_outfile, "%-*s ", max, matches[idx]); + fprintf(e->el_outfile, "\n"); + } +} + +/* + * Complete the word at or before point, called by rl_complete() + * 'what_to_do' says what to do with the completion. + * `?' means list the possible completions. + * TAB means do standard completion. + * `*' 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 + */ +static int +rl_complete_internal(int what_to_do) +{ + CPFunction *complet_func; + const LineInfo *li; + char *temp, **matches; + const char *ctemp; + size_t len; + + rl_completion_type = what_to_do; + + if (h == NULL || e == NULL) + rl_initialize(); + + complet_func = rl_completion_entry_function; + if (!complet_func) + complet_func = filename_completion_function; + + /* We now look backwards for the start of a filename/variable word */ + li = el_line(e); + ctemp = (const char *) li->cursor; + while (ctemp > li->buffer + && !strchr(rl_basic_word_break_characters, ctemp[-1]) + && (!rl_special_prefixes + || !strchr(rl_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 (*rl_attempted_completion_function)() */ + rl_point = li->cursor - li->buffer; + rl_end = li->lastchar - li->buffer; + + if (!rl_attempted_completion_function) + matches = completion_matches(temp, complet_func); + else { + int end = li->cursor - li->buffer; + matches = (*rl_attempted_completion_function) (temp, (int) + (end - len), end); + } + + 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(e, (int) len); + el_insertstr(e, 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 completition and the + * object is a directory. + */ + size_t alen = strlen(matches[0]); + if ((complet_func != filename_completion_function + || (alen > 0 && (matches[0])[alen - 1] != '/')) + && rl_completion_append_character) { + char buf[2]; + buf[0] = rl_completion_append_character; + buf[1] = '\0'; + el_insertstr(e, buf); + } + } 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 */ + fprintf(e->el_outfile, "\n"); + + /* + * If there are too many items, ask user for display + * confirmation. + */ + if (matches_num > rl_completion_query_items) { + fprintf(e->el_outfile, + "Display all %d possibilities? (y or n) ", + matches_num); + fflush(e->el_outfile); + if (getc(stdin) != 'y') + match_display = 0; + fprintf(e->el_outfile, "\n"); + } + + if (match_display) + rl_display_match_list(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(e); + } else { + /* lcd is not a valid object - further specification */ + /* is needed */ + el_beep(e); + 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); +} + + +/* + * complete word at current point + */ +int +rl_complete(int ignore, int invoking_key) +{ + if (h == NULL || e == NULL) + rl_initialize(); + + if (rl_inhibit_completion) { + rl_insert(ignore, invoking_key); + return (CC_REFRESH); + } else if (e->el_state.lastcmd == el_rl_complete_cmdnum) + return rl_complete_internal('?'); + else if (_rl_complete_show_all) + return rl_complete_internal('!'); + else + return (rl_complete_internal(TAB)); +} + + +/* + * misc other functions + */ + +/* + * bind key c to readline-type function func + */ +int +rl_bind_key(int c, int func(int, int)) +{ + int retval = -1; + + if (h == NULL || e == NULL) + rl_initialize(); + + if (func == rl_insert) { + /* XXX notice there is no range checking of ``c'' */ + e->el_map.key[c] = ED_INSERT; + retval = 0; + } + return (retval); +} + + +/* + * read one key from input - handles chars pushed back + * to input stream also + */ +int +rl_read_key(void) +{ + char fooarr[2 * sizeof(int)]; + + if (e == NULL || h == NULL) + rl_initialize(); + + return (el_getc(e, fooarr)); +} + + +/* + * reset the terminal + */ +/* ARGSUSED */ +void +rl_reset_terminal(const char *p) +{ + + if (h == NULL || e == NULL) + rl_initialize(); + el_reset(e); +} + + +/* + * insert character ``c'' back into input stream, ``count'' times + */ +int +rl_insert(int count, int c) +{ + char arr[2]; + + if (h == NULL || e == NULL) + rl_initialize(); + + /* XXX - int -> char conversion can lose on multichars */ + arr[0] = c; + arr[1] = '\0'; + + for (; count > 0; count--) + el_push(e, arr); + + return (0); +} diff --git a/dist/readline/Makefile b/dist/readline/Makefile new file mode 100644 index 0000000..ea8f093 --- /dev/null +++ b/dist/readline/Makefile @@ -0,0 +1,13 @@ +# $NetBSD: Makefile,v 1.4 2001/05/16 07:09:26 enami Exp $ + +.PATH: ${CURDIR}/.. + +INCS= readline.h +INCSDIR= /usr/include/readline +SYMLINKS= readline.h ${INCSDIR}/history.h + +MKOBJ= no + +incinstall:: linksinstall + +.include <bsd.prog.mk> diff --git a/dist/readline/readline.h b/dist/readline/readline.h new file mode 100644 index 0000000..cd59a4c --- /dev/null +++ b/dist/readline/readline.h @@ -0,0 +1,114 @@ +/* $NetBSD: readline.h,v 1.1 2001/01/05 21:15:50 jdolecek 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 _READLINE_H_ +#define _READLINE_H_ + +#include <sys/types.h> + +/* list of readline stuff supported by editline library's readline wrapper */ + +/* typedefs */ +typedef int Function(const char *, int); +typedef void VFunction(void); +typedef char *CPFunction(const char *, int); +typedef char **CPPFunction(const char *, int, int); + +typedef struct _hist_entry { + const char *line; + const char *data; +} HIST_ENTRY; + +/* global variables used by readline enabled applications */ +__BEGIN_DECLS +extern const char *rl_library_version; +extern char *rl_readline_name; +extern FILE *rl_instream; +extern FILE *rl_outstream; +extern char *rl_line_buffer; +extern int rl_point, rl_end; +extern int history_base, history_length; +extern int max_input_history; +extern char *rl_basic_word_break_characters; +extern char *rl_completer_word_break_characters; +extern char *rl_completer_quote_characters; +extern CPFunction *rl_completion_entry_function; +extern CPPFunction *rl_attempted_completion_function; +extern int rl_completion_type; +extern int rl_completion_query_items; +extern char *rl_special_prefixes; +extern int rl_completion_append_character; + +/* supported functions */ +char *readline(const char *); +int rl_initialize(void); + +void using_history(void); +int add_history(const char *); +void clear_history(void); +void stifle_history(int); +int unstifle_history(void); +int history_is_stifled(void); +int where_history(void); +HIST_ENTRY *current_history(void); +HIST_ENTRY *history_get(int); +int history_total_bytes(void); +int history_set_pos(int); +HIST_ENTRY *previous_history(void); +HIST_ENTRY *next_history(void); +int history_search(const char *, int); +int history_search_prefix(const char *, int); +int history_search_pos(const char *, int, int); +int read_history(const char *); +int write_history(const char *); +int history_expand(char *, char **); +char **history_tokenize(const char *); + +char *tilde_expand(char *); +char *filename_completion_function(const char *, int); +char *username_completion_function(const char *, int); +int rl_complete(int, int); +int rl_read_key(void); +char **completion_matches(const char *, CPFunction *); +void rl_display_match_list(char **, int, int); + +int rl_insert(int, int); +void rl_reset_terminal(const char *); +int rl_bind_key(int, int (*)(int, int)); +__END_DECLS + +#endif /* _READLINE_H_ */ diff --git a/dist/refresh.c b/dist/refresh.c index 304b806..b2ef6e4 100644 --- a/dist/refresh.c +++ b/dist/refresh.c @@ -1,4 +1,4 @@ -/* $NetBSD: refresh.c,v 1.2 1997/01/11 06:48:07 lukem Exp $ */ +/* $NetBSD: refresh.c,v 1.17 2001/04/13 00:53:11 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,11 +36,12 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: refresh.c,v 1.2 1997/01/11 06:48:07 lukem Exp $"; +__RCSID("$NetBSD: refresh.c,v 1.17 2001/04/13 00:53:11 lukem Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -55,43 +56,40 @@ static char rcsid[] = "$NetBSD: refresh.c,v 1.2 1997/01/11 06:48:07 lukem Exp $" #include "el.h" -private void re_addc __P((EditLine *, int)); -private void re_update_line __P((EditLine *, char *, char *, int)); -private void re_insert __P((EditLine *, char *, int, int, - char *, int)); -private void re_delete __P((EditLine *, char *, int, int, - int)); -private void re_fastputc __P((EditLine *, int)); - -private void re__strncopy __P((char *, char *, size_t)); -private void re__copy_and_pad __P((char *, char *, size_t)); +private void re_addc(EditLine *, int); +private void re_update_line(EditLine *, char *, char *, int); +private void re_insert (EditLine *, char *, int, int, char *, int); +private void re_delete(EditLine *, char *, int, int, int); +private void re_fastputc(EditLine *, int); +private void re__strncopy(char *, char *, size_t); +private void re__copy_and_pad(char *, char *, size_t); #ifdef DEBUG_REFRESH -private void re_printstr __P((EditLine *, char *, char *, - char *)); -# define __F el->el_errfile -# define RE_DEBUG(a, b, c) do \ +private void re_printstr(EditLine *, char *, char *, char *); +#define __F el->el_errfile +#define ELRE_ASSERT(a, b, c) do \ if (a) { \ (void) fprintf b; \ c; \ } \ while (0) +#define ELRE_DEBUG(a, b) ELRE_ASSERT(a,b,;) + /* re_printstr(): * Print a string on the debugging pty */ private void -re_printstr(el, str, f, t) - EditLine *el; - char *str; - char *f, *t; +re_printstr(EditLine *el, char *str, char *f, char *t) { - RE_DEBUG(1,(__F, "%s:\"", str),); - while (f < t) - RE_DEBUG(1,(__F, "%c", *f++ & 0177),); - RE_DEBUG(1,(__F, "\"\r\n"),); -} + + ELRE_DEBUG(1, (__F, "%s:\"", str)); + while (f < t) + ELRE_DEBUG(1, (__F, "%c", *f++ & 0177)); + ELRE_DEBUG(1, (__F, "\"\r\n")); +} #else -# define RE_DEBUG(a, b, c) +#define ELRE_ASSERT(a, b, c) +#define ELRE_DEBUG(a, b) #endif @@ -99,66 +97,87 @@ re_printstr(el, str, f, t) * Draw c, expanding tabs, control chars etc. */ private void -re_addc(el, c) - EditLine *el; - int c; +re_addc(EditLine *el, int c) { - if (isprint(c)) { - re_putc(el, c); - return; - } - if (c == '\n') { /* expand the newline */ - re_putc(el, '\0'); /* assure end of line */ - el->el_refresh.r_cursor.h = 0; /* reset cursor pos */ - el->el_refresh.r_cursor.v++; - return; - } - if (c == '\t') { /* expand the tab */ - for (;;) { - re_putc(el, ' '); - if ((el->el_refresh.r_cursor.h & 07) == 0) - break; /* go until tab stop */ + + if (isprint(c)) { + re_putc(el, c, 1); + return; + } + if (c == '\n') { /* expand the newline */ + int oldv = el->el_refresh.r_cursor.v; + re_putc(el, '\0', 0); /* assure end of line */ + if (oldv == el->el_refresh.r_cursor.v) { /* XXX */ + el->el_refresh.r_cursor.h = 0; /* reset cursor pos */ + el->el_refresh.r_cursor.v++; + } + return; + } + if (c == '\t') { /* expand the tab */ + for (;;) { + re_putc(el, ' ', 1); + if ((el->el_refresh.r_cursor.h & 07) == 0) + break; /* go until tab stop */ + } + } else if (iscntrl(c)) { + re_putc(el, '^', 1); + if (c == '\177') + re_putc(el, '?', 1); + else + /* uncontrolify it; works only for iso8859-1 like sets */ + re_putc(el, (c | 0100), 1); + } else { + re_putc(el, '\\', 1); + re_putc(el, (int) ((((unsigned int) c >> 6) & 07) + '0'), 1); + re_putc(el, (int) ((((unsigned int) c >> 3) & 07) + '0'), 1); + re_putc(el, (c & 07) + '0', 1); } - } - else if (iscntrl(c)) { - re_putc(el, '^'); - if (c == '\177') - re_putc(el, '?'); - else - /* uncontrolify it; works only for iso8859-1 like sets */ - re_putc(el, (c | 0100)); - } - else { - re_putc(el, '\\'); - re_putc(el, ((c >> 6) & 07) + '0'); - re_putc(el, ((c >> 3) & 07) + '0'); - re_putc(el, (c & 07) + '0'); - } -} /* end re_addc */ +} /* re_putc(): * Draw the character given */ protected void -re_putc(el, c) - EditLine *el; - int c; +re_putc(EditLine *el, int c, int shift) { - RE_DEBUG(1,(__F, "printing %3.3o '%c'\r\n", c, c),); - - el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_refresh.r_cursor.h] = c; - el->el_refresh.r_cursor.h++; /* advance to next place */ - if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) { - el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h] = '\0'; - /* assure end of line */ - el->el_refresh.r_cursor.h = 0; /* reset it. */ - el->el_refresh.r_cursor.v++; - RE_DEBUG(el->el_refresh.r_cursor.v >= el->el_term.t_size.v, - (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n", - el->el_refresh.r_cursor.v, el->el_term.t_size.v), abort()); - } -} /* end re_putc */ + + ELRE_DEBUG(1, (__F, "printing %3.3o '%c'\r\n", c, c)); + + el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_refresh.r_cursor.h] = c; + if (!shift) + return; + + el->el_refresh.r_cursor.h++; /* advance to next place */ + if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) { + el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h] = '\0'; + /* assure end of line */ + el->el_refresh.r_cursor.h = 0; /* reset it. */ + + /* + * If we would overflow (input is longer than terminal size), + * emulate scroll by dropping first line and shuffling the rest. + * We do this via pointer shuffling - it's safe in this case + * and we avoid memcpy(). + */ + if (el->el_refresh.r_cursor.v + 1 >= el->el_term.t_size.v) { + int i, lins = el->el_term.t_size.v; + char *firstline = el->el_vdisplay[0]; + + for(i=1; i < lins; i++) + el->el_vdisplay[i-1] = el->el_vdisplay[i]; + + firstline[0] = '\0'; /* empty the string */ + el->el_vdisplay[i-1] = firstline; + } else + el->el_refresh.r_cursor.v++; + + ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_term.t_size.v, + (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n", + el->el_refresh.r_cursor.v, el->el_term.t_size.v), + abort()); + } +} /* re_refresh(): @@ -168,196 +187,235 @@ re_putc(el, c) * easily in hopes of a smarter one being placed there. */ protected void -re_refresh(el) - EditLine *el; +re_refresh(EditLine *el) { - int i; - char *cp; - coord_t cur; + int i, rhdiff; + char *cp, *st; + coord_t cur; +#ifdef notyet + size_t termsz; +#endif + + ELRE_DEBUG(1, (__F, "el->el_line.buffer = :%s:\r\n", + el->el_line.buffer)); + + /* reset the Drawing cursor */ + el->el_refresh.r_cursor.h = 0; + el->el_refresh.r_cursor.v = 0; + + /* temporarily draw rprompt to calculate its size */ + prompt_print(el, EL_RPROMPT); - RE_DEBUG(1,(__F, "el->el_line.buffer = :%s:\r\n", el->el_line.buffer),); + /* reset the Drawing cursor */ + el->el_refresh.r_cursor.h = 0; + el->el_refresh.r_cursor.v = 0; - /* reset the Drawing cursor */ - el->el_refresh.r_cursor.h = 0; - el->el_refresh.r_cursor.v = 0; + cur.h = -1; /* set flag in case I'm not set */ + cur.v = 0; - cur.h = -1; /* set flag in case I'm not set */ - cur.v = 0; + prompt_print(el, EL_PROMPT); - prompt_print(el); + /* draw the current input buffer */ +#if notyet + termsz = el->el_term.t_size.h * el->el_term.t_size.v; + if (el->el_line.lastchar - el->el_line.buffer > termsz) { + /* + * If line is longer than terminal, process only part + * of line which would influence display. + */ + size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz; - /* draw the current input buffer */ - for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) { - if (cp == el->el_line.cursor) { - cur.h = el->el_refresh.r_cursor.h; /* save for later */ - cur.v = el->el_refresh.r_cursor.v; + st = el->el_line.lastchar - rem + - (termsz - (((rem / el->el_term.t_size.v) - 1) + * el->el_term.t_size.v)); + } else +#endif + st = el->el_line.buffer; + + for (cp = st; cp < el->el_line.lastchar; cp++) { + if (cp == el->el_line.cursor) { + /* save for later */ + cur.h = el->el_refresh.r_cursor.h; + cur.v = el->el_refresh.r_cursor.v; + } + re_addc(el, (unsigned char) *cp); } - re_addc(el, *cp); - } - - if (cur.h == -1) { /* if I haven't been set yet, I'm at the end */ - cur.h = el->el_refresh.r_cursor.h; - cur.v = el->el_refresh.r_cursor.v; - } - /* must be done BEFORE the NUL is written */ - el->el_refresh.r_newcv = el->el_refresh.r_cursor.v; - re_putc(el, '\0'); /* put NUL on end */ - - RE_DEBUG(1,(__F, - "term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n", - el->el_term.t_size.h, el->el_refresh.r_cursor.h, - el->el_refresh.r_cursor.v, el->el_vdisplay[0]),); - - RE_DEBUG(1,(__F, "updating %d lines.\r\n", el->el_refresh.r_newcv),); - for (i = 0; i <= el->el_refresh.r_newcv; i++) { - /* NOTE THAT re_update_line MAY CHANGE el_display[i] */ - re_update_line(el, el->el_display[i], el->el_vdisplay[i], i); - /* - * Copy the new line to be the current one, and pad out with spaces - * to the full width of the terminal so that if we try moving the - * cursor by writing the character that is at the end of the - * screen line, it won't be a NUL or some old leftover stuff. - */ - re__copy_and_pad(el->el_display[i], el->el_vdisplay[i], - el->el_term.t_size.h); - } - RE_DEBUG(1,(__F, - "\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n", - el->el_refresh.r_cursor.v, el->el_refresh.r_oldcv, i),); - - if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv) - for (; i <= el->el_refresh.r_oldcv; i++) { - term_move_to_line(el, i); - term_move_to_char(el, 0); - term_clear_EOL(el, strlen(el->el_display[i])); + if (cur.h == -1) { /* if I haven't been set yet, I'm at the end */ + cur.h = el->el_refresh.r_cursor.h; + cur.v = el->el_refresh.r_cursor.v; + } + rhdiff = el->el_term.t_size.h - el->el_refresh.r_cursor.h - + el->el_rprompt.p_pos.h; + if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v && + !el->el_refresh.r_cursor.v && rhdiff > 1) { + /* + * have a right-hand side prompt that will fit + * on the end of the first line with at least + * one character gap to the input buffer. + */ + while (--rhdiff > 0) /* pad out with spaces */ + re_putc(el, ' ', 1); + prompt_print(el, EL_RPROMPT); + } else { + el->el_rprompt.p_pos.h = 0; /* flag "not using rprompt" */ + el->el_rprompt.p_pos.v = 0; + } + + re_putc(el, '\0', 0); /* make line ended with NUL, no cursor shift */ + + el->el_refresh.r_newcv = el->el_refresh.r_cursor.v; + + ELRE_DEBUG(1, (__F, + "term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n", + el->el_term.t_size.h, el->el_refresh.r_cursor.h, + el->el_refresh.r_cursor.v, el->el_vdisplay[0])); + + ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv)); + for (i = 0; i <= el->el_refresh.r_newcv; i++) { + /* NOTE THAT re_update_line MAY CHANGE el_display[i] */ + re_update_line(el, el->el_display[i], el->el_vdisplay[i], i); + + /* + * Copy the new line to be the current one, and pad out with + * spaces to the full width of the terminal so that if we try + * moving the cursor by writing the character that is at the + * end of the screen line, it won't be a NUL or some old + * leftover stuff. + */ + re__copy_and_pad(el->el_display[i], el->el_vdisplay[i], + (size_t) el->el_term.t_size.h); + } + ELRE_DEBUG(1, (__F, + "\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n", + el->el_refresh.r_cursor.v, el->el_refresh.r_oldcv, i)); + + if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv) + for (; i <= el->el_refresh.r_oldcv; i++) { + term_move_to_line(el, i); + term_move_to_char(el, 0); + term_clear_EOL(el, (int) strlen(el->el_display[i])); #ifdef DEBUG_REFRESH - term_overwrite(el, "C\b", 2); + term_overwrite(el, "C\b", 2); #endif /* DEBUG_REFRESH */ - *el->el_display[i] = '\0'; - } - - el->el_refresh.r_oldcv = el->el_refresh.r_newcv; /* set for next time */ - RE_DEBUG(1,(__F, - "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n", - el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v, - cur.h, cur.v),); - term_move_to_line(el, cur.v); /* go to where the cursor is */ - term_move_to_char(el, cur.h); -} /* end re_refresh */ + el->el_display[i][0] = '\0'; + } + + el->el_refresh.r_oldcv = el->el_refresh.r_newcv; /* set for next time */ + ELRE_DEBUG(1, (__F, + "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n", + el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v, + cur.h, cur.v)); + term_move_to_line(el, cur.v); /* go to where the cursor is */ + term_move_to_char(el, cur.h); +} /* re_goto_bottom(): - * used to go to last used screen line + * used to go to last used screen line */ protected void -re_goto_bottom(el) - EditLine *el; +re_goto_bottom(EditLine *el) { - term_move_to_line(el, el->el_refresh.r_oldcv); - term__putc('\r'); - term__putc('\n'); - re_clear_display(el); - term__flush(); -} /* end re_goto_bottom */ + + term_move_to_line(el, el->el_refresh.r_oldcv); + term__putc('\r'); + term__putc('\n'); + re_clear_display(el); + term__flush(); +} /* re_insert(): * insert num characters of s into d (in front of the character) - * at dat, maximum length of d is dlen + * at dat, maximum length of d is dlen */ private void /*ARGSUSED*/ -re_insert(el, d, dat, dlen, s, num) - EditLine *el; - char *d; - int dat, dlen; - char *s; - int num; +re_insert(EditLine *el, char *d, int dat, int dlen, char *s, int num) { - char *a, *b; - - if (num <= 0) - return; - if (num > dlen - dat) - num = dlen - dat; - - RE_DEBUG(1,(__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, d),); - RE_DEBUG(1,(__F, "s == \"%s\"n", s),); - - /* open up the space for num chars */ - if (num > 0) { - b = d + dlen - 1; - a = b - num; - while (a >= &d[dat]) - *b-- = *a--; - d[dlen] = '\0'; /* just in case */ - } - RE_DEBUG(1,(__F, + char *a, *b; + + if (num <= 0) + return; + if (num > dlen - dat) + num = dlen - dat; + + ELRE_DEBUG(1, + (__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n", + num, dat, dlen, d)); + ELRE_DEBUG(1, (__F, "s == \"%s\"n", s)); + + /* open up the space for num chars */ + if (num > 0) { + b = d + dlen - 1; + a = b - num; + while (a >= &d[dat]) + *b-- = *a--; + d[dlen] = '\0'; /* just in case */ + } + ELRE_DEBUG(1, (__F, "re_insert() after insert: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, d),); - RE_DEBUG(1,(__F, "s == \"%s\"n", s),); + num, dat, dlen, d)); + ELRE_DEBUG(1, (__F, "s == \"%s\"n", s)); - /* copy the characters */ - for (a = d + dat; (a < d + dlen) && (num > 0); num--) - *a++ = *s++; + /* copy the characters */ + for (a = d + dat; (a < d + dlen) && (num > 0); num--) + *a++ = *s++; - RE_DEBUG(1,(__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n", - num, dat, dlen, d, s),); - RE_DEBUG(1,(__F, "s == \"%s\"n", s),); -} /* end re_insert */ + ELRE_DEBUG(1, + (__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n", + num, dat, dlen, d, s)); + ELRE_DEBUG(1, (__F, "s == \"%s\"n", s)); +} /* re_delete(): - * delete num characters d at dat, maximum length of d is dlen + * delete num characters d at dat, maximum length of d is dlen */ private void /*ARGSUSED*/ -re_delete(el, d, dat, dlen, num) - EditLine *el; - char *d; - int dat, dlen, num; +re_delete(EditLine *el, char *d, int dat, int dlen, int num) { - char *a, *b; - - if (num <= 0) - return; - if (dat + num >= dlen) { - d[dat] = '\0'; - return; - } - - RE_DEBUG(1,(__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, d),); - - /* open up the space for num chars */ - if (num > 0) { - b = d + dat; - a = b + num; - while (a < &d[dlen]) - *b++ = *a++; - d[dlen] = '\0'; /* just in case */ - } - RE_DEBUG(1,(__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, d),); -} /* end re_delete */ + char *a, *b; + + if (num <= 0) + return; + if (dat + num >= dlen) { + d[dat] = '\0'; + return; + } + ELRE_DEBUG(1, + (__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n", + num, dat, dlen, d)); + + /* open up the space for num chars */ + if (num > 0) { + b = d + dat; + a = b + num; + while (a < &d[dlen]) + *b++ = *a++; + d[dlen] = '\0'; /* just in case */ + } + ELRE_DEBUG(1, + (__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n", + num, dat, dlen, d)); +} /* re__strncopy(): * Like strncpy without padding. */ private void -re__strncopy(a, b, n) - char *a, *b; - size_t n; +re__strncopy(char *a, char *b, size_t n) { - while (n-- && *b) - *a++ = *b++; -} /* end re__strncopy */ + + while (n-- && *b) + *a++ = *b++; +} -/* **************************************************************** +/***************************************************************** re_update_line() is based on finding the middle difference of each line on the screen; vis: @@ -379,641 +437,669 @@ new: eddie> Oh, my little buggy says to me, as lurgid as * going back out. This should really be calculated from the termcap * data... For the moment, a good number for ANSI terminals. */ -#define MIN_END_KEEP 4 +#define MIN_END_KEEP 4 private void -re_update_line(el, old, new, i) - EditLine *el; - char *old, *new; - int i; +re_update_line(EditLine *el, char *old, char *new, int i) { - char *o, *n, *p, c; - char *ofd, *ols, *oe, *nfd, *nls, *ne; - char *osb, *ose, *nsb, *nse; - int fx, sx; - - /* - * find first diff - */ - for (o = old, n = new; *o && (*o == *n); o++, n++) - continue; - ofd = o; - nfd = n; - - /* - * Find the end of both old and new - */ - while (*o) - o++; - /* - * Remove any trailing blanks off of the end, being careful not to - * back up past the beginning. - */ - while (ofd < o) { - if (o[-1] != ' ') - break; - o--; - } - oe = o; - *oe = '\0'; - - while (*n) - n++; - - /* remove blanks from end of new */ - while (nfd < n) { - if (n[-1] != ' ') - break; - n--; - } - ne = n; - *ne = '\0'; - - /* - * if no diff, continue to next line of redraw - */ - if (*ofd == '\0' && *nfd == '\0') { - RE_DEBUG(1,(__F, "no difference.\r\n"),); - return; - } - - /* - * find last same pointer - */ - while ((o > ofd) && (n > nfd) && (*--o == *--n)) - continue; - ols = ++o; - nls = ++n; - - /* - * find same begining and same end - */ - osb = ols; - nsb = nls; - ose = ols; - nse = nls; - - /* - * case 1: insert: scan from nfd to nls looking for *ofd - */ - if (*ofd) { - for (c = *ofd, n = nfd; n < nls; n++) { - if (c == *n) { - for (o = ofd, p = n; p < nls && o < ols && *o == *p; o++, p++) - continue; - /* - * if the new match is longer and it's worth keeping, then we - * take it - */ - if (((nse - nsb) < (p - n)) && (2 * (p - n) > n - nfd)) { - nsb = n; - nse = p; - osb = ofd; - ose = o; - } - } - } - } - - /* - * case 2: delete: scan from ofd to ols looking for *nfd - */ - if (*nfd) { - for (c = *nfd, o = ofd; o < ols; o++) { - if (c == *o) { - for (n = nfd, p = o; p < ols && n < nls && *p == *n; p++, n++) - continue; - /* - * if the new match is longer and it's worth keeping, then we - * take it - */ - if (((ose - osb) < (p - o)) && (2 * (p - o) > o - ofd)) { - nsb = nfd; - nse = n; - osb = o; - ose = p; - } - } - } - } - - /* - * Pragmatics I: If old trailing whitespace or not enough characters to - * save to be worth it, then don't save the last same info. - */ - if ((oe - ols) < MIN_END_KEEP) { - ols = oe; - nls = ne; - } - - /* - * Pragmatics II: if the terminal isn't smart enough, make the data dumber - * so the smart update doesn't try anything fancy - */ - - /* - * fx is the number of characters we need to insert/delete: in the - * beginning to bring the two same begins together - */ - fx = (nsb - nfd) - (osb - ofd); - /* - * sx is the number of characters we need to insert/delete: in the end to - * bring the two same last parts together - */ - sx = (nls - nse) - (ols - ose); - - if (!EL_CAN_INSERT) { - if (fx > 0) { - osb = ols; - ose = ols; - nsb = nls; - nse = nls; - } - if (sx > 0) { - ols = oe; - nls = ne; - } - if ((ols - ofd) < (nls - nfd)) { - ols = oe; - nls = ne; - } - } - if (!EL_CAN_DELETE) { - if (fx < 0) { - osb = ols; - ose = ols; - nsb = nls; - nse = nls; + char *o, *n, *p, c; + char *ofd, *ols, *oe, *nfd, *nls, *ne; + char *osb, *ose, *nsb, *nse; + int fx, sx; + + /* + * find first diff + */ + for (o = old, n = new; *o && (*o == *n); o++, n++) + continue; + ofd = o; + nfd = n; + + /* + * Find the end of both old and new + */ + while (*o) + o++; + /* + * Remove any trailing blanks off of the end, being careful not to + * back up past the beginning. + */ + while (ofd < o) { + if (o[-1] != ' ') + break; + o--; } - if (sx < 0) { - ols = oe; - nls = ne; + oe = o; + *oe = '\0'; + + while (*n) + n++; + + /* remove blanks from end of new */ + while (nfd < n) { + if (n[-1] != ' ') + break; + n--; } - if ((ols - ofd) > (nls - nfd)) { - ols = oe; - nls = ne; + ne = n; + *ne = '\0'; + + /* + * if no diff, continue to next line of redraw + */ + if (*ofd == '\0' && *nfd == '\0') { + ELRE_DEBUG(1, (__F, "no difference.\r\n")); + return; } - } - - /* - * Pragmatics III: make sure the middle shifted pointers are correct if - * they don't point to anything (we may have moved ols or nls). - */ - /* if the change isn't worth it, don't bother */ - /* was: if (osb == ose) */ - if ((ose - osb) < MIN_END_KEEP) { + /* + * find last same pointer + */ + while ((o > ofd) && (n > nfd) && (*--o == *--n)) + continue; + ols = ++o; + nls = ++n; + + /* + * find same begining and same end + */ osb = ols; - ose = ols; nsb = nls; + ose = ols; nse = nls; - } - - /* - * Now that we are done with pragmatics we recompute fx, sx - */ - fx = (nsb - nfd) - (osb - ofd); - sx = (nls - nse) - (ols - ose); - - RE_DEBUG(1,(__F, "\n"),); - RE_DEBUG(1,(__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n", - ofd - old, osb - old, ose - old, ols - old, oe - old),); - RE_DEBUG(1,(__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n", - nfd - new, nsb - new, nse - new, nls - new, ne - new),); - RE_DEBUG(1,(__F, - "xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n"),); - RE_DEBUG(1,(__F, - "xxx-xxx:\"01234567890123456789012345678901234567890\"\r\n"),); -#ifdef DEBUG_REFRESH - re_printstr(el, "old- oe", old, oe); - re_printstr(el, "new- ne", new, ne); - re_printstr(el, "old-ofd", old, ofd); - re_printstr(el, "new-nfd", new, nfd); - re_printstr(el, "ofd-osb", ofd, osb); - re_printstr(el, "nfd-nsb", nfd, nsb); - re_printstr(el, "osb-ose", osb, ose); - re_printstr(el, "nsb-nse", nsb, nse); - re_printstr(el, "ose-ols", ose, ols); - re_printstr(el, "nse-nls", nse, nls); - re_printstr(el, "ols- oe", ols, oe); - re_printstr(el, "nls- ne", nls, ne); -#endif /* DEBUG_REFRESH */ - /* - * el_cursor.v to this line i MUST be in this routine so that if we - * don't have to change the line, we don't move to it. el_cursor.h to first - * diff char - */ - term_move_to_line(el, i); - - /* - * at this point we have something like this: - * - * /old /ofd /osb /ose /ols /oe - * v.....................v v..................v v........v - * eddie> Oh, my fredded gruntle-buggy is to me, as foo var lurgid as - * eddie> Oh, my fredded quiux buggy is to me, as gruntle-lurgid as - * ^.....................^ ^..................^ ^........^ - * \new \nfd \nsb \nse \nls \ne - * - * fx is the difference in length between the the chars between nfd and - * nsb, and the chars between ofd and osb, and is thus the number of - * characters to delete if < 0 (new is shorter than old, as above), - * or insert (new is longer than short). - * - * sx is the same for the second differences. - */ - - /* - * if we have a net insert on the first difference, AND inserting the net - * amount ((nsb-nfd) - (osb-ofd)) won't push the last useful character - * (which is ne if nls != ne, otherwise is nse) off the edge of the screen - * (el->el_term.t_size.h) else we do the deletes first so that we keep everything we need - * to. - */ - - /* - * if the last same is the same like the end, there is no last same part, - * otherwise we want to keep the last same part set p to the last useful - * old character - */ - p = (ols != oe) ? oe : ose; - - /* - * if (There is a diffence in the beginning) && (we need to insert - * characters) && (the number of characters to insert is less than the term - * width) We need to do an insert! else if (we need to delete characters) - * We need to delete characters! else No insert or delete - */ - if ((nsb != nfd) && fx > 0 && ((p - old) + fx <= el->el_term.t_size.h)) { - RE_DEBUG(1,(__F, "first diff insert at %d...\r\n", nfd - new),); /* - * Move to the first char to insert, where the first diff is. - */ - term_move_to_char(el, nfd - new); - /* - * Check if we have stuff to keep at end - */ - if (nsb != ne) { - RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),); - /* - * insert fx chars of new starting at nfd - */ - if (fx > 0) { - RE_DEBUG(!EL_CAN_INSERT, - (__F, "ERROR: cannot insert in early first diff\n"),); - term_insertwrite(el, nfd, fx); - re_insert(el, old, ofd - old, el->el_term.t_size.h, nfd, fx); - } - /* - * write (nsb-nfd) - fx chars of new starting at (nfd + fx) - */ - term_overwrite(el, nfd + fx, (nsb - nfd) - fx); - re__strncopy(ofd + fx, nfd + fx, (nsb - nfd) - fx); + * case 1: insert: scan from nfd to nls looking for *ofd + */ + if (*ofd) { + for (c = *ofd, n = nfd; n < nls; n++) { + if (c == *n) { + for (o = ofd, p = n; + p < nls && o < ols && *o == *p; + o++, p++) + continue; + /* + * if the new match is longer and it's worth + * keeping, then we take it + */ + if (((nse - nsb) < (p - n)) && + (2 * (p - n) > n - nfd)) { + nsb = n; + nse = p; + osb = ofd; + ose = o; + } + } + } } - else { - RE_DEBUG(1,(__F, "without anything to save\r\n"),); - term_overwrite(el, nfd, (nsb - nfd)); - re__strncopy(ofd, nfd, (nsb - nfd)); - /* - * Done - */ - return; + /* + * case 2: delete: scan from ofd to ols looking for *nfd + */ + if (*nfd) { + for (c = *nfd, o = ofd; o < ols; o++) { + if (c == *o) { + for (n = nfd, p = o; + p < ols && n < nls && *p == *n; + p++, n++) + continue; + /* + * if the new match is longer and it's worth + * keeping, then we take it + */ + if (((ose - osb) < (p - o)) && + (2 * (p - o) > o - ofd)) { + nsb = nfd; + nse = n; + osb = o; + ose = p; + } + } + } } - } - else if (fx < 0) { - RE_DEBUG(1,(__F, "first diff delete at %d...\r\n", ofd - old),); /* - * move to the first char to delete where the first diff is - */ - term_move_to_char(el, ofd - old); + * Pragmatics I: If old trailing whitespace or not enough characters to + * save to be worth it, then don't save the last same info. + */ + if ((oe - ols) < MIN_END_KEEP) { + ols = oe; + nls = ne; + } /* - * Check if we have stuff to save - */ - if (osb != oe) { - RE_DEBUG(1,(__F, "with stuff to save at end\r\n"),); - /* - * fx is less than zero *always* here but we check for code - * symmetry - */ - if (fx < 0) { - RE_DEBUG(!EL_CAN_DELETE, - (__F, "ERROR: cannot delete in first diff\n"),); - term_deletechars(el, -fx); - re_delete(el, old, ofd - old, el->el_term.t_size.h, -fx); - } - /* - * write (nsb-nfd) chars of new starting at nfd - */ - term_overwrite(el, nfd, (nsb - nfd)); - re__strncopy(ofd, nfd, (nsb - nfd)); + * Pragmatics II: if the terminal isn't smart enough, make the data + * dumber so the smart update doesn't try anything fancy + */ + /* + * fx is the number of characters we need to insert/delete: in the + * beginning to bring the two same begins together + */ + fx = (nsb - nfd) - (osb - ofd); + /* + * sx is the number of characters we need to insert/delete: in the + * end to bring the two same last parts together + */ + sx = (nls - nse) - (ols - ose); + + if (!EL_CAN_INSERT) { + if (fx > 0) { + osb = ols; + ose = ols; + nsb = nls; + nse = nls; + } + if (sx > 0) { + ols = oe; + nls = ne; + } + if ((ols - ofd) < (nls - nfd)) { + ols = oe; + nls = ne; + } } - else { - RE_DEBUG(1,(__F, "but with nothing left to save\r\n"),); - /* - * write (nsb-nfd) chars of new starting at nfd - */ - term_overwrite(el, nfd, (nsb - nfd)); - RE_DEBUG(1,(__F, "cleareol %d\n", (oe - old) - (ne - new)),); - term_clear_EOL(el, (oe - old) - (ne - new)); - /* - * Done - */ - return; + if (!EL_CAN_DELETE) { + if (fx < 0) { + osb = ols; + ose = ols; + nsb = nls; + nse = nls; + } + if (sx < 0) { + ols = oe; + nls = ne; + } + if ((ols - ofd) > (nls - nfd)) { + ols = oe; + nls = ne; + } + } + /* + * Pragmatics III: make sure the middle shifted pointers are correct if + * they don't point to anything (we may have moved ols or nls). + */ + /* if the change isn't worth it, don't bother */ + /* was: if (osb == ose) */ + if ((ose - osb) < MIN_END_KEEP) { + osb = ols; + ose = ols; + nsb = nls; + nse = nls; } - } - else - fx = 0; + /* + * Now that we are done with pragmatics we recompute fx, sx + */ + fx = (nsb - nfd) - (osb - ofd); + sx = (nls - nse) - (ols - ose); + + ELRE_DEBUG(1, (__F, "\n")); + ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n", + ofd - old, osb - old, ose - old, ols - old, oe - old)); + ELRE_DEBUG(1, (__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n", + nfd - new, nsb - new, nse - new, nls - new, ne - new)); + ELRE_DEBUG(1, (__F, + "xxx-xxx:\"00000000001111111111222222222233333333334\"\r\n")); + ELRE_DEBUG(1, (__F, + "xxx-xxx:\"01234567890123456789012345678901234567890\"\r\n")); +#ifdef DEBUG_REFRESH + re_printstr(el, "old- oe", old, oe); + re_printstr(el, "new- ne", new, ne); + re_printstr(el, "old-ofd", old, ofd); + re_printstr(el, "new-nfd", new, nfd); + re_printstr(el, "ofd-osb", ofd, osb); + re_printstr(el, "nfd-nsb", nfd, nsb); + re_printstr(el, "osb-ose", osb, ose); + re_printstr(el, "nsb-nse", nsb, nse); + re_printstr(el, "ose-ols", ose, ols); + re_printstr(el, "nse-nls", nse, nls); + re_printstr(el, "ols- oe", ols, oe); + re_printstr(el, "nls- ne", nls, ne); +#endif /* DEBUG_REFRESH */ - if (sx < 0) { - RE_DEBUG(1,(__F, "second diff delete at %d...\r\n", (ose - old) + fx),); /* - * Check if we have stuff to delete - */ + * el_cursor.v to this line i MUST be in this routine so that if we + * don't have to change the line, we don't move to it. el_cursor.h to + * first diff char + */ + term_move_to_line(el, i); + /* - * fx is the number of characters inserted (+) or deleted (-) - */ + * at this point we have something like this: + * + * /old /ofd /osb /ose /ols /oe + * v.....................v v..................v v........v + * eddie> Oh, my fredded gruntle-buggy is to me, as foo var lurgid as + * eddie> Oh, my fredded quiux buggy is to me, as gruntle-lurgid as + * ^.....................^ ^..................^ ^........^ + * \new \nfd \nsb \nse \nls \ne + * + * fx is the difference in length between the chars between nfd and + * nsb, and the chars between ofd and osb, and is thus the number of + * characters to delete if < 0 (new is shorter than old, as above), + * or insert (new is longer than short). + * + * sx is the same for the second differences. + */ - term_move_to_char(el, (ose - old) + fx); /* - * Check if we have stuff to save - */ - if (ols != oe) { - RE_DEBUG(1,(__F, "with stuff to save at end\r\n"),); - /* - * Again a duplicate test. - */ - if (sx < 0) { - RE_DEBUG(!EL_CAN_DELETE, - (__F, "ERROR: cannot delete in second diff\n"),); - term_deletechars(el, -sx); - } - - /* - * write (nls-nse) chars of new starting at nse - */ - term_overwrite(el, nse, (nls - nse)); - } - else { - RE_DEBUG(1,(__F, "but with nothing left to save\r\n"),); - term_overwrite(el, nse, (nls - nse)); - RE_DEBUG(1,(__F, "cleareol %d\n", (oe - old) - (ne - new)),); - term_clear_EOL(el, (oe - old) - (ne - new)); - } - } + * if we have a net insert on the first difference, AND inserting the + * net amount ((nsb-nfd) - (osb-ofd)) won't push the last useful + * character (which is ne if nls != ne, otherwise is nse) off the edge + * of the screen (el->el_term.t_size.h) else we do the deletes first + * so that we keep everything we need to. + */ - /* - * if we have a first insert AND WE HAVEN'T ALREADY DONE IT... - */ - if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) { - RE_DEBUG(1,(__F, "late first diff insert at %d...\r\n", nfd - new),); + /* + * if the last same is the same like the end, there is no last same + * part, otherwise we want to keep the last same part set p to the + * last useful old character + */ + p = (ols != oe) ? oe : ose; - term_move_to_char(el, nfd - new); /* - * Check if we have stuff to keep at the end - */ - if (nsb != ne) { - RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),); - /* - * We have to recalculate fx here because we set it - * to zero above as a flag saying that we hadn't done - * an early first insert. - */ - fx = (nsb - nfd) - (osb - ofd); - if (fx > 0) { + * if (There is a diffence in the beginning) && (we need to insert + * characters) && (the number of characters to insert is less than + * the term width) + * We need to do an insert! + * else if (we need to delete characters) + * We need to delete characters! + * else + * No insert or delete + */ + if ((nsb != nfd) && fx > 0 && + ((p - old) + fx <= el->el_term.t_size.h)) { + ELRE_DEBUG(1, + (__F, "first diff insert at %d...\r\n", nfd - new)); /* - * insert fx chars of new starting at nfd + * Move to the first char to insert, where the first diff is. */ - RE_DEBUG(!EL_CAN_INSERT, - (__F, "ERROR: cannot insert in late first diff\n"),); - term_insertwrite(el, nfd, fx); - re_insert(el, old, ofd - old, el->el_term.t_size.h, nfd, fx); - } - - /* - * write (nsb-nfd) - fx chars of new starting at (nfd + fx) - */ - term_overwrite(el, nfd + fx, (nsb - nfd) - fx); - re__strncopy(ofd + fx, nfd + fx, (nsb - nfd) - fx); - } - else { - RE_DEBUG(1,(__F, "without anything to save\r\n"),); - term_overwrite(el, nfd, (nsb - nfd)); - re__strncopy(ofd, nfd, (nsb - nfd)); + term_move_to_char(el, nfd - new); + /* + * Check if we have stuff to keep at end + */ + if (nsb != ne) { + ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n")); + /* + * insert fx chars of new starting at nfd + */ + if (fx > 0) { + ELRE_DEBUG(!EL_CAN_INSERT, (__F, + "ERROR: cannot insert in early first diff\n")); + term_insertwrite(el, nfd, fx); + re_insert(el, old, ofd - old, + el->el_term.t_size.h, nfd, fx); + } + /* + * write (nsb-nfd) - fx chars of new starting at + * (nfd + fx) + */ + term_overwrite(el, nfd + fx, (nsb - nfd) - fx); + re__strncopy(ofd + fx, nfd + fx, + (size_t) ((nsb - nfd) - fx)); + } else { + ELRE_DEBUG(1, (__F, "without anything to save\r\n")); + term_overwrite(el, nfd, (nsb - nfd)); + re__strncopy(ofd, nfd, (size_t) (nsb - nfd)); + /* + * Done + */ + return; + } + } else if (fx < 0) { + ELRE_DEBUG(1, + (__F, "first diff delete at %d...\r\n", ofd - old)); + /* + * move to the first char to delete where the first diff is + */ + term_move_to_char(el, ofd - old); + /* + * Check if we have stuff to save + */ + if (osb != oe) { + ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n")); + /* + * fx is less than zero *always* here but we check + * for code symmetry + */ + if (fx < 0) { + ELRE_DEBUG(!EL_CAN_DELETE, (__F, + "ERROR: cannot delete in first diff\n")); + term_deletechars(el, -fx); + re_delete(el, old, ofd - old, + el->el_term.t_size.h, -fx); + } + /* + * write (nsb-nfd) chars of new starting at nfd + */ + term_overwrite(el, nfd, (nsb - nfd)); + re__strncopy(ofd, nfd, (size_t) (nsb - nfd)); + + } else { + ELRE_DEBUG(1, (__F, + "but with nothing left to save\r\n")); + /* + * write (nsb-nfd) chars of new starting at nfd + */ + term_overwrite(el, nfd, (nsb - nfd)); + ELRE_DEBUG(1, (__F, + "cleareol %d\n", (oe - old) - (ne - new))); + term_clear_EOL(el, (oe - old) - (ne - new)); + /* + * Done + */ + return; + } + } else + fx = 0; + + if (sx < 0 && (ose - old) + fx < el->el_term.t_size.h) { + ELRE_DEBUG(1, (__F, + "second diff delete at %d...\r\n", (ose - old) + fx)); + /* + * Check if we have stuff to delete + */ + /* + * fx is the number of characters inserted (+) or deleted (-) + */ + + term_move_to_char(el, (ose - old) + fx); + /* + * Check if we have stuff to save + */ + if (ols != oe) { + ELRE_DEBUG(1, (__F, "with stuff to save at end\r\n")); + /* + * Again a duplicate test. + */ + if (sx < 0) { + ELRE_DEBUG(!EL_CAN_DELETE, (__F, + "ERROR: cannot delete in second diff\n")); + term_deletechars(el, -sx); + } + /* + * write (nls-nse) chars of new starting at nse + */ + term_overwrite(el, nse, (nls - nse)); + } else { + ELRE_DEBUG(1, (__F, + "but with nothing left to save\r\n")); + term_overwrite(el, nse, (nls - nse)); + ELRE_DEBUG(1, (__F, + "cleareol %d\n", (oe - old) - (ne - new))); + if ((oe - old) - (ne - new) != 0) + term_clear_EOL(el, (oe - old) - (ne - new)); + } } - } - - /* - * line is now NEW up to nse - */ - if (sx >= 0) { - RE_DEBUG(1,(__F, "second diff insert at %d...\r\n", nse - new),); - term_move_to_char(el, nse - new); - if (ols != oe) { - RE_DEBUG(1,(__F, "with stuff to keep at end\r\n"),); - if (sx > 0) { - /* insert sx chars of new starting at nse */ - RE_DEBUG(!EL_CAN_INSERT, - (__F, "ERROR: cannot insert in second diff\n"),); - term_insertwrite(el, nse, sx); - } - - /* - * write (nls-nse) - sx chars of new starting at (nse + sx) - */ - term_overwrite(el, nse + sx, (nls - nse) - sx); + /* + * if we have a first insert AND WE HAVEN'T ALREADY DONE IT... + */ + if ((nsb != nfd) && (osb - ofd) <= (nsb - nfd) && (fx == 0)) { + ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n", + nfd - new)); + + term_move_to_char(el, nfd - new); + /* + * Check if we have stuff to keep at the end + */ + if (nsb != ne) { + ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n")); + /* + * We have to recalculate fx here because we set it + * to zero above as a flag saying that we hadn't done + * an early first insert. + */ + fx = (nsb - nfd) - (osb - ofd); + if (fx > 0) { + /* + * insert fx chars of new starting at nfd + */ + ELRE_DEBUG(!EL_CAN_INSERT, (__F, + "ERROR: cannot insert in late first diff\n")); + term_insertwrite(el, nfd, fx); + re_insert(el, old, ofd - old, + el->el_term.t_size.h, nfd, fx); + } + /* + * write (nsb-nfd) - fx chars of new starting at + * (nfd + fx) + */ + term_overwrite(el, nfd + fx, (nsb - nfd) - fx); + re__strncopy(ofd + fx, nfd + fx, + (size_t) ((nsb - nfd) - fx)); + } else { + ELRE_DEBUG(1, (__F, "without anything to save\r\n")); + term_overwrite(el, nfd, (nsb - nfd)); + re__strncopy(ofd, nfd, (size_t) (nsb - nfd)); + } } - else { - RE_DEBUG(1,(__F, "without anything to save\r\n"),); - term_overwrite(el, nse, (nls - nse)); - - /* - * No need to do a clear-to-end here because we were doing - * a second insert, so we will have over written all of the - * old string. - */ + /* + * line is now NEW up to nse + */ + if (sx >= 0) { + ELRE_DEBUG(1, (__F, + "second diff insert at %d...\r\n", nse - new)); + term_move_to_char(el, nse - new); + if (ols != oe) { + ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n")); + if (sx > 0) { + /* insert sx chars of new starting at nse */ + ELRE_DEBUG(!EL_CAN_INSERT, (__F, + "ERROR: cannot insert in second diff\n")); + term_insertwrite(el, nse, sx); + } + /* + * write (nls-nse) - sx chars of new starting at + * (nse + sx) + */ + term_overwrite(el, nse + sx, (nls - nse) - sx); + } else { + ELRE_DEBUG(1, (__F, "without anything to save\r\n")); + term_overwrite(el, nse, (nls - nse)); + + /* + * No need to do a clear-to-end here because we were + * doing a second insert, so we will have over + * written all of the old string. + */ + } } - } - RE_DEBUG(1,(__F, "done.\r\n"),); -} /* re_update_line */ + ELRE_DEBUG(1, (__F, "done.\r\n")); +} /* re__copy_and_pad(): * Copy string and pad with spaces */ private void -re__copy_and_pad(dst, src, width) - char *dst, *src; - size_t width; +re__copy_and_pad(char *dst, char *src, size_t width) { - int i; + int i; + + for (i = 0; i < width; i++) { + if (*src == '\0') + break; + *dst++ = *src++; + } - for (i = 0; i < width; i++) { - if (*src == '\0') - break; - *dst++ = *src++; - } + for (; i < width; i++) + *dst++ = ' '; - while (i < width) { - *dst++ = ' '; - i++; - } - *dst = '\0'; -} /* end re__copy_and_pad */ + *dst = '\0'; +} /* re_refresh_cursor(): * Move to the new cursor position */ protected void -re_refresh_cursor(el) - EditLine *el; +re_refresh_cursor(EditLine *el) { - char *cp, c; - int h, v, th; - - /* first we must find where the cursor is... */ - h = el->el_prompt.p_pos.h; - v = el->el_prompt.p_pos.v; - th = el->el_term.t_size.h; /* optimize for speed */ - - /* do input buffer to el->el_line.cursor */ - for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) { - c = *cp; - h++; /* all chars at least this long */ - - if (c == '\n') { /* handle newline in data part too */ - h = 0; - v++; - } - else { - if (c == '\t') { /* if a tab, to next tab stop */ - while (h & 07) { - h++; - } - } - else if (iscntrl(c)) { /* if control char */ - h++; - if (h > th) { /* if overflow, compensate */ - h = 1; - v++; + char *cp, c; + int h, v, th; + + /* first we must find where the cursor is... */ + h = el->el_prompt.p_pos.h; + v = el->el_prompt.p_pos.v; + th = el->el_term.t_size.h; /* optimize for speed */ + + /* do input buffer to el->el_line.cursor */ + for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) { + c = *cp; + h++; /* all chars at least this long */ + + if (c == '\n') {/* handle newline in data part too */ + h = 0; + v++; + } else { + if (c == '\t') { /* if a tab, to next tab stop */ + while (h & 07) { + h++; + } + } else if (iscntrl((unsigned char) c)) { + /* if control char */ + h++; + if (h > th) { /* if overflow, compensate */ + h = 1; + v++; + } + } else if (!isprint((unsigned char) c)) { + h += 3; + if (h > th) { /* if overflow, compensate */ + h = h - th; + v++; + } + } } - } - else if (!isprint(c)) { - h += 3; - if (h > th) { /* if overflow, compensate */ - h = h - th; - v++; - } - } - } - if (h >= th) { /* check, extra long tabs picked up here also */ - h = 0; - v++; + if (h >= th) { /* check, extra long tabs picked up here also */ + h = 0; + v++; + } } - } - /* now go there */ - term_move_to_line(el, v); - term_move_to_char(el, h); - term__flush(); -} /* re_refresh_cursor */ + /* now go there */ + term_move_to_line(el, v); + term_move_to_char(el, h); + term__flush(); +} /* re_fastputc(): * Add a character fast. */ private void -re_fastputc(el, c) - EditLine *el; - int c; +re_fastputc(EditLine *el, int c) { - term__putc(c); - el->el_display[el->el_cursor.v][el->el_cursor.h++] = c; - if (el->el_cursor.h >= el->el_term.t_size.h) { - /* if we must overflow */ - el->el_cursor.h = 0; - el->el_cursor.v++; - el->el_refresh.r_oldcv++; - term__putc('\r'); - term__putc('\n'); - } -} /* end re_fastputc */ + + term__putc(c); + el->el_display[el->el_cursor.v][el->el_cursor.h++] = c; + if (el->el_cursor.h >= el->el_term.t_size.h) { + /* if we must overflow */ + el->el_cursor.h = 0; + + /* + * If we would overflow (input is longer than terminal size), + * emulate scroll by dropping first line and shuffling the rest. + * We do this via pointer shuffling - it's safe in this case + * and we avoid memcpy(). + */ + if (el->el_cursor.v + 1 >= el->el_term.t_size.v) { + int i, lins = el->el_term.t_size.v; + char *firstline = el->el_display[0]; + + for(i=1; i < lins; i++) + el->el_display[i-1] = el->el_display[i]; + + re__copy_and_pad(firstline, "", 0); + el->el_display[i-1] = firstline; + } else { + el->el_cursor.v++; + el->el_refresh.r_oldcv++; + } + if (EL_HAS_AUTO_MARGINS) { + if (EL_HAS_MAGIC_MARGINS) { + term__putc(' '); + term__putc('\b'); + } + } else { + term__putc('\r'); + term__putc('\n'); + } + } +} /* re_fastaddc(): * we added just one char, handle it fast. - * Assumes that screen cursor == real cursor + * Assumes that screen cursor == real cursor */ protected void -re_fastaddc(el) - EditLine *el; +re_fastaddc(EditLine *el) { - char c; - - c = el->el_line.cursor[-1]; - - if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) { - re_refresh(el); /* too hard to handle */ - return; - } /* else (only do at end of line, no TAB) */ - - if (iscntrl(c)) { /* if control char, do caret */ - char mc = (c == '\177') ? '?' : (c | 0100); - re_fastputc(el, '^'); - re_fastputc(el, mc); - } - else if (isprint(c)) { /* normal char */ - re_fastputc(el, c); - } - else { - re_fastputc(el, '\\'); - re_fastputc(el, ((c >> 6) & 7) + '0'); - re_fastputc(el, ((c >> 3) & 7) + '0'); - re_fastputc(el, (c & 7) + '0'); - } - term__flush(); -} /* end re_fastaddc */ + char c; + int rhdiff; + + c = el->el_line.cursor[-1]; + + if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) { + re_refresh(el); /* too hard to handle */ + return; + } + rhdiff = el->el_term.t_size.h - el->el_cursor.h - + el->el_rprompt.p_pos.h; + if (el->el_rprompt.p_pos.h && rhdiff < 3) { + re_refresh(el); /* clear out rprompt if less than 1 char gap */ + return; + } /* else (only do at end of line, no TAB) */ + if (iscntrl((unsigned char) c)) { /* if control char, do caret */ + char mc = (c == '\177') ? '?' : (c | 0100); + re_fastputc(el, '^'); + re_fastputc(el, mc); + } else if (isprint((unsigned char) c)) { /* normal char */ + re_fastputc(el, c); + } else { + re_fastputc(el, '\\'); + re_fastputc(el, (int) ((((unsigned int) c >> 6) & 7) + '0')); + re_fastputc(el, (int) ((((unsigned int) c >> 3) & 7) + '0')); + re_fastputc(el, (c & 7) + '0'); + } + term__flush(); +} /* re_clear_display(): - * clear the screen buffers so that new new prompt starts fresh. + * clear the screen buffers so that new new prompt starts fresh. */ protected void -re_clear_display(el) - EditLine *el; +re_clear_display(EditLine *el) { - int i; + int i; - el->el_cursor.v = 0; - el->el_cursor.h = 0; - for (i = 0; i < el->el_term.t_size.v; i++) - el->el_display[i][0] = '\0'; - el->el_refresh.r_oldcv = 0; -} /* end re_clear_display */ + el->el_cursor.v = 0; + el->el_cursor.h = 0; + for (i = 0; i < el->el_term.t_size.v; i++) + el->el_display[i][0] = '\0'; + el->el_refresh.r_oldcv = 0; +} /* re_clear_lines(): - * Make sure all lines are *really* blank + * Make sure all lines are *really* blank */ protected void -re_clear_lines(el) - EditLine *el; +re_clear_lines(EditLine *el) { - if (EL_CAN_CEOL) { - int i; - term_move_to_char(el, 0); - for (i = 0; i <= el->el_refresh.r_oldcv; i++) { - /* for each line on the screen */ - term_move_to_line(el, i); - term_clear_EOL(el, el->el_term.t_size.h); + + if (EL_CAN_CEOL) { + int i; + term_move_to_char(el, 0); + for (i = 0; i <= el->el_refresh.r_oldcv; i++) { + /* for each line on the screen */ + term_move_to_line(el, i); + term_clear_EOL(el, el->el_term.t_size.h); + } + term_move_to_line(el, 0); + } else { + term_move_to_line(el, el->el_refresh.r_oldcv); + /* go to last line */ + term__putc('\r'); /* go to BOL */ + term__putc('\n'); /* go to new line */ } - term_move_to_line(el, 0); - } - else { - term_move_to_line(el, el->el_refresh.r_oldcv); /* go to last line */ - term__putc('\r'); /* go to BOL */ - term__putc('\n'); /* go to new line */ - } -} /* end re_clear_lines */ +} diff --git a/dist/refresh.h b/dist/refresh.h index 30533d1..33c0887 100644 --- a/dist/refresh.h +++ b/dist/refresh.h @@ -1,4 +1,4 @@ -/* $NetBSD: refresh.h,v 1.2 1997/01/11 06:48:08 lukem Exp $ */ +/* $NetBSD: refresh.h,v 1.4 2001/01/10 07:45:42 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,21 +42,22 @@ * el.refresh.h: Screen refresh functions */ #ifndef _h_el_refresh -#define _h_el_refresh +#define _h_el_refresh #include "histedit.h" typedef struct { - coord_t r_cursor; /* Refresh cursor position */ - int r_oldcv, r_newcv; /* Vertical locations */ + coord_t r_cursor; /* Refresh cursor position */ + int r_oldcv; /* Vertical locations */ + int r_newcv; } el_refresh_t; -protected void re_putc __P((EditLine *, int)); -protected void re_clear_lines __P((EditLine *)); -protected void re_clear_display __P((EditLine *)); -protected void re_refresh __P((EditLine *)); -protected void re_refresh_cursor __P((EditLine *)); -protected void re_fastaddc __P((EditLine *)); -protected void re_goto_bottom __P((EditLine *)); +protected void re_putc(EditLine *, int, int); +protected void re_clear_lines(EditLine *); +protected void re_clear_display(EditLine *); +protected void re_refresh(EditLine *); +protected void re_refresh_cursor(EditLine *); +protected void re_fastaddc(EditLine *); +protected void re_goto_bottom(EditLine *); #endif /* _h_el_refresh */ diff --git a/dist/search.c b/dist/search.c index 1149a58..20fefad 100644 --- a/dist/search.c +++ b/dist/search.c @@ -1,4 +1,4 @@ -/* $NetBSD: search.c,v 1.4 1997/01/23 14:02:47 mrg Exp $ */ +/* $NetBSD: search.c,v 1.11 2001/01/23 15:55:31 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,11 +36,12 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: search.c,v 1.4 1997/01/23 14:02:47 mrg Exp $"; +__RCSID("$NetBSD: search.c,v 1.11 2001/01/23 15:55:31 jdolecek Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -59,7 +60,7 @@ static char rcsid[] = "$NetBSD: search.c,v 1.4 1997/01/23 14:02:47 mrg Exp $"; /* * Adjust cursor in vi mode to include the character under it */ -#define EL_CURSOR(el) \ +#define EL_CURSOR(el) \ ((el)->el_line.cursor + (((el)->el_map.type == MAP_VI) && \ ((el)->el_map.current == (el)->el_map.alt))) @@ -67,15 +68,17 @@ static char rcsid[] = "$NetBSD: search.c,v 1.4 1997/01/23 14:02:47 mrg Exp $"; * Initialize the search stuff */ protected int -search_init(el) - EditLine *el; +search_init(EditLine *el) { - el->el_search.patbuf = (char *) el_malloc(EL_BUFSIZ); - el->el_search.patlen = 0; - el->el_search.patdir = -1; - el->el_search.chacha = '\0'; - el->el_search.chadir = -1; - return 0; + + el->el_search.patbuf = (char *) el_malloc(EL_BUFSIZ); + if (el->el_search.patbuf == NULL) + return (-1); + el->el_search.patlen = 0; + el->el_search.patdir = -1; + el->el_search.chacha = '\0'; + el->el_search.chadir = -1; + return (0); } @@ -83,68 +86,67 @@ search_init(el) * Initialize the search stuff */ protected void -search_end(el) - EditLine *el; +search_end(EditLine *el) { - el_free((ptr_t) el->el_search.patbuf); - el->el_search.patbuf = NULL; + + el_free((ptr_t) el->el_search.patbuf); + el->el_search.patbuf = NULL; } + #ifdef REGEXP /* regerror(): * Handle regular expression errors */ -public void +public void /*ARGSUSED*/ -regerror(msg) - const char *msg; +regerror(const char *msg) { } #endif + /* el_match(): * Return if string matches pattern */ protected int -el_match(str, pat) - const char *str; - const char *pat; +el_match(const char *str, const char *pat) { #if defined (REGEX) - regex_t re; - int rv; + regex_t re; + int rv; #elif defined (REGEXP) - regexp *rp; - int rv; -#else - extern char *re_comp __P((const char *)); - extern int re_exec __P((const char *)); + regexp *rp; + int rv; +#else + extern char *re_comp(const char *); + extern int re_exec(const char *); #endif - if (strstr(str, pat) != NULL) - return 1; + if (strstr(str, pat) != NULL) + return (1); #if defined(REGEX) - if (regcomp(&re, pat, 0) == 0) { - rv = regexec(&re, str, 0, NULL, 0) == 0; - regfree(&re); - } else { - rv = 0; - } - return rv; + if (regcomp(&re, pat, 0) == 0) { + rv = regexec(&re, str, 0, NULL, 0) == 0; + regfree(&re); + } else { + rv = 0; + } + return (rv); #elif defined(REGEXP) - if ((re = regcomp(pat)) != NULL) { - rv = regexec(re, str); - free((ptr_t) re); - } else { - rv = 0; - } - return rv; + if ((re = regcomp(pat)) != NULL) { + rv = regexec(re, str); + free((ptr_t) re); + } else { + rv = 0; + } + return (rv); #else - if (re_comp(pat) != NULL) - return 0; - else - return re_exec(str) == 1; + if (re_comp(pat) != NULL) + return (0); + else + return (re_exec(str) == 1); #endif } @@ -153,46 +155,44 @@ el_match(str, pat) * return True if the pattern matches the prefix */ protected int -c_hmatch(el, str) - EditLine *el; - const char *str; +c_hmatch(EditLine *el, const char *str) { #ifdef SDEBUG - (void) fprintf(el->el_errfile, "match `%s' with `%s'\n", - el->el_search.patbuf, str); + (void) fprintf(el->el_errfile, "match `%s' with `%s'\n", + el->el_search.patbuf, str); #endif /* SDEBUG */ - - return el_match(str, el->el_search.patbuf); + + return (el_match(str, el->el_search.patbuf)); } -/* c_setpat(): +/* c_setpat(): * Set the history seatch pattern */ protected void -c_setpat(el) - EditLine *el; +c_setpat(EditLine *el) { - if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY && - el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) { - el->el_search.patlen = EL_CURSOR(el) - el->el_line.buffer; - if (el->el_search.patlen >= EL_BUFSIZ) - el->el_search.patlen = EL_BUFSIZ -1; - if (el->el_search.patlen >= 0) { - (void) strncpy(el->el_search.patbuf, el->el_line.buffer, - el->el_search.patlen); - el->el_search.patbuf[el->el_search.patlen] = '\0'; + if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY && + el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) { + el->el_search.patlen = EL_CURSOR(el) - el->el_line.buffer; + if (el->el_search.patlen >= EL_BUFSIZ) + el->el_search.patlen = EL_BUFSIZ - 1; + if (el->el_search.patlen != 0) { + (void) strncpy(el->el_search.patbuf, el->el_line.buffer, + el->el_search.patlen); + el->el_search.patbuf[el->el_search.patlen] = '\0'; + } else + el->el_search.patlen = strlen(el->el_search.patbuf); } - else - el->el_search.patlen = strlen(el->el_search.patbuf); - } #ifdef SDEBUG - (void) fprintf(el->el_errfile, "\neventno = %d\n", el->el_history.eventno); - (void) fprintf(el->el_errfile, "patlen = %d\n", el->el_search.patlen); - (void) fprintf(el->el_errfile, "patbuf = \"%s\"\n", el->el_search.patbuf); - (void) fprintf(el->el_errfile, "cursor %d lastchar %d\n", - EL_CURSOR(el) - el->el_line.buffer, - el->el_line.lastchar - el->el_line.buffer); + (void) fprintf(el->el_errfile, "\neventno = %d\n", + el->el_history.eventno); + (void) fprintf(el->el_errfile, "patlen = %d\n", el->el_search.patlen); + (void) fprintf(el->el_errfile, "patbuf = \"%s\"\n", + el->el_search.patbuf); + (void) fprintf(el->el_errfile, "cursor %d lastchar %d\n", + EL_CURSOR(el) - el->el_line.buffer, + el->el_line.lastchar - el->el_line.buffer); #endif } @@ -201,218 +201,241 @@ c_setpat(el) * Emacs incremental search */ protected el_action_t -ce_inc_search(el, dir) - EditLine *el; - int dir; +ce_inc_search(EditLine *el, int dir) { - static char STRfwd[] = { 'f', 'w', 'd', '\0' }, - STRbck[] = { 'b', 'c', 'k', '\0' }; - static char pchar = ':'; /* ':' = normal, '?' = failed */ - static char endcmd[2] = { '\0', '\0' }; - char ch, *cp, *ocursor = el->el_line.cursor, oldpchar = pchar; + static const char STRfwd[] = {'f', 'w', 'd', '\0'}, + STRbck[] = {'b', 'c', 'k', '\0'}; + static char pchar = ':';/* ':' = normal, '?' = failed */ + static char endcmd[2] = {'\0', '\0'}; + char ch, *ocursor = el->el_line.cursor, oldpchar = pchar; + const char *cp; - el_action_t ret = CC_NORM; + el_action_t ret = CC_NORM; - int ohisteventno = el->el_history.eventno, - oldpatlen = el->el_search.patlen, - newdir = dir, - done, redo; + int ohisteventno = el->el_history.eventno; + int oldpatlen = el->el_search.patlen; + int newdir = dir; + int done, redo; - if (el->el_line.lastchar + sizeof(STRfwd) / sizeof(char) + 2 + - el->el_search.patlen >= el->el_line.limit) - return CC_ERROR; + if (el->el_line.lastchar + sizeof(STRfwd) / sizeof(char) + 2 + + el->el_search.patlen >= el->el_line.limit) + return (CC_ERROR); - for (;;) { + for (;;) { - if (el->el_search.patlen == 0) { /* first round */ - pchar = ':'; + if (el->el_search.patlen == 0) { /* first round */ + pchar = ':'; #ifdef ANCHOR - 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++] = '*'; #endif - } - done = redo = 0; - *el->el_line.lastchar++ = '\n'; - for (cp = newdir == ED_SEARCH_PREV_HISTORY ? STRbck : STRfwd; - *cp; *el->el_line.lastchar++ = *cp++) - continue; - *el->el_line.lastchar++ = pchar; - for (cp = &el->el_search.patbuf[1]; - cp < &el->el_search.patbuf[el->el_search.patlen]; - *el->el_line.lastchar++ = *cp++) - continue; - *el->el_line.lastchar = '\0'; - re_refresh(el); - - if (el_getc(el, &ch) != 1) - return ed_end_of_file(el, 0); - - switch (el->el_map.current[(unsigned char) ch]) { - case ED_INSERT: - case ED_DIGIT: - if (el->el_search.patlen > EL_BUFSIZ - 3) - term_beep(el); - else { - el->el_search.patbuf[el->el_search.patlen++] = ch; - *el->el_line.lastchar++ = ch; + } + done = redo = 0; + *el->el_line.lastchar++ = '\n'; + for (cp = (newdir == ED_SEARCH_PREV_HISTORY) ? STRbck : STRfwd; + *cp; *el->el_line.lastchar++ = *cp++) + continue; + *el->el_line.lastchar++ = pchar; + for (cp = &el->el_search.patbuf[1]; + cp < &el->el_search.patbuf[el->el_search.patlen]; + *el->el_line.lastchar++ = *cp++) + continue; *el->el_line.lastchar = '\0'; re_refresh(el); - } - break; - - case EM_INC_SEARCH_NEXT: - newdir = ED_SEARCH_NEXT_HISTORY; - redo++; - break; - - case EM_INC_SEARCH_PREV: - newdir = ED_SEARCH_PREV_HISTORY; - redo++; - break; - - case ED_DELETE_PREV_CHAR: - if (el->el_search.patlen > 1) - done++; - else - term_beep(el); - break; - default: - switch (ch) { - case 0007: /* ^G: Abort */ - ret = CC_ERROR; - done++; - break; - - case 0027: /* ^W: Append word */ - /* No can do if globbing characters in pattern */ - for (cp = &el->el_search.patbuf[1]; ; cp++) - if (cp >= &el->el_search.patbuf[el->el_search.patlen]) { - el->el_line.cursor += el->el_search.patlen - 1; - cp = c__next_word(el->el_line.cursor, - el->el_line.lastchar, 1, ce__isword); - while (el->el_line.cursor < cp && - *el->el_line.cursor != '\n') { - if (el->el_search.patlen > EL_BUFSIZ - 3) { + if (el_getc(el, &ch) != 1) + return (ed_end_of_file(el, 0)); + + switch (el->el_map.current[(unsigned char) ch]) { + case ED_INSERT: + case ED_DIGIT: + if (el->el_search.patlen > EL_BUFSIZ - 3) term_beep(el); - break; - } - el->el_search.patbuf[el->el_search.patlen++] = - *el->el_line.cursor; - *el->el_line.lastchar++ = *el->el_line.cursor++; + else { + el->el_search.patbuf[el->el_search.patlen++] = + ch; + *el->el_line.lastchar++ = ch; + *el->el_line.lastchar = '\0'; + re_refresh(el); } - el->el_line.cursor = ocursor; - *el->el_line.lastchar = '\0'; - re_refresh(el); break; - } else if (isglob(*cp)) { - term_beep(el); + + case EM_INC_SEARCH_NEXT: + newdir = ED_SEARCH_NEXT_HISTORY; + redo++; + break; + + case EM_INC_SEARCH_PREV: + newdir = ED_SEARCH_PREV_HISTORY; + redo++; break; - } - break; - - default: /* Terminate and execute cmd */ - endcmd[0] = ch; - el_push(el, endcmd); - /*FALLTHROUGH*/ - - case 0033: /* ESC: Terminate */ - ret = CC_REFRESH; - done++; - break; - } - break; - } - while (el->el_line.lastchar > el->el_line.buffer && - *el->el_line.lastchar != '\n') - *el->el_line.lastchar-- = '\0'; - *el->el_line.lastchar = '\0'; + case ED_DELETE_PREV_CHAR: + if (el->el_search.patlen > 1) + done++; + else + term_beep(el); + break; - if (!done) { + default: + switch (ch) { + case 0007: /* ^G: Abort */ + ret = CC_ERROR; + done++; + break; - /* Can't search if unmatched '[' */ - for (cp = &el->el_search.patbuf[el->el_search.patlen-1], ch = ']'; - cp > el->el_search.patbuf; cp--) - if (*cp == '[' || *cp == ']') { - ch = *cp; - break; - } + case 0027: /* ^W: Append word */ + /* No can do if globbing characters in pattern */ + for (cp = &el->el_search.patbuf[1];; cp++) + if (cp >= &el->el_search.patbuf[el->el_search.patlen]) { + el->el_line.cursor += + el->el_search.patlen - 1; + cp = c__next_word(el->el_line.cursor, + el->el_line.lastchar, 1, + ce__isword); + while (el->el_line.cursor < cp && + *el->el_line.cursor != '\n') { + if (el->el_search.patlen > + EL_BUFSIZ - 3) { + term_beep(el); + break; + } + el->el_search.patbuf[el->el_search.patlen++] = + *el->el_line.cursor; + *el->el_line.lastchar++ = + *el->el_line.cursor++; + } + el->el_line.cursor = ocursor; + *el->el_line.lastchar = '\0'; + re_refresh(el); + break; + } else if (isglob(*cp)) { + term_beep(el); + break; + } + break; - if (el->el_search.patlen > 1 && ch != '[') { - if (redo && newdir == dir) { - if (pchar == '?') { /* wrap around */ - el->el_history.eventno = - newdir == ED_SEARCH_PREV_HISTORY ? 0 : 0x7fffffff; - if (hist_get(el) == CC_ERROR) - /* el->el_history.eventno was fixed by first call */ - (void) hist_get(el); - el->el_line.cursor = newdir == ED_SEARCH_PREV_HISTORY ? - el->el_line.lastchar : el->el_line.buffer; - } else - el->el_line.cursor += - newdir == ED_SEARCH_PREV_HISTORY ? -1 : 1; - } -#ifdef ANCHOR - el->el_search.patbuf[el->el_search.patlen++] = '.'; - el->el_search.patbuf[el->el_search.patlen++] = '*'; -#endif - el->el_search.patbuf[el->el_search.patlen] = '\0'; - if (el->el_line.cursor < el->el_line.buffer || - el->el_line.cursor > el->el_line.lastchar || - (ret = ce_search_line(el, &el->el_search.patbuf[1], - newdir)) == CC_ERROR) { - /* avoid c_setpat */ - el->el_state.lastcmd = (el_action_t) newdir; - ret = newdir == ED_SEARCH_PREV_HISTORY ? - ed_search_prev_history(el, 0) : - ed_search_next_history(el, 0); - if (ret != CC_ERROR) { - el->el_line.cursor = newdir == ED_SEARCH_PREV_HISTORY ? - el->el_line.lastchar : el->el_line.buffer; - (void) ce_search_line(el, &el->el_search.patbuf[1], - newdir); - } - } - el->el_search.patbuf[--el->el_search.patlen] = '\0'; - if (ret == CC_ERROR) { - term_beep(el); - if (el->el_history.eventno != ohisteventno) { - el->el_history.eventno = ohisteventno; - if (hist_get(el) == CC_ERROR) - return CC_ERROR; - } - el->el_line.cursor = ocursor; - pchar = '?'; - } else { - pchar = ':'; + default: /* Terminate and execute cmd */ + endcmd[0] = ch; + el_push(el, endcmd); + /* FALLTHROUGH */ + + case 0033: /* ESC: Terminate */ + ret = CC_REFRESH; + done++; + break; + } + break; } - } - ret = ce_inc_search(el, newdir); + while (el->el_line.lastchar > el->el_line.buffer && + *el->el_line.lastchar != '\n') + *el->el_line.lastchar-- = '\0'; + *el->el_line.lastchar = '\0'; - if (ret == CC_ERROR && pchar == '?' && oldpchar == ':') - /* break abort of failed search at last non-failed */ - ret = CC_NORM; + if (!done) { + + /* Can't search if unmatched '[' */ + for (cp = &el->el_search.patbuf[el->el_search.patlen-1], + ch = ']'; + cp > el->el_search.patbuf; + cp--) + if (*cp == '[' || *cp == ']') { + ch = *cp; + break; + } + if (el->el_search.patlen > 1 && ch != '[') { + if (redo && newdir == dir) { + if (pchar == '?') { /* wrap around */ + el->el_history.eventno = + newdir == ED_SEARCH_PREV_HISTORY ? 0 : 0x7fffffff; + if (hist_get(el) == CC_ERROR) + /* el->el_history.event + * no was fixed by + * first call */ + (void) hist_get(el); + el->el_line.cursor = newdir == + ED_SEARCH_PREV_HISTORY ? + el->el_line.lastchar : + el->el_line.buffer; + } else + el->el_line.cursor += + newdir == + ED_SEARCH_PREV_HISTORY ? + -1 : 1; + } +#ifdef ANCHOR + el->el_search.patbuf[el->el_search.patlen++] = + '.'; + el->el_search.patbuf[el->el_search.patlen++] = + '*'; +#endif + el->el_search.patbuf[el->el_search.patlen] = + '\0'; + if (el->el_line.cursor < el->el_line.buffer || + el->el_line.cursor > el->el_line.lastchar || + (ret = ce_search_line(el, + &el->el_search.patbuf[1], + newdir)) == CC_ERROR) { + /* avoid c_setpat */ + el->el_state.lastcmd = + (el_action_t) newdir; + ret = newdir == ED_SEARCH_PREV_HISTORY ? + ed_search_prev_history(el, 0) : + ed_search_next_history(el, 0); + if (ret != CC_ERROR) { + el->el_line.cursor = newdir == + ED_SEARCH_PREV_HISTORY ? + el->el_line.lastchar : + el->el_line.buffer; + (void) ce_search_line(el, + &el->el_search.patbuf[1], + newdir); + } + } + el->el_search.patbuf[--el->el_search.patlen] = + '\0'; + if (ret == CC_ERROR) { + term_beep(el); + if (el->el_history.eventno != + ohisteventno) { + el->el_history.eventno = + ohisteventno; + if (hist_get(el) == CC_ERROR) + return (CC_ERROR); + } + el->el_line.cursor = ocursor; + pchar = '?'; + } else { + pchar = ':'; + } + } + ret = ce_inc_search(el, newdir); - } + if (ret == CC_ERROR && pchar == '?' && oldpchar == ':') + /* + * break abort of failed search at last + * non-failed + */ + ret = CC_NORM; - if (ret == CC_NORM || (ret == CC_ERROR && oldpatlen == 0)) { - /* restore on normal return or error exit */ - pchar = oldpchar; - el->el_search.patlen = oldpatlen; - if (el->el_history.eventno != ohisteventno) { - el->el_history.eventno = ohisteventno; - if (hist_get(el) == CC_ERROR) - return CC_ERROR; - } - el->el_line.cursor = ocursor; - if (ret == CC_ERROR) - re_refresh(el); + } + if (ret == CC_NORM || (ret == CC_ERROR && oldpatlen == 0)) { + /* restore on normal return or error exit */ + pchar = oldpchar; + el->el_search.patlen = oldpatlen; + if (el->el_history.eventno != ohisteventno) { + el->el_history.eventno = ohisteventno; + if (hist_get(el) == CC_ERROR) + return (CC_ERROR); + } + el->el_line.cursor = ocursor; + if (ret == CC_ERROR) + re_refresh(el); + } + if (done || ret != CC_NORM) + return (ret); } - if (done || ret != CC_NORM) - return ret; - } } @@ -420,93 +443,89 @@ ce_inc_search(el, dir) * Vi search. */ protected el_action_t -cv_search(el, dir) - EditLine *el; - int dir; +cv_search(EditLine *el, int dir) { - char ch; - char tmpbuf[EL_BUFSIZ]; - int tmplen; + char ch; + char tmpbuf[EL_BUFSIZ]; + int tmplen; - tmplen = 0; + tmplen = 0; #ifdef ANCHOR - tmpbuf[tmplen++] = '.'; - tmpbuf[tmplen++] = '*'; + tmpbuf[tmplen++] = '.'; + tmpbuf[tmplen++] = '*'; #endif - 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_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; - c_insert(el, 2); /* prompt + '\n' */ - *el->el_line.cursor++ = '\n'; - *el->el_line.cursor++ = dir == ED_SEARCH_PREV_HISTORY ? '/' : '?'; - re_refresh(el); + c_insert(el, 2); /* prompt + '\n' */ + *el->el_line.cursor++ = '\n'; + *el->el_line.cursor++ = dir == ED_SEARCH_PREV_HISTORY ? '/' : '?'; + re_refresh(el); #ifdef ANCHOR -# define LEN 2 +#define LEN 2 #else -# define LEN 0 +#define LEN 0 #endif - tmplen = c_gets(el, &tmpbuf[LEN]) + LEN; - ch = tmpbuf[tmplen]; - tmpbuf[tmplen] = '\0'; - - if (tmplen == LEN) { - /* - * Use the old pattern, but wild-card it. - */ - 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); - return CC_ERROR; - } + tmplen = c_gets(el, &tmpbuf[LEN]) + LEN; + ch = tmpbuf[tmplen]; + tmpbuf[tmplen] = '\0'; + + if (tmplen == LEN) { + /* + * Use the old pattern, but wild-card it. + */ + 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); + return (CC_ERROR); + } #ifdef ANCHOR - if (el->el_search.patbuf[0] != '.' && el->el_search.patbuf[0] != '*') { - (void)strncpy(tmpbuf, el->el_search.patbuf, sizeof(tmpbuf) - 1); - el->el_search.patbuf[0] = '.'; - el->el_search.patbuf[1] = '*'; - (void)strncpy(&el->el_search.patbuf[2], tmpbuf, - sizeof(el->el_search.patbuf) - 3); - el->el_search.patlen++; - el->el_search.patbuf[el->el_search.patlen++] = '.'; - el->el_search.patbuf[el->el_search.patlen++] = '*'; - el->el_search.patbuf[el->el_search.patlen] = '\0'; - } + if (el->el_search.patbuf[0] != '.' && + el->el_search.patbuf[0] != '*') { + (void) strncpy(tmpbuf, el->el_search.patbuf, + sizeof(tmpbuf) - 1); + el->el_search.patbuf[0] = '.'; + el->el_search.patbuf[1] = '*'; + (void) strncpy(&el->el_search.patbuf[2], tmpbuf, + EL_BUFSIZ - 3); + el->el_search.patlen++; + el->el_search.patbuf[el->el_search.patlen++] = '.'; + el->el_search.patbuf[el->el_search.patlen++] = '*'; + el->el_search.patbuf[el->el_search.patlen] = '\0'; + } #endif - } - else { + } else { #ifdef ANCHOR - tmpbuf[tmplen++] = '.'; - tmpbuf[tmplen++] = '*'; + tmpbuf[tmplen++] = '.'; + tmpbuf[tmplen++] = '*'; #endif - tmpbuf[tmplen] = '\0'; - (void)strncpy(el->el_search.patbuf, tmpbuf, - sizeof(el->el_search.patbuf) - 1); - el->el_search.patlen = tmplen; - } - el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */ - el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer; - if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) : - ed_search_next_history(el, 0)) == CC_ERROR) { - re_refresh(el); - return CC_ERROR; - } - else { - if (ch == 0033) { - re_refresh(el); - *el->el_line.lastchar++ = '\n'; - *el->el_line.lastchar = '\0'; - re_goto_bottom(el); - return CC_NEWLINE; + tmpbuf[tmplen] = '\0'; + (void) strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1); + el->el_search.patlen = tmplen; + } + el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */ + el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer; + if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) : + ed_search_next_history(el, 0)) == CC_ERROR) { + re_refresh(el); + return (CC_ERROR); + } 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); } - else - return CC_REFRESH; - } } @@ -514,29 +533,26 @@ cv_search(el, dir) * Look for a pattern inside a line */ protected el_action_t -ce_search_line(el, pattern, dir) - EditLine *el; - char *pattern; - int dir; +ce_search_line(EditLine *el, char *pattern, int dir) { - char *cp; - - if (dir == ED_SEARCH_PREV_HISTORY) { - for (cp = el->el_line.cursor; cp >= el->el_line.buffer; cp--) - if (el_match(cp, pattern)) { - el->el_line.cursor = cp; - return CC_NORM; - } - return CC_ERROR; - } else { - for (cp = el->el_line.cursor; *cp != '\0' && - cp < el->el_line.limit; cp++) - if (el_match(cp, pattern)) { - el->el_line.cursor = cp; - return CC_NORM; - } - return CC_ERROR; - } + char *cp; + + if (dir == ED_SEARCH_PREV_HISTORY) { + for (cp = el->el_line.cursor; cp >= el->el_line.buffer; cp--) + if (el_match(cp, pattern)) { + el->el_line.cursor = cp; + return (CC_NORM); + } + return (CC_ERROR); + } else { + for (cp = el->el_line.cursor; *cp != '\0' && + cp < el->el_line.limit; cp++) + if (el_match(cp, pattern)) { + el->el_line.cursor = cp; + return (CC_NORM); + } + return (CC_ERROR); + } } @@ -544,26 +560,25 @@ ce_search_line(el, pattern, dir) * Vi repeat search */ protected el_action_t -cv_repeat_srch(el, c) - EditLine *el; - int c; +cv_repeat_srch(EditLine *el, int c) { + #ifdef SDEBUG - (void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n", - c, el->el_search.patlen, el->el_search.patbuf); + (void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n", + c, el->el_search.patlen, el->el_search.patbuf); #endif - el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */ - el->el_line.lastchar = el->el_line.buffer; - - switch (c) { - case ED_SEARCH_NEXT_HISTORY: - return ed_search_next_history(el, 0); - case ED_SEARCH_PREV_HISTORY: - return ed_search_prev_history(el, 0); - default: - return CC_ERROR; - } + el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */ + el->el_line.lastchar = el->el_line.buffer; + + switch (c) { + case ED_SEARCH_NEXT_HISTORY: + return (ed_search_next_history(el, 0)); + case ED_SEARCH_PREV_HISTORY: + return (ed_search_prev_history(el, 0)); + default: + return (CC_ERROR); + } } @@ -571,36 +586,33 @@ cv_repeat_srch(el, c) * Vi character search reverse */ protected el_action_t -cv_csearch_back(el, ch, count, tflag) - EditLine *el; - int ch, count, tflag; +cv_csearch_back(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.buffer && *cp != ch) - cp--; - } - - if (cp < el->el_line.buffer || (cp == el->el_line.buffer && *cp != ch)) - return CC_ERROR; + char *cp; + + cp = el->el_line.cursor; + while (count--) { + if (*cp == ch) + cp--; + while (cp > el->el_line.buffer && *cp != ch) + cp--; + } - if (*cp == ch && tflag) - cp++; + if (cp < el->el_line.buffer || (cp == el->el_line.buffer && *cp != ch)) + return (CC_ERROR); - el->el_line.cursor = cp; + if (*cp == ch && tflag) + cp++; - if (el->el_chared.c_vcmd.action & DELETE) { - el->el_line.cursor++; - cv_delfini(el); - return CC_REFRESH; - } + el->el_line.cursor = cp; - re_refresh_cursor(el); - return CC_NORM; + 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); } @@ -608,33 +620,31 @@ cv_csearch_back(el, ch, count, tflag) * Vi character search forward */ protected el_action_t -cv_csearch_fwd(el, ch, count, tflag) - EditLine *el; - int ch, count, tflag; +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; + 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); } diff --git a/dist/search.h b/dist/search.h index 3df5486..676bbe2 100644 --- a/dist/search.h +++ b/dist/search.h @@ -1,4 +1,4 @@ -/* $NetBSD: search.h,v 1.2 1997/01/11 06:48:09 lukem Exp $ */ +/* $NetBSD: search.h,v 1.5 2000/09/04 22:06:32 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -41,30 +41,30 @@ /* * el.search.h: Line and history searching utilities */ -#ifndef _h_el_search -#define _h_el_search +#ifndef _h_el_search +#define _h_el_search #include "histedit.h" typedef struct el_search_t { - char *patbuf; /* The pattern buffer */ - int patlen; /* Length of the pattern buffer */ - int patdir; /* Direction of the last search */ - int chadir; /* Character search direction */ - char chacha; /* Character we are looking for */ + char *patbuf; /* The pattern buffer */ + size_t patlen; /* Length of the pattern buffer */ + int patdir; /* Direction of the last search */ + int chadir; /* Character search direction */ + char chacha; /* Character we are looking for */ } el_search_t; -protected int el_match __P((const char *, const char *)); -protected int search_init __P((EditLine *)); -protected void search_end __P((EditLine *)); -protected int c_hmatch __P((EditLine *, const char *)); -protected void c_setpat __P((EditLine *)); -protected el_action_t ce_inc_search __P((EditLine *, int)); -protected el_action_t cv_search __P((EditLine *, int)); -protected el_action_t ce_search_line __P((EditLine *, char *, int)); -protected el_action_t cv_repeat_srch __P((EditLine *, int)); -protected el_action_t cv_csearch_back __P((EditLine *, int, int, int)); -protected el_action_t cv_csearch_fwd __P((EditLine *, int, int, int)); +protected int el_match(const char *, const char *); +protected int search_init(EditLine *); +protected void search_end(EditLine *); +protected int c_hmatch(EditLine *, const char *); +protected void c_setpat(EditLine *); +protected el_action_t ce_inc_search(EditLine *, int); +protected el_action_t cv_search(EditLine *, int); +protected el_action_t ce_search_line(EditLine *, char *, 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_fwd(EditLine *, int, int, int); #endif /* _h_el_search */ diff --git a/dist/shlib_version b/dist/shlib_version index 97c9f92..24699bb 100644 --- a/dist/shlib_version +++ b/dist/shlib_version @@ -1,2 +1,5 @@ -major=0 -minor=0 +# $NetBSD: shlib_version,v 1.11 2001/01/01 15:54:07 jdolecek Exp $ +# Remember to update distrib/sets/lists/base/shl.* when changing +# +major=2 +minor=5 @@ -1,4 +1,4 @@ -/* $NetBSD: sig.c,v 1.3 1997/04/11 17:52:48 christos Exp $ */ +/* $NetBSD: sig.c,v 1.8 2001/01/09 17:31:04 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,11 +36,12 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: sig.c,v 1.3 1997/04/11 17:52:48 christos Exp $"; +__RCSID("$NetBSD: sig.c,v 1.8 2001/01/09 17:31:04 jdolecek Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -55,14 +56,14 @@ static char rcsid[] = "$NetBSD: sig.c,v 1.3 1997/04/11 17:52:48 christos Exp $"; private EditLine *sel = NULL; -private int sighdl[] = { -#define _DO(a) (a), - ALLSIGS -#undef _DO - -1 +private const int sighdl[] = { +#define _DO(a) (a), + ALLSIGS +#undef _DO + - 1 }; -private void sig_handler __P((int)); +private void sig_handler(int); /* sig_handler(): * This is the handler called for all signals @@ -70,40 +71,39 @@ private void sig_handler __P((int)); * state in a private variable */ private void -sig_handler(signo) - int signo; +sig_handler(int signo) { - int i; - sigset_t nset, oset; - - (void) sigemptyset(&nset); - (void) sigaddset(&nset, signo); - (void) sigprocmask(SIG_BLOCK, &nset, &oset); - - switch (signo) { - case SIGCONT: - tty_rawmode(sel); - if (ed_redisplay(sel, 0) == CC_REFRESH) - re_refresh(sel); - term__flush(); - break; - - case SIGWINCH: - el_resize(sel); - break; - - default: - tty_cookedmode(sel); - break; - } - - for (i = 0; sighdl[i] != -1; i++) - if (signo == sighdl[i]) - break; - - (void) signal(signo, sel->el_signal[i]); - (void) sigprocmask(SIG_SETMASK, &oset, NULL); - (void) kill(0, signo); + int i; + sigset_t nset, oset; + + (void) sigemptyset(&nset); + (void) sigaddset(&nset, signo); + (void) sigprocmask(SIG_BLOCK, &nset, &oset); + + switch (signo) { + case SIGCONT: + tty_rawmode(sel); + if (ed_redisplay(sel, 0) == CC_REFRESH) + re_refresh(sel); + term__flush(); + break; + + case SIGWINCH: + el_resize(sel); + break; + + default: + tty_cookedmode(sel); + break; + } + + for (i = 0; sighdl[i] != -1; i++) + if (signo == sighdl[i]) + break; + + (void) signal(signo, sel->el_signal[i]); + (void) sigprocmask(SIG_SETMASK, &oset, NULL); + (void) kill(0, signo); } @@ -111,27 +111,28 @@ sig_handler(signo) * Initialize all signal stuff */ protected int -sig_init(el) - EditLine *el; +sig_init(EditLine *el) { - int i; - sigset_t nset, oset; + int i; + sigset_t nset, oset; - (void) sigemptyset(&nset); -#define _DO(a) (void) sigaddset(&nset, SIGWINCH); - ALLSIGS -#undef _DO - (void) sigprocmask(SIG_BLOCK, &nset, &oset); + (void) sigemptyset(&nset); +#define _DO(a) (void) sigaddset(&nset, a); + ALLSIGS +#undef _DO + (void) sigprocmask(SIG_BLOCK, &nset, &oset); -#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(sig_t)) +#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(sig_t)) - el->el_signal = (sig_t *) el_malloc(SIGSIZE); - for (i = 0; sighdl[i] != -1; i++) - el->el_signal[i] = SIG_ERR; + el->el_signal = (sig_t *) el_malloc(SIGSIZE); + if (el->el_signal == NULL) + return (-1); + for (i = 0; sighdl[i] != -1; i++) + el->el_signal[i] = SIG_ERR; - (void) sigprocmask(SIG_SETMASK, &oset, NULL); + (void) sigprocmask(SIG_SETMASK, &oset, NULL); - return 0; + return (0); } @@ -139,11 +140,11 @@ sig_init(el) * Clear all signal stuff */ protected void -sig_end(el) - EditLine *el; +sig_end(EditLine *el) { - el_free((ptr_t) el->el_signal); - el->el_signal = NULL; + + el_free((ptr_t) el->el_signal); + el->el_signal = NULL; } @@ -151,26 +152,25 @@ sig_end(el) * set all the signal handlers */ protected void -sig_set(el) - EditLine *el; +sig_set(EditLine *el) { - int i; - sigset_t nset, oset; - - (void) sigemptyset(&nset); -#define _DO(a) (void) sigaddset(&nset, SIGWINCH); - ALLSIGS -#undef _DO - (void) sigprocmask(SIG_BLOCK, &nset, &oset); - - for (i = 0; sighdl[i] != -1; i++) { - sig_t s; - /* This could happen if we get interrupted */ - if ((s = signal(sighdl[i], sig_handler)) != sig_handler) - el->el_signal[i] = s; - } - sel = el; - (void) sigprocmask(SIG_SETMASK, &oset, NULL); + int i; + sigset_t nset, oset; + + (void) sigemptyset(&nset); +#define _DO(a) (void) sigaddset(&nset, a); + ALLSIGS +#undef _DO + (void) sigprocmask(SIG_BLOCK, &nset, &oset); + + for (i = 0; sighdl[i] != -1; i++) { + sig_t s; + /* This could happen if we get interrupted */ + if ((s = signal(sighdl[i], sig_handler)) != sig_handler) + el->el_signal[i] = s; + } + sel = el; + (void) sigprocmask(SIG_SETMASK, &oset, NULL); } @@ -178,22 +178,22 @@ sig_set(el) * clear all the signal handlers */ protected void -sig_clr(el) - EditLine *el; +sig_clr(EditLine *el) { - int i; - sigset_t nset, oset; - - (void) sigemptyset(&nset); -#define _DO(a) (void) sigaddset(&nset, SIGWINCH); - ALLSIGS -#undef _DO - (void) sigprocmask(SIG_BLOCK, &nset, &oset); - - for (i = 0; sighdl[i] != -1; i++) - if (el->el_signal[i] != SIG_ERR) - (void) signal(sighdl[i], el->el_signal[i]); - - sel = NULL; /* we are going to die if the handler is called */ - (void) sigprocmask(SIG_SETMASK, &oset, NULL); + int i; + sigset_t nset, oset; + + (void) sigemptyset(&nset); +#define _DO(a) (void) sigaddset(&nset, a); + ALLSIGS +#undef _DO + (void) sigprocmask(SIG_BLOCK, &nset, &oset); + + for (i = 0; sighdl[i] != -1; i++) + if (el->el_signal[i] != SIG_ERR) + (void) signal(sighdl[i], el->el_signal[i]); + + sel = NULL; /* we are going to die if the handler is + * called */ + (void) sigprocmask(SIG_SETMASK, &oset, NULL); } @@ -1,4 +1,4 @@ -/* $NetBSD: sig.h,v 1.2 1997/01/11 06:48:11 lukem Exp $ */ +/* $NetBSD: sig.h,v 1.3 2000/09/04 22:06:32 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,7 +42,7 @@ * el.sig.h: Signal handling functions */ #ifndef _h_el_sig -#define _h_el_sig +#define _h_el_sig #include <signal.h> @@ -52,21 +52,21 @@ * Define here all the signals we are going to handle * The _DO macro is used to iterate in the source code */ -#define ALLSIGS \ - _DO(SIGINT) \ - _DO(SIGTSTP) \ - _DO(SIGSTOP) \ - _DO(SIGQUIT) \ - _DO(SIGHUP) \ - _DO(SIGTERM) \ - _DO(SIGCONT) \ - _DO(SIGWINCH) +#define ALLSIGS \ + _DO(SIGINT) \ + _DO(SIGTSTP) \ + _DO(SIGSTOP) \ + _DO(SIGQUIT) \ + _DO(SIGHUP) \ + _DO(SIGTERM) \ + _DO(SIGCONT) \ + _DO(SIGWINCH) -typedef sig_t *el_signal_t; +typedef sig_t *el_signal_t; -protected void sig_end __P((EditLine*)); -protected int sig_init __P((EditLine*)); -protected void sig_set __P((EditLine*)); -protected void sig_clr __P((EditLine*)); +protected void sig_end(EditLine*); +protected int sig_init(EditLine*); +protected void sig_set(EditLine*); +protected void sig_clr(EditLine*); #endif /* _h_el_sig */ @@ -1,4 +1,4 @@ -/* $NetBSD: sys.h,v 1.3 1997/01/11 06:48:12 lukem Exp $ */ +/* $NetBSD: sys.h,v 1.4 2000/09/04 22:06:32 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,7 +42,7 @@ * sys.h: Put all the stupid compiler and system dependencies here... */ #ifndef _h_sys -#define _h_sys +#define _h_sys #ifndef public # define public /* Externally visible functions/variables */ @@ -61,20 +61,12 @@ #ifndef _PTR_T # define _PTR_T -# if __STDC__ -typedef void* ptr_t; -# else -typedef char* ptr_t; -# endif +typedef void *ptr_t; #endif #ifndef _IOCTL_T # define _IOCTL_T -# if __STDC__ -typedef void* ioctl_t; -# else -typedef char* ioctl_t; -# endif +typedef void *ioctl_t; #endif #include <stdio.h> @@ -86,33 +78,33 @@ typedef char* ioctl_t; # undef REGEX # undef REGEXP # include <malloc.h> -typedef void (*sig_t)__P((int)); +typedef void (*sig_t)(int); # ifdef __GNUC__ /* * Broken hdrs. */ -extern char *getenv __P((const char *)); -extern int fprintf __P((FILE *, const char *, ...)); -extern int sigsetmask __P((int)); -extern int sigblock __P((int)); -extern int ioctl __P((int, int, void *)); -extern int fputc __P((int, FILE *)); -extern int fgetc __P((FILE *)); -extern int fflush __P((FILE *)); -extern int tolower __P((int)); -extern int toupper __P((int)); +extern char *getenv(const char *); +extern int fprintf(FILE *, const char *, ...); +extern int sigsetmask(int); +extern int sigblock(int); +extern int ioctl(int, int, void *); +extern int fputc(int, FILE *); +extern int fgetc(FILE *); +extern int fflush(FILE *); +extern int tolower(int); +extern int toupper(int); extern int errno, sys_nerr; extern char *sys_errlist[]; -extern void perror __P((const char *)); -extern int read __P((int, const char*, int)); +extern void perror(const char *); +extern int read(int, const char*, int); # include <string.h> # define strerror(e) sys_errlist[e] # endif # ifdef SABER -extern ptr_t memcpy __P((ptr_t, const ptr_t, size_t)); -extern ptr_t memset __P((ptr_t, int, size_t)); +extern ptr_t memcpy(ptr_t, const ptr_t, size_t); +extern ptr_t memset(ptr_t, int, size_t); # endif -extern char *fgetline __P((FILE *, int *)); +extern char *fgetline(FILE *, int *); #endif #endif /* _h_sys */ diff --git a/dist/term.c b/dist/term.c index 6e3670d..dfbe30e 100644 --- a/dist/term.c +++ b/dist/term.c @@ -1,4 +1,4 @@ -/* $NetBSD: term.c,v 1.9 1997/04/11 22:40:06 christos Exp $ */ +/* $NetBSD: term.c,v 1.32 2001/01/23 15:55:31 jdolecek Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,11 +36,12 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 -static char sccsid[] = "@(#)term.c 8.1 (Berkeley) 6/4/93"; +static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; #else -static char rcsid[] = "$NetBSD: term.c,v 1.9 1997/04/11 22:40:06 christos Exp $"; +__RCSID("$NetBSD: term.c,v 1.32 2001/01/23 15:55:31 jdolecek Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -55,8 +56,9 @@ static char rcsid[] = "$NetBSD: term.c,v 1.9 1997/04/11 22:40:06 christos Exp $" #include <string.h> #include <stdlib.h> #include <unistd.h> -#include "termcap.h" /* XXX: should be <termcap.h> */ +#include <termcap.h> #include <sys/types.h> +#include <sys/ioctl.h> #include "el.h" @@ -67,195 +69,201 @@ static char rcsid[] = "$NetBSD: term.c,v 1.9 1997/04/11 22:40:06 christos Exp $" * assumption... */ -#define TC_BUFSIZE 2048 +#define TC_BUFSIZE 2048 -#define GoodStr(a) (el->el_term.t_str[a] != NULL && \ - el->el_term.t_str[a][0] != '\0') -#define Str(a) el->el_term.t_str[a] -#define Val(a) el->el_term.t_val[a] +#define GoodStr(a) (el->el_term.t_str[a] != NULL && \ + el->el_term.t_str[a][0] != '\0') +#define Str(a) el->el_term.t_str[a] +#define Val(a) el->el_term.t_val[a] #ifdef notdef -private struct { - char *b_name; - int b_rate; +private const struct { + const char *b_name; + int b_rate; } baud_rate[] = { #ifdef B0 - { "0", B0 }, + { "0", B0 }, #endif #ifdef B50 - { "50", B50 }, + { "50", B50 }, #endif #ifdef B75 - { "75", B75 }, + { "75", B75 }, #endif #ifdef B110 - { "110", B110 }, + { "110", B110 }, #endif #ifdef B134 - { "134", B134 }, + { "134", B134 }, #endif #ifdef B150 - { "150", B150 }, + { "150", B150 }, #endif #ifdef B200 - { "200", B200 }, + { "200", B200 }, #endif #ifdef B300 - { "300", B300 }, + { "300", B300 }, #endif #ifdef B600 - { "600", B600 }, + { "600", B600 }, #endif #ifdef B900 - { "900", B900 }, + { "900", B900 }, #endif #ifdef B1200 - { "1200", B1200 }, + { "1200", B1200 }, #endif #ifdef B1800 - { "1800", B1800 }, + { "1800", B1800 }, #endif #ifdef B2400 - { "2400", B2400 }, + { "2400", B2400 }, #endif #ifdef B3600 - { "3600", B3600 }, + { "3600", B3600 }, #endif #ifdef B4800 - { "4800", B4800 }, + { "4800", B4800 }, #endif #ifdef B7200 - { "7200", B7200 }, + { "7200", B7200 }, #endif #ifdef B9600 - { "9600", B9600 }, + { "9600", B9600 }, #endif #ifdef EXTA - { "19200", EXTA }, + { "19200", EXTA }, #endif #ifdef B19200 - { "19200", B19200 }, + { "19200", B19200 }, #endif #ifdef EXTB - { "38400", EXTB }, + { "38400", EXTB }, #endif #ifdef B38400 - { "38400", B38400 }, + { "38400", B38400 }, #endif - { NULL, 0 } + { NULL, 0 } }; #endif -private struct termcapstr { - char *name; - char *long_name; +private const struct termcapstr { + const char *name; + const char *long_name; } tstr[] = { - -#define T_al 0 - { "al", "add new blank line" }, -#define T_bl 1 - { "bl", "audible bell" }, -#define T_cd 2 - { "cd", "clear to bottom" }, -#define T_ce 3 - { "ce", "clear to end of line" }, -#define T_ch 4 - { "ch", "cursor to horiz pos" }, -#define T_cl 5 - { "cl", "clear screen" }, +#define T_al 0 + { "al", "add new blank line" }, +#define T_bl 1 + { "bl", "audible bell" }, +#define T_cd 2 + { "cd", "clear to bottom" }, +#define T_ce 3 + { "ce", "clear to end of line" }, +#define T_ch 4 + { "ch", "cursor to horiz pos" }, +#define T_cl 5 + { "cl", "clear screen" }, #define T_dc 6 - { "dc", "delete a character" }, + { "dc", "delete a character" }, #define T_dl 7 - { "dl", "delete a line" }, + { "dl", "delete a line" }, #define T_dm 8 - { "dm", "start delete mode" }, + { "dm", "start delete mode" }, #define T_ed 9 - { "ed", "end delete mode" }, + { "ed", "end delete mode" }, #define T_ei 10 - { "ei", "end insert mode" }, + { "ei", "end insert mode" }, #define T_fs 11 - { "fs", "cursor from status line" }, + { "fs", "cursor from status line" }, #define T_ho 12 - { "ho", "home cursor" }, + { "ho", "home cursor" }, #define T_ic 13 - { "ic", "insert character" }, -#define T_im 14 - { "im", "start insert mode" }, + { "ic", "insert character" }, +#define T_im 14 + { "im", "start insert mode" }, #define T_ip 15 - { "ip", "insert padding" }, + { "ip", "insert padding" }, #define T_kd 16 - { "kd", "sends cursor down" }, + { "kd", "sends cursor down" }, #define T_kl 17 - { "kl", "sends cursor left" }, -#define T_kr 18 - { "kr", "sends cursor right" }, -#define T_ku 19 - { "ku", "sends cursor up" }, -#define T_md 20 - { "md", "begin bold" }, -#define T_me 21 - { "me", "end attributes" }, -#define T_nd 22 - { "nd", "non destructive space" }, -#define T_se 23 - { "se", "end standout" }, -#define T_so 24 - { "so", "begin standout" }, -#define T_ts 25 - { "ts", "cursor to status line" }, -#define T_up 26 - { "up", "cursor up one" }, -#define T_us 27 - { "us", "begin underline" }, -#define T_ue 28 - { "ue", "end underline" }, -#define T_vb 29 - { "vb", "visible bell" }, -#define T_DC 30 - { "DC", "delete multiple chars" }, -#define T_DO 31 - { "DO", "cursor down multiple" }, -#define T_IC 32 - { "IC", "insert multiple chars" }, -#define T_LE 33 - { "LE", "cursor left multiple" }, -#define T_RI 34 - { "RI", "cursor right multiple" }, -#define T_UP 35 - { "UP", "cursor up multiple" }, -#define T_str 36 - { NULL, NULL } + { "kl", "sends cursor left" }, +#define T_kr 18 + { "kr", "sends cursor right" }, +#define T_ku 19 + { "ku", "sends cursor up" }, +#define T_md 20 + { "md", "begin bold" }, +#define T_me 21 + { "me", "end attributes" }, +#define T_nd 22 + { "nd", "non destructive space" }, +#define T_se 23 + { "se", "end standout" }, +#define T_so 24 + { "so", "begin standout" }, +#define T_ts 25 + { "ts", "cursor to status line" }, +#define T_up 26 + { "up", "cursor up one" }, +#define T_us 27 + { "us", "begin underline" }, +#define T_ue 28 + { "ue", "end underline" }, +#define T_vb 29 + { "vb", "visible bell" }, +#define T_DC 30 + { "DC", "delete multiple chars" }, +#define T_DO 31 + { "DO", "cursor down multiple" }, +#define T_IC 32 + { "IC", "insert multiple chars" }, +#define T_LE 33 + { "LE", "cursor left multiple" }, +#define T_RI 34 + { "RI", "cursor right multiple" }, +#define T_UP 35 + { "UP", "cursor up multiple" }, +#define T_kh 36 + { "kh", "send cursor home" }, +#define T_at7 37 + { "@7", "send cursor end" }, +#define T_str 38 + { NULL, NULL } }; -private struct termcapval { - char *name; - char *long_name; +private const struct termcapval { + const char *name; + const char *long_name; } tval[] = { -#define T_pt 0 - { "pt", "has physical tabs" }, -#define T_li 1 - { "li", "Number of lines" }, -#define T_co 2 - { "co", "Number of columns" }, -#define T_km 3 - { "km", "Has meta key" }, -#define T_xt 4 - { "xt", "Tab chars destructive" }, -#define T_MT 5 - { "MT", "Has meta key" }, /* XXX? */ -#define T_val 6 - { NULL, NULL, } +#define T_am 0 + { "am", "has automatic margins" }, +#define T_pt 1 + { "pt", "has physical tabs" }, +#define T_li 2 + { "li", "Number of lines" }, +#define T_co 3 + { "co", "Number of columns" }, +#define T_km 4 + { "km", "Has meta key" }, +#define T_xt 5 + { "xt", "Tab chars destructive" }, +#define T_xn 6 + { "xn", "newline ignored at right margin" }, +#define T_MT 7 + { "MT", "Has meta key" }, /* XXX? */ +#define T_val 8 + { NULL, NULL, } }; - /* do two or more of the attributes use me */ -private void term_rebuffer_display __P((EditLine *)); -private void term_free_display __P((EditLine *)); -private void term_alloc_display __P((EditLine *)); -private void term_alloc __P((EditLine *, - struct termcapstr *, char *)); -private void term_init_arrow __P((EditLine *)); -private void term_reset_arrow __P((EditLine *)); +private void term_setflags(EditLine *); +private int term_rebuffer_display(EditLine *); +private void term_free_display(EditLine *); +private int term_alloc_display(EditLine *); +private void term_alloc(EditLine *, const struct termcapstr *, char *); +private void term_init_arrow(EditLine *); +private void term_reset_arrow(EditLine *); private FILE *term_outfile = NULL; /* XXX: How do we fix that? */ @@ -265,39 +273,44 @@ private FILE *term_outfile = NULL; /* XXX: How do we fix that? */ * Set the terminal capability flags */ private void -term_setflags(el) - EditLine *el; +term_setflags(EditLine *el) { - EL_FLAGS = 0; - if (el->el_tty.t_tabs) - EL_FLAGS |= (Val(T_pt) && !Val(T_xt)) ? TERM_CAN_TAB : 0; - - EL_FLAGS |= (Val(T_km) || Val(T_MT)) ? TERM_HAS_META : 0; - EL_FLAGS |= GoodStr(T_ce) ? TERM_CAN_CEOL : 0; - EL_FLAGS |= (GoodStr(T_dc) || GoodStr(T_DC)) ? TERM_CAN_DELETE : 0; - EL_FLAGS |= (GoodStr(T_im) || GoodStr(T_ic) || GoodStr(T_IC)) ? - TERM_CAN_INSERT : 0; - EL_FLAGS |= (GoodStr(T_up) || GoodStr(T_UP)) ? TERM_CAN_UP : 0; - - if (GoodStr(T_me) && GoodStr(T_ue)) - EL_FLAGS |= (strcmp(Str(T_me), Str(T_ue)) == 0) ? TERM_CAN_ME : 0; - else - EL_FLAGS &= ~TERM_CAN_ME; - if (GoodStr(T_me) && GoodStr(T_se)) - EL_FLAGS |= (strcmp(Str(T_me), Str(T_se)) == 0) ? TERM_CAN_ME : 0; + EL_FLAGS = 0; + if (el->el_tty.t_tabs) + EL_FLAGS |= (Val(T_pt) && !Val(T_xt)) ? TERM_CAN_TAB : 0; + + EL_FLAGS |= (Val(T_km) || Val(T_MT)) ? TERM_HAS_META : 0; + EL_FLAGS |= GoodStr(T_ce) ? TERM_CAN_CEOL : 0; + EL_FLAGS |= (GoodStr(T_dc) || GoodStr(T_DC)) ? TERM_CAN_DELETE : 0; + EL_FLAGS |= (GoodStr(T_im) || GoodStr(T_ic) || GoodStr(T_IC)) ? + TERM_CAN_INSERT : 0; + EL_FLAGS |= (GoodStr(T_up) || GoodStr(T_UP)) ? TERM_CAN_UP : 0; + EL_FLAGS |= Val(T_am) ? TERM_HAS_AUTO_MARGINS : 0; + EL_FLAGS |= Val(T_xn) ? TERM_HAS_MAGIC_MARGINS : 0; + + if (GoodStr(T_me) && GoodStr(T_ue)) + EL_FLAGS |= (strcmp(Str(T_me), Str(T_ue)) == 0) ? + TERM_CAN_ME : 0; + else + EL_FLAGS &= ~TERM_CAN_ME; + if (GoodStr(T_me) && GoodStr(T_se)) + EL_FLAGS |= (strcmp(Str(T_me), Str(T_se)) == 0) ? + TERM_CAN_ME : 0; #ifdef DEBUG_SCREEN - if (!EL_CAN_UP) { - (void) fprintf(el->el_errfile, "WARNING: Your terminal cannot move up.\n"); - (void) fprintf(el->el_errfile, "Editing may be odd for long lines.\n"); - } - if (!EL_CAN_CEOL) - (void) fprintf(el->el_errfile, "no clear EOL capability.\n"); - if (!EL_CAN_DELETE) - (void) fprintf(el->el_errfile, "no delete char capability.\n"); - if (!EL_CAN_INSERT) - (void) fprintf(el->el_errfile, "no insert char capability.\n"); + if (!EL_CAN_UP) { + (void) fprintf(el->el_errfile, + "WARNING: Your terminal cannot move up.\n"); + (void) fprintf(el->el_errfile, + "Editing may be odd for long lines.\n"); + } + if (!EL_CAN_CEOL) + (void) fprintf(el->el_errfile, "no clear EOL capability.\n"); + if (!EL_CAN_DELETE) + (void) fprintf(el->el_errfile, "no delete char capability.\n"); + if (!EL_CAN_INSERT) + (void) fprintf(el->el_errfile, "no insert char capability.\n"); #endif /* DEBUG_SCREEN */ } @@ -306,40 +319,50 @@ term_setflags(el) * Initialize the terminal stuff */ protected int -term_init(el) - EditLine *el; +term_init(EditLine *el) { - el->el_term.t_buf = (char *) el_malloc(TC_BUFSIZE); - el->el_term.t_cap = (char *) el_malloc(TC_BUFSIZE); - el->el_term.t_fkey = (fkey_t *) el_malloc(4 * sizeof(fkey_t)); - el->el_term.t_loc = 0; - el->el_term.t_str = (char **) el_malloc(T_str * sizeof(char*)); - (void) memset(el->el_term.t_str, 0, T_str * sizeof(char*)); - el->el_term.t_val = (int *) el_malloc(T_val * sizeof(int)); - (void) memset(el->el_term.t_val, 0, T_val * sizeof(char*)); - term_outfile = el->el_outfile; - (void) term_set(el, NULL); - term_init_arrow(el); - return 0; -} + el->el_term.t_buf = (char *) el_malloc(TC_BUFSIZE); + if (el->el_term.t_buf == NULL) + return (-1); + el->el_term.t_cap = (char *) el_malloc(TC_BUFSIZE); + if (el->el_term.t_cap == NULL) + return (-1); + el->el_term.t_fkey = (fkey_t *) el_malloc(A_K_NKEYS * sizeof(fkey_t)); + if (el->el_term.t_fkey == NULL) + return (-1); + el->el_term.t_loc = 0; + el->el_term.t_str = (char **) el_malloc(T_str * sizeof(char *)); + if (el->el_term.t_str == NULL) + return (-1); + (void) memset(el->el_term.t_str, 0, T_str * sizeof(char *)); + el->el_term.t_val = (int *) el_malloc(T_val * sizeof(int)); + if (el->el_term.t_val == NULL) + return (-1); + (void) memset(el->el_term.t_val, 0, T_val * sizeof(int)); + term_outfile = el->el_outfile; + if (term_set(el, NULL) == -1) + return (-1); + term_init_arrow(el); + return (0); +} /* term_end(): * Clean up the terminal stuff */ protected void -term_end(el) - EditLine *el; +term_end(EditLine *el) { - el_free((ptr_t) el->el_term.t_buf); - el->el_term.t_buf = NULL; - el_free((ptr_t) el->el_term.t_cap); - el->el_term.t_cap = NULL; - el->el_term.t_loc = 0; - el_free((ptr_t) el->el_term.t_str); - el->el_term.t_str = NULL; - el_free((ptr_t) el->el_term.t_val); - el->el_term.t_val = NULL; - term_free_display(el); + + el_free((ptr_t) el->el_term.t_buf); + el->el_term.t_buf = NULL; + el_free((ptr_t) el->el_term.t_cap); + el->el_term.t_cap = NULL; + el->el_term.t_loc = 0; + el_free((ptr_t) el->el_term.t_str); + el->el_term.t_str = NULL; + el_free((ptr_t) el->el_term.t_val); + el->el_term.t_val = NULL; + term_free_display(el); } @@ -347,139 +370,143 @@ term_end(el) * Maintain a string pool for termcap strings */ private void -term_alloc(el, t, cap) - EditLine *el; - struct termcapstr *t; - char *cap; +term_alloc(EditLine *el, const struct termcapstr *t, char *cap) { - char termbuf[TC_BUFSIZE]; - int tlen, clen; - char **tlist = el->el_term.t_str; - char **tmp, **str = &tlist[t - tstr]; - - if (cap == NULL || *cap == '\0') { - *str = NULL; - return; - } - else - clen = strlen(cap); - - tlen = *str == NULL ? 0 : strlen(*str); - - /* - * New string is shorter; no need to allocate space - */ - if (clen <= tlen) { - (void)strcpy(*str, cap); /* XXX strcpy is safe */ - return; - } - - /* - * New string is longer; see if we have enough space to append - */ - if (el->el_term.t_loc + 3 < TC_BUFSIZE) { - /* XXX strcpy is safe */ - (void)strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], cap); - el->el_term.t_loc += clen + 1; /* one for \0 */ - return; - } - - /* - * Compact our buffer; no need to check compaction, cause we know it - * fits... - */ - tlen = 0; - for (tmp = tlist; tmp < &tlist[T_str]; tmp++) - if (*tmp != NULL && *tmp != '\0' && *tmp != *str) { - char *ptr; - - for (ptr = *tmp; *ptr != '\0'; termbuf[tlen++] = *ptr++) - continue; - termbuf[tlen++] = '\0'; + char termbuf[TC_BUFSIZE]; + int tlen, clen; + char **tlist = el->el_term.t_str; + char **tmp, **str = &tlist[t - tstr]; + + if (cap == NULL || *cap == '\0') { + *str = NULL; + return; + } else + clen = strlen(cap); + + tlen = *str == NULL ? 0 : strlen(*str); + + /* + * New string is shorter; no need to allocate space + */ + if (clen <= tlen) { + (void) strcpy(*str, cap); /* XXX strcpy is safe */ + return; + } + /* + * New string is longer; see if we have enough space to append + */ + if (el->el_term.t_loc + 3 < TC_BUFSIZE) { + /* XXX strcpy is safe */ + (void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], + cap); + el->el_term.t_loc += clen + 1; /* one for \0 */ + return; } - memcpy(el->el_term.t_buf, termbuf, TC_BUFSIZE); - el->el_term.t_loc = tlen; - if (el->el_term.t_loc + 3 >= TC_BUFSIZE) { - (void) fprintf(el->el_errfile, "Out of termcap string space.\n"); + /* + * Compact our buffer; no need to check compaction, cause we know it + * fits... + */ + tlen = 0; + for (tmp = tlist; tmp < &tlist[T_str]; tmp++) + if (*tmp != NULL && *tmp != '\0' && *tmp != *str) { + char *ptr; + + for (ptr = *tmp; *ptr != '\0'; termbuf[tlen++] = *ptr++) + continue; + termbuf[tlen++] = '\0'; + } + memcpy(el->el_term.t_buf, termbuf, TC_BUFSIZE); + el->el_term.t_loc = tlen; + if (el->el_term.t_loc + 3 >= TC_BUFSIZE) { + (void) fprintf(el->el_errfile, + "Out of termcap string space.\n"); + return; + } + /* XXX strcpy is safe */ + (void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], cap); + el->el_term.t_loc += clen + 1; /* one for \0 */ return; - } - /* XXX strcpy is safe */ - (void)strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], cap); - el->el_term.t_loc += clen + 1; /* one for \0 */ - return; -} /* end term_alloc */ +} /* term_rebuffer_display(): * Rebuffer the display after the screen changed size */ -private void -term_rebuffer_display(el) - EditLine *el; +private int +term_rebuffer_display(EditLine *el) { - coord_t *c = &el->el_term.t_size; + coord_t *c = &el->el_term.t_size; - term_free_display(el); + term_free_display(el); - /* make this public, -1 to avoid wraps */ - c->h = Val(T_co) - 1; - c->v = (EL_BUFSIZ * 4) / c->h + 1; + c->h = Val(T_co); + c->v = Val(T_li); - term_alloc_display(el); -} /* end term_rebuffer_display */ + if (term_alloc_display(el) == -1) + return (-1); + return (0); +} /* term_alloc_display(): * Allocate a new display. */ -private void -term_alloc_display(el) - EditLine *el; +private int +term_alloc_display(EditLine *el) { - int i; - char **b; - coord_t *c = &el->el_term.t_size; - - b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1))); - for (i = 0; i < c->v; i++) - b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); - b[c->v] = NULL; - el->el_display = b; - - b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1))); - for (i = 0; i < c->v; i++) - b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); - b[c->v] = NULL; - el->el_vdisplay = b; - -} /* end term_alloc_display */ + int i; + char **b; + coord_t *c = &el->el_term.t_size; + + b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1))); + if (b == NULL) + return (-1); + for (i = 0; i < c->v; i++) { + b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); + if (b[i] == NULL) + return (-1); + } + b[c->v] = NULL; + el->el_display = b; + + b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1))); + if (b == NULL) + return (-1); + for (i = 0; i < c->v; i++) { + b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); + if (b[i] == NULL) + return (-1); + } + b[c->v] = NULL; + el->el_vdisplay = b; + return (0); +} /* term_free_display(): * Free the display buffers */ private void -term_free_display(el) - EditLine *el; +term_free_display(EditLine *el) { - char **b; - char **bufp; - - b = el->el_display; - el->el_display = NULL; - if (b != NULL) { - for (bufp = b; *bufp != NULL; bufp++) - el_free((ptr_t) *bufp); - el_free((ptr_t) b); - } - b = el->el_vdisplay; - el->el_vdisplay = NULL; - if (b != NULL) { - for (bufp = b; *bufp != NULL; bufp++) - el_free((ptr_t) * bufp); - el_free((ptr_t) b); - } -} /* end term_free_display */ + char **b; + char **bufp; + + b = el->el_display; + el->el_display = NULL; + if (b != NULL) { + for (bufp = b; *bufp != NULL; bufp++) + el_free((ptr_t) * bufp); + el_free((ptr_t) b); + } + b = el->el_vdisplay; + el->el_vdisplay = NULL; + if (b != NULL) { + for (bufp = b; *bufp != NULL; bufp++) + el_free((ptr_t) * bufp); + el_free((ptr_t) b); + } +} /* term_move_to_line(): @@ -487,311 +514,342 @@ term_free_display(el) * as efficiently as possible */ protected void -term_move_to_line(el, where) - EditLine *el; - int where; +term_move_to_line(EditLine *el, int where) { - int del, i; + int del; - if (where == el->el_cursor.v) - return; + if (where == el->el_cursor.v) + return; - if (where > el->el_term.t_size.v) { + if (where > el->el_term.t_size.v) { #ifdef DEBUG_SCREEN - (void) fprintf(el->el_errfile, - "term_move_to_line: where is ridiculous: %d\r\n", where); + (void) fprintf(el->el_errfile, + "term_move_to_line: where is ridiculous: %d\r\n", where); #endif /* DEBUG_SCREEN */ - return; - } - - if ((del = where - el->el_cursor.v) > 0) { - if ((del > 1) && GoodStr(T_DO)) - (void) tputs(tgoto(Str(T_DO), del, del), del, term__putc); - else { - for (i = 0; i < del; i++) - term__putc('\n'); - el->el_cursor.h = 0; /* because the \n will become \r\n */ + return; } - } - else { /* del < 0 */ - if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up))) - (void) tputs(tgoto(Str(T_UP), -del, -del), -del, term__putc); - else { - if (GoodStr(T_up)) - for (i = 0; i < -del; i++) - (void) tputs(Str(T_up), 1, term__putc); + if ((del = where - el->el_cursor.v) > 0) { + while (del > 0) { + if (EL_HAS_AUTO_MARGINS && + el->el_display[el->el_cursor.v][0] != '\0') { + /* move without newline */ + term_move_to_char(el, el->el_term.t_size.h - 1); + term_overwrite(el, + &el->el_display[el->el_cursor.v][el->el_cursor.h], + 1); + /* updates Cursor */ + del--; + } else { + if ((del > 1) && GoodStr(T_DO)) { + (void) tputs(tgoto(Str(T_DO), del, del), + del, term__putc); + del = 0; + } else { + for (; del > 0; del--) + term__putc('\n'); + /* because the \n will become \r\n */ + el->el_cursor.h = 0; + } + } + } + } else { /* del < 0 */ + if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up))) + (void) tputs(tgoto(Str(T_UP), -del, -del), -del, + term__putc); + else { + if (GoodStr(T_up)) + for (; del < 0; del++) + (void) tputs(Str(T_up), 1, term__putc); + } } - } - el->el_cursor.v = where; /* now where is here */ -} /* end term_move_to_line */ + el->el_cursor.v = where;/* now where is here */ +} /* term_move_to_char(): * Move to the character position specified */ protected void -term_move_to_char(el, where) - EditLine *el; - int where; +term_move_to_char(EditLine *el, int where) { - int del, i; + int del, i; mc_again: - if (where == el->el_cursor.h) - return; + if (where == el->el_cursor.h) + return; - if (where > (el->el_term.t_size.h + 1)) { + if (where > el->el_term.t_size.h) { #ifdef DEBUG_SCREEN - (void) fprintf(el->el_errfile, - "term_move_to_char: where is riduculous: %d\r\n", where); + (void) fprintf(el->el_errfile, + "term_move_to_char: where is riduculous: %d\r\n", where); #endif /* DEBUG_SCREEN */ - return; - } - - if (!where) { /* if where is first column */ - term__putc('\r'); /* do a CR */ - el->el_cursor.h = 0; - return; - } - - del = where - el->el_cursor.h; - - if ((del < -4 || del > 4) && GoodStr(T_ch)) - /* go there directly */ - (void) tputs(tgoto(Str(T_ch), where, where), where, term__putc); - else { - if (del > 0) { /* moving forward */ - if ((del > 4) && GoodStr(T_RI)) - (void) tputs(tgoto(Str(T_RI), del, del), del, term__putc); - else { - if (EL_CAN_TAB) { /* if I can do tabs, use them */ - if ((el->el_cursor.h & 0370) != (where & 0370)) { - /* if not within tab stop */ - for (i = (el->el_cursor.h & 0370); - i < (where & 0370); i += 8) - term__putc('\t'); /* then tab over */ - el->el_cursor.h = where & 0370; - } - } - /* it's usually cheaper to just write the chars, so we do. */ - - /* NOTE THAT term_overwrite() WILL CHANGE el->el_cursor.h!!! */ - term_overwrite(el, - &el->el_display[el->el_cursor.v][el->el_cursor.h], - where - el->el_cursor.h); - - } + return; + } + if (!where) { /* if where is first column */ + term__putc('\r'); /* do a CR */ + el->el_cursor.h = 0; + return; } - else { /* del < 0 := moving backward */ - if ((-del > 4) && GoodStr(T_LE)) - (void) tputs(tgoto(Str(T_LE), -del, -del), -del, term__putc); - else { /* can't go directly there */ - /* if the "cost" is greater than the "cost" from col 0 */ - if (EL_CAN_TAB ? (-del > ((where >> 3) + (where & 07))) - : (-del > where)) { - term__putc('\r'); /* do a CR */ - el->el_cursor.h = 0; - goto mc_again; /* and try again */ + del = where - el->el_cursor.h; + + if ((del < -4 || del > 4) && GoodStr(T_ch)) + /* go there directly */ + (void) tputs(tgoto(Str(T_ch), where, where), where, term__putc); + else { + if (del > 0) { /* moving forward */ + if ((del > 4) && GoodStr(T_RI)) + (void) tputs(tgoto(Str(T_RI), del, del), + del, term__putc); + else { + /* if I can do tabs, use them */ + if (EL_CAN_TAB) { + if ((el->el_cursor.h & 0370) != + (where & 0370)) { + /* if not within tab stop */ + for (i = + (el->el_cursor.h & 0370); + i < (where & 0370); + i += 8) + term__putc('\t'); + /* then tab over */ + el->el_cursor.h = where & 0370; + } + } + /* + * it's usually cheaper to just write the + * chars, so we do. + */ + /* + * NOTE THAT term_overwrite() WILL CHANGE + * el->el_cursor.h!!! + */ + term_overwrite(el, + &el->el_display[el->el_cursor.v][el->el_cursor.h], + where - el->el_cursor.h); + + } + } else { /* del < 0 := moving backward */ + if ((-del > 4) && GoodStr(T_LE)) + (void) tputs(tgoto(Str(T_LE), -del, -del), + -del, term__putc); + else { /* can't go directly there */ + /* + * if the "cost" is greater than the "cost" + * from col 0 + */ + if (EL_CAN_TAB ? + (-del > (((unsigned int) where >> 3) + + (where & 07))) + : (-del > where)) { + term__putc('\r'); /* do a CR */ + el->el_cursor.h = 0; + goto mc_again; /* and try again */ + } + for (i = 0; i < -del; i++) + term__putc('\b'); + } } - for (i = 0; i < -del; i++) - term__putc('\b'); - } } - } - el->el_cursor.h = where; /* now where is here */ -} /* end term_move_to_char */ + el->el_cursor.h = where; /* now where is here */ +} /* term_overwrite(): * Overstrike num characters */ protected void -term_overwrite(el, cp, n) - EditLine *el; - char *cp; - int n; +term_overwrite(EditLine *el, char *cp, int n) { - if (n <= 0) - return; /* catch bugs */ + if (n <= 0) + return; /* catch bugs */ - if (n > (el->el_term.t_size.h + 1)) { + if (n > el->el_term.t_size.h) { #ifdef DEBUG_SCREEN - (void) fprintf(el->el_errfile, "term_overwrite: n is riduculous: %d\r\n", n); + (void) fprintf(el->el_errfile, + "term_overwrite: n is riduculous: %d\r\n", n); #endif /* DEBUG_SCREEN */ - return; - } - - do { - term__putc(*cp++); - el->el_cursor.h++; - } while (--n); -} /* end term_overwrite */ + return; + } + do { + term__putc(*cp++); + el->el_cursor.h++; + } while (--n); + + if (el->el_cursor.h >= el->el_term.t_size.h) { /* wrap? */ + if (EL_HAS_AUTO_MARGINS) { /* yes */ + el->el_cursor.h = 0; + el->el_cursor.v++; + if (EL_HAS_MAGIC_MARGINS) { + /* force the wrap to avoid the "magic" + * situation */ + char c; + if ((c = el->el_display[el->el_cursor.v][el->el_cursor.h]) + != '\0') + term_overwrite(el, &c, 1); + else + term__putc(' '); + el->el_cursor.h = 1; + } + } else /* no wrap, but cursor stays on screen */ + el->el_cursor.h = el->el_term.t_size.h; + } +} /* term_deletechars(): * Delete num characters */ protected void -term_deletechars(el, num) - EditLine *el; - int num; +term_deletechars(EditLine *el, int num) { - if (num <= 0) - return; + if (num <= 0) + return; - if (!EL_CAN_DELETE) { + if (!EL_CAN_DELETE) { #ifdef DEBUG_EDIT - (void) fprintf(el->el_errfile, " ERROR: cannot delete \n"); + (void) fprintf(el->el_errfile, " ERROR: cannot delete \n"); #endif /* DEBUG_EDIT */ - return; - } - - if (num > el->el_term.t_size.h) { + return; + } + if (num > el->el_term.t_size.h) { #ifdef DEBUG_SCREEN - (void) fprintf(el->el_errfile, - "term_deletechars: num is riduculous: %d\r\n", num); + (void) fprintf(el->el_errfile, + "term_deletechars: num is riduculous: %d\r\n", num); #endif /* DEBUG_SCREEN */ - return; - } - - if (GoodStr(T_DC)) /* if I have multiple delete */ - if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more expen. */ - (void) tputs(tgoto(Str(T_DC), num, num), num, term__putc); - return; + return; } + if (GoodStr(T_DC)) /* if I have multiple delete */ + if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more + * expen. */ + (void) tputs(tgoto(Str(T_DC), num, num), + num, term__putc); + return; + } + if (GoodStr(T_dm)) /* if I have delete mode */ + (void) tputs(Str(T_dm), 1, term__putc); - if (GoodStr(T_dm)) /* if I have delete mode */ - (void) tputs(Str(T_dm), 1, term__putc); - - if (GoodStr(T_dc)) /* else do one at a time */ - while (num--) - (void) tputs(Str(T_dc), 1, term__putc); + if (GoodStr(T_dc)) /* else do one at a time */ + while (num--) + (void) tputs(Str(T_dc), 1, term__putc); - if (GoodStr(T_ed)) /* if I have delete mode */ - (void) tputs(Str(T_ed), 1, term__putc); -} /* end term_deletechars */ + if (GoodStr(T_ed)) /* if I have delete mode */ + (void) tputs(Str(T_ed), 1, term__putc); +} /* term_insertwrite(): - * Puts terminal in insert character mode or inserts num - * characters in the line + * Puts terminal in insert character mode or inserts num + * characters in the line */ protected void -term_insertwrite(el, cp, num) - EditLine *el; - char *cp; - int num; +term_insertwrite(EditLine *el, char *cp, int num) { - if (num <= 0) - return; - if (!EL_CAN_INSERT) { + if (num <= 0) + return; + if (!EL_CAN_INSERT) { #ifdef DEBUG_EDIT - (void) fprintf(el->el_errfile, " ERROR: cannot insert \n"); + (void) fprintf(el->el_errfile, " ERROR: cannot insert \n"); #endif /* DEBUG_EDIT */ - return; - } - - if (num > el->el_term.t_size.h) { + return; + } + if (num > el->el_term.t_size.h) { #ifdef DEBUG_SCREEN - (void) fprintf(el->el_errfile, "StartInsert: num is riduculous: %d\r\n", num); + (void) fprintf(el->el_errfile, + "StartInsert: num is riduculous: %d\r\n", num); #endif /* DEBUG_SCREEN */ - return; - } - - if (GoodStr(T_IC)) /* if I have multiple insert */ - if ((num > 1) || !GoodStr(T_ic)) { /* if ic would be more expen. */ - (void) tputs(tgoto(Str(T_IC), num, num), num, term__putc); - term_overwrite(el, cp, num); /* this updates el_cursor.h */ - return; + return; } + if (GoodStr(T_IC)) /* if I have multiple insert */ + if ((num > 1) || !GoodStr(T_ic)) { + /* if ic would be more expensive */ + (void) tputs(tgoto(Str(T_IC), num, num), + num, term__putc); + term_overwrite(el, cp, num); + /* this updates el_cursor.h */ + return; + } + if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */ + (void) tputs(Str(T_im), 1, term__putc); - if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */ - (void) tputs(Str(T_im), 1, term__putc); - - el->el_cursor.h += num; - do - term__putc(*cp++); - while (--num); + el->el_cursor.h += num; + do + term__putc(*cp++); + while (--num); - if (GoodStr(T_ip)) /* have to make num chars insert */ - (void) tputs(Str(T_ip), 1, term__putc); + if (GoodStr(T_ip)) /* have to make num chars insert */ + (void) tputs(Str(T_ip), 1, term__putc); - (void) tputs(Str(T_ei), 1, term__putc); - return; - } - - do { - if (GoodStr(T_ic)) /* have to make num chars insert */ - (void) tputs(Str(T_ic), 1, term__putc); /* insert a char */ + (void) tputs(Str(T_ei), 1, term__putc); + return; + } + do { + if (GoodStr(T_ic)) /* have to make num chars insert */ + (void) tputs(Str(T_ic), 1, term__putc); + /* insert a char */ - term__putc(*cp++); + term__putc(*cp++); - el->el_cursor.h++; + el->el_cursor.h++; - if (GoodStr(T_ip)) /* have to make num chars insert */ - (void) tputs(Str(T_ip), 1, term__putc);/* pad the inserted char */ + if (GoodStr(T_ip)) /* have to make num chars insert */ + (void) tputs(Str(T_ip), 1, term__putc); + /* pad the inserted char */ - } while (--num); -} /* end term_insertwrite */ + } while (--num); +} /* term_clear_EOL(): - * clear to end of line. There are num characters to clear + * clear to end of line. There are num characters to clear */ protected void -term_clear_EOL(el, num) - EditLine *el; - int num; +term_clear_EOL(EditLine *el, int num) { - int i; + int i; - if (EL_CAN_CEOL && GoodStr(T_ce)) - (void) tputs(Str(T_ce), 1, term__putc); - else { - for (i = 0; i < num; i++) - term__putc(' '); - el->el_cursor.h += num; /* have written num spaces */ - } -} /* end term_clear_EOL */ + if (EL_CAN_CEOL && GoodStr(T_ce)) + (void) tputs(Str(T_ce), 1, term__putc); + else { + for (i = 0; i < num; i++) + term__putc(' '); + el->el_cursor.h += num; /* have written num spaces */ + } +} /* term_clear_screen(): - * Clear the screen + * Clear the screen */ protected void -term_clear_screen(el) - EditLine *el; +term_clear_screen(EditLine *el) { /* clear the whole screen and home */ - if (GoodStr(T_cl)) - /* send the clear screen code */ - (void) tputs(Str(T_cl), Val(T_li), term__putc); - else if (GoodStr(T_ho) && GoodStr(T_cd)) { - (void) tputs(Str(T_ho), Val(T_li), term__putc); /* home */ - /* clear to bottom of screen */ - (void) tputs(Str(T_cd), Val(T_li), term__putc); - } - else { - term__putc('\r'); - term__putc('\n'); - } -} /* end term_clear_screen */ + + if (GoodStr(T_cl)) + /* send the clear screen code */ + (void) tputs(Str(T_cl), Val(T_li), term__putc); + else if (GoodStr(T_ho) && GoodStr(T_cd)) { + (void) tputs(Str(T_ho), Val(T_li), term__putc); /* home */ + /* clear to bottom of screen */ + (void) tputs(Str(T_cd), Val(T_li), term__putc); + } else { + term__putc('\r'); + term__putc('\n'); + } +} /* term_beep(): * Beep the way the terminal wants us */ protected void -term_beep(el) - EditLine *el; +term_beep(EditLine *el) { - if (GoodStr(T_vb)) - (void) tputs(Str(T_vb), 1, term__putc); /* visible bell */ - else if (GoodStr(T_bl)) - /* what termcap says we should use */ - (void) tputs(Str(T_bl), 1, term__putc); - else - term__putc('\007'); /* an ASCII bell; ^G */ -} /* end term_beep */ + if (GoodStr(T_bl)) + /* what termcap says we should use */ + (void) tputs(Str(T_bl), 1, term__putc); + else + term__putc('\007'); /* an ASCII bell; ^G */ +} #ifdef notdef @@ -799,14 +857,13 @@ term_beep(el) * Clear to the bottom of the screen */ protected void -term_clear_to_bottom(el) - EditLine *el; +term_clear_to_bottom(EditLine *el) { - if (GoodStr(T_cd)) - (void) tputs(Str(T_cd), Val(T_li), term__putc); - else if (GoodStr(T_ce)) - (void) tputs(Str(T_ce), Val(T_li), term__putc); -} /* end term_clear_to_bottom */ + if (GoodStr(T_cd)) + (void) tputs(Str(T_cd), Val(T_li), term__putc); + else if (GoodStr(T_ce)) + (void) tputs(Str(T_ce), Val(T_li), term__putc); +} #endif @@ -814,166 +871,180 @@ term_clear_to_bottom(el) * Read in the terminal capabilities from the requested terminal */ protected int -term_set(el, term) - EditLine *el; - char *term; +term_set(EditLine *el, char *term) { - int i; - char buf[TC_BUFSIZE]; - char *area; - struct termcapstr *t; - sigset_t oset, nset; - int lins, cols; - - (void) sigemptyset(&nset); - (void) sigaddset(&nset, SIGWINCH); - (void) sigprocmask(SIG_BLOCK, &nset, &oset); - - area = buf; - - - if (term == NULL) - term = getenv("TERM"); - - if (!term || !term[0]) - term = "dumb"; - - memset(el->el_term.t_cap, 0, TC_BUFSIZE); - - i = tgetent(el->el_term.t_cap, term); - - if (i <= 0) { - if (i == -1) - (void) fprintf(el->el_errfile, "Cannot read termcap database;\n"); - else if (i == 0) - (void) fprintf(el->el_errfile, - "No entry for terminal type \"%s\";\n", term); - (void) fprintf(el->el_errfile, "using dumb terminal settings.\n"); - Val(T_co) = 80; /* do a dumb terminal */ - Val(T_pt) = Val(T_km) = Val(T_li) = 0; - Val(T_xt) = Val(T_MT); - for (t = tstr; t->name != NULL; t++) - term_alloc(el, t, NULL); - } - else { - /* Can we tab */ - Val(T_pt) = tgetflag("pt"); - Val(T_xt) = tgetflag("xt"); - /* do we have a meta? */ - Val(T_km) = tgetflag("km"); - Val(T_MT) = tgetflag("MT"); - /* Get the size */ - Val(T_co) = tgetnum("co"); - Val(T_li) = tgetnum("li"); - for (t = tstr; t->name != NULL; t++) - term_alloc(el, t, tgetstr(t->name, &area)); - } + int i; + char buf[TC_BUFSIZE]; + char *area; + const struct termcapstr *t; + sigset_t oset, nset; + int lins, cols; + + (void) sigemptyset(&nset); + (void) sigaddset(&nset, SIGWINCH); + (void) sigprocmask(SIG_BLOCK, &nset, &oset); + + area = buf; + + + if (term == NULL) + term = getenv("TERM"); + + if (!term || !term[0]) + term = "dumb"; + + if (strcmp(term, "emacs") == 0) + el->el_flags |= EDIT_DISABLED; + + memset(el->el_term.t_cap, 0, TC_BUFSIZE); + + i = tgetent(el->el_term.t_cap, term); + + if (i <= 0) { + if (i == -1) + (void) fprintf(el->el_errfile, + "Cannot read termcap database;\n"); + else if (i == 0) + (void) fprintf(el->el_errfile, + "No entry for terminal type \"%s\";\n", term); + (void) fprintf(el->el_errfile, + "using dumb terminal settings.\n"); + Val(T_co) = 80; /* do a dumb terminal */ + Val(T_pt) = Val(T_km) = Val(T_li) = 0; + Val(T_xt) = Val(T_MT); + for (t = tstr; t->name != NULL; t++) + term_alloc(el, t, NULL); + } else { + /* auto/magic margins */ + Val(T_am) = tgetflag("am"); + Val(T_xn) = tgetflag("xn"); + /* Can we tab */ + Val(T_pt) = tgetflag("pt"); + Val(T_xt) = tgetflag("xt"); + /* do we have a meta? */ + Val(T_km) = tgetflag("km"); + Val(T_MT) = tgetflag("MT"); + /* Get the size */ + Val(T_co) = tgetnum("co"); + Val(T_li) = tgetnum("li"); + for (t = tstr; t->name != NULL; t++) + term_alloc(el, t, tgetstr(t->name, &area)); + } - if (Val(T_co) < 2) - Val(T_co) = 80; /* just in case */ - if (Val(T_li) < 1) - Val(T_li) = 24; + if (Val(T_co) < 2) + Val(T_co) = 80; /* just in case */ + if (Val(T_li) < 1) + Val(T_li) = 24; - el->el_term.t_size.v = Val(T_co); - el->el_term.t_size.h = Val(T_li); + el->el_term.t_size.v = Val(T_co); + el->el_term.t_size.h = Val(T_li); - term_setflags(el); + term_setflags(el); - (void) term_get_size(el, &lins, &cols);/* get the correct window size */ - term_change_size(el, lins, cols); - (void) sigprocmask(SIG_SETMASK, &oset, NULL); - term_bind_arrow(el); - return i <= 0 ? -1 : 0; -} /* end term_set */ + /* get the correct window size */ + (void) term_get_size(el, &lins, &cols); + if (term_change_size(el, lins, cols) == -1) + return (-1); + (void) sigprocmask(SIG_SETMASK, &oset, NULL); + term_bind_arrow(el); + return (i <= 0 ? -1 : 0); +} /* term_get_size(): * Return the new window size in lines and cols, and - * true if the size was changed. + * true if the size was changed. */ protected int -term_get_size(el, lins, cols) - EditLine *el; - int *lins, *cols; +term_get_size(EditLine *el, int *lins, int *cols) { - *cols = Val(T_co); - *lins = Val(T_li); + *cols = Val(T_co); + *lins = Val(T_li); #ifdef TIOCGWINSZ - { - struct winsize ws; - if (ioctl(el->el_infd, TIOCGWINSZ, (ioctl_t) &ws) != -1) { - if (ws.ws_col) - *cols = ws.ws_col; - if (ws.ws_row) - *lins = ws.ws_row; + { + struct winsize ws; + if (ioctl(el->el_infd, TIOCGWINSZ, (ioctl_t) & ws) != -1) { + if (ws.ws_col) + *cols = ws.ws_col; + if (ws.ws_row) + *lins = ws.ws_row; + } } - } #endif #ifdef TIOCGSIZE - { - struct ttysize ts; - if (ioctl(el->el_infd, TIOCGSIZE, (ioctl_t) &ts) != -1) { - if (ts.ts_cols) - *cols = ts.ts_cols; - if (ts.ts_lines) - *lins = ts.ts_lines; + { + struct ttysize ts; + if (ioctl(el->el_infd, TIOCGSIZE, (ioctl_t) & ts) != -1) { + if (ts.ts_cols) + *cols = ts.ts_cols; + if (ts.ts_lines) + *lins = ts.ts_lines; + } } - } #endif - return (Val(T_co) != *cols || Val(T_li) != *lins); -} /* end term_get_size */ + return (Val(T_co) != *cols || Val(T_li) != *lins); +} /* term_change_size(): * Change the size of the terminal */ -protected void -term_change_size(el, lins, cols) - EditLine *el; - int lins, cols; +protected int +term_change_size(EditLine *el, int lins, int cols) { - /* - * Just in case - */ - Val(T_co) = (cols < 2) ? 80 : cols; - Val(T_li) = (lins < 1) ? 24 : lins; - - term_rebuffer_display(el); /* re-make display buffers */ - re_clear_display(el); -} /* end term_change_size */ + /* + * Just in case + */ + Val(T_co) = (cols < 2) ? 80 : cols; + Val(T_li) = (lins < 1) ? 24 : lins; + + /* re-make display buffers */ + if (term_rebuffer_display(el) == -1) + return (-1); + re_clear_display(el); + return (0); +} /* term_init_arrow(): * Initialize the arrow key bindings from termcap */ private void -term_init_arrow(el) - EditLine *el; +term_init_arrow(EditLine *el) { - fkey_t *arrow = el->el_term.t_fkey; - - arrow[A_K_DN].name = "down"; - arrow[A_K_DN].key = T_kd; - arrow[A_K_DN].fun.cmd = ED_NEXT_HISTORY; - arrow[A_K_DN].type = XK_CMD; - - arrow[A_K_UP].name = "up"; - arrow[A_K_UP].key = T_ku; - arrow[A_K_UP].fun.cmd = ED_PREV_HISTORY; - arrow[A_K_UP].type = XK_CMD; - - arrow[A_K_LT].name = "left"; - arrow[A_K_LT].key = T_kl; - arrow[A_K_LT].fun.cmd = ED_PREV_CHAR; - arrow[A_K_LT].type = XK_CMD; - - arrow[A_K_RT].name = "right"; - arrow[A_K_RT].key = T_kr; - arrow[A_K_RT].fun.cmd = ED_NEXT_CHAR; - arrow[A_K_RT].type = XK_CMD; - + fkey_t *arrow = el->el_term.t_fkey; + + arrow[A_K_DN].name = "down"; + arrow[A_K_DN].key = T_kd; + arrow[A_K_DN].fun.cmd = ED_NEXT_HISTORY; + arrow[A_K_DN].type = XK_CMD; + + arrow[A_K_UP].name = "up"; + arrow[A_K_UP].key = T_ku; + arrow[A_K_UP].fun.cmd = ED_PREV_HISTORY; + arrow[A_K_UP].type = XK_CMD; + + arrow[A_K_LT].name = "left"; + arrow[A_K_LT].key = T_kl; + arrow[A_K_LT].fun.cmd = ED_PREV_CHAR; + arrow[A_K_LT].type = XK_CMD; + + arrow[A_K_RT].name = "right"; + arrow[A_K_RT].key = T_kr; + arrow[A_K_RT].fun.cmd = ED_NEXT_CHAR; + arrow[A_K_RT].type = XK_CMD; + + arrow[A_K_HO].name = "home"; + arrow[A_K_HO].key = T_kh; + arrow[A_K_HO].fun.cmd = ED_MOVE_TO_BEG; + arrow[A_K_HO].type = XK_CMD; + + arrow[A_K_EN].name = "end"; + arrow[A_K_EN].key = T_at7; + arrow[A_K_EN].fun.cmd = ED_MOVE_TO_END; + arrow[A_K_EN].type = XK_CMD; } @@ -981,38 +1052,49 @@ term_init_arrow(el) * Reset arrow key bindings */ private void -term_reset_arrow(el) - EditLine *el; +term_reset_arrow(EditLine *el) { - fkey_t *arrow = el->el_term.t_fkey; - static char strA[] = {033, '[', 'A', '\0'}; - static char strB[] = {033, '[', 'B', '\0'}; - static char strC[] = {033, '[', 'C', '\0'}; - static char strD[] = {033, '[', 'D', '\0'}; - static char stOA[] = {033, 'O', 'A', '\0'}; - static char stOB[] = {033, 'O', 'B', '\0'}; - static char stOC[] = {033, 'O', 'C', '\0'}; - static char stOD[] = {033, 'O', 'D', '\0'}; - - key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); - - if (el->el_map.type == MAP_VI) { - key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); - } + fkey_t *arrow = el->el_term.t_fkey; + static const char strA[] = {033, '[', 'A', '\0'}; + static const char strB[] = {033, '[', 'B', '\0'}; + static const char strC[] = {033, '[', 'C', '\0'}; + static const char strD[] = {033, '[', 'D', '\0'}; + static const char strH[] = {033, '[', 'H', '\0'}; + static const char strF[] = {033, '[', 'F', '\0'}; + static const char stOA[] = {033, 'O', 'A', '\0'}; + static const char stOB[] = {033, 'O', 'B', '\0'}; + static const char stOC[] = {033, 'O', 'C', '\0'}; + static const char stOD[] = {033, 'O', 'D', '\0'}; + static const char stOH[] = {033, 'O', 'H', '\0'}; + static const char stOF[] = {033, 'O', 'F', '\0'}; + + key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); + key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); + key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); + key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); + key_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); + key_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); + key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); + key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); + key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); + key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); + key_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); + key_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); + + if (el->el_map.type == MAP_VI) { + key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); + key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); + key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); + key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); + key_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); + key_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); + key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); + key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); + key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); + key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); + key_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); + key_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); + } } @@ -1020,22 +1102,18 @@ term_reset_arrow(el) * Set an arrow key binding */ protected int -term_set_arrow(el, name, fun, type) - EditLine *el; - char *name; - key_value_t *fun; - int type; +term_set_arrow(EditLine *el, char *name, key_value_t *fun, int type) { - fkey_t *arrow = el->el_term.t_fkey; - int i; - - for (i = 0; i < A_K_NKEYS; i++) - if (strcmp(name, arrow[i].name) == 0) { - arrow[i].fun = *fun; - arrow[i].type = type; - return 0; - } - return -1; + fkey_t *arrow = el->el_term.t_fkey; + int i; + + for (i = 0; i < A_K_NKEYS; i++) + if (strcmp(name, arrow[i].name) == 0) { + arrow[i].fun = *fun; + arrow[i].type = type; + return (0); + } + return (-1); } @@ -1043,19 +1121,17 @@ term_set_arrow(el, name, fun, type) * Clear an arrow key binding */ protected int -term_clear_arrow(el, name) - EditLine *el; - char *name; +term_clear_arrow(EditLine *el, char *name) { - fkey_t *arrow = el->el_term.t_fkey; - int i; + fkey_t *arrow = el->el_term.t_fkey; + int i; - for (i = 0; i < A_K_NKEYS; i++) - if (strcmp(name, arrow[i].name) == 0) { - arrow[i].type = XK_NOD; - return 0; - } - return -1; + for (i = 0; i < A_K_NKEYS; i++) + if (strcmp(name, arrow[i].name) == 0) { + arrow[i].type = XK_NOD; + return (0); + } + return (-1); } @@ -1063,17 +1139,16 @@ term_clear_arrow(el, name) * Print the arrow key bindings */ protected void -term_print_arrow(el, name) - EditLine *el; - char *name; +term_print_arrow(EditLine *el, char *name) { - int i; - fkey_t *arrow = el->el_term.t_fkey; - - for (i = 0; i < A_K_NKEYS; i++) - if (*name == '\0' || strcmp(name, arrow[i].name) == 0) - if (arrow[i].type != XK_NOD) - key_kprint(el, arrow[i].name, &arrow[i].fun, arrow[i].type); + int i; + fkey_t *arrow = el->el_term.t_fkey; + + for (i = 0; i < A_K_NKEYS; i++) + if (*name == '\0' || strcmp(name, arrow[i].name) == 0) + if (arrow[i].type != XK_NOD) + key_kprint(el, arrow[i].name, &arrow[i].fun, + arrow[i].type); } @@ -1081,76 +1156,79 @@ term_print_arrow(el, name) * Bind the arrow keys */ protected void -term_bind_arrow(el) - EditLine *el; +term_bind_arrow(EditLine *el) { - el_action_t *map, *dmap; - int i, j; - char *p; - fkey_t *arrow = el->el_term.t_fkey; - - /* Check if the components needed are initialized */ - if (el->el_term.t_buf == NULL || el->el_map.key == NULL) - return; - - map = el->el_map.type == MAP_VI ? el->el_map.alt : el->el_map.key; - dmap = el->el_map.type == MAP_VI ? el->el_map.vic : el->el_map.emacs; - - term_reset_arrow(el); - - for (i = 0; i < 4; i++) { - p = el->el_term.t_str[arrow[i].key]; - if (p && *p) { - j = (unsigned char) *p; - /* - * Assign the arrow keys only if: - * - * 1. They are multi-character arrow keys and the user - * has not re-assigned the leading character, or - * has re-assigned the leading character to be - * ED_SEQUENCE_LEAD_IN - * 2. They are single arrow keys pointing to an unassigned key. - */ - if (arrow[i].type == XK_NOD) - key_clear(el, map, p); - else { - if (p[1] && (dmap[j] == map[j] || - map[j] == ED_SEQUENCE_LEAD_IN)) { - key_add(el, p, &arrow[i].fun, arrow[i].type); - map[j] = ED_SEQUENCE_LEAD_IN; + el_action_t *map; + const el_action_t *dmap; + int i, j; + char *p; + fkey_t *arrow = el->el_term.t_fkey; + + /* Check if the components needed are initialized */ + if (el->el_term.t_buf == NULL || el->el_map.key == NULL) + return; + + map = el->el_map.type == MAP_VI ? el->el_map.alt : el->el_map.key; + dmap = el->el_map.type == MAP_VI ? el->el_map.vic : el->el_map.emacs; + + term_reset_arrow(el); + + for (i = 0; i < A_K_NKEYS; i++) { + p = el->el_term.t_str[arrow[i].key]; + if (p && *p) { + j = (unsigned char) *p; + /* + * Assign the arrow keys only if: + * + * 1. They are multi-character arrow keys and the user + * has not re-assigned the leading character, or + * has re-assigned the leading character to be + * ED_SEQUENCE_LEAD_IN + * 2. They are single arrow keys pointing to an + * unassigned key. + */ + if (arrow[i].type == XK_NOD) + key_clear(el, map, p); + else { + if (p[1] && (dmap[j] == map[j] || + map[j] == ED_SEQUENCE_LEAD_IN)) { + key_add(el, p, &arrow[i].fun, + arrow[i].type); + map[j] = ED_SEQUENCE_LEAD_IN; + } else if (map[j] == ED_UNASSIGNED) { + key_clear(el, map, p); + if (arrow[i].type == XK_CMD) + map[j] = arrow[i].fun.cmd; + else + key_add(el, p, &arrow[i].fun, + arrow[i].type); + } + } } - else if (map[j] == ED_UNASSIGNED) { - key_clear(el, map, p); - if (arrow[i].type == XK_CMD) - map[j] = arrow[i].fun.cmd; - else - key_add(el, p, &arrow[i].fun, arrow[i].type); - } - } } - } } /* term__putc(): * Add a character */ -protected void -term__putc(c) - int c; +protected int +term__putc(int c) { - (void) fputc(c, term_outfile); -} /* end term__putc */ + + return (fputc(c, term_outfile)); +} /* term__flush(): * Flush output */ protected void -term__flush() +term__flush(void) { - (void) fflush(term_outfile); -} /* end term__flush */ + + (void) fflush(term_outfile); +} /* term_telltc(): @@ -1158,37 +1236,33 @@ term__flush() */ protected int /*ARGSUSED*/ -term_telltc(el, argc, argv) - EditLine *el; - int argc; - char **argv; +term_telltc(EditLine *el, int argc, char **argv) { - struct termcapstr *t; - char **ts; - char upbuf[EL_BUFSIZ]; + const struct termcapstr *t; + char **ts; + char upbuf[EL_BUFSIZ]; - (void) fprintf(el->el_outfile, "\n\tYour terminal has the\n"); - (void) fprintf(el->el_outfile, "\tfollowing characteristics:\n\n"); - (void) fprintf(el->el_outfile, "\tIt has %d columns and %d lines\n", + (void) fprintf(el->el_outfile, "\n\tYour terminal has the\n"); + (void) fprintf(el->el_outfile, "\tfollowing characteristics:\n\n"); + (void) fprintf(el->el_outfile, "\tIt has %d columns and %d lines\n", Val(T_co), Val(T_li)); - (void) fprintf(el->el_outfile, - "\tIt has %s meta key\n", EL_HAS_META ? "a" : "no"); - (void) fprintf(el->el_outfile, - "\tIt can%suse tabs\n", EL_CAN_TAB ? " " : "not "); -#ifdef notyet - (void) fprintf(el->el_outfile, "\tIt %s automatic margins\n", - (T_Margin&MARGIN_AUTO)? "has": "does not have"); - if (T_Margin & MARGIN_AUTO) - (void) fprintf(el->el_outfile, "\tIt %s magic margins\n", - (T_Margin&MARGIN_MAGIC)?"has":"does not have"); -#endif - - for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++) - (void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n", t->long_name, - t->name, *ts && **ts ? - key__decode_str(*ts, upbuf, "") : "(empty)"); - (void) fputc('\n', el->el_outfile); - return 0; + (void) fprintf(el->el_outfile, + "\tIt has %s meta key\n", EL_HAS_META ? "a" : "no"); + (void) fprintf(el->el_outfile, + "\tIt can%suse tabs\n", EL_CAN_TAB ? " " : "not "); + (void) fprintf(el->el_outfile, "\tIt %s automatic margins\n", + EL_HAS_AUTO_MARGINS ? "has" : "does not have"); + if (EL_HAS_AUTO_MARGINS) + (void) fprintf(el->el_outfile, "\tIt %s magic margins\n", + EL_HAS_MAGIC_MARGINS ? "has" : "does not have"); + + for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++) + (void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n", + t->long_name, + t->name, *ts && **ts ? + key__decode_str(*ts, upbuf, "") : "(empty)"); + (void) fputc('\n', el->el_outfile); + return (0); } @@ -1197,69 +1271,74 @@ term_telltc(el, argc, argv) */ protected int /*ARGSUSED*/ -term_settc(el, argc, argv) - EditLine *el; - int argc; - char **argv; +term_settc(EditLine *el, int argc, char **argv) { - struct termcapstr *ts; - struct termcapval *tv; - char *what, *how; - - if (argv == NULL || argv[1] == NULL || argv[2] == NULL) - return -1; - - what = argv[1]; - how = argv[2]; - - /* - * Do the strings first - */ - for (ts = tstr; ts->name != NULL; ts++) - if (strcmp(ts->name, what) == 0) - break; - - if (ts->name != NULL) { - term_alloc(el, ts, how); - term_setflags(el); - return 0; - } - - /* - * Do the numeric ones second - */ - for (tv = tval; tv->name != NULL; tv++) - if (strcmp(tv->name, what) == 0) - break; - - if (tv->name != NULL) { - if (tv == &tval[T_pt] || tv == &tval[T_km] -#ifdef notyet - || tv == &tval[T_am] || tv == &tval[T_xn] -#endif - ) { - if (strcmp(how, "yes") == 0) - el->el_term.t_val[tv - tval] = 1; - else if (strcmp(how, "no") == 0) - el->el_term.t_val[tv - tval] = 0; - else { - (void) fprintf(el->el_errfile, "settc: Bad value `%s'.\n", how); - return -1; - } - term_setflags(el); - term_change_size(el, Val(T_li), Val(T_co)); - return 0; + const struct termcapstr *ts; + const struct termcapval *tv; + char *what, *how; + + if (argv == NULL || argv[1] == NULL || argv[2] == NULL) + return (-1); + + what = argv[1]; + how = argv[2]; + + /* + * Do the strings first + */ + for (ts = tstr; ts->name != NULL; ts++) + if (strcmp(ts->name, what) == 0) + break; + + if (ts->name != NULL) { + term_alloc(el, ts, how); + term_setflags(el); + return (0); } - else { - el->el_term.t_val[tv - tval] = atoi(how); - el->el_term.t_size.v = Val(T_co); - el->el_term.t_size.h = Val(T_li); - if (tv == &tval[T_co] || tv == &tval[T_li]) - term_change_size(el, Val(T_li), Val(T_co)); - return 0; + /* + * Do the numeric ones second + */ + for (tv = tval; tv->name != NULL; tv++) + if (strcmp(tv->name, what) == 0) + break; + + if (tv->name != NULL) { + if (tv == &tval[T_pt] || tv == &tval[T_km] || + tv == &tval[T_am] || tv == &tval[T_xn]) { + if (strcmp(how, "yes") == 0) + el->el_term.t_val[tv - tval] = 1; + else if (strcmp(how, "no") == 0) + el->el_term.t_val[tv - tval] = 0; + else { + (void) fprintf(el->el_errfile, + "settc: Bad value `%s'.\n", how); + return (-1); + } + term_setflags(el); + if (term_change_size(el, Val(T_li), Val(T_co)) == -1) + return (-1); + return (0); + } else { + long i; + char *ep; + + i = strtol(how, &ep, 10); + if (*ep != '\0') { + (void) fprintf(el->el_errfile, + "settc: Bad value `%s'.\n", how); + return (-1); + } + el->el_term.t_val[tv - tval] = (int) i; + el->el_term.t_size.v = Val(T_co); + el->el_term.t_size.h = Val(T_li); + if (tv == &tval[T_co] || tv == &tval[T_li]) + if (term_change_size(el, Val(T_li), Val(T_co)) + == -1) + return (-1); + return (0); + } } - } - return -1; + return (-1); } @@ -1268,198 +1347,223 @@ term_settc(el, argc, argv) */ protected int /*ARGSUSED*/ -term_echotc(el, argc, argv) - EditLine *el; - int argc; - char **argv; +term_echotc(EditLine *el, int argc, char **argv) { - char *cap, *scap; - int arg_need, arg_cols, arg_rows; - int verbose = 0, silent = 0; - char *area; - static char *fmts = "%s\n", *fmtd = "%d\n"; - struct termcapstr *t; - char buf[TC_BUFSIZE]; - - area = buf; - - if (argv == NULL || argv[1] == NULL) - return -1; - argv++; - - if (argv[0][0] == '-') { - switch (argv[0][1]) { - case 'v': - verbose = 1; - break; - case 's': - silent = 1; - break; - default: - /* stderror(ERR_NAME | ERR_TCUSAGE); */ - break; - } + char *cap, *scap, *ep; + int arg_need, arg_cols, arg_rows; + int verbose = 0, silent = 0; + char *area; + static const char fmts[] = "%s\n", fmtd[] = "%d\n"; + const struct termcapstr *t; + char buf[TC_BUFSIZE]; + long i; + + area = buf; + + if (argv == NULL || argv[1] == NULL) + return (-1); argv++; - } - if (!*argv || *argv[0] == '\0') - return 0; - if (strcmp(*argv, "tabs") == 0) { - (void) fprintf(el->el_outfile, fmts, EL_CAN_TAB ? "yes" : "no"); - return 0; - } - else if (strcmp(*argv, "meta") == 0) { - (void) fprintf(el->el_outfile, fmts, Val(T_km) ? "yes" : "no"); - return 0; - } -#ifdef notyet - else if (strcmp(*argv, "xn") == 0) { - (void) fprintf(el->el_outfile, fmts, T_Margin & MARGIN_MAGIC ? - "yes" : "no"); - return 0; - } - else if (strcmp(*argv, "am") == 0) { - (void) fprintf(el->el_outfile, fmts, T_Margin & MARGIN_AUTO ? - "yes" : "no"); - return 0; - } -#endif - else if (strcmp(*argv, "baud") == 0) { + + if (argv[0][0] == '-') { + switch (argv[0][1]) { + case 'v': + verbose = 1; + break; + case 's': + silent = 1; + break; + default: + /* stderror(ERR_NAME | ERR_TCUSAGE); */ + break; + } + argv++; + } + if (!*argv || *argv[0] == '\0') + return (0); + if (strcmp(*argv, "tabs") == 0) { + (void) fprintf(el->el_outfile, fmts, EL_CAN_TAB ? "yes" : "no"); + return (0); + } else if (strcmp(*argv, "meta") == 0) { + (void) fprintf(el->el_outfile, fmts, Val(T_km) ? "yes" : "no"); + return (0); + } else if (strcmp(*argv, "xn") == 0) { + (void) fprintf(el->el_outfile, fmts, EL_HAS_MAGIC_MARGINS ? + "yes" : "no"); + return (0); + } else if (strcmp(*argv, "am") == 0) { + (void) fprintf(el->el_outfile, fmts, EL_HAS_AUTO_MARGINS ? + "yes" : "no"); + return (0); + } else if (strcmp(*argv, "baud") == 0) { #ifdef notdef - int i; - - for (i = 0; baud_rate[i].b_name != NULL; i++) - if (el->el_tty.t_speed == baud_rate[i].b_rate) { - (void) fprintf(el->el_outfile, fmts, baud_rate[i].b_name); - return 0; - } - (void) fprintf(el->el_outfile, fmtd, 0); + int i; + + for (i = 0; baud_rate[i].b_name != NULL; i++) + if (el->el_tty.t_speed == baud_rate[i].b_rate) { + (void) fprintf(el->el_outfile, fmts, + baud_rate[i].b_name); + return (0); + } + (void) fprintf(el->el_outfile, fmtd, 0); #else - (void) fprintf(el->el_outfile, fmtd, el->el_tty.t_speed); + (void) fprintf(el->el_outfile, fmtd, el->el_tty.t_speed); #endif - return 0; - } - else if (strcmp(*argv, "rows") == 0 || strcmp(*argv, "lines") == 0) { - (void) fprintf(el->el_outfile, fmtd, Val(T_li)); - return 0; - } - else if (strcmp(*argv, "cols") == 0) { - (void) fprintf(el->el_outfile, fmtd, Val(T_co)); - return 0; - } - - /* - * Try to use our local definition first - */ - scap = NULL; - for (t = tstr; t->name != NULL; t++) - if (strcmp(t->name, *argv) == 0) { - scap = el->el_term.t_str[t - tstr]; - break; + return (0); + } else if (strcmp(*argv, "rows") == 0 || strcmp(*argv, "lines") == 0) { + (void) fprintf(el->el_outfile, fmtd, Val(T_li)); + return (0); + } else if (strcmp(*argv, "cols") == 0) { + (void) fprintf(el->el_outfile, fmtd, Val(T_co)); + return (0); } - if (t->name == NULL) - scap = tgetstr(*argv, &area); - if (!scap || scap[0] == '\0') { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Termcap parameter `%s' not found.\n", *argv); - return -1; - } - - /* - * Count home many values we need for this capability. - */ - for (cap = scap, arg_need = 0; *cap; cap++) - if (*cap == '%') - switch (*++cap) { - case 'd': - case '2': - case '3': - case '.': - case '+': - arg_need++; + /* + * Try to use our local definition first + */ + scap = NULL; + for (t = tstr; t->name != NULL; t++) + if (strcmp(t->name, *argv) == 0) { + scap = el->el_term.t_str[t - tstr]; + break; + } + if (t->name == NULL) + scap = tgetstr(*argv, &area); + if (!scap || scap[0] == '\0') { + if (!silent) + (void) fprintf(el->el_errfile, + "echotc: Termcap parameter `%s' not found.\n", + *argv); + return (-1); + } + /* + * Count home many values we need for this capability. + */ + for (cap = scap, arg_need = 0; *cap; cap++) + if (*cap == '%') + switch (*++cap) { + case 'd': + case '2': + case '3': + case '.': + case '+': + arg_need++; + break; + case '%': + case '>': + case 'i': + case 'r': + case 'n': + case 'B': + case 'D': + break; + default: + /* + * hpux has lot's of them... + */ + if (verbose) + (void) fprintf(el->el_errfile, + "echotc: Warning: unknown termcap %% `%c'.\n", + *cap); + /* This is bad, but I won't complain */ + break; + } + + switch (arg_need) { + case 0: + argv++; + if (*argv && *argv[0]) { + if (!silent) + (void) fprintf(el->el_errfile, + "echotc: Warning: Extra argument `%s'.\n", + *argv); + return (-1); + } + (void) tputs(scap, 1, term__putc); break; - case '%': - case '>': - case 'i': - case 'r': - case 'n': - case 'B': - case 'D': + case 1: + argv++; + if (!*argv || *argv[0] == '\0') { + if (!silent) + (void) fprintf(el->el_errfile, + "echotc: Warning: Missing argument.\n"); + return (-1); + } + arg_cols = 0; + i = strtol(*argv, &ep, 10); + if (*ep != '\0' || i < 0) { + if (!silent) + (void) fprintf(el->el_errfile, + "echotc: Bad value `%s' for rows.\n", + *argv); + return (-1); + } + arg_rows = (int) i; + argv++; + if (*argv && *argv[0]) { + if (!silent) + (void) fprintf(el->el_errfile, + "echotc: Warning: Extra argument `%s'.\n", + *argv); + return (-1); + } + (void) tputs(tgoto(scap, arg_cols, arg_rows), 1, term__putc); break; - default: - /* - * hpux has lot's of them... - */ + default: + /* This is wrong, but I will ignore it... */ if (verbose) - (void) fprintf(el->el_errfile, - "echotc: Warning: unknown termcap %% `%c'.\n", *cap); - /* This is bad, but I won't complain */ + (void) fprintf(el->el_errfile, + "echotc: Warning: Too many required arguments (%d).\n", + arg_need); + /* FALLTHROUGH */ + case 2: + argv++; + if (!*argv || *argv[0] == '\0') { + if (!silent) + (void) fprintf(el->el_errfile, + "echotc: Warning: Missing argument.\n"); + return (-1); + } + i = strtol(*argv, &ep, 10); + if (*ep != '\0' || i < 0) { + if (!silent) + (void) fprintf(el->el_errfile, + "echotc: Bad value `%s' for cols.\n", + *argv); + return (-1); + } + arg_cols = (int) i; + argv++; + if (!*argv || *argv[0] == '\0') { + if (!silent) + (void) fprintf(el->el_errfile, + "echotc: Warning: Missing argument.\n"); + return (-1); + } + i = strtol(*argv, &ep, 10); + if (*ep != '\0' || i < 0) { + if (!silent) + (void) fprintf(el->el_errfile, + "echotc: Bad value `%s' for rows.\n", + *argv); + return (-1); + } + arg_rows = (int) i; + if (*ep != '\0') { + if (!silent) + (void) fprintf(el->el_errfile, + "echotc: Bad value `%s'.\n", *argv); + return (-1); + } + argv++; + if (*argv && *argv[0]) { + if (!silent) + (void) fprintf(el->el_errfile, + "echotc: Warning: Extra argument `%s'.\n", + *argv); + return (-1); + } + (void) tputs(tgoto(scap, arg_cols, arg_rows), arg_rows, + term__putc); break; - } - - switch (arg_need) { - case 0: - argv++; - if (*argv && *argv[0]) { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Warning: Extra argument `%s'.\n", *argv); - return -1; - } - (void) tputs(scap, 1, term__putc); - break; - case 1: - argv++; - if (!*argv || *argv[0] == '\0') { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Warning: Missing argument.\n"); - return -1; - } - arg_cols = 0; - arg_rows = atoi(*argv); - argv++; - if (*argv && *argv[0]) { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Warning: Extra argument `%s'.\n", *argv); - return -1; - } - (void) tputs(tgoto(scap, arg_cols, arg_rows), 1, term__putc); - break; - default: - /* This is wrong, but I will ignore it... */ - if (verbose) - (void) fprintf(el->el_errfile, - "echotc: Warning: Too many required arguments (%d).\n", - arg_need); - /*FALLTHROUGH*/ - case 2: - argv++; - if (!*argv || *argv[0] == '\0') { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Warning: Missing argument.\n"); - return -1; - } - arg_cols = atoi(*argv); - argv++; - if (!*argv || *argv[0] == '\0') { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Warning: Missing argument.\n"); - return -1; - } - arg_rows = atoi(*argv); - argv++; - if (*argv && *argv[0]) { - if (!silent) - (void) fprintf(el->el_errfile, - "echotc: Warning: Extra argument `%s'.\n", *argv); - return -1; } - (void) tputs(tgoto(scap, arg_cols, arg_rows), arg_rows, term__putc); - break; - } - return 0; + return (0); } diff --git a/dist/term.h b/dist/term.h index 73347cf..57b2332 100644 --- a/dist/term.h +++ b/dist/term.h @@ -1,4 +1,4 @@ -/* $NetBSD: term.h,v 1.4 1997/01/11 06:48:14 lukem Exp $ */ +/* $NetBSD: term.h,v 1.12 2001/01/04 15:56:32 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,79 +42,83 @@ * el.term.h: Termcap header */ #ifndef _h_el_term -#define _h_el_term +#define _h_el_term #include "histedit.h" -typedef struct { /* Symbolic function key bindings */ - char *name; /* name of the key */ - int key; /* Index in termcap table */ - key_value_t fun; /* Function bound to it */ - int type; /* Type of function */ +typedef struct { /* Symbolic function key bindings */ + char *name; /* name of the key */ + int key; /* Index in termcap table */ + key_value_t fun; /* Function bound to it */ + int type; /* Type of function */ } fkey_t; typedef struct { - coord_t t_size; /* # lines and cols */ - bool_t t_flags; -#define TERM_CAN_INSERT 0x01 /* Has insert cap */ -#define TERM_CAN_DELETE 0x02 /* Has delete cap */ -#define TERM_CAN_CEOL 0x04 /* Has CEOL cap */ -#define TERM_CAN_TAB 0x08 /* Can use tabs */ -#define TERM_CAN_ME 0x10 /* Can turn all attrs. */ -#define TERM_CAN_UP 0x20 /* Can move up */ -#define TERM_HAS_META 0x40 /* Has a meta key */ - char *t_buf; /* Termcap buffer */ - int t_loc; /* location used */ - char **t_str; /* termcap strings */ - int *t_val; /* termcap values */ - char *t_cap; /* Termcap buffer */ - fkey_t *t_fkey; /* Array of keys */ + coord_t t_size; /* # lines and cols */ + int t_flags; +#define TERM_CAN_INSERT 0x001 /* Has insert cap */ +#define TERM_CAN_DELETE 0x002 /* Has delete cap */ +#define TERM_CAN_CEOL 0x004 /* Has CEOL cap */ +#define TERM_CAN_TAB 0x008 /* Can use tabs */ +#define TERM_CAN_ME 0x010 /* Can turn all attrs. */ +#define TERM_CAN_UP 0x020 /* Can move up */ +#define TERM_HAS_META 0x040 /* Has a meta key */ +#define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */ +#define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */ + char *t_buf; /* Termcap buffer */ + int t_loc; /* location used */ + char **t_str; /* termcap strings */ + int *t_val; /* termcap values */ + char *t_cap; /* Termcap buffer */ + fkey_t *t_fkey; /* Array of keys */ } el_term_t; /* * fKey indexes */ -#define A_K_DN 0 -#define A_K_UP 1 -#define A_K_LT 2 -#define A_K_RT 3 -#define A_K_NKEYS 4 +#define A_K_DN 0 +#define A_K_UP 1 +#define A_K_LT 2 +#define A_K_RT 3 +#define A_K_HO 4 +#define A_K_EN 5 +#define A_K_NKEYS 6 -protected void term_move_to_line __P((EditLine *, int)); -protected void term_move_to_char __P((EditLine *, int)); -protected void term_clear_EOL __P((EditLine *, int)); -protected void term_overwrite __P((EditLine *, char *, int)); -protected void term_insertwrite __P((EditLine *, char *, int)); -protected void term_deletechars __P((EditLine *, int)); -protected void term_clear_screen __P((EditLine *)); -protected void term_beep __P((EditLine *)); -protected void term_change_size __P((EditLine *, int, int)); -protected int term_get_size __P((EditLine *, int *, int *)); -protected int term_init __P((EditLine *)); -protected void term_bind_arrow __P((EditLine *)); -protected void term_print_arrow __P((EditLine *, char *)); -protected int term_clear_arrow __P((EditLine *, char *)); -protected int term_set_arrow __P((EditLine *, char *, - key_value_t *, int)); -protected void term_end __P((EditLine *)); -protected int term_set __P((EditLine *, char *)); -protected int term_settc __P((EditLine *, int, char **)); -protected int term_telltc __P((EditLine *, int, char **)); -protected int term_echotc __P((EditLine *, int, char **)); - -protected void term__putc __P((int)); -protected void term__flush __P((void)); +protected void term_move_to_line(EditLine *, int); +protected void term_move_to_char(EditLine *, int); +protected void term_clear_EOL(EditLine *, int); +protected void term_overwrite(EditLine *, char *, int); +protected void term_insertwrite(EditLine *, char *, int); +protected void term_deletechars(EditLine *, int); +protected void term_clear_screen(EditLine *); +protected void term_beep(EditLine *); +protected int term_change_size(EditLine *, int, int); +protected int term_get_size(EditLine *, int *, int *); +protected int term_init(EditLine *); +protected void term_bind_arrow(EditLine *); +protected void term_print_arrow(EditLine *, char *); +protected int term_clear_arrow(EditLine *, char *); +protected int term_set_arrow(EditLine *, char *, key_value_t *, int); +protected void term_end(EditLine *); +protected int term_set(EditLine *, char *); +protected int term_settc(EditLine *, int, char **); +protected int term_telltc(EditLine *, int, char **); +protected int term_echotc(EditLine *, int, char **); +protected int term__putc(int); +protected void term__flush(void); /* * Easy access macros */ -#define EL_FLAGS (el)->el_term.t_flags +#define EL_FLAGS (el)->el_term.t_flags -#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT) -#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE) -#define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL) -#define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB) -#define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME) -#define EL_HAS_META (EL_FLAGS & TERM_HAS_META) +#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT) +#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE) +#define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL) +#define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB) +#define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME) +#define EL_HAS_META (EL_FLAGS & TERM_HAS_META) +#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS) +#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS) #endif /* _h_el_term */ diff --git a/dist/termcap.h b/dist/termcap.h deleted file mode 100644 index 6b6faac..0000000 --- a/dist/termcap.h +++ /dev/null @@ -1,54 +0,0 @@ -/* $NetBSD: termcap.h,v 1.2 1997/01/11 06:48:14 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. - * - * @(#)termcap.h 8.1 (Berkeley) 6/4/93 - */ - -/* - * termcap.h: I cannot find those in any include files... - */ -#ifndef _h_termcap -#define _h_termcap - -int tgetent __P((char *, char *)); -char *tgetstr __P((char *, char **)); -int tgetflag __P((char *)); -int tgetnum __P((char *)); -char *tgoto __P((char *, int, int)); -char *tputs __P((char *, int, void (*)(int))); - -#endif /* _h_termcap */ diff --git a/dist/tokenizer.c b/dist/tokenizer.c index 49ebf08..ed9f365 100644 --- a/dist/tokenizer.c +++ b/dist/tokenizer.c @@ -1,4 +1,4 @@ -/* $NetBSD: tokenizer.c,v 1.2 1997/01/11 06:48:15 lukem Exp $ */ +/* $NetBSD: tokenizer.c,v 1.7 2001/01/04 15:56:32 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,11 +36,12 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: tokenizer.c,v 1.2 1997/01/11 06:48:15 lukem Exp $"; +__RCSID("$NetBSD: tokenizer.c,v 1.7 2001/01/04 15:56:32 christos Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -52,50 +53,52 @@ static char rcsid[] = "$NetBSD: tokenizer.c,v 1.2 1997/01/11 06:48:15 lukem Exp #include <stdlib.h> #include "tokenizer.h" -typedef enum { Q_none, Q_single, Q_double, Q_one, Q_doubleone } quote_t; +typedef enum { + Q_none, Q_single, Q_double, Q_one, Q_doubleone +} quote_t; -#define IFS "\t \n" +#define IFS "\t \n" -#define TOK_KEEP 1 -#define TOK_EAT 2 +#define TOK_KEEP 1 +#define TOK_EAT 2 -#define WINCR 20 -#define AINCR 10 +#define WINCR 20 +#define AINCR 10 -#define tok_malloc(a) malloc(a) -#define tok_free(a) free(a) -#define tok_realloc(a, b) realloc(a, b) +#define tok_malloc(a) malloc(a) +#define tok_free(a) free(a) +#define tok_realloc(a, b) realloc(a, b) struct tokenizer { - char *ifs; /* In field separator */ - int argc, amax; /* Current and maximum number of args */ - char **argv; /* Argument list */ - char *wptr, *wmax; /* Space and limit on the word buffer */ - char *wstart; /* Beginning of next word */ - char *wspace; /* Space of word buffer */ - quote_t quote; /* Quoting state */ - int flags; /* flags; */ + char *ifs; /* In field separator */ + int argc, amax; /* Current and maximum number of args */ + char **argv; /* Argument list */ + char *wptr, *wmax; /* Space and limit on the word buffer */ + char *wstart; /* Beginning of next word */ + char *wspace; /* Space of word buffer */ + quote_t quote; /* Quoting state */ + int flags; /* flags; */ }; -private void tok_finish __P((Tokenizer *)); +private void tok_finish(Tokenizer *); /* tok_finish(): * Finish a word in the tokenizer. */ private void -tok_finish(tok) - Tokenizer *tok; +tok_finish(Tokenizer *tok) { - *tok->wptr = '\0'; - if ((tok->flags & TOK_KEEP) || tok->wptr != tok->wstart) { - tok->argv[tok->argc++] = tok->wstart; - tok->argv[tok->argc] = NULL; - tok->wstart = ++tok->wptr; - } - tok->flags &= ~TOK_KEEP; + + *tok->wptr = '\0'; + if ((tok->flags & TOK_KEEP) || tok->wptr != tok->wstart) { + tok->argv[tok->argc++] = tok->wstart; + tok->argv[tok->argc] = NULL; + tok->wstart = ++tok->wptr; + } + tok->flags &= ~TOK_KEEP; } @@ -103,24 +106,27 @@ tok_finish(tok) * Initialize the tokenizer */ public Tokenizer * -tok_init(ifs) - const char *ifs; +tok_init(const char *ifs) { - Tokenizer* tok = (Tokenizer*) tok_malloc(sizeof(Tokenizer)); - - tok->ifs = strdup(ifs ? ifs : IFS); - tok->argc = 0; - tok->amax = AINCR; - tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax); - tok->argv[0] = NULL; - tok->wspace = (char *) tok_malloc(WINCR); - tok->wmax = tok->wspace + WINCR; - tok->wstart = tok->wspace; - tok->wptr = tok->wspace; - tok->flags = 0; - tok->quote = Q_none; - - return tok; + Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer)); + + tok->ifs = strdup(ifs ? ifs : IFS); + tok->argc = 0; + tok->amax = AINCR; + tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax); + if (tok->argv == NULL) + return (NULL); + tok->argv[0] = NULL; + tok->wspace = (char *) tok_malloc(WINCR); + if (tok->wspace == NULL) + return (NULL); + tok->wmax = tok->wspace + WINCR; + tok->wstart = tok->wspace; + tok->wptr = tok->wspace; + tok->flags = 0; + tok->quote = Q_none; + + return (tok); } @@ -128,14 +134,14 @@ tok_init(ifs) * Reset the tokenizer */ public void -tok_reset(tok) - Tokenizer *tok; +tok_reset(Tokenizer *tok) { - tok->argc = 0; - tok->wstart = tok->wspace; - tok->wptr = tok->wspace; - tok->flags = 0; - tok->quote = Q_none; + + tok->argc = 0; + tok->wstart = tok->wspace; + tok->wptr = tok->wspace; + tok->flags = 0; + tok->quote = Q_none; } @@ -143,13 +149,13 @@ tok_reset(tok) * Clean up */ public void -tok_end(tok) - Tokenizer *tok; +tok_end(Tokenizer *tok) { - tok_free((ptr_t) tok->ifs); - tok_free((ptr_t) tok->wspace); - tok_free((ptr_t) tok->argv); - tok_free((ptr_t) tok); + + tok_free((ptr_t) tok->ifs); + tok_free((ptr_t) tok->wspace); + tok_free((ptr_t) tok->argv); + tok_free((ptr_t) tok); } @@ -161,231 +167,232 @@ tok_end(tok) * 3: Quoted return * 2: Unmatched double quote * 1: Unmatched single quote - * 0: Ok + * 0: Ok */ public int -tok_line(tok, line, argc, argv) - Tokenizer *tok; - const char* line; - int *argc; - char ***argv; +tok_line(Tokenizer *tok, const char *line, int *argc, char ***argv) { - const char *ptr; - - while (1) { - switch (*(ptr = line++)) { - case '\'': - tok->flags |= TOK_KEEP; - tok->flags &= ~TOK_EAT; - switch (tok->quote) { - case Q_none: - tok->quote = Q_single; /* Enter single quote mode */ - break; - - case Q_single: /* Exit single quote mode */ - tok->quote = Q_none; - break; - - case Q_one: /* Quote this ' */ - tok->quote = Q_none; - *tok->wptr++ = *ptr; - break; - - case Q_double: /* Stay in double quote mode */ - *tok->wptr++ = *ptr; - break; - - case Q_doubleone: /* Quote this ' */ - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - default: - return(-1); - } - break; - - case '"': - tok->flags &= ~TOK_EAT; - tok->flags |= TOK_KEEP; - switch (tok->quote) { - case Q_none: /* Enter double quote mode */ - tok->quote = Q_double; - break; - - case Q_double: - tok->quote = Q_none; /* Exit double quote mode */ - break; - - case Q_one: /* Quote this " */ - tok->quote = Q_none; - *tok->wptr++ = *ptr; - break; - - case Q_single: /* Stay in single quote mode */ - *tok->wptr++ = *ptr; - break; - - case Q_doubleone: /* Quote this " */ - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - default: - return(-1); - } - break; - - case '\\': - tok->flags |= TOK_KEEP; - tok->flags &= ~TOK_EAT; - switch (tok->quote) { - case Q_none: /* Quote next character */ - tok->quote = Q_one; - break; - - case Q_double: - tok->quote = Q_doubleone;/* Quote next character */ - break; - - case Q_one: - *tok->wptr++ = *ptr; - tok->quote = Q_none; /* Quote this, restore state */ - break; - - case Q_single: /* Stay in single quote mode */ - *tok->wptr++ = *ptr; - break; - - case Q_doubleone: /* Quote this \ */ - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - default: - return(-1); - } - break; - - case '\n': - tok->flags &= ~TOK_EAT; - switch (tok->quote) { - case Q_none: - tok_finish(tok); - *argv = tok->argv; - *argc = tok->argc; - return(0); - - case Q_single: - case Q_double: - *tok->wptr++ = *ptr; /* Add the return */ - break; - - case Q_doubleone: - tok->flags |= TOK_EAT; - tok->quote = Q_double; /* Back to double, eat the '\n' */ - break; - - case Q_one: - tok->flags |= TOK_EAT; - tok->quote = Q_none; /* No quote, more eat the '\n' */ - break; - - default: - return(0); - } - break; - - case '\0': - switch (tok->quote) { - case Q_none: - /* Finish word and return */ - if (tok->flags & TOK_EAT) { - tok->flags &= ~TOK_EAT; - return 3; + const char *ptr; + + for (;;) { + switch (*(ptr = line++)) { + case '\'': + tok->flags |= TOK_KEEP; + tok->flags &= ~TOK_EAT; + switch (tok->quote) { + case Q_none: + tok->quote = Q_single; /* Enter single quote + * mode */ + break; + + case Q_single: /* Exit single quote mode */ + tok->quote = Q_none; + break; + + case Q_one: /* Quote this ' */ + tok->quote = Q_none; + *tok->wptr++ = *ptr; + break; + + case Q_double: /* Stay in double quote mode */ + *tok->wptr++ = *ptr; + break; + + case Q_doubleone: /* Quote this ' */ + tok->quote = Q_double; + *tok->wptr++ = *ptr; + break; + + default: + return (-1); + } + break; + + case '"': + tok->flags &= ~TOK_EAT; + tok->flags |= TOK_KEEP; + switch (tok->quote) { + case Q_none: /* Enter double quote mode */ + tok->quote = Q_double; + break; + + case Q_double: /* Exit double quote mode */ + tok->quote = Q_none; + break; + + case Q_one: /* Quote this " */ + tok->quote = Q_none; + *tok->wptr++ = *ptr; + break; + + case Q_single: /* Stay in single quote mode */ + *tok->wptr++ = *ptr; + break; + + case Q_doubleone: /* Quote this " */ + tok->quote = Q_double; + *tok->wptr++ = *ptr; + break; + + default: + return (-1); + } + break; + + case '\\': + tok->flags |= TOK_KEEP; + tok->flags &= ~TOK_EAT; + switch (tok->quote) { + case Q_none: /* Quote next character */ + tok->quote = Q_one; + break; + + case Q_double: /* Quote next character */ + tok->quote = Q_doubleone; + break; + + case Q_one: /* Quote this, restore state */ + *tok->wptr++ = *ptr; + tok->quote = Q_none; + break; + + case Q_single: /* Stay in single quote mode */ + *tok->wptr++ = *ptr; + break; + + case Q_doubleone: /* Quote this \ */ + tok->quote = Q_double; + *tok->wptr++ = *ptr; + break; + + default: + return (-1); + } + break; + + case '\n': + tok->flags &= ~TOK_EAT; + switch (tok->quote) { + case Q_none: + tok_finish(tok); + *argv = tok->argv; + *argc = tok->argc; + return (0); + + case Q_single: + case Q_double: + *tok->wptr++ = *ptr; /* Add the return */ + break; + + case Q_doubleone: /* Back to double, eat the '\n' */ + tok->flags |= TOK_EAT; + tok->quote = Q_double; + break; + + case Q_one: /* No quote, more eat the '\n' */ + tok->flags |= TOK_EAT; + tok->quote = Q_none; + break; + + default: + return (0); + } + break; + + case '\0': + switch (tok->quote) { + case Q_none: + /* Finish word and return */ + if (tok->flags & TOK_EAT) { + tok->flags &= ~TOK_EAT; + return (3); + } + tok_finish(tok); + *argv = tok->argv; + *argc = tok->argc; + return (0); + + case Q_single: + return (1); + + case Q_double: + return (2); + + case Q_doubleone: + tok->quote = Q_double; + *tok->wptr++ = *ptr; + break; + + case Q_one: + tok->quote = Q_none; + *tok->wptr++ = *ptr; + break; + + default: + return (-1); + } + break; + + default: + tok->flags &= ~TOK_EAT; + switch (tok->quote) { + case Q_none: + if (strchr(tok->ifs, *ptr) != NULL) + tok_finish(tok); + else + *tok->wptr++ = *ptr; + break; + + case Q_single: + case Q_double: + *tok->wptr++ = *ptr; + break; + + + case Q_doubleone: + *tok->wptr++ = '\\'; + tok->quote = Q_double; + *tok->wptr++ = *ptr; + break; + + case Q_one: + tok->quote = Q_none; + *tok->wptr++ = *ptr; + break; + + default: + return (-1); + + } + break; } - tok_finish(tok); - *argv = tok->argv; - *argc = tok->argc; - return(0); - - case Q_single: - return(1); - - case Q_double: - return(2); - - case Q_doubleone: - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - case Q_one: - tok->quote = Q_none; - *tok->wptr++ = *ptr; - break; - - default: - return(-1); - } - break; - - default: - tok->flags &= ~TOK_EAT; - switch (tok->quote) { - case Q_none: - if (strchr(tok->ifs, *ptr) != NULL) - tok_finish(tok); - else - *tok->wptr++ = *ptr; - break; - - case Q_single: - case Q_double: - *tok->wptr++ = *ptr; - break; - - - case Q_doubleone: - *tok->wptr++ = '\\'; - tok->quote = Q_double; - *tok->wptr++ = *ptr; - break; - - case Q_one: - tok->quote = Q_none; - *tok->wptr++ = *ptr; - break; - - default: - return(-1); - - } - break; - } - if (tok->wptr >= tok->wmax - 4) { - size_t size = tok->wmax - tok->wspace + WINCR; - char *s = (char *) tok_realloc(tok->wspace, size); - /*SUPPRESS 22*/ - int offs = s - tok->wspace; - - if (offs != 0) { - int i; - for (i = 0; i < tok->argc; i++) - tok->argv[i] = tok->argv[i] + offs; - tok->wptr = tok->wptr + offs; - tok->wstart = tok->wstart + offs; - tok->wmax = s + size; - tok->wspace = s; - } - } - - if (tok->argc >= tok->amax - 4) { - tok->amax += AINCR; - tok->argv = (char **) tok_realloc(tok->argv, - tok->amax * sizeof(char*)); + if (tok->wptr >= tok->wmax - 4) { + size_t size = tok->wmax - tok->wspace + WINCR; + char *s = (char *) tok_realloc(tok->wspace, size); + /* SUPPRESS 22 */ + int offs = s - tok->wspace; + if (s == NULL) + return (-1); + + if (offs != 0) { + int i; + for (i = 0; i < tok->argc; i++) + tok->argv[i] = tok->argv[i] + offs; + tok->wptr = tok->wptr + offs; + tok->wstart = tok->wstart + offs; + tok->wmax = s + size; + tok->wspace = s; + } + } + if (tok->argc >= tok->amax - 4) { + char **p; + tok->amax += AINCR; + p = (char **) tok_realloc(tok->argv, + tok->amax * sizeof(char *)); + if (p == NULL) + return (-1); + tok->argv = p; + } } - - } } diff --git a/dist/tokenizer.h b/dist/tokenizer.h index 11b49ac..7758919 100644 --- a/dist/tokenizer.h +++ b/dist/tokenizer.h @@ -1,4 +1,4 @@ -/* $NetBSD: tokenizer.h,v 1.2 1997/01/11 06:48:16 lukem Exp $ */ +/* $NetBSD: tokenizer.h,v 1.4 2000/09/04 22:06:33 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,14 +42,13 @@ * tokenizer.h: Header file for tokenizer routines */ #ifndef _h_tokenizer -#define _h_tokenizer +#define _h_tokenizer typedef struct tokenizer Tokenizer; -Tokenizer *tok_init __P((const char *)); -void tok_reset __P((Tokenizer *)); -void tok_end __P((Tokenizer *)); -int tok_line __P((Tokenizer *, const char *, - int *, char ***)); +Tokenizer *tok_init(const char *); +void tok_reset(Tokenizer *); +void tok_end(Tokenizer *); +int tok_line(Tokenizer *, const char *, int *, char ***); #endif /* _h_tokenizer */ @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.3 1997/04/11 17:52:49 christos Exp $ */ +/* $NetBSD: tty.c,v 1.15 2001/05/17 01:02:17 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,15 +36,16 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: tty.c,v 1.3 1997/04/11 17:52:49 christos Exp $"; +__RCSID("$NetBSD: tty.c,v 1.15 2001/05/17 01:02:17 christos Exp $"); #endif #endif /* not lint && not SCCSID */ -/* +/* * tty.c: tty interface stuff */ #include "sys.h" @@ -52,504 +53,515 @@ static char rcsid[] = "$NetBSD: tty.c,v 1.3 1997/04/11 17:52:49 christos Exp $"; #include "el.h" typedef struct ttymodes_t { - char *m_name; - u_int m_value; - int m_type; -} ttymodes_t; + const char *m_name; + u_int m_value; + int m_type; +} ttymodes_t; typedef struct ttymap_t { - int nch, och; /* Internal and termio rep of chars */ - el_action_t bind[3]; /* emacs, vi, and vi-cmd */ -} ttymap_t; - - -private ttyperm_t ttyperm = { - { - { "iflag:", ICRNL, (INLCR|IGNCR) }, - { "oflag:", (OPOST|ONLCR), ONLRET }, - { "cflag:", 0, 0 }, - { "lflag:", (ISIG|ICANON|ECHO|ECHOE|ECHOCTL|IEXTEN), - (NOFLSH|ECHONL|EXTPROC|FLUSHO) }, - { "chars:", 0, 0 }, - }, - { - { "iflag:", (INLCR|ICRNL), IGNCR }, - { "oflag:", (OPOST|ONLCR), ONLRET }, - { "cflag:", 0, 0 }, - { "lflag:", ISIG, - (NOFLSH|ICANON|ECHO|ECHOK|ECHONL|EXTPROC|IEXTEN|FLUSHO) }, - { "chars:", (C_SH(C_MIN)|C_SH(C_TIME)|C_SH(C_SWTCH)|C_SH(C_DSWTCH)| - C_SH(C_SUSP)|C_SH(C_DSUSP)|C_SH(C_EOL)|C_SH(C_DISCARD)| - C_SH(C_PGOFF)|C_SH(C_PAGE)|C_SH(C_STATUS)), 0 } - }, - { - { "iflag:", 0, IXON | IXOFF }, - { "oflag:", 0, 0 }, - { "cflag:", 0, 0 }, - { "lflag:", 0, ISIG | IEXTEN }, - { "chars:", 0, 0 }, - } + int nch, och; /* Internal and termio rep of chars */ + el_action_t bind[3]; /* emacs, vi, and vi-cmd */ +} ttymap_t; + + +private const ttyperm_t ttyperm = { + { + {"iflag:", ICRNL, (INLCR | IGNCR)}, + {"oflag:", (OPOST | ONLCR), ONLRET}, + {"cflag:", 0, 0}, + {"lflag:", (ISIG | ICANON | ECHO | ECHOE | ECHOCTL | IEXTEN), + (NOFLSH | ECHONL | EXTPROC | FLUSHO)}, + {"chars:", 0, 0}, + }, + { + {"iflag:", (INLCR | ICRNL), IGNCR}, + {"oflag:", (OPOST | ONLCR), ONLRET}, + {"cflag:", 0, 0}, + {"lflag:", ISIG, + (NOFLSH | ICANON | ECHO | ECHOK | ECHONL | EXTPROC | IEXTEN | FLUSHO)}, + {"chars:", (C_SH(C_MIN) | C_SH(C_TIME) | C_SH(C_SWTCH) | C_SH(C_DSWTCH) | + C_SH(C_SUSP) | C_SH(C_DSUSP) | C_SH(C_EOL) | C_SH(C_DISCARD) | + C_SH(C_PGOFF) | C_SH(C_PAGE) | C_SH(C_STATUS)), 0} + }, + { + {"iflag:", 0, IXON | IXOFF | INLCR | ICRNL}, + {"oflag:", 0, 0}, + {"cflag:", 0, 0}, + {"lflag:", 0, ISIG | IEXTEN}, + {"chars:", 0, 0}, + } }; -private ttychar_t ttychar = { - { - CINTR, CQUIT, CERASE, CKILL, - CEOF, CEOL, CEOL2, CSWTCH, - CDSWTCH, CERASE2, CSTART, CSTOP, - CWERASE, CSUSP, CDSUSP, CREPRINT, - CDISCARD, CLNEXT, CSTATUS, CPAGE, - CPGOFF, CKILL2, CBRK, CMIN, - CTIME - }, - { - CINTR, CQUIT, CERASE, CKILL, - _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, - _POSIX_VDISABLE, CERASE2, CSTART, CSTOP, - _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE, - CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, - _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1, - 0 - }, - { - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0, 0, 0, 0, - 0 - } +private const ttychar_t ttychar = { + { + CINTR, CQUIT, CERASE, CKILL, + CEOF, CEOL, CEOL2, CSWTCH, + CDSWTCH, CERASE2, CSTART, CSTOP, + CWERASE, CSUSP, CDSUSP, CREPRINT, + CDISCARD, CLNEXT, CSTATUS, CPAGE, + CPGOFF, CKILL2, CBRK, CMIN, + CTIME + }, + { + CINTR, CQUIT, CERASE, CKILL, + _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, + _POSIX_VDISABLE, CERASE2, CSTART, CSTOP, + _POSIX_VDISABLE, CSUSP, _POSIX_VDISABLE, _POSIX_VDISABLE, + CDISCARD, _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, + _POSIX_VDISABLE, _POSIX_VDISABLE, _POSIX_VDISABLE, 1, + 0 + }, + { + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0 + } }; -private ttymap_t tty_map[] = { +private const ttymap_t tty_map[] = { #ifdef VERASE - { C_ERASE, VERASE, - { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } }, + {C_ERASE, VERASE, + {ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, #endif /* VERASE */ #ifdef VERASE2 - { C_ERASE2, VERASE2, - { ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR } }, + {C_ERASE2, VERASE2, + {ED_DELETE_PREV_CHAR, VI_DELETE_PREV_CHAR, ED_PREV_CHAR}}, #endif /* VERASE2 */ #ifdef VKILL - { C_KILL, VKILL, - { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } }, + {C_KILL, VKILL, + {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}}, #endif /* VKILL */ #ifdef VKILL2 - { C_KILL2, VKILL2, - { EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED } }, + {C_KILL2, VKILL2, + {EM_KILL_LINE, VI_KILL_LINE_PREV, ED_UNASSIGNED}}, #endif /* VKILL2 */ #ifdef VEOF - { C_EOF, VEOF, - { EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED } }, + {C_EOF, VEOF, + {EM_DELETE_OR_LIST, VI_LIST_OR_EOF, ED_UNASSIGNED}}, #endif /* VEOF */ #ifdef VWERASE - { C_WERASE, VWERASE, - { ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD } }, + {C_WERASE, VWERASE, + {ED_DELETE_PREV_WORD, ED_DELETE_PREV_WORD, ED_PREV_WORD}}, #endif /* VWERASE */ #ifdef VREPRINT - { C_REPRINT, VREPRINT, - { ED_REDISPLAY, ED_INSERT, ED_REDISPLAY } }, + {C_REPRINT, VREPRINT, + {ED_REDISPLAY, ED_INSERT, ED_REDISPLAY}}, #endif /* VREPRINT */ #ifdef VLNEXT - { C_LNEXT, VLNEXT, - { ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED } }, + {C_LNEXT, VLNEXT, + {ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}}, +#endif /* VLNEXT */ + {-1, -1, + {ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}} +}; + +private const ttymodes_t ttymodes[] = { +#ifdef IGNBRK + {"ignbrk", IGNBRK, MD_INP}, +#endif /* IGNBRK */ +#ifdef BRKINT + {"brkint", BRKINT, MD_INP}, +#endif /* BRKINT */ +#ifdef IGNPAR + {"ignpar", IGNPAR, MD_INP}, +#endif /* IGNPAR */ +#ifdef PARMRK + {"parmrk", PARMRK, MD_INP}, +#endif /* PARMRK */ +#ifdef INPCK + {"inpck", INPCK, MD_INP}, +#endif /* INPCK */ +#ifdef ISTRIP + {"istrip", ISTRIP, MD_INP}, +#endif /* ISTRIP */ +#ifdef INLCR + {"inlcr", INLCR, MD_INP}, +#endif /* INLCR */ +#ifdef IGNCR + {"igncr", IGNCR, MD_INP}, +#endif /* IGNCR */ +#ifdef ICRNL + {"icrnl", ICRNL, MD_INP}, +#endif /* ICRNL */ +#ifdef IUCLC + {"iuclc", IUCLC, MD_INP}, +#endif /* IUCLC */ +#ifdef IXON + {"ixon", IXON, MD_INP}, +#endif /* IXON */ +#ifdef IXANY + {"ixany", IXANY, MD_INP}, +#endif /* IXANY */ +#ifdef IXOFF + {"ixoff", IXOFF, MD_INP}, +#endif /* IXOFF */ +#ifdef IMAXBEL + {"imaxbel", IMAXBEL, MD_INP}, +#endif /* IMAXBEL */ + +#ifdef OPOST + {"opost", OPOST, MD_OUT}, +#endif /* OPOST */ +#ifdef OLCUC + {"olcuc", OLCUC, MD_OUT}, +#endif /* OLCUC */ +#ifdef ONLCR + {"onlcr", ONLCR, MD_OUT}, +#endif /* ONLCR */ +#ifdef OCRNL + {"ocrnl", OCRNL, MD_OUT}, +#endif /* OCRNL */ +#ifdef ONOCR + {"onocr", ONOCR, MD_OUT}, +#endif /* ONOCR */ +#ifdef ONOEOT + {"onoeot", ONOEOT, MD_OUT}, +#endif /* ONOEOT */ +#ifdef ONLRET + {"onlret", ONLRET, MD_OUT}, +#endif /* ONLRET */ +#ifdef OFILL + {"ofill", OFILL, MD_OUT}, +#endif /* OFILL */ +#ifdef OFDEL + {"ofdel", OFDEL, MD_OUT}, +#endif /* OFDEL */ +#ifdef NLDLY + {"nldly", NLDLY, MD_OUT}, +#endif /* NLDLY */ +#ifdef CRDLY + {"crdly", CRDLY, MD_OUT}, +#endif /* CRDLY */ +#ifdef TABDLY + {"tabdly", TABDLY, MD_OUT}, +#endif /* TABDLY */ +#ifdef XTABS + {"xtabs", XTABS, MD_OUT}, +#endif /* XTABS */ +#ifdef BSDLY + {"bsdly", BSDLY, MD_OUT}, +#endif /* BSDLY */ +#ifdef VTDLY + {"vtdly", VTDLY, MD_OUT}, +#endif /* VTDLY */ +#ifdef FFDLY + {"ffdly", FFDLY, MD_OUT}, +#endif /* FFDLY */ +#ifdef PAGEOUT + {"pageout", PAGEOUT, MD_OUT}, +#endif /* PAGEOUT */ +#ifdef WRAP + {"wrap", WRAP, MD_OUT}, +#endif /* WRAP */ + +#ifdef CIGNORE + {"cignore", CIGNORE, MD_CTL}, +#endif /* CBAUD */ +#ifdef CBAUD + {"cbaud", CBAUD, MD_CTL}, +#endif /* CBAUD */ +#ifdef CSTOPB + {"cstopb", CSTOPB, MD_CTL}, +#endif /* CSTOPB */ +#ifdef CREAD + {"cread", CREAD, MD_CTL}, +#endif /* CREAD */ +#ifdef PARENB + {"parenb", PARENB, MD_CTL}, +#endif /* PARENB */ +#ifdef PARODD + {"parodd", PARODD, MD_CTL}, +#endif /* PARODD */ +#ifdef HUPCL + {"hupcl", HUPCL, MD_CTL}, +#endif /* HUPCL */ +#ifdef CLOCAL + {"clocal", CLOCAL, MD_CTL}, +#endif /* CLOCAL */ +#ifdef LOBLK + {"loblk", LOBLK, MD_CTL}, +#endif /* LOBLK */ +#ifdef CIBAUD + {"cibaud", CIBAUD, MD_CTL}, +#endif /* CIBAUD */ +#ifdef CRTSCTS +#ifdef CCTS_OFLOW + {"ccts_oflow", CCTS_OFLOW, MD_CTL}, +#else + {"crtscts", CRTSCTS, MD_CTL}, +#endif /* CCTS_OFLOW */ +#endif /* CRTSCTS */ +#ifdef CRTS_IFLOW + {"crts_iflow", CRTS_IFLOW, MD_CTL}, +#endif /* CRTS_IFLOW */ +#ifdef CDTRCTS + {"cdtrcts", CDTRCTS, MD_CTL}, +#endif /* CDTRCTS */ +#ifdef MDMBUF + {"mdmbuf", MDMBUF, MD_CTL}, +#endif /* MDMBUF */ +#ifdef RCV1EN + {"rcv1en", RCV1EN, MD_CTL}, +#endif /* RCV1EN */ +#ifdef XMT1EN + {"xmt1en", XMT1EN, MD_CTL}, +#endif /* XMT1EN */ + +#ifdef ISIG + {"isig", ISIG, MD_LIN}, +#endif /* ISIG */ +#ifdef ICANON + {"icanon", ICANON, MD_LIN}, +#endif /* ICANON */ +#ifdef XCASE + {"xcase", XCASE, MD_LIN}, +#endif /* XCASE */ +#ifdef ECHO + {"echo", ECHO, MD_LIN}, +#endif /* ECHO */ +#ifdef ECHOE + {"echoe", ECHOE, MD_LIN}, +#endif /* ECHOE */ +#ifdef ECHOK + {"echok", ECHOK, MD_LIN}, +#endif /* ECHOK */ +#ifdef ECHONL + {"echonl", ECHONL, MD_LIN}, +#endif /* ECHONL */ +#ifdef NOFLSH + {"noflsh", NOFLSH, MD_LIN}, +#endif /* NOFLSH */ +#ifdef TOSTOP + {"tostop", TOSTOP, MD_LIN}, +#endif /* TOSTOP */ +#ifdef ECHOCTL + {"echoctl", ECHOCTL, MD_LIN}, +#endif /* ECHOCTL */ +#ifdef ECHOPRT + {"echoprt", ECHOPRT, MD_LIN}, +#endif /* ECHOPRT */ +#ifdef ECHOKE + {"echoke", ECHOKE, MD_LIN}, +#endif /* ECHOKE */ +#ifdef DEFECHO + {"defecho", DEFECHO, MD_LIN}, +#endif /* DEFECHO */ +#ifdef FLUSHO + {"flusho", FLUSHO, MD_LIN}, +#endif /* FLUSHO */ +#ifdef PENDIN + {"pendin", PENDIN, MD_LIN}, +#endif /* PENDIN */ +#ifdef IEXTEN + {"iexten", IEXTEN, MD_LIN}, +#endif /* IEXTEN */ +#ifdef NOKERNINFO + {"nokerninfo", NOKERNINFO, MD_LIN}, +#endif /* NOKERNINFO */ +#ifdef ALTWERASE + {"altwerase", ALTWERASE, MD_LIN}, +#endif /* ALTWERASE */ +#ifdef EXTPROC + {"extproc", EXTPROC, MD_LIN}, +#endif /* EXTPROC */ + +#if defined(VINTR) + {"intr", C_SH(C_INTR), MD_CHAR}, +#endif /* VINTR */ +#if defined(VQUIT) + {"quit", C_SH(C_QUIT), MD_CHAR}, +#endif /* VQUIT */ +#if defined(VERASE) + {"erase", C_SH(C_ERASE), MD_CHAR}, +#endif /* VERASE */ +#if defined(VKILL) + {"kill", C_SH(C_KILL), MD_CHAR}, +#endif /* VKILL */ +#if defined(VEOF) + {"eof", C_SH(C_EOF), MD_CHAR}, +#endif /* VEOF */ +#if defined(VEOL) + {"eol", C_SH(C_EOL), MD_CHAR}, +#endif /* VEOL */ +#if defined(VEOL2) + {"eol2", C_SH(C_EOL2), MD_CHAR}, +#endif /* VEOL2 */ +#if defined(VSWTCH) + {"swtch", C_SH(C_SWTCH), MD_CHAR}, +#endif /* VSWTCH */ +#if defined(VDSWTCH) + {"dswtch", C_SH(C_DSWTCH), MD_CHAR}, +#endif /* VDSWTCH */ +#if defined(VERASE2) + {"erase2", C_SH(C_ERASE2), MD_CHAR}, +#endif /* VERASE2 */ +#if defined(VSTART) + {"start", C_SH(C_START), MD_CHAR}, +#endif /* VSTART */ +#if defined(VSTOP) + {"stop", C_SH(C_STOP), MD_CHAR}, +#endif /* VSTOP */ +#if defined(VWERASE) + {"werase", C_SH(C_WERASE), MD_CHAR}, +#endif /* VWERASE */ +#if defined(VSUSP) + {"susp", C_SH(C_SUSP), MD_CHAR}, +#endif /* VSUSP */ +#if defined(VDSUSP) + {"dsusp", C_SH(C_DSUSP), MD_CHAR}, +#endif /* VDSUSP */ +#if defined(VREPRINT) + {"reprint", C_SH(C_REPRINT), MD_CHAR}, +#endif /* VREPRINT */ +#if defined(VDISCARD) + {"discard", C_SH(C_DISCARD), MD_CHAR}, +#endif /* VDISCARD */ +#if defined(VLNEXT) + {"lnext", C_SH(C_LNEXT), MD_CHAR}, #endif /* VLNEXT */ - { -1, -1, - { ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED } } - }; - -private ttymodes_t ttymodes[] = { -# ifdef IGNBRK - { "ignbrk", IGNBRK, M_INP }, -# endif /* IGNBRK */ -# ifdef BRKINT - { "brkint", BRKINT, M_INP }, -# endif /* BRKINT */ -# ifdef IGNPAR - { "ignpar", IGNPAR, M_INP }, -# endif /* IGNPAR */ -# ifdef PARMRK - { "parmrk", PARMRK, M_INP }, -# endif /* PARMRK */ -# ifdef INPCK - { "inpck", INPCK, M_INP }, -# endif /* INPCK */ -# ifdef ISTRIP - { "istrip", ISTRIP, M_INP }, -# endif /* ISTRIP */ -# ifdef INLCR - { "inlcr", INLCR, M_INP }, -# endif /* INLCR */ -# ifdef IGNCR - { "igncr", IGNCR, M_INP }, -# endif /* IGNCR */ -# ifdef ICRNL - { "icrnl", ICRNL, M_INP }, -# endif /* ICRNL */ -# ifdef IUCLC - { "iuclc", IUCLC, M_INP }, -# endif /* IUCLC */ -# ifdef IXON - { "ixon", IXON, M_INP }, -# endif /* IXON */ -# ifdef IXANY - { "ixany", IXANY, M_INP }, -# endif /* IXANY */ -# ifdef IXOFF - { "ixoff", IXOFF, M_INP }, -# endif /* IXOFF */ -# ifdef IMAXBEL - { "imaxbel",IMAXBEL,M_INP }, -# endif /* IMAXBEL */ - -# ifdef OPOST - { "opost", OPOST, M_OUT }, -# endif /* OPOST */ -# ifdef OLCUC - { "olcuc", OLCUC, M_OUT }, -# endif /* OLCUC */ -# ifdef ONLCR - { "onlcr", ONLCR, M_OUT }, -# endif /* ONLCR */ -# ifdef OCRNL - { "ocrnl", OCRNL, M_OUT }, -# endif /* OCRNL */ -# ifdef ONOCR - { "onocr", ONOCR, M_OUT }, -# endif /* ONOCR */ -# ifdef ONOEOT - { "onoeot", ONOEOT, M_OUT }, -# endif /* ONOEOT */ -# ifdef ONLRET - { "onlret", ONLRET, M_OUT }, -# endif /* ONLRET */ -# ifdef OFILL - { "ofill", OFILL, M_OUT }, -# endif /* OFILL */ -# ifdef OFDEL - { "ofdel", OFDEL, M_OUT }, -# endif /* OFDEL */ -# ifdef NLDLY - { "nldly", NLDLY, M_OUT }, -# endif /* NLDLY */ -# ifdef CRDLY - { "crdly", CRDLY, M_OUT }, -# endif /* CRDLY */ -# ifdef TABDLY - { "tabdly", TABDLY, M_OUT }, -# endif /* TABDLY */ -# ifdef XTABS - { "xtabs", XTABS, M_OUT }, -# endif /* XTABS */ -# ifdef BSDLY - { "bsdly", BSDLY, M_OUT }, -# endif /* BSDLY */ -# ifdef VTDLY - { "vtdly", VTDLY, M_OUT }, -# endif /* VTDLY */ -# ifdef FFDLY - { "ffdly", FFDLY, M_OUT }, -# endif /* FFDLY */ -# ifdef PAGEOUT - { "pageout",PAGEOUT,M_OUT }, -# endif /* PAGEOUT */ -# ifdef WRAP - { "wrap", WRAP, M_OUT }, -# endif /* WRAP */ - -# ifdef CIGNORE - { "cignore",CIGNORE,M_CTL }, -# endif /* CBAUD */ -# ifdef CBAUD - { "cbaud", CBAUD, M_CTL }, -# endif /* CBAUD */ -# ifdef CSTOPB - { "cstopb", CSTOPB, M_CTL }, -# endif /* CSTOPB */ -# ifdef CREAD - { "cread", CREAD, M_CTL }, -# endif /* CREAD */ -# ifdef PARENB - { "parenb", PARENB, M_CTL }, -# endif /* PARENB */ -# ifdef PARODD - { "parodd", PARODD, M_CTL }, -# endif /* PARODD */ -# ifdef HUPCL - { "hupcl", HUPCL, M_CTL }, -# endif /* HUPCL */ -# ifdef CLOCAL - { "clocal", CLOCAL, M_CTL }, -# endif /* CLOCAL */ -# ifdef LOBLK - { "loblk", LOBLK, M_CTL }, -# endif /* LOBLK */ -# ifdef CIBAUD - { "cibaud", CIBAUD, M_CTL }, -# endif /* CIBAUD */ -# ifdef CRTSCTS -# ifdef CCTS_OFLOW - { "ccts_oflow",CCTS_OFLOW,M_CTL }, -# else - { "crtscts",CRTSCTS,M_CTL }, -# endif /* CCTS_OFLOW */ -# endif /* CRTSCTS */ -# ifdef CRTS_IFLOW - { "crts_iflow",CRTS_IFLOW,M_CTL }, -# endif /* CRTS_IFLOW */ -# ifdef MDMBUF - { "mdmbuf", MDMBUF, M_CTL }, -# endif /* MDMBUF */ -# ifdef RCV1EN - { "rcv1en", RCV1EN, M_CTL }, -# endif /* RCV1EN */ -# ifdef XMT1EN - { "xmt1en", XMT1EN, M_CTL }, -# endif /* XMT1EN */ - -# ifdef ISIG - { "isig", ISIG, M_LIN }, -# endif /* ISIG */ -# ifdef ICANON - { "icanon", ICANON, M_LIN }, -# endif /* ICANON */ -# ifdef XCASE - { "xcase", XCASE, M_LIN }, -# endif /* XCASE */ -# ifdef ECHO - { "echo", ECHO, M_LIN }, -# endif /* ECHO */ -# ifdef ECHOE - { "echoe", ECHOE, M_LIN }, -# endif /* ECHOE */ -# ifdef ECHOK - { "echok", ECHOK, M_LIN }, -# endif /* ECHOK */ -# ifdef ECHONL - { "echonl", ECHONL, M_LIN }, -# endif /* ECHONL */ -# ifdef NOFLSH - { "noflsh", NOFLSH, M_LIN }, -# endif /* NOFLSH */ -# ifdef TOSTOP - { "tostop", TOSTOP, M_LIN }, -# endif /* TOSTOP */ -# ifdef ECHOCTL - { "echoctl",ECHOCTL,M_LIN }, -# endif /* ECHOCTL */ -# ifdef ECHOPRT - { "echoprt",ECHOPRT,M_LIN }, -# endif /* ECHOPRT */ -# ifdef ECHOKE - { "echoke", ECHOKE, M_LIN }, -# endif /* ECHOKE */ -# ifdef DEFECHO - { "defecho",DEFECHO,M_LIN }, -# endif /* DEFECHO */ -# ifdef FLUSHO - { "flusho", FLUSHO, M_LIN }, -# endif /* FLUSHO */ -# ifdef PENDIN - { "pendin", PENDIN, M_LIN }, -# endif /* PENDIN */ -# ifdef IEXTEN - { "iexten", IEXTEN, M_LIN }, -# endif /* IEXTEN */ -# ifdef NOKERNINFO - { "nokerninfo",NOKERNINFO,M_LIN }, -# endif /* NOKERNINFO */ -# ifdef ALTWERASE - { "altwerase",ALTWERASE,M_LIN }, -# endif /* ALTWERASE */ -# ifdef EXTPROC - { "extproc",EXTPROC, M_LIN }, -# endif /* EXTPROC */ - -# if defined(VINTR) - { "intr", C_SH(C_INTR), M_CHAR }, -# endif /* VINTR */ -# if defined(VQUIT) - { "quit", C_SH(C_QUIT), M_CHAR }, -# endif /* VQUIT */ -# if defined(VERASE) - { "erase", C_SH(C_ERASE), M_CHAR }, -# endif /* VERASE */ -# if defined(VKILL) - { "kill", C_SH(C_KILL), M_CHAR }, -# endif /* VKILL */ -# if defined(VEOF) - { "eof", C_SH(C_EOF), M_CHAR }, -# endif /* VEOF */ -# if defined(VEOL) - { "eol", C_SH(C_EOL), M_CHAR }, -# endif /* VEOL */ -# if defined(VEOL2) - { "eol2", C_SH(C_EOL2), M_CHAR }, -# endif /* VEOL2 */ -# if defined(VSWTCH) - { "swtch", C_SH(C_SWTCH), M_CHAR }, -# endif /* VSWTCH */ -# if defined(VDSWTCH) - { "dswtch", C_SH(C_DSWTCH), M_CHAR }, -# endif /* VDSWTCH */ -# if defined(VERASE2) - { "erase2", C_SH(C_ERASE2), M_CHAR }, -# endif /* VERASE2 */ -# if defined(VSTART) - { "start", C_SH(C_START), M_CHAR }, -# endif /* VSTART */ -# if defined(VSTOP) - { "stop", C_SH(C_STOP), M_CHAR }, -# endif /* VSTOP */ -# if defined(VWERASE) - { "werase", C_SH(C_WERASE), M_CHAR }, -# endif /* VWERASE */ -# if defined(VSUSP) - { "susp", C_SH(C_SUSP), M_CHAR }, -# endif /* VSUSP */ -# if defined(VDSUSP) - { "dsusp", C_SH(C_DSUSP), M_CHAR }, -# endif /* VDSUSP */ -# if defined(VREPRINT) - { "reprint", C_SH(C_REPRINT),M_CHAR }, -# endif /* VREPRINT */ -# if defined(VDISCARD) - { "discard", C_SH(C_DISCARD),M_CHAR }, -# endif /* VDISCARD */ -# if defined(VLNEXT) - { "lnext", C_SH(C_LNEXT), M_CHAR }, -# endif /* VLNEXT */ -# if defined(VSTATUS) - { "status", C_SH(C_STATUS), M_CHAR }, -# endif /* VSTATUS */ -# if defined(VPAGE) - { "page", C_SH(C_PAGE), M_CHAR }, -# endif /* VPAGE */ -# if defined(VPGOFF) - { "pgoff", C_SH(C_PGOFF), M_CHAR }, -# endif /* VPGOFF */ -# if defined(VKILL2) - { "kill2", C_SH(C_KILL2), M_CHAR }, -# endif /* VKILL2 */ -# if defined(VBRK) - { "brk", C_SH(C_BRK), M_CHAR }, -# endif /* VBRK */ -# if defined(VMIN) - { "min", C_SH(C_MIN), M_CHAR }, -# endif /* VMIN */ -# if defined(VTIME) - { "time", C_SH(C_TIME), M_CHAR }, -# endif /* VTIME */ - { NULL, 0, -1 }, +#if defined(VSTATUS) + {"status", C_SH(C_STATUS), MD_CHAR}, +#endif /* VSTATUS */ +#if defined(VPAGE) + {"page", C_SH(C_PAGE), MD_CHAR}, +#endif /* VPAGE */ +#if defined(VPGOFF) + {"pgoff", C_SH(C_PGOFF), MD_CHAR}, +#endif /* VPGOFF */ +#if defined(VKILL2) + {"kill2", C_SH(C_KILL2), MD_CHAR}, +#endif /* VKILL2 */ +#if defined(VBRK) + {"brk", C_SH(C_BRK), MD_CHAR}, +#endif /* VBRK */ +#if defined(VMIN) + {"min", C_SH(C_MIN), MD_CHAR}, +#endif /* VMIN */ +#if defined(VTIME) + {"time", C_SH(C_TIME), MD_CHAR}, +#endif /* VTIME */ + {NULL, 0, -1}, }; -#define tty_getty(el, td) tcgetattr((el)->el_infd, (td)) -#define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td)) +#define tty_getty(el, td) tcgetattr((el)->el_infd, (td)) +#define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td)) -#define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1) -#define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8) -#define tty__cooked_mode(td) ((td)->c_lflag & ICANON) +#define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1) +#define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8) +#define tty__cooked_mode(td) ((td)->c_lflag & ICANON) -private void tty__getchar __P((struct termios *, unsigned char *)); -private void tty__setchar __P((struct termios *, unsigned char *)); -private speed_t tty__getspeed __P((struct termios *)); -private int tty_setup __P((EditLine *)); +private void tty__getchar(struct termios *, unsigned char *); +private void tty__setchar(struct termios *, unsigned char *); +private speed_t tty__getspeed(struct termios *); +private int tty_setup(EditLine *); -#define t_qu t_ts +#define t_qu t_ts /* tty_setup(): * Get the tty parameters and initialize the editing state */ -private int -tty_setup(el) - EditLine *el; +private int +tty_setup(EditLine *el) { - int rst = 1; - if (tty_getty(el, &el->el_tty.t_ed) == -1) { + int rst = 1; + + if (el->el_flags & EDIT_DISABLED) + return (0); + + if (tty_getty(el, &el->el_tty.t_ed) == -1) { #ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, - "tty_setup: tty_getty: %s\n", strerror(errno)); + (void) fprintf(el->el_errfile, + "tty_setup: tty_getty: %s\n", strerror(errno)); #endif /* DEBUG_TTY */ - return(-1); - } - el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed; - - el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex); - el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex); - el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex); - - el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask; - el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask; - - el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask; - el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask; - - el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask; - el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask; - - el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask; - el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask; - - /* - * Reset the tty chars to reasonable defaults - * If they are disabled, then enable them. - */ - if (rst) { - if (tty__cooked_mode(&el->el_tty.t_ts)) { - tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); - /* - * Don't affect CMIN and CTIME for the editor mode - */ - for (rst = 0; rst < C_NCC - 2; rst++) - if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable && - el->el_tty.t_c[ED_IO][rst] != el->el_tty.t_vdisable) - el->el_tty.t_c[ED_IO][rst] = el->el_tty.t_c[TS_IO][rst]; - for (rst = 0; rst < C_NCC; rst++) - if (el->el_tty.t_c[TS_IO][rst] != el->el_tty.t_vdisable && - el->el_tty.t_c[EX_IO][rst] != el->el_tty.t_vdisable) - el->el_tty.t_c[EX_IO][rst] = el->el_tty.t_c[TS_IO][rst]; - } - tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); - if (tty_setty(el, &el->el_tty.t_ex) == -1) { + return (-1); + } + el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed; + + el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex); + el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex); + el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex); + + el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask; + el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask; + + el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask; + el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask; + + el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask; + el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask; + + el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask; + el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask; + + /* + * Reset the tty chars to reasonable defaults + * If they are disabled, then enable them. + */ + if (rst) { + if (tty__cooked_mode(&el->el_tty.t_ts)) { + tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); + /* + * Don't affect CMIN and CTIME for the editor mode + */ + for (rst = 0; rst < C_NCC - 2; rst++) + if (el->el_tty.t_c[TS_IO][rst] != + el->el_tty.t_vdisable + && el->el_tty.t_c[ED_IO][rst] != + el->el_tty.t_vdisable) + el->el_tty.t_c[ED_IO][rst] = + el->el_tty.t_c[TS_IO][rst]; + for (rst = 0; rst < C_NCC; rst++) + if (el->el_tty.t_c[TS_IO][rst] != + el->el_tty.t_vdisable) + el->el_tty.t_c[EX_IO][rst] = + el->el_tty.t_c[TS_IO][rst]; + } + tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); + if (tty_setty(el, &el->el_tty.t_ex) == -1) { #ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "tty_setup: tty_setty: %s\n", - strerror(errno)); + (void) fprintf(el->el_errfile, + "tty_setup: tty_setty: %s\n", + strerror(errno)); #endif /* DEBUG_TTY */ - return(-1); - } - } - else - tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); + return (-1); + } + } else + tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); - el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask; - el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask; + el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; + el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask; - el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask; - el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask; + el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask; + el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][MD_OUT].t_setmask; - el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask; - el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask; + el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask; + el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][MD_CTL].t_setmask; - el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask; - el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask; + el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask; + el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][MD_LIN].t_setmask; - tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); - return 0; + tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); + tty_bind_char(el, 1); + return (0); } protected int -tty_init(el) - EditLine *el; +tty_init(EditLine *el) { - el->el_tty.t_mode = EX_IO; - el->el_tty.t_vdisable = _POSIX_VDISABLE; - (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t)); - (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t)); - return tty_setup(el); -} /* end tty_init */ + + el->el_tty.t_mode = EX_IO; + el->el_tty.t_vdisable = _POSIX_VDISABLE; + (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t)); + (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t)); + return (tty_setup(el)); +} /* tty_end(): @@ -557,10 +569,10 @@ tty_init(el) */ protected void /*ARGSUSED*/ -tty_end(el) - EditLine *el; +tty_end(EditLine *el) { - /* XXX: Maybe reset to an initial state? */ + + /* XXX: Maybe reset to an initial state? */ } @@ -568,560 +580,582 @@ tty_end(el) * Get the tty speed */ private speed_t -tty__getspeed(td) - struct termios *td; +tty__getspeed(struct termios *td) { - speed_t spd; + speed_t spd; - if ((spd = cfgetispeed(td)) == 0) - spd = cfgetospeed(td); - return spd; -} /* end tty__getspeed */ + if ((spd = cfgetispeed(td)) == 0) + spd = cfgetospeed(td); + return (spd); +} /* tty__getchar(): * Get the tty characters */ private void -tty__getchar(td, s) - struct termios *td; - unsigned char *s; -{ -# ifdef VINTR - s[C_INTR] = td->c_cc[VINTR]; -# endif /* VINTR */ -# ifdef VQUIT - s[C_QUIT] = td->c_cc[VQUIT]; -# endif /* VQUIT */ -# ifdef VERASE - s[C_ERASE] = td->c_cc[VERASE]; -# endif /* VERASE */ -# ifdef VKILL - s[C_KILL] = td->c_cc[VKILL]; -# endif /* VKILL */ -# ifdef VEOF - s[C_EOF] = td->c_cc[VEOF]; -# endif /* VEOF */ -# ifdef VEOL - s[C_EOL] = td->c_cc[VEOL]; -# endif /* VEOL */ -# ifdef VEOL2 - s[C_EOL2] = td->c_cc[VEOL2]; -# endif /* VEOL2 */ -# ifdef VSWTCH - s[C_SWTCH] = td->c_cc[VSWTCH]; -# endif /* VSWTCH */ -# ifdef VDSWTCH - s[C_DSWTCH] = td->c_cc[VDSWTCH]; -# endif /* VDSWTCH */ -# ifdef VERASE2 - s[C_ERASE2] = td->c_cc[VERASE2]; -# endif /* VERASE2 */ -# ifdef VSTART - s[C_START] = td->c_cc[VSTART]; -# endif /* VSTART */ -# ifdef VSTOP - s[C_STOP] = td->c_cc[VSTOP]; -# endif /* VSTOP */ -# ifdef VWERASE - s[C_WERASE] = td->c_cc[VWERASE]; -# endif /* VWERASE */ -# ifdef VSUSP - s[C_SUSP] = td->c_cc[VSUSP]; -# endif /* VSUSP */ -# ifdef VDSUSP - s[C_DSUSP] = td->c_cc[VDSUSP]; -# endif /* VDSUSP */ -# ifdef VREPRINT - s[C_REPRINT]= td->c_cc[VREPRINT]; -# endif /* VREPRINT */ -# ifdef VDISCARD - s[C_DISCARD]= td->c_cc[VDISCARD]; -# endif /* VDISCARD */ -# ifdef VLNEXT - s[C_LNEXT] = td->c_cc[VLNEXT]; -# endif /* VLNEXT */ -# ifdef VSTATUS - s[C_STATUS] = td->c_cc[VSTATUS]; -# endif /* VSTATUS */ -# ifdef VPAGE - s[C_PAGE] = td->c_cc[VPAGE]; -# endif /* VPAGE */ -# ifdef VPGOFF - s[C_PGOFF] = td->c_cc[VPGOFF]; -# endif /* VPGOFF */ -# ifdef VKILL2 - s[C_KILL2] = td->c_cc[VKILL2]; -# endif /* KILL2 */ -# ifdef VMIN - s[C_MIN] = td->c_cc[VMIN]; -# endif /* VMIN */ -# ifdef VTIME - s[C_TIME] = td->c_cc[VTIME]; -# endif /* VTIME */ -} /* tty__getchar */ +tty__getchar(struct termios *td, unsigned char *s) +{ + +#ifdef VINTR + s[C_INTR] = td->c_cc[VINTR]; +#endif /* VINTR */ +#ifdef VQUIT + s[C_QUIT] = td->c_cc[VQUIT]; +#endif /* VQUIT */ +#ifdef VERASE + s[C_ERASE] = td->c_cc[VERASE]; +#endif /* VERASE */ +#ifdef VKILL + s[C_KILL] = td->c_cc[VKILL]; +#endif /* VKILL */ +#ifdef VEOF + s[C_EOF] = td->c_cc[VEOF]; +#endif /* VEOF */ +#ifdef VEOL + s[C_EOL] = td->c_cc[VEOL]; +#endif /* VEOL */ +#ifdef VEOL2 + s[C_EOL2] = td->c_cc[VEOL2]; +#endif /* VEOL2 */ +#ifdef VSWTCH + s[C_SWTCH] = td->c_cc[VSWTCH]; +#endif /* VSWTCH */ +#ifdef VDSWTCH + s[C_DSWTCH] = td->c_cc[VDSWTCH]; +#endif /* VDSWTCH */ +#ifdef VERASE2 + s[C_ERASE2] = td->c_cc[VERASE2]; +#endif /* VERASE2 */ +#ifdef VSTART + s[C_START] = td->c_cc[VSTART]; +#endif /* VSTART */ +#ifdef VSTOP + s[C_STOP] = td->c_cc[VSTOP]; +#endif /* VSTOP */ +#ifdef VWERASE + s[C_WERASE] = td->c_cc[VWERASE]; +#endif /* VWERASE */ +#ifdef VSUSP + s[C_SUSP] = td->c_cc[VSUSP]; +#endif /* VSUSP */ +#ifdef VDSUSP + s[C_DSUSP] = td->c_cc[VDSUSP]; +#endif /* VDSUSP */ +#ifdef VREPRINT + s[C_REPRINT] = td->c_cc[VREPRINT]; +#endif /* VREPRINT */ +#ifdef VDISCARD + s[C_DISCARD] = td->c_cc[VDISCARD]; +#endif /* VDISCARD */ +#ifdef VLNEXT + s[C_LNEXT] = td->c_cc[VLNEXT]; +#endif /* VLNEXT */ +#ifdef VSTATUS + s[C_STATUS] = td->c_cc[VSTATUS]; +#endif /* VSTATUS */ +#ifdef VPAGE + s[C_PAGE] = td->c_cc[VPAGE]; +#endif /* VPAGE */ +#ifdef VPGOFF + s[C_PGOFF] = td->c_cc[VPGOFF]; +#endif /* VPGOFF */ +#ifdef VKILL2 + s[C_KILL2] = td->c_cc[VKILL2]; +#endif /* KILL2 */ +#ifdef VMIN + s[C_MIN] = td->c_cc[VMIN]; +#endif /* VMIN */ +#ifdef VTIME + s[C_TIME] = td->c_cc[VTIME]; +#endif /* VTIME */ +} /* tty__getchar */ /* tty__setchar(): * Set the tty characters */ private void -tty__setchar(td, s) - struct termios *td; - unsigned char *s; -{ -# ifdef VINTR - td->c_cc[VINTR] = s[C_INTR]; -# endif /* VINTR */ -# ifdef VQUIT - td->c_cc[VQUIT] = s[C_QUIT]; -# endif /* VQUIT */ -# ifdef VERASE - td->c_cc[VERASE] = s[C_ERASE]; -# endif /* VERASE */ -# ifdef VKILL - td->c_cc[VKILL] = s[C_KILL]; -# endif /* VKILL */ -# ifdef VEOF - td->c_cc[VEOF] = s[C_EOF]; -# endif /* VEOF */ -# ifdef VEOL - td->c_cc[VEOL] = s[C_EOL]; -# endif /* VEOL */ -# ifdef VEOL2 - td->c_cc[VEOL2] = s[C_EOL2]; -# endif /* VEOL2 */ -# ifdef VSWTCH - td->c_cc[VSWTCH] = s[C_SWTCH]; -# endif /* VSWTCH */ -# ifdef VDSWTCH - td->c_cc[VDSWTCH] = s[C_DSWTCH]; -# endif /* VDSWTCH */ -# ifdef VERASE2 - td->c_cc[VERASE2] = s[C_ERASE2]; -# endif /* VERASE2 */ -# ifdef VSTART - td->c_cc[VSTART] = s[C_START]; -# endif /* VSTART */ -# ifdef VSTOP - td->c_cc[VSTOP] = s[C_STOP]; -# endif /* VSTOP */ -# ifdef VWERASE - td->c_cc[VWERASE] = s[C_WERASE]; -# endif /* VWERASE */ -# ifdef VSUSP - td->c_cc[VSUSP] = s[C_SUSP]; -# endif /* VSUSP */ -# ifdef VDSUSP - td->c_cc[VDSUSP] = s[C_DSUSP]; -# endif /* VDSUSP */ -# ifdef VREPRINT - td->c_cc[VREPRINT] = s[C_REPRINT]; -# endif /* VREPRINT */ -# ifdef VDISCARD - td->c_cc[VDISCARD] = s[C_DISCARD]; -# endif /* VDISCARD */ -# ifdef VLNEXT - td->c_cc[VLNEXT] = s[C_LNEXT]; -# endif /* VLNEXT */ -# ifdef VSTATUS - td->c_cc[VSTATUS] = s[C_STATUS]; -# endif /* VSTATUS */ -# ifdef VPAGE - td->c_cc[VPAGE] = s[C_PAGE]; -# endif /* VPAGE */ -# ifdef VPGOFF - td->c_cc[VPGOFF] = s[C_PGOFF]; -# endif /* VPGOFF */ -# ifdef VKILL2 - td->c_cc[VKILL2] = s[C_KILL2]; -# endif /* VKILL2 */ -# ifdef VMIN - td->c_cc[VMIN] = s[C_MIN]; -# endif /* VMIN */ -# ifdef VTIME - td->c_cc[VTIME] = s[C_TIME]; -# endif /* VTIME */ -} /* tty__setchar */ +tty__setchar(struct termios *td, unsigned char *s) +{ + +#ifdef VINTR + td->c_cc[VINTR] = s[C_INTR]; +#endif /* VINTR */ +#ifdef VQUIT + td->c_cc[VQUIT] = s[C_QUIT]; +#endif /* VQUIT */ +#ifdef VERASE + td->c_cc[VERASE] = s[C_ERASE]; +#endif /* VERASE */ +#ifdef VKILL + td->c_cc[VKILL] = s[C_KILL]; +#endif /* VKILL */ +#ifdef VEOF + td->c_cc[VEOF] = s[C_EOF]; +#endif /* VEOF */ +#ifdef VEOL + td->c_cc[VEOL] = s[C_EOL]; +#endif /* VEOL */ +#ifdef VEOL2 + td->c_cc[VEOL2] = s[C_EOL2]; +#endif /* VEOL2 */ +#ifdef VSWTCH + td->c_cc[VSWTCH] = s[C_SWTCH]; +#endif /* VSWTCH */ +#ifdef VDSWTCH + td->c_cc[VDSWTCH] = s[C_DSWTCH]; +#endif /* VDSWTCH */ +#ifdef VERASE2 + td->c_cc[VERASE2] = s[C_ERASE2]; +#endif /* VERASE2 */ +#ifdef VSTART + td->c_cc[VSTART] = s[C_START]; +#endif /* VSTART */ +#ifdef VSTOP + td->c_cc[VSTOP] = s[C_STOP]; +#endif /* VSTOP */ +#ifdef VWERASE + td->c_cc[VWERASE] = s[C_WERASE]; +#endif /* VWERASE */ +#ifdef VSUSP + td->c_cc[VSUSP] = s[C_SUSP]; +#endif /* VSUSP */ +#ifdef VDSUSP + td->c_cc[VDSUSP] = s[C_DSUSP]; +#endif /* VDSUSP */ +#ifdef VREPRINT + td->c_cc[VREPRINT] = s[C_REPRINT]; +#endif /* VREPRINT */ +#ifdef VDISCARD + td->c_cc[VDISCARD] = s[C_DISCARD]; +#endif /* VDISCARD */ +#ifdef VLNEXT + td->c_cc[VLNEXT] = s[C_LNEXT]; +#endif /* VLNEXT */ +#ifdef VSTATUS + td->c_cc[VSTATUS] = s[C_STATUS]; +#endif /* VSTATUS */ +#ifdef VPAGE + td->c_cc[VPAGE] = s[C_PAGE]; +#endif /* VPAGE */ +#ifdef VPGOFF + td->c_cc[VPGOFF] = s[C_PGOFF]; +#endif /* VPGOFF */ +#ifdef VKILL2 + td->c_cc[VKILL2] = s[C_KILL2]; +#endif /* VKILL2 */ +#ifdef VMIN + td->c_cc[VMIN] = s[C_MIN]; +#endif /* VMIN */ +#ifdef VTIME + td->c_cc[VTIME] = s[C_TIME]; +#endif /* VTIME */ +} /* tty__setchar */ /* tty_bind_char(): * Rebind the editline functions */ protected void -tty_bind_char(el, force) - EditLine *el; - int force; +tty_bind_char(EditLine *el, int force) { - unsigned char *t_n = el->el_tty.t_c[ED_IO]; - unsigned char *t_o = el->el_tty.t_ed.c_cc; - char new[2], old[2]; - ttymap_t *tp; - el_action_t *dmap, *dalt, *map, *alt; - new[1] = old[1] = '\0'; - - - map = el->el_map.key; - alt = el->el_map.alt; - if (el->el_map.type == MAP_VI) { - dmap = el->el_map.vii; - dalt = el->el_map.vic; - } - else { - dmap = el->el_map.emacs; - dalt = NULL; - } - - for (tp = tty_map; tp->nch != -1; tp++) { - new[0] = t_n[tp->nch]; - old[0] = t_o[tp->och]; - if (new[0] == old[0] && !force) - continue; - /* Put the old default binding back, and set the new binding */ - key_clear(el, map, old); - map[old[0]] = dmap[old[0]]; - key_clear(el, map, new); - /* MAP_VI == 1, MAP_EMACS == 0... */ - map[new[0]] = tp->bind[el->el_map.type]; - if (dalt) { - key_clear(el, alt, old); - alt[old[0]] = dalt[old[0]]; - key_clear(el, alt, new); - alt[new[0]] = tp->bind[el->el_map.type+1]; + + unsigned char *t_n = el->el_tty.t_c[ED_IO]; + unsigned char *t_o = el->el_tty.t_ed.c_cc; + unsigned char new[2], old[2]; + const ttymap_t *tp; + el_action_t *map, *alt; + const el_action_t *dmap, *dalt; + new[1] = old[1] = '\0'; + + map = el->el_map.key; + alt = el->el_map.alt; + if (el->el_map.type == MAP_VI) { + dmap = el->el_map.vii; + dalt = el->el_map.vic; + } else { + dmap = el->el_map.emacs; + dalt = NULL; + } + + for (tp = tty_map; tp->nch != -1; tp++) { + new[0] = t_n[tp->nch]; + old[0] = t_o[tp->och]; + if (new[0] == old[0] && !force) + continue; + /* Put the old default binding back, and set the new binding */ + key_clear(el, map, (char *)old); + map[old[0]] = dmap[old[0]]; + key_clear(el, map, (char *)new); + /* MAP_VI == 1, MAP_EMACS == 0... */ + map[new[0]] = tp->bind[el->el_map.type]; + if (dalt) { + key_clear(el, alt, (char *)old); + alt[old[0]] = dalt[old[0]]; + key_clear(el, alt, (char *)new); + alt[new[0]] = tp->bind[el->el_map.type + 1]; + } } - } } + /* tty_rawmode(): * Set terminal into 1 character at a time mode. */ protected int -tty_rawmode(el) - EditLine *el; +tty_rawmode(EditLine *el) { - if (el->el_tty.t_mode == ED_IO) - return (0); - - if (tty_getty(el, &el->el_tty.t_ts) == -1) { -#ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", strerror(errno)); -#endif /* DEBUG_TTY */ - return(-1); - } - - /* - * We always keep up with the eight bit setting and the speed of the - * tty. But only we only believe changes that are made to cooked mode! - */ - el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts); - el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts); - - if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed || - tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) { - (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed); - (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed); - (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed); - (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed); - } - - if (tty__cooked_mode(&el->el_tty.t_ts)) { - if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) { - el->el_tty.t_ex.c_cflag = el->el_tty.t_ts.c_cflag; - el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][M_CTL].t_clrmask; - el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][M_CTL].t_setmask; - - el->el_tty.t_ed.c_cflag = el->el_tty.t_ts.c_cflag; - el->el_tty.t_ed.c_cflag &= ~el->el_tty.t_t[ED_IO][M_CTL].t_clrmask; - el->el_tty.t_ed.c_cflag |= el->el_tty.t_t[ED_IO][M_CTL].t_setmask; - } - if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) && - (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) { - el->el_tty.t_ex.c_lflag = el->el_tty.t_ts.c_lflag; - el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][M_LIN].t_clrmask; - el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][M_LIN].t_setmask; - - el->el_tty.t_ed.c_lflag = el->el_tty.t_ts.c_lflag; - el->el_tty.t_ed.c_lflag &= ~el->el_tty.t_t[ED_IO][M_LIN].t_clrmask; - el->el_tty.t_ed.c_lflag |= el->el_tty.t_t[ED_IO][M_LIN].t_setmask; - } + if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO) + return (0); - if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) && - (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) { - el->el_tty.t_ex.c_iflag = el->el_tty.t_ts.c_iflag; - el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][M_INP].t_clrmask; - el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][M_INP].t_setmask; + if (el->el_flags & EDIT_DISABLED) + return (0); - el->el_tty.t_ed.c_iflag = el->el_tty.t_ts.c_iflag; - el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][M_INP].t_clrmask; - el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][M_INP].t_setmask; + if (tty_getty(el, &el->el_tty.t_ts) == -1) { +#ifdef DEBUG_TTY + (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", + strerror(errno)); +#endif /* DEBUG_TTY */ + return (-1); } - - if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) && - (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) { - el->el_tty.t_ex.c_oflag = el->el_tty.t_ts.c_oflag; - el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][M_OUT].t_clrmask; - el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][M_OUT].t_setmask; - - el->el_tty.t_ed.c_oflag = el->el_tty.t_ts.c_oflag; - el->el_tty.t_ed.c_oflag &= ~el->el_tty.t_t[ED_IO][M_OUT].t_clrmask; - el->el_tty.t_ed.c_oflag |= el->el_tty.t_t[ED_IO][M_OUT].t_setmask; + /* + * We always keep up with the eight bit setting and the speed of the + * tty. But only we only believe changes that are made to cooked mode! + */ + el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts); + el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts); + + if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed || + tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) { + (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed); + (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed); + (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed); + (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed); } - - if (tty__gettabs(&el->el_tty.t_ex) == 0) - el->el_tty.t_tabs = 0; - else - el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0; - - { - int i; - - tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); - /* - * Check if the user made any changes. - * If he did, then propagate the changes to the - * edit and execute data structures. - */ - for (i = 0; i < C_NCC; i++) - if (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i]) - break; - - if (i != C_NCC) { - /* - * Propagate changes only to the unprotected chars - * that have been modified just now. - */ - for (i = 0; i < C_NCC; i++) { - if (!((el->el_tty.t_t[ED_IO][M_CHAR].t_setmask & C_SH(i))) - && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])) - el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i]; - if (el->el_tty.t_t[ED_IO][M_CHAR].t_clrmask & C_SH(i)) - el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable; + if (tty__cooked_mode(&el->el_tty.t_ts)) { + if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) { + el->el_tty.t_ex.c_cflag = + el->el_tty.t_ts.c_cflag; + el->el_tty.t_ex.c_cflag &= + ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask; + el->el_tty.t_ex.c_cflag |= + el->el_tty.t_t[EX_IO][MD_CTL].t_setmask; + + el->el_tty.t_ed.c_cflag = + el->el_tty.t_ts.c_cflag; + el->el_tty.t_ed.c_cflag &= + ~el->el_tty.t_t[ED_IO][MD_CTL].t_clrmask; + el->el_tty.t_ed.c_cflag |= + el->el_tty.t_t[ED_IO][MD_CTL].t_setmask; } - tty_bind_char(el, 0); - tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); - - for (i = 0; i < C_NCC; i++) { - if (!((el->el_tty.t_t[EX_IO][M_CHAR].t_setmask & C_SH(i))) - && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])) - el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i]; - if (el->el_tty.t_t[EX_IO][M_CHAR].t_clrmask & C_SH(i)) - el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable; + if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) && + (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) { + el->el_tty.t_ex.c_lflag = + el->el_tty.t_ts.c_lflag; + el->el_tty.t_ex.c_lflag &= + ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask; + el->el_tty.t_ex.c_lflag |= + el->el_tty.t_t[EX_IO][MD_LIN].t_setmask; + + el->el_tty.t_ed.c_lflag = + el->el_tty.t_ts.c_lflag; + el->el_tty.t_ed.c_lflag &= + ~el->el_tty.t_t[ED_IO][MD_LIN].t_clrmask; + el->el_tty.t_ed.c_lflag |= + el->el_tty.t_t[ED_IO][MD_LIN].t_setmask; + } + if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) && + (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) { + el->el_tty.t_ex.c_iflag = + el->el_tty.t_ts.c_iflag; + el->el_tty.t_ex.c_iflag &= + ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask; + el->el_tty.t_ex.c_iflag |= + el->el_tty.t_t[EX_IO][MD_INP].t_setmask; + + el->el_tty.t_ed.c_iflag = + el->el_tty.t_ts.c_iflag; + el->el_tty.t_ed.c_iflag &= + ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; + el->el_tty.t_ed.c_iflag |= + el->el_tty.t_t[ED_IO][MD_INP].t_setmask; + } + if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) && + (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) { + el->el_tty.t_ex.c_oflag = + el->el_tty.t_ts.c_oflag; + el->el_tty.t_ex.c_oflag &= + ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask; + el->el_tty.t_ex.c_oflag |= + el->el_tty.t_t[EX_IO][MD_OUT].t_setmask; + + el->el_tty.t_ed.c_oflag = + el->el_tty.t_ts.c_oflag; + el->el_tty.t_ed.c_oflag &= + ~el->el_tty.t_t[ED_IO][MD_OUT].t_clrmask; + el->el_tty.t_ed.c_oflag |= + el->el_tty.t_t[ED_IO][MD_OUT].t_setmask; + } + if (tty__gettabs(&el->el_tty.t_ex) == 0) + el->el_tty.t_tabs = 0; + else + el->el_tty.t_tabs = EL_CAN_TAB ? 1 : 0; + + { + int i; + + tty__getchar(&el->el_tty.t_ts, el->el_tty.t_c[TS_IO]); + /* + * Check if the user made any changes. + * If he did, then propagate the changes to the + * edit and execute data structures. + */ + for (i = 0; i < C_NCC; i++) + if (el->el_tty.t_c[TS_IO][i] != + el->el_tty.t_c[EX_IO][i]) + break; + + if (i != C_NCC) { + /* + * Propagate changes only to the unprotected + * chars that have been modified just now. + */ + for (i = 0; i < C_NCC; i++) { + if (!((el->el_tty.t_t[ED_IO][MD_CHAR].t_setmask & C_SH(i))) + && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])) + el->el_tty.t_c[ED_IO][i] = el->el_tty.t_c[TS_IO][i]; + if (el->el_tty.t_t[ED_IO][MD_CHAR].t_clrmask & C_SH(i)) + el->el_tty.t_c[ED_IO][i] = el->el_tty.t_vdisable; + } + tty_bind_char(el, 0); + tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); + + for (i = 0; i < C_NCC; i++) { + if (!((el->el_tty.t_t[EX_IO][MD_CHAR].t_setmask & C_SH(i))) + && (el->el_tty.t_c[TS_IO][i] != el->el_tty.t_c[EX_IO][i])) + el->el_tty.t_c[EX_IO][i] = el->el_tty.t_c[TS_IO][i]; + if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i)) + el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable; + } + tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); + } } - tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); - } - } - } - - if (tty_setty(el, &el->el_tty.t_ed) == -1) { + if (tty_setty(el, &el->el_tty.t_ed) == -1) { #ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n", - strerror(errno)); + (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n", + strerror(errno)); #endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_mode = ED_IO; - return (0); -} /* end tty_rawmode */ + return (-1); + } + el->el_tty.t_mode = ED_IO; + return (0); +} /* tty_cookedmode(): * Set the tty back to normal mode */ protected int -tty_cookedmode(el) - EditLine *el; +tty_cookedmode(EditLine *el) { /* set tty in normal setup */ - if (el->el_tty.t_mode == EX_IO) - return (0); - if (tty_setty(el, &el->el_tty.t_ex) == -1) { + if (el->el_tty.t_mode == EX_IO) + return (0); + + if (el->el_flags & EDIT_DISABLED) + return (0); + + if (tty_setty(el, &el->el_tty.t_ex) == -1) { #ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "tty_cookedmode: tty_setty: %s\n", - strerror(errno)); + (void) fprintf(el->el_errfile, + "tty_cookedmode: tty_setty: %s\n", + strerror(errno)); #endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_mode = EX_IO; - return (0); -} /* end tty_cookedmode */ + return (-1); + } + el->el_tty.t_mode = EX_IO; + return (0); +} /* tty_quotemode(): * Turn on quote mode */ protected int -tty_quotemode(el) - EditLine *el; +tty_quotemode(EditLine *el) { - if (el->el_tty.t_mode == QU_IO) - return 0; + if (el->el_tty.t_mode == QU_IO) + return (0); - el->el_tty.t_qu = el->el_tty.t_ed; + el->el_tty.t_qu = el->el_tty.t_ed; - el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][M_INP].t_clrmask; - el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][M_INP].t_setmask; + el->el_tty.t_qu.c_iflag &= ~el->el_tty.t_t[QU_IO][MD_INP].t_clrmask; + el->el_tty.t_qu.c_iflag |= el->el_tty.t_t[QU_IO][MD_INP].t_setmask; - el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][M_OUT].t_clrmask; - el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][M_OUT].t_setmask; + el->el_tty.t_qu.c_oflag &= ~el->el_tty.t_t[QU_IO][MD_OUT].t_clrmask; + el->el_tty.t_qu.c_oflag |= el->el_tty.t_t[QU_IO][MD_OUT].t_setmask; - el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][M_CTL].t_clrmask; - el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][M_CTL].t_setmask; + el->el_tty.t_qu.c_cflag &= ~el->el_tty.t_t[QU_IO][MD_CTL].t_clrmask; + el->el_tty.t_qu.c_cflag |= el->el_tty.t_t[QU_IO][MD_CTL].t_setmask; - el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][M_LIN].t_clrmask; - el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][M_LIN].t_setmask; + el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask; + el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask; - if (tty_setty(el, &el->el_tty.t_qu) == -1) { + if (tty_setty(el, &el->el_tty.t_qu) == -1) { #ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n", - strerror(errno)); + (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n", + strerror(errno)); #endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_mode = QU_IO; - return 0; -} /* end tty_quotemode */ + return (-1); + } + el->el_tty.t_mode = QU_IO; + return (0); +} /* tty_noquotemode(): * Turn off quote mode */ protected int -tty_noquotemode(el) - EditLine *el; +tty_noquotemode(EditLine *el) { - if (el->el_tty.t_mode != QU_IO) - return 0; - if (tty_setty(el, &el->el_tty.t_ed) == -1) { + + if (el->el_tty.t_mode != QU_IO) + return (0); + if (tty_setty(el, &el->el_tty.t_ed) == -1) { #ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n", - strerror(errno)); + (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n", + strerror(errno)); #endif /* DEBUG_TTY */ - return -1; - } - el->el_tty.t_mode = ED_IO; - return 0; + return (-1); + } + el->el_tty.t_mode = ED_IO; + return (0); } + /* tty_stty(): * Stty builtin */ protected int /*ARGSUSED*/ -tty_stty(el, argc, argv) - EditLine *el; - int argc; - char **argv; +tty_stty(EditLine *el, int argc, char **argv) { - ttymodes_t *m; - char x, *d; - int aflag = 0; - char *s; - char *name; - int z = EX_IO; - - if (argv == NULL) - return -1; - name = *argv++; - - while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0') - switch (argv[0][1]) { - case 'a': - aflag++; - argv++; - break; - case 'd': - argv++; - z = ED_IO; - break; - case 'x': - argv++; - z = EX_IO; - break; - case 'q': - argv++; - z = QU_IO; - break; - default: - (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n", - name, argv[0][1]); - return -1; - } - - if (!argv || !*argv) { - int i = -1; - int len = 0, st = 0, cu; - for (m = ttymodes; m->m_name; m++) { - if (m->m_type != i) { - (void) fprintf(el->el_outfile, "%s%s", i != -1 ? "\n" : "", - el->el_tty.t_t[z][m->m_type].t_name); - i = m->m_type; - st = len = strlen(el->el_tty.t_t[z][m->m_type].t_name); - } - - x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) ? '+' : '\0'; - x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) ? '-' : x; - - if (x != '\0' || aflag) { - - cu = strlen(m->m_name) + (x != '\0') + 1; - - if (len + cu >= el->el_term.t_size.h) { - (void) fprintf(el->el_outfile, "\n%*s", st, ""); - len = st + cu; + const ttymodes_t *m; + char x, *d; + int aflag = 0; + char *s; + char *name; + int z = EX_IO; + + if (argv == NULL) + return (-1); + name = *argv++; + + while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0') + switch (argv[0][1]) { + case 'a': + aflag++; + argv++; + break; + case 'd': + argv++; + z = ED_IO; + break; + case 'x': + argv++; + z = EX_IO; + break; + case 'q': + argv++; + z = QU_IO; + break; + default: + (void) fprintf(el->el_errfile, + "%s: Unknown switch `%c'.\n", + name, argv[0][1]); + return (-1); } - else - len += cu; - if (x != '\0') - (void) fprintf(el->el_outfile, "%c%s ", x, m->m_name); - else - (void) fprintf(el->el_outfile, "%s ", m->m_name); - } - } - (void) fprintf(el->el_outfile, "\n"); - return 0; - } - - while (argv && (s = *argv++)) { - switch (*s) { - case '+': - case '-': - x = *s++; - break; - default: - x = '\0'; - break; - } - d = s; - for (m = ttymodes; m->m_name; m++) - if (strcmp(m->m_name, d) == 0) - break; - - if (!m->m_name) { - (void) fprintf(el->el_errfile, "%s: Invalid argument `%s'.\n", - name, d); - return -1; + if (!argv || !*argv) { + int i = -1; + int len = 0, st = 0, cu; + for (m = ttymodes; m->m_name; m++) { + if (m->m_type != i) { + (void) fprintf(el->el_outfile, "%s%s", + i != -1 ? "\n" : "", + el->el_tty.t_t[z][m->m_type].t_name); + i = m->m_type; + st = len = + strlen(el->el_tty.t_t[z][m->m_type].t_name); + } + x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) + ? '+' : '\0'; + x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) + ? '-' : x; + + if (x != '\0' || aflag) { + + cu = strlen(m->m_name) + (x != '\0') + 1; + + if (len + cu >= el->el_term.t_size.h) { + (void) fprintf(el->el_outfile, "\n%*s", + st, ""); + len = st + cu; + } else + len += cu; + + if (x != '\0') + (void) fprintf(el->el_outfile, "%c%s ", + x, m->m_name); + else + (void) fprintf(el->el_outfile, "%s ", + m->m_name); + } + } + (void) fprintf(el->el_outfile, "\n"); + return (0); } - - switch (x) { - 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_clrmask &= ~m->m_value; - break; - 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_clrmask |= m->m_value; - break; - default: - el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value; - el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value; - break; + while (argv && (s = *argv++)) { + switch (*s) { + case '+': + case '-': + x = *s++; + break; + default: + x = '\0'; + break; + } + d = s; + for (m = ttymodes; m->m_name; m++) + if (strcmp(m->m_name, d) == 0) + break; + + if (!m->m_name) { + (void) fprintf(el->el_errfile, + "%s: Invalid argument `%s'.\n", name, d); + return (-1); + } + switch (x) { + 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_clrmask &= ~m->m_value; + break; + 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_clrmask |= m->m_value; + break; + default: + el->el_tty.t_t[z][m->m_type].t_setmask &= ~m->m_value; + el->el_tty.t_t[z][m->m_type].t_clrmask &= ~m->m_value; + break; + } } - } - return 0; -} /* end tty_stty */ + return (0); +} #ifdef notyet @@ -1129,22 +1163,21 @@ tty_stty(el, argc, argv) * DEbugging routine to print the tty characters */ private void -tty_printchar(el, s) - EditLine *el; - unsigned char *s; +tty_printchar(EditLine *el, unsigned char *s) { - ttyperm_t *m; - int i; - - for (i = 0; i < C_NCC; i++) { - for (m = el->el_tty.t_t; m->m_name; m++) - if (m->m_type == M_CHAR && C_SH(i) == m->m_value) - break; - if (m->m_name) - (void) fprintf(el->el_errfile, "%s ^%c ", m->m_name, s[i] + 'A'-1); - if (i % 5 == 0) - (void) fprintf(el->el_errfile, "\n"); - } - (void) fprintf(el->el_errfile, "\n"); + ttyperm_t *m; + int i; + + for (i = 0; i < C_NCC; i++) { + for (m = el->el_tty.t_t; m->m_name; m++) + if (m->m_type == MD_CHAR && C_SH(i) == m->m_value) + break; + if (m->m_name) + (void) fprintf(el->el_errfile, "%s ^%c ", + m->m_name, s[i] + 'A' - 1); + if (i % 5 == 0) + (void) fprintf(el->el_errfile, "\n"); + } + (void) fprintf(el->el_errfile, "\n"); } #endif /* notyet */ @@ -1,4 +1,4 @@ -/* $NetBSD: tty.h,v 1.4 1997/04/11 21:38:02 christos Exp $ */ +/* $NetBSD: tty.h,v 1.8 2000/09/04 22:06:33 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,13 +42,14 @@ * el.tty.h: Local terminal header */ #ifndef _h_el_tty -#define _h_el_tty +#define _h_el_tty #include "histedit.h" #include <termios.h> +#include <unistd.h> /* Define our own since everyone gets it wrong! */ -#define CONTROL(A) ((A) & 037) +#define CONTROL(A) ((A) & 037) /* * Aix compatible names @@ -407,66 +408,66 @@ # endif /* NUMCC */ #endif /* !POSIX */ -#define C_INTR 0 -#define C_QUIT 1 -#define C_ERASE 2 -#define C_KILL 3 -#define C_EOF 4 -#define C_EOL 5 -#define C_EOL2 6 -#define C_SWTCH 7 -#define C_DSWTCH 8 -#define C_ERASE2 9 -#define C_START 10 -#define C_STOP 11 -#define C_WERASE 12 -#define C_SUSP 13 -#define C_DSUSP 14 -#define C_REPRINT 15 -#define C_DISCARD 16 -#define C_LNEXT 17 -#define C_STATUS 18 -#define C_PAGE 19 -#define C_PGOFF 20 -#define C_KILL2 21 -#define C_BRK 22 -#define C_MIN 23 -#define C_TIME 24 -#define C_NCC 25 -#define C_SH(A) (1 << (A)) +#define C_INTR 0 +#define C_QUIT 1 +#define C_ERASE 2 +#define C_KILL 3 +#define C_EOF 4 +#define C_EOL 5 +#define C_EOL2 6 +#define C_SWTCH 7 +#define C_DSWTCH 8 +#define C_ERASE2 9 +#define C_START 10 +#define C_STOP 11 +#define C_WERASE 12 +#define C_SUSP 13 +#define C_DSUSP 14 +#define C_REPRINT 15 +#define C_DISCARD 16 +#define C_LNEXT 17 +#define C_STATUS 18 +#define C_PAGE 19 +#define C_PGOFF 20 +#define C_KILL2 21 +#define C_BRK 22 +#define C_MIN 23 +#define C_TIME 24 +#define C_NCC 25 +#define C_SH(A) (1 << (A)) /* * Terminal dependend data structures */ -#define EX_IO 0 /* while we are executing */ -#define ED_IO 1 /* while we are editing */ -#define TS_IO 2 /* new mode from terminal */ -#define QU_IO 2 /* used only for quoted chars */ -#define NN_IO 3 /* The number of entries */ - -#define M_INP 0 -#define M_OUT 1 -#define M_CTL 2 -#define M_LIN 3 -#define M_CHAR 4 -#define M_NN 5 - -typedef struct { - char *t_name; - u_int t_setmask; - u_int t_clrmask; -} ttyperm_t[NN_IO][M_NN]; +#define EX_IO 0 /* while we are executing */ +#define ED_IO 1 /* while we are editing */ +#define TS_IO 2 /* new mode from terminal */ +#define QU_IO 2 /* used only for quoted chars */ +#define NN_IO 3 /* The number of entries */ + +#define MD_INP 0 +#define MD_OUT 1 +#define MD_CTL 2 +#define MD_LIN 3 +#define MD_CHAR 4 +#define MD_NN 5 + +typedef struct { + char *t_name; + u_int t_setmask; + u_int t_clrmask; +} ttyperm_t[NN_IO][MD_NN]; typedef unsigned char ttychar_t[NN_IO][C_NCC]; -protected int tty_init __P((EditLine *)); -protected void tty_end __P((EditLine *)); -protected int tty_stty __P((EditLine *, int, char**)); -protected int tty_rawmode __P((EditLine *)); -protected int tty_cookedmode __P((EditLine *)); -protected int tty_quotemode __P((EditLine *)); -protected int tty_noquotemode __P((EditLine *)); -protected void tty_bind_char __P((EditLine *, int)); +protected int tty_init(EditLine *); +protected void tty_end(EditLine *); +protected int tty_stty(EditLine *, int, char**); +protected int tty_rawmode(EditLine *); +protected int tty_cookedmode(EditLine *); +protected int tty_quotemode(EditLine *); +protected int tty_noquotemode(EditLine *); +protected void tty_bind_char(EditLine *, int); typedef struct { ttyperm_t t_t; @@ -1,4 +1,4 @@ -/* $NetBSD: vi.c,v 1.2 1997/01/11 06:48:19 lukem Exp $ */ +/* $NetBSD: vi.c,v 1.8 2000/09/04 22:06:33 lukem Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,11 +36,12 @@ * SUCH DAMAGE. */ +#include <sys/cdefs.h> #if !defined(lint) && !defined(SCCSID) #if 0 static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; #else -static char rcsid[] = "$NetBSD: vi.c,v 1.2 1997/01/11 06:48:19 lukem Exp $"; +__RCSID("$NetBSD: vi.c,v 1.8 2000/09/04 22:06:33 lukem Exp $"); #endif #endif /* not lint && not SCCSID */ @@ -50,58 +51,56 @@ static char rcsid[] = "$NetBSD: vi.c,v 1.2 1997/01/11 06:48:19 lukem Exp $"; #include "sys.h" #include "el.h" -private el_action_t cv_action __P((EditLine *, int)); +private el_action_t cv_action(EditLine *, int); +private el_action_t cv_paste(EditLine *, int); /* cv_action(): * Handle vi actions. */ private el_action_t -cv_action(el, c) - EditLine *el; - int c; +cv_action(EditLine *el, int c) { - register char *cp, *kp; + char *cp, *kp; - if (el->el_chared.c_vcmd.action & DELETE) { - el->el_chared.c_vcmd.action = NOP; - el->el_chared.c_vcmd.pos = 0; - - el->el_chared.c_undo.isize = 0; - el->el_chared.c_undo.dsize = 0; - kp = el->el_chared.c_undo.buf; - for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) { - *kp++ = *cp; - el->el_chared.c_undo.dsize++; + if (el->el_chared.c_vcmd.action & DELETE) { + el->el_chared.c_vcmd.action = NOP; + el->el_chared.c_vcmd.pos = 0; + + el->el_chared.c_undo.isize = 0; + el->el_chared.c_undo.dsize = 0; + kp = el->el_chared.c_undo.buf; + for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) { + *kp++ = *cp; + el->el_chared.c_undo.dsize++; + } + + el->el_chared.c_undo.action = INSERT; + el->el_chared.c_undo.ptr = el->el_line.buffer; + el->el_line.lastchar = el->el_line.buffer; + el->el_line.cursor = el->el_line.buffer; + if (c & INSERT) + el->el_map.current = el->el_map.key; + + return (CC_REFRESH); } - - el->el_chared.c_undo.action = INSERT; - el->el_chared.c_undo.ptr = el->el_line.buffer; - el->el_line.lastchar = el->el_line.buffer; - el->el_line.cursor = el->el_line.buffer; - if (c & INSERT) - el->el_map.current = el->el_map.key; - - return CC_REFRESH; - } - - el->el_chared.c_vcmd.pos = el->el_line.cursor; - el->el_chared.c_vcmd.action = c; - return CC_ARGHACK; - -#ifdef notdef - /* - * I don't think that this is needed. But we keep it for now - */ - else if (el_chared.c_vcmd.action == NOP) { el->el_chared.c_vcmd.pos = el->el_line.cursor; el->el_chared.c_vcmd.action = c; - return CC_ARGHACK; - } - else { - el->el_chared.c_vcmd.action = 0; - el->el_chared.c_vcmd.pos = 0; - return CC_ERROR; - } + return (CC_ARGHACK); + +#ifdef notdef + /* + * I don't think that this is needed. But we keep it for now + */ + else + if (el_chared.c_vcmd.action == NOP) { + el->el_chared.c_vcmd.pos = el->el_line.cursor; + el->el_chared.c_vcmd.action = c; + return (CC_ARGHACK); + } else { + el->el_chared.c_vcmd.action = 0; + el->el_chared.c_vcmd.pos = 0; + return (CC_ERROR); + } #endif } @@ -109,318 +108,299 @@ cv_action(el, c) /* cv_paste(): * Paste previous deletion before or after the cursor */ -protected el_action_t -cv_paste(el, c) - EditLine *el; - int c; +private el_action_t +cv_paste(EditLine *el, int c) { - char *ptr; - c_undo_t *un = &el->el_chared.c_undo; + char *ptr; + c_undo_t *un = &el->el_chared.c_undo; + #ifdef DEBUG_PASTE - (void) fprintf(el->el_errfile, "Paste: %x \"%s\" +%d -%d\n", - un->action, un->buf, un->isize, un->dsize); + (void) fprintf(el->el_errfile, "Paste: %x \"%s\" +%d -%d\n", + un->action, un->buf, un->isize, un->dsize); #endif - if (un->isize == 0) - return CC_ERROR; + if (un->isize == 0) + return (CC_ERROR); - if (!c && el->el_line.cursor < el->el_line.lastchar) - el->el_line.cursor++; - ptr = el->el_line.cursor; - - c_insert(el, un->isize); - if (el->el_line.cursor + un->isize > el->el_line.lastchar) - return CC_ERROR; - (void) memcpy(ptr, un->buf, un->isize); - return CC_REFRESH; + if (!c && el->el_line.cursor < el->el_line.lastchar) + el->el_line.cursor++; + ptr = el->el_line.cursor; + + c_insert(el, (int) un->isize); + if (el->el_line.cursor + un->isize > el->el_line.lastchar) + return (CC_ERROR); + (void) memcpy(ptr, un->buf, un->isize); + return (CC_REFRESH); } -/* vi_paste_next(): +/* vi_paste_next(): * Vi paste previous deletion to the right of the cursor * [p] */ protected el_action_t /*ARGSUSED*/ -vi_paste_next(el, c) - EditLine *el; - int c; +vi_paste_next(EditLine *el, int c) { - return cv_paste(el, 0); + + return (cv_paste(el, 0)); } -/* vi_paste_prev(): +/* vi_paste_prev(): * Vi paste previous deletion to the left of the cursor * [P] */ protected el_action_t /*ARGSUSED*/ -vi_paste_prev(el, c) - EditLine *el; - int c; +vi_paste_prev(EditLine *el, int c) { - return cv_paste(el, 1); + + return (cv_paste(el, 1)); } -/* vi_prev_space_word(): +/* vi_prev_space_word(): * Vi move to the previous space delimited word * [B] */ protected el_action_t /*ARGSUSED*/ -vi_prev_space_word(el, c) - EditLine *el; - int c; +vi_prev_space_word(EditLine *el, int c) { - if (el->el_line.cursor == el->el_line.buffer) - return CC_ERROR; - el->el_line.cursor = cv_prev_word(el, el->el_line.cursor, - el->el_line.buffer, - el->el_state.argument, - cv__isword); + if (el->el_line.cursor == el->el_line.buffer) + return (CC_ERROR); - if (el->el_chared.c_vcmd.action & DELETE) { - cv_delfini(el); - return CC_REFRESH; - } + el->el_line.cursor = cv_prev_word(el, el->el_line.cursor, + el->el_line.buffer, + el->el_state.argument, + cv__isword); - return CC_CURSOR; + if (el->el_chared.c_vcmd.action & DELETE) { + cv_delfini(el); + return (CC_REFRESH); + } + return (CC_CURSOR); } -/* vi_prev_word(): +/* vi_prev_word(): * Vi move to the previous word * [B] */ protected el_action_t /*ARGSUSED*/ -vi_prev_word(el, c) - EditLine *el; - int c; +vi_prev_word(EditLine *el, int c) { - if (el->el_line.cursor == el->el_line.buffer) - return CC_ERROR; - el->el_line.cursor = cv_prev_word(el, el->el_line.cursor, - el->el_line.buffer, - el->el_state.argument, - ce__isword); + if (el->el_line.cursor == el->el_line.buffer) + return (CC_ERROR); - if (el->el_chared.c_vcmd.action & DELETE) { - cv_delfini(el); - return CC_REFRESH; - } + el->el_line.cursor = cv_prev_word(el, el->el_line.cursor, + el->el_line.buffer, + el->el_state.argument, + ce__isword); - return CC_CURSOR; + if (el->el_chared.c_vcmd.action & DELETE) { + cv_delfini(el); + return (CC_REFRESH); + } + return (CC_CURSOR); } -/* vi_next_space_word(): +/* vi_next_space_word(): * Vi move to the next space delimited word * [W] */ protected el_action_t /*ARGSUSED*/ -vi_next_space_word(el, c) - EditLine *el; - int c; +vi_next_space_word(EditLine *el, int c) { - if (el->el_line.cursor == el->el_line.lastchar) - return CC_ERROR; - el->el_line.cursor = cv_next_word(el, el->el_line.cursor, - el->el_line.lastchar, - el->el_state.argument, - cv__isword); + if (el->el_line.cursor == el->el_line.lastchar) + return (CC_ERROR); - if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action & DELETE) { - cv_delfini(el); - return CC_REFRESH; - } + el->el_line.cursor = cv_next_word(el, el->el_line.cursor, + el->el_line.lastchar, + el->el_state.argument, + cv__isword); - return CC_CURSOR; + if (el->el_map.type == MAP_VI) + if (el->el_chared.c_vcmd.action & DELETE) { + cv_delfini(el); + return (CC_REFRESH); + } + return (CC_CURSOR); } -/* vi_next_word(): + +/* vi_next_word(): * Vi move to the next word * [w] */ protected el_action_t /*ARGSUSED*/ -vi_next_word(el, c) - EditLine *el; - int c; +vi_next_word(EditLine *el, int c) { - if (el->el_line.cursor == el->el_line.lastchar) - return CC_ERROR; - el->el_line.cursor = cv_next_word(el, el->el_line.cursor, - el->el_line.lastchar, - el->el_state.argument, - ce__isword); + if (el->el_line.cursor == el->el_line.lastchar) + return (CC_ERROR); - if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action & DELETE) { - cv_delfini(el); - return CC_REFRESH; - } + el->el_line.cursor = cv_next_word(el, el->el_line.cursor, + el->el_line.lastchar, + el->el_state.argument, + ce__isword); - return CC_CURSOR; + if (el->el_map.type == MAP_VI) + if (el->el_chared.c_vcmd.action & DELETE) { + cv_delfini(el); + return (CC_REFRESH); + } + return (CC_CURSOR); } - -/* vi_change_case(): +/* vi_change_case(): * Vi change case of character under the cursor and advance one character * [~] */ protected el_action_t -vi_change_case(el, c) - EditLine *el; - int c; +vi_change_case(EditLine *el, int c) { - if (el->el_line.cursor < el->el_line.lastchar) { - c = *el->el_line.cursor; - if (isupper(c)) - *el->el_line.cursor++ = tolower(c); - else if (islower(c)) - *el->el_line.cursor++ = toupper(c); - else - el->el_line.cursor++; - re_fastaddc(el); - return CC_NORM; - } - return CC_ERROR; + + if (el->el_line.cursor < el->el_line.lastchar) { + c = *el->el_line.cursor; + if (isupper(c)) + *el->el_line.cursor++ = tolower(c); + else if (islower(c)) + *el->el_line.cursor++ = toupper(c); + else + el->el_line.cursor++; + re_fastaddc(el); + return (CC_NORM); + } + return (CC_ERROR); } -/* vi_change_meta(): +/* vi_change_meta(): * Vi change prefix command * [c] */ protected el_action_t /*ARGSUSED*/ -vi_change_meta(el, c) - EditLine *el; - int c; +vi_change_meta(EditLine *el, int c) { - /* - * Delete with insert == change: first we delete and then we leave in - * insert mode. - */ - return cv_action(el, DELETE|INSERT); + + /* + * Delete with insert == change: first we delete and then we leave in + * insert mode. + */ + return (cv_action(el, DELETE | INSERT)); } -/* vi_insert_at_bol(): +/* vi_insert_at_bol(): * Vi enter insert mode at the beginning of line * [I] */ protected el_action_t /*ARGSUSED*/ -vi_insert_at_bol(el, c) - EditLine *el; - int c; +vi_insert_at_bol(EditLine *el, int c) { - el->el_line.cursor = el->el_line.buffer; - el->el_chared.c_vcmd.ins = el->el_line.cursor; - el->el_chared.c_undo.ptr = el->el_line.cursor; - el->el_chared.c_undo.action = DELETE; + el->el_line.cursor = el->el_line.buffer; + el->el_chared.c_vcmd.ins = el->el_line.cursor; - el->el_map.current = el->el_map.key; - return CC_CURSOR; + el->el_chared.c_undo.ptr = el->el_line.cursor; + el->el_chared.c_undo.action = DELETE; + + el->el_map.current = el->el_map.key; + return (CC_CURSOR); } -/* vi_replace_char(): +/* vi_replace_char(): * Vi replace character under the cursor with the next character typed * [r] */ protected el_action_t /*ARGSUSED*/ -vi_replace_char(el, c) - EditLine *el; - int c; +vi_replace_char(EditLine *el, int c) { - el->el_map.current = el->el_map.key; - el->el_state.inputmode = MODE_REPLACE_1; - el->el_chared.c_undo.action = CHANGE; - el->el_chared.c_undo.ptr = el->el_line.cursor; - el->el_chared.c_undo.isize = 0; - el->el_chared.c_undo.dsize = 0; - return CC_NORM; + + el->el_map.current = el->el_map.key; + el->el_state.inputmode = MODE_REPLACE_1; + el->el_chared.c_undo.action = CHANGE; + el->el_chared.c_undo.ptr = el->el_line.cursor; + el->el_chared.c_undo.isize = 0; + el->el_chared.c_undo.dsize = 0; + return (CC_NORM); } -/* vi_replace_mode(): +/* vi_replace_mode(): * Vi enter replace mode * [R] */ protected el_action_t /*ARGSUSED*/ -vi_replace_mode(el, c) - EditLine *el; - int c; +vi_replace_mode(EditLine *el, int c) { - el->el_map.current = el->el_map.key; - el->el_state.inputmode = MODE_REPLACE; - el->el_chared.c_undo.action = CHANGE; - el->el_chared.c_undo.ptr = el->el_line.cursor; - el->el_chared.c_undo.isize = 0; - el->el_chared.c_undo.dsize = 0; - return CC_NORM; + + el->el_map.current = el->el_map.key; + el->el_state.inputmode = MODE_REPLACE; + el->el_chared.c_undo.action = CHANGE; + el->el_chared.c_undo.ptr = el->el_line.cursor; + el->el_chared.c_undo.isize = 0; + el->el_chared.c_undo.dsize = 0; + return (CC_NORM); } -/* vi_substitute_char(): +/* vi_substitute_char(): * Vi replace character under the cursor and enter insert mode * [r] */ protected el_action_t /*ARGSUSED*/ -vi_substitute_char(el, c) - EditLine *el; - int c; +vi_substitute_char(EditLine *el, int c) { - c_delafter(el, el->el_state.argument); - el->el_map.current = el->el_map.key; - return CC_REFRESH; + + c_delafter(el, el->el_state.argument); + el->el_map.current = el->el_map.key; + return (CC_REFRESH); } -/* vi_substitute_line(): +/* vi_substitute_line(): * Vi substitute entire line * [S] */ protected el_action_t /*ARGSUSED*/ -vi_substitute_line(el, c) - EditLine *el; - int c; +vi_substitute_line(EditLine *el, int c) { - (void) em_kill_line(el, 0); - el->el_map.current = el->el_map.key; - return CC_REFRESH; + + (void) em_kill_line(el, 0); + el->el_map.current = el->el_map.key; + return (CC_REFRESH); } -/* vi_change_to_eol(): +/* vi_change_to_eol(): * Vi change to end of line * [C] */ protected el_action_t /*ARGSUSED*/ -vi_change_to_eol(el, c) - EditLine *el; - int c; +vi_change_to_eol(EditLine *el, int c) { - (void) ed_kill_line(el, 0); - el->el_map.current = el->el_map.key; - return CC_REFRESH; + + (void) ed_kill_line(el, 0); + el->el_map.current = el->el_map.key; + return (CC_REFRESH); } @@ -430,46 +410,43 @@ vi_change_to_eol(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_insert(el, c) - EditLine *el; - int c; +vi_insert(EditLine *el, int c) { - el->el_map.current = el->el_map.key; - el->el_chared.c_vcmd.ins = el->el_line.cursor; - el->el_chared.c_undo.ptr = el->el_line.cursor; - el->el_chared.c_undo.action = DELETE; + el->el_map.current = el->el_map.key; + + el->el_chared.c_vcmd.ins = el->el_line.cursor; + el->el_chared.c_undo.ptr = el->el_line.cursor; + el->el_chared.c_undo.action = DELETE; - return CC_NORM; + return (CC_NORM); } /* vi_add(): - * Vi enter insert mode after the cursor + * Vi enter insert mode after the cursor * [a] */ protected el_action_t /*ARGSUSED*/ -vi_add(el, c) - EditLine *el; - int c; +vi_add(EditLine *el, int c) { - int ret; - el->el_map.current = el->el_map.key; - if (el->el_line.cursor < el->el_line.lastchar) { - el->el_line.cursor++; - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; - ret = CC_CURSOR; - } - else - ret = CC_NORM; + int ret; - el->el_chared.c_vcmd.ins = el->el_line.cursor; - el->el_chared.c_undo.ptr = el->el_line.cursor; - el->el_chared.c_undo.action = DELETE; + el->el_map.current = el->el_map.key; + if (el->el_line.cursor < el->el_line.lastchar) { + el->el_line.cursor++; + if (el->el_line.cursor > el->el_line.lastchar) + el->el_line.cursor = el->el_line.lastchar; + ret = CC_CURSOR; + } else + ret = CC_NORM; - return ret; + el->el_chared.c_vcmd.ins = el->el_line.cursor; + el->el_chared.c_undo.ptr = el->el_line.cursor; + el->el_chared.c_undo.action = DELETE; + + return (ret); } @@ -479,58 +456,54 @@ vi_add(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_add_at_eol(el, c) - EditLine *el; - int c; +vi_add_at_eol(EditLine *el, int c) { - el->el_map.current = el->el_map.key; - el->el_line.cursor = el->el_line.lastchar; - /* Mark where insertion begins */ - el->el_chared.c_vcmd.ins = el->el_line.lastchar; - el->el_chared.c_undo.ptr = el->el_line.lastchar; - el->el_chared.c_undo.action = DELETE; - return CC_CURSOR; + el->el_map.current = el->el_map.key; + el->el_line.cursor = el->el_line.lastchar; + + /* Mark where insertion begins */ + el->el_chared.c_vcmd.ins = el->el_line.lastchar; + el->el_chared.c_undo.ptr = el->el_line.lastchar; + el->el_chared.c_undo.action = DELETE; + return (CC_CURSOR); } /* vi_delete_meta(): - * Vi delete prefix command + * Vi delete prefix command * [d] */ protected el_action_t /*ARGSUSED*/ -vi_delete_meta(el, c) - EditLine *el; - int c; +vi_delete_meta(EditLine *el, int c) { - return cv_action(el, DELETE); + + return (cv_action(el, DELETE)); } /* vi_end_word(): - * Vi move to the end of the current space delimited word - * [E] + * Vi move to the end of the current space delimited word + * [E] */ protected el_action_t /*ARGSUSED*/ -vi_end_word(el, c) - EditLine *el; - int c; +vi_end_word(EditLine *el, int c) { - if (el->el_line.cursor == el->el_line.lastchar) - return CC_ERROR; - el->el_line.cursor = cv__endword(el->el_line.cursor, el->el_line.lastchar, - el->el_state.argument); + if (el->el_line.cursor == el->el_line.lastchar) + return (CC_ERROR); - if (el->el_chared.c_vcmd.action & DELETE) { - el->el_line.cursor++; - cv_delfini(el); - return CC_REFRESH; - } + el->el_line.cursor = cv__endword(el->el_line.cursor, + el->el_line.lastchar, el->el_state.argument); - return CC_CURSOR; + if (el->el_chared.c_vcmd.action & DELETE) { + el->el_line.cursor++; + cv_delfini(el); + return (CC_REFRESH); + } + return (CC_CURSOR); } @@ -540,23 +513,21 @@ vi_end_word(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_to_end_word(el, c) - EditLine *el; - int c; +vi_to_end_word(EditLine *el, int c) { - if (el->el_line.cursor == el->el_line.lastchar) - return CC_ERROR; - el->el_line.cursor = cv__endword(el->el_line.cursor, el->el_line.lastchar, - el->el_state.argument); + if (el->el_line.cursor == el->el_line.lastchar) + return (CC_ERROR); - if (el->el_chared.c_vcmd.action & DELETE) { - el->el_line.cursor++; - cv_delfini(el); - return CC_REFRESH; - } + el->el_line.cursor = cv__endword(el->el_line.cursor, + el->el_line.lastchar, el->el_state.argument); - return CC_CURSOR; + if (el->el_chared.c_vcmd.action & DELETE) { + el->el_line.cursor++; + cv_delfini(el); + return (CC_REFRESH); + } + return (CC_CURSOR); } @@ -566,107 +537,104 @@ vi_to_end_word(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_undo(el, c) - EditLine *el; - int c; +vi_undo(EditLine *el, int c) { - char *cp, *kp; - char temp; - int i, size; - c_undo_t *un = &el->el_chared.c_undo; + char *cp, *kp; + char temp; + int i, size; + c_undo_t *un = &el->el_chared.c_undo; #ifdef DEBUG_UNDO - (void) fprintf(el->el_errfile, "Undo: %x \"%s\" +%d -%d\n", - un->action, un->buf, un->isize, un->dsize); + (void) fprintf(el->el_errfile, "Undo: %x \"%s\" +%d -%d\n", + un->action, un->buf, un->isize, un->dsize); #endif - switch (un->action) { - case DELETE: - if (un->dsize == 0) - return CC_NORM; - - (void) memcpy(un->buf, un->ptr, un->dsize); - for (cp = un->ptr; cp <= el->el_line.lastchar; cp++) - *cp = cp[un->dsize]; - - el->el_line.lastchar -= un->dsize; - el->el_line.cursor = un->ptr; - - un->action = INSERT; - un->isize = un->dsize; - un->dsize = 0; - break; - - case DELETE|INSERT: - size = un->isize - un->dsize; - if (size > 0) - i = un->dsize; - else - i = un->isize; - cp = un->ptr; - kp = un->buf; - while (i-- > 0) { - temp = *kp; - *kp++ = *cp; - *cp++ = temp; - } - if (size > 0) { - el->el_line.cursor = cp; - c_insert(el, size); - while (size-- > 0 && cp < el->el_line.lastchar) { - temp = *kp; - *kp++ = *cp; - *cp++ = temp; - } - } - else if (size < 0) { - size = -size; - for (; cp <= el->el_line.lastchar; cp++) { - *kp++ = *cp; - *cp = cp[size]; - } - el->el_line.lastchar -= size; - } - el->el_line.cursor = un->ptr; - i = un->dsize; - un->dsize = un->isize; - un->isize = i; - break; - - case INSERT: - if (un->isize == 0) - return CC_NORM; - - el->el_line.cursor = un->ptr; - c_insert(el, un->isize); - memcpy(un->ptr, un->buf, un->isize); - un->action = DELETE; - un->dsize = un->isize; - un->isize = 0; - break; - - case CHANGE: - if (un->isize == 0) - return CC_NORM; - - el->el_line.cursor = un->ptr; - size = (int) (el->el_line.cursor - el->el_line.lastchar); - if (size < un->isize) - size = un->isize; - cp = un->ptr; - kp = un->buf; - for(i = 0; i < size; i++) { - temp = *kp; - *kp++ = *cp; - *cp++ = temp; + switch (un->action) { + case DELETE: + if (un->dsize == 0) + return (CC_NORM); + + (void) memcpy(un->buf, un->ptr, un->dsize); + for (cp = un->ptr; cp <= el->el_line.lastchar; cp++) + *cp = cp[un->dsize]; + + el->el_line.lastchar -= un->dsize; + el->el_line.cursor = un->ptr; + + un->action = INSERT; + un->isize = un->dsize; + un->dsize = 0; + break; + + case DELETE | INSERT: + size = un->isize - un->dsize; + if (size > 0) + i = un->dsize; + else + i = un->isize; + cp = un->ptr; + kp = un->buf; + while (i-- > 0) { + temp = *kp; + *kp++ = *cp; + *cp++ = temp; + } + if (size > 0) { + el->el_line.cursor = cp; + c_insert(el, size); + while (size-- > 0 && cp < el->el_line.lastchar) { + temp = *kp; + *kp++ = *cp; + *cp++ = temp; + } + } else if (size < 0) { + size = -size; + for (; cp <= el->el_line.lastchar; cp++) { + *kp++ = *cp; + *cp = cp[size]; + } + el->el_line.lastchar -= size; + } + el->el_line.cursor = un->ptr; + i = un->dsize; + un->dsize = un->isize; + un->isize = i; + break; + + case INSERT: + if (un->isize == 0) + return (CC_NORM); + + el->el_line.cursor = un->ptr; + c_insert(el, (int) un->isize); + (void) memcpy(un->ptr, un->buf, un->isize); + un->action = DELETE; + un->dsize = un->isize; + un->isize = 0; + break; + + case CHANGE: + if (un->isize == 0) + return (CC_NORM); + + el->el_line.cursor = un->ptr; + size = (int) (el->el_line.cursor - el->el_line.lastchar); + if (size < un->isize) + size = un->isize; + cp = un->ptr; + kp = un->buf; + for (i = 0; i < size; i++) { + temp = *kp; + *kp++ = *cp; + *cp++ = temp; + } + un->dsize = 0; + break; + + default: + return (CC_ERROR); } - un->dsize = 0; - break; - default: - return CC_ERROR; - } - - return CC_REFRESH; + return (CC_REFRESH); } @@ -676,84 +644,81 @@ vi_undo(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_command_mode(el, c) - EditLine *el; - int c; +vi_command_mode(EditLine *el, int c) { - int size; - /* [Esc] cancels pending action */ - el->el_chared.c_vcmd.ins = 0; - el->el_chared.c_vcmd.action = NOP; - el->el_chared.c_vcmd.pos = 0; + int size; - el->el_state.doingarg = 0; - size = el->el_chared.c_undo.ptr - el->el_line.cursor; - if (size < 0) - size = -size; - if (el->el_chared.c_undo.action == (INSERT|DELETE) || - el->el_chared.c_undo.action == DELETE) - el->el_chared.c_undo.dsize = size; - else - el->el_chared.c_undo.isize = size; + /* [Esc] cancels pending action */ + el->el_chared.c_vcmd.ins = 0; + el->el_chared.c_vcmd.action = NOP; + el->el_chared.c_vcmd.pos = 0; + + el->el_state.doingarg = 0; + size = el->el_chared.c_undo.ptr - el->el_line.cursor; + if (size < 0) + size = -size; + if (el->el_chared.c_undo.action == (INSERT | DELETE) || + el->el_chared.c_undo.action == DELETE) + el->el_chared.c_undo.dsize = size; + else + el->el_chared.c_undo.isize = size; - el->el_state.inputmode = MODE_INSERT; - el->el_map.current = el->el_map.alt; + el->el_state.inputmode = MODE_INSERT; + el->el_map.current = el->el_map.alt; #ifdef VI_MOVE - if (el->el_line.cursor > el->el_line.buffer) - el->el_line.cursor--; + if (el->el_line.cursor > el->el_line.buffer) + el->el_line.cursor--; #endif - return CC_CURSOR; + return (CC_CURSOR); } + /* vi_zero(): - * Vi move to the beginning of line + * Vi move to the beginning of line * [0] */ protected el_action_t -vi_zero(el, c) - EditLine *el; - int c; +vi_zero(EditLine *el, int c) { - if (el->el_state.doingarg) { - if (el->el_state.argument > 1000000) - return CC_ERROR; - el->el_state.argument = - (el->el_state.argument * 10) + (c - '0'); - return CC_ARGHACK; - } - else { - el->el_line.cursor = el->el_line.buffer; - if (el->el_chared.c_vcmd.action & DELETE) { - cv_delfini(el); - return CC_REFRESH; - } - return CC_CURSOR; - } + + if (el->el_state.doingarg) { + if (el->el_state.argument > 1000000) + return (CC_ERROR); + el->el_state.argument = + (el->el_state.argument * 10) + (c - '0'); + return (CC_ARGHACK); + } else { + el->el_line.cursor = el->el_line.buffer; + if (el->el_chared.c_vcmd.action & DELETE) { + cv_delfini(el); + return (CC_REFRESH); + } + return (CC_CURSOR); + } } /* vi_delete_prev_char(): - * Vi move to previous character (backspace) + * Vi move to previous character (backspace) * [^H] - */ + */ protected el_action_t /*ARGSUSED*/ -vi_delete_prev_char(el, c) - EditLine *el; - int c; +vi_delete_prev_char(EditLine *el, int c) { - if (el->el_chared.c_vcmd.ins == 0) - return CC_ERROR; - if (el->el_chared.c_vcmd.ins > - el->el_line.cursor - el->el_state.argument) - return CC_ERROR; + if (el->el_chared.c_vcmd.ins == 0) + return (CC_ERROR); + + if (el->el_chared.c_vcmd.ins > + el->el_line.cursor - el->el_state.argument) + return (CC_ERROR); - c_delbefore(el, el->el_state.argument); - el->el_line.cursor -= el->el_state.argument; + c_delbefore(el, el->el_state.argument); + el->el_line.cursor -= el->el_state.argument; - return CC_REFRESH; -} /* end v_del_char_prev */ + return (CC_REFRESH); +} /* vi_list_or_eof(): @@ -762,48 +727,44 @@ vi_delete_prev_char(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_list_or_eof(el, c) - EditLine *el; - int c; +vi_list_or_eof(EditLine *el, int c) { + #ifdef notyet - if (el->el_line.cursor == el->el_line.lastchar && - el->el_line.cursor == el->el_line.buffer) { + if (el->el_line.cursor == el->el_line.lastchar && + el->el_line.cursor == el->el_line.buffer) { #endif - term_overwrite(el, STReof, 4); /* then do a EOF */ - term__flush(); - return CC_EOF; + term_overwrite(el, STReof, 4); /* then do a EOF */ + term__flush(); + return (CC_EOF); #ifdef notyet - } - else { - re_goto_bottom(el); - *el->el_line.lastchar = '\0'; /* just in case */ - return CC_LIST_CHOICES; - } + } else { + re_goto_bottom(el); + *el->el_line.lastchar = '\0'; /* just in case */ + return (CC_LIST_CHOICES); + } #endif } /* vi_kill_line_prev(): - * Vi cut from beginning of line to cursor + * Vi cut from beginning of line to cursor * [^U] */ protected el_action_t /*ARGSUSED*/ -vi_kill_line_prev(el, c) - EditLine *el; - int c; +vi_kill_line_prev(EditLine *el, int c) { - char *kp, *cp; + char *kp, *cp; - cp = el->el_line.buffer; - kp = el->el_chared.c_kill.buf; - while (cp < el->el_line.cursor) - *kp++ = *cp++; /* copy it */ - el->el_chared.c_kill.last = kp; - c_delbefore(el, el->el_line.cursor - el->el_line.buffer); - el->el_line.cursor = el->el_line.buffer; /* zap! */ - return CC_REFRESH; + cp = el->el_line.buffer; + kp = el->el_chared.c_kill.buf; + while (cp < el->el_line.cursor) + *kp++ = *cp++; /* copy it */ + el->el_chared.c_kill.last = kp; + c_delbefore(el, el->el_line.cursor - el->el_line.buffer); + el->el_line.cursor = el->el_line.buffer; /* zap! */ + return (CC_REFRESH); } @@ -813,11 +774,10 @@ vi_kill_line_prev(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_search_prev(el, c) - EditLine *el; - int c; +vi_search_prev(EditLine *el, int c) { - return cv_search(el, ED_SEARCH_PREV_HISTORY); + + return (cv_search(el, ED_SEARCH_PREV_HISTORY)); } @@ -827,11 +787,10 @@ vi_search_prev(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_search_next(el, c) - EditLine *el; - int c; +vi_search_next(EditLine *el, int c) { - return cv_search(el, ED_SEARCH_NEXT_HISTORY); + + return (cv_search(el, ED_SEARCH_NEXT_HISTORY)); } @@ -841,14 +800,13 @@ vi_search_next(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_repeat_search_next(el, c) - EditLine *el; - int c; +vi_repeat_search_next(EditLine *el, int c) { - if (el->el_search.patlen == 0) - return CC_ERROR; - else - return cv_repeat_srch(el, el->el_search.patdir); + + if (el->el_search.patlen == 0) + return (CC_ERROR); + else + return (cv_repeat_srch(el, el->el_search.patdir)); } @@ -858,16 +816,15 @@ vi_repeat_search_next(el, c) */ /*ARGSUSED*/ protected el_action_t -vi_repeat_search_prev(el, c) - EditLine *el; - int c; +vi_repeat_search_prev(EditLine *el, int c) { - if (el->el_search.patlen == 0) - return CC_ERROR; - else - return cv_repeat_srch(el, - el->el_search.patdir == ED_SEARCH_PREV_HISTORY ? - ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY); + + if (el->el_search.patlen == 0) + return (CC_ERROR); + else + return (cv_repeat_srch(el, + el->el_search.patdir == ED_SEARCH_PREV_HISTORY ? + ED_SEARCH_NEXT_HISTORY : ED_SEARCH_PREV_HISTORY)); } @@ -877,19 +834,17 @@ vi_repeat_search_prev(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_next_char(el, c) - EditLine *el; - int c; +vi_next_char(EditLine *el, int c) { - char ch; + char ch; - if (el_getc(el, &ch) != 1) - return ed_end_of_file(el, 0); + if (el_getc(el, &ch) != 1) + return (ed_end_of_file(el, 0)); - el->el_search.chadir = CHAR_FWD; - el->el_search.chacha = ch; + el->el_search.chadir = CHAR_FWD; + el->el_search.chacha = ch; - return cv_csearch_fwd(el, ch, el->el_state.argument, 0); + return (cv_csearch_fwd(el, ch, el->el_state.argument, 0)); } @@ -900,19 +855,17 @@ vi_next_char(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_prev_char(el, c) - EditLine *el; - int c; +vi_prev_char(EditLine *el, int c) { - char ch; + char ch; - if (el_getc(el, &ch) != 1) - return ed_end_of_file(el, 0); + if (el_getc(el, &ch) != 1) + return (ed_end_of_file(el, 0)); - el->el_search.chadir = CHAR_BACK; - el->el_search.chacha = ch; + el->el_search.chadir = CHAR_BACK; + el->el_search.chacha = ch; - return cv_csearch_back(el, ch, el->el_state.argument, 0); + return (cv_csearch_back(el, ch, el->el_state.argument, 0)); } @@ -922,16 +875,14 @@ vi_prev_char(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_to_next_char(el, c) - EditLine *el; - int c; +vi_to_next_char(EditLine *el, int c) { - char ch; + char ch; - if (el_getc(el, &ch) != 1) - return ed_end_of_file(el, 0); + if (el_getc(el, &ch) != 1) + return (ed_end_of_file(el, 0)); - return cv_csearch_fwd(el, ch, el->el_state.argument, 1); + return (cv_csearch_fwd(el, ch, el->el_state.argument, 1)); } @@ -942,15 +893,14 @@ vi_to_next_char(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_to_prev_char(el, c) - EditLine *el; - int c; +vi_to_prev_char(EditLine *el, int c) { - char ch; - if (el_getc(el, &ch) != 1) - return ed_end_of_file(el, 0); + char ch; + + if (el_getc(el, &ch) != 1) + return (ed_end_of_file(el, 0)); - return cv_csearch_back(el, ch, el->el_state.argument, 1); + return (cv_csearch_back(el, ch, el->el_state.argument, 1)); } @@ -960,16 +910,17 @@ vi_to_prev_char(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_repeat_next_char(el, c) - EditLine *el; - int c; +vi_repeat_next_char(EditLine *el, int c) { - if (el->el_search.chacha == 0) - return CC_ERROR; - return el->el_search.chadir == CHAR_FWD ? - cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) : - cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0); + if (el->el_search.chacha == 0) + return (CC_ERROR); + + return (el->el_search.chadir == CHAR_FWD + ? cv_csearch_fwd(el, el->el_search.chacha, + el->el_state.argument, 0) + : cv_csearch_back(el, el->el_search.chacha, + el->el_state.argument, 0)); } @@ -979,14 +930,13 @@ vi_repeat_next_char(el, c) */ protected el_action_t /*ARGSUSED*/ -vi_repeat_prev_char(el, c) - EditLine *el; - int c; +vi_repeat_prev_char(EditLine *el, int c) { - if (el->el_search.chacha == 0) - return CC_ERROR; - return el->el_search.chadir == CHAR_BACK ? - cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) : - cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0); + if (el->el_search.chacha == 0) + return (CC_ERROR); + + return el->el_search.chadir == CHAR_BACK ? + cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) : + cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0); } |