Vendor import NetBSD's libedit of "2010/06/01 18:20:26 UTC".

Obtained from:	NetBSD
This commit is contained in:
David E. O'Brien 2011-03-31 18:34:50 +00:00
parent 8dfe73baa3
commit 703cb6130c
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/vendor/NetBSD/libedit/dist/; revision=220220
svn path=/vendor/NetBSD/libedit/2010-06-01/; revision=220221; tag=vendor/NetBSD/libedit/2010-06-01
49 changed files with 4015 additions and 1737 deletions

View File

@ -1,15 +1,16 @@
# $NetBSD: Makefile,v 1.35 2006/08/31 20:20:38 rpaulo Exp $
# $NetBSD: Makefile,v 1.41 2010/02/03 15:34:43 roy Exp $
# @(#)Makefile 8.1 (Berkeley) 6/4/93
USE_SHLIBDIR= yes
WARNS= 3
WIDECHAR ?= yes
WARNS= 4
LIB= edit
LIBDPLIBS= termcap ${.CURDIR}/../libterm
LIBDPLIBS+= terminfo ${.CURDIR}/../libterminfo
OSRCS= chared.c common.c el.c emacs.c fcns.c filecomplete.c help.c hist.c \
key.c map.c \
OSRCS= chared.c common.c el.c emacs.c fcns.c filecomplete.c help.c \
hist.c key.c map.c chartype.c \
parse.c prompt.c read.c refresh.c search.c sig.c term.c tty.c vi.c
MAN= editline.3 editrc.5
@ -25,9 +26,16 @@ MLINKS= editline.3 el_init.3 editline.3 el_end.3 editline.3 el_reset.3 \
editline.3 tok_line.3 editline.3 tok_str.3
# For speed and debugging
#SRCS= ${OSRCS} tokenizer.c history.c readline.c
#SRCS= ${OSRCS} readline.c tokenizer.c history.c
# For protection
SRCS= editline.c tokenizer.c history.c readline.c
SRCS= editline.c readline.c tokenizer.c history.c
.if ${WIDECHAR} == "yes"
OSRCS += eln.c
SRCS += tokenizern.c historyn.c
CLEANFILES+=tokenizern.c.tmp tokenizern.c historyn.c.tmp historyn.c
CPPFLAGS+=-DWIDECHAR
.endif
LIBEDITDIR?=${.CURDIR}
@ -36,8 +44,8 @@ INCSDIR=/usr/include
CLEANFILES+=editline.c
CLEANFILES+=common.h.tmp editline.c.tmp emacs.h.tmp fcns.c.tmp fcns.h.tmp
CLEANFILES+=help.c.tmp help.h.tmp vi.h.tmp
CLEANFILES+=tc1.o tc1
CLEANFILES+=help.c.tmp help.h.tmp vi.h.tmp tc1.o tc1
CLEANFILES+=tokenizern.c.tmp tokenizern.c tokenizerw.c.tmp tokenizerw.c
CPPFLAGS+=-I. -I${LIBEDITDIR}
CPPFLAGS+=-I. -I${.CURDIR}
CPPFLAGS+=#-DDEBUG_TTY -DDEBUG_KEY -DDEBUG_READ -DDEBUG -DDEBUG_REFRESH
@ -94,11 +102,21 @@ editline.c: ${OSRCS} makelist Makefile
${HOST_SH} ${LIBEDITDIR}/makelist -e ${OSRCS:T} > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET}
tokenizern.c: makelist Makefile
${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -n tokenizer.c > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET}
historyn.c: makelist Makefile
${_MKTARGET_CREATE}
${HOST_SH} ${LIBEDITDIR}/makelist -n history.c > ${.TARGET}.tmp && \
mv ${.TARGET}.tmp ${.TARGET}
tc1.o: ${LIBEDITDIR}/TEST/tc1.c
tc1: libedit.a tc1.o
${_MKTARGET_LINK}
${CC} ${LDFLAGS} ${.ALLSRC} -o ${.TARGET} libedit.a ${LDADD} -ltermcap
${CC} ${LDFLAGS} ${.ALLSRC} -o ${.TARGET} libedit.a ${LDADD} -ltermlib
.include <bsd.lib.mk>
.include <bsd.subdir.mk>

View File

@ -1,10 +1,10 @@
# $NetBSD: Makefile,v 1.3 2006/08/31 20:20:38 rpaulo Exp $
# $NetBSD: Makefile,v 1.5 2010/02/03 15:34:43 roy Exp $
NOMAN=1
PROG=tc1
PROG=wtc1
CPPFLAGS=-I${.CURDIR}/..
LDADD+=-ledit -ltermcap
DPADD+=${LIBEDIT} ${LIBTERMCAP}
LDADD+=-ledit -ltermlib
DPADD+=${LIBEDIT} ${LIBTERMLIB}
.ifdef DEBUG
CPPFLAGS+=-DDEBUG

View File

@ -1,4 +1,4 @@
/* $NetBSD: tc1.c,v 1.1 2006/08/31 20:20:38 rpaulo Exp $ */
/* $NetBSD: tc1.c,v 1.5 2010/04/18 21:17:47 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -42,7 +42,7 @@ __COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
#if 0
static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: tc1.c,v 1.1 2006/08/31 20:20:38 rpaulo Exp $");
__RCSID("$NetBSD: tc1.c,v 1.5 2010/04/18 21:17:47 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -57,6 +57,7 @@ __RCSID("$NetBSD: tc1.c,v 1.1 2006/08/31 20:20:38 rpaulo Exp $");
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <locale.h>
#include "histedit.h"
@ -71,7 +72,7 @@ static void sig(int);
static char *
prompt(EditLine *el)
{
static char a[] = "Edit$ ";
static char a[] = "\1\033[7m\1Edit$\1\033[0m\1 ";
static char b[] = "Edit> ";
return (continuation ? b : a);
@ -91,6 +92,7 @@ complete(EditLine *el, int ch)
const char* ptr;
const LineInfo *lf = el_line(el);
int len;
int res = CC_ERROR;
/*
* Find the last word
@ -104,16 +106,16 @@ complete(EditLine *el, int ch)
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);
res = CC_ERROR;
else
return (CC_REFRESH);
res = CC_REFRESH;
break;
}
}
closedir(dd);
return (CC_ERROR);
return res;
}
int
@ -130,6 +132,7 @@ main(int argc, char *argv[])
History *hist;
HistEvent ev;
(void) setlocale(LC_CTYPE, "");
(void) signal(SIGINT, sig);
(void) signal(SIGQUIT, sig);
(void) signal(SIGHUP, sig);
@ -146,7 +149,7 @@ main(int argc, char *argv[])
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 */
el_set(el, EL_PROMPT_ESC, prompt, '\1');/* Set the prompt function */
/* Tell editline to use this history interface */
el_set(el, EL_HIST, history, hist);

269
TEST/wtc1.c Normal file
View File

@ -0,0 +1,269 @@
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <limits.h>
#include <locale.h>
#include "../histedit.h"
static int continuation;
volatile sig_atomic_t gotsig;
static wchar_t *
prompt(EditLine *el)
{
static wchar_t a[] = L"\1\033[7m\1Edit$\1\033[0m\1 ";
static wchar_t b[] = L"Edit> ";
return continuation ? b : a;
}
static void
sig(int i)
{
gotsig = i;
}
const char *
my_wcstombs(const wchar_t *wstr)
{
static struct {
char *str;
int len;
} buf;
int needed = wcstombs(0, wstr, 0) + 1;
if (needed > buf.len) {
buf.str = malloc(needed);
buf.len = needed;
}
wcstombs(buf.str, wstr, needed);
buf.str[needed - 1] = 0;
return buf.str;
}
static unsigned char
complete(EditLine *el, int ch)
{
DIR *dd = opendir(".");
struct dirent *dp;
const wchar_t *ptr;
char *buf, *bptr;
const LineInfoW *lf = el_wline(el);
int len, mblen, i;
unsigned char res;
/* Find the last word */
for (ptr = lf->cursor -1; !iswspace(*ptr) && ptr > lf->buffer; --ptr)
continue;
len = lf->cursor - ++ptr;
/* Convert last word to multibyte encoding, so we can compare to it */
wctomb(NULL, 0); /* Reset shift state */
mblen = MB_LEN_MAX * len + 1;
buf = bptr =(char *)malloc(mblen);
for (i = 0; i < len; ++i) {
/* Note: really should test for -1 return from wctomb */
bptr += wctomb(bptr, ptr[i]);
}
*bptr = 0; /* Terminate multibyte string */
mblen = bptr - buf;
/* Scan directory for matching name */
for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
if (mblen > strlen(dp->d_name))
continue;
if (strncmp(dp->d_name, buf, mblen) == 0) {
if (el_insertstr(el, &dp->d_name[mblen]) == -1)
res = CC_ERROR;
else
res = CC_REFRESH;
break;
}
}
closedir(dd);
free(buf);
return res;
}
int
main(int argc, char *argv[])
{
EditLine *el = NULL;
int numc, ncontinuation;
const wchar_t *line;
TokenizerW *tok;
HistoryW *hist;
HistEventW ev;
#ifdef DEBUG
int i;
#endif
setlocale(LC_ALL, "");
(void)signal(SIGINT, sig);
(void)signal(SIGQUIT, sig);
(void)signal(SIGHUP, sig);
(void)signal(SIGTERM, sig);
hist = history_winit(); /* Init built-in history */
history_w(hist, &ev, H_SETSIZE, 100); /* Remember 100 events */
tok = tok_winit(NULL); /* Init the tokenizer */
el = el_init(argv[0], stdin, stdout, stderr);
el_wset(el, EL_EDITOR, L"vi"); /* Default editor is vi */
el_wset(el, EL_SIGNAL, 1); /* Handle signals gracefully */
el_wset(el, EL_PROMPT_ESC, prompt, '\1'); /* Set the prompt function */
el_wset(el, EL_HIST, history_w, hist); /* FIXME - history_w? */
/* Add a user-defined function */
el_wset(el, EL_ADDFN, L"ed-complete", L"Complete argument", complete);
/* Bind <tab> to it */
el_wset(el, EL_BIND, L"^I", L"ed-complete", NULL);
/*
* Bind j, k in vi command mode to previous and next line, instead
* of previous and next history.
*/
el_wset(el, EL_BIND, L"-a", L"k", L"ed-prev-line", NULL);
el_wset(el, EL_BIND, L"-a", L"j", L"ed-next-line", NULL);
/* Source the user's defaults file. */
el_source(el, NULL);
while((line = el_wgets(el, &numc)) != NULL && numc != 0) {
int ac, cc, co, rc;
const wchar_t **av;
const LineInfoW *li;
li = el_wline(el);
#ifdef DEBUG
(void)fwprintf(stderr, L"==> got %d %ls", numc, line);
(void)fwprintf(stderr, L" > li `%.*ls_%.*ls'\n",
(li->cursor - li->buffer), li->buffer,
(li->lastchar - 1 - li->cursor),
(li->cursor >= li->lastchar) ? L"" : li->cursor);
#endif
if (gotsig) {
(void)fprintf(stderr, "Got signal %d.\n", gotsig);
gotsig = 0;
el_reset(el);
}
if(!continuation && numc == 1)
continue; /* Only got a linefeed */
ac = cc = co = 0;
ncontinuation = tok_wline(tok, li, &ac, &av, &cc, &co);
if (ncontinuation < 0) {
(void) fprintf(stderr, "Internal error\n");
continuation = 0;
continue;
}
#ifdef DEBUG
(void)fprintf(stderr, " > nc %d ac %d cc %d co %d\n",
ncontinuation, ac, cc, co);
#endif
history_w(hist, &ev, continuation ? H_APPEND : H_ENTER, line);
continuation = ncontinuation;
ncontinuation = 0;
if(continuation)
continue;
#ifdef DEBUG
for (i = 0; i < ac; ++i) {
(void)fwprintf(stderr, L" > arg# %2d ", i);
if (i != cc)
(void)fwprintf(stderr, L"`%ls'\n", av[i]);
else
(void)fwprintf(stderr, L"`%.*ls_%ls'\n",
co, av[i], av[i] + co);
}
#endif
if (wcscmp (av[0], L"history") == 0) {
switch(ac) {
case 1:
for(rc = history_w(hist, &ev, H_LAST);
rc != -1;
rc = history_w(hist, &ev, H_PREV))
(void)fwprintf(stdout, L"%4d %ls",
ev.num, ev.str);
break;
case 2:
if (wcscmp(av[1], L"clear") == 0)
history_w(hist, &ev, H_CLEAR);
else
goto badhist;
break;
case 3:
if (wcscmp(av[1], L"load") == 0)
history_w(hist, &ev, H_LOAD,
my_wcstombs(av[2]));
else if (wcscmp(av[1], L"save") == 0)
history_w(hist, &ev, H_SAVE,
my_wcstombs(av[2]));
else
goto badhist;
break;
badhist:
default:
(void)fprintf(stderr,
"Bad history arguments\n");
break;
}
} else if (el_wparse(el, ac, av) == -1) {
switch (fork()) {
case 0: {
Tokenizer *ntok = tok_init(NULL);
int nargc;
const char **nav;
tok_str(ntok, my_wcstombs(line), &nargc, &nav);
execvp(nav[0],(char **)nav);
perror(nav[0]);
_exit(1);
/* NOTREACHED */
break;
}
case -1:
perror("fork");
break;
default:
if (wait(&rc) == -1)
perror("wait");
(void)fprintf(stderr, "Exit %x\n", rc);
break;
}
}
tok_wreset(tok);
}
el_end(el);
tok_wend(tok);
history_wend(hist);
fprintf(stdout, "\n");
return 0;
}

183
chared.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: chared.c,v 1.25 2005/08/08 01:41:30 christos Exp $ */
/* $NetBSD: chared.c,v 1.28 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: chared.c,v 1.25 2005/08/08 01:41:30 christos Exp $");
__RCSID("$NetBSD: chared.c,v 1.28 2009/12/30 22:37:40 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -47,7 +47,7 @@ __RCSID("$NetBSD: chared.c,v 1.25 2005/08/08 01:41:30 christos Exp $");
#include <stdlib.h>
#include "el.h"
private void ch__clearmacro __P((EditLine *));
private void ch__clearmacro (EditLine *);
/* value to leave unused in line buffer */
#define EL_LEAVE 2
@ -60,13 +60,13 @@ cv_undo(EditLine *el)
{
c_undo_t *vu = &el->el_chared.c_undo;
c_redo_t *r = &el->el_chared.c_redo;
unsigned int size;
size_t size;
/* Save entire line for undo */
size = el->el_line.lastchar - el->el_line.buffer;
vu->len = size;
vu->cursor = el->el_line.cursor - el->el_line.buffer;
memcpy(vu->buf, el->el_line.buffer, size);
vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer);
(void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf));
/* save command info for redo */
r->count = el->el_state.doingarg ? el->el_state.argument : 0;
@ -80,11 +80,11 @@ cv_undo(EditLine *el)
* Save yank/delete data for paste
*/
protected void
cv_yank(EditLine *el, const char *ptr, int size)
cv_yank(EditLine *el, const Char *ptr, int size)
{
c_kill_t *k = &el->el_chared.c_kill;
memcpy(k->buf, ptr, size +0u);
(void)memcpy(k->buf, ptr, size * sizeof(*k->buf));
k->last = k->buf + size;
}
@ -95,10 +95,10 @@ cv_yank(EditLine *el, const char *ptr, int size)
protected void
c_insert(EditLine *el, int num)
{
char *cp;
Char *cp;
if (el->el_line.lastchar + num >= el->el_line.limit) {
if (!ch_enlargebufs(el, num +0u))
if (!ch_enlargebufs(el, (size_t)num))
return; /* can't go past end of buffer */
}
@ -119,7 +119,7 @@ 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;
num = (int)(el->el_line.lastchar - el->el_line.cursor);
if (el->el_map.current != el->el_map.emacs) {
cv_undo(el);
@ -127,7 +127,7 @@ c_delafter(EditLine *el, int num)
}
if (num > 0) {
char *cp;
Char *cp;
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
*cp = cp[num];
@ -143,7 +143,7 @@ c_delafter(EditLine *el, int num)
protected void
c_delafter1(EditLine *el)
{
char *cp;
Char *cp;
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
*cp = cp[1];
@ -160,7 +160,7 @@ 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;
num = (int)(el->el_line.cursor - el->el_line.buffer);
if (el->el_map.current != el->el_map.emacs) {
cv_undo(el);
@ -168,7 +168,7 @@ c_delbefore(EditLine *el, int num)
}
if (num > 0) {
char *cp;
Char *cp;
for (cp = el->el_line.cursor - num;
cp <= el->el_line.lastchar;
@ -186,7 +186,7 @@ c_delbefore(EditLine *el, int num)
protected void
c_delbefore1(EditLine *el)
{
char *cp;
Char *cp;
for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
*cp = cp[1];
@ -199,9 +199,9 @@ c_delbefore1(EditLine *el)
* Return if p is part of a word according to emacs
*/
protected int
ce__isword(int p)
ce__isword(Int p)
{
return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL);
return (Isalnum(p) || Strchr(STR("*?_-.[]~="), p) != NULL);
}
@ -209,11 +209,11 @@ ce__isword(int p)
* Return if p is part of a word according to vi
*/
protected int
cv__isword(int p)
cv__isword(Int p)
{
if (isalnum(p) || p == '_')
if (Isalnum(p) || p == '_')
return 1;
if (isgraph(p))
if (Isgraph(p))
return 2;
return 0;
}
@ -223,24 +223,24 @@ cv__isword(int p)
* Return if p is part of a big word according to vi
*/
protected int
cv__isWord(int p)
cv__isWord(Int p)
{
return (!isspace(p));
return (!Isspace(p));
}
/* c__prev_word():
* Find the previous word
*/
protected char *
c__prev_word(char *p, char *low, int n, int (*wtest)(int))
protected Char *
c__prev_word(Char *p, Char *low, int n, int (*wtest)(Int))
{
p--;
while (n--) {
while ((p >= low) && !(*wtest)((unsigned char) *p))
while ((p >= low) && !(*wtest)(*p))
p--;
while ((p >= low) && (*wtest)((unsigned char) *p))
while ((p >= low) && (*wtest)(*p))
p--;
}
@ -256,13 +256,13 @@ c__prev_word(char *p, char *low, int n, int (*wtest)(int))
/* c__next_word():
* Find the next word
*/
protected char *
c__next_word(char *p, char *high, int n, int (*wtest)(int))
protected Char *
c__next_word(Char *p, Char *high, int n, int (*wtest)(Int))
{
while (n--) {
while ((p < high) && !(*wtest)((unsigned char) *p))
while ((p < high) && !(*wtest)(*p))
p++;
while ((p < high) && (*wtest)((unsigned char) *p))
while ((p < high) && (*wtest)(*p))
p++;
}
if (p > high)
@ -274,21 +274,21 @@ c__next_word(char *p, char *high, int n, int (*wtest)(int))
/* cv_next_word():
* Find the next word vi style
*/
protected char *
cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int))
protected Char *
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)
test = (*wtest)(*p);
while ((p < high) && (*wtest)(*p) == test)
p++;
/*
* vi historically deletes with cw only the word preserving the
* trailing whitespace! This is not what 'w' does..
*/
if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
while ((p < high) && isspace((unsigned char) *p))
while ((p < high) && Isspace(*p))
p++;
}
@ -303,17 +303,17 @@ cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int))
/* cv_prev_word():
* Find the previous word vi style
*/
protected char *
cv_prev_word(char *p, char *low, int n, int (*wtest)(int))
protected Char *
cv_prev_word(Char *p, Char *low, int n, int (*wtest)(Int))
{
int test;
p--;
while (n--) {
while ((p > low) && isspace((unsigned char) *p))
while ((p > low) && Isspace(*p))
p--;
test = (*wtest)((unsigned char) *p);
while ((p >= low) && (*wtest)((unsigned char) *p) == test)
test = (*wtest)(*p);
while ((p >= low) && (*wtest)(*p) == test)
p--;
}
p++;
@ -332,9 +332,9 @@ cv_prev_word(char *p, char *low, int n, int (*wtest)(int))
* A '$' by itself means a big number; "$-" is for negative; '^' means 1.
* Return p pointing to last char used.
*/
protected char *
protected Char *
c__number(
char *p, /* character position */
Char *p, /* character position */
int *num, /* Return value */
int dval) /* dval is the number to subtract from like $-3 */
{
@ -353,7 +353,8 @@ c__number(
sign = -1; /* Handle $- */
++p;
}
for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
/* XXX: this assumes ASCII compatible digits */
for (i = 0; Isdigit(*p); i = 10 * i + *p++ - '0')
continue;
*num = (sign < 0 ? dval - i : i);
return (--p);
@ -376,7 +377,7 @@ cv_delfini(EditLine *el)
/* sanity */
return;
size = el->el_line.cursor - el->el_chared.c_vcmd.pos;
size = (int)(el->el_line.cursor - el->el_chared.c_vcmd.pos);
if (size == 0)
size = 1;
el->el_line.cursor = el->el_chared.c_vcmd.pos;
@ -402,15 +403,15 @@ cv_delfini(EditLine *el)
/* ce__endword():
* Go to the end of this word according to emacs
*/
protected char *
ce__endword(char *p, char *high, int n)
protected Char *
ce__endword(Char *p, Char *high, int n)
{
p++;
while (n--) {
while ((p < high) && isspace((unsigned char) *p))
while ((p < high) && Isspace(*p))
p++;
while ((p < high) && !isspace((unsigned char) *p))
while ((p < high) && !Isspace(*p))
p++;
}
@ -423,19 +424,19 @@ ce__endword(char *p, char *high, int n)
/* cv__endword():
* Go to the end of this word according to vi
*/
protected char *
cv__endword(char *p, char *high, int n, int (*wtest)(int))
protected Char *
cv__endword(Char *p, Char *high, int n, int (*wtest)(Int))
{
int test;
p++;
while (n--) {
while ((p < high) && isspace((unsigned char) *p))
while ((p < high) && Isspace(*p))
p++;
test = (*wtest)((unsigned char) *p);
while ((p < high) && (*wtest)((unsigned char) *p) == test)
test = (*wtest)(*p);
while ((p < high) && (*wtest)(*p) == test)
p++;
}
p--;
@ -450,22 +451,27 @@ ch_init(EditLine *el)
{
c_macro_t *ma = &el->el_chared.c_macro;
el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ);
el->el_line.buffer = el_malloc(EL_BUFSIZ *
sizeof(*el->el_line.buffer));
if (el->el_line.buffer == NULL)
return (-1);
(void) memset(el->el_line.buffer, 0, EL_BUFSIZ);
(void) memset(el->el_line.buffer, 0, EL_BUFSIZ *
sizeof(*el->el_line.buffer));
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 - EL_LEAVE];
el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ);
el->el_chared.c_undo.buf = el_malloc(EL_BUFSIZ *
sizeof(*el->el_chared.c_undo.buf));
if (el->el_chared.c_undo.buf == NULL)
return (-1);
(void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ);
(void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ *
sizeof(*el->el_chared.c_undo.buf));
el->el_chared.c_undo.len = -1;
el->el_chared.c_undo.cursor = 0;
el->el_chared.c_redo.buf = (char *) el_malloc(EL_BUFSIZ);
el->el_chared.c_redo.buf = el_malloc(EL_BUFSIZ *
sizeof(*el->el_chared.c_redo.buf));
if (el->el_chared.c_redo.buf == NULL)
return (-1);
el->el_chared.c_redo.pos = el->el_chared.c_redo.buf;
@ -475,10 +481,12 @@ ch_init(EditLine *el)
el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_vcmd.pos = el->el_line.buffer;
el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ);
el->el_chared.c_kill.buf = el_malloc(EL_BUFSIZ *
sizeof(*el->el_chared.c_kill.buf));
if (el->el_chared.c_kill.buf == NULL)
return (-1);
(void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ);
(void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ *
sizeof(*el->el_chared.c_kill.buf));
el->el_chared.c_kill.mark = el->el_line.buffer;
el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
@ -492,7 +500,7 @@ ch_init(EditLine *el)
ma->level = -1;
ma->offset = 0;
ma->macro = (char **) el_malloc(EL_MAXMACRO * sizeof(char *));
ma->macro = el_malloc(EL_MAXMACRO * sizeof(*ma->macro));
if (ma->macro == NULL)
return (-1);
return (0);
@ -530,8 +538,7 @@ ch_reset(EditLine *el, int mclear)
}
private void
ch__clearmacro(el)
EditLine *el;
ch__clearmacro(EditLine *el)
{
c_macro_t *ma = &el->el_chared.c_macro;
while (ma->level >= 0)
@ -543,12 +550,10 @@ ch__clearmacro(el)
* Returns 1 if successful, 0 if not.
*/
protected int
ch_enlargebufs(el, addlen)
EditLine *el;
size_t addlen;
ch_enlargebufs(EditLine *el, size_t addlen)
{
size_t sz, newsz;
char *newbuffer, *oldbuf, *oldkbuf;
Char *newbuffer, *oldbuf, *oldkbuf;
sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE;
newsz = sz * 2;
@ -564,12 +569,12 @@ ch_enlargebufs(el, addlen)
/*
* Reallocate line buffer.
*/
newbuffer = el_realloc(el->el_line.buffer, newsz);
newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer));
if (!newbuffer)
return 0;
/* zero the newly added memory, leave old data in */
(void) memset(&newbuffer[sz], 0, newsz - sz);
(void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
oldbuf = el->el_line.buffer;
@ -582,12 +587,12 @@ ch_enlargebufs(el, addlen)
/*
* Reallocate kill buffer.
*/
newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz);
newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz * sizeof(*newbuffer));
if (!newbuffer)
return 0;
/* zero the newly added memory, leave old data in */
(void) memset(&newbuffer[sz], 0, newsz - sz);
(void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
oldkbuf = el->el_chared.c_kill.buf;
@ -600,15 +605,17 @@ ch_enlargebufs(el, addlen)
/*
* Reallocate undo buffer.
*/
newbuffer = el_realloc(el->el_chared.c_undo.buf, newsz);
newbuffer = el_realloc(el->el_chared.c_undo.buf,
newsz * sizeof(*newbuffer));
if (!newbuffer)
return 0;
/* zero the newly added memory, leave old data in */
(void) memset(&newbuffer[sz], 0, newsz - sz);
(void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
el->el_chared.c_undo.buf = newbuffer;
newbuffer = el_realloc(el->el_chared.c_redo.buf, newsz);
newbuffer = el_realloc(el->el_chared.c_redo.buf,
newsz * sizeof(*newbuffer));
if (!newbuffer)
return 0;
el->el_chared.c_redo.pos = newbuffer +
@ -653,11 +660,11 @@ ch_end(EditLine *el)
* Insert string at cursorI
*/
public int
el_insertstr(EditLine *el, const char *s)
FUN(el,insertstr)(EditLine *el, const Char *s)
{
size_t len;
if ((len = strlen(s)) == 0)
if ((len = Strlen(s)) == 0)
return (-1);
if (el->el_line.lastchar + len >= el->el_line.limit) {
if (!ch_enlargebufs(el, len))
@ -693,15 +700,15 @@ el_deletestr(EditLine *el, int n)
* Get a string
*/
protected int
c_gets(EditLine *el, char *buf, const char *prompt)
c_gets(EditLine *el, Char *buf, const Char *prompt)
{
char ch;
int len;
char *cp = el->el_line.buffer;
Char ch;
ssize_t len;
Char *cp = el->el_line.buffer;
if (prompt) {
len = strlen(prompt);
memcpy(cp, prompt, len + 0u);
len = Strlen(prompt);
(void)memcpy(cp, prompt, len * sizeof(*cp));
cp += len;
}
len = 0;
@ -712,7 +719,7 @@ c_gets(EditLine *el, char *buf, const char *prompt)
el->el_line.lastchar = cp + 1;
re_refresh(el);
if (el_getc(el, &ch) != 1) {
if (FUN(el,getc)(el, &ch) != 1) {
ed_end_of_file(el, 0);
len = -1;
break;
@ -722,7 +729,7 @@ c_gets(EditLine *el, char *buf, const char *prompt)
case 0010: /* Delete and backspace */
case 0177:
if (len <= 0) {
if (len == 0) {
len = -1;
break;
}
@ -750,7 +757,7 @@ c_gets(EditLine *el, char *buf, const char *prompt)
el->el_line.buffer[0] = '\0';
el->el_line.lastchar = el->el_line.buffer;
el->el_line.cursor = el->el_line.buffer;
return len;
return (int)len;
}
@ -760,7 +767,7 @@ c_gets(EditLine *el, char *buf, const char *prompt)
protected int
c_hpos(EditLine *el)
{
char *ptr;
Char *ptr;
/*
* Find how many characters till the beginning of this line.
@ -772,6 +779,6 @@ c_hpos(EditLine *el)
ptr >= el->el_line.buffer && *ptr != '\n';
ptr--)
continue;
return (el->el_line.cursor - ptr - 1);
return (int)(el->el_line.cursor - ptr - 1);
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: chared.h,v 1.17 2006/03/06 21:11:56 christos Exp $ */
/* $NetBSD: chared.h,v 1.20 2010/04/15 00:57:33 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -63,25 +63,25 @@
typedef struct c_macro_t {
int level;
int offset;
char **macro;
Char **macro;
} c_macro_t;
/*
* Undo information for vi - no undo in emacs (yet)
*/
typedef struct c_undo_t {
int len; /* length of saved line */
ssize_t len; /* length of saved line */
int cursor; /* position of saved cursor */
char *buf; /* full saved text */
Char *buf; /* full saved text */
} c_undo_t;
/* redo for vi */
typedef struct c_redo_t {
char *buf; /* redo insert key sequence */
char *pos;
char *lim;
Char *buf; /* redo insert key sequence */
Char *pos;
Char *lim;
el_action_t cmd; /* command to redo */
char ch; /* char that invoked it */
Char ch; /* char that invoked it */
int count;
int action; /* from cv_action() */
} c_redo_t;
@ -91,16 +91,16 @@ typedef struct c_redo_t {
*/
typedef struct c_vcmd_t {
int action;
char *pos;
Char *pos;
} 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;
/*
@ -119,7 +119,6 @@ typedef struct el_chared_t {
#define STRQQ "\"\""
#define isglob(a) (strchr("*[]?", (a)) != NULL)
#define isword(a) (isprint(a))
#define NOP 0x00
#define DELETE 0x01
@ -140,23 +139,23 @@ typedef struct el_chared_t {
#include "fcns.h"
protected int cv__isword(int);
protected int cv__isWord(int);
protected int cv__isword(Int);
protected int cv__isWord(Int);
protected void cv_delfini(EditLine *);
protected char *cv__endword(char *, char *, int, int (*)(int));
protected int ce__isword(int);
protected Char *cv__endword(Char *, Char *, int, int (*)(Int));
protected int ce__isword(Int);
protected void cv_undo(EditLine *);
protected void cv_yank(EditLine *, const char *, int);
protected char *cv_next_word(EditLine*, char *, char *, int, int (*)(int));
protected char *cv_prev_word(char *, char *, int, int (*)(int));
protected char *c__next_word(char *, char *, int, int (*)(int));
protected char *c__prev_word(char *, char *, int, int (*)(int));
protected void cv_yank(EditLine *, const Char *, int);
protected Char *cv_next_word(EditLine*, Char *, Char *, int, int (*)(Int));
protected Char *cv_prev_word(Char *, Char *, int, int (*)(Int));
protected Char *c__next_word(Char *, Char *, int, int (*)(Int));
protected Char *c__prev_word(Char *, Char *, int, int (*)(Int));
protected void c_insert(EditLine *, int);
protected void c_delbefore(EditLine *, int);
protected void c_delbefore1(EditLine *);
protected void c_delafter(EditLine *, int);
protected void c_delafter1(EditLine *);
protected int c_gets(EditLine *, char *, const char *);
protected int c_gets(EditLine *, Char *, const Char *);
protected int c_hpos(EditLine *);
protected int ch_init(EditLine *);

360
chartype.c Normal file
View File

@ -0,0 +1,360 @@
/* $NetBSD: chartype.c,v 1.4 2010/04/15 00:55:57 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* 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.
*/
/*
* chartype.c: character classification and meta information
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: chartype.c,v 1.4 2010/04/15 00:55:57 christos Exp $");
#endif /* not lint && not SCCSID */
#include "el.h"
#include <stdlib.h>
#define CT_BUFSIZ 1024
#ifdef WIDECHAR
protected void
ct_conv_buff_resize(ct_buffer_t *conv, size_t mincsize, size_t minwsize)
{
void *p;
if (mincsize > conv->csize) {
conv->csize = mincsize;
p = el_realloc(conv->cbuff, conv->csize);
if (p == NULL) {
conv->csize = 0;
el_free(conv->cbuff);
conv->cbuff = NULL;
} else
conv->cbuff = p;
}
if (minwsize > conv->wsize) {
conv->wsize = minwsize;
p = el_realloc(conv->wbuff, conv->wsize);
if (p == NULL) {
conv->wsize = 0;
el_free(conv->wbuff);
conv->wbuff = NULL;
} else
conv->wbuff = p;
}
}
public char *
ct_encode_string(const Char *s, ct_buffer_t *conv)
{
char *dst;
ssize_t used = 0;
if (!s)
return NULL;
if (!conv->cbuff)
ct_conv_buff_resize(conv, CT_BUFSIZ, 0);
if (!conv->cbuff)
return NULL;
dst = conv->cbuff;
while (*s) {
used = ct_encode_char(dst, (int)(conv->csize -
(dst - conv->cbuff)), *s);
if (used == -1) { /* failed to encode, need more buffer space */
used = dst - conv->cbuff;
ct_conv_buff_resize(conv, conv->csize + CT_BUFSIZ, 0);
if (!conv->cbuff)
return NULL;
dst = conv->cbuff + used;
/* don't increment s here - we want to retry it! */
}
else
++s;
dst += used;
}
if (dst >= (conv->cbuff + conv->csize)) {
used = dst - conv->cbuff;
ct_conv_buff_resize(conv, conv->csize + 1, 0);
if (!conv->cbuff)
return NULL;
dst = conv->cbuff + used;
}
*dst = '\0';
return conv->cbuff;
}
public Char *
ct_decode_string(const char *s, ct_buffer_t *conv)
{
size_t len = 0;
if (!s)
return NULL;
if (!conv->wbuff)
ct_conv_buff_resize(conv, 0, CT_BUFSIZ);
if (!conv->wbuff)
return NULL;
len = ct_mbstowcs(0, s, 0);
if (len > conv->wsize)
ct_conv_buff_resize(conv, 0, len + 1);
if (!conv->wbuff)
return NULL;
ct_mbstowcs(conv->wbuff, s, conv->wsize);
return conv->wbuff;
}
protected Char **
ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv)
{
size_t bufspace;
int i;
Char *p;
Char **wargv;
ssize_t bytes;
/* Make sure we have enough space in the conversion buffer to store all
* the argv strings. */
for (i = 0, bufspace = 0; i < argc; ++i)
bufspace += argv[i] ? strlen(argv[i]) + 1 : 0;
ct_conv_buff_resize(conv, 0, bufspace);
if (!conv->wsize)
return NULL;
wargv = el_malloc(argc * sizeof(*wargv));
for (i = 0, p = conv->wbuff; i < argc; ++i) {
if (!argv[i]) { /* don't pass null pointers to mbstowcs */
wargv[i] = NULL;
continue;
} else {
wargv[i] = p;
bytes = mbstowcs(p, argv[i], bufspace);
}
if (bytes == -1) {
el_free(wargv);
return NULL;
} else
bytes++; /* include '\0' in the count */
bufspace -= bytes;
p += bytes;
}
return wargv;
}
protected size_t
ct_enc_width(Char c)
{
/* UTF-8 encoding specific values */
if (c < 0x80)
return 1;
else if (c < 0x0800)
return 2;
else if (c < 0x10000)
return 3;
else if (c < 0x110000)
return 4;
else
return 0; /* not a valid codepoint */
}
protected ssize_t
ct_encode_char(char *dst, size_t len, Char c)
{
ssize_t l = 0;
if (len < ct_enc_width(c))
return -1;
l = ct_wctomb(dst, c);
if (l < 0) {
ct_wctomb_reset;
l = 0;
}
return l;
}
#endif
protected const Char *
ct_visual_string(const Char *s)
{
static Char *buff = NULL;
static size_t buffsize = 0;
void *p;
Char *dst;
ssize_t used = 0;
if (!s)
return NULL;
if (!buff) {
buffsize = CT_BUFSIZ;
buff = el_malloc(buffsize * sizeof(*buff));
}
dst = buff;
while (*s) {
used = ct_visual_char(dst, buffsize - (dst - buff), *s);
if (used == -1) { /* failed to encode, need more buffer space */
used = dst - buff;
buffsize += CT_BUFSIZ;
p = el_realloc(buff, buffsize * sizeof(*buff));
if (p == NULL)
goto out;
buff = p;
dst = buff + used;
/* don't increment s here - we want to retry it! */
}
else
++s;
dst += used;
}
if (dst >= (buff + buffsize)) { /* sigh */
buffsize += 1;
p = el_realloc(buff, buffsize * sizeof(*buff));
if (p == NULL)
goto out;
buff = p;
dst = buff + buffsize - 1;
}
*dst = 0;
return buff;
out:
el_free(buff);
buffsize = 0;
return NULL;
}
protected int
ct_visual_width(Char c)
{
int t = ct_chr_class(c);
switch (t) {
case CHTYPE_ASCIICTL:
return 2; /* ^@ ^? etc. */
case CHTYPE_TAB:
return 1; /* Hmm, this really need to be handled outside! */
case CHTYPE_NL:
return 0; /* Should this be 1 instead? */
#ifdef WIDECHAR
case CHTYPE_PRINT:
return wcwidth(c);
case CHTYPE_NONPRINT:
if (c > 0xffff) /* prefer standard 4-byte display over 5-byte */
return 8; /* \U+12345 */
else
return 7; /* \U+1234 */
#else
case CHTYPE_PRINT:
return 1;
case CHTYPE_NONPRINT:
return 4; /* \123 */
#endif
default:
return 0; /* should not happen */
}
}
protected ssize_t
ct_visual_char(Char *dst, size_t len, Char c)
{
int t = ct_chr_class(c);
switch (t) {
case CHTYPE_TAB:
case CHTYPE_NL:
case CHTYPE_ASCIICTL:
if (len < 2)
return -1; /* insufficient space */
*dst++ = '^';
if (c == '\177')
*dst = '?'; /* DEL -> ^? */
else
*dst = c | 0100; /* uncontrolify it */
return 2;
case CHTYPE_PRINT:
if (len < 1)
return -1; /* insufficient space */
*dst = c;
return 1;
case CHTYPE_NONPRINT:
/* we only use single-width glyphs for display,
* so this is right */
if ((ssize_t)len < ct_visual_width(c))
return -1; /* insufficient space */
#ifdef WIDECHAR
*dst++ = '\\';
*dst++ = 'U';
*dst++ = '+';
#define tohexdigit(v) "0123456789ABCDEF"[v]
if (c > 0xffff) /* prefer standard 4-byte display over 5-byte */
*dst++ = tohexdigit(((unsigned int) c >> 16) & 0xf);
*dst++ = tohexdigit(((unsigned int) c >> 12) & 0xf);
*dst++ = tohexdigit(((unsigned int) c >> 8) & 0xf);
*dst++ = tohexdigit(((unsigned int) c >> 4) & 0xf);
*dst = tohexdigit(((unsigned int) c ) & 0xf);
return (c > 0xffff) ? 8 : 7;
#else
*dst++ = '\\';
#define tooctaldigit(v) ((v) + '0')
*dst++ = tooctaldigit(((unsigned int) c >> 6) & 0x7);
*dst++ = tooctaldigit(((unsigned int) c >> 3) & 0x7);
*dst++ = tooctaldigit(((unsigned int) c ) & 0x7);
#endif
/*FALLTHROUGH*/
/* these two should be handled outside this function */
default: /* we should never hit the default */
return 0;
}
}
protected int
ct_chr_class(Char c)
{
if (c == '\t')
return CHTYPE_TAB;
else if (c == '\n')
return CHTYPE_NL;
else if (IsASCII(c) && Iscntrl(c))
return CHTYPE_ASCIICTL;
else if (Isprint(c))
return CHTYPE_PRINT;
else
return CHTYPE_NONPRINT;
}

245
chartype.h Normal file
View File

@ -0,0 +1,245 @@
/* $NetBSD: chartype.h,v 1.6 2010/04/20 02:01:13 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* 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 _h_chartype_f
#define _h_chartype_f
#ifdef WIDECHAR
/* Ideally we should also test the value of the define to see if it
* supports non-BMP code points without requiring UTF-16, but nothing
* seems to actually advertise this properly, despite Unicode 3.1 having
* been around since 2001... */
#if !defined(__NetBSD__) && !defined(__sun) && !(defined(__APPLE__) && defined(__MACH__))
#ifndef __STDC_ISO_10646__
/* In many places it is assumed that the first 127 code points are ASCII
* compatible, so ensure wchar_t indeed does ISO 10646 and not some other
* funky encoding that could break us in weird and wonderful ways. */
#error wchar_t must store ISO 10646 characters
#endif
#endif
/* Oh for a <uchar.h> with char32_t and __STDC_UTF_32__ in it...
* ref: ISO/IEC DTR 19769
*/
#if WCHAR_MAX < INT32_MAX
#warning Build environment does not support non-BMP characters
#endif
#define ct_mbtowc mbtowc
#define ct_mbtowc_reset mbtowc(0,0,0)
#define ct_wctomb wctomb
#define ct_wctomb_reset wctomb(0,0)
#define ct_wcstombs wcstombs
#define ct_mbstowcs mbstowcs
#define Char wchar_t
#define Int wint_t
#define FUN(prefix,rest) prefix ## _w ## rest
#define FUNW(type) type ## _w
#define TYPE(type) type ## W
#define FSTR "%ls"
#define STR(x) L ## x
#define UC(c) c
#define Isalpha(x) iswalpha(x)
#define Isalnum(x) iswalnum(x)
#define Isgraph(x) iswgraph(x)
#define Isspace(x) iswspace(x)
#define Isdigit(x) iswdigit(x)
#define Iscntrl(x) iswcntrl(x)
#define Isprint(x) iswprint(x)
#define Isupper(x) iswupper(x)
#define Islower(x) iswlower(x)
#define Toupper(x) towupper(x)
#define Tolower(x) towlower(x)
#define IsASCII(x) (x < 0x100)
#define Strlen(x) wcslen(x)
#define Strchr(s,c) wcschr(s,c)
#define Strrchr(s,c) wcsrchr(s,c)
#define Strstr(s,v) wcsstr(s,v)
#define Strdup(x) wcsdup(x)
#define Strcpy(d,s) wcscpy(d,s)
#define Strncpy(d,s,n) wcsncpy(d,s,n)
#define Strncat(d,s,n) wcsncat(d,s,n)
#define Strcmp(s,v) wcscmp(s,v)
#define Strncmp(s,v,n) wcsncmp(s,v,n)
#define Strcspn(s,r) wcscspn(s,r)
#define Strtol(p,e,b) wcstol(p,e,b)
#define Width(c) wcwidth(c)
#else /* NARROW */
#define ct_mbtowc error
#define ct_mbtowc_reset
#define ct_wctomb error
#define ct_wctomb_reset
#define ct_wcstombs(a, b, c) (strncpy(a, b, c), strlen(a))
#define ct_mbstowcs(a, b, c) (strncpy(a, b, c), strlen(a))
#define Char char
#define Int int
#define FUN(prefix,rest) prefix ## _ ## rest
#define FUNW(type) type
#define TYPE(type) type
#define FSTR "%s"
#define STR(x) x
#define UC(c) (unsigned char)(c)
#define Isalpha(x) isalpha((unsigned char)x)
#define Isalnum(x) isalnum((unsigned char)x)
#define Isgraph(x) isgraph((unsigned char)x)
#define Isspace(x) isspace((unsigned char)x)
#define Isdigit(x) isdigit((unsigned char)x)
#define Iscntrl(x) iscntrl((unsigned char)x)
#define Isprint(x) isprint((unsigned char)x)
#define Isupper(x) isupper((unsigned char)x)
#define Islower(x) islower((unsigned char)x)
#define Toupper(x) toupper((unsigned char)x)
#define Tolower(x) tolower((unsigned char)x)
#define IsASCII(x) isascii((unsigned char)x)
#define Strlen(x) strlen(x)
#define Strchr(s,c) strchr(s,c)
#define Strrchr(s,c) strrchr(s,c)
#define Strstr(s,v) strstr(s,v)
#define Strdup(x) strdup(x)
#define Strcpy(d,s) strcpy(d,s)
#define Strncpy(d,s,n) strncpy(d,s,n)
#define Strncat(d,s,n) strncat(d,s,n)
#define Strcmp(s,v) strcmp(s,v)
#define Strncmp(s,v,n) strncmp(s,v,n)
#define Strcspn(s,r) strcspn(s,r)
#define Strtol(p,e,b) strtol(p,e,b)
#define Width(c) 1
#endif
#ifdef WIDECHAR
/*
* Conversion buffer
*/
typedef struct ct_buffer_t {
char *cbuff;
size_t csize;
Char *wbuff;
size_t wsize;
} ct_buffer_t;
#define ct_encode_string __ct_encode_string
/* Encode a wide character string and return the UTF-8 encoded result. */
public char *ct_encode_string(const Char *, ct_buffer_t *);
#define ct_decode_string __ct_decode_string
/* Decode a (multi)?byte string and return the wide character string result. */
public Char *ct_decode_string(const char *, ct_buffer_t *);
/* Decode a (multi)?byte argv string array.
* The pointer returned must be free()d when done. */
protected Char **ct_decode_argv(int, const char *[], ct_buffer_t *);
/* Resizes the conversion buffer(s) if needed. */
protected void ct_conv_buff_resize(ct_buffer_t *, size_t, size_t);
protected ssize_t ct_encode_char(char *, size_t, Char);
protected size_t ct_enc_width(Char);
#define ct_free_argv(s) el_free(s)
#else
#define ct_encode_string(s, b) (s)
#define ct_decode_string(s, b) (s)
#define ct_decode_argv(l, s, b) (s)
#define ct_conv_buff_resize(b, os, ns)
#define ct_encode_char(d, l, s) (*d = s, 1)
#define ct_free_argv(s)
#endif
#ifndef NARROWCHAR
/* Encode a characted into the destination buffer, provided there is sufficent
* buffer space available. Returns the number of bytes used up (zero if the
* character cannot be encoded, -1 if there was not enough space available). */
/* The maximum buffer size to hold the most unwieldly visual representation,
* in this case \U+nnnnn. */
#define VISUAL_WIDTH_MAX 8
/* The terminal is thought of in terms of X columns by Y lines. In the cases
* where a wide character takes up more than one column, the adjacent
* occupied column entries will contain this faux character. */
#define MB_FILL_CHAR ((Char)-1)
/* Visual width of character c, taking into account ^? , \0177 and \U+nnnnn
* style visual expansions. */
protected int ct_visual_width(Char);
/* Turn the given character into the appropriate visual format, matching
* the width given by ct_visual_width(). Returns the number of characters used
* up, or -1 if insufficient space. Buffer length is in count of Char's. */
protected ssize_t ct_visual_char(Char *, size_t, Char);
/* Convert the given string into visual format, using the ct_visual_char()
* function. Uses a static buffer, so not threadsafe. */
protected const Char *ct_visual_string(const Char *);
/* printable character, use ct_visual_width() to find out display width */
#define CHTYPE_PRINT ( 0)
/* control character found inside the ASCII portion of the charset */
#define CHTYPE_ASCIICTL (-1)
/* a \t */
#define CHTYPE_TAB (-2)
/* a \n */
#define CHTYPE_NL (-3)
/* non-printable character */
#define CHTYPE_NONPRINT (-4)
/* classification of character c, as one of the above defines */
protected int ct_chr_class(Char c);
#endif
#endif /* _chartype_f */

126
common.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: common.c,v 1.19 2006/03/06 21:11:56 christos Exp $ */
/* $NetBSD: common.c,v 1.24 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: common.c,v 1.19 2006/03/06 21:11:56 christos Exp $");
__RCSID("$NetBSD: common.c,v 1.24 2009/12/30 22:37:40 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -52,7 +52,7 @@ __RCSID("$NetBSD: common.c,v 1.19 2006/03/06 21:11:56 christos Exp $");
*/
protected el_action_t
/*ARGSUSED*/
ed_end_of_file(EditLine *el, int c __attribute__((__unused__)))
ed_end_of_file(EditLine *el, Int c __attribute__((__unused__)))
{
re_goto_bottom(el);
@ -66,7 +66,7 @@ ed_end_of_file(EditLine *el, int c __attribute__((__unused__)))
* Insert a character [bound to all insert keys]
*/
protected el_action_t
ed_insert(EditLine *el, int c)
ed_insert(EditLine *el, Int c)
{
int count = el->el_state.argument;
@ -109,9 +109,9 @@ ed_insert(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
ed_delete_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp, *p, *kp;
Char *cp, *p, *kp;
if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR);
@ -123,7 +123,7 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
*kp++ = *p;
el->el_chared.c_kill.last = kp;
c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */
c_delbefore(el, (int)(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 */
@ -137,7 +137,7 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
ed_delete_next_char(EditLine *el, int c)
ed_delete_next_char(EditLine *el, Int c)
{
#ifdef notdef /* XXX */
#define EL el->el_line
@ -155,7 +155,7 @@ ed_delete_next_char(EditLine *el, int c)
return (CC_ERROR);
#else
/* then do an EOF */
term_writechar(el, c);
term_writec(el, c);
return (CC_EOF);
#endif
} else {
@ -187,9 +187,9 @@ ed_delete_next_char(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
ed_kill_line(EditLine *el, int c __attribute__((__unused__)))
ed_kill_line(EditLine *el, Int c __attribute__((__unused__)))
{
char *kp, *cp;
Char *kp, *cp;
cp = el->el_line.cursor;
kp = el->el_chared.c_kill.buf;
@ -208,18 +208,18 @@ ed_kill_line(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
ed_move_to_end(EditLine *el, int c __attribute__((__unused__)))
ed_move_to_end(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.lastchar;
if (el->el_map.type == MAP_VI) {
#ifdef VI_MOVE
el->el_line.cursor--;
#endif
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
return (CC_REFRESH);
}
#ifdef VI_MOVE
el->el_line.cursor--;
#endif
}
return (CC_CURSOR);
}
@ -231,14 +231,14 @@ ed_move_to_end(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
ed_move_to_beg(EditLine *el, int c __attribute__((__unused__)))
ed_move_to_beg(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.buffer;
if (el->el_map.type == MAP_VI) {
/* We want FIRST non space character */
while (isspace((unsigned char) *el->el_line.cursor))
while (Isspace(*el->el_line.cursor))
el->el_line.cursor++;
if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el);
@ -254,7 +254,7 @@ ed_move_to_beg(EditLine *el, int c __attribute__((__unused__)))
* [^T] [^T]
*/
protected el_action_t
ed_transpose_chars(EditLine *el, int c)
ed_transpose_chars(EditLine *el, Int c)
{
if (el->el_line.cursor < el->el_line.lastchar) {
@ -280,9 +280,9 @@ ed_transpose_chars(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
ed_next_char(EditLine *el, int c __attribute__((__unused__)))
ed_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
char *lim = el->el_line.lastchar;
Char *lim = el->el_line.lastchar;
if (el->el_line.cursor >= lim ||
(el->el_line.cursor == lim - 1 &&
@ -309,7 +309,7 @@ ed_next_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
ed_prev_word(EditLine *el, int c __attribute__((__unused__)))
ed_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.buffer)
@ -335,7 +335,7 @@ ed_prev_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
ed_prev_char(EditLine *el, int c __attribute__((__unused__)))
ed_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor > el->el_line.buffer) {
@ -359,14 +359,14 @@ ed_prev_char(EditLine *el, int c __attribute__((__unused__)))
* [^V] [^V]
*/
protected el_action_t
ed_quoted_insert(EditLine *el, int c)
ed_quoted_insert(EditLine *el, Int c)
{
int num;
char tc;
Char tc;
tty_quotemode(el);
num = el_getc(el, &tc);
c = (unsigned char) tc;
num = FUN(el,getc)(el, &tc);
c = tc;
tty_noquotemode(el);
if (num == 1)
return (ed_insert(el, c));
@ -379,10 +379,10 @@ ed_quoted_insert(EditLine *el, int c)
* Adds to argument or enters a digit
*/
protected el_action_t
ed_digit(EditLine *el, int c)
ed_digit(EditLine *el, Int c)
{
if (!isdigit(c))
if (!Isdigit(c))
return (CC_ERROR);
if (el->el_state.doingarg) {
@ -407,10 +407,10 @@ ed_digit(EditLine *el, int c)
* For ESC-n
*/
protected el_action_t
ed_argument_digit(EditLine *el, int c)
ed_argument_digit(EditLine *el, Int c)
{
if (!isdigit(c))
if (!Isdigit(c))
return (CC_ERROR);
if (el->el_state.doingarg) {
@ -432,7 +432,7 @@ ed_argument_digit(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
ed_unassigned(EditLine *el, int c __attribute__((__unused__)))
ed_unassigned(EditLine *el, Int c __attribute__((__unused__)))
{
return (CC_ERROR);
@ -450,7 +450,7 @@ ed_unassigned(EditLine *el, int c __attribute__((__unused__)))
protected el_action_t
/*ARGSUSED*/
ed_tty_sigint(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
Int c __attribute__((__unused__)))
{
return (CC_NORM);
@ -464,7 +464,7 @@ ed_tty_sigint(EditLine *el __attribute__((__unused__)),
protected el_action_t
/*ARGSUSED*/
ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
Int c __attribute__((__unused__)))
{
return (CC_NORM);
@ -478,7 +478,7 @@ ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
protected el_action_t
/*ARGSUSED*/
ed_tty_flush_output(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
Int c __attribute__((__unused__)))
{
return (CC_NORM);
@ -492,7 +492,7 @@ ed_tty_flush_output(EditLine *el __attribute__((__unused__)),
protected el_action_t
/*ARGSUSED*/
ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
Int c __attribute__((__unused__)))
{
return (CC_NORM);
@ -506,7 +506,7 @@ ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
protected el_action_t
/*ARGSUSED*/
ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
Int c __attribute__((__unused__)))
{
return (CC_NORM);
@ -520,7 +520,7 @@ ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
protected el_action_t
/*ARGSUSED*/
ed_tty_stop_output(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
Int c __attribute__((__unused__)))
{
return (CC_NORM);
@ -534,7 +534,7 @@ ed_tty_stop_output(EditLine *el __attribute__((__unused__)),
protected el_action_t
/*ARGSUSED*/
ed_tty_start_output(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
Int c __attribute__((__unused__)))
{
return (CC_NORM);
@ -547,7 +547,7 @@ ed_tty_start_output(EditLine *el __attribute__((__unused__)),
*/
protected el_action_t
/*ARGSUSED*/
ed_newline(EditLine *el, int c __attribute__((__unused__)))
ed_newline(EditLine *el, Int c __attribute__((__unused__)))
{
re_goto_bottom(el);
@ -563,7 +563,7 @@ ed_newline(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
ed_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor <= el->el_line.buffer)
@ -583,7 +583,7 @@ ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
ed_clear_screen(EditLine *el, int c __attribute__((__unused__)))
ed_clear_screen(EditLine *el, Int c __attribute__((__unused__)))
{
term_clear_screen(el); /* clear the whole real screen */
@ -599,7 +599,7 @@ ed_clear_screen(EditLine *el, int c __attribute__((__unused__)))
protected el_action_t
/*ARGSUSED*/
ed_redisplay(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
Int c __attribute__((__unused__)))
{
return (CC_REDISPLAY);
@ -612,7 +612,7 @@ ed_redisplay(EditLine *el __attribute__((__unused__)),
*/
protected el_action_t
/*ARGSUSED*/
ed_start_over(EditLine *el, int c __attribute__((__unused__)))
ed_start_over(EditLine *el, Int c __attribute__((__unused__)))
{
ch_reset(el, 0);
@ -627,7 +627,7 @@ ed_start_over(EditLine *el, int c __attribute__((__unused__)))
protected el_action_t
/*ARGSUSED*/
ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__)))
Int c __attribute__((__unused__)))
{
return (CC_NORM);
@ -640,7 +640,7 @@ ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
*/
protected el_action_t
/*ARGSUSED*/
ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
ed_prev_history(EditLine *el, Int c __attribute__((__unused__)))
{
char beep = 0;
int sv_event = el->el_history.eventno;
@ -650,7 +650,7 @@ ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
if (el->el_history.eventno == 0) { /* save the current buffer
* away */
(void) strncpy(el->el_history.buf, el->el_line.buffer,
(void) 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);
@ -660,7 +660,7 @@ ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
if (hist_get(el) == CC_ERROR) {
if (el->el_map.type == MAP_VI) {
el->el_history.eventno = sv_event;
return CC_ERROR;
}
beep = 1;
/* el->el_history.eventno was fixed by first call */
@ -678,7 +678,7 @@ ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
ed_next_history(EditLine *el, int c __attribute__((__unused__)))
ed_next_history(EditLine *el, Int c __attribute__((__unused__)))
{
el_action_t beep = CC_REFRESH, rval;
@ -705,9 +705,9 @@ ed_next_history(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
ed_search_prev_history(EditLine *el, Int c __attribute__((__unused__)))
{
const char *hp;
const Char *hp;
int h;
bool_t found = 0;
@ -723,7 +723,7 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
return (CC_ERROR);
}
if (el->el_history.eventno == 0) {
(void) strncpy(el->el_history.buf, el->el_line.buffer,
(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);
@ -744,7 +744,7 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
#endif
if ((strncmp(hp, el->el_line.buffer, (size_t)
if ((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)) {
@ -773,9 +773,9 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
ed_search_next_history(EditLine *el, Int c __attribute__((__unused__)))
{
const char *hp;
const Char *hp;
int h;
bool_t found = 0;
@ -799,7 +799,7 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
#endif
if ((strncmp(hp, el->el_line.buffer, (size_t)
if ((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))
@ -827,9 +827,9 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
ed_prev_line(EditLine *el, Int c __attribute__((__unused__)))
{
char *ptr;
Char *ptr;
int nchars = c_hpos(el);
/*
@ -870,9 +870,9 @@ ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
ed_next_line(EditLine *el, int c __attribute__((__unused__)))
ed_next_line(EditLine *el, Int c __attribute__((__unused__)))
{
char *ptr;
Char *ptr;
int nchars = c_hpos(el);
/*
@ -904,13 +904,13 @@ ed_next_line(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
ed_command(EditLine *el, int c __attribute__((__unused__)))
ed_command(EditLine *el, Int c __attribute__((__unused__)))
{
char tmpbuf[EL_BUFSIZ];
Char tmpbuf[EL_BUFSIZ];
int tmplen;
tmplen = c_gets(el, tmpbuf, "\n: ");
term__putc('\n');
tmplen = c_gets(el, tmpbuf, STR("\n: "));
term__putc(el, '\n');
if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
term_beep(el);

View File

@ -15,4 +15,6 @@
#define HAVE_STRVIS 1
#define HAVE_STRUNVIS 1
#define HAVE_STRUCT_DIRENT_D_NAMLEN 1
#include "sys.h"

View File

@ -1,4 +1,4 @@
.\" $NetBSD: editline.3,v 1.55 2007/01/12 16:31:13 christos Exp $
.\" $NetBSD: editline.3,v 1.73 2010/01/03 19:05:26 wiz Exp $
.\"
.\" Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -13,9 +13,6 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. 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
@ -29,33 +26,50 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd January 12, 2007
.Os
.Dd January 3, 2010
.Dt EDITLINE 3
.Os
.Sh NAME
.Nm editline ,
.Nm el_init ,
.Nm el_end ,
.Nm el_reset ,
.Nm el_gets ,
.Nm el_wgets ,
.Nm el_getc ,
.Nm el_wgetc ,
.Nm el_push ,
.Nm el_wpush ,
.Nm el_parse ,
.Nm el_wparse ,
.Nm el_set ,
.Nm el_wset ,
.Nm el_get ,
.Nm el_wget ,
.Nm el_source ,
.Nm el_resize ,
.Nm el_line ,
.Nm el_wline ,
.Nm el_insertstr ,
.Nm el_winsertstr ,
.Nm el_deletestr ,
.Nm el_wdeletestr ,
.Nm history_init ,
.Nm history_winit ,
.Nm history_end ,
.Nm history_wend ,
.Nm history ,
.Nm history_w ,
.Nm tok_init ,
.Nm tok_winit ,
.Nm tok_end ,
.Nm tok_wend ,
.Nm tok_reset ,
.Nm tok_wreset ,
.Nm tok_line ,
.Nm tok_wline ,
.Nm tok_str
.Nm tok_wstr
.Nd line editor, history and tokenization functions
.Sh LIBRARY
.Lb libedit
@ -69,17 +83,29 @@
.Fn el_reset "EditLine *e"
.Ft const char *
.Fn el_gets "EditLine *e" "int *count"
.Ft const wchar_t *
.Fn el_wgets "EditLine *e" "int *count"
.Ft int
.Fn el_getc "EditLine *e" "char *ch"
.Ft int
.Fn el_wgetc "EditLine *e" "wchar_t *ch"
.Ft void
.Fn el_push "EditLine *e" "const char *str"
.Ft void
.Fn el_wpush "EditLine *e" "const wchar_t *str"
.Ft int
.Fn el_parse "EditLine *e" "int argc" "const char *argv[]"
.Ft int
.Fn el_wparse "EditLine *e" "int argc" "const wchar_t *argv[]"
.Ft int
.Fn el_set "EditLine *e" "int op" "..."
.Ft int
.Fn el_wset "EditLine *e" "int op" "..."
.Ft int
.Fn el_get "EditLine *e" "int op" "..."
.Ft int
.Fn el_wget "EditLine *e" "int op" "..."
.Ft int
.Fn el_source "EditLine *e" "const char *file"
.Ft void
.Fn el_resize "EditLine *e"
@ -87,24 +113,44 @@
.Fn el_line "EditLine *e"
.Ft int
.Fn el_insertstr "EditLine *e" "const char *str"
.Ft int
.Fn el_winsertstr "EditLine *e" "const wchar_t *str"
.Ft void
.Fn el_deletestr "EditLine *e" "int count"
.Ft void
.Fn el_wdeletestr "EditLine *e" "int count"
.Ft History *
.Fn history_init
.Ft HistoryW *
.Fn history_winit
.Ft void
.Fn history_end "History *h"
.Ft void
.Fn history_wend "HistoryW *h"
.Ft int
.Fn history "History *h" "HistEvent *ev" "int op" "..."
.Ft int
.Fn history_w "HistoryW *h" "HistEventW *ev" "int op" "..."
.Ft Tokenizer *
.Fn tok_init "const char *IFS"
.Ft TokenizerW *
.Fn tok_winit "const wchar_t *IFS"
.Ft void
.Fn tok_end "Tokenizer *t"
.Ft void
.Fn tok_wend "TokenizerW *t"
.Ft void
.Fn tok_reset "Tokenizer *t"
.Ft void
.Fn tok_wreset "TokenizerW *t"
.Ft int
.Fn tok_line "Tokenizer *t" "const LineInfo *li" "int *argc" "const char **argv[]" "int *cursorc" "int *cursoro"
.Ft int
.Fn tok_wline "TokenizerW *t" "const LineInfoW *li" "int *argc" "const wchar_t **argv[]" "int *cursorc" "int *cursoro"
.Ft int
.Fn tok_str "Tokenizer *t" "const char *str" "int *argc" "const char **argv[]"
.Ft int
.Fn tok_wstr "TokenizerW *t" "const wchar_t *str" "int *argc" "const wchar_t **argv[]"
.Sh DESCRIPTION
The
.Nm
@ -127,6 +173,9 @@ which is created by
and freed by
.Fn el_end .
.Pp
The wide character functions behave the same way as their narrow
counterparts.
.Pp
The following functions are available:
.Bl -tag -width 4n
.It Fn el_init
@ -160,6 +209,14 @@ is modified to contain the number of characters read.
Returns the line read if successful, or
.Dv NULL
if no characters were read or if an error occurred.
If an error occurred,
.Fa count
is set to \-1 and
.Dv errno
contains the error code that caused it.
The return value may not remain valid across calls to
.Fn el_gets
and must be copied if the data is to be retained.
.It Fn el_getc
Read a character from the tty.
.Fa ch
@ -220,10 +277,30 @@ 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_PROMPT_ESC , Fa "char *(*f)(EditLine *)" , Fa "char c"
Same as
.Dv EL_PROMPT ,
but the
.Fa c
argument indicates the start/stop literal prompt character.
.Pp
If a start/stop literal character is found in the prompt, the
character itself
is not printed, but characters after it are printed directly to the
terminal without affecting the state of the current line.
A subsequent second start/stop literal character ends this behavior.
This is typically used to embed literal escape sequences that change the
color/style of the terminal in the prompt.
.Dv 0
unsets it.
.It Dv EL_REFRESH
Re-display the current line on the next terminal line.
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)"
Define right side prompt printing function as
.Fa f ,
which is to return a string that contains the prompt.
.It Dv EL_RPROMPT_ESC , Fa "char *(*f)(EditLine *)" , Fa "char c"
Define the right prompt printing function but with a literal escape character.
.It Dv EL_TERMINAL , Fa "const char *type"
Define terminal type of the tty to be
.Fa type ,
@ -257,66 +334,43 @@ reading command input:
and
.Dv SIGWINCH .
Otherwise, the current signal handlers will be used.
.It Dv EL_BIND , Xo
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
.It Dv EL_BIND , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic bind
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_ECHOTC , Xo
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
.It Dv EL_ECHOTC , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic echotc
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_SETTC , Xo
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
.It Dv EL_SETTC , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic settc
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_SETTY , Xo
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
.It Dv EL_SETTY , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic setty
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_TELLTC , Xo
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
.It Dv EL_TELLTC , Fa "const char *" , Fa "..." , Dv NULL
Perform the
.Ic telltc
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_ADDFN , Xo
.Fa "const char *name" ,
.Fa "const char *help" ,
.Fa "unsigned char (*func)(EditLine *e, int ch)"
.Xc
.It Dv EL_ADDFN , Fa "const char *name" , Fa "const char *help" , \
Fa "unsigned char (*func)(EditLine *e, int ch)"
Add a user defined function,
.Fn func ,
referred to as
@ -358,10 +412,8 @@ Beep, and flush tty.
.It Dv CC_FATAL
Fatal error, reset tty to known state.
.El
.It Dv EL_HIST , Xo
.Fa "History *(*func)(History *, int op, ...)" ,
.Fa "const char *ptr"
.Xc
.It Dv EL_HIST , Fa "History *(*func)(History *, int op, ...)" , \
Fa "const char *ptr"
Defines which history function to use, which is usually
.Fn history .
.Fa ptr
@ -390,7 +442,8 @@ This function is called internally by
and
.Fn el_getc .
The builtin function can be set or restored with the special function
name ``EL_BUILTIN_GETCFN''.
name
.Dq Dv EL_BUILTIN_GETCFN .
.It Dv EL_CLIENTDATA , Fa "void *data"
Register
.Fa data
@ -432,10 +485,22 @@ The following values for
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_PROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
Return a pointer to the function that displays the prompt in
.Fa f .
If
.Fa c
is not
.Dv NULL ,
return the start/stop literal prompt character in it.
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)" , Fa "char *c"
Return a pointer to the function that displays the prompt in
.Fa f .
If
.Fa c
is not
.Dv NULL ,
return the start/stop literal prompt character in it.
.It Dv EL_EDITOR , Fa "const char *"
Return the name of the editor, which will be one of
.Dq emacs
@ -460,7 +525,8 @@ above).
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.
.Dq Dv EL_BUILTIN_GETCFN
in the case of the default builtin function.
.It Dv EL_CLIENTDATA , Fa "void **data"
Retrieve
.Fa data
@ -599,18 +665,11 @@ assumed to be created with
.Fn history_init .
.It Dv H_CLEAR
Clear the history.
.It Dv H_FUNC , Xo
.Fa "void *ptr" ,
.Fa "history_gfun_t first" ,
.Fa "history_gfun_t next" ,
.Fa "history_gfun_t last" ,
.Fa "history_gfun_t prev" ,
.Fa "history_gfun_t curr" ,
.Fa "history_sfun_t set" ,
.Fa "history_vfun_t clear" ,
.Fa "history_efun_t enter" ,
.Fa "history_efun_t add"
.Xc
.It Dv H_FUNC , Fa "void *ptr" , Fa "history_gfun_t first" , \
Fa "history_gfun_t next" , Fa "history_gfun_t last" , \
Fa "history_gfun_t prev" , Fa "history_gfun_t curr" , \
Fa "history_sfun_t set" , Fa "history_vfun_t clear" , \
Fa "history_efun_t enter" , Fa "history_efun_t add"
Define functions to perform various history operations.
.Fa ptr
is the argument given to a function when it's invoked.
@ -802,6 +861,7 @@ Luke Mewburn wrote this manual and implemented
and
.Dv EL_RPROMPT .
Jaromir Dolecek implemented the readline emulation.
Johny Mattsson implemented wide character support.
.Sh BUGS
At this time, it is the responsibility of the caller to
check the result of the

View File

@ -1,4 +1,4 @@
.\" $NetBSD: editrc.5,v 1.20 2006/08/21 12:45:30 christos Exp $
.\" $NetBSD: editrc.5,v 1.24 2009/04/11 22:17:52 wiz Exp $
.\"
.\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -13,9 +13,6 @@
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. 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
@ -30,8 +27,8 @@
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd October 18, 2003
.Os
.Dt EDITRC 5
.Os
.Sh NAME
.Nm editrc
.Nd configuration file for editline library
@ -90,16 +87,8 @@ shell.
.Pp
The following builtin commands are available:
.Bl -tag -width 4n
.It Ic bind Xo
.Op Fl a
.Op Fl e
.Op Fl k
.Op Fl l
.Op Fl r
.Op Fl s
.Op Fl v
.Op Ar key Op Ar command
.Xc
.It Ic bind Oo Fl a Oc Oo Fl e Oc Oo Fl k Oc Oo Fl l Oc Oo Fl r Oc \
Oo Fl s Oc Oo Fl v Oc Oo Ar key Op Ar command Oc
Without options, list all bound keys, and the editor command to which
each is bound.
If
@ -195,11 +184,7 @@ if it has any, notably
.Sq \e
and
.Sq ^ .
.It Ic echotc Xo
.Op Fl sv
.Ar arg
.Ar ...
.Xc
.It Ic echotc Oo Fl sv Oc Ar arg Ar ...
Exercise terminal capabilities given in
.Ar arg Ar ... .
If
@ -227,7 +212,7 @@ Enable or disable the
.Nm editline
functionality in a program.
.It Ic history Ar list | Ar size Dv n | Ar unique Dv n
The
The
.Ar list
command lists all entries in the history.
The
@ -255,16 +240,8 @@ to
as defined in
.Xr termcap 5 .
No sanity checking is done.
.It Ic setty Xo
.Op Fl a
.Op Fl d
.Op Fl q
.Op Fl x
.Op Ar +mode
.Op Ar -mode
.Op Ar mode
.Op Ar char=c
.Xc
.It Ic setty Oo Fl a Oc Oo Fl d Oc Oo Fl q Oc Oo Fl x Oc Oo Ar +mode Oc \
Oo Ar -mode Oc Oo Ar mode Oc Oo Ar char=c Oc
Control which tty modes that
.Nm
won't allow the user to change.

149
el.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: el.c,v 1.44 2006/12/15 22:13:33 christos Exp $ */
/* $NetBSD: el.c,v 1.59 2010/04/15 00:56:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
#else
__RCSID("$NetBSD: el.c,v 1.44 2006/12/15 22:13:33 christos Exp $");
__RCSID("$NetBSD: el.c,v 1.59 2010/04/15 00:56:40 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -49,6 +49,9 @@ __RCSID("$NetBSD: el.c,v 1.44 2006/12/15 22:13:33 christos Exp $");
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <ctype.h>
#include <locale.h>
#include <langinfo.h>
#include "el.h"
/* el_init():
@ -57,7 +60,6 @@ __RCSID("$NetBSD: el.c,v 1.44 2006/12/15 22:13:33 christos Exp $");
public EditLine *
el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
{
EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
if (el == NULL)
@ -71,7 +73,8 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
el->el_infd = fileno(fin);
if ((el->el_prog = el_strdup(prog)) == NULL) {
el->el_prog = Strdup(ct_decode_string(prog, &el->el_scratch));
if (el->el_prog == NULL) {
el_free(el);
return NULL;
}
@ -80,6 +83,12 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
* Initialize all the modules. Order is important!!!
*/
el->el_flags = 0;
#ifdef WIDECHAR
if (setlocale(LC_CTYPE, NULL) != NULL){
if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0)
el->el_flags |= CHARSET_IS_UTF8;
}
#endif
if (term_init(el) == -1) {
el_free(el->el_prog);
@ -125,6 +134,12 @@ el_end(EditLine *el)
el_free((ptr_t) el->el_prog);
el_free((ptr_t) el);
#ifdef WIDECHAR
el_free((ptr_t) el->el_scratch.cbuff);
el_free((ptr_t) el->el_scratch.wbuff);
el_free((ptr_t) el->el_lgcyconv.cbuff);
el_free((ptr_t) el->el_lgcyconv.wbuff);
#endif
}
@ -144,7 +159,7 @@ el_reset(EditLine *el)
* set the editline parameters
*/
public int
el_set(EditLine *el, int op, ...)
FUN(el,set)(EditLine *el, int op, ...)
{
va_list ap;
int rv = 0;
@ -155,16 +170,28 @@ el_set(EditLine *el, int op, ...)
switch (op) {
case EL_PROMPT:
case EL_RPROMPT:
rv = prompt_set(el, va_arg(ap, el_pfunc_t), op);
case EL_RPROMPT: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
rv = prompt_set(el, p, 0, op, 1);
break;
}
case EL_PROMPT_ESC:
case EL_RPROMPT_ESC: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
int c = va_arg(ap, int);
rv = prompt_set(el, p, c, op, 1);
break;
}
case EL_TERMINAL:
rv = term_set(el, va_arg(ap, char *));
break;
case EL_EDITOR:
rv = map_set_editor(el, va_arg(ap, char *));
rv = map_set_editor(el, va_arg(ap, Char *));
break;
case EL_SIGNAL:
@ -177,40 +204,39 @@ el_set(EditLine *el, int op, ...)
case EL_BIND:
case EL_TELLTC:
case EL_SETTC:
case EL_GETTC:
case EL_ECHOTC:
case EL_SETTY:
{
const char *argv[20];
const Char *argv[20];
int i;
for (i = 1; i < 20; i++)
if ((argv[i] = va_arg(ap, char *)) == NULL)
if ((argv[i] = va_arg(ap, Char *)) == NULL)
break;
switch (op) {
case EL_BIND:
argv[0] = "bind";
argv[0] = STR("bind");
rv = map_bind(el, i, argv);
break;
case EL_TELLTC:
argv[0] = "telltc";
argv[0] = STR("telltc");
rv = term_telltc(el, i, argv);
break;
case EL_SETTC:
argv[0] = "settc";
argv[0] = STR("settc");
rv = term_settc(el, i, argv);
break;
case EL_ECHOTC:
argv[0] = "echotc";
argv[0] = STR("echotc");
rv = term_echotc(el, i, argv);
break;
case EL_SETTY:
argv[0] = "setty";
argv[0] = STR("setty");
rv = tty_stty(el, i, argv);
break;
@ -224,8 +250,8 @@ el_set(EditLine *el, int op, ...)
case EL_ADDFN:
{
char *name = va_arg(ap, char *);
char *help = va_arg(ap, char *);
Char *name = va_arg(ap, Char *);
Char *help = va_arg(ap, Char *);
el_func_t func = va_arg(ap, el_func_t);
rv = map_addfunc(el, name, help, func);
@ -235,9 +261,11 @@ el_set(EditLine *el, int op, ...)
case EL_HIST:
{
hist_fun_t func = va_arg(ap, hist_fun_t);
ptr_t ptr = va_arg(ap, char *);
ptr_t ptr = va_arg(ap, ptr_t);
rv = hist_set(el, func, ptr);
if (!(el->el_flags & CHARSET_IS_UTF8))
el->el_flags &= ~NARROW_HISTORY;
break;
}
@ -253,6 +281,7 @@ el_set(EditLine *el, int op, ...)
{
el_rfunc_t rc = va_arg(ap, el_rfunc_t);
rv = el_read_setfn(el, rc);
el->el_flags &= ~NARROW_READ;
break;
}
@ -308,6 +337,12 @@ el_set(EditLine *el, int op, ...)
break;
}
case EL_REFRESH:
re_clear_display(el);
re_refresh(el);
term__flush(el);
break;
default:
rv = -1;
break;
@ -322,7 +357,7 @@ el_set(EditLine *el, int op, ...)
* retrieve the editline parameters
*/
public int
el_get(EditLine *el, int op, ...)
FUN(el,get)(EditLine *el, int op, ...)
{
va_list ap;
int rv;
@ -334,12 +369,22 @@ el_get(EditLine *el, int op, ...)
switch (op) {
case EL_PROMPT:
case EL_RPROMPT:
rv = prompt_get(el, va_arg(ap, el_pfunc_t *), op);
case EL_RPROMPT: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
rv = prompt_get(el, p, 0, op);
break;
}
case EL_PROMPT_ESC:
case EL_RPROMPT_ESC: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
Char *c = va_arg(ap, Char *);
rv = prompt_get(el, p, c, op);
break;
}
case EL_EDITOR:
rv = map_get_editor(el, va_arg(ap, const char **));
rv = map_get_editor(el, va_arg(ap, const Char **));
break;
case EL_SIGNAL:
@ -363,7 +408,7 @@ el_get(EditLine *el, int op, ...)
char *argv[20];
int i;
for (i = 1; i < sizeof(argv) / sizeof(argv[0]); i++)
for (i = 1; i < (int)(sizeof(argv) / sizeof(argv[0])); i++)
if ((argv[i] = va_arg(ap, char *)) == NULL)
break;
@ -381,26 +426,6 @@ el_get(EditLine *el, int op, ...)
break;
}
#if 0 /* XXX */
case EL_ADDFN:
{
char *name = va_arg(ap, char *);
char *help = va_arg(ap, char *);
el_func_t func = va_arg(ap, el_func_t);
rv = map_addfunc(el, name, help, func);
break;
}
case EL_HIST:
{
hist_fun_t func = va_arg(ap, hist_fun_t);
ptr_t ptr = va_arg(ap, char *);
rv = hist_set(el, func, ptr);
}
break;
#endif /* XXX */
case EL_GETCFN:
*va_arg(ap, el_rfunc_t *) = el_read_getfn(el);
rv = 0;
@ -453,11 +478,11 @@ el_get(EditLine *el, int op, ...)
/* el_line():
* Return editing info
*/
public const LineInfo *
el_line(EditLine *el)
public const TYPE(LineInfo) *
FUN(el,line)(EditLine *el)
{
return (const LineInfo *) (void *) &el->el_line;
return (const TYPE(LineInfo) *) (void *) &el->el_line;
}
@ -470,12 +495,15 @@ el_source(EditLine *el, const char *fname)
FILE *fp;
size_t len;
char *ptr;
#ifdef HAVE_ISSETUGID
char path[MAXPATHLEN];
#endif
const Char *dptr;
fp = NULL;
if (fname == NULL) {
#ifdef HAVE_ISSETUGID
static const char elpath[] = "/.editrc";
char path[MAXPATHLEN];
if (issetugid())
return (-1);
@ -501,10 +529,18 @@ el_source(EditLine *el, const char *fname)
return (-1);
while ((ptr = fgetln(fp, &len)) != NULL) {
if (len > 0 && ptr[len - 1] == '\n')
dptr = ct_decode_string(ptr, &el->el_scratch);
if (!dptr)
continue;
if (len > 0 && dptr[len - 1] == '\n')
--len;
ptr[len] = '\0';
if (parse_line(el, ptr) == -1) {
/* loop until first non-space char or EOL */
while (*dptr != '\0' && Isspace(*dptr))
dptr++;
if (*dptr == '#')
continue; /* ignore, this is a comment line */
if (parse_line(el, dptr) == -1) {
(void) fclose(fp);
return (-1);
}
@ -552,23 +588,24 @@ el_beep(EditLine *el)
*/
protected int
/*ARGSUSED*/
el_editmode(EditLine *el, int argc, const char **argv)
el_editmode(EditLine *el, int argc, const Char **argv)
{
const char *how;
const Char *how;
if (argv == NULL || argc != 2 || argv[1] == NULL)
return (-1);
how = argv[1];
if (strcmp(how, "on") == 0) {
if (Strcmp(how, STR("on")) == 0) {
el->el_flags &= ~EDIT_DISABLED;
tty_rawmode(el);
} else if (strcmp(how, "off") == 0) {
} else if (Strcmp(how, STR("off")) == 0) {
tty_cookedmode(el);
el->el_flags |= EDIT_DISABLED;
}
else {
(void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how);
(void) fprintf(el->el_errfile, "edit: Bad value `" FSTR "'.\n",
how);
return (-1);
}
return (0);

33
el.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: el.h,v 1.17 2006/12/15 22:13:33 christos Exp $ */
/* $NetBSD: el.h,v 1.21 2009/12/31 15:58:26 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -46,6 +46,8 @@
#define VIDEFAULT
#define ANCHOR
#include "histedit.h"
#include "chartype.h"
#include <stdio.h>
#include <sys/types.h>
@ -55,6 +57,10 @@
#define NO_TTY 0x02
#define EDIT_DISABLED 0x04
#define UNBUFFERED 0x08
#define CHARSET_IS_UTF8 0x10
#define IGNORE_EXTCHARS 0x20 /* Ignore characters read > 0xff */
#define NARROW_HISTORY 0x40
#define NARROW_READ 0x80
typedef int bool_t; /* True or not */
@ -66,10 +72,10 @@ typedef struct coord_t { /* Position on the screen */
} coord_t;
typedef struct el_line_t {
char *buffer; /* Input line */
char *cursor; /* Cursor position */
char *lastchar; /* Last character */
const char *limit; /* Max position */
Char *buffer; /* Input line */
Char *cursor; /* Cursor position */
Char *lastchar; /* Last character */
const Char *limit; /* Max position */
} el_line_t;
/*
@ -82,13 +88,12 @@ typedef struct el_state_t {
int metanext; /* Is the next char a meta char */
el_action_t lastcmd; /* Previous command */
el_action_t thiscmd; /* this command */
char thisch; /* char that generated it */
Char thisch; /* char that generated it */
} el_state_t;
/*
* Until we come up with something better...
*/
#define el_strdup(a) strdup(a)
#define el_malloc(a) malloc(a)
#define el_realloc(a,b) realloc(a, b)
#define el_free(a) free(a)
@ -109,15 +114,16 @@ typedef struct el_state_t {
#include "read.h"
struct editline {
char *el_prog; /* the program name */
Char *el_prog; /* the program name */
FILE *el_infile; /* Stdio stuff */
FILE *el_outfile; /* Stdio stuff */
FILE *el_errfile; /* Stdio stuff */
int el_infd; /* Input file descriptor */
int el_flags; /* Various flags. */
int el_errno; /* Local copy of errno */
coord_t el_cursor; /* Cursor location */
char **el_display; /* Real screen image = what is there */
char **el_vdisplay; /* Virtual screen image = what we see */
Char **el_display; /* Real screen image = what is there */
Char **el_vdisplay; /* Virtual screen image = what we see */
void *el_data; /* Client data */
el_line_t el_line; /* The current line information */
el_state_t el_state; /* Current editor state */
@ -133,9 +139,14 @@ struct editline {
el_search_t el_search; /* Search stuff */
el_signal_t el_signal; /* Signal handling stuff */
el_read_t el_read; /* Character reading stuff */
#ifdef WIDECHAR
ct_buffer_t el_scratch; /* Scratch conversion buffer */
ct_buffer_t el_lgcyconv; /* Buffer for legacy wrappers */
LineInfo el_lgcylinfo; /* Legacy LineInfo buffer */
#endif
};
protected int el_editmode(EditLine *, int, const char **);
protected int el_editmode(EditLine *, int, const Char **);
#ifdef DEBUG
#define EL_ABORT(a) do { \

365
eln.c Normal file
View File

@ -0,0 +1,365 @@
/* $NetBSD: eln.c,v 1.7 2010/04/15 00:52:48 christos Exp $ */
/*-
* Copyright (c) 2009 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the NetBSD
* Foundation, Inc. and its contributors.
* 4. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: eln.c,v 1.7 2010/04/15 00:52:48 christos Exp $");
#endif /* not lint && not SCCSID */
#include "histedit.h"
#include "el.h"
#include "read.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
public int
el_getc(EditLine *el, char *cp)
{
int num_read;
wchar_t wc = 0;
if (!(el->el_flags & CHARSET_IS_UTF8))
el->el_flags |= IGNORE_EXTCHARS;
num_read = el_wgetc (el, &wc);
if (!(el->el_flags & CHARSET_IS_UTF8))
el->el_flags &= ~IGNORE_EXTCHARS;
if (num_read > 0)
*cp = (unsigned char)wc;
return num_read;
}
public void
el_push(EditLine *el, const char *str)
{
/* Using multibyte->wide string decoding works fine under single-byte
* character sets too, and Does The Right Thing. */
el_wpush(el, ct_decode_string(str, &el->el_lgcyconv));
}
public const char *
el_gets(EditLine *el, int *nread)
{
const wchar_t *tmp;
el->el_flags |= IGNORE_EXTCHARS;
tmp = el_wgets(el, nread);
el->el_flags &= ~IGNORE_EXTCHARS;
return ct_encode_string(tmp, &el->el_lgcyconv);
}
public int
el_parse(EditLine *el, int argc, const char *argv[])
{
int ret;
const wchar_t **wargv;
wargv = (const wchar_t **)
ct_decode_argv(argc, argv, &el->el_lgcyconv);
if (!wargv)
return -1;
ret = el_wparse(el, argc, wargv);
ct_free_argv(wargv);
return ret;
}
public int
el_set(EditLine *el, int op, ...)
{
va_list ap;
int ret;
if (!el)
return -1;
va_start(ap, op);
switch (op) {
case EL_PROMPT: /* el_pfunc_t */
case EL_RPROMPT: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
ret = prompt_set(el, p, 0, op, 0);
break;
}
case EL_TERMINAL: /* const char * */
ret = el_wset(el, op, va_arg(ap, char *));
break;
case EL_EDITOR: /* const wchar_t * */
ret = el_wset(el, op, ct_decode_string(va_arg(ap, char *),
&el->el_lgcyconv));
break;
case EL_SIGNAL: /* int */
case EL_EDITMODE:
case EL_UNBUFFERED:
case EL_PREP_TERM:
ret = el_wset(el, op, va_arg(ap, int));
break;
case EL_BIND: /* const char * list -> const wchar_t * list */
case EL_TELLTC:
case EL_SETTC:
case EL_ECHOTC:
case EL_SETTY: {
const char *argv[20];
int i;
const wchar_t **wargv;
for (i = 1; i < (int)__arraycount(argv); ++i)
if ((argv[i] = va_arg(ap, char *)) == NULL)
break;
argv[0] = NULL;
wargv = (const wchar_t **)
ct_decode_argv(i, argv, &el->el_lgcyconv);
if (!wargv) {
ret = -1;
goto out;
}
/*
* AFAIK we can't portably pass through our new wargv to
* el_wset(), so we have to reimplement the body of
* el_wset() for these ops.
*/
switch (op) {
case EL_BIND:
wargv[0] = STR("bind");
ret = map_bind(el, i, wargv);
break;
case EL_TELLTC:
wargv[0] = STR("telltc");
ret = term_telltc(el, i, wargv);
break;
case EL_SETTC:
wargv[0] = STR("settc");
ret = term_settc(el, i, wargv);
break;
case EL_ECHOTC:
wargv[0] = STR("echotc");
ret = term_echotc(el, i, wargv);
break;
case EL_SETTY:
wargv[0] = STR("setty");
ret = tty_stty(el, i, wargv);
break;
default:
ret = -1;
}
ct_free_argv(wargv);
break;
}
/* XXX: do we need to change el_func_t too? */
case EL_ADDFN: { /* const char *, const char *, el_func_t */
const char *args[2];
el_func_t func;
wchar_t **wargv;
args[0] = va_arg(ap, const char *);
args[1] = va_arg(ap, const char *);
func = va_arg(ap, el_func_t);
wargv = ct_decode_argv(2, args, &el->el_lgcyconv);
if (!wargv) {
ret = -1;
goto out;
}
// XXX: The two strdup's leak
ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]),
func);
ct_free_argv(wargv);
break;
}
case EL_HIST: { /* hist_fun_t, const char * */
hist_fun_t fun = va_arg(ap, hist_fun_t);
ptr_t ptr = va_arg(ap, ptr_t);
ret = hist_set(el, fun, ptr);
if (!(el->el_flags & CHARSET_IS_UTF8))
el->el_flags |= NARROW_HISTORY;
break;
}
/* XXX: do we need to change el_rfunc_t? */
case EL_GETCFN: /* el_rfunc_t */
ret = el_wset(el, op, va_arg(ap, el_rfunc_t));
el->el_flags |= NARROW_READ;
break;
case EL_CLIENTDATA: /* void * */
ret = el_wset(el, op, va_arg(ap, void *));
break;
case EL_SETFP: { /* int, FILE * */
int what = va_arg(ap, int);
FILE *fp = va_arg(ap, FILE *);
ret = el_wset(el, op, what, fp);
break;
}
case EL_PROMPT_ESC: /* el_pfunc_t, char */
case EL_RPROMPT_ESC: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
char c = va_arg(ap, int);
ret = prompt_set(el, p, c, op, 0);
break;
}
default:
ret = -1;
break;
}
out:
va_end(ap);
return ret;
}
public int
el_get(EditLine *el, int op, ...)
{
va_list ap;
int ret;
if (!el)
return -1;
va_start(ap, op);
switch (op) {
case EL_PROMPT: /* el_pfunc_t * */
case EL_RPROMPT: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
ret = prompt_get(el, p, 0, op);
break;
}
case EL_PROMPT_ESC: /* el_pfunc_t *, char **/
case EL_RPROMPT_ESC: {
el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
char *c = va_arg(ap, char *);
wchar_t wc;
ret = prompt_get(el, p, &wc, op);
*c = (unsigned char)wc;
break;
}
case EL_EDITOR: {
const char **p = va_arg(ap, const char **);
const wchar_t *pw;
ret = el_wget(el, op, &pw);
*p = ct_encode_string(pw, &el->el_lgcyconv);
if (!el->el_lgcyconv.csize)
ret = -1;
break;
}
case EL_TERMINAL: /* const char ** */
ret = el_wget(el, op, va_arg(ap, const char **));
break;
case EL_SIGNAL: /* int * */
case EL_EDITMODE:
case EL_UNBUFFERED:
case EL_PREP_TERM:
ret = el_wget(el, op, va_arg(ap, int *));
break;
case EL_GETTC: {
char *argv[20];
static char gettc[] = "gettc";
int i;
for (i = 1; i < (int)__arraycount(argv); ++i)
if ((argv[i] = va_arg(ap, char *)) == NULL)
break;
argv[0] = gettc;
ret = term_gettc(el, i, argv);
break;
}
/* XXX: do we need to change el_rfunc_t? */
case EL_GETCFN: /* el_rfunc_t */
ret = el_wget(el, op, va_arg(ap, el_rfunc_t *));
break;
case EL_CLIENTDATA: /* void ** */
ret = el_wget(el, op, va_arg(ap, void **));
break;
case EL_GETFP: { /* int, FILE ** */
int what = va_arg(ap, int);
FILE **fpp = va_arg(ap, FILE **);
ret = el_wget(el, op, what, fpp);
break;
}
default:
ret = -1;
break;
}
va_end(ap);
return ret;
}
const LineInfo *
el_line(EditLine *el)
{
const LineInfoW *winfo = el_wline(el);
LineInfo *info = &el->el_lgcylinfo;
size_t offset;
const Char *p;
info->buffer = ct_encode_string(winfo->buffer, &el->el_lgcyconv);
offset = 0;
for (p = winfo->buffer; p < winfo->cursor; p++)
offset += ct_enc_width(*p);
info->cursor = info->buffer + offset;
offset = 0;
for (p = winfo->buffer; p < winfo->lastchar; p++)
offset += ct_enc_width(*p);
info->lastchar = info->buffer + offset;
return info;
}
int
el_insertstr(EditLine *el, const char *str)
{
return el_winsertstr(el, ct_decode_string(str, &el->el_lgcyconv));
}

93
emacs.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: emacs.c,v 1.21 2006/03/06 21:11:56 christos Exp $ */
/* $NetBSD: emacs.c,v 1.23 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: emacs.c,v 1.21 2006/03/06 21:11:56 christos Exp $");
__RCSID("$NetBSD: emacs.c,v 1.23 2009/12/30 22:37:40 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -52,7 +52,7 @@ __RCSID("$NetBSD: emacs.c,v 1.21 2006/03/06 21:11:56 christos Exp $");
*/
protected el_action_t
/*ARGSUSED*/
em_delete_or_list(EditLine *el, int c)
em_delete_or_list(EditLine *el, Int c)
{
if (el->el_line.cursor == el->el_line.lastchar) {
@ -88,9 +88,9 @@ em_delete_or_list(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
em_delete_next_word(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp, *p, *kp;
Char *cp, *p, *kp;
if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR);
@ -103,7 +103,7 @@ em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
*kp++ = *p;
el->el_chared.c_kill.last = kp;
c_delafter(el, cp - el->el_line.cursor); /* delete after dot */
c_delafter(el, (int)(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 */
@ -117,9 +117,9 @@ em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_yank(EditLine *el, int c __attribute__((__unused__)))
em_yank(EditLine *el, Int c __attribute__((__unused__)))
{
char *kp, *cp;
Char *kp, *cp;
if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
return (CC_NORM);
@ -133,7 +133,8 @@ em_yank(EditLine *el, int c __attribute__((__unused__)))
cp = el->el_line.cursor;
/* open the space, */
c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf);
c_insert(el,
(int)(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;
@ -152,9 +153,9 @@ em_yank(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_kill_line(EditLine *el, int c __attribute__((__unused__)))
em_kill_line(EditLine *el, Int c __attribute__((__unused__)))
{
char *kp, *cp;
Char *kp, *cp;
cp = el->el_line.buffer;
kp = el->el_chared.c_kill.buf;
@ -174,9 +175,9 @@ em_kill_line(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_kill_region(EditLine *el, int c __attribute__((__unused__)))
em_kill_region(EditLine *el, Int c __attribute__((__unused__)))
{
char *kp, *cp;
Char *kp, *cp;
if (!el->el_chared.c_kill.mark)
return (CC_ERROR);
@ -187,14 +188,14 @@ em_kill_region(EditLine *el, int c __attribute__((__unused__)))
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);
c_delafter(el, (int)(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);
c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark));
el->el_line.cursor = el->el_chared.c_kill.mark;
}
return (CC_REFRESH);
@ -207,9 +208,9 @@ em_kill_region(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_copy_region(EditLine *el, int c __attribute__((__unused__)))
em_copy_region(EditLine *el, Int c __attribute__((__unused__)))
{
char *kp, *cp;
Char *kp, *cp;
if (!el->el_chared.c_kill.mark)
return (CC_ERROR);
@ -236,7 +237,7 @@ em_copy_region(EditLine *el, int c __attribute__((__unused__)))
* Gosling emacs transpose chars [^T]
*/
protected el_action_t
em_gosmacs_transpose(EditLine *el, int c)
em_gosmacs_transpose(EditLine *el, Int c)
{
if (el->el_line.cursor > &el->el_line.buffer[1]) {
@ -256,7 +257,7 @@ em_gosmacs_transpose(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
em_next_word(EditLine *el, int c __attribute__((__unused__)))
em_next_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR);
@ -281,16 +282,16 @@ em_next_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_upper_case(EditLine *el, int c __attribute__((__unused__)))
em_upper_case(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp, *ep;
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 (islower((unsigned char)*cp))
*cp = toupper((unsigned char)*cp);
if (Islower(*cp))
*cp = Toupper(*cp);
el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar)
@ -305,24 +306,24 @@ em_upper_case(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_capitol_case(EditLine *el, int c __attribute__((__unused__)))
em_capitol_case(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp, *ep;
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((unsigned char)*cp);
if (Isalpha(*cp)) {
if (Islower(*cp))
*cp = Toupper(*cp);
cp++;
break;
}
}
for (; cp < ep; cp++)
if (isupper((unsigned char)*cp))
*cp = tolower((unsigned char)*cp);
if (Isupper(*cp))
*cp = Tolower(*cp);
el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar)
@ -337,16 +338,16 @@ em_capitol_case(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_lower_case(EditLine *el, int c __attribute__((__unused__)))
em_lower_case(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp, *ep;
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 (isupper((unsigned char)*cp))
*cp = tolower((unsigned char)*cp);
if (Isupper(*cp))
*cp = Tolower(*cp);
el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar)
@ -361,7 +362,7 @@ em_lower_case(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_set_mark(EditLine *el, int c __attribute__((__unused__)))
em_set_mark(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_chared.c_kill.mark = el->el_line.cursor;
@ -375,9 +376,9 @@ em_set_mark(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_exchange_mark(EditLine *el, int c __attribute__((__unused__)))
em_exchange_mark(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp;
Char *cp;
cp = el->el_line.cursor;
el->el_line.cursor = el->el_chared.c_kill.mark;
@ -392,7 +393,7 @@ em_exchange_mark(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_universal_argument(EditLine *el, int c __attribute__((__unused__)))
em_universal_argument(EditLine *el, Int c __attribute__((__unused__)))
{ /* multiply current argument by 4 */
if (el->el_state.argument > 1000000)
@ -409,7 +410,7 @@ em_universal_argument(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_meta_next(EditLine *el, int c __attribute__((__unused__)))
em_meta_next(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_state.metanext = 1;
@ -422,7 +423,7 @@ em_meta_next(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__)))
em_toggle_overwrite(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
@ -436,9 +437,9 @@ em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_copy_prev_word(EditLine *el, int c __attribute__((__unused__)))
em_copy_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{
char *cp, *oldc, *dp;
Char *cp, *oldc, *dp;
if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR);
@ -448,7 +449,7 @@ em_copy_prev_word(EditLine *el, int c __attribute__((__unused__)))
cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
el->el_state.argument, ce__isword);
c_insert(el, oldc - cp);
c_insert(el, (int)(oldc - cp));
for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
*dp++ = *cp;
@ -463,7 +464,7 @@ em_copy_prev_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_inc_search_next(EditLine *el, int c __attribute__((__unused__)))
em_inc_search_next(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_search.patlen = 0;
@ -476,7 +477,7 @@ em_inc_search_next(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_inc_search_prev(EditLine *el, int c __attribute__((__unused__)))
em_inc_search_prev(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_search.patlen = 0;
@ -490,7 +491,7 @@ em_inc_search_prev(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
em_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
em_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor <= el->el_line.buffer)

View File

@ -1,4 +1,4 @@
/* $NetBSD: filecomplete.c,v 1.10 2006/11/09 16:58:38 christos Exp $ */
/* $NetBSD: filecomplete.c,v 1.19 2010/06/01 18:20:26 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -15,9 +15,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@ -34,7 +31,7 @@
#include "config.h"
#if !defined(lint) && !defined(SCCSID)
__RCSID("$NetBSD: filecomplete.c,v 1.10 2006/11/09 16:58:38 christos Exp $");
__RCSID("$NetBSD: filecomplete.c,v 1.19 2010/06/01 18:20:26 christos Exp $");
#endif /* not lint && not SCCSID */
#include <sys/types.h>
@ -62,8 +59,8 @@ __RCSID("$NetBSD: filecomplete.c,v 1.10 2006/11/09 16:58:38 christos Exp $");
#include "histedit.h"
#include "filecomplete.h"
static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
'>', '<', '=', ';', '|', '&', '{', '(', '\0' };
static Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@',
'$', '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
/********************************/
@ -149,20 +146,24 @@ fn_filename_completion_function(const char *text, int state)
nptr = realloc(filename, strlen(temp) + 1);
if (nptr == NULL) {
free(filename);
filename = NULL;
return NULL;
}
filename = nptr;
(void)strcpy(filename, temp);
len = temp - text; /* including last slash */
nptr = realloc(dirname, len + 1);
if (nptr == NULL) {
free(filename);
free(dirname);
dirname = NULL;
return NULL;
}
dirname = nptr;
(void)strncpy(dirname, text, len);
dirname[len] = '\0';
} else {
free(filename);
if (*text == 0)
filename = NULL;
else {
@ -170,6 +171,7 @@ fn_filename_completion_function(const char *text, int state)
if (filename == NULL)
return NULL;
}
free(dirname);
dirname = NULL;
}
@ -179,12 +181,14 @@ fn_filename_completion_function(const char *text, int state)
}
/* support for ``~user'' syntax */
free(dirpath);
if (dirname == NULL && (dirname = strdup("./")) == NULL)
return NULL;
if (*dirname == '~')
dirpath = NULL;
if (dirname == NULL) {
if ((dirname = strdup("")) == NULL)
return NULL;
dirpath = strdup("./");
} else if (*dirname == '~')
dirpath = fn_tilde_expand(dirname);
else
dirpath = strdup(dirname);
@ -211,10 +215,10 @@ fn_filename_completion_function(const char *text, int state)
/* otherwise, get first entry where first */
/* filename_len characters are equal */
if (entry->d_name[0] == filename[0]
#if defined(__SVR4) || defined(__linux__)
&& strlen(entry->d_name) >= filename_len
#else
#if HAVE_STRUCT_DIRENT_D_NAMLEN
&& entry->d_namlen >= filename_len
#else
&& strlen(entry->d_name) >= filename_len
#endif
&& strncmp(entry->d_name, filename,
filename_len) == 0)
@ -223,10 +227,10 @@ fn_filename_completion_function(const char *text, int state)
if (entry) { /* match found */
#if defined(__SVR4) || defined(__linux__)
len = strlen(entry->d_name);
#else
#if HAVE_STRUCT_DIRENT_D_NAMLEN
len = entry->d_namlen;
#else
len = strlen(entry->d_name);
#endif
temp = malloc(strlen(dirname) + len + 1);
@ -248,7 +252,7 @@ append_char_function(const char *name)
{
struct stat stbuf;
char *expname = *name == '~' ? fn_tilde_expand(name) : NULL;
const char *rs = "";
const char *rs = " ";
if (stat(expname ? expname : name, &stbuf) == -1)
goto out;
@ -338,9 +342,9 @@ _fn_qsort_string_compare(const void *i1, const void *i2)
* 'max' is maximum length of string in 'matches'.
*/
void
fn_display_match_list (EditLine *el, char **matches, int len, int max)
fn_display_match_list (EditLine *el, char **matches, size_t len, size_t max)
{
int i, idx, limit, count;
size_t i, idx, limit, count;
int screenwidth = el->el_term.t_size.h;
/*
@ -362,9 +366,12 @@ fn_display_match_list (EditLine *el, char **matches, int len, int max)
idx = 1;
for(; count > 0; count--) {
for(i = 0; i < limit && matches[idx]; i++, idx++)
(void)fprintf(el->el_outfile, "%-*s ", max,
matches[idx]);
int more = limit > 0 && matches[0];
for(i = 0; more; i++, idx++) {
more = ++i < limit && matches[idx + 1];
(void)fprintf(el->el_outfile, "%-*s%s", (int)max,
matches[idx], more ? " " : "");
}
(void)fprintf(el->el_outfile, "\n");
}
}
@ -385,13 +392,14 @@ int
fn_complete(EditLine *el,
char *(*complet_func)(const char *, int),
char **(*attempted_completion_function)(const char *, int, int),
const char *word_break, const char *special_prefixes,
const char *(*app_func)(const char *), int query_items,
const Char *word_break, const Char *special_prefixes,
const char *(*app_func)(const char *), size_t query_items,
int *completion_type, int *over, int *point, int *end)
{
const LineInfo *li;
char *temp, **matches;
const char *ctemp;
const TYPE(LineInfo) *li;
Char *temp;
char **matches;
const Char *ctemp;
size_t len;
int what_to_do = '\t';
int retval = CC_NORM;
@ -409,45 +417,45 @@ fn_complete(EditLine *el,
app_func = append_char_function;
/* We now look backwards for the start of a filename/variable word */
li = el_line(el);
ctemp = (const char *) li->cursor;
li = FUN(el,line)(el);
ctemp = li->cursor;
while (ctemp > li->buffer
&& !strchr(word_break, ctemp[-1])
&& (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) )
&& !Strchr(word_break, ctemp[-1])
&& (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) )
ctemp--;
len = li->cursor - ctemp;
#if defined(__SSP__) || defined(__SSP_ALL__)
temp = malloc(len + 1);
temp = malloc(sizeof(*temp) * (len + 1));
#else
temp = alloca(len + 1);
temp = alloca(sizeof(*temp) * (len + 1));
#endif
(void)strncpy(temp, ctemp, len);
(void)Strncpy(temp, ctemp, len);
temp[len] = '\0';
/* these can be used by function called in completion_matches() */
/* or (*attempted_completion_function)() */
if (point != 0)
*point = li->cursor - li->buffer;
*point = (int)(li->cursor - li->buffer);
if (end != NULL)
*end = li->lastchar - li->buffer;
*end = (int)(li->lastchar - li->buffer);
if (attempted_completion_function) {
int cur_off = li->cursor - li->buffer;
matches = (*attempted_completion_function) (temp,
int cur_off = (int)(li->cursor - li->buffer);
matches = (*attempted_completion_function) (ct_encode_string(temp, &el->el_scratch),
(int)(cur_off - len), cur_off);
} else
matches = 0;
if (!attempted_completion_function ||
(over != NULL && !*over && !matches))
matches = completion_matches(temp, complet_func);
matches = completion_matches(ct_encode_string(temp, &el->el_scratch), complet_func);
if (over != NULL)
*over = 0;
if (matches) {
int i;
int matches_num, maxlen, match_len, match_display=1;
size_t matches_num, maxlen, match_len, match_display=1;
retval = CC_REFRESH;
/*
@ -456,7 +464,8 @@ fn_complete(EditLine *el,
*/
if (matches[0][0] != '\0') {
el_deletestr(el, (int) len);
el_insertstr(el, matches[0]);
FUN(el,insertstr)(el,
ct_decode_string(matches[0], &el->el_scratch));
}
if (what_to_do == '?')
@ -468,7 +477,9 @@ fn_complete(EditLine *el,
* it, unless we do filename completion and the
* object is a directory.
*/
el_insertstr(el, (*append_char_function)(matches[0]));
FUN(el,insertstr)(el,
ct_decode_string((*app_func)(matches[0]),
&el->el_scratch));
} else if (what_to_do == '!') {
display_matches:
/*
@ -476,7 +487,7 @@ fn_complete(EditLine *el,
* matches.
*/
for(i=1, maxlen=0; matches[i]; i++) {
for(i = 1, maxlen = 0; matches[i]; i++) {
match_len = strlen(matches[i]);
if (match_len > maxlen)
maxlen = match_len;
@ -492,7 +503,7 @@ fn_complete(EditLine *el,
*/
if (matches_num > query_items) {
(void)fprintf(el->el_outfile,
"Display all %d possibilities? (y or n) ",
"Display all %zu possibilities? (y or n) ",
matches_num);
(void)fflush(el->el_outfile);
if (getc(stdin) != 'y')
@ -502,7 +513,7 @@ fn_complete(EditLine *el,
if (match_display)
fn_display_match_list(el, matches, matches_num,
maxlen);
maxlen);
retval = CC_REDISPLAY;
} else if (matches[0][0]) {
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: filecomplete.h,v 1.5 2006/08/21 12:45:30 christos Exp $ */
/* $NetBSD: filecomplete.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -15,9 +15,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. 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
@ -37,10 +34,10 @@
int fn_complete(EditLine *,
char *(*)(const char *, int),
char **(*)(const char *, int, int),
const char *, const char *, const char *(*)(const char *), int,
const Char *, const Char *, const char *(*)(const char *), size_t,
int *, int *, int *, int *);
void fn_display_match_list(EditLine *, char **, int, int);
void fn_display_match_list(EditLine *, char **, size_t, size_t);
char *fn_tilde_expand(const char *);
char *fn_filename_completion_function(const char *, int);

47
hist.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $ */
/* $NetBSD: hist.c,v 1.17 2009/12/30 23:54:52 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $");
__RCSID("$NetBSD: hist.c,v 1.17 2009/12/30 23:54:52 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -56,7 +56,7 @@ 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.buf = el_malloc(EL_BUFSIZ * sizeof(*el->el_history.buf));
el->el_history.sz = EL_BUFSIZ;
if (el->el_history.buf == NULL)
return (-1);
@ -97,11 +97,11 @@ hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr)
protected el_action_t
hist_get(EditLine *el)
{
const char *hp;
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,
(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);
@ -128,9 +128,10 @@ hist_get(EditLine *el)
el->el_history.eventno = h;
return (CC_ERROR);
}
(void) strlcpy(el->el_line.buffer, hp,
(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);
el->el_line.buffer[el->el_line.limit - el->el_line.buffer - 1] = '\0';
el->el_line.lastchar = el->el_line.buffer + Strlen(el->el_line.buffer);
if (el->el_line.lastchar > el->el_line.buffer
&& el->el_line.lastchar[-1] == '\n')
@ -153,33 +154,33 @@ hist_get(EditLine *el)
* process a history command
*/
protected int
hist_command(EditLine *el, int argc, const char **argv)
hist_command(EditLine *el, int argc, const Char **argv)
{
const char *str;
const Char *str;
int num;
HistEvent ev;
if (el->el_history.ref == NULL)
return (-1);
if (argc == 1 || strcmp(argv[1], "list") == 0) {
if (argc == 1 || Strcmp(argv[1], STR("list")) == 0) {
/* List history entries */
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
(void) fprintf(el->el_outfile, "%d %s",
el->el_history.ev.num, str);
el->el_history.ev.num, ct_encode_string(str, &el->el_scratch));
return (0);
}
if (argc != 3)
return (-1);
num = (int)strtol(argv[2], NULL, 0);
num = (int)Strtol(argv[2], NULL, 0);
if (strcmp(argv[1], "size") == 0)
if (Strcmp(argv[1], STR("size")) == 0)
return history(el->el_history.ref, &ev, H_SETSIZE, num);
if (strcmp(argv[1], "unique") == 0)
if (Strcmp(argv[1], STR("unique")) == 0)
return history(el->el_history.ref, &ev, H_SETUNIQUE, num);
return -1;
@ -193,13 +194,13 @@ protected int
/*ARGSUSED*/
hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
{
char *newbuf;
Char *newbuf;
newbuf = realloc(el->el_history.buf, newsz);
newbuf = el_realloc(el->el_history.buf, newsz * sizeof(*newbuf));
if (!newbuf)
return 0;
(void) memset(&newbuf[oldsz], '\0', newsz - oldsz);
(void) memset(&newbuf[oldsz], '\0', (newsz - oldsz) * sizeof(*newbuf));
el->el_history.last = newbuf +
(el->el_history.last - el->el_history.buf);
@ -208,3 +209,15 @@ hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
return 1;
}
#ifdef WIDECHAR
protected wchar_t *
hist_convert(EditLine *el, int fn, ptr_t arg)
{
HistEventW ev;
if ((*(el)->el_history.fun)((el)->el_history.ref, &ev, fn, arg) == -1)
return NULL;
return ct_decode_string((const char *)(const void *)ev.str,
&el->el_scratch);
}
#endif

25
hist.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: hist.h,v 1.10 2003/08/07 16:44:31 agc Exp $ */
/* $NetBSD: hist.h,v 1.12 2009/12/30 23:54:52 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -42,21 +42,29 @@
#include "histedit.h"
typedef int (*hist_fun_t)(ptr_t, HistEvent *, int, ...);
typedef int (*hist_fun_t)(ptr_t, TYPE(HistEvent) *, int, ...);
typedef struct el_history_t {
char *buf; /* The history buffer */
Char *buf; /* The history buffer */
size_t sz; /* Size of history buffer */
char *last; /* The last character */
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 */
TYPE(HistEvent) ev; /* Event cookie */
} el_history_t;
#define HIST_FUN(el, fn, arg) \
#define HIST_FUN_INTERNAL(el, fn, arg) \
((((*(el)->el_history.fun) ((el)->el_history.ref, &(el)->el_history.ev, \
fn, arg)) == -1) ? NULL : (el)->el_history.ev.str)
#ifdef WIDECHAR
#define HIST_FUN(el, fn, arg) \
(((el)->el_flags & NARROW_HISTORY) ? hist_convert(el, fn, arg) : \
HIST_FUN_INTERNAL(el, fn, arg))
#else
#define HIST_FUN(el, fn, arg) HIST_FUN_INTERNAL(el, fn, arg)
#endif
#define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL)
#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL)
@ -70,7 +78,10 @@ protected int hist_init(EditLine *);
protected void hist_end(EditLine *);
protected el_action_t hist_get(EditLine *);
protected int hist_set(EditLine *, hist_fun_t, ptr_t);
protected int hist_command(EditLine *, int, const char **);
protected int hist_command(EditLine *, int, const Char **);
protected int hist_enlargebuf(EditLine *, size_t, size_t);
#ifdef WIDECHAR
protected wchar_t *hist_convert(EditLine *, int, ptr_t);
#endif
#endif /* _h_el_hist */

View File

@ -1,4 +1,4 @@
/* $NetBSD: histedit.h,v 1.31 2006/12/15 22:13:33 christos Exp $ */
/* $NetBSD: histedit.h,v 1.46 2010/04/15 00:50:03 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -41,7 +41,9 @@
#define _HISTEDIT_H_
#define LIBEDIT_MAJOR 2
#define LIBEDIT_MINOR 10
#define LIBEDIT_MINOR 11
#include <stdint.h>
#include <sys/types.h>
#include <stdio.h>
@ -92,7 +94,7 @@ void el_reset(EditLine *);
*/
const char *el_gets(EditLine *, int *);
int el_getc(EditLine *, char *);
void el_push(EditLine *, char *);
void el_push(EditLine *, const char *);
/*
* Beep!
@ -114,30 +116,47 @@ unsigned char _el_fn_complete(EditLine *, int);
/*
* 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_BIND 4 /* , const char *, ..., NULL); */
#define EL_TELLTC 5 /* , const char *, ..., NULL); */
#define EL_SETTC 6 /* , const char *, ..., NULL); */
#define EL_ECHOTC 7 /* , const char *, ..., NULL); */
#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_EDITMODE 11 /* , int); */
#define EL_RPROMPT 12 /* , el_pfunc_t); */
#define EL_GETCFN 13 /* , el_rfunc_t); */
#define EL_CLIENTDATA 14 /* , void *); */
#define EL_UNBUFFERED 15 /* , int); */
#define EL_PREP_TERM 16 /* , int); */
#define EL_GETTC 17 /* , const char *, ..., NULL); */
#define EL_GETFP 18 /* , int, FILE **) */
#define EL_SETFP 19 /* , int, FILE *) */
*
* When using el_wset/el_wget (as opposed to el_set/el_get):
* Char is wchar_t, otherwise it is char.
* prompt_func is el_wpfunc_t, otherwise it is el_pfunc_t .
#define EL_BUILTIN_GETCFN (NULL)
* Prompt function prototypes are:
* typedef char *(*el_pfunct_t) (EditLine *);
* typedef wchar_t *(*el_wpfunct_t) (EditLine *);
*
* For operations that support set or set/get, the argument types listed are for
* the "set" operation. For "get", each listed type must be a pointer.
* E.g. EL_EDITMODE takes an int when set, but an int* when get.
*
* Operations that only support "get" have the correct argument types listed.
*/
#define EL_PROMPT 0 /* , prompt_func); set/get */
#define EL_TERMINAL 1 /* , const char *); set/get */
#define EL_EDITOR 2 /* , const Char *); set/get */
#define EL_SIGNAL 3 /* , int); set/get */
#define EL_BIND 4 /* , const Char *, ..., NULL); set */
#define EL_TELLTC 5 /* , const Char *, ..., NULL); set */
#define EL_SETTC 6 /* , const Char *, ..., NULL); set */
#define EL_ECHOTC 7 /* , const Char *, ..., NULL); set */
#define EL_SETTY 8 /* , const Char *, ..., NULL); set */
#define EL_ADDFN 9 /* , const Char *, const Char, set */
/* el_func_t); */
#define EL_HIST 10 /* , hist_fun_t, const ptr_t); set */
#define EL_EDITMODE 11 /* , int); set/get */
#define EL_RPROMPT 12 /* , prompt_func); set/get */
#define EL_GETCFN 13 /* , el_rfunc_t); set/get */
#define EL_CLIENTDATA 14 /* , void *); set/get */
#define EL_UNBUFFERED 15 /* , int); set/get */
#define EL_PREP_TERM 16 /* , int); set */
#define EL_GETTC 17 /* , const Char *, ..., NULL); get */
#define EL_GETFP 18 /* , int, FILE **); get */
#define EL_SETFP 19 /* , int, FILE *); set */
#define EL_REFRESH 20 /* , void); set */
#define EL_PROMPT_ESC 21 /* , prompt_func, Char); set/get */
#define EL_RPROMPT_ESC 22 /* , prompt_func, Char); set/get */
#define EL_BUILTIN_GETCFN (NULL)
/*
* Source named file or $PWD/.editrc or $HOME/.editrc
@ -187,12 +206,12 @@ int history(History *, HistEvent *, int, ...);
#define H_NEXT 6 /* , void); */
#define H_CURR 8 /* , const int); */
#define H_SET 7 /* , int); */
#define H_ADD 9 /* , const char *); */
#define H_ENTER 10 /* , const char *); */
#define H_APPEND 11 /* , const char *); */
#define H_ADD 9 /* , const wchar_t *); */
#define H_ENTER 10 /* , const wchar_t *); */
#define H_APPEND 11 /* , const wchar_t *); */
#define H_END 12 /* , void); */
#define H_NEXT_STR 13 /* , const char *); */
#define H_PREV_STR 14 /* , const char *); */
#define H_NEXT_STR 13 /* , const wchar_t *); */
#define H_PREV_STR 14 /* , const wchar_t *); */
#define H_NEXT_EVENT 15 /* , const int); */
#define H_PREV_EVENT 16 /* , const int); */
#define H_LOAD 17 /* , const char *); */
@ -201,6 +220,10 @@ int history(History *, HistEvent *, int, ...);
#define H_SETUNIQUE 20 /* , int); */
#define H_GETUNIQUE 21 /* , void); */
#define H_DEL 22 /* , int); */
#define H_NEXT_EVDATA 23 /* , const int, histdata_t *); */
#define H_DELDATA 24 /* , int, histdata_t *);*/
#define H_REPLACE 25 /* , const char *, histdata_t); */
/*
@ -220,6 +243,74 @@ int tok_line(Tokenizer *, const LineInfo *,
int tok_str(Tokenizer *, const char *,
int *, const char ***);
/*
* Begin Wide Character Support
*/
#ifdef __linux__
/* Apparently we need _GNU_SOURCE defined to get access to wcsdup on Linux */
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#endif
#include <wchar.h>
#include <wctype.h>
/*
* Wide character versions
*/
/*
* ==== Editing ====
*/
typedef struct lineinfow {
const wchar_t *buffer;
const wchar_t *cursor;
const wchar_t *lastchar;
} LineInfoW;
const wchar_t *el_wgets(EditLine *, int *);
int el_wgetc(EditLine *, wchar_t *);
void el_wpush(EditLine *, const wchar_t *);
int el_wparse(EditLine *, int, const wchar_t **);
int el_wset(EditLine *, int, ...);
int el_wget(EditLine *, int, ...);
const LineInfoW *el_wline(EditLine *);
int el_winsertstr(EditLine *, const wchar_t *);
#define el_wdeletestr el_deletestr
/*
* ==== History ====
*/
typedef struct histeventW {
int num;
const wchar_t *str;
} HistEventW;
typedef struct historyW HistoryW;
HistoryW * history_winit(void);
void history_wend(HistoryW *);
int history_w(HistoryW *, HistEventW *, int, ...);
/*
* ==== Tokenization ====
*/
typedef struct tokenizerW TokenizerW;
/* Wide character tokenizer support */
TokenizerW *tok_winit(const wchar_t *);
void tok_wend(TokenizerW *);
void tok_wreset(TokenizerW *);
int tok_wline(TokenizerW *, const LineInfoW *,
int *, const wchar_t ***, int *, int *);
int tok_wstr(TokenizerW *, const wchar_t *,
int *, const wchar_t ***);
#ifdef __cplusplus
}
#endif

337
history.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: history.c,v 1.32 2006/09/28 13:52:51 christos Exp $ */
/* $NetBSD: history.c,v 1.37 2010/01/03 18:27:10 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,12 +37,12 @@
#if 0
static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: history.c,v 1.32 2006/09/28 13:52:51 christos Exp $");
__RCSID("$NetBSD: history.c,v 1.37 2010/01/03 18:27:10 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/*
* hist.c: History access functions
* hist.c: TYPE(History) access functions
*/
#include <string.h>
#include <stdlib.h>
@ -57,13 +57,14 @@ __RCSID("$NetBSD: history.c,v 1.32 2006/09/28 13:52:51 christos Exp $");
static const char hist_cookie[] = "_HiStOrY_V2_\n";
#include "histedit.h"
#include "chartype.h"
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);
typedef int (*history_gfun_t)(ptr_t, TYPE(HistEvent) *);
typedef int (*history_efun_t)(ptr_t, TYPE(HistEvent) *, const Char *);
typedef void (*history_vfun_t)(ptr_t, TYPE(HistEvent) *);
typedef int (*history_sfun_t)(ptr_t, TYPE(HistEvent) *, const int);
struct history {
struct TYPE(history) {
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 */
@ -89,29 +90,29 @@ struct history {
#define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str)
#define HDEL(h, ev, n) (*(h)->h_del)((h)->h_ref, ev, n)
#define h_strdup(a) strdup(a)
#define h_strdup(a) Strdup(a)
#define h_malloc(a) malloc(a)
#define h_realloc(a, b) realloc((a), (b))
#define h_free(a) free(a)
typedef struct {
int num;
char *str;
Char *str;
} HistEventPrivate;
private int history_setsize(History *, HistEvent *, int);
private int history_getsize(History *, HistEvent *);
private int history_setunique(History *, HistEvent *, int);
private int history_getunique(History *, HistEvent *);
private int history_set_fun(History *, History *);
private int history_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 *);
private int history_setsize(TYPE(History) *, TYPE(HistEvent) *, int);
private int history_getsize(TYPE(History) *, TYPE(HistEvent) *);
private int history_setunique(TYPE(History) *, TYPE(HistEvent) *, int);
private int history_getunique(TYPE(History) *, TYPE(HistEvent) *);
private int history_set_fun(TYPE(History) *, TYPE(History) *);
private int history_load(TYPE(History) *, const char *);
private int history_save(TYPE(History) *, const char *);
private int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int);
private int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int);
private int history_next_string(TYPE(History) *, TYPE(HistEvent) *, const Char *);
private int history_prev_string(TYPE(History) *, TYPE(HistEvent) *, const Char *);
/***********************************************************************/
@ -120,7 +121,8 @@ private int history_prev_string(History *, HistEvent *, const char *);
* Builtin- history implementation
*/
typedef struct hentry_t {
HistEvent ev; /* What we return */
TYPE(HistEvent) ev; /* What we return */
void *data; /* data */
struct hentry_t *next; /* Next entry */
struct hentry_t *prev; /* Previous entry */
} hentry_t;
@ -131,24 +133,27 @@ typedef struct history_t {
int max; /* Maximum number of events */
int cur; /* Current number of events */
int eventid; /* For generation of unique event id */
int flags; /* History flags */
int flags; /* TYPE(History) flags */
#define H_UNIQUE 1 /* Store only unique elements */
} history_t;
private int history_def_next(ptr_t, HistEvent *);
private int history_def_first(ptr_t, HistEvent *);
private int history_def_prev(ptr_t, HistEvent *);
private int history_def_last(ptr_t, HistEvent *);
private int history_def_curr(ptr_t, HistEvent *);
private int history_def_set(ptr_t, HistEvent *, const int);
private void history_def_clear(ptr_t, HistEvent *);
private int history_def_enter(ptr_t, HistEvent *, const char *);
private int history_def_add(ptr_t, HistEvent *, const char *);
private int history_def_del(ptr_t, HistEvent *, const int);
private int history_def_next(ptr_t, TYPE(HistEvent) *);
private int history_def_first(ptr_t, TYPE(HistEvent) *);
private int history_def_prev(ptr_t, TYPE(HistEvent) *);
private int history_def_last(ptr_t, TYPE(HistEvent) *);
private int history_def_curr(ptr_t, TYPE(HistEvent) *);
private int history_def_set(ptr_t, TYPE(HistEvent) *, const int);
private void history_def_clear(ptr_t, TYPE(HistEvent) *);
private int history_def_enter(ptr_t, TYPE(HistEvent) *, const Char *);
private int history_def_add(ptr_t, TYPE(HistEvent) *, const Char *);
private int history_def_del(ptr_t, TYPE(HistEvent) *, const int);
private int history_def_init(ptr_t *, HistEvent *, int);
private int history_def_insert(history_t *, HistEvent *, const char *);
private void history_def_delete(history_t *, HistEvent *, hentry_t *);
private int history_def_init(ptr_t *, TYPE(HistEvent) *, int);
private int history_def_insert(history_t *, TYPE(HistEvent) *, const Char *);
private void history_def_delete(history_t *, TYPE(HistEvent) *, hentry_t *);
private int history_deldata_nth(history_t *, TYPE(HistEvent) *, int, void **);
private int history_set_nth(ptr_t, TYPE(HistEvent) *, int);
#define history_def_setsize(p, num)(void) (((history_t *)p)->max = (num))
#define history_def_getsize(p) (((history_t *)p)->cur)
@ -166,23 +171,23 @@ private void history_def_delete(history_t *, HistEvent *, hentry_t *);
}
/* 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"
static const Char *const he_errlist[] = {
STR("OK"),
STR("unknown error"),
STR("malloc() failed"),
STR("first event not found"),
STR("last event not found"),
STR("empty list"),
STR("no next event"),
STR("no previous event"),
STR("current event is invalid"),
STR("event not found"),
STR("can't read history from file"),
STR("can't write history"),
STR("required parameter(s) not supplied"),
STR("history size negative"),
STR("function not allowed with other history-functions-set the default"),
STR("bad parameters")
};
/* error codes */
#define _HE_OK 0
@ -206,7 +211,7 @@ static const char *const he_errlist[] = {
* Default function to return the first event in the history.
*/
private int
history_def_first(ptr_t p, HistEvent *ev)
history_def_first(ptr_t p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@ -226,7 +231,7 @@ history_def_first(ptr_t p, HistEvent *ev)
* Default function to return the last event in the history.
*/
private int
history_def_last(ptr_t p, HistEvent *ev)
history_def_last(ptr_t p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@ -246,7 +251,7 @@ history_def_last(ptr_t p, HistEvent *ev)
* Default function to return the next event in the history.
*/
private int
history_def_next(ptr_t p, HistEvent *ev)
history_def_next(ptr_t p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@ -271,7 +276,7 @@ history_def_next(ptr_t p, HistEvent *ev)
* Default function to return the previous event in the history.
*/
private int
history_def_prev(ptr_t p, HistEvent *ev)
history_def_prev(ptr_t p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@ -297,7 +302,7 @@ history_def_prev(ptr_t p, HistEvent *ev)
* Default function to return the current event in the history.
*/
private int
history_def_curr(ptr_t p, HistEvent *ev)
history_def_curr(ptr_t p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@ -318,7 +323,7 @@ history_def_curr(ptr_t p, HistEvent *ev)
* given one.
*/
private int
history_def_set(ptr_t p, HistEvent *ev, const int n)
history_def_set(ptr_t p, TYPE(HistEvent) *ev, const int n)
{
history_t *h = (history_t *) p;
@ -340,27 +345,53 @@ history_def_set(ptr_t p, HistEvent *ev, const int n)
}
/* history_set_nth():
* Default function to set the current event in the history to the
* n-th one.
*/
private int
history_set_nth(ptr_t p, TYPE(HistEvent) *ev, int n)
{
history_t *h = (history_t *) p;
if (h->cur == 0) {
he_seterrev(ev, _HE_EMPTY_LIST);
return (-1);
}
for (h->cursor = h->list.prev; h->cursor != &h->list;
h->cursor = h->cursor->prev)
if (n-- <= 0)
break;
if (h->cursor == &h->list) {
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
}
return (0);
}
/* history_def_add():
* Append string to element
*/
private int
history_def_add(ptr_t p, HistEvent *ev, const char *str)
history_def_add(ptr_t p, TYPE(HistEvent) *ev, const Char *str)
{
history_t *h = (history_t *) p;
size_t len;
char *s;
Char *s;
HistEventPrivate *evp = (void *)&h->cursor->ev;
if (h->cursor == &h->list)
return (history_def_enter(p, ev, str));
len = strlen(evp->str) + strlen(str) + 1;
s = (char *) h_malloc(len);
len = Strlen(evp->str) + Strlen(str) + 1;
s = h_malloc(len * sizeof(*s));
if (s == NULL) {
he_seterrev(ev, _HE_MALLOC_FAILED);
return (-1);
}
(void) strlcpy(s, h->cursor->ev.str, len);
(void) strlcat(s, str, len);
(void) Strncpy(s, h->cursor->ev.str, len);
s[len - 1] = '\0';
(void) Strncat(s, str, len - Strlen(s) - 1);
h_free((ptr_t)evp->str);
evp->str = s;
*ev = h->cursor->ev;
@ -368,18 +399,36 @@ history_def_add(ptr_t p, HistEvent *ev, const char *str)
}
private int
history_deldata_nth(history_t *h, TYPE(HistEvent) *ev,
int num, void **data)
{
if (history_set_nth(h, ev, num) != 0)
return (-1);
/* magic value to skip delete (just set to n-th history) */
if (data == (void **)-1)
return (0);
ev->str = Strdup(h->cursor->ev.str);
ev->num = h->cursor->ev.num;
if (data)
*data = h->cursor->data;
history_def_delete(h, ev, h->cursor);
return (0);
}
/* history_def_del():
* Delete element hp of the h list
*/
/* ARGSUSED */
private int
history_def_del(ptr_t p, HistEvent *ev __attribute__((__unused__)),
history_def_del(ptr_t p, TYPE(HistEvent) *ev __attribute__((__unused__)),
const int num)
{
history_t *h = (history_t *) p;
if (history_def_set(h, ev, num) != 0)
return (-1);
ev->str = strdup(h->cursor->ev.str);
ev->str = Strdup(h->cursor->ev.str);
ev->num = h->cursor->ev.num;
history_def_delete(h, ev, h->cursor);
return (0);
@ -392,13 +441,16 @@ history_def_del(ptr_t p, HistEvent *ev __attribute__((__unused__)),
/* ARGSUSED */
private void
history_def_delete(history_t *h,
HistEvent *ev __attribute__((__unused__)), hentry_t *hp)
TYPE(HistEvent) *ev __attribute__((__unused__)), hentry_t *hp)
{
HistEventPrivate *evp = (void *)&hp->ev;
if (hp == &h->list)
abort();
if (h->cursor == hp)
if (h->cursor == hp) {
h->cursor = hp->prev;
if (h->cursor == &h->list)
h->cursor = hp->next;
}
hp->prev->next = hp->next;
hp->next->prev = hp->prev;
h_free((ptr_t) evp->str);
@ -411,7 +463,7 @@ history_def_delete(history_t *h,
* Insert element with string str in the h list
*/
private int
history_def_insert(history_t *h, HistEvent *ev, const char *str)
history_def_insert(history_t *h, TYPE(HistEvent) *ev, const Char *str)
{
h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t));
@ -421,6 +473,7 @@ history_def_insert(history_t *h, HistEvent *ev, const char *str)
h_free((ptr_t)h->cursor);
goto oomem;
}
h->cursor->data = NULL;
h->cursor->ev.num = ++h->eventid;
h->cursor->next = h->list.next;
h->cursor->prev = &h->list;
@ -440,12 +493,12 @@ history_def_insert(history_t *h, HistEvent *ev, const char *str)
* Default function to enter an item in the history
*/
private int
history_def_enter(ptr_t p, HistEvent *ev, const char *str)
history_def_enter(ptr_t p, TYPE(HistEvent) *ev, const Char *str)
{
history_t *h = (history_t *) p;
if ((h->flags & H_UNIQUE) != 0 && h->list.next != &h->list &&
strcmp(h->list.next->ev.str, str) == 0)
Strcmp(h->list.next->ev.str, str) == 0)
return (0);
if (history_def_insert(h, ev, str) == -1)
@ -467,7 +520,7 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str)
*/
/* ARGSUSED */
private int
history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n)
history_def_init(ptr_t *p, TYPE(HistEvent) *ev __attribute__((__unused__)), int n)
{
history_t *h = (history_t *) h_malloc(sizeof(history_t));
if (h == NULL)
@ -492,7 +545,7 @@ history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n)
* Default history cleanup function
*/
private void
history_def_clear(ptr_t p, HistEvent *ev)
history_def_clear(ptr_t p, TYPE(HistEvent) *ev)
{
history_t *h = (history_t *) p;
@ -510,11 +563,11 @@ history_def_clear(ptr_t p, HistEvent *ev)
/* history_init():
* Initialization function.
*/
public History *
history_init(void)
public TYPE(History) *
FUN(history,init)(void)
{
HistEvent ev;
History *h = (History *) h_malloc(sizeof(History));
TYPE(HistEvent) ev;
TYPE(History) *h = (TYPE(History) *) h_malloc(sizeof(TYPE(History)));
if (h == NULL)
return NULL;
@ -542,9 +595,9 @@ history_init(void)
* clean up history;
*/
public void
history_end(History *h)
FUN(history,end)(TYPE(History) *h)
{
HistEvent ev;
TYPE(HistEvent) ev;
if (h->h_next == history_def_next)
history_def_clear(h->h_ref, &ev);
@ -558,7 +611,7 @@ history_end(History *h)
* Set history number of events
*/
private int
history_setsize(History *h, HistEvent *ev, int num)
history_setsize(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
{
if (h->h_next != history_def_next) {
@ -578,7 +631,7 @@ history_setsize(History *h, HistEvent *ev, int num)
* Get number of events currently in history
*/
private int
history_getsize(History *h, HistEvent *ev)
history_getsize(TYPE(History) *h, TYPE(HistEvent) *ev)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
@ -597,7 +650,7 @@ history_getsize(History *h, HistEvent *ev)
* Set if adjacent equal events should not be entered in history.
*/
private int
history_setunique(History *h, HistEvent *ev, int uni)
history_setunique(TYPE(History) *h, TYPE(HistEvent) *ev, int uni)
{
if (h->h_next != history_def_next) {
@ -613,7 +666,7 @@ history_setunique(History *h, HistEvent *ev, int uni)
* Get if adjacent equal events should not be entered in history.
*/
private int
history_getunique(History *h, HistEvent *ev)
history_getunique(TYPE(History) *h, TYPE(HistEvent) *ev)
{
if (h->h_next != history_def_next) {
he_seterrev(ev, _HE_NOT_ALLOWED);
@ -628,9 +681,9 @@ history_getunique(History *h, HistEvent *ev)
* Set history functions
*/
private int
history_set_fun(History *h, History *nh)
history_set_fun(TYPE(History) *h, TYPE(History) *nh)
{
HistEvent ev;
TYPE(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 ||
@ -671,17 +724,20 @@ history_set_fun(History *h, History *nh)
/* history_load():
* History load function
* TYPE(History) load function
*/
private int
history_load(History *h, const char *fname)
history_load(TYPE(History) *h, const char *fname)
{
FILE *fp;
char *line;
size_t sz, max_size;
char *ptr;
int i = -1;
HistEvent ev;
TYPE(HistEvent) ev;
#ifdef WIDECHAR
static ct_buffer_t conv;
#endif
if ((fp = fopen(fname, "r")) == NULL)
return (i);
@ -715,9 +771,9 @@ history_load(History *h, const char *fname)
}
(void) strunvis(ptr, line);
line[sz] = c;
if (HENTER(h, &ev, ptr) == -1) {
h_free((ptr_t)ptr);
return -1;
if (HENTER(h, &ev, ct_decode_string(ptr, &conv)) == -1) {
i = -1;
goto oomem;
}
}
oomem:
@ -729,16 +785,19 @@ history_load(History *h, const char *fname)
/* history_save():
* History save function
* TYPE(History) save function
*/
private int
history_save(History *h, const char *fname)
history_save(TYPE(History) *h, const char *fname)
{
FILE *fp;
HistEvent ev;
TYPE(HistEvent) ev;
int i = -1, retval;
size_t len, max_size;
char *ptr;
#ifdef WIDECHAR
static ct_buffer_t conv;
#endif
if ((fp = fopen(fname, "w")) == NULL)
return (-1);
@ -753,7 +812,7 @@ history_save(History *h, const char *fname)
for (i = 0, retval = HLAST(h, &ev);
retval != -1;
retval = HPREV(h, &ev), i++) {
len = strlen(ev.str) * 4;
len = Strlen(ev.str) * 4;
if (len >= max_size) {
char *nptr;
max_size = (len + 1024) & ~1023;
@ -764,7 +823,7 @@ history_save(History *h, const char *fname)
}
ptr = nptr;
}
(void) strvis(ptr, ev.str, VIS_WHITE);
(void) strvis(ptr, ct_encode_string(ev.str, &conv), VIS_WHITE);
(void) fprintf(fp, "%s\n", ptr);
}
oomem:
@ -779,7 +838,7 @@ history_save(History *h, const char *fname)
* Find the previous event, with number given
*/
private int
history_prev_event(History *h, HistEvent *ev, int num)
history_prev_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
{
int retval;
@ -792,11 +851,28 @@ history_prev_event(History *h, HistEvent *ev, int num)
}
private int
history_next_evdata(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d)
{
int retval;
for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
if (num-- <= 0) {
if (d)
*d = ((history_t *)h->h_ref)->cursor->data;
return (0);
}
he_seterrev(ev, _HE_NOT_FOUND);
return (-1);
}
/* history_next_event():
* Find the next event, with number given
*/
private int
history_next_event(History *h, HistEvent *ev, int num)
history_next_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num)
{
int retval;
@ -813,13 +889,13 @@ history_next_event(History *h, HistEvent *ev, int num)
* Find the previous event beginning with string
*/
private int
history_prev_string(History *h, HistEvent *ev, const char *str)
history_prev_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
{
size_t len = strlen(str);
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)
if (Strncmp(str, ev->str, len) == 0)
return (0);
he_seterrev(ev, _HE_NOT_FOUND);
@ -831,13 +907,13 @@ history_prev_string(History *h, HistEvent *ev, const char *str)
* Find the next event beginning with string
*/
private int
history_next_string(History *h, HistEvent *ev, const char *str)
history_next_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str)
{
size_t len = strlen(str);
size_t len = Strlen(str);
int retval;
for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev))
if (strncmp(str, ev->str, len) == 0)
if (Strncmp(str, ev->str, len) == 0)
return (0);
he_seterrev(ev, _HE_NOT_FOUND);
@ -849,10 +925,10 @@ history_next_string(History *h, HistEvent *ev, const char *str)
* User interface to history functions.
*/
int
history(History *h, HistEvent *ev, int fun, ...)
FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...)
{
va_list va;
const char *str;
const Char *str;
int retval;
va_start(va, fun);
@ -877,7 +953,7 @@ history(History *h, HistEvent *ev, int fun, ...)
break;
case H_ADD:
str = va_arg(va, const char *);
str = va_arg(va, const Char *);
retval = HADD(h, ev, str);
break;
@ -886,13 +962,13 @@ history(History *h, HistEvent *ev, int fun, ...)
break;
case H_ENTER:
str = va_arg(va, const char *);
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 *);
str = va_arg(va, const Char *);
if ((retval = HSET(h, ev, h->h_ent)) != -1)
retval = HADD(h, ev, str);
break;
@ -947,16 +1023,16 @@ history(History *h, HistEvent *ev, int fun, ...)
break;
case H_PREV_STR:
retval = history_prev_string(h, ev, va_arg(va, const char *));
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 *));
retval = history_next_string(h, ev, va_arg(va, const Char *));
break;
case H_FUNC:
{
History hf;
TYPE(History) hf;
hf.h_ref = va_arg(va, ptr_t);
h->h_ent = -1;
@ -977,15 +1053,46 @@ history(History *h, HistEvent *ev, int fun, ...)
}
case H_END:
history_end(h);
FUN(history,end)(h);
retval = 0;
break;
case H_NEXT_EVDATA:
{
int num = va_arg(va, int);
void **d = va_arg(va, void **);
retval = history_next_evdata(h, ev, num, d);
break;
}
case H_DELDATA:
{
int num = va_arg(va, int);
void **d = va_arg(va, void **);
retval = history_deldata_nth((history_t *)h->h_ref, ev, num, d);
break;
}
case H_REPLACE: /* only use after H_NEXT_EVDATA */
{
const Char *line = va_arg(va, const Char *);
void *d = va_arg(va, void *);
const Char *s;
if(!line || !(s = Strdup(line))) {
retval = -1;
break;
}
((history_t *)h->h_ref)->cursor->ev.str = s;
((history_t *)h->h_ref)->cursor->data = d;
retval = 0;
break;
}
default:
retval = -1;
he_seterrev(ev, _HE_UNKNOWN);
break;
}
va_end(va);
return (retval);
return retval;
}

181
key.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: key.c,v 1.19 2006/03/23 20:22:51 christos Exp $ */
/* $NetBSD: key.c,v 1.23 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: key.c,v 1.19 2006/03/23 20:22:51 christos Exp $");
__RCSID("$NetBSD: key.c,v 1.23 2009/12/30 22:37:40 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -72,7 +72,7 @@ __RCSID("$NetBSD: key.c,v 1.19 2006/03/23 20:22:51 christos Exp $");
* of these node elements
*/
struct key_node_t {
char ch; /* single character of key */
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 */
@ -80,17 +80,17 @@ struct key_node_t {
struct key_node_t *sibling; /* ptr to another key with same prefix*/
};
private int node_trav(EditLine *, key_node_t *, char *,
private int node_trav(EditLine *, key_node_t *, Char *,
key_value_t *);
private int node__try(EditLine *, key_node_t *, const char *,
private int node__try(EditLine *, key_node_t *, const Char *,
key_value_t *, int);
private key_node_t *node__get(int);
private key_node_t *node__get(Int);
private void node__free(key_node_t *);
private void node__put(EditLine *, key_node_t *);
private int node__delete(EditLine *, key_node_t **, const char *);
private int node_lookup(EditLine *, const char *, key_node_t *,
int);
private int node_enum(EditLine *, key_node_t *, int);
private int node__delete(EditLine *, key_node_t **, const Char *);
private int node_lookup(EditLine *, const Char *, key_node_t *,
size_t);
private int node_enum(EditLine *, key_node_t *, size_t);
#define KEY_BUFSIZ EL_BUFSIZ
@ -102,7 +102,7 @@ protected int
key_init(EditLine *el)
{
el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ);
el->el_key.buf = el_malloc(KEY_BUFSIZ * sizeof(*el->el_key.buf));
if (el->el_key.buf == NULL)
return (-1);
el->el_key.map = NULL;
@ -139,7 +139,7 @@ key_map_cmd(EditLine *el, int cmd)
* Associate str with a key value
*/
protected key_value_t *
key_map_str(EditLine *el, char *str)
key_map_str(EditLine *el, Char *str)
{
el->el_key.val.str = str;
@ -171,7 +171,7 @@ key_reset(EditLine *el)
* The last character read is returned in *ch.
*/
protected int
key_get(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));
@ -185,7 +185,7 @@ key_get(EditLine *el, char *ch, key_value_t *val)
* out str or a unix command.
*/
protected void
key_add(EditLine *el, const 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') {
@ -213,9 +213,12 @@ key_add(EditLine *el, const char *key, key_value_t *val, int ntype)
*
*/
protected void
key_clear(EditLine *el, el_action_t *map, const char *in)
key_clear(EditLine *el, el_action_t *map, const Char *in)
{
#ifdef WIDECHAR
if (*in > N_KEYS) /* can't be in the map */
return;
#endif
if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) &&
((map == el->el_map.key &&
el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) ||
@ -230,7 +233,7 @@ key_clear(EditLine *el, el_action_t *map, const char *in)
* they exists.
*/
protected int
key_delete(EditLine *el, const char *key)
key_delete(EditLine *el, const Char *key)
{
if (key[0] == '\0') {
@ -251,7 +254,7 @@ key_delete(EditLine *el, const char *key)
* Print entire el->el_key.map if null
*/
protected void
key_print(EditLine *el, const char *key)
key_print(EditLine *el, const Char *key)
{
/* do nothing if el->el_key.map is empty and null key specified */
@ -261,7 +264,7 @@ key_print(EditLine *el, const char *key)
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",
(void) fprintf(el->el_errfile, "Unbound extended key \"" FSTR "\"\n",
key);
return;
}
@ -272,14 +275,14 @@ key_print(EditLine *el, const char *key)
* found. May read in more characters.
*/
private int
node_trav(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 */
if (FUN(el,getc)(el, ch) != 1) {/* if EOF or error */
val->cmd = ED_END_OF_FILE;
return (XK_CMD);
/* PWP: Pretend we just read an end-of-file */
@ -309,7 +312,7 @@ node_trav(EditLine *el, key_node_t *ptr, char *ch, key_value_t *val)
* Find a node that matches *str or allocate a new one
*/
private int
node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int ntype)
node__try(EditLine *el, key_node_t *ptr, const Char *str, key_value_t *val, int ntype)
{
if (ptr->ch != *str) {
@ -350,7 +353,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
break;
case XK_STR:
case XK_EXE:
if ((ptr->val.str = el_strdup(val->str)) == NULL)
if ((ptr->val.str = Strdup(val->str)) == NULL)
return -1;
break;
default:
@ -371,7 +374,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
* Delete node that matches str
*/
private int
node__delete(EditLine *el, key_node_t **inptr, const char *str)
node__delete(EditLine *el, key_node_t **inptr, const Char *str)
{
key_node_t *ptr;
key_node_t *prev_ptr = NULL;
@ -451,7 +454,7 @@ node__put(EditLine *el, key_node_t *ptr)
* Returns pointer to a key_node_t for ch.
*/
private key_node_t *
node__get(int ch)
node__get(Int ch)
{
key_node_t *ptr;
@ -481,14 +484,14 @@ node__free(key_node_t *k)
* Print if last node
*/
private int
node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
node_lookup(EditLine *el, const Char *str, key_node_t *ptr, size_t cnt)
{
int ncnt;
ssize_t used;
if (ptr == NULL)
return (-1); /* cannot have null ptr */
if (*str == 0) {
if (!str || *str == 0) {
/* no more chars in str. node_enum from here. */
(void) node_enum(el, ptr, cnt);
return (0);
@ -496,17 +499,19 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
/* 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, KEY_BUFSIZ, cnt,
(unsigned char) ptr->ch);
used = ct_visual_char(el->el_key.buf + cnt,
KEY_BUFSIZ - cnt, ptr->ch);
if (used == -1)
return (-1); /* ran out of buffer space */
if (ptr->next != NULL)
/* not yet at leaf */
return (node_lookup(el, str + 1, ptr->next,
ncnt + 1));
used + cnt));
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';
el->el_key.buf[cnt + used ] = '"';
el->el_key.buf[cnt + used + 1] = '\0';
key_kprint(el, el->el_key.buf,
&ptr->val, ptr->type);
return (0);
@ -530,16 +535,16 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
* Traverse the node printing the characters it is bound in buffer
*/
private int
node_enum(EditLine *el, key_node_t *ptr, int cnt)
node_enum(EditLine *el, key_node_t *ptr, size_t cnt)
{
int ncnt;
ssize_t used;
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);
(void) fprintf(el->el_errfile, " \"" FSTR "...\"\n", el->el_key.buf);
return (0);
}
if (ptr == NULL) {
@ -550,15 +555,14 @@ node_enum(EditLine *el, key_node_t *ptr, int cnt)
return (-1);
}
/* put this char at end of str */
ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt,
(unsigned char)ptr->ch);
used = ct_visual_char(el->el_key.buf + cnt, KEY_BUFSIZ - cnt, ptr->ch);
if (ptr->next == NULL) {
/* print this key and function */
el->el_key.buf[ncnt + 1] = '"';
el->el_key.buf[ncnt + 2] = '\0';
el->el_key.buf[cnt + used ] = '"';
el->el_key.buf[cnt + used + 1] = '\0';
key_kprint(el, el->el_key.buf, &ptr->val, ptr->type);
} else
(void) node_enum(el, ptr->next, ncnt + 1);
(void) node_enum(el, ptr->next, cnt + used);
/* go to sibling if there is one */
if (ptr->sibling)
@ -572,7 +576,7 @@ node_enum(EditLine *el, key_node_t *ptr, int cnt)
* function specified by val
*/
protected void
key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
key_kprint(EditLine *el, const Char *key, key_value_t *val, int ntype)
{
el_bindings_t *fp;
char unparsbuf[EL_BUFSIZ];
@ -585,13 +589,16 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
(void) key__decode_str(val->str, unparsbuf,
sizeof(unparsbuf),
ntype == XK_STR ? "\"\"" : "[]");
(void) fprintf(el->el_outfile, fmt, key, unparsbuf);
(void) fprintf(el->el_outfile, fmt,
ct_encode_string(key, &el->el_scratch), unparsbuf);
break;
case XK_CMD:
for (fp = el->el_map.help; fp->name; fp++)
if (val->cmd == fp->func) {
ct_wcstombs(unparsbuf, fp->name, sizeof(unparsbuf));
unparsbuf[sizeof(unparsbuf) -1] = '\0';
(void) fprintf(el->el_outfile, fmt,
key, fp->name);
ct_encode_string(key, &el->el_scratch), unparsbuf);
break;
}
#ifdef DEBUG_KEY
@ -606,7 +613,8 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
break;
}
else
(void) fprintf(el->el_outfile, fmt, key, "no input");
(void) fprintf(el->el_outfile, fmt, ct_encode_string(key,
&el->el_scratch), "no input");
}
@ -615,52 +623,14 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
*b++ = c; \
else \
b++
/* key__decode_char():
* Put a printable form of char in buf.
*/
protected int
key__decode_char(char *buf, int cnt, int off, int ch)
{
char *sb = buf + off;
char *eb = buf + cnt;
char *b = sb;
if (ch == 0) {
ADDC('^');
ADDC('@');
return b - sb;
}
if (iscntrl(ch)) {
ADDC('^');
if (ch == '\177')
ADDC('?');
else
ADDC(ch | 0100);
} else if (ch == '^') {
ADDC('\\');
ADDC('^');
} else if (ch == '\\') {
ADDC('\\');
ADDC('\\');
} else if (ch == ' ' || (isprint(ch) && !isspace(ch))) {
ADDC(ch);
} else {
ADDC('\\');
ADDC((((unsigned int) ch >> 6) & 7) + '0');
ADDC((((unsigned int) ch >> 3) & 7) + '0');
ADDC((ch & 7) + '0');
}
return b - sb;
}
/* key__decode_str():
* Make a printable version of the ey
*/
protected int
key__decode_str(const char *str, char *buf, int len, const char *sep)
protected size_t
key__decode_str(const Char *str, char *buf, size_t len, const char *sep)
{
char *b = buf, *eb = b + len;
const char *p;
const Char *p;
b = buf;
if (sep[0] != '\0') {
@ -669,38 +639,27 @@ key__decode_str(const char *str, char *buf, int len, const char *sep)
if (*str == '\0') {
ADDC('^');
ADDC('@');
if (sep[0] != '\0' && sep[1] != '\0') {
ADDC(sep[1]);
}
goto done;
goto add_endsep;
}
for (p = str; *p != 0; p++) {
if (iscntrl((unsigned char) *p)) {
ADDC('^');
if (*p == '\177') {
ADDC('?');
} else {
ADDC(*p | 0100);
}
} else if (*p == '^' || *p == '\\') {
ADDC('\\');
ADDC(*p);
} else if (*p == ' ' || (isprint((unsigned char) *p) &&
!isspace((unsigned char) *p))) {
ADDC(*p);
} else {
ADDC('\\');
ADDC((((unsigned int) *p >> 6) & 7) + '0');
ADDC((((unsigned int) *p >> 3) & 7) + '0');
ADDC((*p & 7) + '0');
Char dbuf[VISUAL_WIDTH_MAX];
Char *p2 = dbuf;
ssize_t l = ct_visual_char(dbuf, VISUAL_WIDTH_MAX, *p);
while (l-- > 0) {
ssize_t n = ct_encode_char(b, (size_t)(eb - b), *p2++);
if (n == -1) /* ran out of space */
goto add_endsep;
else
b += n;
}
}
add_endsep:
if (sep[0] != '\0' && sep[1] != '\0') {
ADDC(sep[1]);
}
done:
ADDC('\0');
if (b - buf >= len)
if ((size_t)(b - buf) >= len)
buf[len - 1] = '\0';
return b - buf;
return (size_t)(b - buf);
}

23
key.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: key.h,v 1.10 2006/03/23 20:22:51 christos Exp $ */
/* $NetBSD: key.h,v 1.13 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -42,13 +42,13 @@
typedef union key_value_t {
el_action_t cmd; /* If it is a command the # */
char *str; /* If it is a string... */
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 */
Char *buf; /* Key print buffer */
key_node_t *map; /* Key map */
key_value_t val; /* Local conversion buffer */
} el_key_t;
@ -65,17 +65,16 @@ typedef struct el_key_t {
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 key_value_t *key_map_str(EditLine *, Char *);
protected void key_reset(EditLine *);
protected int key_get(EditLine *, char *, key_value_t *);
protected void key_add(EditLine *, const char *, key_value_t *, int);
protected void key_clear(EditLine *, el_action_t *, const char *);
protected int key_delete(EditLine *, const char *);
protected void key_print(EditLine *, const char *);
protected void key_kprint(EditLine *, const char *, key_value_t *,
protected int key_get(EditLine *, Char *, key_value_t *);
protected void key_add(EditLine *, const Char *, key_value_t *, int);
protected void key_clear(EditLine *, el_action_t *, const Char *);
protected int key_delete(EditLine *, const Char *);
protected void key_print(EditLine *, const Char *);
protected void key_kprint(EditLine *, const Char *, key_value_t *,
int);
protected int key__decode_str(const char *, char *, int,
protected size_t key__decode_str(const Char *, char *, size_t,
const char *);
protected int key__decode_char(char *, int, int, int);
#endif /* _h_el_key */

View File

@ -1,5 +1,5 @@
#!/bin/sh -
# $NetBSD: makelist,v 1.11 2005/10/22 16:45:03 christos Exp $
# $NetBSD: makelist,v 1.16 2010/04/18 21:17:05 christos Exp $
#
# Copyright (c) 1992, 1993
# The Regents of the University of California. All rights reserved.
@ -36,7 +36,7 @@
# makelist.sh: Automatically generate header files...
AWK=awk
USAGE="Usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
USAGE="Usage: $0 -n|-h|-e|-fc|-fh|-bc|-bh|-m <filenames>"
if [ "x$1" = "x" ]
then
@ -53,6 +53,14 @@ case $FLAG in
# generate foo.h file from foo.c
#
-n)
cat << _EOF
#undef WIDECHAR
#define NARROWCHAR
#include "${FILES}"
_EOF
;;
-h)
set - `echo $FILES | sed -e 's/\\./_/g'`
hdr="_h_`basename $1`"
@ -69,7 +77,7 @@ case $FLAG in
# XXX: need a space between name and prototype so that -fc and -fh
# parsing is much easier
#
printf("protected el_action_t\t%s (EditLine *, int);\n", name);
printf("protected el_action_t\t%s (EditLine *, Int);\n", name);
}
}
END {
@ -83,7 +91,8 @@ case $FLAG in
cat $FILES | $AWK '
BEGIN {
printf("/* Automatically generated file, do not edit */\n");
printf("#include \"sys.h\"\n#include \"el.h\"\n");
printf("#include \"config.h\"\n#include \"el.h\"\n");
printf("#include \"chartype.h\"\n");
printf("private const struct el_bindings_t el_func_help[] = {\n");
low = "abcdefghijklmnopqrstuvwxyz_";
high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_";
@ -104,16 +113,16 @@ case $FLAG in
fname = fname s;
}
printf(" { %-30.30s %-30.30s\n","\"" fname "\",", uname ",");
printf(" { %-30.30s %-30.30s\n","STR(\"" fname "\"),", uname ",");
ok = 1;
}
}
/^ \*/ {
if (ok) {
printf(" \"");
printf(" STR(\"");
for (i = 2; i < NF; i++)
printf("%s ", $i);
printf("%s\" },\n", $i);
printf("%s\") },\n", $i);
ok = 0;
}
}
@ -152,7 +161,7 @@ case $FLAG in
END {
printf("#define\t%-30.30s\t%3d\n", "EL_NUM_FCNS", count);
printf("typedef el_action_t (*el_func_t)(EditLine *, int);");
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");
}'
@ -164,7 +173,7 @@ case $FLAG in
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("#include \"config.h\"\n#include \"el.h\"\n");
printf("private const el_func_t el_func[] = {");
maxlen = 80;
needn = 1;

71
map.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: map.c,v 1.24 2006/04/09 01:36:51 christos Exp $ */
/* $NetBSD: map.c,v 1.25 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: map.c,v 1.24 2006/04/09 01:36:51 christos Exp $");
__RCSID("$NetBSD: map.c,v 1.25 2009/12/30 22:37:40 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -47,10 +47,8 @@ __RCSID("$NetBSD: map.c,v 1.24 2006/04/09 01:36:51 christos Exp $");
#include <stdlib.h>
#include "el.h"
#define N_KEYS 256
private void map_print_key(EditLine *, el_action_t *, const char *);
private void map_print_some_keys(EditLine *, el_action_t *, int, int);
private void map_print_key(EditLine *, el_action_t *, const Char *);
private void map_print_some_keys(EditLine *, el_action_t *, Int, Int);
private void map_print_all_keys(EditLine *);
private void map_init_nls(EditLine *);
private void map_init_meta(EditLine *);
@ -968,7 +966,7 @@ map_init_nls(EditLine *el)
el_action_t *map = el->el_map.key;
for (i = 0200; i <= 0377; i++)
if (isprint(i))
if (Isprint(i))
map[i] = ED_INSERT;
}
@ -979,7 +977,7 @@ map_init_nls(EditLine *el)
private void
map_init_meta(EditLine *el)
{
char buf[3];
Char buf[3];
int i;
el_action_t *map = el->el_map.key;
el_action_t *alt = el->el_map.alt;
@ -997,7 +995,7 @@ map_init_meta(EditLine *el)
} else
map = alt;
}
buf[0] = (char) i;
buf[0] = (Char) i;
buf[2] = 0;
for (i = 0200; i <= 0377; i++)
switch (map[i]) {
@ -1051,7 +1049,7 @@ protected void
map_init_emacs(EditLine *el)
{
int i;
char buf[3];
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;
@ -1082,14 +1080,14 @@ map_init_emacs(EditLine *el)
* Set the editor
*/
protected int
map_set_editor(EditLine *el, char *editor)
map_set_editor(EditLine *el, Char *editor)
{
if (strcmp(editor, "emacs") == 0) {
if (Strcmp(editor, STR("emacs")) == 0) {
map_init_emacs(el);
return (0);
}
if (strcmp(editor, "vi") == 0) {
if (Strcmp(editor, STR("vi")) == 0) {
map_init_vi(el);
return (0);
}
@ -1101,17 +1099,17 @@ map_set_editor(EditLine *el, char *editor)
* Retrieve the editor
*/
protected int
map_get_editor(EditLine *el, const char **editor)
map_get_editor(EditLine *el, const Char **editor)
{
if (editor == NULL)
return (-1);
switch (el->el_map.type) {
case MAP_EMACS:
*editor = "emacs";
*editor = STR("emacs");
return (0);
case MAP_VI:
*editor = "vi";
*editor = STR("vi");
return (0);
}
return (-1);
@ -1122,7 +1120,7 @@ map_get_editor(EditLine *el, const char **editor)
* Print the function description for 1 key
*/
private void
map_print_key(EditLine *el, el_action_t *map, const char *in)
map_print_key(EditLine *el, el_action_t *map, const Char *in)
{
char outbuf[EL_BUFSIZ];
el_bindings_t *bp, *ep;
@ -1133,7 +1131,7 @@ map_print_key(EditLine *el, el_action_t *map, const char *in)
for (bp = el->el_map.help; bp < ep; bp++)
if (bp->func == map[(unsigned char) *in]) {
(void) fprintf(el->el_outfile,
"%s\t->\t%s\n", outbuf, bp->name);
"%s\t->\t" FSTR "\n", outbuf, bp->name);
return;
}
} else
@ -1145,10 +1143,10 @@ map_print_key(EditLine *el, el_action_t *map, const char *in)
* Print keys from first to last
*/
private void
map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
map_print_some_keys(EditLine *el, el_action_t *map, Int first, Int last)
{
el_bindings_t *bp, *ep;
char firstbuf[2], lastbuf[2];
Char firstbuf[2], lastbuf[2];
char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ];
firstbuf[0] = first;
@ -1170,7 +1168,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
if (first == last) {
(void) key__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile, "%-15s-> %s\n",
(void) fprintf(el->el_outfile, "%-15s-> " FSTR "\n",
unparsbuf, bp->name);
} else {
(void) key__decode_str(firstbuf, unparsbuf,
@ -1178,7 +1176,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
(void) key__decode_str(lastbuf, extrabuf,
sizeof(extrabuf), STRQQ);
(void) fprintf(el->el_outfile,
"%-4s to %-7s-> %s\n",
"%-4s to %-7s-> " FSTR "\n",
unparsbuf, extrabuf, bp->name);
}
return;
@ -1234,9 +1232,9 @@ map_print_all_keys(EditLine *el)
map_print_some_keys(el, el->el_map.alt, prev, i - 1);
(void) fprintf(el->el_outfile, "Multi-character bindings\n");
key_print(el, "");
key_print(el, STR(""));
(void) fprintf(el->el_outfile, "Arrow key bindings\n");
term_print_arrow(el, "");
term_print_arrow(el, STR(""));
}
@ -1244,15 +1242,15 @@ map_print_all_keys(EditLine *el)
* Add/remove/change bindings
*/
protected int
map_bind(EditLine *el, int argc, const char **argv)
map_bind(EditLine *el, int argc, const Char **argv)
{
el_action_t *map;
int ntype, rem;
const char *p;
char inbuf[EL_BUFSIZ];
char outbuf[EL_BUFSIZ];
const char *in = NULL;
char *out = NULL;
const Char *p;
Char inbuf[EL_BUFSIZ];
Char outbuf[EL_BUFSIZ];
const Char *in = NULL;
Char *out = NULL;
el_bindings_t *bp, *ep;
int cmd;
int key;
@ -1298,12 +1296,12 @@ map_bind(EditLine *el, int argc, const char **argv)
ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++)
(void) fprintf(el->el_outfile,
"%s\n\t%s\n",
"" FSTR "\n\t" FSTR "\n",
bp->name, bp->description);
return (0);
default:
(void) fprintf(el->el_errfile,
"%s: Invalid switch `%c'.\n",
"" FSTR ": Invalid switch `%c'.\n",
argv[0], p[1]);
}
else
@ -1317,7 +1315,7 @@ map_bind(EditLine *el, int argc, const char **argv)
in = argv[argc++];
else if ((in = parse__string(inbuf, argv[argc++])) == NULL) {
(void) fprintf(el->el_errfile,
"%s: Invalid \\ or ^ in instring.\n",
"" FSTR ": Invalid \\ or ^ in instring.\n",
argv[0]);
return (-1);
}
@ -1353,7 +1351,7 @@ map_bind(EditLine *el, int argc, const char **argv)
case XK_EXE:
if ((out = parse__string(outbuf, argv[argc])) == NULL) {
(void) fprintf(el->el_errfile,
"%s: Invalid \\ or ^ in outstring.\n", argv[0]);
"" FSTR ": Invalid \\ or ^ in outstring.\n", argv[0]);
return (-1);
}
if (key)
@ -1366,7 +1364,8 @@ map_bind(EditLine *el, int argc, const char **argv)
case XK_CMD:
if ((cmd = parse_cmd(el, argv[argc])) == -1) {
(void) fprintf(el->el_errfile,
"%s: Invalid command `%s'.\n", argv[0], argv[argc]);
"" FSTR ": Invalid command `" FSTR "'.\n",
argv[0], argv[argc]);
return (-1);
}
if (key)
@ -1394,7 +1393,7 @@ map_bind(EditLine *el, int argc, const char **argv)
* add a user defined function
*/
protected int
map_addfunc(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)
{
void *p;
int nf = el->el_map.nfunc + 1;

16
map.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: map.h,v 1.8 2003/08/07 16:44:32 agc Exp $ */
/* $NetBSD: map.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -41,9 +41,9 @@
#define _h_el_map
typedef struct el_bindings_t { /* for the "bind" shell command */
const char *name; /* function name for bind command */
const Char *name; /* function name for bind command */
int func; /* function numeric value */
const char *description; /* description of function */
const Char *description; /* description of function */
} el_bindings_t;
@ -63,13 +63,15 @@ typedef struct el_map_t {
#define MAP_EMACS 0
#define MAP_VI 1
protected int map_bind(EditLine *, int, const char **);
#define N_KEYS 256
protected int map_bind(EditLine *, int, const Char **);
protected int map_init(EditLine *);
protected void map_end(EditLine *);
protected void map_init_vi(EditLine *);
protected void map_init_emacs(EditLine *);
protected int map_set_editor(EditLine *, char *);
protected int map_get_editor(EditLine *, const char **);
protected int map_addfunc(EditLine *, const char *, const char *, el_func_t);
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 */

92
parse.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $ */
/* $NetBSD: parse.c,v 1.23 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $");
__RCSID("$NetBSD: parse.c,v 1.23 2009/12/30 22:37:40 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -58,17 +58,17 @@ __RCSID("$NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $");
#include <stdlib.h>
private const struct {
const char *name;
int (*func)(EditLine *, int, const char **);
const Char *name;
int (*func)(EditLine *, int, const Char **);
} cmds[] = {
{ "bind", map_bind },
{ "echotc", term_echotc },
{ "edit", el_editmode },
{ "history", hist_command },
{ "telltc", term_telltc },
{ "settc", term_settc },
{ "setty", tty_stty },
{ NULL, NULL }
{ STR("bind"), map_bind },
{ STR("echotc"), term_echotc },
{ STR("edit"), el_editmode },
{ STR("history"), hist_command },
{ STR("telltc"), term_telltc },
{ STR("settc"), term_settc },
{ STR("setty"), tty_stty },
{ NULL, NULL }
};
@ -76,16 +76,16 @@ private const struct {
* Parse a line and dispatch it
*/
protected int
parse_line(EditLine *el, const char *line)
parse_line(EditLine *el, const Char *line)
{
const char **argv;
const Char **argv;
int argc;
Tokenizer *tok;
TYPE(Tokenizer) *tok;
tok = tok_init(NULL);
tok_str(tok, line, &argc, &argv);
argc = el_parse(el, argc, argv);
tok_end(tok);
tok = FUN(tok,init)(NULL);
FUN(tok,str)(tok, line, &argc, &argv);
argc = FUN(el,parse)(el, argc, argv);
FUN(tok,end)(tok);
return (argc);
}
@ -94,25 +94,25 @@ parse_line(EditLine *el, const char *line)
* Command dispatcher
*/
public int
el_parse(EditLine *el, int argc, const char *argv[])
FUN(el,parse)(EditLine *el, int argc, const Char *argv[])
{
const char *ptr;
const Char *ptr;
int i;
if (argc < 1)
return (-1);
ptr = strchr(argv[0], ':');
ptr = Strchr(argv[0], ':');
if (ptr != NULL) {
char *tprog;
Char *tprog;
size_t l;
if (ptr == argv[0])
return (0);
l = ptr - argv[0] - 1;
tprog = (char *) el_malloc(l + 1);
tprog = el_malloc((l + 1) * sizeof(*tprog));
if (tprog == NULL)
return (0);
(void) strncpy(tprog, argv[0], l);
(void) Strncpy(tprog, argv[0], l);
tprog[l] = '\0';
ptr++;
l = el_match(el->el_prog, tprog);
@ -123,7 +123,7 @@ el_parse(EditLine *el, int argc, const char *argv[])
ptr = argv[0];
for (i = 0; cmds[i].name != NULL; i++)
if (strcmp(cmds[i].name, ptr) == 0) {
if (Strcmp(cmds[i].name, ptr) == 0) {
i = (*cmds[i].func) (el, argc, argv);
return (-i);
}
@ -132,14 +132,14 @@ el_parse(EditLine *el, int argc, const char *argv[])
/* parse__escape():
* Parse a string of the form ^<char> \<odigit> \<char> and return
* Parse a string of the form ^<char> \<odigit> \<char> \U+xxxx and return
* the appropriate character or -1 if the escape is not valid
*/
protected int
parse__escape(const char **ptr)
parse__escape(const Char **ptr)
{
const char *p;
int c;
const Char *p;
Int c;
p = *ptr;
@ -173,6 +173,28 @@ parse__escape(const char **ptr)
case 'e':
c = '\033'; /* Escape */
break;
case 'U': /* Unicode \U+xxxx or \U+xxxxx format */
{
int i;
const Char hex[] = STR("0123456789ABCDEF");
const Char *h;
++p;
if (*p++ != '+')
return (-1);
c = 0;
for (i = 0; i < 5; ++i) {
h = Strchr(hex, *p++);
if (!h && i < 4)
return (-1);
else if (h)
c = (c << 4) | ((int)(h - hex));
else
--p;
}
if (c > 0x10FFFF) /* outside valid character range */
return -1;
break;
}
case '0':
case '1':
case '2':
@ -213,10 +235,10 @@ parse__escape(const char **ptr)
/* parse__string():
* Parse the escapes from in and put the raw string out
*/
protected char *
parse__string(char *out, const char *in)
protected Char *
parse__string(Char *out, const Char *in)
{
char *rv = out;
Char *rv = out;
int n;
for (;;)
@ -252,12 +274,12 @@ parse__string(char *out, const char *in)
* or -1 if one is not found
*/
protected int
parse_cmd(EditLine *el, const char *cmd)
parse_cmd(EditLine *el, const Char *cmd)
{
el_bindings_t *b;
for (b = el->el_map.help; b->name != NULL; b++)
if (strcmp(b->name, cmd) == 0)
if (Strcmp(b->name, cmd) == 0)
return (b->func);
return (-1);
}

10
parse.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.h,v 1.6 2005/05/29 04:58:15 lukem Exp $ */
/* $NetBSD: parse.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -40,9 +40,9 @@
#ifndef _h_el_parse
#define _h_el_parse
protected int parse_line(EditLine *, const char *);
protected int parse__escape(const char **);
protected char *parse__string(char *, const char *);
protected int parse_cmd(EditLine *, const char *);
protected int parse_line(EditLine *, const Char *);
protected int parse__escape(const Char **);
protected Char *parse__string(Char *, const Char *);
protected int parse_cmd(EditLine *, const Char *);
#endif /* _h_el_parse */

View File

@ -1,4 +1,4 @@
/* $NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $ */
/* $NetBSD: prompt.c,v 1.18 2009/12/31 15:58:26 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $");
__RCSID("$NetBSD: prompt.c,v 1.18 2009/12/31 15:58:26 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -47,17 +47,17 @@ __RCSID("$NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $");
#include <stdio.h>
#include "el.h"
private char *prompt_default(EditLine *);
private char *prompt_default_r(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 *
private Char *
/*ARGSUSED*/
prompt_default(EditLine *el __attribute__((__unused__)))
{
static char a[3] = {'?', ' ', '\0'};
static Char a[3] = {'?', ' ', '\0'};
return (a);
}
@ -66,11 +66,11 @@ prompt_default(EditLine *el __attribute__((__unused__)))
/* prompt_default_r():
* Just a default rprompt, in case the user did not provide one
*/
private char *
private Char *
/*ARGSUSED*/
prompt_default_r(EditLine *el __attribute__((__unused__)))
{
static char a[1] = {'\0'};
static Char a[1] = {'\0'};
return (a);
}
@ -78,23 +78,35 @@ prompt_default_r(EditLine *el __attribute__((__unused__)))
/* prompt_print():
* Print the prompt and update the prompt position.
* We use an array of integers in case we want to pass
* literal escape sequences in the prompt and we want a
* bit to flag them
*/
protected void
prompt_print(EditLine *el, int op)
{
el_prompt_t *elp;
char *p;
Char *p;
int ignore = 0;
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);
if (elp->p_wide)
p = (*elp->p_func)(el);
else
p = ct_decode_string((char *)(void *)(*elp->p_func)(el),
&el->el_scratch);
for (; *p; p++) {
if (elp->p_ignore == *p) {
ignore = !ignore;
continue;
}
if (ignore)
term__putc(el, *p);
else
re_putc(el, *p, 1);
}
elp->p_pos.v = el->el_refresh.r_cursor.v;
elp->p_pos.h = el->el_refresh.r_cursor.h;
@ -111,10 +123,12 @@ 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;
el->el_prompt.p_ignore = '\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);
el->el_rprompt.p_ignore = '\0';
return 0;
}
@ -132,24 +146,31 @@ prompt_end(EditLine *el __attribute__((__unused__)))
* Install a prompt printing function
*/
protected int
prompt_set(EditLine *el, el_pfunc_t prf, int op)
prompt_set(EditLine *el, el_pfunc_t prf, Char c, int op, int wide)
{
el_prompt_t *p;
if (op == EL_PROMPT)
if (op == EL_PROMPT || op == EL_PROMPT_ESC)
p = &el->el_prompt;
else
p = &el->el_rprompt;
if (prf == NULL) {
if (op == EL_PROMPT)
if (op == EL_PROMPT || op == EL_PROMPT_ESC)
p->p_func = prompt_default;
else
p->p_func = prompt_default_r;
} else
} else {
p->p_func = prf;
}
p->p_ignore = c;
p->p_pos.v = 0;
p->p_pos.h = 0;
return (0);
p->p_wide = wide;
return 0;
}
@ -157,14 +178,22 @@ prompt_set(EditLine *el, el_pfunc_t prf, int op)
* Retrieve the prompt printing function
*/
protected int
prompt_get(EditLine *el, el_pfunc_t *prf, int op)
prompt_get(EditLine *el, el_pfunc_t *prf, Char *c, int op)
{
el_prompt_t *p;
if (prf == NULL)
return (-1);
return -1;
if (op == EL_PROMPT)
*prf = el->el_prompt.p_func;
p = &el->el_prompt;
else
*prf = el->el_rprompt.p_func;
return (0);
p = &el->el_rprompt;
if (prf)
*prf = p->p_func;
if (c)
*c = p->p_ignore;
return 0;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: prompt.h,v 1.6 2003/08/07 16:44:32 agc Exp $ */
/* $NetBSD: prompt.h,v 1.10 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -42,16 +42,18 @@
#include "histedit.h"
typedef char * (*el_pfunc_t)(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 */
Char p_ignore; /* character to start/end literal */
int p_wide;
} el_prompt_t;
protected void prompt_print(EditLine *, int);
protected int prompt_set(EditLine *, el_pfunc_t, int);
protected int prompt_get(EditLine *, el_pfunc_t *, int);
protected int prompt_set(EditLine *, el_pfunc_t, Char, int, int);
protected int prompt_get(EditLine *, el_pfunc_t *, Char *, int);
protected int prompt_init(EditLine *);
protected void prompt_end(EditLine *);

212
read.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: read.c,v 1.39 2005/08/02 12:11:14 christos Exp $ */
/* $NetBSD: read.c,v 1.55 2010/03/22 22:59:06 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: read.c,v 1.39 2005/08/02 12:11:14 christos Exp $");
__RCSID("$NetBSD: read.c,v 1.55 2010/03/22 22:59:06 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -49,14 +49,16 @@ __RCSID("$NetBSD: read.c,v 1.39 2005/08/02 12:11:14 christos Exp $");
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
#include "el.h"
#define OKCMD -1
#define OKCMD -1 /* must be -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 *);
private int read_char(EditLine *, Char *);
private int read_getcmd(EditLine *, el_action_t *, Char *);
private void read_pop(c_macro_t *);
/* read_init():
* Initialize the read stuff
@ -190,6 +192,9 @@ read_preread(EditLine *el)
if (el->el_tty.t_mode == ED_IO)
return (0);
#ifndef WIDECHAR
/* FIONREAD attempts to buffer up multiple bytes, and to make that work
* properly with partial wide/UTF-8 characters would need some careful work. */
#ifdef FIONREAD
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
if (chrs > 0) {
@ -203,7 +208,7 @@ read_preread(EditLine *el)
}
}
#endif /* FIONREAD */
#endif
return (chrs > 0);
}
@ -212,33 +217,37 @@ read_preread(EditLine *el)
* Push a macro
*/
public void
el_push(EditLine *el, char *str)
FUN(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++;
if ((ma->macro[ma->level] = el_strdup(str)) != NULL)
if ((ma->macro[ma->level] = Strdup(str)) != NULL)
return;
ma->level--;
}
term_beep(el);
term__flush();
term__flush(el);
}
/* read_getcmd():
* Return next command from the input stream.
* Character values > 255 are not looked up in the map, but inserted.
*/
private int
read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
{
el_action_t cmd;
int num;
el->el_errno = 0;
do {
if ((num = el_getc(el, ch)) != 1) /* if EOF or error */
if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */
el->el_errno = num == 0 ? 0 : errno;
return (num);
}
#ifdef KANJI
if ((*ch & 0200)) {
@ -252,7 +261,12 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
el->el_state.metanext = 0;
*ch |= 0200;
}
cmd = el->el_map.current[(unsigned char) *ch];
#ifdef WIDECHAR
if (*ch >= N_KEYS)
cmd = ED_INSERT;
else
#endif
cmd = el->el_map.current[(unsigned char) *ch];
if (cmd == ED_SEQUENCE_LEAD_IN) {
key_value_t val;
switch (key_get(el, ch, &val)) {
@ -260,7 +274,7 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
cmd = val.cmd;
break;
case XK_STR:
el_push(el, val.str);
FUN(el,push)(el, val.str);
break;
#ifdef notyet
case XK_EXE:
@ -280,57 +294,117 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
return (OKCMD);
}
#ifdef WIDECHAR
/* utf8_islead():
* Test whether a byte is a leading byte of a UTF-8 sequence.
*/
private int
utf8_islead(unsigned char c)
{
return (c < 0x80) || /* single byte char */
(c >= 0xc2 && c <= 0xf4); /* start of multibyte sequence */
}
#endif
/* read_char():
* Read a character from the tty.
*/
private int
read_char(EditLine *el, char *cp)
read_char(EditLine *el, Char *cp)
{
int num_read;
ssize_t num_read;
int tried = 0;
char cbuf[MB_LEN_MAX];
int cbp = 0;
int bytes = 0;
while ((num_read = read(el->el_infd, cp, 1)) == -1)
again:
el->el_signal->sig_no = 0;
while ((num_read = read(el->el_infd, cbuf + cbp, 1)) == -1) {
if (el->el_signal->sig_no == SIGCONT) {
sig_set(el);
el_set(el, EL_REFRESH);
goto again;
}
if (!tried && read__fixio(el->el_infd, errno) == 0)
tried = 1;
else {
*cp = '\0';
return (-1);
}
}
return (num_read);
#ifdef WIDECHAR
if (el->el_flags & CHARSET_IS_UTF8) {
if (!utf8_islead((unsigned char)cbuf[0]))
goto again; /* discard the byte we read and try again */
++cbp;
if ((bytes = ct_mbtowc(cp, cbuf, cbp)) == -1) {
ct_mbtowc_reset;
if (cbp >= MB_LEN_MAX) { /* "shouldn't happen" */
*cp = '\0';
return (-1);
}
goto again;
}
} else /* we don't support other multibyte charsets */
#endif
*cp = (unsigned char)cbuf[0];
if ((el->el_flags & IGNORE_EXTCHARS) && bytes > 1) {
cbp = 0; /* skip this character */
goto again;
}
return (int)num_read;
}
/* read_pop():
* Pop a macro from the stack
*/
private void
read_pop(c_macro_t *ma)
{
int i;
el_free(ma->macro[0]);
for (i = 0; i < ma->level; i++)
ma->macro[i] = ma->macro[i + 1];
ma->level--;
ma->offset = 0;
}
/* el_getc():
* Read a character
*/
public int
el_getc(EditLine *el, char *cp)
FUN(el,getc)(EditLine *el, Char *cp)
{
int num_read;
c_macro_t *ma = &el->el_chared.c_macro;
term__flush();
term__flush(el);
for (;;) {
if (ma->level < 0) {
if (!read_preread(el))
break;
}
if (ma->level < 0)
break;
if (ma->macro[ma->level][ma->offset] == '\0') {
el_free(ma->macro[ma->level--]);
ma->offset = 0;
if (ma->macro[0][ma->offset] == '\0') {
read_pop(ma);
continue;
}
*cp = ma->macro[ma->level][ma->offset++] & 0377;
if (ma->macro[ma->level][ma->offset] == '\0') {
*cp = ma->macro[0][ma->offset++];
if (ma->macro[0][ma->offset] == '\0') {
/* Needed for QuoteMode On */
el_free(ma->macro[ma->level--]);
ma->offset = 0;
read_pop(ma);
}
return (1);
}
@ -344,6 +418,10 @@ el_getc(EditLine *el, char *cp)
(void) fprintf(el->el_errfile, "Reading a character\n");
#endif /* DEBUG_READ */
num_read = (*el->el_read.read_char)(el, cp);
#ifdef WIDECHAR
if (el->el_flags & NARROW_READ)
*cp = *(char *)(void *)cp;
#endif
#ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Got it %c\n", *cp);
#endif /* DEBUG_READ */
@ -368,7 +446,7 @@ read_prepare(EditLine *el)
re_refresh(el); /* print the prompt */
if (el->el_flags & UNBUFFERED)
term__flush();
term__flush(el);
}
protected void
@ -380,23 +458,28 @@ read_finish(EditLine *el)
sig_clr(el);
}
public const char *
el_gets(EditLine *el, int *nread)
public const Char *
FUN(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;
Char ch;
int crlf = 0;
int nrb;
#ifdef FIONREAD
c_macro_t *ma = &el->el_chared.c_macro;
#endif /* FIONREAD */
if (nread == NULL)
nread = &nrb;
*nread = 0;
if (el->el_flags & NO_TTY) {
char *cp = el->el_line.buffer;
Char *cp = el->el_line.buffer;
size_t idx;
while ((*el->el_read.read_char)(el, cp) == 1) {
while ((num = (*el->el_read.read_char)(el, cp)) == 1) {
/* make sure there is space for next character */
if (cp + 1 >= el->el_line.limit) {
idx = (cp - el->el_line.buffer);
@ -410,12 +493,16 @@ el_gets(EditLine *el, int *nread)
if (cp[-1] == '\r' || cp[-1] == '\n')
break;
}
if (num == -1) {
if (errno == EINTR)
cp = el->el_line.buffer;
el->el_errno = errno;
}
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);
*nread = (int)(el->el_line.cursor - el->el_line.buffer);
goto done;
}
@ -426,8 +513,8 @@ el_gets(EditLine *el, int *nread)
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs);
if (chrs == 0) {
if (tty_rawmode(el) < 0) {
if (nread)
*nread = 0;
errno = 0;
*nread = 0;
return (NULL);
}
}
@ -438,16 +525,17 @@ el_gets(EditLine *el, int *nread)
read_prepare(el);
if (el->el_flags & EDIT_DISABLED) {
char *cp;
Char *cp;
size_t idx;
if ((el->el_flags & UNBUFFERED) == 0)
cp = el->el_line.buffer;
else
cp = el->el_line.lastchar;
term__flush();
term__flush(el);
while ((*el->el_read.read_char)(el, cp) == 1) {
while ((num = (*el->el_read.read_char)(el, cp)) == 1) {
/* make sure there is space next character */
if (cp + 1 >= el->el_line.limit) {
idx = (cp - el->el_line.buffer);
@ -455,8 +543,6 @@ el_gets(EditLine *el, int *nread)
break;
cp = &el->el_line.buffer[idx];
}
if (*cp == 4) /* ought to be stty eof */
break;
cp++;
crlf = cp[-1] == '\r' || cp[-1] == '\n';
if (el->el_flags & UNBUFFERED)
@ -465,11 +551,15 @@ el_gets(EditLine *el, int *nread)
break;
}
if (num == -1) {
if (errno == EINTR)
cp = el->el_line.buffer;
el->el_errno = errno;
}
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);
goto done;
}
for (num = OKCMD; num == OKCMD;) { /* while still editing this
@ -485,7 +575,13 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_READ */
break;
}
if ((unsigned int)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
if (el->el_errno == EINTR) {
el->el_line.buffer[0] = '\0';
el->el_line.lastchar =
el->el_line.cursor = el->el_line.buffer;
break;
}
if ((unsigned int)cmdnum >= (unsigned int)el->el_map.nfunc) { /* BUG CHECK command */
#ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile,
"ERROR: illegal command from key 0%o\r\n", ch);
@ -515,7 +611,7 @@ el_gets(EditLine *el, int *nread)
el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
if (cmdnum == VI_DELETE_PREV_CHAR &&
el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
&& isprint((unsigned char)el->el_chared.c_redo.pos[-1]))
&& Isprint(el->el_chared.c_redo.pos[-1]))
el->el_chared.c_redo.pos--;
else
*el->el_chared.c_redo.pos++ = ch;
@ -567,7 +663,7 @@ el_gets(EditLine *el, int *nread)
break;
case CC_NEWLINE: /* normal end of line */
num = el->el_line.lastchar - el->el_line.buffer;
num = (int)(el->el_line.lastchar - el->el_line.buffer);
break;
case CC_FATAL: /* fatal error, reset to known state */
@ -588,7 +684,7 @@ el_gets(EditLine *el, int *nread)
"*** editor ERROR ***\r\n\n");
#endif /* DEBUG_READ */
term_beep(el);
term__flush();
term__flush(el);
break;
}
el->el_state.argument = 1;
@ -598,15 +694,21 @@ el_gets(EditLine *el, int *nread)
break;
}
term__flush(); /* flush any buffered output */
term__flush(el); /* flush any buffered output */
/* make sure the tty is set up correctly */
if ((el->el_flags & UNBUFFERED) == 0) {
read_finish(el);
if (nread)
*nread = num;
*nread = num != -1 ? num : 0;
} else {
if (nread)
*nread = el->el_line.lastchar - el->el_line.buffer;
*nread = (int)(el->el_line.lastchar - el->el_line.buffer);
}
return (num ? el->el_line.buffer : NULL);
done:
if (*nread == 0) {
if (num == -1) {
*nread = -1;
errno = el->el_errno;
}
return NULL;
} else
return el->el_line.buffer;
}

7
read.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: read.h,v 1.5 2006/08/21 12:45:30 christos Exp $ */
/* $NetBSD: read.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -15,9 +15,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of The NetBSD Foundation nor the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@ -38,7 +35,7 @@
#ifndef _h_el_read
#define _h_el_read
typedef int (*el_rfunc_t)(EditLine *, char *);
typedef int (*el_rfunc_t)(EditLine *, Char *);
typedef struct el_read_t {
el_rfunc_t read_char; /* Function to read a character */

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: readline.h,v 1.19 2006/11/24 00:01:17 christos Exp $ */
/* $NetBSD: readline.h,v 1.30 2009/09/07 21:24:34 christos Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -15,9 +15,6 @@
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. 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
@ -35,6 +32,7 @@
#define _READLINE_H_
#include <sys/types.h>
#include <stdio.h>
/* list of readline stuff supported by editline library's readline wrapper */
@ -44,10 +42,19 @@ typedef void VFunction(void);
typedef void VCPFunction(char *);
typedef char *CPFunction(const char *, int);
typedef char **CPPFunction(const char *, int, int);
typedef char *rl_compentry_func_t(const char *, int);
typedef int rl_command_func_t(int, int);
/* only supports length */
typedef struct {
int length;
} HISTORY_STATE;
typedef void *histdata_t;
typedef struct _hist_entry {
const char *line;
const char *data;
histdata_t data;
} HIST_ENTRY;
typedef struct _keymap_entry {
@ -68,7 +75,7 @@ typedef KEYMAP_ENTRY *Keymap;
#ifndef CTRL
#include <sys/ioctl.h>
#if !defined(__sun__) && !defined(__hpux__)
#if !defined(__sun) && !defined(__hpux) && !defined(_AIX)
#include <sys/ttydefaults.h>
#endif
#ifndef CTRL
@ -81,12 +88,16 @@ typedef KEYMAP_ENTRY *Keymap;
#define RUBOUT 0x7f
#define ABORT_CHAR CTRL('G')
#define RL_READLINE_VERSION 0x0402
#define RL_PROMPT_START_IGNORE '\1'
#define RL_PROMPT_END_IGNORE '\2'
/* global variables used by readline enabled applications */
#ifdef __cplusplus
extern "C" {
#endif
extern const char *rl_library_version;
extern int rl_readline_version;
extern char *rl_readline_name;
extern FILE *rl_instream;
extern FILE *rl_outstream;
@ -118,7 +129,7 @@ extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
emacs_ctlx_keymap;
extern int rl_filename_completion_desired;
extern int rl_ignore_completion_duplicates;
extern Function *rl_getc_function;
extern int (*rl_getc_function)(FILE *);
extern VFunction *rl_redisplay_function;
extern VFunction *rl_completion_display_matches_hook;
extern VFunction *rl_prep_term_function;
@ -140,6 +151,8 @@ int where_history(void);
HIST_ENTRY *current_history(void);
HIST_ENTRY *history_get(int);
HIST_ENTRY *remove_history(int);
/*###152 [lint] syntax error 'histdata_t' [249]%%%*/
HIST_ENTRY *replace_history_entry(int, const char *, histdata_t);
int history_total_bytes(void);
int history_set_pos(int);
HIST_ENTRY *previous_history(void);
@ -149,6 +162,7 @@ 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_truncate_file (const char *, int);
int history_expand(char *, char **);
char **history_tokenize(const char *);
const char *get_history_event(const char *, int *, int);
@ -163,8 +177,9 @@ char **completion_matches(const char *, CPFunction *);
void rl_display_match_list(char **, int, int);
int rl_insert(int, int);
int rl_insert_text(const char *);
void rl_reset_terminal(const char *);
int rl_bind_key(int, int (*)(int, int));
int rl_bind_key(int, rl_command_func_t *);
int rl_newline(int, int);
void rl_callback_read_char(void);
void rl_callback_handler_install(const char *, VCPFunction *);
@ -178,11 +193,15 @@ int rl_parse_and_bind(const char *);
int rl_variable_bind(const char *, const char *);
void rl_stuff_char(int);
int rl_add_defun(const char *, Function *, int);
HISTORY_STATE *history_get_history_state(void);
void rl_get_screen_size(int *, int *);
void rl_set_screen_size(int, int);
char *rl_filename_completion_function (const char *, int);
int _rl_abort_internal(void);
int _rl_qsort_string_compare(char **, char **);
char **rl_completion_matches(const char *, rl_compentry_func_t *);
void rl_forced_update_display(void);
int rl_set_prompt(const char *);
/*
* The following are not implemented
@ -192,7 +211,9 @@ Keymap rl_get_keymap(void);
void rl_set_keymap(Keymap);
Keymap rl_make_bare_keymap(void);
int rl_generic_bind(int, const char *, const char *, Keymap);
int rl_bind_key_in_map(int, Function *, Keymap);
int rl_bind_key_in_map(int, rl_command_func_t *, Keymap);
void rl_cleanup_after_signal(void);
void rl_free_line_state(void);
#ifdef __cplusplus
}
#endif

400
refresh.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: refresh.c,v 1.27 2005/11/09 22:11:10 christos Exp $ */
/* $NetBSD: refresh.c,v 1.35 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: refresh.c,v 1.27 2005/11/09 22:11:10 christos Exp $");
__RCSID("$NetBSD: refresh.c,v 1.35 2009/12/30 22:37:40 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -51,14 +51,15 @@ __RCSID("$NetBSD: refresh.c,v 1.27 2005/11/09 22:11:10 christos Exp $");
#include "el.h"
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_nextline(EditLine *);
private void re_addc(EditLine *, Int);
private void re_update_line(EditLine *, Char *, Char *, int);
private void re_insert (EditLine *, Char *, int, int, Char *, int);
private void re_delete(EditLine *, Char *, int, int, int);
private void re_fastputc(EditLine *, Int);
private void re_clear_eol(EditLine *, int, int, int);
private void re__strncopy(char *, char *, size_t);
private void re__copy_and_pad(char *, const char *, size_t);
private void re__strncopy(Char *, Char *, size_t);
private void re__copy_and_pad(Char *, const Char *, size_t);
#ifdef DEBUG_REFRESH
private void re_printstr(EditLine *, const char *, char *, char *);
@ -88,45 +89,70 @@ re_printstr(EditLine *el, const char *str, char *f, char *t)
#define ELRE_DEBUG(a, b)
#endif
/* re_nextline():
* Move to the next line or scroll
*/
private void
re_nextline(EditLine *el)
{
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_addc():
* Draw c, expanding tabs, control chars etc.
*/
private void
re_addc(EditLine *el, int c)
re_addc(EditLine *el, Int c)
{
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 */
switch (ct_chr_class((Char)c)) {
case CHTYPE_TAB: /* 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);
break;
case CHTYPE_NL: {
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 */
re_nextline(el);
break;
}
case CHTYPE_PRINT:
re_putc(el, c, 1);
break;
default: {
Char visbuf[VISUAL_WIDTH_MAX];
ssize_t i, n =
ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
for (i = 0; n-- > 0; ++i)
re_putc(el, visbuf[i], 1);
break;
}
}
}
@ -135,43 +161,31 @@ re_addc(EditLine *el, int c)
* Draw the character given
*/
protected void
re_putc(EditLine *el, int c, int shift)
re_putc(EditLine *el, Int c, int shift)
{
int i, w = Width(c);
ELRE_DEBUG(1, (__F, "printing %5x '%c'\r\n", c, c));
ELRE_DEBUG(1, (__F, "printing %3.3o '%c'\r\n", c, c));
while (shift && (el->el_refresh.r_cursor.h + w > el->el_term.t_size.h))
re_putc(el, ' ', 1);
el->el_vdisplay[el->el_refresh.r_cursor.v]
[el->el_refresh.r_cursor.h] = c;
/* assumes !shift is only used for single-column chars */
i = w;
while (--i > 0)
el->el_vdisplay[el->el_refresh.r_cursor.v]
[el->el_refresh.r_cursor.h + i] = MB_FILL_CHAR;
el->el_vdisplay[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 */
el->el_refresh.r_cursor.h += w; /* 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());
el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h]
= '\0';
re_nextline(el);
}
}
@ -186,7 +200,7 @@ protected void
re_refresh(EditLine *el)
{
int i, rhdiff;
char *cp, *st;
Char *cp, *st;
coord_t cur;
#ifdef notyet
size_t termsz;
@ -238,11 +252,18 @@ re_refresh(EditLine *el)
for (cp = st; cp < el->el_line.lastchar; cp++) {
if (cp == el->el_line.cursor) {
int w = Width(*cp);
/* save for later */
cur.h = el->el_refresh.r_cursor.h;
cur.v = el->el_refresh.r_cursor.v;
/* handle being at a linebroken doublewidth char */
if (w > 1 && el->el_refresh.r_cursor.h + w >
el->el_term.t_size.h) {
cur.h = 0;
cur.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 */
@ -273,7 +294,7 @@ re_refresh(EditLine *el)
ELRE_DEBUG(1, (__F,
"term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n",
el->el_term.t_size.h, el->el_refresh.r_cursor.h,
el->el_refresh.r_cursor.v, el->el_vdisplay[0]));
el->el_refresh.r_cursor.v, ct_encode_string(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++) {
@ -298,9 +319,10 @@ re_refresh(EditLine *el)
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]));
/* This Strlen should be safe even with MB_FILL_CHARs */
term_clear_EOL(el, (int) Strlen(el->el_display[i]));
#ifdef DEBUG_REFRESH
term_overwrite(el, "C\b", 2);
term_overwrite(el, "C\b", (size_t)2);
#endif /* DEBUG_REFRESH */
el->el_display[i][0] = '\0';
}
@ -323,9 +345,9 @@ re_goto_bottom(EditLine *el)
{
term_move_to_line(el, el->el_refresh.r_oldcv);
term__putc('\n');
term__putc(el, '\n');
re_clear_display(el);
term__flush();
term__flush(el);
}
@ -336,9 +358,9 @@ re_goto_bottom(EditLine *el)
private void
/*ARGSUSED*/
re_insert(EditLine *el __attribute__((__unused__)),
char *d, int dat, int dlen, char *s, int num)
Char *d, int dat, int dlen, Char *s, int num)
{
char *a, *b;
Char *a, *b;
if (num <= 0)
return;
@ -347,8 +369,8 @@ re_insert(EditLine *el __attribute__((__unused__)),
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));
num, dat, dlen, ct_encode_string(d)));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));
/* open up the space for num chars */
if (num > 0) {
@ -358,19 +380,24 @@ re_insert(EditLine *el __attribute__((__unused__)),
*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));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
num, dat, dlen, ct_encode_string(d)));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));
/* copy the characters */
for (a = d + dat; (a < d + dlen) && (num > 0); num--)
*a++ = *s++;
#ifdef notyet
/* ct_encode_string() uses a static buffer, so we can't conveniently
* encode both d & s here */
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));
#endif
}
@ -380,9 +407,9 @@ re_insert(EditLine *el __attribute__((__unused__)),
private void
/*ARGSUSED*/
re_delete(EditLine *el __attribute__((__unused__)),
char *d, int dat, int dlen, int num)
Char *d, int dat, int dlen, int num)
{
char *a, *b;
Char *a, *b;
if (num <= 0)
return;
@ -392,7 +419,7 @@ re_delete(EditLine *el __attribute__((__unused__)),
}
ELRE_DEBUG(1,
(__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, d));
num, dat, dlen, ct_encode_string(d)));
/* open up the space for num chars */
if (num > 0) {
@ -404,7 +431,7 @@ re_delete(EditLine *el __attribute__((__unused__)),
}
ELRE_DEBUG(1,
(__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, d));
num, dat, dlen, ct_encode_string(d)));
}
@ -412,7 +439,7 @@ re_delete(EditLine *el __attribute__((__unused__)),
* Like strncpy without padding.
*/
private void
re__strncopy(char *a, char *b, size_t n)
re__strncopy(Char *a, Char *b, size_t n)
{
while (n-- && *b)
@ -423,7 +450,7 @@ re__strncopy(char *a, char *b, size_t n)
* Find the number of characters we need to clear till the end of line
* in order to make sure that we have cleared the previous contents of
* the line. fx and sx is the number of characters inserted or deleted
* int the first or second diff, diff is the difference between the
* in the first or second diff, diff is the difference between the
* number of characters between the new and old line.
*/
private void
@ -471,12 +498,13 @@ new: eddie> Oh, my little buggy says to me, as lurgid as
#define MIN_END_KEEP 4
private void
re_update_line(EditLine *el, char *old, char *new, int i)
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;
Char *o, *n, *p, c;
Char *ofd, *ols, *oe, *nfd, *nls, *ne;
Char *osb, *ose, *nsb, *nse;
int fx, sx;
size_t len;
/*
* find first diff
@ -603,12 +631,12 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* 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);
fx = (int)((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);
sx = (int)((nls - nse) - (ols - ose));
if (!EL_CAN_INSERT) {
if (fx > 0) {
@ -657,8 +685,8 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/*
* Now that we are done with pragmatics we recompute fx, sx
*/
fx = (nsb - nfd) - (osb - ofd);
sx = (nls - nse) - (ols - ose);
fx = (int)((nsb - nfd) - (osb - ofd));
sx = (int)((nls - nse) - (ols - ose));
ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx));
ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
@ -741,7 +769,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/*
* Move to the first char to insert, where the first diff is.
*/
term_move_to_char(el, nfd - new);
term_move_to_char(el, (int)(nfd - new));
/*
* Check if we have stuff to keep at end
*/
@ -754,20 +782,21 @@ re_update_line(EditLine *el, char *old, char *new, int i)
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,
re_insert(el, old, (int)(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));
len = (size_t) ((nsb - nfd) - fx);
term_overwrite(el, (nfd + fx), len);
re__strncopy(ofd + fx, nfd + fx, len);
} 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));
len = (size_t)(nsb - nfd);
term_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
/*
* Done
*/
@ -779,7 +808,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/*
* move to the first char to delete where the first diff is
*/
term_move_to_char(el, ofd - old);
term_move_to_char(el, (int)(ofd - old));
/*
* Check if we have stuff to save
*/
@ -793,14 +822,15 @@ re_update_line(EditLine *el, char *old, char *new, int i)
ELRE_DEBUG(!EL_CAN_DELETE, (__F,
"ERROR: cannot delete in first diff\n"));
term_deletechars(el, -fx);
re_delete(el, old, ofd - old,
re_delete(el, old, (int)(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));
len = (size_t) (nsb - nfd);
term_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
} else {
ELRE_DEBUG(1, (__F,
@ -808,8 +838,9 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/*
* write (nsb-nfd) chars of new starting at nfd
*/
term_overwrite(el, nfd, (nsb - nfd));
re_clear_eol(el, fx, sx, (oe - old) - (ne - new));
term_overwrite(el, nfd, (size_t)(nsb - nfd));
re_clear_eol(el, fx, sx,
(int)((oe - old) - (ne - new)));
/*
* Done
*/
@ -828,7 +859,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* fx is the number of characters inserted (+) or deleted (-)
*/
term_move_to_char(el, (ose - old) + fx);
term_move_to_char(el, (int)((ose - old) + fx));
/*
* Check if we have stuff to save
*/
@ -845,12 +876,13 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/*
* write (nls-nse) chars of new starting at nse
*/
term_overwrite(el, nse, (nls - nse));
term_overwrite(el, nse, (size_t)(nls - nse));
} else {
ELRE_DEBUG(1, (__F,
"but with nothing left to save\r\n"));
term_overwrite(el, nse, (nls - nse));
re_clear_eol(el, fx, sx, (oe - old) - (ne - new));
term_overwrite(el, nse, (size_t)(nls - nse));
re_clear_eol(el, fx, sx,
(int)((oe - old) - (ne - new)));
}
}
/*
@ -860,7 +892,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n",
nfd - new));
term_move_to_char(el, nfd - new);
term_move_to_char(el, (int)(nfd - new));
/*
* Check if we have stuff to keep at the end
*/
@ -871,7 +903,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* to zero above as a flag saying that we hadn't done
* an early first insert.
*/
fx = (nsb - nfd) - (osb - ofd);
fx = (int)((nsb - nfd) - (osb - ofd));
if (fx > 0) {
/*
* insert fx chars of new starting at nfd
@ -879,20 +911,21 @@ re_update_line(EditLine *el, char *old, char *new, int i)
ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in late first diff\n"));
term_insertwrite(el, nfd, fx);
re_insert(el, old, ofd - old,
re_insert(el, old, (int)(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));
len = (size_t) ((nsb - nfd) - fx);
term_overwrite(el, (nfd + fx), len);
re__strncopy(ofd + fx, nfd + fx, len);
} 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));
len = (size_t) (nsb - nfd);
term_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
}
}
/*
@ -900,8 +933,8 @@ re_update_line(EditLine *el, char *old, char *new, int i)
*/
if (sx >= 0) {
ELRE_DEBUG(1, (__F,
"second diff insert at %d...\r\n", nse - new));
term_move_to_char(el, nse - new);
"second diff insert at %d...\r\n", (int)(nse - new)));
term_move_to_char(el, (int)(nse - new));
if (ols != oe) {
ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
if (sx > 0) {
@ -914,10 +947,11 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* write (nls-nse) - sx chars of new starting at
* (nse + sx)
*/
term_overwrite(el, nse + sx, (nls - nse) - sx);
term_overwrite(el, (nse + sx),
(size_t)((nls - nse) - sx));
} else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
term_overwrite(el, nse, (nls - nse));
term_overwrite(el, nse, (size_t)(nls - nse));
/*
* No need to do a clear-to-end here because we were
@ -934,7 +968,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* Copy string and pad with spaces
*/
private void
re__copy_and_pad(char *dst, const char *src, size_t width)
re__copy_and_pad(Char *dst, const Char *src, size_t width)
{
size_t i;
@ -957,8 +991,8 @@ re__copy_and_pad(char *dst, const char *src, size_t width)
protected void
re_refresh_cursor(EditLine *el)
{
char *cp, c;
int h, v, th;
Char *cp;
int h, v, th, w;
if (el->el_line.cursor >= el->el_line.lastchar) {
if (el->el_map.current == el->el_map.alt
@ -975,43 +1009,42 @@ re_refresh_cursor(EditLine *el)
/* 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 */
switch (ct_chr_class(*cp)) {
case CHTYPE_NL: /* 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++;
}
break;
case CHTYPE_TAB: /* if a tab, to next tab stop */
while (++h & 07)
continue;
break;
default:
w = Width(*cp);
if (w > 1 && h + w > th) { /* won't fit on line */
h = 0;
v++;
}
}
h += ct_visual_width(*cp);
break;
}
if (h >= th) { /* check, extra long tabs picked up here also */
h = 0;
h -= th;
v++;
}
}
/* if we have a next character, and it's a doublewidth one, we need to
* check whether we need to linebreak for it to fit */
if (cp < el->el_line.lastchar && (w = Width(*cp)) > 1)
if (h + w > th) {
h = 0;
v++;
}
/* now go there */
term_move_to_line(el, v);
term_move_to_char(el, h);
term__flush();
term__flush(el);
}
@ -1019,11 +1052,18 @@ re_refresh_cursor(EditLine *el)
* Add a character fast.
*/
private void
re_fastputc(EditLine *el, int c)
re_fastputc(EditLine *el, Int c)
{
int w = Width((Char)c);
while (w > 1 && el->el_cursor.h + w > el->el_term.t_size.h)
re_fastputc(el, ' ');
term__putc(c);
term__putc(el, c);
el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
while (--w > 0)
el->el_display[el->el_cursor.v][el->el_cursor.h++]
= MB_FILL_CHAR;
if (el->el_cursor.h >= el->el_term.t_size.h) {
/* if we must overflow */
el->el_cursor.h = 0;
@ -1036,25 +1076,25 @@ re_fastputc(EditLine *el, int c)
*/
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];
Char *firstline = el->el_display[0];
for(i=1; i < lins; i++)
el->el_display[i-1] = el->el_display[i];
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;
re__copy_and_pad(firstline, STR(""), 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');
term__putc(el, ' ');
term__putc(el, '\b');
}
} else {
term__putc('\r');
term__putc('\n');
term__putc(el, '\r');
term__putc(el, '\n');
}
}
}
@ -1067,7 +1107,7 @@ re_fastputc(EditLine *el, int c)
protected void
re_fastaddc(EditLine *el)
{
char c;
Char c;
int rhdiff;
c = el->el_line.cursor[-1];
@ -1082,19 +1122,24 @@ re_fastaddc(EditLine *el)
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 */
switch (ct_chr_class(c)) {
case CHTYPE_TAB: /* already handled, should never happen here */
break;
case CHTYPE_NL:
case CHTYPE_PRINT:
re_fastputc(el, c);
} else {
re_fastputc(el, '\\');
re_fastputc(el, (int)(((((unsigned int)c) >> 6) & 3) + '0'));
re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0'));
re_fastputc(el, (c & 7) + '0');
break;
case CHTYPE_ASCIICTL:
case CHTYPE_NONPRINT: {
Char visbuf[VISUAL_WIDTH_MAX];
ssize_t i, n =
ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c);
for (i = 0; n-- > 0; ++i)
re_fastputc(el, visbuf[i]);
break;
}
term__flush();
}
term__flush(el);
}
@ -1123,17 +1168,16 @@ 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 (i = el->el_refresh.r_oldcv; i >= 0; i--) {
/* for each line on the screen */
term_move_to_line(el, i);
term_move_to_char(el, 0);
term_clear_EOL(el, el->el_term.t_size.h);
}
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__putc(el, '\r'); /* go to BOL */
term__putc(el, '\n'); /* go to new line */
}
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: refresh.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */
/* $NetBSD: refresh.h,v 1.6 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -48,7 +48,7 @@ typedef struct {
int r_newcv;
} el_refresh_t;
protected void re_putc(EditLine *, int, int);
protected void re_putc(EditLine *, Int, int);
protected void re_clear_lines(EditLine *);
protected void re_clear_display(EditLine *);
protected void re_refresh(EditLine *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $ */
/* $NetBSD: search.c,v 1.24 2010/04/15 00:57:33 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $");
__RCSID("$NetBSD: search.c,v 1.24 2010/04/15 00:57:33 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -66,7 +66,8 @@ protected int
search_init(EditLine *el)
{
el->el_search.patbuf = (char *) el_malloc(EL_BUFSIZ);
el->el_search.patbuf = el_malloc(EL_BUFSIZ *
sizeof(*el->el_search.patbuf));
if (el->el_search.patbuf == NULL)
return (-1);
el->el_search.patlen = 0;
@ -106,8 +107,11 @@ regerror(const char *msg)
* Return if string matches pattern
*/
protected int
el_match(const char *str, const char *pat)
el_match(const Char *str, const Char *pat)
{
#ifdef WIDECHAR
static ct_buffer_t conv;
#endif
#if defined (REGEX)
regex_t re;
int rv;
@ -119,30 +123,30 @@ el_match(const char *str, const char *pat)
extern int re_exec(const char *);
#endif
if (strstr(str, pat) != NULL)
if (Strstr(str, pat) != 0)
return (1);
#if defined(REGEX)
if (regcomp(&re, pat, 0) == 0) {
rv = regexec(&re, str, 0, NULL, 0) == 0;
if (regcomp(&re, ct_encode_string(pat, &conv), 0) == 0) {
rv = regexec(&re, ct_encode_string(str, &conv), 0, NULL, 0) == 0;
regfree(&re);
} else {
rv = 0;
}
return (rv);
#elif defined(REGEXP)
if ((re = regcomp(pat)) != NULL) {
rv = regexec(re, str);
if ((re = regcomp(ct_encode_string(pat, &conv))) != NULL) {
rv = regexec(re, ct_encode_string(str, &conv));
free((ptr_t) re);
} else {
rv = 0;
}
return (rv);
#else
if (re_comp(pat) != NULL)
if (re_comp(ct_encode_string(pat, &conv)) != NULL)
return (0);
else
return (re_exec(str) == 1);
return (re_exec(ct_encode_string(str, &conv)) == 1);
#endif
}
@ -151,7 +155,7 @@ el_match(const char *str, const char *pat)
* return True if the pattern matches the prefix
*/
protected int
c_hmatch(EditLine *el, const char *str)
c_hmatch(EditLine *el, const Char *str)
{
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "match `%s' with `%s'\n",
@ -174,11 +178,11 @@ c_setpat(EditLine *el)
if (el->el_search.patlen >= EL_BUFSIZ)
el->el_search.patlen = EL_BUFSIZ - 1;
if (el->el_search.patlen != 0) {
(void) strncpy(el->el_search.patbuf, el->el_line.buffer,
(void) 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);
el->el_search.patlen = Strlen(el->el_search.patbuf);
}
#ifdef SDEBUG
(void) fprintf(el->el_errfile, "\neventno = %d\n",
@ -199,21 +203,22 @@ c_setpat(EditLine *el)
protected el_action_t
ce_inc_search(EditLine *el, int dir)
{
static const char STRfwd[] = {'f', 'w', 'd', '\0'},
static const Char STRfwd[] = {'f', 'w', 'd', '\0'},
STRbck[] = {'b', 'c', 'k', '\0'};
static char pchar = ':';/* ':' = normal, '?' = failed */
static char endcmd[2] = {'\0', '\0'};
char ch, *ocursor = el->el_line.cursor, oldpchar = pchar;
const char *cp;
static 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;
int ohisteventno = el->el_history.eventno;
int oldpatlen = el->el_search.patlen;
size_t oldpatlen = el->el_search.patlen;
int newdir = dir;
int done, redo;
if (el->el_line.lastchar + sizeof(STRfwd) / sizeof(char) + 2 +
if (el->el_line.lastchar + sizeof(STRfwd) /
sizeof(*el->el_line.lastchar) + 2 +
el->el_search.patlen >= el->el_line.limit)
return (CC_ERROR);
@ -242,7 +247,7 @@ ce_inc_search(EditLine *el, int dir)
*el->el_line.lastchar = '\0';
re_refresh(el);
if (el_getc(el, &ch) != 1)
if (FUN(el,getc)(el, &ch) != 1)
return (ed_end_of_file(el, 0));
switch (el->el_map.current[(unsigned char) ch]) {
@ -318,7 +323,7 @@ ce_inc_search(EditLine *el, int dir)
default: /* Terminate and execute cmd */
endcmd[0] = ch;
el_push(el, endcmd);
FUN(el,push)(el, endcmd);
/* FALLTHROUGH */
case 0033: /* ESC: Terminate */
@ -445,8 +450,8 @@ ce_inc_search(EditLine *el, int dir)
protected el_action_t
cv_search(EditLine *el, int dir)
{
char ch;
char tmpbuf[EL_BUFSIZ];
Char ch;
Char tmpbuf[EL_BUFSIZ];
int tmplen;
#ifdef ANCHOR
@ -458,7 +463,7 @@ cv_search(EditLine *el, int dir)
el->el_search.patdir = dir;
tmplen = c_gets(el, &tmpbuf[LEN],
dir == ED_SEARCH_PREV_HISTORY ? "\n/" : "\n?" );
dir == ED_SEARCH_PREV_HISTORY ? STR("\n/") : STR("\n?") );
if (tmplen == -1)
return CC_REFRESH;
@ -477,11 +482,11 @@ cv_search(EditLine *el, int dir)
#ifdef ANCHOR
if (el->el_search.patbuf[0] != '.' &&
el->el_search.patbuf[0] != '*') {
(void) strncpy(tmpbuf, el->el_search.patbuf,
sizeof(tmpbuf) - 1);
(void) Strncpy(tmpbuf, el->el_search.patbuf,
sizeof(tmpbuf) / sizeof(*tmpbuf) - 1);
el->el_search.patbuf[0] = '.';
el->el_search.patbuf[1] = '*';
(void) strncpy(&el->el_search.patbuf[2], tmpbuf,
(void) Strncpy(&el->el_search.patbuf[2], tmpbuf,
EL_BUFSIZ - 3);
el->el_search.patlen++;
el->el_search.patbuf[el->el_search.patlen++] = '.';
@ -495,7 +500,7 @@ cv_search(EditLine *el, int dir)
tmpbuf[tmplen++] = '*';
#endif
tmpbuf[tmplen] = '\0';
(void) strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1);
(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 */
@ -519,9 +524,9 @@ cv_search(EditLine *el, int dir)
protected el_action_t
ce_search_line(EditLine *el, int dir)
{
char *cp = el->el_line.cursor;
char *pattern = el->el_search.patbuf;
char oc, *ocp;
Char *cp = el->el_line.cursor;
Char *pattern = el->el_search.patbuf;
Char oc, *ocp;
#ifdef ANCHOR
ocp = &pattern[1];
oc = *ocp;
@ -559,12 +564,12 @@ ce_search_line(EditLine *el, int dir)
* Vi repeat search
*/
protected el_action_t
cv_repeat_srch(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);
c, el->el_search.patlen, ct_encode_string(el->el_search.patbuf));
#endif
el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */
@ -585,16 +590,16 @@ cv_repeat_srch(EditLine *el, int c)
* Vi character search
*/
protected el_action_t
cv_csearch(EditLine *el, int direction, int ch, int count, int tflag)
cv_csearch(EditLine *el, int direction, Int ch, int count, int tflag)
{
char *cp;
Char *cp;
if (ch == 0)
return CC_ERROR;
if (ch == -1) {
char c;
if (el_getc(el, &c) != 1)
Char c;
if (FUN(el,getc)(el, &c) != 1)
return ed_end_of_file(el, 0);
ch = c;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: search.h,v 1.8 2003/10/18 23:27:36 christos Exp $ */
/* $NetBSD: search.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -43,24 +43,24 @@
#include "histedit.h"
typedef struct el_search_t {
char *patbuf; /* The pattern buffer */
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 */
Char chacha; /* Character we are looking for */
char chatflg; /* 0 if f, 1 if t */
} el_search_t;
protected int el_match(const char *, const char *);
protected int el_match(const Char *, const Char *);
protected int search_init(EditLine *);
protected void search_end(EditLine *);
protected int c_hmatch(EditLine *, const char *);
protected int c_hmatch(EditLine *, const Char *);
protected void c_setpat(EditLine *);
protected el_action_t ce_inc_search(EditLine *, int);
protected el_action_t cv_search(EditLine *, int);
protected el_action_t ce_search_line(EditLine *, int);
protected el_action_t cv_repeat_srch(EditLine *, int);
protected el_action_t cv_csearch(EditLine *, int, int, int, int);
protected el_action_t cv_repeat_srch(EditLine *, Int);
protected el_action_t cv_csearch(EditLine *, int, Int, int, int);
#endif /* _h_el_search */

View File

@ -1,5 +1,5 @@
# $NetBSD: shlib_version,v 1.16 2006/11/24 00:01:17 christos Exp $
# $NetBSD: shlib_version,v 1.18 2009/01/11 03:07:48 christos Exp $
# Remember to update distrib/sets/lists/base/shl.* when changing
#
major=2
minor=10
major=3
minor=0

80
sig.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $ */
/* $NetBSD: sig.c,v 1.15 2009/02/19 15:20:22 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $");
__RCSID("$NetBSD: sig.c,v 1.15 2009/02/19 15:20:22 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -75,12 +75,14 @@ sig_handler(int signo)
(void) sigaddset(&nset, signo);
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
sel->el_signal->sig_no = signo;
switch (signo) {
case SIGCONT:
tty_rawmode(sel);
if (ed_redisplay(sel, 0) == CC_REFRESH)
re_refresh(sel);
term__flush();
term__flush(sel);
break;
case SIGWINCH:
@ -96,7 +98,10 @@ sig_handler(int signo)
if (signo == sighdl[i])
break;
(void) signal(signo, sel->el_signal[i]);
(void) sigaction(signo, &sel->el_signal->sig_action[i], NULL);
sel->el_signal->sig_action[i].sa_handler = SIG_ERR;
sel->el_signal->sig_action[i].sa_flags = 0;
sigemptyset(&sel->el_signal->sig_action[i].sa_mask);
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
(void) kill(0, signo);
}
@ -108,26 +113,29 @@ sig_handler(int signo)
protected int
sig_init(EditLine *el)
{
int i;
sigset_t nset, oset;
size_t i;
sigset_t *nset, oset;
(void) sigemptyset(&nset);
#define _DO(a) (void) sigaddset(&nset, a);
el->el_signal = el_malloc(sizeof(*el->el_signal));
if (el->el_signal == NULL)
return -1;
nset = &el->el_signal->sig_set;
(void) sigemptyset(nset);
#define _DO(a) (void) sigaddset(nset, a);
ALLSIGS
#undef _DO
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
(void) sigprocmask(SIG_BLOCK, nset, &oset);
#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(el_signalhandler_t))
el->el_signal = (el_signalhandler_t *) el_malloc(SIGSIZE);
if (el->el_signal == NULL)
return (-1);
for (i = 0; sighdl[i] != -1; i++)
el->el_signal[i] = SIG_ERR;
for (i = 0; sighdl[i] != -1; i++) {
el->el_signal->sig_action[i].sa_handler = SIG_ERR;
el->el_signal->sig_action[i].sa_flags = 0;
sigemptyset(&el->el_signal->sig_action[i].sa_mask);
}
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
return (0);
return 0;
}
@ -149,20 +157,21 @@ sig_end(EditLine *el)
protected void
sig_set(EditLine *el)
{
int i;
sigset_t nset, oset;
size_t i;
sigset_t oset;
struct sigaction osa, nsa;
(void) sigemptyset(&nset);
#define _DO(a) (void) sigaddset(&nset, a);
ALLSIGS
#undef _DO
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
nsa.sa_handler = sig_handler;
nsa.sa_flags = 0;
sigemptyset(&nsa.sa_mask);
(void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
for (i = 0; sighdl[i] != -1; i++) {
el_signalhandler_t s;
/* This could happen if we get interrupted */
if ((s = signal(sighdl[i], sig_handler)) != sig_handler)
el->el_signal[i] = s;
if (sigaction(sighdl[i], &nsa, &osa) != -1 &&
osa.sa_handler != sig_handler)
el->el_signal->sig_action[i] = osa;
}
sel = el;
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
@ -175,20 +184,17 @@ sig_set(EditLine *el)
protected void
sig_clr(EditLine *el)
{
int i;
sigset_t nset, oset;
size_t i;
sigset_t oset;
(void) sigemptyset(&nset);
#define _DO(a) (void) sigaddset(&nset, a);
ALLSIGS
#undef _DO
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
(void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
for (i = 0; sighdl[i] != -1; i++)
if (el->el_signal[i] != SIG_ERR)
(void) signal(sighdl[i], el->el_signal[i]);
if (el->el_signal->sig_action[i].sa_handler != SIG_ERR)
(void)sigaction(sighdl[i],
&el->el_signal->sig_action[i], NULL);
sel = NULL; /* we are going to die if the handler is
* called */
(void) sigprocmask(SIG_SETMASK, &oset, NULL);
(void)sigprocmask(SIG_SETMASK, &oset, NULL);
}

11
sig.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: sig.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */
/* $NetBSD: sig.h,v 1.8 2009/02/19 15:20:22 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -51,15 +51,18 @@
#define ALLSIGS \
_DO(SIGINT) \
_DO(SIGTSTP) \
_DO(SIGSTOP) \
_DO(SIGQUIT) \
_DO(SIGHUP) \
_DO(SIGTERM) \
_DO(SIGCONT) \
_DO(SIGWINCH)
#define ALLSIGSNO 7
typedef void (*el_signalhandler_t)(int);
typedef el_signalhandler_t *el_signal_t;
typedef struct {
struct sigaction sig_action[ALLSIGSNO];
sigset_t sig_set;
volatile sig_atomic_t sig_no;
} *el_signal_t;
protected void sig_end(EditLine*);
protected int sig_init(EditLine*);

15
sys.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: sys.h,v 1.9 2004/01/17 17:57:40 christos Exp $ */
/* $NetBSD: sys.h,v 1.13 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -71,6 +71,10 @@
/* When we want to hide everything */
#endif
#ifndef __arraycount
# define __arraycount(a) (sizeof(a) / sizeof(*(a)))
#endif
#ifndef _PTR_T
# define _PTR_T
typedef void *ptr_t;
@ -101,6 +105,15 @@ char *fgetln(FILE *fp, size_t *len);
#define REGEX /* Use POSIX.2 regular expression functions */
#undef REGEXP /* Use UNIX V8 regular expression functions */
#if defined(__sun)
extern int tgetent(char *, const char *);
extern int tgetflag(char *);
extern int tgetnum(char *);
extern int tputs(const char *, int, int (*)(int));
extern char* tgoto(const char*, int, int);
extern char* tgetstr(char*, char**);
#endif
#ifdef notdef
# undef REGEX
# undef REGEXP

451
term.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: term.c,v 1.46 2006/11/24 00:01:17 christos Exp $ */
/* $NetBSD: term.c,v 1.57 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95";
#else
__RCSID("$NetBSD: term.c,v 1.46 2006/11/24 00:01:17 christos Exp $");
__RCSID("$NetBSD: term.c,v 1.57 2009/12/30 22:37:40 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -51,27 +51,32 @@ __RCSID("$NetBSD: term.c,v 1.46 2006/11/24 00:01:17 christos Exp $");
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#ifdef HAVE_TERMCAP_H
#include <termcap.h>
#endif
#ifdef HAVE_CURSES_H
#include <curses.h>
#endif
#ifdef HAVE_NCURSES_H
#elif HAVE_NCURSES_H
#include <ncurses.h>
#endif
/* Solaris's term.h does horrid things. */
#if (defined(HAVE_TERM_H) && !defined(SUNOS))
#if defined(HAVE_TERM_H) && !defined(__sun)
#include <term.h>
#endif
#include <sys/types.h>
#include <sys/ioctl.h>
#ifdef _REENTRANT
#include <pthread.h>
#endif
#include "el.h"
/*
* IMPORTANT NOTE: these routines are allowed to look at the current screen
* and the current possition assuming that it is correct. If this is not
* and the current position assuming that it is correct. If this is not
* true, then the update will be WRONG! This is (should be) a valid
* assumption...
*/
@ -271,9 +276,13 @@ private int term_alloc_display(EditLine *);
private void term_alloc(EditLine *, const struct termcapstr *, const char *);
private void term_init_arrow(EditLine *);
private void term_reset_arrow(EditLine *);
private int term_putc(int);
private void term_tputs(EditLine *, const char *, int);
private FILE *term_outfile = NULL; /* XXX: How do we fix that? */
#ifdef _REENTRANT
private pthread_mutex_t term_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
private FILE *term_outfile = NULL;
/* term_setflags():
@ -321,7 +330,6 @@ term_setflags(EditLine *el)
#endif /* DEBUG_SCREEN */
}
/* term_init():
* Initialize the terminal stuff
*/
@ -347,7 +355,6 @@ term_init(EditLine *el)
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;
(void) term_set(el, NULL);
term_init_arrow(el);
return (0);
@ -382,7 +389,7 @@ private void
term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
{
char termbuf[TC_BUFSIZE];
int tlen, clen;
size_t tlen, clen;
char **tlist = el->el_term.t_str;
char **tmp, **str = &tlist[t - tstr];
@ -409,7 +416,7 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
/* 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 */
el->el_term.t_loc += (int)clen + 1; /* one for \0 */
return;
}
/*
@ -426,7 +433,7 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
termbuf[tlen++] = '\0';
}
memcpy(el->el_term.t_buf, termbuf, TC_BUFSIZE);
el->el_term.t_loc = tlen;
el->el_term.t_loc = (int)tlen;
if (el->el_term.t_loc + 3 >= TC_BUFSIZE) {
(void) fprintf(el->el_errfile,
"Out of termcap string space.\n");
@ -434,7 +441,7 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
}
/* 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 */
el->el_term.t_loc += (int)clen + 1; /* one for \0 */
return;
}
@ -465,14 +472,14 @@ private int
term_alloc_display(EditLine *el)
{
int i;
char **b;
Char **b;
coord_t *c = &el->el_term.t_size;
b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1)));
b = el_malloc(sizeof(*b) * (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)));
b[i] = el_malloc(sizeof(**b) * (c->h + 1));
if (b[i] == NULL) {
while (--i >= 0)
el_free((ptr_t) b[i]);
@ -483,11 +490,11 @@ term_alloc_display(EditLine *el)
b[c->v] = NULL;
el->el_display = b;
b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1)));
b = el_malloc(sizeof(*b) * (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)));
b[i] = el_malloc(sizeof(**b) * (c->h + 1));
if (b[i] == NULL) {
while (--i >= 0)
el_free((ptr_t) b[i]);
@ -507,21 +514,21 @@ term_alloc_display(EditLine *el)
private void
term_free_display(EditLine *el)
{
char **b;
char **bufp;
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) *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) *bufp);
el_free((ptr_t) b);
}
}
@ -550,21 +557,30 @@ term_move_to_line(EditLine *el, int where)
while (del > 0) {
if (EL_HAS_AUTO_MARGINS &&
el->el_display[el->el_cursor.v][0] != '\0') {
size_t h = el->el_term.t_size.h - 1;
#ifdef WIDECHAR
for (; h > 0 &&
el->el_display[el->el_cursor.v][h] ==
MB_FILL_CHAR;
h--)
continue;
#endif
/* move without newline */
term_move_to_char(el, el->el_term.t_size.h - 1);
term_overwrite(el,
&el->el_display[el->el_cursor.v][el->el_cursor.h],
1);
term_move_to_char(el, (int)h);
term_overwrite(el, &el->el_display
[el->el_cursor.v][el->el_cursor.h],
(size_t)(el->el_term.t_size.h -
el->el_cursor.h));
/* updates Cursor */
del--;
} else {
if ((del > 1) && GoodStr(T_DO)) {
(void) tputs(tgoto(Str(T_DO), del, del),
del, term__putc);
term_tputs(el, tgoto(Str(T_DO), del,
del), del);
del = 0;
} else {
for (; del > 0; del--)
term__putc('\n');
term__putc(el, '\n');
/* because the \n will become \r\n */
el->el_cursor.h = 0;
}
@ -572,12 +588,11 @@ term_move_to_line(EditLine *el, int where)
}
} else { /* del < 0 */
if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up)))
(void) tputs(tgoto(Str(T_UP), -del, -del), -del,
term__putc);
term_tputs(el, tgoto(Str(T_UP), -del, -del), -del);
else {
if (GoodStr(T_up))
for (; del < 0; del++)
(void) tputs(Str(T_up), 1, term__putc);
term_tputs(el, Str(T_up), 1);
}
}
el->el_cursor.v = where;/* now where is here */
@ -604,7 +619,7 @@ term_move_to_char(EditLine *el, int where)
return;
}
if (!where) { /* if where is first column */
term__putc('\r'); /* do a CR */
term__putc(el, '\r'); /* do a CR */
el->el_cursor.h = 0;
return;
}
@ -612,25 +627,30 @@ term_move_to_char(EditLine *el, int where)
if ((del < -4 || del > 4) && GoodStr(T_ch))
/* go there directly */
(void) tputs(tgoto(Str(T_ch), where, where), where, term__putc);
term_tputs(el, tgoto(Str(T_ch), where, where), where);
else {
if (del > 0) { /* moving forward */
if ((del > 4) && GoodStr(T_RI))
(void) tputs(tgoto(Str(T_RI), del, del),
del, term__putc);
term_tputs(el, tgoto(Str(T_RI), del, del), del);
else {
/* if I can do tabs, use them */
if (EL_CAN_TAB) {
if ((el->el_cursor.h & 0370) !=
(where & 0370)) {
(where & ~0x7)
#ifdef WIDECHAR
&& (el->el_display[
el->el_cursor.v][where & 0370] !=
MB_FILL_CHAR)
#endif
) {
/* if not within tab stop */
for (i =
(el->el_cursor.h & 0370);
i < (where & 0370);
i < (where & ~0x7);
i += 8)
term__putc('\t');
term__putc(el, '\t');
/* then tab over */
el->el_cursor.h = where & 0370;
el->el_cursor.h = where & ~0x7;
}
}
/*
@ -641,15 +661,15 @@ term_move_to_char(EditLine *el, int where)
* 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);
term_overwrite(el, &el->el_display[
el->el_cursor.v][el->el_cursor.h],
(size_t)(where - el->el_cursor.h));
}
} else { /* del < 0 := moving backward */
if ((-del > 4) && GoodStr(T_LE))
(void) tputs(tgoto(Str(T_LE), -del, -del),
-del, term__putc);
term_tputs(el, tgoto(Str(T_LE), -del, -del),
-del);
else { /* can't go directly there */
/*
* if the "cost" is greater than the "cost"
@ -660,12 +680,12 @@ term_move_to_char(EditLine *el, int where)
(((unsigned int) where >> 3) +
(where & 07)))
: (-del > where)) {
term__putc('\r'); /* do a CR */
term__putc(el, '\r'); /* do a CR */
el->el_cursor.h = 0;
goto mc_again; /* and try again */
}
for (i = 0; i < -del; i++)
term__putc('\b');
term__putc(el, '\b');
}
}
}
@ -675,24 +695,27 @@ term_move_to_char(EditLine *el, int where)
/* term_overwrite():
* Overstrike num characters
* Assumes MB_FILL_CHARs are present to keep the column count correct
*/
protected void
term_overwrite(EditLine *el, const char *cp, int n)
term_overwrite(EditLine *el, const Char *cp, size_t n)
{
if (n <= 0)
return; /* catch bugs */
if (n == 0)
return;
if (n > el->el_term.t_size.h) {
if (n > (size_t)el->el_term.t_size.h) {
#ifdef DEBUG_SCREEN
(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);
do {
/* term__putc() ignores any MB_FILL_CHARs */
term__putc(el, *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 */
@ -701,16 +724,22 @@ term_overwrite(EditLine *el, const char *cp, int n)
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')
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;
#ifdef WIDECHAR
while (el->el_display[el->el_cursor.v]
[el->el_cursor.h] == MB_FILL_CHAR)
el->el_cursor.h++;
#endif
} else {
term__putc(el, ' ');
el->el_cursor.h = 1;
}
}
} else /* no wrap, but cursor stays on screen */
el->el_cursor.h = el->el_term.t_size.h;
el->el_cursor.h = el->el_term.t_size.h - 1;
}
}
@ -740,28 +769,28 @@ term_deletechars(EditLine *el, int num)
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);
term_tputs(el, tgoto(Str(T_DC), num, num), num);
return;
}
if (GoodStr(T_dm)) /* if I have delete mode */
(void) tputs(Str(T_dm), 1, term__putc);
term_tputs(el, Str(T_dm), 1);
if (GoodStr(T_dc)) /* else do one at a time */
while (num--)
(void) tputs(Str(T_dc), 1, term__putc);
term_tputs(el, Str(T_dc), 1);
if (GoodStr(T_ed)) /* if I have delete mode */
(void) tputs(Str(T_ed), 1, term__putc);
term_tputs(el, Str(T_ed), 1);
}
/* term_insertwrite():
* Puts terminal in insert character mode or inserts num
* characters in the line
* Assumes MB_FILL_CHARs are present to keep column count correct
*/
protected void
term_insertwrite(EditLine *el, char *cp, int num)
term_insertwrite(EditLine *el, Char *cp, int num)
{
if (num <= 0)
return;
@ -781,37 +810,35 @@ term_insertwrite(EditLine *el, char *cp, int num)
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);
term_tputs(el, tgoto(Str(T_IC), num, num), num);
term_overwrite(el, cp, (size_t)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);
term_tputs(el, Str(T_im), 1);
el->el_cursor.h += num;
do
term__putc(*cp++);
term__putc(el, *cp++);
while (--num);
if (GoodStr(T_ip)) /* have to make num chars insert */
(void) tputs(Str(T_ip), 1, term__putc);
term_tputs(el, Str(T_ip), 1);
(void) tputs(Str(T_ei), 1, term__putc);
term_tputs(el, Str(T_ei), 1);
return;
}
do {
if (GoodStr(T_ic)) /* have to make num chars insert */
(void) tputs(Str(T_ic), 1, term__putc);
/* insert a char */
term_tputs(el, Str(T_ic), 1);
term__putc(*cp++);
term__putc(el, *cp++);
el->el_cursor.h++;
if (GoodStr(T_ip)) /* have to make num chars insert */
(void) tputs(Str(T_ip), 1, term__putc);
term_tputs(el, Str(T_ip), 1);
/* pad the inserted char */
} while (--num);
@ -827,10 +854,10 @@ term_clear_EOL(EditLine *el, int num)
int i;
if (EL_CAN_CEOL && GoodStr(T_ce))
(void) tputs(Str(T_ce), 1, term__putc);
term_tputs(el, Str(T_ce), 1);
else {
for (i = 0; i < num; i++)
term__putc(' ');
term__putc(el, ' ');
el->el_cursor.h += num; /* have written num spaces */
}
}
@ -845,14 +872,14 @@ term_clear_screen(EditLine *el)
if (GoodStr(T_cl))
/* send the clear screen code */
(void) tputs(Str(T_cl), Val(T_li), term__putc);
term_tputs(el, Str(T_cl), Val(T_li));
else if (GoodStr(T_ho) && GoodStr(T_cd)) {
(void) tputs(Str(T_ho), Val(T_li), term__putc); /* home */
term_tputs(el, Str(T_ho), Val(T_li)); /* home */
/* clear to bottom of screen */
(void) tputs(Str(T_cd), Val(T_li), term__putc);
term_tputs(el, Str(T_cd), Val(T_li));
} else {
term__putc('\r');
term__putc('\n');
term__putc(el, '\r');
term__putc(el, '\n');
}
}
@ -865,9 +892,9 @@ term_beep(EditLine *el)
{
if (GoodStr(T_bl))
/* what termcap says we should use */
(void) tputs(Str(T_bl), 1, term__putc);
term_tputs(el, Str(T_bl), 1);
else
term__putc('\007'); /* an ASCII bell; ^G */
term__putc(el, '\007'); /* an ASCII bell; ^G */
}
@ -879,9 +906,9 @@ protected void
term_clear_to_bottom(EditLine *el)
{
if (GoodStr(T_cd))
(void) tputs(Str(T_cd), Val(T_li), term__putc);
term_tputs(el, Str(T_cd), Val(T_li));
else if (GoodStr(T_ce))
(void) tputs(Str(T_ce), Val(T_li), term__putc);
term_tputs(el, Str(T_ce), Val(T_li));
}
#endif
@ -1045,32 +1072,32 @@ term_init_arrow(EditLine *el)
{
fkey_t *arrow = el->el_term.t_fkey;
arrow[A_K_DN].name = "down";
arrow[A_K_DN].name = STR("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].name = STR("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].name = STR("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].name = STR("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].name = STR("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].name = STR("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;
@ -1084,18 +1111,18 @@ private void
term_reset_arrow(EditLine *el)
{
fkey_t *arrow = el->el_term.t_fkey;
static const char strA[] = {033, '[', 'A', '\0'};
static const char strB[] = {033, '[', 'B', '\0'};
static const char strC[] = {033, '[', 'C', '\0'};
static const char strD[] = {033, '[', 'D', '\0'};
static const char strH[] = {033, '[', 'H', '\0'};
static const char strF[] = {033, '[', 'F', '\0'};
static const char stOA[] = {033, 'O', 'A', '\0'};
static const char stOB[] = {033, 'O', 'B', '\0'};
static const char stOC[] = {033, 'O', 'C', '\0'};
static const char stOD[] = {033, 'O', 'D', '\0'};
static const char stOH[] = {033, 'O', 'H', '\0'};
static const char stOF[] = {033, 'O', 'F', '\0'};
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);
@ -1131,13 +1158,13 @@ term_reset_arrow(EditLine *el)
* Set an arrow key binding
*/
protected int
term_set_arrow(EditLine *el, const char *name, key_value_t *fun, int type)
term_set_arrow(EditLine *el, const Char *name, key_value_t *fun, int type)
{
fkey_t *arrow = el->el_term.t_fkey;
int i;
for (i = 0; i < A_K_NKEYS; i++)
if (strcmp(name, arrow[i].name) == 0) {
if (Strcmp(name, arrow[i].name) == 0) {
arrow[i].fun = *fun;
arrow[i].type = type;
return (0);
@ -1150,13 +1177,13 @@ term_set_arrow(EditLine *el, const char *name, key_value_t *fun, int type)
* Clear an arrow key binding
*/
protected int
term_clear_arrow(EditLine *el, const char *name)
term_clear_arrow(EditLine *el, const Char *name)
{
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) {
if (Strcmp(name, arrow[i].name) == 0) {
arrow[i].type = XK_NOD;
return (0);
}
@ -1168,13 +1195,13 @@ term_clear_arrow(EditLine *el, const char *name)
* Print the arrow key bindings
*/
protected void
term_print_arrow(EditLine *el, const char *name)
term_print_arrow(EditLine *el, const 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 (*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);
@ -1203,73 +1230,111 @@ term_bind_arrow(EditLine *el)
term_reset_arrow(el);
for (i = 0; i < A_K_NKEYS; i++) {
Char wt_str[VISUAL_WIDTH_MAX];
Char *px;
size_t n;
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,
if (!p || !*p)
continue;
for (n = 0; n < VISUAL_WIDTH_MAX && p[n]; ++n)
wt_str[n] = p[n];
while (n < VISUAL_WIDTH_MAX)
wt_str[n++] = '\0';
px = wt_str;
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, px);
else {
if (p[1] && (dmap[j] == map[j] ||
map[j] == ED_SEQUENCE_LEAD_IN)) {
key_add(el, px, &arrow[i].fun,
arrow[i].type);
map[j] = ED_SEQUENCE_LEAD_IN;
} else if (map[j] == ED_UNASSIGNED) {
key_clear(el, map, px);
if (arrow[i].type == XK_CMD)
map[j] = arrow[i].fun.cmd;
else
key_add(el, px, &arrow[i].fun,
arrow[i].type);
map[j] = ED_SEQUENCE_LEAD_IN;
} else if (map[j] == ED_UNASSIGNED) {
key_clear(el, map, 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
*/
private int
term_putc(int c)
{
if (term_outfile == NULL)
return -1;
return fputc(c, term_outfile);
}
private void
term_tputs(EditLine *el, const char *cap, int affcnt)
{
#ifdef _REENTRANT
pthread_mutex_lock(&term_mutex);
#endif
term_outfile = el->el_outfile;
(void)tputs(cap, affcnt, term_putc);
#ifdef _REENTRANT
pthread_mutex_unlock(&term_mutex);
#endif
}
/* term__putc():
* Add a character
*/
protected int
term__putc(int c)
term__putc(EditLine *el, Int c)
{
return (fputc(c, term_outfile));
char buf[MB_LEN_MAX +1];
ssize_t i;
if (c == MB_FILL_CHAR)
return 0;
i = ct_encode_char(buf, MB_LEN_MAX, c);
if (i <= 0)
return (int)i;
buf[i] = '\0';
return fputs(buf, el->el_outfile);
}
/* term__flush():
* Flush output
*/
protected void
term__flush(void)
term__flush(EditLine *el)
{
(void) fflush(term_outfile);
(void) fflush(el->el_outfile);
}
/* term_writec():
* Write the given character out, in a human readable form
*/
protected void
term_writec(EditLine *el, int c)
term_writec(EditLine *el, Int c)
{
char buf[8];
int cnt = key__decode_char(buf, sizeof(buf), 0, c);
buf[cnt] = '\0';
term_overwrite(el, buf, cnt);
term__flush();
Char visbuf[VISUAL_WIDTH_MAX +1];
ssize_t vcnt = ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c);
visbuf[vcnt] = '\0';
term_overwrite(el, visbuf, (size_t)vcnt);
term__flush(el);
}
@ -1279,11 +1344,10 @@ term_writec(EditLine *el, int c)
protected int
/*ARGSUSED*/
term_telltc(EditLine *el, int argc __attribute__((__unused__)),
const char **argv __attribute__((__unused__)))
const Char **argv __attribute__((__unused__)))
{
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");
@ -1302,10 +1366,11 @@ term_telltc(EditLine *el, int argc __attribute__((__unused__)),
for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++) {
const char *ub;
if (*ts && **ts) {
(void) key__decode_str(*ts, upbuf, sizeof(upbuf), "");
ub = upbuf;
ub = ct_encode_string(ct_visual_string(
ct_decode_string(*ts, &el->el_scratch)),
&el->el_scratch);
} else {
ub = "(empty)";
ub = "(empty)";
}
(void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n",
t->long_name, t->name, ub);
@ -1321,17 +1386,19 @@ term_telltc(EditLine *el, int argc __attribute__((__unused__)),
protected int
/*ARGSUSED*/
term_settc(EditLine *el, int argc __attribute__((__unused__)),
const char **argv)
const Char **argv)
{
const struct termcapstr *ts;
const struct termcapval *tv;
const char *what, *how;
char what[8], how[8];
if (argv == NULL || argv[1] == NULL || argv[2] == NULL)
return -1;
what = argv[1];
how = argv[2];
strncpy(what, ct_encode_string(argv[1], &el->el_scratch), sizeof(what));
what[sizeof(what) - 1] = '\0';
strncpy(how, ct_encode_string(argv[2], &el->el_scratch), sizeof(how));
how[sizeof(how) - 1] = '\0';
/*
* Do the strings first
@ -1363,7 +1430,7 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)),
el->el_term.t_val[tv - tval] = 0;
else {
(void) fprintf(el->el_errfile,
"%s: Bad value `%s'.\n", argv[0], how);
"" FSTR ": Bad value `%s'.\n", argv[0], how);
return -1;
}
term_setflags(el);
@ -1377,7 +1444,7 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)),
i = strtol(how, &ep, 10);
if (*ep != '\0') {
(void) fprintf(el->el_errfile,
"%s: Bad value `%s'.\n", argv[0], how);
"" FSTR ": Bad value `%s'.\n", argv[0], how);
return -1;
}
el->el_term.t_val[tv - tval] = (int) i;
@ -1452,9 +1519,10 @@ term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv)
protected int
/*ARGSUSED*/
term_echotc(EditLine *el, int argc __attribute__((__unused__)),
const char **argv)
const Char **argv)
{
char *cap, *scap, *ep;
char *cap, *scap;
Char *ep;
int arg_need, arg_cols, arg_rows;
int verbose = 0, silent = 0;
char *area;
@ -1485,21 +1553,21 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
}
if (!*argv || *argv[0] == '\0')
return (0);
if (strcmp(*argv, "tabs") == 0) {
if (Strcmp(*argv, STR("tabs")) == 0) {
(void) fprintf(el->el_outfile, fmts, EL_CAN_TAB ? "yes" : "no");
return (0);
} else if (strcmp(*argv, "meta") == 0) {
} else if (Strcmp(*argv, STR("meta")) == 0) {
(void) fprintf(el->el_outfile, fmts, Val(T_km) ? "yes" : "no");
return (0);
} else if (strcmp(*argv, "xn") == 0) {
} else if (Strcmp(*argv, STR("xn")) == 0) {
(void) fprintf(el->el_outfile, fmts, EL_HAS_MAGIC_MARGINS ?
"yes" : "no");
return (0);
} else if (strcmp(*argv, "am") == 0) {
} else if (Strcmp(*argv, STR("am")) == 0) {
(void) fprintf(el->el_outfile, fmts, EL_HAS_AUTO_MARGINS ?
"yes" : "no");
return (0);
} else if (strcmp(*argv, "baud") == 0) {
} else if (Strcmp(*argv, STR("baud")) == 0) {
#ifdef notdef
int i;
@ -1514,10 +1582,11 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
(void) fprintf(el->el_outfile, fmtd, (int)el->el_tty.t_speed);
#endif
return (0);
} else if (strcmp(*argv, "rows") == 0 || strcmp(*argv, "lines") == 0) {
} else if (Strcmp(*argv, STR("rows")) == 0 ||
Strcmp(*argv, STR("lines")) == 0) {
(void) fprintf(el->el_outfile, fmtd, Val(T_li));
return (0);
} else if (strcmp(*argv, "cols") == 0) {
} else if (Strcmp(*argv, STR("cols")) == 0) {
(void) fprintf(el->el_outfile, fmtd, Val(T_co));
return (0);
}
@ -1526,18 +1595,19 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
*/
scap = NULL;
for (t = tstr; t->name != NULL; t++)
if (strcmp(t->name, *argv) == 0) {
if (strcmp(t->name,
ct_encode_string(*argv, &el->el_scratch)) == 0) {
scap = el->el_term.t_str[t - tstr];
break;
}
if (t->name == NULL) {
/* XXX: some systems' tgetstr needs non const */
scap = tgetstr(strchr(*argv, **argv), &area);
scap = tgetstr(ct_encode_string(*argv, &el->el_scratch), &area);
}
if (!scap || scap[0] == '\0') {
if (!silent)
(void) fprintf(el->el_errfile,
"echotc: Termcap parameter `%s' not found.\n",
"echotc: Termcap parameter `" FSTR "' not found.\n",
*argv);
return (-1);
}
@ -1580,11 +1650,11 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
if (*argv && *argv[0]) {
if (!silent)
(void) fprintf(el->el_errfile,
"echotc: Warning: Extra argument `%s'.\n",
"echotc: Warning: Extra argument `" FSTR "'.\n",
*argv);
return (-1);
}
(void) tputs(scap, 1, term__putc);
term_tputs(el, scap, 1);
break;
case 1:
argv++;
@ -1595,11 +1665,11 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
return (-1);
}
arg_cols = 0;
i = strtol(*argv, &ep, 10);
i = Strtol(*argv, &ep, 10);
if (*ep != '\0' || i < 0) {
if (!silent)
(void) fprintf(el->el_errfile,
"echotc: Bad value `%s' for rows.\n",
"echotc: Bad value `" FSTR "' for rows.\n",
*argv);
return (-1);
}
@ -1608,11 +1678,11 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
if (*argv && *argv[0]) {
if (!silent)
(void) fprintf(el->el_errfile,
"echotc: Warning: Extra argument `%s'.\n",
"echotc: Warning: Extra argument `" FSTR "'.\n",
*argv);
return (-1);
}
(void) tputs(tgoto(scap, arg_cols, arg_rows), 1, term__putc);
term_tputs(el, tgoto(scap, arg_cols, arg_rows), 1);
break;
default:
/* This is wrong, but I will ignore it... */
@ -1629,11 +1699,11 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
"echotc: Warning: Missing argument.\n");
return (-1);
}
i = strtol(*argv, &ep, 10);
i = Strtol(*argv, &ep, 10);
if (*ep != '\0' || i < 0) {
if (!silent)
(void) fprintf(el->el_errfile,
"echotc: Bad value `%s' for cols.\n",
"echotc: Bad value `" FSTR "' for cols.\n",
*argv);
return (-1);
}
@ -1645,11 +1715,11 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
"echotc: Warning: Missing argument.\n");
return (-1);
}
i = strtol(*argv, &ep, 10);
i = Strtol(*argv, &ep, 10);
if (*ep != '\0' || i < 0) {
if (!silent)
(void) fprintf(el->el_errfile,
"echotc: Bad value `%s' for rows.\n",
"echotc: Bad value `" FSTR "' for rows.\n",
*argv);
return (-1);
}
@ -1657,19 +1727,18 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
if (*ep != '\0') {
if (!silent)
(void) fprintf(el->el_errfile,
"echotc: Bad value `%s'.\n", *argv);
"echotc: Bad value `" FSTR "'.\n", *argv);
return (-1);
}
argv++;
if (*argv && *argv[0]) {
if (!silent)
(void) fprintf(el->el_errfile,
"echotc: Warning: Extra argument `%s'.\n",
"echotc: Warning: Extra argument `" FSTR "'.\n",
*argv);
return (-1);
}
(void) tputs(tgoto(scap, arg_cols, arg_rows), arg_rows,
term__putc);
term_tputs(el, tgoto(scap, arg_cols, arg_rows), arg_rows);
break;
}
return (0);

26
term.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: term.h,v 1.18 2006/11/24 00:01:17 christos Exp $ */
/* $NetBSD: term.h,v 1.21 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -43,7 +43,7 @@
#include "histedit.h"
typedef struct { /* Symbolic function key bindings */
const char *name; /* name of the key */
const 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 */
@ -84,8 +84,8 @@ typedef struct {
protected void term_move_to_line(EditLine *, int);
protected void term_move_to_char(EditLine *, int);
protected void term_clear_EOL(EditLine *, int);
protected void term_overwrite(EditLine *, const char *, int);
protected void term_insertwrite(EditLine *, char *, int);
protected void term_overwrite(EditLine *, const Char *, size_t);
protected void term_insertwrite(EditLine *, Char *, int);
protected void term_deletechars(EditLine *, int);
protected void term_clear_screen(EditLine *);
protected void term_beep(EditLine *);
@ -93,19 +93,19 @@ protected int term_change_size(EditLine *, int, int);
protected int term_get_size(EditLine *, int *, int *);
protected int term_init(EditLine *);
protected void term_bind_arrow(EditLine *);
protected void term_print_arrow(EditLine *, const char *);
protected int term_clear_arrow(EditLine *, const char *);
protected int term_set_arrow(EditLine *, const char *, key_value_t *, int);
protected void term_print_arrow(EditLine *, const Char *);
protected int term_clear_arrow(EditLine *, const Char *);
protected int term_set_arrow(EditLine *, const Char *, key_value_t *, int);
protected void term_end(EditLine *);
protected void term_get(EditLine *, const char **);
protected int term_set(EditLine *, const char *);
protected int term_settc(EditLine *, int, const char **);
protected int term_settc(EditLine *, int, const Char **);
protected int term_gettc(EditLine *, int, char **);
protected int term_telltc(EditLine *, int, const char **);
protected int term_echotc(EditLine *, int, const char **);
protected void term_writec(EditLine *, int);
protected int term__putc(int);
protected void term__flush(void);
protected int term_telltc(EditLine *, int, const Char **);
protected int term_echotc(EditLine *, int, const Char **);
protected void term_writec(EditLine *, Int);
protected int term__putc(EditLine *, Int);
protected void term__flush(EditLine *);
/*
* Easy access macros

View File

@ -1,4 +1,4 @@
/* $NetBSD: tokenizer.c,v 1.14 2003/12/05 13:37:48 lukem Exp $ */
/* $NetBSD: tokenizer.c,v 1.18 2010/01/03 18:27:10 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,55 +37,57 @@
#if 0
static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: tokenizer.c,v 1.14 2003/12/05 13:37:48 lukem Exp $");
__RCSID("$NetBSD: tokenizer.c,v 1.18 2010/01/03 18:27:10 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
/* We build this file twice, once as NARROW, once as WIDE. */
/*
* tokenize.c: Bourne shell like tokenizer
*/
#include <string.h>
#include <stdlib.h>
#include "histedit.h"
#include "chartype.h"
typedef enum {
Q_none, Q_single, Q_double, Q_one, Q_doubleone
} quote_t;
#define IFS "\t \n"
#define TOK_KEEP 1
#define TOK_EAT 2
#define WINCR 20
#define AINCR 10
#define tok_strdup(a) strdup(a)
#define IFS STR("\t \n")
#define tok_malloc(a) malloc(a)
#define tok_free(a) free(a)
#define tok_realloc(a, b) realloc(a, b)
#define tok_strdup(a) Strdup(a)
struct tokenizer {
char *ifs; /* In field separator */
struct TYPE(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 */
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(Tokenizer *);
private void FUN(tok,finish)(TYPE(Tokenizer) *);
/* tok_finish():
/* FUN(tok,finish)():
* Finish a word in the tokenizer.
*/
private void
tok_finish(Tokenizer *tok)
FUN(tok,finish)(TYPE(Tokenizer) *tok)
{
*tok->wptr = '\0';
@ -98,13 +100,13 @@ tok_finish(Tokenizer *tok)
}
/* tok_init():
/* FUN(tok,init)():
* Initialize the tokenizer
*/
public Tokenizer *
tok_init(const char *ifs)
public TYPE(Tokenizer) *
FUN(tok,init)(const Char *ifs)
{
Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer));
TYPE(Tokenizer) *tok = tok_malloc(sizeof(TYPE(Tokenizer)));
if (tok == NULL)
return NULL;
@ -115,14 +117,14 @@ tok_init(const char *ifs)
}
tok->argc = 0;
tok->amax = AINCR;
tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax);
tok->argv = tok_malloc(sizeof(*tok->argv) * tok->amax);
if (tok->argv == NULL) {
tok_free((ptr_t)tok->ifs);
tok_free((ptr_t)tok);
return NULL;
}
tok->argv[0] = NULL;
tok->wspace = (char *) tok_malloc(WINCR);
tok->wspace = tok_malloc(WINCR * sizeof(*tok->wspace));
if (tok->wspace == NULL) {
tok_free((ptr_t)tok->argv);
tok_free((ptr_t)tok->ifs);
@ -139,11 +141,11 @@ tok_init(const char *ifs)
}
/* tok_reset():
/* FUN(tok,reset)():
* Reset the tokenizer
*/
public void
tok_reset(Tokenizer *tok)
FUN(tok,reset)(TYPE(Tokenizer) *tok)
{
tok->argc = 0;
@ -154,11 +156,11 @@ tok_reset(Tokenizer *tok)
}
/* tok_end():
/* FUN(tok,end)():
* Clean up
*/
public void
tok_end(Tokenizer *tok)
FUN(tok,end)(TYPE(Tokenizer) *tok)
{
tok_free((ptr_t) tok->ifs);
@ -169,10 +171,10 @@ tok_end(Tokenizer *tok)
/* tok_line():
/* FUN(tok,line)():
* Bourne shell (sh(1)) like tokenizing
* Arguments:
* tok current tokenizer state (setup with tok_init())
* tok current tokenizer state (setup with FUN(tok,init)())
* line line to parse
* Returns:
* -1 Internal error
@ -187,20 +189,20 @@ tok_end(Tokenizer *tok)
* cursorv if !NULL, offset in argv[cursorc] of cursor
*/
public int
tok_line(Tokenizer *tok, const LineInfo *line,
int *argc, const char ***argv, int *cursorc, int *cursoro)
FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
int *argc, const Char ***argv, int *cursorc, int *cursoro)
{
const char *ptr;
const Char *ptr;
int cc, co;
cc = co = -1;
ptr = line->buffer;
for (ptr = line->buffer; ;ptr++) {
if (ptr >= line->lastchar)
ptr = "";
ptr = STR("");
if (ptr == line->cursor) {
cc = tok->argc;
co = tok->wptr - tok->wstart;
co = (int)(tok->wptr - tok->wstart);
}
switch (*ptr) {
case '\'':
@ -358,8 +360,8 @@ tok_line(Tokenizer *tok, const LineInfo *line,
tok->flags &= ~TOK_EAT;
switch (tok->quote) {
case Q_none:
if (strchr(tok->ifs, *ptr) != NULL)
tok_finish(tok);
if (Strchr(tok->ifs, *ptr) != NULL)
FUN(tok,finish)(tok);
else
*tok->wptr++ = *ptr;
break;
@ -390,7 +392,8 @@ tok_line(Tokenizer *tok, const LineInfo *line,
if (tok->wptr >= tok->wmax - 4) {
size_t size = tok->wmax - tok->wspace + WINCR;
char *s = (char *) tok_realloc(tok->wspace, size);
Char *s = tok_realloc(tok->wspace,
size * sizeof(*s));
if (s == NULL)
return (-1);
@ -407,10 +410,9 @@ tok_line(Tokenizer *tok, const LineInfo *line,
tok->wmax = s + size;
}
if (tok->argc >= tok->amax - 4) {
char **p;
Char **p;
tok->amax += AINCR;
p = (char **) tok_realloc(tok->argv,
tok->amax * sizeof(char *));
p = tok_realloc(tok->argv, tok->amax * sizeof(*p));
if (p == NULL)
return (-1);
tok->argv = p;
@ -419,29 +421,30 @@ tok_line(Tokenizer *tok, const LineInfo *line,
tok_line_outok:
if (cc == -1 && co == -1) {
cc = tok->argc;
co = tok->wptr - tok->wstart;
co = (int)(tok->wptr - tok->wstart);
}
if (cursorc != NULL)
*cursorc = cc;
if (cursoro != NULL)
*cursoro = co;
tok_finish(tok);
*argv = (const char **)tok->argv;
FUN(tok,finish)(tok);
*argv = (const Char **)tok->argv;
*argc = tok->argc;
return (0);
}
/* tok_str():
/* FUN(tok,str)():
* Simpler version of tok_line, taking a NUL terminated line
* and splitting into words, ignoring cursor state.
*/
public int
tok_str(Tokenizer *tok, const char *line, int *argc, const char ***argv)
FUN(tok,str)(TYPE(Tokenizer) *tok, const Char *line, int *argc,
const Char ***argv)
{
LineInfo li;
TYPE(LineInfo) li;
memset(&li, 0, sizeof(li));
li.buffer = line;
li.cursor = li.lastchar = strchr(line, '\0');
return (tok_line(tok, &li, argc, argv, NULL, NULL));
li.cursor = li.lastchar = Strchr(line, '\0');
return (FUN(tok,line)(tok, &li, argc, argv, NULL, NULL));
}

109
tty.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.c,v 1.25 2006/03/18 09:09:41 christos Exp $ */
/* $NetBSD: tty.c,v 1.33 2010/04/18 21:17:22 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: tty.c,v 1.25 2006/03/18 09:09:41 christos Exp $");
__RCSID("$NetBSD: tty.c,v 1.33 2010/04/18 21:17:22 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -45,8 +45,10 @@ __RCSID("$NetBSD: tty.c,v 1.25 2006/03/18 09:09:41 christos Exp $");
* tty.c: tty interface stuff
*/
#include <assert.h>
#include "tty.h"
#include <errno.h>
#include <strings.h> /* for ffs */
#include "el.h"
#include "tty.h"
typedef struct ttymodes_t {
const char *m_name;
@ -55,7 +57,7 @@ typedef struct ttymodes_t {
} ttymodes_t;
typedef struct ttymap_t {
int nch, och; /* Internal and termio rep of chars */
Int nch, och; /* Internal and termio rep of chars */
el_action_t bind[3]; /* emacs, vi, and vi-cmd */
} ttymap_t;
@ -445,13 +447,12 @@ private const ttymodes_t ttymodes[] = {
#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)
private int tty_getty(EditLine *, struct termios *);
private int tty_setty(EditLine *, int, const struct termios *);
private int tty__getcharindex(int);
private void tty__getchar(struct termios *, unsigned char *);
private void tty__setchar(struct termios *, unsigned char *);
@ -460,6 +461,29 @@ private int tty_setup(EditLine *);
#define t_qu t_ts
/* tty_getty():
* Wrapper for tcgetattr to handle EINTR
*/
private int
tty_getty(EditLine *el, struct termios *t)
{
int rv;
while ((rv = tcgetattr(el->el_infd, t)) == -1 && errno == EINTR)
continue;
return rv;
}
/* tty_setty():
* Wrapper for tcsetattr to handle EINTR
*/
private int
tty_setty(EditLine *el, int action, const struct termios *t)
{
int rv;
while ((rv = tcsetattr(el->el_infd, action, t)) == -1 && errno == EINTR)
continue;
return rv;
}
/* tty_setup():
* Get the tty parameters and initialize the editing state
@ -521,7 +545,7 @@ tty_setup(EditLine *el)
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) {
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_setup: tty_setty: %s\n",
@ -870,7 +894,7 @@ 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;
unsigned char new[2], old[2];
Char new[2], old[2];
const ttymap_t *tp;
el_action_t *map, *alt;
const el_action_t *dmap, *dalt;
@ -892,16 +916,16 @@ tty_bind_char(EditLine *el, int force)
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);
key_clear(el, map, old);
map[UC(old[0])] = dmap[UC(old[0])];
key_clear(el, map, new);
/* MAP_VI == 1, MAP_EMACS == 0... */
map[new[0]] = tp->bind[el->el_map.type];
map[UC(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];
key_clear(el, alt, old);
alt[UC(old[0])] = dalt[UC(old[0])];
key_clear(el, alt, new);
alt[UC(new[0])] = tp->bind[el->el_map.type + 1];
}
}
}
@ -929,7 +953,7 @@ tty_rawmode(EditLine *el)
}
/*
* 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!
* tty. But 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);
@ -1050,7 +1074,7 @@ tty_rawmode(EditLine *el)
}
}
}
if (tty_setty(el, &el->el_tty.t_ed) == -1) {
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
strerror(errno));
@ -1075,7 +1099,7 @@ tty_cookedmode(EditLine *el)
if (el->el_flags & EDIT_DISABLED)
return (0);
if (tty_setty(el, &el->el_tty.t_ex) == -1) {
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_cookedmode: tty_setty: %s\n",
@ -1111,7 +1135,7 @@ tty_quotemode(EditLine *el)
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, TCSADRAIN, &el->el_tty.t_qu) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
strerror(errno));
@ -1132,7 +1156,7 @@ 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 (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
strerror(errno));
@ -1149,19 +1173,20 @@ tty_noquotemode(EditLine *el)
*/
protected int
/*ARGSUSED*/
tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv)
{
const ttymodes_t *m;
char x;
int aflag = 0;
const char *s, *d;
const char *name;
const Char *s, *d;
char name[EL_BUFSIZ];
struct termios *tios = &el->el_tty.t_ex;
int z = EX_IO;
if (argv == NULL)
return (-1);
name = *argv++;
strncpy(name, ct_encode_string(*argv++, &el->el_scratch), sizeof(name));
name[sizeof(name) - 1] = '\0';
while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
switch (argv[0][1]) {
@ -1193,7 +1218,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
if (!argv || !*argv) {
int i = -1;
int len = 0, st = 0, cu;
size_t len = 0, st = 0, cu;
for (m = ttymodes; m->m_name; m++) {
if (m->m_type != i) {
(void) fprintf(el->el_outfile, "%s%s",
@ -1216,9 +1241,9 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
cu = strlen(m->m_name) + (x != '\0') + 1;
if (len + cu >= el->el_term.t_size.h) {
if (len + cu >= (size_t)el->el_term.t_size.h) {
(void) fprintf(el->el_outfile, "\n%*s",
st, "");
(int)st, "");
len = st + cu;
} else
len += cu;
@ -1235,7 +1260,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
return (0);
}
while (argv && (s = *argv++)) {
const char *p;
const Char *p;
switch (*s) {
case '+':
case '-':
@ -1246,23 +1271,24 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
break;
}
d = s;
p = strchr(s, '=');
p = Strchr(s, '=');
for (m = ttymodes; m->m_name; m++)
if ((p ? strncmp(m->m_name, d, (size_t)(p - d)) :
strcmp(m->m_name, d)) == 0 &&
if ((p ? strncmp(m->m_name, ct_encode_string(d, &el->el_scratch), (size_t)(p - d)) :
strcmp(m->m_name, ct_encode_string(d, &el->el_scratch))) == 0 &&
(p == NULL || m->m_type == MD_CHAR))
break;
if (!m->m_name) {
(void) fprintf(el->el_errfile,
"%s: Invalid argument `%s'.\n", name, d);
"%s: Invalid argument `" FSTR "'.\n", name, d);
return (-1);
}
if (p) {
int c = ffs((int)m->m_value);
int v = *++p ? parse__escape((const char **) &p) :
int v = *++p ? parse__escape(&p) :
el->el_tty.t_vdisable;
assert(c-- != 0);
assert(c != 0);
c--;
c = tty__getcharindex(c);
assert(c != -1);
tios->c_cc[c] = v;
@ -1283,6 +1309,17 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
break;
}
}
if (el->el_tty.t_mode == z) {
if (tty_setty(el, TCSADRAIN, tios) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_stty: tty_setty: %s\n", strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
}
}
return (0);
}

5
tty.h
View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.h,v 1.11 2005/06/01 11:37:52 lukem Exp $ */
/* $NetBSD: tty.h,v 1.12 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -40,6 +40,7 @@
#ifndef _h_el_tty
#define _h_el_tty
#include "sys.h"
#include "histedit.h"
#include <termios.h>
#include <unistd.h>
@ -458,7 +459,7 @@ typedef unsigned char ttychar_t[NN_IO][C_NCC];
protected int tty_init(EditLine *);
protected void tty_end(EditLine *);
protected int tty_stty(EditLine *, int, const char **);
protected int tty_stty(EditLine *, int, const Char **);
protected int tty_rawmode(EditLine *);
protected int tty_cookedmode(EditLine *);
protected int tty_quotemode(EditLine *);

226
vi.c
View File

@ -1,4 +1,4 @@
/* $NetBSD: vi.c,v 1.27 2006/10/22 07:48:13 mrg Exp $ */
/* $NetBSD: vi.c,v 1.31 2009/12/30 22:37:40 christos Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -35,13 +35,14 @@
#include "config.h"
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <sys/wait.h>
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: vi.c,v 1.27 2006/10/22 07:48:13 mrg Exp $");
__RCSID("$NetBSD: vi.c,v 1.31 2009/12/30 22:37:40 christos Exp $");
#endif
#endif /* not lint && not SCCSID */
@ -50,14 +51,14 @@ __RCSID("$NetBSD: vi.c,v 1.27 2006/10/22 07:48:13 mrg Exp $");
*/
#include "el.h"
private el_action_t cv_action(EditLine *, int);
private el_action_t cv_paste(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(EditLine *el, int c)
cv_action(EditLine *el, Int c)
{
if (el->el_chared.c_vcmd.action != NOP) {
@ -68,7 +69,7 @@ cv_action(EditLine *el, int c)
if (!(c & YANK))
cv_undo(el);
cv_yank(el, el->el_line.buffer,
el->el_line.lastchar - el->el_line.buffer);
(int)(el->el_line.lastchar - el->el_line.buffer));
el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_vcmd.pos = 0;
if (!(c & YANK)) {
@ -89,15 +90,15 @@ cv_action(EditLine *el, int c)
* Paste previous deletion before or after the cursor
*/
private el_action_t
cv_paste(EditLine *el, int c)
cv_paste(EditLine *el, Int c)
{
c_kill_t *k = &el->el_chared.c_kill;
int len = k->last - k->buf;
size_t len = (size_t)(k->last - k->buf);
if (k->buf == NULL || len == 0)
return (CC_ERROR);
#ifdef DEBUG_PASTE
(void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", len, k->buf);
(void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", (int)len, k->buf);
#endif
cv_undo(el);
@ -105,10 +106,11 @@ cv_paste(EditLine *el, int c)
if (!c && el->el_line.cursor < el->el_line.lastchar)
el->el_line.cursor++;
c_insert(el, len);
c_insert(el, (int)len);
if (el->el_line.cursor + len > el->el_line.lastchar)
return (CC_ERROR);
(void) memcpy(el->el_line.cursor, k->buf, len +0u);
(void) memcpy(el->el_line.cursor, k->buf, len *
sizeof(*el->el_line.cursor));
return (CC_REFRESH);
}
@ -120,7 +122,7 @@ cv_paste(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_paste_next(EditLine *el, int c __attribute__((__unused__)))
vi_paste_next(EditLine *el, Int c __attribute__((__unused__)))
{
return (cv_paste(el, 0));
@ -133,7 +135,7 @@ vi_paste_next(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_paste_prev(EditLine *el, int c __attribute__((__unused__)))
vi_paste_prev(EditLine *el, Int c __attribute__((__unused__)))
{
return (cv_paste(el, 1));
@ -146,7 +148,7 @@ vi_paste_prev(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_prev_big_word(EditLine *el, int c)
vi_prev_big_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.buffer)
@ -171,7 +173,7 @@ vi_prev_big_word(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_prev_word(EditLine *el, int c __attribute__((__unused__)))
vi_prev_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.buffer)
@ -196,7 +198,7 @@ vi_prev_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_next_big_word(EditLine *el, int c)
vi_next_big_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor >= el->el_line.lastchar - 1)
@ -220,7 +222,7 @@ vi_next_big_word(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_next_word(EditLine *el, int c __attribute__((__unused__)))
vi_next_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor >= el->el_line.lastchar - 1)
@ -243,7 +245,7 @@ vi_next_word(EditLine *el, int c __attribute__((__unused__)))
* [~]
*/
protected el_action_t
vi_change_case(EditLine *el, int c)
vi_change_case(EditLine *el, Int c)
{
int i;
@ -252,11 +254,11 @@ vi_change_case(EditLine *el, int c)
cv_undo(el);
for (i = 0; i < el->el_state.argument; i++) {
c = *(unsigned char *)el->el_line.cursor;
if (isupper(c))
*el->el_line.cursor = tolower(c);
else if (islower(c))
*el->el_line.cursor = toupper(c);
c = *el->el_line.cursor;
if (Isupper(c))
*el->el_line.cursor = Tolower(c);
else if (Islower(c))
*el->el_line.cursor = Toupper(c);
if (++el->el_line.cursor >= el->el_line.lastchar) {
el->el_line.cursor--;
@ -275,7 +277,7 @@ vi_change_case(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_change_meta(EditLine *el, int c __attribute__((__unused__)))
vi_change_meta(EditLine *el, Int c __attribute__((__unused__)))
{
/*
@ -292,7 +294,7 @@ vi_change_meta(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_insert_at_bol(EditLine *el, int c __attribute__((__unused__)))
vi_insert_at_bol(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_line.cursor = el->el_line.buffer;
@ -308,7 +310,7 @@ vi_insert_at_bol(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_replace_char(EditLine *el, int c __attribute__((__unused__)))
vi_replace_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor >= el->el_line.lastchar)
@ -327,7 +329,7 @@ vi_replace_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_replace_mode(EditLine *el, int c __attribute__((__unused__)))
vi_replace_mode(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_map.current = el->el_map.key;
@ -343,7 +345,7 @@ vi_replace_mode(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_substitute_char(EditLine *el, int c __attribute__((__unused__)))
vi_substitute_char(EditLine *el, Int c __attribute__((__unused__)))
{
c_delafter(el, el->el_state.argument);
@ -358,12 +360,12 @@ vi_substitute_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_substitute_line(EditLine *el, int c __attribute__((__unused__)))
vi_substitute_line(EditLine *el, Int c __attribute__((__unused__)))
{
cv_undo(el);
cv_yank(el, el->el_line.buffer,
el->el_line.lastchar - el->el_line.buffer);
(int)(el->el_line.lastchar - el->el_line.buffer));
(void) em_kill_line(el, 0);
el->el_map.current = el->el_map.key;
return (CC_REFRESH);
@ -376,12 +378,12 @@ vi_substitute_line(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_change_to_eol(EditLine *el, int c __attribute__((__unused__)))
vi_change_to_eol(EditLine *el, Int c __attribute__((__unused__)))
{
cv_undo(el);
cv_yank(el, el->el_line.cursor,
el->el_line.lastchar - el->el_line.cursor);
(int)(el->el_line.lastchar - el->el_line.cursor));
(void) ed_kill_line(el, 0);
el->el_map.current = el->el_map.key;
return (CC_REFRESH);
@ -394,7 +396,7 @@ vi_change_to_eol(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_insert(EditLine *el, int c __attribute__((__unused__)))
vi_insert(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_map.current = el->el_map.key;
@ -409,7 +411,7 @@ vi_insert(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_add(EditLine *el, int c __attribute__((__unused__)))
vi_add(EditLine *el, Int c __attribute__((__unused__)))
{
int ret;
@ -434,7 +436,7 @@ vi_add(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_add_at_eol(EditLine *el, int c __attribute__((__unused__)))
vi_add_at_eol(EditLine *el, Int c __attribute__((__unused__)))
{
el->el_map.current = el->el_map.key;
@ -450,7 +452,7 @@ vi_add_at_eol(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_delete_meta(EditLine *el, int c __attribute__((__unused__)))
vi_delete_meta(EditLine *el, Int c __attribute__((__unused__)))
{
return (cv_action(el, DELETE));
@ -463,7 +465,7 @@ vi_delete_meta(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_end_big_word(EditLine *el, int c)
vi_end_big_word(EditLine *el, Int c)
{
if (el->el_line.cursor == el->el_line.lastchar)
@ -487,7 +489,7 @@ vi_end_big_word(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_end_word(EditLine *el, int c __attribute__((__unused__)))
vi_end_word(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor == el->el_line.lastchar)
@ -511,7 +513,7 @@ vi_end_word(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_undo(EditLine *el, int c __attribute__((__unused__)))
vi_undo(EditLine *el, Int c __attribute__((__unused__)))
{
c_undo_t un = el->el_chared.c_undo;
@ -521,7 +523,8 @@ vi_undo(EditLine *el, int c __attribute__((__unused__)))
/* switch line buffer and undo buffer */
el->el_chared.c_undo.buf = el->el_line.buffer;
el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer;
el->el_chared.c_undo.cursor = el->el_line.cursor - el->el_line.buffer;
el->el_chared.c_undo.cursor =
(int)(el->el_line.cursor - el->el_line.buffer);
el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer);
el->el_line.buffer = un.buf;
el->el_line.cursor = un.buf + un.cursor;
@ -537,7 +540,7 @@ vi_undo(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_command_mode(EditLine *el, int c __attribute__((__unused__)))
vi_command_mode(EditLine *el, Int c __attribute__((__unused__)))
{
/* [Esc] cancels pending action */
@ -561,7 +564,7 @@ vi_command_mode(EditLine *el, int c __attribute__((__unused__)))
* [0]
*/
protected el_action_t
vi_zero(EditLine *el, int c)
vi_zero(EditLine *el, Int c)
{
if (el->el_state.doingarg)
@ -582,7 +585,7 @@ vi_zero(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
vi_delete_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_line.cursor <= el->el_line.buffer)
@ -600,7 +603,7 @@ vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_list_or_eof(EditLine *el, int c)
vi_list_or_eof(EditLine *el, Int c)
{
if (el->el_line.cursor == el->el_line.lastchar) {
@ -637,16 +640,16 @@ vi_list_or_eof(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_kill_line_prev(EditLine *el, int c __attribute__((__unused__)))
vi_kill_line_prev(EditLine *el, Int c __attribute__((__unused__)))
{
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);
c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer));
el->el_line.cursor = el->el_line.buffer; /* zap! */
return (CC_REFRESH);
}
@ -658,7 +661,7 @@ vi_kill_line_prev(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_search_prev(EditLine *el, int c __attribute__((__unused__)))
vi_search_prev(EditLine *el, Int c __attribute__((__unused__)))
{
return (cv_search(el, ED_SEARCH_PREV_HISTORY));
@ -671,7 +674,7 @@ vi_search_prev(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_search_next(EditLine *el, int c __attribute__((__unused__)))
vi_search_next(EditLine *el, Int c __attribute__((__unused__)))
{
return (cv_search(el, ED_SEARCH_NEXT_HISTORY));
@ -684,7 +687,7 @@ vi_search_next(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_repeat_search_next(EditLine *el, int c __attribute__((__unused__)))
vi_repeat_search_next(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_search.patlen == 0)
@ -700,7 +703,7 @@ vi_repeat_search_next(EditLine *el, int c __attribute__((__unused__)))
*/
/*ARGSUSED*/
protected el_action_t
vi_repeat_search_prev(EditLine *el, int c __attribute__((__unused__)))
vi_repeat_search_prev(EditLine *el, Int c __attribute__((__unused__)))
{
if (el->el_search.patlen == 0)
@ -718,7 +721,7 @@ vi_repeat_search_prev(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_next_char(EditLine *el, int c __attribute__((__unused__)))
vi_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0);
}
@ -730,7 +733,7 @@ vi_next_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_prev_char(EditLine *el, int c __attribute__((__unused__)))
vi_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0);
}
@ -742,7 +745,7 @@ vi_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_to_next_char(EditLine *el, int c __attribute__((__unused__)))
vi_to_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1);
}
@ -754,7 +757,7 @@ vi_to_next_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_to_prev_char(EditLine *el, int c __attribute__((__unused__)))
vi_to_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1);
}
@ -766,7 +769,7 @@ vi_to_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_repeat_next_char(EditLine *el, int c __attribute__((__unused__)))
vi_repeat_next_char(EditLine *el, Int c __attribute__((__unused__)))
{
return cv_csearch(el, el->el_search.chadir, el->el_search.chacha,
@ -780,7 +783,7 @@ vi_repeat_next_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_repeat_prev_char(EditLine *el, int c __attribute__((__unused__)))
vi_repeat_prev_char(EditLine *el, Int c __attribute__((__unused__)))
{
el_action_t r;
int dir = el->el_search.chadir;
@ -798,20 +801,20 @@ vi_repeat_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/
protected el_action_t
/*ARGSUSED*/
vi_match(EditLine *el, int c)
vi_match(EditLine *el, Int c)
{
const char match_chars[] = "()[]{}";
char *cp;
int delta, i, count;
char o_ch, c_ch;
const Char match_chars[] = STR("()[]{}");
Char *cp;
size_t delta, i, count;
Char o_ch, c_ch;
*el->el_line.lastchar = '\0'; /* just in case */
i = strcspn(el->el_line.cursor, match_chars);
i = Strcspn(el->el_line.cursor, match_chars);
o_ch = el->el_line.cursor[i];
if (o_ch == 0)
return CC_ERROR;
delta = strchr(match_chars, o_ch) - match_chars;
delta = Strchr(match_chars, o_ch) - match_chars;
c_ch = match_chars[delta ^ 1];
count = 1;
delta = 1 - (delta & 1) * 2;
@ -845,7 +848,7 @@ vi_match(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_undo_line(EditLine *el, int c)
vi_undo_line(EditLine *el, Int c)
{
cv_undo(el);
@ -859,7 +862,7 @@ vi_undo_line(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_to_column(EditLine *el, int c)
vi_to_column(EditLine *el, Int c)
{
el->el_line.cursor = el->el_line.buffer;
@ -873,11 +876,11 @@ vi_to_column(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_yank_end(EditLine *el, int c)
vi_yank_end(EditLine *el, Int c)
{
cv_yank(el, el->el_line.cursor,
el->el_line.lastchar - el->el_line.cursor);
(int)(el->el_line.lastchar - el->el_line.cursor));
return CC_REFRESH;
}
@ -887,7 +890,7 @@ vi_yank_end(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_yank(EditLine *el, int c)
vi_yank(EditLine *el, Int c)
{
return cv_action(el, YANK);
@ -899,7 +902,7 @@ vi_yank(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_comment_out(EditLine *el, int c)
vi_comment_out(EditLine *el, Int c)
{
el->el_line.cursor = el->el_line.buffer;
@ -920,7 +923,7 @@ extern char *get_alias_text(const char *) __weak_reference(get_alias_text);
#endif
protected el_action_t
/*ARGSUSED*/
vi_alias(EditLine *el, int c)
vi_alias(EditLine *el, Int c)
{
#ifdef __weak_reference
char alias_name[3];
@ -937,7 +940,7 @@ vi_alias(EditLine *el, int c)
alias_text = get_alias_text(alias_name);
if (alias_text != NULL)
el_push(el, alias_text);
FUN(el,push)(el, ct_decode_string(alias_text, &el->el_scratch));
return CC_NORM;
#else
return CC_ERROR;
@ -950,14 +953,14 @@ vi_alias(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_to_history_line(EditLine *el, int c)
vi_to_history_line(EditLine *el, Int c)
{
int sv_event_no = el->el_history.eventno;
el_action_t rval;
if (el->el_history.eventno == 0) {
(void) strncpy(el->el_history.buf, el->el_line.buffer,
(void) 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);
@ -995,13 +998,16 @@ vi_to_history_line(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_histedit(EditLine *el, int c)
vi_histedit(EditLine *el, Int c)
{
int fd;
pid_t pid;
int st;
ssize_t st;
int status;
char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
char *cp;
size_t len;
Char *line;
if (el->el_state.doingarg) {
if (vi_to_history_line(el, 0) == CC_ERROR)
@ -1011,29 +1017,54 @@ vi_histedit(EditLine *el, int c)
fd = mkstemp(tempfile);
if (fd < 0)
return CC_ERROR;
cp = el->el_line.buffer;
write(fd, cp, el->el_line.lastchar - cp +0u);
len = (size_t)(el->el_line.lastchar - el->el_line.buffer);
#define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX)
cp = el_malloc(TMP_BUFSIZ);
if (cp == NULL)
return CC_ERROR;
line = el_malloc(len * sizeof(*line));
if (line == NULL) {
el_free((ptr_t)cp);
return CC_ERROR;
}
Strncpy(line, el->el_line.buffer, len);
line[len] = '\0';
ct_wcstombs(cp, line, TMP_BUFSIZ - 1);
cp[TMP_BUFSIZ - 1] = '\0';
len = strlen(cp);
write(fd, cp, len);
write(fd, "\n", 1);
pid = fork();
switch (pid) {
case -1:
close(fd);
unlink(tempfile);
el_free(cp);
el_free(line);
return CC_ERROR;
case 0:
close(fd);
execlp("vi", "vi", tempfile, NULL);
execlp("vi", "vi", tempfile, (char *)NULL);
exit(0);
/*NOTREACHED*/
default:
while (waitpid(pid, &st, 0) != pid)
while (waitpid(pid, &status, 0) != pid)
continue;
lseek(fd, 0ll, SEEK_SET);
st = read(fd, cp, el->el_line.limit - cp +0u);
if (st > 0 && cp[st - 1] == '\n')
st--;
el->el_line.cursor = cp;
el->el_line.lastchar = cp + st;
lseek(fd, (off_t)0, SEEK_SET);
st = read(fd, cp, TMP_BUFSIZ);
if (st > 0) {
len = (size_t)(el->el_line.lastchar -
el->el_line.buffer);
len = ct_mbstowcs(el->el_line.buffer, cp, len);
if (len > 0 && el->el_line.buffer[len -1] == '\n')
--len;
}
else
len = 0;
el->el_line.cursor = el->el_line.buffer;
el->el_line.lastchar = el->el_line.buffer + len;
el_free(cp);
el_free(line);
break;
}
@ -1051,34 +1082,35 @@ vi_histedit(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_history_word(EditLine *el, int c)
vi_history_word(EditLine *el, Int c)
{
const char *wp = HIST_FIRST(el);
const char *wep, *wsp;
const Char *wp = HIST_FIRST(el);
const Char *wep, *wsp;
int len;
char *cp;
const char *lim;
Char *cp;
const Char *lim;
if (wp == NULL)
return CC_ERROR;
wep = wsp = 0;
do {
while (isspace((unsigned char)*wp))
while (Isspace(*wp))
wp++;
if (*wp == 0)
break;
wsp = wp;
while (*wp && !isspace((unsigned char)*wp))
while (*wp && !Isspace(*wp))
wp++;
wep = wp;
} while ((!el->el_state.doingarg || --el->el_state.argument > 0) && *wp != 0);
} while ((!el->el_state.doingarg || --el->el_state.argument > 0)
&& *wp != 0);
if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0))
return CC_ERROR;
cv_undo(el);
len = wep - wsp;
len = (int)(wep - wsp);
if (el->el_line.cursor < el->el_line.lastchar)
el->el_line.cursor++;
c_insert(el, len + 1);
@ -1100,7 +1132,7 @@ vi_history_word(EditLine *el, int c)
*/
protected el_action_t
/*ARGSUSED*/
vi_redo(EditLine *el, int c)
vi_redo(EditLine *el, Int c)
{
c_redo_t *r = &el->el_chared.c_redo;
@ -1116,7 +1148,7 @@ vi_redo(EditLine *el, int c)
/* sanity */
r->pos = r->lim - 1;
r->pos[0] = 0;
el_push(el, r->buf);
FUN(el,push)(el, r->buf);
}
el->el_state.thiscmd = r->cmd;