diff options
author | Michael Widenius <monty@askmonty.org> | 2011-12-11 11:34:44 +0200 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2011-12-11 11:34:44 +0200 |
commit | 6d4224a31c9d32c8f8067a4f7d16daa29bcdee6b (patch) | |
tree | 79e3143528495069ad232f673532573b30afe425 /cmd-line-utils | |
parent | 3e2cb35e11cb5ee6668d538a62a3b32e017944a5 (diff) | |
parent | 701c0f822abe4ee9eeafd244fa30dc2fcf067b81 (diff) | |
download | mariadb-git-6d4224a31c9d32c8f8067a4f7d16daa29bcdee6b.tar.gz |
Merge with 5.2.
no_error handling for select (used by INSERT ... SELECT) still needs to be fixed, but I will do that in a separate commit
Diffstat (limited to 'cmd-line-utils')
51 files changed, 5412 insertions, 3018 deletions
diff --git a/cmd-line-utils/libedit/Makefile.am b/cmd-line-utils/libedit/Makefile.am index ddafa4aab44..b68eca7f44a 100644 --- a/cmd-line-utils/libedit/Makefile.am +++ b/cmd-line-utils/libedit/Makefile.am @@ -7,20 +7,20 @@ INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include noinst_LIBRARIES = libedit.a -libedit_a_SOURCES = chared.c el.c history.c map.c prompt.c readline.c \ - search.c tokenizer.c vi.c common.c emacs.c \ - hist.c key.c parse.c read.c refresh.c sig.c term.c \ +libedit_a_SOURCES = chared.c el.c eln.c history.c historyn.c map.c prompt.c chartype.c \ + readline.c search.c tokenizer.c tokenizern.c vi.c common.c emacs.c \ + hist.c keymacro.c parse.c read.c refresh.c sig.c terminal.c \ tty.c help.c fcns.c filecomplete.c \ np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c \ - np/fgetln.c + np/fgetln.c np/wcsdup.c libedit_a_LIBADD = @LIBEDIT_LOBJECTS@ libedit_a_DEPENDENCIES = @LIBEDIT_LOBJECTS@ pkginclude_HEADERS = readline/readline.h -noinst_HEADERS = chared.h el.h el_term.h histedit.h key.h parse.h refresh.h sig.h \ - sys.h config.h hist.h map.h prompt.h read.h \ +noinst_HEADERS = chared.h chartype.h el.h el_terminal.h histedit.h keymacro.h parse.h \ + refresh.h sig.h sys.h config.h hist.h map.h prompt.h read.h \ search.h tty.h filecomplete.h np/vis.h EXTRA_DIST = makelist.sh @@ -70,22 +70,26 @@ fcns.c: ${AHDR} fcns.h makelist chared.o: vi.h emacs.h common.h help.h fcns.h el.o: vi.h emacs.h common.h help.h fcns.h +eln.o: vi.h emacs.h common.h help.h fcns.h history.o: vi.h emacs.h common.h help.h fcns.h +historyn.o: vi.h emacs.h common.h help.h fcns.h map.o: vi.h emacs.h common.h help.h fcns.h +chartype.o: vi.h emacs.h common.h help.h fcns.h prompt.o: vi.h emacs.h common.h help.h fcns.h readline.o: vi.h emacs.h common.h help.h fcns.h search.o: vi.h emacs.h common.h help.h fcns.h tokenizer.o: vi.h emacs.h common.h help.h fcns.h +tokenizern.o: vi.h emacs.h common.h help.h fcns.h vi.o: vi.h emacs.h common.h help.h fcns.h common.o: vi.h emacs.h common.h help.h fcns.h emacs.o: vi.h emacs.h common.h help.h fcns.h hist.o: vi.h emacs.h common.h help.h fcns.h -key.o: vi.h emacs.h common.h help.h fcns.h +keymacro.o: vi.h emacs.h common.h help.h fcns.h parse.o: vi.h emacs.h common.h help.h fcns.h read.o: vi.h emacs.h common.h help.h fcns.h refresh.o: vi.h emacs.h common.h help.h fcns.h sig.o: vi.h emacs.h common.h help.h fcns.h -term.o: vi.h emacs.h common.h help.h fcns.h +terminal.o: vi.h emacs.h common.h help.h fcns.h tty.o: vi.h emacs.h common.h help.h fcns.h help.o: vi.h emacs.h common.h help.h fcns.h fcns.o: vi.h emacs.h common.h help.h fcns.h diff --git a/cmd-line-utils/libedit/README b/cmd-line-utils/libedit/README index 0b698a6150d..c4bc1554b03 100644 --- a/cmd-line-utils/libedit/README +++ b/cmd-line-utils/libedit/README @@ -2,7 +2,7 @@ An approximate method to merge from upstream is: # Fetch latest from upstream (we also include some compat stuff) $ CVS_RSH=ssh; export CVS_RSH - $ CVSROOT="anoncvs@stripped:/cvsroot" + $ CVSROOT="anoncvs@anoncvs.netbsd.org:/cvsroot" $ cvs co -d libedit -P src/lib/libedit $ mkdir libedit/np $ for f in src/common/lib/libc/string/strlcat.c \ @@ -24,13 +24,13 @@ An approximate method to merge from upstream is: # Rename files to match our naming $ mv makelist makelist.sh - $ mv term.h el_term.h + $ mv terminal.h el_terminal.h # Remove NetBSD-specific bits $ for file in $(find . -type f) > do > cp ${file} ${file}.orig - > sed -e 's/#include "term.h"/#include "el_term.h"/g' \ + > sed -e 's/#include "terminal.h"/#include "el_terminal.h"/g' \ > -e 's/sig_handler/el_sig_handler/g' \ > -e 's/isprint/el_isprint/g' \ > -e '/^__RCSID/d' \ @@ -42,9 +42,9 @@ then merge remaining bits by hand. All MySQL-specific changes should be marked with XXXMYSQL to make them easier to identify and merge. To generate a 'clean' diff against upstream you can use the above commands but use - cvs co -D "2009/02/06 20:09:00" [..] + cvs co -D "2011/10/23 17:37:55" [..] to fetch the baseline of most recent merge. -Please feed any fixes to Jonathan Perkin <jperkin@stripped> who will endeavour -to merge them upstream and keep diffs minimal. +Please feed any fixes to Jonathan Perkin <jonathan.perkin@oracle.com> who will +endeavour to merge them upstream and keep diffs minimal. diff --git a/cmd-line-utils/libedit/chared.c b/cmd-line-utils/libedit/chared.c index e4823db7147..647a5afe439 100644 --- a/cmd-line-utils/libedit/chared.c +++ b/cmd-line-utils/libedit/chared.c @@ -1,4 +1,4 @@ -/* $NetBSD: chared.c,v 1.26 2009/02/06 12:45:25 sketch Exp $ */ +/* $NetBSD: chared.c,v 1.36 2011/10/23 17:37:55 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -59,13 +59,13 @@ cv_undo(EditLine *el) { c_undo_t *vu = &el->el_chared.c_undo; c_redo_t *r = &el->el_chared.c_redo; - unsigned int size; + size_t size; /* Save entire line for undo */ - size = el->el_line.lastchar - el->el_line.buffer; - vu->len = size; - vu->cursor = el->el_line.cursor - el->el_line.buffer; - memcpy(vu->buf, el->el_line.buffer, size); + 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); + (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 +79,11 @@ cv_undo(EditLine *el) * Save yank/delete data for paste */ protected void -cv_yank(EditLine *el, const char *ptr, int size) +cv_yank(EditLine *el, const Char *ptr, int size) { c_kill_t *k = &el->el_chared.c_kill; - memcpy(k->buf, ptr, size +0u); + (void)memcpy(k->buf, ptr, (size_t)size * sizeof(*k->buf)); k->last = k->buf + size; } @@ -94,10 +94,10 @@ cv_yank(EditLine *el, const char *ptr, int size) protected void c_insert(EditLine *el, int num) { - char *cp; + Char *cp; if (el->el_line.lastchar + num >= el->el_line.limit) { - if (!ch_enlargebufs(el, num +0u)) + if (!ch_enlargebufs(el, (size_t)num)) return; /* can't go past end of buffer */ } @@ -118,7 +118,7 @@ c_delafter(EditLine *el, int num) { if (el->el_line.cursor + num > el->el_line.lastchar) - num = el->el_line.lastchar - el->el_line.cursor; + num = (int)(el->el_line.lastchar - el->el_line.cursor); if (el->el_map.current != el->el_map.emacs) { cv_undo(el); @@ -126,7 +126,7 @@ c_delafter(EditLine *el, int num) } if (num > 0) { - char *cp; + Char *cp; for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) *cp = cp[num]; @@ -142,7 +142,7 @@ c_delafter(EditLine *el, int num) protected void c_delafter1(EditLine *el) { - char *cp; + Char *cp; for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) *cp = cp[1]; @@ -159,7 +159,7 @@ c_delbefore(EditLine *el, int num) { if (el->el_line.cursor - num < el->el_line.buffer) - num = el->el_line.cursor - el->el_line.buffer; + num = (int)(el->el_line.cursor - el->el_line.buffer); if (el->el_map.current != el->el_map.emacs) { cv_undo(el); @@ -167,7 +167,7 @@ c_delbefore(EditLine *el, int num) } if (num > 0) { - char *cp; + Char *cp; for (cp = el->el_line.cursor - num; cp <= el->el_line.lastchar; @@ -185,7 +185,7 @@ c_delbefore(EditLine *el, int num) protected void c_delbefore1(EditLine *el) { - char *cp; + Char *cp; for (cp = el->el_line.cursor - 1; cp <= el->el_line.lastchar; cp++) *cp = cp[1]; @@ -198,9 +198,9 @@ c_delbefore1(EditLine *el) * Return if p is part of a word according to emacs */ protected int -ce__isword(int p) +ce__isword(Int p) { - return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL); + return Isalnum(p) || Strchr(STR("*?_-.[]~="), p) != NULL; } @@ -208,11 +208,11 @@ ce__isword(int p) * Return if p is part of a word according to vi */ protected int -cv__isword(int p) +cv__isword(Int p) { - if (isalnum(p) || p == '_') + if (Isalnum(p) || p == '_') return 1; - if (isgraph(p)) + if (Isgraph(p)) return 2; return 0; } @@ -222,24 +222,24 @@ cv__isword(int p) * Return if p is part of a big word according to vi */ protected int -cv__isWord(int p) +cv__isWord(Int p) { - return (!isspace(p)); + return !Isspace(p); } /* c__prev_word(): * Find the previous word */ -protected char * -c__prev_word(char *p, char *low, int n, int (*wtest)(int)) +protected Char * +c__prev_word(Char *p, Char *low, int n, int (*wtest)(Int)) { p--; while (n--) { - while ((p >= low) && !(*wtest)((unsigned char) *p)) + while ((p >= low) && !(*wtest)(*p)) p--; - while ((p >= low) && (*wtest)((unsigned char) *p)) + while ((p >= low) && (*wtest)(*p)) p--; } @@ -248,117 +248,83 @@ c__prev_word(char *p, char *low, int n, int (*wtest)(int)) if (p < low) p = low; /* cp now points where we want it */ - return (p); + return p; } /* 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 * 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; } /* 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++; /* 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 */ @@ -375,7 +341,7 @@ cv_delfini(EditLine *el) /* sanity */ return; - size = el->el_line.cursor - el->el_chared.c_vcmd.pos; + size = (int)(el->el_line.cursor - el->el_chared.c_vcmd.pos); if (size == 0) size = 1; el->el_line.cursor = el->el_chared.c_vcmd.pos; @@ -397,48 +363,26 @@ cv_delfini(EditLine *el) } -#ifdef notdef -/* ce__endword(): - * Go to the end of this word according to emacs - */ -protected char * -ce__endword(char *p, char *high, int n) -{ - p++; - - while (n--) { - while ((p < high) && isspace((unsigned char) *p)) - p++; - while ((p < high) && !isspace((unsigned char) *p)) - p++; - } - - p--; - return (p); -} -#endif - - /* cv__endword(): * Go to the end of this word according to vi */ -protected char * -cv__endword(char *p, char *high, int n, int (*wtest)(int)) +protected Char * +cv__endword(Char *p, Char *high, int n, int (*wtest)(Int)) { int test; p++; while (n--) { - while ((p < high) && isspace((unsigned char) *p)) + while ((p < high) && Isspace(*p)) p++; - test = (*wtest)((unsigned char) *p); - while ((p < high) && (*wtest)((unsigned char) *p) == test) + test = (*wtest)(*p); + while ((p < high) && (*wtest)(*p) == test) p++; } p--; - return (p); + return p; } /* ch_init(): @@ -449,24 +393,29 @@ ch_init(EditLine *el) { c_macro_t *ma = &el->el_chared.c_macro; - el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ); + el->el_line.buffer = el_malloc(EL_BUFSIZ * + sizeof(*el->el_line.buffer)); if (el->el_line.buffer == NULL) - return (-1); + 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 +423,16 @@ ch_init(EditLine *el) el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.pos = el->el_line.buffer; - el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ); + el->el_chared.c_kill.buf = el_malloc(EL_BUFSIZ * + sizeof(*el->el_chared.c_kill.buf)); if (el->el_chared.c_kill.buf == NULL) - return (-1); - (void) memset(el->el_chared.c_kill.buf, 0, EL_BUFSIZ); + 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 +444,10 @@ ch_init(EditLine *el) ma->level = -1; ma->offset = 0; - ma->macro = (char **) el_malloc(EL_MAXMACRO * sizeof(char *)); + ma->macro = el_malloc(EL_MAXMACRO * sizeof(*ma->macro)); if (ma->macro == NULL) - return (-1); - return (0); + return -1; + return 0; } /* ch_reset(): @@ -529,12 +482,11 @@ ch_reset(EditLine *el, int mclear) } private void -ch__clearmacro(el) - EditLine *el; +ch__clearmacro(EditLine *el) { c_macro_t *ma = &el->el_chared.c_macro; while (ma->level >= 0) - el_free((ptr_t)ma->macro[ma->level--]); + el_free(ma->macro[ma->level--]); } /* ch_enlargebufs(): @@ -542,14 +494,12 @@ ch__clearmacro(el) * Returns 1 if successful, 0 if not. */ protected int -ch_enlargebufs(el, addlen) - EditLine *el; - size_t addlen; +ch_enlargebufs(EditLine *el, size_t addlen) { size_t sz, newsz; - char *newbuffer, *oldbuf, *oldkbuf; + Char *newbuffer, *oldbuf, *oldkbuf; - sz = el->el_line.limit - el->el_line.buffer + EL_LEAVE; + 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 @@ -563,12 +513,12 @@ ch_enlargebufs(el, addlen) /* * Reallocate line buffer. */ - newbuffer = el_realloc(el->el_line.buffer, newsz); + newbuffer = el_realloc(el->el_line.buffer, newsz * sizeof(*newbuffer)); if (!newbuffer) return 0; /* zero the newly added memory, leave old data in */ - (void) memset(&newbuffer[sz], 0, newsz - sz); + (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); oldbuf = el->el_line.buffer; @@ -581,12 +531,13 @@ ch_enlargebufs(el, addlen) /* * Reallocate kill buffer. */ - newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz); + newbuffer = el_realloc(el->el_chared.c_kill.buf, newsz * + sizeof(*newbuffer)); if (!newbuffer) return 0; /* zero the newly added memory, leave old data in */ - (void) memset(&newbuffer[sz], 0, newsz - sz); + (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); oldkbuf = el->el_chared.c_kill.buf; @@ -599,15 +550,17 @@ ch_enlargebufs(el, addlen) /* * Reallocate undo buffer. */ - newbuffer = el_realloc(el->el_chared.c_undo.buf, newsz); + newbuffer = el_realloc(el->el_chared.c_undo.buf, + newsz * sizeof(*newbuffer)); if (!newbuffer) return 0; /* zero the newly added memory, leave old data in */ - (void) memset(&newbuffer[sz], 0, newsz - sz); + (void) memset(&newbuffer[sz], 0, (newsz - sz) * sizeof(*newbuffer)); el->el_chared.c_undo.buf = newbuffer; - newbuffer = el_realloc(el->el_chared.c_redo.buf, newsz); + newbuffer = el_realloc(el->el_chared.c_redo.buf, + newsz * sizeof(*newbuffer)); if (!newbuffer) return 0; el->el_chared.c_redo.pos = newbuffer + @@ -621,6 +574,8 @@ ch_enlargebufs(el, addlen) /* 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; } @@ -630,20 +585,20 @@ ch_enlargebufs(el, addlen) 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; } @@ -652,21 +607,21 @@ ch_end(EditLine *el) * Insert string at cursorI */ public int -el_insertstr(EditLine *el, const char *s) +FUN(el,insertstr)(EditLine *el, const Char *s) { size_t len; - if ((len = strlen(s)) == 0) - return (-1); + if ((len = Strlen(s)) == 0) + return -1; if (el->el_line.lastchar + len >= el->el_line.limit) { if (!ch_enlargebufs(el, len)) - return (-1); + return -1; } c_insert(el, (int)len); while (*s) *el->el_line.cursor++ = *s++; - return (0); + return 0; } @@ -692,15 +647,15 @@ el_deletestr(EditLine *el, int n) * Get a string */ protected int -c_gets(EditLine *el, char *buf, const char *prompt) +c_gets(EditLine *el, Char *buf, const Char *prompt) { - char ch; - int len; - char *cp = el->el_line.buffer; + Char ch; + ssize_t len; + Char *cp = el->el_line.buffer; if (prompt) { - len = strlen(prompt); - memcpy(cp, prompt, len + 0u); + len = (ssize_t)Strlen(prompt); + (void)memcpy(cp, prompt, (size_t)len * sizeof(*cp)); cp += len; } len = 0; @@ -711,7 +666,7 @@ c_gets(EditLine *el, char *buf, const char *prompt) el->el_line.lastchar = cp + 1; re_refresh(el); - if (el_getc(el, &ch) != 1) { + if (FUN(el,getc)(el, &ch) != 1) { ed_end_of_file(el, 0); len = -1; break; @@ -721,7 +676,7 @@ c_gets(EditLine *el, char *buf, const char *prompt) case 0010: /* Delete and backspace */ case 0177: - if (len <= 0) { + if (len == 0) { len = -1; break; } @@ -735,8 +690,8 @@ c_gets(EditLine *el, char *buf, const char *prompt) 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; @@ -749,7 +704,7 @@ c_gets(EditLine *el, char *buf, const char *prompt) el->el_line.buffer[0] = '\0'; el->el_line.lastchar = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer; - return len; + return (int)len; } @@ -759,18 +714,26 @@ c_gets(EditLine *el, char *buf, const char *prompt) protected int c_hpos(EditLine *el) { - char *ptr; + Char *ptr; /* * Find how many characters till the beginning of this line. */ 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'; ptr--) continue; - return (el->el_line.cursor - ptr - 1); + return (int)(el->el_line.cursor - ptr - 1); } } + +protected int +ch_resizefun(EditLine *el, el_zfunc_t f, void *a) +{ + el->el_chared.c_resizefun = f; + el->el_chared.c_resizearg = a; + return 0; +} diff --git a/cmd-line-utils/libedit/chared.h b/cmd-line-utils/libedit/chared.h index fa8f5a58d83..176475ac8f0 100644 --- a/cmd-line-utils/libedit/chared.h +++ b/cmd-line-utils/libedit/chared.h @@ -1,4 +1,4 @@ -/* $NetBSD: chared.h,v 1.17 2006/03/06 21:11:56 christos Exp $ */ +/* $NetBSD: chared.h,v 1.21 2010/08/28 15:44:59 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -63,25 +63,25 @@ typedef struct c_macro_t { int level; int offset; - char **macro; + Char **macro; } c_macro_t; /* * Undo information for vi - no undo in emacs (yet) */ typedef struct c_undo_t { - int len; /* length of saved line */ + ssize_t len; /* length of saved line */ int cursor; /* position of saved cursor */ - char *buf; /* full saved text */ + Char *buf; /* full saved text */ } c_undo_t; /* redo for vi */ typedef struct c_redo_t { - char *buf; /* redo insert key sequence */ - char *pos; - char *lim; + Char *buf; /* redo insert key sequence */ + Char *pos; + Char *lim; el_action_t cmd; /* command to redo */ - char ch; /* char that invoked it */ + Char ch; /* char that invoked it */ int count; int action; /* from cv_action() */ } c_redo_t; @@ -91,18 +91,20 @@ typedef struct c_redo_t { */ typedef struct c_vcmd_t { int action; - char *pos; + Char *pos; } c_vcmd_t; /* * Kill buffer for emacs */ typedef struct c_kill_t { - char *buf; - char *last; - char *mark; + Char *buf; + Char *last; + Char *mark; } c_kill_t; +typedef void (*el_zfunc_t)(EditLine *, void *); + /* * Note that we use both data structures because the user can bind * commands from both editors! @@ -113,13 +115,14 @@ typedef struct el_chared_t { 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; #define STRQQ "\"\"" #define isglob(a) (strchr("*[]?", (a)) != NULL) -#define isword(a) (el_isprint(a)) #define NOP 0x00 #define DELETE 0x01 @@ -140,27 +143,28 @@ typedef struct el_chared_t { #include "fcns.h" -protected int cv__isword(int); -protected int cv__isWord(int); +protected int cv__isword(Int); +protected int cv__isWord(Int); protected void cv_delfini(EditLine *); -protected char *cv__endword(char *, char *, int, int (*)(int)); -protected int ce__isword(int); +protected Char *cv__endword(Char *, Char *, int, int (*)(Int)); +protected int ce__isword(Int); protected void cv_undo(EditLine *); -protected void cv_yank(EditLine *, const char *, int); -protected char *cv_next_word(EditLine*, char *, char *, int, int (*)(int)); -protected char *cv_prev_word(char *, char *, int, int (*)(int)); -protected char *c__next_word(char *, char *, int, int (*)(int)); -protected char *c__prev_word(char *, char *, int, int (*)(int)); +protected void cv_yank(EditLine *, const Char *, int); +protected Char *cv_next_word(EditLine*, Char *, Char *, int, int (*)(Int)); +protected Char *cv_prev_word(Char *, Char *, int, int (*)(Int)); +protected Char *c__next_word(Char *, Char *, int, int (*)(Int)); +protected Char *c__prev_word(Char *, Char *, int, int (*)(Int)); protected void c_insert(EditLine *, int); protected void c_delbefore(EditLine *, int); protected void c_delbefore1(EditLine *); protected void c_delafter(EditLine *, int); protected void c_delafter1(EditLine *); -protected int c_gets(EditLine *, char *, const char *); +protected int c_gets(EditLine *, Char *, const Char *); protected int c_hpos(EditLine *); protected int ch_init(EditLine *); 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 *); diff --git a/cmd-line-utils/libedit/chartype.c b/cmd-line-utils/libedit/chartype.c new file mode 100644 index 00000000000..b70aebeec46 --- /dev/null +++ b/cmd-line-utils/libedit/chartype.c @@ -0,0 +1,361 @@ +/* $NetBSD: chartype.c,v 1.10 2011/08/16 16:25:15 christos Exp $ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * chartype.c: character classification and meta information + */ +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#endif /* not lint && not SCCSID */ +#include "el.h" +#include <stdlib.h> + +#define CT_BUFSIZ ((size_t)1024) + +#ifdef WIDECHAR +protected void +ct_conv_buff_resize(ct_buffer_t *conv, size_t mincsize, size_t minwsize) +{ + void *p; + if (mincsize > conv->csize) { + conv->csize = mincsize; + p = el_realloc(conv->cbuff, conv->csize * sizeof(*conv->cbuff)); + if (p == NULL) { + conv->csize = 0; + el_free(conv->cbuff); + conv->cbuff = NULL; + } else + conv->cbuff = p; + } + + if (minwsize > conv->wsize) { + conv->wsize = minwsize; + p = el_realloc(conv->wbuff, conv->wsize * sizeof(*conv->wbuff)); + if (p == NULL) { + conv->wsize = 0; + el_free(conv->wbuff); + conv->wbuff = NULL; + } else + conv->wbuff = p; + } +} + + +public char * +ct_encode_string(const Char *s, ct_buffer_t *conv) +{ + char *dst; + ssize_t used = 0; + mbstate_t state; + + memset(&state, 0, sizeof(mbstate_t)); + + if (!s) + return NULL; + if (!conv->cbuff) + ct_conv_buff_resize(conv, CT_BUFSIZ, (size_t)0); + if (!conv->cbuff) + return NULL; + + dst = conv->cbuff; + while (*s) { + used = (ssize_t)(conv->csize - (size_t)(dst - conv->cbuff)); + if (used < 5) { + used = dst - conv->cbuff; + ct_conv_buff_resize(conv, conv->csize + CT_BUFSIZ, + (size_t)0); + if (!conv->cbuff) + return NULL; + dst = conv->cbuff + used; + } + used = ct_encode_char(dst, (size_t)5, *s, &state); + if (used == -1) /* failed to encode, need more buffer space */ + abort(); + ++s; + dst += used; + } + *dst = '\0'; + return conv->cbuff; +} + +public Char * +ct_decode_string(const char *s, ct_buffer_t *conv) +{ + size_t len = 0; + + if (!s) + return NULL; + if (!conv->wbuff) + ct_conv_buff_resize(conv, (size_t)0, CT_BUFSIZ); + if (!conv->wbuff) + return NULL; + + len = ct_mbstowcs(NULL, s, (size_t)0); + if (len == (size_t)-1) + return NULL; + if (len > conv->wsize) + ct_conv_buff_resize(conv, (size_t)0, len + 1); + if (!conv->wbuff) + return NULL; + ct_mbstowcs(conv->wbuff, s, conv->wsize); + return conv->wbuff; +} + + +protected Char ** +ct_decode_argv(int argc, const char *argv[], ct_buffer_t *conv) +{ + size_t bufspace; + int i; + Char *p; + Char **wargv; + ssize_t bytes; + mbstate_t state; + + /* Make sure we have enough space in the conversion buffer to store all + * the argv strings. */ + for (i = 0, bufspace = 0; i < argc; ++i) + bufspace += argv[i] ? strlen(argv[i]) + 1 : 0; + ct_conv_buff_resize(conv, (size_t)0, bufspace); + if (!conv->wsize) + return NULL; + + wargv = el_malloc((size_t)argc * sizeof(*wargv)); + + for (i = 0, p = conv->wbuff; i < argc; ++i) { + if (!argv[i]) { /* don't pass null pointers to mbsrtowcs */ + wargv[i] = NULL; + continue; + } else { + wargv[i] = p; + memset(&state, 0, sizeof(mbstate_t)); + bytes = (ssize_t)mbsrtowcs(p, argv + i, bufspace, &state); + } + if (bytes == -1) { + el_free(wargv); + return NULL; + } else + bytes++; /* include '\0' in the count */ + bufspace -= (size_t)bytes; + p += bytes; + } + + return wargv; +} + + +protected size_t +ct_enc_width(Char c) +{ + /* UTF-8 encoding specific values */ + if (c < 0x80) + return 1; + else if (c < 0x0800) + return 2; + else if (c < 0x10000) + return 3; + else if (c < 0x110000) + return 4; + else + return 0; /* not a valid codepoint */ +} + +protected ssize_t +ct_encode_char(char *dst, size_t len, Char c, mbstate_t *state) +{ + ssize_t l = 0; + + if (len < ct_enc_width(c)) + return -1; + + l = wcrtomb(dst, c, state); + + if (l < 0) { + memset (state, 0, sizeof (mbstate_t)); + l = 0; + } + return l; +} +#endif + +protected const Char * +ct_visual_string(const Char *s) +{ + static Char *buff = NULL; + static size_t buffsize = 0; + void *p; + Char *dst; + ssize_t used = 0; + + if (!s) + return NULL; + if (!buff) { + buffsize = CT_BUFSIZ; + buff = el_malloc(buffsize * sizeof(*buff)); + } + dst = buff; + while (*s) { + used = ct_visual_char(dst, buffsize - (size_t)(dst - buff), *s); + if (used == -1) { /* failed to encode, need more buffer space */ + used = dst - buff; + buffsize += CT_BUFSIZ; + p = el_realloc(buff, buffsize * sizeof(*buff)); + if (p == NULL) + goto out; + buff = p; + dst = buff + used; + /* don't increment s here - we want to retry it! */ + } + else + ++s; + dst += used; + } + if (dst >= (buff + buffsize)) { /* sigh */ + buffsize += 1; + p = el_realloc(buff, buffsize * sizeof(*buff)); + if (p == NULL) + goto out; + buff = p; + dst = buff + buffsize - 1; + } + *dst = 0; + return buff; +out: + el_free(buff); + buffsize = 0; + return NULL; +} + + +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; +} diff --git a/cmd-line-utils/libedit/chartype.h b/cmd-line-utils/libedit/chartype.h new file mode 100644 index 00000000000..678d13683be --- /dev/null +++ b/cmd-line-utils/libedit/chartype.h @@ -0,0 +1,252 @@ +/* $NetBSD: chartype.h,v 1.8 2011/07/29 23:44:44 christos Exp $ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _h_chartype_f +#define _h_chartype_f + + + +#ifdef WIDECHAR + +/* Ideally we should also test the value of the define to see if it + * supports non-BMP code points without requiring UTF-16, but nothing + * seems to actually advertise this properly, despite Unicode 3.1 having + * been around since 2001... */ + +/* XXXMYSQL : Added FreeBSD to bypass this check. + TODO : Verify if FreeBSD stores ISO 10646 in wchar_t. */ +#if !defined(__NetBSD__) && !defined(__sun) \ + && !(defined(__APPLE__) && defined(__MACH__)) \ + && !defined(__FreeBSD__) +#ifndef __STDC_ISO_10646__ +/* In many places it is assumed that the first 127 code points are ASCII + * compatible, so ensure wchar_t indeed does ISO 10646 and not some other + * funky encoding that could break us in weird and wonderful ways. */ + #error wchar_t must store ISO 10646 characters +#endif +#endif + +/* Oh for a <uchar.h> with char32_t and __STDC_UTF_32__ in it... + * ref: ISO/IEC DTR 19769 + */ +#if WCHAR_MAX < INT32_MAX +#warning Build environment does not support non-BMP characters +#endif + +#ifndef HAVE_WCSDUP +wchar_t *wcsdup(const wchar_t *s); +#endif + +#define ct_wctomb wctomb +#define ct_wctomb_reset wctomb(0,0) +#define ct_wcstombs wcstombs +#define ct_mbstowcs mbstowcs + +#define Char wchar_t +#define Int wint_t +#define FUN(prefix,rest) prefix ## _w ## rest +#define FUNW(type) type ## _w +#define TYPE(type) type ## W +#define FSTR "%ls" +#define STR(x) L ## x +#define UC(c) c +#define Isalpha(x) iswalpha(x) +#define Isalnum(x) iswalnum(x) +#define Isgraph(x) iswgraph(x) +#define Isspace(x) iswspace(x) +#define Isdigit(x) iswdigit(x) +#define Iscntrl(x) iswcntrl(x) +#define Isprint(x) iswprint(x) + +#define Isupper(x) iswupper(x) +#define Islower(x) iswlower(x) +#define Toupper(x) towupper(x) +#define Tolower(x) towlower(x) + +#define IsASCII(x) (x < 0x100) + +#define Strlen(x) wcslen(x) +#define Strchr(s,c) wcschr(s,c) +#define Strrchr(s,c) wcsrchr(s,c) +#define Strstr(s,v) wcsstr(s,v) +#define Strdup(x) wcsdup(x) +#define Strcpy(d,s) wcscpy(d,s) +#define Strncpy(d,s,n) wcsncpy(d,s,n) +#define Strncat(d,s,n) wcsncat(d,s,n) + +#define Strcmp(s,v) wcscmp(s,v) +#define Strncmp(s,v,n) wcsncmp(s,v,n) +#define Strcspn(s,r) wcscspn(s,r) + +#define Strtol(p,e,b) wcstol(p,e,b) + +#define Width(c) wcwidth(c) + +#else /* NARROW */ + +#define ct_mbtowc error +#define ct_mbtowc_reset +#define ct_wctomb error +#define ct_wctomb_reset +#define ct_wcstombs(a, b, c) (strncpy(a, b, c), strlen(a)) +#define ct_mbstowcs(a, b, c) (strncpy(a, b, c), strlen(a)) + +#define Char char +#define Int int +#define FUN(prefix,rest) prefix ## _ ## rest +#define FUNW(type) type +#define TYPE(type) type +#define FSTR "%s" +#define STR(x) x +#define UC(c) (unsigned char)(c) + +#define Isalpha(x) isalpha((unsigned char)x) +#define Isalnum(x) isalnum((unsigned char)x) +#define Isgraph(x) isgraph((unsigned char)x) +#define Isspace(x) isspace((unsigned char)x) +#define Isdigit(x) isdigit((unsigned char)x) +#define Iscntrl(x) iscntrl((unsigned char)x) +#define Isprint(x) isprint((unsigned char)x) + +#define Isupper(x) isupper((unsigned char)x) +#define Islower(x) islower((unsigned char)x) +#define Toupper(x) toupper((unsigned char)x) +#define Tolower(x) tolower((unsigned char)x) + +#define IsASCII(x) isascii((unsigned char)x) + +#define Strlen(x) strlen(x) +#define Strchr(s,c) strchr(s,c) +#define Strrchr(s,c) strrchr(s,c) +#define Strstr(s,v) strstr(s,v) +#define Strdup(x) strdup(x) +#define Strcpy(d,s) strcpy(d,s) +#define Strncpy(d,s,n) strncpy(d,s,n) +#define Strncat(d,s,n) strncat(d,s,n) + +#define Strcmp(s,v) strcmp(s,v) +#define Strncmp(s,v,n) strncmp(s,v,n) +#define Strcspn(s,r) strcspn(s,r) + +#define Strtol(p,e,b) strtol(p,e,b) + +#define Width(c) 1 + +#endif + + +#ifdef WIDECHAR +/* + * Conversion buffer + */ +typedef struct ct_buffer_t { + char *cbuff; + size_t csize; + Char *wbuff; + size_t wsize; +} ct_buffer_t; + +#define ct_encode_string __ct_encode_string +/* Encode a wide-character string and return the UTF-8 encoded result. */ +public char *ct_encode_string(const Char *, ct_buffer_t *); + +#define ct_decode_string __ct_decode_string +/* Decode a (multi)?byte string and return the wide-character string result. */ +public Char *ct_decode_string(const char *, ct_buffer_t *); + +/* Decode a (multi)?byte argv string array. + * The pointer returned must be free()d when done. */ +protected Char **ct_decode_argv(int, const char *[], ct_buffer_t *); + +/* Resizes the conversion buffer(s) if needed. */ +protected void ct_conv_buff_resize(ct_buffer_t *, size_t, size_t); +protected ssize_t ct_encode_char(char *, size_t, Char, mbstate_t *); +protected size_t ct_enc_width(Char); + +#define ct_free_argv(s) el_free(s) + +#else +#define ct_encode_string(s, b) (s) +#define ct_decode_string(s, b) (s) +#define ct_decode_argv(l, s, b) (s) +#define ct_conv_buff_resize(b, os, ns) +#define ct_encode_char(d, l, s, ps) (*d = s, 1) +#define ct_free_argv(s) +#endif + +#ifndef NARROWCHAR +/* Encode a characted into the destination buffer, provided there is sufficent + * buffer space available. Returns the number of bytes used up (zero if the + * character cannot be encoded, -1 if there was not enough space available). */ + +/* The maximum buffer size to hold the most unwieldly visual representation, + * in this case \U+nnnnn. */ +#define VISUAL_WIDTH_MAX ((size_t)8) + +/* The terminal is thought of in terms of X columns by Y lines. In the cases + * where a wide character takes up more than one column, the adjacent + * occupied column entries will contain this faux character. */ +#define MB_FILL_CHAR ((Char)-1) + +/* Visual width of character c, taking into account ^? , \0177 and \U+nnnnn + * style visual expansions. */ +protected int ct_visual_width(Char); + +/* Turn the given character into the appropriate visual format, matching + * the width given by ct_visual_width(). Returns the number of characters used + * up, or -1 if insufficient space. Buffer length is in count of Char's. */ +protected ssize_t ct_visual_char(Char *, size_t, Char); + +/* Convert the given string into visual format, using the ct_visual_char() + * function. Uses a static buffer, so not threadsafe. */ +protected const Char *ct_visual_string(const Char *); + + +/* printable character, use ct_visual_width() to find out display width */ +#define CHTYPE_PRINT ( 0) +/* control character found inside the ASCII portion of the charset */ +#define CHTYPE_ASCIICTL (-1) +/* a \t */ +#define CHTYPE_TAB (-2) +/* a \n */ +#define CHTYPE_NL (-3) +/* non-printable character */ +#define CHTYPE_NONPRINT (-4) +/* classification of character c, as one of the above defines */ +protected int ct_chr_class(Char c); +#endif + + +#endif /* _chartype_f */ diff --git a/cmd-line-utils/libedit/common.c b/cmd-line-utils/libedit/common.c index ba5890fa606..c0512061e6f 100644 --- a/cmd-line-utils/libedit/common.c +++ b/cmd-line-utils/libedit/common.c @@ -1,4 +1,4 @@ -/* $NetBSD: common.c,v 1.21 2008/09/30 08:37:42 aymeric Exp $ */ +/* $NetBSD: common.c,v 1.28 2011/07/29 20:58:07 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -51,12 +51,12 @@ static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93"; */ protected el_action_t /*ARGSUSED*/ -ed_end_of_file(EditLine *el, int c __attribute__((__unused__))) +ed_end_of_file(EditLine *el, Int c __attribute__((__unused__))) { re_goto_bottom(el); *el->el_line.lastchar = '\0'; - return (CC_EOF); + return CC_EOF; } @@ -65,12 +65,12 @@ ed_end_of_file(EditLine *el, int c __attribute__((__unused__))) * Insert a character [bound to all insert keys] */ 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) { @@ -98,7 +98,7 @@ ed_insert(EditLine *el, int c) if (el->el_state.inputmode == MODE_REPLACE_1) return vi_command_mode(el, 0); - return (CC_NORM); + return CC_NORM; } @@ -108,12 +108,12 @@ ed_insert(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__))) +ed_delete_prev_word(EditLine *el, Int c __attribute__((__unused__))) { - char *cp, *p, *kp; + Char *cp, *p, *kp; if (el->el_line.cursor == el->el_line.buffer) - return (CC_ERROR); + return CC_ERROR; cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, el->el_state.argument, ce__isword); @@ -122,11 +122,11 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__))) *kp++ = *p; el->el_chared.c_kill.last = kp; - c_delbefore(el, el->el_line.cursor - cp); /* delete before dot */ + c_delbefore(el, (int)(el->el_line.cursor - cp));/* delete before dot */ el->el_line.cursor = cp; if (el->el_line.cursor < el->el_line.buffer) el->el_line.cursor = el->el_line.buffer; /* bounds check */ - return (CC_REFRESH); + return CC_REFRESH; } @@ -136,9 +136,9 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) +ed_delete_next_char(EditLine *el, Int c __attribute__((__unused__))) { -#ifdef notdef /* XXX */ +#ifdef DEBUG_EDIT #define EL el->el_line (void) fprintf(el->el_errlfile, "\nD(b: %x(%s) c: %x(%s) last: %x(%s) limit: %x(%s)\n", @@ -151,24 +151,24 @@ ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) if (el->el_line.cursor == el->el_line.buffer) { /* if 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 { if (el->el_line.cursor != el->el_line.buffer) el->el_line.cursor--; else - return (CC_ERROR); + return CC_ERROR; } } c_delafter(el, el->el_state.argument); /* delete after dot */ @@ -176,7 +176,7 @@ ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) el->el_line.cursor > el->el_line.buffer) /* bounds check */ el->el_line.cursor = el->el_line.lastchar - 1; - return (CC_REFRESH); + return CC_REFRESH; } @@ -186,9 +186,9 @@ ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_kill_line(EditLine *el, int c __attribute__((__unused__))) +ed_kill_line(EditLine *el, Int c __attribute__((__unused__))) { - char *kp, *cp; + Char *kp, *cp; cp = el->el_line.cursor; kp = el->el_chared.c_kill.buf; @@ -197,7 +197,7 @@ ed_kill_line(EditLine *el, int c __attribute__((__unused__))) 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; } @@ -207,20 +207,20 @@ ed_kill_line(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_move_to_end(EditLine *el, int c __attribute__((__unused__))) +ed_move_to_end(EditLine *el, Int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.lastchar; if (el->el_map.type == MAP_VI) { if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } #ifdef VI_MOVE el->el_line.cursor--; #endif } - return (CC_CURSOR); + return CC_CURSOR; } @@ -230,21 +230,21 @@ ed_move_to_end(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_move_to_beg(EditLine *el, int c __attribute__((__unused__))) +ed_move_to_beg(EditLine *el, Int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; if (el->el_map.type == MAP_VI) { /* We want FIRST non space character */ - while (isspace((unsigned char) *el->el_line.cursor)) + while (Isspace(*el->el_line.cursor)) el->el_line.cursor++; if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } } - return (CC_CURSOR); + return CC_CURSOR; } @@ -253,12 +253,12 @@ ed_move_to_beg(EditLine *el, int c __attribute__((__unused__))) * [^T] [^T] */ 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++; } @@ -267,9 +267,9 @@ ed_transpose_chars(EditLine *el, int c) 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; } @@ -279,15 +279,15 @@ ed_transpose_chars(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -ed_next_char(EditLine *el, int c __attribute__((__unused__))) +ed_next_char(EditLine *el, Int c __attribute__((__unused__))) { - char *lim = el->el_line.lastchar; + Char *lim = el->el_line.lastchar; if (el->el_line.cursor >= lim || (el->el_line.cursor == lim - 1 && 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) @@ -296,9 +296,9 @@ ed_next_char(EditLine *el, int c __attribute__((__unused__))) 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; } @@ -308,11 +308,11 @@ ed_next_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_prev_word(EditLine *el, int c __attribute__((__unused__))) +ed_prev_word(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.buffer) - return (CC_ERROR); + return CC_ERROR; el->el_line.cursor = c__prev_word(el->el_line.cursor, el->el_line.buffer, @@ -322,9 +322,9 @@ ed_prev_word(EditLine *el, int c __attribute__((__unused__))) if (el->el_map.type == MAP_VI) if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -334,7 +334,7 @@ ed_prev_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_prev_char(EditLine *el, int c __attribute__((__unused__))) +ed_prev_char(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor > el->el_line.buffer) { @@ -345,11 +345,11 @@ ed_prev_char(EditLine *el, int c __attribute__((__unused__))) 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; } @@ -358,19 +358,19 @@ ed_prev_char(EditLine *el, int c __attribute__((__unused__))) * [^V] [^V] */ protected el_action_t -ed_quoted_insert(EditLine *el, int c) +ed_quoted_insert(EditLine *el, Int c) { int num; - char tc; + Char tc; tty_quotemode(el); - num = el_getc(el, &tc); - c = (unsigned char) tc; + num = FUN(el,getc)(el, &tc); + c = tc; tty_noquotemode(el); if (num == 1) - return (ed_insert(el, c)); + return ed_insert(el, c); else - return (ed_end_of_file(el, 0)); + return ed_end_of_file(el, 0); } @@ -378,11 +378,11 @@ ed_quoted_insert(EditLine *el, int c) * Adds to argument or enters a digit */ protected el_action_t -ed_digit(EditLine *el, int c) +ed_digit(EditLine *el, Int c) { - if (!isdigit(c)) - return (CC_ERROR); + if (!Isdigit(c)) + return CC_ERROR; if (el->el_state.doingarg) { /* if doing an arg, add this in... */ @@ -390,11 +390,11 @@ ed_digit(EditLine *el, int c) 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); @@ -406,22 +406,22 @@ ed_digit(EditLine *el, int c) * For ESC-n */ protected el_action_t -ed_argument_digit(EditLine *el, int c) +ed_argument_digit(EditLine *el, Int c) { - if (!isdigit(c)) - 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 */ el->el_state.argument = c - '0'; el->el_state.doingarg = 1; } - return (CC_ARGHACK); + return CC_ARGHACK; } @@ -432,10 +432,10 @@ ed_argument_digit(EditLine *el, int c) protected el_action_t /*ARGSUSED*/ ed_unassigned(EditLine *el __attribute__((__unused__)), - int c __attribute__((__unused__))) + Int c __attribute__((__unused__))) { - return (CC_ERROR); + return CC_ERROR; } @@ -450,10 +450,10 @@ ed_unassigned(EditLine *el __attribute__((__unused__)), protected el_action_t /*ARGSUSED*/ ed_tty_sigint(EditLine *el __attribute__((__unused__)), - int c __attribute__((__unused__))) + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -464,10 +464,10 @@ ed_tty_sigint(EditLine *el __attribute__((__unused__)), protected el_action_t /*ARGSUSED*/ ed_tty_dsusp(EditLine *el __attribute__((__unused__)), - int c __attribute__((__unused__))) + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -478,10 +478,10 @@ ed_tty_dsusp(EditLine *el __attribute__((__unused__)), protected el_action_t /*ARGSUSED*/ ed_tty_flush_output(EditLine *el __attribute__((__unused__)), - int c __attribute__((__unused__))) + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -492,10 +492,10 @@ ed_tty_flush_output(EditLine *el __attribute__((__unused__)), protected el_action_t /*ARGSUSED*/ ed_tty_sigquit(EditLine *el __attribute__((__unused__)), - int c __attribute__((__unused__))) + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -506,10 +506,10 @@ ed_tty_sigquit(EditLine *el __attribute__((__unused__)), protected el_action_t /*ARGSUSED*/ ed_tty_sigtstp(EditLine *el __attribute__((__unused__)), - int c __attribute__((__unused__))) + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -520,10 +520,10 @@ ed_tty_sigtstp(EditLine *el __attribute__((__unused__)), protected el_action_t /*ARGSUSED*/ ed_tty_stop_output(EditLine *el __attribute__((__unused__)), - int c __attribute__((__unused__))) + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -534,10 +534,10 @@ ed_tty_stop_output(EditLine *el __attribute__((__unused__)), protected el_action_t /*ARGSUSED*/ ed_tty_start_output(EditLine *el __attribute__((__unused__)), - int c __attribute__((__unused__))) + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -547,13 +547,13 @@ ed_tty_start_output(EditLine *el __attribute__((__unused__)), */ protected el_action_t /*ARGSUSED*/ -ed_newline(EditLine *el, int c __attribute__((__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; } @@ -563,17 +563,17 @@ ed_newline(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__))) +ed_delete_prev_char(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor <= el->el_line.buffer) - 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; } @@ -583,12 +583,12 @@ ed_delete_prev_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_clear_screen(EditLine *el, int c __attribute__((__unused__))) +ed_clear_screen(EditLine *el, Int c __attribute__((__unused__))) { - term_clear_screen(el); /* clear the whole real screen */ + terminal_clear_screen(el); /* clear the whole real screen */ re_clear_display(el); /* reset everything */ - return (CC_REFRESH); + return CC_REFRESH; } @@ -599,10 +599,10 @@ ed_clear_screen(EditLine *el, int c __attribute__((__unused__))) protected el_action_t /*ARGSUSED*/ ed_redisplay(EditLine *el __attribute__((__unused__)), - int c __attribute__((__unused__))) + Int c __attribute__((__unused__))) { - return (CC_REDISPLAY); + return CC_REDISPLAY; } @@ -612,11 +612,11 @@ ed_redisplay(EditLine *el __attribute__((__unused__)), */ protected el_action_t /*ARGSUSED*/ -ed_start_over(EditLine *el, int c __attribute__((__unused__))) +ed_start_over(EditLine *el, Int c __attribute__((__unused__))) { ch_reset(el, 0); - return (CC_REFRESH); + return CC_REFRESH; } @@ -627,10 +627,10 @@ ed_start_over(EditLine *el, int c __attribute__((__unused__))) protected el_action_t /*ARGSUSED*/ ed_sequence_lead_in(EditLine *el __attribute__((__unused__)), - int c __attribute__((__unused__))) + Int c __attribute__((__unused__))) { - return (CC_NORM); + return CC_NORM; } @@ -640,7 +640,7 @@ ed_sequence_lead_in(EditLine *el __attribute__((__unused__)), */ protected el_action_t /*ARGSUSED*/ -ed_prev_history(EditLine *el, int c __attribute__((__unused__))) +ed_prev_history(EditLine *el, Int c __attribute__((__unused__))) { char beep = 0; int sv_event = el->el_history.eventno; @@ -650,7 +650,7 @@ ed_prev_history(EditLine *el, int c __attribute__((__unused__))) if (el->el_history.eventno == 0) { /* save the current buffer * away */ - (void) strncpy(el->el_history.buf, el->el_line.buffer, + (void) Strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ); el->el_history.last = el->el_history.buf + (el->el_line.lastchar - el->el_line.buffer); @@ -660,7 +660,7 @@ ed_prev_history(EditLine *el, int c __attribute__((__unused__))) if (hist_get(el) == CC_ERROR) { if (el->el_map.type == MAP_VI) { el->el_history.eventno = sv_event; - return CC_ERROR; + } beep = 1; /* el->el_history.eventno was fixed by first call */ @@ -678,7 +678,7 @@ ed_prev_history(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_next_history(EditLine *el, int c __attribute__((__unused__))) +ed_next_history(EditLine *el, Int c __attribute__((__unused__))) { el_action_t beep = CC_REFRESH, rval; @@ -705,9 +705,9 @@ ed_next_history(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_search_prev_history(EditLine *el, int c __attribute__((__unused__))) +ed_search_prev_history(EditLine *el, Int c __attribute__((__unused__))) { - const char *hp; + const Char *hp; int h; bool_t found = 0; @@ -720,20 +720,20 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__))) "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 !! */ @@ -744,7 +744,7 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__))) #ifdef SDEBUG (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); #endif - if ((strncmp(hp, el->el_line.buffer, (size_t) + if ((Strncmp(hp, el->el_line.buffer, (size_t) (el->el_line.lastchar - el->el_line.buffer)) || hp[el->el_line.lastchar - el->el_line.buffer]) && c_hmatch(el, hp)) { @@ -759,11 +759,11 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__))) #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); } @@ -773,9 +773,9 @@ ed_search_prev_history(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_search_next_history(EditLine *el, int c __attribute__((__unused__))) +ed_search_next_history(EditLine *el, Int c __attribute__((__unused__))) { - const char *hp; + const Char *hp; int h; bool_t found = 0; @@ -784,14 +784,14 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__))) *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 !! */ @@ -799,7 +799,7 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__))) #ifdef SDEBUG (void) fprintf(el->el_errfile, "Comparing with \"%s\"\n", hp); #endif - if ((strncmp(hp, el->el_line.buffer, (size_t) + if ((Strncmp(hp, el->el_line.buffer, (size_t) (el->el_line.lastchar - el->el_line.buffer)) || hp[el->el_line.lastchar - el->el_line.buffer]) && c_hmatch(el, hp)) @@ -812,12 +812,12 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__))) #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); } @@ -827,9 +827,9 @@ ed_search_next_history(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_prev_line(EditLine *el, int c __attribute__((__unused__))) +ed_prev_line(EditLine *el, Int c __attribute__((__unused__))) { - char *ptr; + Char *ptr; int nchars = c_hpos(el); /* @@ -843,7 +843,7 @@ ed_prev_line(EditLine *el, int c __attribute__((__unused__))) break; if (el->el_state.argument > 0) - return (CC_ERROR); + return CC_ERROR; /* * Move to the beginning of the line @@ -860,7 +860,7 @@ ed_prev_line(EditLine *el, int c __attribute__((__unused__))) continue; el->el_line.cursor = ptr; - return (CC_CURSOR); + return CC_CURSOR; } @@ -870,9 +870,9 @@ ed_prev_line(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_next_line(EditLine *el, int c __attribute__((__unused__))) +ed_next_line(EditLine *el, Int c __attribute__((__unused__))) { - char *ptr; + Char *ptr; int nchars = c_hpos(el); /* @@ -883,7 +883,7 @@ ed_next_line(EditLine *el, int c __attribute__((__unused__))) break; if (el->el_state.argument > 0) - return (CC_ERROR); + return CC_ERROR; /* * Move to the character requested @@ -894,7 +894,7 @@ ed_next_line(EditLine *el, int c __attribute__((__unused__))) continue; el->el_line.cursor = ptr; - return (CC_CURSOR); + return CC_CURSOR; } @@ -904,16 +904,16 @@ ed_next_line(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -ed_command(EditLine *el, int c __attribute__((__unused__))) +ed_command(EditLine *el, Int c __attribute__((__unused__))) { - char tmpbuf[EL_BUFSIZ]; + Char tmpbuf[EL_BUFSIZ]; int tmplen; - tmplen = c_gets(el, tmpbuf, "\n: "); - term__putc(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); diff --git a/cmd-line-utils/libedit/config.h b/cmd-line-utils/libedit/config.h index 2c3989ee316..c06d5e28a0a 100644 --- a/cmd-line-utils/libedit/config.h +++ b/cmd-line-utils/libedit/config.h @@ -1,2 +1,5 @@ #include "my_config.h" #include "sys.h" +#ifndef NARROW_WRAPPER +#define WIDECHAR +#endif diff --git a/cmd-line-utils/libedit/el.c b/cmd-line-utils/libedit/el.c index d99946eb68f..c7f4f81ec93 100644 --- a/cmd-line-utils/libedit/el.c +++ b/cmd-line-utils/libedit/el.c @@ -1,4 +1,4 @@ -/* $NetBSD: el.c,v 1.47 2009/01/18 12:17:24 lukem Exp $ */ +/* $NetBSD: el.c,v 1.68 2011/07/29 15:16:33 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -48,6 +48,9 @@ static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94"; #include <string.h> #include <stdlib.h> #include <stdarg.h> +#include <ctype.h> +#include <locale.h> +#include <langinfo.h> #include "el.h" /* el_init(): @@ -56,11 +59,10 @@ static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94"; public EditLine * el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) { - - EditLine *el = (EditLine *) el_malloc(sizeof(EditLine)); + EditLine *el = el_malloc(sizeof(*el)); if (el == NULL) - return (NULL); + return NULL; memset(el, 0, sizeof(EditLine)); @@ -69,8 +71,11 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) el->el_errfile = ferr; el->el_infd = fileno(fin); + el->el_outfd = fileno(fout); + el->el_errfd = fileno(ferr); - if ((el->el_prog = el_strdup(prog)) == NULL) { + el->el_prog = Strdup(ct_decode_string(prog, &el->el_scratch)); + if (el->el_prog == NULL) { el_free(el); return NULL; } @@ -79,13 +84,18 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) * Initialize all the modules. Order is important!!! */ el->el_flags = 0; +#ifdef WIDECHAR + setlocale(LC_CTYPE, NULL); + if (MB_CUR_MAX > 1) + el->el_flags |= CHARSET_IS_MULTIBYTE; +#endif - if (term_init(el) == -1) { + if (terminal_init(el) == -1) { el_free(el->el_prog); el_free(el); return NULL; } - (void) key_init(el); + (void) keymacro_init(el); (void) map_init(el); if (tty_init(el) == -1) el->el_flags |= NO_TTY; @@ -96,7 +106,7 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) (void) sig_init(el); (void) read_init(el); - return (el); + return el; } @@ -112,8 +122,8 @@ el_end(EditLine *el) el_reset(el); - term_end(el); - key_end(el); + terminal_end(el); + keymacro_end(el); map_end(el); tty_end(el); ch_end(el); @@ -122,8 +132,14 @@ el_end(EditLine *el) 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); } @@ -143,27 +159,46 @@ el_reset(EditLine *el) * set the editline parameters */ public int -el_set(EditLine *el, int op, ...) +FUN(el,set)(EditLine *el, int op, ...) { va_list ap; int rv = 0; if (el == NULL) - return (-1); + return -1; va_start(ap, op); switch (op) { case EL_PROMPT: - case EL_RPROMPT: - rv = prompt_set(el, va_arg(ap, el_pfunc_t), op); + case EL_RPROMPT: { + el_pfunc_t p = va_arg(ap, el_pfunc_t); + + rv = prompt_set(el, p, 0, op, 1); break; + } + + case EL_RESIZE: { + el_zfunc_t p = va_arg(ap, el_zfunc_t); + void *arg = va_arg(ap, void *); + rv = ch_resizefun(el, p, arg); + break; + } + + case EL_PROMPT_ESC: + case EL_RPROMPT_ESC: { + el_pfunc_t p = va_arg(ap, el_pfunc_t); + int c = va_arg(ap, int); + + rv = prompt_set(el, p, c, op, 1); + break; + } case EL_TERMINAL: - 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: @@ -176,40 +211,39 @@ el_set(EditLine *el, int op, ...) case EL_BIND: case EL_TELLTC: case EL_SETTC: - case EL_GETTC: case EL_ECHOTC: case EL_SETTY: { - const char *argv[20]; + const Char *argv[20]; int i; for (i = 1; i < 20; i++) - if ((argv[i] = va_arg(ap, char *)) == NULL) + if ((argv[i] = va_arg(ap, Char *)) == NULL) break; switch (op) { case EL_BIND: - argv[0] = "bind"; + argv[0] = STR("bind"); rv = map_bind(el, i, argv); break; case EL_TELLTC: - argv[0] = "telltc"; - 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; @@ -223,8 +257,8 @@ el_set(EditLine *el, int op, ...) case EL_ADDFN: { - char *name = va_arg(ap, char *); - char *help = va_arg(ap, char *); + Char *name = va_arg(ap, Char *); + Char *help = va_arg(ap, Char *); el_func_t func = va_arg(ap, el_func_t); rv = map_addfunc(el, name, help, func); @@ -234,9 +268,11 @@ el_set(EditLine *el, int op, ...) case EL_HIST: { hist_fun_t func = va_arg(ap, hist_fun_t); - ptr_t ptr = va_arg(ap, char *); + void *ptr = va_arg(ap, void *); rv = hist_set(el, func, ptr); + if (!(el->el_flags & CHARSET_IS_MULTIBYTE)) + el->el_flags &= ~NARROW_HISTORY; break; } @@ -252,6 +288,7 @@ el_set(EditLine *el, int op, ...) { el_rfunc_t rc = va_arg(ap, el_rfunc_t); rv = el_read_setfn(el, rc); + el->el_flags &= ~NARROW_READ; break; } @@ -296,9 +333,11 @@ el_set(EditLine *el, int op, ...) 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; @@ -310,7 +349,7 @@ el_set(EditLine *el, int op, ...) case EL_REFRESH: re_clear_display(el); re_refresh(el); - term__flush(el); + terminal__flush(el); break; default: @@ -319,7 +358,7 @@ el_set(EditLine *el, int op, ...) } va_end(ap); - return (rv); + return rv; } @@ -327,7 +366,7 @@ el_set(EditLine *el, int op, ...) * retrieve the editline parameters */ public int -el_get(EditLine *el, int op, ...) +FUN(el,get)(EditLine *el, int op, ...) { va_list ap; int rv; @@ -339,12 +378,22 @@ el_get(EditLine *el, int op, ...) switch (op) { case EL_PROMPT: - case EL_RPROMPT: - rv = prompt_get(el, va_arg(ap, el_pfunc_t *), op); + case EL_RPROMPT: { + el_pfunc_t *p = va_arg(ap, el_pfunc_t *); + rv = prompt_get(el, p, 0, op); + break; + } + case EL_PROMPT_ESC: + case EL_RPROMPT_ESC: { + el_pfunc_t *p = va_arg(ap, el_pfunc_t *); + Char *c = va_arg(ap, Char *); + + rv = prompt_get(el, p, c, op); break; + } case EL_EDITOR: - rv = map_get_editor(el, va_arg(ap, const char **)); + rv = map_get_editor(el, va_arg(ap, const Char **)); break; case EL_SIGNAL: @@ -358,7 +407,7 @@ el_get(EditLine *el, int op, ...) break; case EL_TERMINAL: - term_get(el, va_arg(ap, const char **)); + terminal_get(el, va_arg(ap, const char **)); rv = 0; break; @@ -375,7 +424,7 @@ el_get(EditLine *el, int op, ...) switch (op) { case EL_GETTC: argv[0] = name; - rv = term_gettc(el, i, argv); + rv = terminal_gettc(el, i, argv); break; default: @@ -386,26 +435,6 @@ el_get(EditLine *el, int op, ...) break; } -#if 0 /* XXX */ - case EL_ADDFN: - { - char *name = va_arg(ap, char *); - char *help = va_arg(ap, char *); - el_func_t func = va_arg(ap, el_func_t); - - rv = map_addfunc(el, name, help, func); - break; - } - - case EL_HIST: - { - hist_fun_t func = va_arg(ap, hist_fun_t); - ptr_t ptr = va_arg(ap, char *); - rv = hist_set(el, func, ptr); - } - break; -#endif /* XXX */ - case EL_GETCFN: *va_arg(ap, el_rfunc_t *) = el_read_getfn(el); rv = 0; @@ -451,18 +480,18 @@ el_get(EditLine *el, int op, ...) } va_end(ap); - return (rv); + return rv; } /* 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; } @@ -475,53 +504,74 @@ el_source(EditLine *el, const char *fname) FILE *fp; size_t len; char *ptr; + char *path = NULL; + const Char *dptr; + int error = 0; fp = NULL; if (fname == NULL) { -#ifdef HAVE_ISSETUGID - static const char elpath[] = "/.editrc"; -/* XXXMYSQL: Portability fix (for which platforms?) */ -#ifdef MAXPATHLEN - char path[MAXPATHLEN]; -#else - char path[4096]; +/* XXXMYSQL: Bug#49967 */ +#if defined(HAVE_GETUID) && defined(HAVE_GETEUID) && \ + defined(HAVE_GETGID) && defined(HAVE_GETEGID) +#define HAVE_IDENTITY_FUNCS 1 #endif +#if (defined(HAVE_ISSETUGID) || defined(HAVE_IDENTITY_FUNCS)) + static const char elpath[] = "/.editrc"; + size_t plen = sizeof(elpath); +/* XXXMYSQL: Portability fix (for which platforms?) */ +#ifdef HAVE_ISSETUGID if (issetugid()) - return (-1); + return -1; +#elif defined(HAVE_IDENTITY_FUNCS) + if (getuid() != geteuid() || getgid() != getegid()) + return (-1); +#endif 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 /* - * If issetugid() is missing, always return an error, in order - * to keep from inadvertently opening up the user to a security - * hole. + * If issetugid() or the above mentioned get[e][u|g]id() + * functions are missing, always return an error, in order + * 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'; - if (parse_line(el, ptr) == -1) { - (void) fclose(fp); - return (-1); - } + + /* loop until first non-space char or EOL */ + while (*dptr != '\0' && Isspace(*dptr)) + dptr++; + if (*dptr == '#') + continue; /* ignore, this is a comment line */ + if ((error = parse_line(el, dptr)) == -1) + break; } + el_free(path); (void) fclose(fp); - return (0); + return error; } @@ -539,8 +589,8 @@ el_resize(EditLine *el) (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); } @@ -553,7 +603,7 @@ public void el_beep(EditLine *el) { - term_beep(el); + terminal_beep(el); } @@ -562,24 +612,25 @@ el_beep(EditLine *el) */ protected int /*ARGSUSED*/ -el_editmode(EditLine *el, int argc, const char **argv) +el_editmode(EditLine *el, int argc, const Char **argv) { - const char *how; + const Char *how; if (argv == NULL || argc != 2 || argv[1] == NULL) - return (-1); + 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; } diff --git a/cmd-line-utils/libedit/el.h b/cmd-line-utils/libedit/el.h index 05d88ad88ba..403a44aa806 100644 --- a/cmd-line-utils/libedit/el.h +++ b/cmd-line-utils/libedit/el.h @@ -1,4 +1,4 @@ -/* $NetBSD: el.h,v 1.17 2006/12/15 22:13:33 christos Exp $ */ +/* $NetBSD: el.h,v 1.25 2011/07/29 23:44:44 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -46,15 +46,21 @@ #define VIDEFAULT #define ANCHOR +#include "histedit.h" +#include "chartype.h" #include <stdio.h> #include <sys/types.h> -#define EL_BUFSIZ 1024 /* Maximum line size */ +#define EL_BUFSIZ ((size_t)4096) /* Maximum line size */ -#define HANDLE_SIGNALS 0x01 -#define NO_TTY 0x02 -#define EDIT_DISABLED 0x04 -#define UNBUFFERED 0x08 +#define HANDLE_SIGNALS 0x01 +#define NO_TTY 0x02 +#define EDIT_DISABLED 0x04 +#define UNBUFFERED 0x08 +#define CHARSET_IS_MULTIBYTE 0x10 +#define IGNORE_EXTCHARS 0x20 /* Ignore characters read > 0xff */ +#define NARROW_HISTORY 0x40 +#define NARROW_READ 0x80 typedef int bool_t; /* True or not */ @@ -66,10 +72,10 @@ typedef struct coord_t { /* Position on the screen */ } coord_t; typedef struct el_line_t { - char *buffer; /* Input line */ - char *cursor; /* Cursor position */ - char *lastchar; /* Last character */ - const char *limit; /* Max position */ + Char *buffer; /* Input line */ + Char *cursor; /* Cursor position */ + Char *lastchar; /* Last character */ + const Char *limit; /* Max position */ } el_line_t; /* @@ -82,21 +88,20 @@ typedef struct el_state_t { int metanext; /* Is the next char a meta char */ el_action_t lastcmd; /* Previous command */ el_action_t thiscmd; /* this command */ - char thisch; /* char that generated it */ + Char thisch; /* char that generated it */ } el_state_t; /* * Until we come up with something better... */ -#define el_strdup(a) strdup(a) #define el_malloc(a) malloc(a) #define el_realloc(a,b) realloc(a, b) #define el_free(a) free(a) #include "tty.h" #include "prompt.h" -#include "key.h" -#include "el_term.h" +#include "keymacro.h" +#include "el_terminal.h" #include "refresh.h" #include "chared.h" #include "common.h" @@ -109,33 +114,41 @@ typedef struct el_state_t { #include "read.h" struct editline { - char *el_prog; /* the program name */ + Char *el_prog; /* the program name */ FILE *el_infile; /* Stdio stuff */ FILE *el_outfile; /* Stdio stuff */ FILE *el_errfile; /* Stdio stuff */ int el_infd; /* Input file descriptor */ + int el_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 */ 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 **); /* XXXMYSQL: Bug#23097 mysql can't insert korean on mysql prompt. */ #define el_isprint(x) ((unsigned char) (x) < 0x80 ? isprint(x) : 1) diff --git a/cmd-line-utils/libedit/el_term.h b/cmd-line-utils/libedit/el_terminal.h index 0e7ddd555f4..807c651783e 100644 --- a/cmd-line-utils/libedit/el_term.h +++ b/cmd-line-utils/libedit/el_terminal.h @@ -1,4 +1,4 @@ -/* $NetBSD: term.h,v 1.19 2008/09/10 15:45:37 christos Exp $ */ +/* $NetBSD: terminal.h,v 1.3 2011/07/29 23:44:45 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -37,17 +37,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 +63,12 @@ typedef struct { #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 @@ -81,36 +81,36 @@ typedef struct { #define A_K_EN 5 #define A_K_NKEYS 6 -protected void term_move_to_line(EditLine *, int); -protected void term_move_to_char(EditLine *, int); -protected void term_clear_EOL(EditLine *, int); -protected void term_overwrite(EditLine *, const char *, int); -protected void term_insertwrite(EditLine *, char *, int); -protected void term_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) @@ -122,4 +122,4 @@ protected void term__flush(EditLine *); #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 */ diff --git a/cmd-line-utils/libedit/eln.c b/cmd-line-utils/libedit/eln.c new file mode 100644 index 00000000000..4b9f16c38f3 --- /dev/null +++ b/cmd-line-utils/libedit/eln.c @@ -0,0 +1,364 @@ +/* $NetBSD: eln.c,v 1.13 2011/08/16 16:25:15 christos Exp $ */ + +/*- + * Copyright (c) 2009 The NetBSD Foundation, Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#endif /* not lint && not SCCSID */ + +#include "histedit.h" +#include "el.h" +#include "read.h" +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> + +public int +el_getc(EditLine *el, char *cp) +{ + int num_read; + wchar_t wc = 0; + + num_read = el_wgetc (el, &wc); + + if (num_read > 0) + *cp = (char)wc; + return num_read; +} + + +public void +el_push(EditLine *el, const char *str) +{ + /* Using multibyte->wide string decoding works fine under single-byte + * character sets too, and Does The Right Thing. */ + el_wpush(el, ct_decode_string(str, &el->el_lgcyconv)); +} + + +public const char * +el_gets(EditLine *el, int *nread) +{ + const wchar_t *tmp; + + tmp = el_wgets(el, nread); + return ct_encode_string(tmp, &el->el_lgcyconv); +} + + +public int +el_parse(EditLine *el, int argc, const char *argv[]) +{ + int ret; + const wchar_t **wargv; + + wargv = (const wchar_t **) + ct_decode_argv(argc, argv, &el->el_lgcyconv); + if (!wargv) + return -1; + ret = el_wparse(el, argc, wargv); + ct_free_argv(wargv); + + return ret; +} + + +public int +el_set(EditLine *el, int op, ...) +{ + va_list ap; + int ret; + + if (!el) + return -1; + va_start(ap, op); + + switch (op) { + case EL_PROMPT: /* el_pfunc_t */ + case EL_RPROMPT: { + el_pfunc_t p = va_arg(ap, el_pfunc_t); + ret = prompt_set(el, p, 0, op, 0); + break; + } + + case EL_RESIZE: { + el_zfunc_t p = va_arg(ap, el_zfunc_t); + void *arg = va_arg(ap, void *); + ret = ch_resizefun(el, p, arg); + break; + } + + case EL_TERMINAL: /* const char * */ + ret = el_wset(el, op, va_arg(ap, char *)); + break; + + case EL_EDITOR: /* const wchar_t * */ + ret = el_wset(el, op, ct_decode_string(va_arg(ap, char *), + &el->el_lgcyconv)); + break; + + case EL_SIGNAL: /* int */ + case EL_EDITMODE: + case EL_UNBUFFERED: + case EL_PREP_TERM: + ret = el_wset(el, op, va_arg(ap, int)); + break; + + case EL_BIND: /* const char * list -> const wchar_t * list */ + case EL_TELLTC: + case EL_SETTC: + case EL_ECHOTC: + case EL_SETTY: { + const char *argv[20]; + int i; + const wchar_t **wargv; + for (i = 1; i < (int)__arraycount(argv); ++i) + if ((argv[i] = va_arg(ap, char *)) == NULL) + break; + argv[0] = NULL; + wargv = (const wchar_t **) + ct_decode_argv(i, argv, &el->el_lgcyconv); + if (!wargv) { + ret = -1; + goto out; + } + /* + * AFAIK we can't portably pass through our new wargv to + * el_wset(), so we have to reimplement the body of + * el_wset() for these ops. + */ + switch (op) { + case EL_BIND: + wargv[0] = STR("bind"); + ret = map_bind(el, i, wargv); + break; + case EL_TELLTC: + wargv[0] = STR("telltc"); + ret = terminal_telltc(el, i, wargv); + break; + case EL_SETTC: + wargv[0] = STR("settc"); + ret = terminal_settc(el, i, wargv); + break; + case EL_ECHOTC: + wargv[0] = STR("echotc"); + ret = terminal_echotc(el, i, wargv); + break; + case EL_SETTY: + wargv[0] = STR("setty"); + ret = tty_stty(el, i, wargv); + break; + default: + ret = -1; + } + ct_free_argv(wargv); + break; + } + + /* XXX: do we need to change el_func_t too? */ + case EL_ADDFN: { /* const char *, const char *, el_func_t */ + const char *args[2]; + el_func_t func; + wchar_t **wargv; + + args[0] = va_arg(ap, const char *); + args[1] = va_arg(ap, const char *); + func = va_arg(ap, el_func_t); + + wargv = ct_decode_argv(2, args, &el->el_lgcyconv); + if (!wargv) { + ret = -1; + goto out; + } + // XXX: The two strdup's leak + ret = map_addfunc(el, Strdup(wargv[0]), Strdup(wargv[1]), + func); + ct_free_argv(wargv); + break; + } + case EL_HIST: { /* hist_fun_t, const char * */ + hist_fun_t fun = va_arg(ap, hist_fun_t); + void *ptr = va_arg(ap, void *); + ret = hist_set(el, fun, ptr); + el->el_flags |= NARROW_HISTORY; + break; + } + /* XXX: do we need to change el_rfunc_t? */ + case EL_GETCFN: /* el_rfunc_t */ + ret = el_wset(el, op, va_arg(ap, el_rfunc_t)); + el->el_flags |= NARROW_READ; + break; + case EL_CLIENTDATA: /* void * */ + ret = el_wset(el, op, va_arg(ap, void *)); + break; + case EL_SETFP: { /* int, FILE * */ + int what = va_arg(ap, int); + FILE *fp = va_arg(ap, FILE *); + ret = el_wset(el, op, what, fp); + break; + } + case EL_PROMPT_ESC: /* el_pfunc_t, char */ + case EL_RPROMPT_ESC: { + el_pfunc_t p = va_arg(ap, el_pfunc_t); + char c = (char)va_arg(ap, int); + ret = prompt_set(el, p, c, op, 0); + break; + } + default: + ret = -1; + break; + } + +out: + va_end(ap); + return ret; +} + + +public int +el_get(EditLine *el, int op, ...) +{ + va_list ap; + int ret; + + if (!el) + return -1; + + va_start(ap, op); + + switch (op) { + case EL_PROMPT: /* el_pfunc_t * */ + case EL_RPROMPT: { + el_pfunc_t *p = va_arg(ap, el_pfunc_t *); + ret = prompt_get(el, p, 0, op); + break; + } + + case EL_PROMPT_ESC: /* el_pfunc_t *, char **/ + case EL_RPROMPT_ESC: { + el_pfunc_t *p = va_arg(ap, el_pfunc_t *); + char *c = va_arg(ap, char *); + wchar_t wc = 0; + ret = prompt_get(el, p, &wc, op); + *c = (char)wc; + break; + } + + case EL_EDITOR: { + const char **p = va_arg(ap, const char **); + const wchar_t *pw; + ret = el_wget(el, op, &pw); + *p = ct_encode_string(pw, &el->el_lgcyconv); + if (!el->el_lgcyconv.csize) + ret = -1; + break; + } + + case EL_TERMINAL: /* const char ** */ + ret = el_wget(el, op, va_arg(ap, const char **)); + break; + + case EL_SIGNAL: /* int * */ + case EL_EDITMODE: + case EL_UNBUFFERED: + case EL_PREP_TERM: + ret = el_wget(el, op, va_arg(ap, int *)); + break; + + case EL_GETTC: { + char *argv[20]; + static char gettc[] = "gettc"; + int i; + for (i = 1; i < (int)__arraycount(argv); ++i) + if ((argv[i] = va_arg(ap, char *)) == NULL) + break; + argv[0] = gettc; + ret = terminal_gettc(el, i, argv); + break; + } + + /* XXX: do we need to change el_rfunc_t? */ + case EL_GETCFN: /* el_rfunc_t */ + ret = el_wget(el, op, va_arg(ap, el_rfunc_t *)); + break; + + case EL_CLIENTDATA: /* void ** */ + ret = el_wget(el, op, va_arg(ap, void **)); + break; + + case EL_GETFP: { /* int, FILE ** */ + int what = va_arg(ap, int); + FILE **fpp = va_arg(ap, FILE **); + ret = el_wget(el, op, what, fpp); + break; + } + + default: + ret = -1; + break; + } + + va_end(ap); + return ret; +} + + +const LineInfo * +el_line(EditLine *el) +{ + const LineInfoW *winfo = el_wline(el); + LineInfo *info = &el->el_lgcylinfo; + size_t offset; + const Char *p; + + info->buffer = ct_encode_string(winfo->buffer, &el->el_lgcyconv); + + offset = 0; + for (p = winfo->buffer; p < winfo->cursor; p++) + offset += ct_enc_width(*p); + info->cursor = info->buffer + offset; + + offset = 0; + for (p = winfo->buffer; p < winfo->lastchar; p++) + offset += ct_enc_width(*p); + info->lastchar = info->buffer + offset; + + return info; +} + + +int +el_insertstr(EditLine *el, const char *str) +{ + return el_winsertstr(el, ct_decode_string(str, &el->el_lgcyconv)); +} diff --git a/cmd-line-utils/libedit/emacs.c b/cmd-line-utils/libedit/emacs.c index 135bd75f566..554d3970485 100644 --- a/cmd-line-utils/libedit/emacs.c +++ b/cmd-line-utils/libedit/emacs.c @@ -1,4 +1,4 @@ -/* $NetBSD: emacs.c,v 1.21 2006/03/06 21:11:56 christos Exp $ */ +/* $NetBSD: emacs.c,v 1.25 2011/07/29 15:16:33 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -51,22 +51,22 @@ static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93"; */ 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) { /* 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) @@ -76,7 +76,7 @@ em_delete_or_list(EditLine *el, int c) 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; } } @@ -87,12 +87,12 @@ em_delete_or_list(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -em_delete_next_word(EditLine *el, int c __attribute__((__unused__))) +em_delete_next_word(EditLine *el, Int c __attribute__((__unused__))) { - char *cp, *p, *kp; + Char *cp, *p, *kp; if (el->el_line.cursor == el->el_line.lastchar) - return (CC_ERROR); + return CC_ERROR; cp = c__next_word(el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, ce__isword); @@ -102,11 +102,11 @@ em_delete_next_word(EditLine *el, int c __attribute__((__unused__))) *kp++ = *p; el->el_chared.c_kill.last = kp; - c_delafter(el, cp - el->el_line.cursor); /* delete after dot */ + c_delafter(el, (int)(cp - el->el_line.cursor)); /* delete after dot */ if (el->el_line.cursor > el->el_line.lastchar) el->el_line.cursor = el->el_line.lastchar; /* bounds check */ - return (CC_REFRESH); + return CC_REFRESH; } @@ -116,23 +116,24 @@ em_delete_next_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_yank(EditLine *el, int c __attribute__((__unused__))) +em_yank(EditLine *el, Int c __attribute__((__unused__))) { - char *kp, *cp; + Char *kp, *cp; if (el->el_chared.c_kill.last == el->el_chared.c_kill.buf) - return (CC_NORM); + 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; @@ -141,7 +142,7 @@ em_yank(EditLine *el, int c __attribute__((__unused__))) if (el->el_state.argument == 1) el->el_line.cursor = cp; - return (CC_REFRESH); + return CC_REFRESH; } @@ -151,9 +152,9 @@ em_yank(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_kill_line(EditLine *el, int c __attribute__((__unused__))) +em_kill_line(EditLine *el, Int c __attribute__((__unused__))) { - char *kp, *cp; + Char *kp, *cp; cp = el->el_line.buffer; kp = el->el_chared.c_kill.buf; @@ -163,7 +164,7 @@ em_kill_line(EditLine *el, int c __attribute__((__unused__))) /* 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; } @@ -173,12 +174,12 @@ em_kill_line(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_kill_region(EditLine *el, int c __attribute__((__unused__))) +em_kill_region(EditLine *el, Int c __attribute__((__unused__))) { - char *kp, *cp; + Char *kp, *cp; if (!el->el_chared.c_kill.mark) - return (CC_ERROR); + return CC_ERROR; if (el->el_chared.c_kill.mark > el->el_line.cursor) { cp = el->el_line.cursor; @@ -186,17 +187,17 @@ em_kill_region(EditLine *el, int c __attribute__((__unused__))) while (cp < el->el_chared.c_kill.mark) *kp++ = *cp++; /* copy it */ el->el_chared.c_kill.last = kp; - c_delafter(el, cp - el->el_line.cursor); + c_delafter(el, (int)(cp - el->el_line.cursor)); } else { /* mark is before cursor */ cp = el->el_chared.c_kill.mark; kp = el->el_chared.c_kill.buf; while (cp < el->el_line.cursor) *kp++ = *cp++; /* copy it */ el->el_chared.c_kill.last = kp; - c_delbefore(el, cp - el->el_chared.c_kill.mark); + c_delbefore(el, (int)(cp - el->el_chared.c_kill.mark)); el->el_line.cursor = el->el_chared.c_kill.mark; } - return (CC_REFRESH); + return CC_REFRESH; } @@ -206,12 +207,12 @@ em_kill_region(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_copy_region(EditLine *el, int c __attribute__((__unused__))) +em_copy_region(EditLine *el, Int c __attribute__((__unused__))) { - char *kp, *cp; + Char *kp, *cp; if (!el->el_chared.c_kill.mark) - return (CC_ERROR); + return CC_ERROR; if (el->el_chared.c_kill.mark > el->el_line.cursor) { cp = el->el_line.cursor; @@ -226,7 +227,7 @@ em_copy_region(EditLine *el, int c __attribute__((__unused__))) *kp++ = *cp++; /* copy it */ el->el_chared.c_kill.last = kp; } - return (CC_NORM); + return CC_NORM; } @@ -235,7 +236,7 @@ em_copy_region(EditLine *el, int c __attribute__((__unused__))) * Gosling emacs transpose chars [^T] */ 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]) { @@ -243,9 +244,9 @@ em_gosmacs_transpose(EditLine *el, int c) 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; } @@ -255,10 +256,10 @@ em_gosmacs_transpose(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -em_next_word(EditLine *el, int c __attribute__((__unused__))) +em_next_word(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.lastchar) - return (CC_ERROR); + return CC_ERROR; el->el_line.cursor = c__next_word(el->el_line.cursor, el->el_line.lastchar, @@ -268,9 +269,9 @@ em_next_word(EditLine *el, int c __attribute__((__unused__))) if (el->el_map.type == MAP_VI) if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -280,21 +281,21 @@ em_next_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_upper_case(EditLine *el, int c __attribute__((__unused__))) +em_upper_case(EditLine *el, Int c __attribute__((__unused__))) { - char *cp, *ep; + Char *cp, *ep; ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, ce__isword); for (cp = el->el_line.cursor; cp < ep; cp++) - if (islower((unsigned char)*cp)) - *cp = toupper((unsigned char)*cp); + if (Islower(*cp)) + *cp = Toupper(*cp); el->el_line.cursor = ep; if (el->el_line.cursor > el->el_line.lastchar) el->el_line.cursor = el->el_line.lastchar; - return (CC_REFRESH); + return CC_REFRESH; } @@ -304,29 +305,29 @@ em_upper_case(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_capitol_case(EditLine *el, int c __attribute__((__unused__))) +em_capitol_case(EditLine *el, Int c __attribute__((__unused__))) { - char *cp, *ep; + Char *cp, *ep; ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, ce__isword); for (cp = el->el_line.cursor; cp < ep; cp++) { - if (isalpha((unsigned char)*cp)) { - if (islower((unsigned char)*cp)) - *cp = toupper((unsigned char)*cp); + if (Isalpha(*cp)) { + if (Islower(*cp)) + *cp = Toupper(*cp); cp++; break; } } for (; cp < ep; cp++) - if (isupper((unsigned char)*cp)) - *cp = tolower((unsigned char)*cp); + if (Isupper(*cp)) + *cp = Tolower(*cp); el->el_line.cursor = ep; if (el->el_line.cursor > el->el_line.lastchar) el->el_line.cursor = el->el_line.lastchar; - return (CC_REFRESH); + return CC_REFRESH; } @@ -336,21 +337,21 @@ em_capitol_case(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_lower_case(EditLine *el, int c __attribute__((__unused__))) +em_lower_case(EditLine *el, Int c __attribute__((__unused__))) { - char *cp, *ep; + Char *cp, *ep; ep = c__next_word(el->el_line.cursor, el->el_line.lastchar, el->el_state.argument, ce__isword); for (cp = el->el_line.cursor; cp < ep; cp++) - if (isupper((unsigned char)*cp)) - *cp = tolower((unsigned char)*cp); + if (Isupper(*cp)) + *cp = Tolower(*cp); el->el_line.cursor = ep; if (el->el_line.cursor > el->el_line.lastchar) el->el_line.cursor = el->el_line.lastchar; - return (CC_REFRESH); + return CC_REFRESH; } @@ -360,11 +361,11 @@ em_lower_case(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_set_mark(EditLine *el, int c __attribute__((__unused__))) +em_set_mark(EditLine *el, Int c __attribute__((__unused__))) { el->el_chared.c_kill.mark = el->el_line.cursor; - return (CC_NORM); + return CC_NORM; } @@ -374,14 +375,14 @@ em_set_mark(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_exchange_mark(EditLine *el, int c __attribute__((__unused__))) +em_exchange_mark(EditLine *el, Int c __attribute__((__unused__))) { - char *cp; + Char *cp; cp = el->el_line.cursor; el->el_line.cursor = el->el_chared.c_kill.mark; el->el_chared.c_kill.mark = cp; - return (CC_CURSOR); + return CC_CURSOR; } @@ -391,14 +392,14 @@ em_exchange_mark(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_universal_argument(EditLine *el, int c __attribute__((__unused__))) +em_universal_argument(EditLine *el, Int c __attribute__((__unused__))) { /* multiply current argument by 4 */ if (el->el_state.argument > 1000000) - return (CC_ERROR); + return CC_ERROR; el->el_state.doingarg = 1; el->el_state.argument *= 4; - return (CC_ARGHACK); + return CC_ARGHACK; } @@ -408,11 +409,11 @@ em_universal_argument(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_meta_next(EditLine *el, int c __attribute__((__unused__))) +em_meta_next(EditLine *el, Int c __attribute__((__unused__))) { el->el_state.metanext = 1; - return (CC_ARGHACK); + return CC_ARGHACK; } @@ -421,12 +422,12 @@ em_meta_next(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__))) +em_toggle_overwrite(EditLine *el, Int c __attribute__((__unused__))) { el->el_state.inputmode = (el->el_state.inputmode == MODE_INSERT) ? MODE_REPLACE : MODE_INSERT; - return (CC_NORM); + return CC_NORM; } @@ -435,25 +436,25 @@ em_toggle_overwrite(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_copy_prev_word(EditLine *el, int c __attribute__((__unused__))) +em_copy_prev_word(EditLine *el, Int c __attribute__((__unused__))) { - char *cp, *oldc, *dp; + Char *cp, *oldc, *dp; if (el->el_line.cursor == el->el_line.buffer) - return (CC_ERROR); + return CC_ERROR; oldc = el->el_line.cursor; /* does a bounds check */ cp = c__prev_word(el->el_line.cursor, el->el_line.buffer, el->el_state.argument, ce__isword); - 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; } @@ -462,11 +463,11 @@ em_copy_prev_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_inc_search_next(EditLine *el, int c __attribute__((__unused__))) +em_inc_search_next(EditLine *el, Int c __attribute__((__unused__))) { el->el_search.patlen = 0; - return (ce_inc_search(el, ED_SEARCH_NEXT_HISTORY)); + return ce_inc_search(el, ED_SEARCH_NEXT_HISTORY); } @@ -475,11 +476,11 @@ em_inc_search_next(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_inc_search_prev(EditLine *el, int c __attribute__((__unused__))) +em_inc_search_prev(EditLine *el, Int c __attribute__((__unused__))) { el->el_search.patlen = 0; - return (ce_inc_search(el, ED_SEARCH_PREV_HISTORY)); + return ce_inc_search(el, ED_SEARCH_PREV_HISTORY); } @@ -489,11 +490,11 @@ em_inc_search_prev(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -em_delete_prev_char(EditLine *el, int c __attribute__((__unused__))) +em_delete_prev_char(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor <= el->el_line.buffer) - return (CC_ERROR); + return CC_ERROR; if (el->el_state.doingarg) c_delbefore(el, el->el_state.argument); @@ -502,5 +503,5 @@ em_delete_prev_char(EditLine *el, int c __attribute__((__unused__))) el->el_line.cursor -= el->el_state.argument; if (el->el_line.cursor < el->el_line.buffer) el->el_line.cursor = el->el_line.buffer; - return (CC_REFRESH); + return CC_REFRESH; } diff --git a/cmd-line-utils/libedit/filecomplete.c b/cmd-line-utils/libedit/filecomplete.c index 05bd10e9f9e..b67b54510bf 100644 --- a/cmd-line-utils/libedit/filecomplete.c +++ b/cmd-line-utils/libedit/filecomplete.c @@ -1,4 +1,4 @@ -/* $NetBSD: filecomplete.c,v 1.13 2009/01/26 17:32:41 apb Exp $ */ +/* $NetBSD: filecomplete.c,v 1.31 2011/09/16 16:13:16 plunky Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -78,8 +78,8 @@ extern char *alloca (); #include "histedit.h" #include "filecomplete.h" -static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', - '>', '<', '=', ';', '|', '&', '{', '(', '\0' }; +static const Char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', + '$', '>', '<', '=', ';', '|', '&', '{', '(', '\0' }; /********************************/ @@ -95,12 +95,16 @@ static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', char * fn_tilde_expand(const char *txt) { +#if defined(HAVE_GETPW_R_POSIX) || defined(HAVE_GETPW_R_DRAFT) + struct passwd pwres; + char pwbuf[1024]; +#endif struct passwd *pass; char *temp; size_t len = 0; if (txt[0] != '~') - return (strdup(txt)); + return strdup(txt); temp = strchr(txt + 1, '/'); if (temp == NULL) { @@ -108,33 +112,49 @@ fn_tilde_expand(const char *txt) 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); temp[len - 2] = '\0'; } - /* XXXMYSQL: use non-_r functions for now */ if (temp[0] == 0) { +#ifdef HAVE_GETPW_R_POSIX + if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf), + &pass) != 0) + pass = NULL; +#elif HAVE_GETPW_R_DRAFT + pass = getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf)); +#else pass = getpwuid(getuid()); +#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 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; } @@ -160,23 +180,29 @@ fn_filename_completion_function(const char *text, int state) 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 */ - nptr = realloc(dirname, len + 1); + len = (size_t)(temp - text); /* including last slash */ + + nptr = el_realloc(dirname, (len + 1) * + sizeof(*nptr)); if (nptr == NULL) { - free(filename); + el_free(dirname); + dirname = NULL; return NULL; } dirname = nptr; (void)strncpy(dirname, text, len); dirname[len] = '\0'; } else { + el_free(filename); if (*text == 0) filename = NULL; else { @@ -184,6 +210,7 @@ fn_filename_completion_function(const char *text, int state) if (filename == NULL) return NULL; } + el_free(dirname); dirname = NULL; } @@ -193,12 +220,14 @@ fn_filename_completion_function(const char *text, int state) } /* support for ``~user'' syntax */ - free(dirpath); - if (dirname == NULL && (dirname = strdup("./")) == NULL) - return NULL; - - if (*dirname == '~') + el_free(dirpath); + dirpath = NULL; + if (dirname == NULL) { + if ((dirname = strdup("")) == NULL) + return NULL; + dirpath = strdup("./"); + } else if (*dirname == '~') dirpath = fn_tilde_expand(dirname); else dirpath = strdup(dirname); @@ -208,7 +237,7 @@ fn_filename_completion_function(const char *text, int state) 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; @@ -243,17 +272,18 @@ fn_filename_completion_function(const char *text, int state) 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; temp = NULL; } - return (temp); + return temp; } @@ -270,7 +300,7 @@ append_char_function(const char *name) rs = "/"; out: if (expname) - free(expname); + el_free(expname); return rs; } /* @@ -293,10 +323,10 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int)) 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; @@ -319,9 +349,9 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int)) 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); @@ -329,9 +359,9 @@ completion_matches(const char *text, char *(*genfunc)(const char *, int)) 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; } /* @@ -348,37 +378,47 @@ _fn_qsort_string_compare(const void *i1, const void *i2) /* * Display list of strings in columnar format on readline's output stream. - * '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, int len, int max) +fn_display_match_list (EditLine *el, char **matches, size_t num, size_t width) { - int 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; - - /* how many lines of output */ - count = len / limit; - if (count * limit < len) - count++; - - /* Sort the items if they are not already sorted. */ - qsort(&matches[1], (size_t)(len - 1), sizeof(char *), - _fn_qsort_string_compare); - - idx = 1; - for(; count > 0; count--) { - for(i = 0; i < limit && matches[idx]; i++, idx++) - (void)fprintf(el->el_outfile, "%-*s ", max, - matches[idx]); + cols = (size_t)screenwidth / (width + 1); + if (cols == 0) + cols = 1; + + /* how many lines of output, rounded up */ + lines = (num + cols - 1) / cols; + + /* Sort the items. */ + qsort(matches, num, sizeof(char *), _fn_qsort_string_compare); + + /* + * 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"); } } @@ -399,13 +439,14 @@ int fn_complete(EditLine *el, char *(*complet_func)(const char *, int), char **(*attempted_completion_function)(const char *, int, int), - const char *word_break, const char *special_prefixes, - const char *(*app_func)(const char *), int query_items, + const Char *word_break, const Char *special_prefixes, + const char *(*app_func)(const char *), size_t query_items, int *completion_type, int *over, int *point, int *end) { - const LineInfo *li; - char *temp, **matches; - const char *ctemp; + const TYPE(LineInfo) *li; + Char *temp; + char **matches; + const Char *ctemp; size_t len; int what_to_do = '\t'; int retval = CC_NORM; @@ -423,45 +464,47 @@ fn_complete(EditLine *el, app_func = append_char_function; /* We now look backwards for the start of a filename/variable word */ - li = el_line(el); - ctemp = (const char *) li->cursor; + li = FUN(el,line)(el); + ctemp = li->cursor; while (ctemp > li->buffer - && !strchr(word_break, ctemp[-1]) - && (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) ) + && !Strchr(word_break, ctemp[-1]) + && (!special_prefixes || !Strchr(special_prefixes, ctemp[-1]) ) ) ctemp--; - len = li->cursor - ctemp; + len = (size_t)(li->cursor - ctemp); #if defined(__SSP__) || defined(__SSP_ALL__) - temp = malloc(len + 1); + temp = el_malloc((len + 1) * sizeof(*temp)); #else - temp = alloca(len + 1); + temp = alloca((len + 1) * sizeof(*temp)); #endif - (void)strncpy(temp, ctemp, len); + (void)Strncpy(temp, ctemp, len); temp[len] = '\0'; /* these can be used by function called in completion_matches() */ /* or (*attempted_completion_function)() */ if (point != 0) - *point = li->cursor - li->buffer; + *point = (int)(li->cursor - li->buffer); if (end != NULL) - *end = li->lastchar - li->buffer; + *end = (int)(li->lastchar - li->buffer); if (attempted_completion_function) { - int cur_off = li->cursor - li->buffer; - matches = (*attempted_completion_function) (temp, - (int)(cur_off - len), cur_off); + int cur_off = (int)(li->cursor - li->buffer); + 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(temp, complet_func); + matches = completion_matches( + ct_encode_string(temp, &el->el_scratch), complet_func); if (over != NULL) *over = 0; if (matches) { int i; - int matches_num, maxlen, match_len, match_display=1; + size_t matches_num, maxlen, match_len, match_display=1; retval = CC_REFRESH; /* @@ -470,7 +513,8 @@ fn_complete(EditLine *el, */ if (matches[0][0] != '\0') { el_deletestr(el, (int) len); - el_insertstr(el, matches[0]); + FUN(el,insertstr)(el, + ct_decode_string(matches[0], &el->el_scratch)); } if (what_to_do == '?') @@ -482,7 +526,9 @@ fn_complete(EditLine *el, * 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: /* @@ -490,12 +536,13 @@ fn_complete(EditLine *el, * matches. */ - for(i=1, maxlen=0; matches[i]; i++) { + for(i = 1, maxlen = 0; matches[i]; i++) { match_len = strlen(matches[i]); if (match_len > maxlen) maxlen = match_len; } - 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"); @@ -506,7 +553,7 @@ fn_complete(EditLine *el, */ if (matches_num > query_items) { (void)fprintf(el->el_outfile, - "Display all %d possibilities? (y or n) ", + "Display all %zu possibilities? (y or n) ", matches_num); (void)fflush(el->el_outfile); if (getc(stdin) != 'y') @@ -514,9 +561,17 @@ fn_complete(EditLine *el, (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]) { /* @@ -534,12 +589,12 @@ fn_complete(EditLine *el, /* 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; } #if defined(__SSP__) || defined(__SSP_ALL__) - free(temp); + el_free(temp); #endif return retval; } @@ -552,6 +607,6 @@ unsigned char _el_fn_complete(EditLine *el, int ch __attribute__((__unused__))) { return (unsigned char)fn_complete(el, NULL, NULL, - break_chars, NULL, NULL, 100, + break_chars, NULL, NULL, (size_t)100, NULL, NULL, NULL, NULL); } diff --git a/cmd-line-utils/libedit/filecomplete.h b/cmd-line-utils/libedit/filecomplete.h index 12e0c6f14b0..971e6e05939 100644 --- a/cmd-line-utils/libedit/filecomplete.h +++ b/cmd-line-utils/libedit/filecomplete.h @@ -1,4 +1,4 @@ -/* $NetBSD: filecomplete.h,v 1.6 2008/04/29 06:53:01 martin Exp $ */ +/* $NetBSD: filecomplete.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -34,10 +34,10 @@ int fn_complete(EditLine *, char *(*)(const char *, int), char **(*)(const char *, int, int), - const char *, const char *, const char *(*)(const char *), int, + const Char *, const Char *, const char *(*)(const char *), size_t, int *, int *, int *, int *); -void fn_display_match_list(EditLine *, char **, int, int); +void fn_display_match_list(EditLine *, char **, size_t, size_t); char *fn_tilde_expand(const char *); char *fn_filename_completion_function(const char *, int); diff --git a/cmd-line-utils/libedit/hist.c b/cmd-line-utils/libedit/hist.c index c0b23ee6641..d24f5e7ff53 100644 --- a/cmd-line-utils/libedit/hist.c +++ b/cmd-line-utils/libedit/hist.c @@ -1,4 +1,4 @@ -/* $NetBSD: hist.c,v 1.15 2003/11/01 23:36:39 christos Exp $ */ +/* $NetBSD: hist.c,v 1.20 2011/07/29 15:16:33 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -55,12 +55,12 @@ hist_init(EditLine *el) el->el_history.fun = NULL; el->el_history.ref = NULL; - el->el_history.buf = (char *) el_malloc(EL_BUFSIZ); + el->el_history.buf = el_malloc(EL_BUFSIZ * sizeof(*el->el_history.buf)); el->el_history.sz = EL_BUFSIZ; if (el->el_history.buf == NULL) - return (-1); + return -1; el->el_history.last = el->el_history.buf; - return (0); + return 0; } @@ -71,7 +71,7 @@ protected void hist_end(EditLine *el) { - el_free((ptr_t) el->el_history.buf); + el_free(el->el_history.buf); el->el_history.buf = NULL; } @@ -80,12 +80,12 @@ hist_end(EditLine *el) * 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; } @@ -96,11 +96,11 @@ hist_set(EditLine *el, hist_fun_t fun, ptr_t ptr) protected el_action_t hist_get(EditLine *el) { - const char *hp; + const Char *hp; int h; if (el->el_history.eventno == 0) { /* if really the current line */ - (void) strncpy(el->el_line.buffer, el->el_history.buf, + (void) Strncpy(el->el_line.buffer, el->el_history.buf, el->el_history.sz); el->el_line.lastchar = el->el_line.buffer + (el->el_history.last - el->el_history.buf); @@ -112,24 +112,25 @@ hist_get(EditLine *el) #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') @@ -144,7 +145,7 @@ hist_get(EditLine *el) #endif /* KSHVI */ el->el_line.cursor = el->el_line.lastchar; - return (CC_REFRESH); + return CC_REFRESH; } @@ -152,34 +153,34 @@ hist_get(EditLine *el) * process a history command */ 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; } @@ -192,13 +193,13 @@ protected int /*ARGSUSED*/ hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz) { - char *newbuf; + Char *newbuf; - newbuf = realloc(el->el_history.buf, newsz); + newbuf = el_realloc(el->el_history.buf, newsz * sizeof(*newbuf)); if (!newbuf) return 0; - (void) memset(&newbuf[oldsz], '\0', newsz - oldsz); + (void) memset(&newbuf[oldsz], '\0', (newsz - oldsz) * sizeof(*newbuf)); el->el_history.last = newbuf + (el->el_history.last - el->el_history.buf); @@ -207,3 +208,15 @@ hist_enlargebuf(EditLine *el, size_t oldsz, size_t newsz) 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 diff --git a/cmd-line-utils/libedit/hist.h b/cmd-line-utils/libedit/hist.h index 46e14634adf..a63be499dbd 100644 --- a/cmd-line-utils/libedit/hist.h +++ b/cmd-line-utils/libedit/hist.h @@ -1,4 +1,4 @@ -/* $NetBSD: hist.h,v 1.10 2003/08/07 16:44:31 agc Exp $ */ +/* $NetBSD: hist.h,v 1.13 2011/07/28 20:50:55 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,21 +42,29 @@ #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) @@ -69,8 +77,11 @@ typedef struct el_history_t { 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 */ diff --git a/cmd-line-utils/libedit/histedit.h b/cmd-line-utils/libedit/histedit.h index 37823141c06..523d27b0be2 100644 --- a/cmd-line-utils/libedit/histedit.h +++ b/cmd-line-utils/libedit/histedit.h @@ -1,4 +1,4 @@ -/* $NetBSD: histedit.h,v 1.35 2009/02/05 19:15:44 christos Exp $ */ +/* $NetBSD: histedit.h,v 1.48 2011/07/28 20:50:55 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -43,6 +43,13 @@ #define LIBEDIT_MAJOR 2 #define LIBEDIT_MINOR 11 +/* XXXMYSQL : stdint.h might not be available on older Solaris platforms. */ +#if defined(__sun) || defined(__sun__) +#include <sys/inttypes.h> +#else +#include <stdint.h> +#endif + #include <sys/types.h> #include <stdio.h> @@ -114,29 +121,46 @@ unsigned char _el_fn_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_REFRESH 20 /* , void); */ +#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 */ +#define EL_RESIZE 23 /* , el_zfunc_t, void *); set */ #define EL_BUILTIN_GETCFN (NULL) @@ -188,12 +212,12 @@ int history(History *, HistEvent *, int, ...); #define H_NEXT 6 /* , void); */ #define H_CURR 8 /* , const int); */ #define H_SET 7 /* , int); */ -#define H_ADD 9 /* , const char *); */ -#define H_ENTER 10 /* , const char *); */ -#define H_APPEND 11 /* , const char *); */ +#define H_ADD 9 /* , const wchar_t *); */ +#define H_ENTER 10 /* , const wchar_t *); */ +#define H_APPEND 11 /* , const wchar_t *); */ #define H_END 12 /* , void); */ -#define H_NEXT_STR 13 /* , const char *); */ -#define H_PREV_STR 14 /* , const char *); */ +#define H_NEXT_STR 13 /* , const wchar_t *); */ +#define H_PREV_STR 14 /* , const wchar_t *); */ #define H_NEXT_EVENT 15 /* , const int); */ #define H_PREV_EVENT 16 /* , const int); */ #define H_LOAD 17 /* , const char *); */ @@ -202,6 +226,10 @@ int history(History *, HistEvent *, int, ...); #define H_SETUNIQUE 20 /* , int); */ #define H_GETUNIQUE 21 /* , void); */ #define H_DEL 22 /* , int); */ +#define H_NEXT_EVDATA 23 /* , const int, histdata_t *); */ +#define H_DELDATA 24 /* , int, histdata_t *);*/ +#define H_REPLACE 25 /* , const char *, histdata_t); */ + /* @@ -221,6 +249,65 @@ int tok_line(Tokenizer *, const LineInfo *, int tok_str(Tokenizer *, const char *, int *, const char ***); +/* + * Begin Wide Character Support + */ + +/* + * Wide character versions + */ + +/* + * ==== Editing ==== + */ +typedef struct lineinfow { + const wchar_t *buffer; + const wchar_t *cursor; + const wchar_t *lastchar; +} LineInfoW; + +const wchar_t *el_wgets(EditLine *, int *); +int el_wgetc(EditLine *, wchar_t *); +void el_wpush(EditLine *, const wchar_t *); + +int el_wparse(EditLine *, int, const wchar_t **); + +int el_wset(EditLine *, int, ...); +int el_wget(EditLine *, int, ...); + +const LineInfoW *el_wline(EditLine *); +int el_winsertstr(EditLine *, const wchar_t *); +#define el_wdeletestr el_deletestr + +/* + * ==== History ==== + */ +typedef struct histeventW { + int num; + const wchar_t *str; +} HistEventW; + +typedef struct historyW HistoryW; + +HistoryW * history_winit(void); +void history_wend(HistoryW *); + +int history_w(HistoryW *, HistEventW *, int, ...); + +/* + * ==== Tokenization ==== + */ +typedef struct tokenizerW TokenizerW; + +/* Wide character tokenizer support */ +TokenizerW *tok_winit(const wchar_t *); +void tok_wend(TokenizerW *); +void tok_wreset(TokenizerW *); +int tok_wline(TokenizerW *, const LineInfoW *, + int *, const wchar_t ***, int *, int *); +int tok_wstr(TokenizerW *, const wchar_t *, + int *, const wchar_t ***); + #ifdef __cplusplus } #endif diff --git a/cmd-line-utils/libedit/history.c b/cmd-line-utils/libedit/history.c index 3080dd231f6..6d2176c258b 100644 --- a/cmd-line-utils/libedit/history.c +++ b/cmd-line-utils/libedit/history.c @@ -1,4 +1,4 @@ -/* $NetBSD: history.c,v 1.33 2009/02/06 14:40:32 sketch Exp $ */ +/* $NetBSD: history.c,v 1.45 2011/07/29 23:44:44 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -41,7 +41,7 @@ static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ /* - * hist.c: History access functions + * hist.c: TYPE(History) access functions */ #include <string.h> #include <stdlib.h> @@ -56,14 +56,15 @@ static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; 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 */ @@ -88,29 +89,29 @@ struct history { #define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str) #define HDEL(h, ev, n) (*(h)->h_del)((h)->h_ref, ev, n) -#define h_strdup(a) strdup(a) +#define h_strdup(a) Strdup(a) #define h_malloc(a) malloc(a) #define h_realloc(a, b) realloc((a), (b)) #define h_free(a) free(a) typedef struct { int num; - char *str; + Char *str; } HistEventPrivate; -private int history_setsize(History *, HistEvent *, int); -private int history_getsize(History *, HistEvent *); -private int history_setunique(History *, HistEvent *, int); -private int history_getunique(History *, HistEvent *); -private int history_set_fun(History *, History *); -private int history_load(History *, const char *); -private int history_save(History *, const char *); -private int history_prev_event(History *, HistEvent *, int); -private int history_next_event(History *, HistEvent *, int); -private int history_next_string(History *, HistEvent *, const char *); -private int history_prev_string(History *, HistEvent *, const char *); +private int history_setsize(TYPE(History) *, TYPE(HistEvent) *, int); +private int history_getsize(TYPE(History) *, TYPE(HistEvent) *); +private int history_setunique(TYPE(History) *, TYPE(HistEvent) *, int); +private int history_getunique(TYPE(History) *, TYPE(HistEvent) *); +private int history_set_fun(TYPE(History) *, TYPE(History) *); +private int history_load(TYPE(History) *, const char *); +private int history_save(TYPE(History) *, const char *); +private int history_prev_event(TYPE(History) *, TYPE(HistEvent) *, int); +private int history_next_event(TYPE(History) *, TYPE(HistEvent) *, int); +private int history_next_string(TYPE(History) *, TYPE(HistEvent) *, const Char *); +private int history_prev_string(TYPE(History) *, TYPE(HistEvent) *, const Char *); /***********************************************************************/ @@ -119,7 +120,8 @@ private int history_prev_string(History *, HistEvent *, const char *); * Builtin- history implementation */ typedef struct hentry_t { - HistEvent ev; /* What we return */ + TYPE(HistEvent) ev; /* What we return */ + void *data; /* data */ struct hentry_t *next; /* Next entry */ struct hentry_t *prev; /* Previous entry */ } hentry_t; @@ -130,24 +132,27 @@ typedef struct history_t { int max; /* Maximum number of events */ int cur; /* Current number of events */ int eventid; /* For generation of unique event id */ - int flags; /* History flags */ + int flags; /* TYPE(History) flags */ #define H_UNIQUE 1 /* Store only unique elements */ } history_t; -private int history_def_next(ptr_t, HistEvent *); -private int history_def_first(ptr_t, HistEvent *); -private int history_def_prev(ptr_t, HistEvent *); -private int history_def_last(ptr_t, HistEvent *); -private int history_def_curr(ptr_t, HistEvent *); -private int history_def_set(ptr_t, HistEvent *, const int); -private void history_def_clear(ptr_t, HistEvent *); -private int history_def_enter(ptr_t, HistEvent *, const char *); -private int history_def_add(ptr_t, HistEvent *, const char *); -private int history_def_del(ptr_t, HistEvent *, const int); - -private int history_def_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_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(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 *, 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 +170,23 @@ private void history_def_delete(history_t *, HistEvent *, hentry_t *); } /* error messages */ -static const char *const he_errlist[] = { - "OK", - "unknown error", - "malloc() failed", - "first event not found", - "last event not found", - "empty list", - "no next event", - "no previous event", - "current event is invalid", - "event not found", - "can't read history from file", - "can't write history", - "required parameter(s) not supplied", - "history size negative", - "function not allowed with other history-functions-set the default", - "bad parameters" +static const Char *const he_errlist[] = { + STR("OK"), + STR("unknown error"), + STR("malloc() failed"), + STR("first event not found"), + STR("last event not found"), + STR("empty list"), + STR("no next event"), + STR("no previous event"), + STR("current event is invalid"), + STR("event not found"), + STR("can't read history from file"), + STR("can't write history"), + STR("required parameter(s) not supplied"), + STR("history size negative"), + STR("function not allowed with other history-functions-set the default"), + STR("bad parameters") }; /* error codes */ #define _HE_OK 0 @@ -205,7 +210,7 @@ static const char *const he_errlist[] = { * Default function to return the first event in the history. */ private int -history_def_first(ptr_t p, HistEvent *ev) +history_def_first(void *p, TYPE(HistEvent) *ev) { history_t *h = (history_t *) p; @@ -214,10 +219,10 @@ history_def_first(ptr_t p, HistEvent *ev) *ev = h->cursor->ev; else { he_seterrev(ev, _HE_FIRST_NOTFOUND); - return (-1); + return -1; } - return (0); + return 0; } @@ -225,7 +230,7 @@ history_def_first(ptr_t p, HistEvent *ev) * Default function to return the last event in the history. */ private int -history_def_last(ptr_t p, HistEvent *ev) +history_def_last(void *p, TYPE(HistEvent) *ev) { history_t *h = (history_t *) p; @@ -234,10 +239,10 @@ history_def_last(ptr_t p, HistEvent *ev) *ev = h->cursor->ev; else { he_seterrev(ev, _HE_LAST_NOTFOUND); - return (-1); + return -1; } - return (0); + return 0; } @@ -245,24 +250,24 @@ history_def_last(ptr_t p, HistEvent *ev) * Default function to return the next event in the history. */ private int -history_def_next(ptr_t p, HistEvent *ev) +history_def_next(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,25 +275,25 @@ history_def_next(ptr_t p, HistEvent *ev) * Default function to return the previous event in the history. */ private int -history_def_prev(ptr_t p, HistEvent *ev) +history_def_prev(void *p, TYPE(HistEvent) *ev) { history_t *h = (history_t *) p; 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 +301,7 @@ history_def_prev(ptr_t p, HistEvent *ev) * Default function to return the current event in the history. */ private int -history_def_curr(ptr_t p, HistEvent *ev) +history_def_curr(void *p, TYPE(HistEvent) *ev) { history_t *h = (history_t *) p; @@ -305,10 +310,10 @@ history_def_curr(ptr_t p, HistEvent *ev) else { he_seterrev(ev, (h->cur > 0) ? _HE_CURR_INVALID : _HE_EMPTY_LIST); - return (-1); + return -1; } - return (0); + return 0; } @@ -317,13 +322,13 @@ history_def_curr(ptr_t p, HistEvent *ev) * given one. */ private int -history_def_set(ptr_t p, HistEvent *ev, const int n) +history_def_set(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 +338,34 @@ history_def_set(ptr_t p, HistEvent *ev, const int n) } if (h->cursor == &h->list) { he_seterrev(ev, _HE_NOT_FOUND); - return (-1); + return -1; } - return (0); + return 0; +} + + +/* history_set_nth(): + * Default function to set the current event in the history to the + * n-th one. + */ +private int +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; + } + for (h->cursor = h->list.prev; h->cursor != &h->list; + h->cursor = h->cursor->prev) + if (n-- <= 0) + break; + if (h->cursor == &h->list) { + he_seterrev(ev, _HE_NOT_FOUND); + return -1; + } + return 0; } @@ -343,27 +373,46 @@ history_def_set(ptr_t p, HistEvent *ev, const int n) * 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, TYPE(HistEvent) *ev, + int num, void **data) +{ + if (history_set_nth(h, ev, num) != 0) + return -1; + /* magic value to skip delete (just set to n-th history) */ + if (data == (void **)-1) + return 0; + ev->str = Strdup(h->cursor->ev.str); + ev->num = h->cursor->ev.num; + if (data) + *data = h->cursor->data; + history_def_delete(h, ev, h->cursor); + return 0; } @@ -372,16 +421,16 @@ history_def_add(ptr_t p, HistEvent *ev, const char *str) */ /* ARGSUSED */ private int -history_def_del(ptr_t p, HistEvent *ev __attribute__((__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; } @@ -391,16 +440,19 @@ history_def_del(ptr_t p, HistEvent *ev __attribute__((__unused__)), /* ARGSUSED */ private void history_def_delete(history_t *h, - HistEvent *ev __attribute__((__unused__)), hentry_t *hp) + TYPE(HistEvent) *ev __attribute__((__unused__)), hentry_t *hp) { HistEventPrivate *evp = (void *)&hp->ev; if (hp == &h->list) abort(); - if (h->cursor == hp) + if (h->cursor == hp) { h->cursor = hp->prev; + if (h->cursor == &h->list) + h->cursor = hp->next; + } hp->prev->next = hp->next; hp->next->prev = hp->prev; - h_free((ptr_t) evp->str); + h_free(evp->str); h_free(hp); h->cur--; } @@ -410,28 +462,31 @@ history_def_delete(history_t *h, * Insert element with string str in the h list */ private int -history_def_insert(history_t *h, HistEvent *ev, const char *str) +history_def_insert(history_t *h, TYPE(HistEvent) *ev, const Char *str) { + 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->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; } @@ -439,16 +494,16 @@ oomem: * 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. @@ -457,7 +512,7 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str) while (h->cur > h->max && h->cur > 0) history_def_delete(h, ev, h->list.prev); - return (1); + return 1; } @@ -466,9 +521,9 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str) */ /* ARGSUSED */ private int -history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n) +history_def_init(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; @@ -482,7 +537,7 @@ history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n) h->list.ev.num = 0; h->cursor = &h->list; h->flags = 0; - *p = (ptr_t) h; + *p = h; return 0; } @@ -491,12 +546,13 @@ history_def_init(ptr_t *p, HistEvent *ev __attribute__((__unused__)), int n) * Default history cleanup function */ private void -history_def_clear(ptr_t p, HistEvent *ev) +history_def_clear(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; } @@ -509,16 +565,16 @@ history_def_clear(ptr_t p, HistEvent *ev) /* history_init(): * Initialization function. */ -public History * -history_init(void) +public TYPE(History) * +FUN(history,init)(void) { - HistEvent ev; - History *h = (History *) h_malloc(sizeof(History)); + TYPE(HistEvent) ev; + TYPE(History) *h = (TYPE(History) *) h_malloc(sizeof(*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; @@ -533,7 +589,7 @@ history_init(void) h->h_add = history_def_add; h->h_del = history_def_del; - return (h); + return h; } @@ -541,9 +597,9 @@ history_init(void) * clean up history; */ public void -history_end(History *h) +FUN(history,end)(TYPE(History) *h) { - HistEvent ev; + TYPE(HistEvent) ev; if (h->h_next == history_def_next) history_def_clear(h->h_ref, &ev); @@ -557,19 +613,19 @@ history_end(History *h) * Set history number of events */ private int -history_setsize(History *h, HistEvent *ev, int num) +history_setsize(TYPE(History) *h, TYPE(HistEvent) *ev, int num) { if (h->h_next != history_def_next) { 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; } @@ -577,18 +633,18 @@ history_setsize(History *h, HistEvent *ev, int num) * Get number of events currently in history */ private int -history_getsize(History *h, HistEvent *ev) +history_getsize(TYPE(History) *h, TYPE(HistEvent) *ev) { if (h->h_next != history_def_next) { he_seterrev(ev, _HE_NOT_ALLOWED); - 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; } @@ -596,15 +652,15 @@ history_getsize(History *h, HistEvent *ev) * Set if adjacent equal events should not be entered in history. */ private int -history_setunique(History *h, HistEvent *ev, int uni) +history_setunique(TYPE(History) *h, TYPE(HistEvent) *ev, int uni) { if (h->h_next != history_def_next) { he_seterrev(ev, _HE_NOT_ALLOWED); - return (-1); + return -1; } history_def_setunique(h->h_ref, uni); - return (0); + return 0; } @@ -612,14 +668,14 @@ history_setunique(History *h, HistEvent *ev, int uni) * Get if adjacent equal events should not be entered in history. */ private int -history_getunique(History *h, HistEvent *ev) +history_getunique(TYPE(History) *h, TYPE(HistEvent) *ev) { if (h->h_next != history_def_next) { he_seterrev(ev, _HE_NOT_ALLOWED); - return (-1); + return -1; } ev->num = history_def_getunique(h->h_ref); - return (0); + return 0; } @@ -627,9 +683,9 @@ history_getunique(History *h, HistEvent *ev) * Set history functions */ private int -history_set_fun(History *h, History *nh) +history_set_fun(TYPE(History) *h, TYPE(History) *nh) { - HistEvent ev; + TYPE(HistEvent) ev; if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL || nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == NULL || @@ -648,7 +704,7 @@ history_set_fun(History *h, History *nh) 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); @@ -665,25 +721,28 @@ history_set_fun(History *h, History *nh) 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; 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; @@ -691,7 +750,7 @@ history_load(History *h, const char *fname) 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++) { @@ -704,8 +763,8 @@ history_load(History *h, const char *fname) 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; @@ -714,63 +773,68 @@ history_load(History *h, const char *fname) } (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; } 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; } @@ -778,16 +842,33 @@ done: * 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(TYPE(History) *h, TYPE(HistEvent) *ev, int num, void **d) +{ + int retval; + + for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) + if (ev->num == num) { + if (d) + *d = ((history_t *)h->h_ref)->cursor->data; + return 0; + } + + he_seterrev(ev, _HE_NOT_FOUND); + return -1; } @@ -795,16 +876,16 @@ history_prev_event(History *h, HistEvent *ev, int num) * 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; } @@ -812,17 +893,17 @@ history_next_event(History *h, HistEvent *ev, int num) * Find the previous event beginning with string */ private int -history_prev_string(History *h, HistEvent *ev, const char *str) +history_prev_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str) { - size_t len = strlen(str); + size_t len = Strlen(str); int retval; for (retval = HCURR(h, ev); retval != -1; retval = HNEXT(h, ev)) - if (strncmp(str, ev->str, len) == 0) - return (0); + if (Strncmp(str, ev->str, len) == 0) + return 0; he_seterrev(ev, _HE_NOT_FOUND); - return (-1); + return -1; } @@ -830,17 +911,17 @@ history_prev_string(History *h, HistEvent *ev, const char *str) * Find the next event beginning with string */ private int -history_next_string(History *h, HistEvent *ev, const char *str) +history_next_string(TYPE(History) *h, TYPE(HistEvent) *ev, const Char *str) { - size_t len = strlen(str); + size_t len = Strlen(str); int retval; for (retval = HCURR(h, ev); retval != -1; retval = HPREV(h, ev)) - if (strncmp(str, ev->str, len) == 0) - return (0); + if (Strncmp(str, ev->str, len) == 0) + return 0; he_seterrev(ev, _HE_NOT_FOUND); - return (-1); + return -1; } @@ -848,10 +929,10 @@ history_next_string(History *h, HistEvent *ev, const char *str) * User interface to history functions. */ int -history(History *h, HistEvent *ev, int fun, ...) +FUNW(history)(TYPE(History) *h, TYPE(HistEvent) *ev, int fun, ...) { va_list va; - const char *str; + const Char *str; int retval; va_start(va, fun); @@ -876,7 +957,7 @@ history(History *h, HistEvent *ev, int fun, ...) break; case H_ADD: - str = va_arg(va, const char *); + str = va_arg(va, const Char *); retval = HADD(h, ev, str); break; @@ -885,13 +966,13 @@ history(History *h, HistEvent *ev, int fun, ...) break; case H_ENTER: - str = va_arg(va, const char *); + str = va_arg(va, const Char *); if ((retval = HENTER(h, ev, str)) != -1) h->h_ent = ev->num; break; case H_APPEND: - str = va_arg(va, const char *); + str = va_arg(va, const Char *); if ((retval = HSET(h, ev, h->h_ent)) != -1) retval = HADD(h, ev, str); break; @@ -946,18 +1027,18 @@ history(History *h, HistEvent *ev, int fun, ...) break; case H_PREV_STR: - retval = history_prev_string(h, ev, va_arg(va, const char *)); + retval = history_prev_string(h, ev, va_arg(va, const Char *)); break; case H_NEXT_STR: - retval = history_next_string(h, ev, va_arg(va, const char *)); + retval = history_next_string(h, ev, va_arg(va, const Char *)); break; case H_FUNC: { - History hf; + TYPE(History) hf; - hf.h_ref = va_arg(va, ptr_t); + 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); @@ -976,15 +1057,46 @@ history(History *h, HistEvent *ev, int fun, ...) } case H_END: - history_end(h); + FUN(history,end)(h); retval = 0; break; + case H_NEXT_EVDATA: + { + int num = va_arg(va, int); + void **d = va_arg(va, void **); + retval = history_next_evdata(h, ev, num, d); + break; + } + + case H_DELDATA: + { + int num = va_arg(va, int); + void **d = va_arg(va, void **); + retval = history_deldata_nth((history_t *)h->h_ref, ev, num, d); + break; + } + + case H_REPLACE: /* only use after H_NEXT_EVDATA */ + { + const Char *line = va_arg(va, const Char *); + void *d = va_arg(va, void *); + const Char *s; + if(!line || !(s = Strdup(line))) { + retval = -1; + break; + } + ((history_t *)h->h_ref)->cursor->ev.str = s; + ((history_t *)h->h_ref)->cursor->data = d; + retval = 0; + break; + } + default: retval = -1; he_seterrev(ev, _HE_UNKNOWN); break; } va_end(va); - return (retval); + return retval; } diff --git a/cmd-line-utils/libedit/historyn.c b/cmd-line-utils/libedit/historyn.c new file mode 100644 index 00000000000..99871ea2075 --- /dev/null +++ b/cmd-line-utils/libedit/historyn.c @@ -0,0 +1,5 @@ +#define NARROW_WRAPPER +#include "config.h" +#undef WIDECHAR +#define NARROWCHAR +#include "./history.c" diff --git a/cmd-line-utils/libedit/key.c b/cmd-line-utils/libedit/keymacro.c index cda02816861..8df60e85d6c 100644 --- a/cmd-line-utils/libedit/key.c +++ b/cmd-line-utils/libedit/keymacro.c @@ -1,4 +1,4 @@ -/* $NetBSD: key.c,v 1.19 2006/03/23 20:22:51 christos Exp $ */ +/* $NetBSD: keymacro.c,v 1.7 2011/08/16 16:25:15 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -41,20 +41,21 @@ static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93"; #endif /* not lint && not SCCSID */ /* - * 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). * * 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: * ------------- @@ -67,102 +68,104 @@ static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93"; #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 *, - int); -private int node_enum(EditLine *, key_node_t *, int); +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). @@ -170,98 +173,101 @@ key_reset(EditLine *el) * 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; } @@ -271,34 +277,34 @@ key_print(EditLine *el, const char *key) * found. May read in more characters. */ private int -node_trav(EditLine *el, key_node_t *ptr, char *ch, key_value_t *val) +node_trav(EditLine *el, keymacro_node_t *ptr, Char *ch, keymacro_value_t *val) { if (ptr->ch == *ch) { /* match found */ if (ptr->next) { /* key not complete so get next char */ - if (el_getc(el, ch) != 1) { /* if EOF or error */ + if (FUN(el,getc)(el, ch) != 1) {/* if EOF or error */ val->cmd = ED_END_OF_FILE; - return (XK_CMD); + 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; } } } @@ -308,11 +314,12 @@ node_trav(EditLine *el, key_node_t *ptr, char *ch, key_value_t *val) * Find a node that matches *str or allocate a new one */ 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) @@ -335,7 +342,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int case XK_STR: case XK_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", @@ -349,7 +356,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int break; case XK_STR: case XK_EXE: - if ((ptr->val.str = el_strdup(val->str)) == NULL) + if ((ptr->val.str = Strdup(val->str)) == NULL) return -1; break; default: @@ -362,7 +369,7 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int ptr->next = node__get(*str); /* setup new node */ (void) node__try(el, ptr->next, str, val, ntype); } - return (0); + return 0; } @@ -370,21 +377,21 @@ node__try(EditLine *el, key_node_t *ptr, const char *str, key_value_t *val, int * Delete node that matches str */ 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; } @@ -396,20 +403,20 @@ node__delete(EditLine *el, key_node_t **inptr, const char *str) 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 prev_ptr->sibling = ptr->sibling; ptr->sibling = NULL; node__put(el, ptr); - return (1); + return 1; } else { - return (0); + return 0; } } @@ -418,7 +425,7 @@ node__delete(EditLine *el, key_node_t **inptr, const char *str) * Puts a tree of nodes onto free list using free(3). */ private void -node__put(EditLine *el, key_node_t *ptr) +node__put(EditLine *el, keymacro_node_t *ptr) { if (ptr == NULL) return; @@ -436,25 +443,25 @@ node__put(EditLine *el, key_node_t *ptr) 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; @@ -462,17 +469,17 @@ node__get(int ch) 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(): @@ -480,37 +487,40 @@ node__free(key_node_t *k) * Print if last node */ private int -node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt) +node_lookup(EditLine *el, const Char *str, keymacro_node_t *ptr, size_t cnt) { - int 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, 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 { @@ -519,7 +529,7 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt) return (node_lookup(el, str, ptr->sibling, cnt)); else - return (-1); + return -1; } } } @@ -529,68 +539,76 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt) * Traverse the node printing the characters it is bound in buffer */ private int -node_enum(EditLine *el, key_node_t *ptr, int cnt) +node_enum(EditLine *el, keymacro_node_t *ptr, size_t cnt) { - int ncnt; + ssize_t used; if (cnt >= KEY_BUFSIZ - 5) { /* buffer too small */ - 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 (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, 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]; static const char fmt[] = "%-15s-> %s\n"; + mbstate_t state; + memset(&state, 0, sizeof(mbstate_t)); if (val != NULL) 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) { + memset(&state, 0, sizeof(mbstate_t)); + wcsrtombs(unparsbuf, (const wchar_t **) &fp->name, + sizeof(unparsbuf), &state); + unparsbuf[sizeof(unparsbuf) -1] = '\0'; (void) fprintf(el->el_outfile, fmt, - key, fp->name); + ct_encode_string(key, &el->el_scratch), unparsbuf); break; } #ifdef DEBUG_KEY @@ -605,7 +623,8 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype) break; } else - (void) fprintf(el->el_outfile, fmt, key, "no input"); + (void) fprintf(el->el_outfile, fmt, ct_encode_string(key, + &el->el_scratch), "no input"); } @@ -614,53 +633,17 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype) *b++ = c; \ else \ b++ -/* key__decode_char(): - * Put a printable form of char in buf. - */ -protected int -key__decode_char(char *buf, int cnt, int off, int ch) -{ - char *sb = buf + off; - char *eb = buf + cnt; - char *b = sb; - if (ch == 0) { - ADDC('^'); - ADDC('@'); - return b - sb; - } - if (iscntrl(ch)) { - ADDC('^'); - if (ch == '\177') - ADDC('?'); - else - ADDC(ch | 0100); - } else if (ch == '^') { - ADDC('\\'); - ADDC('^'); - } else if (ch == '\\') { - ADDC('\\'); - ADDC('\\'); - } else if (ch == ' ' || (el_isprint(ch) && !isspace(ch))) { - ADDC(ch); - } else { - ADDC('\\'); - ADDC((((unsigned int) ch >> 6) & 7) + '0'); - ADDC((((unsigned int) ch >> 3) & 7) + '0'); - ADDC((ch & 7) + '0'); - } - return b - sb; -} - - -/* key__decode_str(): +/* keymacro__decode_str(): * Make a printable version of the ey */ -protected int -key__decode_str(const char *str, char *buf, int len, const char *sep) +protected size_t +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; + mbstate_t state; + memset(&state, 0, sizeof(mbstate_t)); b = buf; if (sep[0] != '\0') { ADDC(sep[0]); @@ -668,38 +651,27 @@ key__decode_str(const char *str, char *buf, int len, const char *sep) if (*str == '\0') { ADDC('^'); ADDC('@'); - if (sep[0] != '\0' && sep[1] != '\0') { - ADDC(sep[1]); - } - goto done; + goto add_endsep; } for (p = str; *p != 0; p++) { - if (iscntrl((unsigned char) *p)) { - ADDC('^'); - if (*p == '\177') { - ADDC('?'); - } else { - ADDC(*p | 0100); - } - } else if (*p == '^' || *p == '\\') { - ADDC('\\'); - ADDC(*p); - } else if (*p == ' ' || (el_isprint((unsigned char) *p) && - !isspace((unsigned char) *p))) { - ADDC(*p); - } else { - ADDC('\\'); - ADDC((((unsigned int) *p >> 6) & 7) + '0'); - ADDC((((unsigned int) *p >> 3) & 7) + '0'); - ADDC((*p & 7) + '0'); + 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++, + &state); + if (n == -1) /* ran out of space */ + goto add_endsep; + else + b += n; } } +add_endsep: if (sep[0] != '\0' && sep[1] != '\0') { ADDC(sep[1]); } -done: ADDC('\0'); - if (b - buf >= len) + if ((size_t)(b - buf) >= len) buf[len - 1] = '\0'; - return b - buf; + return (size_t)(b - buf); } diff --git a/cmd-line-utils/libedit/key.h b/cmd-line-utils/libedit/keymacro.h index 9c6844e6d99..2445de5a5bc 100644 --- a/cmd-line-utils/libedit/key.h +++ b/cmd-line-utils/libedit/keymacro.h @@ -1,4 +1,4 @@ -/* $NetBSD: key.h,v 1.10 2006/03/23 20:22:51 christos Exp $ */ +/* $NetBSD: keymacro.h,v 1.2 2011/07/28 03:44:36 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -35,47 +35,42 @@ */ /* - * 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 #define XK_NOD 2 #define XK_EXE 3 -#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 int key__decode_str(const char *, char *, int, +protected size_t keymacro__decode_str(const Char *, char *, size_t, const char *); -protected int key__decode_char(char *, int, int, int); -#endif /* _h_el_key */ +#endif /* _h_el_keymacro */ diff --git a/cmd-line-utils/libedit/makelist.sh b/cmd-line-utils/libedit/makelist.sh index 5d25b4776c9..b1a28c32370 100644 --- a/cmd-line-utils/libedit/makelist.sh +++ b/cmd-line-utils/libedit/makelist.sh @@ -1,5 +1,5 @@ #!/bin/sh - -# $NetBSD: makelist,v 1.11 2005/10/22 16:45:03 christos Exp $ +# $NetBSD: makelist,v 1.16 2010/04/18 21:17:05 christos Exp $ # # Copyright (c) 1992, 1993 # The Regents of the University of California. All rights reserved. @@ -36,7 +36,7 @@ # makelist.sh: Automatically generate header files... AWK=@AWK@ -USAGE="Usage: $0 -h|-e|-fc|-fh|-bc|-bh|-m <filenames>" +USAGE="Usage: $0 -n|-h|-e|-fc|-fh|-bc|-bh|-m <filenames>" if [ "x$1" = "x" ] then @@ -53,6 +53,14 @@ case $FLAG in # generate foo.h file from foo.c # +-n) + cat << _EOF +#undef WIDECHAR +#define NARROWCHAR +#include "${FILES}" +_EOF + ;; + -h) set - `echo $FILES | sed -e 's/\\./_/g'` hdr="_h_`basename $1`" @@ -70,7 +78,7 @@ case $FLAG in # XXX: need a space between name and prototype so that -fc and -fh # parsing is much easier # - printf("protected el_action_t\t%s (EditLine *, int);\n", name); + printf("protected el_action_t\t%s (EditLine *, Int);\n", name); } } END { @@ -85,6 +93,7 @@ case $FLAG in BEGIN { printf("/* Automatically generated file, do not edit */\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_"; @@ -106,18 +115,18 @@ case $FLAG in fname = fname s; } - printf(" { %-30.30s %-30.30s\n","\"" fname "\",", uname ","); + printf(" { %-30.30s %-30.30s\n","STR(\"" fname "\"),", uname ","); ok = 1; } } /^ \*/ { if (ok) { - printf(" \""); + printf(" STR(\""); for (i = 2; i < NF; i++) printf("%s ", $i); - # XXXMYSQL: support CRLF + # XXXMYSQL: support CRLF sub("\r", "", $i); - printf("%s\" },\n", $i); + printf("%s\") },\n", $i); ok = 0; } } @@ -157,7 +166,7 @@ case $FLAG in END { printf("#define\t%-30.30s\t%3d\n", "EL_NUM_FCNS", count); - printf("typedef el_action_t (*el_func_t)(EditLine *, int);"); + printf("typedef el_action_t (*el_func_t)(EditLine *, Int);"); printf("\nprotected const el_func_t* func__get(void);\n"); printf("#endif /* _h_fcns_c */\n"); }' diff --git a/cmd-line-utils/libedit/map.c b/cmd-line-utils/libedit/map.c index 693b56c82ba..17b07391b69 100644 --- a/cmd-line-utils/libedit/map.c +++ b/cmd-line-utils/libedit/map.c @@ -1,4 +1,4 @@ -/* $NetBSD: map.c,v 1.24 2006/04/09 01:36:51 christos Exp $ */ +/* $NetBSD: map.c,v 1.30 2011/08/16 16:25:15 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -46,10 +46,8 @@ static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93"; #include <stdlib.h> #include "el.h" -#define N_KEYS 256 - -private void map_print_key(EditLine *, el_action_t *, const char *); -private void map_print_some_keys(EditLine *, el_action_t *, int, int); +private void map_print_key(EditLine *, el_action_t *, const Char *); +private void map_print_some_keys(EditLine *, el_action_t *, Int, Int); private void map_print_all_keys(EditLine *); private void map_init_nls(EditLine *); private void map_init_meta(EditLine *); @@ -904,26 +902,25 @@ map_init(EditLine *el) 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 @@ -931,7 +928,7 @@ map_init(EditLine *el) #else map_init_emacs(el); #endif /* VIDEFAULT */ - return (0); + return 0; } @@ -942,16 +939,16 @@ protected void 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; } @@ -967,7 +964,7 @@ map_init_nls(EditLine *el) el_action_t *map = el->el_map.key; for (i = 0200; i <= 0377; i++) - if (el_isprint(i)) + if (Isprint(i)) map[i] = ED_INSERT; } @@ -978,7 +975,7 @@ map_init_nls(EditLine *el) private void map_init_meta(EditLine *el) { - char buf[3]; + Char buf[3]; int i; el_action_t *map = el->el_map.key; el_action_t *alt = el->el_map.alt; @@ -996,7 +993,7 @@ map_init_meta(EditLine *el) } else map = alt; } - buf[0] = (char) i; + buf[0] = (Char) i; buf[2] = 0; for (i = 0200; i <= 0377; i++) switch (map[i]) { @@ -1006,7 +1003,7 @@ map_init_meta(EditLine *el) 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; @@ -1028,7 +1025,7 @@ map_init_vi(EditLine *el) 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]; @@ -1039,7 +1036,7 @@ map_init_vi(EditLine *el) map_init_nls(el); tty_bind_char(el, 1); - term_bind_arrow(el); + terminal_bind_arrow(el); } @@ -1050,14 +1047,14 @@ protected void map_init_emacs(EditLine *el) { int i; - char buf[3]; + Char buf[3]; el_action_t *key = el->el_map.key; el_action_t *alt = el->el_map.alt; const el_action_t *emacs = el->el_map.emacs; 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]; @@ -1070,10 +1067,10 @@ map_init_emacs(EditLine *el) buf[0] = CONTROL('X'); buf[1] = CONTROL('X'); buf[2] = 0; - key_add(el, buf, key_map_cmd(el, EM_EXCHANGE_MARK), XK_CMD); + 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); } @@ -1081,18 +1078,18 @@ map_init_emacs(EditLine *el) * Set the editor */ protected int -map_set_editor(EditLine *el, char *editor) +map_set_editor(EditLine *el, Char *editor) { - if (strcmp(editor, "emacs") == 0) { + if (Strcmp(editor, STR("emacs")) == 0) { map_init_emacs(el); - return (0); + 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; } @@ -1100,20 +1097,20 @@ map_set_editor(EditLine *el, char *editor) * Retrieve the editor */ protected int -map_get_editor(EditLine *el, const char **editor) +map_get_editor(EditLine *el, const Char **editor) { if (editor == NULL) - return (-1); + 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; } @@ -1121,22 +1118,22 @@ map_get_editor(EditLine *el, const char **editor) * Print the function description for 1 key */ private void -map_print_key(EditLine *el, el_action_t *map, const char *in) +map_print_key(EditLine *el, el_action_t *map, const Char *in) { char outbuf[EL_BUFSIZ]; el_bindings_t *bp, *ep; 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); } @@ -1144,10 +1141,10 @@ map_print_key(EditLine *el, el_action_t *map, const char *in) * Print keys from first to last */ private void -map_print_some_keys(EditLine *el, el_action_t *map, int first, int last) +map_print_some_keys(EditLine *el, el_action_t *map, Int first, Int last) { el_bindings_t *bp, *ep; - char firstbuf[2], lastbuf[2]; + Char firstbuf[2], lastbuf[2]; char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ]; firstbuf[0] = first; @@ -1156,7 +1153,7 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last) 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); @@ -1167,17 +1164,17 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last) for (bp = el->el_map.help; bp < ep; bp++) { 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; @@ -1185,14 +1182,14 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last) } #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); (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); @@ -1233,9 +1230,9 @@ map_print_all_keys(EditLine *el) map_print_some_keys(el, el->el_map.alt, prev, i - 1); (void) fprintf(el->el_outfile, "Multi-character bindings\n"); - key_print(el, ""); + keymacro_print(el, STR("")); (void) fprintf(el->el_outfile, "Arrow key bindings\n"); - term_print_arrow(el, ""); + terminal_print_arrow(el, STR("")); } @@ -1243,21 +1240,21 @@ map_print_all_keys(EditLine *el) * Add/remove/change bindings */ protected int -map_bind(EditLine *el, int argc, const char **argv) +map_bind(EditLine *el, int argc, const Char **argv) { el_action_t *map; int ntype, rem; - const char *p; - char inbuf[EL_BUFSIZ]; - char outbuf[EL_BUFSIZ]; - const char *in = NULL; - char *out = NULL; + const Char *p; + Char inbuf[EL_BUFSIZ]; + Char outbuf[EL_BUFSIZ]; + const Char *in = NULL; + Char *out = NULL; el_bindings_t *bp, *ep; int cmd; int key; if (argv == NULL) - return (-1); + return -1; map = el->el_map.key; ntype = XK_CMD; @@ -1287,63 +1284,63 @@ map_bind(EditLine *el, int argc, const char **argv) 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", - argv[0], p[1]); + "" FSTR ": Invalid switch `%c'.\n", + argv[0], (int) p[1]); } else break; 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 @@ -1352,31 +1349,32 @@ map_bind(EditLine *el, int argc, const char **argv) case XK_EXE: if ((out = parse__string(outbuf, argv[argc])) == NULL) { (void) fprintf(el->el_errfile, - "%s: Invalid \\ or ^ in outstring.\n", argv[0]); - 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; 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_str(el, out), ntype); + terminal_set_arrow(el, in, keymacro_map_str(el, out), 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; @@ -1385,7 +1383,7 @@ map_bind(EditLine *el, int argc, const char **argv) EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype)); break; } - return (0); + return 0; } @@ -1393,29 +1391,30 @@ map_bind(EditLine *el, int argc, const char **argv) * add a user defined function */ protected int -map_addfunc(EditLine *el, const char *name, const char *help, el_func_t func) +map_addfunc(EditLine *el, const Char *name, const Char *help, el_func_t func) { void *p; - int nf = el->el_map.nfunc + 1; + 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; } diff --git a/cmd-line-utils/libedit/map.h b/cmd-line-utils/libedit/map.h index 3b08f48be7a..8e0c7e4eaa1 100644 --- a/cmd-line-utils/libedit/map.h +++ b/cmd-line-utils/libedit/map.h @@ -1,4 +1,4 @@ -/* $NetBSD: map.h,v 1.8 2003/08/07 16:44:32 agc Exp $ */ +/* $NetBSD: map.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -41,9 +41,9 @@ #define _h_el_map typedef struct el_bindings_t { /* for the "bind" shell command */ - const char *name; /* function name for bind command */ + const Char *name; /* function name for bind command */ int func; /* function numeric value */ - const char *description; /* description of function */ + const Char *description; /* description of function */ } el_bindings_t; @@ -63,13 +63,15 @@ typedef struct el_map_t { #define MAP_EMACS 0 #define MAP_VI 1 -protected int map_bind(EditLine *, int, const char **); +#define N_KEYS 256 + +protected int map_bind(EditLine *, int, const Char **); protected int map_init(EditLine *); protected void map_end(EditLine *); protected void map_init_vi(EditLine *); protected void map_init_emacs(EditLine *); -protected int map_set_editor(EditLine *, char *); -protected int map_get_editor(EditLine *, const char **); -protected int map_addfunc(EditLine *, const char *, const char *, el_func_t); +protected int map_set_editor(EditLine *, Char *); +protected int map_get_editor(EditLine *, const Char **); +protected int map_addfunc(EditLine *, const Char *, const Char *, el_func_t); #endif /* _h_el_map */ diff --git a/cmd-line-utils/libedit/np/strlcpy.c b/cmd-line-utils/libedit/np/strlcpy.c index 092a9757c0f..ccbe6812dfc 100644 --- a/cmd-line-utils/libedit/np/strlcpy.c +++ b/cmd-line-utils/libedit/np/strlcpy.c @@ -23,6 +23,7 @@ #else #include "config.h" #endif + #if defined(LIBC_SCCS) && !defined(lint) #endif /* LIBC_SCCS and not lint */ diff --git a/cmd-line-utils/libedit/np/unvis.c b/cmd-line-utils/libedit/np/unvis.c index 3c37c231ceb..812d280b2d8 100644 --- a/cmd-line-utils/libedit/np/unvis.c +++ b/cmd-line-utils/libedit/np/unvis.c @@ -1,4 +1,4 @@ -/* $NetBSD: unvis.c,v 1.28 2005/09/13 01:44:09 christos Exp $ */ +/* $NetBSD: unvis.c,v 1.36 2011/03/18 09:07:20 martin Exp $ */ /*- * Copyright (c) 1989, 1993 @@ -38,19 +38,33 @@ static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; #endif #endif /* LIBC_SCCS and not lint */ +/* XXXMYSQL : Make compiler happy. */ +#ifdef _LIBC +#include "namespace.h" +#endif + #include <sys/types.h> #include <assert.h> #include <ctype.h> -#include <stdio.h> -#ifdef HAVE_VIS_H -#include <vis.h> + +/* XXXMYSQL : stdint.h might not be available on older Solaris platforms. */ +#if defined(__sun) || defined(__sun__) +#include <sys/inttypes.h> #else -#include "np/vis.h" +#include <stdint.h> #endif +#include <stdio.h> +#include <errno.h> +/* + XXXMYSQL : Due to different versions of vis.h available, + use the one bundled with libedit. +*/ +#include "np/vis.h" + #ifdef __weak_alias -__weak_alias(strunvis,_strunvis) +__weak_alias(strnunvisx,_strnunvisx) #endif #if !HAVE_VIS @@ -64,143 +78,276 @@ __weak_alias(strunvis,_strunvis) #define S_CTRL 4 /* control char started (^) */ #define S_OCTAL2 5 /* octal digit 2 */ #define S_OCTAL3 6 /* octal digit 3 */ -#define S_HEX1 7 /* hex digit */ -#define S_HEX2 8 /* hex digit 2 */ +#define S_HEX1 7 /* http hex digit */ +#define S_HEX2 8 /* http hex digit 2 */ +#define S_MIME1 9 /* mime hex digit 1 */ +#define S_MIME2 10 /* mime hex digit 2 */ +#define S_EATCRNL 11 /* mime eating CRNL */ +#define S_AMP 12 /* seen & */ +#define S_NUMBER 13 /* collecting number */ +#define S_STRING 14 /* collecting string */ #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') #define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) +#define XTOD(c) (isdigit(c) ? (c - '0') : ((c - 'A') + 10)) + +/* + * RFC 1866 + */ +static const struct nv { + const char *name; + uint8_t value; +} nv[] = { + { "AElig", 198 }, /* capital AE diphthong (ligature) */ + { "Aacute", 193 }, /* capital A, acute accent */ + { "Acirc", 194 }, /* capital A, circumflex accent */ + { "Agrave", 192 }, /* capital A, grave accent */ + { "Aring", 197 }, /* capital A, ring */ + { "Atilde", 195 }, /* capital A, tilde */ + { "Auml", 196 }, /* capital A, dieresis or umlaut mark */ + { "Ccedil", 199 }, /* capital C, cedilla */ + { "ETH", 208 }, /* capital Eth, Icelandic */ + { "Eacute", 201 }, /* capital E, acute accent */ + { "Ecirc", 202 }, /* capital E, circumflex accent */ + { "Egrave", 200 }, /* capital E, grave accent */ + { "Euml", 203 }, /* capital E, dieresis or umlaut mark */ + { "Iacute", 205 }, /* capital I, acute accent */ + { "Icirc", 206 }, /* capital I, circumflex accent */ + { "Igrave", 204 }, /* capital I, grave accent */ + { "Iuml", 207 }, /* capital I, dieresis or umlaut mark */ + { "Ntilde", 209 }, /* capital N, tilde */ + { "Oacute", 211 }, /* capital O, acute accent */ + { "Ocirc", 212 }, /* capital O, circumflex accent */ + { "Ograve", 210 }, /* capital O, grave accent */ + { "Oslash", 216 }, /* capital O, slash */ + { "Otilde", 213 }, /* capital O, tilde */ + { "Ouml", 214 }, /* capital O, dieresis or umlaut mark */ + { "THORN", 222 }, /* capital THORN, Icelandic */ + { "Uacute", 218 }, /* capital U, acute accent */ + { "Ucirc", 219 }, /* capital U, circumflex accent */ + { "Ugrave", 217 }, /* capital U, grave accent */ + { "Uuml", 220 }, /* capital U, dieresis or umlaut mark */ + { "Yacute", 221 }, /* capital Y, acute accent */ + { "aacute", 225 }, /* small a, acute accent */ + { "acirc", 226 }, /* small a, circumflex accent */ + { "acute", 180 }, /* acute accent */ + { "aelig", 230 }, /* small ae diphthong (ligature) */ + { "agrave", 224 }, /* small a, grave accent */ + { "amp", 38 }, /* ampersand */ + { "aring", 229 }, /* small a, ring */ + { "atilde", 227 }, /* small a, tilde */ + { "auml", 228 }, /* small a, dieresis or umlaut mark */ + { "brvbar", 166 }, /* broken (vertical) bar */ + { "ccedil", 231 }, /* small c, cedilla */ + { "cedil", 184 }, /* cedilla */ + { "cent", 162 }, /* cent sign */ + { "copy", 169 }, /* copyright sign */ + { "curren", 164 }, /* general currency sign */ + { "deg", 176 }, /* degree sign */ + { "divide", 247 }, /* divide sign */ + { "eacute", 233 }, /* small e, acute accent */ + { "ecirc", 234 }, /* small e, circumflex accent */ + { "egrave", 232 }, /* small e, grave accent */ + { "eth", 240 }, /* small eth, Icelandic */ + { "euml", 235 }, /* small e, dieresis or umlaut mark */ + { "frac12", 189 }, /* fraction one-half */ + { "frac14", 188 }, /* fraction one-quarter */ + { "frac34", 190 }, /* fraction three-quarters */ + { "gt", 62 }, /* greater than */ + { "iacute", 237 }, /* small i, acute accent */ + { "icirc", 238 }, /* small i, circumflex accent */ + { "iexcl", 161 }, /* inverted exclamation mark */ + { "igrave", 236 }, /* small i, grave accent */ + { "iquest", 191 }, /* inverted question mark */ + { "iuml", 239 }, /* small i, dieresis or umlaut mark */ + { "laquo", 171 }, /* angle quotation mark, left */ + { "lt", 60 }, /* less than */ + { "macr", 175 }, /* macron */ + { "micro", 181 }, /* micro sign */ + { "middot", 183 }, /* middle dot */ + { "nbsp", 160 }, /* no-break space */ + { "not", 172 }, /* not sign */ + { "ntilde", 241 }, /* small n, tilde */ + { "oacute", 243 }, /* small o, acute accent */ + { "ocirc", 244 }, /* small o, circumflex accent */ + { "ograve", 242 }, /* small o, grave accent */ + { "ordf", 170 }, /* ordinal indicator, feminine */ + { "ordm", 186 }, /* ordinal indicator, masculine */ + { "oslash", 248 }, /* small o, slash */ + { "otilde", 245 }, /* small o, tilde */ + { "ouml", 246 }, /* small o, dieresis or umlaut mark */ + { "para", 182 }, /* pilcrow (paragraph sign) */ + { "plusmn", 177 }, /* plus-or-minus sign */ + { "pound", 163 }, /* pound sterling sign */ + { "quot", 34 }, /* double quote */ + { "raquo", 187 }, /* angle quotation mark, right */ + { "reg", 174 }, /* registered sign */ + { "sect", 167 }, /* section sign */ + { "shy", 173 }, /* soft hyphen */ + { "sup1", 185 }, /* superscript one */ + { "sup2", 178 }, /* superscript two */ + { "sup3", 179 }, /* superscript three */ + { "szlig", 223 }, /* small sharp s, German (sz ligature) */ + { "thorn", 254 }, /* small thorn, Icelandic */ + { "times", 215 }, /* multiply sign */ + { "uacute", 250 }, /* small u, acute accent */ + { "ucirc", 251 }, /* small u, circumflex accent */ + { "ugrave", 249 }, /* small u, grave accent */ + { "uml", 168 }, /* umlaut (dieresis) */ + { "uuml", 252 }, /* small u, dieresis or umlaut mark */ + { "yacute", 253 }, /* small y, acute accent */ + { "yen", 165 }, /* yen sign */ + { "yuml", 255 }, /* small y, dieresis or umlaut mark */ +}; /* * unvis - decode characters previously encoded by vis */ int -unvis(cp, c, astate, flag) - char *cp; - int c; - int *astate, flag; +unvis(char *cp, int c, int *astate, int flag) { unsigned char uc = (unsigned char)c; + unsigned char st, ia, is, lc; + +/* + * Bottom 8 bits of astate hold the state machine state. + * Top 8 bits hold the current character in the http 1866 nv string decoding + */ +#define GS(a) ((a) & 0xff) +#define SS(a, b) (((uint32_t)(a) << 24) | (b)) +#define GI(a) ((uint32_t)(a) >> 24) _DIAGASSERT(cp != NULL); _DIAGASSERT(astate != NULL); + st = GS(*astate); if (flag & UNVIS_END) { - if (*astate == S_OCTAL2 || *astate == S_OCTAL3 - || *astate == S_HEX2) { - *astate = S_GROUND; - return (UNVIS_VALID); + switch (st) { + case S_OCTAL2: + case S_OCTAL3: + case S_HEX2: + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + case S_GROUND: + return UNVIS_NOCHAR; + default: + return UNVIS_SYNBAD; } - return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); } - switch (*astate) { + switch (st) { case S_GROUND: *cp = 0; - if (c == '\\') { - *astate = S_START; - return (0); + if ((flag & VIS_NOESCAPE) == 0 && c == '\\') { + *astate = SS(0, S_START); + return UNVIS_NOCHAR; + } + if ((flag & VIS_HTTP1808) && c == '%') { + *astate = SS(0, S_HEX1); + return UNVIS_NOCHAR; + } + if ((flag & VIS_HTTP1866) && c == '&') { + *astate = SS(0, S_AMP); + return UNVIS_NOCHAR; } - if ((flag & VIS_HTTPSTYLE) && c == '%') { - *astate = S_HEX1; - return (0); + if ((flag & VIS_MIMESTYLE) && c == '=') { + *astate = SS(0, S_MIME1); + return UNVIS_NOCHAR; } *cp = c; - return (UNVIS_VALID); + return UNVIS_VALID; case S_START: switch(c) { case '\\': *cp = c; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': *cp = (c - '0'); - *astate = S_OCTAL2; - return (0); + *astate = SS(0, S_OCTAL2); + return UNVIS_NOCHAR; case 'M': *cp = (char)0200; - *astate = S_META; - return (0); + *astate = SS(0, S_META); + return UNVIS_NOCHAR; case '^': - *astate = S_CTRL; - return (0); + *astate = SS(0, S_CTRL); + return UNVIS_NOCHAR; case 'n': *cp = '\n'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 'r': *cp = '\r'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 'b': *cp = '\b'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 'a': *cp = '\007'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 'v': *cp = '\v'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 't': *cp = '\t'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 'f': *cp = '\f'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 's': *cp = ' '; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case 'E': *cp = '\033'; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case '\n': /* * hidden newline */ - *astate = S_GROUND; - return (UNVIS_NOCHAR); + *astate = SS(0, S_GROUND); + return UNVIS_NOCHAR; case '$': /* * hidden marker */ - *astate = S_GROUND; - return (UNVIS_NOCHAR); + *astate = SS(0, S_GROUND); + return UNVIS_NOCHAR; } - *astate = S_GROUND; - return (UNVIS_SYNBAD); + goto bad; case S_META: if (c == '-') - *astate = S_META1; + *astate = SS(0, S_META1); else if (c == '^') - *astate = S_CTRL; - else { - *astate = S_GROUND; - return (UNVIS_SYNBAD); - } - return (0); + *astate = SS(0, S_CTRL); + else + goto bad; + return UNVIS_NOCHAR; case S_META1: - *astate = S_GROUND; + *astate = SS(0, S_GROUND); *cp |= c; - return (UNVIS_VALID); + return UNVIS_VALID; case S_CTRL: if (c == '?') *cp |= 0177; else *cp |= c & 037; - *astate = S_GROUND; - return (UNVIS_VALID); + *astate = SS(0, S_GROUND); + return UNVIS_VALID; case S_OCTAL2: /* second possible octal digit */ if (isoctal(uc)) { @@ -208,102 +355,206 @@ unvis(cp, c, astate, flag) * yes - and maybe a third */ *cp = (*cp << 3) + (c - '0'); - *astate = S_OCTAL3; - return (0); + *astate = SS(0, S_OCTAL3); + return UNVIS_NOCHAR; } /* * no - done with current sequence, push back passed char */ - *astate = S_GROUND; - return (UNVIS_VALIDPUSH); + *astate = SS(0, S_GROUND); + return UNVIS_VALIDPUSH; case S_OCTAL3: /* third possible octal digit */ - *astate = S_GROUND; + *astate = SS(0, S_GROUND); if (isoctal(uc)) { *cp = (*cp << 3) + (c - '0'); - return (UNVIS_VALID); + return UNVIS_VALID; } /* * we were done, push back passed char */ - return (UNVIS_VALIDPUSH); + return UNVIS_VALIDPUSH; case S_HEX1: if (isxdigit(uc)) { *cp = xtod(uc); - *astate = S_HEX2; - return (0); + *astate = SS(0, S_HEX2); + return UNVIS_NOCHAR; } /* * no - done with current sequence, push back passed char */ - *astate = S_GROUND; - return (UNVIS_VALIDPUSH); + *astate = SS(0, S_GROUND); + return UNVIS_VALIDPUSH; case S_HEX2: *astate = S_GROUND; if (isxdigit(uc)) { *cp = xtod(uc) | (*cp << 4); - return (UNVIS_VALID); + return UNVIS_VALID; + } + return UNVIS_VALIDPUSH; + + case S_MIME1: + if (uc == '\n' || uc == '\r') { + *astate = SS(0, S_EATCRNL); + return UNVIS_NOCHAR; + } + if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) { + *cp = XTOD(uc); + *astate = SS(0, S_MIME2); + return UNVIS_NOCHAR; } - return (UNVIS_VALIDPUSH); + goto bad; + + case S_MIME2: + if (isxdigit(uc) && (isdigit(uc) || isupper(uc))) { + *astate = SS(0, S_GROUND); + *cp = XTOD(uc) | (*cp << 4); + return UNVIS_VALID; + } + goto bad; + + case S_EATCRNL: + switch (uc) { + case '\r': + case '\n': + return UNVIS_NOCHAR; + case '=': + *astate = SS(0, S_MIME1); + return UNVIS_NOCHAR; + default: + *cp = uc; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + } + + case S_AMP: + *cp = 0; + if (uc == '#') { + *astate = SS(0, S_NUMBER); + return UNVIS_NOCHAR; + } + *astate = SS(0, S_STRING); + /*FALLTHROUGH*/ + + case S_STRING: + ia = *cp; /* index in the array */ + is = GI(*astate); /* index in the string */ + lc = is == 0 ? 0 : nv[ia].name[is - 1]; /* last character */ + + if (uc == ';') + uc = '\0'; + + for (; ia < __arraycount(nv); ia++) { + if (is != 0 && nv[ia].name[is - 1] != lc) + goto bad; + if (nv[ia].name[is] == uc) + break; + } + + if (ia == __arraycount(nv)) + goto bad; + + if (uc != 0) { + *cp = ia; + *astate = SS(is + 1, S_STRING); + return UNVIS_NOCHAR; + } + + *cp = nv[ia].value; + *astate = SS(0, S_GROUND); + return UNVIS_VALID; + + case S_NUMBER: + if (uc == ';') + return UNVIS_VALID; + if (!isdigit(uc)) + goto bad; + *cp += (*cp * 10) + uc - '0'; + return UNVIS_NOCHAR; default: + bad: /* * decoder in unknown state - (probably uninitialized) */ - *astate = S_GROUND; - return (UNVIS_SYNBAD); + *astate = SS(0, S_GROUND); + return UNVIS_SYNBAD; } } /* - * strunvis - decode src into dst + * strnunvisx - decode src into dst * * Number of chars decoded into dst is returned, -1 on error. * Dst is null terminated. */ int -strunvisx(dst, src, flag) - char *dst; - const char *src; - int flag; +strnunvisx(char *dst, size_t dlen, const char *src, int flag) { char c; - char *start = dst; + char t, *start = dst; int state = 0; _DIAGASSERT(src != NULL); _DIAGASSERT(dst != NULL); +#define CHECKSPACE() \ + do { \ + if (dlen-- == 0) { \ + errno = ENOSPC; \ + return -1; \ + } \ + } while (/*CONSTCOND*/0) while ((c = *src++) != '\0') { again: - switch (unvis(dst, c, &state, flag)) { + switch (unvis(&t, c, &state, flag)) { case UNVIS_VALID: - dst++; + CHECKSPACE(); + *dst++ = t; break; case UNVIS_VALIDPUSH: - dst++; + CHECKSPACE(); + *dst++ = t; goto again; case 0: case UNVIS_NOCHAR: break; + case UNVIS_SYNBAD: + errno = EINVAL; + return -1; default: - return (-1); + _DIAGASSERT(0); + errno = EINVAL; + return -1; } } - if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID) - dst++; + if (unvis(&t, c, &state, UNVIS_END) == UNVIS_VALID) { + CHECKSPACE(); + *dst++ = t; + } + CHECKSPACE(); *dst = '\0'; - return (dst - start); + return (int)(dst - start); +} + +int +strunvisx(char *dst, const char *src, int flag) +{ + return strnunvisx(dst, (size_t)~0, src, flag); +} + +int +strunvis(char *dst, const char *src) +{ + return strnunvisx(dst, (size_t)~0, src, 0); } int -strunvis(dst, src) - char *dst; - const char *src; +strnunvis(char *dst, size_t dlen, const char *src) { - return strunvisx(dst, src, 0); + return strnunvisx(dst, dlen, src, 0); } #endif diff --git a/cmd-line-utils/libedit/np/vis.c b/cmd-line-utils/libedit/np/vis.c index 2a746274681..d7cc37b4f47 100644 --- a/cmd-line-utils/libedit/np/vis.c +++ b/cmd-line-utils/libedit/np/vis.c @@ -1,4 +1,4 @@ -/* $NetBSD: vis.c,v 1.38 2008/09/04 09:41:44 lukem Exp $ */ +/* $NetBSD: vis.c,v 1.44 2011/03/12 19:52:48 christos Exp $ */ /*- * Copyright (c) 1989, 1993 @@ -60,23 +60,24 @@ #if defined(LIBC_SCCS) && !defined(lint) #endif /* LIBC_SCCS and not lint */ +/* XXXMYSQL : Make compiler happy. */ +#ifdef _LIBC +#include "namespace.h" +#endif + #include <sys/types.h> #include <assert.h> -#ifdef HAVE_VIS_H -#include <vis.h> -#else +/* + XXXMYSQL : Due to different versions of vis.h available, + use the one bundled with libedit. +*/ #include "np/vis.h" -#endif +#include <errno.h> #include <stdlib.h> #ifdef __weak_alias -__weak_alias(strsvis,_strsvis) -__weak_alias(strsvisx,_strsvisx) -__weak_alias(strvis,_strvis) __weak_alias(strvisx,_strvisx) -__weak_alias(svis,_svis) -__weak_alias(vis,_vis) #endif #if !HAVE_VIS || !HAVE_SVIS @@ -85,7 +86,7 @@ __weak_alias(vis,_vis) #include <stdio.h> #include <string.h> -static char *do_svis(char *, int, int, int, const char *); +static char *do_svis(char *, size_t *, int, int, int, const char *); #undef BELL #define BELL '\a' @@ -94,6 +95,7 @@ static char *do_svis(char *, int, int, int, const char *); #define iswhite(c) (c == ' ' || c == '\t' || c == '\n') #define issafe(c) (c == '\b' || c == BELL || c == '\r') #define xtoa(c) "0123456789abcdef"[c] +#define XTOA(c) "0123456789ABCDEF"[c] #define MAXEXTRAS 5 @@ -120,14 +122,54 @@ do { \ * This is do_hvis, for HTTP style (RFC 1808) */ static char * -do_hvis(char *dst, int c, int flag, int nextc, const char *extra) +do_hvis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra) { - if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { + + if ((isascii(c) && isalnum(c)) + /* safe */ + || c == '$' || c == '-' || c == '_' || c == '.' || c == '+' + /* extra */ + || c == '!' || c == '*' || c == '\'' || c == '(' || c == ')' + || c == ',') { + dst = do_svis(dst, dlen, c, flag, nextc, extra); + } else { + if (dlen) { + if (*dlen < 3) + return NULL; + *dlen -= 3; + } *dst++ = '%'; *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); *dst++ = xtoa((unsigned int)c & 0xf); + } + + return dst; +} + +/* + * This is do_mvis, for Quoted-Printable MIME (RFC 2045) + * NB: No handling of long lines or CRLF. + */ +static char * +do_mvis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra) +{ + if ((c != '\n') && + /* Space at the end of the line */ + ((isspace(c) && (nextc == '\r' || nextc == '\n')) || + /* Out of range */ + (!isspace(c) && (c < 33 || (c > 60 && c < 62) || c > 126)) || + /* Specific char to be escaped */ + strchr("#$@[\\]^`{|}~", c) != NULL)) { + if (dlen) { + if (*dlen < 3) + return NULL; + *dlen -= 3; + } + *dst++ = '='; + *dst++ = XTOA(((unsigned int)c >> 4) & 0xf); + *dst++ = XTOA((unsigned int)c & 0xf); } else { - dst = do_svis(dst, c, flag, nextc, extra); + dst = do_svis(dst, dlen, c, flag, nextc, extra); } return dst; } @@ -142,16 +184,28 @@ do_hvis(char *dst, int c, int flag, int nextc, const char *extra) * backslash-protected. */ static char * -do_svis(char *dst, int c, int flag, int nextc, const char *extra) +do_svis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra) { int isextra; + size_t odlen = dlen ? *dlen : 0; + isextra = strchr(extra, c) != NULL; +#define HAVE(x) \ + do { \ + if (dlen) { \ + if (*dlen < (x)) \ + goto out; \ + *dlen -= (x); \ + } \ + } while (/*CONSTCOND*/0) if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || ((flag & VIS_SAFE) && issafe(c)))) { + HAVE(1); *dst++ = c; return dst; } if (flag & VIS_CSTYLE) { + HAVE(2); switch (c) { case '\n': *dst++ = '\\'; *dst++ = 'n'; @@ -180,6 +234,7 @@ do_svis(char *dst, int c, int flag, int nextc, const char *extra) case '\0': *dst++ = '\\'; *dst++ = '0'; if (isoctal(nextc)) { + HAVE(2); *dst++ = '0'; *dst++ = '0'; } @@ -189,57 +244,104 @@ do_svis(char *dst, int c, int flag, int nextc, const char *extra) *dst++ = '\\'; *dst++ = c; return dst; } + if (dlen) + *dlen = odlen; } } if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { + HAVE(4); *dst++ = '\\'; *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; *dst++ = (c & 07) + '0'; } else { - if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; + if ((flag & VIS_NOSLASH) == 0) { + HAVE(1); + *dst++ = '\\'; + } + if (c & 0200) { + HAVE(1); c &= 0177; *dst++ = 'M'; } + if (iscntrl(c)) { + HAVE(2); *dst++ = '^'; if (c == 0177) *dst++ = '?'; else *dst++ = c + '@'; } else { + HAVE(2); *dst++ = '-'; *dst++ = c; } } return dst; +out: + *dlen = odlen; + return NULL; } +typedef char *(*visfun_t)(char *, size_t *, int, int, int, const char *); + +/* + * Return the appropriate encoding function depending on the flags given. + */ +static visfun_t +getvisfun(int flag) +{ + if (flag & VIS_HTTPSTYLE) + return do_hvis; + if (flag & VIS_MIMESTYLE) + return do_mvis; + return do_svis; +} /* - * svis - visually encode characters, also encoding the characters + * isnvis - visually encode characters, also encoding the characters * pointed to by `extra' */ -char * -svis(char *dst, int c, int flag, int nextc, const char *extra) +static char * +isnvis(char *dst, size_t *dlen, int c, int flag, int nextc, const char *extra) { char *nextra = NULL; + visfun_t f; _DIAGASSERT(dst != NULL); _DIAGASSERT(extra != NULL); MAKEEXTRALIST(flag, nextra, extra); if (!nextra) { + if (dlen && *dlen == 0) { + errno = ENOSPC; + return NULL; + } *dst = '\0'; /* can't create nextra, return "" */ return dst; } - if (flag & VIS_HTTPSTYLE) - dst = do_hvis(dst, c, flag, nextc, nextra); - else - dst = do_svis(dst, c, flag, nextc, nextra); + f = getvisfun(flag); + dst = (*f)(dst, dlen, c, flag, nextc, nextra); free(nextra); + if (dst == NULL || (dlen && *dlen == 0)) { + errno = ENOSPC; + return NULL; + } *dst = '\0'; return dst; } +char * +svis(char *dst, int c, int flag, int nextc, const char *extra) +{ + return isnvis(dst, NULL, c, flag, nextc, extra); +} + +char * +snvis(char *dst, size_t dlen, int c, int flag, int nextc, const char *extra) +{ + return isnvis(dst, &dlen, c, flag, nextc, extra); +} + /* * strsvis, strsvisx - visually encode characters from src into dst @@ -256,13 +358,14 @@ svis(char *dst, int c, int flag, int nextc, const char *extra) * Strsvisx encodes exactly len bytes from src into dst. * This is useful for encoding a block of data. */ -int -strsvis(char *dst, const char *csrc, int flag, const char *extra) +static int +istrsnvis(char *dst, size_t *dlen, const char *csrc, int flag, const char *extra) { int c; char *start; char *nextra = NULL; const unsigned char *src = (const unsigned char *)csrc; + visfun_t f; _DIAGASSERT(dst != NULL); _DIAGASSERT(src != NULL); @@ -272,52 +375,87 @@ strsvis(char *dst, const char *csrc, int flag, const char *extra) *dst = '\0'; /* can't create nextra, return "" */ return 0; } - if (flag & VIS_HTTPSTYLE) { - for (start = dst; (c = *src++) != '\0'; /* empty */) - dst = do_hvis(dst, c, flag, *src, nextra); - } else { - for (start = dst; (c = *src++) != '\0'; /* empty */) - dst = do_svis(dst, c, flag, *src, nextra); + f = getvisfun(flag); + for (start = dst; (c = *src++) != '\0'; /* empty */) { + dst = (*f)(dst, dlen, c, flag, *src, nextra); + if (dst == NULL) { + errno = ENOSPC; + return -1; + } } free(nextra); + if (dlen && *dlen == 0) { + errno = ENOSPC; + return -1; + } *dst = '\0'; - return (dst - start); + return (int)(dst - start); } +int +strsvis(char *dst, const char *csrc, int flag, const char *extra) +{ + return istrsnvis(dst, NULL, csrc, flag, extra); +} int -strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra) +strsnvis(char *dst, size_t dlen, const char *csrc, int flag, const char *extra) +{ + return istrsnvis(dst, &dlen, csrc, flag, extra); +} + +static int +istrsnvisx(char *dst, size_t *dlen, const char *csrc, size_t len, int flag, + const char *extra) { unsigned char c; char *start; char *nextra = NULL; const unsigned char *src = (const unsigned char *)csrc; + visfun_t f; _DIAGASSERT(dst != NULL); _DIAGASSERT(src != NULL); _DIAGASSERT(extra != NULL); MAKEEXTRALIST(flag, nextra, extra); if (! nextra) { + if (dlen && *dlen == 0) { + errno = ENOSPC; + return -1; + } *dst = '\0'; /* can't create nextra, return "" */ return 0; } - if (flag & VIS_HTTPSTYLE) { - for (start = dst; len > 0; len--) { - c = *src++; - dst = do_hvis(dst, c, flag, - len > 1 ? *src : '\0', nextra); - } - } else { - for (start = dst; len > 0; len--) { - c = *src++; - dst = do_svis(dst, c, flag, - len > 1 ? *src : '\0', nextra); + f = getvisfun(flag); + for (start = dst; len > 0; len--) { + c = *src++; + dst = (*f)(dst, dlen, c, flag, len > 1 ? *src : '\0', nextra); + if (dst == NULL) { + errno = ENOSPC; + return -1; } } free(nextra); + if (dlen && *dlen == 0) { + errno = ENOSPC; + return -1; + } *dst = '\0'; - return (dst - start); + return (int)(dst - start); +} + +int +strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra) +{ + return istrsnvisx(dst, NULL, csrc, len, flag, extra); +} + +int +strsnvisx(char *dst, size_t dlen, const char *csrc, size_t len, int flag, + const char *extra) +{ + return istrsnvisx(dst, &dlen, csrc, len, flag, extra); } #endif @@ -325,28 +463,47 @@ strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra) /* * vis - visually encode characters */ -char * -vis(char *dst, int c, int flag, int nextc) +static char * +invis(char *dst, size_t *dlen, int c, int flag, int nextc) { char *extra = NULL; unsigned char uc = (unsigned char)c; + visfun_t f; _DIAGASSERT(dst != NULL); MAKEEXTRALIST(flag, extra, ""); if (! extra) { + if (dlen && *dlen == 0) { + errno = ENOSPC; + return NULL; + } *dst = '\0'; /* can't create extra, return "" */ return dst; } - if (flag & VIS_HTTPSTYLE) - dst = do_hvis(dst, uc, flag, nextc, extra); - else - dst = do_svis(dst, uc, flag, nextc, extra); + f = getvisfun(flag); + dst = (*f)(dst, dlen, uc, flag, nextc, extra); free(extra); + if (dst == NULL || (dlen && *dlen == 0)) { + errno = ENOSPC; + return NULL; + } *dst = '\0'; return dst; } +char * +vis(char *dst, int c, int flag, int nextc) +{ + return invis(dst, NULL, c, flag, nextc); +} + +char * +nvis(char *dst, size_t dlen, int c, int flag, int nextc) +{ + return invis(dst, &dlen, c, flag, nextc); +} + /* * strvis, strvisx - visually encode characters from src into dst @@ -358,36 +515,68 @@ vis(char *dst, int c, int flag, int nextc) * Strvisx encodes exactly len bytes from src into dst. * This is useful for encoding a block of data. */ -int -strvis(char *dst, const char *src, int flag) +static int +istrnvis(char *dst, size_t *dlen, const char *src, int flag) { char *extra = NULL; int rv; MAKEEXTRALIST(flag, extra, ""); if (!extra) { + if (dlen && *dlen == 0) { + errno = ENOSPC; + return -1; + } *dst = '\0'; /* can't create extra, return "" */ return 0; } - rv = strsvis(dst, src, flag, extra); + rv = istrsnvis(dst, dlen, src, flag, extra); free(extra); return rv; } +int +strvis(char *dst, const char *src, int flag) +{ + return istrnvis(dst, NULL, src, flag); +} int -strvisx(char *dst, const char *src, size_t len, int flag) +strnvis(char *dst, size_t dlen, const char *src, int flag) +{ + return istrnvis(dst, &dlen, src, flag); +} + +static int +istrnvisx(char *dst, size_t *dlen, const char *src, size_t len, int flag) { char *extra = NULL; int rv; MAKEEXTRALIST(flag, extra, ""); if (!extra) { + if (dlen && *dlen == 0) { + errno = ENOSPC; + return -1; + } *dst = '\0'; /* can't create extra, return "" */ return 0; } - rv = strsvisx(dst, src, len, flag, extra); + rv = istrsnvisx(dst, dlen, src, len, flag, extra); free(extra); return rv; } + +int +strvisx(char *dst, const char *src, size_t len, int flag) +{ + return istrnvisx(dst, NULL, src, len, flag); +} + +int +strnvisx(char *dst, size_t dlen, const char *src, size_t len, int flag) +{ + return istrnvisx(dst, &dlen, src, len, flag); +} + #endif diff --git a/cmd-line-utils/libedit/np/vis.h b/cmd-line-utils/libedit/np/vis.h index 11f5b740e2d..54a76e9108f 100644 --- a/cmd-line-utils/libedit/np/vis.h +++ b/cmd-line-utils/libedit/np/vis.h @@ -1,4 +1,4 @@ -/* $NetBSD: vis.h,v 1.16 2005/09/13 01:44:32 christos Exp $ */ +/* $NetBSD: vis.h,v 1.19 2011/03/12 19:52:45 christos Exp $ */ /*- * Copyright (c) 1990, 1993 @@ -39,24 +39,29 @@ /* * to select alternate encoding format */ -#define VIS_OCTAL 0x01 /* use octal \ddd format */ -#define VIS_CSTYLE 0x02 /* use \[nrft0..] where appropiate */ +#define VIS_OCTAL 0x001 /* use octal \ddd format */ +#define VIS_CSTYLE 0x002 /* use \[nrft0..] where appropiate */ /* * to alter set of characters encoded (default is to encode all * non-graphic except space, tab, and newline). */ -#define VIS_SP 0x04 /* also encode space */ -#define VIS_TAB 0x08 /* also encode tab */ -#define VIS_NL 0x10 /* also encode newline */ +#define VIS_SP 0x004 /* also encode space */ +#define VIS_TAB 0x008 /* also encode tab */ +#define VIS_NL 0x010 /* also encode newline */ #define VIS_WHITE (VIS_SP | VIS_TAB | VIS_NL) -#define VIS_SAFE 0x20 /* only encode "unsafe" characters */ +#define VIS_SAFE 0x020 /* only encode "unsafe" characters */ /* * other */ -#define VIS_NOSLASH 0x40 /* inhibit printing '\' */ -#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */ +#define VIS_NOSLASH 0x040 /* inhibit printing '\' */ +#define VIS_HTTP1808 0x080 /* http-style escape % hex hex */ +#define VIS_HTTPSTYLE 0x080 /* http-style escape % hex hex */ +#define VIS_MIMESTYLE 0x100 /* mime-style escape = HEX HEX */ +#define VIS_HTTP1866 0x200 /* http-style &#num; or &string; */ +#define VIS_NOESCAPE 0x400 /* don't decode `\' */ +#define _VIS_END 0x800 /* for unvis */ /* * unvis return codes @@ -70,18 +75,40 @@ /* * unvis flags */ -#define UNVIS_END 1 /* no more characters */ +#define UNVIS_END _VIS_END /* no more characters */ +/* XXXMYSQL */ +#ifndef __RENAME +#define __RENAME(x) +#endif __BEGIN_DECLS char *vis(char *, int, int, int); +char *nvis(char *, size_t, int, int, int); + char *svis(char *, int, int, int, const char *); +char *snvis(char *, size_t, int, int, int, const char *); + int strvis(char *, const char *, int); +int strnvis(char *, size_t, const char *, int); + int strsvis(char *, const char *, int, const char *); +int strsnvis(char *, size_t, const char *, int, const char *); + int strvisx(char *, const char *, size_t, int); +int strnvisx(char *, size_t, const char *, size_t, int); + int strsvisx(char *, const char *, size_t, int, const char *); +int strsnvisx(char *, size_t, const char *, size_t, int, const char *); + int strunvis(char *, const char *); +int strnunvis(char *, size_t, const char *); + int strunvisx(char *, const char *, int); -int unvis(char *, int, int *, int); +int strnunvisx(char *, size_t, const char *, int); + +#ifndef __LIBC12_SOURCE__ +int unvis(char *, int, int *, int) __RENAME(__unvis50); +#endif __END_DECLS #endif /* !_VIS_H_ */ diff --git a/cmd-line-utils/libedit/np/wcsdup.c b/cmd-line-utils/libedit/np/wcsdup.c new file mode 100644 index 00000000000..2a77375e0b7 --- /dev/null +++ b/cmd-line-utils/libedit/np/wcsdup.c @@ -0,0 +1,43 @@ +/* $NetBSD: wcsdup.c,v 1.3 2008/05/26 13:17:48 haad Exp $ */ + +/* + * Copyright (C) 2006 Aleksey Cheusov + * + * This material is provided "as is", with absolutely no warranty expressed + * or implied. Any use is at your own risk. + * + * Permission to use or copy this software for any purpose is hereby granted + * without fee. Permission to modify the code and to distribute modified + * code is also granted without any restrictions. + */ + +#ifndef HAVE_WCSDUP + +#include "config.h" + +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: wcsdup.c,v 1.3 2008/05/26 13:17:48 haad Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include <stdlib.h> +#include <assert.h> +#include <wchar.h> + +wchar_t * +wcsdup(const wchar_t *str) +{ + wchar_t *copy; + size_t len; + + _DIAGASSERT(str != NULL); + + len = wcslen(str) + 1; + copy = malloc(len * sizeof (wchar_t)); + + if (!copy) + return NULL; + + return wmemcpy(copy, str, len); +} + +#endif diff --git a/cmd-line-utils/libedit/parse.c b/cmd-line-utils/libedit/parse.c index 5bdefb5a0e4..b14e4ae7165 100644 --- a/cmd-line-utils/libedit/parse.c +++ b/cmd-line-utils/libedit/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $ */ +/* $NetBSD: parse.c,v 1.26 2011/08/16 16:25:15 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -57,17 +57,17 @@ static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93"; #include <stdlib.h> private const struct { - const char *name; - int (*func)(EditLine *, int, const char **); + const Char *name; + int (*func)(EditLine *, int, const Char **); } cmds[] = { - { "bind", map_bind }, - { "echotc", term_echotc }, - { "edit", el_editmode }, - { "history", hist_command }, - { "telltc", term_telltc }, - { "settc", term_settc }, - { "setty", tty_stty }, - { NULL, NULL } + { STR("bind"), map_bind }, + { STR("echotc"), terminal_echotc }, + { STR("edit"), el_editmode }, + { STR("history"), hist_command }, + { STR("telltc"), terminal_telltc }, + { STR("settc"), terminal_settc }, + { STR("setty"), tty_stty }, + { NULL, NULL } }; @@ -75,17 +75,17 @@ private const struct { * Parse a line and dispatch it */ protected int -parse_line(EditLine *el, const char *line) +parse_line(EditLine *el, const Char *line) { - const char **argv; + const Char **argv; int argc; - Tokenizer *tok; + TYPE(Tokenizer) *tok; - tok = tok_init(NULL); - tok_str(tok, line, &argc, &argv); - argc = el_parse(el, argc, argv); - tok_end(tok); - 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; } @@ -93,57 +93,57 @@ parse_line(EditLine *el, const char *line) * Command dispatcher */ public int -el_parse(EditLine *el, int argc, const char *argv[]) +FUN(el,parse)(EditLine *el, int argc, const Char *argv[]) { - const char *ptr; + const Char *ptr; int i; if (argc < 1) - return (-1); - ptr = strchr(argv[0], ':'); + 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 ^<char> \<odigit> \<char> and return + * Parse a string of the form ^<char> \<odigit> \<char> \U+xxxx and return * the appropriate character or -1 if the escape is not valid */ protected int -parse__escape(const char **ptr) +parse__escape(const Char **ptr) { - const char *p; - int c; + const Char *p; + Int c; p = *ptr; if (p[1] == 0) - return (-1); + return -1; if (*p == '\\') { p++; @@ -172,6 +172,28 @@ parse__escape(const char **ptr) case 'e': c = '\033'; /* Escape */ break; + case 'U': /* Unicode \U+xxxx or \U+xxxxx format */ + { + int i; + const Char hex[] = STR("0123456789ABCDEF"); + const Char *h; + ++p; + if (*p++ != '+') + return -1; + c = 0; + for (i = 0; i < 5; ++i) { + h = Strchr(hex, *p++); + if (!h && i < 4) + return -1; + else if (h) + c = (c << 4) | ((int)(h - hex)); + else + --p; + } + if (c > 0x10FFFF) /* outside valid character range */ + return -1; + break; + } case '0': case '1': case '2': @@ -191,8 +213,8 @@ parse__escape(const char **ptr) } c = (c << 3) | (ch - '0'); } - if ((c & 0xffffff00) != 0) - return (-1); + if ((c & (wint_t)0xffffff00) != (wint_t)0) + return -1; --p; break; } @@ -206,28 +228,28 @@ parse__escape(const char **ptr) } else c = *p; *ptr = ++p; - return (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 (;;) 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; @@ -251,12 +273,12 @@ parse__string(char *out, const char *in) * or -1 if one is not found */ protected int -parse_cmd(EditLine *el, const char *cmd) +parse_cmd(EditLine *el, const Char *cmd) { el_bindings_t *b; for (b = el->el_map.help; b->name != NULL; b++) - if (strcmp(b->name, cmd) == 0) - return (b->func); - return (-1); + if (Strcmp(b->name, cmd) == 0) + return b->func; + return -1; } diff --git a/cmd-line-utils/libedit/parse.h b/cmd-line-utils/libedit/parse.h index 58dced1aeaa..ec04051bc27 100644 --- a/cmd-line-utils/libedit/parse.h +++ b/cmd-line-utils/libedit/parse.h @@ -1,4 +1,4 @@ -/* $NetBSD: parse.h,v 1.6 2005/05/29 04:58:15 lukem Exp $ */ +/* $NetBSD: parse.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -40,9 +40,9 @@ #ifndef _h_el_parse #define _h_el_parse -protected int parse_line(EditLine *, const char *); -protected int parse__escape(const char **); -protected char *parse__string(char *, const char *); -protected int parse_cmd(EditLine *, const char *); +protected int parse_line(EditLine *, const Char *); +protected int parse__escape(const Char **); +protected Char *parse__string(Char *, const Char *); +protected int parse_cmd(EditLine *, const Char *); #endif /* _h_el_parse */ diff --git a/cmd-line-utils/libedit/prompt.c b/cmd-line-utils/libedit/prompt.c index 982943afd30..3f8d73303ec 100644 --- a/cmd-line-utils/libedit/prompt.c +++ b/cmd-line-utils/libedit/prompt.c @@ -1,4 +1,4 @@ -/* $NetBSD: prompt.c,v 1.11 2003/08/07 16:44:32 agc Exp $ */ +/* $NetBSD: prompt.c,v 1.20 2011/07/29 15:16:33 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -46,54 +46,66 @@ static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93"; #include <stdio.h> #include "el.h" -private char *prompt_default(EditLine *); -private char *prompt_default_r(EditLine *); +private Char *prompt_default(EditLine *); +private Char *prompt_default_r(EditLine *); /* prompt_default(): * Just a default prompt, in case the user did not provide one */ -private char * +private Char * /*ARGSUSED*/ prompt_default(EditLine *el __attribute__((__unused__))) { - static char a[3] = {'?', ' ', '\0'}; + static Char a[3] = {'?', ' ', '\0'}; - return (a); + return a; } /* prompt_default_r(): * Just a default rprompt, in case the user did not provide one */ -private char * +private Char * /*ARGSUSED*/ prompt_default_r(EditLine *el __attribute__((__unused__))) { - static char a[1] = {'\0'}; + static Char a[1] = {'\0'}; - return (a); + 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) elp = &el->el_prompt; else elp = &el->el_rprompt; - p = (elp->p_func) (el); - while (*p) - re_putc(el, *p++, 1); + + if (elp->p_wide) + p = (*elp->p_func)(el); + else + p = ct_decode_string((char *)(void *)(*elp->p_func)(el), + &el->el_scratch); + + for (; *p; p++) { + if (elp->p_ignore == *p) { + ignore = !ignore; + continue; + } + if (ignore) + terminal__putc(el, *p); + else + re_putc(el, *p, 1); + } elp->p_pos.v = el->el_refresh.r_cursor.v; elp->p_pos.h = el->el_refresh.r_cursor.h; @@ -110,10 +122,12 @@ prompt_init(EditLine *el) el->el_prompt.p_func = prompt_default; el->el_prompt.p_pos.v = 0; el->el_prompt.p_pos.h = 0; + el->el_prompt.p_ignore = '\0'; el->el_rprompt.p_func = prompt_default_r; el->el_rprompt.p_pos.v = 0; el->el_rprompt.p_pos.h = 0; - return (0); + el->el_rprompt.p_ignore = '\0'; + return 0; } @@ -131,24 +145,31 @@ prompt_end(EditLine *el __attribute__((__unused__))) * Install a prompt printing function */ protected int -prompt_set(EditLine *el, el_pfunc_t prf, int op) +prompt_set(EditLine *el, el_pfunc_t prf, Char c, int op, int wide) { el_prompt_t *p; - if (op == EL_PROMPT) + if (op == EL_PROMPT || op == EL_PROMPT_ESC) p = &el->el_prompt; else p = &el->el_rprompt; + if (prf == NULL) { - if (op == EL_PROMPT) + if (op == EL_PROMPT || op == EL_PROMPT_ESC) p->p_func = prompt_default; else p->p_func = prompt_default_r; - } else + } else { p->p_func = prf; + } + + p->p_ignore = c; + p->p_pos.v = 0; p->p_pos.h = 0; - return (0); + p->p_wide = wide; + + return 0; } @@ -156,14 +177,22 @@ prompt_set(EditLine *el, el_pfunc_t prf, int op) * Retrieve the prompt printing function */ protected int -prompt_get(EditLine *el, el_pfunc_t *prf, int op) +prompt_get(EditLine *el, el_pfunc_t *prf, Char *c, int op) { + el_prompt_t *p; if (prf == NULL) - return (-1); + return -1; + if (op == EL_PROMPT) - *prf = el->el_prompt.p_func; + p = &el->el_prompt; else - *prf = el->el_rprompt.p_func; - return (0); + p = &el->el_rprompt; + + if (prf) + *prf = p->p_func; + if (c) + *c = p->p_ignore; + + return 0; } diff --git a/cmd-line-utils/libedit/prompt.h b/cmd-line-utils/libedit/prompt.h index d18110861f8..af63b82b684 100644 --- a/cmd-line-utils/libedit/prompt.h +++ b/cmd-line-utils/libedit/prompt.h @@ -1,4 +1,4 @@ -/* $NetBSD: prompt.h,v 1.6 2003/08/07 16:44:32 agc Exp $ */ +/* $NetBSD: prompt.h,v 1.10 2009/12/30 22:37:40 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -42,16 +42,18 @@ #include "histedit.h" -typedef char * (*el_pfunc_t)(EditLine*); +typedef Char *(*el_pfunc_t)(EditLine *); typedef struct el_prompt_t { - el_pfunc_t p_func; /* Function to return the prompt */ - coord_t p_pos; /* position in the line after prompt */ + el_pfunc_t p_func; /* Function to return the prompt */ + coord_t p_pos; /* position in the line after prompt */ + Char p_ignore; /* character to start/end literal */ + int p_wide; } el_prompt_t; protected void prompt_print(EditLine *, int); -protected int prompt_set(EditLine *, el_pfunc_t, int); -protected int prompt_get(EditLine *, el_pfunc_t *, int); +protected int prompt_set(EditLine *, el_pfunc_t, Char, int, int); +protected int prompt_get(EditLine *, el_pfunc_t *, Char *, int); protected int prompt_init(EditLine *); protected void prompt_end(EditLine *); diff --git a/cmd-line-utils/libedit/read.c b/cmd-line-utils/libedit/read.c index ac768142e79..a919b888965 100644 --- a/cmd-line-utils/libedit/read.c +++ b/cmd-line-utils/libedit/read.c @@ -1,4 +1,4 @@ -/* $NetBSD: read.c,v 1.43 2009/02/05 19:15:44 christos Exp $ */ +/* $NetBSD: read.c,v 1.67 2011/08/16 16:25:15 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -48,14 +48,15 @@ static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; #include <fcntl.h> #include <unistd.h> #include <stdlib.h> +#include <limits.h> #include "el.h" -#define OKCMD -1 +#define OKCMD -1 /* must be -1! */ private int read__fixio(int, int); private int read_preread(EditLine *); -private int read_char(EditLine *, char *); -private int read_getcmd(EditLine *, el_action_t *, char *); +private int read_char(EditLine *, Char *); +private int read_getcmd(EditLine *, el_action_t *, Char *); private void read_pop(c_macro_t *); /* read_init(): @@ -89,7 +90,7 @@ el_read_setfn(EditLine *el, el_rfunc_t rc) 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; } @@ -131,7 +132,7 @@ read__fixio(int fd __attribute__((__unused__)), int e) #ifdef EWOULDBLOCK case EWOULDBLOCK: #ifndef TRY_AGAIN -#define TRY_AGAIN +#define TRY_AGAIN #endif #endif /* EWOULDBLOCK */ @@ -139,7 +140,7 @@ read__fixio(int fd __attribute__((__unused__)), int e) #if defined(EWOULDBLOCK) && EWOULDBLOCK != EAGAIN case EAGAIN: #ifndef TRY_AGAIN -#define TRY_AGAIN +#define TRY_AGAIN #endif #endif /* EWOULDBLOCK && EWOULDBLOCK != EAGAIN */ #endif /* POSIX && EAGAIN */ @@ -148,10 +149,10 @@ read__fixio(int fd __attribute__((__unused__)), int e) #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 */ @@ -160,21 +161,21 @@ read__fixio(int fd __attribute__((__unused__)), int e) { int zero = 0; - if (ioctl(fd, FIONBIO, (ioctl_t) & zero) == -1) - return (-1); + if (ioctl(fd, FIONBIO, &zero) == -1) + return -1; else e = 1; } #endif /* FIONBIO */ #endif /* TRY_AGAIN */ - return (e ? 0 : -1); + return e ? 0 : -1; case EINTR: - return (0); + return 0; default: - return (-1); + return -1; } } @@ -188,10 +189,13 @@ read_preread(EditLine *el) 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]; @@ -203,8 +207,8 @@ read_preread(EditLine *el) } } #endif /* FIONREAD */ - - return (chrs > 0); +#endif + return chrs > 0; } @@ -212,33 +216,37 @@ read_preread(EditLine *el) * 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. + * Character values > 255 are not looked up in the map, but inserted. */ private int -read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) +read_getcmd(EditLine *el, el_action_t *cmdnum, Char *ch) { el_action_t cmd; int num; + el->el_errno = 0; do { - if ((num = el_getc(el, ch)) != 1) /* if EOF or error */ - return (num); + if ((num = FUN(el,getc)(el, ch)) != 1) {/* if EOF or error */ + el->el_errno = num == 0 ? 0 : errno; + return num; + } #ifdef KANJI if ((*ch & 0200)) { @@ -252,15 +260,20 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) el->el_state.metanext = 0; *ch |= 0200; } - cmd = el->el_map.current[(unsigned char) *ch]; +#ifdef WIDECHAR + if (*ch >= N_KEYS) + cmd = ED_INSERT; + else +#endif + cmd = el->el_map.current[(unsigned char) *ch]; if (cmd == ED_SEQUENCE_LEAD_IN) { - key_value_t val; - switch (key_get(el, ch, &val)) { + 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: @@ -277,28 +290,82 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) el->el_map.current = el->el_map.key; } while (cmd == ED_SEQUENCE_LEAD_IN); *cmdnum = cmd; - return (OKCMD); + return OKCMD; } - /* read_char(): * Read a character from the tty. */ private int -read_char(EditLine *el, char *cp) +read_char(EditLine *el, Char *cp) { - int num_read; + ssize_t num_read; int tried = 0; + char cbuf[MB_LEN_MAX]; + size_t cbp = 0; + int bytes = 0; - while ((num_read = read(el->el_infd, cp, 1)) == -1) +#ifdef WIDECHAR +static mbstate_t state, temp_state; +memset(&state, 0, sizeof(mbstate_t)); +#endif + + again: + el->el_signal->sig_no = 0; + while ((num_read = read(el->el_infd, cbuf + cbp, (size_t)1)) == -1) { + switch (el->el_signal->sig_no) { + case SIGCONT: + FUN(el,set)(el, EL_REFRESH); + /*FALLTHROUGH*/ + case SIGWINCH: + sig_set(el); + goto again; + default: + break; + } if (!tried && read__fixio(el->el_infd, errno) == 0) tried = 1; else { *cp = '\0'; - return (-1); + return -1; } + } + +#ifdef WIDECHAR + ++cbp; + if (cbp > (size_t) MB_CUR_MAX) { /* "shouldn't happen" */ + *cp = '\0'; + return (-1); + } + + temp_state= state; + + if ((bytes = mbrtowc(cp, cbuf, cbp, &state)) == -2) + { + /* Incomplete sequence, restore the state and scan more bytes. */ + state= temp_state; + goto again; + } + else if (bytes == -1) + { + /* Invalid sequence, reset the state and continue. */ + cbp= 0; + memset(&state, 0, sizeof(mbstate_t)); + goto again; + } + /* We successfully read one single or multi-byte character */ +#else + *cp = (unsigned char)cbuf[0]; +#endif - return (num_read); +#if 0 + if ((el->el_flags & IGNORE_EXTCHARS) && bytes > 1) { + cbp = 0; /* skip this character */ + goto again; + } +#endif + + return (int)num_read; } /* read_pop(): @@ -310,8 +377,9 @@ read_pop(c_macro_t *ma) int i; el_free(ma->macro[0]); - for (i = ma->level--; i > 0; i--) - ma->macro[i - 1] = ma->macro[i]; + for (i = 0; i < ma->level; i++) + ma->macro[i] = ma->macro[i + 1]; + ma->level--; ma->offset = 0; } @@ -319,12 +387,12 @@ read_pop(c_macro_t *ma) * 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)) @@ -339,30 +407,34 @@ el_getc(EditLine *el, char *cp) 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 */ read_pop(ma); } - return (1); + return 1; } #ifdef DEBUG_READ (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); +#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 @@ -383,7 +455,7 @@ read_prepare(EditLine *el) re_refresh(el); /* print the prompt */ if (el->el_flags & UNBUFFERED) - term__flush(el); + terminal__flush(el); } protected void @@ -395,27 +467,32 @@ read_finish(EditLine *el) sig_clr(el); } -public const char * -el_gets(EditLine *el, int *nread) +public const Char * +FUN(el,gets)(EditLine *el, int *nread) { int retval; el_action_t cmdnum = 0; int num; /* how many chars we have read at NL */ - char ch; + Char ch, *cp; int crlf = 0; + int nrb; #ifdef FIONREAD c_macro_t *ma = &el->el_chared.c_macro; #endif /* FIONREAD */ + if (nread == NULL) + nread = &nrb; + *nread = 0; + if (el->el_flags & NO_TTY) { - char *cp = el->el_line.buffer; size_t idx; - while ((*el->el_read.read_char)(el, cp) == 1) { + cp = el->el_line.buffer; + while ((num = (*el->el_read.read_char)(el, cp)) == 1) { /* make sure there is space for next character */ 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]; } @@ -425,12 +502,13 @@ el_gets(EditLine *el, int *nread) if (cp[-1] == '\r' || cp[-1] == '\n') break; } + if (num == -1) { + if (errno == EINTR) + cp = el->el_line.buffer; + el->el_errno = errno; + } - el->el_line.cursor = el->el_line.lastchar = cp; - *cp = '\0'; - if (nread) - *nread = el->el_line.cursor - el->el_line.buffer; - return (el->el_line.buffer); + goto noedit; } @@ -438,12 +516,12 @@ el_gets(EditLine *el, int *nread) 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) { - if (nread) - *nread = 0; - return (NULL); + errno = 0; + *nread = 0; + return NULL; } } } @@ -453,25 +531,23 @@ el_gets(EditLine *el, int *nread) read_prepare(el); if (el->el_flags & EDIT_DISABLED) { - char *cp; size_t idx; + if ((el->el_flags & UNBUFFERED) == 0) cp = el->el_line.buffer; else cp = el->el_line.lastchar; - term__flush(el); + terminal__flush(el); - while ((*el->el_read.read_char)(el, cp) == 1) { + while ((num = (*el->el_read.read_char)(el, cp)) == 1) { /* make sure there is space next character */ 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]; } - if (*cp == 4) /* ought to be stty eof */ - break; cp++; crlf = cp[-1] == '\r' || cp[-1] == '\n'; if (el->el_flags & UNBUFFERED) @@ -480,11 +556,13 @@ el_gets(EditLine *el, int *nread) break; } - el->el_line.cursor = el->el_line.lastchar = cp; - *cp = '\0'; - if (nread) - *nread = el->el_line.cursor - el->el_line.buffer; - return (el->el_line.buffer); + if (num == -1) { + if (errno == EINTR) + cp = el->el_line.buffer; + el->el_errno = errno; + } + + goto noedit; } for (num = OKCMD; num == OKCMD;) { /* while still editing this @@ -500,6 +578,12 @@ el_gets(EditLine *el, int *nread) #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, @@ -530,7 +614,7 @@ el_gets(EditLine *el, int *nread) el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) { if (cmdnum == VI_DELETE_PREV_CHAR && el->el_chared.c_redo.pos != el->el_chared.c_redo.buf - && el_isprint((unsigned char)el->el_chared.c_redo.pos[-1])) + && Isprint(el->el_chared.c_redo.pos[-1])) el->el_chared.c_redo.pos--; else *el->el_chared.c_redo.pos++ = ch; @@ -561,7 +645,7 @@ el_gets(EditLine *el, int *nread) case CC_REFRESH_BEEP: re_refresh(el); - term_beep(el); + terminal_beep(el); break; case CC_NORM: /* normal char */ @@ -582,7 +666,7 @@ el_gets(EditLine *el, int *nread) break; case CC_NEWLINE: /* normal end of line */ - num = el->el_line.lastchar - el->el_line.buffer; + num = (int)(el->el_line.lastchar - el->el_line.buffer); break; case CC_FATAL: /* fatal error, reset to known state */ @@ -593,7 +677,7 @@ el_gets(EditLine *el, int *nread) /* 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: @@ -602,8 +686,8 @@ el_gets(EditLine *el, int *nread) (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; @@ -613,15 +697,26 @@ el_gets(EditLine *el, int *nread) 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); - if (nread) - *nread = num; + *nread = num != -1 ? num : 0; } else { - if (nread) - *nread = el->el_line.lastchar - el->el_line.buffer; + *nread = (int)(el->el_line.lastchar - el->el_line.buffer); } - return (num ? el->el_line.buffer : NULL); + goto done; +noedit: + el->el_line.cursor = el->el_line.lastchar = cp; + *cp = '\0'; + *nread = (int)(el->el_line.cursor - el->el_line.buffer); +done: + if (*nread == 0) { + if (num == -1) { + *nread = -1; + errno = el->el_errno; + } + return NULL; + } else + return el->el_line.buffer; } diff --git a/cmd-line-utils/libedit/read.h b/cmd-line-utils/libedit/read.h index bd8d4c1f5bb..852606a9c17 100644 --- a/cmd-line-utils/libedit/read.h +++ b/cmd-line-utils/libedit/read.h @@ -1,4 +1,4 @@ -/* $NetBSD: read.h,v 1.6 2008/04/29 06:53:01 martin Exp $ */ +/* $NetBSD: read.h,v 1.7 2009/12/30 22:37:40 christos Exp $ */ /*- * Copyright (c) 2001 The NetBSD Foundation, Inc. @@ -35,7 +35,7 @@ #ifndef _h_el_read #define _h_el_read -typedef int (*el_rfunc_t)(EditLine *, char *); +typedef int (*el_rfunc_t)(EditLine *, Char *); typedef struct el_read_t { el_rfunc_t read_char; /* Function to read a character */ diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index 0318ab409b3..eaf26d4c497 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -1,4 +1,4 @@ -/* $NetBSD: readline.c,v 1.78 2009/02/05 19:15:26 christos Exp $ */ +/* $NetBSD: readline.c,v 1.99 2011/08/16 16:25:15 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -69,6 +69,7 @@ void rl_deprep_terminal(void); /* readline compatibility stuff - look at readline sources/documentation */ /* to see what these variables mean */ const char *rl_library_version = "EditLine wrapper"; +int rl_readline_version = RL_READLINE_VERSION; static char empty[] = { '\0' }; static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' }; static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', @@ -117,6 +118,7 @@ Function *rl_startup_hook = NULL; VFunction *rl_completion_display_matches_hook = NULL; VFunction *rl_prep_term_function = (VFunction *)rl_prep_terminal; VFunction *rl_deprep_term_function = (VFunction *)rl_deprep_terminal; +KEYMAP_ENTRY_ARRAY emacs_meta_keymap; /* * The current prompt string. @@ -174,7 +176,7 @@ static char * _get_prompt(EditLine *el __attribute__((__unused__))) { rl_already_prompted = 1; - return (rl_prompt); + return rl_prompt; } @@ -188,12 +190,12 @@ _move_history(int op) static HIST_ENTRY rl_he; if (history(h, &ev, op) != 0) - return (HIST_ENTRY *) NULL; + return NULL; rl_he.line = ev.str; rl_he.data = NULL; - return (&rl_he); + return &rl_he; } @@ -209,10 +211,34 @@ _getc_function(EditLine *el __attribute__((__unused__)), char *c) i = (*rl_getc_function)(NULL); if (i == -1) return 0; - *c = i; + *c = (char)i; return 1; } +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]; + + if (*path) + return path; + if ((p = getpwuid(getuid())) == NULL) + return NULL; + (void)snprintf(path, sizeof(path), "%s/.history", p->pw_dir); + return path; +} /* * READLINE compatibility stuff @@ -224,14 +250,22 @@ _getc_function(EditLine *el __attribute__((__unused__)), char *c) int rl_set_prompt(const char *prompt) { + char *p; + if (!prompt) prompt = ""; 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); - return rl_prompt == NULL ? -1 : 0; + if (rl_prompt == NULL) + return -1; + + while ((p = strchr(rl_prompt, RL_PROMPT_END_IGNORE)) != NULL) + *p = RL_PROMPT_START_IGNORE; + + return 0; } /* @@ -241,7 +275,6 @@ int rl_initialize(void) { HistEvent ev; - const LineInfo *li; int editmode = 1; struct termios t; @@ -268,13 +301,16 @@ rl_initialize(void) h = history_init(); if (!e || !h) - return (-1); + return -1; history(h, &ev, H_SETSIZE, INT_MAX); /* unlimited */ history_length = 0; max_input_history = INT_MAX; el_set(e, EL_HIST, history, h); + /* 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); @@ -285,7 +321,7 @@ rl_initialize(void) el_end(e); return -1; } - el_set(e, EL_PROMPT, _get_prompt); + el_set(e, EL_PROMPT, _get_prompt, RL_PROMPT_START_IGNORE); el_set(e, EL_SIGNAL, rl_catch_signals); /* set default mode to "emacs"-style and read setting afterwards */ @@ -312,7 +348,38 @@ rl_initialize(void) "ReadLine compatible suspend function", _el_rl_tstp); el_set(e, EL_BIND, "^Z", "rl_tstp", NULL); - + + /* + * Set some readline compatible key-bindings. + */ + el_set(e, EL_BIND, "^R", "em-inc-search-prev", NULL); + + /* + * Allow the use of Home/End keys. + */ + el_set(e, EL_BIND, "\\e[1~", "ed-move-to-beg", NULL); + el_set(e, EL_BIND, "\\e[4~", "ed-move-to-end", NULL); + el_set(e, EL_BIND, "\\e[7~", "ed-move-to-beg", NULL); + el_set(e, EL_BIND, "\\e[8~", "ed-move-to-end", NULL); + el_set(e, EL_BIND, "\\e[H", "ed-move-to-beg", NULL); + el_set(e, EL_BIND, "\\e[F", "ed-move-to-end", NULL); + + /* + * Allow the use of the Delete/Insert keys. + */ + el_set(e, EL_BIND, "\\e[3~", "ed-delete-next-char", NULL); + el_set(e, EL_BIND, "\\e[2~", "ed-quoted-insert", NULL); + + /* + * Ctrl-left-arrow and Ctrl-right-arrow for word moving. + */ + el_set(e, EL_BIND, "\\e[1;5C", "em-next-word", NULL); + el_set(e, EL_BIND, "\\e[1;5D", "ed-prev-word", NULL); + el_set(e, EL_BIND, "\\e[5C", "em-next-word", NULL); + el_set(e, EL_BIND, "\\e[5D", "ed-prev-word", NULL); + el_set(e, EL_BIND, "\\e\\e[C", "em-next-word", NULL); + el_set(e, EL_BIND, "\\e\\e[D", "ed-prev-word", NULL); + /* read settings from configuration file */ el_source(e, NULL); @@ -320,15 +387,13 @@ rl_initialize(void) * 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; } @@ -437,7 +502,7 @@ _rl_compat_sub(const char *str, const char *what, const char *with, } else s++; } - r = result = malloc(len + 1); + r = result = el_malloc((len + 1) * sizeof(*r)); if (result == NULL) return NULL; s = str; @@ -448,13 +513,13 @@ _rl_compat_sub(const char *str, const char *what, const char *with, 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 */ @@ -471,14 +536,14 @@ get_history_event(const char *cmd, int *cindex, int qchar) 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 (history(h, &ev, H_FIRST) != 0) - return(NULL); + return NULL; *cindex = cmd[idx]? (idx + 1):idx; - return(ev.str); + return ev.str; } sign = 0; if (cmd[idx] == '-') { @@ -498,10 +563,10 @@ get_history_event(const char *cmd, int *cindex, int qchar) 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] == '?') { @@ -519,15 +584,15 @@ get_history_event(const char *cmd, int *cindex, int qchar) 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'; @@ -535,15 +600,15 @@ get_history_event(const char *cmd, int *cindex, int qchar) if (history(h, &ev, H_CURR) != 0) { if (pat != last_search_pat) - free(pat); - return (NULL); + el_free(pat); + return NULL; } num = ev.num; 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); @@ -555,21 +620,21 @@ get_history_event(const char *cmd, int *cindex, int qchar) 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 (history(h, &ev, H_CURR) != 0) - return(NULL); + return NULL; *cindex = idx; rptr = ev.str; @@ -621,7 +686,8 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, } 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'; @@ -632,17 +698,19 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, 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); + *result = strdup(aptr ? aptr : ptr); if (aptr) - free(aptr); - return(1); + el_free(aptr); + if (*result == NULL) + return -1; + return 1; } cmd = command + offs + idx + 1; @@ -687,18 +755,18 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, (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++) { @@ -710,7 +778,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, } 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 */ @@ -719,7 +787,7 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, } 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 */ @@ -736,10 +804,10 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, 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; @@ -748,11 +816,12 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, 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; @@ -762,17 +831,17 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, 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 */ @@ -780,10 +849,10 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, 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; @@ -792,10 +861,11 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, 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; @@ -818,14 +888,14 @@ _history_expand_command(const char *command, size_t offs, size_t cmdlen, aptr = _rl_compat_sub(tmp, from, to, g_on); if (aptr) { - free(tmp); + el_free(tmp); tmp = aptr; } g_on = 0; } } *result = tmp; - return (p_on? 2:1); + return p_on? 2:1; } @@ -844,13 +914,13 @@ history_expand(char *str, char **output) 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; @@ -867,11 +937,12 @@ history_expand(char *str, char **output) #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; \ @@ -938,7 +1009,7 @@ loop: ADD_STRING(tmp, len, 1); } if (tmp) { - free(tmp); + el_free(tmp); tmp = NULL; } i = j; @@ -955,10 +1026,10 @@ loop: ret = -1; #endif } - free(*output); + el_free(*output); *output = result; - return (ret); + return ret; } /* @@ -968,40 +1039,39 @@ char * history_arg_extract(int start, int end, const char *str) { size_t i, len, max; - char **arr, *result; + char **arr, *result = NULL; arr = history_tokenize(str); if (!arr) - return(NULL); - if (arr && *arr == NULL) { - free(arr); - return(NULL); - } + return NULL; + if (arr && *arr == NULL) + goto out; for (max = 0; arr[max]; max++) continue; max--; if (start == '$') - start = max; + start = (int)max; if (end == '$') - end = max; + end = (int)max; if (end < 0) - end = max + end + 1; + end = (int)max + end + 1; if (start < 0) start = end; - if (start < 0 || end < 0 || (size_t)start > max || (size_t)end > max || start > end) - return(NULL); + if (start < 0 || end < 0 || (size_t)start > max || + (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) - return 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) @@ -1009,11 +1079,12 @@ history_arg_extract(int start, int end, const char *str) } result[len] = '\0'; +out: for (i = 0; arr[i]; i++) - free(arr[i]); - free(arr); + el_free(arr[i]); + el_free(arr); - return(result); + return result; } /* @@ -1050,19 +1121,19 @@ history_tokenize(const char *str) 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); @@ -1072,7 +1143,7 @@ history_tokenize(const char *str) if (str[i]) i++; } - return (result); + return result; } @@ -1104,7 +1175,7 @@ unstifle_history(void) 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 */ } @@ -1113,7 +1184,146 @@ history_is_stifled(void) { /* cannot return true answer */ - return (max_input_history != INT_MAX); + return max_input_history != INT_MAX; +} + +static const char _history_tmp_template[] = "/tmp/.historyXXXXXX"; + +int +history_truncate_file (const char *filename, int nlines) +{ + int ret = 0; + FILE *fp, *tp; + char template[sizeof(_history_tmp_template)]; + char buf[4096]; + int fd; + char *cp; + off_t off; + int count = 0; + ssize_t left = 0; + + if (filename == NULL && (filename = _default_history_file()) == NULL) + return errno; + if ((fp = fopen(filename, "r+")) == NULL) + return errno; + strcpy(template, _history_tmp_template); + if ((fd = mkstemp(template)) == -1) { + ret = errno; + goto out1; + } + + if ((tp = fdopen(fd, "r+")) == NULL) { + close(fd); + ret = errno; + goto out2; + } + + for(;;) { + if (fread(buf, sizeof(buf), (size_t)1, fp) != 1) { + if (ferror(fp)) { + ret = errno; + break; + } + if (fseeko(fp, (off_t)sizeof(buf) * count, SEEK_SET) == + (off_t)-1) { + ret = errno; + break; + } + left = (ssize_t)fread(buf, (size_t)1, sizeof(buf), fp); + if (ferror(fp)) { + ret = errno; + break; + } + if (left == 0) { + count--; + left = sizeof(buf); + } else if (fwrite(buf, (size_t)left, (size_t)1, tp) + != 1) { + ret = errno; + break; + } + fflush(tp); + break; + } + if (fwrite(buf, sizeof(buf), (size_t)1, tp) != 1) { + ret = errno; + break; + } + count++; + } + if (ret) + goto out3; + cp = buf + left - 1; + if(*cp != '\n') + cp++; + for(;;) { + while (--cp >= buf) { + if (*cp == '\n') { + if (--nlines == 0) { + if (++cp >= buf + sizeof(buf)) { + count++; + cp = buf; + } + break; + } + } + } + if (nlines <= 0 || count == 0) + break; + count--; + if (fseeko(tp, (off_t)sizeof(buf) * count, SEEK_SET) < 0) { + ret = errno; + break; + } + if (fread(buf, sizeof(buf), (size_t)1, tp) != 1) { + if (ferror(tp)) { + ret = errno; + break; + } + ret = EAGAIN; + break; + } + cp = buf + sizeof(buf); + } + + if (ret || nlines > 0) + goto out3; + + if (fseeko(fp, (off_t)0, SEEK_SET) == (off_t)-1) { + ret = errno; + goto out3; + } + + if (fseeko(tp, (off_t)sizeof(buf) * count + (cp - buf), SEEK_SET) == + (off_t)-1) { + ret = errno; + goto out3; + } + + for(;;) { + 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, (size_t)1, fp) != 1) { + ret = errno; + break; + } + } + fflush(fp); + if((off = ftello(fp)) > 0) { + if (ftruncate(fileno(fp), off) == -1) + ret = errno; + } +out3: + fclose(tp); +out2: + unlink(template); +out1: + fclose(fp); + + return ret; } @@ -1127,7 +1337,10 @@ read_history(const char *filename) if (h == NULL || e == NULL) rl_initialize(); - return (history(h, &ev, H_LOAD, filename) == -1); + if (filename == NULL && (filename = _default_history_file()) == NULL) + return errno; + return history(h, &ev, H_LOAD, filename) == -1 ? + (errno ? errno : EINVAL) : 0; } @@ -1141,7 +1354,10 @@ write_history(const char *filename) if (h == NULL || e == NULL) rl_initialize(); - return (history(h, &ev, H_SAVE, filename) == -1); + if (filename == NULL && (filename = _default_history_file()) == NULL) + return errno; + return history(h, &ev, H_SAVE, filename) == -1 ? + (errno ? errno : EINVAL) : 0; } @@ -1162,24 +1378,23 @@ history_get(int num) /* save current position */ if (history(h, &ev, H_CURR) != 0) - return (NULL); + return NULL; curr_num = ev.num; - /* start from most recent */ - if (history(h, &ev, H_FIRST) != 0) - return (NULL); /* error */ + /* start from the oldest */ + if (history(h, &ev, H_LAST) != 0) + return NULL; /* error */ - /* look backwards for event matching specified offset */ - if (history(h, &ev, H_NEXT_EVENT, num + 1)) - return (NULL); + /* look forwards for event matching specified offset */ + if (history(h, &ev, H_NEXT_EVDATA, num, &she.data)) + return NULL; she.line = ev.str; - she.data = NULL; /* restore pointer to where it was */ (void)history(h, &ev, H_SET, curr_num); - return (&she); + return &she; } @@ -1198,7 +1413,7 @@ add_history(const char *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 */ } @@ -1208,26 +1423,75 @@ add_history(const char *line) HIST_ENTRY * remove_history(int num) { - HIST_ENTRY *she; + HIST_ENTRY *he; HistEvent ev; if (h == NULL || e == NULL) rl_initialize(); - if (history(h, &ev, H_DEL, num) != 0) + if ((he = el_malloc(sizeof(*he))) == NULL) return NULL; - if ((she = malloc(sizeof(*she))) == NULL) + if (history(h, &ev, H_DELDATA, num, &he->data) != 0) { + el_free(he); return NULL; + } - she->line = ev.str; - she->data = NULL; + he->line = ev.str; + if (history(h, &ev, H_GETSIZE) == 0) + history_length = ev.num; - return she; + return he; } /* + * replace the line and data of the num-th entry + */ +HIST_ENTRY * +replace_history_entry(int num, const char *line, histdata_t data) +{ + HIST_ENTRY *he; + HistEvent ev; + int curr_num; + + if (h == NULL || e == NULL) + rl_initialize(); + + /* save current position */ + if (history(h, &ev, H_CURR) != 0) + return NULL; + curr_num = ev.num; + + /* start from the oldest */ + if (history(h, &ev, H_LAST) != 0) + return NULL; /* error */ + + if ((he = el_malloc(sizeof(*he))) == NULL) + return NULL; + + /* look forwards for event matching specified offset */ + if (history(h, &ev, H_NEXT_EVDATA, num, &he->data)) + goto out; + + he->line = strdup(ev.str); + if (he->line == NULL) + goto out; + + if (history(h, &ev, H_REPLACE, line, data)) + goto out; + + /* restore pointer to where it was */ + if (history(h, &ev, H_SET, curr_num)) + goto out; + + return he; +out: + el_free(he); + return NULL; +} + +/* * clear the history list - delete all entries */ void @@ -1235,7 +1499,8 @@ clear_history(void) { HistEvent ev; - history(h, &ev, H_CLEAR); + (void)history(h, &ev, H_CLEAR); + history_length = 0; } @@ -1249,15 +1514,15 @@ where_history(void) int curr_num, off; if (history(h, &ev, H_CURR) != 0) - return (0); + return 0; curr_num = ev.num; - history(h, &ev, H_FIRST); + (void)history(h, &ev, H_FIRST); off = 1; while (ev.num != curr_num && history(h, &ev, H_NEXT) == 0) off++; - return (off); + return off; } @@ -1268,7 +1533,7 @@ HIST_ENTRY * current_history(void) { - return (_move_history(H_CURR)); + return _move_history(H_CURR); } @@ -1279,22 +1544,23 @@ int history_total_bytes(void) { HistEvent ev; - int curr_num, size; + int curr_num; + size_t size; if (history(h, &ev, H_CURR) != 0) - return (-1); + return -1; curr_num = ev.num; - history(h, &ev, H_FIRST); + (void)history(h, &ev, H_FIRST); size = 0; do - size += strlen(ev.str); + size += strlen(ev.str) * sizeof(*ev.str); while (history(h, &ev, H_NEXT) == 0); /* get to the same position as before */ history(h, &ev, H_PREV_EVENT, curr_num); - return (size); + return (int)size; } @@ -1307,17 +1573,21 @@ history_set_pos(int pos) HistEvent ev; int curr_num; - if (pos > history_length || pos < 0) - return (-1); + if (pos >= history_length || pos < 0) + return -1; - history(h, &ev, H_CURR); + (void)history(h, &ev, H_CURR); curr_num = ev.num; - if (history(h, &ev, H_SET, pos)) { - history(h, &ev, H_SET, curr_num); - return(-1); + /* + * use H_DELDATA to set to nth history (without delete) by passing + * (void **)-1 + */ + if (history(h, &ev, H_DELDATA, pos, (void **)-1)) { + (void)history(h, &ev, H_SET, curr_num); + return -1; } - return (0); + return 0; } @@ -1328,7 +1598,7 @@ HIST_ENTRY * previous_history(void) { - return (_move_history(H_PREV)); + return _move_history(H_PREV); } @@ -1339,7 +1609,7 @@ HIST_ENTRY * next_history(void) { - return (_move_history(H_NEXT)); + return _move_history(H_NEXT); } @@ -1354,17 +1624,17 @@ history_search(const char *str, int direction) int curr_num; if (history(h, &ev, H_CURR) != 0) - return (-1); + return -1; curr_num = ev.num; for (;;) { if ((strp = strstr(ev.str, str)) != NULL) - return (int) (strp - ev.str); + return (int)(strp - ev.str); if (history(h, &ev, direction < 0 ? H_NEXT:H_PREV) != 0) break; } - history(h, &ev, H_SET, curr_num); - return (-1); + (void)history(h, &ev, H_SET, curr_num); + return -1; } @@ -1376,7 +1646,8 @@ history_search_prefix(const char *str, int direction) { HistEvent ev; - return (history(h, &ev, direction < 0? H_PREV_STR:H_NEXT_STR, str)); + return (history(h, &ev, direction < 0 ? + H_PREV_STR : H_NEXT_STR, str)); } @@ -1396,24 +1667,24 @@ history_search_pos(const char *str, pos = (pos > 0) ? 1 : -1; if (history(h, &ev, H_CURR) != 0) - return (-1); + return -1; curr_num = ev.num; if (history_set_pos(off) != 0 || history(h, &ev, H_CURR) != 0) - return (-1); - + return -1; for (;;) { if (strstr(ev.str, str)) - return (off); + return off; if (history(h, &ev, (pos < 0) ? H_PREV : H_NEXT) != 0) break; } /* set "current" pointer back to previous state */ - history(h, &ev, (pos < 0) ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); + (void)history(h, &ev, + pos < 0 ? H_NEXT_EVENT : H_PREV_EVENT, curr_num); - return (-1); + return -1; } @@ -1436,16 +1707,20 @@ filename_completion_function(const char *name, int state) * 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; +#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++; @@ -1453,15 +1728,21 @@ username_completion_function(const char *text, int state) if (state == 0) setpwent(); - /* XXXMYSQL: just use non-_r functions for now */ - while ((pwd = getpwent()) && 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 NULL; } - return (strdup(pwd->pw_name)); + return strdup(pass->pw_name); } @@ -1485,7 +1766,7 @@ void rl_display_match_list(char **matches, int len, int max) { - fn_display_match_list(e, matches, len, max); + fn_display_match_list(e, matches, (size_t)len, (size_t)max); } static const char * @@ -1494,7 +1775,7 @@ _rl_completion_append_character_function(const char *dummy __attribute__((__unused__))) { static char buf[2]; - buf[0] = rl_completion_append_character; + buf[0] = (char)rl_completion_append_character; buf[1] = '\0'; return buf; } @@ -1507,6 +1788,10 @@ _rl_completion_append_character_function(const char *dummy int rl_complete(int ignore __attribute__((__unused__)), int invoking_key) { +#ifdef WIDECHAR + static ct_buffer_t wbreak_conv, sprefix_conv; +#endif + if (h == NULL || e == NULL) rl_initialize(); @@ -1515,17 +1800,21 @@ rl_complete(int ignore __attribute__((__unused__)), int invoking_key) arr[0] = (char)invoking_key; arr[1] = '\0'; el_insertstr(e, arr); - return (CC_REFRESH); + return CC_REFRESH; } /* Just look at how many global variables modify this operation! */ return fn_complete(e, (CPFunction *)rl_completion_entry_function, rl_attempted_completion_function, - rl_basic_word_break_characters, rl_special_prefixes, - _rl_completion_append_character_function, rl_completion_query_items, + ct_decode_string(rl_basic_word_break_characters, &wbreak_conv), + ct_decode_string(rl_special_prefixes, &sprefix_conv), + _rl_completion_append_character_function, + (size_t)rl_completion_query_items, &rl_completion_type, &rl_attempted_completion_over, &rl_point, &rl_end); + + } @@ -1544,7 +1833,7 @@ _el_rl_complete(EditLine *el __attribute__((__unused__)), int ch) * bind key c to readline-type function func */ int -rl_bind_key(int c, int func(int, int)) +rl_bind_key(int c, rl_command_func_t *func) { int retval = -1; @@ -1556,7 +1845,7 @@ rl_bind_key(int c, int func(int, int)) e->el_map.key[c] = ED_INSERT; retval = 0; } - return (retval); + return retval; } @@ -1572,7 +1861,7 @@ rl_read_key(void) if (e == NULL || h == NULL) rl_initialize(); - return (el_getc(e, fooarr)); + return el_getc(e, fooarr); } @@ -1602,19 +1891,33 @@ rl_insert(int count, int c) 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 +rl_insert_text(const char *text) +{ + if (!text || *text == 0) + return 0; + + if (h == NULL || e == NULL) + rl_initialize(); + + if (el_insertstr(e, text) < 0) + return 0; + return (int)strlen(text); } /*ARGSUSED*/ int rl_newline(int count __attribute__((__unused__)), - int c __attribute__((__unused__))) + int c __attribute__((__unused__))) { /* * Readline-4.0 appears to ignore the args. @@ -1675,7 +1978,7 @@ rl_callback_read_char() } else wbuf = NULL; (*(void (*)(const char *))rl_linefunc)(wbuf); - el_set(e, EL_UNBUFFERED, 1); + //el_set(e, EL_UNBUFFERED, 1); } } @@ -1701,7 +2004,7 @@ void 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); } @@ -1710,7 +2013,7 @@ int 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); @@ -1733,7 +2036,7 @@ rl_deprep_terminal(void) int rl_read_init_file(const char *s) { - return(el_source(e, s)); + return el_source(e, s); } int @@ -1747,7 +2050,7 @@ rl_parse_and_bind(const char *line) tok_str(tok, line, &argc, &argv); argc = el_parse(e, argc, argv); tok_end(tok); - return (argc ? 1 : 0); + return argc ? 1 : 0; } int @@ -1757,7 +2060,7 @@ rl_variable_bind(const char *var, const char *value) * 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) == -1 ? 1 : 0; } void @@ -1765,7 +2068,7 @@ rl_stuff_char(int c) { char buf[2]; - buf[0] = c; + buf[0] = (char)c; buf[1] = '\0'; el_insertstr(e, buf); } @@ -1773,7 +2076,8 @@ rl_stuff_char(int c) static int _rl_event_read_char(EditLine *el, char *cp) { - int n, num_read = 0; + int n; + ssize_t num_read = 0; *cp = '\0'; while (rl_event_hook) { @@ -1782,23 +2086,23 @@ _rl_event_read_char(EditLine *el, char *cp) #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) @@ -1809,7 +2113,7 @@ _rl_event_read_char(EditLine *el, char *cp) } if (!rl_event_hook) el_set(el, EL_GETCFN, EL_BUILTIN_GETCFN); - return(num_read); + return (int)num_read; } static void @@ -1817,8 +2121,8 @@ _rl_update_pos(void) { const LineInfo *li = el_line(e); - rl_point = li->cursor - li->buffer; - rl_end = li->lastchar - li->buffer; + rl_point = (int)(li->cursor - li->buffer); + rl_end = (int)(li->lastchar - li->buffer); } void @@ -1848,18 +2152,18 @@ rl_completion_matches(const char *str, rl_compentry_func_t *fun) 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) { + list[len++] = match; 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; } - list[len++] = match; } if (len == 1) goto out; @@ -1883,7 +2187,7 @@ rl_completion_matches(const char *str, rl_compentry_func_t *fun) 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'; @@ -1891,7 +2195,7 @@ rl_completion_matches(const char *str, rl_compentry_func_t *fun) return list; out: - free(list); + el_free(list); return NULL; } @@ -1921,10 +2225,21 @@ _rl_qsort_string_compare(char **s1, char **s2) return strcoll(*s1, *s2); } +HISTORY_STATE * +history_get_history_state(void) +{ + HISTORY_STATE *hs; + + if ((hs = el_malloc(sizeof(*hs))) == NULL) + return NULL; + hs->length = history_length; + return hs; +} + int /*ARGSUSED*/ rl_kill_text(int from __attribute__((__unused__)), - int to __attribute__((__unused__))) + int to __attribute__((__unused__))) { return 0; } @@ -1950,9 +2265,9 @@ rl_set_keymap(Keymap k __attribute__((__unused__))) int /*ARGSUSED*/ rl_generic_bind(int type __attribute__((__unused__)), - const char * keyseq __attribute__((__unused__)), - const char * data __attribute__((__unused__)), - Keymap k __attribute__((__unused__))) + const char * keyseq __attribute__((__unused__)), + const char * data __attribute__((__unused__)), + Keymap k __attribute__((__unused__))) { return 0; } @@ -1960,8 +2275,20 @@ rl_generic_bind(int type __attribute__((__unused__)), int /*ARGSUSED*/ rl_bind_key_in_map(int key __attribute__((__unused__)), - Function *fun __attribute__((__unused__)), - Keymap k __attribute__((__unused__))) + rl_command_func_t *fun __attribute__((__unused__)), + Keymap k __attribute__((__unused__))) +{ + return 0; +} + +/* unsupported, but needed by python */ +void +rl_cleanup_after_signal(void) +{ +} + +int +rl_on_new_line(void) { return 0; } diff --git a/cmd-line-utils/libedit/readline/readline.h b/cmd-line-utils/libedit/readline/readline.h index 0e300faed89..d9efe3e01a8 100644 --- a/cmd-line-utils/libedit/readline/readline.h +++ b/cmd-line-utils/libedit/readline/readline.h @@ -1,4 +1,4 @@ -/* $NetBSD: readline.h,v 1.24 2009/02/05 19:15:26 christos Exp $ */ +/* $NetBSD: readline.h,v 1.32 2010/09/16 20:08:52 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -32,6 +32,7 @@ #define _READLINE_H_ #include <sys/types.h> +#include <stdio.h> /* list of readline stuff supported by editline library's readline wrapper */ @@ -42,10 +43,18 @@ typedef void VCPFunction(char *); typedef char *CPFunction(const char *, int); typedef char **CPPFunction(const char *, int, int); typedef char *rl_compentry_func_t(const char *, int); +typedef int rl_command_func_t(int, int); + +/* only supports length */ +typedef struct { + int length; +} HISTORY_STATE; + +typedef void *histdata_t; typedef struct _hist_entry { const char *line; - const char *data; + histdata_t data; } HIST_ENTRY; typedef struct _keymap_entry { @@ -79,12 +88,16 @@ typedef KEYMAP_ENTRY *Keymap; #define RUBOUT 0x7f #define ABORT_CHAR CTRL('G') +#define RL_READLINE_VERSION 0x0402 +#define RL_PROMPT_START_IGNORE '\1' +#define RL_PROMPT_END_IGNORE '\2' /* global variables used by readline enabled applications */ #ifdef __cplusplus extern "C" { #endif extern const char *rl_library_version; +extern int rl_readline_version; extern char *rl_readline_name; extern FILE *rl_instream; extern FILE *rl_outstream; @@ -138,6 +151,7 @@ int where_history(void); HIST_ENTRY *current_history(void); HIST_ENTRY *history_get(int); HIST_ENTRY *remove_history(int); +HIST_ENTRY *replace_history_entry(int, const char *, histdata_t); int history_total_bytes(void); int history_set_pos(int); HIST_ENTRY *previous_history(void); @@ -147,6 +161,7 @@ int history_search_prefix(const char *, int); int history_search_pos(const char *, int, int); int read_history(const char *); int write_history(const char *); +int history_truncate_file (const char *, int); int history_expand(char *, char **); char **history_tokenize(const char *); const char *get_history_event(const char *, int *, int); @@ -161,8 +176,9 @@ char **completion_matches(const char *, CPFunction *); void rl_display_match_list(char **, int, int); int rl_insert(int, int); +int rl_insert_text(const char *); void rl_reset_terminal(const char *); -int rl_bind_key(int, int (*)(int, int)); +int rl_bind_key(int, rl_command_func_t *); int rl_newline(int, int); void rl_callback_read_char(void); void rl_callback_handler_install(const char *, VCPFunction *); @@ -176,6 +192,7 @@ int rl_parse_and_bind(const char *); int rl_variable_bind(const char *, const char *); void rl_stuff_char(int); int rl_add_defun(const char *, Function *, int); +HISTORY_STATE *history_get_history_state(void); void rl_get_screen_size(int *, int *); void rl_set_screen_size(int, int); char *rl_filename_completion_function (const char *, int); @@ -184,6 +201,7 @@ 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 *); +int rl_on_new_line(void); /* * The following are not implemented @@ -193,7 +211,9 @@ Keymap rl_get_keymap(void); void rl_set_keymap(Keymap); Keymap rl_make_bare_keymap(void); int rl_generic_bind(int, const char *, const char *, Keymap); -int rl_bind_key_in_map(int, Function *, Keymap); +int rl_bind_key_in_map(int, rl_command_func_t *, Keymap); +void rl_cleanup_after_signal(void); +void rl_free_line_state(void); #ifdef __cplusplus } #endif diff --git a/cmd-line-utils/libedit/refresh.c b/cmd-line-utils/libedit/refresh.c index 5edd1fe78fc..64057eaabfe 100644 --- a/cmd-line-utils/libedit/refresh.c +++ b/cmd-line-utils/libedit/refresh.c @@ -1,4 +1,4 @@ -/* $NetBSD: refresh.c,v 1.28 2008/09/10 15:45:37 christos Exp $ */ +/* $NetBSD: refresh.c,v 1.37 2011/07/29 23:44:45 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -50,14 +50,15 @@ static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93"; #include "el.h" -private void re_addc(EditLine *, int); -private void re_update_line(EditLine *, char *, char *, int); -private void re_insert (EditLine *, char *, int, int, char *, int); -private void re_delete(EditLine *, char *, int, int, int); -private void re_fastputc(EditLine *, int); +private void re_nextline(EditLine *); +private void re_addc(EditLine *, Int); +private void re_update_line(EditLine *, Char *, Char *, int); +private void re_insert (EditLine *, Char *, int, int, Char *, int); +private void re_delete(EditLine *, Char *, int, int, int); +private void re_fastputc(EditLine *, Int); private void re_clear_eol(EditLine *, int, int, int); -private void re__strncopy(char *, char *, size_t); -private void re__copy_and_pad(char *, const char *, size_t); +private void re__strncopy(Char *, Char *, size_t); +private void re__copy_and_pad(Char *, const Char *, size_t); #ifdef DEBUG_REFRESH private void re_printstr(EditLine *, const char *, char *, char *); @@ -87,45 +88,70 @@ re_printstr(EditLine *el, const char *str, char *f, char *t) #define ELRE_DEBUG(a, b) #endif +/* re_nextline(): + * Move to the next line or scroll + */ +private void +re_nextline(EditLine *el) +{ + el->el_refresh.r_cursor.h = 0; /* reset it. */ + + /* + * If we would overflow (input is longer than terminal size), + * emulate scroll by dropping first line and shuffling the rest. + * We do this via pointer shuffling - it's safe in this case + * and we avoid memcpy(). + */ + if (el->el_refresh.r_cursor.v + 1 >= el->el_terminal.t_size.v) { + int i, lins = el->el_terminal.t_size.v; + Char *firstline = el->el_vdisplay[0]; + + for(i = 1; i < lins; i++) + el->el_vdisplay[i - 1] = el->el_vdisplay[i]; + + firstline[0] = '\0'; /* empty the string */ + el->el_vdisplay[i - 1] = firstline; + } else + el->el_refresh.r_cursor.v++; + + ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_terminal.t_size.v, + (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n", + el->el_refresh.r_cursor.v, el->el_terminal.t_size.v), + abort()); +} /* re_addc(): * Draw c, expanding tabs, control chars etc. */ private void -re_addc(EditLine *el, int c) +re_addc(EditLine *el, Int c) { - - if (el_isprint(c)) { - re_putc(el, c, 1); - return; - } - if (c == '\n') { /* expand the newline */ - int oldv = el->el_refresh.r_cursor.v; - re_putc(el, '\0', 0); /* assure end of line */ - if (oldv == el->el_refresh.r_cursor.v) { /* XXX */ - el->el_refresh.r_cursor.h = 0; /* reset cursor pos */ - el->el_refresh.r_cursor.v++; - } - return; - } - if (c == '\t') { /* expand the tab */ + switch (ct_chr_class((Char)c)) { + case CHTYPE_TAB: /* expand the tab */ for (;;) { re_putc(el, ' ', 1); if ((el->el_refresh.r_cursor.h & 07) == 0) break; /* go until tab stop */ } - } else if (iscntrl(c)) { - re_putc(el, '^', 1); - if (c == '\177') - re_putc(el, '?', 1); - else - /* uncontrolify it; works only for iso8859-1 like sets */ - re_putc(el, (c | 0100), 1); - } else { - re_putc(el, '\\', 1); - re_putc(el, (int) ((((unsigned int) c >> 6) & 07) + '0'), 1); - re_putc(el, (int) ((((unsigned int) c >> 3) & 07) + '0'), 1); - re_putc(el, (c & 07) + '0', 1); + break; + case CHTYPE_NL: { + int oldv = el->el_refresh.r_cursor.v; + re_putc(el, '\0', 0); /* assure end of line */ + if (oldv == el->el_refresh.r_cursor.v) /* XXX */ + re_nextline(el); + break; + } + case CHTYPE_PRINT: + re_putc(el, c, 1); + break; + default: { + Char visbuf[VISUAL_WIDTH_MAX]; + ssize_t i, n = + ct_visual_char(visbuf, VISUAL_WIDTH_MAX, (Char)c); + for (i = 0; n-- > 0; ++i) + re_putc(el, visbuf[i], 1); + break; + } } } @@ -134,43 +160,31 @@ re_addc(EditLine *el, int c) * Draw the character given */ protected void -re_putc(EditLine *el, int c, int shift) +re_putc(EditLine *el, Int c, int shift) { + int i, w = Width(c); + ELRE_DEBUG(1, (__F, "printing %5x '%c'\r\n", c, c)); + + while (shift && (el->el_refresh.r_cursor.h + w > el->el_terminal.t_size.h)) + re_putc(el, ' ', 1); - ELRE_DEBUG(1, (__F, "printing %3.3o '%c'\r\n", c, c)); + el->el_vdisplay[el->el_refresh.r_cursor.v] + [el->el_refresh.r_cursor.h] = c; + /* assumes !shift is only used for single-column chars */ + i = w; + while (--i > 0) + el->el_vdisplay[el->el_refresh.r_cursor.v] + [el->el_refresh.r_cursor.h + i] = MB_FILL_CHAR; - el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_refresh.r_cursor.h] = c; if (!shift) return; - el->el_refresh.r_cursor.h++; /* advance to next place */ - if (el->el_refresh.r_cursor.h >= el->el_term.t_size.h) { - el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_term.t_size.h] = '\0'; + 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_refresh.r_cursor.h = 0; /* reset it. */ - - /* - * If we would overflow (input is longer than terminal size), - * emulate scroll by dropping first line and shuffling the rest. - * We do this via pointer shuffling - it's safe in this case - * and we avoid memcpy(). - */ - if (el->el_refresh.r_cursor.v + 1 >= el->el_term.t_size.v) { - int i, lins = el->el_term.t_size.v; - char *firstline = el->el_vdisplay[0]; - - for(i=1; i < lins; i++) - el->el_vdisplay[i-1] = el->el_vdisplay[i]; - - firstline[0] = '\0'; /* empty the string */ - el->el_vdisplay[i-1] = firstline; - } else - el->el_refresh.r_cursor.v++; - - ELRE_ASSERT(el->el_refresh.r_cursor.v >= el->el_term.t_size.v, - (__F, "\r\nre_putc: overflow! r_cursor.v == %d > %d\r\n", - el->el_refresh.r_cursor.v, el->el_term.t_size.v), - abort()); + el->el_vdisplay[el->el_refresh.r_cursor.v][el->el_terminal.t_size.h] + = '\0'; + re_nextline(el); } } @@ -185,7 +199,7 @@ protected void re_refresh(EditLine *el) { int i, rhdiff; - char *cp, *st; + Char *cp, *st; coord_t cur; #ifdef notyet size_t termsz; @@ -220,7 +234,7 @@ re_refresh(EditLine *el) /* 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 @@ -229,26 +243,33 @@ re_refresh(EditLine *el) 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; 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 */ 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) { @@ -271,8 +292,8 @@ re_refresh(EditLine *el) ELRE_DEBUG(1, (__F, "term.h=%d vcur.h=%d vcur.v=%d vdisplay[0]=\r\n:%80.80s:\r\n", - el->el_term.t_size.h, el->el_refresh.r_cursor.h, - el->el_refresh.r_cursor.v, el->el_vdisplay[0])); + el->el_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++) { @@ -287,7 +308,7 @@ re_refresh(EditLine *el) * 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", @@ -295,11 +316,12 @@ re_refresh(EditLine *el) 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", 2); + terminal_overwrite(el, "C\b", (size_t)2); #endif /* DEBUG_REFRESH */ el->el_display[i][0] = '\0'; } @@ -309,8 +331,8 @@ re_refresh(EditLine *el) "\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); } @@ -321,10 +343,10 @@ protected void 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); } @@ -335,9 +357,9 @@ re_goto_bottom(EditLine *el) private void /*ARGSUSED*/ re_insert(EditLine *el __attribute__((__unused__)), - char *d, int dat, int dlen, char *s, int num) + Char *d, int dat, int dlen, Char *s, int num) { - char *a, *b; + Char *a, *b; if (num <= 0) return; @@ -346,8 +368,8 @@ re_insert(EditLine *el __attribute__((__unused__)), ELRE_DEBUG(1, (__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, d)); - ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); + num, dat, dlen, ct_encode_string(d))); + ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s))); /* open up the space for num chars */ if (num > 0) { @@ -357,19 +379,24 @@ re_insert(EditLine *el __attribute__((__unused__)), *b-- = *a--; d[dlen] = '\0'; /* just in case */ } + ELRE_DEBUG(1, (__F, "re_insert() after insert: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, d)); - ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); + num, dat, dlen, ct_encode_string(d))); + ELRE_DEBUG(1, (__F, "s == \"%s\"\n", ct_encode_string(s))); /* copy the characters */ for (a = d + dat; (a < d + dlen) && (num > 0); num--) *a++ = *s++; +#ifdef notyet + /* ct_encode_string() uses a static buffer, so we can't conveniently + * encode both d & s here */ ELRE_DEBUG(1, (__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n", num, dat, dlen, d, s)); ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s)); +#endif } @@ -379,9 +406,9 @@ re_insert(EditLine *el __attribute__((__unused__)), private void /*ARGSUSED*/ re_delete(EditLine *el __attribute__((__unused__)), - char *d, int dat, int dlen, int num) + Char *d, int dat, int dlen, int num) { - char *a, *b; + Char *a, *b; if (num <= 0) return; @@ -391,7 +418,7 @@ re_delete(EditLine *el __attribute__((__unused__)), } ELRE_DEBUG(1, (__F, "re_delete() starting: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, d)); + num, dat, dlen, ct_encode_string(d))); /* open up the space for num chars */ if (num > 0) { @@ -403,7 +430,7 @@ re_delete(EditLine *el __attribute__((__unused__)), } ELRE_DEBUG(1, (__F, "re_delete() after delete: %d at %d max %d, d == \"%s\"\n", - num, dat, dlen, d)); + num, dat, dlen, ct_encode_string(d))); } @@ -411,7 +438,7 @@ re_delete(EditLine *el __attribute__((__unused__)), * Like strncpy without padding. */ private void -re__strncopy(char *a, char *b, size_t n) +re__strncopy(Char *a, Char *b, size_t n) { while (n-- && *b) @@ -422,7 +449,7 @@ re__strncopy(char *a, char *b, size_t n) * Find the number of characters we need to clear till the end of line * in order to make sure that we have cleared the previous contents of * the line. fx and sx is the number of characters inserted or deleted - * int the first or second diff, diff is the difference between the + * in the first or second diff, diff is the difference between the * number of characters between the new and old line. */ private void @@ -442,7 +469,7 @@ re_clear_eol(EditLine *el, int fx, int sx, int diff) diff = sx; ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff)); - term_clear_EOL(el, diff); + terminal_clear_EOL(el, diff); } /***************************************************************** @@ -470,12 +497,13 @@ new: eddie> Oh, my little buggy says to me, as lurgid as #define MIN_END_KEEP 4 private void -re_update_line(EditLine *el, char *old, char *new, int i) +re_update_line(EditLine *el, Char *old, Char *new, int i) { - char *o, *n, *p, c; - char *ofd, *ols, *oe, *nfd, *nls, *ne; - char *osb, *ose, *nsb, *nse; + Char *o, *n, *p, c; + Char *ofd, *ols, *oe, *nfd, *nls, *ne; + Char *osb, *ose, *nsb, *nse; int fx, sx; + size_t len; /* * find first diff @@ -602,12 +630,12 @@ re_update_line(EditLine *el, char *old, char *new, int i) * fx is the number of characters we need to insert/delete: in the * beginning to bring the two same begins together */ - fx = (nsb - nfd) - (osb - ofd); + fx = (int)((nsb - nfd) - (osb - ofd)); /* * sx is the number of characters we need to insert/delete: in the * end to bring the two same last parts together */ - sx = (nls - nse) - (ols - ose); + sx = (int)((nls - nse) - (ols - ose)); if (!EL_CAN_INSERT) { if (fx > 0) { @@ -656,8 +684,8 @@ re_update_line(EditLine *el, char *old, char *new, int i) /* * Now that we are done with pragmatics we recompute fx, sx */ - fx = (nsb - nfd) - (osb - ofd); - sx = (nls - nse) - (ols - ose); + fx = (int)((nsb - nfd) - (osb - ofd)); + sx = (int)((nls - nse) - (ols - ose)); ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx)); ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n", @@ -688,7 +716,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) * don't have to change the line, we don't move to it. el_cursor.h to * first diff char */ - term_move_to_line(el, i); + terminal_move_to_line(el, i); /* * at this point we have something like this: @@ -712,7 +740,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) * if we have a net insert on the first difference, AND inserting the * 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. */ @@ -734,13 +762,13 @@ re_update_line(EditLine *el, char *old, char *new, int i) * 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, nfd - new); + terminal_move_to_char(el, (int)(nfd - new)); /* * Check if we have stuff to keep at end */ @@ -752,21 +780,22 @@ re_update_line(EditLine *el, char *old, char *new, int i) if (fx > 0) { ELRE_DEBUG(!EL_CAN_INSERT, (__F, "ERROR: cannot insert in early first diff\n")); - term_insertwrite(el, nfd, fx); - re_insert(el, old, ofd - old, - el->el_term.t_size.h, nfd, fx); + terminal_insertwrite(el, nfd, fx); + re_insert(el, old, (int)(ofd - old), + el->el_terminal.t_size.h, nfd, fx); } /* * write (nsb-nfd) - fx chars of new starting at * (nfd + fx) */ - term_overwrite(el, nfd + fx, (nsb - nfd) - fx); - re__strncopy(ofd + fx, nfd + fx, - (size_t) ((nsb - nfd) - fx)); + len = (size_t) ((nsb - nfd) - fx); + terminal_overwrite(el, (nfd + fx), len); + re__strncopy(ofd + fx, nfd + fx, len); } else { ELRE_DEBUG(1, (__F, "without anything to save\r\n")); - term_overwrite(el, nfd, (nsb - nfd)); - re__strncopy(ofd, nfd, (size_t) (nsb - nfd)); + len = (size_t)(nsb - nfd); + terminal_overwrite(el, nfd, len); + re__strncopy(ofd, nfd, len); /* * Done */ @@ -778,7 +807,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) /* * move to the first char to delete where the first diff is */ - term_move_to_char(el, ofd - old); + terminal_move_to_char(el, (int)(ofd - old)); /* * Check if we have stuff to save */ @@ -791,15 +820,16 @@ re_update_line(EditLine *el, char *old, char *new, int i) if (fx < 0) { ELRE_DEBUG(!EL_CAN_DELETE, (__F, "ERROR: cannot delete in first diff\n")); - term_deletechars(el, -fx); - re_delete(el, old, ofd - old, - el->el_term.t_size.h, -fx); + terminal_deletechars(el, -fx); + re_delete(el, old, (int)(ofd - old), + el->el_terminal.t_size.h, -fx); } /* * write (nsb-nfd) chars of new starting at nfd */ - term_overwrite(el, nfd, (nsb - nfd)); - re__strncopy(ofd, nfd, (size_t) (nsb - nfd)); + len = (size_t) (nsb - nfd); + terminal_overwrite(el, nfd, len); + re__strncopy(ofd, nfd, len); } else { ELRE_DEBUG(1, (__F, @@ -807,8 +837,9 @@ re_update_line(EditLine *el, char *old, char *new, int i) /* * write (nsb-nfd) chars of new starting at nfd */ - term_overwrite(el, nfd, (nsb - nfd)); - re_clear_eol(el, fx, sx, (oe - old) - (ne - new)); + terminal_overwrite(el, nfd, (size_t)(nsb - nfd)); + re_clear_eol(el, fx, sx, + (int)((oe - old) - (ne - new))); /* * Done */ @@ -817,7 +848,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) } 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)); /* @@ -827,7 +858,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) * fx is the number of characters inserted (+) or deleted (-) */ - term_move_to_char(el, (ose - old) + fx); + terminal_move_to_char(el, (int)((ose - old) + fx)); /* * Check if we have stuff to save */ @@ -839,17 +870,18 @@ re_update_line(EditLine *el, char *old, char *new, int i) 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, (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, (nls - nse)); - re_clear_eol(el, fx, sx, (oe - old) - (ne - new)); + terminal_overwrite(el, nse, (size_t)(nls - nse)); + re_clear_eol(el, fx, sx, + (int)((oe - old) - (ne - new))); } } /* @@ -859,7 +891,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) ELRE_DEBUG(1, (__F, "late first diff insert at %d...\r\n", nfd - new)); - term_move_to_char(el, nfd - new); + terminal_move_to_char(el, (int)(nfd - new)); /* * Check if we have stuff to keep at the end */ @@ -870,28 +902,29 @@ re_update_line(EditLine *el, char *old, char *new, int i) * to zero above as a flag saying that we hadn't done * an early first insert. */ - fx = (nsb - nfd) - (osb - ofd); + fx = (int)((nsb - nfd) - (osb - ofd)); if (fx > 0) { /* * insert fx chars of new starting at nfd */ ELRE_DEBUG(!EL_CAN_INSERT, (__F, "ERROR: cannot insert in late first diff\n")); - term_insertwrite(el, nfd, fx); - re_insert(el, old, ofd - old, - el->el_term.t_size.h, nfd, fx); + terminal_insertwrite(el, nfd, fx); + re_insert(el, old, (int)(ofd - old), + el->el_terminal.t_size.h, nfd, fx); } /* * write (nsb-nfd) - fx chars of new starting at * (nfd + fx) */ - term_overwrite(el, nfd + fx, (nsb - nfd) - fx); - re__strncopy(ofd + fx, nfd + fx, - (size_t) ((nsb - nfd) - fx)); + len = (size_t) ((nsb - nfd) - fx); + terminal_overwrite(el, (nfd + fx), len); + re__strncopy(ofd + fx, nfd + fx, len); } else { ELRE_DEBUG(1, (__F, "without anything to save\r\n")); - term_overwrite(el, nfd, (nsb - nfd)); - re__strncopy(ofd, nfd, (size_t) (nsb - nfd)); + len = (size_t) (nsb - nfd); + terminal_overwrite(el, nfd, len); + re__strncopy(ofd, nfd, len); } } /* @@ -899,24 +932,25 @@ re_update_line(EditLine *el, char *old, char *new, int i) */ if (sx >= 0) { ELRE_DEBUG(1, (__F, - "second diff insert at %d...\r\n", nse - new)); - term_move_to_char(el, nse - new); + "second diff insert at %d...\r\n", (int)(nse - new))); + 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) { /* 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, (nls - 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, (nls - nse)); + terminal_overwrite(el, nse, (size_t)(nls - nse)); /* * No need to do a clear-to-end here because we were @@ -933,7 +967,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) * Copy string and pad with spaces */ private void -re__copy_and_pad(char *dst, const char *src, size_t width) +re__copy_and_pad(Char *dst, const Char *src, size_t width) { size_t i; @@ -956,8 +990,8 @@ re__copy_and_pad(char *dst, const char *src, size_t width) protected void re_refresh_cursor(EditLine *el) { - char *cp, c; - int h, v, th; + Char *cp; + int h, v, th, w; if (el->el_line.cursor >= el->el_line.lastchar) { if (el->el_map.current == el->el_map.alt @@ -970,47 +1004,46 @@ re_refresh_cursor(EditLine *el) /* 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; - h++; /* all chars at least this long */ - - if (c == '\n') {/* handle newline in data part too */ + switch (ct_chr_class(*cp)) { + case CHTYPE_NL: /* handle newline in data part too */ h = 0; v++; - } else { - if (c == '\t') { /* if a tab, to next tab stop */ - while (h & 07) { - h++; - } - } else if (iscntrl((unsigned char) c)) { - /* if control char */ - h++; - if (h > th) { /* if overflow, compensate */ - h = 1; - v++; - } - } else if (!el_isprint((unsigned char) c)) { - h += 3; - if (h > th) { /* if overflow, compensate */ - h = h - th; - v++; - } + break; + case CHTYPE_TAB: /* if a tab, to next tab stop */ + while (++h & 07) + continue; + break; + default: + w = Width(*cp); + if (w > 1 && h + w > th) { /* won't fit on line */ + h = 0; + v++; } - } + h += ct_visual_width(*cp); + break; + } if (h >= th) { /* check, extra long tabs picked up here also */ - h = 0; + h -= th; v++; } } + /* if we have a next character, and it's a doublewidth one, we need to + * check whether we need to linebreak for it to fit */ + if (cp < el->el_line.lastchar && (w = Width(*cp)) > 1) + if (h + w > th) { + h = 0; + v++; + } /* now go there */ - term_move_to_line(el, v); - term_move_to_char(el, h); - term__flush(el); + terminal_move_to_line(el, v); + terminal_move_to_char(el, h); + terminal__flush(el); } @@ -1018,12 +1051,19 @@ re_refresh_cursor(EditLine *el) * Add a character fast. */ private void -re_fastputc(EditLine *el, int c) +re_fastputc(EditLine *el, Int c) { + int w = Width((Char)c); + while (w > 1 && el->el_cursor.h + w > el->el_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; @@ -1033,27 +1073,27 @@ re_fastputc(EditLine *el, int c) * 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]; + for(i = 1; i < lins; i++) + el->el_display[i - 1] = el->el_display[i]; - re__copy_and_pad(firstline, "", 0); - el->el_display[i-1] = firstline; + re__copy_and_pad(firstline, STR(""), (size_t)0); + el->el_display[i - 1] = firstline; } else { el->el_cursor.v++; el->el_refresh.r_oldcv++; } if (EL_HAS_AUTO_MARGINS) { if (EL_HAS_MAGIC_MARGINS) { - term__putc(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'); } } } @@ -1066,7 +1106,7 @@ re_fastputc(EditLine *el, int c) protected void re_fastaddc(EditLine *el) { - char c; + Char c; int rhdiff; c = el->el_line.cursor[-1]; @@ -1075,25 +1115,30 @@ re_fastaddc(EditLine *el) 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 == '\177') ? '?' : (c | 0100); - re_fastputc(el, '^'); - re_fastputc(el, mc); - } else if (el_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); } @@ -1107,7 +1152,7 @@ re_clear_display(EditLine *el) 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; } @@ -1122,17 +1167,16 @@ re_clear_lines(EditLine *el) if (EL_CAN_CEOL) { int i; - term_move_to_char(el, 0); - for (i = 0; i <= el->el_refresh.r_oldcv; i++) { + for (i = el->el_refresh.r_oldcv; i >= 0; i--) { /* for each line on the screen */ - term_move_to_line(el, i); - term_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); } - term_move_to_line(el, 0); } 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 */ } } diff --git a/cmd-line-utils/libedit/refresh.h b/cmd-line-utils/libedit/refresh.h index dd2bd02094b..f80be463545 100644 --- a/cmd-line-utils/libedit/refresh.h +++ b/cmd-line-utils/libedit/refresh.h @@ -1,4 +1,4 @@ -/* $NetBSD: refresh.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */ +/* $NetBSD: refresh.h,v 1.6 2009/12/30 22:37:40 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -48,7 +48,7 @@ typedef struct { int r_newcv; } el_refresh_t; -protected void re_putc(EditLine *, int, int); +protected void re_putc(EditLine *, Int, int); protected void re_clear_lines(EditLine *); protected void re_clear_display(EditLine *); protected void re_refresh(EditLine *); diff --git a/cmd-line-utils/libedit/search.c b/cmd-line-utils/libedit/search.c index df50c7e7370..2324cc94d76 100644 --- a/cmd-line-utils/libedit/search.c +++ b/cmd-line-utils/libedit/search.c @@ -1,4 +1,4 @@ -/* $NetBSD: search.c,v 1.20 2004/11/04 01:16:03 christos Exp $ */ +/* $NetBSD: search.c,v 1.30 2011/10/04 15:27:04 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -65,15 +65,16 @@ protected int search_init(EditLine *el) { - el->el_search.patbuf = (char *) el_malloc(EL_BUFSIZ); + el->el_search.patbuf = el_malloc(EL_BUFSIZ * + sizeof(*el->el_search.patbuf)); if (el->el_search.patbuf == NULL) - return (-1); + 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; } @@ -84,7 +85,7 @@ protected void search_end(EditLine *el) { - el_free((ptr_t) el->el_search.patbuf); + el_free(el->el_search.patbuf); el->el_search.patbuf = NULL; } @@ -105,8 +106,11 @@ regerror(const char *msg) * Return if string matches pattern */ protected int -el_match(const char *str, const char *pat) +el_match(const Char *str, const Char *pat) { +#ifdef WIDECHAR + static ct_buffer_t conv; +#endif #if defined (REGEX) regex_t re; int rv; @@ -118,30 +122,31 @@ el_match(const char *str, const char *pat) 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 } @@ -150,14 +155,14 @@ el_match(const char *str, const char *pat) * return True if the pattern matches the prefix */ protected int -c_hmatch(EditLine *el, const char *str) +c_hmatch(EditLine *el, const Char *str) { #ifdef SDEBUG (void) fprintf(el->el_errfile, "match `%s' with `%s'\n", el->el_search.patbuf, str); #endif /* SDEBUG */ - return (el_match(str, el->el_search.patbuf)); + return el_match(str, el->el_search.patbuf); } @@ -169,15 +174,16 @@ c_setpat(EditLine *el) { if (el->el_state.lastcmd != ED_SEARCH_PREV_HISTORY && 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", @@ -198,23 +204,24 @@ c_setpat(EditLine *el) protected el_action_t ce_inc_search(EditLine *el, int dir) { - static const char STRfwd[] = {'f', 'w', 'd', '\0'}, + static const Char STRfwd[] = {'f', 'w', 'd', '\0'}, STRbck[] = {'b', 'c', 'k', '\0'}; - static char pchar = ':';/* ':' = normal, '?' = failed */ - static char endcmd[2] = {'\0', '\0'}; - char ch, *ocursor = el->el_line.cursor, oldpchar = pchar; - const char *cp; + static Char pchar = ':';/* ':' = normal, '?' = failed */ + static Char endcmd[2] = {'\0', '\0'}; + Char ch, *ocursor = el->el_line.cursor, oldpchar = pchar; + const Char *cp; el_action_t ret = CC_NORM; int ohisteventno = el->el_history.eventno; - int oldpatlen = el->el_search.patlen; + size_t oldpatlen = el->el_search.patlen; int newdir = dir; int done, redo; - if (el->el_line.lastchar + sizeof(STRfwd) / sizeof(char) + 2 + + if (el->el_line.lastchar + sizeof(STRfwd) / + sizeof(*el->el_line.lastchar) + 2 + el->el_search.patlen >= el->el_line.limit) - return (CC_ERROR); + return CC_ERROR; for (;;) { @@ -241,14 +248,14 @@ ce_inc_search(EditLine *el, int dir) *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; @@ -273,7 +280,7 @@ ce_inc_search(EditLine *el, int dir) if (el->el_search.patlen > LEN) done++; else - term_beep(el); + terminal_beep(el); break; default: @@ -297,7 +304,7 @@ ce_inc_search(EditLine *el, int dir) *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++] = @@ -310,14 +317,14 @@ ce_inc_search(EditLine *el, int dir) re_refresh(el); break; } else if (isglob(*cp)) { - term_beep(el); + terminal_beep(el); break; } break; default: /* Terminate and execute cmd */ endcmd[0] = ch; - el_push(el, endcmd); + FUN(el,push)(el, endcmd); /* FALLTHROUGH */ case 0033: /* ESC: Terminate */ @@ -379,9 +386,10 @@ ce_inc_search(EditLine *el, int dir) /* 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 ? @@ -395,13 +403,13 @@ ce_inc_search(EditLine *el, int dir) 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 = '?'; @@ -426,14 +434,14 @@ ce_inc_search(EditLine *el, int dir) 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) re_refresh(el); } if (done || ret != CC_NORM) - return (ret); + return ret; } } @@ -444,9 +452,9 @@ ce_inc_search(EditLine *el, int dir) 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] = '.'; @@ -457,7 +465,7 @@ cv_search(EditLine *el, int dir) el->el_search.patdir = dir; tmplen = c_gets(el, &tmpbuf[LEN], - dir == ED_SEARCH_PREV_HISTORY ? "\n/" : "\n?" ); + dir == ED_SEARCH_PREV_HISTORY ? STR("\n/") : STR("\n?") ); if (tmplen == -1) return CC_REFRESH; @@ -471,16 +479,16 @@ cv_search(EditLine *el, int dir) */ 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++] = '.'; @@ -494,21 +502,21 @@ cv_search(EditLine *el, int dir) 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; 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; } @@ -518,9 +526,9 @@ cv_search(EditLine *el, int dir) protected el_action_t ce_search_line(EditLine *el, int dir) { - char *cp = el->el_line.cursor; - char *pattern = el->el_search.patbuf; - char oc, *ocp; + Char *cp = el->el_line.cursor; + Char *pattern = el->el_search.patbuf; + Char oc, *ocp; #ifdef ANCHOR ocp = &pattern[1]; oc = *ocp; @@ -535,21 +543,21 @@ ce_search_line(EditLine *el, int dir) 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; } } @@ -558,12 +566,12 @@ ce_search_line(EditLine *el, int dir) * Vi repeat search */ protected el_action_t -cv_repeat_srch(EditLine *el, int c) +cv_repeat_srch(EditLine *el, Int c) { #ifdef SDEBUG (void) fprintf(el->el_errfile, "dir %d patlen %d patbuf %s\n", - c, el->el_search.patlen, el->el_search.patbuf); + c, el->el_search.patlen, ct_encode_string(el->el_search.patbuf)); #endif el->el_state.lastcmd = (el_action_t) c; /* Hack to stop c_setpat */ @@ -571,11 +579,11 @@ cv_repeat_srch(EditLine *el, int c) 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; } } @@ -584,16 +592,16 @@ cv_repeat_srch(EditLine *el, int c) * Vi character search */ protected el_action_t -cv_csearch(EditLine *el, int direction, int ch, int count, int tflag) +cv_csearch(EditLine *el, int direction, Int ch, int count, int tflag) { - char *cp; + Char *cp; if (ch == 0) return CC_ERROR; - if (ch == -1) { - char c; - if (el_getc(el, &c) != 1) + if (ch == (Int)-1) { + Char c; + if (FUN(el,getc)(el, &c) != 1) return ed_end_of_file(el, 0); ch = c; } @@ -601,18 +609,18 @@ cv_csearch(EditLine *el, int direction, int ch, int count, int tflag) /* 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) return CC_ERROR; if (cp < el->el_line.buffer) return CC_ERROR; - if (*cp == ch) + if ((Int)*cp == ch) break; } } diff --git a/cmd-line-utils/libedit/search.h b/cmd-line-utils/libedit/search.h index 2aa8f985013..d9f27e56185 100644 --- a/cmd-line-utils/libedit/search.h +++ b/cmd-line-utils/libedit/search.h @@ -1,4 +1,4 @@ -/* $NetBSD: search.h,v 1.8 2003/10/18 23:27:36 christos Exp $ */ +/* $NetBSD: search.h,v 1.9 2009/12/30 22:37:40 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -43,24 +43,24 @@ #include "histedit.h" typedef struct el_search_t { - char *patbuf; /* The pattern buffer */ + Char *patbuf; /* The pattern buffer */ size_t patlen; /* Length of the pattern buffer */ int patdir; /* Direction of the last search */ int chadir; /* Character search direction */ - char chacha; /* Character we are looking for */ + Char chacha; /* Character we are looking for */ char chatflg; /* 0 if f, 1 if t */ } el_search_t; -protected int el_match(const char *, const char *); +protected int el_match(const Char *, const Char *); protected int search_init(EditLine *); protected void search_end(EditLine *); -protected int c_hmatch(EditLine *, const char *); +protected int c_hmatch(EditLine *, const Char *); protected void c_setpat(EditLine *); protected el_action_t ce_inc_search(EditLine *, int); protected el_action_t cv_search(EditLine *, int); protected el_action_t ce_search_line(EditLine *, int); -protected el_action_t cv_repeat_srch(EditLine *, int); -protected el_action_t cv_csearch(EditLine *, int, int, int, int); +protected el_action_t cv_repeat_srch(EditLine *, Int); +protected el_action_t cv_csearch(EditLine *, int, Int, int, int); #endif /* _h_el_search */ diff --git a/cmd-line-utils/libedit/sig.c b/cmd-line-utils/libedit/sig.c index 5307ee6ec60..986ad5792e2 100644 --- a/cmd-line-utils/libedit/sig.c +++ b/cmd-line-utils/libedit/sig.c @@ -1,4 +1,4 @@ -/* $NetBSD: sig.c,v 1.12 2008/09/10 15:45:37 christos Exp $ */ +/* $NetBSD: sig.c,v 1.17 2011/07/28 20:50:55 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -57,15 +57,15 @@ private const int sighdl[] = { - 1 }; -private void el_sig_handler(int); +private void sig_handler(int); -/* el_sig_handler(): +/* sig_handler(): * This is the handler called for all signals * XXX: we cannot pass any data so we just store the old editline * state in a private variable */ private void -el_sig_handler(int signo) +sig_handler(int signo) { int i; sigset_t nset, oset; @@ -74,12 +74,14 @@ el_sig_handler(int signo) (void) sigaddset(&nset, signo); (void) sigprocmask(SIG_BLOCK, &nset, &oset); + sel->el_signal->sig_no = signo; + switch (signo) { case SIGCONT: tty_rawmode(sel); if (ed_redisplay(sel, 0) == CC_REFRESH) re_refresh(sel); - term__flush(sel); + terminal__flush(sel); break; case SIGWINCH: @@ -95,7 +97,10 @@ el_sig_handler(int signo) if (signo == sighdl[i]) break; - (void) signal(signo, sel->el_signal[i]); + (void) sigaction(signo, &sel->el_signal->sig_action[i], NULL); + sel->el_signal->sig_action[i].sa_handler = SIG_ERR; + sel->el_signal->sig_action[i].sa_flags = 0; + sigemptyset(&sel->el_signal->sig_action[i].sa_mask); (void) sigprocmask(SIG_SETMASK, &oset, NULL); (void) kill(0, signo); } @@ -107,26 +112,29 @@ el_sig_handler(int signo) protected int sig_init(EditLine *el) { - int i; - sigset_t nset, oset; + size_t i; + sigset_t *nset, oset; - (void) sigemptyset(&nset); -#define _DO(a) (void) sigaddset(&nset, a); + el->el_signal = el_malloc(sizeof(*el->el_signal)); + if (el->el_signal == NULL) + return -1; + + nset = &el->el_signal->sig_set; + (void) sigemptyset(nset); +#define _DO(a) (void) sigaddset(nset, a); ALLSIGS #undef _DO - (void) sigprocmask(SIG_BLOCK, &nset, &oset); + (void) sigprocmask(SIG_BLOCK, nset, &oset); -#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(el_signalhandler_t)) - - el->el_signal = (el_signalhandler_t *) el_malloc(SIGSIZE); - if (el->el_signal == NULL) - return (-1); - for (i = 0; sighdl[i] != -1; i++) - el->el_signal[i] = SIG_ERR; + for (i = 0; sighdl[i] != -1; i++) { + el->el_signal->sig_action[i].sa_handler = SIG_ERR; + el->el_signal->sig_action[i].sa_flags = 0; + sigemptyset(&el->el_signal->sig_action[i].sa_mask); + } (void) sigprocmask(SIG_SETMASK, &oset, NULL); - return (0); + return 0; } @@ -137,7 +145,7 @@ protected void sig_end(EditLine *el) { - el_free((ptr_t) el->el_signal); + el_free(el->el_signal); el->el_signal = NULL; } @@ -148,20 +156,21 @@ sig_end(EditLine *el) protected void sig_set(EditLine *el) { - int i; - sigset_t nset, oset; + size_t i; + sigset_t oset; + struct sigaction osa, nsa; - (void) sigemptyset(&nset); -#define _DO(a) (void) sigaddset(&nset, a); - ALLSIGS -#undef _DO - (void) sigprocmask(SIG_BLOCK, &nset, &oset); + nsa.sa_handler = sig_handler; + nsa.sa_flags = 0; + sigemptyset(&nsa.sa_mask); + + (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset); for (i = 0; sighdl[i] != -1; i++) { - el_signalhandler_t s; /* This could happen if we get interrupted */ - if ((s = signal(sighdl[i], el_sig_handler)) != el_sig_handler) - el->el_signal[i] = s; + if (sigaction(sighdl[i], &nsa, &osa) != -1 && + osa.sa_handler != sig_handler) + el->el_signal->sig_action[i] = osa; } sel = el; (void) sigprocmask(SIG_SETMASK, &oset, NULL); @@ -174,20 +183,17 @@ sig_set(EditLine *el) protected void sig_clr(EditLine *el) { - int i; - sigset_t nset, oset; + size_t i; + sigset_t oset; - (void) sigemptyset(&nset); -#define _DO(a) (void) sigaddset(&nset, a); - ALLSIGS -#undef _DO - (void) sigprocmask(SIG_BLOCK, &nset, &oset); + (void) sigprocmask(SIG_BLOCK, &el->el_signal->sig_set, &oset); for (i = 0; sighdl[i] != -1; i++) - if (el->el_signal[i] != SIG_ERR) - (void) signal(sighdl[i], el->el_signal[i]); + if (el->el_signal->sig_action[i].sa_handler != SIG_ERR) + (void)sigaction(sighdl[i], + &el->el_signal->sig_action[i], NULL); sel = NULL; /* we are going to die if the handler is * called */ - (void) sigprocmask(SIG_SETMASK, &oset, NULL); + (void)sigprocmask(SIG_SETMASK, &oset, NULL); } diff --git a/cmd-line-utils/libedit/sig.h b/cmd-line-utils/libedit/sig.h index 2bd3c516d46..c957cfdf5a7 100644 --- a/cmd-line-utils/libedit/sig.h +++ b/cmd-line-utils/libedit/sig.h @@ -1,4 +1,4 @@ -/* $NetBSD: sig.h,v 1.6 2008/07/12 15:27:14 christos Exp $ */ +/* $NetBSD: sig.h,v 1.8 2009/02/19 15:20:22 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -56,9 +56,13 @@ _DO(SIGTERM) \ _DO(SIGCONT) \ _DO(SIGWINCH) +#define ALLSIGSNO 7 -typedef void (*el_signalhandler_t)(int); -typedef el_signalhandler_t *el_signal_t; +typedef struct { + struct sigaction sig_action[ALLSIGSNO]; + sigset_t sig_set; + volatile sig_atomic_t sig_no; +} *el_signal_t; protected void sig_end(EditLine*); protected int sig_init(EditLine*); diff --git a/cmd-line-utils/libedit/sys.h b/cmd-line-utils/libedit/sys.h index a0369affbb0..33638d1565b 100644 --- a/cmd-line-utils/libedit/sys.h +++ b/cmd-line-utils/libedit/sys.h @@ -1,4 +1,4 @@ -/* $NetBSD: sys.h,v 1.9 2004/01/17 17:57:40 christos Exp $ */ +/* $NetBSD: sys.h,v 1.17 2011/09/28 14:08:04 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -48,14 +48,6 @@ # define __attribute__(A) #endif -#ifndef _DIAGASSERT -# define _DIAGASSERT(x) -#endif - -#ifndef SIZE_T_MAX -# define SIZE_T_MAX UINT_MAX -#endif - #ifndef __BEGIN_DECLS # ifdef __cplusplus # define __BEGIN_DECLS extern "C" { @@ -79,18 +71,8 @@ /* When we want to hide everything */ #endif -#ifndef HAVE_U_INT32_T -typedef unsigned int u_int32_t; -#endif - -#ifndef _PTR_T -# define _PTR_T -typedef void *ptr_t; -#endif - -#ifndef _IOCTL_T -# define _IOCTL_T -typedef void *ioctl_t; +#ifndef __arraycount +# define __arraycount(a) (sizeof(a) / sizeof(*(a))) #endif #include <stdio.h> @@ -110,10 +92,44 @@ size_t strlcpy(char *dst, const char *src, size_t size); char *fgetln(FILE *fp, size_t *len); #endif +#ifdef __linux__ +/* Apparently we need _GNU_SOURCE defined to get access to wcsdup on Linux */ +#ifndef _GNU_SOURCE +#define _GNU_SOURCE +#endif +#endif + +#ifndef __USE_XOPEN +#define __USE_XOPEN +#endif + +#include <wchar.h> +#include <wctype.h> + +#ifndef HAVE_WCSDUP +wchar_t *wcsdup(const wchar_t *); +#endif + +#ifndef _DIAGASSERT +#define _DIAGASSERT(x) +#endif + +#ifndef __RCSID +#define __RCSID(x) +#endif + +#ifndef HAVE_U_INT32_T +typedef unsigned int u_int32_t; +#endif + +#ifndef SIZE_T_MAX +#define SIZE_T_MAX ((size_t)-1) +#endif + #define REGEX /* Use POSIX.2 regular expression functions */ #undef REGEXP /* Use UNIX V8 regular expression functions */ -#ifdef __SunOS +#if defined(__sun) extern int tgetent(char *, const char *); extern int tgetflag(char *); extern int tgetnum(char *); @@ -162,8 +178,8 @@ extern void perror(const char *); # 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); +extern void * memcpy(void *, const void *, size_t); +extern void * memset(void *, int, size_t); # endif extern char *fgetline(FILE *, int *); #endif diff --git a/cmd-line-utils/libedit/term.c b/cmd-line-utils/libedit/terminal.c index 2f1aefa7117..fb5600a4140 100644 --- a/cmd-line-utils/libedit/term.c +++ b/cmd-line-utils/libedit/terminal.c @@ -1,4 +1,4 @@ -/* $NetBSD: term.c,v 1.48 2009/02/06 20:08:13 sketch Exp $ */ +/* $NetBSD: terminal.c,v 1.10 2011/10/04 15:27:04 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -41,15 +41,16 @@ static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; #endif /* not lint && not SCCSID */ /* - * 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 <stdio.h> #include <signal.h> #include <string.h> #include <stdlib.h> #include <unistd.h> +#include <limits.h> #if 0 /* TODO: do we need this */ #ifdef HAVE_TERMCAP_H #include <termcap.h> @@ -57,14 +58,15 @@ static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; #endif #ifdef HAVE_CURSES_H #include <curses.h> -#endif -#ifdef HAVE_NCURSES_H +#elif HAVE_NCURSES_H #include <ncurses.h> #endif -/* Don't use Solaris's term.h. */ -#if (defined(HAVE_TERM_H) && !defined(__SunOS)) + +/* Solaris's term.h does horrid things. */ +#if defined(HAVE_TERM_H) && !defined(__sun) #include <term.h> #endif + #include <sys/types.h> #include <sys/ioctl.h> @@ -76,89 +78,17 @@ static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; /* * 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 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 TC_BUFSIZE ((size_t)2048) -#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 +#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] private const struct termcapstr { const char *name; @@ -269,27 +199,28 @@ private const struct termcapval { }; /* 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) @@ -330,67 +261,74 @@ term_setflags(EditLine *el) #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]; - int tlen, clen; - char **tlist = el->el_term.t_str; + size_t tlen, clen; + char **tlist = el->el_terminal.t_str; char **tmp, **str = &tlist[t - tstr]; if (cap == NULL || *cap == '\0') { @@ -412,11 +350,11 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap) /* * 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 += 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; } /* @@ -432,124 +370,126 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap) continue; termbuf[tlen++] = '\0'; } - memcpy(el->el_term.t_buf, termbuf, TC_BUFSIZE); - el->el_term.t_loc = tlen; - if (el->el_term.t_loc + 3 >= TC_BUFSIZE) { + 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 += 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 <where> (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; 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; } @@ -557,21 +497,31 @@ term_move_to_line(EditLine *el, int where) while (del > 0) { if (EL_HAS_AUTO_MARGINS && el->el_display[el->el_cursor.v][0] != '\0') { + size_t h = (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[el->el_cursor.v][el->el_cursor.h], - 1); + 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_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; } @@ -579,22 +529,22 @@ term_move_to_line(EditLine *el, int where) } } 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 */ } -/* 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; @@ -602,15 +552,16 @@ mc_again: 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; } @@ -618,24 +569,32 @@ mc_again: 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 & 0370)) { + (where & ~0x7) +#ifdef WIDECHAR + && (el->el_display[ + el->el_cursor.v][where & 0370] != + MB_FILL_CHAR) +#endif + ) { /* if not within tab stop */ for (i = (el->el_cursor.h & 0370); - i < (where & 0370); + i < (where & ~0x7); i += 8) - term__putc(el, '\t'); + terminal__putc(el, + '\t'); /* then tab over */ - el->el_cursor.h = where & 0370; + el->el_cursor.h = where & ~0x7; } } /* @@ -643,17 +602,17 @@ mc_again: * 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[el->el_cursor.v][el->el_cursor.h], - where - el->el_cursor.h); + terminal_overwrite(el, &el->el_display[ + el->el_cursor.v][el->el_cursor.h], + (size_t)(where - el->el_cursor.h)); } } else { /* del < 0 := moving backward */ if ((-del > 4) && GoodStr(T_LE)) - 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 */ /* @@ -665,12 +624,12 @@ mc_again: (((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'); } } } @@ -678,53 +637,72 @@ mc_again: } -/* 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, int n) +terminal_overwrite(EditLine *el, const Char *cp, size_t n) { - if (n <= 0) - return; /* catch bugs */ +#ifdef WIDECHAR + int width; +#endif - if (n > el->el_term.t_size.h) { + if (n == 0) + return; + + 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); - if (el->el_cursor.h >= el->el_term.t_size.h) { /* wrap? */ + do { +#ifdef WIDECHAR + width = wcwidth(*cp); /* Returns -1 for faux character. */ + if (width != -1) + el->el_cursor.h += width; +#else + el->el_cursor.h++; +#endif + /* terminal__putc() ignores any MB_FILL_CHARs */ + terminal__putc(el, *cp++); + } while (--n); + + 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++; if (EL_HAS_MAGIC_MARGINS) { /* force the wrap to avoid the "magic" * situation */ - char c; - if ((c = el->el_display[el->el_cursor.v][el->el_cursor.h]) - != '\0') - term_overwrite(el, &c, 1); - else - term__putc(el, ' '); - el->el_cursor.h = 1; + 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; + 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; @@ -735,37 +713,38 @@ term_deletechars(EditLine *el, int num) #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; } 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; @@ -775,7 +754,7 @@ term_insertwrite(EditLine *el, char *cp, int num) #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); @@ -785,120 +764,106 @@ term_insertwrite(EditLine *el, char *cp, int num) if (GoodStr(T_IC)) /* if I have multiple insert */ if ((num > 1) || !GoodStr(T_ic)) { /* if ic would be more expensive */ - term_tputs(el, tgoto(Str(T_IC), num, num), num); - term_overwrite(el, cp, 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); } -/* 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) -{ - 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)); -} -#endif - protected void -term_get(EditLine *el, const char **term) +terminal_get(EditLine *el, const char **term) { - *term = el->el_term.t_name; + *term = el->el_terminal.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]; @@ -923,9 +888,9 @@ term_set(EditLine *el, const char *term) if (strcmp(term, "emacs") == 0) el->el_flags |= EDIT_DISABLED; - memset(el->el_term.t_cap, 0, TC_BUFSIZE); + 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) @@ -940,23 +905,23 @@ term_set(EditLine *el, const char *term) 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"); - Val(T_xn) = tgetflag("xn"); + Val(T_am) = tgetflag((char*) "am"); + Val(T_xn) = tgetflag((char*) "xn"); /* Can we tab */ - Val(T_pt) = tgetflag("pt"); - Val(T_xt) = tgetflag("xt"); + Val(T_pt) = tgetflag((char*) "pt"); + Val(T_xt) = tgetflag((char*) "xt"); /* do we have a meta? */ - Val(T_km) = tgetflag("km"); - Val(T_MT) = tgetflag("MT"); + Val(T_km) = tgetflag((char*) "km"); + Val(T_MT) = tgetflag((char*) "MT"); /* Get the size */ - Val(T_co) = tgetnum("co"); - Val(T_li) = tgetnum("li"); + Val(T_co) = tgetnum((char*) "co"); + Val(T_li) = tgetnum((char*) "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)); } } @@ -966,28 +931,28 @@ term_set(EditLine *el, const char *term) 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); @@ -996,7 +961,7 @@ term_get_size(EditLine *el, int *lins, int *cols) #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) @@ -1007,7 +972,7 @@ term_get_size(EditLine *el, int *lins, int *cols) #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) @@ -1015,15 +980,15 @@ term_get_size(EditLine *el, int *lins, int *cols) } } #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 @@ -1032,283 +997,301 @@ term_change_size(EditLine *el, int lins, int cols) 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; } -/* 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 stOA[] = {033, 'O', 'A', '\0'}; - static const char stOB[] = {033, 'O', 'B', '\0'}; - static const char stOC[] = {033, 'O', 'C', '\0'}; - static const char stOD[] = {033, 'O', 'D', '\0'}; - static const char stOH[] = {033, 'O', 'H', '\0'}; - static const char stOF[] = {033, 'O', 'F', '\0'}; - - key_add(el, strA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, strB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, strC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, strD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, strH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, strF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); - key_add(el, stOA, &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, stOB, &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, stOC, &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, stOD, &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, stOH, &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, stOF, &arrow[A_K_EN].fun, arrow[A_K_EN].type); - - if (el->el_map.type == MAP_VI) { - key_add(el, &strA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, &strB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, &strC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, &strD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, &strH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, &strF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); - key_add(el, &stOA[1], &arrow[A_K_UP].fun, arrow[A_K_UP].type); - key_add(el, &stOB[1], &arrow[A_K_DN].fun, arrow[A_K_DN].type); - key_add(el, &stOC[1], &arrow[A_K_RT].fun, arrow[A_K_RT].type); - key_add(el, &stOD[1], &arrow[A_K_LT].fun, arrow[A_K_LT].type); - key_add(el, &stOH[1], &arrow[A_K_HO].fun, arrow[A_K_HO].type); - key_add(el, &stOF[1], &arrow[A_K_EN].fun, arrow[A_K_EN].type); - } + 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'}; + + 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) + 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) { + char buf[MB_LEN_MAX +1]; + ssize_t i; + mbstate_t state; - return fputc(c, el->el_outfile); + memset(&state, 0, sizeof(mbstate_t)); + if (c == (Int)MB_FILL_CHAR) + return 0; + i = ct_encode_char(buf, (size_t)MB_CUR_MAX, c, &state); + 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]; - int cnt = key__decode_char(buf, sizeof(buf), 0, c); - buf[cnt] = '\0'; - term_overwrite(el, buf, cnt); - term__flush(el); + Char visbuf[VISUAL_WIDTH_MAX +1]; + ssize_t vcnt = ct_visual_char(visbuf, VISUAL_WIDTH_MAX, c); + 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 __attribute__((__unused__)), - const char **argv __attribute__((__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"); @@ -1324,39 +1307,42 @@ term_telltc(EditLine *el, int argc __attribute__((__unused__)), (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 __attribute__((__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 @@ -1366,8 +1352,8 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), break; if (ts->name != NULL) { - term_alloc(el, ts, how); - term_setflags(el); + terminal_alloc(el, ts, how); + terminal_setflags(el); return 0; } /* @@ -1383,16 +1369,16 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), 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 { @@ -1402,14 +1388,14 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), i = strtol(how, &ep, 10); if (*ep != '\0') { (void) fprintf(el->el_errfile, - "%s: Bad value `%s'.\n", argv[0], how); + "" FSTR ": Bad value `%s'.\n", argv[0], how); return -1; } - el->el_term.t_val[tv - tval] = (int) i; - 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; @@ -1417,12 +1403,12 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)), } -/* term_gettc(): +/* terminal_gettc(): * Get the current terminal characteristics */ protected int /*ARGSUSED*/ -term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) +terminal_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) { const struct termcapstr *ts; const struct termcapval *tv; @@ -1430,7 +1416,7 @@ term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) void *how; if (argv == NULL || argv[1] == NULL || argv[2] == NULL) - return (-1); + return -1; what = argv[1]; how = argv[2]; @@ -1443,7 +1429,7 @@ term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) 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; } /* @@ -1460,26 +1446,27 @@ term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv) 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 __attribute__((__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; @@ -1491,7 +1478,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), area = buf; if (argv == NULL || argv[1] == NULL) - return (-1); + return -1; argv++; if (argv[0][0] == '-') { @@ -1509,62 +1496,52 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), 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 */ 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. @@ -1605,11 +1582,11 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), if (*argv && *argv[0]) { if (!silent) (void) fprintf(el->el_errfile, - "echotc: Warning: Extra argument `%s'.\n", + "echotc: Warning: Extra argument `" FSTR "'.\n", *argv); - return (-1); + return -1; } - term_tputs(el, scap, 1); + terminal_tputs(el, scap, 1); break; case 1: argv++; @@ -1617,27 +1594,27 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), 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++; 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... */ @@ -1652,15 +1629,15 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), 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++; @@ -1668,33 +1645,33 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)), 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; } diff --git a/cmd-line-utils/libedit/tokenizer.c b/cmd-line-utils/libedit/tokenizer.c index 5161cdd0a22..7267164e9b6 100644 --- a/cmd-line-utils/libedit/tokenizer.c +++ b/cmd-line-utils/libedit/tokenizer.c @@ -1,4 +1,4 @@ -/* $NetBSD: tokenizer.c,v 1.14 2003/12/05 13:37:48 lukem Exp $ */ +/* $NetBSD: tokenizer.c,v 1.19 2011/07/28 20:50:55 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -40,51 +40,53 @@ static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93"; #endif #endif /* not lint && not SCCSID */ +/* We build this file twice, once as NARROW, once as WIDE. */ /* * tokenize.c: Bourne shell like tokenizer */ #include <string.h> #include <stdlib.h> #include "histedit.h" +#include "chartype.h" typedef enum { Q_none, Q_single, Q_double, Q_one, Q_doubleone } quote_t; -#define IFS "\t \n" - #define TOK_KEEP 1 #define TOK_EAT 2 #define WINCR 20 #define AINCR 10 -#define tok_strdup(a) strdup(a) +#define IFS STR("\t \n") + #define tok_malloc(a) malloc(a) #define tok_free(a) free(a) #define tok_realloc(a, b) realloc(a, b) +#define tok_strdup(a) Strdup(a) -struct tokenizer { - char *ifs; /* In field separator */ +struct TYPE(tokenizer) { + Char *ifs; /* In field separator */ int argc, amax; /* Current and maximum number of args */ - char **argv; /* Argument list */ - char *wptr, *wmax; /* Space and limit on the word buffer */ - char *wstart; /* Beginning of next word */ - char *wspace; /* Space of word buffer */ + Char **argv; /* Argument list */ + Char *wptr, *wmax; /* Space and limit on the word buffer */ + Char *wstart; /* Beginning of next word */ + Char *wspace; /* Space of word buffer */ quote_t quote; /* Quoting state */ int flags; /* flags; */ }; -private void tok_finish(Tokenizer *); +private void FUN(tok,finish)(TYPE(Tokenizer) *); -/* tok_finish(): +/* FUN(tok,finish)(): * Finish a word in the tokenizer. */ private void -tok_finish(Tokenizer *tok) +FUN(tok,finish)(TYPE(Tokenizer) *tok) { *tok->wptr = '\0'; @@ -97,35 +99,35 @@ tok_finish(Tokenizer *tok) } -/* tok_init(): +/* FUN(tok,init)(): * Initialize the tokenizer */ -public Tokenizer * -tok_init(const char *ifs) +public TYPE(Tokenizer) * +FUN(tok,init)(const Char *ifs) { - Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer)); + TYPE(Tokenizer) *tok = tok_malloc(sizeof(*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; @@ -138,11 +140,11 @@ tok_init(const char *ifs) } -/* tok_reset(): +/* FUN(tok,reset)(): * Reset the tokenizer */ public void -tok_reset(Tokenizer *tok) +FUN(tok,reset)(TYPE(Tokenizer) *tok) { tok->argc = 0; @@ -153,25 +155,25 @@ tok_reset(Tokenizer *tok) } -/* tok_end(): +/* FUN(tok,end)(): * Clean up */ public void -tok_end(Tokenizer *tok) +FUN(tok,end)(TYPE(Tokenizer) *tok) { - tok_free((ptr_t) tok->ifs); - 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 @@ -186,20 +188,20 @@ tok_end(Tokenizer *tok) * cursorv if !NULL, offset in argv[cursorc] of cursor */ public int -tok_line(Tokenizer *tok, const LineInfo *line, - int *argc, const char ***argv, int *cursorc, int *cursoro) +FUN(tok,line)(TYPE(Tokenizer) *tok, const TYPE(LineInfo) *line, + int *argc, const Char ***argv, int *cursorc, int *cursoro) { - const char *ptr; + const Char *ptr; int cc, co; cc = co = -1; ptr = line->buffer; for (ptr = line->buffer; ;ptr++) { if (ptr >= line->lastchar) - ptr = ""; + ptr = STR(""); if (ptr == line->cursor) { cc = tok->argc; - co = tok->wptr - tok->wstart; + co = (int)(tok->wptr - tok->wstart); } switch (*ptr) { case '\'': @@ -357,8 +359,8 @@ tok_line(Tokenizer *tok, const LineInfo *line, tok->flags &= ~TOK_EAT; switch (tok->quote) { case Q_none: - if (strchr(tok->ifs, *ptr) != NULL) - tok_finish(tok); + if (Strchr(tok->ifs, *ptr) != NULL) + FUN(tok,finish)(tok); else *tok->wptr++ = *ptr; break; @@ -389,7 +391,8 @@ tok_line(Tokenizer *tok, const LineInfo *line, if (tok->wptr >= tok->wmax - 4) { size_t size = tok->wmax - tok->wspace + WINCR; - char *s = (char *) tok_realloc(tok->wspace, size); + Char *s = tok_realloc(tok->wspace, + size * sizeof(*s)); if (s == NULL) return (-1); @@ -406,10 +409,9 @@ tok_line(Tokenizer *tok, const LineInfo *line, tok->wmax = s + size; } if (tok->argc >= tok->amax - 4) { - char **p; + Char **p; tok->amax += AINCR; - p = (char **) tok_realloc(tok->argv, - tok->amax * sizeof(char *)); + p = tok_realloc(tok->argv, tok->amax * sizeof(*p)); if (p == NULL) return (-1); tok->argv = p; @@ -418,29 +420,30 @@ tok_line(Tokenizer *tok, const LineInfo *line, tok_line_outok: if (cc == -1 && co == -1) { cc = tok->argc; - co = tok->wptr - tok->wstart; + co = (int)(tok->wptr - tok->wstart); } if (cursorc != NULL) *cursorc = cc; if (cursoro != NULL) *cursoro = co; - tok_finish(tok); - *argv = (const char **)tok->argv; + FUN(tok,finish)(tok); + *argv = (const Char **)tok->argv; *argc = tok->argc; return (0); } -/* tok_str(): +/* FUN(tok,str)(): * Simpler version of tok_line, taking a NUL terminated line * and splitting into words, ignoring cursor state. */ public int -tok_str(Tokenizer *tok, const char *line, int *argc, const char ***argv) +FUN(tok,str)(TYPE(Tokenizer) *tok, const Char *line, int *argc, + const Char ***argv) { - LineInfo li; + TYPE(LineInfo) li; memset(&li, 0, sizeof(li)); li.buffer = line; - li.cursor = li.lastchar = strchr(line, '\0'); - return (tok_line(tok, &li, argc, argv, NULL, NULL)); + li.cursor = li.lastchar = Strchr(line, '\0'); + return (FUN(tok,line)(tok, &li, argc, argv, NULL, NULL)); } diff --git a/cmd-line-utils/libedit/tokenizern.c b/cmd-line-utils/libedit/tokenizern.c new file mode 100644 index 00000000000..92376e066f1 --- /dev/null +++ b/cmd-line-utils/libedit/tokenizern.c @@ -0,0 +1,5 @@ +#define NARROW_WRAPPER +#include "config.h" +#undef WIDECHAR +#define NARROWCHAR +#include "./tokenizer.c" diff --git a/cmd-line-utils/libedit/tty.c b/cmd-line-utils/libedit/tty.c index 3706905fc79..eea00bfc245 100644 --- a/cmd-line-utils/libedit/tty.c +++ b/cmd-line-utils/libedit/tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.28 2009/02/06 19:53:23 sketch Exp $ */ +/* $NetBSD: tty.c,v 1.41 2011/10/04 15:27:04 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -45,8 +45,10 @@ static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93"; */ #include <assert.h> #include <errno.h> -#include "tty.h" +#include <unistd.h> /* for isatty */ +#include <strings.h> /* for ffs */ #include "el.h" +#include "tty.h" typedef struct ttymodes_t { const char *m_name; @@ -55,7 +57,7 @@ typedef struct ttymodes_t { } ttymodes_t; typedef struct ttymap_t { - int nch, och; /* Internal and termio rep of chars */ + Int nch, och; /* Internal and termio rep of chars */ el_action_t bind[3]; /* emacs, vi, and vi-cmd */ } ttymap_t; @@ -151,7 +153,7 @@ private const ttymap_t tty_map[] = { {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}} }; @@ -492,14 +494,21 @@ tty_setup(EditLine *el) int rst = 1; if (el->el_flags & EDIT_DISABLED) - return (0); + return 0; + if (!isatty(el->el_outfd)) { +#ifdef DEBUG_TTY + (void) fprintf(el->el_errfile, + "tty_setup: isatty: %s\n", strerror(errno)); +#endif /* DEBUG_TTY */ + return -1; + } if (tty_getty(el, &el->el_tty.t_ed) == -1) { #ifdef DEBUG_TTY (void) fprintf(el->el_errfile, "tty_setup: tty_getty: %s\n", strerror(errno)); #endif /* DEBUG_TTY */ - return (-1); + return -1; } el->el_tty.t_ts = el->el_tty.t_ex = el->el_tty.t_ed; @@ -549,13 +558,9 @@ tty_setup(EditLine *el) "tty_setup: tty_setty: %s\n", strerror(errno)); #endif /* DEBUG_TTY */ - return (-1); + return -1; } } -#ifdef notdef - else - tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); -#endif el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask; @@ -571,7 +576,7 @@ tty_setup(EditLine *el) 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 @@ -582,7 +587,7 @@ tty_init(EditLine *el) 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); } @@ -608,7 +613,7 @@ tty__getspeed(struct termios *td) if ((spd = cfgetispeed(td)) == 0) spd = cfgetospeed(td); - return (spd); + return spd; } /* tty__getspeed(): @@ -892,7 +897,7 @@ tty_bind_char(EditLine *el, int force) unsigned char *t_n = el->el_tty.t_c[ED_IO]; unsigned char *t_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; @@ -908,22 +913,22 @@ tty_bind_char(EditLine *el, int force) 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]; } } } @@ -937,21 +942,21 @@ tty_rawmode(EditLine *el) { 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", 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); @@ -1077,10 +1082,10 @@ tty_rawmode(EditLine *el) (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n", strerror(errno)); #endif /* DEBUG_TTY */ - return (-1); + return -1; } el->el_tty.t_mode = ED_IO; - return (0); + return 0; } @@ -1092,10 +1097,10 @@ tty_cookedmode(EditLine *el) { /* 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, TCSADRAIN, &el->el_tty.t_ex) == -1) { #ifdef DEBUG_TTY @@ -1103,10 +1108,10 @@ tty_cookedmode(EditLine *el) "tty_cookedmode: tty_setty: %s\n", strerror(errno)); #endif /* DEBUG_TTY */ - return (-1); + return -1; } el->el_tty.t_mode = EX_IO; - return (0); + return 0; } @@ -1117,7 +1122,7 @@ protected int 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; @@ -1138,10 +1143,10 @@ tty_quotemode(EditLine *el) (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n", strerror(errno)); #endif /* DEBUG_TTY */ - return (-1); + return -1; } el->el_tty.t_mode = QU_IO; - return (0); + return 0; } @@ -1153,16 +1158,16 @@ tty_noquotemode(EditLine *el) { if (el->el_tty.t_mode != QU_IO) - return (0); + 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", strerror(errno)); #endif /* DEBUG_TTY */ - return (-1); + return -1; } el->el_tty.t_mode = ED_IO; - return (0); + return 0; } @@ -1171,19 +1176,20 @@ tty_noquotemode(EditLine *el) */ protected int /*ARGSUSED*/ -tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) +tty_stty(EditLine *el, int argc __attribute__((__unused__)), const Char **argv) { const ttymodes_t *m; char x; int aflag = 0; - const char *s, *d; - const char *name; + const Char *s, *d; + char name[EL_BUFSIZ]; struct termios *tios = &el->el_tty.t_ex; int z = EX_IO; if (argv == NULL) - return (-1); - name = *argv++; + 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]) { @@ -1209,13 +1215,13 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) default: (void) fprintf(el->el_errfile, "%s: Unknown switch `%c'.\n", - name, argv[0][1]); - return (-1); + name, (int) argv[0][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", @@ -1228,8 +1234,9 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) 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'; } @@ -1238,9 +1245,9 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) cu = strlen(m->m_name) + (x != '\0') + 1; - if (len + cu >= el->el_term.t_size.h) { + if (len + cu >= (size_t)el->el_terminal.t_size.h) { (void) fprintf(el->el_outfile, "\n%*s", - st, ""); + (int)st, ""); len = st + cu; } else len += cu; @@ -1254,40 +1261,41 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) } } (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'; 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) { @@ -1312,11 +1320,11 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv) (void) fprintf(el->el_errfile, "tty_stty: tty_setty: %s\n", strerror(errno)); #endif /* DEBUG_TTY */ - return (-1); + return -1; } } - return (0); + return 0; } diff --git a/cmd-line-utils/libedit/tty.h b/cmd-line-utils/libedit/tty.h index 10e9b98c953..04485eb83ad 100644 --- a/cmd-line-utils/libedit/tty.h +++ b/cmd-line-utils/libedit/tty.h @@ -1,4 +1,4 @@ -/* $NetBSD: tty.h,v 1.11 2005/06/01 11:37:52 lukem Exp $ */ +/* $NetBSD: tty.h,v 1.13 2011/08/16 16:25:15 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -40,6 +40,7 @@ #ifndef _h_el_tty #define _h_el_tty +#include "sys.h" #include "histedit.h" #include <termios.h> #include <unistd.h> @@ -430,7 +431,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 +459,7 @@ typedef unsigned char ttychar_t[NN_IO][C_NCC]; protected int tty_init(EditLine *); protected void tty_end(EditLine *); -protected int tty_stty(EditLine *, int, const char **); +protected int tty_stty(EditLine *, int, const Char **); protected int tty_rawmode(EditLine *); protected int tty_cookedmode(EditLine *); protected int tty_quotemode(EditLine *); diff --git a/cmd-line-utils/libedit/vi.c b/cmd-line-utils/libedit/vi.c index beffc7b40b5..9a4b97a977e 100644 --- a/cmd-line-utils/libedit/vi.c +++ b/cmd-line-utils/libedit/vi.c @@ -1,4 +1,4 @@ -/* $NetBSD: vi.c,v 1.28 2009/02/06 13:14:37 sketch Exp $ */ +/* $NetBSD: vi.c,v 1.41 2011/10/04 15:27:04 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -35,6 +35,7 @@ #include "config.h" #include <stdlib.h> #include <unistd.h> +#include <limits.h> #include <sys/wait.h> #if !defined(lint) && !defined(SCCSID) @@ -49,25 +50,25 @@ static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; */ #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)) cv_undo(el); cv_yank(el, el->el_line.buffer, - el->el_line.lastchar - el->el_line.buffer); + (int)(el->el_line.lastchar - el->el_line.buffer)); el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.pos = 0; if (!(c & YANK)) { @@ -77,26 +78,26 @@ cv_action(EditLine *el, int c) 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(): * Paste previous deletion before or after the cursor */ private el_action_t -cv_paste(EditLine *el, int c) +cv_paste(EditLine *el, Int c) { c_kill_t *k = &el->el_chared.c_kill; - int len = k->last - k->buf; + size_t len = (size_t)(k->last - k->buf); if (k->buf == NULL || len == 0) - return (CC_ERROR); + return CC_ERROR; #ifdef DEBUG_PASTE - (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", len, k->buf); + (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", (int)len, k->buf); #endif cv_undo(el); @@ -104,12 +105,13 @@ cv_paste(EditLine *el, int c) if (!c && el->el_line.cursor < el->el_line.lastchar) el->el_line.cursor++; - c_insert(el, len); + c_insert(el, (int)len); if (el->el_line.cursor + len > el->el_line.lastchar) - return (CC_ERROR); - (void) memcpy(el->el_line.cursor, k->buf, len +0u); + return CC_ERROR; + (void) memcpy(el->el_line.cursor, k->buf, len * + sizeof(*el->el_line.cursor)); - return (CC_REFRESH); + return CC_REFRESH; } @@ -119,10 +121,10 @@ cv_paste(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_paste_next(EditLine *el, int c __attribute__((__unused__))) +vi_paste_next(EditLine *el, Int c __attribute__((__unused__))) { - return (cv_paste(el, 0)); + return cv_paste(el, 0); } @@ -132,10 +134,10 @@ vi_paste_next(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_paste_prev(EditLine *el, int c __attribute__((__unused__))) +vi_paste_prev(EditLine *el, Int c __attribute__((__unused__))) { - return (cv_paste(el, 1)); + return cv_paste(el, 1); } @@ -145,11 +147,11 @@ vi_paste_prev(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_prev_big_word(EditLine *el, int c __attribute__((__unused__))) +vi_prev_big_word(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.buffer) - return (CC_ERROR); + return CC_ERROR; el->el_line.cursor = cv_prev_word(el->el_line.cursor, el->el_line.buffer, @@ -158,9 +160,9 @@ vi_prev_big_word(EditLine *el, int c __attribute__((__unused__))) if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -170,11 +172,11 @@ vi_prev_big_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_prev_word(EditLine *el, int c __attribute__((__unused__))) +vi_prev_word(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.buffer) - return (CC_ERROR); + return CC_ERROR; el->el_line.cursor = cv_prev_word(el->el_line.cursor, el->el_line.buffer, @@ -183,9 +185,9 @@ vi_prev_word(EditLine *el, int c __attribute__((__unused__))) if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - return (CC_CURSOR); + return CC_CURSOR; } @@ -195,11 +197,11 @@ vi_prev_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_next_big_word(EditLine *el, int c __attribute__((__unused__))) +vi_next_big_word(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor >= el->el_line.lastchar - 1) - 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); @@ -207,9 +209,9 @@ vi_next_big_word(EditLine *el, int c __attribute__((__unused__))) 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; } @@ -219,11 +221,11 @@ vi_next_big_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_next_word(EditLine *el, int c __attribute__((__unused__))) +vi_next_word(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor >= el->el_line.lastchar - 1) - 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); @@ -231,9 +233,9 @@ vi_next_word(EditLine *el, int c __attribute__((__unused__))) 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; } @@ -242,20 +244,20 @@ vi_next_word(EditLine *el, int c __attribute__((__unused__))) * [~] */ protected el_action_t -vi_change_case(EditLine *el, int c) +vi_change_case(EditLine *el, Int c) { int i; 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--; @@ -274,14 +276,14 @@ vi_change_case(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_change_meta(EditLine *el, int c __attribute__((__unused__))) +vi_change_meta(EditLine *el, Int c __attribute__((__unused__))) { /* * 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); } @@ -291,13 +293,13 @@ vi_change_meta(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_insert_at_bol(EditLine *el, int c __attribute__((__unused__))) +vi_insert_at_bol(EditLine *el, Int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; cv_undo(el); el->el_map.current = el->el_map.key; - return (CC_CURSOR); + return CC_CURSOR; } @@ -307,7 +309,7 @@ vi_insert_at_bol(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_replace_char(EditLine *el, int c __attribute__((__unused__))) +vi_replace_char(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor >= el->el_line.lastchar) @@ -316,7 +318,7 @@ vi_replace_char(EditLine *el, int c __attribute__((__unused__))) el->el_map.current = el->el_map.key; el->el_state.inputmode = MODE_REPLACE_1; cv_undo(el); - return (CC_ARGHACK); + return CC_ARGHACK; } @@ -326,13 +328,13 @@ vi_replace_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_replace_mode(EditLine *el, int c __attribute__((__unused__))) +vi_replace_mode(EditLine *el, Int c __attribute__((__unused__))) { el->el_map.current = el->el_map.key; el->el_state.inputmode = MODE_REPLACE; cv_undo(el); - return (CC_NORM); + return CC_NORM; } @@ -342,12 +344,12 @@ vi_replace_mode(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_substitute_char(EditLine *el, int c __attribute__((__unused__))) +vi_substitute_char(EditLine *el, Int c __attribute__((__unused__))) { c_delafter(el, el->el_state.argument); el->el_map.current = el->el_map.key; - return (CC_REFRESH); + return CC_REFRESH; } @@ -357,15 +359,15 @@ vi_substitute_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_substitute_line(EditLine *el, int c __attribute__((__unused__))) +vi_substitute_line(EditLine *el, Int c __attribute__((__unused__))) { cv_undo(el); cv_yank(el, el->el_line.buffer, - el->el_line.lastchar - el->el_line.buffer); + (int)(el->el_line.lastchar - el->el_line.buffer)); (void) em_kill_line(el, 0); el->el_map.current = el->el_map.key; - return (CC_REFRESH); + return CC_REFRESH; } @@ -375,15 +377,15 @@ vi_substitute_line(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_change_to_eol(EditLine *el, int c __attribute__((__unused__))) +vi_change_to_eol(EditLine *el, Int c __attribute__((__unused__))) { cv_undo(el); cv_yank(el, el->el_line.cursor, - el->el_line.lastchar - el->el_line.cursor); + (int)(el->el_line.lastchar - el->el_line.cursor)); (void) ed_kill_line(el, 0); el->el_map.current = el->el_map.key; - return (CC_REFRESH); + return CC_REFRESH; } @@ -393,12 +395,12 @@ vi_change_to_eol(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_insert(EditLine *el, int c __attribute__((__unused__))) +vi_insert(EditLine *el, Int c __attribute__((__unused__))) { el->el_map.current = el->el_map.key; cv_undo(el); - return (CC_NORM); + return CC_NORM; } @@ -408,7 +410,7 @@ vi_insert(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_add(EditLine *el, int c __attribute__((__unused__))) +vi_add(EditLine *el, Int c __attribute__((__unused__))) { int ret; @@ -423,7 +425,7 @@ vi_add(EditLine *el, int c __attribute__((__unused__))) cv_undo(el); - return (ret); + return (el_action_t)ret; } @@ -433,13 +435,13 @@ vi_add(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_add_at_eol(EditLine *el, int c __attribute__((__unused__))) +vi_add_at_eol(EditLine *el, Int c __attribute__((__unused__))) { el->el_map.current = el->el_map.key; el->el_line.cursor = el->el_line.lastchar; cv_undo(el); - return (CC_CURSOR); + return CC_CURSOR; } @@ -449,10 +451,10 @@ vi_add_at_eol(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_delete_meta(EditLine *el, int c __attribute__((__unused__))) +vi_delete_meta(EditLine *el, Int c __attribute__((__unused__))) { - return (cv_action(el, DELETE)); + return cv_action(el, DELETE); } @@ -462,11 +464,11 @@ vi_delete_meta(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_end_big_word(EditLine *el, int c __attribute__((__unused__))) +vi_end_big_word(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.lastchar) - 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); @@ -474,9 +476,9 @@ vi_end_big_word(EditLine *el, int c __attribute__((__unused__))) 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; } @@ -486,11 +488,11 @@ vi_end_big_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_end_word(EditLine *el, int c __attribute__((__unused__))) +vi_end_word(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor == el->el_line.lastchar) - 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); @@ -498,9 +500,9 @@ vi_end_word(EditLine *el, int c __attribute__((__unused__))) 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; } @@ -510,7 +512,7 @@ vi_end_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_undo(EditLine *el, int c __attribute__((__unused__))) +vi_undo(EditLine *el, Int c __attribute__((__unused__))) { c_undo_t un = el->el_chared.c_undo; @@ -520,13 +522,14 @@ vi_undo(EditLine *el, int c __attribute__((__unused__))) /* switch line buffer and undo buffer */ el->el_chared.c_undo.buf = el->el_line.buffer; el->el_chared.c_undo.len = el->el_line.lastchar - el->el_line.buffer; - el->el_chared.c_undo.cursor = el->el_line.cursor - el->el_line.buffer; + el->el_chared.c_undo.cursor = + (int)(el->el_line.cursor - el->el_line.buffer); el->el_line.limit = un.buf + (el->el_line.limit - el->el_line.buffer); el->el_line.buffer = un.buf; el->el_line.cursor = un.buf + un.cursor; el->el_line.lastchar = un.buf + un.len; - return (CC_REFRESH); + return CC_REFRESH; } @@ -536,7 +539,7 @@ vi_undo(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_command_mode(EditLine *el, int c __attribute__((__unused__))) +vi_command_mode(EditLine *el, Int c __attribute__((__unused__))) { /* [Esc] cancels pending action */ @@ -551,7 +554,7 @@ vi_command_mode(EditLine *el, int c __attribute__((__unused__))) if (el->el_line.cursor > el->el_line.buffer) el->el_line.cursor--; #endif - return (CC_CURSOR); + return CC_CURSOR; } @@ -560,7 +563,7 @@ vi_command_mode(EditLine *el, int c __attribute__((__unused__))) * [0] */ protected el_action_t -vi_zero(EditLine *el, int c) +vi_zero(EditLine *el, Int c) { if (el->el_state.doingarg) @@ -569,9 +572,9 @@ vi_zero(EditLine *el, int c) 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; } @@ -581,15 +584,15 @@ vi_zero(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__))) +vi_delete_prev_char(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_line.cursor <= el->el_line.buffer) - return (CC_ERROR); + return CC_ERROR; c_delbefore1(el); el->el_line.cursor--; - return (CC_REFRESH); + return CC_REFRESH; } @@ -599,32 +602,32 @@ vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*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 } } @@ -636,18 +639,18 @@ vi_list_or_eof(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -vi_kill_line_prev(EditLine *el, int c __attribute__((__unused__))) +vi_kill_line_prev(EditLine *el, Int c __attribute__((__unused__))) { - char *kp, *cp; + Char *kp, *cp; cp = el->el_line.buffer; kp = el->el_chared.c_kill.buf; while (cp < el->el_line.cursor) *kp++ = *cp++; /* copy it */ el->el_chared.c_kill.last = kp; - c_delbefore(el, el->el_line.cursor - el->el_line.buffer); + c_delbefore(el, (int)(el->el_line.cursor - el->el_line.buffer)); el->el_line.cursor = el->el_line.buffer; /* zap! */ - return (CC_REFRESH); + return CC_REFRESH; } @@ -657,10 +660,10 @@ vi_kill_line_prev(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_search_prev(EditLine *el, int c __attribute__((__unused__))) +vi_search_prev(EditLine *el, Int c __attribute__((__unused__))) { - return (cv_search(el, ED_SEARCH_PREV_HISTORY)); + return cv_search(el, ED_SEARCH_PREV_HISTORY); } @@ -670,10 +673,10 @@ vi_search_prev(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_search_next(EditLine *el, int c __attribute__((__unused__))) +vi_search_next(EditLine *el, Int c __attribute__((__unused__))) { - return (cv_search(el, ED_SEARCH_NEXT_HISTORY)); + return cv_search(el, ED_SEARCH_NEXT_HISTORY); } @@ -683,13 +686,13 @@ vi_search_next(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_repeat_search_next(EditLine *el, int c __attribute__((__unused__))) +vi_repeat_search_next(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_search.patlen == 0) - 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); } @@ -699,11 +702,11 @@ vi_repeat_search_next(EditLine *el, int c __attribute__((__unused__))) */ /*ARGSUSED*/ protected el_action_t -vi_repeat_search_prev(EditLine *el, int c __attribute__((__unused__))) +vi_repeat_search_prev(EditLine *el, Int c __attribute__((__unused__))) { if (el->el_search.patlen == 0) - return (CC_ERROR); + return CC_ERROR; else return (cv_repeat_srch(el, el->el_search.patdir == ED_SEARCH_PREV_HISTORY ? @@ -717,7 +720,7 @@ vi_repeat_search_prev(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_next_char(EditLine *el, int c __attribute__((__unused__))) +vi_next_char(EditLine *el, Int c __attribute__((__unused__))) { return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0); } @@ -729,7 +732,7 @@ vi_next_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_prev_char(EditLine *el, int c __attribute__((__unused__))) +vi_prev_char(EditLine *el, Int c __attribute__((__unused__))) { return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0); } @@ -741,7 +744,7 @@ vi_prev_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_to_next_char(EditLine *el, int c __attribute__((__unused__))) +vi_to_next_char(EditLine *el, Int c __attribute__((__unused__))) { return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1); } @@ -753,7 +756,7 @@ vi_to_next_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_to_prev_char(EditLine *el, int c __attribute__((__unused__))) +vi_to_prev_char(EditLine *el, Int c __attribute__((__unused__))) { return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1); } @@ -765,7 +768,7 @@ vi_to_prev_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_repeat_next_char(EditLine *el, int c __attribute__((__unused__))) +vi_repeat_next_char(EditLine *el, Int c __attribute__((__unused__))) { return cv_csearch(el, el->el_search.chadir, el->el_search.chacha, @@ -779,7 +782,7 @@ vi_repeat_next_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_repeat_prev_char(EditLine *el, int c __attribute__((__unused__))) +vi_repeat_prev_char(EditLine *el, Int c __attribute__((__unused__))) { el_action_t r; int dir = el->el_search.chadir; @@ -797,20 +800,20 @@ vi_repeat_prev_char(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_match(EditLine *el, int c __attribute__((__unused__))) +vi_match(EditLine *el, Int c __attribute__((__unused__))) { - const char match_chars[] = "()[]{}"; - char *cp; - int delta, i, count; - char o_ch, c_ch; + const Char match_chars[] = STR("()[]{}"); + Char *cp; + size_t delta, i, count; + Char o_ch, c_ch; *el->el_line.lastchar = '\0'; /* just in case */ - i = strcspn(el->el_line.cursor, match_chars); + i = Strcspn(el->el_line.cursor, match_chars); o_ch = el->el_line.cursor[i]; if (o_ch == 0) return CC_ERROR; - delta = strchr(match_chars, o_ch) - match_chars; + delta = (size_t)(Strchr(match_chars, o_ch) - match_chars); c_ch = match_chars[delta ^ 1]; count = 1; delta = 1 - (delta & 1) * 2; @@ -833,9 +836,9 @@ vi_match(EditLine *el, int c __attribute__((__unused__))) 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(): @@ -844,7 +847,7 @@ vi_match(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_undo_line(EditLine *el, int c __attribute__((__unused__))) +vi_undo_line(EditLine *el, Int c __attribute__((__unused__))) { cv_undo(el); @@ -858,7 +861,7 @@ vi_undo_line(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_to_column(EditLine *el, int c __attribute__((__unused__))) +vi_to_column(EditLine *el, Int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; @@ -872,11 +875,11 @@ vi_to_column(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_yank_end(EditLine *el, int c __attribute__((__unused__))) +vi_yank_end(EditLine *el, Int c __attribute__((__unused__))) { cv_yank(el, el->el_line.cursor, - el->el_line.lastchar - el->el_line.cursor); + (int)(el->el_line.lastchar - el->el_line.cursor)); return CC_REFRESH; } @@ -886,7 +889,7 @@ vi_yank_end(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_yank(EditLine *el, int c __attribute__((__unused__))) +vi_yank(EditLine *el, Int c __attribute__((__unused__))) { return cv_action(el, YANK); @@ -898,7 +901,7 @@ vi_yank(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_comment_out(EditLine *el, int c __attribute__((__unused__))) +vi_comment_out(EditLine *el, Int c __attribute__((__unused__))) { el->el_line.cursor = el->el_line.buffer; @@ -915,18 +918,19 @@ vi_comment_out(EditLine *el, int c __attribute__((__unused__))) * this is against historical precedent... */ #if defined(__weak_reference) && !defined(__FreeBSD__) -extern char *get_alias_text(const char *) __weak_reference(get_alias_text); +__weakref_visible char *my_get_alias_text(const char *) + __weak_reference(get_alias_text); #endif protected el_action_t /*ARGSUSED*/ vi_alias(EditLine *el __attribute__((__unused__)), - int c __attribute__((__unused__))) + Int c __attribute__((__unused__))) { #if defined(__weak_reference) && !defined(__FreeBSD__) char alias_name[3]; char *alias_text; - if (get_alias_text == 0) { + if (my_get_alias_text == 0) { return CC_ERROR; } @@ -935,9 +939,9 @@ vi_alias(EditLine *el __attribute__((__unused__)), 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; @@ -950,14 +954,14 @@ vi_alias(EditLine *el __attribute__((__unused__)), */ protected el_action_t /*ARGSUSED*/ -vi_to_history_line(EditLine *el, int c __attribute__((__unused__))) +vi_to_history_line(EditLine *el, Int c __attribute__((__unused__))) { int sv_event_no = el->el_history.eventno; el_action_t rval; if (el->el_history.eventno == 0) { - (void) strncpy(el->el_history.buf, el->el_line.buffer, + (void) Strncpy(el->el_history.buf, el->el_line.buffer, EL_BUFSIZ); el->el_history.last = el->el_history.buf + (el->el_line.lastchar - el->el_line.buffer); @@ -995,14 +999,19 @@ vi_to_history_line(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_histedit(EditLine *el, int c __attribute__((__unused__))) +vi_histedit(EditLine *el, Int c __attribute__((__unused__))) { int fd; pid_t pid; - int st; + ssize_t st; + int status; char tempfile[] = "/tmp/histedit.XXXXXXXXXX"; char *cp; + size_t len; + Char *line; + mbstate_t state; + memset(&state, 0, sizeof(mbstate_t)); if (el->el_state.doingarg) { if (vi_to_history_line(el, 0) == CC_ERROR) return CC_ERROR; @@ -1011,16 +1020,35 @@ vi_histedit(EditLine *el, int c __attribute__((__unused__))) fd = mkstemp(tempfile); if (fd < 0) return CC_ERROR; - cp = el->el_line.buffer; - if (write(fd, cp, el->el_line.lastchar - cp +0u) == -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) { + unlink(tempfile); + close(fd); + return CC_ERROR; + } + line = el_malloc(len * sizeof(*line)); + if (line == NULL) { + el_free(cp); + return CC_ERROR; + } + Strncpy(line, el->el_line.buffer, len); + line[len] = '\0'; + wcsrtombs(cp, (const wchar_t **) &line, TMP_BUFSIZ - 1, &state); + cp[TMP_BUFSIZ - 1] = '\0'; + len = strlen(cp); + if (write(fd, cp, len) == -1) goto error; - if (write(fd, "\n", 1) == -1) + if (write(fd, "\n", (size_t)1) == -1) goto error; pid = fork(); switch (pid) { case -1: close(fd); unlink(tempfile); + el_free(cp); + el_free(line); return CC_ERROR; case 0: close(fd); @@ -1028,14 +1056,25 @@ vi_histedit(EditLine *el, int c __attribute__((__unused__))) exit(0); /*NOTREACHED*/ default: - while (waitpid(pid, &st, 0) != pid) + while (waitpid(pid, &status, 0) != pid) continue; - lseek(fd, 0ll, SEEK_SET); - st = read(fd, cp, el->el_line.limit - cp +0u); - if (st > 0 && cp[st - 1] == '\n') - st--; - el->el_line.cursor = cp; - el->el_line.lastchar = cp + st; + lseek(fd, (off_t)0, SEEK_SET); + st = read(fd, cp, TMP_BUFSIZ); + if (st > 0) { + len = (size_t)(el->el_line.lastchar - + el->el_line.buffer); + memset(&state, 0, sizeof(mbstate_t)); + len = mbsrtowcs(el->el_line.buffer, + (const char**) &cp, len, &state); + if (len > 0 && el->el_line.buffer[len -1] == '\n') + --len; + } + else + len = 0; + el->el_line.cursor = el->el_line.buffer; + el->el_line.lastchar = el->el_line.buffer + len; + el_free(cp); + el_free(line); break; } @@ -1059,34 +1098,35 @@ error: */ protected el_action_t /*ARGSUSED*/ -vi_history_word(EditLine *el, int c __attribute__((__unused__))) +vi_history_word(EditLine *el, Int c __attribute__((__unused__))) { - const char *wp = HIST_FIRST(el); - const char *wep, *wsp; + const Char *wp = HIST_FIRST(el); + const Char *wep, *wsp; int len; - char *cp; - const char *lim; + Char *cp; + const Char *lim; if (wp == NULL) return CC_ERROR; wep = wsp = 0; do { - while (isspace((unsigned char)*wp)) + while (Isspace(*wp)) wp++; if (*wp == 0) break; wsp = wp; - while (*wp && !isspace((unsigned char)*wp)) + while (*wp && !Isspace(*wp)) wp++; wep = wp; - } while ((!el->el_state.doingarg || --el->el_state.argument > 0) && *wp != 0); + } while ((!el->el_state.doingarg || --el->el_state.argument > 0) + && *wp != 0); if (wsp == 0 || (el->el_state.doingarg && el->el_state.argument != 0)) return CC_ERROR; cv_undo(el); - len = wep - wsp; + len = (int)(wep - wsp); if (el->el_line.cursor < el->el_line.lastchar) el->el_line.cursor++; c_insert(el, len + 1); @@ -1108,7 +1148,7 @@ vi_history_word(EditLine *el, int c __attribute__((__unused__))) */ protected el_action_t /*ARGSUSED*/ -vi_redo(EditLine *el, int c __attribute__((__unused__))) +vi_redo(EditLine *el, Int c __attribute__((__unused__))) { c_redo_t *r = &el->el_chared.c_redo; @@ -1124,10 +1164,10 @@ vi_redo(EditLine *el, int c __attribute__((__unused__))) /* 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); } |