Index: bin/sh/histedit.c =================================================================== --- bin/sh/histedit.c (revision 258914) +++ bin/sh/histedit.c (working copy) @@ -124,7 +124,7 @@ el_set(el, EL_PROMPT, getprompt); el_set(el, EL_ADDFN, "sh-complete", "Filename completion", - _el_fn_sh_complete); + _el_fn_complete); } else { bad: out2fmt_flush("sh: can't initialize editing\n"); Index: lib/libedit/Makefile =================================================================== --- lib/libedit/Makefile (revision 258914) +++ lib/libedit/Makefile (working copy) @@ -1,14 +1,17 @@ -# $NetBSD: Makefile,v 1.34 2005/05/28 12:02:53 lukem Exp $ +# $NetBSD: Makefile,v 1.51 2012/08/10 12:20:10 joerg Exp $ # @(#)Makefile 8.1 (Berkeley) 6/4/93 # $FreeBSD$ +# on FreeBSD we always choose WIDECHAR=yes option +WIDECHAR = yes + LIB= edit SHLIB_MAJOR= 7 SHLIBDIR?= /lib OSRCS= chared.c common.c el.c emacs.c fcns.c filecomplete.c help.c \ - hist.c key.c map.c \ - parse.c prompt.c read.c refresh.c search.c sig.c term.c tty.c vi.c + hist.c keymacro.c map.c chartype.c \ + parse.c prompt.c read.c refresh.c search.c sig.c terminal.c tty.c vi.c DPADD= ${LIBNCURSES} LDADD= -lncurses @@ -15,13 +18,13 @@ MAN= editline.3 editrc.5 -MLINKS= editline.3 el_deletestr.3 editline.3 el_end.3 editline.3 el_init.3 \ - editline.3 el_get.3 editline.3 el_getc.3 editline.3 el_gets.3 \ - editline.3 history.3 editline.3 history_end.3 \ - editline.3 history_init.3 editline.3 el_insertstr.3 \ - editline.3 el_line.3 editline.3 el_parse.3 editline.3 el_push.3 \ - editline.3 el_reset.3 editline.3 el_resize.3 editline.3 el_set.3 \ - editline.3 el_source.3 \ +MLINKS= editline.3 el_init.3 editline.3 el_end.3 editline.3 el_reset.3 \ + editline.3 el_gets.3 editline.3 el_getc.3 editline.3 el_push.3 \ + editline.3 el_parse.3 editline.3 el_set.3 editline.3 el_get.3 \ + editline.3 el_source.3 editline.3 el_resize.3 editline.3 el_line.3 \ + editline.3 el_insertstr.3 editline.3 el_deletestr.3 \ + editline.3 history_init.3 editline.3 history_end.3 \ + editline.3 history.3 \ editline.3 tok_init.3 editline.3 tok_end.3 editline.3 tok_reset.3 \ editline.3 tok_line.3 editline.3 tok_str.3 @@ -31,6 +34,15 @@ SRCS= editline.c SRCS+= tokenizer.c history.c readline.c SRCS+= common.h emacs.h fcns.h help.h vi.h + +.if ${WIDECHAR} == "yes" +OSRCS += eln.c +SRCS += tokenizern.c historyn.c +CLEANFILES+=tokenizern.c.tmp tokenizern.c historyn.c.tmp historyn.c +CFLAGS+=-DWIDECHAR +CPPFLAGS+=-DWIDECHAR +.endif + CLEANFILES+= common.h editline.c emacs.h fcns.c fcns.h help.c help.h vi.h INCS= histedit.h @@ -63,6 +75,14 @@ help.h: ${ASRC} makelist sh ${.CURDIR}/makelist -bh ${ASRC} > ${.TARGET} +tokenizern.c: makelist Makefile + ${_MKTARGET_CREATE} + sh ${.CURDIR}/makelist -n tokenizer.c > ${.TARGET} + +historyn.c: makelist Makefile + ${_MKTARGET_CREATE} + sh ${.CURDIR}/makelist -n history.c > ${.TARGET} + editline.c: ${OSRCS} sh ${.CURDIR}/makelist -e ${.ALLSRC:T} > ${.TARGET} @@ -76,3 +96,11 @@ ${CC} ${CFLAGS} ${.ALLSRC} -o ${.TARGET} libedit.a ${LDADD} .include +.include + +# XXX +.if defined(HAVE_GCC) && ${HAVE_GCC} >= 45 +COPTS.editline.c+= -Wno-cast-qual +COPTS.tokenizer.c+= -Wno-cast-qual +COPTS.tokenizern.c+= -Wno-cast-qual +.endif Index: lib/libedit/chared.c =================================================================== --- lib/libedit/chared.c (revision 258914) +++ lib/libedit/chared.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: chared.c,v 1.39 2013/07/12 22:39:50 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: chared.c,v 1.27 2009/02/15 21:55:23 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -41,12 +42,10 @@ /* * chared.c: Character editor utilities */ -#include "sys.h" - #include #include "el.h" -private void ch__clearmacro(EditLine *); +private void ch__clearmacro (EditLine *); /* value to leave unused in line buffer */ #define EL_LEAVE 2 @@ -62,10 +61,10 @@ size_t size; /* Save entire line for undo */ - size = el->el_line.lastchar - el->el_line.buffer; - vu->len = size; + size = (size_t)(el->el_line.lastchar - el->el_line.buffer); + vu->len = (ssize_t)size; 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 */ r->count = el->el_state.doingarg ? el->el_state.argument : 0; @@ -79,11 +78,11 @@ * Save yank/delete data for paste */ protected void -cv_yank(EditLine *el, const char *ptr, int size) +cv_yank(EditLine *el, const Char *ptr, int size) { c_kill_t *k = &el->el_chared.c_kill; - memcpy(k->buf, ptr, (size_t)size); + (void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf)); k->last = k->buf + size; } @@ -94,7 +93,7 @@ protected void c_insert(EditLine *el, int num) { - char *cp; + Char *cp; if (el->el_line.lastchar + num >= el->el_line.limit) { if (!ch_enlargebufs(el, (size_t)num)) @@ -126,7 +125,7 @@ } if (num > 0) { - char *cp; + Char *cp; for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) *cp = cp[num]; @@ -142,7 +141,7 @@ protected void c_delafter1(EditLine *el) { - char *cp; + Char *cp; for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) *cp = cp[1]; @@ -167,7 +166,7 @@ } if (num > 0) { - char *cp; + Char *cp; for (cp = el->el_line.cursor - num; cp <= el->el_line.lastchar; @@ -185,7 +184,7 @@ protected void c_delbefore1(EditLine *el) { - char *cp; + Char *cp; for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++) *cp = cp[1]; @@ -198,9 +197,9 @@ * Return if p is part of a word according to emacs */ protected int -ce__isword(int p) +ce__isword(Int p) { - return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL); + return Isalnum(p) || Strchr(STR("*?_-.[]~="), p) != NULL; } @@ -208,11 +207,11 @@ * Return if p is part of a word according to vi */ protected int -cv__isword(int p) +cv__isword(Int p) { - if (isalnum(p) || p == '_') + if (Isalnum(p) || p == '_') return 1; - if (isgraph(p)) + if (Isgraph(p)) return 2; return 0; } @@ -222,9 +221,9 @@ * Return if p is part of a big word according to vi */ protected int -cv__isWord(int p) +cv__isWord(Int p) { - return (!isspace(p)); + return !Isspace(p); } @@ -231,15 +230,15 @@ /* c__prev_word(): * Find the previous word */ -protected char * -c__prev_word(char *p, char *low, int n, int (*wtest)(int)) +protected Char * +c__prev_word(Char *p, Char *low, int n, int (*wtest)(Int)) { p--; while (n--) { - while ((p >= low) && !(*wtest)((unsigned char) *p)) + while ((p >= low) && !(*wtest)(*p)) p--; - while ((p >= low) && (*wtest)((unsigned char) *p)) + while ((p >= low) && (*wtest)(*p)) p--; } @@ -248,7 +247,7 @@ if (p < low) p = low; /* cp now points where we want it */ - return (p); + return p; } @@ -255,32 +254,32 @@ /* c__next_word(): * Find the next word */ -protected char * -c__next_word(char *p, char *high, int n, int (*wtest)(int)) +protected Char * +c__next_word(Char *p, Char *high, int n, int (*wtest)(Int)) { while (n--) { - while ((p < high) && !(*wtest)((unsigned char) *p)) + while ((p < high) && !(*wtest)(*p)) p++; - while ((p < high) && (*wtest)((unsigned char) *p)) + while ((p < high) && (*wtest)(*p)) p++; } if (p > high) p = high; /* p now points where we want it */ - return (p); + return p; } /* cv_next_word(): * Find the next word vi style */ -protected char * -cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int)) +protected Char * +cv_next_word(EditLine *el, Char *p, Char *high, int n, int (*wtest)(Int)) { int test; while (n--) { - test = (*wtest)((unsigned char) *p); - while ((p < high) && (*wtest)((unsigned char) *p) == test) + test = (*wtest)(*p); + while ((p < high) && (*wtest)(*p) == test) p++; /* * vi historically deletes with cw only the word preserving the @@ -287,15 +286,15 @@ * trailing whitespace! This is not what 'w' does.. */ if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT)) - while ((p < high) && isspace((unsigned char) *p)) + while ((p < high) && Isspace(*p)) p++; } /* p now points where we want it */ if (p > high) - return (high); + return high; else - return (p); + return p; } @@ -302,17 +301,17 @@ /* cv_prev_word(): * Find the previous word vi style */ -protected char * -cv_prev_word(char *p, char *low, int n, int (*wtest)(int)) +protected Char * +cv_prev_word(Char *p, Char *low, int n, int (*wtest)(Int)) { int test; p--; while (n--) { - while ((p > low) && isspace((unsigned char) *p)) + while ((p > low) && Isspace(*p)) p--; - test = (*wtest)((unsigned char) *p); - while ((p >= low) && (*wtest)((unsigned char) *p) == test) + test = (*wtest)(*p); + while ((p >= low) && (*wtest)(*p) == test) p--; } p++; @@ -319,46 +318,12 @@ /* p now points where we want it */ if (p < low) - return (low); + return low; 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(): * Finish vi delete action */ @@ -397,33 +362,11 @@ } -#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(): * Go to the end of this word according to vi */ -protected char * -cv__endword(char *p, char *high, int n, int (*wtest)(int)) +protected Char * +cv__endword(Char *p, Char *high, int n, int (*wtest)(Int)) { int test; @@ -430,15 +373,15 @@ p++; while (n--) { - while ((p < high) && isspace((unsigned char) *p)) + while ((p < high) && Isspace(*p)) p++; - test = (*wtest)((unsigned char) *p); - while ((p < high) && (*wtest)((unsigned char) *p) == test) + test = (*wtest)(*p); + while ((p < high) && (*wtest)(*p) == test) p++; } p--; - return (p); + return p; } /* ch_init(): @@ -449,24 +392,29 @@ { c_macro_t *ma = &el->el_chared.c_macro; - el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ); + el->el_line.buffer = el_malloc(EL_BUFSIZ * + sizeof(*el->el_line.buffer)); if (el->el_line.buffer == NULL) - return (-1); + return -1; - (void) memset(el->el_line.buffer, 0, EL_BUFSIZ); + (void) memset(el->el_line.buffer, 0, EL_BUFSIZ * + sizeof(*el->el_line.buffer)); el->el_line.cursor = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer; el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE]; - el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ); + el->el_chared.c_undo.buf = el_malloc(EL_BUFSIZ * + sizeof(*el->el_chared.c_undo.buf)); if (el->el_chared.c_undo.buf == NULL) - return (-1); - (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ); + return -1; + (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ * + sizeof(*el->el_chared.c_undo.buf)); el->el_chared.c_undo.len = -1; el->el_chared.c_undo.cursor = 0; - el->el_chared.c_redo.buf = (char *) el_malloc(EL_BUFSIZ); + el->el_chared.c_redo.buf = el_malloc(EL_BUFSIZ * + sizeof(*el->el_chared.c_redo.buf)); if (el->el_chared.c_redo.buf == NULL) - return (-1); + return -1; el->el_chared.c_redo.pos = el->el_chared.c_redo.buf; el->el_chared.c_redo.lim = el->el_chared.c_redo.buf + EL_BUFSIZ; el->el_chared.c_redo.cmd = ED_UNASSIGNED; @@ -474,12 +422,16 @@ el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.pos = el->el_line.buffer; - el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ); + el->el_chared.c_kill.buf = el_malloc(EL_BUFSIZ * + sizeof(*el->el_chared.c_kill.buf)); if (el->el_chared.c_kill.buf == NULL) - return (-1); - (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ); + return -1; + (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ * + sizeof(*el->el_chared.c_kill.buf)); el->el_chared.c_kill.mark = el->el_line.buffer; el->el_chared.c_kill.last = el->el_chared.c_kill.buf; + el->el_chared.c_resizefun = NULL; + el->el_chared.c_resizearg = NULL; el->el_map.current = el->el_map.key; @@ -491,10 +443,10 @@ ma->level = -1; ma->offset = 0; - ma->macro = (char **) el_malloc(EL_MAXMACRO * sizeof(char *)); + ma->macro = el_malloc(EL_MAXMACRO * sizeof(*ma->macro)); if (ma->macro == NULL) - return (-1); - return (0); + return -1; + return 0; } /* ch_reset(): @@ -533,7 +485,7 @@ { c_macro_t *ma = &el->el_chared.c_macro; while (ma->level >= 0) - el_free((ptr_t)ma->macro[ma->level--]); + el_free(ma->macro[ma->level--]); } /* ch_enlargebufs(): @@ -544,9 +496,9 @@ ch_enlargebufs(EditLine *el, size_t addlen) { size_t sz, newsz; - char *newbuffer, *oldbuf, *oldkbuf; + Char *newbuffer, *oldbuf, *oldkbuf; - sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE; + sz = (size_t)(el->el_line.limit - el->el_line.buffer + EL_LEAVE); newsz = sz * 2; /* * If newly required length is longer than current buffer, we need @@ -560,12 +512,12 @@ /* * Reallocate line buffer. */ - newbuffer = el_realloc(el->el_line.buffer, newsz); + newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer)); if (!newbuffer) return 0; /* zero the newly added memory, leave old data in */ - (void) memset(&newbuffer[sz], 0, newsz - sz); + (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); oldbuf = el->el_line.buffer; @@ -578,12 +530,13 @@ /* * Reallocate kill buffer. */ - newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz); + newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz * + sizeof(*newbuffer)); if (!newbuffer) return 0; /* zero the newly added memory, leave old data in */ - (void) memset(&newbuffer[sz], 0, newsz - sz); + (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); oldkbuf = el->el_chared.c_kill.buf; @@ -596,15 +549,17 @@ /* * Reallocate undo buffer. */ - newbuffer = el_realloc(el->el_chared.c_undo.buf, newsz); + newbuffer = el_realloc(el->el_chared.c_undo.buf, + newsz * sizeof(*newbuffer)); if (!newbuffer) return 0; /* zero the newly added memory, leave old data in */ - (void) memset(&newbuffer[sz], 0, newsz - sz); + (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); el->el_chared.c_undo.buf = newbuffer; - newbuffer = el_realloc(el->el_chared.c_redo.buf, newsz); + newbuffer = el_realloc(el->el_chared.c_redo.buf, + newsz * sizeof(*newbuffer)); if (!newbuffer) return 0; el->el_chared.c_redo.pos = newbuffer + @@ -618,6 +573,8 @@ /* Safe to set enlarged buffer size */ 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; } @@ -627,20 +584,20 @@ protected void 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.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_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.pos = NULL; el->el_chared.c_redo.lim = NULL; el->el_chared.c_redo.cmd = ED_UNASSIGNED; - el_free((ptr_t) el->el_chared.c_kill.buf); + el_free(el->el_chared.c_kill.buf); el->el_chared.c_kill.buf = NULL; 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; } @@ -649,21 +606,21 @@ * Insert string at cursorI */ public int -el_insertstr(EditLine *el, const char *s) +FUN(el,insertstr)(EditLine *el, const Char *s) { size_t len; - if ((len = strlen(s)) == 0) - return (-1); + if (s == NULL || (len = Strlen(s)) == 0) + return -1; if (el->el_line.lastchar + len >= el->el_line.limit) { if (!ch_enlargebufs(el, len)) - return (-1); + return -1; } c_insert(el, (int)len); while (*s) *el->el_line.cursor++ = *s++; - return (0); + return 0; } @@ -685,19 +642,38 @@ el->el_line.cursor = el->el_line.buffer; } +/* el_cursor(): + * Move the cursor to the left or the right of the current position + */ +public int +el_cursor(EditLine *el, int n) +{ + if (n == 0) + goto out; + + el->el_line.cursor += n; + + if (el->el_line.cursor < el->el_line.buffer) + el->el_line.cursor = el->el_line.buffer; + if (el->el_line.cursor > el->el_line.lastchar) + el->el_line.cursor = el->el_line.lastchar; +out: + return (int)(el->el_line.cursor - el->el_line.buffer); +} + /* c_gets(): * Get a string */ protected int -c_gets(EditLine *el, char *buf, const char *prompt) +c_gets(EditLine *el, Char *buf, const Char *prompt) { - char ch; + Char ch; ssize_t len; - char *cp = el->el_line.buffer; + Char *cp = el->el_line.buffer; if (prompt) { - len = strlen(prompt); - memcpy(cp, prompt, (size_t)len); + len = (ssize_t)Strlen(prompt); + (void)memcpy(cp, prompt, (size_t)len * sizeof(*cp)); cp += len; } len = 0; @@ -708,7 +684,7 @@ el->el_line.lastchar = cp + 1; re_refresh(el); - if (el_getc(el, &ch) != 1) { + if (FUN(el,getc)(el, &ch) != 1) { ed_end_of_file(el, 0); len = -1; break; @@ -716,8 +692,8 @@ switch (ch) { - case '\010': /* Delete and backspace */ - case '\177': + case 0010: /* Delete and backspace */ + case 0177: if (len == 0) { len = -1; break; @@ -725,7 +701,7 @@ cp--; continue; - case '\033': /* ESC */ + case 0033: /* ESC */ case '\r': /* Newline */ case '\n': buf[len] = ch; @@ -732,8 +708,8 @@ break; default: - if (len >= EL_BUFSIZ - 16) - term_beep(el); + if (len >= (ssize_t)(EL_BUFSIZ - 16)) + terminal_beep(el); else { buf[len++] = ch; *cp++ = ch; @@ -756,13 +732,13 @@ protected int c_hpos(EditLine *el) { - char *ptr; + Char *ptr; /* * Find how many characters till the beginning of this line. */ if (el->el_line.cursor == el->el_line.buffer) - return (0); + return 0; else { for (ptr = el->el_line.cursor - 1; ptr >= el->el_line.buffer && *ptr != '\n'; @@ -771,3 +747,11 @@ 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; +} Index: lib/libedit/chared.h =================================================================== --- lib/libedit/chared.h (revision 258914) +++ lib/libedit/chared.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: chared.h,v 1.21 2010/08/28 15:44:59 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +32,6 @@ * SUCH DAMAGE. * * @(#)chared.h 8.1 (Berkeley) 6/4/93 - * $NetBSD: chared.h,v 1.18 2009/02/15 21:55:23 christos Exp $ * $FreeBSD$ */ @@ -63,7 +64,7 @@ typedef struct c_macro_t { int level; int offset; - char **macro; + Char **macro; } c_macro_t; /* @@ -72,16 +73,16 @@ typedef struct c_undo_t { ssize_t len; /* length of saved line */ int cursor; /* position of saved cursor */ - char *buf; /* full saved text */ + Char *buf; /* full saved text */ } c_undo_t; /* redo for vi */ typedef struct c_redo_t { - char *buf; /* redo insert key sequence */ - char *pos; - char *lim; + Char *buf; /* redo insert key sequence */ + Char *pos; + Char *lim; el_action_t cmd; /* command to redo */ - char ch; /* char that invoked it */ + Char ch; /* char that invoked it */ int count; int action; /* from cv_action() */ } c_redo_t; @@ -91,7 +92,7 @@ */ typedef struct c_vcmd_t { int action; - char *pos; + Char *pos; } c_vcmd_t; /* @@ -98,11 +99,13 @@ * Kill buffer for emacs */ typedef struct c_kill_t { - char *buf; - char *last; - char *mark; + Char *buf; + Char *last; + Char *mark; } c_kill_t; +typedef void (*el_zfunc_t)(EditLine *, void *); + /* * Note that we use both data structures because the user can bind * commands from both editors! @@ -113,6 +116,8 @@ c_redo_t c_redo; c_vcmd_t c_vcmd; c_macro_t c_macro; + el_zfunc_t c_resizefun; + void * c_resizearg; } el_chared_t; @@ -119,7 +124,6 @@ #define STRQQ "\"\"" #define isglob(a) (strchr("*[]?", (a)) != NULL) -#define isword(a) (isprint(a)) #define NOP 0x00 #define DELETE 0x01 @@ -140,27 +144,28 @@ #include "fcns.h" -protected int cv__isword(int); -protected int cv__isWord(int); +protected int cv__isword(Int); +protected int cv__isWord(Int); protected void cv_delfini(EditLine *); -protected char *cv__endword(char *, char *, int, int (*)(int)); -protected int ce__isword(int); +protected Char *cv__endword(Char *, Char *, int, int (*)(Int)); +protected int ce__isword(Int); protected void cv_undo(EditLine *); -protected void cv_yank(EditLine *, const char *, int); -protected char *cv_next_word(EditLine*, char *, char *, int, int (*)(int)); -protected char *cv_prev_word(char *, char *, int, int (*)(int)); -protected char *c__next_word(char *, char *, int, int (*)(int)); -protected char *c__prev_word(char *, char *, int, int (*)(int)); +protected void cv_yank(EditLine *, const Char *, int); +protected Char *cv_next_word(EditLine*, Char *, Char *, int, int (*)(Int)); +protected Char *cv_prev_word(Char *, Char *, int, int (*)(Int)); +protected Char *c__next_word(Char *, Char *, int, int (*)(Int)); +protected Char *c__prev_word(Char *, Char *, int, int (*)(Int)); protected void c_insert(EditLine *, int); protected void c_delbefore(EditLine *, int); protected void c_delbefore1(EditLine *); protected void c_delafter(EditLine *, int); protected void c_delafter1(EditLine *); -protected int c_gets(EditLine *, char *, const char *); +protected int c_gets(EditLine *, Char *, const Char *); protected int c_hpos(EditLine *); protected int ch_init(EditLine *); protected void ch_reset(EditLine *, int); +protected int ch_resizefun(EditLine *, el_zfunc_t, void *); protected int ch_enlargebufs(EditLine *, size_t); protected void ch_end(EditLine *); Index: lib/libedit/chartype.c =================================================================== --- lib/libedit/chartype.c (revision 0) +++ lib/libedit/chartype.c (working copy) @@ -0,0 +1,353 @@ +/* $NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $ */ + +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Christos Zoulas of Cornell University. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + * chartype.c: character classification and meta information + */ +#include "config.h" +#include "el.h" +#include +__FBSDID("$FreeBSD$"); + +#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; + + 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); + 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; + + /* 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 mbstowcs */ + wargv[i] = NULL; + continue; + } else { + wargv[i] = p; + bytes = (ssize_t)mbstowcs(p, argv[i], bufspace); + } + 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) +{ + ssize_t l = 0; + if (len < ct_enc_width(c)) + return -1; + l = ct_wctomb(dst, c); + + if (l < 0) { + ct_wctomb_reset; + l = 0; + } + return l; +} +#endif + +protected const Char * +ct_visual_string(const Char *s) +{ + static Char *buff = NULL; + static size_t buffsize = 0; + void *p; + Char *dst; + ssize_t used = 0; + + if (!s) + return NULL; + if (!buff) { + buffsize = CT_BUFSIZ; + buff = el_malloc(buffsize * sizeof(*buff)); + } + dst = buff; + while (*s) { + used = ct_visual_char(dst, buffsize - (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; +} + + + +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; +} Property changes on: lib/libedit/chartype.c ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: lib/libedit/chartype.h =================================================================== --- lib/libedit/chartype.h (revision 258914) +++ lib/libedit/chartype.h (working copy) @@ -1,4 +1,4 @@ -/* $NetBSD: chartype.h,v 1.6 2010/04/20 02:01:13 christos Exp $ */ +/* $NetBSD: chartype.h,v 1.10 2011/11/16 01:45:10 christos Exp $ */ /*- * Copyright (c) 2009 The NetBSD Foundation, Inc. @@ -51,7 +51,7 @@ /* 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 + /* #error wchar_t must store ISO 10646 characters */ #endif #endif @@ -63,7 +63,7 @@ #endif #define ct_mbtowc mbtowc -#define ct_mbtowc_reset mbtowc(0,0,0) +#define ct_mbtowc_reset mbtowc(0,0,(size_t)0) #define ct_wctomb wctomb #define ct_wctomb_reset wctomb(0,0) #define ct_wcstombs wcstombs @@ -107,7 +107,12 @@ #define Strtol(p,e,b) wcstol(p,e,b) -#define Width(c) wcwidth(c) +static inline int +Width(wchar_t c) +{ + int w = wcwidth(c); + return w < 0 ? 0 : w; +} #else /* NARROW */ @@ -174,11 +179,11 @@ } ct_buffer_t; #define ct_encode_string __ct_encode_string -/* Encode a wide character string and return the UTF-8 encoded result. */ +/* 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. */ +/* 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. @@ -208,7 +213,7 @@ /* The maximum buffer size to hold the most unwieldly visual representation, * in this case \U+nnnnn. */ -#define VISUAL_WIDTH_MAX 8 +#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 Index: lib/libedit/common.c =================================================================== --- lib/libedit/common.c (revision 258914) +++ lib/libedit/common.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: common.c,v 1.29 2012/03/24 20:08:43 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: common.c,v 1.19 2006/03/06 21:11:56 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -41,7 +42,6 @@ /* * common.c: Common Editor functions */ -#include "sys.h" #include "el.h" /* ed_end_of_file(): @@ -50,12 +50,12 @@ */ protected el_action_t /*ARGSUSED*/ -ed_end_of_file(EditLine *el, int c __unused) +ed_end_of_file(EditLine *el, Int c __attribute__((__unused__))) { re_goto_bottom(el); *el->el_line.lastchar = '\0'; - return (CC_EOF); + return CC_EOF; } @@ -64,12 +64,12 @@ * Insert a character [bound to all insert keys] */ protected el_action_t -ed_insert(EditLine *el, int c) +ed_insert(EditLine *el, Int c) { int count = el->el_state.argument; if (c == '\0') - return (CC_ERROR); + return CC_ERROR; if (el->el_line.lastchar + el->el_state.argument >= el->el_line.limit) { @@ -97,7 +97,7 @@ if (el->el_state.inputmode == MODE_REPLACE_1) return vi_command_mode(el, 0); - return (CC_NORM); + return CC_NORM; } @@ -107,12 +107,12 @@ */ protected el_action_t /*ARGSUSED*/ -ed_delete_prev_word(EditLine *el, int c __unused) +ed_delete_prev_word(EditLine *el, Int c __attribute__((__unused__))) { - char *cp, *p, *kp; + Char *cp, *p, *kp; if (el->el_line.cursor == el->el_line.buffer) - return (CC_ERROR); + return CC_ERROR; cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, el->el_state.argument, ce__isword); @@ -121,11 +121,11 @@ *kp++ = *p; el->el_chared.c_kill.last = kp; - c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */ + c_delbefore(el, (int)(el->el_line.cursor - cp));/* delete before dot */ el->el_line.cursor = cp; if (el->el_line.cursor < el->el_line.buffer) el->el_line.cursor = el->el_line.buffer; /* bounds check */ - return (CC_REFRESH); + return CC_REFRESH; } @@ -135,9 +135,9 @@ */ protected el_action_t /*ARGSUSED*/ -ed_delete_next_char(EditLine *el, int c) +ed_delete_next_char(EditLine *el, Int c __attribute__((__unused__))) { -#ifdef notdef /* XXX */ +#ifdef DEBUG_EDIT #define EL el->el_line (void) fprintf(el->el_errlfile, "\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n", @@ -150,21 +150,21 @@ if (el->el_line.cursor == el->el_line.buffer) { /* if I'm also at the beginning */ #ifdef KSHVI - return (CC_ERROR); + return CC_ERROR; #else /* then do an EOF */ - term_writechar(el, c); - return (CC_EOF); + terminal_writec(el, c); + return CC_EOF; #endif } else { #ifdef KSHVI el->el_line.cursor--; #else - return (CC_ERROR); + return CC_ERROR; #endif } } else - return (CC_ERROR); + return CC_ERROR; } c_delafter(el, el->el_state.argument); /* delete after dot */ if (el->el_map.type == MAP_VI && @@ -172,7 +172,7 @@ el->el_line.cursor > el->el_line.buffer) /* bounds check */ el->el_line.cursor = el->el_line.lastchar - 1; - return (CC_REFRESH); + return CC_REFRESH; } @@ -182,9 +182,9 @@ */ protected el_action_t /*ARGSUSED*/ -ed_kill_line(EditLine *el, int c __unused) +ed_kill_line(EditLine *el, Int c __attribute__((__unused__))) { - char *kp, *cp; + Char *kp, *cp; cp = el->el_line.cursor; kp = el->el_chared.c_kill.buf; @@ -193,7 +193,7 @@ el->el_chared.c_kill.last = kp; /* zap! -- delete to end */ el->el_line.lastchar = el->el_line.cursor; - return (CC_REFRESH); + return CC_REFRESH; } @@ -203,20 +203,20 @@ */ protected el_action_t /*ARGSUSED*/ -ed_move_to_end(EditLine *el, int c __unused) +ed_move_to_end(EditLine *el, Int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.lastchar; if (el->el_map.type == MAP_VI) { + if (el->el_chared.c_vcmd.action != NOP) { + cv_delfini(el); + return CC_REFRESH; + } #ifdef VI_MOVE el->el_line.cursor--; #endif - if (el->el_chared.c_vcmd.action != NOP) { - cv_delfini(el); - return (CC_REFRESH); - } } - return (CC_CURSOR); + return CC_CURSOR; } @@ -226,7 +226,7 @@ */ protected el_action_t /*ARGSUSED*/ -ed_move_to_beg(EditLine *el, int c __unused) +ed_move_to_beg(EditLine *el, Int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; @@ -233,14 +233,14 @@ if (el->el_map.type == MAP_VI) { /* We want FIRST non space character */ - while (isspace((unsigned char) *el->el_line.cursor)) + while (Isspace(*el->el_line.cursor)) el->el_line.cursor++; if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } } - return (CC_CURSOR); + return CC_CURSOR; } @@ -249,12 +249,12 @@ * [^T] [^T] */ protected el_action_t -ed_transpose_chars(EditLine *el, int c) +ed_transpose_chars(EditLine *el, Int c) { if (el->el_line.cursor < el->el_line.lastchar) { if (el->el_line.lastchar <= &el->el_line.buffer[1]) - return (CC_ERROR); + return CC_ERROR; else el->el_line.cursor++; } @@ -263,9 +263,9 @@ c = el->el_line.cursor[-2]; el->el_line.cursor[-2] = el->el_line.cursor[-1]; el->el_line.cursor[-1] = c; - return (CC_REFRESH); + return CC_REFRESH; } else - return (CC_ERROR); + return CC_ERROR; } @@ -275,15 +275,15 @@ */ protected el_action_t /*ARGSUSED*/ -ed_next_char(EditLine *el, int c __unused) +ed_next_char(EditLine *el, Int c __attribute__((__unused__))) { - char *lim = el->el_line.lastchar; + Char *lim = el->el_line.lastchar; if (el->el_line.cursor >= lim || (el->el_line.cursor == lim - 1 && el->el_map.type == MAP_VI && el->el_chared.c_vcmd.action == NOP)) - return (CC_ERROR); + return CC_ERROR; el->el_line.cursor += el->el_state.argument; if (el->el_line.cursor > lim) @@ -292,9 +292,9 @@ if (el->el_map.type == MAP_VI) if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -304,11 +304,11 @@ */ protected el_action_t /*ARGSUSED*/ -ed_prev_word(EditLine *el, int c __unused) +ed_prev_word(EditLine *el, Int c __attribute__((__unused__))) { 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.buffer, @@ -318,9 +318,9 @@ if (el->el_map.type == MAP_VI) if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -330,7 +330,7 @@ */ protected el_action_t /*ARGSUSED*/ -ed_prev_char(EditLine *el, int c __unused) +ed_prev_char(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor > el->el_line.buffer) { @@ -341,11 +341,11 @@ if (el->el_map.type == MAP_VI) if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } else - return (CC_ERROR); + return CC_ERROR; } @@ -354,19 +354,19 @@ * [^V] [^V] */ protected el_action_t -ed_quoted_insert(EditLine *el, int c) +ed_quoted_insert(EditLine *el, Int c) { int num; - char tc; + Char tc; tty_quotemode(el); - num = el_getc(el, &tc); - c = (unsigned char) tc; + num = FUN(el,getc)(el, &tc); + c = tc; tty_noquotemode(el); if (num == 1) - return (ed_insert(el, c)); + return ed_insert(el, c); else - return (ed_end_of_file(el, 0)); + return ed_end_of_file(el, 0); } @@ -374,11 +374,11 @@ * Adds to argument or enters a digit */ protected el_action_t -ed_digit(EditLine *el, int c) +ed_digit(EditLine *el, Int c) { - if (!isdigit((unsigned char) c)) - return (CC_ERROR); + if (!Isdigit(c)) + return CC_ERROR; if (el->el_state.doingarg) { /* if doing an arg, add this in... */ @@ -386,11 +386,11 @@ el->el_state.argument = c - '0'; else { if (el->el_state.argument > 1000000) - return (CC_ERROR); + return CC_ERROR; el->el_state.argument = (el->el_state.argument * 10) + (c - '0'); } - return (CC_ARGHACK); + return CC_ARGHACK; } return ed_insert(el, c); @@ -402,15 +402,15 @@ * For ESC-n */ protected el_action_t -ed_argument_digit(EditLine *el, int c) +ed_argument_digit(EditLine *el, Int c) { - if (!isdigit((unsigned char) c)) - return (CC_ERROR); + if (!Isdigit(c)) + return CC_ERROR; if (el->el_state.doingarg) { if (el->el_state.argument > 1000000) - return (CC_ERROR); + return CC_ERROR; el->el_state.argument = (el->el_state.argument * 10) + (c - '0'); } else { /* else starting an argument */ @@ -417,7 +417,7 @@ el->el_state.argument = c - '0'; el->el_state.doingarg = 1; } - return (CC_ARGHACK); + return CC_ARGHACK; } @@ -427,10 +427,11 @@ */ protected el_action_t /*ARGSUSED*/ -ed_unassigned(EditLine *el, int c __unused) +ed_unassigned(EditLine *el __attribute__((__unused__)), + Int c __attribute__((__unused__))) { - return (CC_ERROR); + return CC_ERROR; } @@ -444,11 +445,11 @@ */ protected el_action_t /*ARGSUSED*/ -ed_tty_sigint(EditLine *el __unused, - int c __unused) +ed_tty_sigint(EditLine *el __attribute__((__unused__)), + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -458,11 +459,11 @@ */ protected el_action_t /*ARGSUSED*/ -ed_tty_dsusp(EditLine *el __unused, - int c __unused) +ed_tty_dsusp(EditLine *el __attribute__((__unused__)), + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -472,11 +473,11 @@ */ protected el_action_t /*ARGSUSED*/ -ed_tty_flush_output(EditLine *el __unused, - int c __unused) +ed_tty_flush_output(EditLine *el __attribute__((__unused__)), + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -486,11 +487,11 @@ */ protected el_action_t /*ARGSUSED*/ -ed_tty_sigquit(EditLine *el __unused, - int c __unused) +ed_tty_sigquit(EditLine *el __attribute__((__unused__)), + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -500,11 +501,11 @@ */ protected el_action_t /*ARGSUSED*/ -ed_tty_sigtstp(EditLine *el __unused, - int c __unused) +ed_tty_sigtstp(EditLine *el __attribute__((__unused__)), + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -514,11 +515,11 @@ */ protected el_action_t /*ARGSUSED*/ -ed_tty_stop_output(EditLine *el __unused, - int c __unused) +ed_tty_stop_output(EditLine *el __attribute__((__unused__)), + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -528,11 +529,11 @@ */ protected el_action_t /*ARGSUSED*/ -ed_tty_start_output(EditLine *el __unused, - int c __unused) +ed_tty_start_output(EditLine *el __attribute__((__unused__)), + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -542,13 +543,13 @@ */ protected el_action_t /*ARGSUSED*/ -ed_newline(EditLine *el, int c __unused) +ed_newline(EditLine *el, Int c __attribute__((__unused__))) { re_goto_bottom(el); *el->el_line.lastchar++ = '\n'; *el->el_line.lastchar = '\0'; - return (CC_NEWLINE); + return CC_NEWLINE; } @@ -558,17 +559,17 @@ */ protected el_action_t /*ARGSUSED*/ -ed_delete_prev_char(EditLine *el, int c __unused) +ed_delete_prev_char(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor <= el->el_line.buffer) - return (CC_ERROR); + return CC_ERROR; c_delbefore(el, el->el_state.argument); el->el_line.cursor -= el->el_state.argument; if (el->el_line.cursor < el->el_line.buffer) el->el_line.cursor = el->el_line.buffer; - return (CC_REFRESH); + return CC_REFRESH; } @@ -578,12 +579,12 @@ */ protected el_action_t /*ARGSUSED*/ -ed_clear_screen(EditLine *el, int c __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 */ - return (CC_REFRESH); + return CC_REFRESH; } @@ -593,11 +594,11 @@ */ protected el_action_t /*ARGSUSED*/ -ed_redisplay(EditLine *el __unused, - int c __unused) +ed_redisplay(EditLine *el __attribute__((__unused__)), + Int c __attribute__((__unused__))) { - return (CC_REDISPLAY); + return CC_REDISPLAY; } @@ -607,11 +608,11 @@ */ protected el_action_t /*ARGSUSED*/ -ed_start_over(EditLine *el, int c __unused) +ed_start_over(EditLine *el, Int c __attribute__((__unused__))) { ch_reset(el, 0); - return (CC_REFRESH); + return CC_REFRESH; } @@ -621,11 +622,11 @@ */ protected el_action_t /*ARGSUSED*/ -ed_sequence_lead_in(EditLine *el __unused, - int c __unused) +ed_sequence_lead_in(EditLine *el __attribute__((__unused__)), + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -635,7 +636,7 @@ */ protected el_action_t /*ARGSUSED*/ -ed_prev_history(EditLine *el, int c __unused) +ed_prev_history(EditLine *el, Int c __attribute__((__unused__))) { char beep = 0; int sv_event = el->el_history.eventno; @@ -645,7 +646,7 @@ if (el->el_history.eventno == 0) { /* save the current buffer * away */ - (void) strncpy(el->el_history.buf, el->el_line.buffer, + (void) Strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ); el->el_history.last = el->el_history.buf + (el->el_line.lastchar - el->el_line.buffer); @@ -655,7 +656,7 @@ if (hist_get(el) == CC_ERROR) { if (el->el_map.type == MAP_VI) { el->el_history.eventno = sv_event; - return CC_ERROR; + } beep = 1; /* el->el_history.eventno was fixed by first call */ @@ -673,7 +674,7 @@ */ protected el_action_t /*ARGSUSED*/ -ed_next_history(EditLine *el, int c __unused) +ed_next_history(EditLine *el, Int c __attribute__((__unused__))) { el_action_t beep = CC_REFRESH, rval; @@ -700,9 +701,9 @@ */ protected el_action_t /*ARGSUSED*/ -ed_search_prev_history(EditLine *el, int c __unused) +ed_search_prev_history(EditLine *el, Int c __attribute__((__unused__))) { - const char *hp; + const Char *hp; int h; bool_t found = 0; @@ -715,20 +716,20 @@ "e_prev_search_hist(): eventno < 0;\n"); #endif el->el_history.eventno = 0; - return (CC_ERROR); + return CC_ERROR; } if (el->el_history.eventno == 0) { - (void) strncpy(el->el_history.buf, el->el_line.buffer, + (void) Strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ); el->el_history.last = el->el_history.buf + (el->el_line.lastchar - el->el_line.buffer); } if (el->el_history.ref == NULL) - return (CC_ERROR); + return CC_ERROR; hp = HIST_FIRST(el); if (hp == NULL) - return (CC_ERROR); + return CC_ERROR; c_setpat(el); /* Set search pattern !! */ @@ -739,7 +740,7 @@ #ifdef SDEBUG (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); #endif - if ((strncmp(hp, el->el_line.buffer, (size_t) + if ((Strncmp(hp, el->el_line.buffer, (size_t) (el->el_line.lastchar - el->el_line.buffer)) || hp[el->el_line.lastchar - el->el_line.buffer]) && c_hmatch(el, hp)) { @@ -754,11 +755,11 @@ #ifdef SDEBUG (void) fprintf(el->el_errfile, "not found\n"); #endif - return (CC_ERROR); + return CC_ERROR; } el->el_history.eventno = h; - return (hist_get(el)); + return hist_get(el); } @@ -768,9 +769,9 @@ */ protected el_action_t /*ARGSUSED*/ -ed_search_next_history(EditLine *el, int c __unused) +ed_search_next_history(EditLine *el, Int c __attribute__((__unused__))) { - const char *hp; + const Char *hp; int h; bool_t found = 0; @@ -779,14 +780,14 @@ *el->el_line.lastchar = '\0'; /* just in case */ if (el->el_history.eventno == 0) - return (CC_ERROR); + return CC_ERROR; if (el->el_history.ref == NULL) - return (CC_ERROR); + return CC_ERROR; hp = HIST_FIRST(el); if (hp == NULL) - return (CC_ERROR); + return CC_ERROR; c_setpat(el); /* Set search pattern !! */ @@ -794,7 +795,7 @@ #ifdef SDEBUG (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); #endif - if ((strncmp(hp, el->el_line.buffer, (size_t) + if ((Strncmp(hp, el->el_line.buffer, (size_t) (el->el_line.lastchar - el->el_line.buffer)) || hp[el->el_line.lastchar - el->el_line.buffer]) && c_hmatch(el, hp)) @@ -807,12 +808,12 @@ #ifdef SDEBUG (void) fprintf(el->el_errfile, "not found\n"); #endif - return (CC_ERROR); + return CC_ERROR; } } el->el_history.eventno = found; - return (hist_get(el)); + return hist_get(el); } @@ -822,9 +823,9 @@ */ protected el_action_t /*ARGSUSED*/ -ed_prev_line(EditLine *el, int c __unused) +ed_prev_line(EditLine *el, Int c __attribute__((__unused__))) { - char *ptr; + Char *ptr; int nchars = c_hpos(el); /* @@ -838,7 +839,7 @@ break; if (el->el_state.argument > 0) - return (CC_ERROR); + return CC_ERROR; /* * Move to the beginning of the line @@ -855,7 +856,7 @@ continue; el->el_line.cursor = ptr; - return (CC_CURSOR); + return CC_CURSOR; } @@ -865,9 +866,9 @@ */ protected el_action_t /*ARGSUSED*/ -ed_next_line(EditLine *el, int c __unused) +ed_next_line(EditLine *el, Int c __attribute__((__unused__))) { - char *ptr; + Char *ptr; int nchars = c_hpos(el); /* @@ -878,7 +879,7 @@ break; if (el->el_state.argument > 0) - return (CC_ERROR); + return CC_ERROR; /* * Move to the character requested @@ -889,7 +890,7 @@ continue; el->el_line.cursor = ptr; - return (CC_CURSOR); + return CC_CURSOR; } @@ -899,16 +900,16 @@ */ protected el_action_t /*ARGSUSED*/ -ed_command(EditLine *el, int c __unused) +ed_command(EditLine *el, Int c __attribute__((__unused__))) { - char tmpbuf[EL_BUFSIZ]; + Char tmpbuf[EL_BUFSIZ]; int tmplen; - tmplen = c_gets(el, tmpbuf, "\n: "); - term__putc(el, '\n'); + tmplen = c_gets(el, tmpbuf, STR("\n: ")); + terminal__putc(el, '\n'); 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; re_clear_display(el); Index: lib/libedit/config.h =================================================================== --- lib/libedit/config.h (revision 0) +++ lib/libedit/config.h (working copy) @@ -0,0 +1,318 @@ +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Christos Zoulas of Cornell University. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* Define to 1 if the `closedir' function returns void instead of `int'. */ +/* #undef CLOSEDIR_VOID */ + +/* Define to 1 if you have the header file. */ +#define HAVE_CURSES_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +#define HAVE_DIRENT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_DLFCN_H 1 + +/* Define to 1 if you have the `endpwent' function. */ +#define HAVE_ENDPWENT 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `fgetln' function. */ +#define HAVE_FGETLN 1 + +/* Define to 1 if you have the `fork' function. */ +#define HAVE_FORK 1 + +/* Define to 1 if you have getpwnam_r and getpwuid_r that are draft POSIX.1 + versions. */ +/* #undef HAVE_GETPW_R_DRAFT */ + +/* Define to 1 if you have getpwnam_r and getpwuid_r that are POSIX.1 + compatible. */ +#define HAVE_GETPW_R_POSIX 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the `isascii' function. */ +#define HAVE_ISASCII 1 + +/* Define to 1 if you have the `issetugid' function. */ +#define HAVE_ISSETUGID 1 + +/* Define to 1 if you have the `curses' library (-lcurses). */ +/* #undef HAVE_LIBCURSES */ + +/* Define to 1 if you have the `ncurses' library (-lncurses). */ +/* #undef HAVE_LIBNCURSES */ + +/* Define to 1 if you have the `termcap' library (-ltermcap). */ +/* #undef HAVE_LIBTERMCAP */ + +/* Define to 1 if you have the `terminfo' library (-lterminfo). */ +#define HAVE_LIBTERMINFO 1 + +/* Define to 1 if you have the `termlib' library (-ltermlib). */ +/* #undef HAVE_LIBTERMLIB */ + +/* Define to 1 if you have the header file. */ +#define HAVE_LIMITS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MALLOC_H 1 + +/* Define to 1 if you have the `memchr' function. */ +#define HAVE_MEMCHR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#define HAVE_MEMSET 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_NCURSES_H */ + +/* Define to 1 if you have the header file, and it defines `DIR'. */ +/* #undef HAVE_NDIR_H */ + +/* Define to 1 if you have the `regcomp' function. */ +#define HAVE_REGCOMP 1 + +/* Define to 1 if you have the `re_comp' function. */ +/* #undef HAVE_RE_COMP */ + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +/* #undef HAVE_STAT_EMPTY_STRING_BUG */ + +/* Define to 1 if you have the header file. */ +#define HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strcasecmp' function. */ +#define HAVE_STRCASECMP 1 + +/* Define to 1 if you have the `strchr' function. */ +#define HAVE_STRCHR 1 + +/* Define to 1 if you have the `strcspn' function. */ +#define HAVE_STRCSPN 1 + +/* Define to 1 if you have the `strdup' function. */ +#define HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#define HAVE_STRERROR 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_STRING_H 1 + +/* Define to 1 if you have the `strlcat' function. */ +#define HAVE_STRLCAT 1 + +/* Define to 1 if you have the `strlcpy' function. */ +#define HAVE_STRLCPY 1 + +/* Define to 1 if you have the `strrchr' function. */ +#define HAVE_STRRCHR 1 + +/* Define to 1 if you have the `strstr' function. */ +#define HAVE_STRSTR 1 + +/* Define to 1 if you have the `strtol' function. */ +#define HAVE_STRTOL 1 + +/* Define to 1 if struct dirent has member d_namlen */ +#define HAVE_STRUCT_DIRENT_D_NAMLEN 1 + +/* Define to 1 if you have the `strunvis' function. */ +#define HAVE_STRUNVIS 1 + +/* Define to 1 if you have the `strvis' function. */ +#define HAVE_STRVIS 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_CDEFS_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_DIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file, and it defines `DIR'. + */ +/* #undef HAVE_SYS_NDIR_H */ + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_PARAM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#define HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TERMCAP_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_TERM_H 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_UNISTD_H 1 + +/* Define to 1 if the system has the type `u_int32_t'. */ +#define HAVE_U_INT32_T 1 + +/* Define to 1 if you have the `vfork' function. */ +#define HAVE_VFORK 1 + +/* Define to 1 if you have the header file. */ +/* #undef HAVE_VFORK_H */ + +/* Define to 1 if you have the `vis' function. */ +#define HAVE_VIS 1 + +/* Define to 1 if you have the `wcsdup' function. */ +#define HAVE_WCSDUP 1 + +/* Define to 1 if `fork' works. */ +#define HAVE_WORKING_FORK 1 + +/* Define to 1 if `vfork' works. */ +#define HAVE_WORKING_VFORK 1 + +/* Define to 1 if `lstat' dereferences a symlink specified with a trailing + slash. */ +#define LSTAT_FOLLOWS_SLASHED_SYMLINK 1 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +#define LT_OBJDIR ".libs/" + +/* Name of package */ +#define PACKAGE "libedit-20110729" + +/* Define to the address where bug reports for this package should be sent. */ +#define PACKAGE_BUGREPORT "" + +/* Define to the full name of this package. */ +#define PACKAGE_NAME "libedit" + +/* Define to the full name and version of this package. */ +#define PACKAGE_STRING "libedit 3.0" + +/* Define to the one symbol short name of this package. */ +#define PACKAGE_TARNAME "libedit-20110729" + +/* Define to the home page for this package. */ +#define PACKAGE_URL "" + +/* Define to the version of this package. */ +#define PACKAGE_VERSION "3.0" + +/* Define as the return type of signal handlers (`int' or `void'). */ +#define RETSIGTYPE void + +/* Define to 1 if you have the ANSI C header files. */ +#define STDC_HEADERS 1 + +/* Enable extensions on AIX 3, Interix. */ +#ifndef _ALL_SOURCE +# define _ALL_SOURCE 1 +#endif +/* Enable GNU extensions on systems that have them. */ +#ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +#endif +/* Enable threading extensions on Solaris. */ +#ifndef _POSIX_PTHREAD_SEMANTICS +# define _POSIX_PTHREAD_SEMANTICS 1 +#endif +/* Enable extensions on HP NonStop. */ +#ifndef _TANDEM_SOURCE +# define _TANDEM_SOURCE 1 +#endif +/* Enable general extensions on Solaris. */ +#ifndef __EXTENSIONS__ +# define __EXTENSIONS__ 1 +#endif + + +/* Version number of package */ +#define VERSION "3.0" + +/* Define to 1 if you want wide-character code */ +/* #undef WIDECHAR */ + +/* Define to 1 if on MINIX. */ +/* #undef _MINIX */ + +/* Define to 2 if the system does not provide POSIX.1 features except with + this defined. */ +/* #undef _POSIX_1_SOURCE */ + +/* Define to 1 if you need to in order for `stat' and other things to work. */ +/* #undef _POSIX_SOURCE */ + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #undef const */ + +/* Define to `int' if does not define. */ +/* #undef pid_t */ + +/* Define to `unsigned int' if does not define. */ +/* #undef size_t */ + +/* Define as `fork' if `vfork' does not work. */ +/* #undef vfork */ + + +#include "sys.h" +/* #undef SCCSID */ +/* #undef LIBC_SCCS */ +/* #undef lint */ + Property changes on: lib/libedit/config.h ___________________________________________________________________ Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Index: lib/libedit/edit/readline/readline.h =================================================================== --- lib/libedit/edit/readline/readline.h (revision 258914) +++ lib/libedit/edit/readline/readline.h (working copy) @@ -1,4 +1,4 @@ -/* $NetBSD: readline.h,v 1.31 2010/08/04 20:29:18 christos Exp $ */ +/* $NetBSD: readline.h,v 1.34 2013/05/28 00:10:34 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -111,6 +111,7 @@ extern char *rl_completer_word_break_characters; extern char *rl_completer_quote_characters; extern Function *rl_completion_entry_function; +extern char *(*rl_completion_word_break_hook)(void); extern CPPFunction *rl_attempted_completion_function; extern int rl_attempted_completion_over; extern int rl_completion_type; @@ -126,6 +127,8 @@ /* * The following is not implemented */ +extern int rl_catch_signals; +extern int rl_catch_sigwinch; extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_meta_keymap, emacs_ctlx_keymap; @@ -153,7 +156,6 @@ HIST_ENTRY *current_history(void); HIST_ENTRY *history_get(int); HIST_ENTRY *remove_history(int); -/*###152 [lint] syntax error 'histdata_t' [249]%%%*/ HIST_ENTRY *replace_history_entry(int, const char *, histdata_t); int history_total_bytes(void); int history_set_pos(int); @@ -200,6 +202,7 @@ void rl_set_screen_size(int, int); char *rl_filename_completion_function (const char *, int); int _rl_abort_internal(void); +int _rl_qsort_string_compare(char **, char **); char **rl_completion_matches(const char *, rl_compentry_func_t *); void rl_forced_update_display(void); int rl_set_prompt(const char *); Index: lib/libedit/editline.3 =================================================================== --- lib/libedit/editline.3 (revision 258914) +++ lib/libedit/editline.3 (working copy) @@ -1,6 +1,6 @@ -.\" $NetBSD: editline.3,v 1.70 2009/07/05 21:55:24 perry Exp $ +.\" $NetBSD: editline.3,v 1.80 2013/07/12 17:48:29 christos Exp $ .\" -.\" Copyright (c) 1997-2003 The NetBSD Foundation, Inc. +.\" Copyright (c) 1997-2013 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This file was contributed to The NetBSD Foundation by Luke Mewburn. @@ -26,35 +26,52 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd July 5, 2009 +.Dd July 12, 2013 .Dt EDITLINE 3 .Os .Sh NAME .Nm editline , .Nm el_init , +.Nm el_init_fd , .Nm el_end , .Nm el_reset , .Nm el_gets , +.Nm el_wgets , .Nm el_getc , +.Nm el_wgetc , .Nm el_push , +.Nm el_wpush , .Nm el_parse , +.Nm el_wparse , .Nm el_set , +.Nm el_wset , .Nm el_get , +.Nm el_wget , .Nm el_source , .Nm el_resize , +.Nm el_cursor , .Nm el_line , +.Nm el_wline , .Nm el_insertstr , +.Nm el_winsertstr , .Nm el_deletestr , +.Nm el_wdeletestr , .Nm history_init , +.Nm history_winit , .Nm history_end , +.Nm history_wend , .Nm history , +.Nm history_w , .Nm tok_init , +.Nm tok_winit , .Nm tok_end , +.Nm tok_wend , .Nm tok_reset , +.Nm tok_wreset , .Nm tok_line , +.Nm tok_wline , .Nm tok_str +.Nm tok_wstr .Nd line editor, history and tokenization functions .Sh LIBRARY .Lb libedit @@ -62,6 +79,8 @@ .In histedit.h .Ft EditLine * .Fn el_init "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr" +.Ft EditLine * +.Fn el_init_fd "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr" "int fdin" "int fdout" "int fderr" .Ft void .Fn el_end "EditLine *e" .Ft void @@ -68,45 +87,78 @@ .Fn el_reset "EditLine *e" .Ft const char * .Fn el_gets "EditLine *e" "int *count" +.Ft const wchar_t * +.Fn el_wgets "EditLine *e" "int *count" .Ft int .Fn el_getc "EditLine *e" "char *ch" +.Ft int +.Fn el_wgetc "EditLine *e" "wchar_t *ch" .Ft void -.Fn el_push "EditLine *e" "char *str" +.Fn el_push "EditLine *e" "const char *str" +.Ft void +.Fn el_wpush "EditLine *e" "const wchar_t *str" .Ft int .Fn el_parse "EditLine *e" "int argc" "const char *argv[]" .Ft int +.Fn el_wparse "EditLine *e" "int argc" "const wchar_t *argv[]" +.Ft int .Fn el_set "EditLine *e" "int op" "..." .Ft int +.Fn el_wset "EditLine *e" "int op" "..." +.Ft int .Fn el_get "EditLine *e" "int op" "..." .Ft int +.Fn el_wget "EditLine *e" "int op" "..." +.Ft int .Fn el_source "EditLine *e" "const char *file" .Ft void .Fn el_resize "EditLine *e" +.Fn int +.Fn el_cursor "EditLine *e" "int count" .Ft const LineInfo * .Fn el_line "EditLine *e" +.Ft const LineInfoW * +.Fn el_wline "EditLine *e" .Ft int .Fn el_insertstr "EditLine *e" "const char *str" +.Ft int +.Fn el_winsertstr "EditLine *e" "const wchar_t *str" .Ft void .Fn el_deletestr "EditLine *e" "int count" +.Ft void +.Fn el_wdeletestr "EditLine *e" "int count" .Ft History * .Fn history_init +.Ft HistoryW * +.Fn history_winit .Ft void .Fn history_end "History *h" +.Ft void +.Fn history_wend "HistoryW *h" .Ft int .Fn history "History *h" "HistEvent *ev" "int op" "..." +.Ft int +.Fn history_w "HistoryW *h" "HistEventW *ev" "int op" "..." .Ft Tokenizer * .Fn tok_init "const char *IFS" +.Ft TokenizerW * +.Fn tok_winit "const wchar_t *IFS" .Ft void .Fn tok_end "Tokenizer *t" .Ft void +.Fn tok_wend "TokenizerW *t" +.Ft void .Fn tok_reset "Tokenizer *t" +.Ft void +.Fn tok_wreset "TokenizerW *t" .Ft int -.Fo tok_line -.Fa "Tokenizer *t" "const LineInfo *li" "int *argc" "const char **argv[]" -.Fa "int *cursorc" "int *cursoro" -.Fc +.Fn tok_line "Tokenizer *t" "const LineInfo *li" "int *argc" "const char **argv[]" "int *cursorc" "int *cursoro" .Ft int +.Fn tok_wline "TokenizerW *t" "const LineInfoW *li" "int *argc" "const wchar_t **argv[]" "int *cursorc" "int *cursoro" +.Ft int .Fn tok_str "Tokenizer *t" "const char *str" "int *argc" "const char **argv[]" +.Ft int +.Fn tok_wstr "TokenizerW *t" "const wchar_t *str" "int *argc" "const wchar_t **argv[]" .Sh DESCRIPTION The .Nm @@ -126,9 +178,14 @@ .Fa EditLine , which is created by .Fn el_init +or +.Fn el_init_fd and freed by .Fn el_end . .Pp +The wide-character functions behave the same way as their narrow +counterparts. +.Pp The following functions are available: .Bl -tag -width 4n .It Fn el_init @@ -146,11 +203,20 @@ In this documentation, references to .Dq the tty are actually to this input/output stream combination. +.It Fn el_init_fd +Like +.Fn el_init +but allows specifying file descriptors for the +.Xr stdio 3 +corresponding streams, in case those were created with +.Xr funopen 3 . .It Fn el_end Clean up and finish with .Fa e , assumed to have been created with -.Fn el_init . +.Fn el_init +or +.Fn el_init_fd . .It Fn el_reset Reset the tty and the parser. This should be called after an error which may have upset the tty's @@ -174,7 +240,10 @@ Read a character from the tty. .Fa ch is modified to contain the character read. -Returns the number of characters read if successful, \-1 otherwise. +Returns the number of characters read if successful, \-1 otherwise, +in which case +.Dv errno +can be inspected for the cause. .It Fn el_push Pushes .Fa str @@ -196,7 +265,7 @@ .Nm commands. If the command is prefixed with -.Dq prog: +.Dq prog : then .Fn el_parse will only execute the command if @@ -209,7 +278,7 @@ \-1 if the command is unknown, 0 if there was no error or .Dq prog -did not match, or +didn't match, or 1 if the command returned an error. Refer to .Xr editrc 5 @@ -385,6 +454,14 @@ (using .Fn el_get ) to determine if editing should be enabled or not. +.It Dv EL_UNBUFFERED , Fa "int flag" +If +.Fa flag +is zero, +unbuffered mode is disabled (the default). +In unbuffered mode, +.Fn el_gets +will return immediately after processing a single character. .It Dv EL_GETCFN , Fa "int (*f)(EditLine *, char *c)" Define the character reading function as .Fa f , @@ -396,7 +473,7 @@ .Fn el_getc . The builtin function can be set or restored with the special function name -.Dv EL_BUILTIN_GETCFN . +.Dq Dv EL_BUILTIN_GETCFN . .It Dv EL_CLIENTDATA , Fa "void *data" Register .Fa data @@ -454,7 +531,7 @@ is not .Dv NULL , return the start/stop literal prompt character in it. -.It Dv EL_EDITOR , Fa "const char *" +.It Dv EL_EDITOR , Fa "const char **" Return the name of the editor, which will be one of .Dq emacs or @@ -478,7 +555,7 @@ Return non-zero if editing is enabled. .It Dv EL_GETCFN , Fa "int (**f)(EditLine *, char *)" Return a pointer to the function that read characters, which is equal to -.Dv EL_BUILTIN_GETCFN +.Dq Dv EL_BUILTIN_GETCFN in the case of the default builtin function. .It Dv EL_CLIENTDATA , Fa "void **data" Retrieve @@ -487,10 +564,7 @@ .Fn el_set call. .It Dv EL_UNBUFFERED , Fa "int" -Sets or clears unbuffered mode. -In this mode, -.Fn el_gets -will return immediately after processing a single character. +Return non-zero if unbuffered mode is enabled. .It Dv EL_PREP_TERM , Fa "int" Sets or clears terminal editing mode. .It Dv EL_GETFP , Fa "int fd", Fa "FILE **fp" @@ -538,9 +612,14 @@ has been set with .Fn el_set , then this is done automatically. -Otherwise, it is the responsibility of the application to call +Otherwise, it's the responsibility of the application to call .Fn el_resize on the appropriate occasions. +.It Fn el_cursor +Move the cursor to the right (if positive) or to the left (if negative) +.Fa count +characters. +Returns the resulting offset of the cursor from the beginning of the line. .It Fn el_line Return the editing information for the current line in a .Fa LineInfo @@ -568,7 +647,7 @@ into the line at the cursor. Returns \-1 if .Fa str -is empty or will not fit, and 0 otherwise. +is empty or won't fit, and 0 otherwise. .It Fn el_deletestr Delete .Fa count @@ -623,7 +702,7 @@ Fa "history_efun_t enter" , Fa "history_efun_t add" Define functions to perform various history operations. .Fa ptr -is the argument given to a function when it is invoked. +is the argument given to a function when it's invoked. .It Dv H_FIRST Return the first element in the history. .It Dv H_LAST @@ -698,9 +777,8 @@ .Fa HistEvent . .El .Pp -The .Fn history -function returns \*[Ge] 0 if the operation +returns \*[Gt]= 0 if the operation .Fa op succeeds. Otherwise, \-1 is returned and @@ -744,7 +822,7 @@ .It Fn tok_line Tokenize .Fa li , -if successful, modify +If successful, modify: .Fa argv to contain the words, .Fa argc @@ -771,6 +849,7 @@ .Aq newline . A positive exit code indicates that another line should be read and tokenization attempted again. +. .It Fn tok_str A simpler form of .Fn tok_line ; @@ -777,6 +856,7 @@ .Fa str is a NUL terminated string to tokenize. .El +. .\"XXX.Sh EXAMPLES .\"XXX: provide some examples .Sh SEE ALSO @@ -793,27 +873,25 @@ .Dv CC_REDISPLAY appeared in .Nx 1.3 . -.Dv CC_REFRESH_BEEP -and +.Dv CC_REFRESH_BEEP , .Dv EL_EDITMODE -appeared in +and the readline emulation appeared in .Nx 1.4 . .Dv EL_RPROMPT appeared in .Nx 1.5 . .Sh AUTHORS -.An -nosplit The .Nm -library was written by -.An Christos Zoulas . -.An Luke Mewburn -wrote this manual and implemented +library was written by Christos Zoulas. +Luke Mewburn wrote this manual and implemented .Dv CC_REDISPLAY , .Dv CC_REFRESH_BEEP , .Dv EL_EDITMODE , and .Dv EL_RPROMPT . +Jaromir Dolecek implemented the readline emulation. +Johny Mattsson implemented wide-character support. .Sh BUGS At this time, it is the responsibility of the caller to check the result of the Index: lib/libedit/editrc.5 =================================================================== --- lib/libedit/editrc.5 (revision 258914) +++ lib/libedit/editrc.5 (working copy) @@ -1,4 +1,4 @@ -.\" $NetBSD: editrc.5,v 1.24 2009/04/11 22:17:52 wiz Exp $ +.\" $NetBSD: editrc.5,v 1.27 2013/01/10 16:03:42 wiz Exp $ .\" .\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -26,9 +26,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.\" $FreeBSD$ -.\" -.Dd October 18, 2003 +.Dd January 10, 2013 .Dt EDITRC 5 .Os .Sh NAME @@ -150,8 +148,10 @@ .Sm off .Sq No ^ Ar character .Sm on -(e.g.\& -.Sq ^A ) , +.Po +e.g. +.Sq ^A +.Pc , and the following backslashed escape sequences: .Pp .Bl -tag -compact -offset indent -width 4n @@ -194,7 +194,8 @@ .Sq cols , .Sq lines , .Sq rows , -.Sq meta or +.Sq meta , +or .Sq tabs , the value of that capability is printed, with .Dq yes @@ -207,7 +208,7 @@ causing an error. .Fl v causes messages to be verbose. -.It Ic edit Op Cm on | off +.It Ic edit Op Li on | Li off Enable or disable the .Nm editline functionality in a program. @@ -244,7 +245,7 @@ Oo Ar -mode Oc Oo Ar mode Oc Oo Ar char=c Oc Control which tty modes that .Nm -will not allow the user to change. +won't allow the user to change. .Fl d , .Fl q or @@ -262,9 +263,13 @@ Without other arguments, .Ic setty lists the modes in the chosen set which are fixed on -.Pq Sq +mode +.Po +.Sq +mode +.Pc or off -.Pq Sq -mode . +.Po +.Sq -mode +.Pc . .Fl a lists all tty modes in the chosen set regardless of the setting. With @@ -485,12 +490,9 @@ .Xr regex 3 , .Xr termcap 5 .Sh AUTHORS -.An -nosplit The .Nm editline -library was written by -.An Christos Zoulas , -and this manual was written by -.An Luke Mewburn , +library was written by Christos Zoulas, +and this manual was written by Luke Mewburn, with some sections inspired by .Xr tcsh 1 . Index: lib/libedit/el.c =================================================================== --- lib/libedit/el.c (revision 258914) +++ lib/libedit/el.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: el.c,v 1.72 2013/01/22 20:23:21 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: el.c,v 1.55 2009/07/25 21:19:23 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94"; #endif /* not lint && not SCCSID */ @@ -41,8 +42,6 @@ /* * el.c: EditLine interface functions */ -#include "sys.h" - #include #include #include @@ -49,10 +48,10 @@ #include #include #include +#include +#include #include "el.h" -#define HAVE_ISSETUGID - /* el_init(): * Initialize editline and set default parameters. */ @@ -59,11 +58,18 @@ public EditLine * el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) { + return el_init_fd(prog, fin, fout, ferr, fileno(fin), fileno(fout), + fileno(ferr)); +} - EditLine *el = (EditLine *) el_malloc(sizeof(EditLine)); +public EditLine * +el_init_fd(const char *prog, FILE *fin, FILE *fout, FILE *ferr, + int fdin, int fdout, int fderr) +{ + EditLine *el = el_malloc(sizeof(*el)); if (el == NULL) - return (NULL); + return NULL; memset(el, 0, sizeof(EditLine)); @@ -71,9 +77,12 @@ el->el_outfile = fout; el->el_errfile = ferr; - el->el_infd = fileno(fin); + el->el_infd = fdin; + el->el_outfd = fdout; + el->el_errfd = fderr; - if ((el->el_prog = el_strdup(prog)) == NULL) { + el->el_prog = Strdup(ct_decode_string(prog, &el->el_scratch)); + if (el->el_prog == NULL) { el_free(el); return NULL; } @@ -82,13 +91,19 @@ * Initialize all the modules. Order is important!!! */ el->el_flags = 0; +#ifdef WIDECHAR + if (setlocale(LC_CTYPE, NULL) != NULL){ + if (strcmp(nl_langinfo(CODESET), "UTF-8") == 0) + el->el_flags |= CHARSET_IS_UTF8; + } +#endif - if (term_init(el) == -1) { + if (terminal_init(el) == -1) { el_free(el->el_prog); el_free(el); return NULL; } - (void) key_init(el); + (void) keymacro_init(el); (void) map_init(el); if (tty_init(el) == -1) el->el_flags |= NO_TTY; @@ -99,7 +114,7 @@ (void) sig_init(el); (void) read_init(el); - return (el); + return el; } @@ -115,8 +130,8 @@ el_reset(el); - term_end(el); - key_end(el); + terminal_end(el); + keymacro_end(el); map_end(el); tty_end(el); ch_end(el); @@ -125,8 +140,14 @@ prompt_end(el); sig_end(el); - el_free((ptr_t) el->el_prog); - el_free((ptr_t) el); + el_free(el->el_prog); +#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); } @@ -146,13 +167,13 @@ * set the editline parameters */ public int -el_set(EditLine *el, int op, ...) +FUN(el,set)(EditLine *el, int op, ...) { va_list ap; int rv = 0; if (el == NULL) - return (-1); + return -1; va_start(ap, op); switch (op) { @@ -160,25 +181,32 @@ case EL_RPROMPT: { el_pfunc_t p = va_arg(ap, el_pfunc_t); - rv = prompt_set(el, p, 0, op); + rv = prompt_set(el, p, 0, op, 1); 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); - char c = va_arg(ap, int); + int c = va_arg(ap, int); - rv = prompt_set(el, p, c, op); + rv = prompt_set(el, p, c, op, 1); break; } case EL_TERMINAL: - rv = term_set(el, va_arg(ap, char *)); + rv = terminal_set(el, va_arg(ap, char *)); break; case EL_EDITOR: - rv = map_set_editor(el, va_arg(ap, char *)); + rv = map_set_editor(el, va_arg(ap, Char *)); break; case EL_SIGNAL: @@ -191,40 +219,39 @@ case EL_BIND: case EL_TELLTC: case EL_SETTC: - case EL_GETTC: case EL_ECHOTC: case EL_SETTY: { - const char *argv[20]; + const Char *argv[20]; int i; - for (i = 1; i < 20; i++) - if ((argv[i] = va_arg(ap, char *)) == NULL) + for (i = 1; i < (int)__arraycount(argv); i++) + if ((argv[i] = va_arg(ap, Char *)) == NULL) break; switch (op) { case EL_BIND: - argv[0] = "bind"; + argv[0] = STR("bind"); rv = map_bind(el, i, argv); break; case EL_TELLTC: - argv[0] = "telltc"; - rv = term_telltc(el, i, argv); + argv[0] = STR("telltc"); + rv = terminal_telltc(el, i, argv); break; case EL_SETTC: - argv[0] = "settc"; - rv = term_settc(el, i, argv); + argv[0] = STR("settc"); + rv = terminal_settc(el, i, argv); break; case EL_ECHOTC: - argv[0] = "echotc"; - rv = term_echotc(el, i, argv); + argv[0] = STR("echotc"); + rv = terminal_echotc(el, i, argv); break; case EL_SETTY: - argv[0] = "setty"; + argv[0] = STR("setty"); rv = tty_stty(el, i, argv); break; @@ -238,8 +265,8 @@ case EL_ADDFN: { - char *name = va_arg(ap, char *); - char *help = va_arg(ap, char *); + Char *name = va_arg(ap, Char *); + Char *help = va_arg(ap, Char *); el_func_t func = va_arg(ap, el_func_t); rv = map_addfunc(el, name, help, func); @@ -249,9 +276,11 @@ case EL_HIST: { 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); + if (!(el->el_flags & CHARSET_IS_UTF8)) + el->el_flags &= ~NARROW_HISTORY; break; } @@ -267,6 +296,7 @@ { el_rfunc_t rc = va_arg(ap, el_rfunc_t); rv = el_read_setfn(el, rc); + el->el_flags &= ~NARROW_READ; break; } @@ -311,9 +341,11 @@ break; case 1: el->el_outfile = fp; + el->el_outfd = fileno(fp); break; case 2: el->el_errfile = fp; + el->el_errfd = fileno(fp); break; default: rv = -1; @@ -325,7 +357,7 @@ case EL_REFRESH: re_clear_display(el); re_refresh(el); - term__flush(el); + terminal__flush(el); break; default: @@ -334,7 +366,7 @@ } va_end(ap); - return (rv); + return rv; } @@ -342,7 +374,7 @@ * retrieve the editline parameters */ public int -el_get(EditLine *el, int op, ...) +FUN(el,get)(EditLine *el, int op, ...) { va_list ap; int rv; @@ -356,7 +388,13 @@ case EL_PROMPT: case EL_RPROMPT: { el_pfunc_t *p = va_arg(ap, el_pfunc_t *); - char *c = va_arg(ap, char *); + rv = prompt_get(el, p, 0, op); + break; + } + case EL_PROMPT_ESC: + case EL_RPROMPT_ESC: { + el_pfunc_t *p = va_arg(ap, el_pfunc_t *); + Char *c = va_arg(ap, Char *); rv = prompt_get(el, p, c, op); break; @@ -363,7 +401,7 @@ } case EL_EDITOR: - rv = map_get_editor(el, va_arg(ap, const char **)); + rv = map_get_editor(el, va_arg(ap, const Char **)); break; case EL_SIGNAL: @@ -377,7 +415,7 @@ break; case EL_TERMINAL: - term_get(el, va_arg(ap, const char **)); + terminal_get(el, va_arg(ap, const char **)); rv = 0; break; @@ -387,44 +425,15 @@ char *argv[20]; int i; - for (i = 1; i < (int)(sizeof(argv) / sizeof(argv[0])); i++) + for (i = 1; i < (int)__arraycount(argv); i++) if ((argv[i] = va_arg(ap, char *)) == NULL) break; - switch (op) { - case EL_GETTC: - argv[0] = name; - rv = term_gettc(el, i, argv); - break; - - default: - rv = -1; - EL_ABORT((el->el_errfile, "Bad op %d\n", op)); - break; - } + argv[0] = name; + rv = terminal_gettc(el, i, argv); break; } -#if 0 /* XXX */ - case EL_ADDFN: - { - char *name = va_arg(ap, char *); - char *help = va_arg(ap, char *); - el_func_t func = va_arg(ap, el_func_t); - - rv = map_addfunc(el, name, help, func); - break; - } - - case EL_HIST: - { - hist_fun_t func = va_arg(ap, hist_fun_t); - ptr_t ptr = va_arg(ap, char *); - rv = hist_set(el, func, ptr); - } - break; -#endif /* XXX */ - case EL_GETCFN: *va_arg(ap, el_rfunc_t *) = el_read_getfn(el); rv = 0; @@ -436,7 +445,7 @@ break; case EL_UNBUFFERED: - *va_arg(ap, int *) = (!(el->el_flags & UNBUFFERED)); + *va_arg(ap, int *) = (el->el_flags & UNBUFFERED) != 0; rv = 0; break; @@ -470,7 +479,7 @@ } va_end(ap); - return (rv); + return rv; } @@ -477,11 +486,11 @@ /* el_line(): * Return editing info */ -public const LineInfo * -el_line(EditLine *el) +public const TYPE(LineInfo) * +FUN(el,line)(EditLine *el) { - return (const LineInfo *) (void *) &el->el_line; + return (const TYPE(LineInfo) *)(void *)&el->el_line; } @@ -494,23 +503,24 @@ FILE *fp; size_t len; char *ptr; -#ifdef HAVE_ISSETUGID - char path[MAXPATHLEN]; -#endif + char *path = NULL; + const Char *dptr; + int error = 0; fp = NULL; if (fname == NULL) { #ifdef HAVE_ISSETUGID static const char elpath[] = "/.editrc"; + size_t plen = sizeof(elpath); if (issetugid()) - return (-1); + return -1; if ((ptr = getenv("HOME")) == NULL) - return (-1); - if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path)) - return (-1); - if (strlcat(path, elpath, sizeof(path)) >= sizeof(path)) - return (-1); + return -1; + plen += strlen(ptr); + if ((path = el_malloc(plen * sizeof(*path))) == NULL) + return -1; + (void)snprintf(path, plen, "%s%s", ptr, elpath); fname = path; #else /* @@ -518,33 +528,37 @@ * to keep from inadvertently opening up the user to a security * hole. */ - return (-1); + return -1; #endif } if (fp == NULL) fp = fopen(fname, "r"); - if (fp == NULL) - return (-1); + if (fp == NULL) { + el_free(path); + return -1; + } while ((ptr = fgetln(fp, &len)) != NULL) { - if (len > 0 && ptr[len - 1] == '\n') + 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; - ptr[len] = '\0'; /* loop until first non-space char or EOL */ - while (*ptr != '\0' && isspace((unsigned char)*ptr)) - ptr++; - if (*ptr == '#') + while (*dptr != '\0' && Isspace(*dptr)) + dptr++; + if (*dptr == '#') continue; /* ignore, this is a comment line */ - - if (parse_line(el, ptr) == -1) { - (void) fclose(fp); - return (-1); - } + if ((error = parse_line(el, dptr)) == -1) + break; } + el_free(path); (void) fclose(fp); - return (0); + return error; } @@ -562,8 +576,8 @@ (void) sigprocmask(SIG_BLOCK, &nset, &oset); /* get the correct window size */ - if (term_get_size(el, &lins, &cols)) - term_change_size(el, lins, cols); + if (terminal_get_size(el, &lins, &cols)) + terminal_change_size(el, lins, cols); (void) sigprocmask(SIG_SETMASK, &oset, NULL); } @@ -576,7 +590,7 @@ el_beep(EditLine *el) { - term_beep(el); + terminal_beep(el); } @@ -585,24 +599,25 @@ */ protected int /*ARGSUSED*/ -el_editmode(EditLine *el, int argc, const char **argv) +el_editmode(EditLine *el, int argc, const Char **argv) { - const char *how; + const Char *how; if (argv == NULL || argc != 2 || argv[1] == NULL) - return (-1); + return -1; how = argv[1]; - if (strcmp(how, "on") == 0) { + if (Strcmp(how, STR("on")) == 0) { el->el_flags &= ~EDIT_DISABLED; tty_rawmode(el); - } else if (strcmp(how, "off") == 0) { + } else if (Strcmp(how, STR("off")) == 0) { tty_cookedmode(el); el->el_flags |= EDIT_DISABLED; } else { - (void) fprintf(el->el_errfile, "edit: Bad value `%s'.\n", how); - return (-1); + (void) fprintf(el->el_errfile, "edit: Bad value `" FSTR "'.\n", + how); + return -1; } - return (0); + return 0; } Index: lib/libedit/el.h =================================================================== --- lib/libedit/el.h (revision 258914) +++ lib/libedit/el.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: el.h,v 1.25 2011/07/29 23:44:44 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +32,6 @@ * SUCH DAMAGE. * * @(#)el.h 8.1 (Berkeley) 6/4/93 - * $NetBSD: el.h,v 1.17 2006/12/15 22:13:33 christos Exp $ * $FreeBSD$ */ @@ -46,15 +47,21 @@ #define VIDEFAULT #define ANCHOR +#include "histedit.h" +#include "chartype.h" #include #include -#define EL_BUFSIZ 1024 /* Maximum line size */ +#define EL_BUFSIZ ((size_t)1024) /* Maximum line size */ #define HANDLE_SIGNALS 0x01 #define NO_TTY 0x02 #define EDIT_DISABLED 0x04 #define UNBUFFERED 0x08 +#define CHARSET_IS_UTF8 0x10 +#define IGNORE_EXTCHARS 0x20 /* Ignore characters read > 0xff */ +#define NARROW_HISTORY 0x40 +#define NARROW_READ 0x80 typedef int bool_t; /* True or not */ @@ -66,10 +73,10 @@ } coord_t; typedef struct el_line_t { - char *buffer; /* Input line */ - char *cursor; /* Cursor position */ - char *lastchar; /* Last character */ - const char *limit; /* Max position */ + Char *buffer; /* Input line */ + Char *cursor; /* Cursor position */ + Char *lastchar; /* Last character */ + const Char *limit; /* Max position */ } el_line_t; /* @@ -82,13 +89,12 @@ int metanext; /* Is the next char a meta char */ el_action_t lastcmd; /* Previous command */ el_action_t thiscmd; /* this command */ - char thisch; /* char that generated it */ + Char thisch; /* char that generated it */ } el_state_t; /* * Until we come up with something better... */ -#define el_strdup(a) strdup(a) #define el_malloc(a) malloc(a) #define el_realloc(a,b) realloc(a, b) #define el_free(a) free(a) @@ -95,8 +101,8 @@ #include "tty.h" #include "prompt.h" -#include "key.h" -#include "term.h" +#include "keymacro.h" +#include "terminal.h" #include "refresh.h" #include "chared.h" #include "common.h" @@ -109,20 +115,22 @@ #include "read.h" struct editline { - char *el_prog; /* the program name */ + Char *el_prog; /* the program name */ FILE *el_infile; /* Stdio stuff */ FILE *el_outfile; /* Stdio stuff */ FILE *el_errfile; /* Stdio stuff */ int el_infd; /* Input file descriptor */ + int el_outfd; /* Output file descriptor */ + int el_errfd; /* Error file descriptor */ int el_flags; /* Various flags. */ int el_errno; /* Local copy of errno */ coord_t el_cursor; /* Cursor location */ - char **el_display; /* Real screen image = what is there */ - char **el_vdisplay; /* Virtual screen image = what we see */ + Char **el_display; /* Real screen image = what is there */ + Char **el_vdisplay; /* Virtual screen image = what we see */ void *el_data; /* Client data */ el_line_t el_line; /* The current line information */ el_state_t el_state; /* Current editor state */ - 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_refresh_t el_refresh; /* Refresh stuff */ el_prompt_t el_prompt; /* Prompt stuff */ @@ -129,14 +137,19 @@ el_prompt_t el_rprompt; /* Prompt stuff */ el_chared_t el_chared; /* Characted editor stuff */ el_map_t el_map; /* Key mapping stuff */ - el_key_t el_key; /* Key binding stuff */ + el_keymacro_t el_keymacro; /* Key binding stuff */ el_history_t el_history; /* History stuff */ el_search_t el_search; /* Search stuff */ el_signal_t el_signal; /* Signal handling stuff */ el_read_t el_read; /* Character reading stuff */ +#ifdef WIDECHAR + ct_buffer_t el_scratch; /* Scratch conversion buffer */ + ct_buffer_t el_lgcyconv; /* Buffer for legacy wrappers */ + LineInfo el_lgcylinfo; /* Legacy LineInfo buffer */ +#endif }; -protected int el_editmode(EditLine *, int, const char **); +protected int el_editmode(EditLine *, int, const Char **); #ifdef DEBUG #define EL_ABORT(a) do { \ Index: lib/libedit/eln.c =================================================================== --- lib/libedit/eln.c (revision 0) +++ lib/libedit/eln.c (working copy) @@ -0,0 +1,368 @@ +/* $NetBSD: eln.c,v 1.14 2012/03/11 21:15:25 christos Exp $ */ + +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Christos Zoulas of Cornell University. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include "config.h" +#include "histedit.h" +#include "el.h" +#include "read.h" +#include +#include +#include +__FBSDID("$FreeBSD$"); + +public int +el_getc(EditLine *el, char *cp) +{ + int num_read; + wchar_t wc = 0; + + if (!(el->el_flags & CHARSET_IS_UTF8)) + el->el_flags |= IGNORE_EXTCHARS; + num_read = el_wgetc (el, &wc); + if (!(el->el_flags & CHARSET_IS_UTF8)) + el->el_flags &= ~IGNORE_EXTCHARS; + + if (num_read > 0) + *cp = (char)wc; + return num_read; +} + + +public void +el_push(EditLine *el, const char *str) +{ + /* Using multibyte->wide string decoding works fine under single-byte + * character sets too, and Does The Right Thing. */ + el_wpush(el, ct_decode_string(str, &el->el_lgcyconv)); +} + + +public const char * +el_gets(EditLine *el, int *nread) +{ + const wchar_t *tmp; + + el->el_flags |= IGNORE_EXTCHARS; + tmp = el_wgets(el, nread); + el->el_flags &= ~IGNORE_EXTCHARS; + return ct_encode_string(tmp, &el->el_lgcyconv); +} + + +public int +el_parse(EditLine *el, int argc, const char *argv[]) +{ + int ret; + const wchar_t **wargv; + + wargv = (const wchar_t **) + ct_decode_argv(argc, argv, &el->el_lgcyconv); + if (!wargv) + return -1; + ret = el_wparse(el, argc, wargv); + ct_free_argv(wargv); + + return ret; +} + + +public int +el_set(EditLine *el, int op, ...) +{ + va_list ap; + int ret; + + if (!el) + return -1; + va_start(ap, op); + + switch (op) { + case EL_PROMPT: /* el_pfunc_t */ + case EL_RPROMPT: { + el_pfunc_t p = va_arg(ap, el_pfunc_t); + ret = prompt_set(el, p, 0, op, 0); + break; + } + + case EL_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 + 1, 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)); +} Property changes on: lib/libedit/eln.c ___________________________________________________________________ Added: svn:mime-type ## -0,0 +1 ## +text/plain \ No newline at end of property Added: svn:keywords ## -0,0 +1 ## +FreeBSD=%H \ No newline at end of property Added: svn:eol-style ## -0,0 +1 ## +native \ No newline at end of property Index: lib/libedit/emacs.c =================================================================== --- lib/libedit/emacs.c (revision 258914) +++ lib/libedit/emacs.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: emacs.c,v 1.25 2011/07/29 15:16:33 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: emacs.c,v 1.21 2006/03/06 21:11:56 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -41,7 +42,6 @@ /* * emacs.c: Emacs functions */ -#include "sys.h" #include "el.h" /* em_delete_or_list(): @@ -50,7 +50,7 @@ */ protected el_action_t /*ARGSUSED*/ -em_delete_or_list(EditLine *el, int c) +em_delete_or_list(EditLine *el, Int c) { if (el->el_line.cursor == el->el_line.lastchar) { @@ -57,15 +57,15 @@ /* if I'm at the end */ if (el->el_line.cursor == el->el_line.buffer) { /* and the beginning */ - term_writec(el, c); /* then do an EOF */ - return (CC_EOF); + terminal_writec(el, c); /* then do an EOF */ + return CC_EOF; } else { /* * Here we could list completions, but it is an * error right now */ - term_beep(el); - return (CC_ERROR); + terminal_beep(el); + return CC_ERROR; } } else { if (el->el_state.doingarg) @@ -75,7 +75,7 @@ if (el->el_line.cursor > el->el_line.lastchar) el->el_line.cursor = el->el_line.lastchar; /* bounds check */ - return (CC_REFRESH); + return CC_REFRESH; } } @@ -86,12 +86,12 @@ */ protected el_action_t /*ARGSUSED*/ -em_delete_next_word(EditLine *el, int c __unused) +em_delete_next_word(EditLine *el, Int c __attribute__((__unused__))) { - char *cp, *p, *kp; + Char *cp, *p, *kp; if (el->el_line.cursor == el->el_line.lastchar) - return (CC_ERROR); + return CC_ERROR; cp = c__next_word(el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, ce__isword); @@ -101,11 +101,11 @@ *kp++ = *p; el->el_chared.c_kill.last = kp; - c_delafter(el, cp - el->el_line.cursor); /* delete after dot */ + c_delafter(el, (int)(cp - el->el_line.cursor)); /* delete after dot */ if (el->el_line.cursor > el->el_line.lastchar) el->el_line.cursor = el->el_line.lastchar; /* bounds check */ - return (CC_REFRESH); + return CC_REFRESH; } @@ -115,23 +115,24 @@ */ protected el_action_t /*ARGSUSED*/ -em_yank(EditLine *el, int c __unused) +em_yank(EditLine *el, Int c __attribute__((__unused__))) { - char *kp, *cp; + Char *kp, *cp; if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) - return (CC_NORM); + return CC_NORM; if (el->el_line.lastchar + (el->el_chared.c_kill.last - el->el_chared.c_kill.buf) >= el->el_line.limit) - return (CC_ERROR); + return CC_ERROR; el->el_chared.c_kill.mark = el->el_line.cursor; cp = el->el_line.cursor; /* open the space, */ - c_insert(el, el->el_chared.c_kill.last - el->el_chared.c_kill.buf); + c_insert(el, + (int)(el->el_chared.c_kill.last - el->el_chared.c_kill.buf)); /* copy the chars */ for (kp = el->el_chared.c_kill.buf; kp < el->el_chared.c_kill.last; kp++) *cp++ = *kp; @@ -140,7 +141,7 @@ if (el->el_state.argument == 1) el->el_line.cursor = cp; - return (CC_REFRESH); + return CC_REFRESH; } @@ -150,9 +151,9 @@ */ protected el_action_t /*ARGSUSED*/ -em_kill_line(EditLine *el, int c __unused) +em_kill_line(EditLine *el, Int c __attribute__((__unused__))) { - char *kp, *cp; + Char *kp, *cp; cp = el->el_line.buffer; kp = el->el_chared.c_kill.buf; @@ -162,7 +163,7 @@ /* zap! -- delete all of it */ el->el_line.lastchar = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer; - return (CC_REFRESH); + return CC_REFRESH; } @@ -172,12 +173,12 @@ */ protected el_action_t /*ARGSUSED*/ -em_kill_region(EditLine *el, int c __unused) +em_kill_region(EditLine *el, Int c __attribute__((__unused__))) { - char *kp, *cp; + Char *kp, *cp; if (!el->el_chared.c_kill.mark) - return (CC_ERROR); + return CC_ERROR; if (el->el_chared.c_kill.mark > el->el_line.cursor) { cp = el->el_line.cursor; @@ -185,7 +186,7 @@ while (cp < el->el_chared.c_kill.mark) *kp++ = *cp++; /* copy it */ el->el_chared.c_kill.last = kp; - c_delafter(el, cp - el->el_line.cursor); + c_delafter(el, (int)(cp - el->el_line.cursor)); } else { /* mark is before cursor */ cp = el->el_chared.c_kill.mark; kp = el->el_chared.c_kill.buf; @@ -192,10 +193,10 @@ while (cp < el->el_line.cursor) *kp++ = *cp++; /* copy it */ el->el_chared.c_kill.last = kp; - c_delbefore(el, cp - el->el_chared.c_kill.mark); + c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark)); el->el_line.cursor = el->el_chared.c_kill.mark; } - return (CC_REFRESH); + return CC_REFRESH; } @@ -205,12 +206,12 @@ */ protected el_action_t /*ARGSUSED*/ -em_copy_region(EditLine *el, int c __unused) +em_copy_region(EditLine *el, Int c __attribute__((__unused__))) { - char *kp, *cp; + Char *kp, *cp; if (!el->el_chared.c_kill.mark) - return (CC_ERROR); + return CC_ERROR; if (el->el_chared.c_kill.mark > el->el_line.cursor) { cp = el->el_line.cursor; @@ -225,7 +226,7 @@ *kp++ = *cp++; /* copy it */ el->el_chared.c_kill.last = kp; } - return (CC_NORM); + return CC_NORM; } @@ -234,7 +235,7 @@ * Gosling emacs transpose chars [^T] */ protected el_action_t -em_gosmacs_transpose(EditLine *el, int c) +em_gosmacs_transpose(EditLine *el, Int c) { if (el->el_line.cursor > &el->el_line.buffer[1]) { @@ -242,9 +243,9 @@ c = el->el_line.cursor[-2]; el->el_line.cursor[-2] = el->el_line.cursor[-1]; el->el_line.cursor[-1] = c; - return (CC_REFRESH); + return CC_REFRESH; } else - return (CC_ERROR); + return CC_ERROR; } @@ -254,10 +255,10 @@ */ protected el_action_t /*ARGSUSED*/ -em_next_word(EditLine *el, int c __unused) +em_next_word(EditLine *el, Int c __attribute__((__unused__))) { 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.lastchar, @@ -267,9 +268,9 @@ if (el->el_map.type == MAP_VI) if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -279,21 +280,21 @@ */ protected el_action_t /*ARGSUSED*/ -em_upper_case(EditLine *el, int c __unused) +em_upper_case(EditLine *el, Int c __attribute__((__unused__))) { - char *cp, *ep; + Char *cp, *ep; ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, ce__isword); for (cp = el->el_line.cursor; cp < ep; cp++) - if (islower((unsigned char)*cp)) - *cp = toupper((unsigned char)*cp); + if (Islower(*cp)) + *cp = Toupper(*cp); el->el_line.cursor = ep; if (el->el_line.cursor > el->el_line.lastchar) el->el_line.cursor = el->el_line.lastchar; - return (CC_REFRESH); + return CC_REFRESH; } @@ -303,29 +304,29 @@ */ protected el_action_t /*ARGSUSED*/ -em_capitol_case(EditLine *el, int c __unused) +em_capitol_case(EditLine *el, Int c __attribute__((__unused__))) { - char *cp, *ep; + Char *cp, *ep; ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, ce__isword); for (cp = el->el_line.cursor; cp < ep; cp++) { - if (isalpha((unsigned char)*cp)) { - if (islower((unsigned char)*cp)) - *cp = toupper((unsigned char)*cp); + if (Isalpha(*cp)) { + if (Islower(*cp)) + *cp = Toupper(*cp); cp++; break; } } for (; cp < ep; cp++) - if (isupper((unsigned char)*cp)) - *cp = tolower((unsigned char)*cp); + if (Isupper(*cp)) + *cp = Tolower(*cp); el->el_line.cursor = ep; if (el->el_line.cursor > el->el_line.lastchar) el->el_line.cursor = el->el_line.lastchar; - return (CC_REFRESH); + return CC_REFRESH; } @@ -335,21 +336,21 @@ */ protected el_action_t /*ARGSUSED*/ -em_lower_case(EditLine *el, int c __unused) +em_lower_case(EditLine *el, Int c __attribute__((__unused__))) { - char *cp, *ep; + Char *cp, *ep; ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, ce__isword); for (cp = el->el_line.cursor; cp < ep; cp++) - if (isupper((unsigned char)*cp)) - *cp = tolower((unsigned char)*cp); + if (Isupper(*cp)) + *cp = Tolower(*cp); el->el_line.cursor = ep; if (el->el_line.cursor > el->el_line.lastchar) el->el_line.cursor = el->el_line.lastchar; - return (CC_REFRESH); + return CC_REFRESH; } @@ -359,11 +360,11 @@ */ protected el_action_t /*ARGSUSED*/ -em_set_mark(EditLine *el, int c __unused) +em_set_mark(EditLine *el, Int c __attribute__((__unused__))) { el->el_chared.c_kill.mark = el->el_line.cursor; - return (CC_NORM); + return CC_NORM; } @@ -373,14 +374,14 @@ */ protected el_action_t /*ARGSUSED*/ -em_exchange_mark(EditLine *el, int c __unused) +em_exchange_mark(EditLine *el, Int c __attribute__((__unused__))) { - char *cp; + Char *cp; cp = el->el_line.cursor; el->el_line.cursor = el->el_chared.c_kill.mark; el->el_chared.c_kill.mark = cp; - return (CC_CURSOR); + return CC_CURSOR; } @@ -390,14 +391,14 @@ */ protected el_action_t /*ARGSUSED*/ -em_universal_argument(EditLine *el, int c __unused) +em_universal_argument(EditLine *el, Int c __attribute__((__unused__))) { /* multiply current argument by 4 */ if (el->el_state.argument > 1000000) - return (CC_ERROR); + return CC_ERROR; el->el_state.doingarg = 1; el->el_state.argument *= 4; - return (CC_ARGHACK); + return CC_ARGHACK; } @@ -407,11 +408,11 @@ */ protected el_action_t /*ARGSUSED*/ -em_meta_next(EditLine *el, int c __unused) +em_meta_next(EditLine *el, Int c __attribute__((__unused__))) { el->el_state.metanext = 1; - return (CC_ARGHACK); + return CC_ARGHACK; } @@ -420,12 +421,12 @@ */ protected el_action_t /*ARGSUSED*/ -em_toggle_overwrite(EditLine *el, int c __unused) +em_toggle_overwrite(EditLine *el, Int c __attribute__((__unused__))) { el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ? MODE_REPLACE : MODE_INSERT; - return (CC_NORM); + return CC_NORM; } @@ -434,12 +435,12 @@ */ protected el_action_t /*ARGSUSED*/ -em_copy_prev_word(EditLine *el, int c __unused) +em_copy_prev_word(EditLine *el, Int c __attribute__((__unused__))) { - char *cp, *oldc, *dp; + Char *cp, *oldc, *dp; if (el->el_line.cursor == el->el_line.buffer) - return (CC_ERROR); + return CC_ERROR; oldc = el->el_line.cursor; /* does a bounds check */ @@ -446,13 +447,13 @@ cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, el->el_state.argument, ce__isword); - c_insert(el, oldc - cp); + c_insert(el, (int)(oldc - cp)); for (dp = oldc; cp < oldc && dp < el->el_line.lastchar; cp++) *dp++ = *cp; el->el_line.cursor = dp;/* put cursor at end */ - return (CC_REFRESH); + return CC_REFRESH; } @@ -461,11 +462,11 @@ */ protected el_action_t /*ARGSUSED*/ -em_inc_search_next(EditLine *el, int c __unused) +em_inc_search_next(EditLine *el, Int c __attribute__((__unused__))) { el->el_search.patlen = 0; - return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY)); + return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY); } @@ -474,11 +475,11 @@ */ protected el_action_t /*ARGSUSED*/ -em_inc_search_prev(EditLine *el, int c __unused) +em_inc_search_prev(EditLine *el, Int c __attribute__((__unused__))) { el->el_search.patlen = 0; - return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY)); + return ce_inc_search(el, ED_SEARCH_PREV_HISTORY); } @@ -488,11 +489,11 @@ */ protected el_action_t /*ARGSUSED*/ -em_delete_prev_char(EditLine *el, int c __unused) +em_delete_prev_char(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor <= el->el_line.buffer) - return (CC_ERROR); + return CC_ERROR; if (el->el_state.doingarg) c_delbefore(el, el->el_state.argument); @@ -501,5 +502,5 @@ el->el_line.cursor -= el->el_state.argument; if (el->el_line.cursor < el->el_line.buffer) el->el_line.cursor = el->el_line.buffer; - return (CC_REFRESH); + return CC_REFRESH; } Index: lib/libedit/filecomplete.c =================================================================== --- lib/libedit/filecomplete.c (revision 258914) +++ lib/libedit/filecomplete.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: filecomplete.c,v 1.31 2011/09/16 16:13:16 plunky Exp $ */ + /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. * All rights reserved. @@ -25,10 +27,9 @@ * 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. - * - * $NetBSD: filecomplete.c,v 1.19 2010/06/01 18:20:26 christos Exp $ */ +#include "config.h" #include __FBSDID("$FreeBSD$"); @@ -44,16 +45,14 @@ #include #include #include -#include + #include "el.h" #include "fcns.h" /* for EL_NUM_FCNS */ #include "histedit.h" #include "filecomplete.h" -static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', - '>', '<', '=', ';', '|', '&', '{', '(', '\0' }; -/* Tilde is deliberately omitted here, we treat it specially. */ -static char extra_quote_chars[] = { ')', '}', '*', '?', '[', '$', '\0' }; +static const Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', + '$', '>', '<', '=', ';', '|', '&', '{', '(', '\0' }; /********************************/ @@ -69,13 +68,16 @@ char * fn_tilde_expand(const char *txt) { - struct passwd pwres, *pass; +#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT) + struct passwd pwres; + char pwbuf[1024]; +#endif + struct passwd *pass; char *temp; size_t len = 0; - char pwbuf[1024]; if (txt[0] != '~') - return (strdup(txt)); + return strdup(txt); temp = strchr(txt + 1, '/'); if (temp == NULL) { @@ -83,8 +85,9 @@ if (temp == NULL) return NULL; } else { - len = temp - txt + 1; /* text until string after slash */ - temp = malloc(len); + /* text until string after slash */ + len = (size_t)(temp - txt + 1); + temp = el_malloc(len * sizeof(*temp)); if (temp == NULL) return NULL; (void)strncpy(temp, txt + 1, len - 2); @@ -91,26 +94,40 @@ temp[len - 2] = '\0'; } if (temp[0] == 0) { - if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf), &pass) != 0) - pass = NULL; +#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()); +#endif } 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); +#endif } - free(temp); /* value no more needed */ + el_free(temp); /* value no more needed */ if (pass == NULL) - return (strdup(txt)); + return strdup(txt); - /* update pointer txt to point at string immediately following */ + /* update pointer txt to point at string immedially following */ /* first slash */ 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) 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; } @@ -136,19 +153,21 @@ if (temp) { char *nptr; temp++; - nptr = realloc(filename, strlen(temp) + 1); + nptr = el_realloc(filename, (strlen(temp) + 1) * + sizeof(*nptr)); if (nptr == NULL) { - free(filename); + el_free(filename); filename = NULL; return NULL; } filename = nptr; (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) { - free(dirname); + el_free(dirname); dirname = NULL; return NULL; } @@ -156,7 +175,7 @@ (void)strncpy(dirname, text, len); dirname[len] = '\0'; } else { - free(filename); + el_free(filename); if (*text == 0) filename = NULL; else { @@ -164,7 +183,7 @@ if (filename == NULL) return NULL; } - free(dirname); + el_free(dirname); dirname = NULL; } @@ -175,7 +194,7 @@ /* support for ``~user'' syntax */ - free(dirpath); + el_free(dirpath); dirpath = NULL; if (dirname == NULL) { if ((dirname = strdup("")) == NULL) @@ -191,7 +210,7 @@ dir = opendir(dirpath); if (!dir) - return (NULL); /* cannot open the directory */ + return NULL; /* cannot open the directory */ /* will be used in cycle */ filename_len = filename ? strlen(filename) : 0; @@ -208,7 +227,11 @@ /* otherwise, get first entry where first */ /* filename_len characters are equal */ if (entry->d_name[0] == filename[0] +#if HAVE_STRUCT_DIRENT_D_NAMLEN && entry->d_namlen >= filename_len +#else + && strlen(entry->d_name) >= filename_len +#endif && strncmp(entry->d_name, filename, filename_len) == 0) break; @@ -215,12 +238,18 @@ } if (entry) { /* match found */ + +#if HAVE_STRUCT_DIRENT_D_NAMLEN len = entry->d_namlen; +#else + len = strlen(entry->d_name); +#endif - temp = malloc(strlen(dirname) + len + 1); + len = strlen(dirname) + len + 1; + temp = el_malloc(len * sizeof(*temp)); if (temp == NULL) return NULL; - (void)sprintf(temp, "%s%s", dirname, entry->d_name); + (void)snprintf(temp, len, "%s%s", dirname, entry->d_name); } else { (void)closedir(dir); dir = NULL; @@ -227,7 +256,7 @@ temp = NULL; } - return (temp); + return temp; } @@ -244,11 +273,9 @@ rs = "/"; out: if (expname) - free(expname); + el_free(expname); return rs; } - - /* * returns list of completions for text given * non-static for readline. @@ -269,10 +296,10 @@ char **nmatch_list; while (matches + 3 >= match_list_len) match_list_len <<= 1; - nmatch_list = realloc(match_list, - match_list_len * sizeof(char *)); + nmatch_list = el_realloc(match_list, + match_list_len * sizeof(*nmatch_list)); if (nmatch_list == NULL) { - free(match_list); + el_free(match_list); return NULL; } match_list = nmatch_list; @@ -295,9 +322,9 @@ max_equal = i; } - retstr = malloc(max_equal + 1); + retstr = el_malloc((max_equal + 1) * sizeof(*retstr)); if (retstr == NULL) { - free(match_list); + el_free(match_list); return NULL; } (void)strncpy(retstr, match_list[1], max_equal); @@ -305,12 +332,11 @@ match_list[0] = retstr; /* 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; } - /* * Sort function for qsort(). Just wrapper around strcasecmp(). */ @@ -323,47 +349,53 @@ return strcasecmp(s1, s2); } - /* * Display list of strings in columnar format on readline's output stream. - * 'matches' is list of strings, 'len' is number of strings in 'matches', - * 'max' is maximum length of string in 'matches'. + * 'matches' is list of strings, 'num' is number of strings 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 -fn_display_match_list(EditLine *el, char **matches, size_t len, size_t max) +fn_display_match_list (EditLine *el, char **matches, size_t num, size_t width) { - size_t i, idx, limit, count; - int screenwidth = el->el_term.t_size.h; + size_t line, lines, col, cols, thisguy; + 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 - * with two spaces between strings. + * Find out how many entries can be put on one line; count + * with one space between strings the same way it's printed. */ - limit = screenwidth / (max + 2); - if (limit == 0) - limit = 1; + cols = (size_t)screenwidth / (width + 1); + if (cols == 0) + cols = 1; - /* how many lines of output */ - count = len / limit; - if (count * limit < len) - count++; + /* how many lines of output, rounded up */ + lines = (num + cols - 1) / cols; - /* Sort the items if they are not already sorted. */ - qsort(&matches[1], len, sizeof(char *), _fn_qsort_string_compare); + /* Sort the items. */ + qsort(matches, num, sizeof(char *), _fn_qsort_string_compare); - idx = 1; - for(; count > 0; count--) { - int more = limit > 0 && matches[0]; - for(i = 0; more; idx++) { - more = ++i < limit && matches[idx + 1]; - (void)fprintf(el->el_outfile, "%-*s%s", (int)max, - matches[idx], more ? " " : ""); + /* + * On the ith line print elements i, i+lines, i+lines*2, etc. + */ + for (line = 0; line < lines; line++) { + 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"); } } - /* * Complete the word at or before point, * 'what_to_do' says what to do with the completion. @@ -380,18 +412,14 @@ fn_complete(EditLine *el, char *(*complet_func)(const char *, int), char **(*attempted_completion_function)(const char *, int, int), - const char *word_break, const char *special_prefixes, + const Char *word_break, const Char *special_prefixes, const char *(*app_func)(const char *), size_t query_items, - int *completion_type, int *over, int *point, int *end, - const char *(*find_word_start_func)(const char *, const char *), - char *(*dequoting_func)(const char *), - char *(*quoting_func)(const char *)) + int *completion_type, int *over, int *point, int *end) { - const LineInfo *li; - char *temp; - char *dequoted_temp; - char **matches; - const char *ctemp; + const TYPE(LineInfo) *li; + Char *temp; + char **matches; + const Char *ctemp; size_t len; int what_to_do = '\t'; int retval = CC_NORM; @@ -409,35 +437,18 @@ app_func = append_char_function; /* We now look backwards for the start of a filename/variable word */ - li = el_line(el); - if (find_word_start_func) - ctemp = find_word_start_func(li->buffer, li->cursor); - else { - ctemp = li->cursor; - while (ctemp > li->buffer - && !strchr(word_break, ctemp[-1]) - && (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) ) - ctemp--; - } + li = FUN(el,line)(el); + ctemp = li->cursor; + while (ctemp > li->buffer + && !Strchr(word_break, ctemp[-1]) + && (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) ) + ctemp--; - len = li->cursor - ctemp; -#if defined(__SSP__) || defined(__SSP_ALL__) - temp = malloc(sizeof(*temp) * (len + 1)); - if (temp == NULL) - return retval; -#else - temp = alloca(sizeof(*temp) * (len + 1)); -#endif - (void)strncpy(temp, ctemp, len); + len = (size_t)(li->cursor - ctemp); + temp = el_malloc((len + 1) * sizeof(*temp)); + (void)Strncpy(temp, ctemp, len); temp[len] = '\0'; - if (dequoting_func) { - dequoted_temp = dequoting_func(temp); - if (dequoted_temp == NULL) - return retval; - } else - dequoted_temp = NULL; - /* these can be used by function called in completion_matches() */ /* or (*attempted_completion_function)() */ if (point != 0) @@ -447,13 +458,15 @@ if (attempted_completion_function) { int cur_off = (int)(li->cursor - li->buffer); - matches = (*attempted_completion_function) (dequoted_temp ? dequoted_temp : temp, - (int)(cur_off - len), cur_off); + matches = (*attempted_completion_function)( + ct_encode_string(temp, &el->el_scratch), + cur_off - (int)len, cur_off); } else matches = 0; if (!attempted_completion_function || (over != NULL && !*over && !matches)) - matches = completion_matches(dequoted_temp ? dequoted_temp : temp, complet_func); + matches = completion_matches( + ct_encode_string(temp, &el->el_scratch), complet_func); if (over != NULL) *over = 0; @@ -468,18 +481,9 @@ * possible matches if there is possible completion. */ if (matches[0][0] != '\0') { - char *quoted_match; - if (quoting_func) { - quoted_match = quoting_func(matches[0]); - if (quoted_match == NULL) - goto free_matches; - } else - quoted_match = NULL; - el_deletestr(el, (int) len); - el_insertstr(el, quoted_match ? quoted_match : matches[0]); - - free(quoted_match); + FUN(el,insertstr)(el, + ct_decode_string(matches[0], &el->el_scratch)); } if (what_to_do == '?') @@ -491,7 +495,9 @@ * it, unless we do filename completion and the * 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 == '!') { display_matches: /* @@ -504,7 +510,8 @@ if (match_len > maxlen) 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 */ (void)fprintf(el->el_outfile, "\n"); @@ -523,9 +530,17 @@ (void)fprintf(el->el_outfile, "\n"); } - if (match_display) - fn_display_match_list(el, matches, matches_num, - maxlen); + if (match_display) { + /* + * 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; } else if (matches[0][0]) { /* @@ -541,21 +556,16 @@ retval = CC_NORM; } -free_matches: /* free elements of array and the array itself */ for (i = 0; matches[i]; i++) - free(matches[i]); - free(matches); + el_free(matches[i]); + el_free(matches); matches = NULL; } - free(dequoted_temp); -#if defined(__SSP__) || defined(__SSP_ALL__) - free(temp); -#endif + el_free(temp); return retval; } - /* * el-compatible wrapper around rl_complete; needed for key binding */ @@ -564,104 +574,6 @@ _el_fn_complete(EditLine *el, int ch __attribute__((__unused__))) { return (unsigned char)fn_complete(el, NULL, NULL, - break_chars, NULL, NULL, 100, - NULL, NULL, NULL, NULL, - NULL, NULL, NULL); + break_chars, NULL, NULL, (size_t)100, + NULL, NULL, NULL, NULL); } - - -static const char * -sh_find_word_start(const char *buffer, const char *cursor) -{ - const char *word_start = buffer; - - while (buffer < cursor) { - if (*buffer == '\\') - buffer++; - else if (strchr(break_chars, *buffer)) - word_start = buffer + 1; - - buffer++; - } - - return word_start; -} - - -static char * -sh_quote(const char *str) -{ - const char *src; - int extra_len = 0; - char *quoted_str, *dst; - - if (*str == '-' || *str == '+') - extra_len += 2; - for (src = str; *src != '\0'; src++) - if (strchr(break_chars, *src) || - strchr(extra_quote_chars, *src)) - extra_len++; - - quoted_str = malloc(sizeof(*quoted_str) * - (strlen(str) + extra_len + 1)); - if (quoted_str == NULL) - return NULL; - - dst = quoted_str; - if (*str == '-' || *str == '+') - *dst++ = '.', *dst++ = '/'; - for (src = str; *src != '\0'; src++) { - if (strchr(break_chars, *src) || - strchr(extra_quote_chars, *src)) - *dst++ = '\\'; - *dst++ = *src; - } - *dst = '\0'; - - return quoted_str; -} - - -static char * -sh_dequote(const char *str) -{ - char *dequoted_str, *dst; - - /* save extra space to replace \~ with ./~ */ - dequoted_str = malloc(sizeof(*dequoted_str) * (strlen(str) + 1 + 1)); - if (dequoted_str == NULL) - return NULL; - - dst = dequoted_str; - - /* dequote \~ at start as ./~ */ - if (*str == '\\' && str[1] == '~') { - str++; - *dst++ = '.'; - *dst++ = '/'; - } - - while (*str) { - if (*str == '\\') - str++; - if (*str) - *dst++ = *str++; - } - *dst = '\0'; - - return dequoted_str; -} - - -/* - * completion function using sh quoting rules; for key binding - */ -/* ARGSUSED */ -unsigned char -_el_fn_sh_complete(EditLine *el, int ch __attribute__((__unused__))) -{ - return (unsigned char)fn_complete(el, NULL, NULL, - break_chars, NULL, NULL, 100, - NULL, NULL, NULL, NULL, - sh_find_word_start, sh_dequote, sh_quote); -} Index: lib/libedit/filecomplete.h =================================================================== --- lib/libedit/filecomplete.h (revision 258914) +++ lib/libedit/filecomplete.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: filecomplete.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */ + /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. * All rights reserved. @@ -26,7 +28,6 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $NetBSD: filecomplete.h,v 1.9 2009/12/30 22:37:40 christos Exp $ * $FreeBSD$ */ #ifndef _FILECOMPLETE_H_ @@ -35,11 +36,8 @@ int fn_complete(EditLine *, char *(*)(const char *, int), char **(*)(const char *, int, int), - const char *, const char *, const char *(*)(const char *), size_t, - int *, int *, int *, int *, - const char *(*)(const char *, const char *), - char *(*)(const char *), - char *(*)(const char *)); + const Char *, const Char *, const char *(*)(const char *), size_t, + int *, int *, int *, int *); void fn_display_match_list(EditLine *, char **, size_t, size_t); char *fn_tilde_expand(const char *); Index: lib/libedit/hist.c =================================================================== --- lib/libedit/hist.c (revision 258914) +++ lib/libedit/hist.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: hist.c,v 1.20 2011/07/29 15:16:33 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -41,7 +42,6 @@ /* * hist.c: History access functions */ -#include "sys.h" #include #include "el.h" @@ -54,12 +54,12 @@ el->el_history.fun = NULL; el->el_history.ref = NULL; - el->el_history.buf = (char *) el_malloc(EL_BUFSIZ); + el->el_history.buf = el_malloc(EL_BUFSIZ * sizeof(*el->el_history.buf)); el->el_history.sz = EL_BUFSIZ; if (el->el_history.buf == NULL) - return (-1); + return -1; el->el_history.last = el->el_history.buf; - return (0); + return 0; } @@ -70,7 +70,7 @@ hist_end(EditLine *el) { - el_free((ptr_t) el->el_history.buf); + el_free(el->el_history.buf); el->el_history.buf = NULL; } @@ -79,12 +79,12 @@ * Set new history interface */ 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.fun = fun; - return (0); + return 0; } @@ -95,11 +95,11 @@ protected el_action_t hist_get(EditLine *el) { - const char *hp; + const Char *hp; int h; if (el->el_history.eventno == 0) { /* if really the current line */ - (void) strncpy(el->el_line.buffer, el->el_history.buf, + (void) Strncpy(el->el_line.buffer, el->el_history.buf, el->el_history.sz); el->el_line.lastchar = el->el_line.buffer + (el->el_history.last - el->el_history.buf); @@ -111,24 +111,25 @@ #endif /* KSHVI */ el->el_line.cursor = el->el_line.lastchar; - return (CC_REFRESH); + return CC_REFRESH; } if (el->el_history.ref == NULL) - return (CC_ERROR); + return CC_ERROR; hp = HIST_FIRST(el); if (hp == NULL) - return (CC_ERROR); + return CC_ERROR; for (h = 1; h < el->el_history.eventno; h++) if ((hp = HIST_NEXT(el)) == NULL) { el->el_history.eventno = h; - return (CC_ERROR); + return CC_ERROR; } - (void) strlcpy(el->el_line.buffer, hp, + (void) Strncpy(el->el_line.buffer, hp, (size_t)(el->el_line.limit - el->el_line.buffer)); - el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer); + el->el_line.buffer[el->el_line.limit - el->el_line.buffer - 1] = '\0'; + el->el_line.lastchar = el->el_line.buffer + Strlen(el->el_line.buffer); if (el->el_line.lastchar > el->el_line.buffer && el->el_line.lastchar[-1] == '\n') @@ -143,7 +144,7 @@ #endif /* KSHVI */ el->el_line.cursor = el->el_line.lastchar; - return (CC_REFRESH); + return CC_REFRESH; } @@ -151,34 +152,34 @@ * process a history command */ protected int -hist_command(EditLine *el, int argc, const char **argv) +hist_command(EditLine *el, int argc, const Char **argv) { - const char *str; + const Char *str; int num; - HistEvent ev; + TYPE(HistEvent) ev; 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 */ for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el)) (void) fprintf(el->el_outfile, "%d %s", - el->el_history.ev.num, str); - return (0); + el->el_history.ev.num, ct_encode_string(str, &el->el_scratch)); + return 0; } 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) - return history(el->el_history.ref, &ev, H_SETSIZE, num); + if (Strcmp(argv[1], STR("size")) == 0) + return FUNW(history)(el->el_history.ref, &ev, H_SETSIZE, num); - if (strcmp(argv[1], "unique") == 0) - return history(el->el_history.ref, &ev, H_SETUNIQUE, num); + if (Strcmp(argv[1], STR("unique")) == 0) + return FUNW(history)(el->el_history.ref, &ev, H_SETUNIQUE, num); return -1; } @@ -191,13 +192,13 @@ /*ARGSUSED*/ hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz) { - char *newbuf; + Char *newbuf; - newbuf = realloc(el->el_history.buf, newsz); + newbuf = el_realloc(el->el_history.buf, newsz * sizeof(*newbuf)); if (!newbuf) return 0; - (void) memset(&newbuf[oldsz], '\0', newsz - oldsz); + (void) memset(&newbuf[oldsz], '\0', (newsz - oldsz) * sizeof(*newbuf)); el->el_history.last = newbuf + (el->el_history.last - el->el_history.buf); @@ -206,3 +207,15 @@ 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 Index: lib/libedit/hist.h =================================================================== --- lib/libedit/hist.h (revision 258914) +++ lib/libedit/hist.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: hist.h,v 1.13 2011/07/28 20:50:55 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +32,6 @@ * SUCH DAMAGE. * * @(#)hist.h 8.1 (Berkeley) 6/4/93 - * $NetBSD: hist.h,v 1.10 2003/08/07 16:44:31 agc Exp $ * $FreeBSD$ */ @@ -42,22 +43,30 @@ #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 { - char *buf; /* The history buffer */ + Char *buf; /* The history buffer */ size_t sz; /* Size of history buffer */ - char *last; /* The last character */ + Char *last; /* The last character */ int eventno; /* Event we are looking for */ - ptr_t ref; /* Argument for history fcns */ + void * ref; /* Argument for history fcns */ hist_fun_t fun; /* Event access */ - HistEvent ev; /* Event cookie */ + TYPE(HistEvent) ev; /* Event cookie */ } el_history_t; -#define HIST_FUN(el, fn, arg) \ +#define HIST_FUN_INTERNAL(el, fn, arg) \ ((((*(el)->el_history.fun) ((el)->el_history.ref, &(el)->el_history.ev, \ fn, arg)) == -1) ? NULL : (el)->el_history.ev.str) +#ifdef WIDECHAR +#define HIST_FUN(el, fn, arg) \ + (((el)->el_flags & NARROW_HISTORY) ? hist_convert(el, fn, arg) : \ + HIST_FUN_INTERNAL(el, fn, arg)) +#else +#define HIST_FUN(el, fn, arg) HIST_FUN_INTERNAL(el, fn, arg) +#endif + #define HIST_NEXT(el) HIST_FUN(el, H_NEXT, NULL) #define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL) #define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL) @@ -69,8 +78,11 @@ protected int hist_init(EditLine *); protected void hist_end(EditLine *); protected el_action_t hist_get(EditLine *); -protected int hist_set(EditLine *, hist_fun_t, ptr_t); -protected int hist_command(EditLine *, int, const char **); +protected int hist_set(EditLine *, hist_fun_t, void *); +protected int hist_command(EditLine *, int, const Char **); protected int hist_enlargebuf(EditLine *, size_t, size_t); +#ifdef WIDECHAR +protected wchar_t *hist_convert(EditLine *, int, void *); +#endif #endif /* _h_el_hist */ Index: lib/libedit/histedit.h =================================================================== --- lib/libedit/histedit.h (revision 258914) +++ lib/libedit/histedit.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: histedit.h,v 1.51 2013/07/12 17:48:29 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +32,6 @@ * SUCH DAMAGE. * * @(#)histedit.h 8.2 (Berkeley) 1/3/94 - * $NetBSD: histedit.h,v 1.32 2007/06/10 20:20:28 christos Exp $ * $FreeBSD$ */ @@ -40,10 +41,12 @@ #ifndef _HISTEDIT_H_ #define _HISTEDIT_H_ +#define LIBEDIT_MAJOR 2 +#define LIBEDIT_MINOR 11 + #include #include -__BEGIN_DECLS #ifdef __cplusplus extern "C" { #endif @@ -82,6 +85,8 @@ * Initialization, cleanup, and resetting */ EditLine *el_init(const char *, FILE *, FILE *, FILE *); +EditLine *el_init_fd(const char *, FILE *, FILE *, FILE *, + int, int, int); void el_end(EditLine *); void el_reset(EditLine *); @@ -109,32 +114,45 @@ int el_set(EditLine *, int, ...); int el_get(EditLine *, int, ...); unsigned char _el_fn_complete(EditLine *, int); -unsigned char _el_fn_sh_complete(EditLine *, int); /* * 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_TERMINAL 1 /* , const char *); */ -#define EL_EDITOR 2 /* , const char *); */ -#define EL_SIGNAL 3 /* , int); */ -#define EL_BIND 4 /* , const char *, ..., NULL); */ -#define EL_TELLTC 5 /* , const char *, ..., NULL); */ -#define EL_SETTC 6 /* , const char *, ..., NULL); */ -#define EL_ECHOTC 7 /* , const char *, ..., NULL); */ -#define EL_SETTY 8 /* , const char *, ..., NULL); */ -#define EL_ADDFN 9 /* , const char *, const char * */ - /* , el_func_t); */ -#define EL_HIST 10 /* , hist_fun_t, const char *); */ -#define EL_EDITMODE 11 /* , int); */ -#define EL_RPROMPT 12 /* , el_pfunc_t); */ -#define EL_GETCFN 13 /* , el_rfunc_t); */ -#define EL_CLIENTDATA 14 /* , void *); */ -#define EL_UNBUFFERED 15 /* , int); */ -#define EL_PREP_TERM 16 /* , int); */ -#define EL_GETTC 17 /* , const char *, ..., NULL); */ -#define EL_GETFP 18 /* , int, FILE **); */ -#define EL_SETFP 19 /* , int, FILE *); */ +#define EL_PROMPT 0 /* , prompt_func); set/get */ +#define EL_TERMINAL 1 /* , const char *); set/get */ +#define EL_EDITOR 2 /* , const Char *); set/get */ +#define EL_SIGNAL 3 /* , int); set/get */ +#define EL_BIND 4 /* , const Char *, ..., NULL); set */ +#define EL_TELLTC 5 /* , const Char *, ..., NULL); set */ +#define EL_SETTC 6 /* , const Char *, ..., NULL); set */ +#define EL_ECHOTC 7 /* , const Char *, ..., NULL); set */ +#define EL_SETTY 8 /* , const Char *, ..., NULL); set */ +#define EL_ADDFN 9 /* , const Char *, const Char, set */ + /* el_func_t); */ +#define EL_HIST 10 /* , hist_fun_t, const void *); set */ +#define EL_EDITMODE 11 /* , int); set/get */ +#define EL_RPROMPT 12 /* , prompt_func); set/get */ +#define EL_GETCFN 13 /* , el_rfunc_t); set/get */ +#define EL_CLIENTDATA 14 /* , void *); set/get */ +#define EL_UNBUFFERED 15 /* , int); set/get */ +#define EL_PREP_TERM 16 /* , int); set */ +#define EL_GETTC 17 /* , const Char *, ..., NULL); get */ +#define EL_GETFP 18 /* , int, FILE **); get */ +#define EL_SETFP 19 /* , int, FILE *); set */ #define EL_REFRESH 20 /* , void); set */ #define EL_PROMPT_ESC 21 /* , prompt_func, Char); set/get */ #define EL_RPROMPT_ESC 22 /* , prompt_func, Char); set/get */ @@ -183,7 +201,6 @@ #define H_FUNC 0 /* , UTSL */ #define H_SETSIZE 1 /* , const int); */ -#define H_EVENT 1 /* , const int); */ #define H_GETSIZE 2 /* , void); */ #define H_FIRST 3 /* , void); */ #define H_LAST 4 /* , void); */ @@ -191,12 +208,12 @@ #define H_NEXT 6 /* , void); */ #define H_CURR 8 /* , const int); */ #define H_SET 7 /* , int); */ -#define H_ADD 9 /* , const char *); */ -#define H_ENTER 10 /* , const char *); */ -#define H_APPEND 11 /* , const char *); */ +#define H_ADD 9 /* , const wchar_t *); */ +#define H_ENTER 10 /* , const wchar_t *); */ +#define H_APPEND 11 /* , const wchar_t *); */ #define H_END 12 /* , void); */ -#define H_NEXT_STR 13 /* , const char *); */ -#define H_PREV_STR 14 /* , const char *); */ +#define H_NEXT_STR 13 /* , const wchar_t *); */ +#define H_PREV_STR 14 /* , const wchar_t *); */ #define H_NEXT_EVENT 15 /* , const int); */ #define H_PREV_EVENT 16 /* , const int); */ #define H_LOAD 17 /* , const char *); */ @@ -210,6 +227,7 @@ #define H_REPLACE 25 /* , const char *, histdata_t); */ + /* * ==== Tokenization ==== */ @@ -227,7 +245,75 @@ int tok_str(Tokenizer *, const char *, int *, const char ***); -__END_DECLS +/* + * 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 +#include + +/* + * 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, ...); + +int el_cursor(EditLine *, int); +const LineInfoW *el_wline(EditLine *); +int el_winsertstr(EditLine *, const wchar_t *); +#define el_wdeletestr el_deletestr + +/* + * ==== History ==== + */ +typedef struct histeventW { + int num; + const wchar_t *str; +} HistEventW; + +typedef struct historyW HistoryW; + +HistoryW * history_winit(void); +void history_wend(HistoryW *); + +int history_w(HistoryW *, HistEventW *, int, ...); + +/* + * ==== Tokenization ==== + */ +typedef struct tokenizerW TokenizerW; + +/* Wide character tokenizer support */ +TokenizerW *tok_winit(const wchar_t *); +void tok_wend(TokenizerW *); +void tok_wreset(TokenizerW *); +int tok_wline(TokenizerW *, const LineInfoW *, + int *, const wchar_t ***, int *, int *); +int tok_wstr(TokenizerW *, const wchar_t *, + int *, const wchar_t ***); + #ifdef __cplusplus } #endif Index: lib/libedit/history.c =================================================================== --- lib/libedit/history.c (revision 258914) +++ lib/libedit/history.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: history.c,v 1.46 2011/11/18 20:39:18 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: history.c,v 1.34 2009/09/07 21:24:33 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -39,10 +40,8 @@ __FBSDID("$FreeBSD$"); /* - * hist.c: History access functions + * hist.c: TYPE(History) access functions */ -#include "sys.h" - #include #include #include @@ -52,14 +51,15 @@ static const char hist_cookie[] = "_HiStOrY_V2_\n"; #include "histedit.h" +#include "chartype.h" -typedef int (*history_gfun_t)(ptr_t, HistEvent *); -typedef int (*history_efun_t)(ptr_t, HistEvent *, const char *); -typedef void (*history_vfun_t)(ptr_t, HistEvent *); -typedef int (*history_sfun_t)(ptr_t, HistEvent *, const int); +typedef int (*history_gfun_t)(void *, TYPE(HistEvent) *); +typedef int (*history_efun_t)(void *, TYPE(HistEvent) *, const Char *); +typedef void (*history_vfun_t)(void *, TYPE(HistEvent) *); +typedef int (*history_sfun_t)(void *, TYPE(HistEvent) *, const int); -struct history { - ptr_t h_ref; /* Argument for history fcns */ +struct TYPE(history) { + void *h_ref; /* Argument for history fcns */ int h_ent; /* Last entry point for history */ history_gfun_t h_first; /* Get the first element */ history_gfun_t h_next; /* Get the next element */ @@ -84,7 +84,7 @@ #define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str) #define HDEL(h, ev, n) (*(h)->h_del)((h)->h_ref, ev, n) -#define h_strdup(a) strdup(a) +#define h_strdup(a) Strdup(a) #define h_malloc(a) malloc(a) #define h_realloc(a, b) realloc((a), (b)) #define h_free(a) free(a) @@ -91,22 +91,22 @@ typedef struct { int num; - char *str; + Char *str; } HistEventPrivate; -private int history_setsize(History *, HistEvent *, int); -private int history_getsize(History *, HistEvent *); -private int history_setunique(History *, HistEvent *, int); -private int history_getunique(History *, HistEvent *); -private int history_set_fun(History *, History *); -private int history_load(History *, const char *); -private int history_save(History *, const char *); -private int history_prev_event(History *, HistEvent *, int); -private int history_next_event(History *, HistEvent *, int); -private int history_next_string(History *, HistEvent *, const char *); -private int history_prev_string(History *, HistEvent *, const char *); +private int history_setsize(TYPE(History) *, TYPE(HistEvent) *, int); +private int history_getsize(TYPE(History) *, TYPE(HistEvent) *); +private int history_setunique(TYPE(History) *, TYPE(HistEvent) *, int); +private int history_getunique(TYPE(History) *, TYPE(HistEvent) *); +private int history_set_fun(TYPE(History) *, TYPE(History) *); +private int history_load(TYPE(History) *, const char *); +private int history_save(TYPE(History) *, const char *); +private int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int); +private int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int); +private int history_next_string(TYPE(History) *, TYPE(HistEvent) *, const Char *); +private int history_prev_string(TYPE(History) *, TYPE(HistEvent) *, const Char *); /***********************************************************************/ @@ -115,7 +115,7 @@ * Builtin- history implementation */ typedef struct hentry_t { - HistEvent ev; /* What we return */ + TYPE(HistEvent) ev; /* What we return */ void *data; /* data */ struct hentry_t *next; /* Next entry */ struct hentry_t *prev; /* Previous entry */ @@ -127,27 +127,27 @@ int max; /* Maximum number of events */ int cur; /* Current number of events */ int eventid; /* For generation of unique event id */ - int flags; /* History flags */ + int flags; /* TYPE(History) flags */ #define H_UNIQUE 1 /* Store only unique elements */ } history_t; -private int history_def_next(ptr_t, HistEvent *); -private int history_def_first(ptr_t, HistEvent *); -private int history_def_prev(ptr_t, HistEvent *); -private int history_def_last(ptr_t, HistEvent *); -private int history_def_curr(ptr_t, HistEvent *); -private int history_def_set(ptr_t, HistEvent *, const int); -private void history_def_clear(ptr_t, HistEvent *); -private int history_def_enter(ptr_t, HistEvent *, const char *); -private int history_def_add(ptr_t, HistEvent *, const char *); -private int history_def_del(ptr_t, HistEvent *, const int); +private int history_def_next(void *, TYPE(HistEvent) *); +private int history_def_first(void *, TYPE(HistEvent) *); +private int history_def_prev(void *, TYPE(HistEvent) *); +private int history_def_last(void *, TYPE(HistEvent) *); +private int history_def_curr(void *, TYPE(HistEvent) *); +private int history_def_set(void *, TYPE(HistEvent) *, const int); +private void history_def_clear(void *, TYPE(HistEvent) *); +private int history_def_enter(void *, TYPE(HistEvent) *, const Char *); +private int history_def_add(void *, TYPE(HistEvent) *, const Char *); +private int history_def_del(void *, TYPE(HistEvent) *, const int); -private int history_def_init(ptr_t *, HistEvent *, int); -private int history_def_insert(history_t *, HistEvent *, const char *); -private void history_def_delete(history_t *, HistEvent *, hentry_t *); +private int history_def_init(void **, TYPE(HistEvent) *, int); +private int history_def_insert(history_t *, TYPE(HistEvent) *, const Char *); +private void history_def_delete(history_t *, TYPE(HistEvent) *, hentry_t *); -private int history_deldata_nth(history_t *, HistEvent *, int, void **); -private int history_set_nth(ptr_t, HistEvent *, int); +private int history_deldata_nth(history_t *, TYPE(HistEvent) *, int, void **); +private int history_set_nth(void *, TYPE(HistEvent) *, int); #define history_def_setsize(p, num)(void) (((history_t *)p)->max = (num)) #define history_def_getsize(p) (((history_t *)p)->cur) @@ -165,23 +165,23 @@ } /* error messages */ -static const char *const he_errlist[] = { - "OK", - "unknown error", - "malloc() failed", - "first event not found", - "last event not found", - "empty list", - "no next event", - "no previous event", - "current event is invalid", - "event not found", - "can't read history from file", - "can't write history", - "required parameter(s) not supplied", - "history size negative", - "function not allowed with other history-functions-set the default", - "bad parameters" +static const Char *const he_errlist[] = { + STR("OK"), + STR("unknown error"), + STR("malloc() failed"), + STR("first event not found"), + STR("last event not found"), + STR("empty list"), + STR("no next event"), + STR("no previous event"), + STR("current event is invalid"), + STR("event not found"), + STR("can't read history from file"), + STR("can't write history"), + STR("required parameter(s) not supplied"), + STR("history size negative"), + STR("function not allowed with other history-functions-set the default"), + STR("bad parameters") }; /* error codes */ #define _HE_OK 0 @@ -205,7 +205,7 @@ * Default function to return the first event in the history. */ private int -history_def_first(ptr_t p, HistEvent *ev) +history_def_first(void *p, TYPE(HistEvent) *ev) { history_t *h = (history_t *) p; @@ -214,10 +214,10 @@ *ev = h->cursor->ev; else { he_seterrev(ev, _HE_FIRST_NOTFOUND); - return (-1); + return -1; } - return (0); + return 0; } @@ -225,7 +225,7 @@ * Default function to return the last event in the history. */ private int -history_def_last(ptr_t p, HistEvent *ev) +history_def_last(void *p, TYPE(HistEvent) *ev) { history_t *h = (history_t *) p; @@ -234,10 +234,10 @@ *ev = h->cursor->ev; else { he_seterrev(ev, _HE_LAST_NOTFOUND); - return (-1); + return -1; } - return (0); + return 0; } @@ -245,24 +245,24 @@ * Default function to return the next event in the history. */ private int -history_def_next(ptr_t p, HistEvent *ev) +history_def_next(void *p, TYPE(HistEvent) *ev) { history_t *h = (history_t *) p; if (h->cursor == &h->list) { he_seterrev(ev, _HE_EMPTY_LIST); - return (-1); + return -1; } if (h->cursor->next == &h->list) { he_seterrev(ev, _HE_END_REACHED); - return (-1); + return -1; } h->cursor = h->cursor->next; *ev = h->cursor->ev; - return (0); + return 0; } @@ -270,7 +270,7 @@ * Default function to return the previous event in the history. */ private int -history_def_prev(ptr_t p, HistEvent *ev) +history_def_prev(void *p, TYPE(HistEvent) *ev) { history_t *h = (history_t *) p; @@ -277,18 +277,18 @@ if (h->cursor == &h->list) { he_seterrev(ev, (h->cur > 0) ? _HE_END_REACHED : _HE_EMPTY_LIST); - return (-1); + return -1; } if (h->cursor->prev == &h->list) { he_seterrev(ev, _HE_START_REACHED); - return (-1); + return -1; } h->cursor = h->cursor->prev; *ev = h->cursor->ev; - return (0); + return 0; } @@ -296,7 +296,7 @@ * Default function to return the current event in the history. */ private int -history_def_curr(ptr_t p, HistEvent *ev) +history_def_curr(void *p, TYPE(HistEvent) *ev) { history_t *h = (history_t *) p; @@ -305,10 +305,10 @@ else { he_seterrev(ev, (h->cur > 0) ? _HE_CURR_INVALID : _HE_EMPTY_LIST); - return (-1); + return -1; } - return (0); + return 0; } @@ -317,13 +317,13 @@ * given one. */ private int -history_def_set(ptr_t p, HistEvent *ev, const int n) +history_def_set(void *p, TYPE(HistEvent) *ev, const int n) { history_t *h = (history_t *) p; if (h->cur == 0) { he_seterrev(ev, _HE_EMPTY_LIST); - return (-1); + return -1; } if (h->cursor == &h->list || h->cursor->ev.num != n) { for (h->cursor = h->list.next; h->cursor != &h->list; @@ -333,9 +333,9 @@ } if (h->cursor == &h->list) { he_seterrev(ev, _HE_NOT_FOUND); - return (-1); + return -1; } - return (0); + return 0; } @@ -344,13 +344,13 @@ * n-th one. */ private int -history_set_nth(ptr_t p, HistEvent *ev, int n) +history_set_nth(void *p, TYPE(HistEvent) *ev, int n) { history_t *h = (history_t *) p; if (h->cur == 0) { he_seterrev(ev, _HE_EMPTY_LIST); - return (-1); + return -1; } for (h->cursor = h->list.prev; h->cursor != &h->list; h->cursor = h->cursor->prev) @@ -358,9 +358,9 @@ break; if (h->cursor == &h->list) { he_seterrev(ev, _HE_NOT_FOUND); - return (-1); + return -1; } - return (0); + return 0; } @@ -368,45 +368,46 @@ * Append string to element */ private int -history_def_add(ptr_t p, HistEvent *ev, const char *str) +history_def_add(void *p, TYPE(HistEvent) *ev, const Char *str) { history_t *h = (history_t *) p; size_t len; - char *s; + Char *s; HistEventPrivate *evp = (void *)&h->cursor->ev; if (h->cursor == &h->list) - return (history_def_enter(p, ev, str)); - len = strlen(evp->str) + strlen(str) + 1; - s = (char *) h_malloc(len); + return history_def_enter(p, ev, str); + len = Strlen(evp->str) + Strlen(str) + 1; + s = h_malloc(len * sizeof(*s)); if (s == NULL) { he_seterrev(ev, _HE_MALLOC_FAILED); - return (-1); + return -1; } - (void) strlcpy(s, h->cursor->ev.str, len); - (void) strlcat(s, str, len); - h_free((ptr_t)evp->str); + (void) Strncpy(s, h->cursor->ev.str, len); + s[len - 1] = '\0'; + (void) Strncat(s, str, len - Strlen(s) - 1); + h_free(evp->str); evp->str = s; *ev = h->cursor->ev; - return (0); + return 0; } private int -history_deldata_nth(history_t *h, HistEvent *ev, +history_deldata_nth(history_t *h, TYPE(HistEvent) *ev, int num, void **data) { if (history_set_nth(h, ev, num) != 0) - return (-1); + return -1; /* magic value to skip delete (just set to n-th history) */ if (data == (void **)-1) - return (0); - ev->str = strdup(h->cursor->ev.str); + return 0; + ev->str = Strdup(h->cursor->ev.str); ev->num = h->cursor->ev.num; if (data) *data = h->cursor->data; history_def_delete(h, ev, h->cursor); - return (0); + return 0; } @@ -415,16 +416,16 @@ */ /* ARGSUSED */ private int -history_def_del(ptr_t p, HistEvent *ev __unused, +history_def_del(void *p, TYPE(HistEvent) *ev __attribute__((__unused__)), const int num) { history_t *h = (history_t *) p; if (history_def_set(h, ev, num) != 0) - return (-1); - ev->str = strdup(h->cursor->ev.str); + return -1; + ev->str = Strdup(h->cursor->ev.str); ev->num = h->cursor->ev.num; history_def_delete(h, ev, h->cursor); - return (0); + return 0; } @@ -434,7 +435,7 @@ /* ARGSUSED */ private void history_def_delete(history_t *h, - HistEvent *ev __unused, hentry_t *hp) + TYPE(HistEvent) *ev __attribute__((__unused__)), hentry_t *hp) { HistEventPrivate *evp = (void *)&hp->ev; if (hp == &h->list) @@ -446,7 +447,7 @@ } hp->prev->next = hp->next; hp->next->prev = hp->prev; - h_free((ptr_t) evp->str); + h_free(evp->str); h_free(hp); h->cur--; } @@ -456,29 +457,31 @@ * Insert element with string str in the h list */ private int -history_def_insert(history_t *h, HistEvent *ev, const char *str) +history_def_insert(history_t *h, TYPE(HistEvent) *ev, const Char *str) { + hentry_t *c; - h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t)); - if (h->cursor == NULL) + c = h_malloc(sizeof(*c)); + if (c == NULL) goto oomem; - if ((h->cursor->ev.str = h_strdup(str)) == NULL) { - h_free((ptr_t)h->cursor); + if ((c->ev.str = h_strdup(str)) == NULL) { + h_free(c); goto oomem; } - h->cursor->data = NULL; - h->cursor->ev.num = ++h->eventid; - h->cursor->next = h->list.next; - h->cursor->prev = &h->list; - h->list.next->prev = h->cursor; - h->list.next = h->cursor; + c->data = NULL; + c->ev.num = ++h->eventid; + c->next = h->list.next; + c->prev = &h->list; + h->list.next->prev = c; + h->list.next = c; h->cur++; + h->cursor = c; - *ev = h->cursor->ev; - return (0); + *ev = c->ev; + return 0; oomem: he_seterrev(ev, _HE_MALLOC_FAILED); - return (-1); + return -1; } @@ -486,16 +489,16 @@ * Default function to enter an item in the history */ private int -history_def_enter(ptr_t p, HistEvent *ev, const char *str) +history_def_enter(void *p, TYPE(HistEvent) *ev, const Char *str) { history_t *h = (history_t *) p; if ((h->flags & H_UNIQUE) != 0 && h->list.next != &h->list && - strcmp(h->list.next->ev.str, str) == 0) - return (0); + Strcmp(h->list.next->ev.str, str) == 0) + return 0; if (history_def_insert(h, ev, str) == -1) - return (-1); /* error, keep error message */ + return -1; /* error, keep error message */ /* * Always keep at least one entry. @@ -504,7 +507,7 @@ while (h->cur > h->max && h->cur > 0) history_def_delete(h, ev, h->list.prev); - return (1); + return 1; } @@ -513,9 +516,9 @@ */ /* ARGSUSED */ private int -history_def_init(ptr_t *p, HistEvent *ev __unused, int n) +history_def_init(void **p, TYPE(HistEvent) *ev __attribute__((__unused__)), int n) { - history_t *h = (history_t *) h_malloc(sizeof(history_t)); + history_t *h = (history_t *) h_malloc(sizeof(*h)); if (h == NULL) return -1; @@ -529,7 +532,7 @@ h->list.ev.num = 0; h->cursor = &h->list; h->flags = 0; - *p = (ptr_t) h; + *p = h; return 0; } @@ -538,12 +541,13 @@ * Default history cleanup function */ private void -history_def_clear(ptr_t p, HistEvent *ev) +history_def_clear(void *p, TYPE(HistEvent) *ev) { history_t *h = (history_t *) p; while (h->list.prev != &h->list) history_def_delete(h, ev, h->list.prev); + h->cursor = &h->list; h->eventid = 0; h->cur = 0; } @@ -556,16 +560,16 @@ /* history_init(): * Initialization function. */ -public History * -history_init(void) +public TYPE(History) * +FUN(history,init)(void) { - HistEvent ev; - History *h = (History *) h_malloc(sizeof(History)); + TYPE(HistEvent) ev; + TYPE(History) *h = (TYPE(History) *) h_malloc(sizeof(*h)); if (h == NULL) return NULL; if (history_def_init(&h->h_ref, &ev, 0) == -1) { - h_free((ptr_t)h); + h_free(h); return NULL; } h->h_ent = -1; @@ -580,7 +584,7 @@ h->h_add = history_def_add; h->h_del = history_def_del; - return (h); + return h; } @@ -588,9 +592,9 @@ * clean up history; */ public void -history_end(History *h) +FUN(history,end)(TYPE(History) *h) { - HistEvent ev; + TYPE(HistEvent) ev; if (h->h_next == history_def_next) history_def_clear(h->h_ref, &ev); @@ -604,19 +608,19 @@ * Set history number of events */ private int -history_setsize(History *h, HistEvent *ev, int num) +history_setsize(TYPE(History) *h, TYPE(HistEvent) *ev, int num) { if (h->h_next != history_def_next) { he_seterrev(ev, _HE_NOT_ALLOWED); - return (-1); + return -1; } if (num < 0) { he_seterrev(ev, _HE_BAD_PARAM); - return (-1); + return -1; } history_def_setsize(h->h_ref, num); - return (0); + return 0; } @@ -624,18 +628,18 @@ * Get number of events currently in history */ private int -history_getsize(History *h, HistEvent *ev) +history_getsize(TYPE(History) *h, TYPE(HistEvent) *ev) { if (h->h_next != history_def_next) { he_seterrev(ev, _HE_NOT_ALLOWED); - return (-1); + return -1; } ev->num = history_def_getsize(h->h_ref); if (ev->num < -1) { he_seterrev(ev, _HE_SIZE_NEGATIVE); - return (-1); + return -1; } - return (0); + return 0; } @@ -643,15 +647,15 @@ * Set if adjacent equal events should not be entered in history. */ private int -history_setunique(History *h, HistEvent *ev, int uni) +history_setunique(TYPE(History) *h, TYPE(HistEvent) *ev, int uni) { if (h->h_next != history_def_next) { he_seterrev(ev, _HE_NOT_ALLOWED); - return (-1); + return -1; } history_def_setunique(h->h_ref, uni); - return (0); + return 0; } @@ -659,14 +663,14 @@ * Get if adjacent equal events should not be entered in history. */ private int -history_getunique(History *h, HistEvent *ev) +history_getunique(TYPE(History) *h, TYPE(HistEvent) *ev) { if (h->h_next != history_def_next) { he_seterrev(ev, _HE_NOT_ALLOWED); - return (-1); + return -1; } ev->num = history_def_getunique(h->h_ref); - return (0); + return 0; } @@ -674,9 +678,9 @@ * Set history functions */ private int -history_set_fun(History *h, History *nh) +history_set_fun(TYPE(History) *h, TYPE(History) *nh) { - HistEvent ev; + TYPE(HistEvent) ev; if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL || nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == NULL || @@ -683,7 +687,8 @@ nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL || nh->h_del == NULL || nh->h_ref == NULL) { if (h->h_next != history_def_next) { - history_def_init(&h->h_ref, &ev, 0); + if (history_def_init(&h->h_ref, &ev, 0) == -1) + return -1; h->h_first = history_def_first; h->h_next = history_def_next; h->h_last = history_def_last; @@ -695,7 +700,7 @@ h->h_add = history_def_add; h->h_del = history_def_del; } - return (-1); + return -1; } if (h->h_next == history_def_next) history_def_clear(h->h_ref, &ev); @@ -712,15 +717,15 @@ h->h_add = nh->h_add; h->h_del = nh->h_del; - return (0); + return 0; } /* history_load(): - * History load function + * TYPE(History) load function */ private int -history_load(History *h, const char *fname) +history_load(TYPE(History) *h, const char *fname) { FILE *fp; char *line; @@ -727,10 +732,13 @@ size_t sz, max_size; char *ptr; int i = -1; - HistEvent ev; + TYPE(HistEvent) ev; +#ifdef WIDECHAR + static ct_buffer_t conv; +#endif if ((fp = fopen(fname, "r")) == NULL) - return (i); + return i; if ((line = fgetln(fp, &sz)) == NULL) goto done; @@ -738,7 +746,7 @@ if (strncmp(line, hist_cookie, sz) != 0) goto done; - ptr = h_malloc(max_size = 1024); + ptr = h_malloc((max_size = 1024) * sizeof(*ptr)); if (ptr == NULL) goto done; for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) { @@ -751,8 +759,8 @@ if (max_size < sz) { char *nptr; - max_size = (sz + 1024) & ~1023; - nptr = h_realloc(ptr, max_size); + max_size = (sz + 1024) & (size_t)~1023; + nptr = h_realloc(ptr, max_size * sizeof(*ptr)); if (nptr == NULL) { i = -1; goto oomem; @@ -761,49 +769,54 @@ } (void) strunvis(ptr, line); line[sz] = c; - if (HENTER(h, &ev, ptr) == -1) { + if (HENTER(h, &ev, ct_decode_string(ptr, &conv)) == -1) { i = -1; goto oomem; } } oomem: - h_free((ptr_t)ptr); + h_free(ptr); done: (void) fclose(fp); - return (i); + return i; } /* history_save(): - * History save function + * TYPE(History) save function */ private int -history_save(History *h, const char *fname) +history_save(TYPE(History) *h, const char *fname) { FILE *fp; - HistEvent ev; + TYPE(HistEvent) ev; int i = -1, retval; size_t len, max_size; char *ptr; + const char *str; +#ifdef WIDECHAR + static ct_buffer_t conv; +#endif if ((fp = fopen(fname, "w")) == NULL) - return (-1); + return -1; if (fchmod(fileno(fp), S_IRUSR|S_IWUSR) == -1) goto done; if (fputs(hist_cookie, fp) == EOF) goto done; - ptr = h_malloc(max_size = 1024); + ptr = h_malloc((max_size = 1024) * sizeof(*ptr)); if (ptr == NULL) goto done; for (i = 0, retval = HLAST(h, &ev); retval != -1; retval = HPREV(h, &ev), i++) { - len = strlen(ev.str) * 4; + str = ct_encode_string(ev.str, &conv); + len = strlen(str) * 4; if (len >= max_size) { char *nptr; - max_size = (len + 1024) & ~1023; - nptr = h_realloc(ptr, max_size); + max_size = (len + 1024) & (size_t)~1023; + nptr = h_realloc(ptr, max_size * sizeof(*ptr)); if (nptr == NULL) { i = -1; goto oomem; @@ -810,14 +823,14 @@ } ptr = nptr; } - (void) strvis(ptr, ev.str, VIS_WHITE); + (void) strvis(ptr, str, VIS_WHITE); (void) fprintf(fp, "%s\n", ptr); } oomem: - h_free((ptr_t)ptr); + h_free(ptr); done: (void) fclose(fp); - return (i); + return i; } @@ -825,33 +838,33 @@ * Find the previous event, with number given */ private int -history_prev_event(History *h, HistEvent *ev, int num) +history_prev_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num) { int retval; for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) if (ev->num == num) - return (0); + return 0; he_seterrev(ev, _HE_NOT_FOUND); - return (-1); + return -1; } private int -history_next_evdata(History *h, HistEvent *ev, int num, void **d) +history_next_evdata(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d) { int retval; for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) - if (num-- <= 0) { + if (ev->num == num) { if (d) *d = ((history_t *)h->h_ref)->cursor->data; - return (0); + return 0; } he_seterrev(ev, _HE_NOT_FOUND); - return (-1); + return -1; } @@ -859,16 +872,16 @@ * Find the next event, with number given */ private int -history_next_event(History *h, HistEvent *ev, int num) +history_next_event(TYPE(History) *h, TYPE(HistEvent) *ev, int num) { int retval; for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev)) if (ev->num == num) - return (0); + return 0; he_seterrev(ev, _HE_NOT_FOUND); - return (-1); + return -1; } @@ -876,17 +889,17 @@ * Find the previous event beginning with string */ private int -history_prev_string(History *h, HistEvent *ev, const char *str) +history_prev_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str) { - size_t len = strlen(str); + size_t len = Strlen(str); int retval; for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev)) - if (strncmp(str, ev->str, len) == 0) - return (0); + if (Strncmp(str, ev->str, len) == 0) + return 0; he_seterrev(ev, _HE_NOT_FOUND); - return (-1); + return -1; } @@ -894,17 +907,17 @@ * Find the next event beginning with string */ private int -history_next_string(History *h, HistEvent *ev, const char *str) +history_next_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str) { - size_t len = strlen(str); + size_t len = Strlen(str); int retval; for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) - if (strncmp(str, ev->str, len) == 0) - return (0); + if (Strncmp(str, ev->str, len) == 0) + return 0; he_seterrev(ev, _HE_NOT_FOUND); - return (-1); + return -1; } @@ -912,10 +925,10 @@ * User interface to history functions. */ int -history(History *h, HistEvent *ev, int fun, ...) +FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...) { va_list va; - const char *str; + const Char *str; int retval; va_start(va, fun); @@ -940,7 +953,7 @@ break; case H_ADD: - str = va_arg(va, const char *); + str = va_arg(va, const Char *); retval = HADD(h, ev, str); break; @@ -949,13 +962,13 @@ break; case H_ENTER: - str = va_arg(va, const char *); + str = va_arg(va, const Char *); if ((retval = HENTER(h, ev, str)) != -1) h->h_ent = ev->num; break; case H_APPEND: - str = va_arg(va, const char *); + str = va_arg(va, const Char *); if ((retval = HSET(h, ev, h->h_ent)) != -1) retval = HADD(h, ev, str); break; @@ -1010,18 +1023,18 @@ break; case H_PREV_STR: - retval = history_prev_string(h, ev, va_arg(va, const char *)); + retval = history_prev_string(h, ev, va_arg(va, const Char *)); break; case H_NEXT_STR: - retval = history_next_string(h, ev, va_arg(va, const char *)); + retval = history_next_string(h, ev, va_arg(va, const Char *)); break; case H_FUNC: { - History hf; + TYPE(History) hf; - hf.h_ref = va_arg(va, ptr_t); + hf.h_ref = va_arg(va, void *); h->h_ent = -1; hf.h_first = va_arg(va, history_gfun_t); hf.h_next = va_arg(va, history_gfun_t); @@ -1040,7 +1053,7 @@ } case H_END: - history_end(h); + FUN(history,end)(h); retval = 0; break; @@ -1062,10 +1075,10 @@ case H_REPLACE: /* only use after H_NEXT_EVDATA */ { - const char *line = va_arg(va, const char *); + const Char *line = va_arg(va, const Char *); void *d = va_arg(va, void *); - const char *s; - if(!line || !(s = strdup(line))) { + const Char *s; + if(!line || !(s = Strdup(line))) { retval = -1; break; } Index: lib/libedit/keymacro.c =================================================================== --- lib/libedit/keymacro.c (revision 258914) +++ lib/libedit/keymacro.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: keymacro.c,v 1.7 2011/08/16 16:25:15 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: key.c,v 1.20 2009/02/15 21:55:23 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -39,12 +40,13 @@ __FBSDID("$FreeBSD$"); /* - * key.c: This module contains the procedures for maintaining - * the extended-key map. + * keymacro.c: This module contains the procedures for maintaining + * the extended-key map. * * An extended-key (key) is a sequence of keystrokes introduced * 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 * (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE). * @@ -51,8 +53,8 @@ * Warning: * If key is a substr of some other keys, then the longer * 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 - * definitions to be lost. + * are in el->el_keymacro.map, adding the key "abc" will cause + * the first two definitions to be lost. * * Restrictions: * ------------- @@ -65,102 +67,104 @@ #include "el.h" /* - * The Nodes of the el->el_key.map. The el->el_key.map is a linked list - * of these node elements + * The Nodes of the el->el_keymacro.map. The el->el_keymacro.map is a + * linked list of these node elements */ -struct key_node_t { - char ch; /* single character of key */ - int type; /* node type */ - key_value_t val; /* command code or pointer to str, */ +struct keymacro_node_t { + Char ch; /* single character of key */ + int type; /* node type */ + keymacro_value_t val; /* command code or pointer to str, */ /* if this is a leaf */ - struct key_node_t *next; /* ptr to next char of this key */ - struct key_node_t *sibling; /* ptr to another key with same prefix*/ + struct keymacro_node_t *next; /* ptr to next char of this key */ + struct keymacro_node_t *sibling;/* ptr to another key with same prefix*/ }; -private int node_trav(EditLine *, key_node_t *, char *, - key_value_t *); -private int node__try(EditLine *, key_node_t *, const char *, - key_value_t *, int); -private key_node_t *node__get(int); -private void node__free(key_node_t *); -private void node__put(EditLine *, key_node_t *); -private int node__delete(EditLine *, key_node_t **, const char *); -private int node_lookup(EditLine *, const char *, key_node_t *, - size_t); -private int node_enum(EditLine *, key_node_t *, size_t); +private int node_trav(EditLine *, keymacro_node_t *, Char *, + keymacro_value_t *); +private int node__try(EditLine *, keymacro_node_t *, const Char *, + keymacro_value_t *, int); +private keymacro_node_t *node__get(Int); +private void node__free(keymacro_node_t *); +private void node__put(EditLine *, keymacro_node_t *); +private int node__delete(EditLine *, keymacro_node_t **, + const Char *); +private int node_lookup(EditLine *, const Char *, + keymacro_node_t *, size_t); +private int node_enum(EditLine *, keymacro_node_t *, size_t); #define KEY_BUFSIZ EL_BUFSIZ -/* key_init(): +/* keymacro_init(): * Initialize the key maps */ protected int -key_init(EditLine *el) +keymacro_init(EditLine *el) { - el->el_key.buf = (char *) el_malloc(KEY_BUFSIZ); - if (el->el_key.buf == NULL) - return (-1); - el->el_key.map = NULL; - key_reset(el); - return (0); + el->el_keymacro.buf = el_malloc(KEY_BUFSIZ * + sizeof(*el->el_keymacro.buf)); + if (el->el_keymacro.buf == NULL) + return -1; + el->el_keymacro.map = NULL; + keymacro_reset(el); + return 0; } -/* key_end(): +/* keymacro_end(): * Free the key maps */ protected void -key_end(EditLine *el) +keymacro_end(EditLine *el) { - el_free((ptr_t) el->el_key.buf); - el->el_key.buf = NULL; - node__free(el->el_key.map); + el_free(el->el_keymacro.buf); + el->el_keymacro.buf = NULL; + node__free(el->el_keymacro.map); } -/* key_map_cmd(): +/* keymacro_map_cmd(): * Associate cmd with a key value */ -protected key_value_t * -key_map_cmd(EditLine *el, int cmd) +protected keymacro_value_t * +keymacro_map_cmd(EditLine *el, int cmd) { - el->el_key.val.cmd = (el_action_t) cmd; - return (&el->el_key.val); + el->el_keymacro.val.cmd = (el_action_t) cmd; + return &el->el_keymacro.val; } -/* key_map_str(): +/* keymacro_map_str(): * Associate str with a key value */ -protected key_value_t * -key_map_str(EditLine *el, char *str) +protected keymacro_value_t * +keymacro_map_str(EditLine *el, Char *str) { - el->el_key.val.str = str; - return (&el->el_key.val); + el->el_keymacro.val.str = str; + return &el->el_keymacro.val; } -/* key_reset(): - * Takes all nodes on el->el_key.map and puts them on free list. Then - * initializes el->el_key.map with arrow keys +/* keymacro_reset(): + * Takes all nodes on el->el_keymacro.map and puts them on free list. + * Then initializes el->el_keymacro.map with arrow keys * [Always bind the ansi arrow keys?] */ protected void -key_reset(EditLine *el) +keymacro_reset(EditLine *el) { - node__put(el, el->el_key.map); - el->el_key.map = NULL; + node__put(el, el->el_keymacro.map); + el->el_keymacro.map = NULL; return; } -/* key_get(): - * Calls the recursive function with entry point el->el_key.map +/* keymacro_get(): + * Calls the recursive function with entry point el->el_keymacro.map * Looks up *ch in map and then reads characters until a * complete match is found or a mismatch occurs. Returns the * type of the match found (XK_STR, XK_CMD, or XK_EXE). @@ -168,98 +172,101 @@ * The last character read is returned in *ch. */ 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(): - * Adds key to the el->el_key.map and associates the value in val with it. - * If key is already is in el->el_key.map, the new code is applied to the - * existing key. Ntype specifies if code is a command, an - * out str or a unix command. +/* keymacro_add(): + * Adds key to the el->el_keymacro.map and associates the value in + * val with it. If key is already is in el->el_keymacro.map, the new + * code is applied to the existing key. Ntype specifies if code is a + * command, an out str or a unix command. */ 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') { (void) fprintf(el->el_errfile, - "key_add: Null extended-key not allowed.\n"); + "keymacro_add: Null extended-key not allowed.\n"); return; } if (ntype == XK_CMD && val->cmd == ED_SEQUENCE_LEAD_IN) { (void) fprintf(el->el_errfile, - "key_add: sequence-lead-in command not allowed\n"); + "keymacro_add: sequence-lead-in command not allowed\n"); 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] */ - el->el_key.map = node__get(key[0]); + el->el_keymacro.map = node__get(key[0]); /* it is properly initialized */ - /* Now recurse through el->el_key.map */ - (void) node__try(el, el->el_key.map, key, val, ntype); + /* Now recurse through el->el_keymacro.map */ + (void) node__try(el, el->el_keymacro.map, key, val, ntype); return; } -/* key_clear(): +/* keymacro_clear(): * */ 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) && ((map == el->el_map.key && el->el_map.alt[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN) || (map == el->el_map.alt && el->el_map.key[(unsigned char)*in] != ED_SEQUENCE_LEAD_IN))) - (void) key_delete(el, in); + (void) keymacro_delete(el, in); } -/* key_delete(): +/* keymacro_delete(): * Delete the key and all longer keys staring with key, if * they exists. */ protected int -key_delete(EditLine *el, const char *key) +keymacro_delete(EditLine *el, const Char *key) { if (key[0] == '\0') { (void) fprintf(el->el_errfile, - "key_delete: Null extended-key not allowed.\n"); - return (-1); + "keymacro_delete: Null extended-key not allowed.\n"); + return -1; } - if (el->el_key.map == NULL) - return (0); + if (el->el_keymacro.map == NULL) + return 0; - (void) node__delete(el, &el->el_key.map, key); - return (0); + (void) node__delete(el, &el->el_keymacro.map, key); + return 0; } -/* key_print(): +/* keymacro_print(): * 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 -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 */ - if (el->el_key.map == NULL && *key == 0) + /* do nothing if el->el_keymacro.map is empty and null key specified */ + if (el->el_keymacro.map == NULL && *key == 0) return; - el->el_key.buf[0] = '"'; - if (node_lookup(el, key, el->el_key.map, 1) <= -1) + el->el_keymacro.buf[0] = '"'; + if (node_lookup(el, key, el->el_keymacro.map, (size_t)1) <= -1) /* key is not bound */ - (void) fprintf(el->el_errfile, "Unbound extended key \"%s\"\n", - key); + (void) fprintf(el->el_errfile, "Unbound extended key \"" FSTR + "\"\n", key); return; } @@ -269,7 +276,7 @@ * found. May read in more characters. */ private int -node_trav(EditLine *el, key_node_t *ptr, char *ch, key_value_t *val) +node_trav(EditLine *el, keymacro_node_t *ptr, Char *ch, keymacro_value_t *val) { if (ptr->ch == *ch) { @@ -276,27 +283,27 @@ /* match found */ if (ptr->next) { /* key not complete so get next char */ - if (el_getc(el, ch) != 1) { /* if EOF or error */ + if (FUN(el,getc)(el, ch) != 1) {/* if EOF or error */ val->cmd = ED_END_OF_FILE; - return (XK_CMD); + return XK_CMD; /* 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 { *val = ptr->val; if (ptr->type != XK_CMD) *ch = '\0'; - return (ptr->type); + return ptr->type; } } else { /* no match found here */ if (ptr->sibling) { /* try next sibling */ - return (node_trav(el, ptr->sibling, ch, val)); + return node_trav(el, ptr->sibling, ch, val); } else { /* no next sibling -- mismatch */ val->str = NULL; - return (XK_STR); + return XK_STR; } } } @@ -306,11 +313,12 @@ * Find a node that matches *str or allocate a new one */ private int -node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int ntype) +node__try(EditLine *el, keymacro_node_t *ptr, const Char *str, + keymacro_value_t *val, int ntype) { if (ptr->ch != *str) { - key_node_t *xm; + keymacro_node_t *xm; for (xm = ptr; xm->sibling != NULL; xm = xm->sibling) if (xm->sibling->ch == *str) @@ -333,7 +341,7 @@ case XK_STR: case XK_EXE: if (ptr->val.str) - el_free((ptr_t) ptr->val.str); + el_free(ptr->val.str); break; default: EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", @@ -347,7 +355,7 @@ break; case XK_STR: case XK_EXE: - if ((ptr->val.str = el_strdup(val->str)) == NULL) + if ((ptr->val.str = Strdup(val->str)) == NULL) return -1; break; default: @@ -360,7 +368,7 @@ ptr->next = node__get(*str); /* setup new node */ (void) node__try(el, ptr->next, str, val, ntype); } - return (0); + return 0; } @@ -368,21 +376,21 @@ * Delete node that matches str */ 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; - key_node_t *prev_ptr = NULL; + keymacro_node_t *ptr; + keymacro_node_t *prev_ptr = NULL; ptr = *inptr; if (ptr->ch != *str) { - key_node_t *xm; + keymacro_node_t *xm; for (xm = ptr; xm->sibling != NULL; xm = xm->sibling) if (xm->sibling->ch == *str) break; if (xm->sibling == NULL) - return (0); + return 0; prev_ptr = xm; ptr = xm->sibling; } @@ -394,11 +402,11 @@ prev_ptr->sibling = ptr->sibling; ptr->sibling = NULL; node__put(el, ptr); - return (1); + return 1; } else if (ptr->next != NULL && node__delete(el, &ptr->next, str) == 1) { if (ptr->next != NULL) - return (0); + return 0; if (prev_ptr == NULL) *inptr = ptr->sibling; else @@ -405,9 +413,9 @@ prev_ptr->sibling = ptr->sibling; ptr->sibling = NULL; node__put(el, ptr); - return (1); + return 1; } else { - return (0); + return 0; } } @@ -416,7 +424,7 @@ * Puts a tree of nodes onto free list using free(3). */ private void -node__put(EditLine *el, key_node_t *ptr) +node__put(EditLine *el, keymacro_node_t *ptr) { if (ptr == NULL) return; @@ -434,25 +442,25 @@ case XK_EXE: case XK_STR: if (ptr->val.str != NULL) - el_free((ptr_t) ptr->val.str); + el_free(ptr->val.str); break; default: EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ptr->type)); break; } - el_free((ptr_t) ptr); + el_free(ptr); } /* node__get(): - * Returns pointer to a key_node_t for ch. + * Returns pointer to a keymacro_node_t for ch. */ -private key_node_t * -node__get(int ch) +private keymacro_node_t * +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) return NULL; ptr->ch = ch; @@ -460,17 +468,17 @@ ptr->val.str = NULL; ptr->next = NULL; ptr->sibling = NULL; - return (ptr); + return ptr; } private void -node__free(key_node_t *k) +node__free(keymacro_node_t *k) { if (k == NULL) return; node__free(k->sibling); node__free(k->next); - el_free((ptr_t) k); + el_free(k); } /* node_lookup(): @@ -478,38 +486,40 @@ * Print if last node */ private int -node_lookup(EditLine *el, const char *str, key_node_t *ptr, size_t cnt) +node_lookup(EditLine *el, const Char *str, keymacro_node_t *ptr, size_t cnt) { - size_t ncnt; + ssize_t used; 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. */ (void) node_enum(el, ptr, cnt); - return (0); + return 0; } 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) { /* match found */ - ncnt = key__decode_char(el->el_key.buf, - (size_t)KEY_BUFSIZ, cnt, - (unsigned char) ptr->ch); + used = ct_visual_char(el->el_keymacro.buf + cnt, + KEY_BUFSIZ - cnt, ptr->ch); + if (used == -1) + return -1; /* ran out of buffer space */ if (ptr->next != NULL) /* not yet at leaf */ return (node_lookup(el, str + 1, ptr->next, - ncnt + 1)); + (size_t)used + cnt)); else { /* next node is null so key should be complete */ if (str[1] == 0) { - el->el_key.buf[ncnt + 1] = '"'; - el->el_key.buf[ncnt + 2] = '\0'; - key_kprint(el, el->el_key.buf, + size_t px = cnt + (size_t)used; + el->el_keymacro.buf[px] = '"'; + el->el_keymacro.buf[px + 1] = '\0'; + keymacro_kprint(el, el->el_keymacro.buf, &ptr->val, ptr->type); - return (0); + return 0; } else - return (-1); + return -1; /* mismatch -- str still has chars */ } } else { @@ -518,7 +528,7 @@ return (node_lookup(el, str, ptr->sibling, cnt)); else - return (-1); + return -1; } } } @@ -528,17 +538,18 @@ * Traverse the node printing the characters it is bound in buffer */ private int -node_enum(EditLine *el, key_node_t *ptr, size_t cnt) +node_enum(EditLine *el, keymacro_node_t *ptr, size_t cnt) { - size_t ncnt; + ssize_t used; if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */ - el->el_key.buf[++cnt] = '"'; - el->el_key.buf[++cnt] = '\0'; + el->el_keymacro.buf[++cnt] = '"'; + el->el_keymacro.buf[++cnt] = '\0'; (void) fprintf(el->el_errfile, "Some extended keys too long for internal print buffer"); - (void) fprintf(el->el_errfile, " \"%s...\"\n", el->el_key.buf); - return (0); + (void) fprintf(el->el_errfile, " \"" FSTR "...\"\n", + el->el_keymacro.buf); + return 0; } if (ptr == NULL) { #ifdef DEBUG_EDIT @@ -545,32 +556,32 @@ (void) fprintf(el->el_errfile, "node_enum: BUG!! Null ptr passed\n!"); #endif - return (-1); + return -1; } /* put this char at end of str */ - ncnt = key__decode_char(el->el_key.buf, (size_t)KEY_BUFSIZ, cnt, - (unsigned char)ptr->ch); + used = ct_visual_char(el->el_keymacro.buf + cnt, KEY_BUFSIZ - cnt, + ptr->ch); if (ptr->next == NULL) { /* print this key and function */ - el->el_key.buf[ncnt + 1] = '"'; - el->el_key.buf[ncnt + 2] = '\0'; - key_kprint(el, el->el_key.buf, &ptr->val, ptr->type); + el->el_keymacro.buf[cnt + (size_t)used ] = '"'; + el->el_keymacro.buf[cnt + (size_t)used + 1] = '\0'; + keymacro_kprint(el, el->el_keymacro.buf, &ptr->val, ptr->type); } 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 */ if (ptr->sibling) (void) node_enum(el, ptr->sibling, cnt); - return (0); + return 0; } -/* key_kprint(): +/* keymacro_kprint(): * Print the specified key and its associated * function specified by val */ 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; char unparsbuf[EL_BUFSIZ]; @@ -580,16 +591,19 @@ switch (ntype) { case XK_STR: case XK_EXE: - (void) key__decode_str(val->str, unparsbuf, + (void) keymacro__decode_str(val->str, unparsbuf, sizeof(unparsbuf), ntype == XK_STR ? "\"\"" : "[]"); - (void) fprintf(el->el_outfile, fmt, key, unparsbuf); + (void) fprintf(el->el_outfile, fmt, + ct_encode_string(key, &el->el_scratch), unparsbuf); break; case XK_CMD: for (fp = el->el_map.help; fp->name; fp++) if (val->cmd == fp->func) { + ct_wcstombs(unparsbuf, fp->name, sizeof(unparsbuf)); + unparsbuf[sizeof(unparsbuf) -1] = '\0'; (void) fprintf(el->el_outfile, fmt, - key, fp->name); + ct_encode_string(key, &el->el_scratch), unparsbuf); break; } #ifdef DEBUG_KEY @@ -604,7 +618,8 @@ break; } else - (void) fprintf(el->el_outfile, fmt, key, "no input"); + (void) fprintf(el->el_outfile, fmt, ct_encode_string(key, + &el->el_scratch), "no input"); } @@ -613,54 +628,14 @@ *b++ = c; \ else \ b++ -/* key__decode_char(): - * Put a printable form of char in buf. - */ -protected size_t -key__decode_char(char *buf, size_t cnt, size_t off, int ch) -{ - char *sb = buf + off; - char *eb = buf + cnt; - char *b = sb; - - ch = (unsigned char)ch; - if (ch == 0) { - ADDC('^'); - ADDC('@'); - return (int)(b - sb); - } - if (iscntrl(ch)) { - ADDC('^'); - if (ch == '\177') - ADDC('?'); - else - ADDC(toascii(ch) | 0100); - } else if (ch == '^') { - ADDC('\\'); - ADDC('^'); - } else if (ch == '\\') { - ADDC('\\'); - ADDC('\\'); - } else if (ch == ' ' || (isprint(ch) && !isspace(ch))) { - ADDC(ch); - } else { - ADDC('\\'); - ADDC((((unsigned int) ch >> 6) & 7) + '0'); - ADDC((((unsigned int) ch >> 3) & 7) + '0'); - ADDC((ch & 7) + '0'); - } - return (size_t)(b - sb); -} - - -/* key__decode_str(): +/* keymacro__decode_str(): * Make a printable version of the ey */ protected size_t -key__decode_str(const char *str, char *buf, size_t len, const char *sep) +keymacro__decode_str(const Char *str, char *buf, size_t len, const char *sep) { char *b = buf, *eb = b + len; - const char *p; + const Char *p; b = buf; if (sep[0] != '\0') { @@ -669,36 +644,24 @@ if (*str == '\0') { ADDC('^'); ADDC('@'); - if (sep[0] != '\0' && sep[1] != '\0') { - ADDC(sep[1]); - } - goto done; + goto add_endsep; } for (p = str; *p != 0; p++) { - if (iscntrl((unsigned char) *p)) { - ADDC('^'); - if (*p == '\177') { - ADDC('?'); - } else { - ADDC(toascii(*p) | 0100); - } - } else if (*p == '^' || *p == '\\') { - ADDC('\\'); - ADDC(*p); - } else if (*p == ' ' || (isprint((unsigned char) *p) && - !isspace((unsigned char) *p))) { - ADDC(*p); - } else { - ADDC('\\'); - ADDC((((unsigned int) *p >> 6) & 7) + '0'); - ADDC((((unsigned int) *p >> 3) & 7) + '0'); - ADDC((*p & 7) + '0'); + Char dbuf[VISUAL_WIDTH_MAX]; + Char *p2 = dbuf; + ssize_t l = ct_visual_char(dbuf, VISUAL_WIDTH_MAX, *p); + while (l-- > 0) { + ssize_t n = ct_encode_char(b, (size_t)(eb - b), *p2++); + if (n == -1) /* ran out of space */ + goto add_endsep; + else + b += n; } } +add_endsep: if (sep[0] != '\0' && sep[1] != '\0') { ADDC(sep[1]); } -done: ADDC('\0'); if ((size_t)(b - buf) >= len) buf[len - 1] = '\0'; Index: lib/libedit/keymacro.h =================================================================== --- lib/libedit/keymacro.h (revision 258914) +++ lib/libedit/keymacro.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: keymacro.h,v 1.2 2011/07/28 03:44:36 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,28 +32,27 @@ * SUCH DAMAGE. * * @(#)key.h 8.1 (Berkeley) 6/4/93 - * $NetBSD: key.h,v 1.10 2006/03/23 20:22:51 christos Exp $ * $FreeBSD$ */ /* - * el.key.h: Key macro header + * el.keymacro.h: Key macro header */ -#ifndef _h_el_key -#define _h_el_key +#ifndef _h_el_keymacro +#define _h_el_keymacro -typedef union key_value_t { +typedef union keymacro_value_t { el_action_t cmd; /* If it is a command the # */ - char *str; /* If it is a string... */ -} key_value_t; + Char *str; /* If it is a string... */ +} keymacro_value_t; -typedef struct key_node_t key_node_t; +typedef struct keymacro_node_t keymacro_node_t; -typedef struct el_key_t { - char *buf; /* Key print buffer */ - key_node_t *map; /* Key map */ - key_value_t val; /* Local conversion buffer */ -} el_key_t; +typedef struct el_keymacromacro_t { + Char *buf; /* Key print buffer */ + keymacro_node_t *map; /* Key map */ + keymacro_value_t val; /* Local conversion buffer */ +} el_keymacro_t; #define XK_CMD 0 #define XK_STR 1 @@ -58,26 +59,19 @@ #define XK_NOD 2 #define XK_EXE 3 -#include - -#undef key_end -#undef key_clear -#undef key_print - -protected int key_init(EditLine *); -protected void key_end(EditLine *); -protected key_value_t *key_map_cmd(EditLine *, int); -protected key_value_t *key_map_str(EditLine *, char *); -protected void key_reset(EditLine *); -protected int key_get(EditLine *, char *, key_value_t *); -protected void key_add(EditLine *, const char *, key_value_t *, int); -protected void key_clear(EditLine *, el_action_t *, const char *); -protected int key_delete(EditLine *, const char *); -protected void key_print(EditLine *, const char *); -protected void key_kprint(EditLine *, const char *, key_value_t *, +protected int keymacro_init(EditLine *); +protected void keymacro_end(EditLine *); +protected keymacro_value_t *keymacro_map_cmd(EditLine *, int); +protected keymacro_value_t *keymacro_map_str(EditLine *, Char *); +protected void keymacro_reset(EditLine *); +protected int keymacro_get(EditLine *, Char *, keymacro_value_t *); +protected void keymacro_add(EditLine *, const Char *, keymacro_value_t *, int); +protected void keymacro_clear(EditLine *, el_action_t *, const Char *); +protected int keymacro_delete(EditLine *, const Char *); +protected void keymacro_print(EditLine *, const Char *); +protected void keymacro_kprint(EditLine *, const Char *, keymacro_value_t *, int); -protected size_t key__decode_str(const char *, char *, size_t, +protected size_t keymacro__decode_str(const Char *, char *, size_t, const char *); -protected size_t key__decode_char(char *, size_t, size_t, int); -#endif /* _h_el_key */ +#endif /* _h_el_keymacro */ Index: lib/libedit/makelist =================================================================== --- lib/libedit/makelist (revision 258914) +++ lib/libedit/makelist (working copy) @@ -1,5 +1,5 @@ #!/bin/sh - -# $NetBSD: makelist,v 1.11 2005/10/22 16:45:03 christos Exp $ +# $NetBSD: makelist,v 1.18 2012/03/21 05:34:54 matt Exp $ # $FreeBSD$ # # Copyright (c) 1992, 1993 @@ -37,7 +37,7 @@ # makelist.sh: Automatically generate header files... AWK=awk -USAGE="usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m " +USAGE="Usage: $0 -n|-h|-e|-fc|-fh|-bc|-bh|-m " if [ "x$1" = "x" ] then @@ -54,6 +54,15 @@ # generate foo.h file from foo.c # +-n) + cat << _EOF +#include "config.h" +#undef WIDECHAR +#define NARROWCHAR +#include "${FILES}" +_EOF + ;; + -h) set - `echo $FILES | sed -e 's/\\./_/g'` hdr="_h_`basename $1`" @@ -70,7 +79,7 @@ # XXX: need a space between name and prototype so that -fc and -fh # parsing is much easier # - printf("protected el_action_t\t%s (EditLine *, int);\n", name); + printf("protected el_action_t\t%s (EditLine *, Int);\n", name); } } END { @@ -84,7 +93,8 @@ cat $FILES | $AWK ' BEGIN { printf("/* Automatically generated file, do not edit */\n"); - printf("#include \"sys.h\"\n#include \"el.h\"\n"); + printf("#include \"config.h\"\n#include \"el.h\"\n"); + printf("#include \"chartype.h\"\n"); printf("private const struct el_bindings_t el_func_help[] = {\n"); low = "abcdefghijklmnopqrstuvwxyz_"; high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"; @@ -105,22 +115,22 @@ fname = fname s; } - printf(" { %-30.30s %-30.30s\n","\"" fname "\",", uname ","); + printf(" { %-30.30s %-30.30s\n","STR(\"" fname "\"),", uname ","); ok = 1; } } /^ \*/ { if (ok) { - printf(" \""); + printf(" STR(\""); for (i = 2; i < NF; i++) printf("%s ", $i); - printf("%s\" },\n", $i); + printf("%s\") },\n", $i); ok = 0; } } END { printf("};\n"); - printf("\nprotected const el_bindings_t* help__get()"); + printf("\nprotected const el_bindings_t* help__get(void)"); printf("{ return el_func_help; }\n"); }' ;; @@ -141,7 +151,7 @@ # -fh) cat $FILES | $AWK '/el_action_t/ { print $3 }' | \ - sort | LC_ALL=C tr '[:lower:]' '[:upper:]' | $AWK ' + sort | tr '[:lower:]' '[:upper:]' | $AWK ' BEGIN { printf("/* Automatically generated file, do not edit */\n"); printf("#ifndef _h_fcns_c\n#define _h_fcns_c\n"); @@ -153,7 +163,7 @@ END { printf("#define\t%-30.30s\t%3d\n", "EL_NUM_FCNS", count); - printf("typedef el_action_t (*el_func_t)(EditLine *, int);"); + printf("typedef el_action_t (*el_func_t)(EditLine *, Int);"); printf("\nprotected const el_func_t* func__get(void);\n"); printf("#endif /* _h_fcns_c */\n"); }' @@ -165,7 +175,7 @@ cat $FILES | $AWK '/el_action_t/ { print $3 }' | sort | $AWK ' BEGIN { printf("/* Automatically generated file, do not edit */\n"); - printf("#include \"sys.h\"\n#include \"el.h\"\n"); + printf("#include \"config.h\"\n#include \"el.h\"\n"); printf("private const el_func_t el_func[] = {"); maxlen = 80; needn = 1; @@ -186,7 +196,7 @@ } END { printf("\n};\n"); - printf("\nprotected const el_func_t* func__get() { return el_func; }\n"); + printf("\nprotected const el_func_t* func__get(void) { return el_func; }\n"); }' ;; Index: lib/libedit/map.c =================================================================== --- lib/libedit/map.c (revision 258914) +++ lib/libedit/map.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: map.c,v 1.33 2013/01/01 15:34:02 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: map.c,v 1.24 2006/04/09 01:36:51 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -41,14 +42,11 @@ /* * map.c: Editor function definitions */ -#include "sys.h" #include #include "el.h" -#define N_KEYS 256 - -private void map_print_key(EditLine *, el_action_t *, const char *); -private void map_print_some_keys(EditLine *, el_action_t *, int, int); +private void map_print_key(EditLine *, el_action_t *, const Char *); +private void map_print_some_keys(EditLine *, el_action_t *, Int, Int); private void map_print_all_keys(EditLine *); private void map_init_nls(EditLine *); private void map_init_meta(EditLine *); @@ -903,26 +901,25 @@ EL_ABORT((el->errfile, "Vi insert map incorrect\n")); #endif - el->el_map.alt = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS); + el->el_map.alt = el_malloc(sizeof(*el->el_map.alt) * N_KEYS); if (el->el_map.alt == NULL) - return (-1); - el->el_map.key = (el_action_t *)el_malloc(sizeof(el_action_t) * N_KEYS); + return -1; + el->el_map.key = el_malloc(sizeof(*el->el_map.key) * N_KEYS); if (el->el_map.key == NULL) - return (-1); + return -1; el->el_map.emacs = el_map_emacs; el->el_map.vic = el_map_vi_command; el->el_map.vii = el_map_vi_insert; - el->el_map.help = (el_bindings_t *) el_malloc(sizeof(el_bindings_t) * - EL_NUM_FCNS); + el->el_map.help = el_malloc(sizeof(*el->el_map.help) * EL_NUM_FCNS); if (el->el_map.help == NULL) - return (-1); + return -1; (void) memcpy(el->el_map.help, help__get(), - sizeof(el_bindings_t) * EL_NUM_FCNS); - el->el_map.func = (el_func_t *)el_malloc(sizeof(el_func_t) * - EL_NUM_FCNS); + sizeof(*el->el_map.help) * EL_NUM_FCNS); + el->el_map.func = el_malloc(sizeof(*el->el_map.func) * EL_NUM_FCNS); if (el->el_map.func == NULL) - return (-1); - memcpy(el->el_map.func, func__get(), sizeof(el_func_t) * EL_NUM_FCNS); + return -1; + memcpy(el->el_map.func, func__get(), sizeof(*el->el_map.func) + * EL_NUM_FCNS); el->el_map.nfunc = EL_NUM_FCNS; #ifdef VIDEFAULT @@ -930,7 +927,7 @@ #else map_init_emacs(el); #endif /* VIDEFAULT */ - return (0); + return 0; } @@ -941,16 +938,16 @@ map_end(EditLine *el) { - el_free((ptr_t) el->el_map.alt); + el_free(el->el_map.alt); 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.emacs = NULL; el->el_map.vic = 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_free((ptr_t) el->el_map.func); + el_free(el->el_map.func); el->el_map.func = NULL; } @@ -966,7 +963,7 @@ el_action_t *map = el->el_map.key; for (i = 0200; i <= 0377; i++) - if (isprint(i)) + if (Isprint(i)) map[i] = ED_INSERT; } @@ -977,7 +974,7 @@ private void map_init_meta(EditLine *el) { - char buf[3]; + Char buf[3]; int i; el_action_t *map = el->el_map.key; el_action_t *alt = el->el_map.alt; @@ -995,7 +992,7 @@ } else map = alt; } - buf[0] = (char) i; + buf[0] = (Char) i; buf[2] = 0; for (i = 0200; i <= 0377; i++) switch (map[i]) { @@ -1005,7 +1002,7 @@ break; default: 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; } map[(int) buf[0]] = ED_SEQUENCE_LEAD_IN; @@ -1027,7 +1024,7 @@ el->el_map.type = MAP_VI; el->el_map.current = el->el_map.key; - key_reset(el); + keymacro_reset(el); for (i = 0; i < N_KEYS; i++) { key[i] = vii[i]; @@ -1038,7 +1035,7 @@ map_init_nls(el); tty_bind_char(el, 1); - term_bind_arrow(el); + terminal_bind_arrow(el); } @@ -1049,7 +1046,7 @@ map_init_emacs(EditLine *el) { int i; - char buf[3]; + Char buf[3]; el_action_t *key = el->el_map.key; el_action_t *alt = el->el_map.alt; const el_action_t *emacs = el->el_map.emacs; @@ -1056,7 +1053,7 @@ el->el_map.type = MAP_EMACS; el->el_map.current = el->el_map.key; - key_reset(el); + keymacro_reset(el); for (i = 0; i < N_KEYS; i++) { key[i] = emacs[i]; @@ -1069,10 +1066,10 @@ buf[0] = CONTROL('X'); buf[1] = CONTROL('X'); 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); - term_bind_arrow(el); + terminal_bind_arrow(el); } @@ -1080,18 +1077,18 @@ * Set the editor */ protected int -map_set_editor(EditLine *el, char *editor) +map_set_editor(EditLine *el, Char *editor) { - if (strcmp(editor, "emacs") == 0) { + if (Strcmp(editor, STR("emacs")) == 0) { map_init_emacs(el); - return (0); + return 0; } - if (strcmp(editor, "vi") == 0) { + if (Strcmp(editor, STR("vi")) == 0) { map_init_vi(el); - return (0); + return 0; } - return (-1); + return -1; } @@ -1099,20 +1096,20 @@ * Retrieve the editor */ protected int -map_get_editor(EditLine *el, const char **editor) +map_get_editor(EditLine *el, const Char **editor) { if (editor == NULL) - return (-1); + return -1; switch (el->el_map.type) { case MAP_EMACS: - *editor = "emacs"; - return (0); + *editor = STR("emacs"); + return 0; case MAP_VI: - *editor = "vi"; - return (0); + *editor = STR("vi"); + return 0; } - return (-1); + return -1; } @@ -1120,22 +1117,22 @@ * Print the function description for 1 key */ private void -map_print_key(EditLine *el, el_action_t *map, const char *in) +map_print_key(EditLine *el, el_action_t *map, const Char *in) { char outbuf[EL_BUFSIZ]; el_bindings_t *bp, *ep; 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]; for (bp = el->el_map.help; bp < ep; bp++) if (bp->func == map[(unsigned char) *in]) { (void) fprintf(el->el_outfile, - "%s\t->\t%s\n", outbuf, bp->name); + "%s\t->\t" FSTR "\n", outbuf, bp->name); return; } } else - key_print(el, in); + keymacro_print(el, in); } @@ -1143,10 +1140,10 @@ * Print keys from first to last */ private void -map_print_some_keys(EditLine *el, el_action_t *map, int first, int last) +map_print_some_keys(EditLine *el, el_action_t *map, Int first, Int last) { el_bindings_t *bp, *ep; - char firstbuf[2], lastbuf[2]; + Char firstbuf[2], lastbuf[2]; char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ]; firstbuf[0] = first; @@ -1155,7 +1152,7 @@ lastbuf[1] = 0; if (map[first] == ED_UNASSIGNED) { if (first == last) { - (void) key__decode_str(firstbuf, unparsbuf, + (void) keymacro__decode_str(firstbuf, unparsbuf, sizeof(unparsbuf), STRQQ); (void) fprintf(el->el_outfile, "%-15s-> is undefined\n", unparsbuf); @@ -1166,17 +1163,17 @@ for (bp = el->el_map.help; bp < ep; bp++) { if (bp->func == map[first]) { if (first == last) { - (void) key__decode_str(firstbuf, unparsbuf, + (void) keymacro__decode_str(firstbuf, unparsbuf, sizeof(unparsbuf), STRQQ); - (void) fprintf(el->el_outfile, "%-15s-> %s\n", + (void) fprintf(el->el_outfile, "%-15s-> " FSTR "\n", unparsbuf, bp->name); } else { - (void) key__decode_str(firstbuf, unparsbuf, + (void) keymacro__decode_str(firstbuf, unparsbuf, sizeof(unparsbuf), STRQQ); - (void) key__decode_str(lastbuf, extrabuf, + (void) keymacro__decode_str(lastbuf, extrabuf, sizeof(extrabuf), STRQQ); (void) fprintf(el->el_outfile, - "%-4s to %-7s-> %s\n", + "%-4s to %-7s-> " FSTR "\n", unparsbuf, extrabuf, bp->name); } return; @@ -1184,7 +1181,7 @@ } #ifdef MAP_DEBUG if (map == el->el_map.key) { - (void) key__decode_str(firstbuf, unparsbuf, + (void) keymacro__decode_str(firstbuf, unparsbuf, sizeof(unparsbuf), STRQQ); (void) fprintf(el->el_outfile, "BUG!!! %s isn't bound to anything.\n", unparsbuf); @@ -1191,7 +1188,7 @@ (void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n", first, el->el_map.key[first]); } else { - (void) key__decode_str(firstbuf, unparsbuf, + (void) keymacro__decode_str(firstbuf, unparsbuf, sizeof(unparsbuf), STRQQ); (void) fprintf(el->el_outfile, "BUG!!! %s isn't bound to anything.\n", unparsbuf); @@ -1232,9 +1229,9 @@ map_print_some_keys(el, el->el_map.alt, prev, i - 1); (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"); - term_print_arrow(el, ""); + terminal_print_arrow(el, STR("")); } @@ -1242,21 +1239,21 @@ * Add/remove/change bindings */ protected int -map_bind(EditLine *el, int argc, const char **argv) +map_bind(EditLine *el, int argc, const Char **argv) { el_action_t *map; int ntype, rem; - const char *p; - char inbuf[EL_BUFSIZ]; - char outbuf[EL_BUFSIZ]; - const char *in = NULL; - char *out; + const Char *p; + Char inbuf[EL_BUFSIZ]; + Char outbuf[EL_BUFSIZ]; + const Char *in = NULL; + Char *out; el_bindings_t *bp, *ep; int cmd; int key; if (argv == NULL) - return (-1); + return -1; map = el->el_map.key; ntype = XK_CMD; @@ -1286,22 +1283,22 @@ case 'v': map_init_vi(el); - return (0); + return 0; case 'e': map_init_emacs(el); - return (0); + return 0; case 'l': ep = &el->el_map.help[el->el_map.nfunc]; for (bp = el->el_map.help; bp < ep; bp++) (void) fprintf(el->el_outfile, - "%s\n\t%s\n", + "" FSTR "\n\t" FSTR "\n", bp->name, bp->description); - return (0); + return 0; default: (void) fprintf(el->el_errfile, - "%s: Invalid switch `%c'.\n", + "" FSTR ": Invalid switch `%c'.\n", argv[0], p[1]); } else @@ -1309,40 +1306,40 @@ if (argv[argc] == NULL) { map_print_all_keys(el); - return (0); + return 0; } if (key) in = argv[argc++]; else if ((in = parse__string(inbuf, argv[argc++])) == NULL) { (void) fprintf(el->el_errfile, - "%s: Invalid \\ or ^ in instring.\n", + "" FSTR ": Invalid \\ or ^ in instring.\n", argv[0]); - return (-1); + return -1; } if (rem) { if (key) { - (void) term_clear_arrow(el, in); - return (-1); + (void) terminal_clear_arrow(el, in); + return -1; } if (in[1]) - (void) key_delete(el, in); + (void) keymacro_delete(el, in); else if (map[(unsigned char) *in] == ED_SEQUENCE_LEAD_IN) - (void) key_delete(el, in); + (void) keymacro_delete(el, in); else map[(unsigned char) *in] = ED_UNASSIGNED; - return (0); + return 0; } if (argv[argc] == NULL) { if (key) - term_print_arrow(el, in); + terminal_print_arrow(el, in); else map_print_key(el, map, in); - return (0); + return 0; } #ifdef notyet if (argv[argc + 1] != NULL) { - bindkey_usage(); - return (-1); + bindkeymacro_usage(); + return -1; } #endif @@ -1351,13 +1348,13 @@ case XK_EXE: if ((out = parse__string(outbuf, argv[argc])) == NULL) { (void) fprintf(el->el_errfile, - "%s: Invalid \\ or ^ in outstring.\n", argv[0]); - return (-1); + "" FSTR ": Invalid \\ or ^ in outstring.\n", argv[0]); + return -1; } 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 - 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; break; @@ -1364,27 +1361,29 @@ case XK_CMD: if ((cmd = parse_cmd(el, argv[argc])) == -1) { (void) fprintf(el->el_errfile, - "%s: Invalid command `%s'.\n", argv[0], argv[argc]); - return (-1); + "" FSTR ": Invalid command `" FSTR "'.\n", + argv[0], argv[argc]); + return -1; } if (key) - term_set_arrow(el, in, key_map_cmd(el, cmd), ntype); + terminal_set_arrow(el, in, keymacro_map_cmd(el, cmd), ntype); else { 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; } else { - key_clear(el, map, in); - map[(unsigned char) *in] = cmd; + keymacro_clear(el, map, in); + map[(unsigned char) *in] = (el_action_t)cmd; } } break; + /* coverity[dead_error_begin] */ default: EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); break; } - return (0); + return 0; } @@ -1392,29 +1391,30 @@ * add a user defined function */ protected int -map_addfunc(EditLine *el, const char *name, const char *help, el_func_t func) +map_addfunc(EditLine *el, const Char *name, const Char *help, el_func_t func) { void *p; - int nf = el->el_map.nfunc + 1; + size_t nf = (size_t)el->el_map.nfunc + 1; 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) - return (-1); - el->el_map.func = (el_func_t *) p; - if ((p = el_realloc(el->el_map.help, nf * sizeof(el_bindings_t))) + if ((p = el_realloc(el->el_map.func, nf * + sizeof(*el->el_map.func))) == NULL) + return -1; + el->el_map.func = p; + if ((p = el_realloc(el->el_map.help, nf * sizeof(*el->el_map.help))) == NULL) - return (-1); - el->el_map.help = (el_bindings_t *) p; + return -1; + 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.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.nfunc++; - return (0); + return 0; } Index: lib/libedit/map.h =================================================================== --- lib/libedit/map.h (revision 258914) +++ lib/libedit/map.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: map.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +32,6 @@ * SUCH DAMAGE. * * @(#)map.h 8.1 (Berkeley) 6/4/93 - * $NetBSD: map.h,v 1.8 2003/08/07 16:44:32 agc Exp $ * $FreeBSD$ */ @@ -41,9 +42,9 @@ #define _h_el_map typedef struct el_bindings_t { /* for the "bind" shell command */ - const char *name; /* function name for bind command */ + const Char *name; /* function name for bind command */ int func; /* function numeric value */ - const char *description; /* description of function */ + const Char *description; /* description of function */ } el_bindings_t; @@ -63,13 +64,15 @@ #define MAP_EMACS 0 #define MAP_VI 1 -protected int map_bind(EditLine *, int, const char **); +#define N_KEYS 256 + +protected int map_bind(EditLine *, int, const Char **); protected int map_init(EditLine *); protected void map_end(EditLine *); protected void map_init_vi(EditLine *); protected void map_init_emacs(EditLine *); -protected int map_set_editor(EditLine *, char *); -protected int map_get_editor(EditLine *, const char **); -protected int map_addfunc(EditLine *, const char *, const char *, el_func_t); +protected int map_set_editor(EditLine *, Char *); +protected int map_get_editor(EditLine *, const Char **); +protected int map_addfunc(EditLine *, const Char *, const Char *, el_func_t); #endif /* _h_el_map */ Index: lib/libedit/parse.c =================================================================== --- lib/libedit/parse.c (revision 258914) +++ lib/libedit/parse.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: parse.c,v 1.26 2011/08/16 16:25:15 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -51,22 +52,21 @@ * settc * setty */ -#include "sys.h" #include "el.h" #include private const struct { - const char *name; - int (*func)(EditLine *, int, const char **); + const Char *name; + int (*func)(EditLine *, int, const Char **); } cmds[] = { - { "bind", map_bind }, - { "echotc", term_echotc }, - { "edit", el_editmode }, - { "history", hist_command }, - { "telltc", term_telltc }, - { "settc", term_settc }, - { "setty", tty_stty }, - { NULL, NULL } + { STR("bind"), map_bind }, + { STR("echotc"), terminal_echotc }, + { STR("edit"), el_editmode }, + { STR("history"), hist_command }, + { STR("telltc"), terminal_telltc }, + { STR("settc"), terminal_settc }, + { STR("setty"), tty_stty }, + { NULL, NULL } }; @@ -74,17 +74,17 @@ * Parse a line and dispatch it */ protected int -parse_line(EditLine *el, const char *line) +parse_line(EditLine *el, const Char *line) { - const char **argv; + const Char **argv; int argc; - Tokenizer *tok; + TYPE(Tokenizer) *tok; - tok = tok_init(NULL); - tok_str(tok, line, &argc, &argv); - argc = el_parse(el, argc, argv); - tok_end(tok); - return (argc); + tok = FUN(tok,init)(NULL); + FUN(tok,str)(tok, line, &argc, &argv); + argc = FUN(el,parse)(el, argc, argv); + FUN(tok,end)(tok); + return argc; } @@ -92,57 +92,57 @@ * Command dispatcher */ public int -el_parse(EditLine *el, int argc, const char *argv[]) +FUN(el,parse)(EditLine *el, int argc, const Char *argv[]) { - const char *ptr; + const Char *ptr; int i; if (argc < 1) - return (-1); - ptr = strchr(argv[0], ':'); + return -1; + ptr = Strchr(argv[0], ':'); if (ptr != NULL) { - char *tprog; + Char *tprog; size_t l; if (ptr == argv[0]) - return (0); - l = ptr - argv[0] - 1; - tprog = (char *) el_malloc(l + 1); + return 0; + l = (size_t)(ptr - argv[0] - 1); + tprog = el_malloc((l + 1) * sizeof(*tprog)); if (tprog == NULL) - return (0); - (void) strncpy(tprog, argv[0], l); + return 0; + (void) Strncpy(tprog, argv[0], l); tprog[l] = '\0'; ptr++; - l = el_match(el->el_prog, tprog); + l = (size_t)el_match(el->el_prog, tprog); el_free(tprog); if (!l) - return (0); + return 0; } else ptr = argv[0]; for (i = 0; cmds[i].name != NULL; i++) - if (strcmp(cmds[i].name, ptr) == 0) { + if (Strcmp(cmds[i].name, ptr) == 0) { i = (*cmds[i].func) (el, argc, argv); - return (-i); + return -i; } - return (-1); + return -1; } /* parse__escape(): - * Parse a string of the form ^ \ \ and return + * Parse a string of the form ^ \ \ \U+xxxx and return * the appropriate character or -1 if the escape is not valid */ protected int -parse__escape(const char **ptr) +parse__escape(const Char **ptr) { - const char *p; - int c; + const Char *p; + Int c; p = *ptr; if (p[1] == 0) - return (-1); + return -1; if (*p == '\\') { p++; @@ -171,6 +171,28 @@ case 'e': c = '\033'; /* Escape */ break; + case 'U': /* Unicode \U+xxxx or \U+xxxxx format */ + { + int i; + const Char hex[] = STR("0123456789ABCDEF"); + const Char *h; + ++p; + if (*p++ != '+') + return -1; + c = 0; + for (i = 0; i < 5; ++i) { + h = Strchr(hex, *p++); + if (!h && i < 4) + return -1; + else if (h) + c = (c << 4) | ((int)(h - hex)); + else + --p; + } + if (c > 0x10FFFF) /* outside valid character range */ + return -1; + break; + } case '0': case '1': case '2': @@ -190,8 +212,8 @@ } c = (c << 3) | (ch - '0'); } - if ((c & 0xffffff00) != 0) - return (-1); + if ((c & (wint_t)0xffffff00) != (wint_t)0) + return -1; --p; break; } @@ -205,16 +227,16 @@ } else c = *p; *ptr = ++p; - return ((unsigned char)c); + return c; } /* parse__string(): * Parse the escapes from in and put the raw string out */ -protected char * -parse__string(char *out, const char *in) +protected Char * +parse__string(Char *out, const Char *in) { - char *rv = out; + Char *rv = out; int n; for (;;) @@ -221,12 +243,12 @@ switch (*in) { case '\0': *out = '\0'; - return (rv); + return rv; case '\\': case '^': if ((n = parse__escape(&in)) == -1) - return (NULL); + return NULL; *out++ = n; break; @@ -250,12 +272,12 @@ * or -1 if one is not found */ protected int -parse_cmd(EditLine *el, const char *cmd) +parse_cmd(EditLine *el, const Char *cmd) { el_bindings_t *b; for (b = el->el_map.help; b->name != NULL; b++) - if (strcmp(b->name, cmd) == 0) - return (b->func); - return (-1); + if (Strcmp(b->name, cmd) == 0) + return b->func; + return -1; } Index: lib/libedit/parse.h =================================================================== --- lib/libedit/parse.h (revision 258914) +++ lib/libedit/parse.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: parse.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +32,6 @@ * SUCH DAMAGE. * * @(#)parse.h 8.1 (Berkeley) 6/4/93 - * $NetBSD: parse.h,v 1.6 2005/05/29 04:58:15 lukem Exp $ * $FreeBSD$ */ @@ -40,9 +41,9 @@ #ifndef _h_el_parse #define _h_el_parse -protected int parse_line(EditLine *, const char *); -protected int parse__escape(const char **); -protected char *parse__string(char *, const char *); -protected int parse_cmd(EditLine *, const char *); +protected int parse_line(EditLine *, const Char *); +protected int parse__escape(const Char **); +protected Char *parse__string(Char *, const Char *); +protected int parse_cmd(EditLine *, const Char *); #endif /* _h_el_parse */ Index: lib/libedit/prompt.c =================================================================== --- lib/libedit/prompt.c (revision 258914) +++ lib/libedit/prompt.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: prompt.c,v 1.20 2011/07/29 15:16:33 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -41,23 +42,22 @@ /* * prompt.c: Prompt printing functions */ -#include "sys.h" #include #include "el.h" -private char *prompt_default(EditLine *); -private char *prompt_default_r(EditLine *); +private Char *prompt_default(EditLine *); +private Char *prompt_default_r(EditLine *); /* prompt_default(): * Just a default prompt, in case the user did not provide one */ -private char * +private Char * /*ARGSUSED*/ -prompt_default(EditLine *el __unused) +prompt_default(EditLine *el __attribute__((__unused__))) { - static char a[3] = {'?', ' ', '\0'}; + static Char a[3] = {'?', ' ', '\0'}; - return (a); + return a; } @@ -64,27 +64,24 @@ /* prompt_default_r(): * Just a default rprompt, in case the user did not provide one */ -private char * +private Char * /*ARGSUSED*/ -prompt_default_r(EditLine *el __unused) +prompt_default_r(EditLine *el __attribute__((__unused__))) { - static char a[1] = {'\0'}; + static Char a[1] = {'\0'}; - return (a); + return a; } /* prompt_print(): * Print the prompt and update the prompt position. - * We use an array of integers in case we want to pass - * literal escape sequences in the prompt and we want a - * bit to flag them */ protected void prompt_print(EditLine *el, int op) { el_prompt_t *elp; - char *p; + Char *p; int ignore = 0; if (op == EL_PROMPT) @@ -92,13 +89,19 @@ else elp = &el->el_rprompt; - for (p = (*elp->p_func)(el); *p; p++) { + if (elp->p_wide) + p = (*elp->p_func)(el); + else + p = ct_decode_string((char *)(void *)(*elp->p_func)(el), + &el->el_scratch); + + for (; *p; p++) { if (elp->p_ignore == *p) { ignore = !ignore; continue; } if (ignore) - term__putc(el, *p); + terminal__putc(el, *p); else re_putc(el, *p, 1); } @@ -132,7 +135,7 @@ */ protected void /*ARGSUSED*/ -prompt_end(EditLine *el __unused) +prompt_end(EditLine *el __attribute__((__unused__))) { } @@ -141,7 +144,7 @@ * Install a prompt printing function */ protected int -prompt_set(EditLine *el, el_pfunc_t prf, char c, int op) +prompt_set(EditLine *el, el_pfunc_t prf, Char c, int op, int wide) { el_prompt_t *p; @@ -155,13 +158,15 @@ p->p_func = prompt_default; else p->p_func = prompt_default_r; - } else + } else { p->p_func = prf; + } p->p_ignore = c; p->p_pos.v = 0; p->p_pos.h = 0; + p->p_wide = wide; return 0; } @@ -171,7 +176,7 @@ * Retrieve the prompt printing function */ protected int -prompt_get(EditLine *el, el_pfunc_t *prf, char *c, int op) +prompt_get(EditLine *el, el_pfunc_t *prf, Char *c, int op) { el_prompt_t *p; @@ -183,8 +188,8 @@ else p = &el->el_rprompt; - *prf = el->el_rprompt.p_func; - + if (prf) + *prf = p->p_func; if (c) *c = p->p_ignore; Index: lib/libedit/prompt.h =================================================================== --- lib/libedit/prompt.h (revision 258914) +++ lib/libedit/prompt.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: prompt.h,v 1.10 2009/12/30 22:37:40 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +32,6 @@ * SUCH DAMAGE. * * @(#)prompt.h 8.1 (Berkeley) 6/4/93 - * $NetBSD: prompt.h,v 1.6 2003/08/07 16:44:32 agc Exp $ * $FreeBSD$ */ @@ -42,18 +43,18 @@ #include "histedit.h" -typedef char * (*el_pfunc_t)(EditLine*); +typedef Char *(*el_pfunc_t)(EditLine *); typedef struct el_prompt_t { - el_pfunc_t p_func; /* Function to return the prompt */ - coord_t p_pos; /* position in the line after prompt */ - char p_ignore; /* character to start/end literal -*/ + el_pfunc_t p_func; /* Function to return the prompt */ + coord_t p_pos; /* position in the line after prompt */ + Char p_ignore; /* character to start/end literal */ + int p_wide; } el_prompt_t; protected void prompt_print(EditLine *, int); -protected int prompt_set(EditLine *, el_pfunc_t, char, int); -protected int prompt_get(EditLine *, el_pfunc_t *, char *, int); +protected int prompt_set(EditLine *, el_pfunc_t, Char, int, int); +protected int prompt_get(EditLine *, el_pfunc_t *, Char *, int); protected int prompt_init(EditLine *); protected void prompt_end(EditLine *); Index: lib/libedit/read.c =================================================================== --- lib/libedit/read.c (revision 258914) +++ lib/libedit/read.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: read.c,v 1.70 2013/05/27 23:55:55 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: read.c,v 1.52 2009/07/22 15:57:00 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -42,19 +43,19 @@ * read.c: Clean this junk up! This is horrible code. * Terminal read functions */ -#include "sys.h" #include #include #include #include +#include #include "el.h" -#define OKCMD -1 +#define OKCMD -1 /* must be -1! */ private int read__fixio(int, int); private int read_preread(EditLine *); -private int read_char(EditLine *, char *); -private int read_getcmd(EditLine *, el_action_t *, char *); +private int read_char(EditLine *, Char *); +private int read_getcmd(EditLine *, el_action_t *, Char *); private void read_pop(c_macro_t *); /* read_init(): @@ -88,7 +89,7 @@ protected el_rfunc_t 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; } @@ -121,7 +122,7 @@ */ /* ARGSUSED */ private int -read__fixio(int fd __unused, int e) +read__fixio(int fd __attribute__((__unused__)), int e) { switch (e) { @@ -130,7 +131,7 @@ #ifdef EWOULDBLOCK case EWOULDBLOCK: #ifndef TRY_AGAIN -#define TRY_AGAIN +#define TRY_AGAIN #endif #endif /* EWOULDBLOCK */ @@ -138,7 +139,7 @@ #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN case EAGAIN: #ifndef TRY_AGAIN -#define TRY_AGAIN +#define TRY_AGAIN #endif #endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */ #endif /* POSIX && EAGAIN */ @@ -147,10 +148,10 @@ #ifdef TRY_AGAIN #if defined(F_SETFL) && defined(O_NDELAY) if ((e = fcntl(fd, F_GETFL, 0)) == -1) - return (-1); + return -1; if (fcntl(fd, F_SETFL, e & ~O_NDELAY) == -1) - return (-1); + return -1; else e = 1; #endif /* F_SETFL && O_NDELAY */ @@ -159,8 +160,8 @@ { int zero = 0; - if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1) - return (-1); + if (ioctl(fd, FIONBIO, &zero) == -1) + return -1; else e = 1; } @@ -167,13 +168,13 @@ #endif /* FIONBIO */ #endif /* TRY_AGAIN */ - return (e ? 0 : -1); + return e ? 0 : -1; case EINTR: - return (0); + return 0; default: - return (-1); + return -1; } } @@ -187,10 +188,13 @@ int chrs = 0; 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 - (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); + (void) ioctl(el->el_infd, FIONREAD, &chrs); if (chrs > 0) { char buf[EL_BUFSIZ]; @@ -202,8 +206,8 @@ } } #endif /* FIONREAD */ - - return (chrs > 0); +#endif + return chrs > 0; } @@ -211,26 +215,27 @@ * Push a macro */ 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; if (str != NULL && ma->level + 1 < EL_MAXMACRO) { ma->level++; - if ((ma->macro[ma->level] = el_strdup(str)) != NULL) + if ((ma->macro[ma->level] = Strdup(str)) != NULL) return; ma->level--; } - term_beep(el); - term__flush(el); + terminal_beep(el); + terminal__flush(el); } /* read_getcmd(): - * Return next command from the input stream. + * Get next command from the input stream, return OKCMD on success. + * Character values > 255 are not looked up in the map, but inserted. */ private int -read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) +read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch) { el_action_t cmd; int num; @@ -237,9 +242,9 @@ el->el_errno = 0; do { - if ((num = el_getc(el, ch)) != 1) { /* if EOF or error */ + if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */ el->el_errno = num == 0 ? 0 : errno; - return (num); + return 0; /* not OKCMD */ } #ifdef KANJI @@ -254,15 +259,20 @@ el->el_state.metanext = 0; *ch |= 0200; } - cmd = el->el_map.current[(unsigned char) *ch]; +#ifdef WIDECHAR + if (*ch >= N_KEYS) + cmd = ED_INSERT; + else +#endif + cmd = el->el_map.current[(unsigned char) *ch]; if (cmd == ED_SEQUENCE_LEAD_IN) { - key_value_t val; - switch (key_get(el, ch, &val)) { + keymacro_value_t val; + switch (keymacro_get(el, ch, &val)) { case XK_CMD: cmd = val.cmd; break; case XK_STR: - el_push(el, val.str); + FUN(el,push)(el, val.str); break; #ifdef notyet case XK_EXE: @@ -279,34 +289,90 @@ el->el_map.current = el->el_map.key; } while (cmd == ED_SEQUENCE_LEAD_IN); *cmdnum = cmd; - return (OKCMD); + return OKCMD; } +#ifdef WIDECHAR +/* utf8_islead(): + * Test whether a byte is a leading byte of a UTF-8 sequence. + */ +private int +utf8_islead(int c) +{ + return c < 0x80 || /* single byte char */ + (c >= 0xc2 && c <= 0xf4); /* start of multibyte sequence */ +} +#endif /* read_char(): * Read a character from the tty. */ private int -read_char(EditLine *el, char *cp) +read_char(EditLine *el, Char *cp) { ssize_t num_read; int tried = 0; + char cbuf[MB_LEN_MAX]; + size_t cbp = 0; + int bytes = 0; again: el->el_signal->sig_no = 0; - while ((num_read = read(el->el_infd, cp, 1)) == -1) { - if (el->el_signal->sig_no == SIGCONT) { + while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) { + int e = errno; + switch (el->el_signal->sig_no) { + case SIGCONT: + FUN(el,set)(el, EL_REFRESH); + /*FALLTHROUGH*/ + case SIGWINCH: sig_set(el); - el_set(el, EL_REFRESH); goto again; + default: + break; } - if (!tried && read__fixio(el->el_infd, errno) == 0) + if (!tried && read__fixio(el->el_infd, e) == 0) tried = 1; else { + errno = e; *cp = '\0'; - return (-1); + return -1; } } + + /* Test for EOF */ + if (num_read == 0) { + errno = 0; + *cp = '\0'; + return 0; + } + +#ifdef WIDECHAR + if (el->el_flags & CHARSET_IS_UTF8) { + if (!utf8_islead((unsigned char)cbuf[0])) + goto again; /* discard the byte we read and try again */ + ++cbp; + if ((bytes = ct_mbtowc(cp, cbuf, cbp)) == -1) { + ct_mbtowc_reset; + if (cbp >= MB_LEN_MAX) { /* "shouldn't happen" */ + errno = EILSEQ; + *cp = '\0'; + return -1; + } + goto again; + } + } else if (isascii((unsigned char)cbuf[0]) || + /* we don't support other multibyte charsets */ + ++cbp != 1 || + /* Try non-ASCII characters in a 8-bit character set */ + (bytes = ct_mbtowc(cp, cbuf, cbp)) != 1) +#endif + *cp = (unsigned char)cbuf[0]; + + if ((el->el_flags & IGNORE_EXTCHARS) && bytes > 1) { + cbp = 0; /* skip this character */ + goto again; + } + return (int)num_read; } @@ -329,12 +395,12 @@ * Read a character */ public int -el_getc(EditLine *el, char *cp) +FUN(el,getc)(EditLine *el, Char *cp) { int num_read; c_macro_t *ma = &el->el_chared.c_macro; - term__flush(el); + terminal__flush(el); for (;;) { if (ma->level < 0) { if (!read_preread(el)) @@ -349,7 +415,7 @@ continue; } - *cp = ma->macro[0][ma->offset++] & 0377; + *cp = ma->macro[0][ma->offset++]; if (ma->macro[0][ma->offset] == '\0') { /* Needed for QuoteMode On */ @@ -356,7 +422,7 @@ read_pop(ma); } - return (1); + return 1; } #ifdef DEBUG_READ @@ -363,16 +429,22 @@ (void) fprintf(el->el_errfile, "Turning raw mode on\n"); #endif /* DEBUG_READ */ if (tty_rawmode(el) < 0)/* make sure the tty is set up correctly */ - return (0); + return 0; #ifdef DEBUG_READ (void) fprintf(el->el_errfile, "Reading a character\n"); #endif /* DEBUG_READ */ num_read = (*el->el_read.read_char)(el, cp); + if (num_read < 0) + el->el_errno = errno; +#ifdef WIDECHAR + if (el->el_flags & NARROW_READ) + *cp = *(char *)(void *)cp; +#endif #ifdef DEBUG_READ (void) fprintf(el->el_errfile, "Got it %c\n", *cp); #endif /* DEBUG_READ */ - return (num_read); + return num_read; } protected void @@ -393,7 +465,7 @@ re_refresh(el); /* print the prompt */ if (el->el_flags & UNBUFFERED) - term__flush(el); + terminal__flush(el); } protected void @@ -405,13 +477,13 @@ sig_clr(el); } -public const char * -el_gets(EditLine *el, int *nread) +public const Char * +FUN(el,gets)(EditLine *el, int *nread) { int retval; el_action_t cmdnum = 0; int num; /* how many chars we have read at NL */ - char ch; + Char ch, *cp; int crlf = 0; int nrb; #ifdef FIONREAD @@ -423,14 +495,14 @@ *nread = 0; if (el->el_flags & NO_TTY) { - char *cp = el->el_line.buffer; size_t idx; + cp = el->el_line.buffer; while ((num = (*el->el_read.read_char)(el, cp)) == 1) { /* make sure there is space for next character */ if (cp + 1 >= el->el_line.limit) { - idx = (cp - el->el_line.buffer); - if (!ch_enlargebufs(el, 2)) + idx = (size_t)(cp - el->el_line.buffer); + if (!ch_enlargebufs(el, (size_t)2)) break; cp = &el->el_line.buffer[idx]; } @@ -440,13 +512,13 @@ if (cp[-1] == '\r' || cp[-1] == '\n') break; } - if (num == -1) + if (num == -1) { + if (errno == EINTR) + cp = el->el_line.buffer; el->el_errno = errno; + } - el->el_line.cursor = el->el_line.lastchar = cp; - *cp = '\0'; - *nread = (int)(el->el_line.cursor - el->el_line.buffer); - goto done; + goto noedit; } @@ -454,12 +526,12 @@ if (el->el_tty.t_mode == EX_IO && ma->level < 0) { long chrs = 0; - (void) ioctl(el->el_infd, FIONREAD, (ioctl_t) & chrs); + (void) ioctl(el->el_infd, FIONREAD, &chrs); if (chrs == 0) { if (tty_rawmode(el) < 0) { errno = 0; *nread = 0; - return (NULL); + return NULL; } } } @@ -469,7 +541,6 @@ read_prepare(el); if (el->el_flags & EDIT_DISABLED) { - char *cp; size_t idx; if ((el->el_flags & UNBUFFERED) == 0) @@ -477,13 +548,13 @@ else cp = el->el_line.lastchar; - term__flush(el); + terminal__flush(el); while ((num = (*el->el_read.read_char)(el, cp)) == 1) { /* make sure there is space next character */ if (cp + 1 >= el->el_line.limit) { - idx = (cp - el->el_line.buffer); - if (!ch_enlargebufs(el, 2)) + idx = (size_t)(cp - el->el_line.buffer); + if (!ch_enlargebufs(el, (size_t)2)) break; cp = &el->el_line.buffer[idx]; } @@ -496,12 +567,12 @@ } if (num == -1) { + if (errno == EINTR) + cp = el->el_line.buffer; el->el_errno = errno; } - el->el_line.cursor = el->el_line.lastchar = cp; - *cp = '\0'; - goto done; + goto noedit; } for (num = OKCMD; num == OKCMD;) { /* while still editing this @@ -511,6 +582,7 @@ #endif /* DEBUG_EDIT */ /* if EOF or error */ if ((num = read_getcmd(el, &cmdnum, &ch)) != OKCMD) { + num = -1; #ifdef DEBUG_READ (void) fprintf(el->el_errfile, "Returning from el_gets %d\n", num); @@ -517,6 +589,12 @@ #endif /* DEBUG_READ */ 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 */ #ifdef DEBUG_EDIT (void) fprintf(el->el_errfile, @@ -547,7 +625,7 @@ el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) { if (cmdnum == VI_DELETE_PREV_CHAR && el->el_chared.c_redo.pos != el->el_chared.c_redo.buf - && isprint((unsigned char)el->el_chared.c_redo.pos[-1])) + && Isprint(el->el_chared.c_redo.pos[-1])) el->el_chared.c_redo.pos--; else *el->el_chared.c_redo.pos++ = ch; @@ -578,7 +656,7 @@ case CC_REFRESH_BEEP: re_refresh(el); - term_beep(el); + terminal_beep(el); break; case CC_NORM: /* normal char */ @@ -610,7 +688,7 @@ /* put (real) cursor in a known place */ re_clear_display(el); /* reset the display stuff */ ch_reset(el, 1); /* reset the input pointers */ - re_refresh(el); /* print the prompt again */ + re_refresh(el); /* print the prompt again */ break; case CC_ERROR: @@ -619,8 +697,8 @@ (void) fprintf(el->el_errfile, "*** editor ERROR ***\r\n\n"); #endif /* DEBUG_READ */ - term_beep(el); - term__flush(el); + terminal_beep(el); + terminal__flush(el); break; } el->el_state.argument = 1; @@ -630,7 +708,7 @@ break; } - term__flush(el); /* flush any buffered output */ + terminal__flush(el); /* flush any buffered output */ /* make sure the tty is set up correctly */ if ((el->el_flags & UNBUFFERED) == 0) { read_finish(el); @@ -638,6 +716,11 @@ } else { *nread = (int)(el->el_line.lastchar - el->el_line.buffer); } + goto done; +noedit: + el->el_line.cursor = el->el_line.lastchar = cp; + *cp = '\0'; + *nread = (int)(el->el_line.cursor - el->el_line.buffer); done: if (*nread == 0) { if (num == -1) { Index: lib/libedit/read.h =================================================================== --- lib/libedit/read.h (revision 258914) +++ lib/libedit/read.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: read.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */ + /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. * All rights reserved. @@ -26,7 +28,6 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * - * $NetBSD: read.h,v 1.5 2006/08/21 12:45:30 christos Exp $ * $FreeBSD$ */ @@ -36,7 +37,7 @@ #ifndef _h_el_read #define _h_el_read -typedef int (*el_rfunc_t)(EditLine *, char *); +typedef int (*el_rfunc_t)(EditLine *, Char *); typedef struct el_read_t { el_rfunc_t read_char; /* Function to read a character */ Index: lib/libedit/readline.c =================================================================== --- lib/libedit/readline.c (revision 258914) +++ lib/libedit/readline.c (working copy) @@ -1,4 +1,4 @@ -/* $NetBSD: readline.c,v 1.90 2010/08/04 20:29:18 christos Exp $ */ +/* $NetBSD: readline.c,v 1.109 2013/08/28 08:05:21 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -29,8 +29,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "config.h" #include -__RCSID("$NetBSD: readline.c,v 1.90 2010/08/04 20:29:18 christos Exp $"); __FBSDID("$FreeBSD$"); #include @@ -47,9 +47,8 @@ #include #include #include -#include "sys.h" + #include "readline/readline.h" -#include "chartype.h" #include "el.h" #include "fcns.h" /* for EL_NUM_FCNS */ #include "histedit.h" @@ -84,6 +83,14 @@ KEYMAP_ENTRY_ARRAY emacs_standard_keymap, emacs_meta_keymap, emacs_ctlx_keymap; +/* + * The following is not implemented; we always catch signals in the + * libedit fashion: set handlers on entry to el_gets() and clear them + * on the way out. This simplistic approach works for most cases; if + * it does not work for your application, please let us know. + */ +int rl_catch_signals = 1; +int rl_catch_sigwinch = 1; int history_base = 1; /* probably never subject to change */ int history_length = 0; @@ -100,6 +107,7 @@ char *rl_completer_word_break_characters = NULL; char *rl_completer_quote_characters = NULL; Function *rl_completion_entry_function = NULL; +char *(*rl_completion_word_break_hook)(void) = NULL; CPPFunction *rl_attempted_completion_function = NULL; Function *rl_pre_input_hook = NULL; Function *rl_startup1_hook = NULL; @@ -108,7 +116,6 @@ int rl_already_prompted = 0; int rl_filename_completion_desired = 0; int rl_ignore_completion_duplicates = 0; -int rl_catch_signals = 1; int readline_echoing_p = 1; int _rl_print_completions_horizontally = 0; VFunction *rl_redisplay_function = NULL; @@ -118,10 +125,6 @@ VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal; KEYMAP_ENTRY_ARRAY emacs_meta_keymap; -#ifdef WIDECHAR -static ct_buffer_t conv; -#endif - /* * The current prompt string. */ @@ -154,7 +157,7 @@ /* stuff below is used internally by libedit for readline emulation */ -static TYPE(History) *h = NULL; +static History *h = NULL; static EditLine *e = NULL; static Function *map[256]; static jmp_buf topbuf; @@ -178,7 +181,7 @@ _get_prompt(EditLine *el __attribute__((__unused__))) { rl_already_prompted = 1; - return (rl_prompt); + return rl_prompt; } @@ -188,16 +191,16 @@ static HIST_ENTRY * _move_history(int op) { - TYPE(HistEvent) ev; + HistEvent ev; static HIST_ENTRY rl_he; - if (FUNW(history)(h, &ev, op) != 0) - return (HIST_ENTRY *) NULL; + if (history(h, &ev, op) != 0) + return NULL; - rl_he.line = ct_encode_string(ev.str, &conv); + rl_he.line = ev.str; rl_he.data = NULL; - return (&rl_he); + return &rl_he; } @@ -206,7 +209,7 @@ */ static int /*ARGSUSED*/ -_getc_function(EditLine *el, char *c) +_getc_function(EditLine *el __attribute__((__unused__)), char *c) { int i; @@ -213,24 +216,39 @@ i = (*rl_getc_function)(NULL); if (i == -1) return 0; - *c = i; + *c = (char)i; return 1; } -static const char _dothistory[] = "/.history"; +static void +_resize_fun(EditLine *el, void *a) +{ + const LineInfo *li; + char **ap = a; + li = el_line(el); + /* a cheesy way to get rid of const cast. */ + *ap = memchr(li->buffer, *li->buffer, (size_t)1); +} + static const char * _default_history_file(void) { struct passwd *p; - static char path[PATH_MAX]; + static char *path; + size_t len; - if (*path) + if (path) return path; + if ((p = getpwuid(getuid())) == NULL) return NULL; - strlcpy(path, p->pw_dir, PATH_MAX); - strlcat(path, _dothistory, PATH_MAX); + + len = strlen(p->pw_dir) + sizeof("/.history"); + if ((path = malloc(len)) == NULL) + return NULL; + + (void)snprintf(path, len, "%s/.history", p->pw_dir); return path; } @@ -251,7 +269,7 @@ if (rl_prompt != NULL && strcmp(rl_prompt, prompt) == 0) return 0; if (rl_prompt) - free(rl_prompt); + el_free(rl_prompt); rl_prompt = strdup(prompt); if (rl_prompt == NULL) return -1; @@ -268,8 +286,7 @@ int rl_initialize(void) { - TYPE(HistEvent) ev; - const LineInfo *li; + HistEvent ev; int editmode = 1; struct termios t; @@ -276,7 +293,7 @@ if (e != NULL) el_end(e); if (h != NULL) - FUN(history,end)(h); + history_end(h); if (!rl_instream) rl_instream = stdin; @@ -292,17 +309,20 @@ e = el_init(rl_readline_name, rl_instream, rl_outstream, stderr); if (!editmode) - FUN(el,set)(e, EL_EDITMODE, 0); + el_set(e, EL_EDITMODE, 0); - h = FUN(history,init)(); + h = history_init(); if (!e || !h) - return (-1); + return -1; - FUNW(history)(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */ + history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */ history_length = 0; max_input_history = INT_MAX; el_set(e, EL_HIST, history, h); + /* Setup resize function */ + el_set(e, EL_RESIZE, _resize_fun, &rl_line_buffer); + /* setup getc function if valid */ if (rl_getc_function) el_set(e, EL_GETCFN, _getc_function); @@ -309,7 +329,7 @@ /* for proper prompt printing in readline() */ if (rl_set_prompt("") == -1) { - FUN(history,end)(h); + history_end(h); el_end(e); return -1; } @@ -348,15 +368,13 @@ * Unfortunately, some applications really do use rl_point * and rl_line_buffer directly. */ - li = el_line(e); - /* a cheesy way to get rid of const cast. */ - rl_line_buffer = memchr(li->buffer, *li->buffer, 1); + _resize_fun(e, &rl_line_buffer); _rl_update_pos(); if (rl_startup_hook) (*rl_startup_hook)(NULL, 0); - return (0); + return 0; } @@ -367,7 +385,7 @@ char * readline(const char *p) { - TYPE(HistEvent) ev; + HistEvent ev; const char * volatile prompt = p; int count; const char *ret; @@ -415,7 +433,7 @@ } else buf = NULL; - FUNW(history)(h, &ev, H_GETSIZE); + history(h, &ev, H_GETSIZE); history_length = ev.num; return buf; @@ -465,7 +483,7 @@ } else s++; } - r = result = malloc(len + 1); + r = result = el_malloc((len + 1) * sizeof(*r)); if (result == NULL) return NULL; s = str; @@ -476,13 +494,13 @@ s += what_len; if (!globally) { (void)strcpy(r, s); - return(result); + return result; } } else *r++ = *s++; } *r = '\0'; - return(result); + return result; } static char *last_search_pat; /* last !?pat[?] search pattern */ @@ -495,18 +513,18 @@ size_t len; char *pat; const char *rptr; - TYPE(HistEvent) ev; + HistEvent ev; idx = *cindex; if (cmd[idx++] != history_expansion_char) - return(NULL); + return NULL; /* find out which event to take */ if (cmd[idx] == history_expansion_char || cmd[idx] == '\0') { - if (FUNW(history)(h, &ev, H_FIRST) != 0) - return(NULL); + if (history(h, &ev, H_FIRST) != 0) + return NULL; *cindex = cmd[idx]? (idx + 1):idx; - return ct_encode_string(ev.str, &conv); + return ev.str; } sign = 0; if (cmd[idx] == '-') { @@ -526,10 +544,10 @@ num = history_length - num + 1; if (!(rl_he = history_get(num))) - return(NULL); + return NULL; *cindex = idx; - return(rl_he->line); + return rl_he->line; } sub = 0; if (cmd[idx] == '?') { @@ -547,24 +565,24 @@ break; idx++; } - len = idx - begin; + len = (size_t)idx - (size_t)begin; if (sub && cmd[idx] == '?') idx++; if (sub && len == 0 && last_search_pat && *last_search_pat) pat = last_search_pat; else if (len == 0) - return(NULL); + return NULL; else { - if ((pat = malloc(len + 1)) == NULL) + if ((pat = el_malloc((len + 1) * sizeof(*pat))) == NULL) return NULL; (void)strncpy(pat, cmd + begin, len); pat[len] = '\0'; } - if (FUNW(history)(h, &ev, H_CURR) != 0) { + if (history(h, &ev, H_CURR) != 0) { if (pat != last_search_pat) - free(pat); - return (NULL); + el_free(pat); + return NULL; } num = ev.num; @@ -571,7 +589,7 @@ if (sub) { if (pat != last_search_pat) { if (last_search_pat) - free(last_search_pat); + el_free(last_search_pat); last_search_pat = pat; } ret = history_search(pat, -1); @@ -580,29 +598,29 @@ if (ret == -1) { /* restore to end of list on failed search */ - FUNW(history)(h, &ev, H_FIRST); + history(h, &ev, H_FIRST); (void)fprintf(rl_outstream, "%s: Event not found\n", pat); if (pat != last_search_pat) - free(pat); - return(NULL); + el_free(pat); + return NULL; } if (sub && len) { if (last_search_match && last_search_match != pat) - free(last_search_match); + el_free(last_search_match); last_search_match = pat; } if (pat != last_search_pat) - free(pat); + el_free(pat); - if (FUNW(history)(h, &ev, H_CURR) != 0) - return(NULL); + if (history(h, &ev, H_CURR) != 0) + return NULL; *cindex = idx; - rptr = ct_encode_string(ev.str, &conv); + rptr = ev.str; /* roll back to original position */ - (void)FUNW(history)(h, &ev, H_SET, num); + (void)history(h, &ev, H_SET, num); return rptr; } @@ -649,7 +667,8 @@ } else { if (command[offs + 1] == '#') { /* use command so far */ - if ((aptr = malloc(offs + 1)) == NULL) + if ((aptr = el_malloc((offs + 1) * sizeof(*aptr))) + == NULL) return -1; (void)strncpy(aptr, command, offs); aptr[offs] = '\0'; @@ -660,19 +679,19 @@ qchar = (offs > 0 && command[offs - 1] == '"')? '"':0; ptr = get_history_event(command + offs, &idx, qchar); } - has_mods = command[offs + idx] == ':'; + has_mods = command[offs + (size_t)idx] == ':'; } if (ptr == NULL && aptr == NULL) - return(-1); + return -1; if (!has_mods) { *result = strdup(aptr ? aptr : ptr); if (aptr) - free(aptr); + el_free(aptr); if (*result == NULL) return -1; - return(1); + return 1; } cmd = command + offs + idx + 1; @@ -717,18 +736,18 @@ (void)fprintf(rl_outstream, "%s: Bad word specifier", command + offs + idx); if (aptr) - free(aptr); - return(-1); + el_free(aptr); + return -1; } } else tmp = strdup(aptr? aptr:ptr); if (aptr) - free(aptr); + el_free(aptr); if (*cmd == '\0' || ((size_t)(cmd - (command + offs)) >= cmdlen)) { *result = tmp; - return(1); + return 1; } for (; *cmd; cmd++) { @@ -740,7 +759,7 @@ } else if (*cmd == 't') { /* remove leading path */ if ((aptr = strrchr(tmp, '/')) != NULL) { aptr = strdup(aptr + 1); - free(tmp); + el_free(tmp); tmp = aptr; } } else if (*cmd == 'r') { /* remove trailing suffix */ @@ -749,7 +768,7 @@ } else if (*cmd == 'e') { /* remove all but suffix */ if ((aptr = strrchr(tmp, '.')) != NULL) { aptr = strdup(aptr); - free(tmp); + el_free(tmp); tmp = aptr; } } else if (*cmd == 'p') /* print only */ @@ -766,10 +785,10 @@ else if (*cmd == 's') { delim = *(++cmd), cmd++; size = 16; - what = realloc(from, size); + what = el_realloc(from, size * sizeof(*what)); if (what == NULL) { - free(from); - free(tmp); + el_free(from); + el_free(tmp); return 0; } len = 0; @@ -778,11 +797,12 @@ cmd++; if (len >= size) { char *nwhat; - nwhat = realloc(what, - (size <<= 1)); + nwhat = el_realloc(what, + (size <<= 1) * + sizeof(*nwhat)); if (nwhat == NULL) { - free(what); - free(tmp); + el_free(what); + el_free(tmp); return 0; } what = nwhat; @@ -792,17 +812,17 @@ what[len] = '\0'; from = what; if (*what == '\0') { - free(what); + el_free(what); if (search) { from = strdup(search); if (from == NULL) { - free(tmp); + el_free(tmp); return 0; } } else { from = NULL; - free(tmp); - return (-1); + el_free(tmp); + return -1; } } cmd++; /* shift after delim */ @@ -810,10 +830,10 @@ continue; size = 16; - with = realloc(to, size); + with = el_realloc(to, size * sizeof(*with)); if (with == NULL) { - free(to); - free(tmp); + el_free(to); + el_free(tmp); return -1; } len = 0; @@ -822,10 +842,11 @@ if (len + from_len + 1 >= size) { char *nwith; size += from_len + 1; - nwith = realloc(with, size); + nwith = el_realloc(with, + size * sizeof(*nwith)); if (nwith == NULL) { - free(with); - free(tmp); + el_free(with); + el_free(tmp); return -1; } with = nwith; @@ -848,7 +869,7 @@ aptr = _rl_compat_sub(tmp, from, to, g_on); if (aptr) { - free(tmp); + el_free(tmp); tmp = aptr; } g_on = 0; @@ -855,7 +876,7 @@ } } *result = tmp; - return (p_on? 2:1); + return p_on? 2:1; } @@ -874,13 +895,13 @@ if (history_expansion_char == 0) { *output = strdup(str); - return(0); + return 0; } *output = NULL; if (str[0] == history_subst_char) { /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */ - *output = malloc(strlen(str) + 4 + 1); + *output = el_malloc((strlen(str) + 4 + 1) * sizeof(**output)); if (*output == NULL) return 0; (*output)[0] = (*output)[1] = history_expansion_char; @@ -897,11 +918,12 @@ #define ADD_STRING(what, len, fr) \ { \ if (idx + len + 1 > size) { \ - char *nresult = realloc(result, (size += len + 1));\ + char *nresult = el_realloc(result, \ + (size += len + 1) * sizeof(*nresult)); \ if (nresult == NULL) { \ - free(*output); \ + el_free(*output); \ if (/*CONSTCOND*/fr) \ - free(tmp); \ + el_free(tmp); \ return 0; \ } \ result = nresult; \ @@ -968,7 +990,7 @@ ADD_STRING(tmp, len, 1); } if (tmp) { - free(tmp); + el_free(tmp); tmp = NULL; } i = j; @@ -985,10 +1007,10 @@ ret = -1; #endif } - free(*output); + el_free(*output); *output = result; - return (ret); + return ret; } /* @@ -1023,14 +1045,14 @@ (size_t)end > max || start > end) goto out; - for (i = start, len = 0; i <= (size_t)end; i++) + for (i = (size_t)start, len = 0; i <= (size_t)end; i++) len += strlen(arr[i]) + 1; len++; - result = malloc(len); + result = el_malloc(len * sizeof(*result)); if (result == NULL) goto out; - for (i = start, len = 0; i <= (size_t)end; i++) { + for (i = (size_t)start, len = 0; i <= (size_t)end; i++) { (void)strcpy(result + len, arr[i]); len += strlen(arr[i]); if (i < (size_t)end) @@ -1040,8 +1062,8 @@ out: for (i = 0; arr[i]; i++) - free(arr[i]); - free(arr); + el_free(arr[i]); + el_free(arr); return result; } @@ -1080,19 +1102,19 @@ if (idx + 2 >= size) { char **nresult; size <<= 1; - nresult = realloc(result, size * sizeof(char *)); + nresult = el_realloc(result, (size_t)size * sizeof(*nresult)); if (nresult == NULL) { - free(result); + el_free(result); return NULL; } result = nresult; } - len = i - start; - temp = malloc(len + 1); + len = (size_t)i - (size_t)start; + temp = el_malloc((size_t)(len + 1) * sizeof(*temp)); if (temp == NULL) { for (i = 0; i < idx; i++) - free(result[i]); - free(result); + el_free(result[i]); + el_free(result); return NULL; } (void)strncpy(temp, &str[start], len); @@ -1102,7 +1124,7 @@ if (str[i]) i++; } - return (result); + return result; } @@ -1112,12 +1134,12 @@ void stifle_history(int max) { - TYPE(HistEvent) ev; + HistEvent ev; if (h == NULL || e == NULL) rl_initialize(); - if (FUNW(history)(h, &ev, H_SETSIZE, max) == 0) + if (history(h, &ev, H_SETSIZE, max) == 0) max_input_history = max; } @@ -1128,13 +1150,13 @@ int unstifle_history(void) { - TYPE(HistEvent) ev; + HistEvent ev; int omax; - FUNW(history)(h, &ev, H_SETSIZE, INT_MAX); + history(h, &ev, H_SETSIZE, INT_MAX); omax = max_input_history; max_input_history = INT_MAX; - return (omax); /* some value _must_ be returned */ + return omax; /* some value _must_ be returned */ } @@ -1143,7 +1165,7 @@ { /* cannot return true answer */ - return (max_input_history != INT_MAX); + return max_input_history != INT_MAX; } static const char _history_tmp_template[] = "/tmp/.historyXXXXXX"; @@ -1178,7 +1200,7 @@ } for(;;) { - if (fread(buf, sizeof(buf), 1, fp) != 1) { + if (fread(buf, sizeof(buf), (size_t)1, fp) != 1) { if (ferror(fp)) { ret = errno; break; @@ -1188,7 +1210,7 @@ ret = errno; break; } - left = fread(buf, 1, sizeof(buf), fp); + left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), fp); if (ferror(fp)) { ret = errno; break; @@ -1196,7 +1218,8 @@ if (left == 0) { count--; left = sizeof(buf); - } else if (fwrite(buf, (size_t)left, 1, tp) != 1) { + } else if (fwrite(buf, (size_t)left, (size_t)1, tp) + != 1) { ret = errno; break; } @@ -1203,7 +1226,7 @@ fflush(tp); break; } - if (fwrite(buf, sizeof(buf), 1, tp) != 1) { + if (fwrite(buf, sizeof(buf), (size_t)1, tp) != 1) { ret = errno; break; } @@ -1233,7 +1256,7 @@ ret = errno; break; } - if (fread(buf, sizeof(buf), 1, tp) != 1) { + if (fread(buf, sizeof(buf), (size_t)1, tp) != 1) { if (ferror(tp)) { ret = errno; break; @@ -1247,7 +1270,7 @@ if (ret || nlines > 0) goto out3; - if (fseeko(fp, 0, SEEK_SET) == (off_t)-1) { + if (fseeko(fp, (off_t)0, SEEK_SET) == (off_t)-1) { ret = errno; goto out3; } @@ -1259,12 +1282,12 @@ } for(;;) { - if ((left = fread(buf, 1, sizeof(buf), tp)) == 0) { + if ((left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), tp)) == 0) { if (ferror(fp)) ret = errno; break; } - if (fwrite(buf, (size_t)left, 1, fp) != 1) { + if (fwrite(buf, (size_t)left, (size_t)1, fp) != 1) { ret = errno; break; } @@ -1289,14 +1312,14 @@ int read_history(const char *filename) { - TYPE(HistEvent) ev; + HistEvent ev; if (h == NULL || e == NULL) rl_initialize(); if (filename == NULL && (filename = _default_history_file()) == NULL) return errno; - return (FUNW(history)(h, &ev, H_LOAD, filename) == -1 ? - (errno ? errno : EINVAL) : 0); + return history(h, &ev, H_LOAD, filename) == -1 ? + (errno ? errno : EINVAL) : 0; } @@ -1306,14 +1329,14 @@ int write_history(const char *filename) { - TYPE(HistEvent) ev; + HistEvent ev; if (h == NULL || e == NULL) rl_initialize(); if (filename == NULL && (filename = _default_history_file()) == NULL) return errno; - return (FUNW(history)(h, &ev, H_SAVE, filename) == -1 ? - (errno ? errno : EINVAL) : 0); + return history(h, &ev, H_SAVE, filename) == -1 ? + (errno ? errno : EINVAL) : 0; } @@ -1326,7 +1349,7 @@ history_get(int num) { static HIST_ENTRY she; - TYPE(HistEvent) ev; + HistEvent ev; int curr_num; if (h == NULL || e == NULL) @@ -1333,24 +1356,24 @@ rl_initialize(); /* save current position */ - if (FUNW(history)(h, &ev, H_CURR) != 0) - return (NULL); + if (history(h, &ev, H_CURR) != 0) + return NULL; curr_num = ev.num; /* start from the oldest */ - if (FUNW(history)(h, &ev, H_LAST) != 0) - return (NULL); /* error */ + if (history(h, &ev, H_LAST) != 0) + return NULL; /* error */ /* look forwards for event matching specified offset */ - if (FUNW(history)(h, &ev, H_NEXT_EVDATA, num, &she.data)) - return (NULL); + if (history(h, &ev, H_NEXT_EVDATA, num, &she.data)) + return NULL; - she.line = ct_encode_string(ev.str, &conv); + she.line = ev.str; /* restore pointer to where it was */ - (void)FUNW(history)(h, &ev, H_SET, curr_num); + (void)history(h, &ev, H_SET, curr_num); - return (&she); + return &she; } @@ -1360,8 +1383,7 @@ int add_history(const char *line) { - TYPE(HistEvent) ev; - const Char *wline; + HistEvent ev; if (line == NULL) return 0; @@ -1369,13 +1391,11 @@ if (h == NULL || e == NULL) rl_initialize(); - wline = ct_decode_string(line, &conv); - - (void)FUNW(history)(h, &ev, H_ENTER, wline); - if (FUNW(history)(h, &ev, H_GETSIZE) == 0) + (void)history(h, &ev, H_ENTER, line); + if (history(h, &ev, H_GETSIZE) == 0) history_length = ev.num; - return (!(history_length > 0)); /* return 0 if all is okay */ + return !(history_length > 0); /* return 0 if all is okay */ } @@ -1386,21 +1406,21 @@ remove_history(int num) { HIST_ENTRY *he; - TYPE(HistEvent) ev; + HistEvent ev; if (h == NULL || e == NULL) rl_initialize(); - if ((he = malloc(sizeof(*he))) == NULL) + if ((he = el_malloc(sizeof(*he))) == NULL) return NULL; - if (FUNW(history)(h, &ev, H_DELDATA, num, &he->data) != 0) { - free(he); + if (history(h, &ev, H_DELDATA, num, &he->data) != 0) { + el_free(he); return NULL; } - he->line = ct_encode_string(ev.str, &conv); - if (FUNW(history)(h, &ev, H_GETSIZE) == 0) + he->line = ev.str; + if (history(h, &ev, H_GETSIZE) == 0) history_length = ev.num; return he; @@ -1414,7 +1434,7 @@ replace_history_entry(int num, const char *line, histdata_t data) { HIST_ENTRY *he; - TYPE(HistEvent) ev; + HistEvent ev; int curr_num; if (h == NULL || e == NULL) @@ -1421,35 +1441,35 @@ rl_initialize(); /* save current position */ - if (FUNW(history)(h, &ev, H_CURR) != 0) + if (history(h, &ev, H_CURR) != 0) return NULL; curr_num = ev.num; /* start from the oldest */ - if (FUNW(history)(h, &ev, H_LAST) != 0) + if (history(h, &ev, H_LAST) != 0) return NULL; /* error */ - if ((he = malloc(sizeof(*he))) == NULL) + if ((he = el_malloc(sizeof(*he))) == NULL) return NULL; /* look forwards for event matching specified offset */ - if (FUNW(history)(h, &ev, H_NEXT_EVDATA, num, &he->data)) + if (history(h, &ev, H_NEXT_EVDATA, num, &he->data)) goto out; - he->line = strdup(ct_encode_string(ev.str, &e->el_scratch)); + he->line = strdup(ev.str); if (he->line == NULL) goto out; - if (FUNW(history)(h, &ev, H_REPLACE, line, data)) + if (history(h, &ev, H_REPLACE, line, data)) goto out; /* restore pointer to where it was */ - if (FUNW(history)(h, &ev, H_SET, curr_num)) + if (history(h, &ev, H_SET, curr_num)) goto out; return he; out: - free(he); + el_free(he); return NULL; } @@ -1459,9 +1479,9 @@ void clear_history(void) { - TYPE(HistEvent) ev; + HistEvent ev; - (void)FUNW(history)(h, &ev, H_CLEAR); + (void)history(h, &ev, H_CLEAR); history_length = 0; } @@ -1472,19 +1492,19 @@ int where_history(void) { - TYPE(HistEvent) ev; + HistEvent ev; int curr_num, off; - if (FUNW(history)(h, &ev, H_CURR) != 0) - return (0); + if (history(h, &ev, H_CURR) != 0) + return 0; curr_num = ev.num; - (void)FUNW(history)(h, &ev, H_FIRST); + (void)history(h, &ev, H_FIRST); off = 1; - while (ev.num != curr_num && FUNW(history)(h, &ev, H_NEXT) == 0) + while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0) off++; - return (off); + return off; } @@ -1495,7 +1515,7 @@ current_history(void) { - return (_move_history(H_CURR)); + return _move_history(H_CURR); } @@ -1505,24 +1525,24 @@ int history_total_bytes(void) { - TYPE(HistEvent) ev; + HistEvent ev; int curr_num; size_t size; - if (FUNW(history)(h, &ev, H_CURR) != 0) - return (-1); + if (history(h, &ev, H_CURR) != 0) + return -1; curr_num = ev.num; - (void)FUNW(history)(h, &ev, H_FIRST); + (void)history(h, &ev, H_FIRST); size = 0; do - size += Strlen(ev.str) * sizeof(*ev.str); - while (FUNW(history)(h, &ev, H_NEXT) == 0); + size += strlen(ev.str) * sizeof(*ev.str); + while (history(h, &ev, H_NEXT) == 0); /* get to the same position as before */ - FUNW(history)(h, &ev, H_PREV_EVENT, curr_num); + history(h, &ev, H_PREV_EVENT, curr_num); - return (int)(size); + return (int)size; } @@ -1532,13 +1552,13 @@ int history_set_pos(int pos) { - TYPE(HistEvent) ev; + HistEvent ev; int curr_num; if (pos >= history_length || pos < 0) - return (-1); + return -1; - (void)FUNW(history)(h, &ev, H_CURR); + (void)history(h, &ev, H_CURR); curr_num = ev.num; /* @@ -1545,11 +1565,11 @@ * use H_DELDATA to set to nth history (without delete) by passing * (void **)-1 */ - if (FUNW(history)(h, &ev, H_DELDATA, pos, (void **)-1)) { - (void)FUNW(history)(h, &ev, H_SET, curr_num); - return(-1); + if (history(h, &ev, H_DELDATA, pos, (void **)-1)) { + (void)history(h, &ev, H_SET, curr_num); + return -1; } - return (0); + return 0; } @@ -1560,7 +1580,7 @@ previous_history(void) { - return (_move_history(H_PREV)); + return _move_history(H_PREV); } @@ -1571,7 +1591,7 @@ next_history(void) { - return (_move_history(H_NEXT)); + return _move_history(H_NEXT); } @@ -1581,24 +1601,22 @@ int history_search(const char *str, int direction) { - TYPE(HistEvent) ev; - const Char *strp; - const Char *wstr; + HistEvent ev; + const char *strp; int curr_num; - if (FUNW(history)(h, &ev, H_CURR) != 0) - return (-1); + if (history(h, &ev, H_CURR) != 0) + return -1; curr_num = ev.num; - wstr = ct_decode_string(str, &conv); for (;;) { - if ((strp = Strstr(ev.str, wstr)) != NULL) - return (int) (strp - ev.str); - if (FUNW(history)(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0) + if ((strp = strstr(ev.str, str)) != NULL) + return (int)(strp - ev.str); + if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0) break; } - (void)FUNW(history)(h, &ev, H_SET, curr_num); - return (-1); + (void)history(h, &ev, H_SET, curr_num); + return -1; } @@ -1608,9 +1626,9 @@ int history_search_prefix(const char *str, int direction) { - TYPE(HistEvent) ev; + HistEvent ev; - return (FUNW(history)(h, &ev, direction < 0 ? + return (history(h, &ev, direction < 0 ? H_PREV_STR : H_NEXT_STR, str)); } @@ -1624,33 +1642,31 @@ history_search_pos(const char *str, int direction __attribute__((__unused__)), int pos) { - TYPE(HistEvent) ev; + HistEvent ev; int curr_num, off; - const Char *wstr; off = (pos > 0) ? pos : -pos; pos = (pos > 0) ? 1 : -1; - if (FUNW(history)(h, &ev, H_CURR) != 0) - return (-1); + if (history(h, &ev, H_CURR) != 0) + return -1; curr_num = ev.num; - if (history_set_pos(off) != 0 || FUNW(history)(h, &ev, H_CURR) != 0) - return (-1); + if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0) + return -1; - wstr = ct_decode_string(str, &conv); for (;;) { - if (Strstr(ev.str, wstr)) - return (off); - if (FUNW(history)(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0) + if (strstr(ev.str, str)) + return off; + if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0) break; } /* set "current" pointer back to previous state */ - (void)FUNW(history)(h, &ev, + (void)history(h, &ev, pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); - return (-1); + return -1; } @@ -1673,17 +1689,20 @@ * a completion generator for usernames; returns _first_ username * which starts with supplied text * text contains a partial username preceded by random character - * (usually '~'); state is ignored + * (usually '~'); state resets search from start (??? should we do that anyway) * it's callers responsibility to free returned value */ char * username_completion_function(const char *text, int state) { - struct passwd *pwd, pwres; +#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT) + struct passwd pwres; char pwbuf[1024]; +#endif + struct passwd *pass = NULL; if (text[0] == '\0') - return (NULL); + return NULL; if (*text == '~') text++; @@ -1691,15 +1710,21 @@ if (state == 0) setpwent(); - while (getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pwd) == 0 - && pwd != NULL && text[0] == pwd->pw_name[0] - && strcmp(text, pwd->pw_name) == 0); + while ( +#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT) + getpwent_r(&pwres, pwbuf, sizeof(pwbuf), &pass) == 0 && pass != NULL +#else + (pass = getpwent()) != NULL +#endif + && text[0] == pass->pw_name[0] + && strcmp(text, pass->pw_name) == 0) + continue; - if (pwd == NULL) { + if (pass == NULL) { endpwent(); return NULL; } - return strdup(pwd->pw_name); + return strdup(pass->pw_name); } @@ -1732,7 +1757,7 @@ __attribute__((__unused__))) { static char buf[2]; - buf[0] = rl_completion_append_character; + buf[0] = (char)rl_completion_append_character; buf[1] = '\0'; return buf; } @@ -1748,6 +1773,7 @@ #ifdef WIDECHAR static ct_buffer_t wbreak_conv, sprefix_conv; #endif + char *breakchars; if (h == NULL || e == NULL) rl_initialize(); @@ -1757,19 +1783,26 @@ arr[0] = (char)invoking_key; arr[1] = '\0'; el_insertstr(e, arr); - return (CC_REFRESH); + return CC_REFRESH; } + if (rl_completion_word_break_hook != NULL) + breakchars = (*rl_completion_word_break_hook)(); + else + breakchars = rl_basic_word_break_characters; + /* Just look at how many global variables modify this operation! */ return fn_complete(e, (CPFunction *)rl_completion_entry_function, rl_attempted_completion_function, ct_decode_string(rl_basic_word_break_characters, &wbreak_conv), - ct_decode_string(rl_special_prefixes, &sprefix_conv), + ct_decode_string(breakchars, &sprefix_conv), _rl_completion_append_character_function, (size_t)rl_completion_query_items, &rl_completion_type, &rl_attempted_completion_over, - &rl_point, &rl_end, NULL, NULL, NULL); + &rl_point, &rl_end); + + } @@ -1800,7 +1833,7 @@ e->el_map.key[c] = ED_INSERT; retval = 0; } - return (retval); + return retval; } @@ -1816,7 +1849,7 @@ if (e == NULL || h == NULL) rl_initialize(); - return (el_getc(e, fooarr)); + return el_getc(e, fooarr); } @@ -1846,13 +1879,13 @@ rl_initialize(); /* XXX - int -> char conversion can lose on multichars */ - arr[0] = c; + arr[0] = (char)c; arr[1] = '\0'; for (; count > 0; count--) el_push(e, arr); - return (0); + return 0; } int @@ -1859,19 +1892,20 @@ rl_insert_text(const char *text) { if (!text || *text == 0) - return (0); + return 0; if (h == NULL || e == NULL) rl_initialize(); if (el_insertstr(e, text) < 0) - return (0); + return 0; return (int)strlen(text); } /*ARGSUSED*/ int -rl_newline(int count, int c) +rl_newline(int count __attribute__((__unused__)), + int c __attribute__((__unused__))) { /* * Readline-4.0 appears to ignore the args. @@ -1881,7 +1915,7 @@ /*ARGSUSED*/ static unsigned char -rl_bind_wrapper(EditLine *el, unsigned char c) +rl_bind_wrapper(EditLine *el __attribute__((__unused__)), unsigned char c) { if (map[c] == NULL) return CC_ERROR; @@ -1906,12 +1940,12 @@ map[(unsigned char)c] = fun; el_set(e, EL_ADDFN, name, name, rl_bind_wrapper); vis(dest, c, VIS_WHITE|VIS_NOSLASH, 0); - el_set(e, EL_BIND, dest, name); + el_set(e, EL_BIND, dest, name, NULL); return 0; } void -rl_callback_read_char() +rl_callback_read_char(void) { int count = 0, done = 0; const char *buf = el_gets(e, &count); @@ -1958,7 +1992,7 @@ rl_redisplay(void) { char a[2]; - a[0] = e->el_tty.t_c[TS_IO][C_REPRINT]; + a[0] = (char)e->el_tty.t_c[TS_IO][C_REPRINT]; a[1] = '\0'; el_push(e, a); } @@ -1967,7 +2001,7 @@ rl_get_previous_history(int count, int key) { char a[2]; - a[0] = key; + a[0] = (char)key; a[1] = '\0'; while (count--) el_push(e, a); @@ -1976,7 +2010,7 @@ void /*ARGSUSED*/ -rl_prep_terminal(int meta_flag) +rl_prep_terminal(int meta_flag __attribute__((__unused__))) { el_set(e, EL_PREP_TERM, 1); } @@ -1990,7 +2024,7 @@ int rl_read_init_file(const char *s) { - return(el_source(e, s)); + return el_source(e, s); } int @@ -2004,7 +2038,7 @@ tok_str(tok, line, &argc, &argv); argc = el_parse(e, argc, argv); tok_end(tok); - return (argc ? 1 : 0); + return argc ? 1 : 0; } int @@ -2014,7 +2048,7 @@ * The proper return value is undocument, but this is what the * readline source seems to do. */ - return ((el_set(e, EL_BIND, "", var, value) == -1) ? 1 : 0); + return el_set(e, EL_BIND, "", var, value, NULL) == -1 ? 1 : 0; } void @@ -2022,7 +2056,7 @@ { char buf[2]; - buf[0] = c; + buf[0] = (char)c; buf[1] = '\0'; el_insertstr(e, buf); } @@ -2040,23 +2074,23 @@ #if defined(FIONREAD) if (ioctl(el->el_infd, FIONREAD, &n) < 0) - return(-1); + return -1; if (n) - num_read = read(el->el_infd, cp, 1); + num_read = read(el->el_infd, cp, (size_t)1); else num_read = 0; #elif defined(F_SETFL) && defined(O_NDELAY) if ((n = fcntl(el->el_infd, F_GETFL, 0)) < 0) - return(-1); + return -1; if (fcntl(el->el_infd, F_SETFL, n|O_NDELAY) < 0) - return(-1); + return -1; num_read = read(el->el_infd, cp, 1); if (fcntl(el->el_infd, F_SETFL, n)) - return(-1); + return -1; #else /* not non-blocking, but what you gonna do? */ num_read = read(el->el_infd, cp, 1); - return(-1); + return -1; #endif if (num_read < 0 && errno == EAGAIN) @@ -2083,9 +2117,9 @@ rl_get_screen_size(int *rows, int *cols) { if (rows) - el_get(e, EL_GETTC, "li", rows); + el_get(e, EL_GETTC, "li", rows, (void *)0); if (cols) - el_get(e, EL_GETTC, "co", cols); + el_get(e, EL_GETTC, "co", cols, (void *)0); } void @@ -2093,9 +2127,9 @@ { char buf[64]; (void)snprintf(buf, sizeof(buf), "%d", rows); - el_set(e, EL_SETTC, "li", buf); + el_set(e, EL_SETTC, "li", buf, NULL); (void)snprintf(buf, sizeof(buf), "%d", cols); - el_set(e, EL_SETTC, "co", buf); + el_set(e, EL_SETTC, "co", buf, NULL); } char ** @@ -2106,7 +2140,7 @@ len = 1; max = 10; - if ((list = malloc(max * sizeof(*list))) == NULL) + if ((list = el_malloc(max * sizeof(*list))) == NULL) return NULL; while ((match = (*fun)(str, (int)(len - 1))) != NULL) { @@ -2114,7 +2148,7 @@ if (len == max) { char **nl; max += 10; - if ((nl = realloc(list, max * sizeof(*nl))) == NULL) + if ((nl = el_realloc(list, max * sizeof(*nl))) == NULL) goto out; list = nl; } @@ -2141,7 +2175,7 @@ if ((list[0] = strdup(str)) == NULL) goto out; } else { - if ((list[0] = malloc(min + 1)) == NULL) + if ((list[0] = el_malloc((min + 1) * sizeof(*list[0]))) == NULL) goto out; (void)memcpy(list[0], list[1], min); list[0][min] = '\0'; @@ -2149,7 +2183,7 @@ return list; out: - free(list); + el_free(list); return NULL; } @@ -2184,15 +2218,16 @@ { HISTORY_STATE *hs; - if ((hs = malloc(sizeof(HISTORY_STATE))) == NULL) - return (NULL); + if ((hs = el_malloc(sizeof(*hs))) == NULL) + return NULL; hs->length = history_length; - return (hs); + return hs; } int /*ARGSUSED*/ -rl_kill_text(int from, int to) +rl_kill_text(int from __attribute__((__unused__)), + int to __attribute__((__unused__))) { return 0; } @@ -2211,13 +2246,16 @@ void /*ARGSUSED*/ -rl_set_keymap(Keymap k) +rl_set_keymap(Keymap k __attribute__((__unused__))) { } int /*ARGSUSED*/ -rl_generic_bind(int type, const char * keyseq, const char * data, Keymap k) +rl_generic_bind(int type __attribute__((__unused__)), + const char * keyseq __attribute__((__unused__)), + const char * data __attribute__((__unused__)), + Keymap k __attribute__((__unused__))) { return 0; } @@ -2224,7 +2262,9 @@ int /*ARGSUSED*/ -rl_bind_key_in_map(int key, rl_command_func_t *fun, Keymap k) +rl_bind_key_in_map(int key __attribute__((__unused__)), + rl_command_func_t *fun __attribute__((__unused__)), + Keymap k __attribute__((__unused__))) { return 0; } @@ -2240,3 +2280,8 @@ { return 0; } + +void +rl_free_line_state(void) +{ +} Index: lib/libedit/refresh.c =================================================================== --- lib/libedit/refresh.c (revision 258914) +++ lib/libedit/refresh.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: refresh.c,v 1.37 2011/07/29 23:44:45 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: refresh.c,v 1.34 2009/12/28 22:15:36 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -41,7 +42,6 @@ /* * refresh.c: Lower level screen refreshing functions */ -#include "sys.h" #include #include #include @@ -50,14 +50,14 @@ #include "el.h" private void re_nextline(EditLine *); -private void re_addc(EditLine *, int); -private void re_update_line(EditLine *, char *, char *, int); -private void re_insert (EditLine *, char *, int, int, char *, int); -private void re_delete(EditLine *, char *, int, int, int); -private void re_fastputc(EditLine *, int); +private void re_addc(EditLine *, Int); +private void re_update_line(EditLine *, Char *, Char *, int); +private void re_insert (EditLine *, Char *, int, int, Char *, int); +private void re_delete(EditLine *, Char *, int, int, int); +private void re_fastputc(EditLine *, Int); private void re_clear_eol(EditLine *, int, int, int); -private void re__strncopy(char *, char *, size_t); -private void re__copy_and_pad(char *, const char *, size_t); +private void re__strncopy(Char *, Char *, size_t); +private void re__copy_and_pad(Char *, const Char *, size_t); #ifdef DEBUG_REFRESH private void re_printstr(EditLine *, const char *, char *, char *); @@ -101,9 +101,9 @@ * 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]; + 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]; @@ -113,9 +113,9 @@ } else el->el_refresh.r_cursor.v++; - ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_term.t_size.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_term.t_size.v), + el->el_refresh.r_cursor.v, el->el_terminal.t_size.v), abort()); } @@ -123,39 +123,35 @@ * Draw c, expanding tabs, control chars etc. */ private void -re_addc(EditLine *el, int c) +re_addc(EditLine *el, Int c) { - - if (isprint(c)) { - re_putc(el, c, 1); - return; - } - if (c == '\n') { /* expand the newline */ - int oldv = el->el_refresh.r_cursor.v; - re_putc(el, '\0', 0); /* assure end of line */ - if (oldv == el->el_refresh.r_cursor.v) /* XXX */ - re_nextline(el); - return; - } - if (c == '\t') { /* expand the tab */ + switch (ct_chr_class((Char)c)) { + case CHTYPE_TAB: /* expand the tab */ for (;;) { re_putc(el, ' ', 1); if ((el->el_refresh.r_cursor.h & 07) == 0) break; /* go until tab stop */ } - } else if (iscntrl(c)) { - re_putc(el, '^', 1); - if (c == 0177) - re_putc(el, '?', 1); - else - /* uncontrolify it; works only for iso8859-1 like sets */ - re_putc(el, (toascii(c) | 0100), 1); - } else { - re_putc(el, '\\', 1); - re_putc(el, (int) ((((unsigned int) c >> 6) & 07) + '0'), 1); - re_putc(el, (int) ((((unsigned int) c >> 3) & 07) + '0'), 1); - re_putc(el, (c & 07) + '0', 1); + break; + case CHTYPE_NL: { + int oldv = el->el_refresh.r_cursor.v; + re_putc(el, '\0', 0); /* assure end of line */ + if (oldv == el->el_refresh.r_cursor.v) /* XXX */ + re_nextline(el); + break; } + case CHTYPE_PRINT: + re_putc(el, c, 1); + break; + default: { + Char visbuf[VISUAL_WIDTH_MAX]; + ssize_t i, n = + ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c); + for (i = 0; n-- > 0; ++i) + re_putc(el, visbuf[i], 1); + break; + } + } } @@ -163,23 +159,32 @@ * Draw the character given */ protected void -re_putc(EditLine *el, int c, int shift) +re_putc(EditLine *el, Int c, int shift) { + int i, w = Width(c); + ELRE_DEBUG(1, (__F, "printing %5x '%c'\r\n", c, c)); - ELRE_DEBUG(1, (__F, "printing %3.3o '%c'\r\n", c, c)); + while (shift && (el->el_refresh.r_cursor.h + w > el->el_terminal.t_size.h)) + re_putc(el, ' ', 1); - el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_refresh.r_cursor.h] = c; + 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; + if (!shift) return; - el->el_refresh.r_cursor.h++; /* advance to next place */ - if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) { + el->el_refresh.r_cursor.h += w; /* advance to next place */ + if (el->el_refresh.r_cursor.h >= el->el_terminal.t_size.h) { /* assure end of line */ - el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h] + el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_terminal.t_size.h] = '\0'; re_nextline(el); } - } @@ -193,7 +198,7 @@ re_refresh(EditLine *el) { int i, rhdiff; - char *cp, *st; + Char *cp, *st; coord_t cur; #ifdef notyet size_t termsz; @@ -228,7 +233,7 @@ /* draw the current input buffer */ #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 line is longer than terminal, process only part @@ -237,8 +242,8 @@ size_t rem = (el->el_line.lastchar-el->el_line.buffer)%termsz; st = el->el_line.lastchar - rem - - (termsz - (((rem / el->el_term.t_size.v) - 1) - * el->el_term.t_size.v)); + - (termsz - (((rem / el->el_terminal.t_size.v) - 1) + * el->el_terminal.t_size.v)); } else #endif st = el->el_line.buffer; @@ -245,11 +250,18 @@ for (cp = st; cp < el->el_line.lastchar; cp++) { if (cp == el->el_line.cursor) { + int w = Width(*cp); /* save for later */ cur.h = el->el_refresh.r_cursor.h; cur.v = el->el_refresh.r_cursor.v; + /* handle being at a linebroken doublewidth char */ + if (w > 1 && el->el_refresh.r_cursor.h + w > + el->el_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 */ @@ -256,7 +268,7 @@ cur.h = el->el_refresh.r_cursor.h; cur.v = el->el_refresh.r_cursor.v; } - rhdiff = el->el_term.t_size.h - el->el_refresh.r_cursor.h - + rhdiff = el->el_terminal.t_size.h - el->el_refresh.r_cursor.h - el->el_rprompt.p_pos.h; if (el->el_rprompt.p_pos.h && !el->el_rprompt.p_pos.v && !el->el_refresh.r_cursor.v && rhdiff > 1) { @@ -279,8 +291,8 @@ ELRE_DEBUG(1, (__F, "term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n", - el->el_term.t_size.h, el->el_refresh.r_cursor.h, - el->el_refresh.r_cursor.v, el->el_vdisplay[0])); + el->el_terminal.t_size.h, el->el_refresh.r_cursor.h, + el->el_refresh.r_cursor.v, ct_encode_string(el->el_vdisplay[0]))); ELRE_DEBUG(1, (__F, "updating %d lines.\r\n", el->el_refresh.r_newcv)); for (i = 0; i <= el->el_refresh.r_newcv; i++) { @@ -295,7 +307,7 @@ * leftover stuff. */ 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, "\r\nel->el_refresh.r_cursor.v=%d,el->el_refresh.r_oldcv=%d i=%d\r\n", @@ -303,11 +315,12 @@ if (el->el_refresh.r_oldcv > el->el_refresh.r_newcv) for (; i <= el->el_refresh.r_oldcv; i++) { - term_move_to_line(el, i); - term_move_to_char(el, 0); - term_clear_EOL(el, (int) strlen(el->el_display[i])); + terminal_move_to_line(el, i); + terminal_move_to_char(el, 0); + /* This Strlen should be safe even with MB_FILL_CHARs */ + terminal_clear_EOL(el, (int) Strlen(el->el_display[i])); #ifdef DEBUG_REFRESH - term_overwrite(el, "C\b", (size_t)2); + terminal_overwrite(el, "C\b", (size_t)2); #endif /* DEBUG_REFRESH */ el->el_display[i][0] = '\0'; } @@ -317,8 +330,8 @@ "\r\ncursor.h = %d, cursor.v = %d, cur.h = %d, cur.v = %d\r\n", el->el_refresh.r_cursor.h, el->el_refresh.r_cursor.v, cur.h, cur.v)); - term_move_to_line(el, cur.v); /* go to where the cursor is */ - term_move_to_char(el, cur.h); + terminal_move_to_line(el, cur.v); /* go to where the cursor is */ + terminal_move_to_char(el, cur.h); } @@ -329,10 +342,10 @@ re_goto_bottom(EditLine *el) { - term_move_to_line(el, el->el_refresh.r_oldcv); - term__putc(el, '\n'); + terminal_move_to_line(el, el->el_refresh.r_oldcv); + terminal__putc(el, '\n'); re_clear_display(el); - term__flush(el); + terminal__flush(el); } @@ -342,10 +355,10 @@ */ private void /*ARGSUSED*/ -re_insert(EditLine *el __unused, - char *d, int dat, int dlen, char *s, int num) +re_insert(EditLine *el __attribute__((__unused__)), + Char *d, int dat, int dlen, Char *s, int num) { - char *a, *b; + Char *a, *b; if (num <= 0) return; @@ -354,8 +367,8 @@ ELRE_DEBUG(1, (__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, d)); - ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); + num, dat, dlen, ct_encode_string(d))); + ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s))); /* open up the space for num chars */ if (num > 0) { @@ -365,19 +378,24 @@ *b-- = *a--; d[dlen] = '\0'; /* just in case */ } + ELRE_DEBUG(1, (__F, "re_insert() after insert: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, d)); - ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); + num, dat, dlen, ct_encode_string(d))); + ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s))); /* copy the characters */ for (a = d + dat; (a < d + dlen) && (num > 0); num--) *a++ = *s++; +#ifdef notyet + /* ct_encode_string() uses a static buffer, so we can't conveniently + * encode both d & s here */ ELRE_DEBUG(1, (__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n", num, dat, dlen, d, s)); ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); +#endif } @@ -386,10 +404,10 @@ */ private void /*ARGSUSED*/ -re_delete(EditLine *el __unused, - char *d, int dat, int dlen, int num) +re_delete(EditLine *el __attribute__((__unused__)), + Char *d, int dat, int dlen, int num) { - char *a, *b; + Char *a, *b; if (num <= 0) return; @@ -399,7 +417,7 @@ } ELRE_DEBUG(1, (__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, d)); + num, dat, dlen, ct_encode_string(d))); /* open up the space for num chars */ if (num > 0) { @@ -411,7 +429,7 @@ } ELRE_DEBUG(1, (__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, d)); + num, dat, dlen, ct_encode_string(d))); } @@ -419,7 +437,7 @@ * Like strncpy without padding. */ private void -re__strncopy(char *a, char *b, size_t n) +re__strncopy(Char *a, Char *b, size_t n) { while (n-- && *b) @@ -430,7 +448,7 @@ * Find the number of characters we need to clear till the end of line * in order to make sure that we have cleared the previous contents of * the line. fx and sx is the number of characters inserted or deleted - * int the first or second diff, diff is the difference between the + * in the first or second diff, diff is the difference between the * number of characters between the new and old line. */ private void @@ -450,7 +468,7 @@ diff = sx; ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff)); - term_clear_EOL(el, diff); + terminal_clear_EOL(el, diff); } /***************************************************************** @@ -478,11 +496,11 @@ #define MIN_END_KEEP 4 private void -re_update_line(EditLine *el, char *old, char *new, int i) +re_update_line(EditLine *el, Char *old, Char *new, int i) { - char *o, *n, *p, c; - char *ofd, *ols, *oe, *nfd, *nls, *ne; - char *osb, *ose, *nsb, *nse; + Char *o, *n, *p, c; + Char *ofd, *ols, *oe, *nfd, *nls, *ne; + Char *osb, *ose, *nsb, *nse; int fx, sx; size_t len; @@ -697,7 +715,7 @@ * don't have to change the line, we don't move to it. el_cursor.h to * first diff char */ - term_move_to_line(el, i); + terminal_move_to_line(el, i); /* * at this point we have something like this: @@ -721,7 +739,7 @@ * if we have a net insert on the first difference, AND inserting the * net amount ((nsb-nfd) - (osb-ofd)) won't push the last useful * character (which is ne if nls != ne, otherwise is nse) off the edge - * of the screen (el->el_term.t_size.h) else we do the deletes first + * of the screen (el->el_terminal.t_size.h) else we do the deletes first * so that we keep everything we need to. */ @@ -743,13 +761,13 @@ * No insert or delete */ 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, (__F, "first diff insert at %d...\r\n", nfd - new)); /* * Move to the first char to insert, where the first diff is. */ - term_move_to_char(el, (int)(nfd - new)); + terminal_move_to_char(el, (int)(nfd - new)); /* * Check if we have stuff to keep at end */ @@ -761,9 +779,9 @@ if (fx > 0) { ELRE_DEBUG(!EL_CAN_INSERT, (__F, "ERROR: cannot insert in early first diff\n")); - term_insertwrite(el, nfd, fx); + terminal_insertwrite(el, nfd, fx); 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 @@ -770,12 +788,12 @@ * (nfd + fx) */ len = (size_t) ((nsb - nfd) - fx); - term_overwrite(el, (nfd + fx), len); + terminal_overwrite(el, (nfd + fx), len); re__strncopy(ofd + fx, nfd + fx, len); } else { ELRE_DEBUG(1, (__F, "without anything to save\r\n")); len = (size_t)(nsb - nfd); - term_overwrite(el, nfd, len); + terminal_overwrite(el, nfd, len); re__strncopy(ofd, nfd, len); /* * Done @@ -788,7 +806,7 @@ /* * move to the first char to delete where the first diff is */ - term_move_to_char(el, (int)(ofd - old)); + terminal_move_to_char(el, (int)(ofd - old)); /* * Check if we have stuff to save */ @@ -801,15 +819,15 @@ if (fx < 0) { ELRE_DEBUG(!EL_CAN_DELETE, (__F, "ERROR: cannot delete in first diff\n")); - term_deletechars(el, -fx); + terminal_deletechars(el, -fx); 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 */ len = (size_t) (nsb - nfd); - term_overwrite(el, nfd, len); + terminal_overwrite(el, nfd, len); re__strncopy(ofd, nfd, len); } else { @@ -818,7 +836,7 @@ /* * write (nsb-nfd) chars of new starting at nfd */ - term_overwrite(el, nfd, (size_t)(nsb - nfd)); + terminal_overwrite(el, nfd, (size_t)(nsb - nfd)); re_clear_eol(el, fx, sx, (int)((oe - old) - (ne - new))); /* @@ -829,7 +847,7 @@ } else 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, "second diff delete at %d...\r\n", (ose - old) + fx)); /* @@ -839,7 +857,7 @@ * fx is the number of characters inserted (+) or deleted (-) */ - term_move_to_char(el, (int)((ose - old) + fx)); + terminal_move_to_char(el, (int)((ose - old) + fx)); /* * Check if we have stuff to save */ @@ -851,16 +869,16 @@ if (sx < 0) { ELRE_DEBUG(!EL_CAN_DELETE, (__F, "ERROR: cannot delete in second diff\n")); - term_deletechars(el, -sx); + terminal_deletechars(el, -sx); } /* * write (nls-nse) chars of new starting at nse */ - term_overwrite(el, nse, (size_t)(nls - nse)); + terminal_overwrite(el, nse, (size_t)(nls - nse)); } else { ELRE_DEBUG(1, (__F, "but with nothing left to save\r\n")); - term_overwrite(el, nse, (size_t)(nls - nse)); + terminal_overwrite(el, nse, (size_t)(nls - nse)); re_clear_eol(el, fx, sx, (int)((oe - old) - (ne - new))); } @@ -872,7 +890,7 @@ ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n", nfd - new)); - term_move_to_char(el, (int)(nfd - new)); + terminal_move_to_char(el, (int)(nfd - new)); /* * Check if we have stuff to keep at the end */ @@ -890,9 +908,9 @@ */ ELRE_DEBUG(!EL_CAN_INSERT, (__F, "ERROR: cannot insert in late first diff\n")); - term_insertwrite(el, nfd, fx); + terminal_insertwrite(el, nfd, fx); 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 @@ -899,12 +917,12 @@ * (nfd + fx) */ len = (size_t) ((nsb - nfd) - fx); - term_overwrite(el, (nfd + fx), len); + terminal_overwrite(el, (nfd + fx), len); re__strncopy(ofd + fx, nfd + fx, len); } else { ELRE_DEBUG(1, (__F, "without anything to save\r\n")); len = (size_t) (nsb - nfd); - term_overwrite(el, nfd, len); + terminal_overwrite(el, nfd, len); re__strncopy(ofd, nfd, len); } } @@ -914,7 +932,7 @@ if (sx >= 0) { ELRE_DEBUG(1, (__F, "second diff insert at %d...\r\n", (int)(nse - new))); - term_move_to_char(el, (int)(nse - new)); + terminal_move_to_char(el, (int)(nse - new)); if (ols != oe) { ELRE_DEBUG(1, (__F, "with stuff to keep at end\r\n")); if (sx > 0) { @@ -921,17 +939,17 @@ /* insert sx chars of new starting at nse */ ELRE_DEBUG(!EL_CAN_INSERT, (__F, "ERROR: cannot insert in second diff\n")); - term_insertwrite(el, nse, sx); + terminal_insertwrite(el, nse, sx); } /* * write (nls-nse) - sx chars of new starting at * (nse + sx) */ - term_overwrite(el, (nse + sx), + terminal_overwrite(el, (nse + sx), (size_t)((nls - nse) - sx)); } else { ELRE_DEBUG(1, (__F, "without anything to save\r\n")); - term_overwrite(el, nse, (size_t)(nls - nse)); + terminal_overwrite(el, nse, (size_t)(nls - nse)); /* * No need to do a clear-to-end here because we were @@ -948,7 +966,7 @@ * Copy string and pad with spaces */ private void -re__copy_and_pad(char *dst, const char *src, size_t width) +re__copy_and_pad(Char *dst, const Char *src, size_t width) { size_t i; @@ -971,8 +989,8 @@ protected void re_refresh_cursor(EditLine *el) { - char *cp, c; - int h, v, th; + Char *cp; + int h, v, th, w; if (el->el_line.cursor >= el->el_line.lastchar) { if (el->el_map.current == el->el_map.alt @@ -985,30 +1003,28 @@ /* first we must find where the cursor is... */ h = el->el_prompt.p_pos.h; v = el->el_prompt.p_pos.v; - th = el->el_term.t_size.h; /* optimize for speed */ + th = el->el_terminal.t_size.h; /* optimize for speed */ /* do input buffer to el->el_line.cursor */ for (cp = el->el_line.buffer; cp < el->el_line.cursor; cp++) { - c = *cp; - - switch (c) { - case '\n': /* handle newline in data part too */ + switch (ct_chr_class(*cp)) { + case CHTYPE_NL: /* handle newline in data part too */ h = 0; v++; break; - case '\t': /* if a tab, to next tab stop */ + case CHTYPE_TAB: /* if a tab, to next tab stop */ while (++h & 07) continue; break; default: - if (iscntrl((unsigned char) c)) - h += 2; /* ^x */ - else if (!isprint((unsigned char) c)) - h += 4; /* octal \xxx */ - else - h++; + w = Width(*cp); + if (w > 1 && h + w > th) { /* won't fit on line */ + h = 0; + v++; + } + h += ct_visual_width(*cp); break; - } + } if (h >= th) { /* check, extra long tabs picked up here also */ h -= th; @@ -1015,11 +1031,18 @@ v++; } } + /* if we have a next character, and it's a doublewidth one, we need to + * check whether we need to linebreak for it to fit */ + if (cp < el->el_line.lastchar && (w = Width(*cp)) > 1) + if (h + w > th) { + h = 0; + v++; + } /* now go there */ - term_move_to_line(el, v); - term_move_to_char(el, h); - term__flush(el); + terminal_move_to_line(el, v); + terminal_move_to_char(el, h); + terminal__flush(el); } @@ -1027,12 +1050,19 @@ * Add a character fast. */ private void -re_fastputc(EditLine *el, int c) +re_fastputc(EditLine *el, Int c) { + int w = Width((Char)c); + while (w > 1 && el->el_cursor.h + w > el->el_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; - 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 */ el->el_cursor.h = 0; @@ -1042,14 +1072,14 @@ * We do this via pointer shuffling - it's safe in this case * and we avoid memcpy(). */ - if (el->el_cursor.v + 1 >= el->el_term.t_size.v) { - int i, lins = el->el_term.t_size.v; - char *firstline = el->el_display[0]; + if (el->el_cursor.v + 1 >= el->el_terminal.t_size.v) { + int i, lins = el->el_terminal.t_size.v; + Char *firstline = el->el_display[0]; for(i = 1; i < lins; 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; } else { el->el_cursor.v++; @@ -1057,12 +1087,12 @@ } if (EL_HAS_AUTO_MARGINS) { if (EL_HAS_MAGIC_MARGINS) { - term__putc(el, ' '); - term__putc(el, '\b'); + terminal__putc(el, ' '); + terminal__putc(el, '\b'); } } else { - term__putc(el, '\r'); - term__putc(el, '\n'); + terminal__putc(el, '\r'); + terminal__putc(el, '\n'); } } } @@ -1075,34 +1105,39 @@ protected void re_fastaddc(EditLine *el) { - char c; + Char c; int rhdiff; - c = (unsigned char)el->el_line.cursor[-1]; + c = el->el_line.cursor[-1]; if (c == '\t' || el->el_line.cursor != el->el_line.lastchar) { re_refresh(el); /* too hard to handle */ return; } - rhdiff = el->el_term.t_size.h - el->el_cursor.h - + rhdiff = el->el_terminal.t_size.h - el->el_cursor.h - el->el_rprompt.p_pos.h; if (el->el_rprompt.p_pos.h && rhdiff < 3) { re_refresh(el); /* clear out rprompt if less than 1 char gap */ return; } /* else (only do at end of line, no TAB) */ - if (iscntrl((unsigned char) c)) { /* if control char, do caret */ - char mc = (c == 0177) ? '?' : (toascii(c) | 0100); - re_fastputc(el, '^'); - re_fastputc(el, mc); - } else if (isprint((unsigned char) c)) { /* normal char */ + switch (ct_chr_class(c)) { + case CHTYPE_TAB: /* already handled, should never happen here */ + break; + case CHTYPE_NL: + case CHTYPE_PRINT: re_fastputc(el, c); - } else { - re_fastputc(el, '\\'); - re_fastputc(el, (int)(((((unsigned int)c) >> 6) & 3) + '0')); - re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0')); - re_fastputc(el, (c & 7) + '0'); + break; + case CHTYPE_ASCIICTL: + case CHTYPE_NONPRINT: { + Char visbuf[VISUAL_WIDTH_MAX]; + ssize_t i, n = + ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c); + for (i = 0; n-- > 0; ++i) + re_fastputc(el, visbuf[i]); + break; } - term__flush(el); + } + terminal__flush(el); } @@ -1116,7 +1151,7 @@ el->el_cursor.v = 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_refresh.r_oldcv = 0; } @@ -1133,14 +1168,14 @@ int i; for (i = el->el_refresh.r_oldcv; i >= 0; i--) { /* for each line on the screen */ - term_move_to_line(el, i); - term_move_to_char(el, 0); - term_clear_EOL(el, el->el_term.t_size.h); + terminal_move_to_line(el, i); + terminal_move_to_char(el, 0); + terminal_clear_EOL(el, el->el_terminal.t_size.h); } } 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 */ - term__putc(el, '\r'); /* go to BOL */ - term__putc(el, '\n'); /* go to new line */ + terminal__putc(el, '\r'); /* go to BOL */ + terminal__putc(el, '\n'); /* go to new line */ } } Index: lib/libedit/refresh.h =================================================================== --- lib/libedit/refresh.h (revision 258914) +++ lib/libedit/refresh.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: refresh.h,v 1.6 2009/12/30 22:37:40 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +32,6 @@ * SUCH DAMAGE. * * @(#)refresh.h 8.1 (Berkeley) 6/4/93 - * $NetBSD: refresh.h,v 1.5 2003/08/07 16:44:33 agc Exp $ * $FreeBSD$ */ @@ -48,7 +49,7 @@ int r_newcv; } el_refresh_t; -protected void re_putc(EditLine *, int, int); +protected void re_putc(EditLine *, Int, int); protected void re_clear_lines(EditLine *); protected void re_clear_display(EditLine *); protected void re_refresh(EditLine *); Index: lib/libedit/search.c =================================================================== --- lib/libedit/search.c (revision 258914) +++ lib/libedit/search.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: search.c,v 1.30 2011/10/04 15:27:04 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: search.c,v 1.21 2009/02/15 21:55:23 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -41,7 +42,6 @@ /* * search.c: History and character search functions */ -#include "sys.h" #include #if defined(REGEX) #include @@ -64,15 +64,16 @@ search_init(EditLine *el) { - el->el_search.patbuf = (char *) el_malloc(EL_BUFSIZ); + el->el_search.patbuf = el_malloc(EL_BUFSIZ * + sizeof(*el->el_search.patbuf)); if (el->el_search.patbuf == NULL) - return (-1); + return -1; el->el_search.patlen = 0; el->el_search.patdir = -1; el->el_search.chacha = '\0'; el->el_search.chadir = CHAR_FWD; el->el_search.chatflg = 0; - return (0); + return 0; } @@ -83,7 +84,7 @@ search_end(EditLine *el) { - el_free((ptr_t) el->el_search.patbuf); + el_free(el->el_search.patbuf); el->el_search.patbuf = NULL; } @@ -104,8 +105,11 @@ * Return if string matches pattern */ protected int -el_match(const char *str, const char *pat) +el_match(const Char *str, const Char *pat) { +#ifdef WIDECHAR + static ct_buffer_t conv; +#endif #if defined (REGEX) regex_t re; int rv; @@ -117,30 +121,31 @@ extern int re_exec(const char *); #endif - if (strstr(str, pat) != NULL) - return (1); + if (Strstr(str, pat) != 0) + return 1; #if defined(REGEX) - if (regcomp(&re, pat, 0) == 0) { - rv = regexec(&re, str, 0, NULL, 0) == 0; + if (regcomp(&re, ct_encode_string(pat, &conv), 0) == 0) { + rv = regexec(&re, ct_encode_string(str, &conv), (size_t)0, NULL, + 0) == 0; regfree(&re); } else { rv = 0; } - return (rv); + return rv; #elif defined(REGEXP) - if ((re = regcomp(pat)) != NULL) { - rv = regexec(re, str); - free((ptr_t) re); + if ((re = regcomp(ct_encode_string(pat, &conv))) != NULL) { + rv = regexec(re, ct_encode_string(str, &conv)); + el_free(re); } else { rv = 0; } - return (rv); + return rv; #else - if (re_comp(pat) != NULL) - return (0); + if (re_comp(ct_encode_string(pat, &conv)) != NULL) + return 0; else - return (re_exec(str) == 1); + return re_exec(ct_encode_string(str, &conv) == 1); #endif } @@ -149,7 +154,7 @@ * return True if the pattern matches the prefix */ protected int -c_hmatch(EditLine *el, const char *str) +c_hmatch(EditLine *el, const Char *str) { #ifdef SDEBUG (void) fprintf(el->el_errfile, "match `%s' with `%s'\n", @@ -156,7 +161,7 @@ el->el_search.patbuf, str); #endif /* SDEBUG */ - return (el_match(str, el->el_search.patbuf)); + return el_match(str, el->el_search.patbuf); } @@ -168,15 +173,16 @@ { if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY && el->el_state.lastcmd != ED_SEARCH_NEXT_HISTORY) { - el->el_search.patlen = EL_CURSOR(el) - el->el_line.buffer; + el->el_search.patlen = + (size_t)(EL_CURSOR(el) - el->el_line.buffer); if (el->el_search.patlen >= EL_BUFSIZ) el->el_search.patlen = EL_BUFSIZ - 1; if (el->el_search.patlen != 0) { - (void) strncpy(el->el_search.patbuf, el->el_line.buffer, + (void) Strncpy(el->el_search.patbuf, el->el_line.buffer, el->el_search.patlen); el->el_search.patbuf[el->el_search.patlen] = '\0'; } else - el->el_search.patlen = strlen(el->el_search.patbuf); + el->el_search.patlen = Strlen(el->el_search.patbuf); } #ifdef SDEBUG (void) fprintf(el->el_errfile, "\neventno = %d\n", @@ -197,12 +203,12 @@ protected el_action_t ce_inc_search(EditLine *el, int dir) { - static const char STRfwd[] = {'f', 'w', 'd', '\0'}, + static const Char STRfwd[] = {'f', 'w', 'd', '\0'}, STRbck[] = {'b', 'c', 'k', '\0'}; - static char pchar = ':';/* ':' = normal, '?' = failed */ - static char endcmd[2] = {'\0', '\0'}; - char ch, *ocursor = el->el_line.cursor, oldpchar = pchar; - const char *cp; + static Char pchar = ':';/* ':' = normal, '?' = failed */ + static Char endcmd[2] = {'\0', '\0'}; + Char ch, *ocursor = el->el_line.cursor, oldpchar = pchar; + const Char *cp; el_action_t ret = CC_NORM; @@ -211,9 +217,10 @@ int newdir = dir; int done, redo; - if (el->el_line.lastchar + sizeof(STRfwd) / sizeof(char) + 2 + + if (el->el_line.lastchar + sizeof(STRfwd) / + sizeof(*el->el_line.lastchar) + 2 + el->el_search.patlen >= el->el_line.limit) - return (CC_ERROR); + return CC_ERROR; for (;;) { @@ -240,14 +247,14 @@ *el->el_line.lastchar = '\0'; re_refresh(el); - if (el_getc(el, &ch) != 1) - return (ed_end_of_file(el, 0)); + if (FUN(el,getc)(el, &ch) != 1) + return ed_end_of_file(el, 0); switch (el->el_map.current[(unsigned char) ch]) { case ED_INSERT: case ED_DIGIT: if (el->el_search.patlen >= EL_BUFSIZ - LEN) - term_beep(el); + terminal_beep(el); else { el->el_search.patbuf[el->el_search.patlen++] = ch; @@ -272,7 +279,7 @@ if (el->el_search.patlen > LEN) done++; else - term_beep(el); + terminal_beep(el); break; default: @@ -296,7 +303,7 @@ *el->el_line.cursor != '\n') { if (el->el_search.patlen >= EL_BUFSIZ - LEN) { - term_beep(el); + terminal_beep(el); break; } el->el_search.patbuf[el->el_search.patlen++] = @@ -309,7 +316,7 @@ re_refresh(el); break; } else if (isglob(*cp)) { - term_beep(el); + terminal_beep(el); break; } break; @@ -316,7 +323,7 @@ default: /* Terminate and execute cmd */ endcmd[0] = ch; - el_push(el, endcmd); + FUN(el,push)(el, endcmd); /* FALLTHROUGH */ case 0033: /* ESC: Terminate */ @@ -378,9 +385,10 @@ /* avoid c_setpat */ el->el_state.lastcmd = (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_next_history(el, 0); + ed_search_next_history(el, 0)); if (ret != CC_ERROR) { el->el_line.cursor = newdir == ED_SEARCH_PREV_HISTORY ? @@ -394,13 +402,13 @@ el->el_search.patbuf[el->el_search.patlen] = '\0'; if (ret == CC_ERROR) { - term_beep(el); + terminal_beep(el); if (el->el_history.eventno != ohisteventno) { el->el_history.eventno = ohisteventno; if (hist_get(el) == CC_ERROR) - return (CC_ERROR); + return CC_ERROR; } el->el_line.cursor = ocursor; pchar = '?'; @@ -425,7 +433,7 @@ if (el->el_history.eventno != ohisteventno) { el->el_history.eventno = ohisteventno; if (hist_get(el) == CC_ERROR) - return (CC_ERROR); + return CC_ERROR; } el->el_line.cursor = ocursor; if (ret == CC_ERROR) @@ -432,7 +440,7 @@ re_refresh(el); } if (done || ret != CC_NORM) - return (ret); + return ret; } } @@ -443,9 +451,9 @@ protected el_action_t cv_search(EditLine *el, int dir) { - char ch; - char tmpbuf[EL_BUFSIZ]; - int tmplen; + Char ch; + Char tmpbuf[EL_BUFSIZ]; + ssize_t tmplen; #ifdef ANCHOR tmpbuf[0] = '.'; @@ -456,7 +464,7 @@ el->el_search.patdir = dir; tmplen = c_gets(el, &tmpbuf[LEN], - dir == ED_SEARCH_PREV_HISTORY ? "\n/" : "\n?" ); + dir == ED_SEARCH_PREV_HISTORY ? STR("\n/") : STR("\n?") ); if (tmplen == -1) return CC_REFRESH; @@ -470,16 +478,16 @@ */ if (el->el_search.patlen == 0) { re_refresh(el); - return (CC_ERROR); + return CC_ERROR; } #ifdef ANCHOR if (el->el_search.patbuf[0] != '.' && el->el_search.patbuf[0] != '*') { - (void) strncpy(tmpbuf, el->el_search.patbuf, - sizeof(tmpbuf) - 1); + (void) Strncpy(tmpbuf, el->el_search.patbuf, + sizeof(tmpbuf) / sizeof(*tmpbuf) - 1); el->el_search.patbuf[0] = '.'; el->el_search.patbuf[1] = '*'; - (void) strncpy(&el->el_search.patbuf[2], tmpbuf, + (void) Strncpy(&el->el_search.patbuf[2], tmpbuf, EL_BUFSIZ - 3); el->el_search.patlen++; el->el_search.patbuf[el->el_search.patlen++] = '.'; @@ -493,8 +501,8 @@ tmpbuf[tmplen++] = '*'; #endif tmpbuf[tmplen] = '\0'; - (void) strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1); - el->el_search.patlen = tmplen; + (void) Strncpy(el->el_search.patbuf, tmpbuf, EL_BUFSIZ - 1); + el->el_search.patlen = (size_t)tmplen; } el->el_state.lastcmd = (el_action_t) dir; /* avoid c_setpat */ el->el_line.cursor = el->el_line.lastchar = el->el_line.buffer; @@ -501,13 +509,13 @@ if ((dir == ED_SEARCH_PREV_HISTORY ? ed_search_prev_history(el, 0) : ed_search_next_history(el, 0)) == CC_ERROR) { re_refresh(el); - return (CC_ERROR); + return CC_ERROR; } if (ch == 0033) { re_refresh(el); return ed_newline(el, 0); } - return (CC_REFRESH); + return CC_REFRESH; } @@ -517,9 +525,9 @@ protected el_action_t ce_search_line(EditLine *el, int dir) { - char *cp = el->el_line.cursor; - char *pattern = el->el_search.patbuf; - char oc, *ocp; + Char *cp = el->el_line.cursor; + Char *pattern = el->el_search.patbuf; + Char oc, *ocp; #ifdef ANCHOR ocp = &pattern[1]; oc = *ocp; @@ -534,21 +542,21 @@ if (el_match(cp, ocp)) { *ocp = oc; el->el_line.cursor = cp; - return (CC_NORM); + return CC_NORM; } } *ocp = oc; - return (CC_ERROR); + return CC_ERROR; } else { for (; *cp != '\0' && cp < el->el_line.limit; cp++) { if (el_match(cp, ocp)) { *ocp = oc; el->el_line.cursor = cp; - return (CC_NORM); + return CC_NORM; } } *ocp = oc; - return (CC_ERROR); + return CC_ERROR; } } @@ -557,12 +565,12 @@ * Vi repeat search */ protected el_action_t -cv_repeat_srch(EditLine *el, int c) +cv_repeat_srch(EditLine *el, Int c) { #ifdef SDEBUG (void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n", - c, el->el_search.patlen, el->el_search.patbuf); + c, el->el_search.patlen, ct_encode_string(el->el_search.patbuf)); #endif el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */ @@ -570,11 +578,11 @@ switch (c) { case ED_SEARCH_NEXT_HISTORY: - return (ed_search_next_history(el, 0)); + return ed_search_next_history(el, 0); case ED_SEARCH_PREV_HISTORY: - return (ed_search_prev_history(el, 0)); + return ed_search_prev_history(el, 0); default: - return (CC_ERROR); + return CC_ERROR; } } @@ -583,16 +591,16 @@ * Vi character search */ protected el_action_t -cv_csearch(EditLine *el, int direction, int ch, int count, int tflag) +cv_csearch(EditLine *el, int direction, Int ch, int count, int tflag) { - char *cp; + Char *cp; if (ch == 0) return CC_ERROR; - if (ch == -1) { - char c; - if (el_getc(el, &c) != 1) + if (ch == (Int)-1) { + Char c; + if (FUN(el,getc)(el, &c) != 1) return ed_end_of_file(el, 0); ch = c; } @@ -600,11 +608,11 @@ /* Save for ';' and ',' commands */ el->el_search.chacha = ch; el->el_search.chadir = direction; - el->el_search.chatflg = tflag; + el->el_search.chatflg = (char)tflag; cp = el->el_line.cursor; while (count--) { - if (*cp == ch) + if ((Int)*cp == ch) cp += direction; for (;;cp += direction) { if (cp >= el->el_line.lastchar) @@ -611,7 +619,7 @@ return CC_ERROR; if (cp < el->el_line.buffer) return CC_ERROR; - if (*cp == ch) + if ((Int)*cp == ch) break; } } Index: lib/libedit/search.h =================================================================== --- lib/libedit/search.h (revision 258914) +++ lib/libedit/search.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: search.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +32,6 @@ * SUCH DAMAGE. * * @(#)search.h 8.1 (Berkeley) 6/4/93 - * $NetBSD: search.h,v 1.8 2003/10/18 23:27:36 christos Exp $ * $FreeBSD$ */ @@ -43,24 +44,24 @@ #include "histedit.h" typedef struct el_search_t { - char *patbuf; /* The pattern buffer */ + Char *patbuf; /* The pattern buffer */ size_t patlen; /* Length of the pattern buffer */ int patdir; /* Direction of the last search */ int chadir; /* Character search direction */ - char chacha; /* Character we are looking for */ + Char chacha; /* Character we are looking for */ char chatflg; /* 0 if f, 1 if t */ } el_search_t; -protected int el_match(const char *, const char *); +protected int el_match(const Char *, const Char *); protected int search_init(EditLine *); protected void search_end(EditLine *); -protected int c_hmatch(EditLine *, const char *); +protected int c_hmatch(EditLine *, const Char *); protected void c_setpat(EditLine *); protected el_action_t ce_inc_search(EditLine *, int); protected el_action_t cv_search(EditLine *, int); protected el_action_t ce_search_line(EditLine *, int); -protected el_action_t cv_repeat_srch(EditLine *, int); -protected el_action_t cv_csearch(EditLine *, int, int, int, int); +protected el_action_t cv_repeat_srch(EditLine *, Int); +protected el_action_t cv_csearch(EditLine *, int, Int, int, int); #endif /* _h_el_search */ Index: lib/libedit/sig.c =================================================================== --- lib/libedit/sig.c (revision 258914) +++ lib/libedit/sig.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: sig.c,v 1.17 2011/07/28 20:50:55 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,14 +30,9 @@ * 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. - * - * $NetBSD: sig.c,v 1.15 2009/02/19 15:20:22 christos Exp $ */ -#if !defined(lint) && !defined(SCCSID) -static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93"; -#endif /* not lint && not SCCSID */ -#include +#include "config.h" __FBSDID("$FreeBSD$"); /* @@ -43,7 +40,6 @@ * our policy is to trap all signals, set a good state * and pass the ball to our caller. */ -#include "sys.h" #include "el.h" #include @@ -80,7 +76,7 @@ tty_rawmode(sel); if (ed_redisplay(sel, 0) == CC_REFRESH) re_refresh(sel); - term__flush(sel); + terminal__flush(sel); break; case SIGWINCH: @@ -144,7 +140,7 @@ sig_end(EditLine *el) { - el_free((ptr_t) el->el_signal); + el_free(el->el_signal); el->el_signal = NULL; } Index: lib/libedit/sig.h =================================================================== --- lib/libedit/sig.h (revision 258914) +++ lib/libedit/sig.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: sig.h,v 1.8 2009/02/19 15:20:22 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +32,6 @@ * SUCH DAMAGE. * * @(#)sig.h 8.1 (Berkeley) 6/4/93 - * $NetBSD: sig.h,v 1.8 2009/02/19 15:20:22 christos Exp $ * $FreeBSD$ */ Index: lib/libedit/sys.h =================================================================== --- lib/libedit/sys.h (revision 258914) +++ lib/libedit/sys.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: sys.h,v 1.17 2011/09/28 14:08:04 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +32,6 @@ * SUCH DAMAGE. * * @(#)sys.h 8.1 (Berkeley) 6/4/93 - * $NetBSD: sys.h,v 1.9 2004/01/17 17:57:40 christos Exp $ * $FreeBSD$ */ @@ -40,8 +41,24 @@ #ifndef _h_sys #define _h_sys +#ifdef HAVE_SYS_CDEFS_H #include +#endif +#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8) +# define __attribute__(A) +#endif + +#ifndef __BEGIN_DECLS +# ifdef __cplusplus +# define __BEGIN_DECLS extern "C" { +# define __END_DECLS } +# else +# define __BEGIN_DECLS +# define __END_DECLS +# endif +#endif + #ifndef public # define public /* Externally visible functions/variables */ #endif @@ -55,55 +72,60 @@ /* When we want to hide everything */ #endif -#ifndef _PTR_T -# define _PTR_T -typedef void *ptr_t; +#ifndef __arraycount +# define __arraycount(a) (sizeof(a) / sizeof(*(a))) #endif -#ifndef _IOCTL_T -# define _IOCTL_T -typedef void *ioctl_t; +#include + +#ifndef HAVE_STRLCAT +#define strlcat libedit_strlcat +size_t strlcat(char *dst, const char *src, size_t size); #endif -#include +#ifndef HAVE_STRLCPY +#define strlcpy libedit_strlcpy +size_t strlcpy(char *dst, const char *src, size_t size); +#endif +#ifndef HAVE_FGETLN +#define fgetln libedit_fgetln +char *fgetln(FILE *fp, size_t *len); +#endif + +#ifndef HAVE_WCSDUP +#include +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 + +#if 0 /* FreeBSD already has SIZE_T_MAX */ +#ifndef SIZE_T_MAX +#define SIZE_T_MAX ((size_t)-1) +#endif +#endif + #define REGEX /* Use POSIX.2 regular expression functions */ #undef REGEXP /* Use UNIX V8 regular expression functions */ -#ifdef notdef -# undef REGEX -# undef REGEXP -# include -# ifdef __GNUC__ -/* - * Broken hdrs. - */ -extern int tgetent(const char *bp, char *name); -extern int tgetflag(const char *id); -extern int tgetnum(const char *id); -extern char *tgetstr(const char *id, char **area); -extern char *tgoto(const char *cap, int col, int row); -extern int tputs(const char *str, int affcnt, int (*putc)(int)); -extern char *getenv(const char *); -extern int fprintf(FILE *, const char *, ...); -extern int sigsetmask(int); -extern int sigblock(int); -extern int fputc(int, FILE *); -extern int fgetc(FILE *); -extern int fflush(FILE *); -extern int tolower(int); -extern int toupper(int); -extern int errno, sys_nerr; -extern char *sys_errlist[]; -extern void perror(const char *); -# include -# define strerror(e) sys_errlist[e] -# endif -# ifdef SABER -extern ptr_t memcpy(ptr_t, const ptr_t, size_t); -extern ptr_t memset(ptr_t, int, size_t); -# endif -extern char *fgetline(FILE *, int *); +#if defined(__sun) +extern int tgetent(char *, const char *); +extern int tgetflag(char *); +extern int tgetnum(char *); +extern int tputs(const char *, int, int (*)(int)); +extern char* tgoto(const char*, int, int); +extern char* tgetstr(char*, char**); #endif #endif /* _h_sys */ Index: lib/libedit/terminal.c =================================================================== --- lib/libedit/terminal.c (revision 258914) +++ lib/libedit/terminal.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: terminal.c,v 1.14 2012/05/30 18:21:14 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: term.c,v 1.56 2009/12/28 21:54:21 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; #endif /* not lint && not SCCSID */ @@ -39,9 +40,9 @@ __FBSDID("$FreeBSD$"); /* - * term.c: Editor/termcap-curses interface - * We have to declare a static variable here, since the - * termcap putchar routine does not take an argument! + * terminal.c: Editor/termcap-curses interface + * We have to declare a static variable here, since the + * termcap putchar routine does not take an argument! */ #include #include @@ -48,101 +49,44 @@ #include #include #include +#include +#ifdef HAVE_TERMCAP_H #include +#endif +#ifdef HAVE_CURSES_H #include +#elif HAVE_NCURSES_H #include +#endif + +/* Solaris's term.h does horrid things. */ +#if defined(HAVE_TERM_H) && !defined(__sun) && !defined(HAVE_TERMCAP_H) #include +#endif + #include #include +#ifdef _REENTRANT +#include +#endif + #include "el.h" /* * IMPORTANT NOTE: these routines are allowed to look at the current screen - * and the current possition assuming that it is correct. If this is not + * and the current position assuming that it is correct. If this is not * true, then the update will be WRONG! This is (should be) a valid * assumption... */ -#define TC_BUFSIZE 2048 +#define TC_BUFSIZE ((size_t)2048) -#define GoodStr(a) (el->el_term.t_str[a] != NULL && \ - el->el_term.t_str[a][0] != '\0') -#define Str(a) el->el_term.t_str[a] -#define Val(a) el->el_term.t_val[a] +#define GoodStr(a) (el->el_terminal.t_str[a] != NULL && \ + el->el_terminal.t_str[a][0] != '\0') +#define Str(a) el->el_terminal.t_str[a] +#define Val(a) el->el_terminal.t_val[a] -#ifdef notdef -private const struct { - const char *b_name; - int b_rate; -} baud_rate[] = { -#ifdef B0 - { "0", B0 }, -#endif -#ifdef B50 - { "50", B50 }, -#endif -#ifdef B75 - { "75", B75 }, -#endif -#ifdef B110 - { "110", B110 }, -#endif -#ifdef B134 - { "134", B134 }, -#endif -#ifdef B150 - { "150", B150 }, -#endif -#ifdef B200 - { "200", B200 }, -#endif -#ifdef B300 - { "300", B300 }, -#endif -#ifdef B600 - { "600", B600 }, -#endif -#ifdef B900 - { "900", B900 }, -#endif -#ifdef B1200 - { "1200", B1200 }, -#endif -#ifdef B1800 - { "1800", B1800 }, -#endif -#ifdef B2400 - { "2400", B2400 }, -#endif -#ifdef B3600 - { "3600", B3600 }, -#endif -#ifdef B4800 - { "4800", B4800 }, -#endif -#ifdef B7200 - { "7200", B7200 }, -#endif -#ifdef B9600 - { "9600", B9600 }, -#endif -#ifdef EXTA - { "19200", EXTA }, -#endif -#ifdef B19200 - { "19200", B19200 }, -#endif -#ifdef EXTB - { "38400", EXTB }, -#endif -#ifdef B38400 - { "38400", B38400 }, -#endif - { NULL, 0 } -}; -#endif - private const struct termcapstr { const char *name; const char *long_name; @@ -254,27 +198,28 @@ }; /* do two or more of the attributes use me */ -private void term_setflags(EditLine *); -private int term_rebuffer_display(EditLine *); -private void term_free_display(EditLine *); -private int term_alloc_display(EditLine *); -private void term_alloc(EditLine *, const struct termcapstr *, const char *); -private void term_init_arrow(EditLine *); -private void term_reset_arrow(EditLine *); -private int term_putc(int); -private void term_tputs(EditLine *, const char *, int); +private void terminal_setflags(EditLine *); +private int terminal_rebuffer_display(EditLine *); +private void terminal_free_display(EditLine *); +private int terminal_alloc_display(EditLine *); +private void terminal_alloc(EditLine *, const struct termcapstr *, + const char *); +private void terminal_init_arrow(EditLine *); +private void terminal_reset_arrow(EditLine *); +private int terminal_putc(int); +private void terminal_tputs(EditLine *, const char *, int); #ifdef _REENTRANT -private pthread_mutex_t term_mutex = PTHREAD_MUTEX_INITIALIZER; +private pthread_mutex_t terminal_mutex = PTHREAD_MUTEX_INITIALIZER; #endif -private FILE *term_outfile = NULL; +private FILE *terminal_outfile = NULL; -/* term_setflags(): +/* terminal_setflags(): * Set the terminal capability flags */ private void -term_setflags(EditLine *el) +terminal_setflags(EditLine *el) { EL_FLAGS = 0; if (el->el_tty.t_tabs) @@ -315,69 +260,77 @@ #endif /* DEBUG_SCREEN */ } -/* term_init(): +/* terminal_init(): * Initialize the terminal stuff */ protected int -term_init(EditLine *el) +terminal_init(EditLine *el) { - el->el_term.t_buf = (char *) el_malloc(TC_BUFSIZE); - if (el->el_term.t_buf == NULL) - return (-1); - el->el_term.t_cap = (char *) el_malloc(TC_BUFSIZE); - if (el->el_term.t_cap == NULL) - return (-1); - el->el_term.t_fkey = (fkey_t *) el_malloc(A_K_NKEYS * sizeof(fkey_t)); - if (el->el_term.t_fkey == NULL) - return (-1); - el->el_term.t_loc = 0; - el->el_term.t_str = (char **) el_malloc(T_str * sizeof(char *)); - if (el->el_term.t_str == NULL) - return (-1); - (void) memset(el->el_term.t_str, 0, T_str * sizeof(char *)); - el->el_term.t_val = (int *) el_malloc(T_val * sizeof(int)); - if (el->el_term.t_val == NULL) - return (-1); - (void) memset(el->el_term.t_val, 0, T_val * sizeof(int)); - (void) term_set(el, NULL); - term_init_arrow(el); - return (0); + el->el_terminal.t_buf = el_malloc(TC_BUFSIZE * + sizeof(*el->el_terminal.t_buf)); + if (el->el_terminal.t_buf == NULL) + return -1; + el->el_terminal.t_cap = el_malloc(TC_BUFSIZE * + sizeof(*el->el_terminal.t_cap)); + if (el->el_terminal.t_cap == NULL) + return -1; + el->el_terminal.t_fkey = el_malloc(A_K_NKEYS * + sizeof(*el->el_terminal.t_fkey)); + if (el->el_terminal.t_fkey == NULL) + return -1; + el->el_terminal.t_loc = 0; + el->el_terminal.t_str = el_malloc(T_str * + sizeof(*el->el_terminal.t_str)); + if (el->el_terminal.t_str == NULL) + return -1; + (void) memset(el->el_terminal.t_str, 0, T_str * + sizeof(*el->el_terminal.t_str)); + el->el_terminal.t_val = el_malloc(T_val * + sizeof(*el->el_terminal.t_val)); + if (el->el_terminal.t_val == NULL) + return -1; + (void) memset(el->el_terminal.t_val, 0, T_val * + sizeof(*el->el_terminal.t_val)); + (void) terminal_set(el, NULL); + terminal_init_arrow(el); + return 0; } -/* term_end(): +/* terminal_end(): * Clean up the terminal stuff */ protected void -term_end(EditLine *el) +terminal_end(EditLine *el) { - el_free((ptr_t) el->el_term.t_buf); - el->el_term.t_buf = NULL; - el_free((ptr_t) el->el_term.t_cap); - el->el_term.t_cap = NULL; - el->el_term.t_loc = 0; - el_free((ptr_t) el->el_term.t_str); - el->el_term.t_str = NULL; - el_free((ptr_t) el->el_term.t_val); - el->el_term.t_val = NULL; - el_free((ptr_t) el->el_term.t_fkey); - el->el_term.t_fkey = NULL; - term_free_display(el); + el_free(el->el_terminal.t_buf); + el->el_terminal.t_buf = NULL; + el_free(el->el_terminal.t_cap); + el->el_terminal.t_cap = NULL; + el->el_terminal.t_loc = 0; + el_free(el->el_terminal.t_str); + el->el_terminal.t_str = NULL; + el_free(el->el_terminal.t_val); + el->el_terminal.t_val = NULL; + el_free(el->el_terminal.t_fkey); + el->el_terminal.t_fkey = NULL; + terminal_free_display(el); } -/* term_alloc(): +/* terminal_alloc(): * Maintain a string pool for termcap strings */ private void -term_alloc(EditLine *el, const struct termcapstr *t, const char *cap) +terminal_alloc(EditLine *el, const struct termcapstr *t, const char *cap) { char termbuf[TC_BUFSIZE]; size_t tlen, clen; - char **tlist = el->el_term.t_str; + char **tlist = el->el_terminal.t_str; char **tmp, **str = &tlist[t - tstr]; + (void) memset(termbuf, 0, sizeof(termbuf)); if (cap == NULL || *cap == '\0') { *str = NULL; return; @@ -397,11 +350,11 @@ /* * New string is longer; see if we have enough space to append */ - if (el->el_term.t_loc + 3 < TC_BUFSIZE) { + if (el->el_terminal.t_loc + 3 < TC_BUFSIZE) { /* XXX strcpy is safe */ - (void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], - cap); - el->el_term.t_loc += (int)clen + 1; /* one for \0 */ + (void) strcpy(*str = &el->el_terminal.t_buf[ + el->el_terminal.t_loc], cap); + el->el_terminal.t_loc += clen + 1; /* one for \0 */ return; } /* @@ -417,114 +370,115 @@ continue; termbuf[tlen++] = '\0'; } - memcpy(el->el_term.t_buf, termbuf, TC_BUFSIZE); - el->el_term.t_loc = (int)tlen; - if (el->el_term.t_loc + 3 >= TC_BUFSIZE) { + memcpy(el->el_terminal.t_buf, termbuf, TC_BUFSIZE); + el->el_terminal.t_loc = tlen; + if (el->el_terminal.t_loc + 3 >= TC_BUFSIZE) { (void) fprintf(el->el_errfile, "Out of termcap string space.\n"); return; } /* XXX strcpy is safe */ - (void) strcpy(*str = &el->el_term.t_buf[el->el_term.t_loc], cap); - el->el_term.t_loc += (int)clen + 1; /* one for \0 */ + (void) strcpy(*str = &el->el_terminal.t_buf[el->el_terminal.t_loc], + cap); + el->el_terminal.t_loc += (size_t)clen + 1; /* one for \0 */ return; } -/* term_rebuffer_display(): +/* terminal_rebuffer_display(): * Rebuffer the display after the screen changed size */ private int -term_rebuffer_display(EditLine *el) +terminal_rebuffer_display(EditLine *el) { - coord_t *c = &el->el_term.t_size; + coord_t *c = &el->el_terminal.t_size; - term_free_display(el); + terminal_free_display(el); c->h = Val(T_co); c->v = Val(T_li); - if (term_alloc_display(el) == -1) - return (-1); - return (0); + if (terminal_alloc_display(el) == -1) + return -1; + return 0; } -/* term_alloc_display(): +/* terminal_alloc_display(): * Allocate a new display. */ private int -term_alloc_display(EditLine *el) +terminal_alloc_display(EditLine *el) { int i; - char **b; - coord_t *c = &el->el_term.t_size; + Char **b; + coord_t *c = &el->el_terminal.t_size; - b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1))); + b = el_malloc(sizeof(*b) * (size_t)(c->v + 1)); if (b == NULL) - return (-1); + return -1; for (i = 0; i < c->v; i++) { - b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); + b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1)); if (b[i] == NULL) { while (--i >= 0) - el_free((ptr_t) b[i]); - el_free((ptr_t) b); - return (-1); + el_free(b[i]); + el_free(b); + return -1; } } b[c->v] = NULL; el->el_display = b; - b = (char **) el_malloc((size_t) (sizeof(char *) * (c->v + 1))); + b = el_malloc(sizeof(*b) * (size_t)(c->v + 1)); if (b == NULL) - return (-1); + return -1; for (i = 0; i < c->v; i++) { - b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); + b[i] = el_malloc(sizeof(**b) * (size_t)(c->h + 1)); if (b[i] == NULL) { while (--i >= 0) - el_free((ptr_t) b[i]); - el_free((ptr_t) b); - return (-1); + el_free(b[i]); + el_free(b); + return -1; } } b[c->v] = NULL; el->el_vdisplay = b; - return (0); + return 0; } -/* term_free_display(): +/* terminal_free_display(): * Free the display buffers */ private void -term_free_display(EditLine *el) +terminal_free_display(EditLine *el) { - char **b; - char **bufp; + Char **b; + Char **bufp; b = el->el_display; el->el_display = NULL; if (b != NULL) { for (bufp = b; *bufp != NULL; bufp++) - el_free((ptr_t) * bufp); - el_free((ptr_t) b); + el_free(*bufp); + el_free(b); } b = el->el_vdisplay; el->el_vdisplay = NULL; if (b != NULL) { for (bufp = b; *bufp != NULL; bufp++) - el_free((ptr_t) * bufp); - el_free((ptr_t) b); + el_free(*bufp); + el_free(b); } } -/* term_move_to_line(): +/* terminal_move_to_line(): * move to line (first line == 0) * as efficiently as possible */ protected void -term_move_to_line(EditLine *el, int where) +terminal_move_to_line(EditLine *el, int where) { int del; @@ -531,10 +485,11 @@ if (where == el->el_cursor.v) return; - if (where > el->el_term.t_size.v) { + if (where > el->el_terminal.t_size.v) { #ifdef DEBUG_SCREEN (void) fprintf(el->el_errfile, - "term_move_to_line: where is ridiculous: %d\r\n", where); + "terminal_move_to_line: where is ridiculous: %d\r\n", + where); #endif /* DEBUG_SCREEN */ return; } @@ -542,22 +497,31 @@ while (del > 0) { if (EL_HAS_AUTO_MARGINS && el->el_display[el->el_cursor.v][0] != '\0') { + size_t h = (size_t) + (el->el_terminal.t_size.h - 1); +#ifdef WIDECHAR + for (; h > 0 && + el->el_display[el->el_cursor.v][h] == + MB_FILL_CHAR; + h--) + continue; +#endif /* move without newline */ - term_move_to_char(el, el->el_term.t_size.h - 1); - term_overwrite(el, &el->el_display + terminal_move_to_char(el, (int)h); + terminal_overwrite(el, &el->el_display [el->el_cursor.v][el->el_cursor.h], - (size_t)(el->el_term.t_size.h - + (size_t)(el->el_terminal.t_size.h - el->el_cursor.h)); /* updates Cursor */ del--; } else { if ((del > 1) && GoodStr(T_DO)) { - term_tputs(el, tgoto(Str(T_DO), del, + terminal_tputs(el, tgoto(Str(T_DO), del, del), del); del = 0; } else { for (; del > 0; del--) - term__putc(el, '\n'); + terminal__putc(el, '\n'); /* because the \n will become \r\n */ el->el_cursor.h = 0; } @@ -565,11 +529,11 @@ } } else { /* del < 0 */ if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up))) - term_tputs(el, tgoto(Str(T_UP), -del, -del), -del); + terminal_tputs(el, tgoto(Str(T_UP), -del, -del), -del); else { if (GoodStr(T_up)) for (; del < 0; del++) - term_tputs(el, Str(T_up), 1); + terminal_tputs(el, Str(T_up), 1); } } el->el_cursor.v = where;/* now where is here */ @@ -576,11 +540,11 @@ } -/* term_move_to_char(): +/* terminal_move_to_char(): * Move to the character position specified */ protected void -term_move_to_char(EditLine *el, int where) +terminal_move_to_char(EditLine *el, int where) { int del, i; @@ -588,15 +552,16 @@ if (where == el->el_cursor.h) return; - if (where > el->el_term.t_size.h) { + if (where > el->el_terminal.t_size.h) { #ifdef DEBUG_SCREEN (void) fprintf(el->el_errfile, - "term_move_to_char: where is riduculous: %d\r\n", where); + "terminal_move_to_char: where is riduculous: %d\r\n", + where); #endif /* DEBUG_SCREEN */ return; } if (!where) { /* if where is first column */ - term__putc(el, '\r'); /* do a CR */ + terminal__putc(el, '\r'); /* do a CR */ el->el_cursor.h = 0; return; } @@ -604,22 +569,30 @@ if ((del < -4 || del > 4) && GoodStr(T_ch)) /* go there directly */ - term_tputs(el, tgoto(Str(T_ch), where, where), where); + terminal_tputs(el, tgoto(Str(T_ch), where, where), where); else { if (del > 0) { /* moving forward */ if ((del > 4) && GoodStr(T_RI)) - term_tputs(el, tgoto(Str(T_RI), del, del), del); + terminal_tputs(el, tgoto(Str(T_RI), del, del), + del); else { /* if I can do tabs, use them */ if (EL_CAN_TAB) { if ((el->el_cursor.h & 0370) != - (where & ~0x7)) { + (where & ~0x7) +#ifdef WIDECHAR + && (el->el_display[ + el->el_cursor.v][where & 0370] != + MB_FILL_CHAR) +#endif + ) { /* if not within tab stop */ for (i = (el->el_cursor.h & 0370); i < (where & ~0x7); i += 8) - term__putc(el, '\t'); + terminal__putc(el, + '\t'); /* then tab over */ el->el_cursor.h = where & ~0x7; } @@ -629,10 +602,10 @@ * chars, so we do. */ /* - * NOTE THAT term_overwrite() WILL CHANGE + * NOTE THAT terminal_overwrite() WILL CHANGE * el->el_cursor.h!!! */ - term_overwrite(el, &el->el_display[ + terminal_overwrite(el, &el->el_display[ el->el_cursor.v][el->el_cursor.h], (size_t)(where - el->el_cursor.h)); @@ -639,7 +612,7 @@ } } else { /* del < 0 := moving backward */ if ((-del > 4) && GoodStr(T_LE)) - term_tputs(el, tgoto(Str(T_LE), -del, -del), + terminal_tputs(el, tgoto(Str(T_LE), -del, -del), -del); else { /* can't go directly there */ /* @@ -651,12 +624,12 @@ (((unsigned int) where >> 3) + (where & 07))) : (-del > where)) { - term__putc(el, '\r'); /* do a CR */ + terminal__putc(el, '\r');/* do a CR */ el->el_cursor.h = 0; goto mc_again; /* and try again */ } for (i = 0; i < -del; i++) - term__putc(el, '\b'); + terminal__putc(el, '\b'); } } } @@ -664,29 +637,31 @@ } -/* term_overwrite(): +/* terminal_overwrite(): * Overstrike num characters + * Assumes MB_FILL_CHARs are present to keep the column count correct */ protected void -term_overwrite(EditLine *el, const char *cp, size_t n) +terminal_overwrite(EditLine *el, const Char *cp, size_t n) { if (n == 0) return; - if (n > (size_t)el->el_term.t_size.h) { + if (n > (size_t)el->el_terminal.t_size.h) { #ifdef DEBUG_SCREEN (void) fprintf(el->el_errfile, - "term_overwrite: n is riduculous: %d\r\n", n); + "terminal_overwrite: n is riduculous: %d\r\n", n); #endif /* DEBUG_SCREEN */ return; } - do { - term__putc(el, *cp++); - el->el_cursor.h++; - } while (--n); + do { + /* terminal__putc() ignores any MB_FILL_CHARs */ + terminal__putc(el, *cp++); + el->el_cursor.h++; + } while (--n); - if (el->el_cursor.h >= el->el_term.t_size.h) { /* wrap? */ + if (el->el_cursor.h >= el->el_terminal.t_size.h) { /* wrap? */ if (EL_HAS_AUTO_MARGINS) { /* yes */ el->el_cursor.h = 0; el->el_cursor.v++; @@ -693,26 +668,31 @@ if (EL_HAS_MAGIC_MARGINS) { /* force the wrap to avoid the "magic" * situation */ - char c; - if ((c = el->el_display[el->el_cursor.v][el->el_cursor.h]) - != '\0') - term_overwrite(el, &c, 1); - else { - term__putc(el, ' '); + Char c; + if ((c = el->el_display[el->el_cursor.v] + [el->el_cursor.h]) != '\0') { + terminal_overwrite(el, &c, (size_t)1); +#ifdef WIDECHAR + while (el->el_display[el->el_cursor.v] + [el->el_cursor.h] == MB_FILL_CHAR) + el->el_cursor.h++; +#endif + } else { + terminal__putc(el, ' '); el->el_cursor.h = 1; } } } else /* no wrap, but cursor stays on screen */ - el->el_cursor.h = el->el_term.t_size.h - 1; + el->el_cursor.h = el->el_terminal.t_size.h - 1; } } -/* term_deletechars(): +/* terminal_deletechars(): * Delete num characters */ protected void -term_deletechars(EditLine *el, int num) +terminal_deletechars(EditLine *el, int num) { if (num <= 0) return; @@ -723,10 +703,10 @@ #endif /* DEBUG_EDIT */ return; } - if (num > el->el_term.t_size.h) { + if (num > el->el_terminal.t_size.h) { #ifdef DEBUG_SCREEN (void) fprintf(el->el_errfile, - "term_deletechars: num is riduculous: %d\r\n", num); + "terminal_deletechars: num is riduculous: %d\r\n", num); #endif /* DEBUG_SCREEN */ return; } @@ -733,27 +713,28 @@ if (GoodStr(T_DC)) /* if I have multiple delete */ if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more * expen. */ - term_tputs(el, tgoto(Str(T_DC), num, num), num); + terminal_tputs(el, tgoto(Str(T_DC), num, num), num); return; } if (GoodStr(T_dm)) /* if I have delete mode */ - term_tputs(el, Str(T_dm), 1); + terminal_tputs(el, Str(T_dm), 1); if (GoodStr(T_dc)) /* else do one at a time */ while (num--) - term_tputs(el, Str(T_dc), 1); + terminal_tputs(el, Str(T_dc), 1); if (GoodStr(T_ed)) /* if I have delete mode */ - term_tputs(el, Str(T_ed), 1); + terminal_tputs(el, Str(T_ed), 1); } -/* term_insertwrite(): +/* terminal_insertwrite(): * Puts terminal in insert character mode or inserts num * characters in the line + * Assumes MB_FILL_CHARs are present to keep column count correct */ protected void -term_insertwrite(EditLine *el, char *cp, int num) +terminal_insertwrite(EditLine *el, Char *cp, int num) { if (num <= 0) return; @@ -763,7 +744,7 @@ #endif /* DEBUG_EDIT */ return; } - if (num > el->el_term.t_size.h) { + if (num > el->el_terminal.t_size.h) { #ifdef DEBUG_SCREEN (void) fprintf(el->el_errfile, "StartInsert: num is riduculous: %d\r\n", num); @@ -773,35 +754,35 @@ if (GoodStr(T_IC)) /* if I have multiple insert */ if ((num > 1) || !GoodStr(T_ic)) { /* if ic would be more expensive */ - term_tputs(el, tgoto(Str(T_IC), num, num), num); - term_overwrite(el, cp, (size_t)num); + terminal_tputs(el, tgoto(Str(T_IC), num, num), num); + terminal_overwrite(el, cp, (size_t)num); /* this updates el_cursor.h */ return; } if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */ - term_tputs(el, Str(T_im), 1); + terminal_tputs(el, Str(T_im), 1); el->el_cursor.h += num; do - term__putc(el, *cp++); + terminal__putc(el, *cp++); while (--num); if (GoodStr(T_ip)) /* have to make num chars insert */ - term_tputs(el, Str(T_ip), 1); + terminal_tputs(el, Str(T_ip), 1); - term_tputs(el, Str(T_ei), 1); + terminal_tputs(el, Str(T_ei), 1); return; } do { if (GoodStr(T_ic)) /* have to make num chars insert */ - term_tputs(el, Str(T_ic), 1); + terminal_tputs(el, Str(T_ic), 1); - term__putc(el, *cp++); + terminal__putc(el, *cp++); el->el_cursor.h++; if (GoodStr(T_ip)) /* have to make num chars insert */ - term_tputs(el, Str(T_ip), 1); + terminal_tputs(el, Str(T_ip), 1); /* pad the inserted char */ } while (--num); @@ -808,85 +789,71 @@ } -/* term_clear_EOL(): +/* terminal_clear_EOL(): * clear to end of line. There are num characters to clear */ protected void -term_clear_EOL(EditLine *el, int num) +terminal_clear_EOL(EditLine *el, int num) { int i; if (EL_CAN_CEOL && GoodStr(T_ce)) - term_tputs(el, Str(T_ce), 1); + terminal_tputs(el, Str(T_ce), 1); else { for (i = 0; i < num; i++) - term__putc(el, ' '); + terminal__putc(el, ' '); el->el_cursor.h += num; /* have written num spaces */ } } -/* term_clear_screen(): +/* terminal_clear_screen(): * Clear the screen */ protected void -term_clear_screen(EditLine *el) +terminal_clear_screen(EditLine *el) { /* clear the whole screen and home */ if (GoodStr(T_cl)) /* send the clear screen code */ - term_tputs(el, Str(T_cl), Val(T_li)); + terminal_tputs(el, Str(T_cl), Val(T_li)); else if (GoodStr(T_ho) && GoodStr(T_cd)) { - term_tputs(el, Str(T_ho), Val(T_li)); /* home */ + terminal_tputs(el, Str(T_ho), Val(T_li)); /* home */ /* clear to bottom of screen */ - term_tputs(el, Str(T_cd), Val(T_li)); + terminal_tputs(el, Str(T_cd), Val(T_li)); } else { - term__putc(el, '\r'); - term__putc(el, '\n'); + terminal__putc(el, '\r'); + terminal__putc(el, '\n'); } } -/* term_beep(): +/* terminal_beep(): * Beep the way the terminal wants us */ protected void -term_beep(EditLine *el) +terminal_beep(EditLine *el) { if (GoodStr(T_bl)) /* what termcap says we should use */ - term_tputs(el, Str(T_bl), 1); + terminal_tputs(el, Str(T_bl), 1); else - term__putc(el, '\007'); /* an ASCII bell; ^G */ + terminal__putc(el, '\007'); /* an ASCII bell; ^G */ } -#ifdef notdef -/* term_clear_to_bottom(): - * Clear to the bottom of the screen - */ protected void -term_clear_to_bottom(EditLine *el) +terminal_get(EditLine *el, const char **term) { - if (GoodStr(T_cd)) - term_tputs(el, Str(T_cd), Val(T_li)); - else if (GoodStr(T_ce)) - term_tputs(el, Str(T_ce), Val(T_li)); + *term = el->el_terminal.t_name; } -#endif -protected void -term_get(EditLine *el, const char **term) -{ - *term = el->el_term.t_name; -} - -/* term_set(): +/* terminal_set(): * Read in the terminal capabilities from the requested terminal */ protected int -term_set(EditLine *el, const char *term) +terminal_set(EditLine *el, const char *term) { int i; char buf[TC_BUFSIZE]; @@ -911,9 +878,9 @@ if (strcmp(term, "emacs") == 0) el->el_flags |= EDIT_DISABLED; - memset(el->el_term.t_cap, 0, TC_BUFSIZE); + (void) memset(el->el_terminal.t_cap, 0, TC_BUFSIZE); - i = tgetent(el->el_term.t_cap, term); + i = tgetent(el->el_terminal.t_cap, term); if (i <= 0) { if (i == -1) @@ -928,7 +895,7 @@ Val(T_pt) = Val(T_km) = Val(T_li) = 0; Val(T_xt) = Val(T_MT); for (t = tstr; t->name != NULL; t++) - term_alloc(el, t, NULL); + terminal_alloc(el, t, NULL); } else { /* auto/magic margins */ Val(T_am) = tgetflag("am"); @@ -944,7 +911,7 @@ Val(T_li) = tgetnum("li"); for (t = tstr; t->name != NULL; t++) { /* XXX: some systems' tgetstr needs non const */ - term_alloc(el, t, tgetstr(strchr(t->name, *t->name), + terminal_alloc(el, t, tgetstr(strchr(t->name, *t->name), &area)); } } @@ -954,28 +921,28 @@ if (Val(T_li) < 1) Val(T_li) = 24; - el->el_term.t_size.v = Val(T_co); - el->el_term.t_size.h = Val(T_li); + el->el_terminal.t_size.v = Val(T_co); + el->el_terminal.t_size.h = Val(T_li); - term_setflags(el); + terminal_setflags(el); /* get the correct window size */ - (void) term_get_size(el, &lins, &cols); - if (term_change_size(el, lins, cols) == -1) - return (-1); + (void) terminal_get_size(el, &lins, &cols); + if (terminal_change_size(el, lins, cols) == -1) + return -1; (void) sigprocmask(SIG_SETMASK, &oset, NULL); - term_bind_arrow(el); - el->el_term.t_name = term; - return (i <= 0 ? -1 : 0); + terminal_bind_arrow(el); + el->el_terminal.t_name = term; + return i <= 0 ? -1 : 0; } -/* term_get_size(): +/* terminal_get_size(): * Return the new window size in lines and cols, and * true if the size was changed. */ protected int -term_get_size(EditLine *el, int *lins, int *cols) +terminal_get_size(EditLine *el, int *lins, int *cols) { *cols = Val(T_co); @@ -984,7 +951,7 @@ #ifdef TIOCGWINSZ { struct winsize ws; - if (ioctl(el->el_infd, TIOCGWINSZ, (ioctl_t) & ws) != -1) { + if (ioctl(el->el_infd, TIOCGWINSZ, &ws) != -1) { if (ws.ws_col) *cols = ws.ws_col; if (ws.ws_row) @@ -995,7 +962,7 @@ #ifdef TIOCGSIZE { struct ttysize ts; - if (ioctl(el->el_infd, TIOCGSIZE, (ioctl_t) & ts) != -1) { + if (ioctl(el->el_infd, TIOCGSIZE, &ts) != -1) { if (ts.ts_cols) *cols = ts.ts_cols; if (ts.ts_lines) @@ -1003,15 +970,15 @@ } } #endif - return (Val(T_co) != *cols || Val(T_li) != *lins); + return Val(T_co) != *cols || Val(T_li) != *lins; } -/* term_change_size(): +/* terminal_change_size(): * Change the size of the terminal */ protected int -term_change_size(EditLine *el, int lins, int cols) +terminal_change_size(EditLine *el, int lins, int cols) { /* * Just in case @@ -1020,52 +987,52 @@ Val(T_li) = (lins < 1) ? 24 : lins; /* re-make display buffers */ - if (term_rebuffer_display(el) == -1) - return (-1); + if (terminal_rebuffer_display(el) == -1) + return -1; re_clear_display(el); - return (0); + return 0; } -/* term_init_arrow(): +/* terminal_init_arrow(): * Initialize the arrow key bindings from termcap */ private void -term_init_arrow(EditLine *el) +terminal_init_arrow(EditLine *el) { - fkey_t *arrow = el->el_term.t_fkey; + funckey_t *arrow = el->el_terminal.t_fkey; - arrow[A_K_DN].name = "down"; + arrow[A_K_DN].name = STR("down"); arrow[A_K_DN].key = T_kd; arrow[A_K_DN].fun.cmd = ED_NEXT_HISTORY; arrow[A_K_DN].type = XK_CMD; - arrow[A_K_UP].name = "up"; + arrow[A_K_UP].name = STR("up"); arrow[A_K_UP].key = T_ku; arrow[A_K_UP].fun.cmd = ED_PREV_HISTORY; arrow[A_K_UP].type = XK_CMD; - arrow[A_K_LT].name = "left"; + arrow[A_K_LT].name = STR("left"); arrow[A_K_LT].key = T_kl; arrow[A_K_LT].fun.cmd = ED_PREV_CHAR; arrow[A_K_LT].type = XK_CMD; - arrow[A_K_RT].name = "right"; + arrow[A_K_RT].name = STR("right"); arrow[A_K_RT].key = T_kr; arrow[A_K_RT].fun.cmd = ED_NEXT_CHAR; arrow[A_K_RT].type = XK_CMD; - arrow[A_K_HO].name = "home"; + arrow[A_K_HO].name = STR("home"); arrow[A_K_HO].key = T_kh; arrow[A_K_HO].fun.cmd = ED_MOVE_TO_BEG; arrow[A_K_HO].type = XK_CMD; - arrow[A_K_EN].name = "end"; + arrow[A_K_EN].name = STR("end"); arrow[A_K_EN].key = T_at7; arrow[A_K_EN].fun.cmd = ED_MOVE_TO_END; arrow[A_K_EN].type = XK_CMD; - arrow[A_K_DE].name = "delete"; + arrow[A_K_DE].name = STR("delete"); arrow[A_K_DE].key = T_kD; arrow[A_K_DE].fun.cmd = ED_DELETE_NEXT_CHAR; arrow[A_K_DE].type = XK_CMD; @@ -1072,242 +1039,253 @@ } -/* term_reset_arrow(): +/* terminal_reset_arrow(): * Reset arrow key bindings */ private void -term_reset_arrow(EditLine *el) +terminal_reset_arrow(EditLine *el) { - fkey_t *arrow = el->el_term.t_fkey; - static const char strA[] = {033, '[', 'A', '\0'}; - static const char strB[] = {033, '[', 'B', '\0'}; - static const char strC[] = {033, '[', 'C', '\0'}; - static const char strD[] = {033, '[', 'D', '\0'}; - static const char strH[] = {033, '[', 'H', '\0'}; - static const char strF[] = {033, '[', 'F', '\0'}; - static const char str1[] = {033, '[', '1', '~', '\0'}; - static const char str4[] = {033, '[', '4', '~', '\0'}; - static const char stOA[] = {033, 'O', 'A', '\0'}; - static const char stOB[] = {033, 'O', 'B', '\0'}; - static const char stOC[] = {033, 'O', 'C', '\0'}; - static const char stOD[] = {033, 'O', 'D', '\0'}; - static const char stOH[] = {033, 'O', 'H', '\0'}; - static const char stOF[] = {033, 'O', 'F', '\0'}; + funckey_t *arrow = el->el_terminal.t_fkey; + static const Char strA[] = {033, '[', 'A', '\0'}; + static const Char strB[] = {033, '[', 'B', '\0'}; + static const Char strC[] = {033, '[', 'C', '\0'}; + static const Char strD[] = {033, '[', 'D', '\0'}; + static const Char strH[] = {033, '[', 'H', '\0'}; + static const Char strF[] = {033, '[', 'F', '\0'}; + static const Char stOA[] = {033, 'O', 'A', '\0'}; + static const Char stOB[] = {033, 'O', 'B', '\0'}; + static const Char stOC[] = {033, 'O', 'C', '\0'}; + static const Char stOD[] = {033, 'O', 'D', '\0'}; + static const Char stOH[] = {033, 'O', 'H', '\0'}; + static const Char stOF[] = {033, 'O', 'F', '\0'}; - key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); - key_add(el, str1, &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, str4, &arrow[A_K_EN].fun, arrow[A_K_EN].type); - key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); + keymacro_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); + keymacro_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); + keymacro_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); + keymacro_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); + keymacro_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); + keymacro_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); + keymacro_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); + keymacro_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); + keymacro_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); + keymacro_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); + keymacro_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); + keymacro_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); - if (el->el_map.type == MAP_VI) { - key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); - key_add(el, &str1[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, &str4[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); - key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); - } + if (el->el_map.type != MAP_VI) + return; + keymacro_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); + keymacro_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); + keymacro_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); + keymacro_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); + keymacro_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); + keymacro_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); + keymacro_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); + keymacro_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); + keymacro_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); + keymacro_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); + keymacro_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); + keymacro_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); } -/* term_set_arrow(): +/* terminal_set_arrow(): * Set an arrow key binding */ protected int -term_set_arrow(EditLine *el, const char *name, key_value_t *fun, int type) +terminal_set_arrow(EditLine *el, const Char *name, keymacro_value_t *fun, + int type) { - fkey_t *arrow = el->el_term.t_fkey; + funckey_t *arrow = el->el_terminal.t_fkey; int i; for (i = 0; i < A_K_NKEYS; i++) - if (strcmp(name, arrow[i].name) == 0) { + if (Strcmp(name, arrow[i].name) == 0) { arrow[i].fun = *fun; arrow[i].type = type; - return (0); + return 0; } - return (-1); + return -1; } -/* term_clear_arrow(): +/* terminal_clear_arrow(): * Clear an arrow key binding */ protected int -term_clear_arrow(EditLine *el, const char *name) +terminal_clear_arrow(EditLine *el, const Char *name) { - fkey_t *arrow = el->el_term.t_fkey; + funckey_t *arrow = el->el_terminal.t_fkey; int i; for (i = 0; i < A_K_NKEYS; i++) - if (strcmp(name, arrow[i].name) == 0) { + if (Strcmp(name, arrow[i].name) == 0) { arrow[i].type = XK_NOD; - return (0); + return 0; } - return (-1); + return -1; } -/* term_print_arrow(): +/* terminal_print_arrow(): * Print the arrow key bindings */ protected void -term_print_arrow(EditLine *el, const char *name) +terminal_print_arrow(EditLine *el, const Char *name) { int i; - fkey_t *arrow = el->el_term.t_fkey; + funckey_t *arrow = el->el_terminal.t_fkey; for (i = 0; i < A_K_NKEYS; i++) - if (*name == '\0' || strcmp(name, arrow[i].name) == 0) + if (*name == '\0' || Strcmp(name, arrow[i].name) == 0) if (arrow[i].type != XK_NOD) - key_kprint(el, arrow[i].name, &arrow[i].fun, - arrow[i].type); + keymacro_kprint(el, arrow[i].name, + &arrow[i].fun, arrow[i].type); } -/* term_bind_arrow(): +/* terminal_bind_arrow(): * Bind the arrow keys */ protected void -term_bind_arrow(EditLine *el) +terminal_bind_arrow(EditLine *el) { el_action_t *map; const el_action_t *dmap; int i, j; char *p; - fkey_t *arrow = el->el_term.t_fkey; + funckey_t *arrow = el->el_terminal.t_fkey; /* Check if the components needed are initialized */ - if (el->el_term.t_buf == NULL || el->el_map.key == NULL) + if (el->el_terminal.t_buf == NULL || el->el_map.key == NULL) return; map = el->el_map.type == MAP_VI ? el->el_map.alt : el->el_map.key; dmap = el->el_map.type == MAP_VI ? el->el_map.vic : el->el_map.emacs; - term_reset_arrow(el); + terminal_reset_arrow(el); for (i = 0; i < A_K_NKEYS; i++) { - p = el->el_term.t_str[arrow[i].key]; - if (p && *p) { - j = (unsigned char) *p; - /* - * Assign the arrow keys only if: - * - * 1. They are multi-character arrow keys and the user - * has not re-assigned the leading character, or - * has re-assigned the leading character to be - * ED_SEQUENCE_LEAD_IN - * 2. They are single arrow keys pointing to an - * unassigned key. - */ - if (arrow[i].type == XK_NOD) - key_clear(el, map, p); - else { - if (p[1] && (dmap[j] == map[j] || - map[j] == ED_SEQUENCE_LEAD_IN)) { - key_add(el, p, &arrow[i].fun, + Char wt_str[VISUAL_WIDTH_MAX]; + Char *px; + size_t n; + + p = el->el_terminal.t_str[arrow[i].key]; + if (!p || !*p) + continue; + for (n = 0; n < VISUAL_WIDTH_MAX && p[n]; ++n) + wt_str[n] = p[n]; + while (n < VISUAL_WIDTH_MAX) + wt_str[n++] = '\0'; + px = wt_str; + j = (unsigned char) *p; + /* + * Assign the arrow keys only if: + * + * 1. They are multi-character arrow keys and the user + * has not re-assigned the leading character, or + * has re-assigned the leading character to be + * ED_SEQUENCE_LEAD_IN + * 2. They are single arrow keys pointing to an + * unassigned key. + */ + if (arrow[i].type == XK_NOD) + keymacro_clear(el, map, px); + else { + if (p[1] && (dmap[j] == map[j] || + map[j] == ED_SEQUENCE_LEAD_IN)) { + keymacro_add(el, px, &arrow[i].fun, + arrow[i].type); + map[j] = ED_SEQUENCE_LEAD_IN; + } else if (map[j] == ED_UNASSIGNED) { + keymacro_clear(el, map, px); + if (arrow[i].type == XK_CMD) + map[j] = arrow[i].fun.cmd; + else + keymacro_add(el, px, &arrow[i].fun, arrow[i].type); - map[j] = ED_SEQUENCE_LEAD_IN; - } else if (map[j] == ED_UNASSIGNED) { - key_clear(el, map, p); - if (arrow[i].type == XK_CMD) - map[j] = arrow[i].fun.cmd; - else - key_add(el, p, &arrow[i].fun, - arrow[i].type); - } } } } } -/* term_putc(): +/* terminal_putc(): * Add a character */ private int -term_putc(int c) +terminal_putc(int c) { - - if (term_outfile == NULL) + if (terminal_outfile == NULL) return -1; - return fputc(c, term_outfile); + return fputc(c, terminal_outfile); } private void -term_tputs(EditLine *el, const char *cap, int affcnt) +terminal_tputs(EditLine *el, const char *cap, int affcnt) { #ifdef _REENTRANT - pthread_mutex_lock(&term_mutex); + pthread_mutex_lock(&terminal_mutex); #endif - term_outfile = el->el_outfile; - (void)tputs(cap, affcnt, term_putc); + terminal_outfile = el->el_outfile; + (void)tputs(cap, affcnt, terminal_putc); #ifdef _REENTRANT - pthread_mutex_unlock(&term_mutex); + pthread_mutex_unlock(&terminal_mutex); #endif } -/* term__putc(): +/* terminal__putc(): * Add a character */ protected int -term__putc(EditLine *el, int c) +terminal__putc(EditLine *el, Int c) { - - return fputc(c, el->el_outfile); + char buf[MB_LEN_MAX +1]; + ssize_t i; + if (c == (Int)MB_FILL_CHAR) + return 0; + i = ct_encode_char(buf, (size_t)MB_LEN_MAX, c); + if (i <= 0) + return (int)i; + buf[i] = '\0'; + return fputs(buf, el->el_outfile); } -/* term__flush(): +/* terminal__flush(): * Flush output */ protected void -term__flush(EditLine *el) +terminal__flush(EditLine *el) { (void) fflush(el->el_outfile); } -/* term_writec(): +/* terminal_writec(): * Write the given character out, in a human readable form */ protected void -term_writec(EditLine *el, int c) +terminal_writec(EditLine *el, Int c) { - char buf[8]; - size_t cnt = key__decode_char(buf, sizeof(buf), 0, c); - buf[cnt] = '\0'; - term_overwrite(el, buf, (size_t)cnt); - term__flush(el); + Char visbuf[VISUAL_WIDTH_MAX +1]; + ssize_t vcnt = ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c); + if (vcnt < 0) + vcnt = 0; + visbuf[vcnt] = '\0'; + terminal_overwrite(el, visbuf, (size_t)vcnt); + terminal__flush(el); } -/* term_telltc(): +/* terminal_telltc(): * Print the current termcap characteristics */ protected int /*ARGSUSED*/ -term_telltc(EditLine *el, int argc __unused, - const char **argv __unused) +terminal_telltc(EditLine *el, int argc __attribute__((__unused__)), + const Char **argv __attribute__((__unused__))) { const struct termcapstr *t; char **ts; - char upbuf[EL_BUFSIZ]; (void) fprintf(el->el_outfile, "\n\tYour terminal has the\n"); (void) fprintf(el->el_outfile, "\tfollowing characteristics:\n\n"); @@ -1323,39 +1301,42 @@ (void) fprintf(el->el_outfile, "\tIt %s magic margins\n", EL_HAS_MAGIC_MARGINS ? "has" : "does not have"); - for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++) { + for (t = tstr, ts = el->el_terminal.t_str; t->name != NULL; t++, ts++) { const char *ub; if (*ts && **ts) { - (void) key__decode_str(*ts, upbuf, sizeof(upbuf), ""); - ub = upbuf; + ub = ct_encode_string(ct_visual_string( + ct_decode_string(*ts, &el->el_scratch)), + &el->el_scratch); } else { - ub = "(empty)"; + ub = "(empty)"; } (void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n", t->long_name, t->name, ub); } (void) fputc('\n', el->el_outfile); - return (0); + return 0; } -/* term_settc(): +/* terminal_settc(): * Change the current terminal characteristics */ protected int /*ARGSUSED*/ -term_settc(EditLine *el, int argc __unused, - const char **argv) +terminal_settc(EditLine *el, int argc __attribute__((__unused__)), + const Char **argv) { const struct termcapstr *ts; const struct termcapval *tv; - const char *what, *how; + char what[8], how[8]; if (argv == NULL || argv[1] == NULL || argv[2] == NULL) return -1; - what = argv[1]; - how = argv[2]; + strncpy(what, ct_encode_string(argv[1], &el->el_scratch), sizeof(what)); + what[sizeof(what) - 1] = '\0'; + strncpy(how, ct_encode_string(argv[2], &el->el_scratch), sizeof(how)); + how[sizeof(how) - 1] = '\0'; /* * Do the strings first @@ -1365,8 +1346,8 @@ break; if (ts->name != NULL) { - term_alloc(el, ts, how); - term_setflags(el); + terminal_alloc(el, ts, how); + terminal_setflags(el); return 0; } /* @@ -1382,16 +1363,16 @@ if (tv == &tval[T_pt] || tv == &tval[T_km] || tv == &tval[T_am] || tv == &tval[T_xn]) { if (strcmp(how, "yes") == 0) - el->el_term.t_val[tv - tval] = 1; + el->el_terminal.t_val[tv - tval] = 1; else if (strcmp(how, "no") == 0) - el->el_term.t_val[tv - tval] = 0; + el->el_terminal.t_val[tv - tval] = 0; else { (void) fprintf(el->el_errfile, - "%s: Bad value `%s'.\n", argv[0], how); + "" FSTR ": Bad value `%s'.\n", argv[0], how); return -1; } - term_setflags(el); - if (term_change_size(el, Val(T_li), Val(T_co)) == -1) + terminal_setflags(el); + if (terminal_change_size(el, Val(T_li), Val(T_co)) == -1) return -1; return 0; } else { @@ -1401,14 +1382,14 @@ i = strtol(how, &ep, 10); if (*ep != '\0') { (void) fprintf(el->el_errfile, - "%s: Bad value `%s'.\n", argv[0], how); + "" FSTR ": Bad value `%s'.\n", argv[0], how); return -1; } - el->el_term.t_val[tv - tval] = (int) i; - el->el_term.t_size.v = Val(T_co); - el->el_term.t_size.h = Val(T_li); + el->el_terminal.t_val[tv - tval] = (int) i; + el->el_terminal.t_size.v = Val(T_co); + el->el_terminal.t_size.h = Val(T_li); if (tv == &tval[T_co] || tv == &tval[T_li]) - if (term_change_size(el, Val(T_li), Val(T_co)) + if (terminal_change_size(el, Val(T_li), Val(T_co)) == -1) return -1; return 0; @@ -1416,12 +1397,12 @@ } -/* term_gettc(): +/* terminal_gettc(): * Get the current terminal characteristics */ protected int /*ARGSUSED*/ -term_gettc(EditLine *el, int argc __unused, char **argv) +terminal_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) { const struct termcapstr *ts; const struct termcapval *tv; @@ -1429,7 +1410,7 @@ void *how; if (argv == NULL || argv[1] == NULL || argv[2] == NULL) - return (-1); + return -1; what = argv[1]; how = argv[2]; @@ -1442,7 +1423,7 @@ break; if (ts->name != NULL) { - *(char **)how = el->el_term.t_str[ts - tstr]; + *(char **)how = el->el_terminal.t_str[ts - tstr]; return 0; } /* @@ -1459,26 +1440,27 @@ tv == &tval[T_am] || tv == &tval[T_xn]) { static char yes[] = "yes"; static char no[] = "no"; - if (el->el_term.t_val[tv - tval]) + if (el->el_terminal.t_val[tv - tval]) *(char **)how = yes; else *(char **)how = no; return 0; } else { - *(int *)how = el->el_term.t_val[tv - tval]; + *(int *)how = el->el_terminal.t_val[tv - tval]; return 0; } } -/* term_echotc(): +/* terminal_echotc(): * Print the termcap string out with variable substitution */ protected int /*ARGSUSED*/ -term_echotc(EditLine *el, int argc __unused, - const char **argv) +terminal_echotc(EditLine *el, int argc __attribute__((__unused__)), + const Char **argv) { - char *cap, *scap, *ep; + char *cap, *scap; + Char *ep; int arg_need, arg_cols, arg_rows; int verbose = 0, silent = 0; char *area; @@ -1490,7 +1472,7 @@ area = buf; if (argv == NULL || argv[1] == NULL) - return (-1); + return -1; argv++; if (argv[0][0] == '-') { @@ -1508,42 +1490,31 @@ argv++; } if (!*argv || *argv[0] == '\0') - return (0); - if (strcmp(*argv, "tabs") == 0) { + return 0; + if (Strcmp(*argv, STR("tabs")) == 0) { (void) fprintf(el->el_outfile, fmts, EL_CAN_TAB ? "yes" : "no"); - return (0); - } else if (strcmp(*argv, "meta") == 0) { + return 0; + } else if (Strcmp(*argv, STR("meta")) == 0) { (void) fprintf(el->el_outfile, fmts, Val(T_km) ? "yes" : "no"); - return (0); - } else if (strcmp(*argv, "xn") == 0) { + return 0; + } else if (Strcmp(*argv, STR("xn")) == 0) { (void) fprintf(el->el_outfile, fmts, EL_HAS_MAGIC_MARGINS ? "yes" : "no"); - return (0); - } else if (strcmp(*argv, "am") == 0) { + return 0; + } else if (Strcmp(*argv, STR("am")) == 0) { (void) fprintf(el->el_outfile, fmts, EL_HAS_AUTO_MARGINS ? "yes" : "no"); - return (0); - } else if (strcmp(*argv, "baud") == 0) { -#ifdef notdef - int i; - - for (i = 0; baud_rate[i].b_name != NULL; i++) - if (el->el_tty.t_speed == baud_rate[i].b_rate) { - (void) fprintf(el->el_outfile, fmts, - baud_rate[i].b_name); - return (0); - } - (void) fprintf(el->el_outfile, fmtd, 0); -#else + return 0; + } else if (Strcmp(*argv, STR("baud")) == 0) { (void) fprintf(el->el_outfile, fmtd, (int)el->el_tty.t_speed); -#endif - return (0); - } else if (strcmp(*argv, "rows") == 0 || strcmp(*argv, "lines") == 0) { + return 0; + } else if (Strcmp(*argv, STR("rows")) == 0 || + Strcmp(*argv, STR("lines")) == 0) { (void) fprintf(el->el_outfile, fmtd, Val(T_li)); - return (0); - } else if (strcmp(*argv, "cols") == 0) { + return 0; + } else if (Strcmp(*argv, STR("cols")) == 0) { (void) fprintf(el->el_outfile, fmtd, Val(T_co)); - return (0); + return 0; } /* * Try to use our local definition first @@ -1550,20 +1521,21 @@ */ scap = NULL; for (t = tstr; t->name != NULL; t++) - if (strcmp(t->name, *argv) == 0) { - scap = el->el_term.t_str[t - tstr]; + if (strcmp(t->name, + ct_encode_string(*argv, &el->el_scratch)) == 0) { + scap = el->el_terminal.t_str[t - tstr]; break; } if (t->name == NULL) { /* XXX: some systems' tgetstr needs non const */ - scap = tgetstr(strchr(*argv, **argv), &area); + scap = tgetstr(ct_encode_string(*argv, &el->el_scratch), &area); } if (!scap || scap[0] == '\0') { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Termcap parameter `%s' not found.\n", + "echotc: Termcap parameter `" FSTR "' not found.\n", *argv); - return (-1); + return -1; } /* * Count home many values we need for this capability. @@ -1604,11 +1576,11 @@ if (*argv && *argv[0]) { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Warning: Extra argument `%s'.\n", + "echotc: Warning: Extra argument `" FSTR "'.\n", *argv); - return (-1); + return -1; } - term_tputs(el, scap, 1); + terminal_tputs(el, scap, 1); break; case 1: argv++; @@ -1616,16 +1588,16 @@ if (!silent) (void) fprintf(el->el_errfile, "echotc: Warning: Missing argument.\n"); - return (-1); + return -1; } arg_cols = 0; - i = strtol(*argv, &ep, 10); + i = Strtol(*argv, &ep, 10); if (*ep != '\0' || i < 0) { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Bad value `%s' for rows.\n", + "echotc: Bad value `" FSTR "' for rows.\n", *argv); - return (-1); + return -1; } arg_rows = (int) i; argv++; @@ -1632,11 +1604,11 @@ if (*argv && *argv[0]) { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Warning: Extra argument `%s'.\n", - *argv); - return (-1); + "echotc: Warning: Extra argument `" FSTR + "'.\n", *argv); + return -1; } - term_tputs(el, tgoto(scap, arg_cols, arg_rows), 1); + terminal_tputs(el, tgoto(scap, arg_cols, arg_rows), 1); break; default: /* This is wrong, but I will ignore it... */ @@ -1651,15 +1623,15 @@ if (!silent) (void) fprintf(el->el_errfile, "echotc: Warning: Missing argument.\n"); - return (-1); + return -1; } - i = strtol(*argv, &ep, 10); + i = Strtol(*argv, &ep, 10); if (*ep != '\0' || i < 0) { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Bad value `%s' for cols.\n", + "echotc: Bad value `" FSTR "' for cols.\n", *argv); - return (-1); + return -1; } arg_cols = (int) i; argv++; @@ -1667,33 +1639,33 @@ if (!silent) (void) fprintf(el->el_errfile, "echotc: Warning: Missing argument.\n"); - return (-1); + return -1; } - i = strtol(*argv, &ep, 10); + i = Strtol(*argv, &ep, 10); if (*ep != '\0' || i < 0) { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Bad value `%s' for rows.\n", + "echotc: Bad value `" FSTR "' for rows.\n", *argv); - return (-1); + return -1; } arg_rows = (int) i; if (*ep != '\0') { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Bad value `%s'.\n", *argv); - return (-1); + "echotc: Bad value `" FSTR "'.\n", *argv); + return -1; } argv++; if (*argv && *argv[0]) { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Warning: Extra argument `%s'.\n", - *argv); - return (-1); + "echotc: Warning: Extra argument `" FSTR + "'.\n", *argv); + return -1; } - term_tputs(el, tgoto(scap, arg_cols, arg_rows), arg_rows); + terminal_tputs(el, tgoto(scap, arg_cols, arg_rows), arg_rows); break; } - return (0); + return 0; } Index: lib/libedit/terminal.h =================================================================== --- lib/libedit/terminal.h (revision 258914) +++ lib/libedit/terminal.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: terminal.h,v 1.4 2012/03/24 20:09:30 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +32,6 @@ * SUCH DAMAGE. * * @(#)term.h 8.1 (Berkeley) 6/4/93 - * $NetBSD: term.h,v 1.18 2006/11/24 00:01:17 christos Exp $ * $FreeBSD$ */ @@ -37,17 +38,17 @@ /* * el.term.h: Termcap header */ -#ifndef _h_el_term -#define _h_el_term +#ifndef _h_el_terminal +#define _h_el_terminal #include "histedit.h" typedef struct { /* Symbolic function key bindings */ - const char *name; /* name of the key */ + const Char *name; /* name of the key */ int key; /* Index in termcap table */ - key_value_t fun; /* Function bound to it */ + keymacro_value_t fun; /* Function bound to it */ int type; /* Type of function */ -} fkey_t; +} funckey_t; typedef struct { const char *t_name; /* the terminal name */ @@ -63,12 +64,12 @@ #define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */ #define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */ char *t_buf; /* Termcap buffer */ - int t_loc; /* location used */ + size_t t_loc; /* location used */ char **t_str; /* termcap strings */ int *t_val; /* termcap values */ char *t_cap; /* Termcap buffer */ - fkey_t *t_fkey; /* Array of keys */ -} el_term_t; + funckey_t *t_fkey; /* Array of keys */ +} el_terminal_t; /* * fKey indexes @@ -82,36 +83,36 @@ #define A_K_DE 6 #define A_K_NKEYS 7 -protected void term_move_to_line(EditLine *, int); -protected void term_move_to_char(EditLine *, int); -protected void term_clear_EOL(EditLine *, int); -protected void term_overwrite(EditLine *, const char *, size_t); -protected void term_insertwrite(EditLine *, char *, int); -protected void term_deletechars(EditLine *, int); -protected void term_clear_screen(EditLine *); -protected void term_beep(EditLine *); -protected int term_change_size(EditLine *, int, int); -protected int term_get_size(EditLine *, int *, int *); -protected int term_init(EditLine *); -protected void term_bind_arrow(EditLine *); -protected void term_print_arrow(EditLine *, const char *); -protected int term_clear_arrow(EditLine *, const char *); -protected int term_set_arrow(EditLine *, const char *, key_value_t *, int); -protected void term_end(EditLine *); -protected void term_get(EditLine *, const char **); -protected int term_set(EditLine *, const char *); -protected int term_settc(EditLine *, int, const char **); -protected int term_gettc(EditLine *, int, char **); -protected int term_telltc(EditLine *, int, const char **); -protected int term_echotc(EditLine *, int, const char **); -protected void term_writec(EditLine *, int); -protected int term__putc(EditLine *, int); -protected void term__flush(EditLine *); +protected void terminal_move_to_line(EditLine *, int); +protected void terminal_move_to_char(EditLine *, int); +protected void terminal_clear_EOL(EditLine *, int); +protected void terminal_overwrite(EditLine *, const Char *, size_t); +protected void terminal_insertwrite(EditLine *, Char *, int); +protected void terminal_deletechars(EditLine *, int); +protected void terminal_clear_screen(EditLine *); +protected void terminal_beep(EditLine *); +protected int terminal_change_size(EditLine *, int, int); +protected int terminal_get_size(EditLine *, int *, int *); +protected int terminal_init(EditLine *); +protected void terminal_bind_arrow(EditLine *); +protected void terminal_print_arrow(EditLine *, const Char *); +protected int terminal_clear_arrow(EditLine *, const Char *); +protected int terminal_set_arrow(EditLine *, const Char *, keymacro_value_t *, int); +protected void terminal_end(EditLine *); +protected void terminal_get(EditLine *, const char **); +protected int terminal_set(EditLine *, const char *); +protected int terminal_settc(EditLine *, int, const Char **); +protected int terminal_gettc(EditLine *, int, char **); +protected int terminal_telltc(EditLine *, int, const Char **); +protected int terminal_echotc(EditLine *, int, const Char **); +protected void terminal_writec(EditLine *, Int); +protected int terminal__putc(EditLine *, Int); +protected void terminal__flush(EditLine *); /* * 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_DELETE (EL_FLAGS & TERM_CAN_DELETE) @@ -123,4 +124,4 @@ #define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS) #define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS) -#endif /* _h_el_term */ +#endif /* _h_el_terminal */ Index: lib/libedit/tokenizer.c =================================================================== --- lib/libedit/tokenizer.c (revision 258914) +++ lib/libedit/tokenizer.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: tokenizer.c,v 1.21 2011/08/16 16:25:15 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: tokenizer.c,v 1.15 2009/02/15 21:55:23 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -38,20 +39,19 @@ #include __FBSDID("$FreeBSD$"); +/* We build this file twice, once as NARROW, once as WIDE. */ /* * tokenize.c: Bourne shell like tokenizer */ -#include "sys.h" #include #include #include "histedit.h" +#include "chartype.h" typedef enum { Q_none, Q_single, Q_double, Q_one, Q_doubleone } quote_t; -#define IFS "\t \n" - #define TOK_KEEP 1 #define TOK_EAT 2 @@ -58,32 +58,34 @@ #define WINCR 20 #define AINCR 10 -#define tok_strdup(a) strdup(a) +#define IFS STR("\t \n") + #define tok_malloc(a) malloc(a) #define tok_free(a) free(a) #define tok_realloc(a, b) realloc(a, b) +#define tok_strdup(a) Strdup(a) -struct tokenizer { - char *ifs; /* In field separator */ - int argc, amax; /* Current and maximum number of args */ - char **argv; /* Argument list */ - char *wptr, *wmax; /* Space and limit on the word buffer */ - char *wstart; /* Beginning of next word */ - char *wspace; /* Space of word buffer */ +struct TYPE(tokenizer) { + Char *ifs; /* In field separator */ + size_t argc, amax; /* Current and maximum number of args */ + Char **argv; /* Argument list */ + Char *wptr, *wmax; /* Space and limit on the word buffer */ + Char *wstart; /* Beginning of next word */ + Char *wspace; /* Space of word buffer */ quote_t quote; /* Quoting state */ int flags; /* flags; */ }; -private void tok_finish(Tokenizer *); +private void FUN(tok,finish)(TYPE(Tokenizer) *); -/* tok_finish(): +/* FUN(tok,finish)(): * Finish a word in the tokenizer. */ private void -tok_finish(Tokenizer *tok) +FUN(tok,finish)(TYPE(Tokenizer) *tok) { *tok->wptr = '\0'; @@ -96,35 +98,35 @@ } -/* tok_init(): +/* FUN(tok,init)(): * Initialize the tokenizer */ -public Tokenizer * -tok_init(const char *ifs) +public TYPE(Tokenizer) * +FUN(tok,init)(const Char *ifs) { - Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer)); + TYPE(Tokenizer) *tok = tok_malloc(sizeof(*tok)); if (tok == NULL) return NULL; tok->ifs = tok_strdup(ifs ? ifs : IFS); if (tok->ifs == NULL) { - tok_free((ptr_t)tok); + tok_free(tok); return NULL; } tok->argc = 0; tok->amax = AINCR; - tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax); + tok->argv = tok_malloc(sizeof(*tok->argv) * tok->amax); if (tok->argv == NULL) { - tok_free((ptr_t)tok->ifs); - tok_free((ptr_t)tok); + tok_free(tok->ifs); + tok_free(tok); return NULL; } tok->argv[0] = NULL; - tok->wspace = (char *) tok_malloc(WINCR); + tok->wspace = tok_malloc(WINCR * sizeof(*tok->wspace)); if (tok->wspace == NULL) { - tok_free((ptr_t)tok->argv); - tok_free((ptr_t)tok->ifs); - tok_free((ptr_t)tok); + tok_free(tok->argv); + tok_free(tok->ifs); + tok_free(tok); return NULL; } tok->wmax = tok->wspace + WINCR; @@ -133,15 +135,15 @@ tok->flags = 0; tok->quote = Q_none; - return (tok); + return tok; } -/* tok_reset(): +/* FUN(tok,reset)(): * Reset the tokenizer */ public void -tok_reset(Tokenizer *tok) +FUN(tok,reset)(TYPE(Tokenizer) *tok) { tok->argc = 0; @@ -152,25 +154,25 @@ } -/* tok_end(): +/* FUN(tok,end)(): * Clean up */ public void -tok_end(Tokenizer *tok) +FUN(tok,end)(TYPE(Tokenizer) *tok) { - tok_free((ptr_t) tok->ifs); - tok_free((ptr_t) tok->wspace); - tok_free((ptr_t) tok->argv); - tok_free((ptr_t) tok); + tok_free(tok->ifs); + tok_free(tok->wspace); + tok_free(tok->argv); + tok_free(tok); } -/* tok_line(): +/* FUN(tok,line)(): * Bourne shell (sh(1)) like tokenizing * Arguments: - * tok current tokenizer state (setup with tok_init()) + * tok current tokenizer state (setup with FUN(tok,init)()) * line line to parse * Returns: * -1 Internal error @@ -185,10 +187,10 @@ * cursorv if !NULL, offset in argv[cursorc] of cursor */ public int -tok_line(Tokenizer *tok, const LineInfo *line, - int *argc, const char ***argv, int *cursorc, int *cursoro) +FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line, + int *argc, const Char ***argv, int *cursorc, int *cursoro) { - const char *ptr; + const Char *ptr; int cc, co; cc = co = -1; @@ -195,9 +197,9 @@ ptr = line->buffer; for (ptr = line->buffer; ;ptr++) { if (ptr >= line->lastchar) - ptr = ""; + ptr = STR(""); if (ptr == line->cursor) { - cc = tok->argc; + cc = (int)tok->argc; co = (int)(tok->wptr - tok->wstart); } switch (*ptr) { @@ -229,7 +231,7 @@ break; default: - return (-1); + return -1; } break; @@ -260,7 +262,7 @@ break; default: - return (-1); + return -1; } break; @@ -291,7 +293,7 @@ break; default: - return (-1); + return -1; } break; @@ -317,7 +319,7 @@ break; default: - return (0); + return 0; } break; @@ -327,15 +329,15 @@ /* Finish word and return */ if (tok->flags & TOK_EAT) { tok->flags &= ~TOK_EAT; - return (3); + return 3; } goto tok_line_outok; case Q_single: - return (1); + return 1; case Q_double: - return (2); + return 2; case Q_doubleone: tok->quote = Q_double; @@ -348,7 +350,7 @@ break; default: - return (-1); + return -1; } break; @@ -356,8 +358,8 @@ tok->flags &= ~TOK_EAT; switch (tok->quote) { case Q_none: - if (strchr(tok->ifs, *ptr) != NULL) - tok_finish(tok); + if (Strchr(tok->ifs, *ptr) != NULL) + FUN(tok,finish)(tok); else *tok->wptr++ = *ptr; break; @@ -380,7 +382,7 @@ break; default: - return (-1); + return -1; } break; @@ -387,13 +389,14 @@ } if (tok->wptr >= tok->wmax - 4) { - size_t size = tok->wmax - tok->wspace + WINCR; - char *s = (char *) tok_realloc(tok->wspace, size); + size_t size = (size_t)(tok->wmax - tok->wspace + WINCR); + Char *s = tok_realloc(tok->wspace, + size * sizeof(*s)); if (s == NULL) - return (-1); + return -1; if (s != tok->wspace) { - int i; + size_t i; for (i = 0; i < tok->argc; i++) { tok->argv[i] = (tok->argv[i] - tok->wspace) + s; @@ -405,18 +408,17 @@ tok->wmax = s + size; } if (tok->argc >= tok->amax - 4) { - char **p; + Char **p; tok->amax += AINCR; - p = (char **) tok_realloc(tok->argv, - tok->amax * sizeof(char *)); + p = tok_realloc(tok->argv, tok->amax * sizeof(*p)); if (p == NULL) - return (-1); + return -1; tok->argv = p; } } tok_line_outok: if (cc == -1 && co == -1) { - cc = tok->argc; + cc = (int)tok->argc; co = (int)(tok->wptr - tok->wstart); } if (cursorc != NULL) @@ -423,23 +425,24 @@ *cursorc = cc; if (cursoro != NULL) *cursoro = co; - tok_finish(tok); - *argv = (const char **)tok->argv; - *argc = tok->argc; - return (0); + FUN(tok,finish)(tok); + *argv = (const Char **)tok->argv; + *argc = (int)tok->argc; + return 0; } -/* tok_str(): +/* FUN(tok,str)(): * Simpler version of tok_line, taking a NUL terminated line * and splitting into words, ignoring cursor state. */ public int -tok_str(Tokenizer *tok, const char *line, int *argc, const char ***argv) +FUN(tok,str)(TYPE(Tokenizer) *tok, const Char *line, int *argc, + const Char ***argv) { - LineInfo li; + TYPE(LineInfo) li; memset(&li, 0, sizeof(li)); li.buffer = line; - li.cursor = li.lastchar = strchr(line, '\0'); - return (tok_line(tok, &li, argc, argv, NULL, NULL)); + li.cursor = li.lastchar = Strchr(line, '\0'); + return FUN(tok,line(tok, &li, argc, argv, NULL, NULL)); } Index: lib/libedit/tty.c =================================================================== --- lib/libedit/tty.c (revision 258914) +++ lib/libedit/tty.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: tty.c,v 1.42 2012/05/15 15:59:01 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,10 +30,9 @@ * 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. - * - * $NetBSD: tty.c,v 1.25 2006/03/18 09:09:41 christos Exp $ */ +#include "config.h" #if !defined(lint) && !defined(SCCSID) static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ @@ -42,9 +43,11 @@ * tty.c: tty interface stuff */ #include -#include "sys.h" +#include +#include /* for isatty */ +#include /* for ffs */ +#include "el.h" #include "tty.h" -#include "el.h" typedef struct ttymodes_t { const char *m_name; @@ -53,7 +56,7 @@ } ttymodes_t; typedef struct ttymap_t { - int nch, och; /* Internal and termio rep of chars */ + Int nch, och; /* Internal and termio rep of chars */ el_action_t bind[3]; /* emacs, vi, and vi-cmd */ } ttymap_t; @@ -149,7 +152,7 @@ {C_LNEXT, VLNEXT, {ED_QUOTED_INSERT, ED_QUOTED_INSERT, ED_UNASSIGNED}}, #endif /* VLNEXT */ - {-1, -1, + {(Int)-1, (Int)-1, {ED_UNASSIGNED, ED_UNASSIGNED, ED_UNASSIGNED}} }; @@ -443,13 +446,12 @@ -#define tty_getty(el, td) tcgetattr((el)->el_infd, (td)) -#define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td)) - #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1) #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8) #define tty__cooked_mode(td) ((td)->c_lflag & ICANON) +private int tty_getty(EditLine *, struct termios *); +private int tty_setty(EditLine *, int, const struct termios *); private int tty__getcharindex(int); private void tty__getchar(struct termios *, unsigned char *); private void tty__setchar(struct termios *, unsigned char *); @@ -458,7 +460,30 @@ #define t_qu t_ts +/* tty_getty(): + * Wrapper for tcgetattr to handle EINTR + */ +private int +tty_getty(EditLine *el, struct termios *t) +{ + int rv; + while ((rv = tcgetattr(el->el_infd, t)) == -1 && errno == EINTR) + continue; + return rv; +} +/* tty_setty(): + * Wrapper for tcsetattr to handle EINTR + */ +private int +tty_setty(EditLine *el, int action, const struct termios *t) +{ + int rv; + while ((rv = tcsetattr(el->el_infd, action, t)) == -1 && errno == EINTR) + continue; + return rv; +} + /* tty_setup(): * Get the tty parameters and initialize the editing state */ @@ -468,21 +493,40 @@ int rst = 1; if (el->el_flags & EDIT_DISABLED) - return (0); + return 0; - if (tty_getty(el, &el->el_tty.t_ed) == -1) { + if (!isatty(el->el_outfd)) { #ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, - "tty_setup: tty_getty: %s\n", strerror(errno)); + (void) fprintf(el->el_errfile, "%s: isatty: %s\n", __func__, + strerror(errno)); #endif /* DEBUG_TTY */ - return (-1); + return -1; } - el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed; + if (tty_getty(el, &el->el_tty.t_or) == -1) { +#ifdef DEBUG_TTY + (void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__, + strerror(errno)); +#endif /* DEBUG_TTY */ + return -1; + } + el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed = el->el_tty.t_or; el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ex); el->el_tty.t_tabs = tty__gettabs(&el->el_tty.t_ex); el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ex); + el->el_tty.t_ex.c_iflag &= ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask; + el->el_tty.t_ex.c_iflag |= el->el_tty.t_t[EX_IO][MD_INP].t_setmask; + + el->el_tty.t_ex.c_oflag &= ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask; + el->el_tty.t_ex.c_oflag |= el->el_tty.t_t[EX_IO][MD_OUT].t_setmask; + + el->el_tty.t_ex.c_cflag &= ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask; + el->el_tty.t_ex.c_cflag |= el->el_tty.t_t[EX_IO][MD_CTL].t_setmask; + + el->el_tty.t_ex.c_lflag &= ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask; + el->el_tty.t_ex.c_lflag |= el->el_tty.t_t[EX_IO][MD_LIN].t_setmask; + /* * Reset the tty chars to reasonable defaults * If they are disabled, then enable them. @@ -506,6 +550,14 @@ el->el_tty.t_c[EX_IO][rst] = el->el_tty.t_c[TS_IO][rst]; } + tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) { +#ifdef DEBUG_TTY + (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", + __func__, strerror(errno)); +#endif /* DEBUG_TTY */ + return -1; + } } el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; @@ -522,7 +574,7 @@ tty__setchar(&el->el_tty.t_ed, el->el_tty.t_c[ED_IO]); tty_bind_char(el, 1); - return (0); + return 0; } protected int @@ -533,7 +585,7 @@ el->el_tty.t_vdisable = _POSIX_VDISABLE; (void) memcpy(el->el_tty.t_t, ttyperm, sizeof(ttyperm_t)); (void) memcpy(el->el_tty.t_c, ttychar, sizeof(ttychar_t)); - return (tty_setup(el)); + return tty_setup(el); } @@ -542,10 +594,14 @@ */ protected void /*ARGSUSED*/ -tty_end(EditLine *el __unused) +tty_end(EditLine *el) { - - /* XXX: Maybe reset to an initial state? */ + if (tty_setty(el, TCSAFLUSH, &el->el_tty.t_or) == -1) { +#ifdef DEBUG_TTY + (void) fprintf(el->el_errfile, + "%s: tty_setty: %s\n", __func__, strerror(errno)); +#endif /* DEBUG_TTY */ + } } @@ -559,7 +615,7 @@ if ((spd = cfgetispeed(td)) == 0) spd = cfgetospeed(td); - return (spd); + return spd; } /* tty__getspeed(): @@ -843,7 +899,7 @@ unsigned char *t_n = el->el_tty.t_c[ED_IO]; unsigned char *t_o = el->el_tty.t_ed.c_cc; - unsigned char new[2], old[2]; + Char new[2], old[2]; const ttymap_t *tp; el_action_t *map, *alt; const el_action_t *dmap, *dalt; @@ -859,22 +915,22 @@ 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]; old[0] = t_o[tp->och]; if (new[0] == old[0] && !force) continue; /* Put the old default binding back, and set the new binding */ - key_clear(el, map, (char *)old); - map[old[0]] = dmap[old[0]]; - key_clear(el, map, (char *)new); + keymacro_clear(el, map, old); + map[UC(old[0])] = dmap[UC(old[0])]; + keymacro_clear(el, map, new); /* MAP_VI == 1, MAP_EMACS == 0... */ - map[new[0]] = tp->bind[el->el_map.type]; + map[UC(new[0])] = tp->bind[el->el_map.type]; if (dalt) { - key_clear(el, alt, (char *)old); - alt[old[0]] = dalt[old[0]]; - key_clear(el, alt, (char *)new); - alt[new[0]] = tp->bind[el->el_map.type + 1]; + keymacro_clear(el, alt, old); + alt[UC(old[0])] = dalt[UC(old[0])]; + keymacro_clear(el, alt, new); + alt[UC(new[0])] = tp->bind[el->el_map.type + 1]; } } } @@ -888,32 +944,41 @@ { 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) - return (0); + return 0; if (tty_getty(el, &el->el_tty.t_ts) == -1) { #ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "tty_rawmode: tty_getty: %s\n", + (void) fprintf(el->el_errfile, "%s: tty_getty: %s\n", __func__, strerror(errno)); #endif /* DEBUG_TTY */ - return (-1); + return -1; } /* * We always keep up with the eight bit setting and the speed of the - * tty. But only we only believe changes that are made to cooked mode! + * tty. But we only believe changes that are made to cooked mode! */ el->el_tty.t_eight = tty__geteightbit(&el->el_tty.t_ts); el->el_tty.t_speed = tty__getspeed(&el->el_tty.t_ts); - if (tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) { + if (tty__getspeed(&el->el_tty.t_ex) != el->el_tty.t_speed || + tty__getspeed(&el->el_tty.t_ed) != el->el_tty.t_speed) { + (void) cfsetispeed(&el->el_tty.t_ex, el->el_tty.t_speed); + (void) cfsetospeed(&el->el_tty.t_ex, el->el_tty.t_speed); (void) cfsetispeed(&el->el_tty.t_ed, el->el_tty.t_speed); (void) cfsetospeed(&el->el_tty.t_ed, el->el_tty.t_speed); } if (tty__cooked_mode(&el->el_tty.t_ts)) { - if ((el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) && - (el->el_tty.t_ts.c_cflag != el->el_tty.t_ed.c_cflag)) { + if (el->el_tty.t_ts.c_cflag != el->el_tty.t_ex.c_cflag) { + el->el_tty.t_ex.c_cflag = + el->el_tty.t_ts.c_cflag; + el->el_tty.t_ex.c_cflag &= + ~el->el_tty.t_t[EX_IO][MD_CTL].t_clrmask; + el->el_tty.t_ex.c_cflag |= + el->el_tty.t_t[EX_IO][MD_CTL].t_setmask; + el->el_tty.t_ed.c_cflag = el->el_tty.t_ts.c_cflag; el->el_tty.t_ed.c_cflag &= @@ -923,6 +988,13 @@ } if ((el->el_tty.t_ts.c_lflag != el->el_tty.t_ex.c_lflag) && (el->el_tty.t_ts.c_lflag != el->el_tty.t_ed.c_lflag)) { + el->el_tty.t_ex.c_lflag = + el->el_tty.t_ts.c_lflag; + el->el_tty.t_ex.c_lflag &= + ~el->el_tty.t_t[EX_IO][MD_LIN].t_clrmask; + el->el_tty.t_ex.c_lflag |= + el->el_tty.t_t[EX_IO][MD_LIN].t_setmask; + el->el_tty.t_ed.c_lflag = el->el_tty.t_ts.c_lflag; el->el_tty.t_ed.c_lflag &= @@ -932,6 +1004,13 @@ } if ((el->el_tty.t_ts.c_iflag != el->el_tty.t_ex.c_iflag) && (el->el_tty.t_ts.c_iflag != el->el_tty.t_ed.c_iflag)) { + el->el_tty.t_ex.c_iflag = + el->el_tty.t_ts.c_iflag; + el->el_tty.t_ex.c_iflag &= + ~el->el_tty.t_t[EX_IO][MD_INP].t_clrmask; + el->el_tty.t_ex.c_iflag |= + el->el_tty.t_t[EX_IO][MD_INP].t_setmask; + el->el_tty.t_ed.c_iflag = el->el_tty.t_ts.c_iflag; el->el_tty.t_ed.c_iflag &= @@ -941,6 +1020,13 @@ } if ((el->el_tty.t_ts.c_oflag != el->el_tty.t_ex.c_oflag) && (el->el_tty.t_ts.c_oflag != el->el_tty.t_ed.c_oflag)) { + el->el_tty.t_ex.c_oflag = + el->el_tty.t_ts.c_oflag; + el->el_tty.t_ex.c_oflag &= + ~el->el_tty.t_t[EX_IO][MD_OUT].t_clrmask; + el->el_tty.t_ex.c_oflag |= + el->el_tty.t_t[EX_IO][MD_OUT].t_setmask; + el->el_tty.t_ed.c_oflag = el->el_tty.t_ts.c_oflag; el->el_tty.t_ed.c_oflag &= @@ -989,22 +1075,19 @@ if (el->el_tty.t_t[EX_IO][MD_CHAR].t_clrmask & C_SH(i)) el->el_tty.t_c[EX_IO][i] = el->el_tty.t_vdisable; } + tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); } } } - - if (el->el_tty.t_mode == EX_IO) - el->el_tty.t_ex = el->el_tty.t_ts; - - if (tty_setty(el, &el->el_tty.t_ed) == -1) { + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { #ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n", + (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__, strerror(errno)); #endif /* DEBUG_TTY */ - return (-1); + return -1; } el->el_tty.t_mode = ED_IO; - return (0); + return 0; } @@ -1016,21 +1099,20 @@ { /* set tty in normal setup */ if (el->el_tty.t_mode == EX_IO) - return (0); + return 0; if (el->el_flags & EDIT_DISABLED) - return (0); + return 0; - if (tty_setty(el, &el->el_tty.t_ex) == -1) { + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) { #ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, - "tty_cookedmode: tty_setty: %s\n", + (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__, strerror(errno)); #endif /* DEBUG_TTY */ - return (-1); + return -1; } el->el_tty.t_mode = EX_IO; - return (0); + return 0; } @@ -1041,7 +1123,7 @@ tty_quotemode(EditLine *el) { if (el->el_tty.t_mode == QU_IO) - return (0); + return 0; el->el_tty.t_qu = el->el_tty.t_ed; @@ -1057,15 +1139,15 @@ el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask; el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask; - if (tty_setty(el, &el->el_tty.t_qu) == -1) { + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) { #ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n", + (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__, strerror(errno)); #endif /* DEBUG_TTY */ - return (-1); + return -1; } el->el_tty.t_mode = QU_IO; - return (0); + return 0; } @@ -1077,16 +1159,16 @@ { if (el->el_tty.t_mode != QU_IO) - return (0); - if (tty_setty(el, &el->el_tty.t_ed) == -1) { + return 0; + if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) { #ifdef DEBUG_TTY - (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n", + (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", __func__, strerror(errno)); #endif /* DEBUG_TTY */ - return (-1); + return -1; } el->el_tty.t_mode = ED_IO; - return (0); + return 0; } @@ -1095,19 +1177,20 @@ */ protected int /*ARGSUSED*/ -tty_stty(EditLine *el, int argc __unused, const char **argv) +tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv) { const ttymodes_t *m; char x; int aflag = 0; - const char *s, *d; - const char *name; + const Char *s, *d; + char name[EL_BUFSIZ]; struct termios *tios = &el->el_tty.t_ex; int z = EX_IO; if (argv == NULL) - return (-1); - name = *argv++; + return -1; + strncpy(name, ct_encode_string(*argv++, &el->el_scratch), sizeof(name)); + name[sizeof(name) - 1] = '\0'; while (argv && *argv && argv[0][0] == '-' && argv[0][2] == '\0') switch (argv[0][1]) { @@ -1134,12 +1217,12 @@ (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n", name, argv[0][1]); - return (-1); + return -1; } if (!argv || !*argv) { int i = -1; - int len = 0, st = 0, cu; + size_t len = 0, st = 0, cu; for (m = ttymodes; m->m_name; m++) { if (m->m_type != i) { (void) fprintf(el->el_outfile, "%s%s", @@ -1152,8 +1235,9 @@ if (i != -1) { x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) ? '+' : '\0'; - x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) - ? '-' : x; + + if (el->el_tty.t_t[z][i].t_clrmask & m->m_value) + x = '-'; } else { x = '\0'; } @@ -1162,9 +1246,10 @@ 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", - st, ""); + (int)st, ""); len = st + cu; } else len += cu; @@ -1178,14 +1263,14 @@ } } (void) fprintf(el->el_outfile, "\n"); - return (0); + return 0; } while (argv && (s = *argv++)) { - const char *p; + const Char *p; switch (*s) { case '+': case '-': - x = *s++; + x = (char)*s++; break; default: x = '\0'; @@ -1192,26 +1277,29 @@ break; } d = s; - p = strchr(s, '='); + p = Strchr(s, '='); for (m = ttymodes; m->m_name; m++) - if ((p ? strncmp(m->m_name, d, (size_t)(p - d)) : - strcmp(m->m_name, d)) == 0 && + if ((p ? strncmp(m->m_name, ct_encode_string(d, + &el->el_scratch), (size_t)(p - d)) : + strcmp(m->m_name, ct_encode_string(d, + &el->el_scratch))) == 0 && (p == NULL || m->m_type == MD_CHAR)) break; if (!m->m_name) { (void) fprintf(el->el_errfile, - "%s: Invalid argument `%s'.\n", name, d); - return (-1); + "%s: Invalid argument `" FSTR "'.\n", name, d); + return -1; } if (p) { int c = ffs((int)m->m_value); - int v = *++p ? parse__escape((const char **) &p) : + int v = *++p ? parse__escape(&p) : el->el_tty.t_vdisable; - assert(c-- != 0); + assert(c != 0); + c--; c = tty__getcharindex(c); assert(c != -1); - tios->c_cc[c] = v; + tios->c_cc[c] = (cc_t)v; continue; } switch (x) { @@ -1229,7 +1317,18 @@ break; } } - return (0); + + if (el->el_tty.t_mode == z) { + if (tty_setty(el, TCSADRAIN, tios) == -1) { +#ifdef DEBUG_TTY + (void) fprintf(el->el_errfile, "%s: tty_setty: %s\n", + __func__, strerror(errno)); +#endif /* DEBUG_TTY */ + return -1; + } + } + + return 0; } Index: lib/libedit/tty.h =================================================================== --- lib/libedit/tty.h (revision 258914) +++ lib/libedit/tty.h (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: tty.h,v 1.14 2012/05/15 15:59:01 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -30,7 +32,6 @@ * SUCH DAMAGE. * * @(#)tty.h 8.1 (Berkeley) 6/4/93 - * $NetBSD: tty.h,v 1.11 2005/06/01 11:37:52 lukem Exp $ * $FreeBSD$ */ @@ -40,6 +41,7 @@ #ifndef _h_el_tty #define _h_el_tty +#include "sys.h" #include "histedit.h" #include #include @@ -430,7 +432,7 @@ #define C_MIN 23 #define C_TIME 24 #define C_NCC 25 -#define C_SH(A) (1 << (A)) +#define C_SH(A) ((unsigned int)(1 << (A))) /* * Terminal dependend data structures @@ -458,7 +460,7 @@ protected int tty_init(EditLine *); protected void tty_end(EditLine *); -protected int tty_stty(EditLine *, int, const char **); +protected int tty_stty(EditLine *, int, const Char **); protected int tty_rawmode(EditLine *); protected int tty_cookedmode(EditLine *); protected int tty_quotemode(EditLine *); @@ -468,7 +470,7 @@ typedef struct { ttyperm_t t_t; ttychar_t t_c; - struct termios t_ex, t_ed, t_ts; + struct termios t_or, t_ex, t_ed, t_ts; int t_tabs; int t_eight; speed_t t_speed; Index: lib/libedit/vi.c =================================================================== --- lib/libedit/vi.c (revision 258914) +++ lib/libedit/vi.c (working copy) @@ -1,3 +1,5 @@ +/* $NetBSD: vi.c,v 1.43 2012/01/16 14:57:45 christos Exp $ */ + /*- * Copyright (c) 1992, 1993 * The Regents of the University of California. All rights reserved. @@ -28,36 +30,38 @@ * 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. - * - * $NetBSD: vi.c,v 1.30 2009/02/21 23:31:56 christos Exp $ */ -#if !defined(lint) && !defined(SCCSID) -static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; -#endif /* not lint && not SCCSID */ -#include +#include "config.h" +#include +#include +#include +#include __FBSDID("$FreeBSD$"); +#ifdef __weak_reference +#undef __weak_reference +#endif + + /* * vi.c: Vi mode commands. */ -#include -#include "sys.h" #include "el.h" -private el_action_t cv_action(EditLine *, int); -private el_action_t cv_paste(EditLine *, int); +private el_action_t cv_action(EditLine *, Int); +private el_action_t cv_paste(EditLine *, Int); /* cv_action(): * Handle vi actions. */ private el_action_t -cv_action(EditLine *el, int c) +cv_action(EditLine *el, Int c) { if (el->el_chared.c_vcmd.action != NOP) { /* '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; if (!(c & YANK)) @@ -73,11 +77,11 @@ if (c & INSERT) 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.action = c; - return (CC_ARGHACK); + return CC_ARGHACK; } /* cv_paste(): @@ -84,13 +88,13 @@ * Paste previous deletion before or after the cursor */ private el_action_t -cv_paste(EditLine *el, int c) +cv_paste(EditLine *el, Int c) { c_kill_t *k = &el->el_chared.c_kill; size_t len = (size_t)(k->last - k->buf); if (k->buf == NULL || len == 0) - return (CC_ERROR); + return CC_ERROR; #ifdef DEBUG_PASTE (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", (int)len, k->buf); #endif @@ -102,10 +106,11 @@ c_insert(el, (int)len); if (el->el_line.cursor + len > el->el_line.lastchar) - return (CC_ERROR); - (void) memcpy(el->el_line.cursor, k->buf, len); + return CC_ERROR; + (void) memcpy(el->el_line.cursor, k->buf, len * + sizeof(*el->el_line.cursor)); - return (CC_REFRESH); + return CC_REFRESH; } @@ -115,10 +120,10 @@ */ protected el_action_t /*ARGSUSED*/ -vi_paste_next(EditLine *el, int c __unused) +vi_paste_next(EditLine *el, Int c __attribute__((__unused__))) { - return (cv_paste(el, 0)); + return cv_paste(el, 0); } @@ -128,10 +133,10 @@ */ protected el_action_t /*ARGSUSED*/ -vi_paste_prev(EditLine *el, int c __unused) +vi_paste_prev(EditLine *el, Int c __attribute__((__unused__))) { - return (cv_paste(el, 1)); + return cv_paste(el, 1); } @@ -141,11 +146,11 @@ */ protected el_action_t /*ARGSUSED*/ -vi_prev_big_word(EditLine *el, int c) +vi_prev_big_word(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.buffer) - return (CC_ERROR); + return CC_ERROR; el->el_line.cursor = cv_prev_word(el->el_line.cursor, el->el_line.buffer, @@ -154,9 +159,9 @@ if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -166,11 +171,11 @@ */ protected el_action_t /*ARGSUSED*/ -vi_prev_word(EditLine *el, int c __unused) +vi_prev_word(EditLine *el, Int c __attribute__((__unused__))) { 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.buffer, @@ -179,9 +184,9 @@ if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -191,11 +196,11 @@ */ protected el_action_t /*ARGSUSED*/ -vi_next_big_word(EditLine *el, int c) +vi_next_big_word(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor >= el->el_line.lastchar - 1) - return (CC_ERROR); + return CC_ERROR; el->el_line.cursor = cv_next_word(el, el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, cv__isWord); @@ -203,9 +208,9 @@ if (el->el_map.type == MAP_VI) if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -215,11 +220,11 @@ */ protected el_action_t /*ARGSUSED*/ -vi_next_word(EditLine *el, int c __unused) +vi_next_word(EditLine *el, Int c __attribute__((__unused__))) { 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.lastchar, el->el_state.argument, cv__isword); @@ -227,9 +232,9 @@ if (el->el_map.type == MAP_VI) if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -238,20 +243,20 @@ * [~] */ protected el_action_t -vi_change_case(EditLine *el, int c) +vi_change_case(EditLine *el, Int c) { int i; if (el->el_line.cursor >= el->el_line.lastchar) - return (CC_ERROR); + return CC_ERROR; cv_undo(el); for (i = 0; i < el->el_state.argument; i++) { - c = *(unsigned char *)el->el_line.cursor; - if (isupper(c)) - *el->el_line.cursor = tolower(c); - else if (islower(c)) - *el->el_line.cursor = toupper(c); + c = *el->el_line.cursor; + if (Isupper(c)) + *el->el_line.cursor = Tolower(c); + else if (Islower(c)) + *el->el_line.cursor = Toupper(c); if (++el->el_line.cursor >= el->el_line.lastchar) { el->el_line.cursor--; @@ -270,7 +275,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_change_meta(EditLine *el, int c __unused) +vi_change_meta(EditLine *el, Int c __attribute__((__unused__))) { /* @@ -277,7 +282,7 @@ * Delete with insert == change: first we delete and then we leave in * insert mode. */ - return (cv_action(el, DELETE | INSERT)); + return cv_action(el, DELETE | INSERT); } @@ -287,13 +292,13 @@ */ protected el_action_t /*ARGSUSED*/ -vi_insert_at_bol(EditLine *el, int c __unused) +vi_insert_at_bol(EditLine *el, Int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; cv_undo(el); el->el_map.current = el->el_map.key; - return (CC_CURSOR); + return CC_CURSOR; } @@ -303,7 +308,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_replace_char(EditLine *el, int c __unused) +vi_replace_char(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor >= el->el_line.lastchar) @@ -312,7 +317,7 @@ el->el_map.current = el->el_map.key; el->el_state.inputmode = MODE_REPLACE_1; cv_undo(el); - return (CC_ARGHACK); + return CC_ARGHACK; } @@ -322,13 +327,13 @@ */ protected el_action_t /*ARGSUSED*/ -vi_replace_mode(EditLine *el, int c __unused) +vi_replace_mode(EditLine *el, Int c __attribute__((__unused__))) { el->el_map.current = el->el_map.key; el->el_state.inputmode = MODE_REPLACE; cv_undo(el); - return (CC_NORM); + return CC_NORM; } @@ -338,12 +343,12 @@ */ protected el_action_t /*ARGSUSED*/ -vi_substitute_char(EditLine *el, int c __unused) +vi_substitute_char(EditLine *el, Int c __attribute__((__unused__))) { c_delafter(el, el->el_state.argument); el->el_map.current = el->el_map.key; - return (CC_REFRESH); + return CC_REFRESH; } @@ -353,7 +358,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_substitute_line(EditLine *el, int c __unused) +vi_substitute_line(EditLine *el, Int c __attribute__((__unused__))) { cv_undo(el); @@ -361,7 +366,7 @@ (int)(el->el_line.lastchar - el->el_line.buffer)); (void) em_kill_line(el, 0); el->el_map.current = el->el_map.key; - return (CC_REFRESH); + return CC_REFRESH; } @@ -371,7 +376,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_change_to_eol(EditLine *el, int c __unused) +vi_change_to_eol(EditLine *el, Int c __attribute__((__unused__))) { cv_undo(el); @@ -379,7 +384,7 @@ (int)(el->el_line.lastchar - el->el_line.cursor)); (void) ed_kill_line(el, 0); el->el_map.current = el->el_map.key; - return (CC_REFRESH); + return CC_REFRESH; } @@ -389,12 +394,12 @@ */ protected el_action_t /*ARGSUSED*/ -vi_insert(EditLine *el, int c __unused) +vi_insert(EditLine *el, Int c __attribute__((__unused__))) { el->el_map.current = el->el_map.key; cv_undo(el); - return (CC_NORM); + return CC_NORM; } @@ -404,7 +409,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_add(EditLine *el, int c __unused) +vi_add(EditLine *el, Int c __attribute__((__unused__))) { int ret; @@ -419,7 +424,7 @@ cv_undo(el); - return (ret); + return (el_action_t)ret; } @@ -429,13 +434,13 @@ */ protected el_action_t /*ARGSUSED*/ -vi_add_at_eol(EditLine *el, int c __unused) +vi_add_at_eol(EditLine *el, Int c __attribute__((__unused__))) { el->el_map.current = el->el_map.key; el->el_line.cursor = el->el_line.lastchar; cv_undo(el); - return (CC_CURSOR); + return CC_CURSOR; } @@ -445,10 +450,10 @@ */ protected el_action_t /*ARGSUSED*/ -vi_delete_meta(EditLine *el, int c __unused) +vi_delete_meta(EditLine *el, Int c __attribute__((__unused__))) { - return (cv_action(el, DELETE)); + return cv_action(el, DELETE); } @@ -458,11 +463,11 @@ */ protected el_action_t /*ARGSUSED*/ -vi_end_big_word(EditLine *el, int c) +vi_end_big_word(EditLine *el, Int c __attribute__((__unused__))) { 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.lastchar, el->el_state.argument, cv__isWord); @@ -470,9 +475,9 @@ if (el->el_chared.c_vcmd.action != NOP) { el->el_line.cursor++; cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -482,11 +487,11 @@ */ protected el_action_t /*ARGSUSED*/ -vi_end_word(EditLine *el, int c __unused) +vi_end_word(EditLine *el, Int c __attribute__((__unused__))) { 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.lastchar, el->el_state.argument, cv__isword); @@ -494,9 +499,9 @@ if (el->el_chared.c_vcmd.action != NOP) { el->el_line.cursor++; cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -506,7 +511,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_undo(EditLine *el, int c __unused) +vi_undo(EditLine *el, Int c __attribute__((__unused__))) { c_undo_t un = el->el_chared.c_undo; @@ -523,7 +528,7 @@ el->el_line.cursor = un.buf + un.cursor; el->el_line.lastchar = un.buf + un.len; - return (CC_REFRESH); + return CC_REFRESH; } @@ -533,7 +538,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_command_mode(EditLine *el, int c __unused) +vi_command_mode(EditLine *el, Int c __attribute__((__unused__))) { /* [Esc] cancels pending action */ @@ -548,7 +553,7 @@ if (el->el_line.cursor > el->el_line.buffer) el->el_line.cursor--; #endif - return (CC_CURSOR); + return CC_CURSOR; } @@ -557,7 +562,7 @@ * [0] */ protected el_action_t -vi_zero(EditLine *el, int c) +vi_zero(EditLine *el, Int c) { if (el->el_state.doingarg) @@ -566,9 +571,9 @@ el->el_line.cursor = el->el_line.buffer; if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -578,15 +583,15 @@ */ protected el_action_t /*ARGSUSED*/ -vi_delete_prev_char(EditLine *el, int c __unused) +vi_delete_prev_char(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor <= el->el_line.buffer) - return (CC_ERROR); + return CC_ERROR; c_delbefore1(el); el->el_line.cursor--; - return (CC_REFRESH); + return CC_REFRESH; } @@ -596,32 +601,32 @@ */ protected el_action_t /*ARGSUSED*/ -vi_list_or_eof(EditLine *el, int c) +vi_list_or_eof(EditLine *el, Int c) { if (el->el_line.cursor == el->el_line.lastchar) { if (el->el_line.cursor == el->el_line.buffer) { - term_writec(el, c); /* then do a EOF */ - return (CC_EOF); + terminal_writec(el, c); /* then do a EOF */ + return CC_EOF; } else { /* * Here we could list completions, but it is an * error right now */ - term_beep(el); - return (CC_ERROR); + terminal_beep(el); + return CC_ERROR; } } else { #ifdef notyet re_goto_bottom(el); *el->el_line.lastchar = '\0'; /* just in case */ - return (CC_LIST_CHOICES); + return CC_LIST_CHOICES; #else /* * Just complain for now. */ - term_beep(el); - return (CC_ERROR); + terminal_beep(el); + return CC_ERROR; #endif } } @@ -633,9 +638,9 @@ */ protected el_action_t /*ARGSUSED*/ -vi_kill_line_prev(EditLine *el, int c __unused) +vi_kill_line_prev(EditLine *el, Int c __attribute__((__unused__))) { - char *kp, *cp; + Char *kp, *cp; cp = el->el_line.buffer; kp = el->el_chared.c_kill.buf; @@ -644,7 +649,7 @@ el->el_chared.c_kill.last = kp; c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer)); el->el_line.cursor = el->el_line.buffer; /* zap! */ - return (CC_REFRESH); + return CC_REFRESH; } @@ -654,10 +659,10 @@ */ protected el_action_t /*ARGSUSED*/ -vi_search_prev(EditLine *el, int c __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); } @@ -667,10 +672,10 @@ */ protected el_action_t /*ARGSUSED*/ -vi_search_next(EditLine *el, int c __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); } @@ -680,13 +685,13 @@ */ protected el_action_t /*ARGSUSED*/ -vi_repeat_search_next(EditLine *el, int c __unused) +vi_repeat_search_next(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_search.patlen == 0) - return (CC_ERROR); + return CC_ERROR; else - return (cv_repeat_srch(el, el->el_search.patdir)); + return cv_repeat_srch(el, el->el_search.patdir); } @@ -696,11 +701,11 @@ */ /*ARGSUSED*/ protected el_action_t -vi_repeat_search_prev(EditLine *el, int c __unused) +vi_repeat_search_prev(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_search.patlen == 0) - return (CC_ERROR); + return CC_ERROR; else return (cv_repeat_srch(el, el->el_search.patdir == ED_SEARCH_PREV_HISTORY ? @@ -714,7 +719,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_next_char(EditLine *el, int c __unused) +vi_next_char(EditLine *el, Int c __attribute__((__unused__))) { return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0); } @@ -726,7 +731,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_prev_char(EditLine *el, int c __unused) +vi_prev_char(EditLine *el, Int c __attribute__((__unused__))) { return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0); } @@ -738,7 +743,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_to_next_char(EditLine *el, int c __unused) +vi_to_next_char(EditLine *el, Int c __attribute__((__unused__))) { return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1); } @@ -750,7 +755,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_to_prev_char(EditLine *el, int c __unused) +vi_to_prev_char(EditLine *el, Int c __attribute__((__unused__))) { return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1); } @@ -762,7 +767,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_repeat_next_char(EditLine *el, int c __unused) +vi_repeat_next_char(EditLine *el, Int c __attribute__((__unused__))) { return cv_csearch(el, el->el_search.chadir, el->el_search.chacha, @@ -776,7 +781,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_repeat_prev_char(EditLine *el, int c __unused) +vi_repeat_prev_char(EditLine *el, Int c __attribute__((__unused__))) { el_action_t r; int dir = el->el_search.chadir; @@ -794,20 +799,20 @@ */ protected el_action_t /*ARGSUSED*/ -vi_match(EditLine *el, int c) +vi_match(EditLine *el, Int c __attribute__((__unused__))) { - const char match_chars[] = "()[]{}"; - char *cp; + const Char match_chars[] = STR("()[]{}"); + Char *cp; size_t delta, i, count; - char o_ch, c_ch; + Char o_ch, c_ch; *el->el_line.lastchar = '\0'; /* just in case */ - i = strcspn(el->el_line.cursor, match_chars); + i = Strcspn(el->el_line.cursor, match_chars); o_ch = el->el_line.cursor[i]; if (o_ch == 0) return CC_ERROR; - delta = strchr(match_chars, o_ch) - match_chars; + delta = (size_t)(Strchr(match_chars, o_ch) - match_chars); c_ch = match_chars[delta ^ 1]; count = 1; delta = 1 - (delta & 1) * 2; @@ -830,9 +835,9 @@ if (delta > 0) el->el_line.cursor++; cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } /* vi_undo_line(): @@ -841,7 +846,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_undo_line(EditLine *el, int c) +vi_undo_line(EditLine *el, Int c __attribute__((__unused__))) { cv_undo(el); @@ -855,7 +860,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_to_column(EditLine *el, int c) +vi_to_column(EditLine *el, Int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; @@ -869,7 +874,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_yank_end(EditLine *el, int c) +vi_yank_end(EditLine *el, Int c __attribute__((__unused__))) { cv_yank(el, el->el_line.cursor, @@ -883,7 +888,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_yank(EditLine *el, int c) +vi_yank(EditLine *el, Int c __attribute__((__unused__))) { return cv_action(el, YANK); @@ -895,7 +900,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_comment_out(EditLine *el, int c) +vi_comment_out(EditLine *el, Int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; @@ -911,17 +916,19 @@ * NB: posix implies that we should enter insert mode, however * this is against historical precedent... */ +#ifdef __weak_reference +__weakref_visible char *my_get_alias_text(const char *) + __weak_reference(get_alias_text); +#endif protected el_action_t /*ARGSUSED*/ -vi_alias(EditLine *el, int c) +vi_alias(EditLine *el, Int c __attribute__((__unused__))) { -#ifdef __weak_extern +#ifdef __weak_reference char alias_name[3]; char *alias_text; - extern char *get_alias_text(const char *); - __weak_extern(get_alias_text); - if (get_alias_text == 0) { + if (my_get_alias_text == 0) { return CC_ERROR; } @@ -930,9 +937,9 @@ if (el_getc(el, &alias_name[1]) != 1) return CC_ERROR; - alias_text = get_alias_text(alias_name); + alias_text = my_get_alias_text(alias_name); if (alias_text != NULL) - el_push(el, alias_text); + FUN(el,push)(el, ct_decode_string(alias_text, &el->el_scratch)); return CC_NORM; #else return CC_ERROR; @@ -945,7 +952,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_to_history_line(EditLine *el, int c) +vi_to_history_line(EditLine *el, Int c __attribute__((__unused__))) { int sv_event_no = el->el_history.eventno; el_action_t rval; @@ -952,7 +959,7 @@ if (el->el_history.eventno == 0) { - (void) strncpy(el->el_history.buf, el->el_line.buffer, + (void) Strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ); el->el_history.last = el->el_history.buf + (el->el_line.lastchar - el->el_line.buffer); @@ -990,7 +997,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_histedit(EditLine *el, int c) +vi_histedit(EditLine *el, Int c __attribute__((__unused__))) { int fd; pid_t pid; @@ -997,7 +1004,9 @@ ssize_t st; int status; char tempfile[] = "/tmp/histedit.XXXXXXXXXX"; - char *cp; + char *cp = NULL; + size_t len; + Char *line = NULL; if (el->el_state.doingarg) { if (vi_to_history_line(el, 0) == CC_ERROR) @@ -1007,15 +1016,25 @@ fd = mkstemp(tempfile); if (fd < 0) return CC_ERROR; - cp = el->el_line.buffer; - write(fd, cp, (size_t)(el->el_line.lastchar - cp)); - write(fd, "\n", 1); + len = (size_t)(el->el_line.lastchar - el->el_line.buffer); +#define TMP_BUFSIZ (EL_BUFSIZ * MB_LEN_MAX) + cp = el_malloc(TMP_BUFSIZ * sizeof(*cp)); + if (cp == NULL) + goto error; + line = el_malloc(len * sizeof(*line) + 1); + if (line == NULL) + goto error; + Strncpy(line, el->el_line.buffer, len); + line[len] = '\0'; + ct_wcstombs(cp, line, TMP_BUFSIZ - 1); + cp[TMP_BUFSIZ - 1] = '\0'; + len = strlen(cp); + write(fd, cp, len); + write(fd, "\n", (size_t)1); pid = fork(); switch (pid) { case -1: - close(fd); - unlink(tempfile); - return CC_ERROR; + goto error; case 0: close(fd); execlp("vi", "vi", tempfile, (char *)NULL); @@ -1025,11 +1044,20 @@ while (waitpid(pid, &status, 0) != pid) continue; lseek(fd, (off_t)0, SEEK_SET); - st = read(fd, cp, (size_t)(el->el_line.limit - cp)); - if (st > 0 && cp[st - 1] == '\n') - st--; - el->el_line.cursor = cp; - el->el_line.lastchar = cp + st; + st = read(fd, cp, TMP_BUFSIZ); + if (st > 0) { + len = (size_t)(el->el_line.lastchar - + el->el_line.buffer); + len = ct_mbstowcs(el->el_line.buffer, cp, len); + if (len > 0 && el->el_line.buffer[len -1] == '\n') + --len; + } + else + len = 0; + el->el_line.cursor = el->el_line.buffer; + el->el_line.lastchar = el->el_line.buffer + len; + el_free(cp); + el_free(line); break; } @@ -1037,6 +1065,12 @@ unlink(tempfile); /* return CC_REFRESH; */ return ed_newline(el, 0); +error: + el_free(line); + el_free(cp); + close(fd); + unlink(tempfile); + return CC_ERROR; } /* vi_history_word(): @@ -1047,13 +1081,13 @@ */ protected el_action_t /*ARGSUSED*/ -vi_history_word(EditLine *el, int c) +vi_history_word(EditLine *el, Int c __attribute__((__unused__))) { - const char *wp = HIST_FIRST(el); - const char *wep, *wsp; + const Char *wp = HIST_FIRST(el); + const Char *wep, *wsp; int len; - char *cp; - const char *lim; + Char *cp; + const Char *lim; if (wp == NULL) return CC_ERROR; @@ -1060,15 +1094,16 @@ wep = wsp = 0; do { - while (isspace((unsigned char)*wp)) + while (Isspace(*wp)) wp++; if (*wp == 0) break; wsp = wp; - while (*wp && !isspace((unsigned char)*wp)) + while (*wp && !Isspace(*wp)) wp++; wep = wp; - } while ((!el->el_state.doingarg || --el->el_state.argument > 0) && *wp != 0); + } while ((!el->el_state.doingarg || --el->el_state.argument > 0) + && *wp != 0); if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0)) return CC_ERROR; @@ -1096,7 +1131,7 @@ */ protected el_action_t /*ARGSUSED*/ -vi_redo(EditLine *el, int c) +vi_redo(EditLine *el, Int c __attribute__((__unused__))) { c_redo_t *r = &el->el_chared.c_redo; @@ -1112,10 +1147,10 @@ /* sanity */ r->pos = r->lim - 1; r->pos[0] = 0; - el_push(el, r->buf); + FUN(el,push)(el, r->buf); } el->el_state.thiscmd = r->cmd; 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); }