1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

WL#5945 : Improve libedit library

Updated libedit library.
This commit is contained in:
Nirbhay Choubey
2011-10-14 01:03:25 +05:30
parent 41b97529d0
commit 05a38e7bf3
52 changed files with 5379 additions and 3000 deletions

View File

@ -7,19 +7,19 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include
noinst_LIBRARIES = libedit.a noinst_LIBRARIES = libedit.a
libedit_a_SOURCES = chared.c el.c history.c map.c prompt.c readline.c \ libedit_a_SOURCES = chared.c el.c eln.c history.c historyn.c map.c prompt.c readline.c \
search.c tokenizer.c vi.c common.c emacs.c \ search.c tokenizer.c tokenizern.c vi.c common.c emacs.c \
hist.c key.c parse.c read.c refresh.c sig.c term.c \ hist.c keymacro.c parse.c read.c refresh.c sig.c terminal.c \
tty.c help.c fcns.c filecomplete.c \ tty.c help.c fcns.c filecomplete.c \
np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c \ np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c \
np/fgetln.c np/fgetln.c np/wcsdup.c
libedit_a_LIBADD = @LIBEDIT_LOBJECTS@ libedit_a_LIBADD = @LIBEDIT_LOBJECTS@
libedit_a_DEPENDENCIES = @LIBEDIT_LOBJECTS@ libedit_a_DEPENDENCIES = @LIBEDIT_LOBJECTS@
pkginclude_HEADERS = readline/readline.h pkginclude_HEADERS = readline/readline.h
noinst_HEADERS = chared.h el.h el_term.h histedit.h key.h parse.h refresh.h sig.h \ noinst_HEADERS = chared.h el.h el_terminal.h histedit.h keymacro.h parse.h refresh.h sig.h \
sys.h config.h hist.h map.h prompt.h read.h \ sys.h config.h hist.h map.h prompt.h read.h \
search.h tty.h filecomplete.h np/vis.h search.h tty.h filecomplete.h np/vis.h
@ -70,22 +70,25 @@ fcns.c: ${AHDR} fcns.h makelist
chared.o: vi.h emacs.h common.h help.h fcns.h chared.o: vi.h emacs.h common.h help.h fcns.h
el.o: vi.h emacs.h common.h help.h fcns.h el.o: vi.h emacs.h common.h help.h fcns.h
eln.o: vi.h emacs.h common.h help.h fcns.h
history.o: vi.h emacs.h common.h help.h fcns.h history.o: vi.h emacs.h common.h help.h fcns.h
historyn.o: vi.h emacs.h common.h help.h fcns.h
map.o: vi.h emacs.h common.h help.h fcns.h map.o: vi.h emacs.h common.h help.h fcns.h
prompt.o: vi.h emacs.h common.h help.h fcns.h prompt.o: vi.h emacs.h common.h help.h fcns.h
readline.o: vi.h emacs.h common.h help.h fcns.h readline.o: vi.h emacs.h common.h help.h fcns.h
search.o: vi.h emacs.h common.h help.h fcns.h search.o: vi.h emacs.h common.h help.h fcns.h
tokenizer.o: vi.h emacs.h common.h help.h fcns.h tokenizer.o: vi.h emacs.h common.h help.h fcns.h
tokenizern.o: vi.h emacs.h common.h help.h fcns.h
vi.o: vi.h emacs.h common.h help.h fcns.h vi.o: vi.h emacs.h common.h help.h fcns.h
common.o: vi.h emacs.h common.h help.h fcns.h common.o: vi.h emacs.h common.h help.h fcns.h
emacs.o: vi.h emacs.h common.h help.h fcns.h emacs.o: vi.h emacs.h common.h help.h fcns.h
hist.o: vi.h emacs.h common.h help.h fcns.h hist.o: vi.h emacs.h common.h help.h fcns.h
key.o: vi.h emacs.h common.h help.h fcns.h keymacro.o: vi.h emacs.h common.h help.h fcns.h
parse.o: vi.h emacs.h common.h help.h fcns.h parse.o: vi.h emacs.h common.h help.h fcns.h
read.o: vi.h emacs.h common.h help.h fcns.h read.o: vi.h emacs.h common.h help.h fcns.h
refresh.o: vi.h emacs.h common.h help.h fcns.h refresh.o: vi.h emacs.h common.h help.h fcns.h
sig.o: vi.h emacs.h common.h help.h fcns.h sig.o: vi.h emacs.h common.h help.h fcns.h
term.o: vi.h emacs.h common.h help.h fcns.h terminal.o: vi.h emacs.h common.h help.h fcns.h
tty.o: vi.h emacs.h common.h help.h fcns.h tty.o: vi.h emacs.h common.h help.h fcns.h
help.o: vi.h emacs.h common.h help.h fcns.h help.o: vi.h emacs.h common.h help.h fcns.h
fcns.o: vi.h emacs.h common.h help.h fcns.h fcns.o: vi.h emacs.h common.h help.h fcns.h

View File

@ -2,7 +2,7 @@ An approximate method to merge from upstream is:
# Fetch latest from upstream (we also include some compat stuff) # Fetch latest from upstream (we also include some compat stuff)
$ CVS_RSH=ssh; export CVS_RSH $ CVS_RSH=ssh; export CVS_RSH
$ CVSROOT="anoncvs@stripped:/cvsroot" $ CVSROOT="anoncvs@anoncvs.netbsd.org:/cvsroot"
$ cvs co -d libedit -P src/lib/libedit $ cvs co -d libedit -P src/lib/libedit
$ mkdir libedit/np $ mkdir libedit/np
$ for f in src/common/lib/libc/string/strlcat.c \ $ for f in src/common/lib/libc/string/strlcat.c \
@ -24,13 +24,13 @@ An approximate method to merge from upstream is:
# Rename files to match our naming # Rename files to match our naming
$ mv makelist makelist.sh $ mv makelist makelist.sh
$ mv term.h el_term.h $ mv terminal.h el_terminal.h
# Remove NetBSD-specific bits # Remove NetBSD-specific bits
$ for file in $(find . -type f) $ for file in $(find . -type f)
> do > do
> cp ${file} ${file}.orig > cp ${file} ${file}.orig
> sed -e 's/#include "term.h"/#include "el_term.h"/g' \ > sed -e 's/#include "terminal.h"/#include "el_terminal.h"/g' \
> -e 's/sig_handler/el_sig_handler/g' \ > -e 's/sig_handler/el_sig_handler/g' \
> -e 's/isprint/el_isprint/g' \ > -e 's/isprint/el_isprint/g' \
> -e '/^__RCSID/d' \ > -e '/^__RCSID/d' \
@ -42,9 +42,9 @@ then merge remaining bits by hand. All MySQL-specific changes should be
marked with XXXMYSQL to make them easier to identify and merge. To generate marked with XXXMYSQL to make them easier to identify and merge. To generate
a 'clean' diff against upstream you can use the above commands but use a 'clean' diff against upstream you can use the above commands but use
cvs co -D "2009/02/06 20:09:00" [..] cvs co -D "2011/10/04 15:27:04" [..]
to fetch the baseline of most recent merge. to fetch the baseline of most recent merge.
Please feed any fixes to Jonathan Perkin <jperkin@stripped> who will endeavour Please feed any fixes to Jonathan Perkin <jonathan.perkin@oracle.com> who will
to merge them upstream and keep diffs minimal. endeavour to merge them upstream and keep diffs minimal.

View File

@ -1,4 +1,4 @@
/* $NetBSD: chared.c,v 1.26 2009/02/06 12:45:25 sketch Exp $ */ /* $NetBSD: chared.c,v 1.35 2011/08/16 16:25:15 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -59,13 +59,13 @@ cv_undo(EditLine *el)
{ {
c_undo_t *vu = &el->el_chared.c_undo; c_undo_t *vu = &el->el_chared.c_undo;
c_redo_t *r = &el->el_chared.c_redo; c_redo_t *r = &el->el_chared.c_redo;
unsigned int size; size_t size;
/* Save entire line for undo */ /* Save entire line for undo */
size = el->el_line.lastchar - el->el_line.buffer; size = (size_t)(el->el_line.lastchar - el->el_line.buffer);
vu->len = size; vu->len = (ssize_t)size;
vu->cursor = el->el_line.cursor - el->el_line.buffer; vu->cursor = (int)(el->el_line.cursor - el->el_line.buffer);
memcpy(vu->buf, el->el_line.buffer, size); (void)memcpy(vu->buf, el->el_line.buffer, size * sizeof(*vu->buf));
/* save command info for redo */ /* save command info for redo */
r->count = el->el_state.doingarg ? el->el_state.argument : 0; r->count = el->el_state.doingarg ? el->el_state.argument : 0;
@ -79,11 +79,11 @@ cv_undo(EditLine *el)
* Save yank/delete data for paste * Save yank/delete data for paste
*/ */
protected void 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; c_kill_t *k = &el->el_chared.c_kill;
memcpy(k->buf, ptr, size +0u); (void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf));
k->last = k->buf + size; k->last = k->buf + size;
} }
@ -94,10 +94,10 @@ cv_yank(EditLine *el, const char *ptr, int size)
protected void protected void
c_insert(EditLine *el, int num) c_insert(EditLine *el, int num)
{ {
char *cp; Char *cp;
if (el->el_line.lastchar + num >= el->el_line.limit) { if (el->el_line.lastchar + num >= el->el_line.limit) {
if (!ch_enlargebufs(el, num +0u)) if (!ch_enlargebufs(el, (size_t)num))
return; /* can't go past end of buffer */ return; /* can't go past end of buffer */
} }
@ -118,7 +118,7 @@ c_delafter(EditLine *el, int num)
{ {
if (el->el_line.cursor + num > el->el_line.lastchar) if (el->el_line.cursor + num > el->el_line.lastchar)
num = el->el_line.lastchar - el->el_line.cursor; num = (int)(el->el_line.lastchar - el->el_line.cursor);
if (el->el_map.current != el->el_map.emacs) { if (el->el_map.current != el->el_map.emacs) {
cv_undo(el); cv_undo(el);
@ -126,7 +126,7 @@ c_delafter(EditLine *el, int num)
} }
if (num > 0) { if (num > 0) {
char *cp; Char *cp;
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
*cp = cp[num]; *cp = cp[num];
@ -142,7 +142,7 @@ c_delafter(EditLine *el, int num)
protected void protected void
c_delafter1(EditLine *el) c_delafter1(EditLine *el)
{ {
char *cp; Char *cp;
for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++)
*cp = cp[1]; *cp = cp[1];
@ -159,7 +159,7 @@ c_delbefore(EditLine *el, int num)
{ {
if (el->el_line.cursor - num < el->el_line.buffer) if (el->el_line.cursor - num < el->el_line.buffer)
num = el->el_line.cursor - el->el_line.buffer; num = (int)(el->el_line.cursor - el->el_line.buffer);
if (el->el_map.current != el->el_map.emacs) { if (el->el_map.current != el->el_map.emacs) {
cv_undo(el); cv_undo(el);
@ -167,7 +167,7 @@ c_delbefore(EditLine *el, int num)
} }
if (num > 0) { if (num > 0) {
char *cp; Char *cp;
for (cp = el->el_line.cursor - num; for (cp = el->el_line.cursor - num;
cp <= el->el_line.lastchar; cp <= el->el_line.lastchar;
@ -185,7 +185,7 @@ c_delbefore(EditLine *el, int num)
protected void protected void
c_delbefore1(EditLine *el) c_delbefore1(EditLine *el)
{ {
char *cp; Char *cp;
for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++) for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++)
*cp = cp[1]; *cp = cp[1];
@ -198,9 +198,9 @@ c_delbefore1(EditLine *el)
* Return if p is part of a word according to emacs * Return if p is part of a word according to emacs
*/ */
protected int protected int
ce__isword(int p) ce__isword(Int p)
{ {
return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL); return Isalnum(p || Strchr(STR("*?_-.[]~="), p) != NULL);
} }
@ -208,11 +208,11 @@ ce__isword(int p)
* Return if p is part of a word according to vi * Return if p is part of a word according to vi
*/ */
protected int protected int
cv__isword(int p) cv__isword(Int p)
{ {
if (isalnum(p) || p == '_') if (Isalnum(p) || p == '_')
return 1; return 1;
if (isgraph(p)) if (Isgraph(p))
return 2; return 2;
return 0; return 0;
} }
@ -222,24 +222,24 @@ cv__isword(int p)
* Return if p is part of a big word according to vi * Return if p is part of a big word according to vi
*/ */
protected int protected int
cv__isWord(int p) cv__isWord(Int p)
{ {
return (!isspace(p)); return !Isspace(p);
} }
/* c__prev_word(): /* c__prev_word():
* Find the previous word * Find the previous word
*/ */
protected char * protected Char *
c__prev_word(char *p, char *low, int n, int (*wtest)(int)) c__prev_word(Char *p, Char *low, int n, int (*wtest)(Int))
{ {
p--; p--;
while (n--) { while (n--) {
while ((p >= low) && !(*wtest)((unsigned char) *p)) while ((p >= low) && !(*wtest)(*p))
p--; p--;
while ((p >= low) && (*wtest)((unsigned char) *p)) while ((p >= low) && (*wtest)(*p))
p--; p--;
} }
@ -248,117 +248,83 @@ c__prev_word(char *p, char *low, int n, int (*wtest)(int))
if (p < low) if (p < low)
p = low; p = low;
/* cp now points where we want it */ /* cp now points where we want it */
return (p); return p;
} }
/* c__next_word(): /* c__next_word():
* Find the next word * Find the next word
*/ */
protected char * protected Char *
c__next_word(char *p, char *high, int n, int (*wtest)(int)) c__next_word(Char *p, Char *high, int n, int (*wtest)(Int))
{ {
while (n--) { while (n--) {
while ((p < high) && !(*wtest)((unsigned char) *p)) while ((p < high) && !(*wtest)(*p))
p++; p++;
while ((p < high) && (*wtest)((unsigned char) *p)) while ((p < high) && (*wtest)(*p))
p++; p++;
} }
if (p > high) if (p > high)
p = high; p = high;
/* p now points where we want it */ /* p now points where we want it */
return (p); return p;
} }
/* cv_next_word(): /* cv_next_word():
* Find the next word vi style * Find the next word vi style
*/ */
protected char * protected Char *
cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int)) cv_next_word(EditLine *el, Char *p, Char *high, int n, int (*wtest)(Int))
{ {
int test; int test;
while (n--) { while (n--) {
test = (*wtest)((unsigned char) *p); test = (*wtest)(*p);
while ((p < high) && (*wtest)((unsigned char) *p) == test) while ((p < high) && (*wtest)(*p) == test)
p++; p++;
/* /*
* vi historically deletes with cw only the word preserving the * vi historically deletes with cw only the word preserving the
* trailing whitespace! This is not what 'w' does.. * trailing whitespace! This is not what 'w' does..
*/ */
if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT)) if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT))
while ((p < high) && isspace((unsigned char) *p)) while ((p < high) && Isspace(*p))
p++; p++;
} }
/* p now points where we want it */ /* p now points where we want it */
if (p > high) if (p > high)
return (high); return high;
else else
return (p); return p;
} }
/* cv_prev_word(): /* cv_prev_word():
* Find the previous word vi style * Find the previous word vi style
*/ */
protected char * protected Char *
cv_prev_word(char *p, char *low, int n, int (*wtest)(int)) cv_prev_word(Char *p, Char *low, int n, int (*wtest)(Int))
{ {
int test; int test;
p--; p--;
while (n--) { while (n--) {
while ((p > low) && isspace((unsigned char) *p)) while ((p > low) && Isspace(*p))
p--; p--;
test = (*wtest)((unsigned char) *p); test = (*wtest)(*p);
while ((p >= low) && (*wtest)((unsigned char) *p) == test) while ((p >= low) && (*wtest)(*p) == test)
p--; p--;
} }
p++; p++;
/* p now points where we want it */ /* p now points where we want it */
if (p < low) if (p < low)
return (low); return low;
else else
return (p); return p;
} }
#ifdef notdef
/* c__number():
* Ignore character p points to, return number appearing after that.
* A '$' by itself means a big number; "$-" is for negative; '^' means 1.
* Return p pointing to last char used.
*/
protected char *
c__number(
char *p, /* character position */
int *num, /* Return value */
int dval) /* dval is the number to subtract from like $-3 */
{
int i;
int sign = 1;
if (*++p == '^') {
*num = 1;
return (p);
}
if (*p == '$') {
if (*++p != '-') {
*num = 0x7fffffff; /* Handle $ */
return (--p);
}
sign = -1; /* Handle $- */
++p;
}
for (i = 0; isdigit((unsigned char) *p); i = 10 * i + *p++ - '0')
continue;
*num = (sign < 0 ? dval - i : i);
return (--p);
}
#endif
/* cv_delfini(): /* cv_delfini():
* Finish vi delete action * Finish vi delete action
*/ */
@ -375,7 +341,7 @@ cv_delfini(EditLine *el)
/* sanity */ /* sanity */
return; 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) if (size == 0)
size = 1; size = 1;
el->el_line.cursor = el->el_chared.c_vcmd.pos; el->el_line.cursor = el->el_chared.c_vcmd.pos;
@ -397,48 +363,26 @@ cv_delfini(EditLine *el)
} }
#ifdef notdef
/* ce__endword():
* Go to the end of this word according to emacs
*/
protected char *
ce__endword(char *p, char *high, int n)
{
p++;
while (n--) {
while ((p < high) && isspace((unsigned char) *p))
p++;
while ((p < high) && !isspace((unsigned char) *p))
p++;
}
p--;
return (p);
}
#endif
/* cv__endword(): /* cv__endword():
* Go to the end of this word according to vi * Go to the end of this word according to vi
*/ */
protected char * protected Char *
cv__endword(char *p, char *high, int n, int (*wtest)(int)) cv__endword(Char *p, Char *high, int n, int (*wtest)(Int))
{ {
int test; int test;
p++; p++;
while (n--) { while (n--) {
while ((p < high) && isspace((unsigned char) *p)) while ((p < high) && Isspace(*p))
p++; p++;
test = (*wtest)((unsigned char) *p); test = (*wtest)(*p);
while ((p < high) && (*wtest)((unsigned char) *p) == test) while ((p < high) && (*wtest)(*p) == test)
p++; p++;
} }
p--; p--;
return (p); return p;
} }
/* ch_init(): /* ch_init():
@ -449,24 +393,29 @@ ch_init(EditLine *el)
{ {
c_macro_t *ma = &el->el_chared.c_macro; 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) if (el->el_line.buffer == NULL)
return (-1); 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.cursor = el->el_line.buffer;
el->el_line.lastchar = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer;
el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE]; 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) if (el->el_chared.c_undo.buf == NULL)
return (-1); return -1;
(void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ); (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ *
sizeof(*el->el_chared.c_undo.buf));
el->el_chared.c_undo.len = -1; el->el_chared.c_undo.len = -1;
el->el_chared.c_undo.cursor = 0; 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) if (el->el_chared.c_redo.buf == NULL)
return (-1); return -1;
el->el_chared.c_redo.pos = el->el_chared.c_redo.buf; el->el_chared.c_redo.pos = el->el_chared.c_redo.buf;
el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ; el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ;
el->el_chared.c_redo.cmd = ED_UNASSIGNED; el->el_chared.c_redo.cmd = ED_UNASSIGNED;
@ -474,12 +423,16 @@ ch_init(EditLine *el)
el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_vcmd.pos = el->el_line.buffer; el->el_chared.c_vcmd.pos = el->el_line.buffer;
el->el_chared.c_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) if (el->el_chared.c_kill.buf == NULL)
return (-1); 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.mark = el->el_line.buffer;
el->el_chared.c_kill.last = el->el_chared.c_kill.buf; el->el_chared.c_kill.last = el->el_chared.c_kill.buf;
el->el_chared.c_resizefun = NULL;
el->el_chared.c_resizearg = NULL;
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
@ -491,10 +444,10 @@ ch_init(EditLine *el)
ma->level = -1; ma->level = -1;
ma->offset = 0; 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) if (ma->macro == NULL)
return (-1); return -1;
return (0); return 0;
} }
/* ch_reset(): /* ch_reset():
@ -529,12 +482,11 @@ ch_reset(EditLine *el, int mclear)
} }
private void private void
ch__clearmacro(el) ch__clearmacro(EditLine *el)
EditLine *el;
{ {
c_macro_t *ma = &el->el_chared.c_macro; c_macro_t *ma = &el->el_chared.c_macro;
while (ma->level >= 0) while (ma->level >= 0)
el_free((ptr_t)ma->macro[ma->level--]); el_free(ma->macro[ma->level--]);
} }
/* ch_enlargebufs(): /* ch_enlargebufs():
@ -542,14 +494,12 @@ ch__clearmacro(el)
* Returns 1 if successful, 0 if not. * Returns 1 if successful, 0 if not.
*/ */
protected int protected int
ch_enlargebufs(el, addlen) ch_enlargebufs(EditLine *el, size_t addlen)
EditLine *el;
size_t addlen;
{ {
size_t sz, newsz; size_t sz, newsz;
char *newbuffer, *oldbuf, *oldkbuf; Char *newbuffer, *oldbuf, *oldkbuf;
sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE; sz = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE);
newsz = sz * 2; newsz = sz * 2;
/* /*
* If newly required length is longer than current buffer, we need * If newly required length is longer than current buffer, we need
@ -563,12 +513,12 @@ ch_enlargebufs(el, addlen)
/* /*
* Reallocate line buffer. * Reallocate line buffer.
*/ */
newbuffer = el_realloc(el->el_line.buffer, newsz); newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer));
if (!newbuffer) if (!newbuffer)
return 0; return 0;
/* zero the newly added memory, leave old data in */ /* zero the newly added memory, leave old data in */
(void) memset(&newbuffer[sz], 0, newsz - sz); (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
oldbuf = el->el_line.buffer; oldbuf = el->el_line.buffer;
@ -581,12 +531,13 @@ ch_enlargebufs(el, addlen)
/* /*
* Reallocate kill buffer. * 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) if (!newbuffer)
return 0; return 0;
/* zero the newly added memory, leave old data in */ /* zero the newly added memory, leave old data in */
(void) memset(&newbuffer[sz], 0, newsz - sz); (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
oldkbuf = el->el_chared.c_kill.buf; oldkbuf = el->el_chared.c_kill.buf;
@ -599,15 +550,17 @@ ch_enlargebufs(el, addlen)
/* /*
* Reallocate undo buffer. * 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) if (!newbuffer)
return 0; return 0;
/* zero the newly added memory, leave old data in */ /* zero the newly added memory, leave old data in */
(void) memset(&newbuffer[sz], 0, newsz - sz); (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer));
el->el_chared.c_undo.buf = 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) if (!newbuffer)
return 0; return 0;
el->el_chared.c_redo.pos = newbuffer + el->el_chared.c_redo.pos = newbuffer +
@ -621,6 +574,8 @@ ch_enlargebufs(el, addlen)
/* Safe to set enlarged buffer size */ /* Safe to set enlarged buffer size */
el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE]; el->el_line.limit = &el->el_line.buffer[newsz - EL_LEAVE];
if (el->el_chared.c_resizefun)
(*el->el_chared.c_resizefun)(el, el->el_chared.c_resizearg);
return 1; return 1;
} }
@ -630,20 +585,20 @@ ch_enlargebufs(el, addlen)
protected void protected void
ch_end(EditLine *el) ch_end(EditLine *el)
{ {
el_free((ptr_t) el->el_line.buffer); el_free(el->el_line.buffer);
el->el_line.buffer = NULL; el->el_line.buffer = NULL;
el->el_line.limit = NULL; el->el_line.limit = NULL;
el_free((ptr_t) el->el_chared.c_undo.buf); el_free(el->el_chared.c_undo.buf);
el->el_chared.c_undo.buf = NULL; el->el_chared.c_undo.buf = NULL;
el_free((ptr_t) el->el_chared.c_redo.buf); el_free(el->el_chared.c_redo.buf);
el->el_chared.c_redo.buf = NULL; el->el_chared.c_redo.buf = NULL;
el->el_chared.c_redo.pos = NULL; el->el_chared.c_redo.pos = NULL;
el->el_chared.c_redo.lim = NULL; el->el_chared.c_redo.lim = NULL;
el->el_chared.c_redo.cmd = ED_UNASSIGNED; el->el_chared.c_redo.cmd = ED_UNASSIGNED;
el_free((ptr_t) el->el_chared.c_kill.buf); el_free(el->el_chared.c_kill.buf);
el->el_chared.c_kill.buf = NULL; el->el_chared.c_kill.buf = NULL;
ch_reset(el, 1); ch_reset(el, 1);
el_free((ptr_t) el->el_chared.c_macro.macro); el_free(el->el_chared.c_macro.macro);
el->el_chared.c_macro.macro = NULL; el->el_chared.c_macro.macro = NULL;
} }
@ -652,21 +607,21 @@ ch_end(EditLine *el)
* Insert string at cursorI * Insert string at cursorI
*/ */
public int public int
el_insertstr(EditLine *el, const char *s) FUN(el,insertstr)(EditLine *el, const Char *s)
{ {
size_t len; size_t len;
if ((len = strlen(s)) == 0) if ((len = Strlen(s)) == 0)
return (-1); return -1;
if (el->el_line.lastchar + len >= el->el_line.limit) { if (el->el_line.lastchar + len >= el->el_line.limit) {
if (!ch_enlargebufs(el, len)) if (!ch_enlargebufs(el, len))
return (-1); return -1;
} }
c_insert(el, (int)len); c_insert(el, (int)len);
while (*s) while (*s)
*el->el_line.cursor++ = *s++; *el->el_line.cursor++ = *s++;
return (0); return 0;
} }
@ -692,15 +647,15 @@ el_deletestr(EditLine *el, int n)
* Get a string * Get a string
*/ */
protected int protected int
c_gets(EditLine *el, char *buf, const char *prompt) c_gets(EditLine *el, Char *buf, const Char *prompt)
{ {
char ch; Char ch;
int len; ssize_t len;
char *cp = el->el_line.buffer; Char *cp = el->el_line.buffer;
if (prompt) { if (prompt) {
len = strlen(prompt); len = (ssize_t)Strlen(prompt);
memcpy(cp, prompt, len + 0u); (void)memcpy(cp, prompt, (size_t)len * sizeof(*cp));
cp += len; cp += len;
} }
len = 0; len = 0;
@ -711,7 +666,7 @@ c_gets(EditLine *el, char *buf, const char *prompt)
el->el_line.lastchar = cp + 1; el->el_line.lastchar = cp + 1;
re_refresh(el); re_refresh(el);
if (el_getc(el, &ch) != 1) { if (FUN(el,getc)(el, &ch) != 1) {
ed_end_of_file(el, 0); ed_end_of_file(el, 0);
len = -1; len = -1;
break; break;
@ -721,7 +676,7 @@ c_gets(EditLine *el, char *buf, const char *prompt)
case 0010: /* Delete and backspace */ case 0010: /* Delete and backspace */
case 0177: case 0177:
if (len <= 0) { if (len == 0) {
len = -1; len = -1;
break; break;
} }
@ -735,8 +690,8 @@ c_gets(EditLine *el, char *buf, const char *prompt)
break; break;
default: default:
if (len >= EL_BUFSIZ - 16) if (len >= (ssize_t)(EL_BUFSIZ - 16))
term_beep(el); terminal_beep(el);
else { else {
buf[len++] = ch; buf[len++] = ch;
*cp++ = ch; *cp++ = ch;
@ -749,7 +704,7 @@ c_gets(EditLine *el, char *buf, const char *prompt)
el->el_line.buffer[0] = '\0'; el->el_line.buffer[0] = '\0';
el->el_line.lastchar = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer;
el->el_line.cursor = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer;
return len; return (int)len;
} }
@ -759,18 +714,26 @@ c_gets(EditLine *el, char *buf, const char *prompt)
protected int protected int
c_hpos(EditLine *el) c_hpos(EditLine *el)
{ {
char *ptr; Char *ptr;
/* /*
* Find how many characters till the beginning of this line. * Find how many characters till the beginning of this line.
*/ */
if (el->el_line.cursor == el->el_line.buffer) if (el->el_line.cursor == el->el_line.buffer)
return (0); return 0;
else { else {
for (ptr = el->el_line.cursor - 1; for (ptr = el->el_line.cursor - 1;
ptr >= el->el_line.buffer && *ptr != '\n'; ptr >= el->el_line.buffer && *ptr != '\n';
ptr--) ptr--)
continue; continue;
return (el->el_line.cursor - ptr - 1); return (int)(el->el_line.cursor - ptr - 1);
} }
} }
protected int
ch_resizefun(EditLine *el, el_zfunc_t f, void *a)
{
el->el_chared.c_resizefun = f;
el->el_chared.c_resizearg = a;
return 0;
}

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.21 2010/08/28 15:44:59 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -63,25 +63,25 @@
typedef struct c_macro_t { typedef struct c_macro_t {
int level; int level;
int offset; int offset;
char **macro; Char **macro;
} c_macro_t; } c_macro_t;
/* /*
* Undo information for vi - no undo in emacs (yet) * Undo information for vi - no undo in emacs (yet)
*/ */
typedef struct c_undo_t { typedef struct c_undo_t {
int len; /* length of saved line */ ssize_t len; /* length of saved line */
int cursor; /* position of saved cursor */ int cursor; /* position of saved cursor */
char *buf; /* full saved text */ Char *buf; /* full saved text */
} c_undo_t; } c_undo_t;
/* redo for vi */ /* redo for vi */
typedef struct c_redo_t { typedef struct c_redo_t {
char *buf; /* redo insert key sequence */ Char *buf; /* redo insert key sequence */
char *pos; Char *pos;
char *lim; Char *lim;
el_action_t cmd; /* command to redo */ el_action_t cmd; /* command to redo */
char ch; /* char that invoked it */ Char ch; /* char that invoked it */
int count; int count;
int action; /* from cv_action() */ int action; /* from cv_action() */
} c_redo_t; } c_redo_t;
@ -91,18 +91,20 @@ typedef struct c_redo_t {
*/ */
typedef struct c_vcmd_t { typedef struct c_vcmd_t {
int action; int action;
char *pos; Char *pos;
} c_vcmd_t; } c_vcmd_t;
/* /*
* Kill buffer for emacs * Kill buffer for emacs
*/ */
typedef struct c_kill_t { typedef struct c_kill_t {
char *buf; Char *buf;
char *last; Char *last;
char *mark; Char *mark;
} c_kill_t; } c_kill_t;
typedef void (*el_zfunc_t)(EditLine *, void *);
/* /*
* Note that we use both data structures because the user can bind * Note that we use both data structures because the user can bind
* commands from both editors! * commands from both editors!
@ -113,13 +115,14 @@ typedef struct el_chared_t {
c_redo_t c_redo; c_redo_t c_redo;
c_vcmd_t c_vcmd; c_vcmd_t c_vcmd;
c_macro_t c_macro; c_macro_t c_macro;
el_zfunc_t c_resizefun;
void * c_resizearg;
} el_chared_t; } el_chared_t;
#define STRQQ "\"\"" #define STRQQ "\"\""
#define isglob(a) (strchr("*[]?", (a)) != NULL) #define isglob(a) (strchr("*[]?", (a)) != NULL)
#define isword(a) (el_isprint(a))
#define NOP 0x00 #define NOP 0x00
#define DELETE 0x01 #define DELETE 0x01
@ -140,27 +143,28 @@ typedef struct el_chared_t {
#include "fcns.h" #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 void cv_delfini(EditLine *);
protected char *cv__endword(char *, char *, int, int (*)(int)); protected Char *cv__endword(Char *, Char *, int, int (*)(Int));
protected int ce__isword(int); protected int ce__isword(Int);
protected void cv_undo(EditLine *); protected void cv_undo(EditLine *);
protected void cv_yank(EditLine *, const char *, int); protected void cv_yank(EditLine *, const Char *, int);
protected char *cv_next_word(EditLine*, char *, char *, int, int (*)(int)); protected Char *cv_next_word(EditLine*, Char *, Char *, int, int (*)(Int));
protected char *cv_prev_word(char *, char *, int, int (*)(int)); protected Char *cv_prev_word(Char *, Char *, int, int (*)(Int));
protected char *c__next_word(char *, char *, int, int (*)(int)); protected Char *c__next_word(Char *, Char *, int, int (*)(Int));
protected char *c__prev_word(char *, char *, int, int (*)(int)); protected Char *c__prev_word(Char *, Char *, int, int (*)(Int));
protected void c_insert(EditLine *, int); protected void c_insert(EditLine *, int);
protected void c_delbefore(EditLine *, int); protected void c_delbefore(EditLine *, int);
protected void c_delbefore1(EditLine *); protected void c_delbefore1(EditLine *);
protected void c_delafter(EditLine *, int); protected void c_delafter(EditLine *, int);
protected void c_delafter1(EditLine *); 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 c_hpos(EditLine *);
protected int ch_init(EditLine *); protected int ch_init(EditLine *);
protected void ch_reset(EditLine *, int); protected void ch_reset(EditLine *, int);
protected int ch_resizefun(EditLine *, el_zfunc_t, void *);
protected int ch_enlargebufs(EditLine *, size_t); protected int ch_enlargebufs(EditLine *, size_t);
protected void ch_end(EditLine *); protected void ch_end(EditLine *);

View File

@ -0,0 +1,364 @@
/* $NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 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)
#endif /* not lint && not SCCSID */
#include "el.h"
#include <stdlib.h>
#define CT_BUFSIZ ((size_t)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 * sizeof(*conv->cbuff));
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 * sizeof(*conv->wbuff));
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;
mbstate_t state;
memset(&state, 0, sizeof(mbstate_t));
if (!s)
return NULL;
if (!conv->cbuff)
ct_conv_buff_resize(conv, CT_BUFSIZ, (size_t)0);
if (!conv->cbuff)
return NULL;
dst = conv->cbuff;
while (*s) {
used = (ssize_t)(conv->csize - (size_t)(dst - conv->cbuff));
if (used < 5) {
used = dst - conv->cbuff;
ct_conv_buff_resize(conv, conv->csize + CT_BUFSIZ,
(size_t)0);
if (!conv->cbuff)
return NULL;
dst = conv->cbuff + used;
}
used = ct_encode_char(dst, (size_t)5, *s, &state);
if (used == -1) /* failed to encode, need more buffer space */
abort();
++s;
dst += 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, (size_t)0, CT_BUFSIZ);
if (!conv->wbuff)
return NULL;
len = ct_mbstowcs(NULL, s, (size_t)0);
if (len == (size_t)-1)
return NULL;
if (len > conv->wsize)
ct_conv_buff_resize(conv, (size_t)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;
mbstate_t state;
/* 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, (size_t)0, bufspace);
if (!conv->wsize)
return NULL;
wargv = el_malloc((size_t)argc * sizeof(*wargv));
for (i = 0, p = conv->wbuff; i < argc; ++i) {
if (!argv[i]) { /* don't pass null pointers to mbsrtowcs */
wargv[i] = NULL;
continue;
} else {
wargv[i] = p;
memset(&state, 0, sizeof(mbstate_t));
bytes = (ssize_t)mbsrtowcs(p, argv + i, bufspace, &state);
}
if (bytes == -1) {
el_free(wargv);
return NULL;
} else
bytes++; /* include '\0' in the count */
bufspace -= (size_t)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, mbstate_t *state)
{
ssize_t l = 0;
if (len < ct_enc_width(c))
return -1;
l = wcrtomb(dst, c, state);
if (l < 0) {
memset (state, 0, sizeof (mbstate_t));
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 - (size_t)(dst - buff), *s);
if (used == -1) { /* failed to encode, need more buffer space */
used = dst - buff;
buffsize += CT_BUFSIZ;
p = el_realloc(buff, buffsize * sizeof(*buff));
if (p == NULL)
goto out;
buff = p;
dst = buff + used;
/* don't increment s here - we want to retry it! */
}
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;
}
#ifdef WIDECHAR
int wcwidth(wchar_t wc); // Signature.
#endif
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;
}

View File

@ -0,0 +1,252 @@
/* $NetBSD: chartype.h,v 1.8 2011/07/29 23:44:44 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... */
/* XXXMYSQL : Added FreeBSD to bypass this check.
TODO : Verify if FreeBSD stores ISO 10646 in wchar_t. */
#if !defined(__NetBSD__) && !defined(__sun) \
&& !(defined(__APPLE__) && defined(__MACH__)) \
&& !defined(__FreeBSD__)
#ifndef __STDC_ISO_10646__
/* In many places it is assumed that the first 127 code points are ASCII
* compatible, so ensure wchar_t indeed does ISO 10646 and not some other
* 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
#ifndef HAVE_WCSDUP
wchar_t *wcsdup(const wchar_t *s);
#endif
#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, mbstate_t *);
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, ps) (*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 ((size_t)8)
/* The terminal is thought of in terms of X columns by Y lines. In the cases
* where a wide character takes up more than one column, the adjacent
* occupied column entries will contain this faux character. */
#define MB_FILL_CHAR ((Char)-1)
/* 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 */

View File

@ -1,4 +1,4 @@
/* $NetBSD: common.c,v 1.21 2008/09/30 08:37:42 aymeric Exp $ */ /* $NetBSD: common.c,v 1.28 2011/07/29 20:58:07 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -51,12 +51,12 @@ static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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); re_goto_bottom(el);
*el->el_line.lastchar = '\0'; *el->el_line.lastchar = '\0';
return (CC_EOF); return CC_EOF;
} }
@ -65,12 +65,12 @@ ed_end_of_file(EditLine *el, int c __attribute__((__unused__)))
* Insert a character [bound to all insert keys] * Insert a character [bound to all insert keys]
*/ */
protected el_action_t protected el_action_t
ed_insert(EditLine *el, int c) ed_insert(EditLine *el, Int c)
{ {
int count = el->el_state.argument; int count = el->el_state.argument;
if (c == '\0') if (c == '\0')
return (CC_ERROR); return CC_ERROR;
if (el->el_line.lastchar + el->el_state.argument >= if (el->el_line.lastchar + el->el_state.argument >=
el->el_line.limit) { el->el_line.limit) {
@ -98,7 +98,7 @@ ed_insert(EditLine *el, int c)
if (el->el_state.inputmode == MODE_REPLACE_1) if (el->el_state.inputmode == MODE_REPLACE_1)
return vi_command_mode(el, 0); return vi_command_mode(el, 0);
return (CC_NORM); return CC_NORM;
} }
@ -108,12 +108,12 @@ ed_insert(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR); return CC_ERROR;
cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
el->el_state.argument, ce__isword); el->el_state.argument, ce__isword);
@ -122,11 +122,11 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
*kp++ = *p; *kp++ = *p;
el->el_chared.c_kill.last = kp; 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; el->el_line.cursor = cp;
if (el->el_line.cursor < el->el_line.buffer) if (el->el_line.cursor < el->el_line.buffer)
el->el_line.cursor = el->el_line.buffer; /* bounds check */ el->el_line.cursor = el->el_line.buffer; /* bounds check */
return (CC_REFRESH); return CC_REFRESH;
} }
@ -136,9 +136,9 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) ed_delete_next_char(EditLine *el, Int c __attribute__((__unused__)))
{ {
#ifdef notdef /* XXX */ #ifdef DEBUG_EDIT
#define EL el->el_line #define EL el->el_line
(void) fprintf(el->el_errlfile, (void) fprintf(el->el_errlfile,
"\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n", "\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n",
@ -151,24 +151,24 @@ ed_delete_next_char(EditLine *el, int c __attribute__((__unused__)))
if (el->el_line.cursor == el->el_line.buffer) { if (el->el_line.cursor == el->el_line.buffer) {
/* if I'm also at the beginning */ /* if I'm also at the beginning */
#ifdef KSHVI #ifdef KSHVI
return (CC_ERROR); return CC_ERROR;
#else #else
/* then do an EOF */ /* then do an EOF */
term_writechar(el, c); terminal_writec(el, c);
return (CC_EOF); return CC_EOF;
#endif #endif
} else { } else {
#ifdef KSHVI #ifdef KSHVI
el->el_line.cursor--; el->el_line.cursor--;
#else #else
return (CC_ERROR); return CC_ERROR;
#endif #endif
} }
} else { } else {
if (el->el_line.cursor != el->el_line.buffer) if (el->el_line.cursor != el->el_line.buffer)
el->el_line.cursor--; el->el_line.cursor--;
else else
return (CC_ERROR); return CC_ERROR;
} }
} }
c_delafter(el, el->el_state.argument); /* delete after dot */ c_delafter(el, el->el_state.argument); /* delete after dot */
@ -176,7 +176,7 @@ ed_delete_next_char(EditLine *el, int c __attribute__((__unused__)))
el->el_line.cursor > el->el_line.buffer) el->el_line.cursor > el->el_line.buffer)
/* bounds check */ /* bounds check */
el->el_line.cursor = el->el_line.lastchar - 1; el->el_line.cursor = el->el_line.lastchar - 1;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -186,9 +186,9 @@ ed_delete_next_char(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; cp = el->el_line.cursor;
kp = el->el_chared.c_kill.buf; kp = el->el_chared.c_kill.buf;
@ -197,7 +197,7 @@ ed_kill_line(EditLine *el, int c __attribute__((__unused__)))
el->el_chared.c_kill.last = kp; el->el_chared.c_kill.last = kp;
/* zap! -- delete to end */ /* zap! -- delete to end */
el->el_line.lastchar = el->el_line.cursor; el->el_line.lastchar = el->el_line.cursor;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -207,20 +207,20 @@ ed_kill_line(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; el->el_line.cursor = el->el_line.lastchar;
if (el->el_map.type == MAP_VI) { if (el->el_map.type == MAP_VI) {
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
#ifdef VI_MOVE #ifdef VI_MOVE
el->el_line.cursor--; el->el_line.cursor--;
#endif #endif
} }
return (CC_CURSOR); return CC_CURSOR;
} }
@ -230,21 +230,21 @@ ed_move_to_end(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; el->el_line.cursor = el->el_line.buffer;
if (el->el_map.type == MAP_VI) { if (el->el_map.type == MAP_VI) {
/* We want FIRST non space character */ /* We want FIRST non space character */
while (isspace((unsigned char) *el->el_line.cursor)) while (Isspace(*el->el_line.cursor))
el->el_line.cursor++; el->el_line.cursor++;
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
} }
return (CC_CURSOR); return CC_CURSOR;
} }
@ -253,12 +253,12 @@ ed_move_to_beg(EditLine *el, int c __attribute__((__unused__)))
* [^T] [^T] * [^T] [^T]
*/ */
protected el_action_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) { if (el->el_line.cursor < el->el_line.lastchar) {
if (el->el_line.lastchar <= &el->el_line.buffer[1]) if (el->el_line.lastchar <= &el->el_line.buffer[1])
return (CC_ERROR); return CC_ERROR;
else else
el->el_line.cursor++; el->el_line.cursor++;
} }
@ -267,9 +267,9 @@ ed_transpose_chars(EditLine *el, int c)
c = el->el_line.cursor[-2]; c = el->el_line.cursor[-2];
el->el_line.cursor[-2] = el->el_line.cursor[-1]; el->el_line.cursor[-2] = el->el_line.cursor[-1];
el->el_line.cursor[-1] = c; el->el_line.cursor[-1] = c;
return (CC_REFRESH); return CC_REFRESH;
} else } else
return (CC_ERROR); return CC_ERROR;
} }
@ -279,15 +279,15 @@ ed_transpose_chars(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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 || if (el->el_line.cursor >= lim ||
(el->el_line.cursor == lim - 1 && (el->el_line.cursor == lim - 1 &&
el->el_map.type == MAP_VI && el->el_map.type == MAP_VI &&
el->el_chared.c_vcmd.action == NOP)) el->el_chared.c_vcmd.action == NOP))
return (CC_ERROR); return CC_ERROR;
el->el_line.cursor += el->el_state.argument; el->el_line.cursor += el->el_state.argument;
if (el->el_line.cursor > lim) if (el->el_line.cursor > lim)
@ -296,9 +296,9 @@ ed_next_char(EditLine *el, int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI) if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
return (CC_CURSOR); return CC_CURSOR;
} }
@ -308,11 +308,11 @@ ed_next_char(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR); return CC_ERROR;
el->el_line.cursor = c__prev_word(el->el_line.cursor, el->el_line.cursor = c__prev_word(el->el_line.cursor,
el->el_line.buffer, el->el_line.buffer,
@ -322,9 +322,9 @@ ed_prev_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI) if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
return (CC_CURSOR); return CC_CURSOR;
} }
@ -334,7 +334,7 @@ ed_prev_word(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) { if (el->el_line.cursor > el->el_line.buffer) {
@ -345,11 +345,11 @@ ed_prev_char(EditLine *el, int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI) if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
return (CC_CURSOR); return CC_CURSOR;
} else } else
return (CC_ERROR); return CC_ERROR;
} }
@ -358,19 +358,19 @@ ed_prev_char(EditLine *el, int c __attribute__((__unused__)))
* [^V] [^V] * [^V] [^V]
*/ */
protected el_action_t protected el_action_t
ed_quoted_insert(EditLine *el, int c) ed_quoted_insert(EditLine *el, Int c)
{ {
int num; int num;
char tc; Char tc;
tty_quotemode(el); tty_quotemode(el);
num = el_getc(el, &tc); num = FUN(el,getc)(el, &tc);
c = (unsigned char) tc; c = tc;
tty_noquotemode(el); tty_noquotemode(el);
if (num == 1) if (num == 1)
return (ed_insert(el, c)); return ed_insert(el, c);
else else
return (ed_end_of_file(el, 0)); return ed_end_of_file(el, 0);
} }
@ -378,11 +378,11 @@ ed_quoted_insert(EditLine *el, int c)
* Adds to argument or enters a digit * Adds to argument or enters a digit
*/ */
protected el_action_t 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); return CC_ERROR;
if (el->el_state.doingarg) { if (el->el_state.doingarg) {
/* if doing an arg, add this in... */ /* if doing an arg, add this in... */
@ -390,11 +390,11 @@ ed_digit(EditLine *el, int c)
el->el_state.argument = c - '0'; el->el_state.argument = c - '0';
else { else {
if (el->el_state.argument > 1000000) if (el->el_state.argument > 1000000)
return (CC_ERROR); return CC_ERROR;
el->el_state.argument = el->el_state.argument =
(el->el_state.argument * 10) + (c - '0'); (el->el_state.argument * 10) + (c - '0');
} }
return (CC_ARGHACK); return CC_ARGHACK;
} }
return ed_insert(el, c); return ed_insert(el, c);
@ -406,22 +406,22 @@ ed_digit(EditLine *el, int c)
* For ESC-n * For ESC-n
*/ */
protected el_action_t 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); return CC_ERROR;
if (el->el_state.doingarg) { if (el->el_state.doingarg) {
if (el->el_state.argument > 1000000) if (el->el_state.argument > 1000000)
return (CC_ERROR); return CC_ERROR;
el->el_state.argument = (el->el_state.argument * 10) + el->el_state.argument = (el->el_state.argument * 10) +
(c - '0'); (c - '0');
} else { /* else starting an argument */ } else { /* else starting an argument */
el->el_state.argument = c - '0'; el->el_state.argument = c - '0';
el->el_state.doingarg = 1; el->el_state.doingarg = 1;
} }
return (CC_ARGHACK); return CC_ARGHACK;
} }
@ -432,10 +432,10 @@ ed_argument_digit(EditLine *el, int c)
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_unassigned(EditLine *el __attribute__((__unused__)), ed_unassigned(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__))) Int c __attribute__((__unused__)))
{ {
return (CC_ERROR); return CC_ERROR;
} }
@ -450,10 +450,10 @@ ed_unassigned(EditLine *el __attribute__((__unused__)),
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_sigint(EditLine *el __attribute__((__unused__)), ed_tty_sigint(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__))) Int c __attribute__((__unused__)))
{ {
return (CC_NORM); return CC_NORM;
} }
@ -464,10 +464,10 @@ ed_tty_sigint(EditLine *el __attribute__((__unused__)),
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_dsusp(EditLine *el __attribute__((__unused__)), ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__))) Int c __attribute__((__unused__)))
{ {
return (CC_NORM); return CC_NORM;
} }
@ -478,10 +478,10 @@ ed_tty_dsusp(EditLine *el __attribute__((__unused__)),
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_flush_output(EditLine *el __attribute__((__unused__)), ed_tty_flush_output(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__))) Int c __attribute__((__unused__)))
{ {
return (CC_NORM); return CC_NORM;
} }
@ -492,10 +492,10 @@ ed_tty_flush_output(EditLine *el __attribute__((__unused__)),
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_sigquit(EditLine *el __attribute__((__unused__)), ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__))) Int c __attribute__((__unused__)))
{ {
return (CC_NORM); return CC_NORM;
} }
@ -506,10 +506,10 @@ ed_tty_sigquit(EditLine *el __attribute__((__unused__)),
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_sigtstp(EditLine *el __attribute__((__unused__)), ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__))) Int c __attribute__((__unused__)))
{ {
return (CC_NORM); return CC_NORM;
} }
@ -520,10 +520,10 @@ ed_tty_sigtstp(EditLine *el __attribute__((__unused__)),
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_stop_output(EditLine *el __attribute__((__unused__)), ed_tty_stop_output(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__))) Int c __attribute__((__unused__)))
{ {
return (CC_NORM); return CC_NORM;
} }
@ -534,10 +534,10 @@ ed_tty_stop_output(EditLine *el __attribute__((__unused__)),
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_tty_start_output(EditLine *el __attribute__((__unused__)), ed_tty_start_output(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__))) Int c __attribute__((__unused__)))
{ {
return (CC_NORM); return CC_NORM;
} }
@ -547,13 +547,13 @@ ed_tty_start_output(EditLine *el __attribute__((__unused__)),
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_newline(EditLine *el, int c __attribute__((__unused__))) ed_newline(EditLine *el, Int c __attribute__((__unused__)))
{ {
re_goto_bottom(el); re_goto_bottom(el);
*el->el_line.lastchar++ = '\n'; *el->el_line.lastchar++ = '\n';
*el->el_line.lastchar = '\0'; *el->el_line.lastchar = '\0';
return (CC_NEWLINE); return CC_NEWLINE;
} }
@ -563,17 +563,17 @@ ed_newline(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (el->el_line.cursor <= el->el_line.buffer)
return (CC_ERROR); return CC_ERROR;
c_delbefore(el, el->el_state.argument); c_delbefore(el, el->el_state.argument);
el->el_line.cursor -= el->el_state.argument; el->el_line.cursor -= el->el_state.argument;
if (el->el_line.cursor < el->el_line.buffer) if (el->el_line.cursor < el->el_line.buffer)
el->el_line.cursor = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -583,12 +583,12 @@ ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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 */ terminal_clear_screen(el); /* clear the whole real screen */
re_clear_display(el); /* reset everything */ re_clear_display(el); /* reset everything */
return (CC_REFRESH); return CC_REFRESH;
} }
@ -599,10 +599,10 @@ ed_clear_screen(EditLine *el, int c __attribute__((__unused__)))
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_redisplay(EditLine *el __attribute__((__unused__)), ed_redisplay(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__))) Int c __attribute__((__unused__)))
{ {
return (CC_REDISPLAY); return CC_REDISPLAY;
} }
@ -612,11 +612,11 @@ ed_redisplay(EditLine *el __attribute__((__unused__)),
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_start_over(EditLine *el, int c __attribute__((__unused__))) ed_start_over(EditLine *el, Int c __attribute__((__unused__)))
{ {
ch_reset(el, 0); ch_reset(el, 0);
return (CC_REFRESH); return CC_REFRESH;
} }
@ -627,10 +627,10 @@ ed_start_over(EditLine *el, int c __attribute__((__unused__)))
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_sequence_lead_in(EditLine *el __attribute__((__unused__)), ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__))) Int c __attribute__((__unused__)))
{ {
return (CC_NORM); return CC_NORM;
} }
@ -640,7 +640,7 @@ ed_sequence_lead_in(EditLine *el __attribute__((__unused__)),
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_prev_history(EditLine *el, int c __attribute__((__unused__))) ed_prev_history(EditLine *el, Int c __attribute__((__unused__)))
{ {
char beep = 0; char beep = 0;
int sv_event = el->el_history.eventno; 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 if (el->el_history.eventno == 0) { /* save the current buffer
* away */ * away */
(void) strncpy(el->el_history.buf, el->el_line.buffer, (void) Strncpy(el->el_history.buf, el->el_line.buffer,
EL_BUFSIZ); EL_BUFSIZ);
el->el_history.last = el->el_history.buf + el->el_history.last = el->el_history.buf +
(el->el_line.lastchar - el->el_line.buffer); (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 (hist_get(el) == CC_ERROR) {
if (el->el_map.type == MAP_VI) { if (el->el_map.type == MAP_VI) {
el->el_history.eventno = sv_event; el->el_history.eventno = sv_event;
return CC_ERROR;
} }
beep = 1; beep = 1;
/* el->el_history.eventno was fixed by first call */ /* el->el_history.eventno was fixed by first call */
@ -678,7 +678,7 @@ ed_prev_history(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; el_action_t beep = CC_REFRESH, rval;
@ -705,9 +705,9 @@ ed_next_history(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; int h;
bool_t found = 0; bool_t found = 0;
@ -720,20 +720,20 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
"e_prev_search_hist(): eventno < 0;\n"); "e_prev_search_hist(): eventno < 0;\n");
#endif #endif
el->el_history.eventno = 0; el->el_history.eventno = 0;
return (CC_ERROR); return CC_ERROR;
} }
if (el->el_history.eventno == 0) { 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_BUFSIZ);
el->el_history.last = el->el_history.buf + el->el_history.last = el->el_history.buf +
(el->el_line.lastchar - el->el_line.buffer); (el->el_line.lastchar - el->el_line.buffer);
} }
if (el->el_history.ref == NULL) if (el->el_history.ref == NULL)
return (CC_ERROR); return CC_ERROR;
hp = HIST_FIRST(el); hp = HIST_FIRST(el);
if (hp == NULL) if (hp == NULL)
return (CC_ERROR); return CC_ERROR;
c_setpat(el); /* Set search pattern !! */ c_setpat(el); /* Set search pattern !! */
@ -744,7 +744,7 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
#ifdef SDEBUG #ifdef SDEBUG
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
#endif #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)) || (el->el_line.lastchar - el->el_line.buffer)) ||
hp[el->el_line.lastchar - el->el_line.buffer]) && hp[el->el_line.lastchar - el->el_line.buffer]) &&
c_hmatch(el, hp)) { c_hmatch(el, hp)) {
@ -759,11 +759,11 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
#ifdef SDEBUG #ifdef SDEBUG
(void) fprintf(el->el_errfile, "not found\n"); (void) fprintf(el->el_errfile, "not found\n");
#endif #endif
return (CC_ERROR); return CC_ERROR;
} }
el->el_history.eventno = h; el->el_history.eventno = h;
return (hist_get(el)); return hist_get(el);
} }
@ -773,9 +773,9 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; int h;
bool_t found = 0; bool_t found = 0;
@ -784,14 +784,14 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
*el->el_line.lastchar = '\0'; /* just in case */ *el->el_line.lastchar = '\0'; /* just in case */
if (el->el_history.eventno == 0) if (el->el_history.eventno == 0)
return (CC_ERROR); return CC_ERROR;
if (el->el_history.ref == NULL) if (el->el_history.ref == NULL)
return (CC_ERROR); return CC_ERROR;
hp = HIST_FIRST(el); hp = HIST_FIRST(el);
if (hp == NULL) if (hp == NULL)
return (CC_ERROR); return CC_ERROR;
c_setpat(el); /* Set search pattern !! */ c_setpat(el); /* Set search pattern !! */
@ -799,7 +799,7 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
#ifdef SDEBUG #ifdef SDEBUG
(void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp);
#endif #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)) || (el->el_line.lastchar - el->el_line.buffer)) ||
hp[el->el_line.lastchar - el->el_line.buffer]) && hp[el->el_line.lastchar - el->el_line.buffer]) &&
c_hmatch(el, hp)) c_hmatch(el, hp))
@ -812,12 +812,12 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
#ifdef SDEBUG #ifdef SDEBUG
(void) fprintf(el->el_errfile, "not found\n"); (void) fprintf(el->el_errfile, "not found\n");
#endif #endif
return (CC_ERROR); return CC_ERROR;
} }
} }
el->el_history.eventno = found; el->el_history.eventno = found;
return (hist_get(el)); return hist_get(el);
} }
@ -827,9 +827,9 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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); int nchars = c_hpos(el);
/* /*
@ -843,7 +843,7 @@ ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
break; break;
if (el->el_state.argument > 0) if (el->el_state.argument > 0)
return (CC_ERROR); return CC_ERROR;
/* /*
* Move to the beginning of the line * Move to the beginning of the line
@ -860,7 +860,7 @@ ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
continue; continue;
el->el_line.cursor = ptr; el->el_line.cursor = ptr;
return (CC_CURSOR); return CC_CURSOR;
} }
@ -870,9 +870,9 @@ ed_prev_line(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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); int nchars = c_hpos(el);
/* /*
@ -883,7 +883,7 @@ ed_next_line(EditLine *el, int c __attribute__((__unused__)))
break; break;
if (el->el_state.argument > 0) if (el->el_state.argument > 0)
return (CC_ERROR); return CC_ERROR;
/* /*
* Move to the character requested * Move to the character requested
@ -894,7 +894,7 @@ ed_next_line(EditLine *el, int c __attribute__((__unused__)))
continue; continue;
el->el_line.cursor = ptr; el->el_line.cursor = ptr;
return (CC_CURSOR); return CC_CURSOR;
} }
@ -904,16 +904,16 @@ ed_next_line(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; int tmplen;
tmplen = c_gets(el, tmpbuf, "\n: "); tmplen = c_gets(el, tmpbuf, STR("\n: "));
term__putc(el, '\n'); terminal__putc(el, '\n');
if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1) if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
term_beep(el); terminal_beep(el);
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
re_clear_display(el); re_clear_display(el);

View File

@ -1,2 +1,5 @@
#include "my_config.h" #include "my_config.h"
#include "sys.h" #include "sys.h"
#ifndef NARROW_WRAPPER
#define WIDECHAR
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: el.c,v 1.47 2009/01/18 12:17:24 lukem Exp $ */ /* $NetBSD: el.c,v 1.68 2011/07/29 15:16:33 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -48,6 +48,9 @@ static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <ctype.h>
#include <locale.h>
#include <langinfo.h>
#include "el.h" #include "el.h"
/* el_init(): /* el_init():
@ -56,11 +59,10 @@ static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
public EditLine * public EditLine *
el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
{ {
EditLine *el = el_malloc(sizeof(*el));
EditLine *el = (EditLine *) el_malloc(sizeof(EditLine));
if (el == NULL) if (el == NULL)
return (NULL); return NULL;
memset(el, 0, sizeof(EditLine)); memset(el, 0, sizeof(EditLine));
@ -69,8 +71,11 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
el->el_errfile = ferr; el->el_errfile = ferr;
el->el_infd = fileno(fin); el->el_infd = fileno(fin);
el->el_outfd = fileno(fout);
el->el_errfd = fileno(ferr);
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); el_free(el);
return NULL; return NULL;
} }
@ -79,13 +84,18 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
* Initialize all the modules. Order is important!!! * Initialize all the modules. Order is important!!!
*/ */
el->el_flags = 0; el->el_flags = 0;
#ifdef WIDECHAR
setlocale(LC_CTYPE, NULL);
if (MB_CUR_MAX > 1)
el->el_flags |= CHARSET_IS_MULTIBYTE;
#endif
if (term_init(el) == -1) { if (terminal_init(el) == -1) {
el_free(el->el_prog); el_free(el->el_prog);
el_free(el); el_free(el);
return NULL; return NULL;
} }
(void) key_init(el); (void) keymacro_init(el);
(void) map_init(el); (void) map_init(el);
if (tty_init(el) == -1) if (tty_init(el) == -1)
el->el_flags |= NO_TTY; el->el_flags |= NO_TTY;
@ -96,7 +106,7 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
(void) sig_init(el); (void) sig_init(el);
(void) read_init(el); (void) read_init(el);
return (el); return el;
} }
@ -112,8 +122,8 @@ el_end(EditLine *el)
el_reset(el); el_reset(el);
term_end(el); terminal_end(el);
key_end(el); keymacro_end(el);
map_end(el); map_end(el);
tty_end(el); tty_end(el);
ch_end(el); ch_end(el);
@ -122,8 +132,14 @@ el_end(EditLine *el)
prompt_end(el); prompt_end(el);
sig_end(el); sig_end(el);
el_free((ptr_t) el->el_prog); el_free(el->el_prog);
el_free((ptr_t) el); #ifdef WIDECHAR
el_free(el->el_scratch.cbuff);
el_free(el->el_scratch.wbuff);
el_free(el->el_lgcyconv.cbuff);
el_free(el->el_lgcyconv.wbuff);
#endif
el_free(el);
} }
@ -143,27 +159,46 @@ el_reset(EditLine *el)
* set the editline parameters * set the editline parameters
*/ */
public int public int
el_set(EditLine *el, int op, ...) FUN(el,set)(EditLine *el, int op, ...)
{ {
va_list ap; va_list ap;
int rv = 0; int rv = 0;
if (el == NULL) if (el == NULL)
return (-1); return -1;
va_start(ap, op); va_start(ap, op);
switch (op) { switch (op) {
case EL_PROMPT: case EL_PROMPT:
case EL_RPROMPT: case EL_RPROMPT: {
rv = prompt_set(el, va_arg(ap, el_pfunc_t), op); el_pfunc_t p = va_arg(ap, el_pfunc_t);
rv = prompt_set(el, p, 0, op, 1);
break; break;
}
case EL_RESIZE: {
el_zfunc_t p = va_arg(ap, el_zfunc_t);
void *arg = va_arg(ap, void *);
rv = ch_resizefun(el, p, arg);
break;
}
case EL_PROMPT_ESC:
case EL_RPROMPT_ESC: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
int c = va_arg(ap, int);
rv = prompt_set(el, p, c, op, 1);
break;
}
case EL_TERMINAL: case EL_TERMINAL:
rv = term_set(el, va_arg(ap, char *)); rv = terminal_set(el, va_arg(ap, char *));
break; break;
case EL_EDITOR: case EL_EDITOR:
rv = map_set_editor(el, va_arg(ap, char *)); rv = map_set_editor(el, va_arg(ap, Char *));
break; break;
case EL_SIGNAL: case EL_SIGNAL:
@ -176,40 +211,39 @@ el_set(EditLine *el, int op, ...)
case EL_BIND: case EL_BIND:
case EL_TELLTC: case EL_TELLTC:
case EL_SETTC: case EL_SETTC:
case EL_GETTC:
case EL_ECHOTC: case EL_ECHOTC:
case EL_SETTY: case EL_SETTY:
{ {
const char *argv[20]; const Char *argv[20];
int i; int i;
for (i = 1; i < 20; i++) for (i = 1; i < 20; i++)
if ((argv[i] = va_arg(ap, char *)) == NULL) if ((argv[i] = va_arg(ap, Char *)) == NULL)
break; break;
switch (op) { switch (op) {
case EL_BIND: case EL_BIND:
argv[0] = "bind"; argv[0] = STR("bind");
rv = map_bind(el, i, argv); rv = map_bind(el, i, argv);
break; break;
case EL_TELLTC: case EL_TELLTC:
argv[0] = "telltc"; argv[0] = STR("telltc");
rv = term_telltc(el, i, argv); rv = terminal_telltc(el, i, argv);
break; break;
case EL_SETTC: case EL_SETTC:
argv[0] = "settc"; argv[0] = STR("settc");
rv = term_settc(el, i, argv); rv = terminal_settc(el, i, argv);
break; break;
case EL_ECHOTC: case EL_ECHOTC:
argv[0] = "echotc"; argv[0] = STR("echotc");
rv = term_echotc(el, i, argv); rv = terminal_echotc(el, i, argv);
break; break;
case EL_SETTY: case EL_SETTY:
argv[0] = "setty"; argv[0] = STR("setty");
rv = tty_stty(el, i, argv); rv = tty_stty(el, i, argv);
break; break;
@ -223,8 +257,8 @@ el_set(EditLine *el, int op, ...)
case EL_ADDFN: case EL_ADDFN:
{ {
char *name = va_arg(ap, char *); Char *name = va_arg(ap, Char *);
char *help = va_arg(ap, char *); Char *help = va_arg(ap, Char *);
el_func_t func = va_arg(ap, el_func_t); el_func_t func = va_arg(ap, el_func_t);
rv = map_addfunc(el, name, help, func); rv = map_addfunc(el, name, help, func);
@ -234,9 +268,11 @@ el_set(EditLine *el, int op, ...)
case EL_HIST: case EL_HIST:
{ {
hist_fun_t func = va_arg(ap, hist_fun_t); hist_fun_t func = va_arg(ap, hist_fun_t);
ptr_t ptr = va_arg(ap, char *); void *ptr = va_arg(ap, void *);
rv = hist_set(el, func, ptr); rv = hist_set(el, func, ptr);
if (!(el->el_flags & CHARSET_IS_MULTIBYTE))
el->el_flags &= ~NARROW_HISTORY;
break; break;
} }
@ -252,6 +288,7 @@ el_set(EditLine *el, int op, ...)
{ {
el_rfunc_t rc = va_arg(ap, el_rfunc_t); el_rfunc_t rc = va_arg(ap, el_rfunc_t);
rv = el_read_setfn(el, rc); rv = el_read_setfn(el, rc);
el->el_flags &= ~NARROW_READ;
break; break;
} }
@ -296,9 +333,11 @@ el_set(EditLine *el, int op, ...)
break; break;
case 1: case 1:
el->el_outfile = fp; el->el_outfile = fp;
el->el_outfd = fileno(fp);
break; break;
case 2: case 2:
el->el_errfile = fp; el->el_errfile = fp;
el->el_errfd = fileno(fp);
break; break;
default: default:
rv = -1; rv = -1;
@ -310,7 +349,7 @@ el_set(EditLine *el, int op, ...)
case EL_REFRESH: case EL_REFRESH:
re_clear_display(el); re_clear_display(el);
re_refresh(el); re_refresh(el);
term__flush(el); terminal__flush(el);
break; break;
default: default:
@ -319,7 +358,7 @@ el_set(EditLine *el, int op, ...)
} }
va_end(ap); va_end(ap);
return (rv); return rv;
} }
@ -327,7 +366,7 @@ el_set(EditLine *el, int op, ...)
* retrieve the editline parameters * retrieve the editline parameters
*/ */
public int public int
el_get(EditLine *el, int op, ...) FUN(el,get)(EditLine *el, int op, ...)
{ {
va_list ap; va_list ap;
int rv; int rv;
@ -339,12 +378,22 @@ el_get(EditLine *el, int op, ...)
switch (op) { switch (op) {
case EL_PROMPT: case EL_PROMPT:
case EL_RPROMPT: case EL_RPROMPT: {
rv = prompt_get(el, va_arg(ap, el_pfunc_t *), op); el_pfunc_t *p = va_arg(ap, el_pfunc_t *);
rv = prompt_get(el, p, 0, op);
break; 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: case EL_EDITOR:
rv = map_get_editor(el, va_arg(ap, const char **)); rv = map_get_editor(el, va_arg(ap, const Char **));
break; break;
case EL_SIGNAL: case EL_SIGNAL:
@ -358,7 +407,7 @@ el_get(EditLine *el, int op, ...)
break; break;
case EL_TERMINAL: case EL_TERMINAL:
term_get(el, va_arg(ap, const char **)); terminal_get(el, va_arg(ap, const char **));
rv = 0; rv = 0;
break; break;
@ -375,7 +424,7 @@ el_get(EditLine *el, int op, ...)
switch (op) { switch (op) {
case EL_GETTC: case EL_GETTC:
argv[0] = name; argv[0] = name;
rv = term_gettc(el, i, argv); rv = terminal_gettc(el, i, argv);
break; break;
default: default:
@ -386,26 +435,6 @@ el_get(EditLine *el, int op, ...)
break; 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: case EL_GETCFN:
*va_arg(ap, el_rfunc_t *) = el_read_getfn(el); *va_arg(ap, el_rfunc_t *) = el_read_getfn(el);
rv = 0; rv = 0;
@ -451,18 +480,18 @@ el_get(EditLine *el, int op, ...)
} }
va_end(ap); va_end(ap);
return (rv); return rv;
} }
/* el_line(): /* el_line():
* Return editing info * Return editing info
*/ */
public const LineInfo * public const TYPE(LineInfo) *
el_line(EditLine *el) FUN(el,line)(EditLine *el)
{ {
return (const LineInfo *) (void *) &el->el_line; return (const TYPE(LineInfo) *)(void *)&el->el_line;
} }
@ -475,6 +504,9 @@ el_source(EditLine *el, const char *fname)
FILE *fp; FILE *fp;
size_t len; size_t len;
char *ptr; char *ptr;
char *path = NULL;
const Char *dptr;
int error = 0;
fp = NULL; fp = NULL;
if (fname == NULL) { if (fname == NULL) {
@ -486,25 +518,21 @@ el_source(EditLine *el, const char *fname)
#if (defined(HAVE_ISSETUGID) || defined(HAVE_IDENTITY_FUNCS)) #if (defined(HAVE_ISSETUGID) || defined(HAVE_IDENTITY_FUNCS))
static const char elpath[] = "/.editrc"; static const char elpath[] = "/.editrc";
size_t plen = sizeof(elpath);
/* XXXMYSQL: Portability fix (for which platforms?) */ /* XXXMYSQL: Portability fix (for which platforms?) */
#ifdef MAXPATHLEN
char path[MAXPATHLEN];
#else
char path[4096];
#endif
#ifdef HAVE_ISSETUGID #ifdef HAVE_ISSETUGID
if (issetugid()) if (issetugid())
return (-1); return -1;
#elif defined(HAVE_IDENTITY_FUNCS) #elif defined(HAVE_IDENTITY_FUNCS)
if (getuid() != geteuid() || getgid() != getegid()) if (getuid() != geteuid() || getgid() != getegid())
return (-1); return (-1);
#endif #endif
if ((ptr = getenv("HOME")) == NULL) if ((ptr = getenv("HOME")) == NULL)
return (-1); return -1;
if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path)) plen += strlen(ptr);
return (-1); if ((path = el_malloc(plen * sizeof(*path))) == NULL)
if (strlcat(path, elpath, sizeof(path)) >= sizeof(path)) return -1;
return (-1); (void)snprintf(path, plen, "%s%s", ptr, elpath);
fname = path; fname = path;
#else #else
/* /*
@ -513,26 +541,37 @@ el_source(EditLine *el, const char *fname)
* to keep from inadvertently opening up the user to a * to keep from inadvertently opening up the user to a
* security hole. * security hole.
*/ */
return (-1); return -1;
#endif #endif
} }
if (fp == NULL) if (fp == NULL)
fp = fopen(fname, "r"); fp = fopen(fname, "r");
if (fp == NULL) if (fp == NULL) {
return (-1); el_free(path);
return -1;
while ((ptr = fgetln(fp, &len)) != NULL) {
if (len > 0 && ptr[len - 1] == '\n')
--len;
ptr[len] = '\0';
if (parse_line(el, ptr) == -1) {
(void) fclose(fp);
return (-1);
}
} }
while ((ptr = fgetln(fp, &len)) != NULL) {
if (*ptr == '\n')
continue; /* Empty line. */
dptr = ct_decode_string(ptr, &el->el_scratch);
if (!dptr)
continue;
if (len > 0 && dptr[len - 1] == '\n')
--len;
/* loop until first non-space char or EOL */
while (*dptr != '\0' && Isspace(*dptr))
dptr++;
if (*dptr == '#')
continue; /* ignore, this is a comment line */
if ((error = parse_line(el, dptr)) == -1)
break;
}
el_free(path);
(void) fclose(fp); (void) fclose(fp);
return (0); return error;
} }
@ -550,8 +589,8 @@ el_resize(EditLine *el)
(void) sigprocmask(SIG_BLOCK, &nset, &oset); (void) sigprocmask(SIG_BLOCK, &nset, &oset);
/* get the correct window size */ /* get the correct window size */
if (term_get_size(el, &lins, &cols)) if (terminal_get_size(el, &lins, &cols))
term_change_size(el, lins, cols); terminal_change_size(el, lins, cols);
(void) sigprocmask(SIG_SETMASK, &oset, NULL); (void) sigprocmask(SIG_SETMASK, &oset, NULL);
} }
@ -564,7 +603,7 @@ public void
el_beep(EditLine *el) el_beep(EditLine *el)
{ {
term_beep(el); terminal_beep(el);
} }
@ -573,24 +612,25 @@ el_beep(EditLine *el)
*/ */
protected int protected int
/*ARGSUSED*/ /*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) if (argv == NULL || argc != 2 || argv[1] == NULL)
return (-1); return -1;
how = argv[1]; how = argv[1];
if (strcmp(how, "on") == 0) { if (Strcmp(how, STR("on")) == 0) {
el->el_flags &= ~EDIT_DISABLED; el->el_flags &= ~EDIT_DISABLED;
tty_rawmode(el); tty_rawmode(el);
} else if (strcmp(how, "off") == 0) { } else if (Strcmp(how, STR("off")) == 0) {
tty_cookedmode(el); tty_cookedmode(el);
el->el_flags |= EDIT_DISABLED; el->el_flags |= EDIT_DISABLED;
} }
else { else {
(void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how); (void) fprintf(el->el_errfile, "edit: Bad value `" FSTR "'.\n",
return (-1); how);
return -1;
} }
return (0); return 0;
} }

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.25 2011/07/29 23:44:44 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -46,15 +46,21 @@
#define VIDEFAULT #define VIDEFAULT
#define ANCHOR #define ANCHOR
#include "histedit.h"
#include "chartype.h"
#include <stdio.h> #include <stdio.h>
#include <sys/types.h> #include <sys/types.h>
#define EL_BUFSIZ 1024 /* Maximum line size */ #define EL_BUFSIZ ((size_t)4096) /* Maximum line size */
#define HANDLE_SIGNALS 0x01 #define HANDLE_SIGNALS 0x01
#define NO_TTY 0x02 #define NO_TTY 0x02
#define EDIT_DISABLED 0x04 #define EDIT_DISABLED 0x04
#define UNBUFFERED 0x08 #define UNBUFFERED 0x08
#define CHARSET_IS_MULTIBYTE 0x10
#define IGNORE_EXTCHARS 0x20 /* Ignore characters read > 0xff */
#define NARROW_HISTORY 0x40
#define NARROW_READ 0x80
typedef int bool_t; /* True or not */ typedef int bool_t; /* True or not */
@ -66,10 +72,10 @@ typedef struct coord_t { /* Position on the screen */
} coord_t; } coord_t;
typedef struct el_line_t { typedef struct el_line_t {
char *buffer; /* Input line */ Char *buffer; /* Input line */
char *cursor; /* Cursor position */ Char *cursor; /* Cursor position */
char *lastchar; /* Last character */ Char *lastchar; /* Last character */
const char *limit; /* Max position */ const Char *limit; /* Max position */
} el_line_t; } el_line_t;
/* /*
@ -82,21 +88,20 @@ typedef struct el_state_t {
int metanext; /* Is the next char a meta char */ int metanext; /* Is the next char a meta char */
el_action_t lastcmd; /* Previous command */ el_action_t lastcmd; /* Previous command */
el_action_t thiscmd; /* this command */ el_action_t thiscmd; /* this command */
char thisch; /* char that generated it */ Char thisch; /* char that generated it */
} el_state_t; } el_state_t;
/* /*
* Until we come up with something better... * Until we come up with something better...
*/ */
#define el_strdup(a) strdup(a)
#define el_malloc(a) malloc(a) #define el_malloc(a) malloc(a)
#define el_realloc(a,b) realloc(a, b) #define el_realloc(a,b) realloc(a, b)
#define el_free(a) free(a) #define el_free(a) free(a)
#include "tty.h" #include "tty.h"
#include "prompt.h" #include "prompt.h"
#include "key.h" #include "keymacro.h"
#include "el_term.h" #include "el_terminal.h"
#include "refresh.h" #include "refresh.h"
#include "chared.h" #include "chared.h"
#include "common.h" #include "common.h"
@ -109,33 +114,41 @@ typedef struct el_state_t {
#include "read.h" #include "read.h"
struct editline { struct editline {
char *el_prog; /* the program name */ Char *el_prog; /* the program name */
FILE *el_infile; /* Stdio stuff */ FILE *el_infile; /* Stdio stuff */
FILE *el_outfile; /* Stdio stuff */ FILE *el_outfile; /* Stdio stuff */
FILE *el_errfile; /* Stdio stuff */ FILE *el_errfile; /* Stdio stuff */
int el_infd; /* Input file descriptor */ int el_infd; /* Input file descriptor */
int el_outfd; /* Output file descriptor */
int el_errfd; /* Error file descriptor */
int el_flags; /* Various flags. */ int el_flags; /* Various flags. */
int el_errno; /* Local copy of errno */
coord_t el_cursor; /* Cursor location */ coord_t el_cursor; /* Cursor location */
char **el_display; /* Real screen image = what is there */ Char **el_display; /* Real screen image = what is there */
char **el_vdisplay; /* Virtual screen image = what we see */ Char **el_vdisplay; /* Virtual screen image = what we see */
void *el_data; /* Client data */ void *el_data; /* Client data */
el_line_t el_line; /* The current line information */ el_line_t el_line; /* The current line information */
el_state_t el_state; /* Current editor state */ el_state_t el_state; /* Current editor state */
el_term_t el_term; /* Terminal dependent stuff */ el_terminal_t el_terminal; /* Terminal dependent stuff */
el_tty_t el_tty; /* Tty dependent stuff */ el_tty_t el_tty; /* Tty dependent stuff */
el_refresh_t el_refresh; /* Refresh stuff */ el_refresh_t el_refresh; /* Refresh stuff */
el_prompt_t el_prompt; /* Prompt stuff */ el_prompt_t el_prompt; /* Prompt stuff */
el_prompt_t el_rprompt; /* Prompt stuff */ el_prompt_t el_rprompt; /* Prompt stuff */
el_chared_t el_chared; /* Characted editor stuff */ el_chared_t el_chared; /* Characted editor stuff */
el_map_t el_map; /* Key mapping stuff */ el_map_t el_map; /* Key mapping stuff */
el_key_t el_key; /* Key binding stuff */ el_keymacro_t el_keymacro; /* Key binding stuff */
el_history_t el_history; /* History stuff */ el_history_t el_history; /* History stuff */
el_search_t el_search; /* Search stuff */ el_search_t el_search; /* Search stuff */
el_signal_t el_signal; /* Signal handling stuff */ el_signal_t el_signal; /* Signal handling stuff */
el_read_t el_read; /* Character reading 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 **);
/* XXXMYSQL: Bug#23097 mysql can't insert korean on mysql prompt. */ /* XXXMYSQL: Bug#23097 mysql can't insert korean on mysql prompt. */
#define el_isprint(x) ((unsigned char) (x) < 0x80 ? isprint(x) : 1) #define el_isprint(x) ((unsigned char) (x) < 0x80 ? isprint(x) : 1)

View File

@ -1,4 +1,4 @@
/* $NetBSD: term.h,v 1.19 2008/09/10 15:45:37 christos Exp $ */ /* $NetBSD: terminal.h,v 1.3 2011/07/29 23:44:45 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -37,17 +37,17 @@
/* /*
* el.term.h: Termcap header * el.term.h: Termcap header
*/ */
#ifndef _h_el_term #ifndef _h_el_terminal
#define _h_el_term #define _h_el_terminal
#include "histedit.h" #include "histedit.h"
typedef struct { /* Symbolic function key bindings */ 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 */ int key; /* Index in termcap table */
key_value_t fun; /* Function bound to it */ keymacro_value_t fun; /* Function bound to it */
int type; /* Type of function */ int type; /* Type of function */
} fkey_t; } funckey_t;
typedef struct { typedef struct {
const char *t_name; /* the terminal name */ const char *t_name; /* the terminal name */
@ -63,12 +63,12 @@ typedef struct {
#define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */ #define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */
#define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */ #define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */
char *t_buf; /* Termcap buffer */ char *t_buf; /* Termcap buffer */
int t_loc; /* location used */ size_t t_loc; /* location used */
char **t_str; /* termcap strings */ char **t_str; /* termcap strings */
int *t_val; /* termcap values */ int *t_val; /* termcap values */
char *t_cap; /* Termcap buffer */ char *t_cap; /* Termcap buffer */
fkey_t *t_fkey; /* Array of keys */ funckey_t *t_fkey; /* Array of keys */
} el_term_t; } el_terminal_t;
/* /*
* fKey indexes * fKey indexes
@ -81,36 +81,36 @@ typedef struct {
#define A_K_EN 5 #define A_K_EN 5
#define A_K_NKEYS 6 #define A_K_NKEYS 6
protected void term_move_to_line(EditLine *, int); protected void terminal_move_to_line(EditLine *, int);
protected void term_move_to_char(EditLine *, int); protected void terminal_move_to_char(EditLine *, int);
protected void term_clear_EOL(EditLine *, int); protected void terminal_clear_EOL(EditLine *, int);
protected void term_overwrite(EditLine *, const char *, int); protected void terminal_overwrite(EditLine *, const Char *, size_t);
protected void term_insertwrite(EditLine *, char *, int); protected void terminal_insertwrite(EditLine *, Char *, int);
protected void term_deletechars(EditLine *, int); protected void terminal_deletechars(EditLine *, int);
protected void term_clear_screen(EditLine *); protected void terminal_clear_screen(EditLine *);
protected void term_beep(EditLine *); protected void terminal_beep(EditLine *);
protected int term_change_size(EditLine *, int, int); protected int terminal_change_size(EditLine *, int, int);
protected int term_get_size(EditLine *, int *, int *); protected int terminal_get_size(EditLine *, int *, int *);
protected int term_init(EditLine *); protected int terminal_init(EditLine *);
protected void term_bind_arrow(EditLine *); protected void terminal_bind_arrow(EditLine *);
protected void term_print_arrow(EditLine *, const char *); protected void terminal_print_arrow(EditLine *, const Char *);
protected int term_clear_arrow(EditLine *, const char *); protected int terminal_clear_arrow(EditLine *, const Char *);
protected int term_set_arrow(EditLine *, const char *, key_value_t *, int); protected int terminal_set_arrow(EditLine *, const Char *, keymacro_value_t *, int);
protected void term_end(EditLine *); protected void terminal_end(EditLine *);
protected void term_get(EditLine *, const char **); protected void terminal_get(EditLine *, const char **);
protected int term_set(EditLine *, const char *); protected int terminal_set(EditLine *, const char *);
protected int term_settc(EditLine *, int, const char **); protected int terminal_settc(EditLine *, int, const Char **);
protected int term_gettc(EditLine *, int, char **); protected int terminal_gettc(EditLine *, int, char **);
protected int term_telltc(EditLine *, int, const char **); protected int terminal_telltc(EditLine *, int, const Char **);
protected int term_echotc(EditLine *, int, const char **); protected int terminal_echotc(EditLine *, int, const Char **);
protected void term_writec(EditLine *, int); protected void terminal_writec(EditLine *, Int);
protected int term__putc(EditLine *, int); protected int terminal__putc(EditLine *, Int);
protected void term__flush(EditLine *); protected void terminal__flush(EditLine *);
/* /*
* Easy access macros * Easy access macros
*/ */
#define EL_FLAGS (el)->el_term.t_flags #define EL_FLAGS (el)->el_terminal.t_flags
#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT) #define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT)
#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE) #define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE)
@ -122,4 +122,4 @@ protected void term__flush(EditLine *);
#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS) #define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS)
#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS) #define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS)
#endif /* _h_el_term */ #endif /* _h_el_terminal */

View File

@ -0,0 +1,364 @@
/* $NetBSD: eln.c,v 1.13 2011/08/16 16:25:15 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)
#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;
num_read = el_wgetc (el, &wc);
if (num_read > 0)
*cp = (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;
tmp = el_wgets(el, nread);
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_RESIZE: {
el_zfunc_t p = va_arg(ap, el_zfunc_t);
void *arg = va_arg(ap, void *);
ret = ch_resizefun(el, p, arg);
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 = terminal_telltc(el, i, wargv);
break;
case EL_SETTC:
wargv[0] = STR("settc");
ret = terminal_settc(el, i, wargv);
break;
case EL_ECHOTC:
wargv[0] = STR("echotc");
ret = terminal_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);
void *ptr = va_arg(ap, void *);
ret = hist_set(el, fun, ptr);
el->el_flags |= NARROW_HISTORY;
break;
}
/* XXX: do we need to change el_rfunc_t? */
case EL_GETCFN: /* el_rfunc_t */
ret = el_wset(el, op, va_arg(ap, el_rfunc_t));
el->el_flags |= NARROW_READ;
break;
case EL_CLIENTDATA: /* void * */
ret = el_wset(el, op, va_arg(ap, void *));
break;
case EL_SETFP: { /* int, FILE * */
int what = va_arg(ap, int);
FILE *fp = va_arg(ap, FILE *);
ret = el_wset(el, op, what, fp);
break;
}
case EL_PROMPT_ESC: /* el_pfunc_t, char */
case EL_RPROMPT_ESC: {
el_pfunc_t p = va_arg(ap, el_pfunc_t);
char c = (char)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 = 0;
ret = prompt_get(el, p, &wc, op);
*c = (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 = terminal_gettc(el, i, argv);
break;
}
/* XXX: do we need to change el_rfunc_t? */
case EL_GETCFN: /* el_rfunc_t */
ret = el_wget(el, op, va_arg(ap, el_rfunc_t *));
break;
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));
}

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.25 2011/07/29 15:16:33 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -51,22 +51,22 @@ static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_delete_or_list(EditLine *el, int c) em_delete_or_list(EditLine *el, Int c)
{ {
if (el->el_line.cursor == el->el_line.lastchar) { if (el->el_line.cursor == el->el_line.lastchar) {
/* if I'm at the end */ /* if I'm at the end */
if (el->el_line.cursor == el->el_line.buffer) { if (el->el_line.cursor == el->el_line.buffer) {
/* and the beginning */ /* and the beginning */
term_writec(el, c); /* then do an EOF */ terminal_writec(el, c); /* then do an EOF */
return (CC_EOF); return CC_EOF;
} else { } else {
/* /*
* Here we could list completions, but it is an * Here we could list completions, but it is an
* error right now * error right now
*/ */
term_beep(el); terminal_beep(el);
return (CC_ERROR); return CC_ERROR;
} }
} else { } else {
if (el->el_state.doingarg) if (el->el_state.doingarg)
@ -76,7 +76,7 @@ em_delete_or_list(EditLine *el, int c)
if (el->el_line.cursor > el->el_line.lastchar) if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar; el->el_line.cursor = el->el_line.lastchar;
/* bounds check */ /* bounds check */
return (CC_REFRESH); return CC_REFRESH;
} }
} }
@ -87,12 +87,12 @@ em_delete_or_list(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_delete_next_word(EditLine *el, int c __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) if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR); return CC_ERROR;
cp = c__next_word(el->el_line.cursor, el->el_line.lastchar, cp = c__next_word(el->el_line.cursor, el->el_line.lastchar,
el->el_state.argument, ce__isword); el->el_state.argument, ce__isword);
@ -102,11 +102,11 @@ em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
*kp++ = *p; *kp++ = *p;
el->el_chared.c_kill.last = kp; 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) if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar; el->el_line.cursor = el->el_line.lastchar;
/* bounds check */ /* bounds check */
return (CC_REFRESH); return CC_REFRESH;
} }
@ -116,23 +116,24 @@ em_delete_next_word(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf)
return (CC_NORM); return CC_NORM;
if (el->el_line.lastchar + if (el->el_line.lastchar +
(el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >= (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >=
el->el_line.limit) el->el_line.limit)
return (CC_ERROR); return CC_ERROR;
el->el_chared.c_kill.mark = el->el_line.cursor; el->el_chared.c_kill.mark = el->el_line.cursor;
cp = el->el_line.cursor; cp = el->el_line.cursor;
/* open the space, */ /* 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 */ /* copy the chars */
for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++) for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++)
*cp++ = *kp; *cp++ = *kp;
@ -141,7 +142,7 @@ em_yank(EditLine *el, int c __attribute__((__unused__)))
if (el->el_state.argument == 1) if (el->el_state.argument == 1)
el->el_line.cursor = cp; el->el_line.cursor = cp;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -151,9 +152,9 @@ em_yank(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; cp = el->el_line.buffer;
kp = el->el_chared.c_kill.buf; kp = el->el_chared.c_kill.buf;
@ -163,7 +164,7 @@ em_kill_line(EditLine *el, int c __attribute__((__unused__)))
/* zap! -- delete all of it */ /* zap! -- delete all of it */
el->el_line.lastchar = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer;
el->el_line.cursor = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -173,12 +174,12 @@ em_kill_line(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (!el->el_chared.c_kill.mark)
return (CC_ERROR); return CC_ERROR;
if (el->el_chared.c_kill.mark > el->el_line.cursor) { if (el->el_chared.c_kill.mark > el->el_line.cursor) {
cp = el->el_line.cursor; cp = el->el_line.cursor;
@ -186,17 +187,17 @@ em_kill_region(EditLine *el, int c __attribute__((__unused__)))
while (cp < el->el_chared.c_kill.mark) while (cp < el->el_chared.c_kill.mark)
*kp++ = *cp++; /* copy it */ *kp++ = *cp++; /* copy it */
el->el_chared.c_kill.last = kp; 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 */ } else { /* mark is before cursor */
cp = el->el_chared.c_kill.mark; cp = el->el_chared.c_kill.mark;
kp = el->el_chared.c_kill.buf; kp = el->el_chared.c_kill.buf;
while (cp < el->el_line.cursor) while (cp < el->el_line.cursor)
*kp++ = *cp++; /* copy it */ *kp++ = *cp++; /* copy it */
el->el_chared.c_kill.last = kp; 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; el->el_line.cursor = el->el_chared.c_kill.mark;
} }
return (CC_REFRESH); return CC_REFRESH;
} }
@ -206,12 +207,12 @@ em_kill_region(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (!el->el_chared.c_kill.mark)
return (CC_ERROR); return CC_ERROR;
if (el->el_chared.c_kill.mark > el->el_line.cursor) { if (el->el_chared.c_kill.mark > el->el_line.cursor) {
cp = el->el_line.cursor; cp = el->el_line.cursor;
@ -226,7 +227,7 @@ em_copy_region(EditLine *el, int c __attribute__((__unused__)))
*kp++ = *cp++; /* copy it */ *kp++ = *cp++; /* copy it */
el->el_chared.c_kill.last = kp; el->el_chared.c_kill.last = kp;
} }
return (CC_NORM); return CC_NORM;
} }
@ -235,7 +236,7 @@ em_copy_region(EditLine *el, int c __attribute__((__unused__)))
* Gosling emacs transpose chars [^T] * Gosling emacs transpose chars [^T]
*/ */
protected el_action_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]) { if (el->el_line.cursor > &el->el_line.buffer[1]) {
@ -243,9 +244,9 @@ em_gosmacs_transpose(EditLine *el, int c)
c = el->el_line.cursor[-2]; c = el->el_line.cursor[-2];
el->el_line.cursor[-2] = el->el_line.cursor[-1]; el->el_line.cursor[-2] = el->el_line.cursor[-1];
el->el_line.cursor[-1] = c; el->el_line.cursor[-1] = c;
return (CC_REFRESH); return CC_REFRESH;
} else } else
return (CC_ERROR); return CC_ERROR;
} }
@ -255,10 +256,10 @@ em_gosmacs_transpose(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR); return CC_ERROR;
el->el_line.cursor = c__next_word(el->el_line.cursor, el->el_line.cursor = c__next_word(el->el_line.cursor,
el->el_line.lastchar, el->el_line.lastchar,
@ -268,9 +269,9 @@ em_next_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI) if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
return (CC_CURSOR); return CC_CURSOR;
} }
@ -280,21 +281,21 @@ em_next_word(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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, ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
el->el_state.argument, ce__isword); el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++) for (cp = el->el_line.cursor; cp < ep; cp++)
if (islower((unsigned char)*cp)) if (Islower(*cp))
*cp = toupper((unsigned char)*cp); *cp = Toupper(*cp);
el->el_line.cursor = ep; el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar) if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar; el->el_line.cursor = el->el_line.lastchar;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -304,29 +305,29 @@ em_upper_case(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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, ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
el->el_state.argument, ce__isword); el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++) { for (cp = el->el_line.cursor; cp < ep; cp++) {
if (isalpha((unsigned char)*cp)) { if (Isalpha(*cp)) {
if (islower((unsigned char)*cp)) if (Islower(*cp))
*cp = toupper((unsigned char)*cp); *cp = Toupper(*cp);
cp++; cp++;
break; break;
} }
} }
for (; cp < ep; cp++) for (; cp < ep; cp++)
if (isupper((unsigned char)*cp)) if (Isupper(*cp))
*cp = tolower((unsigned char)*cp); *cp = Tolower(*cp);
el->el_line.cursor = ep; el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar) if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar; el->el_line.cursor = el->el_line.lastchar;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -336,21 +337,21 @@ em_capitol_case(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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, ep = c__next_word(el->el_line.cursor, el->el_line.lastchar,
el->el_state.argument, ce__isword); el->el_state.argument, ce__isword);
for (cp = el->el_line.cursor; cp < ep; cp++) for (cp = el->el_line.cursor; cp < ep; cp++)
if (isupper((unsigned char)*cp)) if (Isupper(*cp))
*cp = tolower((unsigned char)*cp); *cp = Tolower(*cp);
el->el_line.cursor = ep; el->el_line.cursor = ep;
if (el->el_line.cursor > el->el_line.lastchar) if (el->el_line.cursor > el->el_line.lastchar)
el->el_line.cursor = el->el_line.lastchar; el->el_line.cursor = el->el_line.lastchar;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -360,11 +361,11 @@ em_lower_case(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; el->el_chared.c_kill.mark = el->el_line.cursor;
return (CC_NORM); return CC_NORM;
} }
@ -374,14 +375,14 @@ em_set_mark(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; cp = el->el_line.cursor;
el->el_line.cursor = el->el_chared.c_kill.mark; el->el_line.cursor = el->el_chared.c_kill.mark;
el->el_chared.c_kill.mark = cp; el->el_chared.c_kill.mark = cp;
return (CC_CURSOR); return CC_CURSOR;
} }
@ -391,14 +392,14 @@ em_exchange_mark(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_universal_argument(EditLine *el, int c __attribute__((__unused__))) em_universal_argument(EditLine *el, Int c __attribute__((__unused__)))
{ /* multiply current argument by 4 */ { /* multiply current argument by 4 */
if (el->el_state.argument > 1000000) if (el->el_state.argument > 1000000)
return (CC_ERROR); return CC_ERROR;
el->el_state.doingarg = 1; el->el_state.doingarg = 1;
el->el_state.argument *= 4; el->el_state.argument *= 4;
return (CC_ARGHACK); return CC_ARGHACK;
} }
@ -408,11 +409,11 @@ em_universal_argument(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_meta_next(EditLine *el, int c __attribute__((__unused__))) em_meta_next(EditLine *el, Int c __attribute__((__unused__)))
{ {
el->el_state.metanext = 1; el->el_state.metanext = 1;
return (CC_ARGHACK); return CC_ARGHACK;
} }
@ -421,12 +422,12 @@ em_meta_next(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) ? el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ?
MODE_REPLACE : MODE_INSERT; MODE_REPLACE : MODE_INSERT;
return (CC_NORM); return CC_NORM;
} }
@ -435,25 +436,25 @@ em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR); return CC_ERROR;
oldc = el->el_line.cursor; oldc = el->el_line.cursor;
/* does a bounds check */ /* does a bounds check */
cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, cp = c__prev_word(el->el_line.cursor, el->el_line.buffer,
el->el_state.argument, ce__isword); 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++) for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++)
*dp++ = *cp; *dp++ = *cp;
el->el_line.cursor = dp;/* put cursor at end */ el->el_line.cursor = dp;/* put cursor at end */
return (CC_REFRESH); return CC_REFRESH;
} }
@ -462,11 +463,11 @@ em_copy_prev_word(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; el->el_search.patlen = 0;
return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY)); return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY);
} }
@ -475,11 +476,11 @@ em_inc_search_next(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; el->el_search.patlen = 0;
return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY)); return ce_inc_search(el, ED_SEARCH_PREV_HISTORY);
} }
@ -489,11 +490,11 @@ em_inc_search_prev(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (el->el_line.cursor <= el->el_line.buffer)
return (CC_ERROR); return CC_ERROR;
if (el->el_state.doingarg) if (el->el_state.doingarg)
c_delbefore(el, el->el_state.argument); c_delbefore(el, el->el_state.argument);
@ -502,5 +503,5 @@ em_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
el->el_line.cursor -= el->el_state.argument; el->el_line.cursor -= el->el_state.argument;
if (el->el_line.cursor < el->el_line.buffer) if (el->el_line.cursor < el->el_line.buffer)
el->el_line.cursor = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer;
return (CC_REFRESH); return CC_REFRESH;
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: filecomplete.c,v 1.13 2009/01/26 17:32:41 apb Exp $ */ /* $NetBSD: filecomplete.c,v 1.31 2011/09/16 16:13:16 plunky Exp $ */
/*- /*-
* Copyright (c) 1997 The NetBSD Foundation, Inc. * Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -78,8 +78,8 @@ extern char *alloca ();
#include "histedit.h" #include "histedit.h"
#include "filecomplete.h" #include "filecomplete.h"
static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', static const Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@',
'>', '<', '=', ';', '|', '&', '{', '(', '\0' }; '$', '>', '<', '=', ';', '|', '&', '{', '(', '\0' };
/********************************/ /********************************/
@ -95,12 +95,16 @@ static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
char * char *
fn_tilde_expand(const char *txt) fn_tilde_expand(const char *txt)
{ {
#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT)
struct passwd pwres;
char pwbuf[1024];
#endif
struct passwd *pass; struct passwd *pass;
char *temp; char *temp;
size_t len = 0; size_t len = 0;
if (txt[0] != '~') if (txt[0] != '~')
return (strdup(txt)); return strdup(txt);
temp = strchr(txt + 1, '/'); temp = strchr(txt + 1, '/');
if (temp == NULL) { if (temp == NULL) {
@ -108,33 +112,49 @@ fn_tilde_expand(const char *txt)
if (temp == NULL) if (temp == NULL)
return NULL; return NULL;
} else { } else {
len = temp - txt + 1; /* text until string after slash */ /* text until string after slash */
temp = malloc(len); len = (size_t)(temp - txt + 1);
temp = el_malloc(len * sizeof(*temp));
if (temp == NULL) if (temp == NULL)
return NULL; return NULL;
(void)strncpy(temp, txt + 1, len - 2); (void)strncpy(temp, txt + 1, len - 2);
temp[len - 2] = '\0'; temp[len - 2] = '\0';
} }
/* XXXMYSQL: use non-_r functions for now */
if (temp[0] == 0) { if (temp[0] == 0) {
#ifdef HAVE_GETPW_R_POSIX
if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf),
&pass) != 0)
pass = NULL;
#elif HAVE_GETPW_R_DRAFT
pass = getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf));
#else
pass = getpwuid(getuid()); pass = getpwuid(getuid());
#endif
} else { } else {
#ifdef HAVE_GETPW_R_POSIX
if (getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf), &pass) != 0)
pass = NULL;
#elif HAVE_GETPW_R_DRAFT
pass = getpwnam_r(temp, &pwres, pwbuf, sizeof(pwbuf));
#else
pass = getpwnam(temp); pass = getpwnam(temp);
#endif
} }
free(temp); /* value no more needed */ el_free(temp); /* value no more needed */
if (pass == NULL) if (pass == NULL)
return (strdup(txt)); return strdup(txt);
/* update pointer txt to point at string immedially following */ /* update pointer txt to point at string immedially following */
/* first slash */ /* first slash */
txt += len; txt += len;
temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1); len = strlen(pass->pw_dir) + 1 + strlen(txt) + 1;
temp = el_malloc(len * sizeof(*temp));
if (temp == NULL) if (temp == NULL)
return NULL; return NULL;
(void)sprintf(temp, "%s/%s", pass->pw_dir, txt); (void)snprintf(temp, len, "%s/%s", pass->pw_dir, txt);
return (temp); return temp;
} }
@ -160,23 +180,29 @@ fn_filename_completion_function(const char *text, int state)
if (temp) { if (temp) {
char *nptr; char *nptr;
temp++; temp++;
nptr = realloc(filename, strlen(temp) + 1); nptr = el_realloc(filename, (strlen(temp) + 1) *
sizeof(*nptr));
if (nptr == NULL) { if (nptr == NULL) {
free(filename); el_free(filename);
filename = NULL;
return NULL; return NULL;
} }
filename = nptr; filename = nptr;
(void)strcpy(filename, temp); (void)strcpy(filename, temp);
len = temp - text; /* including last slash */ len = (size_t)(temp - text); /* including last slash */
nptr = realloc(dirname, len + 1);
nptr = el_realloc(dirname, (len + 1) *
sizeof(*nptr));
if (nptr == NULL) { if (nptr == NULL) {
free(filename); el_free(dirname);
dirname = NULL;
return NULL; return NULL;
} }
dirname = nptr; dirname = nptr;
(void)strncpy(dirname, text, len); (void)strncpy(dirname, text, len);
dirname[len] = '\0'; dirname[len] = '\0';
} else { } else {
el_free(filename);
if (*text == 0) if (*text == 0)
filename = NULL; filename = NULL;
else { else {
@ -184,6 +210,7 @@ fn_filename_completion_function(const char *text, int state)
if (filename == NULL) if (filename == NULL)
return NULL; return NULL;
} }
el_free(dirname);
dirname = NULL; dirname = NULL;
} }
@ -193,12 +220,14 @@ fn_filename_completion_function(const char *text, int state)
} }
/* support for ``~user'' syntax */ /* support for ``~user'' syntax */
free(dirpath);
if (dirname == NULL && (dirname = strdup("./")) == NULL) el_free(dirpath);
return NULL; dirpath = NULL;
if (dirname == NULL) {
if (*dirname == '~') if ((dirname = strdup("")) == NULL)
return NULL;
dirpath = strdup("./");
} else if (*dirname == '~')
dirpath = fn_tilde_expand(dirname); dirpath = fn_tilde_expand(dirname);
else else
dirpath = strdup(dirname); dirpath = strdup(dirname);
@ -208,7 +237,7 @@ fn_filename_completion_function(const char *text, int state)
dir = opendir(dirpath); dir = opendir(dirpath);
if (!dir) if (!dir)
return (NULL); /* cannot open the directory */ return NULL; /* cannot open the directory */
/* will be used in cycle */ /* will be used in cycle */
filename_len = filename ? strlen(filename) : 0; filename_len = filename ? strlen(filename) : 0;
@ -243,17 +272,18 @@ fn_filename_completion_function(const char *text, int state)
len = strlen(entry->d_name); len = strlen(entry->d_name);
#endif #endif
temp = malloc(strlen(dirname) + len + 1); len = strlen(dirname) + len + 1;
temp = el_malloc(len * sizeof(*temp));
if (temp == NULL) if (temp == NULL)
return NULL; return NULL;
(void)sprintf(temp, "%s%s", dirname, entry->d_name); (void)snprintf(temp, len, "%s%s", dirname, entry->d_name);
} else { } else {
(void)closedir(dir); (void)closedir(dir);
dir = NULL; dir = NULL;
temp = NULL; temp = NULL;
} }
return (temp); return temp;
} }
@ -270,7 +300,7 @@ append_char_function(const char *name)
rs = "/"; rs = "/";
out: out:
if (expname) if (expname)
free(expname); el_free(expname);
return rs; return rs;
} }
/* /*
@ -293,10 +323,10 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
char **nmatch_list; char **nmatch_list;
while (matches + 3 >= match_list_len) while (matches + 3 >= match_list_len)
match_list_len <<= 1; match_list_len <<= 1;
nmatch_list = realloc(match_list, nmatch_list = el_realloc(match_list,
match_list_len * sizeof(char *)); match_list_len * sizeof(*nmatch_list));
if (nmatch_list == NULL) { if (nmatch_list == NULL) {
free(match_list); el_free(match_list);
return NULL; return NULL;
} }
match_list = nmatch_list; match_list = nmatch_list;
@ -319,9 +349,9 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
max_equal = i; max_equal = i;
} }
retstr = malloc(max_equal + 1); retstr = el_malloc((max_equal + 1) * sizeof(*retstr));
if (retstr == NULL) { if (retstr == NULL) {
free(match_list); el_free(match_list);
return NULL; return NULL;
} }
(void)strncpy(retstr, match_list[1], max_equal); (void)strncpy(retstr, match_list[1], max_equal);
@ -329,9 +359,9 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int))
match_list[0] = retstr; match_list[0] = retstr;
/* add NULL as last pointer to the array */ /* add NULL as last pointer to the array */
match_list[matches + 1] = (char *) NULL; match_list[matches + 1] = NULL;
return (match_list); return match_list;
} }
/* /*
@ -348,37 +378,47 @@ _fn_qsort_string_compare(const void *i1, const void *i2)
/* /*
* Display list of strings in columnar format on readline's output stream. * Display list of strings in columnar format on readline's output stream.
* 'matches' is list of strings, 'len' is number of strings in 'matches', * 'matches' is list of strings, 'num' is number of strings in 'matches',
* 'max' is maximum length of string in 'matches'. * 'width' is maximum length of string in 'matches'.
*
* matches[0] is not one of the match strings, but it is counted in
* num, so the strings are matches[1] *through* matches[num-1].
*/ */
void void
fn_display_match_list (EditLine *el, char **matches, int len, int max) fn_display_match_list (EditLine *el, char **matches, size_t num, size_t width)
{ {
int i, idx, limit, count; size_t line, lines, col, cols, thisguy;
int screenwidth = el->el_term.t_size.h; int screenwidth = el->el_terminal.t_size.h;
/* Ignore matches[0]. Avoid 1-based array logic below. */
matches++;
num--;
/* /*
* Find out how many entries can be put on one line, count * Find out how many entries can be put on one line; count
* with two spaces between strings. * with one space between strings the same way it's printed.
*/ */
limit = screenwidth / (max + 2); cols = (size_t)screenwidth / (width + 1);
if (limit == 0) if (cols == 0)
limit = 1; cols = 1;
/* how many lines of output */ /* how many lines of output, rounded up */
count = len / limit; lines = (num + cols - 1) / cols;
if (count * limit < len)
count++;
/* Sort the items if they are not already sorted. */ /* Sort the items. */
qsort(&matches[1], (size_t)(len - 1), sizeof(char *), qsort(matches, num, sizeof(char *), _fn_qsort_string_compare);
_fn_qsort_string_compare);
idx = 1; /*
for(; count > 0; count--) { * On the ith line print elements i, i+lines, i+lines*2, etc.
for(i = 0; i < limit && matches[idx]; i++, idx++) */
(void)fprintf(el->el_outfile, "%-*s ", max, for (line = 0; line < lines; line++) {
matches[idx]); for (col = 0; col < cols; col++) {
thisguy = line + col * lines;
if (thisguy >= num)
break;
(void)fprintf(el->el_outfile, "%s%-*s",
col == 0 ? "" : " ", (int)width, matches[thisguy]);
}
(void)fprintf(el->el_outfile, "\n"); (void)fprintf(el->el_outfile, "\n");
} }
} }
@ -399,13 +439,14 @@ int
fn_complete(EditLine *el, fn_complete(EditLine *el,
char *(*complet_func)(const char *, int), char *(*complet_func)(const char *, int),
char **(*attempted_completion_function)(const char *, int, int), char **(*attempted_completion_function)(const char *, int, int),
const char *word_break, const char *special_prefixes, const Char *word_break, const Char *special_prefixes,
const char *(*app_func)(const char *), int query_items, const char *(*app_func)(const char *), size_t query_items,
int *completion_type, int *over, int *point, int *end) int *completion_type, int *over, int *point, int *end)
{ {
const LineInfo *li; const TYPE(LineInfo) *li;
char *temp, **matches; Char *temp;
const char *ctemp; char **matches;
const Char *ctemp;
size_t len; size_t len;
int what_to_do = '\t'; int what_to_do = '\t';
int retval = CC_NORM; int retval = CC_NORM;
@ -423,45 +464,47 @@ fn_complete(EditLine *el,
app_func = append_char_function; app_func = append_char_function;
/* We now look backwards for the start of a filename/variable word */ /* We now look backwards for the start of a filename/variable word */
li = el_line(el); li = FUN(el,line)(el);
ctemp = (const char *) li->cursor; ctemp = li->cursor;
while (ctemp > li->buffer while (ctemp > li->buffer
&& !strchr(word_break, ctemp[-1]) && !Strchr(word_break, ctemp[-1])
&& (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) ) && (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) )
ctemp--; ctemp--;
len = li->cursor - ctemp; len = (size_t)(li->cursor - ctemp);
#if defined(__SSP__) || defined(__SSP_ALL__) #if defined(__SSP__) || defined(__SSP_ALL__)
temp = malloc(len + 1); temp = el_malloc((len + 1) * sizeof(*temp));
#else #else
temp = alloca(len + 1); temp = alloca((len + 1) * sizeof(*temp));
#endif #endif
(void)strncpy(temp, ctemp, len); (void)Strncpy(temp, ctemp, len);
temp[len] = '\0'; temp[len] = '\0';
/* these can be used by function called in completion_matches() */ /* these can be used by function called in completion_matches() */
/* or (*attempted_completion_function)() */ /* or (*attempted_completion_function)() */
if (point != 0) if (point != 0)
*point = li->cursor - li->buffer; *point = (int)(li->cursor - li->buffer);
if (end != NULL) if (end != NULL)
*end = li->lastchar - li->buffer; *end = (int)(li->lastchar - li->buffer);
if (attempted_completion_function) { if (attempted_completion_function) {
int cur_off = li->cursor - li->buffer; int cur_off = (int)(li->cursor - li->buffer);
matches = (*attempted_completion_function) (temp, matches = (*attempted_completion_function)(
(int)(cur_off - len), cur_off); ct_encode_string(temp, &el->el_scratch),
cur_off - (int)len, cur_off);
} else } else
matches = 0; matches = 0;
if (!attempted_completion_function || if (!attempted_completion_function ||
(over != NULL && !*over && !matches)) (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) if (over != NULL)
*over = 0; *over = 0;
if (matches) { if (matches) {
int i; int i;
int matches_num, maxlen, match_len, match_display=1; size_t matches_num, maxlen, match_len, match_display=1;
retval = CC_REFRESH; retval = CC_REFRESH;
/* /*
@ -470,7 +513,8 @@ fn_complete(EditLine *el,
*/ */
if (matches[0][0] != '\0') { if (matches[0][0] != '\0') {
el_deletestr(el, (int) len); 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 == '?') if (what_to_do == '?')
@ -482,7 +526,9 @@ fn_complete(EditLine *el,
* it, unless we do filename completion and the * it, unless we do filename completion and the
* object is a directory. * object is a directory.
*/ */
el_insertstr(el, (*app_func)(matches[0])); FUN(el,insertstr)(el,
ct_decode_string((*app_func)(matches[0]),
&el->el_scratch));
} else if (what_to_do == '!') { } else if (what_to_do == '!') {
display_matches: display_matches:
/* /*
@ -490,12 +536,13 @@ fn_complete(EditLine *el,
* matches. * matches.
*/ */
for(i=1, maxlen=0; matches[i]; i++) { for(i = 1, maxlen = 0; matches[i]; i++) {
match_len = strlen(matches[i]); match_len = strlen(matches[i]);
if (match_len > maxlen) if (match_len > maxlen)
maxlen = match_len; maxlen = match_len;
} }
matches_num = i - 1; /* matches[1] through matches[i-1] are available */
matches_num = (size_t)(i - 1);
/* newline to get on next line from command line */ /* newline to get on next line from command line */
(void)fprintf(el->el_outfile, "\n"); (void)fprintf(el->el_outfile, "\n");
@ -506,7 +553,7 @@ fn_complete(EditLine *el,
*/ */
if (matches_num > query_items) { if (matches_num > query_items) {
(void)fprintf(el->el_outfile, (void)fprintf(el->el_outfile,
"Display all %d possibilities? (y or n) ", "Display all %zu possibilities? (y or n) ",
matches_num); matches_num);
(void)fflush(el->el_outfile); (void)fflush(el->el_outfile);
if (getc(stdin) != 'y') if (getc(stdin) != 'y')
@ -514,9 +561,17 @@ fn_complete(EditLine *el,
(void)fprintf(el->el_outfile, "\n"); (void)fprintf(el->el_outfile, "\n");
} }
if (match_display) if (match_display) {
fn_display_match_list(el, matches, matches_num, /*
maxlen); * Interface of this function requires the
* strings be matches[1..num-1] for compat.
* We have matches_num strings not counting
* the prefix in matches[0], so we need to
* add 1 to matches_num for the call.
*/
fn_display_match_list(el, matches,
matches_num+1, maxlen);
}
retval = CC_REDISPLAY; retval = CC_REDISPLAY;
} else if (matches[0][0]) { } else if (matches[0][0]) {
/* /*
@ -534,12 +589,12 @@ fn_complete(EditLine *el,
/* free elements of array and the array itself */ /* free elements of array and the array itself */
for (i = 0; matches[i]; i++) for (i = 0; matches[i]; i++)
free(matches[i]); el_free(matches[i]);
free(matches); el_free(matches);
matches = NULL; matches = NULL;
} }
#if defined(__SSP__) || defined(__SSP_ALL__) #if defined(__SSP__) || defined(__SSP_ALL__)
free(temp); el_free(temp);
#endif #endif
return retval; return retval;
} }
@ -552,6 +607,6 @@ unsigned char
_el_fn_complete(EditLine *el, int ch __attribute__((__unused__))) _el_fn_complete(EditLine *el, int ch __attribute__((__unused__)))
{ {
return (unsigned char)fn_complete(el, NULL, NULL, return (unsigned char)fn_complete(el, NULL, NULL,
break_chars, NULL, NULL, 100, break_chars, NULL, NULL, (size_t)100,
NULL, NULL, NULL, NULL); NULL, NULL, NULL, NULL);
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: filecomplete.h,v 1.6 2008/04/29 06:53:01 martin Exp $ */ /* $NetBSD: filecomplete.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */
/*- /*-
* Copyright (c) 1997 The NetBSD Foundation, Inc. * Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -34,10 +34,10 @@
int fn_complete(EditLine *, int fn_complete(EditLine *,
char *(*)(const char *, int), char *(*)(const char *, int),
char **(*)(const char *, int, 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 *); 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_tilde_expand(const char *);
char *fn_filename_completion_function(const char *, int); char *fn_filename_completion_function(const char *, int);

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.20 2011/07/29 15:16:33 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -55,12 +55,12 @@ hist_init(EditLine *el)
el->el_history.fun = NULL; el->el_history.fun = NULL;
el->el_history.ref = 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; el->el_history.sz = EL_BUFSIZ;
if (el->el_history.buf == NULL) if (el->el_history.buf == NULL)
return (-1); return -1;
el->el_history.last = el->el_history.buf; el->el_history.last = el->el_history.buf;
return (0); return 0;
} }
@ -71,7 +71,7 @@ protected void
hist_end(EditLine *el) hist_end(EditLine *el)
{ {
el_free((ptr_t) el->el_history.buf); el_free(el->el_history.buf);
el->el_history.buf = NULL; el->el_history.buf = NULL;
} }
@ -80,12 +80,12 @@ hist_end(EditLine *el)
* Set new history interface * Set new history interface
*/ */
protected int protected int
hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr) hist_set(EditLine *el, hist_fun_t fun, void *ptr)
{ {
el->el_history.ref = ptr; el->el_history.ref = ptr;
el->el_history.fun = fun; el->el_history.fun = fun;
return (0); return 0;
} }
@ -96,11 +96,11 @@ hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr)
protected el_action_t protected el_action_t
hist_get(EditLine *el) hist_get(EditLine *el)
{ {
const char *hp; const Char *hp;
int h; int h;
if (el->el_history.eventno == 0) { /* if really the current line */ 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_history.sz);
el->el_line.lastchar = el->el_line.buffer + el->el_line.lastchar = el->el_line.buffer +
(el->el_history.last - el->el_history.buf); (el->el_history.last - el->el_history.buf);
@ -112,24 +112,25 @@ hist_get(EditLine *el)
#endif /* KSHVI */ #endif /* KSHVI */
el->el_line.cursor = el->el_line.lastchar; el->el_line.cursor = el->el_line.lastchar;
return (CC_REFRESH); return CC_REFRESH;
} }
if (el->el_history.ref == NULL) if (el->el_history.ref == NULL)
return (CC_ERROR); return CC_ERROR;
hp = HIST_FIRST(el); hp = HIST_FIRST(el);
if (hp == NULL) if (hp == NULL)
return (CC_ERROR); return CC_ERROR;
for (h = 1; h < el->el_history.eventno; h++) for (h = 1; h < el->el_history.eventno; h++)
if ((hp = HIST_NEXT(el)) == NULL) { if ((hp = HIST_NEXT(el)) == NULL) {
el->el_history.eventno = h; el->el_history.eventno = h;
return (CC_ERROR); 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)); (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 if (el->el_line.lastchar > el->el_line.buffer
&& el->el_line.lastchar[-1] == '\n') && el->el_line.lastchar[-1] == '\n')
@ -144,7 +145,7 @@ hist_get(EditLine *el)
#endif /* KSHVI */ #endif /* KSHVI */
el->el_line.cursor = el->el_line.lastchar; el->el_line.cursor = el->el_line.lastchar;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -152,34 +153,34 @@ hist_get(EditLine *el)
* process a history command * process a history command
*/ */
protected int 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; int num;
HistEvent ev; TYPE(HistEvent) ev;
if (el->el_history.ref == NULL) if (el->el_history.ref == NULL)
return (-1); return -1;
if (argc == 1 || strcmp(argv[1], "list") == 0) { if (argc == 1 || Strcmp(argv[1], STR("list")) == 0) {
/* List history entries */ /* List history entries */
for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el)) for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el))
(void) fprintf(el->el_outfile, "%d %s", (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); return 0;
} }
if (argc != 3) if (argc != 3)
return (-1); 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); return FUNW(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 FUNW(history)(el->el_history.ref, &ev, H_SETUNIQUE, num);
return -1; return -1;
} }
@ -192,13 +193,13 @@ protected int
/*ARGSUSED*/ /*ARGSUSED*/
hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz) 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) if (!newbuf)
return 0; 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 = newbuf +
(el->el_history.last - el->el_history.buf); (el->el_history.last - el->el_history.buf);
@ -207,3 +208,15 @@ hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz)
return 1; return 1;
} }
#ifdef WIDECHAR
protected wchar_t *
hist_convert(EditLine *el, int fn, void *arg)
{
HistEventW ev;
if ((*(el)->el_history.fun)((el)->el_history.ref, &ev, fn, arg) == -1)
return NULL;
return ct_decode_string((const char *)(const void *)ev.str,
&el->el_scratch);
}
#endif

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.13 2011/07/28 20:50:55 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -42,21 +42,29 @@
#include "histedit.h" #include "histedit.h"
typedef int (*hist_fun_t)(ptr_t, HistEvent *, int, ...); typedef int (*hist_fun_t)(void *, TYPE(HistEvent) *, int, ...);
typedef struct el_history_t { typedef struct el_history_t {
char *buf; /* The history buffer */ Char *buf; /* The history buffer */
size_t sz; /* Size of 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 */ int eventno; /* Event we are looking for */
ptr_t ref; /* Argument for history fcns */ void * ref; /* Argument for history fcns */
hist_fun_t fun; /* Event access */ hist_fun_t fun; /* Event access */
HistEvent ev; /* Event cookie */ TYPE(HistEvent) ev; /* Event cookie */
} el_history_t; } 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, \ ((((*(el)->el_history.fun) ((el)->el_history.ref, &(el)->el_history.ev, \
fn, arg)) == -1) ? NULL : (el)->el_history.ev.str) 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_NEXT(el) HIST_FUN(el, H_NEXT, NULL)
#define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL) #define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL)
@ -69,8 +77,11 @@ typedef struct el_history_t {
protected int hist_init(EditLine *); protected int hist_init(EditLine *);
protected void hist_end(EditLine *); protected void hist_end(EditLine *);
protected el_action_t hist_get(EditLine *); protected el_action_t hist_get(EditLine *);
protected int hist_set(EditLine *, hist_fun_t, ptr_t); protected int hist_set(EditLine *, hist_fun_t, void *);
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); protected int hist_enlargebuf(EditLine *, size_t, size_t);
#ifdef WIDECHAR
protected wchar_t *hist_convert(EditLine *, int, void *);
#endif
#endif /* _h_el_hist */ #endif /* _h_el_hist */

View File

@ -1,4 +1,4 @@
/* $NetBSD: histedit.h,v 1.35 2009/02/05 19:15:44 christos Exp $ */ /* $NetBSD: histedit.h,v 1.48 2011/07/28 20:50:55 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -43,6 +43,8 @@
#define LIBEDIT_MAJOR 2 #define LIBEDIT_MAJOR 2
#define LIBEDIT_MINOR 11 #define LIBEDIT_MINOR 11
#include <stdint.h>
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h> #include <stdio.h>
@ -114,29 +116,46 @@ unsigned char _el_fn_complete(EditLine *, int);
/* /*
* el_set/el_get parameters * el_set/el_get parameters
*
* 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 .
* 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 /* , el_pfunc_t); */ #define EL_PROMPT 0 /* , prompt_func); set/get */
#define EL_TERMINAL 1 /* , const char *); */ #define EL_TERMINAL 1 /* , const char *); set/get */
#define EL_EDITOR 2 /* , const char *); */ #define EL_EDITOR 2 /* , const Char *); set/get */
#define EL_SIGNAL 3 /* , int); */ #define EL_SIGNAL 3 /* , int); set/get */
#define EL_BIND 4 /* , const char *, ..., NULL); */ #define EL_BIND 4 /* , const Char *, ..., NULL); set */
#define EL_TELLTC 5 /* , const char *, ..., NULL); */ #define EL_TELLTC 5 /* , const Char *, ..., NULL); set */
#define EL_SETTC 6 /* , const char *, ..., NULL); */ #define EL_SETTC 6 /* , const Char *, ..., NULL); set */
#define EL_ECHOTC 7 /* , const char *, ..., NULL); */ #define EL_ECHOTC 7 /* , const Char *, ..., NULL); set */
#define EL_SETTY 8 /* , const char *, ..., NULL); */ #define EL_SETTY 8 /* , const Char *, ..., NULL); set */
#define EL_ADDFN 9 /* , const char *, const char * */ #define EL_ADDFN 9 /* , const Char *, const Char, set */
/* , el_func_t); */ /* el_func_t); */
#define EL_HIST 10 /* , hist_fun_t, const char *); */ #define EL_HIST 10 /* , hist_fun_t, const void *); set */
#define EL_EDITMODE 11 /* , int); */ #define EL_EDITMODE 11 /* , int); set/get */
#define EL_RPROMPT 12 /* , el_pfunc_t); */ #define EL_RPROMPT 12 /* , prompt_func); set/get */
#define EL_GETCFN 13 /* , el_rfunc_t); */ #define EL_GETCFN 13 /* , el_rfunc_t); set/get */
#define EL_CLIENTDATA 14 /* , void *); */ #define EL_CLIENTDATA 14 /* , void *); set/get */
#define EL_UNBUFFERED 15 /* , int); */ #define EL_UNBUFFERED 15 /* , int); set/get */
#define EL_PREP_TERM 16 /* , int); */ #define EL_PREP_TERM 16 /* , int); set */
#define EL_GETTC 17 /* , const char *, ..., NULL); */ #define EL_GETTC 17 /* , const Char *, ..., NULL); get */
#define EL_GETFP 18 /* , int, FILE **); */ #define EL_GETFP 18 /* , int, FILE **); get */
#define EL_SETFP 19 /* , int, FILE *); */ #define EL_SETFP 19 /* , int, FILE *); set */
#define EL_REFRESH 20 /* , void); */ #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_RESIZE 23 /* , el_zfunc_t, void *); set */
#define EL_BUILTIN_GETCFN (NULL) #define EL_BUILTIN_GETCFN (NULL)
@ -188,12 +207,12 @@ int history(History *, HistEvent *, int, ...);
#define H_NEXT 6 /* , void); */ #define H_NEXT 6 /* , void); */
#define H_CURR 8 /* , const int); */ #define H_CURR 8 /* , const int); */
#define H_SET 7 /* , int); */ #define H_SET 7 /* , int); */
#define H_ADD 9 /* , const char *); */ #define H_ADD 9 /* , const wchar_t *); */
#define H_ENTER 10 /* , const char *); */ #define H_ENTER 10 /* , const wchar_t *); */
#define H_APPEND 11 /* , const char *); */ #define H_APPEND 11 /* , const wchar_t *); */
#define H_END 12 /* , void); */ #define H_END 12 /* , void); */
#define H_NEXT_STR 13 /* , const char *); */ #define H_NEXT_STR 13 /* , const wchar_t *); */
#define H_PREV_STR 14 /* , const char *); */ #define H_PREV_STR 14 /* , const wchar_t *); */
#define H_NEXT_EVENT 15 /* , const int); */ #define H_NEXT_EVENT 15 /* , const int); */
#define H_PREV_EVENT 16 /* , const int); */ #define H_PREV_EVENT 16 /* , const int); */
#define H_LOAD 17 /* , const char *); */ #define H_LOAD 17 /* , const char *); */
@ -202,6 +221,10 @@ int history(History *, HistEvent *, int, ...);
#define H_SETUNIQUE 20 /* , int); */ #define H_SETUNIQUE 20 /* , int); */
#define H_GETUNIQUE 21 /* , void); */ #define H_GETUNIQUE 21 /* , void); */
#define H_DEL 22 /* , int); */ #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); */
/* /*
@ -221,6 +244,74 @@ int tok_line(Tokenizer *, const LineInfo *,
int tok_str(Tokenizer *, const char *, int tok_str(Tokenizer *, const char *,
int *, 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 #ifdef __cplusplus
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,5 @@
#define NARROW_WRAPPER
#include "config.h"
#undef WIDECHAR
#define NARROWCHAR
#include "./history.c"

View File

@ -1,4 +1,4 @@
/* $NetBSD: key.c,v 1.19 2006/03/23 20:22:51 christos Exp $ */ /* $NetBSD: keymacro.c,v 1.7 2011/08/16 16:25:15 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -41,20 +41,21 @@ static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* /*
* key.c: This module contains the procedures for maintaining * keymacro.c: This module contains the procedures for maintaining
* the extended-key map. * the extended-key map.
* *
* An extended-key (key) is a sequence of keystrokes introduced * An extended-key (key) is a sequence of keystrokes introduced
* with a sequence introducer and consisting of an arbitrary * with a sequence introducer and consisting of an arbitrary
* number of characters. This module maintains a map (the el->el_key.map) * number of characters. This module maintains a map (the
* el->el_keymacro.map)
* to convert these extended-key sequences into input strs * to convert these extended-key sequences into input strs
* (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE). * (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE).
* *
* Warning: * Warning:
* If key is a substr of some other keys, then the longer * If key is a substr of some other keys, then the longer
* keys are lost!! That is, if the keys "abcd" and "abcef" * keys are lost!! That is, if the keys "abcd" and "abcef"
* are in el->el_key.map, adding the key "abc" will cause the first two * are in el->el_keymacro.map, adding the key "abc" will cause
* definitions to be lost. * the first two definitions to be lost.
* *
* Restrictions: * Restrictions:
* ------------- * -------------
@ -67,102 +68,104 @@ static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
#include "el.h" #include "el.h"
/* /*
* The Nodes of the el->el_key.map. The el->el_key.map is a linked list * The Nodes of the el->el_keymacro.map. The el->el_keymacro.map is a
* of these node elements * linked list of these node elements
*/ */
struct key_node_t { struct keymacro_node_t {
char ch; /* single character of key */ Char ch; /* single character of key */
int type; /* node type */ int type; /* node type */
key_value_t val; /* command code or pointer to str, */ keymacro_value_t val; /* command code or pointer to str, */
/* if this is a leaf */ /* if this is a leaf */
struct key_node_t *next; /* ptr to next char of this key */ struct keymacro_node_t *next; /* ptr to next char of this key */
struct key_node_t *sibling; /* ptr to another key with same prefix*/ struct keymacro_node_t *sibling;/* ptr to another key with same prefix*/
}; };
private int node_trav(EditLine *, key_node_t *, char *, private int node_trav(EditLine *, keymacro_node_t *, Char *,
key_value_t *); keymacro_value_t *);
private int node__try(EditLine *, key_node_t *, const char *, private int node__try(EditLine *, keymacro_node_t *, const Char *,
key_value_t *, int); keymacro_value_t *, int);
private key_node_t *node__get(int); private keymacro_node_t *node__get(Int);
private void node__free(key_node_t *); private void node__free(keymacro_node_t *);
private void node__put(EditLine *, key_node_t *); private void node__put(EditLine *, keymacro_node_t *);
private int node__delete(EditLine *, key_node_t **, const char *); private int node__delete(EditLine *, keymacro_node_t **,
private int node_lookup(EditLine *, const char *, key_node_t *, const Char *);
int); private int node_lookup(EditLine *, const Char *,
private int node_enum(EditLine *, key_node_t *, int); keymacro_node_t *, size_t);
private int node_enum(EditLine *, keymacro_node_t *, size_t);
#define KEY_BUFSIZ EL_BUFSIZ #define KEY_BUFSIZ EL_BUFSIZ
/* key_init(): /* keymacro_init():
* Initialize the key maps * Initialize the key maps
*/ */
protected int protected int
key_init(EditLine *el) keymacro_init(EditLine *el)
{ {
el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ); el->el_keymacro.buf = el_malloc(KEY_BUFSIZ *
if (el->el_key.buf == NULL) sizeof(*el->el_keymacro.buf));
return (-1); if (el->el_keymacro.buf == NULL)
el->el_key.map = NULL; return -1;
key_reset(el); el->el_keymacro.map = NULL;
return (0); keymacro_reset(el);
return 0;
} }
/* key_end(): /* keymacro_end():
* Free the key maps * Free the key maps
*/ */
protected void protected void
key_end(EditLine *el) keymacro_end(EditLine *el)
{ {
el_free((ptr_t) el->el_key.buf); el_free(el->el_keymacro.buf);
el->el_key.buf = NULL; el->el_keymacro.buf = NULL;
node__free(el->el_key.map); node__free(el->el_keymacro.map);
} }
/* key_map_cmd(): /* keymacro_map_cmd():
* Associate cmd with a key value * Associate cmd with a key value
*/ */
protected key_value_t * protected keymacro_value_t *
key_map_cmd(EditLine *el, int cmd) keymacro_map_cmd(EditLine *el, int cmd)
{ {
el->el_key.val.cmd = (el_action_t) cmd; el->el_keymacro.val.cmd = (el_action_t) cmd;
return (&el->el_key.val); return &el->el_keymacro.val;
} }
/* key_map_str(): /* keymacro_map_str():
* Associate str with a key value * Associate str with a key value
*/ */
protected key_value_t * protected keymacro_value_t *
key_map_str(EditLine *el, char *str) keymacro_map_str(EditLine *el, Char *str)
{ {
el->el_key.val.str = str; el->el_keymacro.val.str = str;
return (&el->el_key.val); return &el->el_keymacro.val;
} }
/* key_reset(): /* keymacro_reset():
* Takes all nodes on el->el_key.map and puts them on free list. Then * Takes all nodes on el->el_keymacro.map and puts them on free list.
* initializes el->el_key.map with arrow keys * Then initializes el->el_keymacro.map with arrow keys
* [Always bind the ansi arrow keys?] * [Always bind the ansi arrow keys?]
*/ */
protected void protected void
key_reset(EditLine *el) keymacro_reset(EditLine *el)
{ {
node__put(el, el->el_key.map); node__put(el, el->el_keymacro.map);
el->el_key.map = NULL; el->el_keymacro.map = NULL;
return; return;
} }
/* key_get(): /* keymacro_get():
* Calls the recursive function with entry point el->el_key.map * Calls the recursive function with entry point el->el_keymacro.map
* Looks up *ch in map and then reads characters until a * Looks up *ch in map and then reads characters until a
* complete match is found or a mismatch occurs. Returns the * complete match is found or a mismatch occurs. Returns the
* type of the match found (XK_STR, XK_CMD, or XK_EXE). * type of the match found (XK_STR, XK_CMD, or XK_EXE).
@ -170,98 +173,101 @@ key_reset(EditLine *el)
* The last character read is returned in *ch. * The last character read is returned in *ch.
*/ */
protected int protected int
key_get(EditLine *el, char *ch, key_value_t *val) keymacro_get(EditLine *el, Char *ch, keymacro_value_t *val)
{ {
return (node_trav(el, el->el_key.map, ch, val)); return node_trav(el, el->el_keymacro.map, ch, val);
} }
/* key_add(): /* keymacro_add():
* Adds key to the el->el_key.map and associates the value in val with it. * Adds key to the el->el_keymacro.map and associates the value in
* If key is already is in el->el_key.map, the new code is applied to the * val with it. If key is already is in el->el_keymacro.map, the new
* existing key. Ntype specifies if code is a command, an * code is applied to the existing key. Ntype specifies if code is a
* out str or a unix command. * command, an out str or a unix command.
*/ */
protected void protected void
key_add(EditLine *el, const char *key, key_value_t *val, int ntype) keymacro_add(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
{ {
if (key[0] == '\0') { if (key[0] == '\0') {
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"key_add: Null extended-key not allowed.\n"); "keymacro_add: Null extended-key not allowed.\n");
return; return;
} }
if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) { if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) {
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"key_add: sequence-lead-in command not allowed\n"); "keymacro_add: sequence-lead-in command not allowed\n");
return; return;
} }
if (el->el_key.map == NULL) if (el->el_keymacro.map == NULL)
/* tree is initially empty. Set up new node to match key[0] */ /* tree is initially empty. Set up new node to match key[0] */
el->el_key.map = node__get(key[0]); el->el_keymacro.map = node__get(key[0]);
/* it is properly initialized */ /* it is properly initialized */
/* Now recurse through el->el_key.map */ /* Now recurse through el->el_keymacro.map */
(void) node__try(el, el->el_key.map, key, val, ntype); (void) node__try(el, el->el_keymacro.map, key, val, ntype);
return; return;
} }
/* key_clear(): /* keymacro_clear():
* *
*/ */
protected void protected void
key_clear(EditLine *el, el_action_t *map, const char *in) keymacro_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) && if ((map[(unsigned char)*in] == ED_SEQUENCE_LEAD_IN) &&
((map == el->el_map.key && ((map == el->el_map.key &&
el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) || el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) ||
(map == el->el_map.alt && (map == el->el_map.alt &&
el->el_map.key[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN))) el->el_map.key[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN)))
(void) key_delete(el, in); (void) keymacro_delete(el, in);
} }
/* key_delete(): /* keymacro_delete():
* Delete the key and all longer keys staring with key, if * Delete the key and all longer keys staring with key, if
* they exists. * they exists.
*/ */
protected int protected int
key_delete(EditLine *el, const char *key) keymacro_delete(EditLine *el, const Char *key)
{ {
if (key[0] == '\0') { if (key[0] == '\0') {
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"key_delete: Null extended-key not allowed.\n"); "keymacro_delete: Null extended-key not allowed.\n");
return (-1); return -1;
} }
if (el->el_key.map == NULL) if (el->el_keymacro.map == NULL)
return (0); return 0;
(void) node__delete(el, &el->el_key.map, key); (void) node__delete(el, &el->el_keymacro.map, key);
return (0); return 0;
} }
/* key_print(): /* keymacro_print():
* Print the binding associated with key key. * Print the binding associated with key key.
* Print entire el->el_key.map if null * Print entire el->el_keymacro.map if null
*/ */
protected void protected void
key_print(EditLine *el, const char *key) keymacro_print(EditLine *el, const Char *key)
{ {
/* do nothing if el->el_key.map is empty and null key specified */ /* do nothing if el->el_keymacro.map is empty and null key specified */
if (el->el_key.map == NULL && *key == 0) if (el->el_keymacro.map == NULL && *key == 0)
return; return;
el->el_key.buf[0] = '"'; el->el_keymacro.buf[0] = '"';
if (node_lookup(el, key, el->el_key.map, 1) <= -1) if (node_lookup(el, key, el->el_keymacro.map, (size_t)1) <= -1)
/* key is not bound */ /* key is not bound */
(void) fprintf(el->el_errfile, "Unbound extended key \"%s\"\n", (void) fprintf(el->el_errfile, "Unbound extended key \"" FSTR
key); "\"\n", key);
return; return;
} }
@ -271,34 +277,34 @@ key_print(EditLine *el, const char *key)
* found. May read in more characters. * found. May read in more characters.
*/ */
private int private int
node_trav(EditLine *el, key_node_t *ptr, char *ch, key_value_t *val) node_trav(EditLine *el, keymacro_node_t *ptr, Char *ch, keymacro_value_t *val)
{ {
if (ptr->ch == *ch) { if (ptr->ch == *ch) {
/* match found */ /* match found */
if (ptr->next) { if (ptr->next) {
/* key not complete so get next char */ /* 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; val->cmd = ED_END_OF_FILE;
return (XK_CMD); return XK_CMD;
/* PWP: Pretend we just read an end-of-file */ /* PWP: Pretend we just read an end-of-file */
} }
return (node_trav(el, ptr->next, ch, val)); return node_trav(el, ptr->next, ch, val);
} else { } else {
*val = ptr->val; *val = ptr->val;
if (ptr->type != XK_CMD) if (ptr->type != XK_CMD)
*ch = '\0'; *ch = '\0';
return (ptr->type); return ptr->type;
} }
} else { } else {
/* no match found here */ /* no match found here */
if (ptr->sibling) { if (ptr->sibling) {
/* try next sibling */ /* try next sibling */
return (node_trav(el, ptr->sibling, ch, val)); return node_trav(el, ptr->sibling, ch, val);
} else { } else {
/* no next sibling -- mismatch */ /* no next sibling -- mismatch */
val->str = NULL; val->str = NULL;
return (XK_STR); return XK_STR;
} }
} }
} }
@ -308,11 +314,12 @@ 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 * Find a node that matches *str or allocate a new one
*/ */
private int private int
node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int ntype) node__try(EditLine *el, keymacro_node_t *ptr, const Char *str,
keymacro_value_t *val, int ntype)
{ {
if (ptr->ch != *str) { if (ptr->ch != *str) {
key_node_t *xm; keymacro_node_t *xm;
for (xm = ptr; xm->sibling != NULL; xm = xm->sibling) for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
if (xm->sibling->ch == *str) if (xm->sibling->ch == *str)
@ -335,7 +342,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
case XK_STR: case XK_STR:
case XK_EXE: case XK_EXE:
if (ptr->val.str) if (ptr->val.str)
el_free((ptr_t) ptr->val.str); el_free(ptr->val.str);
break; break;
default: default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", EL_ABORT((el->el_errfile, "Bad XK_ type %d\n",
@ -349,7 +356,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
break; break;
case XK_STR: case XK_STR:
case XK_EXE: case XK_EXE:
if ((ptr->val.str = el_strdup(val->str)) == NULL) if ((ptr->val.str = Strdup(val->str)) == NULL)
return -1; return -1;
break; break;
default: default:
@ -362,7 +369,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
ptr->next = node__get(*str); /* setup new node */ ptr->next = node__get(*str); /* setup new node */
(void) node__try(el, ptr->next, str, val, ntype); (void) node__try(el, ptr->next, str, val, ntype);
} }
return (0); return 0;
} }
@ -370,21 +377,21 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int
* Delete node that matches str * Delete node that matches str
*/ */
private int private int
node__delete(EditLine *el, key_node_t **inptr, const char *str) node__delete(EditLine *el, keymacro_node_t **inptr, const Char *str)
{ {
key_node_t *ptr; keymacro_node_t *ptr;
key_node_t *prev_ptr = NULL; keymacro_node_t *prev_ptr = NULL;
ptr = *inptr; ptr = *inptr;
if (ptr->ch != *str) { if (ptr->ch != *str) {
key_node_t *xm; keymacro_node_t *xm;
for (xm = ptr; xm->sibling != NULL; xm = xm->sibling) for (xm = ptr; xm->sibling != NULL; xm = xm->sibling)
if (xm->sibling->ch == *str) if (xm->sibling->ch == *str)
break; break;
if (xm->sibling == NULL) if (xm->sibling == NULL)
return (0); return 0;
prev_ptr = xm; prev_ptr = xm;
ptr = xm->sibling; ptr = xm->sibling;
} }
@ -396,20 +403,20 @@ node__delete(EditLine *el, key_node_t **inptr, const char *str)
prev_ptr->sibling = ptr->sibling; prev_ptr->sibling = ptr->sibling;
ptr->sibling = NULL; ptr->sibling = NULL;
node__put(el, ptr); node__put(el, ptr);
return (1); return 1;
} else if (ptr->next != NULL && } else if (ptr->next != NULL &&
node__delete(el, &ptr->next, str) == 1) { node__delete(el, &ptr->next, str) == 1) {
if (ptr->next != NULL) if (ptr->next != NULL)
return (0); return 0;
if (prev_ptr == NULL) if (prev_ptr == NULL)
*inptr = ptr->sibling; *inptr = ptr->sibling;
else else
prev_ptr->sibling = ptr->sibling; prev_ptr->sibling = ptr->sibling;
ptr->sibling = NULL; ptr->sibling = NULL;
node__put(el, ptr); node__put(el, ptr);
return (1); return 1;
} else { } else {
return (0); return 0;
} }
} }
@ -418,7 +425,7 @@ node__delete(EditLine *el, key_node_t **inptr, const char *str)
* Puts a tree of nodes onto free list using free(3). * Puts a tree of nodes onto free list using free(3).
*/ */
private void private void
node__put(EditLine *el, key_node_t *ptr) node__put(EditLine *el, keymacro_node_t *ptr)
{ {
if (ptr == NULL) if (ptr == NULL)
return; return;
@ -436,25 +443,25 @@ node__put(EditLine *el, key_node_t *ptr)
case XK_EXE: case XK_EXE:
case XK_STR: case XK_STR:
if (ptr->val.str != NULL) if (ptr->val.str != NULL)
el_free((ptr_t) ptr->val.str); el_free(ptr->val.str);
break; break;
default: default:
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ptr->type)); EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ptr->type));
break; break;
} }
el_free((ptr_t) ptr); el_free(ptr);
} }
/* node__get(): /* node__get():
* Returns pointer to a key_node_t for ch. * Returns pointer to a keymacro_node_t for ch.
*/ */
private key_node_t * private keymacro_node_t *
node__get(int ch) node__get(Int ch)
{ {
key_node_t *ptr; keymacro_node_t *ptr;
ptr = (key_node_t *) el_malloc((size_t) sizeof(key_node_t)); ptr = el_malloc(sizeof(*ptr));
if (ptr == NULL) if (ptr == NULL)
return NULL; return NULL;
ptr->ch = ch; ptr->ch = ch;
@ -462,17 +469,17 @@ node__get(int ch)
ptr->val.str = NULL; ptr->val.str = NULL;
ptr->next = NULL; ptr->next = NULL;
ptr->sibling = NULL; ptr->sibling = NULL;
return (ptr); return ptr;
} }
private void private void
node__free(key_node_t *k) node__free(keymacro_node_t *k)
{ {
if (k == NULL) if (k == NULL)
return; return;
node__free(k->sibling); node__free(k->sibling);
node__free(k->next); node__free(k->next);
el_free((ptr_t) k); el_free(k);
} }
/* node_lookup(): /* node_lookup():
@ -480,37 +487,40 @@ node__free(key_node_t *k)
* Print if last node * Print if last node
*/ */
private int private int
node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt) node_lookup(EditLine *el, const Char *str, keymacro_node_t *ptr, size_t cnt)
{ {
int ncnt; ssize_t used;
if (ptr == NULL) if (ptr == NULL)
return (-1); /* cannot have null ptr */ return -1; /* cannot have null ptr */
if (*str == 0) { if (!str || *str == 0) {
/* no more chars in str. node_enum from here. */ /* no more chars in str. node_enum from here. */
(void) node_enum(el, ptr, cnt); (void) node_enum(el, ptr, cnt);
return (0); return 0;
} else { } else {
/* If match put this char into el->el_key.buf. Recurse */ /* If match put this char into el->el_keymacro.buf. Recurse */
if (ptr->ch == *str) { if (ptr->ch == *str) {
/* match found */ /* match found */
ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt, used = ct_visual_char(el->el_keymacro.buf + cnt,
(unsigned char) ptr->ch); KEY_BUFSIZ - cnt, ptr->ch);
if (used == -1)
return -1; /* ran out of buffer space */
if (ptr->next != NULL) if (ptr->next != NULL)
/* not yet at leaf */ /* not yet at leaf */
return (node_lookup(el, str + 1, ptr->next, return (node_lookup(el, str + 1, ptr->next,
ncnt + 1)); (size_t)used + cnt));
else { else {
/* next node is null so key should be complete */ /* next node is null so key should be complete */
if (str[1] == 0) { if (str[1] == 0) {
el->el_key.buf[ncnt + 1] = '"'; size_t px = cnt + (size_t)used;
el->el_key.buf[ncnt + 2] = '\0'; el->el_keymacro.buf[px] = '"';
key_kprint(el, el->el_key.buf, el->el_keymacro.buf[px + 1] = '\0';
keymacro_kprint(el, el->el_keymacro.buf,
&ptr->val, ptr->type); &ptr->val, ptr->type);
return (0); return 0;
} else } else
return (-1); return -1;
/* mismatch -- str still has chars */ /* mismatch -- str still has chars */
} }
} else { } else {
@ -519,7 +529,7 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
return (node_lookup(el, str, ptr->sibling, return (node_lookup(el, str, ptr->sibling,
cnt)); cnt));
else else
return (-1); return -1;
} }
} }
} }
@ -529,68 +539,76 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
* Traverse the node printing the characters it is bound in buffer * Traverse the node printing the characters it is bound in buffer
*/ */
private int private int
node_enum(EditLine *el, key_node_t *ptr, int cnt) node_enum(EditLine *el, keymacro_node_t *ptr, size_t cnt)
{ {
int ncnt; ssize_t used;
if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */ if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */
el->el_key.buf[++cnt] = '"'; el->el_keymacro.buf[++cnt] = '"';
el->el_key.buf[++cnt] = '\0'; el->el_keymacro.buf[++cnt] = '\0';
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"Some extended keys too long for internal print buffer"); "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",
return (0); el->el_keymacro.buf);
return 0;
} }
if (ptr == NULL) { if (ptr == NULL) {
#ifdef DEBUG_EDIT #ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"node_enum: BUG!! Null ptr passed\n!"); "node_enum: BUG!! Null ptr passed\n!");
#endif #endif
return (-1); return -1;
} }
/* put this char at end of str */ /* put this char at end of str */
ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt, used = ct_visual_char(el->el_keymacro.buf + cnt, KEY_BUFSIZ - cnt,
(unsigned char)ptr->ch); ptr->ch);
if (ptr->next == NULL) { if (ptr->next == NULL) {
/* print this key and function */ /* print this key and function */
el->el_key.buf[ncnt + 1] = '"'; el->el_keymacro.buf[cnt + (size_t)used ] = '"';
el->el_key.buf[ncnt + 2] = '\0'; el->el_keymacro.buf[cnt + (size_t)used + 1] = '\0';
key_kprint(el, el->el_key.buf, &ptr->val, ptr->type); keymacro_kprint(el, el->el_keymacro.buf, &ptr->val, ptr->type);
} else } else
(void) node_enum(el, ptr->next, ncnt + 1); (void) node_enum(el, ptr->next, cnt + (size_t)used);
/* go to sibling if there is one */ /* go to sibling if there is one */
if (ptr->sibling) if (ptr->sibling)
(void) node_enum(el, ptr->sibling, cnt); (void) node_enum(el, ptr->sibling, cnt);
return (0); return 0;
} }
/* key_kprint(): /* keymacro_kprint():
* Print the specified key and its associated * Print the specified key and its associated
* function specified by val * function specified by val
*/ */
protected void protected void
key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype) keymacro_kprint(EditLine *el, const Char *key, keymacro_value_t *val, int ntype)
{ {
el_bindings_t *fp; el_bindings_t *fp;
char unparsbuf[EL_BUFSIZ]; char unparsbuf[EL_BUFSIZ];
static const char fmt[] = "%-15s-> %s\n"; static const char fmt[] = "%-15s-> %s\n";
mbstate_t state;
memset(&state, 0, sizeof(mbstate_t));
if (val != NULL) if (val != NULL)
switch (ntype) { switch (ntype) {
case XK_STR: case XK_STR:
case XK_EXE: case XK_EXE:
(void) key__decode_str(val->str, unparsbuf, (void) keymacro__decode_str(val->str, unparsbuf,
sizeof(unparsbuf), sizeof(unparsbuf),
ntype == XK_STR ? "\"\"" : "[]"); 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; break;
case XK_CMD: case XK_CMD:
for (fp = el->el_map.help; fp->name; fp++) for (fp = el->el_map.help; fp->name; fp++)
if (val->cmd == fp->func) { if (val->cmd == fp->func) {
memset(&state, 0, sizeof(mbstate_t));
wcsrtombs(unparsbuf, (const wchar_t **) &fp->name,
sizeof(unparsbuf), &state);
unparsbuf[sizeof(unparsbuf) -1] = '\0';
(void) fprintf(el->el_outfile, fmt, (void) fprintf(el->el_outfile, fmt,
key, fp->name); ct_encode_string(key, &el->el_scratch), unparsbuf);
break; break;
} }
#ifdef DEBUG_KEY #ifdef DEBUG_KEY
@ -605,7 +623,8 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
break; break;
} }
else 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");
} }
@ -614,53 +633,17 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
*b++ = c; \ *b++ = c; \
else \ else \
b++ b++
/* key__decode_char(): /* keymacro__decode_str():
* 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 == ' ' || (el_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 * Make a printable version of the ey
*/ */
protected int protected size_t
key__decode_str(const char *str, char *buf, int len, const char *sep) keymacro__decode_str(const Char *str, char *buf, size_t len, const char *sep)
{ {
char *b = buf, *eb = b + len; char *b = buf, *eb = b + len;
const char *p; const Char *p;
mbstate_t state;
memset(&state, 0, sizeof(mbstate_t));
b = buf; b = buf;
if (sep[0] != '\0') { if (sep[0] != '\0') {
ADDC(sep[0]); ADDC(sep[0]);
@ -668,38 +651,27 @@ key__decode_str(const char *str, char *buf, int len, const char *sep)
if (*str == '\0') { if (*str == '\0') {
ADDC('^'); ADDC('^');
ADDC('@'); ADDC('@');
if (sep[0] != '\0' && sep[1] != '\0') { goto add_endsep;
ADDC(sep[1]);
}
goto done;
} }
for (p = str; *p != 0; p++) { for (p = str; *p != 0; p++) {
if (iscntrl((unsigned char) *p)) { Char dbuf[VISUAL_WIDTH_MAX];
ADDC('^'); Char *p2 = dbuf;
if (*p == '\177') { ssize_t l = ct_visual_char(dbuf, VISUAL_WIDTH_MAX, *p);
ADDC('?'); while (l-- > 0) {
} else { ssize_t n = ct_encode_char(b, (size_t)(eb - b), *p2++,
ADDC(*p | 0100); &state);
} if (n == -1) /* ran out of space */
} else if (*p == '^' || *p == '\\') { goto add_endsep;
ADDC('\\'); else
ADDC(*p); b += n;
} else if (*p == ' ' || (el_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');
} }
} }
add_endsep:
if (sep[0] != '\0' && sep[1] != '\0') { if (sep[0] != '\0' && sep[1] != '\0') {
ADDC(sep[1]); ADDC(sep[1]);
} }
done:
ADDC('\0'); ADDC('\0');
if (b - buf >= len) if ((size_t)(b - buf) >= len)
buf[len - 1] = '\0'; buf[len - 1] = '\0';
return b - buf; return (size_t)(b - buf);
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: key.h,v 1.10 2006/03/23 20:22:51 christos Exp $ */ /* $NetBSD: keymacro.h,v 1.2 2011/07/28 03:44:36 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -35,47 +35,42 @@
*/ */
/* /*
* el.key.h: Key macro header * el.keymacro.h: Key macro header
*/ */
#ifndef _h_el_key #ifndef _h_el_keymacro
#define _h_el_key #define _h_el_keymacro
typedef union key_value_t { typedef union keymacro_value_t {
el_action_t cmd; /* If it is a command the # */ 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; } keymacro_value_t;
typedef struct key_node_t key_node_t; typedef struct keymacro_node_t keymacro_node_t;
typedef struct el_key_t { typedef struct el_keymacromacro_t {
char *buf; /* Key print buffer */ Char *buf; /* Key print buffer */
key_node_t *map; /* Key map */ keymacro_node_t *map; /* Key map */
key_value_t val; /* Local conversion buffer */ keymacro_value_t val; /* Local conversion buffer */
} el_key_t; } el_keymacro_t;
#define XK_CMD 0 #define XK_CMD 0
#define XK_STR 1 #define XK_STR 1
#define XK_NOD 2 #define XK_NOD 2
#define XK_EXE 3 #define XK_EXE 3
#undef key_end protected int keymacro_init(EditLine *);
#undef key_clear protected void keymacro_end(EditLine *);
#undef key_print protected keymacro_value_t *keymacro_map_cmd(EditLine *, int);
protected keymacro_value_t *keymacro_map_str(EditLine *, Char *);
protected int key_init(EditLine *); protected void keymacro_reset(EditLine *);
protected void key_end(EditLine *); protected int keymacro_get(EditLine *, Char *, keymacro_value_t *);
protected key_value_t *key_map_cmd(EditLine *, int); protected void keymacro_add(EditLine *, const Char *, keymacro_value_t *, int);
protected key_value_t *key_map_str(EditLine *, char *); protected void keymacro_clear(EditLine *, el_action_t *, const Char *);
protected void key_reset(EditLine *); protected int keymacro_delete(EditLine *, const Char *);
protected int key_get(EditLine *, char *, key_value_t *); protected void keymacro_print(EditLine *, const Char *);
protected void key_add(EditLine *, const char *, key_value_t *, int); protected void keymacro_kprint(EditLine *, const Char *, keymacro_value_t *,
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); int);
protected int key__decode_str(const char *, char *, int, protected size_t keymacro__decode_str(const Char *, char *, size_t,
const char *); const char *);
protected int key__decode_char(char *, int, int, int);
#endif /* _h_el_key */ #endif /* _h_el_keymacro */

View File

@ -1,5 +1,5 @@
#!/bin/sh - #!/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 # Copyright (c) 1992, 1993
# The Regents of the University of California. All rights reserved. # The Regents of the University of California. All rights reserved.
@ -36,7 +36,7 @@
# makelist.sh: Automatically generate header files... # makelist.sh: Automatically generate header files...
AWK=@AWK@ 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" ] if [ "x$1" = "x" ]
then then
@ -53,6 +53,14 @@ case $FLAG in
# generate foo.h file from foo.c # generate foo.h file from foo.c
# #
-n)
cat << _EOF
#undef WIDECHAR
#define NARROWCHAR
#include "${FILES}"
_EOF
;;
-h) -h)
set - `echo $FILES | sed -e 's/\\./_/g'` set - `echo $FILES | sed -e 's/\\./_/g'`
hdr="_h_`basename $1`" hdr="_h_`basename $1`"
@ -70,7 +78,7 @@ case $FLAG in
# XXX: need a space between name and prototype so that -fc and -fh # XXX: need a space between name and prototype so that -fc and -fh
# parsing is much easier # 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 { END {
@ -85,6 +93,7 @@ case $FLAG in
BEGIN { BEGIN {
printf("/* Automatically generated file, do not edit */\n"); printf("/* Automatically generated file, do not edit */\n");
printf("#include \"config.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"); printf("private const struct el_bindings_t el_func_help[] = {\n");
low = "abcdefghijklmnopqrstuvwxyz_"; low = "abcdefghijklmnopqrstuvwxyz_";
high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"; high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_";
@ -106,18 +115,18 @@ case $FLAG in
fname = fname s; fname = fname s;
} }
printf(" { %-30.30s %-30.30s\n","\"" fname "\",", uname ","); printf(" { %-30.30s %-30.30s\n","STR(\"" fname "\"),", uname ",");
ok = 1; ok = 1;
} }
} }
/^ \*/ { /^ \*/ {
if (ok) { if (ok) {
printf(" \""); printf(" STR(\"");
for (i = 2; i < NF; i++) for (i = 2; i < NF; i++)
printf("%s ", $i); printf("%s ", $i);
# XXXMYSQL: support CRLF # XXXMYSQL: support CRLF
sub("\r", "", $i); sub("\r", "", $i);
printf("%s\" },\n", $i); printf("%s\") },\n", $i);
ok = 0; ok = 0;
} }
} }
@ -157,7 +166,7 @@ case $FLAG in
END { END {
printf("#define\t%-30.30s\t%3d\n", "EL_NUM_FCNS", count); 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("\nprotected const el_func_t* func__get(void);\n");
printf("#endif /* _h_fcns_c */\n"); printf("#endif /* _h_fcns_c */\n");
}' }'

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.30 2011/08/16 16:25:15 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -46,10 +46,8 @@ static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
#include <stdlib.h> #include <stdlib.h>
#include "el.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_print_all_keys(EditLine *);
private void map_init_nls(EditLine *); private void map_init_nls(EditLine *);
private void map_init_meta(EditLine *); private void map_init_meta(EditLine *);
@ -904,26 +902,25 @@ map_init(EditLine *el)
EL_ABORT((el->errfile, "Vi insert map incorrect\n")); EL_ABORT((el->errfile, "Vi insert map incorrect\n"));
#endif #endif
el->el_map.alt = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS); el->el_map.alt = el_malloc(sizeof(*el->el_map.alt) * N_KEYS);
if (el->el_map.alt == NULL) if (el->el_map.alt == NULL)
return (-1); return -1;
el->el_map.key = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS); el->el_map.key = el_malloc(sizeof(*el->el_map.key) * N_KEYS);
if (el->el_map.key == NULL) if (el->el_map.key == NULL)
return (-1); return -1;
el->el_map.emacs = el_map_emacs; el->el_map.emacs = el_map_emacs;
el->el_map.vic = el_map_vi_command; el->el_map.vic = el_map_vi_command;
el->el_map.vii = el_map_vi_insert; el->el_map.vii = el_map_vi_insert;
el->el_map.help = (el_bindings_t *) el_malloc(sizeof(el_bindings_t) * el->el_map.help = el_malloc(sizeof(*el->el_map.help) * EL_NUM_FCNS);
EL_NUM_FCNS);
if (el->el_map.help == NULL) if (el->el_map.help == NULL)
return (-1); return -1;
(void) memcpy(el->el_map.help, help__get(), (void) memcpy(el->el_map.help, help__get(),
sizeof(el_bindings_t) * EL_NUM_FCNS); sizeof(*el->el_map.help) * EL_NUM_FCNS);
el->el_map.func = (el_func_t *)el_malloc(sizeof(el_func_t) * el->el_map.func = el_malloc(sizeof(*el->el_map.func) * EL_NUM_FCNS);
EL_NUM_FCNS);
if (el->el_map.func == NULL) if (el->el_map.func == NULL)
return (-1); return -1;
memcpy(el->el_map.func, func__get(), sizeof(el_func_t) * EL_NUM_FCNS); memcpy(el->el_map.func, func__get(), sizeof(*el->el_map.func)
* EL_NUM_FCNS);
el->el_map.nfunc = EL_NUM_FCNS; el->el_map.nfunc = EL_NUM_FCNS;
#ifdef VIDEFAULT #ifdef VIDEFAULT
@ -931,7 +928,7 @@ map_init(EditLine *el)
#else #else
map_init_emacs(el); map_init_emacs(el);
#endif /* VIDEFAULT */ #endif /* VIDEFAULT */
return (0); return 0;
} }
@ -942,16 +939,16 @@ protected void
map_end(EditLine *el) map_end(EditLine *el)
{ {
el_free((ptr_t) el->el_map.alt); el_free(el->el_map.alt);
el->el_map.alt = NULL; el->el_map.alt = NULL;
el_free((ptr_t) el->el_map.key); el_free(el->el_map.key);
el->el_map.key = NULL; el->el_map.key = NULL;
el->el_map.emacs = NULL; el->el_map.emacs = NULL;
el->el_map.vic = NULL; el->el_map.vic = NULL;
el->el_map.vii = NULL; el->el_map.vii = NULL;
el_free((ptr_t) el->el_map.help); el_free(el->el_map.help);
el->el_map.help = NULL; el->el_map.help = NULL;
el_free((ptr_t) el->el_map.func); el_free(el->el_map.func);
el->el_map.func = NULL; el->el_map.func = NULL;
} }
@ -967,7 +964,7 @@ map_init_nls(EditLine *el)
el_action_t *map = el->el_map.key; el_action_t *map = el->el_map.key;
for (i = 0200; i <= 0377; i++) for (i = 0200; i <= 0377; i++)
if (el_isprint(i)) if (Isprint(i))
map[i] = ED_INSERT; map[i] = ED_INSERT;
} }
@ -978,7 +975,7 @@ map_init_nls(EditLine *el)
private void private void
map_init_meta(EditLine *el) map_init_meta(EditLine *el)
{ {
char buf[3]; Char buf[3];
int i; int i;
el_action_t *map = el->el_map.key; el_action_t *map = el->el_map.key;
el_action_t *alt = el->el_map.alt; el_action_t *alt = el->el_map.alt;
@ -996,7 +993,7 @@ map_init_meta(EditLine *el)
} else } else
map = alt; map = alt;
} }
buf[0] = (char) i; buf[0] = (Char) i;
buf[2] = 0; buf[2] = 0;
for (i = 0200; i <= 0377; i++) for (i = 0200; i <= 0377; i++)
switch (map[i]) { switch (map[i]) {
@ -1006,7 +1003,7 @@ map_init_meta(EditLine *el)
break; break;
default: default:
buf[1] = i & 0177; buf[1] = i & 0177;
key_add(el, buf, key_map_cmd(el, (int) map[i]), XK_CMD); keymacro_add(el, buf, keymacro_map_cmd(el, (int) map[i]), XK_CMD);
break; break;
} }
map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN; map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN;
@ -1028,7 +1025,7 @@ map_init_vi(EditLine *el)
el->el_map.type = MAP_VI; el->el_map.type = MAP_VI;
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
key_reset(el); keymacro_reset(el);
for (i = 0; i < N_KEYS; i++) { for (i = 0; i < N_KEYS; i++) {
key[i] = vii[i]; key[i] = vii[i];
@ -1039,7 +1036,7 @@ map_init_vi(EditLine *el)
map_init_nls(el); map_init_nls(el);
tty_bind_char(el, 1); tty_bind_char(el, 1);
term_bind_arrow(el); terminal_bind_arrow(el);
} }
@ -1050,14 +1047,14 @@ protected void
map_init_emacs(EditLine *el) map_init_emacs(EditLine *el)
{ {
int i; int i;
char buf[3]; Char buf[3];
el_action_t *key = el->el_map.key; el_action_t *key = el->el_map.key;
el_action_t *alt = el->el_map.alt; el_action_t *alt = el->el_map.alt;
const el_action_t *emacs = el->el_map.emacs; const el_action_t *emacs = el->el_map.emacs;
el->el_map.type = MAP_EMACS; el->el_map.type = MAP_EMACS;
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
key_reset(el); keymacro_reset(el);
for (i = 0; i < N_KEYS; i++) { for (i = 0; i < N_KEYS; i++) {
key[i] = emacs[i]; key[i] = emacs[i];
@ -1070,10 +1067,10 @@ map_init_emacs(EditLine *el)
buf[0] = CONTROL('X'); buf[0] = CONTROL('X');
buf[1] = CONTROL('X'); buf[1] = CONTROL('X');
buf[2] = 0; buf[2] = 0;
key_add(el, buf, key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD); keymacro_add(el, buf, keymacro_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD);
tty_bind_char(el, 1); tty_bind_char(el, 1);
term_bind_arrow(el); terminal_bind_arrow(el);
} }
@ -1081,18 +1078,18 @@ map_init_emacs(EditLine *el)
* Set the editor * Set the editor
*/ */
protected int 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); map_init_emacs(el);
return (0); return 0;
} }
if (strcmp(editor, "vi") == 0) { if (Strcmp(editor, STR("vi")) == 0) {
map_init_vi(el); map_init_vi(el);
return (0); return 0;
} }
return (-1); return -1;
} }
@ -1100,20 +1097,20 @@ map_set_editor(EditLine *el, char *editor)
* Retrieve the editor * Retrieve the editor
*/ */
protected int protected int
map_get_editor(EditLine *el, const char **editor) map_get_editor(EditLine *el, const Char **editor)
{ {
if (editor == NULL) if (editor == NULL)
return (-1); return -1;
switch (el->el_map.type) { switch (el->el_map.type) {
case MAP_EMACS: case MAP_EMACS:
*editor = "emacs"; *editor = STR("emacs");
return (0); return 0;
case MAP_VI: case MAP_VI:
*editor = "vi"; *editor = STR("vi");
return (0); return 0;
} }
return (-1); return -1;
} }
@ -1121,22 +1118,22 @@ map_get_editor(EditLine *el, const char **editor)
* Print the function description for 1 key * Print the function description for 1 key
*/ */
private void private void
map_print_key(EditLine *el, el_action_t *map, const char *in) map_print_key(EditLine *el, el_action_t *map, const Char *in)
{ {
char outbuf[EL_BUFSIZ]; char outbuf[EL_BUFSIZ];
el_bindings_t *bp, *ep; el_bindings_t *bp, *ep;
if (in[0] == '\0' || in[1] == '\0') { if (in[0] == '\0' || in[1] == '\0') {
(void) key__decode_str(in, outbuf, sizeof(outbuf), ""); (void) keymacro__decode_str(in, outbuf, sizeof(outbuf), "");
ep = &el->el_map.help[el->el_map.nfunc]; ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++) for (bp = el->el_map.help; bp < ep; bp++)
if (bp->func == map[(unsigned char) *in]) { if (bp->func == map[(unsigned char) *in]) {
(void) fprintf(el->el_outfile, (void) fprintf(el->el_outfile,
"%s\t->\t%s\n", outbuf, bp->name); "%s\t->\t" FSTR "\n", outbuf, bp->name);
return; return;
} }
} else } else
key_print(el, in); keymacro_print(el, in);
} }
@ -1144,10 +1141,10 @@ map_print_key(EditLine *el, el_action_t *map, const char *in)
* Print keys from first to last * Print keys from first to last
*/ */
private void 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; el_bindings_t *bp, *ep;
char firstbuf[2], lastbuf[2]; Char firstbuf[2], lastbuf[2];
char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ]; char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ];
firstbuf[0] = first; firstbuf[0] = first;
@ -1156,7 +1153,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
lastbuf[1] = 0; lastbuf[1] = 0;
if (map[first] == ED_UNASSIGNED) { if (map[first] == ED_UNASSIGNED) {
if (first == last) { if (first == last) {
(void) key__decode_str(firstbuf, unparsbuf, (void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ); sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile, (void) fprintf(el->el_outfile,
"%-15s-> is undefined\n", unparsbuf); "%-15s-> is undefined\n", unparsbuf);
@ -1167,17 +1164,17 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
for (bp = el->el_map.help; bp < ep; bp++) { for (bp = el->el_map.help; bp < ep; bp++) {
if (bp->func == map[first]) { if (bp->func == map[first]) {
if (first == last) { if (first == last) {
(void) key__decode_str(firstbuf, unparsbuf, (void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ); sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile, "%-15s-> %s\n", (void) fprintf(el->el_outfile, "%-15s-> " FSTR "\n",
unparsbuf, bp->name); unparsbuf, bp->name);
} else { } else {
(void) key__decode_str(firstbuf, unparsbuf, (void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ); sizeof(unparsbuf), STRQQ);
(void) key__decode_str(lastbuf, extrabuf, (void) keymacro__decode_str(lastbuf, extrabuf,
sizeof(extrabuf), STRQQ); sizeof(extrabuf), STRQQ);
(void) fprintf(el->el_outfile, (void) fprintf(el->el_outfile,
"%-4s to %-7s-> %s\n", "%-4s to %-7s-> " FSTR "\n",
unparsbuf, extrabuf, bp->name); unparsbuf, extrabuf, bp->name);
} }
return; return;
@ -1185,14 +1182,14 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
} }
#ifdef MAP_DEBUG #ifdef MAP_DEBUG
if (map == el->el_map.key) { if (map == el->el_map.key) {
(void) key__decode_str(firstbuf, unparsbuf, (void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ); sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile, (void) fprintf(el->el_outfile,
"BUG!!! %s isn't bound to anything.\n", unparsbuf); "BUG!!! %s isn't bound to anything.\n", unparsbuf);
(void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n", (void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n",
first, el->el_map.key[first]); first, el->el_map.key[first]);
} else { } else {
(void) key__decode_str(firstbuf, unparsbuf, (void) keymacro__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ); sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile, (void) fprintf(el->el_outfile,
"BUG!!! %s isn't bound to anything.\n", unparsbuf); "BUG!!! %s isn't bound to anything.\n", unparsbuf);
@ -1233,9 +1230,9 @@ map_print_all_keys(EditLine *el)
map_print_some_keys(el, el->el_map.alt, prev, i - 1); map_print_some_keys(el, el->el_map.alt, prev, i - 1);
(void) fprintf(el->el_outfile, "Multi-character bindings\n"); (void) fprintf(el->el_outfile, "Multi-character bindings\n");
key_print(el, ""); keymacro_print(el, STR(""));
(void) fprintf(el->el_outfile, "Arrow key bindings\n"); (void) fprintf(el->el_outfile, "Arrow key bindings\n");
term_print_arrow(el, ""); terminal_print_arrow(el, STR(""));
} }
@ -1243,21 +1240,21 @@ map_print_all_keys(EditLine *el)
* Add/remove/change bindings * Add/remove/change bindings
*/ */
protected int protected int
map_bind(EditLine *el, int argc, const char **argv) map_bind(EditLine *el, int argc, const Char **argv)
{ {
el_action_t *map; el_action_t *map;
int ntype, rem; int ntype, rem;
const char *p; const Char *p;
char inbuf[EL_BUFSIZ]; Char inbuf[EL_BUFSIZ];
char outbuf[EL_BUFSIZ]; Char outbuf[EL_BUFSIZ];
const char *in = NULL; const Char *in = NULL;
char *out = NULL; Char *out = NULL;
el_bindings_t *bp, *ep; el_bindings_t *bp, *ep;
int cmd; int cmd;
int key; int key;
if (argv == NULL) if (argv == NULL)
return (-1); return -1;
map = el->el_map.key; map = el->el_map.key;
ntype = XK_CMD; ntype = XK_CMD;
@ -1287,22 +1284,22 @@ map_bind(EditLine *el, int argc, const char **argv)
case 'v': case 'v':
map_init_vi(el); map_init_vi(el);
return (0); return 0;
case 'e': case 'e':
map_init_emacs(el); map_init_emacs(el);
return (0); return 0;
case 'l': case 'l':
ep = &el->el_map.help[el->el_map.nfunc]; ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++) for (bp = el->el_map.help; bp < ep; bp++)
(void) fprintf(el->el_outfile, (void) fprintf(el->el_outfile,
"%s\n\t%s\n", "" FSTR "\n\t" FSTR "\n",
bp->name, bp->description); bp->name, bp->description);
return (0); return 0;
default: default:
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"%s: Invalid switch `%c'.\n", "" FSTR ": Invalid switch `%c'.\n",
argv[0], p[1]); argv[0], p[1]);
} }
else else
@ -1310,40 +1307,40 @@ map_bind(EditLine *el, int argc, const char **argv)
if (argv[argc] == NULL) { if (argv[argc] == NULL) {
map_print_all_keys(el); map_print_all_keys(el);
return (0); return 0;
} }
if (key) if (key)
in = argv[argc++]; in = argv[argc++];
else if ((in = parse__string(inbuf, argv[argc++])) == NULL) { else if ((in = parse__string(inbuf, argv[argc++])) == NULL) {
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"%s: Invalid \\ or ^ in instring.\n", "" FSTR ": Invalid \\ or ^ in instring.\n",
argv[0]); argv[0]);
return (-1); return -1;
} }
if (rem) { if (rem) {
if (key) { if (key) {
(void) term_clear_arrow(el, in); (void) terminal_clear_arrow(el, in);
return (-1); return -1;
} }
if (in[1]) if (in[1])
(void) key_delete(el, in); (void) keymacro_delete(el, in);
else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN) else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN)
(void) key_delete(el, in); (void) keymacro_delete(el, in);
else else
map[(unsigned char) *in] = ED_UNASSIGNED; map[(unsigned char) *in] = ED_UNASSIGNED;
return (0); return 0;
} }
if (argv[argc] == NULL) { if (argv[argc] == NULL) {
if (key) if (key)
term_print_arrow(el, in); terminal_print_arrow(el, in);
else else
map_print_key(el, map, in); map_print_key(el, map, in);
return (0); return 0;
} }
#ifdef notyet #ifdef notyet
if (argv[argc + 1] != NULL) { if (argv[argc + 1] != NULL) {
bindkey_usage(); bindkeymacro_usage();
return (-1); return -1;
} }
#endif #endif
@ -1352,31 +1349,32 @@ map_bind(EditLine *el, int argc, const char **argv)
case XK_EXE: case XK_EXE:
if ((out = parse__string(outbuf, argv[argc])) == NULL) { if ((out = parse__string(outbuf, argv[argc])) == NULL) {
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"%s: Invalid \\ or ^ in outstring.\n", argv[0]); "" FSTR ": Invalid \\ or ^ in outstring.\n", argv[0]);
return (-1); return -1;
} }
if (key) if (key)
term_set_arrow(el, in, key_map_str(el, out), ntype); terminal_set_arrow(el, in, keymacro_map_str(el, out), ntype);
else else
key_add(el, in, key_map_str(el, out), ntype); keymacro_add(el, in, keymacro_map_str(el, out), ntype);
map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN; map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
break; break;
case XK_CMD: case XK_CMD:
if ((cmd = parse_cmd(el, argv[argc])) == -1) { if ((cmd = parse_cmd(el, argv[argc])) == -1) {
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"%s: Invalid command `%s'.\n", argv[0], argv[argc]); "" FSTR ": Invalid command `" FSTR "'.\n",
return (-1); argv[0], argv[argc]);
return -1;
} }
if (key) if (key)
term_set_arrow(el, in, key_map_str(el, out), ntype); terminal_set_arrow(el, in, keymacro_map_str(el, out), ntype);
else { else {
if (in[1]) { if (in[1]) {
key_add(el, in, key_map_cmd(el, cmd), ntype); keymacro_add(el, in, keymacro_map_cmd(el, cmd), ntype);
map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN; map[(unsigned char) *in] = ED_SEQUENCE_LEAD_IN;
} else { } else {
key_clear(el, map, in); keymacro_clear(el, map, in);
map[(unsigned char) *in] = cmd; map[(unsigned char) *in] = (el_action_t)cmd;
} }
} }
break; break;
@ -1385,7 +1383,7 @@ map_bind(EditLine *el, int argc, const char **argv)
EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
break; break;
} }
return (0); return 0;
} }
@ -1393,29 +1391,30 @@ map_bind(EditLine *el, int argc, const char **argv)
* add a user defined function * add a user defined function
*/ */
protected int 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; void *p;
int nf = el->el_map.nfunc + 1; size_t nf = (size_t)el->el_map.nfunc + 1;
if (name == NULL || help == NULL || func == NULL) if (name == NULL || help == NULL || func == NULL)
return (-1); return -1;
if ((p = el_realloc(el->el_map.func, nf * sizeof(el_func_t))) == NULL) if ((p = el_realloc(el->el_map.func, nf *
return (-1); sizeof(*el->el_map.func))) == NULL)
el->el_map.func = (el_func_t *) p; return -1;
if ((p = el_realloc(el->el_map.help, nf * sizeof(el_bindings_t))) el->el_map.func = p;
if ((p = el_realloc(el->el_map.help, nf * sizeof(*el->el_map.help)))
== NULL) == NULL)
return (-1); return -1;
el->el_map.help = (el_bindings_t *) p; el->el_map.help = p;
nf = el->el_map.nfunc; nf = (size_t)el->el_map.nfunc;
el->el_map.func[nf] = func; el->el_map.func[nf] = func;
el->el_map.help[nf].name = name; el->el_map.help[nf].name = name;
el->el_map.help[nf].func = nf; el->el_map.help[nf].func = (int)nf;
el->el_map.help[nf].description = help; el->el_map.help[nf].description = help;
el->el_map.nfunc++; el->el_map.nfunc++;
return (0); return 0;
} }

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 * Copyright (c) 1992, 1993
@ -41,9 +41,9 @@
#define _h_el_map #define _h_el_map
typedef struct el_bindings_t { /* for the "bind" shell command */ 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 */ int func; /* function numeric value */
const char *description; /* description of function */ const Char *description; /* description of function */
} el_bindings_t; } el_bindings_t;
@ -63,13 +63,15 @@ typedef struct el_map_t {
#define MAP_EMACS 0 #define MAP_EMACS 0
#define MAP_VI 1 #define MAP_VI 1
protected int map_bind(EditLine *, int, const char **); #define N_KEYS 256
protected int map_bind(EditLine *, int, const Char **);
protected int map_init(EditLine *); protected int map_init(EditLine *);
protected void map_end(EditLine *); protected void map_end(EditLine *);
protected void map_init_vi(EditLine *); protected void map_init_vi(EditLine *);
protected void map_init_emacs(EditLine *); protected void map_init_emacs(EditLine *);
protected int map_set_editor(EditLine *, char *); protected int map_set_editor(EditLine *, Char *);
protected int map_get_editor(EditLine *, const char **); protected int map_get_editor(EditLine *, const Char **);
protected int map_addfunc(EditLine *, const char *, const char *, el_func_t); protected int map_addfunc(EditLine *, const Char *, const Char *, el_func_t);
#endif /* _h_el_map */ #endif /* _h_el_map */

View File

@ -24,6 +24,7 @@
#include "config.h" #include "config.h"
#endif #endif
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */

View File

@ -23,6 +23,8 @@
#else #else
#include "config.h" #include "config.h"
#endif #endif
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */

View File

@ -1,4 +1,4 @@
/* $NetBSD: unvis.c,v 1.28 2005/09/13 01:44:09 christos Exp $ */ /* $NetBSD: unvis.c,v 1.36 2011/03/18 09:07:20 martin Exp $ */
/*- /*-
* Copyright (c) 1989, 1993 * Copyright (c) 1989, 1993
@ -31,6 +31,7 @@
#include "config.h" #include "config.h"
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
#if 0 #if 0
static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93";
@ -38,11 +39,18 @@ static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93";
#endif #endif
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
/* XXXMYSQL : Make compiler happy. */
#ifdef _LIBC
#include "namespace.h"
#endif
#include <sys/types.h> #include <sys/types.h>
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <stdint.h>
#include <stdio.h> #include <stdio.h>
#include <errno.h>
#ifdef HAVE_VIS_H #ifdef HAVE_VIS_H
#include <vis.h> #include <vis.h>
#else #else
@ -50,7 +58,7 @@ static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93";
#endif #endif
#ifdef __weak_alias #ifdef __weak_alias
__weak_alias(strunvis,_strunvis) __weak_alias(strnunvisx,_strnunvisx)
#endif #endif
#if !HAVE_VIS #if !HAVE_VIS
@ -64,143 +72,276 @@ __weak_alias(strunvis,_strunvis)
#define S_CTRL 4 /* control char started (^) */ #define S_CTRL 4 /* control char started (^) */
#define S_OCTAL2 5 /* octal digit 2 */ #define S_OCTAL2 5 /* octal digit 2 */
#define S_OCTAL3 6 /* octal digit 3 */ #define S_OCTAL3 6 /* octal digit 3 */
#define S_HEX1 7 /* hex digit */ #define S_HEX1 7 /* http hex digit */
#define S_HEX2 8 /* hex digit 2 */ #define S_HEX2 8 /* http hex digit 2 */
#define S_MIME1 9 /* mime hex digit 1 */
#define S_MIME2 10 /* mime hex digit 2 */
#define S_EATCRNL 11 /* mime eating CRNL */
#define S_AMP 12 /* seen & */
#define S_NUMBER 13 /* collecting number */
#define S_STRING 14 /* collecting string */
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) #define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10))
#define XTOD(c) (isdigit(c) ? (c - '0') : ((c - 'A') + 10))
/*
* RFC 1866
*/
static const struct nv {
const char *name;
uint8_t value;
} nv[] = {
{ "AElig", 198 }, /* capital AE diphthong (ligature) */
{ "Aacute", 193 }, /* capital A, acute accent */
{ "Acirc", 194 }, /* capital A, circumflex accent */
{ "Agrave", 192 }, /* capital A, grave accent */
{ "Aring", 197 }, /* capital A, ring */
{ "Atilde", 195 }, /* capital A, tilde */
{ "Auml", 196 }, /* capital A, dieresis or umlaut mark */
{ "Ccedil", 199 }, /* capital C, cedilla */
{ "ETH", 208 }, /* capital Eth, Icelandic */
{ "Eacute", 201 }, /* capital E, acute accent */
{ "Ecirc", 202 }, /* capital E, circumflex accent */
{ "Egrave", 200 }, /* capital E, grave accent */
{ "Euml", 203 }, /* capital E, dieresis or umlaut mark */
{ "Iacute", 205 }, /* capital I, acute accent */
{ "Icirc", 206 }, /* capital I, circumflex accent */
{ "Igrave", 204 }, /* capital I, grave accent */
{ "Iuml", 207 }, /* capital I, dieresis or umlaut mark */
{ "Ntilde", 209 }, /* capital N, tilde */
{ "Oacute", 211 }, /* capital O, acute accent */
{ "Ocirc", 212 }, /* capital O, circumflex accent */
{ "Ograve", 210 }, /* capital O, grave accent */
{ "Oslash", 216 }, /* capital O, slash */
{ "Otilde", 213 }, /* capital O, tilde */
{ "Ouml", 214 }, /* capital O, dieresis or umlaut mark */
{ "THORN", 222 }, /* capital THORN, Icelandic */
{ "Uacute", 218 }, /* capital U, acute accent */
{ "Ucirc", 219 }, /* capital U, circumflex accent */
{ "Ugrave", 217 }, /* capital U, grave accent */
{ "Uuml", 220 }, /* capital U, dieresis or umlaut mark */
{ "Yacute", 221 }, /* capital Y, acute accent */
{ "aacute", 225 }, /* small a, acute accent */
{ "acirc", 226 }, /* small a, circumflex accent */
{ "acute", 180 }, /* acute accent */
{ "aelig", 230 }, /* small ae diphthong (ligature) */
{ "agrave", 224 }, /* small a, grave accent */
{ "amp", 38 }, /* ampersand */
{ "aring", 229 }, /* small a, ring */
{ "atilde", 227 }, /* small a, tilde */
{ "auml", 228 }, /* small a, dieresis or umlaut mark */
{ "brvbar", 166 }, /* broken (vertical) bar */
{ "ccedil", 231 }, /* small c, cedilla */
{ "cedil", 184 }, /* cedilla */
{ "cent", 162 }, /* cent sign */
{ "copy", 169 }, /* copyright sign */
{ "curren", 164 }, /* general currency sign */
{ "deg", 176 }, /* degree sign */
{ "divide", 247 }, /* divide sign */
{ "eacute", 233 }, /* small e, acute accent */
{ "ecirc", 234 }, /* small e, circumflex accent */
{ "egrave", 232 }, /* small e, grave accent */
{ "eth", 240 }, /* small eth, Icelandic */
{ "euml", 235 }, /* small e, dieresis or umlaut mark */
{ "frac12", 189 }, /* fraction one-half */
{ "frac14", 188 }, /* fraction one-quarter */
{ "frac34", 190 }, /* fraction three-quarters */
{ "gt", 62 }, /* greater than */
{ "iacute", 237 }, /* small i, acute accent */
{ "icirc", 238 }, /* small i, circumflex accent */
{ "iexcl", 161 }, /* inverted exclamation mark */
{ "igrave", 236 }, /* small i, grave accent */
{ "iquest", 191 }, /* inverted question mark */
{ "iuml", 239 }, /* small i, dieresis or umlaut mark */
{ "laquo", 171 }, /* angle quotation mark, left */
{ "lt", 60 }, /* less than */
{ "macr", 175 }, /* macron */
{ "micro", 181 }, /* micro sign */
{ "middot", 183 }, /* middle dot */
{ "nbsp", 160 }, /* no-break space */
{ "not", 172 }, /* not sign */
{ "ntilde", 241 }, /* small n, tilde */
{ "oacute", 243 }, /* small o, acute accent */
{ "ocirc", 244 }, /* small o, circumflex accent */
{ "ograve", 242 }, /* small o, grave accent */
{ "ordf", 170 }, /* ordinal indicator, feminine */
{ "ordm", 186 }, /* ordinal indicator, masculine */
{ "oslash", 248 }, /* small o, slash */
{ "otilde", 245 }, /* small o, tilde */
{ "ouml", 246 }, /* small o, dieresis or umlaut mark */
{ "para", 182 }, /* pilcrow (paragraph sign) */
{ "plusmn", 177 }, /* plus-or-minus sign */
{ "pound", 163 }, /* pound sterling sign */
{ "quot", 34 }, /* double quote */
{ "raquo", 187 }, /* angle quotation mark, right */
{ "reg", 174 }, /* registered sign */
{ "sect", 167 }, /* section sign */
{ "shy", 173 }, /* soft hyphen */
{ "sup1", 185 }, /* superscript one */
{ "sup2", 178 }, /* superscript two */
{ "sup3", 179 }, /* superscript three */
{ "szlig", 223 }, /* small sharp s, German (sz ligature) */
{ "thorn", 254 }, /* small thorn, Icelandic */
{ "times", 215 }, /* multiply sign */
{ "uacute", 250 }, /* small u, acute accent */
{ "ucirc", 251 }, /* small u, circumflex accent */
{ "ugrave", 249 }, /* small u, grave accent */
{ "uml", 168 }, /* umlaut (dieresis) */
{ "uuml", 252 }, /* small u, dieresis or umlaut mark */
{ "yacute", 253 }, /* small y, acute accent */
{ "yen", 165 }, /* yen sign */
{ "yuml", 255 }, /* small y, dieresis or umlaut mark */
};
/* /*
* unvis - decode characters previously encoded by vis * unvis - decode characters previously encoded by vis
*/ */
int int
unvis(cp, c, astate, flag) unvis(char *cp, int c, int *astate, int flag)
char *cp;
int c;
int *astate, flag;
{ {
unsigned char uc = (unsigned char)c; unsigned char uc = (unsigned char)c;
unsigned char st, ia, is, lc;
/*
* Bottom 8 bits of astate hold the state machine state.
* Top 8 bits hold the current character in the http 1866 nv string decoding
*/
#define GS(a) ((a) & 0xff)
#define SS(a, b) (((uint32_t)(a) << 24) | (b))
#define GI(a) ((uint32_t)(a) >> 24)
_DIAGASSERT(cp != NULL); _DIAGASSERT(cp != NULL);
_DIAGASSERT(astate != NULL); _DIAGASSERT(astate != NULL);
st = GS(*astate);
if (flag & UNVIS_END) { if (flag & UNVIS_END) {
if (*astate == S_OCTAL2 || *astate == S_OCTAL3 switch (st) {
|| *astate == S_HEX2) { case S_OCTAL2:
*astate = S_GROUND; case S_OCTAL3:
return (UNVIS_VALID); case S_HEX2:
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case S_GROUND:
return UNVIS_NOCHAR;
default:
return UNVIS_SYNBAD;
} }
return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
} }
switch (*astate) { switch (st) {
case S_GROUND: case S_GROUND:
*cp = 0; *cp = 0;
if (c == '\\') { if ((flag & VIS_NOESCAPE) == 0 && c == '\\') {
*astate = S_START; *astate = SS(0, S_START);
return (0); return UNVIS_NOCHAR;
} }
if ((flag & VIS_HTTPSTYLE) && c == '%') { if ((flag & VIS_HTTP1808) && c == '%') {
*astate = S_HEX1; *astate = SS(0, S_HEX1);
return (0); return UNVIS_NOCHAR;
}
if ((flag & VIS_HTTP1866) && c == '&') {
*astate = SS(0, S_AMP);
return UNVIS_NOCHAR;
}
if ((flag & VIS_MIMESTYLE) && c == '=') {
*astate = SS(0, S_MIME1);
return UNVIS_NOCHAR;
} }
*cp = c; *cp = c;
return (UNVIS_VALID); return UNVIS_VALID;
case S_START: case S_START:
switch(c) { switch(c) {
case '\\': case '\\':
*cp = c; *cp = c;
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_VALID); return UNVIS_VALID;
case '0': case '1': case '2': case '3': case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7': case '4': case '5': case '6': case '7':
*cp = (c - '0'); *cp = (c - '0');
*astate = S_OCTAL2; *astate = SS(0, S_OCTAL2);
return (0); return UNVIS_NOCHAR;
case 'M': case 'M':
*cp = (char)0200; *cp = (char)0200;
*astate = S_META; *astate = SS(0, S_META);
return (0); return UNVIS_NOCHAR;
case '^': case '^':
*astate = S_CTRL; *astate = SS(0, S_CTRL);
return (0); return UNVIS_NOCHAR;
case 'n': case 'n':
*cp = '\n'; *cp = '\n';
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_VALID); return UNVIS_VALID;
case 'r': case 'r':
*cp = '\r'; *cp = '\r';
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_VALID); return UNVIS_VALID;
case 'b': case 'b':
*cp = '\b'; *cp = '\b';
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_VALID); return UNVIS_VALID;
case 'a': case 'a':
*cp = '\007'; *cp = '\007';
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_VALID); return UNVIS_VALID;
case 'v': case 'v':
*cp = '\v'; *cp = '\v';
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_VALID); return UNVIS_VALID;
case 't': case 't':
*cp = '\t'; *cp = '\t';
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_VALID); return UNVIS_VALID;
case 'f': case 'f':
*cp = '\f'; *cp = '\f';
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_VALID); return UNVIS_VALID;
case 's': case 's':
*cp = ' '; *cp = ' ';
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_VALID); return UNVIS_VALID;
case 'E': case 'E':
*cp = '\033'; *cp = '\033';
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_VALID); return UNVIS_VALID;
case '\n': case '\n':
/* /*
* hidden newline * hidden newline
*/ */
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_NOCHAR); return UNVIS_NOCHAR;
case '$': case '$':
/* /*
* hidden marker * hidden marker
*/ */
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_NOCHAR); return UNVIS_NOCHAR;
} }
*astate = S_GROUND; goto bad;
return (UNVIS_SYNBAD);
case S_META: case S_META:
if (c == '-') if (c == '-')
*astate = S_META1; *astate = SS(0, S_META1);
else if (c == '^') else if (c == '^')
*astate = S_CTRL; *astate = SS(0, S_CTRL);
else { else
*astate = S_GROUND; goto bad;
return (UNVIS_SYNBAD); return UNVIS_NOCHAR;
}
return (0);
case S_META1: case S_META1:
*astate = S_GROUND; *astate = SS(0, S_GROUND);
*cp |= c; *cp |= c;
return (UNVIS_VALID); return UNVIS_VALID;
case S_CTRL: case S_CTRL:
if (c == '?') if (c == '?')
*cp |= 0177; *cp |= 0177;
else else
*cp |= c & 037; *cp |= c & 037;
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_VALID); return UNVIS_VALID;
case S_OCTAL2: /* second possible octal digit */ case S_OCTAL2: /* second possible octal digit */
if (isoctal(uc)) { if (isoctal(uc)) {
@ -208,102 +349,206 @@ unvis(cp, c, astate, flag)
* yes - and maybe a third * yes - and maybe a third
*/ */
*cp = (*cp << 3) + (c - '0'); *cp = (*cp << 3) + (c - '0');
*astate = S_OCTAL3; *astate = SS(0, S_OCTAL3);
return (0); return UNVIS_NOCHAR;
} }
/* /*
* no - done with current sequence, push back passed char * no - done with current sequence, push back passed char
*/ */
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_VALIDPUSH); return UNVIS_VALIDPUSH;
case S_OCTAL3: /* third possible octal digit */ case S_OCTAL3: /* third possible octal digit */
*astate = S_GROUND; *astate = SS(0, S_GROUND);
if (isoctal(uc)) { if (isoctal(uc)) {
*cp = (*cp << 3) + (c - '0'); *cp = (*cp << 3) + (c - '0');
return (UNVIS_VALID); return UNVIS_VALID;
} }
/* /*
* we were done, push back passed char * we were done, push back passed char
*/ */
return (UNVIS_VALIDPUSH); return UNVIS_VALIDPUSH;
case S_HEX1: case S_HEX1:
if (isxdigit(uc)) { if (isxdigit(uc)) {
*cp = xtod(uc); *cp = xtod(uc);
*astate = S_HEX2; *astate = SS(0, S_HEX2);
return (0); return UNVIS_NOCHAR;
} }
/* /*
* no - done with current sequence, push back passed char * no - done with current sequence, push back passed char
*/ */
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_VALIDPUSH); return UNVIS_VALIDPUSH;
case S_HEX2: case S_HEX2:
*astate = S_GROUND; *astate = S_GROUND;
if (isxdigit(uc)) { if (isxdigit(uc)) {
*cp = xtod(uc) | (*cp << 4); *cp = xtod(uc) | (*cp << 4);
return (UNVIS_VALID); return UNVIS_VALID;
} }
return (UNVIS_VALIDPUSH); return UNVIS_VALIDPUSH;
case S_MIME1:
if (uc == '\n' || uc == '\r') {
*astate = SS(0, S_EATCRNL);
return UNVIS_NOCHAR;
}
if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) {
*cp = XTOD(uc);
*astate = SS(0, S_MIME2);
return UNVIS_NOCHAR;
}
goto bad;
case S_MIME2:
if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) {
*astate = SS(0, S_GROUND);
*cp = XTOD(uc) | (*cp << 4);
return UNVIS_VALID;
}
goto bad;
case S_EATCRNL:
switch (uc) {
case '\r':
case '\n':
return UNVIS_NOCHAR;
case '=':
*astate = SS(0, S_MIME1);
return UNVIS_NOCHAR;
default:
*cp = uc;
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
}
case S_AMP:
*cp = 0;
if (uc == '#') {
*astate = SS(0, S_NUMBER);
return UNVIS_NOCHAR;
}
*astate = SS(0, S_STRING);
/*FALLTHROUGH*/
case S_STRING:
ia = *cp; /* index in the array */
is = GI(*astate); /* index in the string */
lc = is == 0 ? 0 : nv[ia].name[is - 1]; /* last character */
if (uc == ';')
uc = '\0';
for (; ia < __arraycount(nv); ia++) {
if (is != 0 && nv[ia].name[is - 1] != lc)
goto bad;
if (nv[ia].name[is] == uc)
break;
}
if (ia == __arraycount(nv))
goto bad;
if (uc != 0) {
*cp = ia;
*astate = SS(is + 1, S_STRING);
return UNVIS_NOCHAR;
}
*cp = nv[ia].value;
*astate = SS(0, S_GROUND);
return UNVIS_VALID;
case S_NUMBER:
if (uc == ';')
return UNVIS_VALID;
if (!isdigit(uc))
goto bad;
*cp += (*cp * 10) + uc - '0';
return UNVIS_NOCHAR;
default: default:
bad:
/* /*
* decoder in unknown state - (probably uninitialized) * decoder in unknown state - (probably uninitialized)
*/ */
*astate = S_GROUND; *astate = SS(0, S_GROUND);
return (UNVIS_SYNBAD); return UNVIS_SYNBAD;
} }
} }
/* /*
* strunvis - decode src into dst * strnunvisx - decode src into dst
* *
* Number of chars decoded into dst is returned, -1 on error. * Number of chars decoded into dst is returned, -1 on error.
* Dst is null terminated. * Dst is null terminated.
*/ */
int int
strunvisx(dst, src, flag) strnunvisx(char *dst, size_t dlen, const char *src, int flag)
char *dst;
const char *src;
int flag;
{ {
char c; char c;
char *start = dst; char t, *start = dst;
int state = 0; int state = 0;
_DIAGASSERT(src != NULL); _DIAGASSERT(src != NULL);
_DIAGASSERT(dst != NULL); _DIAGASSERT(dst != NULL);
#define CHECKSPACE() \
do { \
if (dlen-- == 0) { \
errno = ENOSPC; \
return -1; \
} \
} while (/*CONSTCOND*/0)
while ((c = *src++) != '\0') { while ((c = *src++) != '\0') {
again: again:
switch (unvis(dst, c, &state, flag)) { switch (unvis(&t, c, &state, flag)) {
case UNVIS_VALID: case UNVIS_VALID:
dst++; CHECKSPACE();
*dst++ = t;
break; break;
case UNVIS_VALIDPUSH: case UNVIS_VALIDPUSH:
dst++; CHECKSPACE();
*dst++ = t;
goto again; goto again;
case 0: case 0:
case UNVIS_NOCHAR: case UNVIS_NOCHAR:
break; break;
case UNVIS_SYNBAD:
errno = EINVAL;
return -1;
default: default:
return (-1); _DIAGASSERT(0);
errno = EINVAL;
return -1;
} }
} }
if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID) if (unvis(&t, c, &state, UNVIS_END) == UNVIS_VALID) {
dst++; CHECKSPACE();
*dst++ = t;
}
CHECKSPACE();
*dst = '\0'; *dst = '\0';
return (dst - start); return (int)(dst - start);
} }
int int
strunvis(dst, src) strunvisx(char *dst, const char *src, int flag)
char *dst;
const char *src;
{ {
return strunvisx(dst, src, 0); return strnunvisx(dst, (size_t)~0, src, flag);
}
int
strunvis(char *dst, const char *src)
{
return strnunvisx(dst, (size_t)~0, src, 0);
}
int
strnunvis(char *dst, size_t dlen, const char *src)
{
return strnunvisx(dst, dlen, src, 0);
} }
#endif #endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: vis.c,v 1.38 2008/09/04 09:41:44 lukem Exp $ */ /* $NetBSD: vis.c,v 1.44 2011/03/12 19:52:48 christos Exp $ */
/*- /*-
* Copyright (c) 1989, 1993 * Copyright (c) 1989, 1993
@ -57,9 +57,15 @@
#include "config.h" #include "config.h"
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
/* XXXMYSQL : Make compiler happy. */
#ifdef _LIBC
#include "namespace.h"
#endif
#include <sys/types.h> #include <sys/types.h>
#include <assert.h> #include <assert.h>
@ -68,15 +74,11 @@
#else #else
#include "np/vis.h" #include "np/vis.h"
#endif #endif
#include <errno.h>
#include <stdlib.h> #include <stdlib.h>
#ifdef __weak_alias #ifdef __weak_alias
__weak_alias(strsvis,_strsvis)
__weak_alias(strsvisx,_strsvisx)
__weak_alias(strvis,_strvis)
__weak_alias(strvisx,_strvisx) __weak_alias(strvisx,_strvisx)
__weak_alias(svis,_svis)
__weak_alias(vis,_vis)
#endif #endif
#if !HAVE_VIS || !HAVE_SVIS #if !HAVE_VIS || !HAVE_SVIS
@ -85,7 +87,7 @@ __weak_alias(vis,_vis)
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
static char *do_svis(char *, int, int, int, const char *); static char *do_svis(char *, size_t *, int, int, int, const char *);
#undef BELL #undef BELL
#define BELL '\a' #define BELL '\a'
@ -94,6 +96,7 @@ static char *do_svis(char *, int, int, int, const char *);
#define iswhite(c) (c == ' ' || c == '\t' || c == '\n') #define iswhite(c) (c == ' ' || c == '\t' || c == '\n')
#define issafe(c) (c == '\b' || c == BELL || c == '\r') #define issafe(c) (c == '\b' || c == BELL || c == '\r')
#define xtoa(c) "0123456789abcdef"[c] #define xtoa(c) "0123456789abcdef"[c]
#define XTOA(c) "0123456789ABCDEF"[c]
#define MAXEXTRAS 5 #define MAXEXTRAS 5
@ -120,14 +123,54 @@ do { \
* This is do_hvis, for HTTP style (RFC 1808) * This is do_hvis, for HTTP style (RFC 1808)
*/ */
static char * static char *
do_hvis(char *dst, int c, int flag, int nextc, const char *extra) do_hvis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra)
{ {
if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) {
if ((isascii(c) && isalnum(c))
/* safe */
|| c == '$' || c == '-' || c == '_' || c == '.' || c == '+'
/* extra */
|| c == '!' || c == '*' || c == '\'' || c == '(' || c == ')'
|| c == ',') {
dst = do_svis(dst, dlen, c, flag, nextc, extra);
} else {
if (dlen) {
if (*dlen < 3)
return NULL;
*dlen -= 3;
}
*dst++ = '%'; *dst++ = '%';
*dst++ = xtoa(((unsigned int)c >> 4) & 0xf); *dst++ = xtoa(((unsigned int)c >> 4) & 0xf);
*dst++ = xtoa((unsigned int)c & 0xf); *dst++ = xtoa((unsigned int)c & 0xf);
}
return dst;
}
/*
* This is do_mvis, for Quoted-Printable MIME (RFC 2045)
* NB: No handling of long lines or CRLF.
*/
static char *
do_mvis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra)
{
if ((c != '\n') &&
/* Space at the end of the line */
((isspace(c) && (nextc == '\r' || nextc == '\n')) ||
/* Out of range */
(!isspace(c) && (c < 33 || (c > 60 && c < 62) || c > 126)) ||
/* Specific char to be escaped */
strchr("#$@[\\]^`{|}~", c) != NULL)) {
if (dlen) {
if (*dlen < 3)
return NULL;
*dlen -= 3;
}
*dst++ = '=';
*dst++ = XTOA(((unsigned int)c >> 4) & 0xf);
*dst++ = XTOA((unsigned int)c & 0xf);
} else { } else {
dst = do_svis(dst, c, flag, nextc, extra); dst = do_svis(dst, dlen, c, flag, nextc, extra);
} }
return dst; return dst;
} }
@ -142,16 +185,28 @@ do_hvis(char *dst, int c, int flag, int nextc, const char *extra)
* backslash-protected. * backslash-protected.
*/ */
static char * static char *
do_svis(char *dst, int c, int flag, int nextc, const char *extra) do_svis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra)
{ {
int isextra; int isextra;
size_t odlen = dlen ? *dlen : 0;
isextra = strchr(extra, c) != NULL; isextra = strchr(extra, c) != NULL;
#define HAVE(x) \
do { \
if (dlen) { \
if (*dlen < (x)) \
goto out; \
*dlen -= (x); \
} \
} while (/*CONSTCOND*/0)
if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) ||
((flag & VIS_SAFE) && issafe(c)))) { ((flag & VIS_SAFE) && issafe(c)))) {
HAVE(1);
*dst++ = c; *dst++ = c;
return dst; return dst;
} }
if (flag & VIS_CSTYLE) { if (flag & VIS_CSTYLE) {
HAVE(2);
switch (c) { switch (c) {
case '\n': case '\n':
*dst++ = '\\'; *dst++ = 'n'; *dst++ = '\\'; *dst++ = 'n';
@ -180,6 +235,7 @@ do_svis(char *dst, int c, int flag, int nextc, const char *extra)
case '\0': case '\0':
*dst++ = '\\'; *dst++ = '0'; *dst++ = '\\'; *dst++ = '0';
if (isoctal(nextc)) { if (isoctal(nextc)) {
HAVE(2);
*dst++ = '0'; *dst++ = '0';
*dst++ = '0'; *dst++ = '0';
} }
@ -189,57 +245,104 @@ do_svis(char *dst, int c, int flag, int nextc, const char *extra)
*dst++ = '\\'; *dst++ = c; *dst++ = '\\'; *dst++ = c;
return dst; return dst;
} }
if (dlen)
*dlen = odlen;
} }
} }
if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
HAVE(4);
*dst++ = '\\'; *dst++ = '\\';
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0';
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0';
*dst++ = (c & 07) + '0'; *dst++ = (c & 07) + '0';
} else { } else {
if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; if ((flag & VIS_NOSLASH) == 0) {
HAVE(1);
*dst++ = '\\';
}
if (c & 0200) { if (c & 0200) {
HAVE(1);
c &= 0177; *dst++ = 'M'; c &= 0177; *dst++ = 'M';
} }
if (iscntrl(c)) { if (iscntrl(c)) {
HAVE(2);
*dst++ = '^'; *dst++ = '^';
if (c == 0177) if (c == 0177)
*dst++ = '?'; *dst++ = '?';
else else
*dst++ = c + '@'; *dst++ = c + '@';
} else { } else {
HAVE(2);
*dst++ = '-'; *dst++ = c; *dst++ = '-'; *dst++ = c;
} }
} }
return dst; return dst;
out:
*dlen = odlen;
return NULL;
} }
typedef char *(*visfun_t)(char *, size_t *, int, int, int, const char *);
/* /*
* svis - visually encode characters, also encoding the characters * Return the appropriate encoding function depending on the flags given.
*/
static visfun_t
getvisfun(int flag)
{
if (flag & VIS_HTTPSTYLE)
return do_hvis;
if (flag & VIS_MIMESTYLE)
return do_mvis;
return do_svis;
}
/*
* isnvis - visually encode characters, also encoding the characters
* pointed to by `extra' * pointed to by `extra'
*/ */
char * static char *
svis(char *dst, int c, int flag, int nextc, const char *extra) isnvis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra)
{ {
char *nextra = NULL; char *nextra = NULL;
visfun_t f;
_DIAGASSERT(dst != NULL); _DIAGASSERT(dst != NULL);
_DIAGASSERT(extra != NULL); _DIAGASSERT(extra != NULL);
MAKEEXTRALIST(flag, nextra, extra); MAKEEXTRALIST(flag, nextra, extra);
if (!nextra) { if (!nextra) {
if (dlen && *dlen == 0) {
errno = ENOSPC;
return NULL;
}
*dst = '\0'; /* can't create nextra, return "" */ *dst = '\0'; /* can't create nextra, return "" */
return dst; return dst;
} }
if (flag & VIS_HTTPSTYLE) f = getvisfun(flag);
dst = do_hvis(dst, c, flag, nextc, nextra); dst = (*f)(dst, dlen, c, flag, nextc, nextra);
else
dst = do_svis(dst, c, flag, nextc, nextra);
free(nextra); free(nextra);
if (dst == NULL || (dlen && *dlen == 0)) {
errno = ENOSPC;
return NULL;
}
*dst = '\0'; *dst = '\0';
return dst; return dst;
} }
char *
svis(char *dst, int c, int flag, int nextc, const char *extra)
{
return isnvis(dst, NULL, c, flag, nextc, extra);
}
char *
snvis(char *dst, size_t dlen, int c, int flag, int nextc, const char *extra)
{
return isnvis(dst, &dlen, c, flag, nextc, extra);
}
/* /*
* strsvis, strsvisx - visually encode characters from src into dst * strsvis, strsvisx - visually encode characters from src into dst
@ -256,13 +359,14 @@ svis(char *dst, int c, int flag, int nextc, const char *extra)
* Strsvisx encodes exactly len bytes from src into dst. * Strsvisx encodes exactly len bytes from src into dst.
* This is useful for encoding a block of data. * This is useful for encoding a block of data.
*/ */
int static int
strsvis(char *dst, const char *csrc, int flag, const char *extra) istrsnvis(char *dst, size_t *dlen, const char *csrc, int flag, const char *extra)
{ {
int c; int c;
char *start; char *start;
char *nextra = NULL; char *nextra = NULL;
const unsigned char *src = (const unsigned char *)csrc; const unsigned char *src = (const unsigned char *)csrc;
visfun_t f;
_DIAGASSERT(dst != NULL); _DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL); _DIAGASSERT(src != NULL);
@ -272,52 +376,87 @@ strsvis(char *dst, const char *csrc, int flag, const char *extra)
*dst = '\0'; /* can't create nextra, return "" */ *dst = '\0'; /* can't create nextra, return "" */
return 0; return 0;
} }
if (flag & VIS_HTTPSTYLE) { f = getvisfun(flag);
for (start = dst; (c = *src++) != '\0'; /* empty */) for (start = dst; (c = *src++) != '\0'; /* empty */) {
dst = do_hvis(dst, c, flag, *src, nextra); dst = (*f)(dst, dlen, c, flag, *src, nextra);
} else { if (dst == NULL) {
for (start = dst; (c = *src++) != '\0'; /* empty */) errno = ENOSPC;
dst = do_svis(dst, c, flag, *src, nextra); return -1;
}
} }
free(nextra); free(nextra);
if (dlen && *dlen == 0) {
errno = ENOSPC;
return -1;
}
*dst = '\0'; *dst = '\0';
return (dst - start); return (int)(dst - start);
} }
int
strsvis(char *dst, const char *csrc, int flag, const char *extra)
{
return istrsnvis(dst, NULL, csrc, flag, extra);
}
int int
strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra) strsnvis(char *dst, size_t dlen, const char *csrc, int flag, const char *extra)
{
return istrsnvis(dst, &dlen, csrc, flag, extra);
}
static int
istrsnvisx(char *dst, size_t *dlen, const char *csrc, size_t len, int flag,
const char *extra)
{ {
unsigned char c; unsigned char c;
char *start; char *start;
char *nextra = NULL; char *nextra = NULL;
const unsigned char *src = (const unsigned char *)csrc; const unsigned char *src = (const unsigned char *)csrc;
visfun_t f;
_DIAGASSERT(dst != NULL); _DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL); _DIAGASSERT(src != NULL);
_DIAGASSERT(extra != NULL); _DIAGASSERT(extra != NULL);
MAKEEXTRALIST(flag, nextra, extra); MAKEEXTRALIST(flag, nextra, extra);
if (! nextra) { if (! nextra) {
if (dlen && *dlen == 0) {
errno = ENOSPC;
return -1;
}
*dst = '\0'; /* can't create nextra, return "" */ *dst = '\0'; /* can't create nextra, return "" */
return 0; return 0;
} }
if (flag & VIS_HTTPSTYLE) { f = getvisfun(flag);
for (start = dst; len > 0; len--) { for (start = dst; len > 0; len--) {
c = *src++; c = *src++;
dst = do_hvis(dst, c, flag, dst = (*f)(dst, dlen, c, flag, len > 1 ? *src : '\0', nextra);
len > 1 ? *src : '\0', nextra); if (dst == NULL) {
} errno = ENOSPC;
} else { return -1;
for (start = dst; len > 0; len--) {
c = *src++;
dst = do_svis(dst, c, flag,
len > 1 ? *src : '\0', nextra);
} }
} }
free(nextra); free(nextra);
if (dlen && *dlen == 0) {
errno = ENOSPC;
return -1;
}
*dst = '\0'; *dst = '\0';
return (dst - start); return (int)(dst - start);
}
int
strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra)
{
return istrsnvisx(dst, NULL, csrc, len, flag, extra);
}
int
strsnvisx(char *dst, size_t dlen, const char *csrc, size_t len, int flag,
const char *extra)
{
return istrsnvisx(dst, &dlen, csrc, len, flag, extra);
} }
#endif #endif
@ -325,28 +464,47 @@ strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra)
/* /*
* vis - visually encode characters * vis - visually encode characters
*/ */
char * static char *
vis(char *dst, int c, int flag, int nextc) invis(char *dst, size_t *dlen, int c, int flag, int nextc)
{ {
char *extra = NULL; char *extra = NULL;
unsigned char uc = (unsigned char)c; unsigned char uc = (unsigned char)c;
visfun_t f;
_DIAGASSERT(dst != NULL); _DIAGASSERT(dst != NULL);
MAKEEXTRALIST(flag, extra, ""); MAKEEXTRALIST(flag, extra, "");
if (! extra) { if (! extra) {
if (dlen && *dlen == 0) {
errno = ENOSPC;
return NULL;
}
*dst = '\0'; /* can't create extra, return "" */ *dst = '\0'; /* can't create extra, return "" */
return dst; return dst;
} }
if (flag & VIS_HTTPSTYLE) f = getvisfun(flag);
dst = do_hvis(dst, uc, flag, nextc, extra); dst = (*f)(dst, dlen, uc, flag, nextc, extra);
else
dst = do_svis(dst, uc, flag, nextc, extra);
free(extra); free(extra);
if (dst == NULL || (dlen && *dlen == 0)) {
errno = ENOSPC;
return NULL;
}
*dst = '\0'; *dst = '\0';
return dst; return dst;
} }
char *
vis(char *dst, int c, int flag, int nextc)
{
return invis(dst, NULL, c, flag, nextc);
}
char *
nvis(char *dst, size_t dlen, int c, int flag, int nextc)
{
return invis(dst, &dlen, c, flag, nextc);
}
/* /*
* strvis, strvisx - visually encode characters from src into dst * strvis, strvisx - visually encode characters from src into dst
@ -358,36 +516,68 @@ vis(char *dst, int c, int flag, int nextc)
* Strvisx encodes exactly len bytes from src into dst. * Strvisx encodes exactly len bytes from src into dst.
* This is useful for encoding a block of data. * This is useful for encoding a block of data.
*/ */
int static int
strvis(char *dst, const char *src, int flag) istrnvis(char *dst, size_t *dlen, const char *src, int flag)
{ {
char *extra = NULL; char *extra = NULL;
int rv; int rv;
MAKEEXTRALIST(flag, extra, ""); MAKEEXTRALIST(flag, extra, "");
if (!extra) { if (!extra) {
if (dlen && *dlen == 0) {
errno = ENOSPC;
return -1;
}
*dst = '\0'; /* can't create extra, return "" */ *dst = '\0'; /* can't create extra, return "" */
return 0; return 0;
} }
rv = strsvis(dst, src, flag, extra); rv = istrsnvis(dst, dlen, src, flag, extra);
free(extra); free(extra);
return rv; return rv;
} }
int
strvis(char *dst, const char *src, int flag)
{
return istrnvis(dst, NULL, src, flag);
}
int
strnvis(char *dst, size_t dlen, const char *src, int flag)
{
return istrnvis(dst, &dlen, src, flag);
}
static int
istrnvisx(char *dst, size_t *dlen, const char *src, size_t len, int flag)
{
char *extra = NULL;
int rv;
MAKEEXTRALIST(flag, extra, "");
if (!extra) {
if (dlen && *dlen == 0) {
errno = ENOSPC;
return -1;
}
*dst = '\0'; /* can't create extra, return "" */
return 0;
}
rv = istrsnvisx(dst, dlen, src, len, flag, extra);
free(extra);
return rv;
}
int int
strvisx(char *dst, const char *src, size_t len, int flag) strvisx(char *dst, const char *src, size_t len, int flag)
{ {
char *extra = NULL; return istrnvisx(dst, NULL, src, len, flag);
int rv;
MAKEEXTRALIST(flag, extra, "");
if (!extra) {
*dst = '\0'; /* can't create extra, return "" */
return 0;
}
rv = strsvisx(dst, src, len, flag, extra);
free(extra);
return rv;
} }
int
strnvisx(char *dst, size_t dlen, const char *src, size_t len, int flag)
{
return istrnvisx(dst, &dlen, src, len, flag);
}
#endif #endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: vis.h,v 1.16 2005/09/13 01:44:32 christos Exp $ */ /* $NetBSD: vis.h,v 1.19 2011/03/12 19:52:45 christos Exp $ */
/*- /*-
* Copyright (c) 1990, 1993 * Copyright (c) 1990, 1993
@ -39,24 +39,29 @@
/* /*
* to select alternate encoding format * to select alternate encoding format
*/ */
#define VIS_OCTAL 0x01 /* use octal \ddd format */ #define VIS_OCTAL 0x001 /* use octal \ddd format */
#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropiate */ #define VIS_CSTYLE 0x002 /* use \[nrft0..] where appropiate */
/* /*
* to alter set of characters encoded (default is to encode all * to alter set of characters encoded (default is to encode all
* non-graphic except space, tab, and newline). * non-graphic except space, tab, and newline).
*/ */
#define VIS_SP 0x04 /* also encode space */ #define VIS_SP 0x004 /* also encode space */
#define VIS_TAB 0x08 /* also encode tab */ #define VIS_TAB 0x008 /* also encode tab */
#define VIS_NL 0x10 /* also encode newline */ #define VIS_NL 0x010 /* also encode newline */
#define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) #define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL)
#define VIS_SAFE 0x20 /* only encode "unsafe" characters */ #define VIS_SAFE 0x020 /* only encode "unsafe" characters */
/* /*
* other * other
*/ */
#define VIS_NOSLASH 0x40 /* inhibit printing '\' */ #define VIS_NOSLASH 0x040 /* inhibit printing '\' */
#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */ #define VIS_HTTP1808 0x080 /* http-style escape % hex hex */
#define VIS_HTTPSTYLE 0x080 /* http-style escape % hex hex */
#define VIS_MIMESTYLE 0x100 /* mime-style escape = HEX HEX */
#define VIS_HTTP1866 0x200 /* http-style &#num; or &string; */
#define VIS_NOESCAPE 0x400 /* don't decode `\' */
#define _VIS_END 0x800 /* for unvis */
/* /*
* unvis return codes * unvis return codes
@ -70,18 +75,41 @@
/* /*
* unvis flags * unvis flags
*/ */
#define UNVIS_END 1 /* no more characters */ #define UNVIS_END _VIS_END /* no more characters */
#include <sys/cdefs.h>
/* XXXMYSQL */
#ifndef __RENAME
#define __RENAME(x)
#endif
__BEGIN_DECLS __BEGIN_DECLS
char *vis(char *, int, int, int); char *vis(char *, int, int, int);
char *nvis(char *, size_t, int, int, int);
char *svis(char *, int, int, int, const char *); char *svis(char *, int, int, int, const char *);
char *snvis(char *, size_t, int, int, int, const char *);
int strvis(char *, const char *, int); int strvis(char *, const char *, int);
int strnvis(char *, size_t, const char *, int);
int strsvis(char *, const char *, int, const char *); int strsvis(char *, const char *, int, const char *);
int strsnvis(char *, size_t, const char *, int, const char *);
int strvisx(char *, const char *, size_t, int); int strvisx(char *, const char *, size_t, int);
int strnvisx(char *, size_t, const char *, size_t, int);
int strsvisx(char *, const char *, size_t, int, const char *); int strsvisx(char *, const char *, size_t, int, const char *);
int strsnvisx(char *, size_t, const char *, size_t, int, const char *);
int strunvis(char *, const char *); int strunvis(char *, const char *);
int strnunvis(char *, size_t, const char *);
int strunvisx(char *, const char *, int); int strunvisx(char *, const char *, int);
int unvis(char *, int, int *, int); int strnunvisx(char *, size_t, const char *, int);
#ifndef __LIBC12_SOURCE__
int unvis(char *, int, int *, int) __RENAME(__unvis50);
#endif
__END_DECLS __END_DECLS
#endif /* !_VIS_H_ */ #endif /* !_VIS_H_ */

View File

@ -0,0 +1,43 @@
/* $NetBSD: wcsdup.c,v 1.3 2008/05/26 13:17:48 haad Exp $ */
/*
* Copyright (C) 2006 Aleksey Cheusov
*
* This material is provided "as is", with absolutely no warranty expressed
* or implied. Any use is at your own risk.
*
* Permission to use or copy this software for any purpose is hereby granted
* without fee. Permission to modify the code and to distribute modified
* code is also granted without any restrictions.
*/
#ifndef HAVE_WCSDUP
#include "config.h"
#if defined(LIBC_SCCS) && !defined(lint)
__RCSID("$NetBSD: wcsdup.c,v 1.3 2008/05/26 13:17:48 haad Exp $");
#endif /* LIBC_SCCS and not lint */
#include <stdlib.h>
#include <assert.h>
#include <wchar.h>
wchar_t *
wcsdup(const wchar_t *str)
{
wchar_t *copy;
size_t len;
_DIAGASSERT(str != NULL);
len = wcslen(str) + 1;
copy = malloc(len * sizeof (wchar_t));
if (!copy)
return NULL;
return wmemcpy(copy, str, len);
}
#endif

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.26 2011/08/16 16:25:15 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -57,17 +57,17 @@ static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
#include <stdlib.h> #include <stdlib.h>
private const struct { private const struct {
const char *name; const Char *name;
int (*func)(EditLine *, int, const char **); int (*func)(EditLine *, int, const Char **);
} cmds[] = { } cmds[] = {
{ "bind", map_bind }, { STR("bind"), map_bind },
{ "echotc", term_echotc }, { STR("echotc"), terminal_echotc },
{ "edit", el_editmode }, { STR("edit"), el_editmode },
{ "history", hist_command }, { STR("history"), hist_command },
{ "telltc", term_telltc }, { STR("telltc"), terminal_telltc },
{ "settc", term_settc }, { STR("settc"), terminal_settc },
{ "setty", tty_stty }, { STR("setty"), tty_stty },
{ NULL, NULL } { NULL, NULL }
}; };
@ -75,17 +75,17 @@ private const struct {
* Parse a line and dispatch it * Parse a line and dispatch it
*/ */
protected int protected int
parse_line(EditLine *el, const char *line) parse_line(EditLine *el, const Char *line)
{ {
const char **argv; const Char **argv;
int argc; int argc;
Tokenizer *tok; TYPE(Tokenizer) *tok;
tok = tok_init(NULL); tok = FUN(tok,init)(NULL);
tok_str(tok, line, &argc, &argv); FUN(tok,str)(tok, line, &argc, &argv);
argc = el_parse(el, argc, argv); argc = FUN(el,parse)(el, argc, argv);
tok_end(tok); FUN(tok,end)(tok);
return (argc); return argc;
} }
@ -93,57 +93,57 @@ parse_line(EditLine *el, const char *line)
* Command dispatcher * Command dispatcher
*/ */
public int 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; int i;
if (argc < 1) if (argc < 1)
return (-1); return -1;
ptr = strchr(argv[0], ':'); ptr = Strchr(argv[0], ':');
if (ptr != NULL) { if (ptr != NULL) {
char *tprog; Char *tprog;
size_t l; size_t l;
if (ptr == argv[0]) if (ptr == argv[0])
return (0); return 0;
l = ptr - argv[0] - 1; l = (size_t)(ptr - argv[0] - 1);
tprog = (char *) el_malloc(l + 1); tprog = el_malloc((l + 1) * sizeof(*tprog));
if (tprog == NULL) if (tprog == NULL)
return (0); return 0;
(void) strncpy(tprog, argv[0], l); (void) Strncpy(tprog, argv[0], l);
tprog[l] = '\0'; tprog[l] = '\0';
ptr++; ptr++;
l = el_match(el->el_prog, tprog); l = (size_t)el_match(el->el_prog, tprog);
el_free(tprog); el_free(tprog);
if (!l) if (!l)
return (0); return 0;
} else } else
ptr = argv[0]; ptr = argv[0];
for (i = 0; cmds[i].name != NULL; i++) 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); i = (*cmds[i].func) (el, argc, argv);
return (-i); return -i;
} }
return (-1); return -1;
} }
/* parse__escape(): /* 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 * the appropriate character or -1 if the escape is not valid
*/ */
protected int protected int
parse__escape(const char **ptr) parse__escape(const Char **ptr)
{ {
const char *p; const Char *p;
int c; Int c;
p = *ptr; p = *ptr;
if (p[1] == 0) if (p[1] == 0)
return (-1); return -1;
if (*p == '\\') { if (*p == '\\') {
p++; p++;
@ -172,6 +172,28 @@ parse__escape(const char **ptr)
case 'e': case 'e':
c = '\033'; /* Escape */ c = '\033'; /* Escape */
break; 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 '0':
case '1': case '1':
case '2': case '2':
@ -191,8 +213,8 @@ parse__escape(const char **ptr)
} }
c = (c << 3) | (ch - '0'); c = (c << 3) | (ch - '0');
} }
if ((c & 0xffffff00) != 0) if ((c & (wint_t)0xffffff00) != (wint_t)0)
return (-1); return -1;
--p; --p;
break; break;
} }
@ -206,28 +228,28 @@ parse__escape(const char **ptr)
} else } else
c = *p; c = *p;
*ptr = ++p; *ptr = ++p;
return (c); return c;
} }
/* parse__string(): /* parse__string():
* Parse the escapes from in and put the raw string out * Parse the escapes from in and put the raw string out
*/ */
protected char * protected Char *
parse__string(char *out, const char *in) parse__string(Char *out, const Char *in)
{ {
char *rv = out; Char *rv = out;
int n; int n;
for (;;) for (;;)
switch (*in) { switch (*in) {
case '\0': case '\0':
*out = '\0'; *out = '\0';
return (rv); return rv;
case '\\': case '\\':
case '^': case '^':
if ((n = parse__escape(&in)) == -1) if ((n = parse__escape(&in)) == -1)
return (NULL); return NULL;
*out++ = n; *out++ = n;
break; break;
@ -251,12 +273,12 @@ parse__string(char *out, const char *in)
* or -1 if one is not found * or -1 if one is not found
*/ */
protected int protected int
parse_cmd(EditLine *el, const char *cmd) parse_cmd(EditLine *el, const Char *cmd)
{ {
el_bindings_t *b; el_bindings_t *b;
for (b = el->el_map.help; b->name != NULL; b++) 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 b->func;
return (-1); return -1;
} }

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 * Copyright (c) 1992, 1993
@ -40,9 +40,9 @@
#ifndef _h_el_parse #ifndef _h_el_parse
#define _h_el_parse #define _h_el_parse
protected int parse_line(EditLine *, const char *); protected int parse_line(EditLine *, const Char *);
protected int parse__escape(const char **); protected int parse__escape(const Char **);
protected char *parse__string(char *, const char *); protected Char *parse__string(Char *, const Char *);
protected int parse_cmd(EditLine *, const char *); protected int parse_cmd(EditLine *, const Char *);
#endif /* _h_el_parse */ #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.20 2011/07/29 15:16:33 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -46,54 +46,66 @@ static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93";
#include <stdio.h> #include <stdio.h>
#include "el.h" #include "el.h"
private char *prompt_default(EditLine *); private Char *prompt_default(EditLine *);
private char *prompt_default_r(EditLine *); private Char *prompt_default_r(EditLine *);
/* prompt_default(): /* prompt_default():
* Just a default prompt, in case the user did not provide one * Just a default prompt, in case the user did not provide one
*/ */
private char * private Char *
/*ARGSUSED*/ /*ARGSUSED*/
prompt_default(EditLine *el __attribute__((__unused__))) prompt_default(EditLine *el __attribute__((__unused__)))
{ {
static char a[3] = {'?', ' ', '\0'}; static Char a[3] = {'?', ' ', '\0'};
return (a); return a;
} }
/* prompt_default_r(): /* prompt_default_r():
* Just a default rprompt, in case the user did not provide one * Just a default rprompt, in case the user did not provide one
*/ */
private char * private Char *
/*ARGSUSED*/ /*ARGSUSED*/
prompt_default_r(EditLine *el __attribute__((__unused__))) prompt_default_r(EditLine *el __attribute__((__unused__)))
{ {
static char a[1] = {'\0'}; static Char a[1] = {'\0'};
return (a); return a;
} }
/* prompt_print(): /* prompt_print():
* Print the prompt and update the prompt position. * 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 protected void
prompt_print(EditLine *el, int op) prompt_print(EditLine *el, int op)
{ {
el_prompt_t *elp; el_prompt_t *elp;
char *p; Char *p;
int ignore = 0;
if (op == EL_PROMPT) if (op == EL_PROMPT)
elp = &el->el_prompt; elp = &el->el_prompt;
else else
elp = &el->el_rprompt; elp = &el->el_rprompt;
p = (elp->p_func) (el);
while (*p) if (elp->p_wide)
re_putc(el, *p++, 1); 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)
terminal__putc(el, *p);
else
re_putc(el, *p, 1);
}
elp->p_pos.v = el->el_refresh.r_cursor.v; elp->p_pos.v = el->el_refresh.r_cursor.v;
elp->p_pos.h = el->el_refresh.r_cursor.h; elp->p_pos.h = el->el_refresh.r_cursor.h;
@ -110,10 +122,12 @@ prompt_init(EditLine *el)
el->el_prompt.p_func = prompt_default; el->el_prompt.p_func = prompt_default;
el->el_prompt.p_pos.v = 0; el->el_prompt.p_pos.v = 0;
el->el_prompt.p_pos.h = 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_func = prompt_default_r;
el->el_rprompt.p_pos.v = 0; el->el_rprompt.p_pos.v = 0;
el->el_rprompt.p_pos.h = 0; el->el_rprompt.p_pos.h = 0;
return (0); el->el_rprompt.p_ignore = '\0';
return 0;
} }
@ -131,24 +145,31 @@ prompt_end(EditLine *el __attribute__((__unused__)))
* Install a prompt printing function * Install a prompt printing function
*/ */
protected int 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; el_prompt_t *p;
if (op == EL_PROMPT) if (op == EL_PROMPT || op == EL_PROMPT_ESC)
p = &el->el_prompt; p = &el->el_prompt;
else else
p = &el->el_rprompt; p = &el->el_rprompt;
if (prf == NULL) { if (prf == NULL) {
if (op == EL_PROMPT) if (op == EL_PROMPT || op == EL_PROMPT_ESC)
p->p_func = prompt_default; p->p_func = prompt_default;
else else
p->p_func = prompt_default_r; p->p_func = prompt_default_r;
} else } else {
p->p_func = prf; p->p_func = prf;
}
p->p_ignore = c;
p->p_pos.v = 0; p->p_pos.v = 0;
p->p_pos.h = 0; p->p_pos.h = 0;
return (0); p->p_wide = wide;
return 0;
} }
@ -156,14 +177,22 @@ prompt_set(EditLine *el, el_pfunc_t prf, int op)
* Retrieve the prompt printing function * Retrieve the prompt printing function
*/ */
protected int 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) if (prf == NULL)
return (-1); return -1;
if (op == EL_PROMPT) if (op == EL_PROMPT)
*prf = el->el_prompt.p_func; p = &el->el_prompt;
else else
*prf = el->el_rprompt.p_func; p = &el->el_rprompt;
return (0);
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 * Copyright (c) 1992, 1993
@ -42,16 +42,18 @@
#include "histedit.h" #include "histedit.h"
typedef char * (*el_pfunc_t)(EditLine*); typedef Char *(*el_pfunc_t)(EditLine *);
typedef struct el_prompt_t { typedef struct el_prompt_t {
el_pfunc_t p_func; /* Function to return the prompt */ el_pfunc_t p_func; /* Function to return the prompt */
coord_t p_pos; /* position in the line after 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; } el_prompt_t;
protected void prompt_print(EditLine *, int); protected void prompt_print(EditLine *, int);
protected int prompt_set(EditLine *, el_pfunc_t, int); protected int prompt_set(EditLine *, el_pfunc_t, Char, int, int);
protected int prompt_get(EditLine *, el_pfunc_t *, int); protected int prompt_get(EditLine *, el_pfunc_t *, Char *, int);
protected int prompt_init(EditLine *); protected int prompt_init(EditLine *);
protected void prompt_end(EditLine *); protected void prompt_end(EditLine *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: read.c,v 1.43 2009/02/05 19:15:44 christos Exp $ */ /* $NetBSD: read.c,v 1.67 2011/08/16 16:25:15 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -48,14 +48,15 @@ static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
#include <fcntl.h> #include <fcntl.h>
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <limits.h>
#include "el.h" #include "el.h"
#define OKCMD -1 #define OKCMD -1 /* must be -1! */
private int read__fixio(int, int); private int read__fixio(int, int);
private int read_preread(EditLine *); private int read_preread(EditLine *);
private int read_char(EditLine *, char *); private int read_char(EditLine *, Char *);
private int read_getcmd(EditLine *, el_action_t *, char *); private int read_getcmd(EditLine *, el_action_t *, Char *);
private void read_pop(c_macro_t *); private void read_pop(c_macro_t *);
/* read_init(): /* read_init():
@ -89,7 +90,7 @@ el_read_setfn(EditLine *el, el_rfunc_t rc)
protected el_rfunc_t protected el_rfunc_t
el_read_getfn(EditLine *el) el_read_getfn(EditLine *el)
{ {
return (el->el_read.read_char == read_char) ? return el->el_read.read_char == read_char ?
EL_BUILTIN_GETCFN : el->el_read.read_char; EL_BUILTIN_GETCFN : el->el_read.read_char;
} }
@ -131,7 +132,7 @@ read__fixio(int fd __attribute__((__unused__)), int e)
#ifdef EWOULDBLOCK #ifdef EWOULDBLOCK
case EWOULDBLOCK: case EWOULDBLOCK:
#ifndef TRY_AGAIN #ifndef TRY_AGAIN
#define TRY_AGAIN #define TRY_AGAIN
#endif #endif
#endif /* EWOULDBLOCK */ #endif /* EWOULDBLOCK */
@ -139,7 +140,7 @@ read__fixio(int fd __attribute__((__unused__)), int e)
#if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN
case EAGAIN: case EAGAIN:
#ifndef TRY_AGAIN #ifndef TRY_AGAIN
#define TRY_AGAIN #define TRY_AGAIN
#endif #endif
#endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */ #endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */
#endif /* POSIX && EAGAIN */ #endif /* POSIX && EAGAIN */
@ -148,10 +149,10 @@ read__fixio(int fd __attribute__((__unused__)), int e)
#ifdef TRY_AGAIN #ifdef TRY_AGAIN
#if defined(F_SETFL) && defined(O_NDELAY) #if defined(F_SETFL) && defined(O_NDELAY)
if ((e = fcntl(fd, F_GETFL, 0)) == -1) if ((e = fcntl(fd, F_GETFL, 0)) == -1)
return (-1); return -1;
if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1) if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1)
return (-1); return -1;
else else
e = 1; e = 1;
#endif /* F_SETFL && O_NDELAY */ #endif /* F_SETFL && O_NDELAY */
@ -160,21 +161,21 @@ read__fixio(int fd __attribute__((__unused__)), int e)
{ {
int zero = 0; int zero = 0;
if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1) if (ioctl(fd, FIONBIO, &zero) == -1)
return (-1); return -1;
else else
e = 1; e = 1;
} }
#endif /* FIONBIO */ #endif /* FIONBIO */
#endif /* TRY_AGAIN */ #endif /* TRY_AGAIN */
return (e ? 0 : -1); return e ? 0 : -1;
case EINTR: case EINTR:
return (0); return 0;
default: default:
return (-1); return -1;
} }
} }
@ -188,10 +189,13 @@ read_preread(EditLine *el)
int chrs = 0; int chrs = 0;
if (el->el_tty.t_mode == ED_IO) if (el->el_tty.t_mode == ED_IO)
return (0); 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 #ifdef FIONREAD
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); (void) ioctl(el->el_infd, FIONREAD, &chrs);
if (chrs > 0) { if (chrs > 0) {
char buf[EL_BUFSIZ]; char buf[EL_BUFSIZ];
@ -203,8 +207,8 @@ read_preread(EditLine *el)
} }
} }
#endif /* FIONREAD */ #endif /* FIONREAD */
#endif
return (chrs > 0); return chrs > 0;
} }
@ -212,33 +216,37 @@ read_preread(EditLine *el)
* Push a macro * Push a macro
*/ */
public void public void
el_push(EditLine *el, const char *str) FUN(el,push)(EditLine *el, const Char *str)
{ {
c_macro_t *ma = &el->el_chared.c_macro; c_macro_t *ma = &el->el_chared.c_macro;
if (str != NULL && ma->level + 1 < EL_MAXMACRO) { if (str != NULL && ma->level + 1 < EL_MAXMACRO) {
ma->level++; ma->level++;
if ((ma->macro[ma->level] = el_strdup(str)) != NULL) if ((ma->macro[ma->level] = Strdup(str)) != NULL)
return; return;
ma->level--; ma->level--;
} }
term_beep(el); terminal_beep(el);
term__flush(el); terminal__flush(el);
} }
/* read_getcmd(): /* read_getcmd():
* Return next command from the input stream. * Return next command from the input stream.
* Character values > 255 are not looked up in the map, but inserted.
*/ */
private int private int
read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch)
{ {
el_action_t cmd; el_action_t cmd;
int num; int num;
el->el_errno = 0;
do { do {
if ((num = el_getc(el, ch)) != 1) /* if EOF or error */ if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */
return (num); el->el_errno = num == 0 ? 0 : errno;
return num;
}
#ifdef KANJI #ifdef KANJI
if ((*ch & 0200)) { if ((*ch & 0200)) {
@ -252,15 +260,20 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
el->el_state.metanext = 0; el->el_state.metanext = 0;
*ch |= 0200; *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) { if (cmd == ED_SEQUENCE_LEAD_IN) {
key_value_t val; keymacro_value_t val;
switch (key_get(el, ch, &val)) { switch (keymacro_get(el, ch, &val)) {
case XK_CMD: case XK_CMD:
cmd = val.cmd; cmd = val.cmd;
break; break;
case XK_STR: case XK_STR:
el_push(el, val.str); FUN(el,push)(el, val.str);
break; break;
#ifdef notyet #ifdef notyet
case XK_EXE: case XK_EXE:
@ -277,28 +290,82 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch)
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
} while (cmd == ED_SEQUENCE_LEAD_IN); } while (cmd == ED_SEQUENCE_LEAD_IN);
*cmdnum = cmd; *cmdnum = cmd;
return (OKCMD); return OKCMD;
} }
/* read_char(): /* read_char():
* Read a character from the tty. * Read a character from the tty.
*/ */
private int private int
read_char(EditLine *el, char *cp) read_char(EditLine *el, Char *cp)
{ {
int num_read; ssize_t num_read;
int tried = 0; int tried = 0;
char cbuf[MB_LEN_MAX];
size_t cbp = 0;
int bytes = 0;
while ((num_read = read(el->el_infd, cp, 1)) == -1) #ifdef WIDECHAR
static mbstate_t state, temp_state;
memset(&state, 0, sizeof(mbstate_t));
#endif
again:
el->el_signal->sig_no = 0;
while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) {
switch (el->el_signal->sig_no) {
case SIGCONT:
FUN(el,set)(el, EL_REFRESH);
/*FALLTHROUGH*/
case SIGWINCH:
sig_set(el);
goto again;
default:
break;
}
if (!tried && read__fixio(el->el_infd, errno) == 0) if (!tried && read__fixio(el->el_infd, errno) == 0)
tried = 1; tried = 1;
else { else {
*cp = '\0'; *cp = '\0';
return (-1); return -1;
} }
}
return (num_read); #ifdef WIDECHAR
++cbp;
if (cbp > MB_CUR_MAX) { /* "shouldn't happen" */
*cp = '\0';
return (-1);
}
temp_state= state;
if ((bytes = mbrtowc(cp, cbuf, cbp, &state)) == -2)
{
/* Incomplete sequence, restore the state and scan more bytes. */
state= temp_state;
goto again;
}
else if (bytes == -1)
{
/* Invalid sequence, reset the state and continue. */
cbp= 0;
memset(&state, 0, sizeof(mbstate_t));
goto again;
}
/* We successfully read one single or multi-byte character */
#else
*cp = (unsigned char)cbuf[0];
#endif
#if 0
if ((el->el_flags & IGNORE_EXTCHARS) && bytes > 1) {
cbp = 0; /* skip this character */
goto again;
}
#endif
return (int)num_read;
} }
/* read_pop(): /* read_pop():
@ -310,8 +377,9 @@ read_pop(c_macro_t *ma)
int i; int i;
el_free(ma->macro[0]); el_free(ma->macro[0]);
for (i = ma->level--; i > 0; i--) for (i = 0; i < ma->level; i++)
ma->macro[i - 1] = ma->macro[i]; ma->macro[i] = ma->macro[i + 1];
ma->level--;
ma->offset = 0; ma->offset = 0;
} }
@ -319,12 +387,12 @@ read_pop(c_macro_t *ma)
* Read a character * Read a character
*/ */
public int public int
el_getc(EditLine *el, char *cp) FUN(el,getc)(EditLine *el, Char *cp)
{ {
int num_read; int num_read;
c_macro_t *ma = &el->el_chared.c_macro; c_macro_t *ma = &el->el_chared.c_macro;
term__flush(el); terminal__flush(el);
for (;;) { for (;;) {
if (ma->level < 0) { if (ma->level < 0) {
if (!read_preread(el)) if (!read_preread(el))
@ -339,30 +407,34 @@ el_getc(EditLine *el, char *cp)
continue; continue;
} }
*cp = ma->macro[0][ma->offset++] & 0377; *cp = ma->macro[0][ma->offset++];
if (ma->macro[0][ma->offset] == '\0') { if (ma->macro[0][ma->offset] == '\0') {
/* Needed for QuoteMode On */ /* Needed for QuoteMode On */
read_pop(ma); read_pop(ma);
} }
return (1); return 1;
} }
#ifdef DEBUG_READ #ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Turning raw mode on\n"); (void) fprintf(el->el_errfile, "Turning raw mode on\n");
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */ if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */
return (0); return 0;
#ifdef DEBUG_READ #ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Reading a character\n"); (void) fprintf(el->el_errfile, "Reading a character\n");
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
num_read = (*el->el_read.read_char)(el, cp); 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 #ifdef DEBUG_READ
(void) fprintf(el->el_errfile, "Got it %c\n", *cp); (void) fprintf(el->el_errfile, "Got it %c\n", *cp);
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
return (num_read); return num_read;
} }
protected void protected void
@ -383,7 +455,7 @@ read_prepare(EditLine *el)
re_refresh(el); /* print the prompt */ re_refresh(el); /* print the prompt */
if (el->el_flags & UNBUFFERED) if (el->el_flags & UNBUFFERED)
term__flush(el); terminal__flush(el);
} }
protected void protected void
@ -395,27 +467,32 @@ read_finish(EditLine *el)
sig_clr(el); sig_clr(el);
} }
public const char * public const Char *
el_gets(EditLine *el, int *nread) FUN(el,gets)(EditLine *el, int *nread)
{ {
int retval; int retval;
el_action_t cmdnum = 0; el_action_t cmdnum = 0;
int num; /* how many chars we have read at NL */ int num; /* how many chars we have read at NL */
char ch; Char ch, *cp;
int crlf = 0; int crlf = 0;
int nrb;
#ifdef FIONREAD #ifdef FIONREAD
c_macro_t *ma = &el->el_chared.c_macro; c_macro_t *ma = &el->el_chared.c_macro;
#endif /* FIONREAD */ #endif /* FIONREAD */
if (nread == NULL)
nread = &nrb;
*nread = 0;
if (el->el_flags & NO_TTY) { if (el->el_flags & NO_TTY) {
char *cp = el->el_line.buffer;
size_t idx; size_t idx;
while ((*el->el_read.read_char)(el, cp) == 1) { cp = el->el_line.buffer;
while ((num = (*el->el_read.read_char)(el, cp)) == 1) {
/* make sure there is space for next character */ /* make sure there is space for next character */
if (cp + 1 >= el->el_line.limit) { if (cp + 1 >= el->el_line.limit) {
idx = (cp - el->el_line.buffer); idx = (size_t)(cp - el->el_line.buffer);
if (!ch_enlargebufs(el, 2)) if (!ch_enlargebufs(el, (size_t)2))
break; break;
cp = &el->el_line.buffer[idx]; cp = &el->el_line.buffer[idx];
} }
@ -425,12 +502,13 @@ el_gets(EditLine *el, int *nread)
if (cp[-1] == '\r' || cp[-1] == '\n') if (cp[-1] == '\r' || cp[-1] == '\n')
break; 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; goto noedit;
*cp = '\0';
if (nread)
*nread = el->el_line.cursor - el->el_line.buffer;
return (el->el_line.buffer);
} }
@ -438,12 +516,12 @@ el_gets(EditLine *el, int *nread)
if (el->el_tty.t_mode == EX_IO && ma->level < 0) { if (el->el_tty.t_mode == EX_IO && ma->level < 0) {
long chrs = 0; long chrs = 0;
(void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); (void) ioctl(el->el_infd, FIONREAD, &chrs);
if (chrs == 0) { if (chrs == 0) {
if (tty_rawmode(el) < 0) { if (tty_rawmode(el) < 0) {
if (nread) errno = 0;
*nread = 0; *nread = 0;
return (NULL); return NULL;
} }
} }
} }
@ -453,25 +531,23 @@ el_gets(EditLine *el, int *nread)
read_prepare(el); read_prepare(el);
if (el->el_flags & EDIT_DISABLED) { if (el->el_flags & EDIT_DISABLED) {
char *cp;
size_t idx; size_t idx;
if ((el->el_flags & UNBUFFERED) == 0) if ((el->el_flags & UNBUFFERED) == 0)
cp = el->el_line.buffer; cp = el->el_line.buffer;
else else
cp = el->el_line.lastchar; cp = el->el_line.lastchar;
term__flush(el); terminal__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 */ /* make sure there is space next character */
if (cp + 1 >= el->el_line.limit) { if (cp + 1 >= el->el_line.limit) {
idx = (cp - el->el_line.buffer); idx = (size_t)(cp - el->el_line.buffer);
if (!ch_enlargebufs(el, 2)) if (!ch_enlargebufs(el, (size_t)2))
break; break;
cp = &el->el_line.buffer[idx]; cp = &el->el_line.buffer[idx];
} }
if (*cp == 4) /* ought to be stty eof */
break;
cp++; cp++;
crlf = cp[-1] == '\r' || cp[-1] == '\n'; crlf = cp[-1] == '\r' || cp[-1] == '\n';
if (el->el_flags & UNBUFFERED) if (el->el_flags & UNBUFFERED)
@ -480,11 +556,13 @@ el_gets(EditLine *el, int *nread)
break; break;
} }
el->el_line.cursor = el->el_line.lastchar = cp; if (num == -1) {
*cp = '\0'; if (errno == EINTR)
if (nread) cp = el->el_line.buffer;
*nread = el->el_line.cursor - el->el_line.buffer; el->el_errno = errno;
return (el->el_line.buffer); }
goto noedit;
} }
for (num = OKCMD; num == OKCMD;) { /* while still editing this for (num = OKCMD; num == OKCMD;) { /* while still editing this
@ -500,6 +578,12 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
break; break;
} }
if (el->el_errno == EINTR) {
el->el_line.buffer[0] = '\0';
el->el_line.lastchar =
el->el_line.cursor = el->el_line.buffer;
break;
}
if ((unsigned int)cmdnum >= (unsigned int)el->el_map.nfunc) { /* BUG CHECK command */ if ((unsigned int)cmdnum >= (unsigned int)el->el_map.nfunc) { /* BUG CHECK command */
#ifdef DEBUG_EDIT #ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
@ -530,7 +614,7 @@ el_gets(EditLine *el, int *nread)
el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) { el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) {
if (cmdnum == VI_DELETE_PREV_CHAR && if (cmdnum == VI_DELETE_PREV_CHAR &&
el->el_chared.c_redo.pos != el->el_chared.c_redo.buf el->el_chared.c_redo.pos != el->el_chared.c_redo.buf
&& el_isprint((unsigned char)el->el_chared.c_redo.pos[-1])) && Isprint(el->el_chared.c_redo.pos[-1]))
el->el_chared.c_redo.pos--; el->el_chared.c_redo.pos--;
else else
*el->el_chared.c_redo.pos++ = ch; *el->el_chared.c_redo.pos++ = ch;
@ -561,7 +645,7 @@ el_gets(EditLine *el, int *nread)
case CC_REFRESH_BEEP: case CC_REFRESH_BEEP:
re_refresh(el); re_refresh(el);
term_beep(el); terminal_beep(el);
break; break;
case CC_NORM: /* normal char */ case CC_NORM: /* normal char */
@ -582,7 +666,7 @@ el_gets(EditLine *el, int *nread)
break; break;
case CC_NEWLINE: /* normal end of line */ 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; break;
case CC_FATAL: /* fatal error, reset to known state */ case CC_FATAL: /* fatal error, reset to known state */
@ -593,7 +677,7 @@ el_gets(EditLine *el, int *nread)
/* put (real) cursor in a known place */ /* put (real) cursor in a known place */
re_clear_display(el); /* reset the display stuff */ re_clear_display(el); /* reset the display stuff */
ch_reset(el, 1); /* reset the input pointers */ ch_reset(el, 1); /* reset the input pointers */
re_refresh(el); /* print the prompt again */ re_refresh(el); /* print the prompt again */
break; break;
case CC_ERROR: case CC_ERROR:
@ -602,8 +686,8 @@ el_gets(EditLine *el, int *nread)
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"*** editor ERROR ***\r\n\n"); "*** editor ERROR ***\r\n\n");
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
term_beep(el); terminal_beep(el);
term__flush(el); terminal__flush(el);
break; break;
} }
el->el_state.argument = 1; el->el_state.argument = 1;
@ -613,15 +697,26 @@ el_gets(EditLine *el, int *nread)
break; break;
} }
term__flush(el); /* flush any buffered output */ terminal__flush(el); /* flush any buffered output */
/* make sure the tty is set up correctly */ /* make sure the tty is set up correctly */
if ((el->el_flags & UNBUFFERED) == 0) { if ((el->el_flags & UNBUFFERED) == 0) {
read_finish(el); read_finish(el);
if (nread) *nread = num != -1 ? num : 0;
*nread = num;
} else { } else {
if (nread) *nread = (int)(el->el_line.lastchar - el->el_line.buffer);
*nread = el->el_line.lastchar - el->el_line.buffer;
} }
return (num ? el->el_line.buffer : NULL); goto done;
noedit:
el->el_line.cursor = el->el_line.lastchar = cp;
*cp = '\0';
*nread = (int)(el->el_line.cursor - el->el_line.buffer);
done:
if (*nread == 0) {
if (num == -1) {
*nread = -1;
errno = el->el_errno;
}
return NULL;
} else
return el->el_line.buffer;
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: read.h,v 1.6 2008/04/29 06:53:01 martin Exp $ */ /* $NetBSD: read.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */
/*- /*-
* Copyright (c) 2001 The NetBSD Foundation, Inc. * Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -35,7 +35,7 @@
#ifndef _h_el_read #ifndef _h_el_read
#define _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 { typedef struct el_read_t {
el_rfunc_t read_char; /* Function to read a character */ 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.24 2009/02/05 19:15:26 christos Exp $ */ /* $NetBSD: readline.h,v 1.32 2010/09/16 20:08:52 christos Exp $ */
/*- /*-
* Copyright (c) 1997 The NetBSD Foundation, Inc. * Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -32,6 +32,7 @@
#define _READLINE_H_ #define _READLINE_H_
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h>
/* list of readline stuff supported by editline library's readline wrapper */ /* list of readline stuff supported by editline library's readline wrapper */
@ -42,10 +43,18 @@ typedef void VCPFunction(char *);
typedef char *CPFunction(const char *, int); typedef char *CPFunction(const char *, int);
typedef char **CPPFunction(const char *, int, int); typedef char **CPPFunction(const char *, int, int);
typedef char *rl_compentry_func_t(const char *, 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 { typedef struct _hist_entry {
const char *line; const char *line;
const char *data; histdata_t data;
} HIST_ENTRY; } HIST_ENTRY;
typedef struct _keymap_entry { typedef struct _keymap_entry {
@ -79,12 +88,16 @@ typedef KEYMAP_ENTRY *Keymap;
#define RUBOUT 0x7f #define RUBOUT 0x7f
#define ABORT_CHAR CTRL('G') #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 */ /* global variables used by readline enabled applications */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
extern const char *rl_library_version; extern const char *rl_library_version;
extern int rl_readline_version;
extern char *rl_readline_name; extern char *rl_readline_name;
extern FILE *rl_instream; extern FILE *rl_instream;
extern FILE *rl_outstream; extern FILE *rl_outstream;
@ -138,6 +151,7 @@ int where_history(void);
HIST_ENTRY *current_history(void); HIST_ENTRY *current_history(void);
HIST_ENTRY *history_get(int); HIST_ENTRY *history_get(int);
HIST_ENTRY *remove_history(int); HIST_ENTRY *remove_history(int);
HIST_ENTRY *replace_history_entry(int, const char *, histdata_t);
int history_total_bytes(void); int history_total_bytes(void);
int history_set_pos(int); int history_set_pos(int);
HIST_ENTRY *previous_history(void); HIST_ENTRY *previous_history(void);
@ -147,6 +161,7 @@ int history_search_prefix(const char *, int);
int history_search_pos(const char *, int, int); int history_search_pos(const char *, int, int);
int read_history(const char *); int read_history(const char *);
int write_history(const char *); int write_history(const char *);
int history_truncate_file (const char *, int);
int history_expand(char *, char **); int history_expand(char *, char **);
char **history_tokenize(const char *); char **history_tokenize(const char *);
const char *get_history_event(const char *, int *, int); const char *get_history_event(const char *, int *, int);
@ -161,8 +176,9 @@ char **completion_matches(const char *, CPFunction *);
void rl_display_match_list(char **, int, int); void rl_display_match_list(char **, int, int);
int rl_insert(int, int); int rl_insert(int, int);
int rl_insert_text(const char *);
void rl_reset_terminal(const char *); void rl_reset_terminal(const char *);
int rl_bind_key(int, int (*)(int, int)); int rl_bind_key(int, rl_command_func_t *);
int rl_newline(int, int); int rl_newline(int, int);
void rl_callback_read_char(void); void rl_callback_read_char(void);
void rl_callback_handler_install(const char *, VCPFunction *); void rl_callback_handler_install(const char *, VCPFunction *);
@ -176,6 +192,7 @@ int rl_parse_and_bind(const char *);
int rl_variable_bind(const char *, const char *); int rl_variable_bind(const char *, const char *);
void rl_stuff_char(int); void rl_stuff_char(int);
int rl_add_defun(const char *, Function *, 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_get_screen_size(int *, int *);
void rl_set_screen_size(int, int); void rl_set_screen_size(int, int);
char *rl_filename_completion_function (const char *, int); char *rl_filename_completion_function (const char *, int);
@ -184,6 +201,7 @@ int _rl_qsort_string_compare(char **, char **);
char **rl_completion_matches(const char *, rl_compentry_func_t *); char **rl_completion_matches(const char *, rl_compentry_func_t *);
void rl_forced_update_display(void); void rl_forced_update_display(void);
int rl_set_prompt(const char *); int rl_set_prompt(const char *);
int rl_on_new_line(void);
/* /*
* The following are not implemented * The following are not implemented
@ -193,7 +211,9 @@ Keymap rl_get_keymap(void);
void rl_set_keymap(Keymap); void rl_set_keymap(Keymap);
Keymap rl_make_bare_keymap(void); Keymap rl_make_bare_keymap(void);
int rl_generic_bind(int, const char *, const char *, Keymap); 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 #ifdef __cplusplus
} }
#endif #endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: refresh.c,v 1.28 2008/09/10 15:45:37 christos Exp $ */ /* $NetBSD: refresh.c,v 1.37 2011/07/29 23:44:45 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -40,6 +40,8 @@ static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
#include "chartype.c" /* XXXMYSQL */
/* /*
* refresh.c: Lower level screen refreshing functions * refresh.c: Lower level screen refreshing functions
*/ */
@ -50,14 +52,15 @@ static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
#include "el.h" #include "el.h"
private void re_addc(EditLine *, int); private void re_nextline(EditLine *);
private void re_update_line(EditLine *, char *, char *, int); private void re_addc(EditLine *, Int);
private void re_insert (EditLine *, char *, int, int, char *, int); private void re_update_line(EditLine *, Char *, Char *, int);
private void re_delete(EditLine *, char *, int, int, int); private void re_insert (EditLine *, Char *, int, int, Char *, int);
private void re_fastputc(EditLine *, 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_clear_eol(EditLine *, int, int, int);
private void re__strncopy(char *, char *, size_t); private void re__strncopy(Char *, Char *, size_t);
private void re__copy_and_pad(char *, const char *, size_t); private void re__copy_and_pad(Char *, const Char *, size_t);
#ifdef DEBUG_REFRESH #ifdef DEBUG_REFRESH
private void re_printstr(EditLine *, const char *, char *, char *); private void re_printstr(EditLine *, const char *, char *, char *);
@ -87,45 +90,70 @@ re_printstr(EditLine *el, const char *str, char *f, char *t)
#define ELRE_DEBUG(a, b) #define ELRE_DEBUG(a, b)
#endif #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_terminal.t_size.v) {
int i, lins = el->el_terminal.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_terminal.t_size.v,
(__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n",
el->el_refresh.r_cursor.v, el->el_terminal.t_size.v),
abort());
}
/* re_addc(): /* re_addc():
* Draw c, expanding tabs, control chars etc. * Draw c, expanding tabs, control chars etc.
*/ */
private void private void
re_addc(EditLine *el, int c) re_addc(EditLine *el, Int c)
{ {
switch (ct_chr_class((Char)c)) {
if (el_isprint(c)) { case CHTYPE_TAB: /* expand the tab */
re_putc(el, c, 1);
return;
}
if (c == '\n') { /* expand the newline */
int oldv = el->el_refresh.r_cursor.v;
re_putc(el, '\0', 0); /* assure end of line */
if (oldv == el->el_refresh.r_cursor.v) { /* XXX */
el->el_refresh.r_cursor.h = 0; /* reset cursor pos */
el->el_refresh.r_cursor.v++;
}
return;
}
if (c == '\t') { /* expand the tab */
for (;;) { for (;;) {
re_putc(el, ' ', 1); re_putc(el, ' ', 1);
if ((el->el_refresh.r_cursor.h & 07) == 0) if ((el->el_refresh.r_cursor.h & 07) == 0)
break; /* go until tab stop */ break; /* go until tab stop */
} }
} else if (iscntrl(c)) { break;
re_putc(el, '^', 1); case CHTYPE_NL: {
if (c == '\177') int oldv = el->el_refresh.r_cursor.v;
re_putc(el, '?', 1); re_putc(el, '\0', 0); /* assure end of line */
else if (oldv == el->el_refresh.r_cursor.v) /* XXX */
/* uncontrolify it; works only for iso8859-1 like sets */ re_nextline(el);
re_putc(el, (c | 0100), 1); break;
} else { }
re_putc(el, '\\', 1); case CHTYPE_PRINT:
re_putc(el, (int) ((((unsigned int) c >> 6) & 07) + '0'), 1); re_putc(el, c, 1);
re_putc(el, (int) ((((unsigned int) c >> 3) & 07) + '0'), 1); break;
re_putc(el, (c & 07) + '0', 1); 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;
}
} }
} }
@ -134,43 +162,31 @@ re_addc(EditLine *el, int c)
* Draw the character given * Draw the character given
*/ */
protected void 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_terminal.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) if (!shift)
return; 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) { if (el->el_refresh.r_cursor.h >= el->el_terminal.t_size.h) {
el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h] = '\0';
/* assure end of line */ /* assure end of line */
el->el_refresh.r_cursor.h = 0; /* reset it. */ el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_terminal.t_size.h]
= '\0';
/* re_nextline(el);
* 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());
} }
} }
@ -185,7 +201,7 @@ protected void
re_refresh(EditLine *el) re_refresh(EditLine *el)
{ {
int i, rhdiff; int i, rhdiff;
char *cp, *st; Char *cp, *st;
coord_t cur; coord_t cur;
#ifdef notyet #ifdef notyet
size_t termsz; size_t termsz;
@ -220,7 +236,7 @@ re_refresh(EditLine *el)
/* draw the current input buffer */ /* draw the current input buffer */
#if notyet #if notyet
termsz = el->el_term.t_size.h * el->el_term.t_size.v; termsz = el->el_terminal.t_size.h * el->el_terminal.t_size.v;
if (el->el_line.lastchar - el->el_line.buffer > termsz) { if (el->el_line.lastchar - el->el_line.buffer > termsz) {
/* /*
* If line is longer than terminal, process only part * If line is longer than terminal, process only part
@ -229,26 +245,33 @@ re_refresh(EditLine *el)
size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz; size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz;
st = el->el_line.lastchar - rem st = el->el_line.lastchar - rem
- (termsz - (((rem / el->el_term.t_size.v) - 1) - (termsz - (((rem / el->el_terminal.t_size.v) - 1)
* el->el_term.t_size.v)); * el->el_terminal.t_size.v));
} else } else
#endif #endif
st = el->el_line.buffer; st = el->el_line.buffer;
for (cp = st; cp < el->el_line.lastchar; cp++) { for (cp = st; cp < el->el_line.lastchar; cp++) {
if (cp == el->el_line.cursor) { if (cp == el->el_line.cursor) {
int w = Width(*cp);
/* save for later */ /* save for later */
cur.h = el->el_refresh.r_cursor.h; cur.h = el->el_refresh.r_cursor.h;
cur.v = el->el_refresh.r_cursor.v; 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_terminal.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 */ if (cur.h == -1) { /* if I haven't been set yet, I'm at the end */
cur.h = el->el_refresh.r_cursor.h; cur.h = el->el_refresh.r_cursor.h;
cur.v = el->el_refresh.r_cursor.v; cur.v = el->el_refresh.r_cursor.v;
} }
rhdiff = el->el_term.t_size.h - el->el_refresh.r_cursor.h - rhdiff = el->el_terminal.t_size.h - el->el_refresh.r_cursor.h -
el->el_rprompt.p_pos.h; el->el_rprompt.p_pos.h;
if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v && if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v &&
!el->el_refresh.r_cursor.v && rhdiff > 1) { !el->el_refresh.r_cursor.v && rhdiff > 1) {
@ -271,8 +294,8 @@ re_refresh(EditLine *el)
ELRE_DEBUG(1, (__F, ELRE_DEBUG(1, (__F,
"term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n", "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_terminal.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)); ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv));
for (i = 0; i <= el->el_refresh.r_newcv; i++) { for (i = 0; i <= el->el_refresh.r_newcv; i++) {
@ -287,7 +310,7 @@ re_refresh(EditLine *el)
* leftover stuff. * leftover stuff.
*/ */
re__copy_and_pad(el->el_display[i], el->el_vdisplay[i], re__copy_and_pad(el->el_display[i], el->el_vdisplay[i],
(size_t) el->el_term.t_size.h); (size_t) el->el_terminal.t_size.h);
} }
ELRE_DEBUG(1, (__F, ELRE_DEBUG(1, (__F,
"\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n", "\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n",
@ -295,11 +318,12 @@ re_refresh(EditLine *el)
if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv) if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv)
for (; i <= el->el_refresh.r_oldcv; i++) { for (; i <= el->el_refresh.r_oldcv; i++) {
term_move_to_line(el, i); terminal_move_to_line(el, i);
term_move_to_char(el, 0); terminal_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 */
terminal_clear_EOL(el, (int) Strlen(el->el_display[i]));
#ifdef DEBUG_REFRESH #ifdef DEBUG_REFRESH
term_overwrite(el, "C\b", 2); terminal_overwrite(el, "C\b", (size_t)2);
#endif /* DEBUG_REFRESH */ #endif /* DEBUG_REFRESH */
el->el_display[i][0] = '\0'; el->el_display[i][0] = '\0';
} }
@ -309,8 +333,8 @@ re_refresh(EditLine *el)
"\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n", "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n",
el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v, el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v,
cur.h, cur.v)); cur.h, cur.v));
term_move_to_line(el, cur.v); /* go to where the cursor is */ terminal_move_to_line(el, cur.v); /* go to where the cursor is */
term_move_to_char(el, cur.h); terminal_move_to_char(el, cur.h);
} }
@ -321,10 +345,10 @@ protected void
re_goto_bottom(EditLine *el) re_goto_bottom(EditLine *el)
{ {
term_move_to_line(el, el->el_refresh.r_oldcv); terminal_move_to_line(el, el->el_refresh.r_oldcv);
term__putc(el, '\n'); terminal__putc(el, '\n');
re_clear_display(el); re_clear_display(el);
term__flush(el); terminal__flush(el);
} }
@ -335,9 +359,9 @@ re_goto_bottom(EditLine *el)
private void private void
/*ARGSUSED*/ /*ARGSUSED*/
re_insert(EditLine *el __attribute__((__unused__)), 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) if (num <= 0)
return; return;
@ -346,8 +370,8 @@ re_insert(EditLine *el __attribute__((__unused__)),
ELRE_DEBUG(1, ELRE_DEBUG(1,
(__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n", (__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, d)); num, dat, dlen, ct_encode_string(d)));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));
/* open up the space for num chars */ /* open up the space for num chars */
if (num > 0) { if (num > 0) {
@ -357,19 +381,24 @@ re_insert(EditLine *el __attribute__((__unused__)),
*b-- = *a--; *b-- = *a--;
d[dlen] = '\0'; /* just in case */ d[dlen] = '\0'; /* just in case */
} }
ELRE_DEBUG(1, (__F, ELRE_DEBUG(1, (__F,
"re_insert() after insert: %d at %d max %d, d == \"%s\"\n", "re_insert() after insert: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, d)); num, dat, dlen, ct_encode_string(d)));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s)));
/* copy the characters */ /* copy the characters */
for (a = d + dat; (a < d + dlen) && (num > 0); num--) for (a = d + dat; (a < d + dlen) && (num > 0); num--)
*a++ = *s++; *a++ = *s++;
#ifdef notyet
/* ct_encode_string() uses a static buffer, so we can't conveniently
* encode both d & s here */
ELRE_DEBUG(1, ELRE_DEBUG(1,
(__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n", (__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n",
num, dat, dlen, d, s)); num, dat, dlen, d, s));
ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
#endif
} }
@ -379,9 +408,9 @@ re_insert(EditLine *el __attribute__((__unused__)),
private void private void
/*ARGSUSED*/ /*ARGSUSED*/
re_delete(EditLine *el __attribute__((__unused__)), 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) if (num <= 0)
return; return;
@ -391,7 +420,7 @@ re_delete(EditLine *el __attribute__((__unused__)),
} }
ELRE_DEBUG(1, ELRE_DEBUG(1,
(__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n", (__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 */ /* open up the space for num chars */
if (num > 0) { if (num > 0) {
@ -403,7 +432,7 @@ re_delete(EditLine *el __attribute__((__unused__)),
} }
ELRE_DEBUG(1, ELRE_DEBUG(1,
(__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n", (__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, d)); num, dat, dlen, ct_encode_string(d)));
} }
@ -411,7 +440,7 @@ re_delete(EditLine *el __attribute__((__unused__)),
* Like strncpy without padding. * Like strncpy without padding.
*/ */
private void private void
re__strncopy(char *a, char *b, size_t n) re__strncopy(Char *a, Char *b, size_t n)
{ {
while (n-- && *b) while (n-- && *b)
@ -422,7 +451,7 @@ re__strncopy(char *a, char *b, size_t n)
* Find the number of characters we need to clear till the end of line * 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 * 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 * 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. * number of characters between the new and old line.
*/ */
private void private void
@ -442,7 +471,7 @@ re_clear_eol(EditLine *el, int fx, int sx, int diff)
diff = sx; diff = sx;
ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff)); ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff));
term_clear_EOL(el, diff); terminal_clear_EOL(el, diff);
} }
/***************************************************************** /*****************************************************************
@ -470,12 +499,13 @@ new: eddie> Oh, my little buggy says to me, as lurgid as
#define MIN_END_KEEP 4 #define MIN_END_KEEP 4
private void 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 *o, *n, *p, c;
char *ofd, *ols, *oe, *nfd, *nls, *ne; Char *ofd, *ols, *oe, *nfd, *nls, *ne;
char *osb, *ose, *nsb, *nse; Char *osb, *ose, *nsb, *nse;
int fx, sx; int fx, sx;
size_t len;
/* /*
* find first diff * find first diff
@ -602,12 +632,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 * fx is the number of characters we need to insert/delete: in the
* beginning to bring the two same begins together * 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 * sx is the number of characters we need to insert/delete: in the
* end to bring the two same last parts together * 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 (!EL_CAN_INSERT) {
if (fx > 0) { if (fx > 0) {
@ -656,8 +686,8 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/* /*
* Now that we are done with pragmatics we recompute fx, sx * Now that we are done with pragmatics we recompute fx, sx
*/ */
fx = (nsb - nfd) - (osb - ofd); fx = (int)((nsb - nfd) - (osb - ofd));
sx = (nls - nse) - (ols - ose); sx = (int)((nls - nse) - (ols - ose));
ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx)); ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx));
ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n", ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
@ -688,7 +718,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* don't have to change the line, we don't move to it. el_cursor.h to * don't have to change the line, we don't move to it. el_cursor.h to
* first diff char * first diff char
*/ */
term_move_to_line(el, i); terminal_move_to_line(el, i);
/* /*
* at this point we have something like this: * at this point we have something like this:
@ -712,7 +742,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* if we have a net insert on the first difference, AND inserting the * if we have a net insert on the first difference, AND inserting the
* net amount ((nsb-nfd) - (osb-ofd)) won't push the last useful * net amount ((nsb-nfd) - (osb-ofd)) won't push the last useful
* character (which is ne if nls != ne, otherwise is nse) off the edge * character (which is ne if nls != ne, otherwise is nse) off the edge
* of the screen (el->el_term.t_size.h) else we do the deletes first * of the screen (el->el_terminal.t_size.h) else we do the deletes first
* so that we keep everything we need to. * so that we keep everything we need to.
*/ */
@ -734,13 +764,13 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* No insert or delete * No insert or delete
*/ */
if ((nsb != nfd) && fx > 0 && if ((nsb != nfd) && fx > 0 &&
((p - old) + fx <= el->el_term.t_size.h)) { ((p - old) + fx <= el->el_terminal.t_size.h)) {
ELRE_DEBUG(1, ELRE_DEBUG(1,
(__F, "first diff insert at %d...\r\n", nfd - new)); (__F, "first diff insert at %d...\r\n", nfd - new));
/* /*
* Move to the first char to insert, where the first diff is. * Move to the first char to insert, where the first diff is.
*/ */
term_move_to_char(el, nfd - new); terminal_move_to_char(el, (int)(nfd - new));
/* /*
* Check if we have stuff to keep at end * Check if we have stuff to keep at end
*/ */
@ -752,21 +782,22 @@ re_update_line(EditLine *el, char *old, char *new, int i)
if (fx > 0) { if (fx > 0) {
ELRE_DEBUG(!EL_CAN_INSERT, (__F, ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in early first diff\n")); "ERROR: cannot insert in early first diff\n"));
term_insertwrite(el, nfd, fx); terminal_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); el->el_terminal.t_size.h, nfd, fx);
} }
/* /*
* write (nsb-nfd) - fx chars of new starting at * write (nsb-nfd) - fx chars of new starting at
* (nfd + fx) * (nfd + fx)
*/ */
term_overwrite(el, nfd + fx, (nsb - nfd) - fx); len = (size_t) ((nsb - nfd) - fx);
re__strncopy(ofd + fx, nfd + fx, terminal_overwrite(el, (nfd + fx), len);
(size_t) ((nsb - nfd) - fx)); re__strncopy(ofd + fx, nfd + fx, len);
} else { } else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n")); ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
term_overwrite(el, nfd, (nsb - nfd)); len = (size_t)(nsb - nfd);
re__strncopy(ofd, nfd, (size_t) (nsb - nfd)); terminal_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
/* /*
* Done * Done
*/ */
@ -778,7 +809,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/* /*
* move to the first char to delete where the first diff is * move to the first char to delete where the first diff is
*/ */
term_move_to_char(el, ofd - old); terminal_move_to_char(el, (int)(ofd - old));
/* /*
* Check if we have stuff to save * Check if we have stuff to save
*/ */
@ -791,15 +822,16 @@ re_update_line(EditLine *el, char *old, char *new, int i)
if (fx < 0) { if (fx < 0) {
ELRE_DEBUG(!EL_CAN_DELETE, (__F, ELRE_DEBUG(!EL_CAN_DELETE, (__F,
"ERROR: cannot delete in first diff\n")); "ERROR: cannot delete in first diff\n"));
term_deletechars(el, -fx); terminal_deletechars(el, -fx);
re_delete(el, old, ofd - old, re_delete(el, old, (int)(ofd - old),
el->el_term.t_size.h, -fx); el->el_terminal.t_size.h, -fx);
} }
/* /*
* write (nsb-nfd) chars of new starting at nfd * write (nsb-nfd) chars of new starting at nfd
*/ */
term_overwrite(el, nfd, (nsb - nfd)); len = (size_t) (nsb - nfd);
re__strncopy(ofd, nfd, (size_t) (nsb - nfd)); terminal_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
} else { } else {
ELRE_DEBUG(1, (__F, ELRE_DEBUG(1, (__F,
@ -807,8 +839,9 @@ re_update_line(EditLine *el, char *old, char *new, int i)
/* /*
* write (nsb-nfd) chars of new starting at nfd * write (nsb-nfd) chars of new starting at nfd
*/ */
term_overwrite(el, nfd, (nsb - nfd)); terminal_overwrite(el, nfd, (size_t)(nsb - nfd));
re_clear_eol(el, fx, sx, (oe - old) - (ne - new)); re_clear_eol(el, fx, sx,
(int)((oe - old) - (ne - new)));
/* /*
* Done * Done
*/ */
@ -817,7 +850,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
} else } else
fx = 0; fx = 0;
if (sx < 0 && (ose - old) + fx < el->el_term.t_size.h) { if (sx < 0 && (ose - old) + fx < el->el_terminal.t_size.h) {
ELRE_DEBUG(1, (__F, ELRE_DEBUG(1, (__F,
"second diff delete at %d...\r\n", (ose - old) + fx)); "second diff delete at %d...\r\n", (ose - old) + fx));
/* /*
@ -827,7 +860,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* fx is the number of characters inserted (+) or deleted (-) * fx is the number of characters inserted (+) or deleted (-)
*/ */
term_move_to_char(el, (ose - old) + fx); terminal_move_to_char(el, (int)((ose - old) + fx));
/* /*
* Check if we have stuff to save * Check if we have stuff to save
*/ */
@ -839,17 +872,18 @@ re_update_line(EditLine *el, char *old, char *new, int i)
if (sx < 0) { if (sx < 0) {
ELRE_DEBUG(!EL_CAN_DELETE, (__F, ELRE_DEBUG(!EL_CAN_DELETE, (__F,
"ERROR: cannot delete in second diff\n")); "ERROR: cannot delete in second diff\n"));
term_deletechars(el, -sx); terminal_deletechars(el, -sx);
} }
/* /*
* write (nls-nse) chars of new starting at nse * write (nls-nse) chars of new starting at nse
*/ */
term_overwrite(el, nse, (nls - nse)); terminal_overwrite(el, nse, (size_t)(nls - nse));
} else { } else {
ELRE_DEBUG(1, (__F, ELRE_DEBUG(1, (__F,
"but with nothing left to save\r\n")); "but with nothing left to save\r\n"));
term_overwrite(el, nse, (nls - nse)); terminal_overwrite(el, nse, (size_t)(nls - nse));
re_clear_eol(el, fx, sx, (oe - old) - (ne - new)); re_clear_eol(el, fx, sx,
(int)((oe - old) - (ne - new)));
} }
} }
/* /*
@ -859,7 +893,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n", ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n",
nfd - new)); nfd - new));
term_move_to_char(el, nfd - new); terminal_move_to_char(el, (int)(nfd - new));
/* /*
* Check if we have stuff to keep at the end * Check if we have stuff to keep at the end
*/ */
@ -870,28 +904,29 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* to zero above as a flag saying that we hadn't done * to zero above as a flag saying that we hadn't done
* an early first insert. * an early first insert.
*/ */
fx = (nsb - nfd) - (osb - ofd); fx = (int)((nsb - nfd) - (osb - ofd));
if (fx > 0) { if (fx > 0) {
/* /*
* insert fx chars of new starting at nfd * insert fx chars of new starting at nfd
*/ */
ELRE_DEBUG(!EL_CAN_INSERT, (__F, ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in late first diff\n")); "ERROR: cannot insert in late first diff\n"));
term_insertwrite(el, nfd, fx); terminal_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); el->el_terminal.t_size.h, nfd, fx);
} }
/* /*
* write (nsb-nfd) - fx chars of new starting at * write (nsb-nfd) - fx chars of new starting at
* (nfd + fx) * (nfd + fx)
*/ */
term_overwrite(el, nfd + fx, (nsb - nfd) - fx); len = (size_t) ((nsb - nfd) - fx);
re__strncopy(ofd + fx, nfd + fx, terminal_overwrite(el, (nfd + fx), len);
(size_t) ((nsb - nfd) - fx)); re__strncopy(ofd + fx, nfd + fx, len);
} else { } else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n")); ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
term_overwrite(el, nfd, (nsb - nfd)); len = (size_t) (nsb - nfd);
re__strncopy(ofd, nfd, (size_t) (nsb - nfd)); terminal_overwrite(el, nfd, len);
re__strncopy(ofd, nfd, len);
} }
} }
/* /*
@ -899,24 +934,25 @@ re_update_line(EditLine *el, char *old, char *new, int i)
*/ */
if (sx >= 0) { if (sx >= 0) {
ELRE_DEBUG(1, (__F, ELRE_DEBUG(1, (__F,
"second diff insert at %d...\r\n", nse - new)); "second diff insert at %d...\r\n", (int)(nse - new)));
term_move_to_char(el, nse - new); terminal_move_to_char(el, (int)(nse - new));
if (ols != oe) { if (ols != oe) {
ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n")); ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n"));
if (sx > 0) { if (sx > 0) {
/* insert sx chars of new starting at nse */ /* insert sx chars of new starting at nse */
ELRE_DEBUG(!EL_CAN_INSERT, (__F, ELRE_DEBUG(!EL_CAN_INSERT, (__F,
"ERROR: cannot insert in second diff\n")); "ERROR: cannot insert in second diff\n"));
term_insertwrite(el, nse, sx); terminal_insertwrite(el, nse, sx);
} }
/* /*
* write (nls-nse) - sx chars of new starting at * write (nls-nse) - sx chars of new starting at
* (nse + sx) * (nse + sx)
*/ */
term_overwrite(el, nse + sx, (nls - nse) - sx); terminal_overwrite(el, (nse + sx),
(size_t)((nls - nse) - sx));
} else { } else {
ELRE_DEBUG(1, (__F, "without anything to save\r\n")); ELRE_DEBUG(1, (__F, "without anything to save\r\n"));
term_overwrite(el, nse, (nls - nse)); terminal_overwrite(el, nse, (size_t)(nls - nse));
/* /*
* No need to do a clear-to-end here because we were * No need to do a clear-to-end here because we were
@ -933,7 +969,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* Copy string and pad with spaces * Copy string and pad with spaces
*/ */
private void private void
re__copy_and_pad(char *dst, const char *src, size_t width) re__copy_and_pad(Char *dst, const Char *src, size_t width)
{ {
size_t i; size_t i;
@ -956,8 +992,8 @@ re__copy_and_pad(char *dst, const char *src, size_t width)
protected void protected void
re_refresh_cursor(EditLine *el) re_refresh_cursor(EditLine *el)
{ {
char *cp, c; Char *cp;
int h, v, th; int h, v, th, w;
if (el->el_line.cursor >= el->el_line.lastchar) { if (el->el_line.cursor >= el->el_line.lastchar) {
if (el->el_map.current == el->el_map.alt if (el->el_map.current == el->el_map.alt
@ -970,47 +1006,46 @@ re_refresh_cursor(EditLine *el)
/* first we must find where the cursor is... */ /* first we must find where the cursor is... */
h = el->el_prompt.p_pos.h; h = el->el_prompt.p_pos.h;
v = el->el_prompt.p_pos.v; v = el->el_prompt.p_pos.v;
th = el->el_term.t_size.h; /* optimize for speed */ th = el->el_terminal.t_size.h; /* optimize for speed */
/* do input buffer to el->el_line.cursor */ /* do input buffer to el->el_line.cursor */
for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) { for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) {
c = *cp; switch (ct_chr_class(*cp)) {
h++; /* all chars at least this long */ case CHTYPE_NL: /* handle newline in data part too */
if (c == '\n') {/* handle newline in data part too */
h = 0; h = 0;
v++; v++;
} else { break;
if (c == '\t') { /* if a tab, to next tab stop */ case CHTYPE_TAB: /* if a tab, to next tab stop */
while (h & 07) { while (++h & 07)
h++; continue;
} break;
} else if (iscntrl((unsigned char) c)) { default:
/* if control char */ w = Width(*cp);
h++; if (w > 1 && h + w > th) { /* won't fit on line */
if (h > th) { /* if overflow, compensate */ h = 0;
h = 1; v++;
v++;
}
} else if (!el_isprint((unsigned char) c)) {
h += 3;
if (h > th) { /* if overflow, compensate */
h = h - th;
v++;
}
} }
} h += ct_visual_width(*cp);
break;
}
if (h >= th) { /* check, extra long tabs picked up here also */ if (h >= th) { /* check, extra long tabs picked up here also */
h = 0; h -= th;
v++; 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 */ /* now go there */
term_move_to_line(el, v); terminal_move_to_line(el, v);
term_move_to_char(el, h); terminal_move_to_char(el, h);
term__flush(el); terminal__flush(el);
} }
@ -1018,12 +1053,19 @@ re_refresh_cursor(EditLine *el)
* Add a character fast. * Add a character fast.
*/ */
private void 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_terminal.t_size.h)
re_fastputc(el, ' ');
term__putc(el, c); terminal__putc(el, c);
el->el_display[el->el_cursor.v][el->el_cursor.h++] = c; el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
if (el->el_cursor.h >= el->el_term.t_size.h) { while (--w > 0)
el->el_display[el->el_cursor.v][el->el_cursor.h++]
= MB_FILL_CHAR;
if (el->el_cursor.h >= el->el_terminal.t_size.h) {
/* if we must overflow */ /* if we must overflow */
el->el_cursor.h = 0; el->el_cursor.h = 0;
@ -1033,27 +1075,27 @@ re_fastputc(EditLine *el, int c)
* We do this via pointer shuffling - it's safe in this case * We do this via pointer shuffling - it's safe in this case
* and we avoid memcpy(). * and we avoid memcpy().
*/ */
if (el->el_cursor.v + 1 >= el->el_term.t_size.v) { if (el->el_cursor.v + 1 >= el->el_terminal.t_size.v) {
int i, lins = el->el_term.t_size.v; int i, lins = el->el_terminal.t_size.v;
char *firstline = el->el_display[0]; Char *firstline = el->el_display[0];
for(i=1; i < lins; i++) for(i = 1; i < lins; i++)
el->el_display[i-1] = el->el_display[i]; el->el_display[i - 1] = el->el_display[i];
re__copy_and_pad(firstline, "", 0); re__copy_and_pad(firstline, STR(""), (size_t)0);
el->el_display[i-1] = firstline; el->el_display[i - 1] = firstline;
} else { } else {
el->el_cursor.v++; el->el_cursor.v++;
el->el_refresh.r_oldcv++; el->el_refresh.r_oldcv++;
} }
if (EL_HAS_AUTO_MARGINS) { if (EL_HAS_AUTO_MARGINS) {
if (EL_HAS_MAGIC_MARGINS) { if (EL_HAS_MAGIC_MARGINS) {
term__putc(el, ' '); terminal__putc(el, ' ');
term__putc(el, '\b'); terminal__putc(el, '\b');
} }
} else { } else {
term__putc(el, '\r'); terminal__putc(el, '\r');
term__putc(el, '\n'); terminal__putc(el, '\n');
} }
} }
} }
@ -1066,7 +1108,7 @@ re_fastputc(EditLine *el, int c)
protected void protected void
re_fastaddc(EditLine *el) re_fastaddc(EditLine *el)
{ {
char c; Char c;
int rhdiff; int rhdiff;
c = el->el_line.cursor[-1]; c = el->el_line.cursor[-1];
@ -1075,25 +1117,30 @@ re_fastaddc(EditLine *el)
re_refresh(el); /* too hard to handle */ re_refresh(el); /* too hard to handle */
return; return;
} }
rhdiff = el->el_term.t_size.h - el->el_cursor.h - rhdiff = el->el_terminal.t_size.h - el->el_cursor.h -
el->el_rprompt.p_pos.h; el->el_rprompt.p_pos.h;
if (el->el_rprompt.p_pos.h && rhdiff < 3) { if (el->el_rprompt.p_pos.h && rhdiff < 3) {
re_refresh(el); /* clear out rprompt if less than 1 char gap */ re_refresh(el); /* clear out rprompt if less than 1 char gap */
return; return;
} /* else (only do at end of line, no TAB) */ } /* else (only do at end of line, no TAB) */
if (iscntrl((unsigned char) c)) { /* if control char, do caret */ switch (ct_chr_class(c)) {
char mc = (c == '\177') ? '?' : (c | 0100); case CHTYPE_TAB: /* already handled, should never happen here */
re_fastputc(el, '^'); break;
re_fastputc(el, mc); case CHTYPE_NL:
} else if (el_isprint((unsigned char) c)) { /* normal char */ case CHTYPE_PRINT:
re_fastputc(el, c); re_fastputc(el, c);
} else { break;
re_fastputc(el, '\\'); case CHTYPE_ASCIICTL:
re_fastputc(el, (int)(((((unsigned int)c) >> 6) & 3) + '0')); case CHTYPE_NONPRINT: {
re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0')); Char visbuf[VISUAL_WIDTH_MAX];
re_fastputc(el, (c & 7) + '0'); 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(el); }
terminal__flush(el);
} }
@ -1107,7 +1154,7 @@ re_clear_display(EditLine *el)
el->el_cursor.v = 0; el->el_cursor.v = 0;
el->el_cursor.h = 0; el->el_cursor.h = 0;
for (i = 0; i < el->el_term.t_size.v; i++) for (i = 0; i < el->el_terminal.t_size.v; i++)
el->el_display[i][0] = '\0'; el->el_display[i][0] = '\0';
el->el_refresh.r_oldcv = 0; el->el_refresh.r_oldcv = 0;
} }
@ -1122,17 +1169,16 @@ re_clear_lines(EditLine *el)
if (EL_CAN_CEOL) { if (EL_CAN_CEOL) {
int i; int i;
term_move_to_char(el, 0); for (i = el->el_refresh.r_oldcv; i >= 0; i--) {
for (i = 0; i <= el->el_refresh.r_oldcv; i++) {
/* for each line on the screen */ /* for each line on the screen */
term_move_to_line(el, i); terminal_move_to_line(el, i);
term_clear_EOL(el, el->el_term.t_size.h); terminal_move_to_char(el, 0);
terminal_clear_EOL(el, el->el_terminal.t_size.h);
} }
term_move_to_line(el, 0);
} else { } else {
term_move_to_line(el, el->el_refresh.r_oldcv); terminal_move_to_line(el, el->el_refresh.r_oldcv);
/* go to last line */ /* go to last line */
term__putc(el, '\r'); /* go to BOL */ terminal__putc(el, '\r'); /* go to BOL */
term__putc(el, '\n'); /* go to new line */ terminal__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 * Copyright (c) 1992, 1993
@ -48,7 +48,7 @@ typedef struct {
int r_newcv; int r_newcv;
} el_refresh_t; } 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_lines(EditLine *);
protected void re_clear_display(EditLine *); protected void re_clear_display(EditLine *);
protected void re_refresh(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.30 2011/10/04 15:27:04 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -65,15 +65,16 @@ protected int
search_init(EditLine *el) 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) if (el->el_search.patbuf == NULL)
return (-1); return -1;
el->el_search.patlen = 0; el->el_search.patlen = 0;
el->el_search.patdir = -1; el->el_search.patdir = -1;
el->el_search.chacha = '\0'; el->el_search.chacha = '\0';
el->el_search.chadir = CHAR_FWD; el->el_search.chadir = CHAR_FWD;
el->el_search.chatflg = 0; el->el_search.chatflg = 0;
return (0); return 0;
} }
@ -84,7 +85,7 @@ protected void
search_end(EditLine *el) search_end(EditLine *el)
{ {
el_free((ptr_t) el->el_search.patbuf); el_free(el->el_search.patbuf);
el->el_search.patbuf = NULL; el->el_search.patbuf = NULL;
} }
@ -105,8 +106,11 @@ regerror(const char *msg)
* Return if string matches pattern * Return if string matches pattern
*/ */
protected int 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) #if defined (REGEX)
regex_t re; regex_t re;
int rv; int rv;
@ -118,30 +122,31 @@ el_match(const char *str, const char *pat)
extern int re_exec(const char *); extern int re_exec(const char *);
#endif #endif
if (strstr(str, pat) != NULL) if (Strstr(str, pat) != 0)
return (1); return 1;
#if defined(REGEX) #if defined(REGEX)
if (regcomp(&re, pat, 0) == 0) { if (regcomp(&re, ct_encode_string(pat, &conv), 0) == 0) {
rv = regexec(&re, str, 0, NULL, 0) == 0; rv = regexec(&re, ct_encode_string(str, &conv), (size_t)0, NULL,
0) == 0;
regfree(&re); regfree(&re);
} else { } else {
rv = 0; rv = 0;
} }
return (rv); return rv;
#elif defined(REGEXP) #elif defined(REGEXP)
if ((re = regcomp(pat)) != NULL) { if ((re = regcomp(ct_encode_string(pat, &conv))) != NULL) {
rv = regexec(re, str); rv = regexec(re, ct_encode_string(str, &conv));
free((ptr_t) re); el_free(re);
} else { } else {
rv = 0; rv = 0;
} }
return (rv); return rv;
#else #else
if (re_comp(pat) != NULL) if (re_comp(ct_encode_string(pat, &conv)) != NULL)
return (0); return 0;
else else
return (re_exec(str) == 1); return re_exec(ct_encode_string(str, &conv) == 1);
#endif #endif
} }
@ -150,14 +155,14 @@ el_match(const char *str, const char *pat)
* return True if the pattern matches the prefix * return True if the pattern matches the prefix
*/ */
protected int protected int
c_hmatch(EditLine *el, const char *str) c_hmatch(EditLine *el, const Char *str)
{ {
#ifdef SDEBUG #ifdef SDEBUG
(void) fprintf(el->el_errfile, "match `%s' with `%s'\n", (void) fprintf(el->el_errfile, "match `%s' with `%s'\n",
el->el_search.patbuf, str); el->el_search.patbuf, str);
#endif /* SDEBUG */ #endif /* SDEBUG */
return (el_match(str, el->el_search.patbuf)); return el_match(str, el->el_search.patbuf);
} }
@ -169,15 +174,16 @@ c_setpat(EditLine *el)
{ {
if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY && if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY &&
el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) { el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) {
el->el_search.patlen = EL_CURSOR(el) - el->el_line.buffer; el->el_search.patlen =
(size_t)(EL_CURSOR(el) - el->el_line.buffer);
if (el->el_search.patlen >= EL_BUFSIZ) if (el->el_search.patlen >= EL_BUFSIZ)
el->el_search.patlen = EL_BUFSIZ - 1; el->el_search.patlen = EL_BUFSIZ - 1;
if (el->el_search.patlen != 0) { 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.patlen);
el->el_search.patbuf[el->el_search.patlen] = '\0'; el->el_search.patbuf[el->el_search.patlen] = '\0';
} else } else
el->el_search.patlen = strlen(el->el_search.patbuf); el->el_search.patlen = Strlen(el->el_search.patbuf);
} }
#ifdef SDEBUG #ifdef SDEBUG
(void) fprintf(el->el_errfile, "\neventno = %d\n", (void) fprintf(el->el_errfile, "\neventno = %d\n",
@ -198,23 +204,24 @@ c_setpat(EditLine *el)
protected el_action_t protected el_action_t
ce_inc_search(EditLine *el, int dir) 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'}; STRbck[] = {'b', 'c', 'k', '\0'};
static char pchar = ':';/* ':' = normal, '?' = failed */ static Char pchar = ':';/* ':' = normal, '?' = failed */
static char endcmd[2] = {'\0', '\0'}; static Char endcmd[2] = {'\0', '\0'};
char ch, *ocursor = el->el_line.cursor, oldpchar = pchar; Char ch, *ocursor = el->el_line.cursor, oldpchar = pchar;
const char *cp; const Char *cp;
el_action_t ret = CC_NORM; el_action_t ret = CC_NORM;
int ohisteventno = el->el_history.eventno; int ohisteventno = el->el_history.eventno;
int oldpatlen = el->el_search.patlen; size_t oldpatlen = el->el_search.patlen;
int newdir = dir; int newdir = dir;
int done, redo; 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) el->el_search.patlen >= el->el_line.limit)
return (CC_ERROR); return CC_ERROR;
for (;;) { for (;;) {
@ -241,14 +248,14 @@ ce_inc_search(EditLine *el, int dir)
*el->el_line.lastchar = '\0'; *el->el_line.lastchar = '\0';
re_refresh(el); re_refresh(el);
if (el_getc(el, &ch) != 1) if (FUN(el,getc)(el, &ch) != 1)
return (ed_end_of_file(el, 0)); return ed_end_of_file(el, 0);
switch (el->el_map.current[(unsigned char) ch]) { switch (el->el_map.current[(unsigned char) ch]) {
case ED_INSERT: case ED_INSERT:
case ED_DIGIT: case ED_DIGIT:
if (el->el_search.patlen >= EL_BUFSIZ - LEN) if (el->el_search.patlen >= EL_BUFSIZ - LEN)
term_beep(el); terminal_beep(el);
else { else {
el->el_search.patbuf[el->el_search.patlen++] = el->el_search.patbuf[el->el_search.patlen++] =
ch; ch;
@ -273,7 +280,7 @@ ce_inc_search(EditLine *el, int dir)
if (el->el_search.patlen > LEN) if (el->el_search.patlen > LEN)
done++; done++;
else else
term_beep(el); terminal_beep(el);
break; break;
default: default:
@ -297,7 +304,7 @@ ce_inc_search(EditLine *el, int dir)
*el->el_line.cursor != '\n') { *el->el_line.cursor != '\n') {
if (el->el_search.patlen >= if (el->el_search.patlen >=
EL_BUFSIZ - LEN) { EL_BUFSIZ - LEN) {
term_beep(el); terminal_beep(el);
break; break;
} }
el->el_search.patbuf[el->el_search.patlen++] = el->el_search.patbuf[el->el_search.patlen++] =
@ -310,14 +317,14 @@ ce_inc_search(EditLine *el, int dir)
re_refresh(el); re_refresh(el);
break; break;
} else if (isglob(*cp)) { } else if (isglob(*cp)) {
term_beep(el); terminal_beep(el);
break; break;
} }
break; break;
default: /* Terminate and execute cmd */ default: /* Terminate and execute cmd */
endcmd[0] = ch; endcmd[0] = ch;
el_push(el, endcmd); FUN(el,push)(el, endcmd);
/* FALLTHROUGH */ /* FALLTHROUGH */
case 0033: /* ESC: Terminate */ case 0033: /* ESC: Terminate */
@ -379,9 +386,10 @@ ce_inc_search(EditLine *el, int dir)
/* avoid c_setpat */ /* avoid c_setpat */
el->el_state.lastcmd = el->el_state.lastcmd =
(el_action_t) newdir; (el_action_t) newdir;
ret = newdir == ED_SEARCH_PREV_HISTORY ? ret = (el_action_t)
(newdir == ED_SEARCH_PREV_HISTORY ?
ed_search_prev_history(el, 0) : ed_search_prev_history(el, 0) :
ed_search_next_history(el, 0); ed_search_next_history(el, 0));
if (ret != CC_ERROR) { if (ret != CC_ERROR) {
el->el_line.cursor = newdir == el->el_line.cursor = newdir ==
ED_SEARCH_PREV_HISTORY ? ED_SEARCH_PREV_HISTORY ?
@ -395,13 +403,13 @@ ce_inc_search(EditLine *el, int dir)
el->el_search.patbuf[el->el_search.patlen] = el->el_search.patbuf[el->el_search.patlen] =
'\0'; '\0';
if (ret == CC_ERROR) { if (ret == CC_ERROR) {
term_beep(el); terminal_beep(el);
if (el->el_history.eventno != if (el->el_history.eventno !=
ohisteventno) { ohisteventno) {
el->el_history.eventno = el->el_history.eventno =
ohisteventno; ohisteventno;
if (hist_get(el) == CC_ERROR) if (hist_get(el) == CC_ERROR)
return (CC_ERROR); return CC_ERROR;
} }
el->el_line.cursor = ocursor; el->el_line.cursor = ocursor;
pchar = '?'; pchar = '?';
@ -426,14 +434,14 @@ ce_inc_search(EditLine *el, int dir)
if (el->el_history.eventno != ohisteventno) { if (el->el_history.eventno != ohisteventno) {
el->el_history.eventno = ohisteventno; el->el_history.eventno = ohisteventno;
if (hist_get(el) == CC_ERROR) if (hist_get(el) == CC_ERROR)
return (CC_ERROR); return CC_ERROR;
} }
el->el_line.cursor = ocursor; el->el_line.cursor = ocursor;
if (ret == CC_ERROR) if (ret == CC_ERROR)
re_refresh(el); re_refresh(el);
} }
if (done || ret != CC_NORM) if (done || ret != CC_NORM)
return (ret); return ret;
} }
} }
@ -444,9 +452,9 @@ ce_inc_search(EditLine *el, int dir)
protected el_action_t protected el_action_t
cv_search(EditLine *el, int dir) cv_search(EditLine *el, int dir)
{ {
char ch; Char ch;
char tmpbuf[EL_BUFSIZ]; Char tmpbuf[EL_BUFSIZ];
int tmplen; ssize_t tmplen;
#ifdef ANCHOR #ifdef ANCHOR
tmpbuf[0] = '.'; tmpbuf[0] = '.';
@ -457,7 +465,7 @@ cv_search(EditLine *el, int dir)
el->el_search.patdir = dir; el->el_search.patdir = dir;
tmplen = c_gets(el, &tmpbuf[LEN], 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) if (tmplen == -1)
return CC_REFRESH; return CC_REFRESH;
@ -471,16 +479,16 @@ cv_search(EditLine *el, int dir)
*/ */
if (el->el_search.patlen == 0) { if (el->el_search.patlen == 0) {
re_refresh(el); re_refresh(el);
return (CC_ERROR); return CC_ERROR;
} }
#ifdef ANCHOR #ifdef ANCHOR
if (el->el_search.patbuf[0] != '.' && if (el->el_search.patbuf[0] != '.' &&
el->el_search.patbuf[0] != '*') { el->el_search.patbuf[0] != '*') {
(void) strncpy(tmpbuf, el->el_search.patbuf, (void) Strncpy(tmpbuf, el->el_search.patbuf,
sizeof(tmpbuf) - 1); sizeof(tmpbuf) / sizeof(*tmpbuf) - 1);
el->el_search.patbuf[0] = '.'; el->el_search.patbuf[0] = '.';
el->el_search.patbuf[1] = '*'; 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_BUFSIZ - 3);
el->el_search.patlen++; el->el_search.patlen++;
el->el_search.patbuf[el->el_search.patlen++] = '.'; el->el_search.patbuf[el->el_search.patlen++] = '.';
@ -494,21 +502,21 @@ cv_search(EditLine *el, int dir)
tmpbuf[tmplen++] = '*'; tmpbuf[tmplen++] = '*';
#endif #endif
tmpbuf[tmplen] = '\0'; 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_search.patlen = (size_t)tmplen;
} }
el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */ el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */
el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer; el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer;
if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) : if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) :
ed_search_next_history(el, 0)) == CC_ERROR) { ed_search_next_history(el, 0)) == CC_ERROR) {
re_refresh(el); re_refresh(el);
return (CC_ERROR); return CC_ERROR;
} }
if (ch == 0033) { if (ch == 0033) {
re_refresh(el); re_refresh(el);
return ed_newline(el, 0); return ed_newline(el, 0);
} }
return (CC_REFRESH); return CC_REFRESH;
} }
@ -518,9 +526,9 @@ cv_search(EditLine *el, int dir)
protected el_action_t protected el_action_t
ce_search_line(EditLine *el, int dir) ce_search_line(EditLine *el, int dir)
{ {
char *cp = el->el_line.cursor; Char *cp = el->el_line.cursor;
char *pattern = el->el_search.patbuf; Char *pattern = el->el_search.patbuf;
char oc, *ocp; Char oc, *ocp;
#ifdef ANCHOR #ifdef ANCHOR
ocp = &pattern[1]; ocp = &pattern[1];
oc = *ocp; oc = *ocp;
@ -535,21 +543,21 @@ ce_search_line(EditLine *el, int dir)
if (el_match(cp, ocp)) { if (el_match(cp, ocp)) {
*ocp = oc; *ocp = oc;
el->el_line.cursor = cp; el->el_line.cursor = cp;
return (CC_NORM); return CC_NORM;
} }
} }
*ocp = oc; *ocp = oc;
return (CC_ERROR); return CC_ERROR;
} else { } else {
for (; *cp != '\0' && cp < el->el_line.limit; cp++) { for (; *cp != '\0' && cp < el->el_line.limit; cp++) {
if (el_match(cp, ocp)) { if (el_match(cp, ocp)) {
*ocp = oc; *ocp = oc;
el->el_line.cursor = cp; el->el_line.cursor = cp;
return (CC_NORM); return CC_NORM;
} }
} }
*ocp = oc; *ocp = oc;
return (CC_ERROR); return CC_ERROR;
} }
} }
@ -558,12 +566,12 @@ ce_search_line(EditLine *el, int dir)
* Vi repeat search * Vi repeat search
*/ */
protected el_action_t protected el_action_t
cv_repeat_srch(EditLine *el, int c) cv_repeat_srch(EditLine *el, Int c)
{ {
#ifdef SDEBUG #ifdef SDEBUG
(void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n", (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 #endif
el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */ el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */
@ -571,11 +579,11 @@ cv_repeat_srch(EditLine *el, int c)
switch (c) { switch (c) {
case ED_SEARCH_NEXT_HISTORY: case ED_SEARCH_NEXT_HISTORY:
return (ed_search_next_history(el, 0)); return ed_search_next_history(el, 0);
case ED_SEARCH_PREV_HISTORY: case ED_SEARCH_PREV_HISTORY:
return (ed_search_prev_history(el, 0)); return ed_search_prev_history(el, 0);
default: default:
return (CC_ERROR); return CC_ERROR;
} }
} }
@ -584,16 +592,16 @@ cv_repeat_srch(EditLine *el, int c)
* Vi character search * Vi character search
*/ */
protected el_action_t 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) if (ch == 0)
return CC_ERROR; return CC_ERROR;
if (ch == -1) { if (ch == (Int)-1) {
char c; Char c;
if (el_getc(el, &c) != 1) if (FUN(el,getc)(el, &c) != 1)
return ed_end_of_file(el, 0); return ed_end_of_file(el, 0);
ch = c; ch = c;
} }
@ -601,18 +609,18 @@ cv_csearch(EditLine *el, int direction, int ch, int count, int tflag)
/* Save for ';' and ',' commands */ /* Save for ';' and ',' commands */
el->el_search.chacha = ch; el->el_search.chacha = ch;
el->el_search.chadir = direction; el->el_search.chadir = direction;
el->el_search.chatflg = tflag; el->el_search.chatflg = (char)tflag;
cp = el->el_line.cursor; cp = el->el_line.cursor;
while (count--) { while (count--) {
if (*cp == ch) if ((Int)*cp == ch)
cp += direction; cp += direction;
for (;;cp += direction) { for (;;cp += direction) {
if (cp >= el->el_line.lastchar) if (cp >= el->el_line.lastchar)
return CC_ERROR; return CC_ERROR;
if (cp < el->el_line.buffer) if (cp < el->el_line.buffer)
return CC_ERROR; return CC_ERROR;
if (*cp == ch) if ((Int)*cp == ch)
break; break;
} }
} }

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 * Copyright (c) 1992, 1993
@ -43,24 +43,24 @@
#include "histedit.h" #include "histedit.h"
typedef struct el_search_t { typedef struct el_search_t {
char *patbuf; /* The pattern buffer */ Char *patbuf; /* The pattern buffer */
size_t patlen; /* Length of the pattern buffer */ size_t patlen; /* Length of the pattern buffer */
int patdir; /* Direction of the last search */ int patdir; /* Direction of the last search */
int chadir; /* Character search direction */ int chadir; /* Character search direction */
char chacha; /* Character we are looking for */ Char chacha; /* Character we are looking for */
char chatflg; /* 0 if f, 1 if t */ char chatflg; /* 0 if f, 1 if t */
} el_search_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 int search_init(EditLine *);
protected void search_end(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 void c_setpat(EditLine *);
protected el_action_t ce_inc_search(EditLine *, int); protected el_action_t ce_inc_search(EditLine *, int);
protected el_action_t cv_search(EditLine *, int); protected el_action_t cv_search(EditLine *, int);
protected el_action_t ce_search_line(EditLine *, int); protected el_action_t ce_search_line(EditLine *, int);
protected el_action_t cv_repeat_srch(EditLine *, int); protected el_action_t cv_repeat_srch(EditLine *, Int);
protected el_action_t cv_csearch(EditLine *, int, int, int, int); protected el_action_t cv_csearch(EditLine *, int, Int, int, int);
#endif /* _h_el_search */ #endif /* _h_el_search */

View File

@ -1,4 +1,4 @@
/* $NetBSD: sig.c,v 1.12 2008/09/10 15:45:37 christos Exp $ */ /* $NetBSD: sig.c,v 1.17 2011/07/28 20:50:55 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -57,15 +57,15 @@ private const int sighdl[] = {
- 1 - 1
}; };
private void el_sig_handler(int); private void sig_handler(int);
/* el_sig_handler(): /* sig_handler():
* This is the handler called for all signals * This is the handler called for all signals
* XXX: we cannot pass any data so we just store the old editline * XXX: we cannot pass any data so we just store the old editline
* state in a private variable * state in a private variable
*/ */
private void private void
el_sig_handler(int signo) sig_handler(int signo)
{ {
int i; int i;
sigset_t nset, oset; sigset_t nset, oset;
@ -74,12 +74,14 @@ el_sig_handler(int signo)
(void) sigaddset(&nset, signo); (void) sigaddset(&nset, signo);
(void) sigprocmask(SIG_BLOCK, &nset, &oset); (void) sigprocmask(SIG_BLOCK, &nset, &oset);
sel->el_signal->sig_no = signo;
switch (signo) { switch (signo) {
case SIGCONT: case SIGCONT:
tty_rawmode(sel); tty_rawmode(sel);
if (ed_redisplay(sel, 0) == CC_REFRESH) if (ed_redisplay(sel, 0) == CC_REFRESH)
re_refresh(sel); re_refresh(sel);
term__flush(sel); terminal__flush(sel);
break; break;
case SIGWINCH: case SIGWINCH:
@ -95,7 +97,10 @@ el_sig_handler(int signo)
if (signo == sighdl[i]) if (signo == sighdl[i])
break; 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) sigprocmask(SIG_SETMASK, &oset, NULL);
(void) kill(0, signo); (void) kill(0, signo);
} }
@ -107,26 +112,29 @@ el_sig_handler(int signo)
protected int protected int
sig_init(EditLine *el) sig_init(EditLine *el)
{ {
int i; size_t i;
sigset_t nset, oset; sigset_t *nset, oset;
(void) sigemptyset(&nset); el->el_signal = el_malloc(sizeof(*el->el_signal));
#define _DO(a) (void) sigaddset(&nset, a); if (el->el_signal == NULL)
return -1;
nset = &el->el_signal->sig_set;
(void) sigemptyset(nset);
#define _DO(a) (void) sigaddset(nset, a);
ALLSIGS ALLSIGS
#undef _DO #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)) for (i = 0; sighdl[i] != -1; i++) {
el->el_signal->sig_action[i].sa_handler = SIG_ERR;
el->el_signal = (el_signalhandler_t *) el_malloc(SIGSIZE); el->el_signal->sig_action[i].sa_flags = 0;
if (el->el_signal == NULL) sigemptyset(&el->el_signal->sig_action[i].sa_mask);
return (-1); }
for (i = 0; sighdl[i] != -1; i++)
el->el_signal[i] = SIG_ERR;
(void) sigprocmask(SIG_SETMASK, &oset, NULL); (void) sigprocmask(SIG_SETMASK, &oset, NULL);
return (0); return 0;
} }
@ -137,7 +145,7 @@ protected void
sig_end(EditLine *el) sig_end(EditLine *el)
{ {
el_free((ptr_t) el->el_signal); el_free(el->el_signal);
el->el_signal = NULL; el->el_signal = NULL;
} }
@ -148,20 +156,21 @@ sig_end(EditLine *el)
protected void protected void
sig_set(EditLine *el) sig_set(EditLine *el)
{ {
int i; size_t i;
sigset_t nset, oset; sigset_t oset;
struct sigaction osa, nsa;
(void) sigemptyset(&nset); nsa.sa_handler = sig_handler;
#define _DO(a) (void) sigaddset(&nset, a); nsa.sa_flags = 0;
ALLSIGS sigemptyset(&nsa.sa_mask);
#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++) { for (i = 0; sighdl[i] != -1; i++) {
el_signalhandler_t s;
/* This could happen if we get interrupted */ /* This could happen if we get interrupted */
if ((s = signal(sighdl[i], el_sig_handler)) != el_sig_handler) if (sigaction(sighdl[i], &nsa, &osa) != -1 &&
el->el_signal[i] = s; osa.sa_handler != sig_handler)
el->el_signal->sig_action[i] = osa;
} }
sel = el; sel = el;
(void) sigprocmask(SIG_SETMASK, &oset, NULL); (void) sigprocmask(SIG_SETMASK, &oset, NULL);
@ -174,20 +183,17 @@ sig_set(EditLine *el)
protected void protected void
sig_clr(EditLine *el) sig_clr(EditLine *el)
{ {
int i; size_t i;
sigset_t nset, oset; sigset_t oset;
(void) sigemptyset(&nset); (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset);
#define _DO(a) (void) sigaddset(&nset, a);
ALLSIGS
#undef _DO
(void) sigprocmask(SIG_BLOCK, &nset, &oset);
for (i = 0; sighdl[i] != -1; i++) for (i = 0; sighdl[i] != -1; i++)
if (el->el_signal[i] != SIG_ERR) if (el->el_signal->sig_action[i].sa_handler != SIG_ERR)
(void) signal(sighdl[i], el->el_signal[i]); (void)sigaction(sighdl[i],
&el->el_signal->sig_action[i], NULL);
sel = NULL; /* we are going to die if the handler is sel = NULL; /* we are going to die if the handler is
* called */ * called */
(void) sigprocmask(SIG_SETMASK, &oset, NULL); (void)sigprocmask(SIG_SETMASK, &oset, NULL);
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: sig.h,v 1.6 2008/07/12 15:27:14 christos Exp $ */ /* $NetBSD: sig.h,v 1.8 2009/02/19 15:20:22 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -56,9 +56,13 @@
_DO(SIGTERM) \ _DO(SIGTERM) \
_DO(SIGCONT) \ _DO(SIGCONT) \
_DO(SIGWINCH) _DO(SIGWINCH)
#define ALLSIGSNO 7
typedef void (*el_signalhandler_t)(int); typedef struct {
typedef el_signalhandler_t *el_signal_t; struct sigaction sig_action[ALLSIGSNO];
sigset_t sig_set;
volatile sig_atomic_t sig_no;
} *el_signal_t;
protected void sig_end(EditLine*); protected void sig_end(EditLine*);
protected int sig_init(EditLine*); protected int sig_init(EditLine*);

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.17 2011/09/28 14:08:04 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -48,14 +48,6 @@
# define __attribute__(A) # define __attribute__(A)
#endif #endif
#ifndef _DIAGASSERT
# define _DIAGASSERT(x)
#endif
#ifndef SIZE_T_MAX
# define SIZE_T_MAX UINT_MAX
#endif
#ifndef __BEGIN_DECLS #ifndef __BEGIN_DECLS
# ifdef __cplusplus # ifdef __cplusplus
# define __BEGIN_DECLS extern "C" { # define __BEGIN_DECLS extern "C" {
@ -79,18 +71,8 @@
/* When we want to hide everything */ /* When we want to hide everything */
#endif #endif
#ifndef HAVE_U_INT32_T #ifndef __arraycount
typedef unsigned int u_int32_t; # define __arraycount(a) (sizeof(a) / sizeof(*(a)))
#endif
#ifndef _PTR_T
# define _PTR_T
typedef void *ptr_t;
#endif
#ifndef _IOCTL_T
# define _IOCTL_T
typedef void *ioctl_t;
#endif #endif
#include <stdio.h> #include <stdio.h>
@ -110,10 +92,31 @@ size_t strlcpy(char *dst, const char *src, size_t size);
char *fgetln(FILE *fp, size_t *len); char *fgetln(FILE *fp, size_t *len);
#endif #endif
#ifndef HAVE_WCSDUP
#include <wchar.h>
wchar_t *wcsdup(const wchar_t *);
#endif
#ifndef _DIAGASSERT
#define _DIAGASSERT(x)
#endif
#ifndef __RCSID
#define __RCSID(x)
#endif
#ifndef HAVE_U_INT32_T
typedef unsigned int u_int32_t;
#endif
#ifndef SIZE_T_MAX
#define SIZE_T_MAX ((size_t)-1)
#endif
#define REGEX /* Use POSIX.2 regular expression functions */ #define REGEX /* Use POSIX.2 regular expression functions */
#undef REGEXP /* Use UNIX V8 regular expression functions */ #undef REGEXP /* Use UNIX V8 regular expression functions */
#ifdef __SunOS #if defined(__sun)
extern int tgetent(char *, const char *); extern int tgetent(char *, const char *);
extern int tgetflag(char *); extern int tgetflag(char *);
extern int tgetnum(char *); extern int tgetnum(char *);
@ -162,8 +165,8 @@ extern void perror(const char *);
# define strerror(e) sys_errlist[e] # define strerror(e) sys_errlist[e]
# endif # endif
# ifdef SABER # ifdef SABER
extern ptr_t memcpy(ptr_t, const ptr_t, size_t); extern void * memcpy(void *, const void *, size_t);
extern ptr_t memset(ptr_t, int, size_t); extern void * memset(void *, int, size_t);
# endif # endif
extern char *fgetline(FILE *, int *); extern char *fgetline(FILE *, int *);
#endif #endif

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.19 2011/07/28 20:50:55 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -40,51 +40,53 @@ static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93";
#endif #endif
#endif /* not lint && not SCCSID */ #endif /* not lint && not SCCSID */
/* We build this file twice, once as NARROW, once as WIDE. */
/* /*
* tokenize.c: Bourne shell like tokenizer * tokenize.c: Bourne shell like tokenizer
*/ */
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "histedit.h" #include "histedit.h"
#include "chartype.h"
typedef enum { typedef enum {
Q_none, Q_single, Q_double, Q_one, Q_doubleone Q_none, Q_single, Q_double, Q_one, Q_doubleone
} quote_t; } quote_t;
#define IFS "\t \n"
#define TOK_KEEP 1 #define TOK_KEEP 1
#define TOK_EAT 2 #define TOK_EAT 2
#define WINCR 20 #define WINCR 20
#define AINCR 10 #define AINCR 10
#define tok_strdup(a) strdup(a) #define IFS STR("\t \n")
#define tok_malloc(a) malloc(a) #define tok_malloc(a) malloc(a)
#define tok_free(a) free(a) #define tok_free(a) free(a)
#define tok_realloc(a, b) realloc(a, b) #define tok_realloc(a, b) realloc(a, b)
#define tok_strdup(a) Strdup(a)
struct tokenizer { struct TYPE(tokenizer) {
char *ifs; /* In field separator */ Char *ifs; /* In field separator */
int argc, amax; /* Current and maximum number of args */ int argc, amax; /* Current and maximum number of args */
char **argv; /* Argument list */ Char **argv; /* Argument list */
char *wptr, *wmax; /* Space and limit on the word buffer */ Char *wptr, *wmax; /* Space and limit on the word buffer */
char *wstart; /* Beginning of next word */ Char *wstart; /* Beginning of next word */
char *wspace; /* Space of word buffer */ Char *wspace; /* Space of word buffer */
quote_t quote; /* Quoting state */ quote_t quote; /* Quoting state */
int flags; /* flags; */ 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. * Finish a word in the tokenizer.
*/ */
private void private void
tok_finish(Tokenizer *tok) FUN(tok,finish)(TYPE(Tokenizer) *tok)
{ {
*tok->wptr = '\0'; *tok->wptr = '\0';
@ -97,35 +99,35 @@ tok_finish(Tokenizer *tok)
} }
/* tok_init(): /* FUN(tok,init)():
* Initialize the tokenizer * Initialize the tokenizer
*/ */
public Tokenizer * public TYPE(Tokenizer) *
tok_init(const char *ifs) FUN(tok,init)(const Char *ifs)
{ {
Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer)); TYPE(Tokenizer) *tok = tok_malloc(sizeof(*tok));
if (tok == NULL) if (tok == NULL)
return NULL; return NULL;
tok->ifs = tok_strdup(ifs ? ifs : IFS); tok->ifs = tok_strdup(ifs ? ifs : IFS);
if (tok->ifs == NULL) { if (tok->ifs == NULL) {
tok_free((ptr_t)tok); tok_free(tok);
return NULL; return NULL;
} }
tok->argc = 0; tok->argc = 0;
tok->amax = AINCR; tok->amax = AINCR;
tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax); tok->argv = tok_malloc(sizeof(*tok->argv) * tok->amax);
if (tok->argv == NULL) { if (tok->argv == NULL) {
tok_free((ptr_t)tok->ifs); tok_free(tok->ifs);
tok_free((ptr_t)tok); tok_free(tok);
return NULL; return NULL;
} }
tok->argv[0] = NULL; tok->argv[0] = NULL;
tok->wspace = (char *) tok_malloc(WINCR); tok->wspace = tok_malloc(WINCR * sizeof(*tok->wspace));
if (tok->wspace == NULL) { if (tok->wspace == NULL) {
tok_free((ptr_t)tok->argv); tok_free(tok->argv);
tok_free((ptr_t)tok->ifs); tok_free(tok->ifs);
tok_free((ptr_t)tok); tok_free(tok);
return NULL; return NULL;
} }
tok->wmax = tok->wspace + WINCR; tok->wmax = tok->wspace + WINCR;
@ -138,11 +140,11 @@ tok_init(const char *ifs)
} }
/* tok_reset(): /* FUN(tok,reset)():
* Reset the tokenizer * Reset the tokenizer
*/ */
public void public void
tok_reset(Tokenizer *tok) FUN(tok,reset)(TYPE(Tokenizer) *tok)
{ {
tok->argc = 0; tok->argc = 0;
@ -153,25 +155,25 @@ tok_reset(Tokenizer *tok)
} }
/* tok_end(): /* FUN(tok,end)():
* Clean up * Clean up
*/ */
public void public void
tok_end(Tokenizer *tok) FUN(tok,end)(TYPE(Tokenizer) *tok)
{ {
tok_free((ptr_t) tok->ifs); tok_free(tok->ifs);
tok_free((ptr_t) tok->wspace); tok_free(tok->wspace);
tok_free((ptr_t) tok->argv); tok_free(tok->argv);
tok_free((ptr_t) tok); tok_free(tok);
} }
/* tok_line(): /* FUN(tok,line)():
* Bourne shell (sh(1)) like tokenizing * Bourne shell (sh(1)) like tokenizing
* Arguments: * Arguments:
* tok current tokenizer state (setup with tok_init()) * tok current tokenizer state (setup with FUN(tok,init)())
* line line to parse * line line to parse
* Returns: * Returns:
* -1 Internal error * -1 Internal error
@ -186,20 +188,20 @@ tok_end(Tokenizer *tok)
* cursorv if !NULL, offset in argv[cursorc] of cursor * cursorv if !NULL, offset in argv[cursorc] of cursor
*/ */
public int public int
tok_line(Tokenizer *tok, const LineInfo *line, FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line,
int *argc, const char ***argv, int *cursorc, int *cursoro) int *argc, const Char ***argv, int *cursorc, int *cursoro)
{ {
const char *ptr; const Char *ptr;
int cc, co; int cc, co;
cc = co = -1; cc = co = -1;
ptr = line->buffer; ptr = line->buffer;
for (ptr = line->buffer; ;ptr++) { for (ptr = line->buffer; ;ptr++) {
if (ptr >= line->lastchar) if (ptr >= line->lastchar)
ptr = ""; ptr = STR("");
if (ptr == line->cursor) { if (ptr == line->cursor) {
cc = tok->argc; cc = tok->argc;
co = tok->wptr - tok->wstart; co = (int)(tok->wptr - tok->wstart);
} }
switch (*ptr) { switch (*ptr) {
case '\'': case '\'':
@ -357,8 +359,8 @@ tok_line(Tokenizer *tok, const LineInfo *line,
tok->flags &= ~TOK_EAT; tok->flags &= ~TOK_EAT;
switch (tok->quote) { switch (tok->quote) {
case Q_none: case Q_none:
if (strchr(tok->ifs, *ptr) != NULL) if (Strchr(tok->ifs, *ptr) != NULL)
tok_finish(tok); FUN(tok,finish)(tok);
else else
*tok->wptr++ = *ptr; *tok->wptr++ = *ptr;
break; break;
@ -389,7 +391,8 @@ tok_line(Tokenizer *tok, const LineInfo *line,
if (tok->wptr >= tok->wmax - 4) { if (tok->wptr >= tok->wmax - 4) {
size_t size = tok->wmax - tok->wspace + WINCR; size_t size = tok->wmax - tok->wspace + WINCR;
char *s = (char *) tok_realloc(tok->wspace, size); Char *s = tok_realloc(tok->wspace,
size * sizeof(*s));
if (s == NULL) if (s == NULL)
return (-1); return (-1);
@ -406,10 +409,9 @@ tok_line(Tokenizer *tok, const LineInfo *line,
tok->wmax = s + size; tok->wmax = s + size;
} }
if (tok->argc >= tok->amax - 4) { if (tok->argc >= tok->amax - 4) {
char **p; Char **p;
tok->amax += AINCR; tok->amax += AINCR;
p = (char **) tok_realloc(tok->argv, p = tok_realloc(tok->argv, tok->amax * sizeof(*p));
tok->amax * sizeof(char *));
if (p == NULL) if (p == NULL)
return (-1); return (-1);
tok->argv = p; tok->argv = p;
@ -418,29 +420,30 @@ tok_line(Tokenizer *tok, const LineInfo *line,
tok_line_outok: tok_line_outok:
if (cc == -1 && co == -1) { if (cc == -1 && co == -1) {
cc = tok->argc; cc = tok->argc;
co = tok->wptr - tok->wstart; co = (int)(tok->wptr - tok->wstart);
} }
if (cursorc != NULL) if (cursorc != NULL)
*cursorc = cc; *cursorc = cc;
if (cursoro != NULL) if (cursoro != NULL)
*cursoro = co; *cursoro = co;
tok_finish(tok); FUN(tok,finish)(tok);
*argv = (const char **)tok->argv; *argv = (const Char **)tok->argv;
*argc = tok->argc; *argc = tok->argc;
return (0); return (0);
} }
/* tok_str(): /* FUN(tok,str)():
* Simpler version of tok_line, taking a NUL terminated line * Simpler version of tok_line, taking a NUL terminated line
* and splitting into words, ignoring cursor state. * and splitting into words, ignoring cursor state.
*/ */
public int 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)); memset(&li, 0, sizeof(li));
li.buffer = line; li.buffer = line;
li.cursor = li.lastchar = strchr(line, '\0'); li.cursor = li.lastchar = Strchr(line, '\0');
return (tok_line(tok, &li, argc, argv, NULL, NULL)); return (FUN(tok,line)(tok, &li, argc, argv, NULL, NULL));
} }

View File

@ -0,0 +1,5 @@
#define NARROW_WRAPPER
#include "config.h"
#undef WIDECHAR
#define NARROWCHAR
#include "./tokenizer.c"

View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.c,v 1.28 2009/02/06 19:53:23 sketch Exp $ */ /* $NetBSD: tty.c,v 1.41 2011/10/04 15:27:04 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -45,8 +45,10 @@ static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
*/ */
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include "tty.h" #include <unistd.h> /* for isatty */
#include <strings.h> /* for ffs */
#include "el.h" #include "el.h"
#include "tty.h"
typedef struct ttymodes_t { typedef struct ttymodes_t {
const char *m_name; const char *m_name;
@ -55,7 +57,7 @@ typedef struct ttymodes_t {
} ttymodes_t; } ttymodes_t;
typedef struct ttymap_t { typedef struct ttymap_t {
int nch, och; /* Internal and termio rep of chars */ Int nch, och; /* Internal and termio rep of chars */
el_action_t bind[3]; /* emacs, vi, and vi-cmd */ el_action_t bind[3]; /* emacs, vi, and vi-cmd */
} ttymap_t; } ttymap_t;
@ -151,7 +153,7 @@ private const ttymap_t tty_map[] = {
{C_LNEXT, VLNEXT, {C_LNEXT, VLNEXT,
{ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}}, {ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}},
#endif /* VLNEXT */ #endif /* VLNEXT */
{-1, -1, {(Int)-1, (Int)-1,
{ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}} {ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}}
}; };
@ -492,14 +494,21 @@ tty_setup(EditLine *el)
int rst = 1; int rst = 1;
if (el->el_flags & EDIT_DISABLED) if (el->el_flags & EDIT_DISABLED)
return (0); return 0;
if (!isatty(el->el_outfd)) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_setup: isatty: %s\n", strerror(errno));
#endif /* DEBUG_TTY */
return -1;
}
if (tty_getty(el, &el->el_tty.t_ed) == -1) { if (tty_getty(el, &el->el_tty.t_ed) == -1) {
#ifdef DEBUG_TTY #ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"tty_setup: tty_getty: %s\n", strerror(errno)); "tty_setup: tty_getty: %s\n", strerror(errno));
#endif /* DEBUG_TTY */ #endif /* DEBUG_TTY */
return (-1); return -1;
} }
el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed; el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed;
@ -549,13 +558,9 @@ tty_setup(EditLine *el)
"tty_setup: tty_setty: %s\n", "tty_setup: tty_setty: %s\n",
strerror(errno)); strerror(errno));
#endif /* DEBUG_TTY */ #endif /* DEBUG_TTY */
return (-1); return -1;
} }
} }
#ifdef notdef
else
tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
#endif
el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask; el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
@ -571,7 +576,7 @@ tty_setup(EditLine *el)
tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]);
tty_bind_char(el, 1); tty_bind_char(el, 1);
return (0); return 0;
} }
protected int protected int
@ -582,7 +587,7 @@ tty_init(EditLine *el)
el->el_tty.t_vdisable = _POSIX_VDISABLE; el->el_tty.t_vdisable = _POSIX_VDISABLE;
(void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t)); (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t));
(void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t)); (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t));
return (tty_setup(el)); return tty_setup(el);
} }
@ -608,7 +613,7 @@ tty__getspeed(struct termios *td)
if ((spd = cfgetispeed(td)) == 0) if ((spd = cfgetispeed(td)) == 0)
spd = cfgetospeed(td); spd = cfgetospeed(td);
return (spd); return spd;
} }
/* tty__getspeed(): /* tty__getspeed():
@ -892,7 +897,7 @@ tty_bind_char(EditLine *el, int force)
unsigned char *t_n = el->el_tty.t_c[ED_IO]; unsigned char *t_n = el->el_tty.t_c[ED_IO];
unsigned char *t_o = el->el_tty.t_ed.c_cc; 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; const ttymap_t *tp;
el_action_t *map, *alt; el_action_t *map, *alt;
const el_action_t *dmap, *dalt; const el_action_t *dmap, *dalt;
@ -908,22 +913,22 @@ tty_bind_char(EditLine *el, int force)
dalt = NULL; dalt = NULL;
} }
for (tp = tty_map; tp->nch != -1; tp++) { for (tp = tty_map; tp->nch != (Int)-1; tp++) {
new[0] = t_n[tp->nch]; new[0] = t_n[tp->nch];
old[0] = t_o[tp->och]; old[0] = t_o[tp->och];
if (new[0] == old[0] && !force) if (new[0] == old[0] && !force)
continue; continue;
/* Put the old default binding back, and set the new binding */ /* Put the old default binding back, and set the new binding */
key_clear(el, map, (char *)old); keymacro_clear(el, map, old);
map[old[0]] = dmap[old[0]]; map[UC(old[0])] = dmap[UC(old[0])];
key_clear(el, map, (char *)new); keymacro_clear(el, map, new);
/* MAP_VI == 1, MAP_EMACS == 0... */ /* 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) { if (dalt) {
key_clear(el, alt, (char *)old); keymacro_clear(el, alt, old);
alt[old[0]] = dalt[old[0]]; alt[UC(old[0])] = dalt[UC(old[0])];
key_clear(el, alt, (char *)new); keymacro_clear(el, alt, new);
alt[new[0]] = tp->bind[el->el_map.type + 1]; alt[UC(new[0])] = tp->bind[el->el_map.type + 1];
} }
} }
} }
@ -937,21 +942,21 @@ tty_rawmode(EditLine *el)
{ {
if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO) if (el->el_tty.t_mode == ED_IO || el->el_tty.t_mode == QU_IO)
return (0); return 0;
if (el->el_flags & EDIT_DISABLED) if (el->el_flags & EDIT_DISABLED)
return (0); return 0;
if (tty_getty(el, &el->el_tty.t_ts) == -1) { if (tty_getty(el, &el->el_tty.t_ts) == -1) {
#ifdef DEBUG_TTY #ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n",
strerror(errno)); strerror(errno));
#endif /* DEBUG_TTY */ #endif /* DEBUG_TTY */
return (-1); return -1;
} }
/* /*
* We always keep up with the eight bit setting and the speed of the * 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_eight = tty__geteightbit(&el->el_tty.t_ts);
el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts); el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts);
@ -1077,10 +1082,10 @@ tty_rawmode(EditLine *el)
(void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n", (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
strerror(errno)); strerror(errno));
#endif /* DEBUG_TTY */ #endif /* DEBUG_TTY */
return (-1); return -1;
} }
el->el_tty.t_mode = ED_IO; el->el_tty.t_mode = ED_IO;
return (0); return 0;
} }
@ -1092,10 +1097,10 @@ tty_cookedmode(EditLine *el)
{ /* set tty in normal setup */ { /* set tty in normal setup */
if (el->el_tty.t_mode == EX_IO) if (el->el_tty.t_mode == EX_IO)
return (0); return 0;
if (el->el_flags & EDIT_DISABLED) if (el->el_flags & EDIT_DISABLED)
return (0); return 0;
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) { if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
#ifdef DEBUG_TTY #ifdef DEBUG_TTY
@ -1103,10 +1108,10 @@ tty_cookedmode(EditLine *el)
"tty_cookedmode: tty_setty: %s\n", "tty_cookedmode: tty_setty: %s\n",
strerror(errno)); strerror(errno));
#endif /* DEBUG_TTY */ #endif /* DEBUG_TTY */
return (-1); return -1;
} }
el->el_tty.t_mode = EX_IO; el->el_tty.t_mode = EX_IO;
return (0); return 0;
} }
@ -1117,7 +1122,7 @@ protected int
tty_quotemode(EditLine *el) tty_quotemode(EditLine *el)
{ {
if (el->el_tty.t_mode == QU_IO) if (el->el_tty.t_mode == QU_IO)
return (0); return 0;
el->el_tty.t_qu = el->el_tty.t_ed; el->el_tty.t_qu = el->el_tty.t_ed;
@ -1138,10 +1143,10 @@ tty_quotemode(EditLine *el)
(void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n", (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
strerror(errno)); strerror(errno));
#endif /* DEBUG_TTY */ #endif /* DEBUG_TTY */
return (-1); return -1;
} }
el->el_tty.t_mode = QU_IO; el->el_tty.t_mode = QU_IO;
return (0); return 0;
} }
@ -1153,16 +1158,16 @@ tty_noquotemode(EditLine *el)
{ {
if (el->el_tty.t_mode != QU_IO) if (el->el_tty.t_mode != QU_IO)
return (0); return 0;
if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
#ifdef DEBUG_TTY #ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n", (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
strerror(errno)); strerror(errno));
#endif /* DEBUG_TTY */ #endif /* DEBUG_TTY */
return (-1); return -1;
} }
el->el_tty.t_mode = ED_IO; el->el_tty.t_mode = ED_IO;
return (0); return 0;
} }
@ -1171,19 +1176,20 @@ tty_noquotemode(EditLine *el)
*/ */
protected int protected int
/*ARGSUSED*/ /*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; const ttymodes_t *m;
char x; char x;
int aflag = 0; int aflag = 0;
const char *s, *d; const Char *s, *d;
const char *name; char name[EL_BUFSIZ];
struct termios *tios = &el->el_tty.t_ex; struct termios *tios = &el->el_tty.t_ex;
int z = EX_IO; int z = EX_IO;
if (argv == NULL) if (argv == NULL)
return (-1); 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') while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0')
switch (argv[0][1]) { switch (argv[0][1]) {
@ -1210,12 +1216,12 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"%s: Unknown switch `%c'.\n", "%s: Unknown switch `%c'.\n",
name, argv[0][1]); name, argv[0][1]);
return (-1); return -1;
} }
if (!argv || !*argv) { if (!argv || !*argv) {
int i = -1; int i = -1;
int len = 0, st = 0, cu; size_t len = 0, st = 0, cu;
for (m = ttymodes; m->m_name; m++) { for (m = ttymodes; m->m_name; m++) {
if (m->m_type != i) { if (m->m_type != i) {
(void) fprintf(el->el_outfile, "%s%s", (void) fprintf(el->el_outfile, "%s%s",
@ -1228,8 +1234,9 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
if (i != -1) { if (i != -1) {
x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) x = (el->el_tty.t_t[z][i].t_setmask & m->m_value)
? '+' : '\0'; ? '+' : '\0';
x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
? '-' : x; if (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
x = '-';
} else { } else {
x = '\0'; x = '\0';
} }
@ -1238,9 +1245,9 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
cu = strlen(m->m_name) + (x != '\0') + 1; cu = strlen(m->m_name) + (x != '\0') + 1;
if (len + cu >= el->el_term.t_size.h) { if (len + cu >= (size_t)el->el_terminal.t_size.h) {
(void) fprintf(el->el_outfile, "\n%*s", (void) fprintf(el->el_outfile, "\n%*s",
st, ""); (int)st, "");
len = st + cu; len = st + cu;
} else } else
len += cu; len += cu;
@ -1254,40 +1261,41 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
} }
} }
(void) fprintf(el->el_outfile, "\n"); (void) fprintf(el->el_outfile, "\n");
return (0); return 0;
} }
while (argv && (s = *argv++)) { while (argv && (s = *argv++)) {
const char *p; const Char *p;
switch (*s) { switch (*s) {
case '+': case '+':
case '-': case '-':
x = *s++; x = (char)*s++;
break; break;
default: default:
x = '\0'; x = '\0';
break; break;
} }
d = s; d = s;
p = strchr(s, '='); p = Strchr(s, '=');
for (m = ttymodes; m->m_name; m++) for (m = ttymodes; m->m_name; m++)
if ((p ? strncmp(m->m_name, d, (size_t)(p - d)) : if ((p ? strncmp(m->m_name, ct_encode_string(d, &el->el_scratch), (size_t)(p - d)) :
strcmp(m->m_name, d)) == 0 && strcmp(m->m_name, ct_encode_string(d, &el->el_scratch))) == 0 &&
(p == NULL || m->m_type == MD_CHAR)) (p == NULL || m->m_type == MD_CHAR))
break; break;
if (!m->m_name) { if (!m->m_name) {
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"%s: Invalid argument `%s'.\n", name, d); "%s: Invalid argument `" FSTR "'.\n", name, d);
return (-1); return -1;
} }
if (p) { if (p) {
int c = ffs((int)m->m_value); 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; el->el_tty.t_vdisable;
assert(c-- != 0); assert(c != 0);
c--;
c = tty__getcharindex(c); c = tty__getcharindex(c);
assert(c != -1); assert(c != -1);
tios->c_cc[c] = v; tios->c_cc[c] = (cc_t)v;
continue; continue;
} }
switch (x) { switch (x) {
@ -1312,11 +1320,11 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"tty_stty: tty_setty: %s\n", strerror(errno)); "tty_stty: tty_setty: %s\n", strerror(errno));
#endif /* DEBUG_TTY */ #endif /* DEBUG_TTY */
return (-1); return -1;
} }
} }
return (0); return 0;
} }

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.13 2011/08/16 16:25:15 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -40,6 +40,7 @@
#ifndef _h_el_tty #ifndef _h_el_tty
#define _h_el_tty #define _h_el_tty
#include "sys.h"
#include "histedit.h" #include "histedit.h"
#include <termios.h> #include <termios.h>
#include <unistd.h> #include <unistd.h>
@ -430,7 +431,7 @@
#define C_MIN 23 #define C_MIN 23
#define C_TIME 24 #define C_TIME 24
#define C_NCC 25 #define C_NCC 25
#define C_SH(A) (1 << (A)) #define C_SH(A) ((unsigned int)(1 << (A)))
/* /*
* Terminal dependend data structures * Terminal dependend data structures
@ -458,7 +459,7 @@ typedef unsigned char ttychar_t[NN_IO][C_NCC];
protected int tty_init(EditLine *); protected int tty_init(EditLine *);
protected void tty_end(EditLine *); protected void tty_end(EditLine *);
protected int tty_stty(EditLine *, int, const char **); protected int tty_stty(EditLine *, int, const Char **);
protected int tty_rawmode(EditLine *); protected int tty_rawmode(EditLine *);
protected int tty_cookedmode(EditLine *); protected int tty_cookedmode(EditLine *);
protected int tty_quotemode(EditLine *); protected int tty_quotemode(EditLine *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: vi.c,v 1.28 2009/02/06 13:14:37 sketch Exp $ */ /* $NetBSD: vi.c,v 1.41 2011/10/04 15:27:04 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -35,6 +35,7 @@
#include "config.h" #include "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <limits.h>
#include <sys/wait.h> #include <sys/wait.h>
#if !defined(lint) && !defined(SCCSID) #if !defined(lint) && !defined(SCCSID)
@ -49,25 +50,25 @@ static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
*/ */
#include "el.h" #include "el.h"
private el_action_t cv_action(EditLine *, int); private el_action_t cv_action(EditLine *, Int);
private el_action_t cv_paste(EditLine *, int); private el_action_t cv_paste(EditLine *, Int);
/* cv_action(): /* cv_action():
* Handle vi actions. * Handle vi actions.
*/ */
private el_action_t private el_action_t
cv_action(EditLine *el, int c) cv_action(EditLine *el, Int c)
{ {
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
/* 'cc', 'dd' and (possibly) friends */ /* 'cc', 'dd' and (possibly) friends */
if (c != el->el_chared.c_vcmd.action) if (c != (Int)el->el_chared.c_vcmd.action)
return CC_ERROR; return CC_ERROR;
if (!(c & YANK)) if (!(c & YANK))
cv_undo(el); cv_undo(el);
cv_yank(el, el->el_line.buffer, 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.action = NOP;
el->el_chared.c_vcmd.pos = 0; el->el_chared.c_vcmd.pos = 0;
if (!(c & YANK)) { if (!(c & YANK)) {
@ -77,26 +78,26 @@ cv_action(EditLine *el, int c)
if (c & INSERT) if (c & INSERT)
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
return (CC_REFRESH); return CC_REFRESH;
} }
el->el_chared.c_vcmd.pos = el->el_line.cursor; el->el_chared.c_vcmd.pos = el->el_line.cursor;
el->el_chared.c_vcmd.action = c; el->el_chared.c_vcmd.action = c;
return (CC_ARGHACK); return CC_ARGHACK;
} }
/* cv_paste(): /* cv_paste():
* Paste previous deletion before or after the cursor * Paste previous deletion before or after the cursor
*/ */
private el_action_t 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; 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) if (k->buf == NULL || len == 0)
return (CC_ERROR); return CC_ERROR;
#ifdef DEBUG_PASTE #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 #endif
cv_undo(el); cv_undo(el);
@ -104,12 +105,13 @@ cv_paste(EditLine *el, int c)
if (!c && el->el_line.cursor < el->el_line.lastchar) if (!c && el->el_line.cursor < el->el_line.lastchar)
el->el_line.cursor++; el->el_line.cursor++;
c_insert(el, len); c_insert(el, (int)len);
if (el->el_line.cursor + len > el->el_line.lastchar) if (el->el_line.cursor + len > el->el_line.lastchar)
return (CC_ERROR); return CC_ERROR;
(void) memcpy(el->el_line.cursor, k->buf, len +0u); (void) memcpy(el->el_line.cursor, k->buf, len *
sizeof(*el->el_line.cursor));
return (CC_REFRESH); return CC_REFRESH;
} }
@ -119,10 +121,10 @@ cv_paste(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_paste_next(EditLine *el, int c __attribute__((__unused__))) vi_paste_next(EditLine *el, Int c __attribute__((__unused__)))
{ {
return (cv_paste(el, 0)); return cv_paste(el, 0);
} }
@ -132,10 +134,10 @@ vi_paste_next(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_paste_prev(EditLine *el, int c __attribute__((__unused__))) vi_paste_prev(EditLine *el, Int c __attribute__((__unused__)))
{ {
return (cv_paste(el, 1)); return cv_paste(el, 1);
} }
@ -145,11 +147,11 @@ vi_paste_prev(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_prev_big_word(EditLine *el, int c __attribute__((__unused__))) vi_prev_big_word(EditLine *el, Int c __attribute__((__unused__)))
{ {
if (el->el_line.cursor == el->el_line.buffer) if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR); return CC_ERROR;
el->el_line.cursor = cv_prev_word(el->el_line.cursor, el->el_line.cursor = cv_prev_word(el->el_line.cursor,
el->el_line.buffer, el->el_line.buffer,
@ -158,9 +160,9 @@ vi_prev_big_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
return (CC_CURSOR); return CC_CURSOR;
} }
@ -170,11 +172,11 @@ vi_prev_big_word(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (el->el_line.cursor == el->el_line.buffer)
return (CC_ERROR); return CC_ERROR;
el->el_line.cursor = cv_prev_word(el->el_line.cursor, el->el_line.cursor = cv_prev_word(el->el_line.cursor,
el->el_line.buffer, el->el_line.buffer,
@ -183,9 +185,9 @@ vi_prev_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
return (CC_CURSOR); return CC_CURSOR;
} }
@ -195,11 +197,11 @@ vi_prev_word(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_next_big_word(EditLine *el, int c __attribute__((__unused__))) vi_next_big_word(EditLine *el, Int c __attribute__((__unused__)))
{ {
if (el->el_line.cursor >= el->el_line.lastchar - 1) if (el->el_line.cursor >= el->el_line.lastchar - 1)
return (CC_ERROR); return CC_ERROR;
el->el_line.cursor = cv_next_word(el, el->el_line.cursor, el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
el->el_line.lastchar, el->el_state.argument, cv__isWord); el->el_line.lastchar, el->el_state.argument, cv__isWord);
@ -207,9 +209,9 @@ vi_next_big_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI) if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
return (CC_CURSOR); return CC_CURSOR;
} }
@ -219,11 +221,11 @@ vi_next_big_word(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (el->el_line.cursor >= el->el_line.lastchar - 1)
return (CC_ERROR); return CC_ERROR;
el->el_line.cursor = cv_next_word(el, el->el_line.cursor, el->el_line.cursor = cv_next_word(el, el->el_line.cursor,
el->el_line.lastchar, el->el_state.argument, cv__isword); el->el_line.lastchar, el->el_state.argument, cv__isword);
@ -231,9 +233,9 @@ vi_next_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_map.type == MAP_VI) if (el->el_map.type == MAP_VI)
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
return (CC_CURSOR); return CC_CURSOR;
} }
@ -242,20 +244,20 @@ vi_next_word(EditLine *el, int c __attribute__((__unused__)))
* [~] * [~]
*/ */
protected el_action_t protected el_action_t
vi_change_case(EditLine *el, int c) vi_change_case(EditLine *el, Int c)
{ {
int i; int i;
if (el->el_line.cursor >= el->el_line.lastchar) if (el->el_line.cursor >= el->el_line.lastchar)
return (CC_ERROR); return CC_ERROR;
cv_undo(el); cv_undo(el);
for (i = 0; i < el->el_state.argument; i++) { for (i = 0; i < el->el_state.argument; i++) {
c = *(unsigned char *)el->el_line.cursor; c = *el->el_line.cursor;
if (isupper(c)) if (Isupper(c))
*el->el_line.cursor = tolower(c); *el->el_line.cursor = Tolower(c);
else if (islower(c)) else if (Islower(c))
*el->el_line.cursor = toupper(c); *el->el_line.cursor = Toupper(c);
if (++el->el_line.cursor >= el->el_line.lastchar) { if (++el->el_line.cursor >= el->el_line.lastchar) {
el->el_line.cursor--; el->el_line.cursor--;
@ -274,14 +276,14 @@ vi_change_case(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_change_meta(EditLine *el, int c __attribute__((__unused__))) vi_change_meta(EditLine *el, Int c __attribute__((__unused__)))
{ {
/* /*
* Delete with insert == change: first we delete and then we leave in * Delete with insert == change: first we delete and then we leave in
* insert mode. * insert mode.
*/ */
return (cv_action(el, DELETE | INSERT)); return cv_action(el, DELETE | INSERT);
} }
@ -291,13 +293,13 @@ vi_change_meta(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; el->el_line.cursor = el->el_line.buffer;
cv_undo(el); cv_undo(el);
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
return (CC_CURSOR); return CC_CURSOR;
} }
@ -307,7 +309,7 @@ vi_insert_at_bol(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (el->el_line.cursor >= el->el_line.lastchar)
@ -316,7 +318,7 @@ vi_replace_char(EditLine *el, int c __attribute__((__unused__)))
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
el->el_state.inputmode = MODE_REPLACE_1; el->el_state.inputmode = MODE_REPLACE_1;
cv_undo(el); cv_undo(el);
return (CC_ARGHACK); return CC_ARGHACK;
} }
@ -326,13 +328,13 @@ vi_replace_char(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; el->el_map.current = el->el_map.key;
el->el_state.inputmode = MODE_REPLACE; el->el_state.inputmode = MODE_REPLACE;
cv_undo(el); cv_undo(el);
return (CC_NORM); return CC_NORM;
} }
@ -342,12 +344,12 @@ vi_replace_mode(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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); c_delafter(el, el->el_state.argument);
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -357,15 +359,15 @@ vi_substitute_char(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_substitute_line(EditLine *el, int c __attribute__((__unused__))) vi_substitute_line(EditLine *el, Int c __attribute__((__unused__)))
{ {
cv_undo(el); cv_undo(el);
cv_yank(el, el->el_line.buffer, 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); (void) em_kill_line(el, 0);
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -375,15 +377,15 @@ vi_substitute_line(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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_undo(el);
cv_yank(el, el->el_line.cursor, 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); (void) ed_kill_line(el, 0);
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -393,12 +395,12 @@ vi_change_to_eol(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; el->el_map.current = el->el_map.key;
cv_undo(el); cv_undo(el);
return (CC_NORM); return CC_NORM;
} }
@ -408,7 +410,7 @@ vi_insert(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_add(EditLine *el, int c __attribute__((__unused__))) vi_add(EditLine *el, Int c __attribute__((__unused__)))
{ {
int ret; int ret;
@ -423,7 +425,7 @@ vi_add(EditLine *el, int c __attribute__((__unused__)))
cv_undo(el); cv_undo(el);
return (ret); return (el_action_t)ret;
} }
@ -433,13 +435,13 @@ vi_add(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; el->el_map.current = el->el_map.key;
el->el_line.cursor = el->el_line.lastchar; el->el_line.cursor = el->el_line.lastchar;
cv_undo(el); cv_undo(el);
return (CC_CURSOR); return CC_CURSOR;
} }
@ -449,10 +451,10 @@ vi_add_at_eol(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_delete_meta(EditLine *el, int c __attribute__((__unused__))) vi_delete_meta(EditLine *el, Int c __attribute__((__unused__)))
{ {
return (cv_action(el, DELETE)); return cv_action(el, DELETE);
} }
@ -462,11 +464,11 @@ vi_delete_meta(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_end_big_word(EditLine *el, int c __attribute__((__unused__))) vi_end_big_word(EditLine *el, Int c __attribute__((__unused__)))
{ {
if (el->el_line.cursor == el->el_line.lastchar) if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR); return CC_ERROR;
el->el_line.cursor = cv__endword(el->el_line.cursor, el->el_line.cursor = cv__endword(el->el_line.cursor,
el->el_line.lastchar, el->el_state.argument, cv__isWord); el->el_line.lastchar, el->el_state.argument, cv__isWord);
@ -474,9 +476,9 @@ vi_end_big_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
el->el_line.cursor++; el->el_line.cursor++;
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
return (CC_CURSOR); return CC_CURSOR;
} }
@ -486,11 +488,11 @@ vi_end_big_word(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (el->el_line.cursor == el->el_line.lastchar)
return (CC_ERROR); return CC_ERROR;
el->el_line.cursor = cv__endword(el->el_line.cursor, el->el_line.cursor = cv__endword(el->el_line.cursor,
el->el_line.lastchar, el->el_state.argument, cv__isword); el->el_line.lastchar, el->el_state.argument, cv__isword);
@ -498,9 +500,9 @@ vi_end_word(EditLine *el, int c __attribute__((__unused__)))
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
el->el_line.cursor++; el->el_line.cursor++;
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
return (CC_CURSOR); return CC_CURSOR;
} }
@ -510,7 +512,7 @@ vi_end_word(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; c_undo_t un = el->el_chared.c_undo;
@ -520,13 +522,14 @@ vi_undo(EditLine *el, int c __attribute__((__unused__)))
/* switch line buffer and undo buffer */ /* switch line buffer and undo buffer */
el->el_chared.c_undo.buf = el->el_line.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.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.limit = un.buf + (el->el_line.limit - el->el_line.buffer);
el->el_line.buffer = un.buf; el->el_line.buffer = un.buf;
el->el_line.cursor = un.buf + un.cursor; el->el_line.cursor = un.buf + un.cursor;
el->el_line.lastchar = un.buf + un.len; el->el_line.lastchar = un.buf + un.len;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -536,7 +539,7 @@ vi_undo(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_command_mode(EditLine *el, int c __attribute__((__unused__))) vi_command_mode(EditLine *el, Int c __attribute__((__unused__)))
{ {
/* [Esc] cancels pending action */ /* [Esc] cancels pending action */
@ -551,7 +554,7 @@ vi_command_mode(EditLine *el, int c __attribute__((__unused__)))
if (el->el_line.cursor > el->el_line.buffer) if (el->el_line.cursor > el->el_line.buffer)
el->el_line.cursor--; el->el_line.cursor--;
#endif #endif
return (CC_CURSOR); return CC_CURSOR;
} }
@ -560,7 +563,7 @@ vi_command_mode(EditLine *el, int c __attribute__((__unused__)))
* [0] * [0]
*/ */
protected el_action_t protected el_action_t
vi_zero(EditLine *el, int c) vi_zero(EditLine *el, Int c)
{ {
if (el->el_state.doingarg) if (el->el_state.doingarg)
@ -569,9 +572,9 @@ vi_zero(EditLine *el, int c)
el->el_line.cursor = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer;
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
return (CC_CURSOR); return CC_CURSOR;
} }
@ -581,15 +584,15 @@ vi_zero(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (el->el_line.cursor <= el->el_line.buffer)
return (CC_ERROR); return CC_ERROR;
c_delbefore1(el); c_delbefore1(el);
el->el_line.cursor--; el->el_line.cursor--;
return (CC_REFRESH); return CC_REFRESH;
} }
@ -599,32 +602,32 @@ vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) { if (el->el_line.cursor == el->el_line.lastchar) {
if (el->el_line.cursor == el->el_line.buffer) { if (el->el_line.cursor == el->el_line.buffer) {
term_writec(el, c); /* then do a EOF */ terminal_writec(el, c); /* then do a EOF */
return (CC_EOF); return CC_EOF;
} else { } else {
/* /*
* Here we could list completions, but it is an * Here we could list completions, but it is an
* error right now * error right now
*/ */
term_beep(el); terminal_beep(el);
return (CC_ERROR); return CC_ERROR;
} }
} else { } else {
#ifdef notyet #ifdef notyet
re_goto_bottom(el); re_goto_bottom(el);
*el->el_line.lastchar = '\0'; /* just in case */ *el->el_line.lastchar = '\0'; /* just in case */
return (CC_LIST_CHOICES); return CC_LIST_CHOICES;
#else #else
/* /*
* Just complain for now. * Just complain for now.
*/ */
term_beep(el); terminal_beep(el);
return (CC_ERROR); return CC_ERROR;
#endif #endif
} }
} }
@ -636,18 +639,18 @@ vi_list_or_eof(EditLine *el, int c)
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; cp = el->el_line.buffer;
kp = el->el_chared.c_kill.buf; kp = el->el_chared.c_kill.buf;
while (cp < el->el_line.cursor) while (cp < el->el_line.cursor)
*kp++ = *cp++; /* copy it */ *kp++ = *cp++; /* copy it */
el->el_chared.c_kill.last = kp; 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! */ el->el_line.cursor = el->el_line.buffer; /* zap! */
return (CC_REFRESH); return CC_REFRESH;
} }
@ -657,10 +660,10 @@ vi_kill_line_prev(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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)); return cv_search(el, ED_SEARCH_PREV_HISTORY);
} }
@ -670,10 +673,10 @@ vi_search_prev(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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)); return cv_search(el, ED_SEARCH_NEXT_HISTORY);
} }
@ -683,13 +686,13 @@ vi_search_next(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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) if (el->el_search.patlen == 0)
return (CC_ERROR); return CC_ERROR;
else else
return (cv_repeat_srch(el, el->el_search.patdir)); return cv_repeat_srch(el, el->el_search.patdir);
} }
@ -699,11 +702,11 @@ vi_repeat_search_next(EditLine *el, int c __attribute__((__unused__)))
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
protected el_action_t 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) if (el->el_search.patlen == 0)
return (CC_ERROR); return CC_ERROR;
else else
return (cv_repeat_srch(el, return (cv_repeat_srch(el,
el->el_search.patdir == ED_SEARCH_PREV_HISTORY ? el->el_search.patdir == ED_SEARCH_PREV_HISTORY ?
@ -717,7 +720,7 @@ vi_repeat_search_prev(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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); return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0);
} }
@ -729,7 +732,7 @@ vi_next_char(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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); return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0);
} }
@ -741,7 +744,7 @@ vi_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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); return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1);
} }
@ -753,7 +756,7 @@ vi_to_next_char(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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); return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1);
} }
@ -765,7 +768,7 @@ vi_to_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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, return cv_csearch(el, el->el_search.chadir, el->el_search.chacha,
@ -779,7 +782,7 @@ vi_repeat_next_char(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*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; el_action_t r;
int dir = el->el_search.chadir; int dir = el->el_search.chadir;
@ -797,20 +800,20 @@ vi_repeat_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_match(EditLine *el, int c __attribute__((__unused__))) vi_match(EditLine *el, Int c __attribute__((__unused__)))
{ {
const char match_chars[] = "()[]{}"; const Char match_chars[] = STR("()[]{}");
char *cp; Char *cp;
int delta, i, count; size_t delta, i, count;
char o_ch, c_ch; Char o_ch, c_ch;
*el->el_line.lastchar = '\0'; /* just in case */ *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]; o_ch = el->el_line.cursor[i];
if (o_ch == 0) if (o_ch == 0)
return CC_ERROR; return CC_ERROR;
delta = strchr(match_chars, o_ch) - match_chars; delta = (size_t)(Strchr(match_chars, o_ch) - match_chars);
c_ch = match_chars[delta ^ 1]; c_ch = match_chars[delta ^ 1];
count = 1; count = 1;
delta = 1 - (delta & 1) * 2; delta = 1 - (delta & 1) * 2;
@ -833,9 +836,9 @@ vi_match(EditLine *el, int c __attribute__((__unused__)))
if (delta > 0) if (delta > 0)
el->el_line.cursor++; el->el_line.cursor++;
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return CC_REFRESH;
} }
return (CC_CURSOR); return CC_CURSOR;
} }
/* vi_undo_line(): /* vi_undo_line():
@ -844,7 +847,7 @@ vi_match(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_undo_line(EditLine *el, int c __attribute__((__unused__))) vi_undo_line(EditLine *el, Int c __attribute__((__unused__)))
{ {
cv_undo(el); cv_undo(el);
@ -858,7 +861,7 @@ vi_undo_line(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_to_column(EditLine *el, int c __attribute__((__unused__))) vi_to_column(EditLine *el, Int c __attribute__((__unused__)))
{ {
el->el_line.cursor = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer;
@ -872,11 +875,11 @@ vi_to_column(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_yank_end(EditLine *el, int c __attribute__((__unused__))) vi_yank_end(EditLine *el, Int c __attribute__((__unused__)))
{ {
cv_yank(el, el->el_line.cursor, 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; return CC_REFRESH;
} }
@ -886,7 +889,7 @@ vi_yank_end(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_yank(EditLine *el, int c __attribute__((__unused__))) vi_yank(EditLine *el, Int c __attribute__((__unused__)))
{ {
return cv_action(el, YANK); return cv_action(el, YANK);
@ -898,7 +901,7 @@ vi_yank(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_comment_out(EditLine *el, int c __attribute__((__unused__))) vi_comment_out(EditLine *el, Int c __attribute__((__unused__)))
{ {
el->el_line.cursor = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer;
@ -915,18 +918,19 @@ vi_comment_out(EditLine *el, int c __attribute__((__unused__)))
* this is against historical precedent... * this is against historical precedent...
*/ */
#if defined(__weak_reference) && !defined(__FreeBSD__) #if defined(__weak_reference) && !defined(__FreeBSD__)
extern char *get_alias_text(const char *) __weak_reference(get_alias_text); __weakref_visible char *my_get_alias_text(const char *)
__weak_reference(get_alias_text);
#endif #endif
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_alias(EditLine *el __attribute__((__unused__)), vi_alias(EditLine *el __attribute__((__unused__)),
int c __attribute__((__unused__))) Int c __attribute__((__unused__)))
{ {
#if defined(__weak_reference) && !defined(__FreeBSD__) #if defined(__weak_reference) && !defined(__FreeBSD__)
char alias_name[3]; char alias_name[3];
char *alias_text; char *alias_text;
if (get_alias_text == 0) { if (my_get_alias_text == 0) {
return CC_ERROR; return CC_ERROR;
} }
@ -935,9 +939,9 @@ vi_alias(EditLine *el __attribute__((__unused__)),
if (el_getc(el, &alias_name[1]) != 1) if (el_getc(el, &alias_name[1]) != 1)
return CC_ERROR; return CC_ERROR;
alias_text = get_alias_text(alias_name); alias_text = my_get_alias_text(alias_name);
if (alias_text != NULL) if (alias_text != NULL)
el_push(el, alias_text); FUN(el,push)(el, ct_decode_string(alias_text, &el->el_scratch));
return CC_NORM; return CC_NORM;
#else #else
return CC_ERROR; return CC_ERROR;
@ -950,14 +954,14 @@ vi_alias(EditLine *el __attribute__((__unused__)),
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_to_history_line(EditLine *el, int c __attribute__((__unused__))) vi_to_history_line(EditLine *el, Int c __attribute__((__unused__)))
{ {
int sv_event_no = el->el_history.eventno; int sv_event_no = el->el_history.eventno;
el_action_t rval; el_action_t rval;
if (el->el_history.eventno == 0) { 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_BUFSIZ);
el->el_history.last = el->el_history.buf + el->el_history.last = el->el_history.buf +
(el->el_line.lastchar - el->el_line.buffer); (el->el_line.lastchar - el->el_line.buffer);
@ -995,14 +999,19 @@ vi_to_history_line(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_histedit(EditLine *el, int c __attribute__((__unused__))) vi_histedit(EditLine *el, Int c __attribute__((__unused__)))
{ {
int fd; int fd;
pid_t pid; pid_t pid;
int st; ssize_t st;
int status;
char tempfile[] = "/tmp/histedit.XXXXXXXXXX"; char tempfile[] = "/tmp/histedit.XXXXXXXXXX";
char *cp; char *cp;
size_t len;
Char *line;
mbstate_t state;
memset(&state, 0, sizeof(mbstate_t));
if (el->el_state.doingarg) { if (el->el_state.doingarg) {
if (vi_to_history_line(el, 0) == CC_ERROR) if (vi_to_history_line(el, 0) == CC_ERROR)
return CC_ERROR; return CC_ERROR;
@ -1011,16 +1020,35 @@ vi_histedit(EditLine *el, int c __attribute__((__unused__)))
fd = mkstemp(tempfile); fd = mkstemp(tempfile);
if (fd < 0) if (fd < 0)
return CC_ERROR; return CC_ERROR;
cp = el->el_line.buffer; len = (size_t)(el->el_line.lastchar - el->el_line.buffer);
if (write(fd, cp, el->el_line.lastchar - cp +0u) == -1) #define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX)
cp = el_malloc(TMP_BUFSIZ * sizeof(*cp));
if (cp == NULL) {
unlink(tempfile);
close(fd);
return CC_ERROR;
}
line = el_malloc(len * sizeof(*line));
if (line == NULL) {
el_free(cp);
return CC_ERROR;
}
Strncpy(line, el->el_line.buffer, len);
line[len] = '\0';
wcsrtombs(cp, (const wchar_t **) &line, TMP_BUFSIZ - 1, &state);
cp[TMP_BUFSIZ - 1] = '\0';
len = strlen(cp);
if (write(fd, cp, len) == -1)
goto error; goto error;
if (write(fd, "\n", 1) == -1) if (write(fd, "\n", (size_t)1) == -1)
goto error; goto error;
pid = fork(); pid = fork();
switch (pid) { switch (pid) {
case -1: case -1:
close(fd); close(fd);
unlink(tempfile); unlink(tempfile);
el_free(cp);
el_free(line);
return CC_ERROR; return CC_ERROR;
case 0: case 0:
close(fd); close(fd);
@ -1028,14 +1056,25 @@ vi_histedit(EditLine *el, int c __attribute__((__unused__)))
exit(0); exit(0);
/*NOTREACHED*/ /*NOTREACHED*/
default: default:
while (waitpid(pid, &st, 0) != pid) while (waitpid(pid, &status, 0) != pid)
continue; continue;
lseek(fd, 0ll, SEEK_SET); lseek(fd, (off_t)0, SEEK_SET);
st = read(fd, cp, el->el_line.limit - cp +0u); st = read(fd, cp, TMP_BUFSIZ);
if (st > 0 && cp[st - 1] == '\n') if (st > 0) {
st--; len = (size_t)(el->el_line.lastchar -
el->el_line.cursor = cp; el->el_line.buffer);
el->el_line.lastchar = cp + st; memset(&state, 0, sizeof(mbstate_t));
len = mbsrtowcs(el->el_line.buffer,
(const char**) &cp, len, &state);
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; break;
} }
@ -1059,34 +1098,35 @@ error:
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_history_word(EditLine *el, int c __attribute__((__unused__))) vi_history_word(EditLine *el, Int c __attribute__((__unused__)))
{ {
const char *wp = HIST_FIRST(el); const Char *wp = HIST_FIRST(el);
const char *wep, *wsp; const Char *wep, *wsp;
int len; int len;
char *cp; Char *cp;
const char *lim; const Char *lim;
if (wp == NULL) if (wp == NULL)
return CC_ERROR; return CC_ERROR;
wep = wsp = 0; wep = wsp = 0;
do { do {
while (isspace((unsigned char)*wp)) while (Isspace(*wp))
wp++; wp++;
if (*wp == 0) if (*wp == 0)
break; break;
wsp = wp; wsp = wp;
while (*wp && !isspace((unsigned char)*wp)) while (*wp && !Isspace(*wp))
wp++; wp++;
wep = 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)) if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0))
return CC_ERROR; return CC_ERROR;
cv_undo(el); cv_undo(el);
len = wep - wsp; len = (int)(wep - wsp);
if (el->el_line.cursor < el->el_line.lastchar) if (el->el_line.cursor < el->el_line.lastchar)
el->el_line.cursor++; el->el_line.cursor++;
c_insert(el, len + 1); c_insert(el, len + 1);
@ -1108,7 +1148,7 @@ vi_history_word(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_redo(EditLine *el, int c __attribute__((__unused__))) vi_redo(EditLine *el, Int c __attribute__((__unused__)))
{ {
c_redo_t *r = &el->el_chared.c_redo; c_redo_t *r = &el->el_chared.c_redo;
@ -1124,10 +1164,10 @@ vi_redo(EditLine *el, int c __attribute__((__unused__)))
/* sanity */ /* sanity */
r->pos = r->lim - 1; r->pos = r->lim - 1;
r->pos[0] = 0; r->pos[0] = 0;
el_push(el, r->buf); FUN(el,push)(el, r->buf);
} }
el->el_state.thiscmd = r->cmd; el->el_state.thiscmd = r->cmd;
el->el_state.thisch = r->ch; el->el_state.thisch = r->ch;
return (*el->el_map.func[r->cmd])(el, r->ch); return (*el->el_map.func[r->cmd])(el, r->ch);
} }