diff options
author | unknown <tomas@poseidon.(none)> | 2004-08-24 22:35:14 +0000 |
---|---|---|
committer | unknown <tomas@poseidon.(none)> | 2004-08-24 22:35:14 +0000 |
commit | 8bb0aaa51661bc842832ad131cb43b6f0e50f29a (patch) | |
tree | 0138fe722f01dc674c37ea0e9b7f181bcd863f82 | |
parent | 1e91f015caeeec47c65b754d19ac956d79ded31d (diff) | |
parent | 9f2b7e91b6a6eee0e4e1629ea4d55782a81c78bb (diff) | |
download | mariadb-git-8bb0aaa51661bc842832ad131cb43b6f0e50f29a.tar.gz |
Merge
acinclude.m4:
Auto merged
configure.in:
Auto merged
ndb/src/common/mgmcommon/ConfigInfo.hpp:
Auto merged
ndb/src/common/mgmcommon/InitConfigFileParser.cpp:
Auto merged
mysql-test/ndb/ndb_config_2_node.ini:
SCCS merged
ndb/src/common/mgmcommon/ConfigInfo.cpp:
SCCS merged
84 files changed, 4579 insertions, 1309 deletions
diff --git a/.bzrignore b/.bzrignore index 1a756801461..162872e39cf 100644 --- a/.bzrignore +++ b/.bzrignore @@ -14,6 +14,7 @@ */.pure *~ .*.swp +./config.h .defs.mk .depend .depend.mk @@ -830,6 +831,7 @@ support-files/MacOSX/postinstall support-files/MacOSX/preinstall support-files/binary-configure support-files/my-huge.cnf +support-files/my-innodb-heavy-4G.cnf support-files/my-large.cnf support-files/my-medium.cnf support-files/my-small.cnf diff --git a/Build-tools/mysql-copyright b/Build-tools/mysql-copyright index 92b8f13bf48..77a90fbf4e4 100755 --- a/Build-tools/mysql-copyright +++ b/Build-tools/mysql-copyright @@ -204,7 +204,7 @@ sub trim_the_fat open(CONFIGURE,">configure.in") or die "Unable to open configure.in for write: $!\n"; print CONFIGURE $configure; close(CONFIGURE); - `autoconf`; + `aclocal && autoheader && aclocal && automake && autoconf`; die "'./configure' was not produced!" unless (-f "configure"); chdir("$cwd"); } diff --git a/acinclude.m4 b/acinclude.m4 index 809e5e768e5..cf9c8c0e3c5 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -6,7 +6,6 @@ AC_DEFUN(MYSQL_CHECK_READLINE_DECLARES_HIST_ENTRY,[ AC_TRY_COMPILE( [ #include "stdio.h" - #undef __P // readline-4.2 declares own __P #include "readline/readline.h" ], [ @@ -27,7 +26,6 @@ AC_DEFUN(MYSQL_CHECK_LIBEDIT_INTERFACE,[ AC_TRY_COMPILE( [ #include "stdio.h" - #undef __P // readline-4.2 declares own __P #include "readline/readline.h" ], [ @@ -49,7 +47,6 @@ AC_DEFUN(MYSQL_CHECK_NEW_RL_INTERFACE,[ AC_TRY_COMPILE( [ #include "stdio.h" - #undef __P // readline-4.2 declares own __P #include "readline/readline.h" ], [ diff --git a/client/mysql.cc b/client/mysql.cc index 0fb6184e78a..be4c6d3df3c 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -84,7 +84,6 @@ extern "C" { #if defined( __WIN__) || defined(OS2) #include <conio.h> #elif !defined(__NETWARE__) -#undef __P // readline-4.2 declares own __P #include <readline/readline.h> #define HAVE_READLINE #endif diff --git a/cmd-line-utils/libedit/Makefile.am b/cmd-line-utils/libedit/Makefile.am index eb6b930c0b2..c532884ca7d 100644 --- a/cmd-line-utils/libedit/Makefile.am +++ b/cmd-line-utils/libedit/Makefile.am @@ -7,28 +7,30 @@ AHDR=vi.h emacs.h common.h INCLUDES = -I$(top_srcdir)/include -I$(srcdir)/../.. -I.. -noinst_LIBRARIES = liblibedit.a +noinst_LIBRARIES = libedit.a -liblibedit_a_SOURCES = chared.c el.c fgetln.c history.c map.c \ - prompt.c readline.c search.c \ - strlcpy.c tokenizer.c vi.c common.c \ - emacs.c hist.c key.c parse.c read.c \ - refresh.c sig.c term.c tty.c help.c \ - fcns.c +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 \ + tty.c help.c fcns.c + +EXTRA_libedit_a_SOURCES = np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c \ + np/fgetln.c + +libedit_a_LIBADD = @LIBEDIT_LOBJECTS@ +libedit_a_DEPENDENCIES = @LIBEDIT_LOBJECTS@ pkginclude_HEADERS = readline/readline.h -noinst_HEADERS = chared.h el.h histedit.h key.h \ - parse.h refresh.h sig.h sys.h \ - tokenizer.h compat.h compat_conf.h fgetln.h \ - hist.h map.h prompt.h search.h \ - strlcpy.h libedit_term.h tty.h +noinst_HEADERS = chared.h el.h histedit.h key.h parse.h refresh.h sig.h \ + sys.h tokenizer.h config.h hist.h map.h prompt.h \ + search.h tty.h -EXTRA_DIST = makelist.sh +EXTRA_DIST = makelist.sh np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c np/fgetln.c -CLEANFILES = makelist +CLEANFILES = makelist common.h emacs.h vi.h fcns.h help.h fcns.c help.c -DEFS = -DUNDEF_THREADS_HACK -DHAVE_CONFIG_H -DNO_KILL_INTR +DEFS = -DUNDEF_THREADS_HACK -DHAVE_CONFIG_H -DNO_KILL_INTR '-D__RCSID(x)=' '-D__COPYRIGHT(x)=' '-D__RENAME(x)=' '-D_DIAGASSERT(x)=' SUFFIXES = .sh @@ -73,13 +75,11 @@ 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 -fgetln.o: vi.h emacs.h common.h help.h fcns.h history.o: vi.h emacs.h common.h help.h fcns.h map.o: vi.h emacs.h common.h help.h fcns.h prompt.o: vi.h emacs.h common.h help.h fcns.h readline.o: vi.h emacs.h common.h help.h fcns.h search.o: vi.h emacs.h common.h help.h fcns.h -strlcpy.o: vi.h emacs.h common.h help.h fcns.h tokenizer.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 diff --git a/cmd-line-utils/libedit/chared.c b/cmd-line-utils/libedit/chared.c index 6ac051c3bb0..559e714d9fd 100644 --- a/cmd-line-utils/libedit/chared.c +++ b/cmd-line-utils/libedit/chared.c @@ -1,4 +1,4 @@ -/* $NetBSD: chared.c,v 1.14 2001/05/17 01:02:17 christos Exp $ */ +/* $NetBSD: chared.c,v 1.18 2002/11/20 16:50:08 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,13 +36,18 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: chared.c,v 1.18 2002/11/20 16:50:08 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * chared.c: Character editor utilities */ -#include "sys.h" - #include <stdlib.h> #include "el.h" @@ -53,17 +58,36 @@ * Handle state for the vi undo command */ protected void -cv_undo(EditLine *el,int action, size_t size, char *ptr) +cv_undo(EditLine *el) { c_undo_t *vu = &el->el_chared.c_undo; - vu->action = action; - vu->ptr = ptr; - vu->isize = size; - (void) memcpy(vu->buf, vu->ptr, size); -#ifdef DEBUG_UNDO - (void) fprintf(el->el_errfile, "Undo buffer \"%s\" size = +%d -%d\n", - vu->ptr, vu->isize, vu->dsize); -#endif + c_redo_t *r = &el->el_chared.c_redo; + uint 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); + + /* save command info for redo */ + r->count = el->el_state.doingarg ? el->el_state.argument : 0; + r->action = el->el_chared.c_vcmd.action; + r->pos = r->buf; + r->cmd = el->el_state.thiscmd; + r->ch = el->el_state.thisch; +} + +/* cv_yank(): + * Save yank/delete data for paste + */ +protected void +cv_yank(EditLine *el, const char *ptr, int size) +{ + c_kill_t *k = &el->el_chared.c_kill; + + memcpy(k->buf, ptr, size +0u); + k->last = k->buf + size; } @@ -75,8 +99,10 @@ c_insert(EditLine *el, int num) { char *cp; - if (el->el_line.lastchar + num >= el->el_line.limit) - return; /* can't go past end of buffer */ + if (el->el_line.lastchar + num >= el->el_line.limit) { + if (!ch_enlargebufs(el, num +0u)) + return; /* can't go past end of buffer */ + } if (el->el_line.cursor < el->el_line.lastchar) { /* if I must move chars */ @@ -97,12 +123,14 @@ c_delafter(EditLine *el, int num) if (el->el_line.cursor + num > el->el_line.lastchar) num = el->el_line.lastchar - el->el_line.cursor; + if (el->el_map.current != el->el_map.emacs) { + cv_undo(el); + cv_yank(el, el->el_line.cursor, num); + } + if (num > 0) { char *cp; - if (el->el_map.current != el->el_map.emacs) - cv_undo(el, INSERT, (size_t)num, el->el_line.cursor); - for (cp = el->el_line.cursor; cp <= el->el_line.lastchar; cp++) *cp = cp[num]; @@ -121,13 +149,14 @@ c_delbefore(EditLine *el, int num) if (el->el_line.cursor - num < el->el_line.buffer) num = el->el_line.cursor - el->el_line.buffer; + if (el->el_map.current != el->el_map.emacs) { + cv_undo(el); + cv_yank(el, el->el_line.cursor - num, num); + } + if (num > 0) { char *cp; - if (el->el_map.current != el->el_map.emacs) - cv_undo(el, INSERT, (size_t)num, - el->el_line.cursor - num); - for (cp = el->el_line.cursor - num; cp <= el->el_line.lastchar; cp++) @@ -144,7 +173,7 @@ c_delbefore(EditLine *el, int num) protected int ce__isword(int p) { - return (isalpha(p) || isdigit(p) || strchr("*?_-.[]~=", p) != NULL); + return (isalnum(p) || strchr("*?_-.[]~=", p) != NULL); } @@ -154,6 +183,20 @@ ce__isword(int p) protected int cv__isword(int p) { + if (isalnum(p) || p == '_') + return 1; + if (isgraph(p)) + return 2; + return 0; +} + + +/* cv__isWord(): + * Return if p is part of a big word according to vi + */ +protected int +cv__isWord(int p) +{ return (!isspace(p)); } @@ -216,7 +259,7 @@ cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int)) * vi historically deletes with cw only the word preserving the * trailing whitespace! This is not what 'w' does.. */ - if (el->el_chared.c_vcmd.action != (DELETE|INSERT)) + if (n || el->el_chared.c_vcmd.action != (DELETE|INSERT)) while ((p < high) && isspace((unsigned char) *p)) p++; } @@ -233,26 +276,19 @@ cv_next_word(EditLine *el, char *p, char *high, int n, int (*wtest)(int)) * Find the previous word vi style */ protected char * -cv_prev_word(EditLine *el, char *p, char *low, int n, int (*wtest)(int)) +cv_prev_word(char *p, char *low, int n, int (*wtest)(int)) { int test; + p--; while (n--) { - p--; - /* - * vi historically deletes with cb only the word preserving the - * leading whitespace! This is not what 'b' does.. - */ - if (el->el_chared.c_vcmd.action != (DELETE|INSERT)) - while ((p > low) && isspace((unsigned char) *p)) - p--; + while ((p > low) && isspace((unsigned char) *p)) + p--; test = (*wtest)((unsigned char) *p); while ((p >= low) && (*wtest)((unsigned char) *p) == test) p--; - p++; - while (isspace((unsigned char) *p)) - p++; } + p++; /* p now points where we want it */ if (p < low) @@ -303,47 +339,34 @@ protected void cv_delfini(EditLine *el) { int size; - int oaction; + int action = el->el_chared.c_vcmd.action; - if (el->el_chared.c_vcmd.action & INSERT) + if (action & INSERT) el->el_map.current = el->el_map.key; - oaction = el->el_chared.c_vcmd.action; - el->el_chared.c_vcmd.action = NOP; - if (el->el_chared.c_vcmd.pos == 0) + /* sanity */ return; - - if (el->el_line.cursor > el->el_chared.c_vcmd.pos) { - size = (int) (el->el_line.cursor - el->el_chared.c_vcmd.pos); - c_delbefore(el, size); - el->el_line.cursor = el->el_chared.c_vcmd.pos; - re_refresh_cursor(el); - } else if (el->el_line.cursor < el->el_chared.c_vcmd.pos) { - size = (int)(el->el_chared.c_vcmd.pos - el->el_line.cursor); - c_delafter(el, size); - } else { + size = el->el_line.cursor - el->el_chared.c_vcmd.pos; + if (size == 0) size = 1; - c_delafter(el, size); - } - switch (oaction) { - case DELETE|INSERT: - el->el_chared.c_undo.action = DELETE|INSERT; - break; - case DELETE: - el->el_chared.c_undo.action = INSERT; - break; - case NOP: - case INSERT: - default: - EL_ABORT((el->el_errfile, "Bad oaction %d\n", oaction)); - break; + el->el_line.cursor = el->el_chared.c_vcmd.pos; + if (action & YANK) { + if (size > 0) + cv_yank(el, el->el_line.cursor, size); + else + cv_yank(el, el->el_line.cursor + size, -size); + } else { + if (size > 0) { + c_delafter(el, size); + re_refresh_cursor(el); + } else { + c_delbefore(el, -size); + el->el_line.cursor += size; + } } - - - el->el_chared.c_undo.ptr = el->el_line.cursor; - el->el_chared.c_undo.dsize = size; + el->el_chared.c_vcmd.action = NOP; } @@ -373,21 +396,19 @@ ce__endword(char *p, char *high, int n) * Go to the end of this word according to vi */ protected char * -cv__endword(char *p, char *high, int n) +cv__endword(char *p, char *high, int n, int (*wtest)(int)) { + int test; + p++; while (n--) { while ((p < high) && isspace((unsigned char) *p)) p++; - if (isalnum((unsigned char) *p)) - while ((p < high) && isalnum((unsigned char) *p)) - p++; - else - while ((p < high) && !(isspace((unsigned char) *p) || - isalnum((unsigned char) *p))) - p++; + test = (*wtest)((unsigned char) *p); + while ((p < high) && (*wtest)((unsigned char) *p) == test) + p++; } p--; return (p); @@ -406,20 +427,23 @@ ch_init(EditLine *el) (void) memset(el->el_line.buffer, 0, EL_BUFSIZ); el->el_line.cursor = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer; - el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - 2]; + el->el_line.limit = &el->el_line.buffer[EL_BUFSIZ - EL_LEAVE]; el->el_chared.c_undo.buf = (char *) el_malloc(EL_BUFSIZ); if (el->el_chared.c_undo.buf == NULL) return (-1); (void) memset(el->el_chared.c_undo.buf, 0, EL_BUFSIZ); - el->el_chared.c_undo.action = NOP; - el->el_chared.c_undo.isize = 0; - el->el_chared.c_undo.dsize = 0; - el->el_chared.c_undo.ptr = el->el_line.buffer; + el->el_chared.c_undo.len = -1; + el->el_chared.c_undo.cursor = 0; + el->el_chared.c_redo.buf = (char *) el_malloc(EL_BUFSIZ); + if (el->el_chared.c_redo.buf == NULL) + 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; el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.pos = el->el_line.buffer; - el->el_chared.c_vcmd.ins = el->el_line.buffer; el->el_chared.c_kill.buf = (char *) el_malloc(EL_BUFSIZ); if (el->el_chared.c_kill.buf == NULL) @@ -454,14 +478,11 @@ ch_reset(EditLine *el) el->el_line.cursor = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer; - el->el_chared.c_undo.action = NOP; - el->el_chared.c_undo.isize = 0; - el->el_chared.c_undo.dsize = 0; - el->el_chared.c_undo.ptr = el->el_line.buffer; + el->el_chared.c_undo.len = -1; + el->el_chared.c_undo.cursor = 0; el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.pos = el->el_line.buffer; - el->el_chared.c_vcmd.ins = el->el_line.buffer; el->el_chared.c_kill.mark = el->el_line.buffer; @@ -516,7 +537,8 @@ ch_enlargebufs(el, addlen) el->el_line.buffer = newbuffer; el->el_line.cursor = newbuffer + (el->el_line.cursor - oldbuf); el->el_line.lastchar = newbuffer + (el->el_line.lastchar - oldbuf); - el->el_line.limit = &newbuffer[newsz - EL_LEAVE]; + /* don't set new size until all buffers are enlarged */ + el->el_line.limit = &newbuffer[sz - EL_LEAVE]; /* * Reallocate kill buffer. @@ -545,14 +567,22 @@ ch_enlargebufs(el, addlen) /* zero the newly added memory, leave old data in */ (void) memset(&newbuffer[sz], 0, newsz - sz); - - el->el_chared.c_undo.ptr = el->el_line.buffer + - (el->el_chared.c_undo.ptr - oldbuf); el->el_chared.c_undo.buf = newbuffer; + + newbuffer = el_realloc(el->el_chared.c_redo.buf, newsz); + if (!newbuffer) + return 0; + el->el_chared.c_redo.pos = newbuffer + + (el->el_chared.c_redo.pos - el->el_chared.c_redo.buf); + el->el_chared.c_redo.lim = newbuffer + + (el->el_chared.c_redo.lim - el->el_chared.c_redo.buf); + el->el_chared.c_redo.buf = newbuffer; if (!hist_enlargebuf(el, sz, newsz)) return 0; + /* Safe to set enlarged buffer size */ + el->el_line.limit = &newbuffer[newsz - EL_LEAVE]; return 1; } @@ -567,6 +597,11 @@ ch_end(EditLine *el) el->el_line.limit = NULL; el_free((ptr_t) el->el_chared.c_undo.buf); el->el_chared.c_undo.buf = NULL; + el_free((ptr_t) el->el_chared.c_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->el_chared.c_kill.buf = NULL; el_free((ptr_t) el->el_chared.c_macro.macro); @@ -619,51 +654,64 @@ el_deletestr(EditLine *el, int n) * Get a string */ protected int -c_gets(EditLine *el, char *buf) +c_gets(EditLine *el, char *buf, const char *prompt) { char ch; - int len = 0; + int len; + char *cp = el->el_line.buffer; + + if (prompt) { + len = strlen(prompt); + memcpy(cp, prompt, len + 0u); + cp += len; + } + len = 0; + + for (;;) { + el->el_line.cursor = cp; + *cp = ' '; + el->el_line.lastchar = cp + 1; + re_refresh(el); + + if (el_getc(el, &ch) != 1) { + ed_end_of_file(el, 0); + len = -1; + break; + } - for (ch = 0; ch == 0;) { - if (el_getc(el, &ch) != 1) - return (ed_end_of_file(el, 0)); switch (ch) { + case 0010: /* Delete and backspace */ case 0177: - if (len > 1) { - *el->el_line.cursor-- = '\0'; - el->el_line.lastchar = el->el_line.cursor; - buf[len--] = '\0'; - } else { - el->el_line.buffer[0] = '\0'; - el->el_line.lastchar = el->el_line.buffer; - el->el_line.cursor = el->el_line.buffer; - return (CC_REFRESH); + if (len <= 0) { + len = -1; + break; } - re_refresh(el); - ch = 0; - break; + cp--; + continue; case 0033: /* ESC */ case '\r': /* Newline */ case '\n': + buf[len] = ch; break; default: - if (len >= EL_BUFSIZ) + if (len >= EL_BUFSIZ - 16) term_beep(el); else { buf[len++] = ch; - *el->el_line.cursor++ = ch; - el->el_line.lastchar = el->el_line.cursor; + *cp++ = ch; } - re_refresh(el); - ch = 0; - break; + continue; } + break; } - buf[len] = ch; - return (len); + + el->el_line.buffer[0] = '\0'; + el->el_line.lastchar = el->el_line.buffer; + el->el_line.cursor = el->el_line.buffer; + return len; } diff --git a/cmd-line-utils/libedit/chared.h b/cmd-line-utils/libedit/chared.h index 2eb9ad32886..d2e6f742413 100644 --- a/cmd-line-utils/libedit/chared.h +++ b/cmd-line-utils/libedit/chared.h @@ -1,4 +1,4 @@ -/* $NetBSD: chared.h,v 1.6 2001/01/10 07:45:41 jdolecek Exp $ */ +/* $NetBSD: chared.h,v 1.11 2002/11/20 16:50:08 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -71,23 +71,31 @@ typedef struct c_macro_t { } c_macro_t; /* - * Undo information for both vi and emacs + * Undo information for vi - no undo in emacs (yet) */ typedef struct c_undo_t { - int action; - size_t isize; - size_t dsize; - char *ptr; - char *buf; + int len; /* length of saved line */ + int cursor; /* position of saved cursor */ + 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; + el_action_t cmd; /* command to redo */ + char ch; /* char that invoked it */ + int count; + int action; /* from cv_action() */ +} c_redo_t; + /* * Current action information for vi */ typedef struct c_vcmd_t { int action; char *pos; - char *ins; } c_vcmd_t; /* @@ -106,6 +114,7 @@ typedef struct c_kill_t { typedef struct el_chared_t { c_undo_t c_undo; c_kill_t c_kill; + c_redo_t c_redo; c_vcmd_t c_vcmd; c_macro_t c_macro; } el_chared_t; @@ -120,10 +129,10 @@ typedef struct el_chared_t { #define NOP 0x00 #define DELETE 0x01 #define INSERT 0x02 -#define CHANGE 0x04 +#define YANK 0x04 -#define CHAR_FWD 0 -#define CHAR_BACK 1 +#define CHAR_FWD (+1) +#define CHAR_BACK (-1) #define MODE_INSERT 0 #define MODE_REPLACE 1 @@ -137,23 +146,25 @@ typedef struct el_chared_t { protected int cv__isword(int); +protected int cv__isWord(int); protected void cv_delfini(EditLine *); -protected char *cv__endword(char *, char *, int); +protected char *cv__endword(char *, char *, int, int (*)(int)); protected int ce__isword(int); -protected void cv_undo(EditLine *, int, size_t, char *); +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(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_delafter(EditLine *, int); -protected int c_gets(EditLine *, char *); +protected int c_gets(EditLine *, char *, const char *); protected int c_hpos(EditLine *); protected int ch_init(EditLine *); protected void ch_reset(EditLine *); -protected int ch_enlargebufs __P((EditLine *, size_t)); +protected int ch_enlargebufs(EditLine *, size_t); protected void ch_end(EditLine *); #endif /* _h_el_chared */ diff --git a/cmd-line-utils/libedit/common.c b/cmd-line-utils/libedit/common.c index 9ac6af9ac1b..f290057568a 100644 --- a/cmd-line-utils/libedit/common.c +++ b/cmd-line-utils/libedit/common.c @@ -1,4 +1,4 @@ -/* $NetBSD: common.c,v 1.10 2001/01/10 07:45:41 jdolecek Exp $ */ +/* $NetBSD: common.c,v 1.14 2002/11/20 16:50:08 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,12 +36,18 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: common.c,v 1.14 2002/11/20 16:50:08 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * common.c: Common Editor functions */ -#include "sys.h" #include "el.h" /* ed_end_of_file(): @@ -66,7 +72,7 @@ ed_end_of_file(EditLine *el, int c __attribute__((unused))) protected el_action_t ed_insert(EditLine *el, int c) { - int i; + int count = el->el_state.argument; if (c == '\0') return (CC_ERROR); @@ -74,42 +80,28 @@ ed_insert(EditLine *el, int c) if (el->el_line.lastchar + el->el_state.argument >= el->el_line.limit) { /* end of buffer space, try to allocate more */ - if (!ch_enlargebufs(el, (size_t) el->el_state.argument)) + if (!ch_enlargebufs(el, (size_t) count)) return CC_ERROR; /* error allocating more */ } - if (el->el_state.argument == 1) { - if (el->el_state.inputmode != MODE_INSERT) { - el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] = - *el->el_line.cursor; - el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = - '\0'; - c_delafter(el, 1); - } - c_insert(el, 1); + if (count == 1) { + if (el->el_state.inputmode == MODE_INSERT + || el->el_line.cursor >= el->el_line.lastchar) + c_insert(el, 1); *el->el_line.cursor++ = c; - el->el_state.doingarg = 0; /* just in case */ re_fastaddc(el); /* fast refresh for one char. */ } else { - if (el->el_state.inputmode != MODE_INSERT) { - for (i = 0; i < el->el_state.argument; i++) - el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] = - el->el_line.cursor[i]; - - el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = - '\0'; - c_delafter(el, el->el_state.argument); - } - c_insert(el, el->el_state.argument); + if (el->el_state.inputmode != MODE_REPLACE_1) + c_insert(el, el->el_state.argument); - while (el->el_state.argument--) + while (count-- && el->el_line.cursor < el->el_line.lastchar) *el->el_line.cursor++ = c; re_refresh(el); } if (el->el_state.inputmode == MODE_REPLACE_1) - (void) vi_command_mode(el, 0); + return vi_command_mode(el, 0); return (CC_NORM); } @@ -229,7 +221,7 @@ ed_move_to_end(EditLine *el, int c __attribute__((unused))) #ifdef VI_MOVE el->el_line.cursor--; #endif - if (el->el_chared.c_vcmd.action & DELETE) { + if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); return (CC_REFRESH); } @@ -253,7 +245,7 @@ ed_move_to_beg(EditLine *el, int c __attribute__((unused))) /* We want FIRST non space character */ while (isspace((unsigned char) *el->el_line.cursor)) el->el_line.cursor++; - if (el->el_chared.c_vcmd.action & DELETE) { + if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); return (CC_REFRESH); } @@ -295,16 +287,20 @@ protected el_action_t /*ARGSUSED*/ ed_next_char(EditLine *el, int c __attribute__((unused))) { + char *lim = el->el_line.lastchar; - if (el->el_line.cursor >= 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); el->el_line.cursor += el->el_state.argument; - if (el->el_line.cursor > el->el_line.lastchar) - el->el_line.cursor = el->el_line.lastchar; + if (el->el_line.cursor > lim) + el->el_line.cursor = lim; if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action & DELETE) { + if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); return (CC_REFRESH); } @@ -330,7 +326,7 @@ ed_prev_word(EditLine *el, int c __attribute__((unused))) ce__isword); if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action & DELETE) { + if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); return (CC_REFRESH); } @@ -353,7 +349,7 @@ ed_prev_char(EditLine *el, int c __attribute__((unused))) el->el_line.cursor = el->el_line.buffer; if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action & DELETE) { + if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); return (CC_REFRESH); } @@ -405,25 +401,9 @@ ed_digit(EditLine *el, int c) (el->el_state.argument * 10) + (c - '0'); } return (CC_ARGHACK); - } else { - if (el->el_line.lastchar + 1 >= el->el_line.limit) { - if (!ch_enlargebufs(el, 1)) - return (CC_ERROR); - } - - if (el->el_state.inputmode != MODE_INSERT) { - el->el_chared.c_undo.buf[el->el_chared.c_undo.isize++] = - *el->el_line.cursor; - el->el_chared.c_undo.buf[el->el_chared.c_undo.isize] = - '\0'; - c_delafter(el, 1); - } - c_insert(el, 1); - *el->el_line.cursor++ = c; - el->el_state.doingarg = 0; - re_fastaddc(el); } - return (CC_NORM); + + return ed_insert(el, c); } @@ -457,12 +437,11 @@ ed_argument_digit(EditLine *el, int c) */ protected el_action_t /*ARGSUSED*/ -ed_unassigned(EditLine *el, int c __attribute__((unused))) +ed_unassigned(EditLine *el __attribute__((unused)), + int c __attribute__((unused))) { - term_beep(el); - term__flush(); - return (CC_NORM); + return (CC_ERROR); } @@ -490,7 +469,7 @@ ed_tty_sigint(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_tty_dsusp(EditLine *el __attribute__((unused)), +ed_tty_dsusp(EditLine *el __attribute__((unused)), int c __attribute__((unused))) { @@ -504,7 +483,7 @@ ed_tty_dsusp(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_tty_flush_output(EditLine *el __attribute__((unused)), +ed_tty_flush_output(EditLine *el __attribute__((unused)), int c __attribute__((unused))) { @@ -518,7 +497,7 @@ ed_tty_flush_output(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_tty_sigquit(EditLine *el __attribute__((unused)), +ed_tty_sigquit(EditLine *el __attribute__((unused)), int c __attribute__((unused))) { @@ -532,7 +511,7 @@ ed_tty_sigquit(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_tty_sigtstp(EditLine *el __attribute__((unused)), +ed_tty_sigtstp(EditLine *el __attribute__((unused)), int c __attribute__((unused))) { @@ -546,7 +525,7 @@ ed_tty_sigtstp(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_tty_stop_output(EditLine *el __attribute__((unused)), +ed_tty_stop_output(EditLine *el __attribute__((unused)), int c __attribute__((unused))) { @@ -560,7 +539,7 @@ ed_tty_stop_output(EditLine *el __attribute__((unused)), */ protected el_action_t /*ARGSUSED*/ -ed_tty_start_output(EditLine *el __attribute__((unused)), +ed_tty_start_output(EditLine *el __attribute__((unused)), int c __attribute__((unused))) { @@ -580,8 +559,6 @@ ed_newline(EditLine *el, int c __attribute__((unused))) re_goto_bottom(el); *el->el_line.lastchar++ = '\n'; *el->el_line.lastchar = '\0'; - if (el->el_map.type == MAP_VI) - el->el_chared.c_vcmd.ins = el->el_line.buffer; return (CC_NEWLINE); } @@ -627,7 +604,7 @@ ed_clear_screen(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_redisplay(EditLine *el __attribute__((unused)), +ed_redisplay(EditLine *el __attribute__((unused)), int c __attribute__((unused))) { @@ -655,7 +632,7 @@ ed_start_over(EditLine *el, int c __attribute__((unused))) */ protected el_action_t /*ARGSUSED*/ -ed_sequence_lead_in(EditLine *el __attribute__((unused)), +ed_sequence_lead_in(EditLine *el __attribute__((unused)), int c __attribute__((unused))) { @@ -672,8 +649,9 @@ protected el_action_t ed_prev_history(EditLine *el, int c __attribute__((unused))) { char beep = 0; + int sv_event = el->el_history.eventno; - el->el_chared.c_undo.action = NOP; + el->el_chared.c_undo.len = -1; *el->el_line.lastchar = '\0'; /* just in case */ if (el->el_history.eventno == 0) { /* save the current buffer @@ -686,15 +664,17 @@ ed_prev_history(EditLine *el, int c __attribute__((unused))) el->el_history.eventno += el->el_state.argument; 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 */ (void) hist_get(el); } - re_refresh(el); if (beep) - return (CC_ERROR); - else - return (CC_NORM); /* was CC_UP_HIST */ + return CC_REFRESH_BEEP; + return CC_REFRESH; } @@ -706,17 +686,22 @@ protected el_action_t /*ARGSUSED*/ ed_next_history(EditLine *el, int c __attribute__((unused))) { + el_action_t beep = CC_REFRESH, rval; - el->el_chared.c_undo.action = NOP; + el->el_chared.c_undo.len = -1; *el->el_line.lastchar = '\0'; /* just in case */ el->el_history.eventno -= el->el_state.argument; if (el->el_history.eventno < 0) { el->el_history.eventno = 0; - return (CC_ERROR);/* make it beep */ + beep = CC_REFRESH_BEEP; } - return (hist_get(el)); + rval = hist_get(el); + if (rval == CC_REFRESH) + return beep; + return rval; + } @@ -733,7 +718,7 @@ ed_search_prev_history(EditLine *el, int c __attribute__((unused))) bool_t found = 0; el->el_chared.c_vcmd.action = NOP; - el->el_chared.c_undo.action = NOP; + el->el_chared.c_undo.len = -1; *el->el_line.lastchar = '\0'; /* just in case */ if (el->el_history.eventno < 0) { #ifdef DEBUG_EDIT @@ -801,7 +786,7 @@ ed_search_next_history(EditLine *el, int c __attribute__((unused))) bool_t found = 0; el->el_chared.c_vcmd.action = NOP; - el->el_chared.c_undo.action = NOP; + el->el_chared.c_undo.len = -1; *el->el_line.lastchar = '\0'; /* just in case */ if (el->el_history.eventno == 0) @@ -930,25 +915,13 @@ ed_command(EditLine *el, int c __attribute__((unused))) char tmpbuf[EL_BUFSIZ]; int tmplen; - el->el_line.buffer[0] = '\0'; - el->el_line.lastchar = el->el_line.buffer; - el->el_line.cursor = el->el_line.buffer; - - c_insert(el, 3); /* prompt + ": " */ - *el->el_line.cursor++ = '\n'; - *el->el_line.cursor++ = ':'; - *el->el_line.cursor++ = ' '; - re_refresh(el); + tmplen = c_gets(el, tmpbuf, "\n: "); + term__putc('\n'); - tmplen = c_gets(el, tmpbuf); - tmpbuf[tmplen] = '\0'; - - el->el_line.buffer[0] = '\0'; - el->el_line.lastchar = el->el_line.buffer; - el->el_line.cursor = el->el_line.buffer; + if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1) + term_beep(el); - if (parse_line(el, tmpbuf) == -1) - return (CC_ERROR); - else - return (CC_REFRESH); + el->el_map.current = el->el_map.key; + re_clear_display(el); + return CC_REFRESH; } diff --git a/cmd-line-utils/libedit/config.h b/cmd-line-utils/libedit/config.h new file mode 100644 index 00000000000..966cd1bedc0 --- /dev/null +++ b/cmd-line-utils/libedit/config.h @@ -0,0 +1,3 @@ + +#include "my_config.h" +#include "sys.h" diff --git a/cmd-line-utils/libedit/el.c b/cmd-line-utils/libedit/el.c index 76b17aba0cf..aa4b5c6896b 100644 --- a/cmd-line-utils/libedit/el.c +++ b/cmd-line-utils/libedit/el.c @@ -1,4 +1,4 @@ -/* $NetBSD: el.c,v 1.21 2001/01/05 22:45:30 christos Exp $ */ +/* $NetBSD: el.c,v 1.30 2002/11/12 00:00:23 thorpej Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,13 +36,18 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94"; +#else +__RCSID("$NetBSD: el.c,v 1.30 2002/11/12 00:00:23 thorpej Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * el.c: EditLine interface functions */ -#include "sys.h" - #include <sys/types.h> #include <sys/param.h> #include <string.h> @@ -58,9 +63,6 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) { EditLine *el = (EditLine *) el_malloc(sizeof(EditLine)); -#ifdef DEBUG - char *tty; -#endif if (el == NULL) return (NULL); @@ -77,7 +79,11 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) */ el->el_flags = 0; - (void) term_init(el); + if (term_init(el) == -1) { + free(el->el_prog); + el_free(el); + return NULL; + } (void) key_init(el); (void) map_init(el); if (tty_init(el) == -1) @@ -87,6 +93,7 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr) (void) hist_init(el); (void) prompt_init(el); (void) sig_init(el); + (void) read_init(el); return (el); } @@ -138,11 +145,12 @@ public int el_set(EditLine *el, int op, ...) { va_list va; - int rv; - va_start(va, op); + int rv = 0; if (el == NULL) return (-1); + va_start(va, op); + switch (op) { case EL_PROMPT: case EL_RPROMPT: @@ -162,7 +170,6 @@ el_set(EditLine *el, int op, ...) el->el_flags |= HANDLE_SIGNALS; else el->el_flags &= ~HANDLE_SIGNALS; - rv = 0; break; case EL_BIND: @@ -239,8 +246,20 @@ el_set(EditLine *el, int op, ...) rv = 0; break; + case EL_GETCFN: + { + el_rfunc_t rc = va_arg(va, el_rfunc_t); + rv = el_read_setfn(el, rc); + break; + } + + case EL_CLIENTDATA: + el->el_data = va_arg(va, void *); + break; + default: rv = -1; + break; } va_end(va); @@ -261,11 +280,11 @@ el_get(EditLine *el, int op, void *ret) switch (op) { case EL_PROMPT: case EL_RPROMPT: - rv = prompt_get(el, (el_pfunc_t *) & ret, op); + rv = prompt_get(el, (void *) &ret, op); break; case EL_EDITOR: - rv = map_get_editor(el, (const char **) &ret); + rv = map_get_editor(el, (void *) &ret); break; case EL_SIGNAL: @@ -349,6 +368,16 @@ el_get(EditLine *el, int op, void *ret) break; #endif /* XXX */ + case EL_GETCFN: + *((el_rfunc_t *)ret) = el_read_getfn(el); + rv = 0; + break; + + case EL_CLIENTDATA: + *((void **)ret) = el->el_data; + rv = 0; + break; + default: rv = -1; } @@ -367,15 +396,6 @@ el_line(EditLine *el) return (const LineInfo *) (void *) &el->el_line; } -static const char elpath[] = "/.editrc"; - -#if defined(MAXPATHLEN) -#define LIBEDIT_MAXPATHLEN MAXPATHLEN -#elif defined(PATH_MAX) -#define LIBEDIT_MAXPATHLEN PATH_MAX -#else -#define LIBEDIT_MAXPATHLEN 1024 -#endif /* el_source(): * Source a file @@ -385,10 +405,14 @@ el_source(EditLine *el, const char *fname) { FILE *fp; size_t len; - char *ptr, path[LIBEDIT_MAXPATHLEN]; + char *ptr; fp = NULL; if (fname == NULL) { +#ifdef HAVE_ISSETUGID + static const char elpath[] = "/.editrc"; + char path[MAXPATHLEN]; + if (issetugid()) return (-1); if ((ptr = getenv("HOME")) == NULL) @@ -398,6 +422,14 @@ el_source(EditLine *el, const char *fname) if (strlcat(path, elpath, sizeof(path)) >= sizeof(path)) return (-1); 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. + */ + return (-1); +#endif } if (fp == NULL) fp = fopen(fname, "r"); diff --git a/cmd-line-utils/libedit/el.h b/cmd-line-utils/libedit/el.h index 7cf17e8f069..9e1731c5857 100644 --- a/cmd-line-utils/libedit/el.h +++ b/cmd-line-utils/libedit/el.h @@ -1,4 +1,4 @@ -/* $NetBSD: el.h,v 1.8 2001/01/06 14:44:50 jdolecek Exp $ */ +/* $NetBSD: el.h,v 1.13 2002/11/15 14:32:33 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -72,7 +72,7 @@ typedef struct el_line_t { char *buffer; /* Input line */ char *cursor; /* Cursor position */ char *lastchar; /* Last character */ - const char *limit; /* Max position */ + const char *limit; /* Max position */ } el_line_t; /* @@ -84,6 +84,8 @@ typedef struct el_state_t { int argument; /* Numeric argument */ 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 */ } el_state_t; /* @@ -96,7 +98,7 @@ typedef struct el_state_t { #include "tty.h" #include "prompt.h" #include "key.h" -#include "libedit_term.h" +#include "term.h" #include "refresh.h" #include "chared.h" #include "common.h" @@ -106,6 +108,7 @@ typedef struct el_state_t { #include "parse.h" #include "sig.h" #include "help.h" +#include "read.h" struct editline { char *el_prog; /* the program name */ @@ -116,6 +119,7 @@ struct editline { coord_t el_cursor; /* Cursor location */ 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 */ @@ -129,13 +133,18 @@ struct editline { el_history_t el_history; /* History stuff */ el_search_t el_search; /* Search stuff */ el_signal_t el_signal; /* Signal handling stuff */ + el_read_t el_read; /* Character reading stuff */ }; protected int el_editmode(EditLine *, int, const char **); #ifdef DEBUG -#define EL_ABORT(a) (void) (fprintf(el->el_errfile, "%s, %d: ", \ - __FILE__, __LINE__), fprintf a, abort()) +#define EL_ABORT(a) do { \ + fprintf(el->el_errfile, "%s, %d: ", \ + __FILE__, __LINE__); \ + fprintf a; \ + abort(); \ + } while( /*CONSTCOND*/0); #else #define EL_ABORT(a) abort() #endif diff --git a/cmd-line-utils/libedit/emacs.c b/cmd-line-utils/libedit/emacs.c index bb5ffb2a9f6..d58d1620693 100644 --- a/cmd-line-utils/libedit/emacs.c +++ b/cmd-line-utils/libedit/emacs.c @@ -1,4 +1,4 @@ -/* $NetBSD: emacs.c,v 1.9 2001/01/10 07:45:41 jdolecek Exp $ */ +/* $NetBSD: emacs.c,v 1.12 2002/11/15 14:32:33 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,12 +36,18 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: emacs.c,v 1.12 2002/11/15 14:32:33 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * emacs.c: Emacs functions */ -#include "sys.h" #include "el.h" /* em_delete_or_list(): @@ -209,7 +215,7 @@ em_copy_region(EditLine *el, int c __attribute__((unused))) { char *kp, *cp; - if (el->el_chared.c_kill.mark) + if (!el->el_chared.c_kill.mark) return (CC_ERROR); if (el->el_chared.c_kill.mark > el->el_line.cursor) { @@ -265,7 +271,7 @@ em_next_word(EditLine *el, int c __attribute__((unused))) ce__isword); if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action & DELETE) { + if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); return (CC_REFRESH); } diff --git a/cmd-line-utils/libedit/hist.c b/cmd-line-utils/libedit/hist.c index 2b20c7d14dc..59c2f39dd34 100644 --- a/cmd-line-utils/libedit/hist.c +++ b/cmd-line-utils/libedit/hist.c @@ -1,4 +1,4 @@ -/* $NetBSD: hist.c,v 1.9 2001/05/17 01:02:17 christos Exp $ */ +/* $NetBSD: hist.c,v 1.12 2003/01/21 18:40:23 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,12 +36,18 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: hist.c,v 1.12 2003/01/21 18:40:23 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * hist.c: History access functions */ -#include "sys.h" #include <stdlib.h> #include "el.h" @@ -126,18 +132,16 @@ hist_get(EditLine *el) el->el_history.eventno = h; return (CC_ERROR); } - (void) strncpy(el->el_line.buffer, hp, + (void) strlcpy(el->el_line.buffer, hp, (size_t)(el->el_line.limit - el->el_line.buffer)); el->el_line.lastchar = el->el_line.buffer + strlen(el->el_line.buffer); - if (el->el_line.lastchar > el->el_line.buffer) { - if (el->el_line.lastchar[-1] == '\n') - el->el_line.lastchar--; - if (el->el_line.lastchar[-1] == ' ') - el->el_line.lastchar--; - if (el->el_line.lastchar < el->el_line.buffer) - el->el_line.lastchar = el->el_line.buffer; - } + if (el->el_line.lastchar > el->el_line.buffer + && el->el_line.lastchar[-1] == '\n') + el->el_line.lastchar--; + if (el->el_line.lastchar > el->el_line.buffer + && el->el_line.lastchar[-1] == ' ') + el->el_line.lastchar--; #ifdef KSHVI if (el->el_map.type == MAP_VI) el->el_line.cursor = el->el_line.buffer; @@ -149,22 +153,41 @@ hist_get(EditLine *el) } -/* hist_list() - * List history entries +/* hist_command() + * process a history command */ protected int /*ARGSUSED*/ -hist_list(EditLine *el, int argc __attribute__((unused)), - const char **argv __attribute__((unused))) +hist_command(EditLine *el, int argc, const char **argv) { const char *str; + int num; + HistEvent ev; if (el->el_history.ref == NULL) return (-1); - for (str = HIST_LAST(el); str != NULL; str = HIST_PREV(el)) - (void) fprintf(el->el_outfile, "%d %s", - el->el_history.ev.num, str); - return (0); + + if (argc == 0 || strcmp(argv[0], "list") == 1) { + /* 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); + } + + if (argc != 2) + return (-1); + + num = (int)strtol(argv[1], NULL, 0); + + if (strcmp(argv[0], "size") == 0) + return history(el->el_history.ref, &ev, H_SETSIZE, num); + + if (strcmp(argv[0], "unique") == 0) + return history(el->el_history.ref, &ev, H_SETUNIQUE, num); + + return -1; } /* hist_enlargebuf() diff --git a/cmd-line-utils/libedit/hist.h b/cmd-line-utils/libedit/hist.h index e650b6a55a9..b713281b382 100644 --- a/cmd-line-utils/libedit/hist.h +++ b/cmd-line-utils/libedit/hist.h @@ -1,4 +1,4 @@ -/* $NetBSD: hist.h,v 1.6 2001/01/10 07:45:41 jdolecek Exp $ */ +/* $NetBSD: hist.h,v 1.9 2003/01/21 18:40:23 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -66,7 +66,7 @@ typedef struct el_history_t { #define HIST_FIRST(el) HIST_FUN(el, H_FIRST, NULL) #define HIST_LAST(el) HIST_FUN(el, H_LAST, NULL) #define HIST_PREV(el) HIST_FUN(el, H_PREV, NULL) -#define HIST_EVENT(el, num) HIST_FUN(el, H_EVENT, num) +#define HIST_SET(el, num) HIST_FUN(el, H_SET, num) #define HIST_LOAD(el, fname) HIST_FUN(el, H_LOAD fname) #define HIST_SAVE(el, fname) HIST_FUN(el, H_SAVE fname) @@ -74,7 +74,7 @@ protected int hist_init(EditLine *); protected void hist_end(EditLine *); protected el_action_t hist_get(EditLine *); protected int hist_set(EditLine *, hist_fun_t, ptr_t); -protected int hist_list(EditLine *, int, const char **); +protected int hist_command(EditLine *, int, const char **); protected int hist_enlargebuf(EditLine *, size_t, size_t); #endif /* _h_el_hist */ diff --git a/cmd-line-utils/libedit/histedit.h b/cmd-line-utils/libedit/histedit.h index 0b8d175cef1..3137bd680a7 100644 --- a/cmd-line-utils/libedit/histedit.h +++ b/cmd-line-utils/libedit/histedit.h @@ -1,4 +1,4 @@ -/* $NetBSD: histedit.h,v 1.16 2000/09/04 22:06:30 lukem Exp $ */ +/* $NetBSD: histedit.h,v 1.21 2003/01/21 18:40:24 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -44,6 +44,9 @@ #ifndef _HISTEDIT_H_ #define _HISTEDIT_H_ +#define LIBEDIT_MAJOR 2 +#define LIBEDIT_MINOR 6 + #include <sys/types.h> #include <stdio.h> @@ -90,7 +93,7 @@ void el_end(EditLine *); */ const char *el_gets(EditLine *, int *); int el_getc(EditLine *, char *); -void el_push(EditLine *, const char *); +void el_push(EditLine *, char *); /* * Beep! @@ -126,6 +129,10 @@ int el_get(EditLine *, int, void *); #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_BUILTIN_GETCFN (NULL) /* * Source named file or $PWD/.editrc or $HOME/.editrc @@ -174,7 +181,7 @@ int history(History *, HistEvent *, int, ...); #define H_PREV 5 /* , void); */ #define H_NEXT 6 /* , void); */ #define H_CURR 8 /* , const int); */ -#define H_SET 7 /* , void); */ +#define H_SET 7 /* , int); */ #define H_ADD 9 /* , const char *); */ #define H_ENTER 10 /* , const char *); */ #define H_APPEND 11 /* , const char *); */ @@ -186,5 +193,7 @@ int history(History *, HistEvent *, int, ...); #define H_LOAD 17 /* , const char *); */ #define H_SAVE 18 /* , const char *); */ #define H_CLEAR 19 /* , void); */ +#define H_SETUNIQUE 20 /* , int); */ +#define H_GETUNIQUE 21 /* , void); */ #endif /* _HISTEDIT_H_ */ diff --git a/cmd-line-utils/libedit/history.c b/cmd-line-utils/libedit/history.c index bae50787b94..0294734b9a3 100644 --- a/cmd-line-utils/libedit/history.c +++ b/cmd-line-utils/libedit/history.c @@ -1,4 +1,4 @@ -/* $NetBSD: history.c,v 1.17 2001/03/20 00:08:31 christos Exp $ */ +/* $NetBSD: history.c,v 1.22 2003/01/21 18:40:24 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,18 +36,25 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: history.c,v 1.22 2003/01/21 18:40:24 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * hist.c: History access functions */ -#include "sys.h" - #include <string.h> #include <stdlib.h> #include <stdarg.h> #ifdef HAVE_VIS_H #include <vis.h> +#else +#include "np/vis.h" #endif #include <sys/stat.h> @@ -73,6 +80,7 @@ struct history { history_efun_t h_enter; /* Add an element */ history_efun_t h_add; /* Append to an element */ }; + #define HNEXT(h, ev) (*(h)->h_next)((h)->h_ref, ev) #define HFIRST(h, ev) (*(h)->h_first)((h)->h_ref, ev) #define HPREV(h, ev) (*(h)->h_prev)((h)->h_ref, ev) @@ -87,9 +95,17 @@ struct history { #define h_realloc(a, b) realloc((a), (b)) #define h_free(a) free(a) +typedef struct { + int num; + 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 *); @@ -108,15 +124,17 @@ typedef struct hentry_t { HistEvent ev; /* What we return */ struct hentry_t *next; /* Next entry */ struct hentry_t *prev; /* Previous entry */ -} hentry_t; +} hentry_t; typedef struct history_t { - hentry_t list; /* Fake list header element */ - hentry_t *cursor; /* Current element in the list */ - int max; /* Maximum number of events */ - int cur; /* Current number of events */ + hentry_t list; /* Fake list header element */ + hentry_t *cursor; /* Current element in the list */ + int max; /* Maximum number of events */ + int cur; /* Current number of events */ int eventid; /* For generation of unique event id */ -} history_t; + int flags; /* History flags */ +#define H_UNIQUE 1 /* Store only unique elements */ +} history_t; private int history_def_first(ptr_t, HistEvent *); private int history_def_last(ptr_t, HistEvent *); @@ -126,13 +144,19 @@ private int history_def_curr(ptr_t, HistEvent *); private int history_def_set(ptr_t, HistEvent *, const int n); private int history_def_enter(ptr_t, HistEvent *, const char *); private int history_def_add(ptr_t, HistEvent *, const char *); -private void history_def_init(ptr_t *, HistEvent *, int); +private int history_def_init(ptr_t *, HistEvent *, int); private void history_def_clear(ptr_t, HistEvent *); private int history_def_insert(history_t *, HistEvent *, const char *); private void history_def_delete(history_t *, HistEvent *, hentry_t *); -#define history_def_setsize(p, num)(void) (((history_t *) p)->max = (num)) -#define history_def_getsize(p) (((history_t *) p)->cur) +#define history_def_setsize(p, num)(void) (((history_t *)p)->max = (num)) +#define history_def_getsize(p) (((history_t *)p)->cur) +#define history_def_getunique(p) (((((history_t *)p)->flags) & H_UNIQUE) != 0) +#define history_def_setunique(p, uni) \ + if (uni) \ + (((history_t *)p)->flags) |= H_UNIQUE; \ + else \ + (((history_t *)p)->flags) &= ~H_UNIQUE #define he_strerror(code) he_errlist[code] #define he_seterrev(evp, code) {\ @@ -326,20 +350,20 @@ history_def_add(ptr_t p, HistEvent *ev, const char *str) history_t *h = (history_t *) p; size_t len; char *s; + HistEventPrivate *evp = (void *)&h->cursor->ev; if (h->cursor == &h->list) return (history_def_enter(p, ev, str)); - len = strlen(h->cursor->ev.str) + strlen(str) + 1; + len = strlen(evp->str) + strlen(str) + 1; s = (char *) h_malloc(len); - if (!s) { + if (s == NULL) { he_seterrev(ev, _HE_MALLOC_FAILED); return (-1); } (void) strlcpy(s, h->cursor->ev.str, len); (void) strlcat(s, str, len); - /* LINTED const cast */ - h_free((ptr_t) h->cursor->ev.str); - h->cursor->ev.str = s; + h_free((ptr_t)evp->str); + evp->str = s; *ev = h->cursor->ev; return (0); } @@ -350,16 +374,14 @@ history_def_add(ptr_t p, HistEvent *ev, const char *str) */ /* ARGSUSED */ private void -history_def_delete(history_t *h, - HistEvent *ev __attribute__((unused)), hentry_t *hp) +history_def_delete(history_t *h, HistEvent *ev __attribute__((unused)), hentry_t *hp) { - + HistEventPrivate *evp = (void *)&hp->ev; if (hp == &h->list) abort(); hp->prev->next = hp->next; hp->next->prev = hp->prev; - /* LINTED const cast */ - h_free((ptr_t) hp->ev.str); + h_free((ptr_t) evp->str); h_free(hp); h->cur--; } @@ -373,11 +395,11 @@ history_def_insert(history_t *h, HistEvent *ev, const char *str) { h->cursor = (hentry_t *) h_malloc(sizeof(hentry_t)); - if (h->cursor) - h->cursor->ev.str = strdup(str); - if (!h->cursor || !h->cursor->ev.str) { - he_seterrev(ev, _HE_MALLOC_FAILED); - return (-1); + if (h->cursor == NULL) + goto oomem; + if ((h->cursor->ev.str = strdup(str)) == NULL) { + h_free((ptr_t)h->cursor); + goto oomem; } h->cursor->ev.num = ++h->eventid; h->cursor->next = h->list.next; @@ -388,6 +410,9 @@ history_def_insert(history_t *h, HistEvent *ev, const char *str) *ev = h->cursor->ev; return (0); +oomem: + he_seterrev(ev, _HE_MALLOC_FAILED); + return (-1); } @@ -399,6 +424,10 @@ history_def_enter(ptr_t p, 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); + if (history_def_insert(h, ev, str) == -1) return (-1); /* error, keep error message */ @@ -406,10 +435,10 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str) * Always keep at least one entry. * This way we don't have to check for the empty list. */ - while (h->cur - 1 > h->max) + while (h->cur > h->max && h->cur > 0) history_def_delete(h, ev, h->list.prev); - return (0); + return (1); } @@ -417,10 +446,12 @@ history_def_enter(ptr_t p, HistEvent *ev, const char *str) * Default history initialization function */ /* ARGSUSED */ -private void +private int history_def_init(ptr_t *p, HistEvent *ev __attribute__((unused)), int n) { history_t *h = (history_t *) h_malloc(sizeof(history_t)); + if (h == NULL) + return -1; if (n <= 0) n = 0; @@ -431,7 +462,9 @@ history_def_init(ptr_t *p, HistEvent *ev __attribute__((unused)), int n) h->list.ev.str = NULL; h->list.ev.num = 0; h->cursor = &h->list; + h->flags = 0; *p = (ptr_t) h; + return 0; } @@ -460,10 +493,15 @@ history_def_clear(ptr_t p, HistEvent *ev) public History * history_init(void) { - History *h = (History *) h_malloc(sizeof(History)); HistEvent ev; + History *h = (History *) h_malloc(sizeof(History)); + if (h == NULL) + return NULL; - history_def_init(&h->h_ref, &ev, 0); + if (history_def_init(&h->h_ref, &ev, 0) == -1) { + h_free((ptr_t)h); + return NULL; + } h->h_ent = -1; h->h_next = history_def_next; h->h_first = history_def_first; @@ -519,18 +557,46 @@ history_setsize(History *h, HistEvent *ev, int num) private int history_getsize(History *h, HistEvent *ev) { - int retval = 0; - if (h->h_next != history_def_next) { he_seterrev(ev, _HE_NOT_ALLOWED); return (-1); } - retval = history_def_getsize(h->h_ref); - if (retval < -1) { + ev->num = history_def_getsize(h->h_ref); + if (ev->num < -1) { he_seterrev(ev, _HE_SIZE_NEGATIVE); return (-1); } - ev->num = retval; + return (0); +} + + +/* history_setunique(): + * Set if adjacent equal events should not be entered in history. + */ +private int +history_setunique(History *h, HistEvent *ev, int uni) +{ + + if (h->h_next != history_def_next) { + he_seterrev(ev, _HE_NOT_ALLOWED); + return (-1); + } + history_def_setunique(h->h_ref, uni); + return (0); +} + + +/* history_getunique(): + * Get if adjacent equal events should not be entered in history. + */ +private int +history_getunique(History *h, HistEvent *ev) +{ + if (h->h_next != history_def_next) { + he_seterrev(ev, _HE_NOT_ALLOWED); + return (-1); + } + ev->num = history_def_getunique(h->h_ref); return (0); } @@ -602,6 +668,8 @@ history_load(History *h, const char *fname) goto done; ptr = h_malloc(max_size = 1024); + if (ptr == NULL) + goto done; for (i = 0; (line = fgetln(fp, &sz)) != NULL; i++) { char c = line[sz]; @@ -611,15 +679,24 @@ history_load(History *h, const char *fname) line[sz] = '\0'; if (max_size < sz) { + char *nptr; max_size = (sz + 1023) & ~1023; - ptr = h_realloc(ptr, max_size); + nptr = h_realloc(ptr, max_size); + if (nptr == NULL) { + i = -1; + goto oomem; + } + ptr = nptr; } (void) strunvis(ptr, line); line[sz] = c; - HENTER(h, &ev, ptr); + if (HENTER(h, &ev, ptr) == -1) { + h_free((ptr_t)ptr); + return -1; + } } - h_free(ptr); - +oomem: + h_free((ptr_t)ptr); done: (void) fclose(fp); return (i); @@ -634,28 +711,40 @@ history_save(History *h, const char *fname) { FILE *fp; HistEvent ev; - int i = 0, retval; + int i = -1, retval; size_t len, max_size; char *ptr; if ((fp = fopen(fname, "w")) == NULL) return (-1); - (void) fchmod(fileno(fp), S_IRUSR|S_IWUSR); - (void) fputs(hist_cookie, fp); + 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); - for (retval = HLAST(h, &ev); + if (ptr == NULL) + goto done; + for (i = 0, retval = HLAST(h, &ev); retval != -1; retval = HPREV(h, &ev), i++) { len = strlen(ev.str) * 4 + 1; if (len >= max_size) { + char *nptr; max_size = (len + 1023) & ~1023; - ptr = h_realloc(ptr, max_size); + nptr = h_realloc(ptr, max_size); + if (nptr == NULL) { + i = -1; + goto oomem; + } + ptr = nptr; } (void) strvis(ptr, ev.str, VIS_WHITE); - (void) fprintf(fp, "%s\n", ev.str); + (void) fprintf(fp, "%s\n", ptr); } - h_free(ptr); +oomem: + h_free((ptr_t)ptr); +done: (void) fclose(fp); return (i); } @@ -754,6 +843,14 @@ history(History *h, HistEvent *ev, int fun, ...) retval = history_setsize(h, ev, va_arg(va, int)); break; + case H_GETUNIQUE: + retval = history_getunique(h, ev); + break; + + case H_SETUNIQUE: + retval = history_setunique(h, ev, va_arg(va, int)); + break; + case H_ADD: str = va_arg(va, const char *); retval = HADD(h, ev, str); diff --git a/cmd-line-utils/libedit/key.c b/cmd-line-utils/libedit/key.c index 629c6aeeb9c..e1e64e328ad 100644 --- a/cmd-line-utils/libedit/key.c +++ b/cmd-line-utils/libedit/key.c @@ -1,4 +1,4 @@ -/* $NetBSD: key.c,v 1.12 2001/05/17 01:02:17 christos Exp $ */ +/* $NetBSD: key.c,v 1.13 2002/03/18 16:00:55 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,7 +36,14 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: key.c,v 1.13 2002/03/18 16:00:55 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * key.c: This module contains the procedures for maintaining @@ -59,7 +66,6 @@ * 1) It is not possible to have one key that is a * substr of another. */ -#include "sys.h" #include <string.h> #include <stdlib.h> @@ -85,8 +91,8 @@ private int node__try(EditLine *, key_node_t *, const char *, private key_node_t *node__get(int); 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_lookup(EditLine *, const char *, key_node_t *, + int); private int node_enum(EditLine *, key_node_t *, int); private int key__decode_char(char *, int, int); @@ -640,7 +646,7 @@ key__decode_char(char *buf, int cnt, int ch) protected char * key__decode_str(const char *str, char *buf, const char *sep) { - char *b; + char *b; const char *p; b = buf; diff --git a/cmd-line-utils/libedit/key.h b/cmd-line-utils/libedit/key.h index e95731d9df5..80d8626b894 100644 --- a/cmd-line-utils/libedit/key.h +++ b/cmd-line-utils/libedit/key.h @@ -1,4 +1,4 @@ -/* $NetBSD: key.h,v 1.5 2001/01/23 15:55:30 jdolecek Exp $ */ +/* $NetBSD: key.h,v 1.6 2002/03/18 16:00:55 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -62,10 +62,6 @@ typedef struct el_key_t { #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); @@ -76,8 +72,8 @@ protected void key_add(EditLine *, const char *, key_value_t *, int); protected void key_clear(EditLine *, el_action_t *, const char *); protected int key_delete(EditLine *, const char *); protected void key_print(EditLine *, const char *); -protected void key_kprint(EditLine *, const char *, - key_value_t *, int); +protected void key_kprint(EditLine *, const char *, key_value_t *, + int); protected char *key__decode_str(const char *, char *, const char *); #endif /* _h_el_key */ diff --git a/cmd-line-utils/libedit/makelist.sh b/cmd-line-utils/libedit/makelist.sh index 13d37512591..fbce06fcc50 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.7 2001/01/09 19:22:31 jdolecek Exp $ +# $NetBSD: makelist,v 1.8 2003/03/10 21:21:10 christos Exp $ # # Copyright (c) 1992, 1993 # The Regents of the University of California. All rights reserved. @@ -87,7 +87,6 @@ case $FLAG in cat $FILES | $AWK ' BEGIN { printf("/* Automatically generated file, do not edit */\n"); - printf("#include \"compat.h\"\n"); printf("#include \"sys.h\"\n#include \"el.h\"\n"); printf("private const struct el_bindings_t el_func_help[] = {\n"); low = "abcdefghijklmnopqrstuvwxyz_"; @@ -170,7 +169,6 @@ case $FLAG in cat $FILES | $AWK '/el_action_t/ { print $3 }' | sort | $AWK ' BEGIN { printf("/* Automatically generated file, do not edit */\n"); - printf("#include \"compat.h\"\n"); printf("#include \"sys.h\"\n#include \"el.h\"\n"); printf("private const el_func_t el_func[] = {"); maxlen = 80; diff --git a/cmd-line-utils/libedit/map.c b/cmd-line-utils/libedit/map.c index 144ccf1ebe0..e044e875382 100644 --- a/cmd-line-utils/libedit/map.c +++ b/cmd-line-utils/libedit/map.c @@ -1,4 +1,4 @@ -/* $NetBSD: map.c,v 1.14 2001/01/09 17:22:09 jdolecek Exp $ */ +/* $NetBSD: map.c,v 1.18 2002/11/15 14:32:33 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,12 +36,18 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: map.c,v 1.18 2002/11/15 14:32:33 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * map.c: Editor function definitions */ -#include "sys.h" #include <stdlib.h> #include "el.h" @@ -373,7 +379,7 @@ private const el_action_t el_map_vi_insert[] = { /* 5 */ ED_MOVE_TO_END, /* ^E */ /* 6 */ ED_NEXT_CHAR, /* ^F */ /* 7 */ ED_UNASSIGNED, /* ^G */ - /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */ + /* 8 */ VI_DELETE_PREV_CHAR, /* ^H */ /* BackSpace key */ /* 9 */ ED_UNASSIGNED, /* ^I */ /* Tab Key */ /* 10 */ ED_NEWLINE, /* ^J */ /* 11 */ ED_KILL_LINE, /* ^K */ @@ -493,135 +499,135 @@ private const el_action_t el_map_vi_insert[] = { /* 124 */ ED_INSERT, /* | */ /* 125 */ ED_INSERT, /* } */ /* 126 */ ED_INSERT, /* ~ */ - /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */ - /* 128 */ ED_UNASSIGNED, /* M-^@ */ - /* 129 */ ED_UNASSIGNED, /* M-^A */ - /* 130 */ ED_UNASSIGNED, /* M-^B */ - /* 131 */ ED_UNASSIGNED, /* M-^C */ - /* 132 */ ED_UNASSIGNED, /* M-^D */ - /* 133 */ ED_UNASSIGNED, /* M-^E */ - /* 134 */ ED_UNASSIGNED, /* M-^F */ - /* 135 */ ED_UNASSIGNED, /* M-^G */ - /* 136 */ ED_UNASSIGNED, /* M-^H */ - /* 137 */ ED_UNASSIGNED, /* M-^I */ - /* 138 */ ED_UNASSIGNED, /* M-^J */ - /* 139 */ ED_UNASSIGNED, /* M-^K */ - /* 140 */ ED_UNASSIGNED, /* M-^L */ - /* 141 */ ED_UNASSIGNED, /* M-^M */ - /* 142 */ ED_UNASSIGNED, /* M-^N */ - /* 143 */ ED_UNASSIGNED, /* M-^O */ - /* 144 */ ED_UNASSIGNED, /* M-^P */ - /* 145 */ ED_UNASSIGNED, /* M-^Q */ - /* 146 */ ED_UNASSIGNED, /* M-^R */ - /* 147 */ ED_UNASSIGNED, /* M-^S */ - /* 148 */ ED_UNASSIGNED, /* M-^T */ - /* 149 */ ED_UNASSIGNED, /* M-^U */ - /* 150 */ ED_UNASSIGNED, /* M-^V */ - /* 151 */ ED_UNASSIGNED, /* M-^W */ - /* 152 */ ED_UNASSIGNED, /* M-^X */ - /* 153 */ ED_UNASSIGNED, /* M-^Y */ - /* 154 */ ED_UNASSIGNED, /* M-^Z */ - /* 155 */ ED_UNASSIGNED, /* M-^[ */ - /* 156 */ ED_UNASSIGNED, /* M-^\ */ - /* 157 */ ED_UNASSIGNED, /* M-^] */ - /* 158 */ ED_UNASSIGNED, /* M-^^ */ - /* 159 */ ED_UNASSIGNED, /* M-^_ */ - /* 160 */ ED_UNASSIGNED, /* M-SPACE */ - /* 161 */ ED_UNASSIGNED, /* M-! */ - /* 162 */ ED_UNASSIGNED, /* M-" */ - /* 163 */ ED_UNASSIGNED, /* M-# */ - /* 164 */ ED_UNASSIGNED, /* M-$ */ - /* 165 */ ED_UNASSIGNED, /* M-% */ - /* 166 */ ED_UNASSIGNED, /* M-& */ - /* 167 */ ED_UNASSIGNED, /* M-' */ - /* 168 */ ED_UNASSIGNED, /* M-( */ - /* 169 */ ED_UNASSIGNED, /* M-) */ - /* 170 */ ED_UNASSIGNED, /* M-* */ - /* 171 */ ED_UNASSIGNED, /* M-+ */ - /* 172 */ ED_UNASSIGNED, /* M-, */ - /* 173 */ ED_UNASSIGNED, /* M-- */ - /* 174 */ ED_UNASSIGNED, /* M-. */ - /* 175 */ ED_UNASSIGNED, /* M-/ */ - /* 176 */ ED_UNASSIGNED, /* M-0 */ - /* 177 */ ED_UNASSIGNED, /* M-1 */ - /* 178 */ ED_UNASSIGNED, /* M-2 */ - /* 179 */ ED_UNASSIGNED, /* M-3 */ - /* 180 */ ED_UNASSIGNED, /* M-4 */ - /* 181 */ ED_UNASSIGNED, /* M-5 */ - /* 182 */ ED_UNASSIGNED, /* M-6 */ - /* 183 */ ED_UNASSIGNED, /* M-7 */ - /* 184 */ ED_UNASSIGNED, /* M-8 */ - /* 185 */ ED_UNASSIGNED, /* M-9 */ - /* 186 */ ED_UNASSIGNED, /* M-: */ - /* 187 */ ED_UNASSIGNED, /* M-; */ - /* 188 */ ED_UNASSIGNED, /* M-< */ - /* 189 */ ED_UNASSIGNED, /* M-= */ - /* 190 */ ED_UNASSIGNED, /* M-> */ - /* 191 */ ED_UNASSIGNED, /* M-? */ - /* 192 */ ED_UNASSIGNED, /* M-@ */ - /* 193 */ ED_UNASSIGNED, /* M-A */ - /* 194 */ ED_UNASSIGNED, /* M-B */ - /* 195 */ ED_UNASSIGNED, /* M-C */ - /* 196 */ ED_UNASSIGNED, /* M-D */ - /* 197 */ ED_UNASSIGNED, /* M-E */ - /* 198 */ ED_UNASSIGNED, /* M-F */ - /* 199 */ ED_UNASSIGNED, /* M-G */ - /* 200 */ ED_UNASSIGNED, /* M-H */ - /* 201 */ ED_UNASSIGNED, /* M-I */ - /* 202 */ ED_UNASSIGNED, /* M-J */ - /* 203 */ ED_UNASSIGNED, /* M-K */ - /* 204 */ ED_UNASSIGNED, /* M-L */ - /* 205 */ ED_UNASSIGNED, /* M-M */ - /* 206 */ ED_UNASSIGNED, /* M-N */ - /* 207 */ ED_UNASSIGNED, /* M-O */ - /* 208 */ ED_UNASSIGNED, /* M-P */ - /* 209 */ ED_UNASSIGNED, /* M-Q */ - /* 210 */ ED_UNASSIGNED, /* M-R */ - /* 211 */ ED_UNASSIGNED, /* M-S */ - /* 212 */ ED_UNASSIGNED, /* M-T */ - /* 213 */ ED_UNASSIGNED, /* M-U */ - /* 214 */ ED_UNASSIGNED, /* M-V */ - /* 215 */ ED_UNASSIGNED, /* M-W */ - /* 216 */ ED_UNASSIGNED, /* M-X */ - /* 217 */ ED_UNASSIGNED, /* M-Y */ - /* 218 */ ED_UNASSIGNED, /* M-Z */ - /* 219 */ ED_UNASSIGNED, /* M-[ */ - /* 220 */ ED_UNASSIGNED, /* M-\ */ - /* 221 */ ED_UNASSIGNED, /* M-] */ - /* 222 */ ED_UNASSIGNED, /* M-^ */ - /* 223 */ ED_UNASSIGNED, /* M-_ */ - /* 224 */ ED_UNASSIGNED, /* M-` */ - /* 225 */ ED_UNASSIGNED, /* M-a */ - /* 226 */ ED_UNASSIGNED, /* M-b */ - /* 227 */ ED_UNASSIGNED, /* M-c */ - /* 228 */ ED_UNASSIGNED, /* M-d */ - /* 229 */ ED_UNASSIGNED, /* M-e */ - /* 230 */ ED_UNASSIGNED, /* M-f */ - /* 231 */ ED_UNASSIGNED, /* M-g */ - /* 232 */ ED_UNASSIGNED, /* M-h */ - /* 233 */ ED_UNASSIGNED, /* M-i */ - /* 234 */ ED_UNASSIGNED, /* M-j */ - /* 235 */ ED_UNASSIGNED, /* M-k */ - /* 236 */ ED_UNASSIGNED, /* M-l */ - /* 237 */ ED_UNASSIGNED, /* M-m */ - /* 238 */ ED_UNASSIGNED, /* M-n */ - /* 239 */ ED_UNASSIGNED, /* M-o */ - /* 240 */ ED_UNASSIGNED, /* M-p */ - /* 241 */ ED_UNASSIGNED, /* M-q */ - /* 242 */ ED_UNASSIGNED, /* M-r */ - /* 243 */ ED_UNASSIGNED, /* M-s */ - /* 244 */ ED_UNASSIGNED, /* M-t */ - /* 245 */ ED_UNASSIGNED, /* M-u */ - /* 246 */ ED_UNASSIGNED, /* M-v */ - /* 247 */ ED_UNASSIGNED, /* M-w */ - /* 248 */ ED_UNASSIGNED, /* M-x */ - /* 249 */ ED_UNASSIGNED, /* M-y */ - /* 250 */ ED_UNASSIGNED, /* M-z */ - /* 251 */ ED_UNASSIGNED, /* M-{ */ - /* 252 */ ED_UNASSIGNED, /* M-| */ - /* 253 */ ED_UNASSIGNED, /* M-} */ - /* 254 */ ED_UNASSIGNED, /* M-~ */ - /* 255 */ ED_UNASSIGNED /* M-^? */ + /* 127 */ VI_DELETE_PREV_CHAR, /* ^? */ + /* 128 */ ED_INSERT, /* M-^@ */ + /* 129 */ ED_INSERT, /* M-^A */ + /* 130 */ ED_INSERT, /* M-^B */ + /* 131 */ ED_INSERT, /* M-^C */ + /* 132 */ ED_INSERT, /* M-^D */ + /* 133 */ ED_INSERT, /* M-^E */ + /* 134 */ ED_INSERT, /* M-^F */ + /* 135 */ ED_INSERT, /* M-^G */ + /* 136 */ ED_INSERT, /* M-^H */ + /* 137 */ ED_INSERT, /* M-^I */ + /* 138 */ ED_INSERT, /* M-^J */ + /* 139 */ ED_INSERT, /* M-^K */ + /* 140 */ ED_INSERT, /* M-^L */ + /* 141 */ ED_INSERT, /* M-^M */ + /* 142 */ ED_INSERT, /* M-^N */ + /* 143 */ ED_INSERT, /* M-^O */ + /* 144 */ ED_INSERT, /* M-^P */ + /* 145 */ ED_INSERT, /* M-^Q */ + /* 146 */ ED_INSERT, /* M-^R */ + /* 147 */ ED_INSERT, /* M-^S */ + /* 148 */ ED_INSERT, /* M-^T */ + /* 149 */ ED_INSERT, /* M-^U */ + /* 150 */ ED_INSERT, /* M-^V */ + /* 151 */ ED_INSERT, /* M-^W */ + /* 152 */ ED_INSERT, /* M-^X */ + /* 153 */ ED_INSERT, /* M-^Y */ + /* 154 */ ED_INSERT, /* M-^Z */ + /* 155 */ ED_INSERT, /* M-^[ */ + /* 156 */ ED_INSERT, /* M-^\ */ + /* 157 */ ED_INSERT, /* M-^] */ + /* 158 */ ED_INSERT, /* M-^^ */ + /* 159 */ ED_INSERT, /* M-^_ */ + /* 160 */ ED_INSERT, /* M-SPACE */ + /* 161 */ ED_INSERT, /* M-! */ + /* 162 */ ED_INSERT, /* M-" */ + /* 163 */ ED_INSERT, /* M-# */ + /* 164 */ ED_INSERT, /* M-$ */ + /* 165 */ ED_INSERT, /* M-% */ + /* 166 */ ED_INSERT, /* M-& */ + /* 167 */ ED_INSERT, /* M-' */ + /* 168 */ ED_INSERT, /* M-( */ + /* 169 */ ED_INSERT, /* M-) */ + /* 170 */ ED_INSERT, /* M-* */ + /* 171 */ ED_INSERT, /* M-+ */ + /* 172 */ ED_INSERT, /* M-, */ + /* 173 */ ED_INSERT, /* M-- */ + /* 174 */ ED_INSERT, /* M-. */ + /* 175 */ ED_INSERT, /* M-/ */ + /* 176 */ ED_INSERT, /* M-0 */ + /* 177 */ ED_INSERT, /* M-1 */ + /* 178 */ ED_INSERT, /* M-2 */ + /* 179 */ ED_INSERT, /* M-3 */ + /* 180 */ ED_INSERT, /* M-4 */ + /* 181 */ ED_INSERT, /* M-5 */ + /* 182 */ ED_INSERT, /* M-6 */ + /* 183 */ ED_INSERT, /* M-7 */ + /* 184 */ ED_INSERT, /* M-8 */ + /* 185 */ ED_INSERT, /* M-9 */ + /* 186 */ ED_INSERT, /* M-: */ + /* 187 */ ED_INSERT, /* M-; */ + /* 188 */ ED_INSERT, /* M-< */ + /* 189 */ ED_INSERT, /* M-= */ + /* 190 */ ED_INSERT, /* M-> */ + /* 191 */ ED_INSERT, /* M-? */ + /* 192 */ ED_INSERT, /* M-@ */ + /* 193 */ ED_INSERT, /* M-A */ + /* 194 */ ED_INSERT, /* M-B */ + /* 195 */ ED_INSERT, /* M-C */ + /* 196 */ ED_INSERT, /* M-D */ + /* 197 */ ED_INSERT, /* M-E */ + /* 198 */ ED_INSERT, /* M-F */ + /* 199 */ ED_INSERT, /* M-G */ + /* 200 */ ED_INSERT, /* M-H */ + /* 201 */ ED_INSERT, /* M-I */ + /* 202 */ ED_INSERT, /* M-J */ + /* 203 */ ED_INSERT, /* M-K */ + /* 204 */ ED_INSERT, /* M-L */ + /* 205 */ ED_INSERT, /* M-M */ + /* 206 */ ED_INSERT, /* M-N */ + /* 207 */ ED_INSERT, /* M-O */ + /* 208 */ ED_INSERT, /* M-P */ + /* 209 */ ED_INSERT, /* M-Q */ + /* 210 */ ED_INSERT, /* M-R */ + /* 211 */ ED_INSERT, /* M-S */ + /* 212 */ ED_INSERT, /* M-T */ + /* 213 */ ED_INSERT, /* M-U */ + /* 214 */ ED_INSERT, /* M-V */ + /* 215 */ ED_INSERT, /* M-W */ + /* 216 */ ED_INSERT, /* M-X */ + /* 217 */ ED_INSERT, /* M-Y */ + /* 218 */ ED_INSERT, /* M-Z */ + /* 219 */ ED_INSERT, /* M-[ */ + /* 220 */ ED_INSERT, /* M-\ */ + /* 221 */ ED_INSERT, /* M-] */ + /* 222 */ ED_INSERT, /* M-^ */ + /* 223 */ ED_INSERT, /* M-_ */ + /* 224 */ ED_INSERT, /* M-` */ + /* 225 */ ED_INSERT, /* M-a */ + /* 226 */ ED_INSERT, /* M-b */ + /* 227 */ ED_INSERT, /* M-c */ + /* 228 */ ED_INSERT, /* M-d */ + /* 229 */ ED_INSERT, /* M-e */ + /* 230 */ ED_INSERT, /* M-f */ + /* 231 */ ED_INSERT, /* M-g */ + /* 232 */ ED_INSERT, /* M-h */ + /* 233 */ ED_INSERT, /* M-i */ + /* 234 */ ED_INSERT, /* M-j */ + /* 235 */ ED_INSERT, /* M-k */ + /* 236 */ ED_INSERT, /* M-l */ + /* 237 */ ED_INSERT, /* M-m */ + /* 238 */ ED_INSERT, /* M-n */ + /* 239 */ ED_INSERT, /* M-o */ + /* 240 */ ED_INSERT, /* M-p */ + /* 241 */ ED_INSERT, /* M-q */ + /* 242 */ ED_INSERT, /* M-r */ + /* 243 */ ED_INSERT, /* M-s */ + /* 244 */ ED_INSERT, /* M-t */ + /* 245 */ ED_INSERT, /* M-u */ + /* 246 */ ED_INSERT, /* M-v */ + /* 247 */ ED_INSERT, /* M-w */ + /* 248 */ ED_INSERT, /* M-x */ + /* 249 */ ED_INSERT, /* M-y */ + /* 250 */ ED_INSERT, /* M-z */ + /* 251 */ ED_INSERT, /* M-{ */ + /* 252 */ ED_INSERT, /* M-| */ + /* 253 */ ED_INSERT, /* M-} */ + /* 254 */ ED_INSERT, /* M-~ */ + /* 255 */ ED_INSERT /* M-^? */ }; private const el_action_t el_map_vi_command[] = { @@ -633,7 +639,7 @@ private const el_action_t el_map_vi_command[] = { /* 5 */ ED_MOVE_TO_END, /* ^E */ /* 6 */ ED_UNASSIGNED, /* ^F */ /* 7 */ ED_UNASSIGNED, /* ^G */ - /* 8 */ ED_PREV_CHAR, /* ^H */ + /* 8 */ ED_DELETE_PREV_CHAR, /* ^H */ /* 9 */ ED_UNASSIGNED, /* ^I */ /* 10 */ ED_NEWLINE, /* ^J */ /* 11 */ ED_KILL_LINE, /* ^K */ @@ -660,9 +666,9 @@ private const el_action_t el_map_vi_command[] = { /* 32 */ ED_NEXT_CHAR, /* SPACE */ /* 33 */ ED_UNASSIGNED, /* ! */ /* 34 */ ED_UNASSIGNED, /* " */ - /* 35 */ ED_UNASSIGNED, /* # */ + /* 35 */ VI_COMMENT_OUT, /* # */ /* 36 */ ED_MOVE_TO_END, /* $ */ - /* 37 */ ED_UNASSIGNED, /* % */ + /* 37 */ VI_MATCH, /* % */ /* 38 */ ED_UNASSIGNED, /* & */ /* 39 */ ED_UNASSIGNED, /* ' */ /* 40 */ ED_UNASSIGNED, /* ( */ @@ -671,7 +677,7 @@ private const el_action_t el_map_vi_command[] = { /* 43 */ ED_NEXT_HISTORY, /* + */ /* 44 */ VI_REPEAT_PREV_CHAR, /* , */ /* 45 */ ED_PREV_HISTORY, /* - */ - /* 46 */ ED_UNASSIGNED, /* . */ + /* 46 */ VI_REDO, /* . */ /* 47 */ VI_SEARCH_PREV, /* / */ /* 48 */ VI_ZERO, /* 0 */ /* 49 */ ED_ARGUMENT_DIGIT, /* 1 */ @@ -689,14 +695,14 @@ private const el_action_t el_map_vi_command[] = { /* 61 */ ED_UNASSIGNED, /* = */ /* 62 */ ED_UNASSIGNED, /* > */ /* 63 */ VI_SEARCH_NEXT, /* ? */ - /* 64 */ ED_UNASSIGNED, /* @ */ + /* 64 */ VI_ALIAS, /* @ */ /* 65 */ VI_ADD_AT_EOL, /* A */ - /* 66 */ VI_PREV_SPACE_WORD, /* B */ + /* 66 */ VI_PREV_BIG_WORD, /* B */ /* 67 */ VI_CHANGE_TO_EOL, /* C */ /* 68 */ ED_KILL_LINE, /* D */ - /* 69 */ VI_TO_END_WORD, /* E */ + /* 69 */ VI_END_BIG_WORD, /* E */ /* 70 */ VI_PREV_CHAR, /* F */ - /* 71 */ ED_UNASSIGNED, /* G */ + /* 71 */ VI_TO_HISTORY_LINE, /* G */ /* 72 */ ED_UNASSIGNED, /* H */ /* 73 */ VI_INSERT_AT_BOL, /* I */ /* 74 */ ED_SEARCH_NEXT_HISTORY, /* J */ @@ -710,17 +716,17 @@ private const el_action_t el_map_vi_command[] = { /* 82 */ VI_REPLACE_MODE, /* R */ /* 83 */ VI_SUBSTITUTE_LINE, /* S */ /* 84 */ VI_TO_PREV_CHAR, /* T */ - /* 85 */ ED_UNASSIGNED, /* U */ + /* 85 */ VI_UNDO_LINE, /* U */ /* 86 */ ED_UNASSIGNED, /* V */ - /* 87 */ VI_NEXT_SPACE_WORD, /* W */ + /* 87 */ VI_NEXT_BIG_WORD, /* W */ /* 88 */ ED_DELETE_PREV_CHAR, /* X */ - /* 89 */ ED_UNASSIGNED, /* Y */ + /* 89 */ VI_YANK_END, /* Y */ /* 90 */ ED_UNASSIGNED, /* Z */ /* 91 */ ED_SEQUENCE_LEAD_IN, /* [ */ /* 92 */ ED_UNASSIGNED, /* \ */ /* 93 */ ED_UNASSIGNED, /* ] */ /* 94 */ ED_MOVE_TO_BEG, /* ^ */ - /* 95 */ ED_UNASSIGNED, /* _ */ + /* 95 */ VI_HISTORY_WORD, /* _ */ /* 96 */ ED_UNASSIGNED, /* ` */ /* 97 */ VI_ADD, /* a */ /* 98 */ VI_PREV_WORD, /* b */ @@ -743,13 +749,13 @@ private const el_action_t el_map_vi_command[] = { /* 115 */ VI_SUBSTITUTE_CHAR, /* s */ /* 116 */ VI_TO_NEXT_CHAR, /* t */ /* 117 */ VI_UNDO, /* u */ - /* 118 */ ED_UNASSIGNED, /* v */ + /* 118 */ VI_HISTEDIT, /* v */ /* 119 */ VI_NEXT_WORD, /* w */ /* 120 */ ED_DELETE_NEXT_CHAR, /* x */ - /* 121 */ ED_UNASSIGNED, /* y */ + /* 121 */ VI_YANK, /* y */ /* 122 */ ED_UNASSIGNED, /* z */ /* 123 */ ED_UNASSIGNED, /* { */ - /* 124 */ ED_UNASSIGNED, /* | */ + /* 124 */ VI_TO_COLUMN, /* | */ /* 125 */ ED_UNASSIGNED, /* } */ /* 126 */ VI_CHANGE_CASE, /* ~ */ /* 127 */ ED_DELETE_PREV_CHAR, /* ^? */ diff --git a/cmd-line-utils/libedit/map.h b/cmd-line-utils/libedit/map.h index 6033eaf1a87..3c9948ccf88 100644 --- a/cmd-line-utils/libedit/map.h +++ b/cmd-line-utils/libedit/map.h @@ -1,4 +1,4 @@ -/* $NetBSD: map.h,v 1.6 2001/01/09 17:22:09 jdolecek Exp $ */ +/* $NetBSD: map.h,v 1.7 2002/03/18 16:00:56 christos Exp $ */ /*- * Copyright (c) 1992, 1993 diff --git a/cmd-line-utils/libedit/np/fgetln.c b/cmd-line-utils/libedit/np/fgetln.c new file mode 100644 index 00000000000..93da9914dc8 --- /dev/null +++ b/cmd-line-utils/libedit/np/fgetln.c @@ -0,0 +1,88 @@ +/* $NetBSD: fgetln.c,v 1.1.1.1 1999/04/12 07:43:21 crooksa Exp $ */ + +/*- + * Copyright (c) 1998 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * 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" +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> +#include <string.h> + +char * +fgetln(fp, len) + FILE *fp; + size_t *len; +{ + static char *buf = NULL; + static size_t bufsiz = 0; + char *ptr; + + + if (buf == NULL) { + bufsiz = BUFSIZ; + if ((buf = malloc(bufsiz)) == NULL) + return NULL; + } + + if (fgets(buf, bufsiz, fp) == NULL) + return NULL; + *len = 0; + + while ((ptr = strchr(&buf[*len], '\n')) == NULL) { + size_t nbufsiz = bufsiz + BUFSIZ; + char *nbuf = realloc(buf, nbufsiz); + + if (nbuf == NULL) { + int oerrno = errno; + free(buf); + errno = oerrno; + buf = NULL; + return NULL; + } else + buf = nbuf; + + *len = bufsiz; + if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) + return buf; + + bufsiz = nbufsiz; + } + + *len = (ptr - buf) + 1; + return buf; +} diff --git a/cmd-line-utils/libedit/np/strlcat.c b/cmd-line-utils/libedit/np/strlcat.c new file mode 100644 index 00000000000..6c9f1e92d79 --- /dev/null +++ b/cmd-line-utils/libedit/np/strlcat.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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(LIBC_SCCS) && !defined(lint) +static char *rcsid = "$OpenBSD: strlcat.c,v 1.2 1999/06/17 16:28:58 millert Exp $"; +#endif /* LIBC_SCCS and not lint */ +#ifndef lint +static const char rcsid[] = + "$FreeBSD: src/lib/libc/string/strlcat.c,v 1.2.4.2 2001/07/09 23:30:06 obrien Exp $"; +#endif + +#include <sys/types.h> +#include <string.h> + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(initial dst) + strlen(src); if retval >= siz, + * truncation occurred. + */ +size_t strlcat(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} diff --git a/cmd-line-utils/libedit/np/strlcpy.c b/cmd-line-utils/libedit/np/strlcpy.c new file mode 100644 index 00000000000..1f154bcf2ea --- /dev/null +++ b/cmd-line-utils/libedit/np/strlcpy.c @@ -0,0 +1,75 @@ +/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */ + +/* + * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> + * 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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(LIBC_SCCS) && !defined(lint) +#if 0 +static char *rcsid = "$OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $"; +#endif +#endif /* LIBC_SCCS and not lint */ +#ifndef lint +static const char rcsid[] = + "$FreeBSD: src/lib/libc/string/strlcpy.c,v 1.2.4.1 2001/07/09 23:30:06 obrien Exp $"; +#endif + +#include <sys/types.h> +#include <string.h> + +/* + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t strlcpy(dst, src, siz) + char *dst; + const char *src; + size_t siz; +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} diff --git a/cmd-line-utils/libedit/np/unvis.c b/cmd-line-utils/libedit/np/unvis.c new file mode 100644 index 00000000000..01056c776e9 --- /dev/null +++ b/cmd-line-utils/libedit/np/unvis.c @@ -0,0 +1,321 @@ +/* $NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $ */ + +/*- + * Copyright (c) 1989, 1993 + * The Regents of the University of California. 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 University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +#if 0 +static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $"); +#endif +#endif /* LIBC_SCCS and not lint */ + +#define __LIBC12_SOURCE__ + +#include <sys/types.h> + +#include <assert.h> +#include <ctype.h> +#include <stdio.h> +#include "np/vis.h" + +#ifdef __weak_alias +__weak_alias(strunvis,_strunvis) +__weak_alias(unvis,_unvis) +#endif + +#ifdef __warn_references +__warn_references(unvis, + "warning: reference to compatibility unvis(); include <vis.h> for correct reference") +#endif + +#if !HAVE_VIS_H +/* + * decode driven by state machine + */ +#define S_GROUND 0 /* haven't seen escape char */ +#define S_START 1 /* start decoding special sequence */ +#define S_META 2 /* metachar started (M) */ +#define S_META1 3 /* metachar more, regular char (-) */ +#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 isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') +#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) + +int +unvis(cp, c, astate, flag) + char *cp; + int c; + int *astate, flag; +{ + return __unvis13(cp, (int)c, astate, flag); +} + +/* + * unvis - decode characters previously encoded by vis + */ +int +__unvis13(cp, c, astate, flag) + char *cp; + int c; + int *astate, flag; +{ + + _DIAGASSERT(cp != NULL); + _DIAGASSERT(astate != NULL); + + if (flag & UNVIS_END) { + if (*astate == S_OCTAL2 || *astate == S_OCTAL3 + || *astate == S_HEX2) { + *astate = S_GROUND; + return (UNVIS_VALID); + } + return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); + } + + switch (*astate) { + + case S_GROUND: + *cp = 0; + if (c == '\\') { + *astate = S_START; + return (0); + } + if ((flag & VIS_HTTPSTYLE) && c == '%') { + *astate = S_HEX1; + return (0); + } + *cp = c; + return (UNVIS_VALID); + + case S_START: + switch(c) { + case '\\': + *cp = c; + *astate = 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); + case 'M': + *cp = (char)0200; + *astate = S_META; + return (0); + case '^': + *astate = S_CTRL; + return (0); + case 'n': + *cp = '\n'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'r': + *cp = '\r'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'b': + *cp = '\b'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'a': + *cp = '\007'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'v': + *cp = '\v'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 't': + *cp = '\t'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'f': + *cp = '\f'; + *astate = S_GROUND; + return (UNVIS_VALID); + case 's': + *cp = ' '; + *astate = S_GROUND; + return (UNVIS_VALID); + case 'E': + *cp = '\033'; + *astate = S_GROUND; + return (UNVIS_VALID); + case '\n': + /* + * hidden newline + */ + *astate = S_GROUND; + return (UNVIS_NOCHAR); + case '$': + /* + * hidden marker + */ + *astate = S_GROUND; + return (UNVIS_NOCHAR); + } + *astate = S_GROUND; + return (UNVIS_SYNBAD); + + case S_META: + if (c == '-') + *astate = S_META1; + else if (c == '^') + *astate = S_CTRL; + else { + *astate = S_GROUND; + return (UNVIS_SYNBAD); + } + return (0); + + case S_META1: + *astate = S_GROUND; + *cp |= c; + return (UNVIS_VALID); + + case S_CTRL: + if (c == '?') + *cp |= 0177; + else + *cp |= c & 037; + *astate = S_GROUND; + return (UNVIS_VALID); + + case S_OCTAL2: /* second possible octal digit */ + if (isoctal(c)) { + /* + * yes - and maybe a third + */ + *cp = (*cp << 3) + (c - '0'); + *astate = S_OCTAL3; + return (0); + } + /* + * no - done with current sequence, push back passed char + */ + *astate = S_GROUND; + return (UNVIS_VALIDPUSH); + + case S_OCTAL3: /* third possible octal digit */ + *astate = S_GROUND; + if (isoctal(c)) { + *cp = (*cp << 3) + (c - '0'); + return (UNVIS_VALID); + } + /* + * we were done, push back passed char + */ + return (UNVIS_VALIDPUSH); + case S_HEX1: + if (isxdigit(c)) { + *cp = xtod(c); + *astate = S_HEX2; + return (0); + } + /* + * no - done with current sequence, push back passed char + */ + *astate = S_GROUND; + return (UNVIS_VALIDPUSH); + case S_HEX2: + *astate = S_GROUND; + if (isxdigit(c)) { + *cp = xtod(c) | (*cp << 4); + return (UNVIS_VALID); + } + return (UNVIS_VALIDPUSH); + default: + /* + * decoder in unknown state - (probably uninitialized) + */ + *astate = S_GROUND; + return (UNVIS_SYNBAD); + } +} + +/* + * strunvis - 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; +{ + char c; + char *start = dst; + int state = 0; + + _DIAGASSERT(src != NULL); + _DIAGASSERT(dst != NULL); + + while ((c = *src++) != '\0') { + again: + switch (__unvis13(dst, c, &state, flag)) { + case UNVIS_VALID: + dst++; + break; + case UNVIS_VALIDPUSH: + dst++; + goto again; + case 0: + case UNVIS_NOCHAR: + break; + default: + return (-1); + } + } + if (__unvis13(dst, c, &state, UNVIS_END) == UNVIS_VALID) + dst++; + *dst = '\0'; + return (dst - start); +} + +int +strunvis(dst, src) + char *dst; + const char *src; +{ + return strunvisx(dst, src, 0); +} +#endif diff --git a/cmd-line-utils/libedit/np/vis.c b/cmd-line-utils/libedit/np/vis.c new file mode 100644 index 00000000000..9abc2e6e478 --- /dev/null +++ b/cmd-line-utils/libedit/np/vis.c @@ -0,0 +1,347 @@ +/* $NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $ */ + +/*- + * Copyright (c) 1999 The NetBSD Foundation, Inc. + * Copyright (c) 1989, 1993 + * The Regents of the University of California. 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 University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +__RCSID("$NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $"); +#endif /* LIBC_SCCS and not lint */ + +#include "config.h" + +#include <sys/types.h> +#include <assert.h> +#ifdef HAVE_ALLOCA_H +#include <alloca.h> +#endif +#include <stdlib.h> + +#include "np/vis.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_H +#include <ctype.h> +#include <limits.h> +#include <stdio.h> +#include <string.h> + +#undef BELL +#if defined(__STDC__) +#define BELL '\a' +#else +#define BELL '\007' +#endif + +#define isoctal(c) (((unsigned char)(c)) >= '0' && ((unsigned char)(c)) <= '7') +#define iswhite(c) (c == ' ' || c == '\t' || c == '\n') +#define issafe(c) (c == '\b' || c == BELL || c == '\r') +#define xtoa(c) "0123456789abcdef"[c] + +#define MAXEXTRAS 5 + + +#define MAKEEXTRALIST(flag, extra, orig) \ +do { \ + const char *o = orig; \ + char *e; \ + while (*o++) \ + continue; \ + extra = alloca((size_t)((o - orig) + MAXEXTRAS)); \ + for (o = orig, e = extra; (*e++ = *o++) != '\0';) \ + continue; \ + e--; \ + if (flag & VIS_SP) *e++ = ' '; \ + if (flag & VIS_TAB) *e++ = '\t'; \ + if (flag & VIS_NL) *e++ = '\n'; \ + if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \ + *e = '\0'; \ +} while (/*CONSTCOND*/0) + + +/* + * This is HVIS, the macro of vis used to HTTP style (RFC 1808) + */ +#define HVIS(dst, c, flag, nextc, extra) \ +do \ + if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \ + *dst++ = '%'; \ + *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); \ + *dst++ = xtoa((unsigned int)c & 0xf); \ + } else { \ + SVIS(dst, c, flag, nextc, extra); \ + } \ +while (/*CONSTCOND*/0) + +/* + * This is SVIS, the central macro of vis. + * dst: Pointer to the destination buffer + * c: Character to encode + * flag: Flag word + * nextc: The character following 'c' + * extra: Pointer to the list of extra characters to be + * backslash-protected. + */ +#define SVIS(dst, c, flag, nextc, extra) \ +do { \ + int isextra, isc; \ + isextra = strchr(extra, c) != NULL; \ + if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \ + ((flag & VIS_SAFE) && issafe(c)))) { \ + *dst++ = c; \ + break; \ + } \ + isc = 0; \ + if (flag & VIS_CSTYLE) { \ + switch (c) { \ + case '\n': \ + isc = 1; *dst++ = '\\'; *dst++ = 'n'; \ + break; \ + case '\r': \ + isc = 1; *dst++ = '\\'; *dst++ = 'r'; \ + break; \ + case '\b': \ + isc = 1; *dst++ = '\\'; *dst++ = 'b'; \ + break; \ + case BELL: \ + isc = 1; *dst++ = '\\'; *dst++ = 'a'; \ + break; \ + case '\v': \ + isc = 1; *dst++ = '\\'; *dst++ = 'v'; \ + break; \ + case '\t': \ + isc = 1; *dst++ = '\\'; *dst++ = 't'; \ + break; \ + case '\f': \ + isc = 1; *dst++ = '\\'; *dst++ = 'f'; \ + break; \ + case ' ': \ + isc = 1; *dst++ = '\\'; *dst++ = 's'; \ + break; \ + case '\0': \ + isc = 1; *dst++ = '\\'; *dst++ = '0'; \ + if (isoctal(nextc)) { \ + *dst++ = '0'; \ + *dst++ = '0'; \ + } \ + } \ + } \ + if (isc) break; \ + if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \ + *dst++ = '\\'; \ + *dst++ = (unsigned char)(((unsigned int)(unsigned char)c >> 6) & 03) + '0'; \ + *dst++ = (unsigned char)(((unsigned int)(unsigned char)c >> 3) & 07) + '0'; \ + *dst++ = (c & 07) + '0'; \ + } else { \ + if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \ + if (c & 0200) { \ + c &= 0177; *dst++ = 'M'; \ + } \ + if (iscntrl(c)) { \ + *dst++ = '^'; \ + if (c == 0177) \ + *dst++ = '?'; \ + else \ + *dst++ = c + '@'; \ + } else { \ + *dst++ = '-'; *dst++ = c; \ + } \ + } \ +} while (/*CONSTCOND*/0) + + +/* + * svis - visually encode characters, also encoding the characters + * pointed to by `extra' + */ +char * +svis(dst, c, flag, nextc, extra) + char *dst; + int c, flag, nextc; + const char *extra; +{ + char *nextra; + _DIAGASSERT(dst != NULL); + _DIAGASSERT(extra != NULL); + MAKEEXTRALIST(flag, nextra, extra); + if (flag & VIS_HTTPSTYLE) + HVIS(dst, c, flag, nextc, nextra); + else + SVIS(dst, c, flag, nextc, nextra); + *dst = '\0'; + return(dst); +} + + +/* + * strsvis, strsvisx - visually encode characters from src into dst + * + * Extra is a pointer to a \0-terminated list of characters to + * be encoded, too. These functions are useful e. g. to + * encode strings in such a way so that they are not interpreted + * by a shell. + * + * Dst must be 4 times the size of src to account for possible + * expansion. The length of dst, not including the trailing NULL, + * is returned. + * + * Strsvisx encodes exactly len bytes from src into dst. + * This is useful for encoding a block of data. + */ +int +strsvis(dst, src, flag, extra) + char *dst; + const char *src; + int flag; + const char *extra; +{ + char c; + char *start; + char *nextra; + + _DIAGASSERT(dst != NULL); + _DIAGASSERT(src != NULL); + _DIAGASSERT(extra != NULL); + MAKEEXTRALIST(flag, nextra, extra); + if (flag & VIS_HTTPSTYLE) { + for (start = dst; (c = *src++) != '\0'; /* empty */) + HVIS(dst, c, flag, *src, nextra); + } else { + for (start = dst; (c = *src++) != '\0'; /* empty */) + SVIS(dst, c, flag, *src, nextra); + } + *dst = '\0'; + return (dst - start); +} + + +int +strsvisx(dst, src, len, flag, extra) + char *dst; + const char *src; + size_t len; + int flag; + const char *extra; +{ + char c; + char *start; + char *nextra; + + _DIAGASSERT(dst != NULL); + _DIAGASSERT(src != NULL); + _DIAGASSERT(extra != NULL); + MAKEEXTRALIST(flag, nextra, extra); + + if (flag & VIS_HTTPSTYLE) { + for (start = dst; len > 0; len--) { + c = *src++; + HVIS(dst, c, flag, len ? *src : '\0', nextra); + } + } else { + for (start = dst; len > 0; len--) { + c = *src++; + SVIS(dst, c, flag, len ? *src : '\0', nextra); + } + } + *dst = '\0'; + return (dst - start); +} + + +/* + * vis - visually encode characters + */ +char * +vis(dst, c, flag, nextc) + char *dst; + int c, flag, nextc; + +{ + char *extra; + + _DIAGASSERT(dst != NULL); + + MAKEEXTRALIST(flag, extra, ""); + if (flag & VIS_HTTPSTYLE) + HVIS(dst, c, flag, nextc, extra); + else + SVIS(dst, c, flag, nextc, extra); + *dst = '\0'; + return (dst); +} + + +/* + * strvis, strvisx - visually encode characters from src into dst + * + * Dst must be 4 times the size of src to account for possible + * expansion. The length of dst, not including the trailing NULL, + * is returned. + * + * Strvisx encodes exactly len bytes from src into dst. + * This is useful for encoding a block of data. + */ +int +strvis(dst, src, flag) + char *dst; + const char *src; + int flag; +{ + char *extra; + + MAKEEXTRALIST(flag, extra, ""); + return (strsvis(dst, src, flag, extra)); +} + + +int +strvisx(dst, src, len, flag) + char *dst; + const char *src; + size_t len; + int flag; +{ + char *extra; + + MAKEEXTRALIST(flag, extra, ""); + return (strsvisx(dst, src, len, flag, extra)); +} +#endif diff --git a/cmd-line-utils/libedit/np/vis.h b/cmd-line-utils/libedit/np/vis.h new file mode 100644 index 00000000000..1a49c9e3ed2 --- /dev/null +++ b/cmd-line-utils/libedit/np/vis.h @@ -0,0 +1,96 @@ +/* $NetBSD: vis.h,v 1.12 2002/03/23 17:39:05 christos Exp $ */ + +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. 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 University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)vis.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _VIS_H_ +#define _VIS_H_ + +#ifdef HAVE_SYS_CDEFS_H +#include <sys/cdefs.h> +#endif + +/* + * to select alternate encoding format + */ +#define VIS_OCTAL 0x01 /* use octal \ddd format */ +#define VIS_CSTYLE 0x02 /* 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_WHITE (VIS_SP | VIS_TAB | VIS_NL) +#define VIS_SAFE 0x20 /* only encode "unsafe" characters */ + +/* + * other + */ +#define VIS_NOSLASH 0x40 /* inhibit printing '\' */ +#define VIS_HTTPSTYLE 0x80 /* http-style escape % HEX HEX */ + +/* + * unvis return codes + */ +#define UNVIS_VALID 1 /* character valid */ +#define UNVIS_VALIDPUSH 2 /* character valid, push back passed char */ +#define UNVIS_NOCHAR 3 /* valid sequence, no character produced */ +#define UNVIS_SYNBAD -1 /* unrecognized escape sequence */ +#define UNVIS_ERROR -2 /* decoder in unknown state (unrecoverable) */ + +/* + * unvis flags + */ +#define UNVIS_END 1 /* no more characters */ + +char *vis(char *, int, int, int); +char *svis(char *, int, int, int, const char *); +int strvis(char *, const char *, int); +int strsvis(char *, const char *, int, const char *); +int strvisx(char *, const char *, size_t, int); +int strsvisx(char *, const char *, size_t, int, const char *); +int strunvis(char *, const char *); +int strunvisx(char *, const char *, int); +#ifdef __LIBC12_SOURCE__ +int unvis(char *, int, int *, int); +int __unvis13(char *, int, int *, int); +#else +int unvis(char *, int, int *, int) __RENAME(__unvis13); +#endif + +#endif /* !_VIS_H_ */ diff --git a/cmd-line-utils/libedit/parse.c b/cmd-line-utils/libedit/parse.c index b6d077793af..b113353d464 100644 --- a/cmd-line-utils/libedit/parse.c +++ b/cmd-line-utils/libedit/parse.c @@ -1,4 +1,4 @@ -/* $NetBSD: parse.c,v 1.14 2001/01/23 15:55:30 jdolecek Exp $ */ +/* $NetBSD: parse.c,v 1.16 2003/01/21 18:40:24 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,7 +36,14 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: parse.c,v 1.16 2003/01/21 18:40:24 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * parse.c: parse an editline extended command @@ -51,7 +58,6 @@ * settc * setty */ -#include "sys.h" #include "el.h" #include "tokenizer.h" #include <stdlib.h> @@ -63,7 +69,7 @@ private const struct { { "bind", map_bind }, { "echotc", term_echotc }, { "edit", el_editmode }, - { "history", hist_list }, + { "history", hist_command }, { "telltc", term_telltc }, { "settc", term_settc }, { "setty", tty_stty }, diff --git a/cmd-line-utils/libedit/prompt.c b/cmd-line-utils/libedit/prompt.c index fb7d9d35936..03d8309a991 100644 --- a/cmd-line-utils/libedit/prompt.c +++ b/cmd-line-utils/libedit/prompt.c @@ -1,4 +1,4 @@ -/* $NetBSD: prompt.c,v 1.8 2001/01/10 07:45:41 jdolecek Exp $ */ +/* $NetBSD: prompt.c,v 1.9 2002/03/18 16:00:56 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,12 +36,18 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: prompt.c,v 1.9 2002/03/18 16:00:56 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * prompt.c: Prompt printing functions */ -#include "sys.h" #include <stdio.h> #include "el.h" diff --git a/cmd-line-utils/libedit/read.c b/cmd-line-utils/libedit/read.c index ffec4671271..7567a81e875 100644 --- a/cmd-line-utils/libedit/read.c +++ b/cmd-line-utils/libedit/read.c @@ -1,4 +1,4 @@ -/* $NetBSD: read.c,v 1.19 2001/01/10 07:45:41 jdolecek Exp $ */ +/* $NetBSD: read.c,v 1.24 2002/11/20 16:50:08 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,13 +36,19 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: read.c,v 1.24 2002/11/20 16:50:08 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * read.c: Clean this junk up! This is horrible code. * Terminal read functions */ -#include "sys.h" #include <errno.h> #include <unistd.h> #include <stdlib.h> @@ -52,12 +58,44 @@ private int read__fixio(int, int); private int read_preread(EditLine *); -private int read_getcmd(EditLine *, el_action_t *, char *); private int read_char(EditLine *, char *); +private int read_getcmd(EditLine *, el_action_t *, char *); + +/* read_init(): + * Initialize the read stuff + */ +protected int +read_init(EditLine *el) +{ + /* builtin read_char */ + el->el_read.read_char = read_char; + return 0; +} + + +/* el_read_setfn(): + * Set the read char function to the one provided. + * If it is set to EL_BUILTIN_GETCFN, then reset to the builtin one. + */ +protected int +el_read_setfn(EditLine *el, el_rfunc_t rc) +{ + el->el_read.read_char = (rc == EL_BUILTIN_GETCFN) ? read_char : rc; + return 0; +} + + +/* el_read_getfn(): + * return the current read char function, or EL_BUILTIN_GETCFN + * if it is the default one + */ +protected el_rfunc_t +el_read_getfn(EditLine *el) +{ + return (el->el_read.read_char == read_char) ? + EL_BUILTIN_GETCFN : el->el_read.read_char; +} -#ifndef MIN -#define MIN(A,B) ((A) < (B) ? (A) : (B)) -#endif #ifdef DEBUG_EDIT private void @@ -83,7 +121,11 @@ read_debug(EditLine *el) */ /* ARGSUSED */ private int -read__fixio(int fd __attribute__((unused)), int e) +read__fixio(int fd +#if !(defined(TRY_AGAIN) && (defined(FIONBIO) || (defined(F_SETFL) && defined(O_NDELAY)))) + __attribute__((unused)) +#endif /* !(defined(TRY_AGAIN) && (defined(FIONBIO) || (defined(F_SETFL) && defined(O_NDELAY)))) */ +, int e) { switch (e) { @@ -178,14 +220,13 @@ read_preread(EditLine *el) * Push a macro */ public void -el_push(EditLine *el, const char *str) +el_push(EditLine *el, char *str) { c_macro_t *ma = &el->el_chared.c_macro; if (str != NULL && ma->level + 1 < EL_MAXMACRO) { ma->level++; - /* LINTED const cast */ - ma->macro[ma->level] = (char *) str; + ma->macro[ma->level] = str; } else { term_beep(el); term__flush(); @@ -199,10 +240,10 @@ el_push(EditLine *el, const char *str) private int read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) { - el_action_t cmd = ED_UNASSIGNED; + el_action_t cmd; int num; - while (cmd == ED_UNASSIGNED || cmd == ED_SEQUENCE_LEAD_IN) { + do { if ((num = el_getc(el, ch)) != 1) /* if EOF or error */ return (num); @@ -241,7 +282,7 @@ read_getcmd(EditLine *el, el_action_t *cmdnum, char *ch) } if (el->el_map.alt == NULL) el->el_map.current = el->el_map.key; - } + } while (cmd == ED_SEQUENCE_LEAD_IN); *cmdnum = cmd; return (OKCMD); } @@ -307,7 +348,7 @@ el_getc(EditLine *el, char *cp) #ifdef DEBUG_READ (void) fprintf(el->el_errfile, "Reading a character\n"); #endif /* DEBUG_READ */ - num_read = read_char(el, cp); + num_read = (*el->el_read.read_char)(el, cp); #ifdef DEBUG_READ (void) fprintf(el->el_errfile, "Got it %c\n", *cp); #endif /* DEBUG_READ */ @@ -333,7 +374,7 @@ el_gets(EditLine *el, int *nread) char *cp = el->el_line.buffer; size_t idx; - while (read_char(el, cp) == 1) { + while ((*el->el_read.read_char)(el, cp) == 1) { /* make sure there is space for next character */ if (cp + 1 >= el->el_line.limit) { idx = (cp - el->el_line.buffer); @@ -352,6 +393,11 @@ el_gets(EditLine *el, int *nread) *nread = el->el_line.cursor - el->el_line.buffer; return (el->el_line.buffer); } + + /* This is relatively cheap, and things go terribly wrong if + we have the wrong size. */ + el_resize(el); + re_clear_display(el); /* reset the display stuff */ ch_reset(el); @@ -378,7 +424,7 @@ el_gets(EditLine *el, int *nread) term__flush(); - while (read_char(el, cp) == 1) { + while ((*el->el_read.read_char)(el, cp) == 1) { /* make sure there is space next character */ if (cp + 1 >= el->el_line.limit) { idx = (cp - el->el_line.buffer); @@ -386,6 +432,8 @@ el_gets(EditLine *el, int *nread) break; cp = &el->el_line.buffer[idx]; } + if (*cp == 4) /* ought to be stty eof */ + break; cp++; if (cp[-1] == '\r' || cp[-1] == '\n') break; @@ -397,6 +445,7 @@ el_gets(EditLine *el, int *nread) *nread = el->el_line.cursor - el->el_line.buffer; return (el->el_line.buffer); } + for (num = OKCMD; num == OKCMD;) { /* while still editing this * line */ #ifdef DEBUG_EDIT @@ -410,7 +459,7 @@ el_gets(EditLine *el, int *nread) #endif /* DEBUG_READ */ break; } - if ((int) cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ + if ((uint)cmdnum >= (uint)(el->el_map.nfunc)) { /* BUG CHECK command */ #ifdef DEBUG_EDIT (void) fprintf(el->el_errfile, "ERROR: illegal command from key 0%o\r\n", ch); @@ -432,7 +481,24 @@ el_gets(EditLine *el, int *nread) "Error command = %d\n", cmdnum); } #endif /* DEBUG_READ */ + /* vi redo needs these way down the levels... */ + el->el_state.thiscmd = cmdnum; + el->el_state.thisch = ch; + if (el->el_map.type == MAP_VI && + el->el_map.current == el->el_map.key && + el->el_chared.c_redo.pos < el->el_chared.c_redo.lim) { + if (cmdnum == VI_DELETE_PREV_CHAR && + el->el_chared.c_redo.pos != el->el_chared.c_redo.buf + && isprint(el->el_chared.c_redo.pos[-1])) + el->el_chared.c_redo.pos--; + else + *el->el_chared.c_redo.pos++ = ch; + } retval = (*el->el_map.func[cmdnum]) (el, ch); +#ifdef DEBUG_READ + (void) fprintf(el->el_errfile, + "Returned state %d\n", retval ); +#endif /* DEBUG_READ */ /* save the last command here */ el->el_state.lastcmd = cmdnum; @@ -440,8 +506,6 @@ el_gets(EditLine *el, int *nread) /* use any return value */ switch (retval) { case CC_CURSOR: - el->el_state.argument = 1; - el->el_state.doingarg = 0; re_refresh_cursor(el); break; @@ -451,26 +515,20 @@ el_gets(EditLine *el, int *nread) /* FALLTHROUGH */ case CC_REFRESH: - el->el_state.argument = 1; - el->el_state.doingarg = 0; re_refresh(el); break; case CC_REFRESH_BEEP: - el->el_state.argument = 1; - el->el_state.doingarg = 0; re_refresh(el); term_beep(el); break; case CC_NORM: /* normal char */ - el->el_state.argument = 1; - el->el_state.doingarg = 0; break; case CC_ARGHACK: /* Suggested by Rich Salz */ /* <rsalz@pineapple.bbn.com> */ - break; /* keep going... */ + continue; /* keep going... */ case CC_EOF: /* end of file typed */ num = 0; @@ -489,8 +547,6 @@ el_gets(EditLine *el, int *nread) re_clear_display(el); /* reset the display stuff */ ch_reset(el); /* reset the input pointers */ re_refresh(el); /* print the prompt again */ - el->el_state.argument = 1; - el->el_state.doingarg = 0; break; case CC_ERROR: @@ -499,17 +555,18 @@ el_gets(EditLine *el, int *nread) (void) fprintf(el->el_errfile, "*** editor ERROR ***\r\n\n"); #endif /* DEBUG_READ */ - el->el_state.argument = 1; - el->el_state.doingarg = 0; term_beep(el); term__flush(); break; } + el->el_state.argument = 1; + el->el_state.doingarg = 0; + el->el_chared.c_vcmd.action = NOP; } - /* make sure the tty is set up correctly */ - (void) tty_cookedmode(el); term__flush(); /* flush any buffered output */ + /* make sure the tty is set up correctly */ + (void) tty_cookedmode(el); if (el->el_flags & HANDLE_SIGNALS) sig_clr(el); if (nread) diff --git a/cmd-line-utils/libedit/read.h b/cmd-line-utils/libedit/read.h new file mode 100644 index 00000000000..b01e77db239 --- /dev/null +++ b/cmd-line-utils/libedit/read.h @@ -0,0 +1,55 @@ +/* $NetBSD: read.h,v 1.1 2001/09/27 19:29:50 christos Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Anthony Mallet. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * el.read.h: Character reading functions + */ +#ifndef _h_el_read +#define _h_el_read + +typedef int (*el_rfunc_t)(EditLine *, char *); + +typedef struct el_read_t { + el_rfunc_t read_char; /* Function to read a character */ +} el_read_t; + +protected int read_init(EditLine *); +protected int el_read_setfn(EditLine *, el_rfunc_t); +protected el_rfunc_t el_read_getfn(EditLine *); + +#endif /* _h_el_read */ diff --git a/cmd-line-utils/libedit/readline.c b/cmd-line-utils/libedit/readline.c index 9069b46d1f8..13b0369de96 100644 --- a/cmd-line-utils/libedit/readline.c +++ b/cmd-line-utils/libedit/readline.c @@ -1,4 +1,4 @@ -/* $NetBSD: readline.c,v 1.19 2001/01/10 08:10:45 jdolecek Exp $ */ +/* $NetBSD: readline.c,v 1.28 2003/03/10 01:14:54 christos Exp $ */ /*- * Copyright (c) 1997 The NetBSD Foundation, Inc. @@ -36,7 +36,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +__RCSID("$NetBSD: readline.c,v 1.28 2003/03/10 01:14:54 christos Exp $"); +#endif /* not lint && not SCCSID */ + #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> @@ -47,14 +51,13 @@ #include <stdlib.h> #include <unistd.h> #include <limits.h> +#ifdef HAVE_ALLOCA_H +#include <alloca.h> +#endif #include "histedit.h" #include "readline/readline.h" -#include "sys.h" #include "el.h" #include "fcns.h" /* for EL_NUM_FCNS */ -#ifdef HAVE_ALLOCA_H -#include <alloca.h> -#endif /* for rl_complete() */ #define TAB '\r' @@ -65,7 +68,11 @@ /* readline compatibility stuff - look at readline sources/documentation */ /* to see what these variables mean */ const char *rl_library_version = "EditLine wrapper"; -const char *rl_readline_name = ""; +static char empty[] = { '\0' }; +static char expand_chars[] = { ' ', '\t', '\n', '=', '(', '\0' }; +static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$', + '>', '<', '=', ';', '|', '&', '{', '(', '\0' }; +char *rl_readline_name = empty; FILE *rl_instream = NULL; FILE *rl_outstream = NULL; int rl_point = 0; @@ -77,12 +84,12 @@ int history_length = 0; int max_input_history = 0; char history_expansion_char = '!'; char history_subst_char = '^'; -const char *history_no_expand_chars = " \t\n=("; +char *history_no_expand_chars = expand_chars; Function *history_inhibit_expansion_function = NULL; int rl_inhibit_completion = 0; int rl_attempted_completion_over = 0; -const char *rl_basic_word_break_characters = " \t\n\"\\'`@$><=;|&{("; +char *rl_basic_word_break_characters = break_chars; char *rl_completer_word_break_characters = NULL; char *rl_completer_quote_characters = NULL; CPFunction *rl_completion_entry_function = NULL; @@ -215,6 +222,11 @@ rl_initialize(void) /* for proper prompt printing in readline() */ el_rl_prompt = strdup(""); + if (el_rl_prompt == NULL) { + history_end(h); + el_end(e); + return -1; + } el_set(e, EL_PROMPT, _get_prompt); el_set(e, EL_SIGNAL, 1); @@ -250,8 +262,8 @@ rl_initialize(void) * and rl_line_buffer directly. */ li = el_line(e); - /* LINTED const cast */ - rl_line_buffer = (char *) li->buffer; + /* a cheesy way to get rid of const cast. */ + rl_line_buffer = memchr(li->buffer, *li->buffer, 1); rl_point = rl_end = 0; return (0); @@ -268,6 +280,7 @@ readline(const char *prompt) HistEvent ev; int count; const char *ret; + char *buf; if (e == NULL || h == NULL) rl_initialize(); @@ -278,28 +291,28 @@ readline(const char *prompt) if (strcmp(el_rl_prompt, prompt) != 0) { free(el_rl_prompt); el_rl_prompt = strdup(prompt); + if (el_rl_prompt == NULL) + return NULL; } /* get one line from input stream */ ret = el_gets(e, &count); if (ret && count > 0) { - char *foo; int lastidx; - foo = strdup(ret); + buf = strdup(ret); + if (buf == NULL) + return NULL; lastidx = count - 1; - if (foo[lastidx] == '\n') - foo[lastidx] = '\0'; - - ret = foo; + if (buf[lastidx] == '\n') + buf[lastidx] = '\0'; } else - ret = NULL; + buf = NULL; history(h, &ev, H_GETSIZE); history_length = ev.num; - /* LINTED const cast */ - return (char *) ret; + return buf; } /* @@ -333,6 +346,8 @@ _rl_compat_sub(const char *str, const char *what, const char *with, size_t size, i; result = malloc((size = 16)); + if (result == NULL) + return NULL; temp = str; with_len = strlen(with); what_len = strlen(what); @@ -343,8 +358,14 @@ _rl_compat_sub(const char *str, const char *what, const char *with, i = new - temp; add = i + with_len; if (i + add + 1 >= size) { + char *nresult; size += add + 1; - result = realloc(result, size); + nresult = realloc(result, size); + if (nresult == NULL) { + free(result); + return NULL; + } + result = nresult; } (void) strncpy(&result[len], temp, i); len += i; @@ -354,8 +375,14 @@ _rl_compat_sub(const char *str, const char *what, const char *with, } else { add = strlen(temp); if (len + add + 1 >= size) { + char *nresult; size += add + 1; - result = realloc(result, size); + nresult = realloc(result, size); + if (nresult == NULL) { + free(result); + return NULL; + } + result = nresult; } (void) strcpy(&result[len], temp); /* safe */ len += add; @@ -392,7 +419,7 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) *result = NULL; - cmd = (char*) alloca(cmdlen + 1); + cmd = alloca(cmdlen + 1); (void) strncpy(cmd, command, cmdlen); cmd[cmdlen] = 0; @@ -425,7 +452,7 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) return (-1); prefix = 0; } - search = (char*) alloca(len + 1); + search = alloca(len + 1); (void) strncpy(search, &cmd[idx], len); search[len] = '\0'; @@ -498,6 +525,8 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) cmd++; line = strdup(event_data); + if (line == NULL) + return 0; for (; *cmd; cmd++) { if (*cmd == ':') continue; @@ -515,7 +544,7 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) g_on = 2; else if (*cmd == 's' || *cmd == '&') { char *what, *with, delim; - size_t len, from_len; + unsigned int len, from_len; size_t size; if (*cmd == '&' && (from == NULL || to == NULL)) @@ -524,23 +553,36 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) delim = *(++cmd), cmd++; size = 16; what = realloc(from, size); + if (what == NULL) { + free(from); + return 0; + } len = 0; for (; *cmd && *cmd != delim; cmd++) { if (*cmd == '\\' && *(cmd + 1) == delim) cmd++; - if (len >= size) - what = realloc(what, + if (len >= size) { + char *nwhat; + nwhat = realloc(what, (size <<= 1)); + if (nwhat == NULL) { + free(what); + return 0; + } + what = nwhat; + } what[len++] = *cmd; } what[len] = '\0'; from = what; if (*what == '\0') { free(what); - if (search) + if (search) { from = strdup(search); - else { + if (from == NULL) + return 0; + } else { from = NULL; return (-1); } @@ -551,12 +593,22 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) size = 16; with = realloc(to, size); + if (with == NULL) { + free(to); + return -1; + } len = 0; from_len = strlen(from); for (; *cmd && *cmd != delim; cmd++) { if (len + from_len + 1 >= size) { + char *nwith; size += from_len + 1; - with = realloc(with, size); + nwith = realloc(with, size); + if (nwith == NULL) { + free(with); + return -1; + } + with = nwith; } if (*cmd == '&') { /* safe */ @@ -575,8 +627,10 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) tempcmd = _rl_compat_sub(line, from, to, (g_on) ? 1 : 0); - free(line); - line = tempcmd; + if (tempcmd) { + free(line); + line = tempcmd; + } g_on = 0; } } @@ -622,14 +676,21 @@ _history_expand_command(const char *command, size_t cmdlen, char **result) } cmdsize = 1, cmdlen = 0; - tempcmd = malloc(cmdsize); + if ((tempcmd = malloc(cmdsize)) == NULL) + return 0; for (i = start; start <= i && i <= end; i++) { int arr_len; arr_len = strlen(arr[i]); if (cmdlen + arr_len + 1 >= cmdsize) { + char *ntempcmd; cmdsize += arr_len + 1; - tempcmd = realloc(tempcmd, cmdsize); + ntempcmd = realloc(tempcmd, cmdsize); + if (ntempcmd == NULL) { + free(tempcmd); + return 0; + } + tempcmd = ntempcmd; } (void) strcpy(&tempcmd[cmdlen], arr[i]); /* safe */ cmdlen += arr_len; @@ -662,10 +723,12 @@ history_expand(char *str, char **output) rl_initialize(); *output = strdup(str); /* do it early */ + if (*output == NULL) + return 0; if (str[0] == history_subst_char) { /* ^foo^foo2^ is equivalent to !!:s^foo^foo2^ */ - temp = (char*) alloca(4 + strlen(str) + 1); + temp = alloca(4 + strlen(str) + 1); temp[0] = temp[1] = history_expansion_char; temp[2] = ':'; temp[3] = 's'; @@ -674,8 +737,14 @@ history_expand(char *str, char **output) } #define ADD_STRING(what, len) \ { \ - if (idx + len + 1 > size) \ - result = realloc(result, (size += len + 1)); \ + if (idx + len + 1 > size) { \ + char *nresult = realloc(result, (size += len + 1));\ + if (nresult == NULL) { \ + free(*output); \ + return 0; \ + } \ + result = nresult; \ + } \ (void)strncpy(&result[idx], what, len); \ idx += len; \ result[idx] = '\0'; \ @@ -789,11 +858,21 @@ history_tokenize(const char *str) } if (result_idx + 2 >= size) { + char **nresult; size <<= 1; - result = realloc(result, size * sizeof(char *)); + nresult = realloc(result, size * sizeof(char *)); + if (nresult == NULL) { + free(result); + return NULL; + } + result = nresult; } len = i - start; temp = malloc(len + 1); + if (temp == NULL) { + free(result); + return NULL; + } (void) strncpy(temp, &str[start], len); temp[len] = '\0'; result[result_idx++] = temp; @@ -1158,11 +1237,15 @@ tilde_expand(char *txt) return (strdup(txt)); temp = strchr(txt + 1, '/'); - if (temp == NULL) + if (temp == NULL) { temp = strdup(txt + 1); - else { + if (temp == NULL) + return NULL; + } else { len = temp - txt + 1; /* text until string after slash */ temp = malloc(len); + if (temp == NULL) + return NULL; (void) strncpy(temp, txt + 1, len - 2); temp[len - 2] = '\0'; } @@ -1176,6 +1259,8 @@ tilde_expand(char *txt) txt += len; temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1); + if (temp == NULL) + return NULL; (void) sprintf(temp, "%s/%s", pass->pw_dir, txt); return (temp); @@ -1200,28 +1285,45 @@ filename_completion_function(const char *text, int state) size_t len; if (state == 0 || dir == NULL) { - if (dir != NULL) { - closedir(dir); - dir = NULL; - } temp = strrchr(text, '/'); if (temp) { + char *nptr; temp++; - filename = realloc(filename, strlen(temp) + 1); + nptr = realloc(filename, strlen(temp) + 1); + if (nptr == NULL) { + free(filename); + return NULL; + } + filename = nptr; (void) strcpy(filename, temp); len = temp - text; /* including last slash */ - dirname = realloc(dirname, len + 1); + nptr = realloc(dirname, len + 1); + if (nptr == NULL) { + free(filename); + return NULL; + } + dirname = nptr; (void) strncpy(dirname, text, len); dirname[len] = '\0'; } else { filename = strdup(text); + if (filename == NULL) + return NULL; dirname = NULL; } /* support for ``~user'' syntax */ if (dirname && *dirname == '~') { + char *nptr; temp = tilde_expand(dirname); - dirname = realloc(dirname, strlen(temp) + 1); + if (temp == NULL) + return NULL; + nptr = realloc(dirname, strlen(temp) + 1); + if (nptr == NULL) { + free(dirname); + return NULL; + } + dirname = nptr; (void) strcpy(dirname, temp); /* safe */ free(temp); /* no longer needed */ } @@ -1230,6 +1332,10 @@ filename_completion_function(const char *text, int state) if (filename_len == 0) return (NULL); /* no expansion possible */ + if (dir != NULL) { + (void)closedir(dir); + dir = NULL; + } dir = opendir(dirname ? dirname : "."); if (!dir) return (NULL); /* cannot open the directory */ @@ -1239,7 +1345,7 @@ filename_completion_function(const char *text, int state) /* otherwise, get first entry where first */ /* filename_len characters are equal */ if (entry->d_name[0] == filename[0] -#ifdef HAVE_DIRENT_H +#if defined(__SVR4) || defined(__linux__) && strlen(entry->d_name) >= filename_len #else && entry->d_namlen >= filename_len @@ -1252,21 +1358,26 @@ filename_completion_function(const char *text, int state) if (entry) { /* match found */ struct stat stbuf; -#ifdef HAVE_DIRENT_H +#if defined(__SVR4) || defined(__linux__) len = strlen(entry->d_name) + #else len = entry->d_namlen + #endif ((dirname) ? strlen(dirname) : 0) + 1 + 1; temp = malloc(len); + if (temp == NULL) + return NULL; (void) sprintf(temp, "%s%s", dirname ? dirname : "", entry->d_name); /* safe */ /* test, if it's directory */ if (stat(temp, &stbuf) == 0 && S_ISDIR(stbuf.st_mode)) strcat(temp, "/"); /* safe */ - } else + } else { + (void)closedir(dir); + dir = NULL; temp = NULL; + } return (temp); } @@ -1331,16 +1442,24 @@ completion_matches(const char *text, CPFunction *genfunc) matches = 0; match_list_len = 1; while ((retstr = (*genfunc) (text, matches)) != NULL) { - if (matches + 1 >= match_list_len) { + /* allow for list terminator here */ + if (matches + 2 >= match_list_len) { + char **nmatch_list; match_list_len <<= 1; - match_list = realloc(match_list, + nmatch_list = realloc(match_list, match_list_len * sizeof(char *)); + if (nmatch_list == NULL) { + free(match_list); + return NULL; + } + match_list = nmatch_list; + } match_list[++matches] = retstr; } if (!match_list) - return (char **) NULL; /* nothing found */ + return NULL; /* nothing found */ /* find least denominator and insert it to match_list[0] */ which = 2; @@ -1354,14 +1473,15 @@ completion_matches(const char *text, CPFunction *genfunc) } retstr = malloc(max_equal + 1); + if (retstr == NULL) { + free(match_list); + return NULL; + } (void) strncpy(retstr, match_list[1], max_equal); retstr[max_equal] = '\0'; match_list[0] = retstr; /* add NULL as last pointer to the array */ - if (matches + 1 >= match_list_len) - match_list = realloc(match_list, - (match_list_len + 1) * sizeof(char *)); match_list[matches + 1] = (char *) NULL; return (match_list); @@ -1374,10 +1494,8 @@ static int _rl_qsort_string_compare(i1, i2) const void *i1, *i2; { - /*LINTED const castaway*/ - const char *s1 = ((const char **)i1)[0]; - /*LINTED const castaway*/ - const char *s2 = ((const char **)i2)[0]; + const char *s1 = ((const char * const *)i1)[0]; + const char *s2 = ((const char * const *)i2)[0]; return strcasecmp(s1, s2); } @@ -1459,7 +1577,7 @@ rl_complete_internal(int what_to_do) ctemp--; len = li->cursor - ctemp; - temp = (char*) alloca(len + 1); + temp = alloca(len + 1); (void) strncpy(temp, ctemp, len); temp[len] = '\0'; diff --git a/cmd-line-utils/libedit/readline/readline.h b/cmd-line-utils/libedit/readline/readline.h index 930c32d6f1c..7485dde4052 100644 --- a/cmd-line-utils/libedit/readline/readline.h +++ b/cmd-line-utils/libedit/readline/readline.h @@ -39,18 +39,6 @@ #define _READLINE_H_ #include <sys/types.h> -#if HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif -#ifndef __BEGIN_DECLS -#if defined(__cplusplus) -#define __BEGIN_DECLS extern "C" { -#define __END_DECLS } -#else -#define __BEGIN_DECLS -#define __END_DECLS -#endif -#endif /* list of readline stuff supported by editline library's readline wrapper */ @@ -66,16 +54,18 @@ typedef struct _hist_entry { } HIST_ENTRY; /* global variables used by readline enabled applications */ -__BEGIN_DECLS +#ifdef __cplusplus +extern "C" { +#endif extern const char *rl_library_version; -extern const char *rl_readline_name; +extern char *rl_readline_name; extern FILE *rl_instream; extern FILE *rl_outstream; extern char *rl_line_buffer; extern int rl_point, rl_end; extern int history_base, history_length; extern int max_input_history; -extern const char *rl_basic_word_break_characters; +extern char *rl_basic_word_break_characters; extern char *rl_completer_word_break_characters; extern char *rl_completer_quote_characters; extern CPFunction *rl_completion_entry_function; @@ -121,6 +111,8 @@ void rl_display_match_list(char **, int, int); int rl_insert(int, int); void rl_reset_terminal(const char *); int rl_bind_key(int, int (*)(int, int)); -__END_DECLS +#ifdef __cplusplus +} +#endif #endif /* _READLINE_H_ */ diff --git a/cmd-line-utils/libedit/refresh.c b/cmd-line-utils/libedit/refresh.c index 534e7e12304..e71bdba2b61 100644 --- a/cmd-line-utils/libedit/refresh.c +++ b/cmd-line-utils/libedit/refresh.c @@ -1,4 +1,4 @@ -/* $NetBSD: refresh.c,v 1.17 2001/04/13 00:53:11 lukem Exp $ */ +/* $NetBSD: refresh.c,v 1.24 2003/03/10 21:18:49 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,12 +36,18 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: refresh.c,v 1.24 2003/03/10 21:18:49 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * refresh.c: Lower level screen refreshing functions */ -#include "sys.h" #include <stdio.h> #include <ctype.h> #include <unistd.h> @@ -51,28 +57,28 @@ 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_insert (EditLine *el, char *, int, int, char *, int); +private void re_delete(EditLine *el, char *, int, int, int); private void re_fastputc(EditLine *, int); private void re__strncopy(char *, char *, size_t); private void re__copy_and_pad(char *, const char *, size_t); #ifdef DEBUG_REFRESH -private void re_printstr(EditLine *, char *, char *, char *); +private void re_printstr(EditLine *, const char *, char *, char *); #define __F el->el_errfile #define ELRE_ASSERT(a, b, c) do \ - if (a) { \ + if (/*CONSTCOND*/ a) { \ (void) fprintf b; \ c; \ } \ - while (0) + while (/*CONSTCOND*/0) #define ELRE_DEBUG(a, b) ELRE_ASSERT(a,b,;) /* re_printstr(): * Print a string on the debugging pty */ private void -re_printstr(EditLine *el, char *str, char *f, char *t) +re_printstr(EditLine *el, const char *str, char *f, char *t) { ELRE_DEBUG(1, (__F, "%s:\"", str)); @@ -203,6 +209,14 @@ re_refresh(EditLine *el) el->el_refresh.r_cursor.h = 0; el->el_refresh.r_cursor.v = 0; + if (el->el_line.cursor >= el->el_line.lastchar) { + if (el->el_map.current == el->el_map.alt + && el->el_line.lastchar != el->el_line.buffer) + el->el_line.cursor = el->el_line.lastchar - 1; + else + el->el_line.cursor = el->el_line.lastchar; + } + cur.h = -1; /* set flag in case I'm not set */ cur.v = 0; @@ -312,7 +326,6 @@ re_goto_bottom(EditLine *el) { term_move_to_line(el, el->el_refresh.r_oldcv); - term__putc('\r'); term__putc('\n'); re_clear_display(el); term__flush(); @@ -325,7 +338,7 @@ re_goto_bottom(EditLine *el) */ private void /*ARGSUSED*/ -re_insert(EditLine *el __attribute__((unused)), +re_insert(EditLine *el __attribute__((unused)), char *d, int dat, int dlen, char *s, int num) { char *a, *b; @@ -369,7 +382,7 @@ re_insert(EditLine *el __attribute__((unused)), */ private void /*ARGSUSED*/ -re_delete(EditLine *el __attribute__((unused)), +re_delete(EditLine *el __attribute__((unused)), char *d, int dat, int dlen, int num) { char *a, *b; @@ -905,7 +918,7 @@ re_update_line(EditLine *el, char *old, char *new, int i) private void re__copy_and_pad(char *dst, const char *src, size_t width) { - unsigned int i; + size_t i; for (i = 0; i < width; i++) { if (*src == '\0') @@ -929,6 +942,14 @@ re_refresh_cursor(EditLine *el) char *cp, c; int h, v, th; + if (el->el_line.cursor >= el->el_line.lastchar) { + if (el->el_map.current == el->el_map.alt + && el->el_line.lastchar != el->el_line.buffer) + el->el_line.cursor = el->el_line.lastchar - 1; + else + el->el_line.cursor = el->el_line.lastchar; + } + /* first we must find where the cursor is... */ h = el->el_prompt.p_pos.h; v = el->el_prompt.p_pos.v; @@ -1051,8 +1072,8 @@ re_fastaddc(EditLine *el) re_fastputc(el, c); } else { re_fastputc(el, '\\'); - re_fastputc(el, (int) ((((unsigned int) c >> 6) & 7) + '0')); - re_fastputc(el, (int) ((((unsigned int) c >> 3) & 7) + '0')); + re_fastputc(el, (int)(((((unsigned int)c) >> 6) & 3) + '0')); + re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0')); re_fastputc(el, (c & 7) + '0'); } term__flush(); diff --git a/cmd-line-utils/libedit/search.c b/cmd-line-utils/libedit/search.c index bdc3a1e8bb9..0957529485c 100644 --- a/cmd-line-utils/libedit/search.c +++ b/cmd-line-utils/libedit/search.c @@ -1,4 +1,4 @@ -/* $NetBSD: search.c,v 1.11 2001/01/23 15:55:31 jdolecek Exp $ */ +/* $NetBSD: search.c,v 1.14 2002/11/20 16:50:08 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,17 +36,21 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: search.c,v 1.14 2002/11/20 16:50:08 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * search.c: History and character search functions */ -#include "sys.h" #include <stdlib.h> -#if HAVE_SYS_TYPES_H -#include <sys/types.h> -#endif #if defined(REGEX) +#include <sys/types.h> #include <regex.h> #elif defined(REGEXP) #include <regexp.h> @@ -73,7 +77,8 @@ search_init(EditLine *el) el->el_search.patlen = 0; el->el_search.patdir = -1; el->el_search.chacha = '\0'; - el->el_search.chadir = -1; + el->el_search.chadir = CHAR_FWD; + el->el_search.chatflg = 0; return (0); } @@ -445,29 +450,23 @@ cv_search(EditLine *el, int dir) char tmpbuf[EL_BUFSIZ]; int tmplen; - tmplen = 0; -#ifdef ANCHOR - tmpbuf[tmplen++] = '.'; - tmpbuf[tmplen++] = '*'; -#endif - - el->el_line.buffer[0] = '\0'; - el->el_line.lastchar = el->el_line.buffer; - el->el_line.cursor = el->el_line.buffer; - el->el_search.patdir = dir; - - c_insert(el, 2); /* prompt + '\n' */ - *el->el_line.cursor++ = '\n'; - *el->el_line.cursor++ = dir == ED_SEARCH_PREV_HISTORY ? '/' : '?'; - re_refresh(el); - #ifdef ANCHOR + tmpbuf[0] = '.'; + tmpbuf[1] = '*'; #define LEN 2 #else #define LEN 0 #endif + tmplen = LEN; + + el->el_search.patdir = dir; + + tmplen = c_gets(el, &tmpbuf[LEN], + dir == ED_SEARCH_PREV_HISTORY ? "\n/" : "\n?" ); + if (tmplen == -1) + return CC_REFRESH; - tmplen = c_gets(el, &tmpbuf[LEN]) + LEN; + tmplen += LEN; ch = tmpbuf[tmplen]; tmpbuf[tmplen] = '\0'; @@ -476,9 +475,6 @@ cv_search(EditLine *el, int dir) * Use the old pattern, but wild-card it. */ if (el->el_search.patlen == 0) { - el->el_line.buffer[0] = '\0'; - el->el_line.lastchar = el->el_line.buffer; - el->el_line.cursor = el->el_line.buffer; re_refresh(el); return (CC_ERROR); } @@ -509,19 +505,15 @@ cv_search(EditLine *el, int dir) 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) { + ed_search_next_history(el, 0)) == CC_ERROR) { re_refresh(el); return (CC_ERROR); - } else { - if (ch == 0033) { - re_refresh(el); - *el->el_line.lastchar++ = '\n'; - *el->el_line.lastchar = '\0'; - re_goto_bottom(el); - return (CC_NEWLINE); - } else - return (CC_REFRESH); } + if (ch == 0033) { + re_refresh(el); + return ed_newline(el, 0); + } + return (CC_REFRESH); } @@ -578,69 +570,53 @@ cv_repeat_srch(EditLine *el, int c) } -/* cv_csearch_back(): - * Vi character search reverse +/* cv_csearch(): + * Vi character search */ protected el_action_t -cv_csearch_back(EditLine *el, int ch, int count, int tflag) +cv_csearch(EditLine *el, int direction, int ch, int count, int tflag) { char *cp; - cp = el->el_line.cursor; - while (count--) { - if (*cp == ch) - cp--; - while (cp > el->el_line.buffer && *cp != ch) - cp--; - } - - if (cp < el->el_line.buffer || (cp == el->el_line.buffer && *cp != ch)) - return (CC_ERROR); - - if (*cp == ch && tflag) - cp++; + if (ch == 0) + return CC_ERROR; - el->el_line.cursor = cp; - - if (el->el_chared.c_vcmd.action & DELETE) { - el->el_line.cursor++; - cv_delfini(el); - return (CC_REFRESH); + if (ch == -1) { + char c; + if (el_getc(el, &c) != 1) + return ed_end_of_file(el, 0); + ch = c; } - re_refresh_cursor(el); - return (CC_NORM); -} - -/* cv_csearch_fwd(): - * Vi character search forward - */ -protected el_action_t -cv_csearch_fwd(EditLine *el, int ch, int count, int tflag) -{ - char *cp; + /* Save for ';' and ',' commands */ + el->el_search.chacha = ch; + el->el_search.chadir = direction; + el->el_search.chatflg = tflag; cp = el->el_line.cursor; while (count--) { if (*cp == ch) - cp++; - while (cp < el->el_line.lastchar && *cp != ch) - cp++; + 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) + break; + } } - if (cp >= el->el_line.lastchar) - return (CC_ERROR); - - if (*cp == ch && tflag) - cp--; + if (tflag) + cp -= direction; el->el_line.cursor = cp; - if (el->el_chared.c_vcmd.action & DELETE) { - el->el_line.cursor++; + if (el->el_chared.c_vcmd.action != NOP) { + if (direction > 0) + el->el_line.cursor++; cv_delfini(el); - return (CC_REFRESH); + return CC_REFRESH; } - re_refresh_cursor(el); - return (CC_NORM); + return CC_CURSOR; } diff --git a/cmd-line-utils/libedit/search.h b/cmd-line-utils/libedit/search.h index 676bbe2e35b..a7363072a4c 100644 --- a/cmd-line-utils/libedit/search.h +++ b/cmd-line-utils/libedit/search.h @@ -1,4 +1,4 @@ -/* $NetBSD: search.h,v 1.5 2000/09/04 22:06:32 lukem Exp $ */ +/* $NetBSD: search.h,v 1.6 2002/11/15 14:32:34 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -52,6 +52,7 @@ typedef struct el_search_t { int patdir; /* Direction of the last search */ int chadir; /* Character search direction */ char chacha; /* Character we are looking for */ + char chatflg; /* 0 if f, 1 if t */ } el_search_t; @@ -64,7 +65,6 @@ protected el_action_t ce_inc_search(EditLine *, int); protected el_action_t cv_search(EditLine *, int); protected el_action_t ce_search_line(EditLine *, char *, int); protected el_action_t cv_repeat_srch(EditLine *, int); -protected el_action_t cv_csearch_back(EditLine *, int, int, int); -protected el_action_t cv_csearch_fwd(EditLine *, int, int, int); +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 bfb3d5c93f9..3730067ed5f 100644 --- a/cmd-line-utils/libedit/sig.c +++ b/cmd-line-utils/libedit/sig.c @@ -1,4 +1,4 @@ -/* $NetBSD: sig.c,v 1.8 2001/01/09 17:31:04 jdolecek Exp $ */ +/* $NetBSD: sig.c,v 1.10 2003/03/10 00:58:05 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,14 +36,20 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: sig.c,v 1.10 2003/03/10 00:58:05 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * sig.c: Signal handling stuff. * our policy is to trap all signals, set a good state * and pass the ball to our caller. */ -#include "sys.h" #include "el.h" #include <stdlib.h> @@ -115,9 +121,9 @@ sig_init(EditLine *el) #undef _DO (void) sigprocmask(SIG_BLOCK, &nset, &oset); -#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(libedit_sig_t)) +#define SIGSIZE (sizeof(sighdl) / sizeof(sighdl[0]) * sizeof(el_signalhandler_t)) - el->el_signal = (el_signal_t) el_malloc(SIGSIZE); + el->el_signal = (el_signalhandler_t *) el_malloc(SIGSIZE); if (el->el_signal == NULL) return (-1); for (i = 0; sighdl[i] != -1; i++) @@ -157,7 +163,7 @@ sig_set(EditLine *el) (void) sigprocmask(SIG_BLOCK, &nset, &oset); for (i = 0; sighdl[i] != -1; i++) { - libedit_sig_t s; + el_signalhandler_t s; /* This could happen if we get interrupted */ if ((s = signal(sighdl[i], sig_handler)) != sig_handler) el->el_signal[i] = s; diff --git a/cmd-line-utils/libedit/sig.h b/cmd-line-utils/libedit/sig.h index 399e3a69437..8effea8e121 100644 --- a/cmd-line-utils/libedit/sig.h +++ b/cmd-line-utils/libedit/sig.h @@ -1,4 +1,4 @@ -/* $NetBSD: sig.h,v 1.3 2000/09/04 22:06:32 lukem Exp $ */ +/* $NetBSD: sig.h,v 1.4 2003/03/10 00:58:05 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -62,9 +62,8 @@ _DO(SIGCONT) \ _DO(SIGWINCH) -typedef RETSIGTYPE (*libedit_sig_t)(); -typedef libedit_sig_t *el_signal_t; - +typedef void (*el_signalhandler_t)(int); +typedef el_signalhandler_t *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 d9007243456..a7477d2c5ba 100644 --- a/cmd-line-utils/libedit/sys.h +++ b/cmd-line-utils/libedit/sys.h @@ -1,4 +1,4 @@ -/* $NetBSD: sys.h,v 1.4 2000/09/04 22:06:32 lukem Exp $ */ +/* $NetBSD: sys.h,v 1.6 2003/03/10 00:57:38 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -44,6 +44,10 @@ #ifndef _h_sys #define _h_sys +#ifdef HAVE_SYS_CDEFS_H +#include <sys/cdefs.h> +#endif + #ifndef public # define public /* Externally visible functions/variables */ #endif @@ -57,10 +61,6 @@ /* When we want to hide everything */ #endif -#if HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif - #ifndef _PTR_T # define _PTR_T typedef void *ptr_t; @@ -73,22 +73,58 @@ typedef void *ioctl_t; #include <stdio.h> +#ifndef HAVE_STRLCAT +#define strlcat libedit_strlcat +size_t strlcat(char *dst, const char *src, size_t size); +#endif + +#ifndef HAVE_STRLCPY +#define strlcpy libedit_strlcpy +size_t strlcpy(char *dst, const char *src, size_t size); +#endif + +#ifndef HAVE_FGETLN +#define fgetln libedit_fgetln +char *fgetln(FILE *fp, size_t *len); +#endif + #define REGEX /* Use POSIX.2 regular expression functions */ #undef REGEXP /* Use UNIX V8 regular expression functions */ -#if defined(__sun__) && defined(__SVR4) +#ifdef notdef # undef REGEX # undef REGEXP # include <malloc.h> -typedef void (*sig_t)(int); -#endif - -#ifndef __P -#ifdef __STDC__ -#define __P(x) x -#else -#define __P(x) () -#endif +# ifdef __GNUC__ +/* + * Broken hdrs. + */ +extern int tgetent(const char *bp, char *name); +extern int tgetflag(const char *id); +extern int tgetnum(const char *id); +extern char *tgetstr(const char *id, char **area); +extern char *tgoto(const char *cap, int col, int row); +extern int tputs(const char *str, int affcnt, int (*putc)(int)); +extern char *getenv(const char *); +extern int fprintf(FILE *, const char *, ...); +extern int sigsetmask(int); +extern int sigblock(int); +extern int fputc(int, FILE *); +extern int fgetc(FILE *); +extern int fflush(FILE *); +extern int tolower(int); +extern int toupper(int); +extern int errno, sys_nerr; +extern char *sys_errlist[]; +extern void perror(const char *); +# include <string.h> +# define strerror(e) sys_errlist[e] +# endif +# ifdef SABER +extern ptr_t memcpy(ptr_t, const ptr_t, size_t); +extern ptr_t memset(ptr_t, int, size_t); +# endif +extern char *fgetline(FILE *, int *); #endif #endif /* _h_sys */ diff --git a/cmd-line-utils/libedit/term.c b/cmd-line-utils/libedit/term.c index bcda9ac1216..f5fb93394d8 100644 --- a/cmd-line-utils/libedit/term.c +++ b/cmd-line-utils/libedit/term.c @@ -1,4 +1,4 @@ -/* $NetBSD: term.c,v 1.32 2001/01/23 15:55:31 jdolecek Exp $ */ +/* $NetBSD: term.c,v 1.35 2002/03/18 16:00:59 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,31 +36,44 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95"; +#else +__RCSID("$NetBSD: term.c,v 1.35 2002/03/18 16:00:59 christos Exp $"); +#endif +#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! */ - -#include "sys.h" #include <stdio.h> #include <signal.h> #include <string.h> #include <stdlib.h> #include <unistd.h> -#if defined(HAVE_TERMCAP_H) +#ifdef HAVE_TERMCAP_H #include <termcap.h> -#elif defined(HAVE_CURSES_H) && defined(HAVE_TERM_H) /* For HPUX11 */ +#endif +#ifdef HAVE_CURSES_H #include <curses.h> +#endif +#ifdef HAVE_NCURSES_H +#include <ncurses.h> +#endif + +#include "el.h" + +/* Solaris's term.h does horrid things. */ +#if (defined(HAVE_TERM_H) && !defined(SUNOS)) #include <term.h> #endif #include <sys/types.h> #include <sys/ioctl.h> -#include "el.h" - /* * IMPORTANT NOTE: these routines are allowed to look at the current screen * and the current possition assuming that it is correct. If this is not @@ -340,8 +353,7 @@ term_init(EditLine *el) return (-1); (void) memset(el->el_term.t_val, 0, T_val * sizeof(int)); term_outfile = el->el_outfile; - if (term_set(el, NULL) == -1) - return (-1); + (void) term_set(el, NULL); term_init_arrow(el); return (0); } @@ -637,7 +649,7 @@ mc_again: * from col 0 */ if (EL_CAN_TAB ? - ((unsigned int)-del > (((unsigned int) where >> 3) + + (((unsigned int)-del) > (((unsigned int) where >> 3) + (where & 07))) : (-del > where)) { term__putc('\r'); /* do a CR */ @@ -897,7 +909,7 @@ term_set(EditLine *el, const char *term) memset(el->el_term.t_cap, 0, TC_BUFSIZE); - i = tgetent(el->el_term.t_cap, (char*) term); + i = tgetent(el->el_term.t_cap, term); if (i <= 0) { if (i == -1) @@ -927,7 +939,7 @@ term_set(EditLine *el, const char *term) Val(T_co) = tgetnum("co"); Val(T_li) = tgetnum("li"); for (t = tstr; t->name != NULL; t++) - term_alloc(el, t, tgetstr((char*) t->name, &area)); + term_alloc(el, t, tgetstr(t->name, &area)); } if (Val(T_co) < 2) @@ -1067,8 +1079,6 @@ term_reset_arrow(EditLine *el) static const char stOH[] = {033, 'O', 'H', '\0'}; static const char stOF[] = {033, 'O', 'F', '\0'}; - term_init_arrow(el); /* Init arrow struct */ - 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); @@ -1237,8 +1247,7 @@ term__flush(void) */ protected int /*ARGSUSED*/ -term_telltc(EditLine *el, int - argc __attribute__((unused)), +term_telltc(EditLine *el, int argc __attribute__((unused)), const char **argv __attribute__((unused))) { const struct termcapstr *t; @@ -1274,7 +1283,8 @@ term_telltc(EditLine *el, int */ protected int /*ARGSUSED*/ -term_settc(EditLine *el, int argc __attribute__((unused)), const char **argv) +term_settc(EditLine *el, int argc __attribute__((unused)), + const char **argv __attribute__((unused))) { const struct termcapstr *ts; const struct termcapval *tv; @@ -1350,7 +1360,9 @@ term_settc(EditLine *el, int argc __attribute__((unused)), const char **argv) */ protected int /*ARGSUSED*/ -term_echotc(EditLine *el, int argc __attribute__((unused)), const char **argv) +term_echotc(EditLine *el __attribute__((unused)), + int argc __attribute__((unused)), + const char **argv __attribute__((unused))) { char *cap, *scap, *ep; int arg_need, arg_cols, arg_rows; @@ -1429,7 +1441,7 @@ term_echotc(EditLine *el, int argc __attribute__((unused)), const char **argv) break; } if (t->name == NULL) - scap = tgetstr((char*) *argv, &area); + scap = tgetstr(*argv, &area); if (!scap || scap[0] == '\0') { if (!silent) (void) fprintf(el->el_errfile, diff --git a/cmd-line-utils/libedit/term.h b/cmd-line-utils/libedit/term.h new file mode 100644 index 00000000000..47e08e84bf4 --- /dev/null +++ b/cmd-line-utils/libedit/term.h @@ -0,0 +1,124 @@ +/* $NetBSD: term.h,v 1.13 2002/03/18 16:01:00 christos Exp $ */ + +/*- + * Copyright (c) 1992, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Christos Zoulas of Cornell University. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)term.h 8.1 (Berkeley) 6/4/93 + */ + +/* + * el.term.h: Termcap header + */ +#ifndef _h_el_term +#define _h_el_term + +#include "histedit.h" + +typedef struct { /* Symbolic function key bindings */ + const char *name; /* name of the key */ + int key; /* Index in termcap table */ + key_value_t fun; /* Function bound to it */ + int type; /* Type of function */ +} fkey_t; + +typedef struct { + coord_t t_size; /* # lines and cols */ + int t_flags; +#define TERM_CAN_INSERT 0x001 /* Has insert cap */ +#define TERM_CAN_DELETE 0x002 /* Has delete cap */ +#define TERM_CAN_CEOL 0x004 /* Has CEOL cap */ +#define TERM_CAN_TAB 0x008 /* Can use tabs */ +#define TERM_CAN_ME 0x010 /* Can turn all attrs. */ +#define TERM_CAN_UP 0x020 /* Can move up */ +#define TERM_HAS_META 0x040 /* Has a meta key */ +#define TERM_HAS_AUTO_MARGINS 0x080 /* Has auto margins */ +#define TERM_HAS_MAGIC_MARGINS 0x100 /* Has magic margins */ + char *t_buf; /* Termcap buffer */ + int t_loc; /* location used */ + char **t_str; /* termcap strings */ + int *t_val; /* termcap values */ + char *t_cap; /* Termcap buffer */ + fkey_t *t_fkey; /* Array of keys */ +} el_term_t; + +/* + * fKey indexes + */ +#define A_K_DN 0 +#define A_K_UP 1 +#define A_K_LT 2 +#define A_K_RT 3 +#define A_K_HO 4 +#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 int term_set(EditLine *, const char *); +protected int term_settc(EditLine *, int, const char **); +protected int term_telltc(EditLine *, int, const char **); +protected int term_echotc(EditLine *, int, const char **); +protected int term__putc(int); +protected void term__flush(void); + +/* + * Easy access macros + */ +#define EL_FLAGS (el)->el_term.t_flags + +#define EL_CAN_INSERT (EL_FLAGS & TERM_CAN_INSERT) +#define EL_CAN_DELETE (EL_FLAGS & TERM_CAN_DELETE) +#define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL) +#define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB) +#define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME) +#define EL_HAS_META (EL_FLAGS & TERM_HAS_META) +#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS) +#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS) + +#endif /* _h_el_term */ diff --git a/cmd-line-utils/libedit/tokenizer.c b/cmd-line-utils/libedit/tokenizer.c index 7a7e5b5ed75..f6892d9954c 100644 --- a/cmd-line-utils/libedit/tokenizer.c +++ b/cmd-line-utils/libedit/tokenizer.c @@ -1,4 +1,4 @@ -/* $NetBSD: tokenizer.c,v 1.7 2001/01/04 15:56:32 christos Exp $ */ +/* $NetBSD: tokenizer.c,v 1.11 2002/10/27 20:24:29 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,12 +36,18 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: tokenizer.c,v 1.11 2002/10/27 20:24:29 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * tokenize.c: Bourne shell like tokenizer */ -#include "sys.h" #include <string.h> #include <stdlib.h> #include "tokenizer.h" @@ -66,7 +72,7 @@ typedef enum { struct tokenizer { char *ifs; /* In field separator */ int argc, amax; /* Current and maximum number of args */ - const char **argv; /* Argument list */ + 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 */ @@ -103,16 +109,29 @@ tok_init(const char *ifs) { Tokenizer *tok = (Tokenizer *) tok_malloc(sizeof(Tokenizer)); + if (tok == NULL) + return NULL; tok->ifs = strdup(ifs ? ifs : IFS); + if (tok->ifs == NULL) { + tok_free((ptr_t)tok); + return NULL; + } tok->argc = 0; tok->amax = AINCR; - tok->argv = (const char **) tok_malloc(sizeof(char *) * tok->amax); - if (tok->argv == NULL) - return (NULL); + tok->argv = (char **) tok_malloc(sizeof(char *) * tok->amax); + if (tok->argv == NULL) { + tok_free((ptr_t)tok->ifs); + tok_free((ptr_t)tok); + return NULL; + } tok->argv[0] = NULL; tok->wspace = (char *) tok_malloc(WINCR); - if (tok->wspace == NULL) - return (NULL); + if (tok->wspace == NULL) { + tok_free((ptr_t)tok->argv); + tok_free((ptr_t)tok->ifs); + tok_free((ptr_t)tok); + return NULL; + } tok->wmax = tok->wspace + WINCR; tok->wstart = tok->wspace; tok->wptr = tok->wspace; @@ -268,7 +287,7 @@ tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv) switch (tok->quote) { case Q_none: tok_finish(tok); - *argv = tok->argv; + *argv = (const char **)tok->argv; *argc = tok->argc; return (0); @@ -301,7 +320,7 @@ tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv) return (3); } tok_finish(tok); - *argv = tok->argv; + *argv = (const char **)tok->argv; *argc = tok->argc; return (0); @@ -363,25 +382,25 @@ tok_line(Tokenizer *tok, const char *line, int *argc, const char ***argv) if (tok->wptr >= tok->wmax - 4) { size_t size = tok->wmax - tok->wspace + WINCR; char *s = (char *) tok_realloc(tok->wspace, size); - /* SUPPRESS 22 */ - int offs = s - tok->wspace; if (s == NULL) return (-1); - if (offs != 0) { + if (s != tok->wspace) { int i; - for (i = 0; i < tok->argc; i++) - tok->argv[i] = tok->argv[i] + offs; - tok->wptr = tok->wptr + offs; - tok->wstart = tok->wstart + offs; - tok->wmax = s + size; + for (i = 0; i < tok->argc; i++) { + tok->argv[i] = + (tok->argv[i] - tok->wspace) + s; + } + tok->wptr = (tok->wptr - tok->wspace) + s; + tok->wstart = (tok->wstart - tok->wspace) + s; tok->wspace = s; } + tok->wmax = s + size; } if (tok->argc >= tok->amax - 4) { - const char **p; + char **p; tok->amax += AINCR; - p = (const char **) tok_realloc(tok->argv, + p = (char **) tok_realloc(tok->argv, tok->amax * sizeof(char *)); if (p == NULL) return (-1); diff --git a/cmd-line-utils/libedit/tokenizer.h b/cmd-line-utils/libedit/tokenizer.h index 14919fd3f84..7cc7a3346e4 100644 --- a/cmd-line-utils/libedit/tokenizer.h +++ b/cmd-line-utils/libedit/tokenizer.h @@ -1,4 +1,4 @@ -/* $NetBSD: tokenizer.h,v 1.4 2000/09/04 22:06:33 lukem Exp $ */ +/* $NetBSD: tokenizer.h,v 1.5 2002/03/18 16:01:00 christos Exp $ */ /*- * Copyright (c) 1992, 1993 diff --git a/cmd-line-utils/libedit/tty.c b/cmd-line-utils/libedit/tty.c index 2c7b502136d..5253fdf87a7 100644 --- a/cmd-line-utils/libedit/tty.c +++ b/cmd-line-utils/libedit/tty.c @@ -1,4 +1,4 @@ -/* $NetBSD: tty.c,v 1.15 2001/05/17 01:02:17 christos Exp $ */ +/* $NetBSD: tty.c,v 1.16 2002/03/18 16:01:01 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,12 +36,18 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: tty.c,v 1.16 2002/03/18 16:01:01 christos Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * tty.c: tty interface stuff */ -#include "sys.h" #include "tty.h" #include "el.h" @@ -54,7 +60,7 @@ typedef struct ttymodes_t { typedef struct ttymap_t { int nch, och; /* Internal and termio rep of chars */ el_action_t bind[3]; /* emacs, vi, and vi-cmd */ -} ttymap_t; +} ttymap_t; private const ttyperm_t ttyperm = { @@ -1039,9 +1045,8 @@ tty_stty(EditLine *el, int argc __attribute__((unused)), const char **argv) { const ttymodes_t *m; char x; - const char *d; int aflag = 0; - const char *s; + const char *s, *d; const char *name; int z = EX_IO; diff --git a/cmd-line-utils/libedit/tty.h b/cmd-line-utils/libedit/tty.h index 5fdcfadf0dc..e9597fceb2b 100644 --- a/cmd-line-utils/libedit/tty.h +++ b/cmd-line-utils/libedit/tty.h @@ -1,4 +1,4 @@ -/* $NetBSD: tty.h,v 1.8 2000/09/04 22:06:33 lukem Exp $ */ +/* $NetBSD: tty.h,v 1.9 2002/03/18 16:01:01 christos Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -453,16 +453,16 @@ #define MD_NN 5 typedef struct { - const char *t_name; - u_int t_setmask; - u_int t_clrmask; + const char *t_name; + u_int t_setmask; + u_int t_clrmask; } ttyperm_t[NN_IO][MD_NN]; typedef unsigned char ttychar_t[NN_IO][C_NCC]; protected int tty_init(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 296e11eb4d9..5380872cf65 100644 --- a/cmd-line-utils/libedit/vi.c +++ b/cmd-line-utils/libedit/vi.c @@ -1,4 +1,4 @@ -/* $NetBSD: vi.c,v 1.8 2000/09/04 22:06:33 lukem Exp $ */ +/* $NetBSD: vi.c,v 1.16 2003/03/10 11:09:25 dsl Exp $ */ /*- * Copyright (c) 1992, 1993 @@ -36,12 +36,22 @@ * SUCH DAMAGE. */ -#include "compat.h" +#include "config.h" +#include <stdlib.h> +#include <unistd.h> +#include <sys/wait.h> + +#if !defined(lint) && !defined(SCCSID) +#if 0 +static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93"; +#else +__RCSID("$NetBSD: vi.c,v 1.16 2003/03/10 11:09:25 dsl Exp $"); +#endif +#endif /* not lint && not SCCSID */ /* * vi.c: Vi mode commands. */ -#include "sys.h" #include "el.h" private el_action_t cv_action(EditLine *, int); @@ -53,22 +63,18 @@ private el_action_t cv_paste(EditLine *, int); private el_action_t cv_action(EditLine *el, int c) { - char *cp, *kp; - if (el->el_chared.c_vcmd.action & DELETE) { + if (el->el_chared.c_vcmd.action != NOP) { + /* 'cc', 'dd' and (possibly) friends */ + if (c != 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); el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.pos = 0; - - el->el_chared.c_undo.isize = 0; - el->el_chared.c_undo.dsize = 0; - kp = el->el_chared.c_undo.buf; - for (cp = el->el_line.buffer; cp < el->el_line.lastchar; cp++) { - *kp++ = *cp; - el->el_chared.c_undo.dsize++; - } - - el->el_chared.c_undo.action = INSERT; - el->el_chared.c_undo.ptr = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer; if (c & INSERT) @@ -79,25 +85,8 @@ cv_action(EditLine *el, int c) el->el_chared.c_vcmd.pos = el->el_line.cursor; el->el_chared.c_vcmd.action = c; return (CC_ARGHACK); - -#ifdef notdef - /* - * I don't think that this is needed. But we keep it for now - */ - else - if (el_chared.c_vcmd.action == NOP) { - el->el_chared.c_vcmd.pos = el->el_line.cursor; - el->el_chared.c_vcmd.action = c; - return (CC_ARGHACK); - } else { - el->el_chared.c_vcmd.action = 0; - el->el_chared.c_vcmd.pos = 0; - return (CC_ERROR); - } -#endif } - /* cv_paste(): * Paste previous deletion before or after the cursor */ @@ -105,23 +94,25 @@ private el_action_t cv_paste(EditLine *el, int c) { char *ptr; - c_undo_t *un = &el->el_chared.c_undo; + c_kill_t *k = &el->el_chared.c_kill; + int len = k->last - k->buf; + if (k->buf == NULL || len == 0) + return (CC_ERROR); #ifdef DEBUG_PASTE - (void) fprintf(el->el_errfile, "Paste: %x \"%s\" +%d -%d\n", - un->action, un->buf, un->isize, un->dsize); + (void) fprintf(el->el_errfile, "Paste: \"%.*s\"\n", len, k->buf); #endif - if (un->isize == 0) - return (CC_ERROR); + + cv_undo(el); if (!c && el->el_line.cursor < el->el_line.lastchar) el->el_line.cursor++; ptr = el->el_line.cursor; - c_insert(el, (int) un->isize); - if (el->el_line.cursor + un->isize > el->el_line.lastchar) + c_insert(el, len); + if (el->el_line.cursor + len > el->el_line.lastchar) return (CC_ERROR); - (void) memcpy(ptr, un->buf, un->isize); + (void) memcpy(ptr, k->buf, len +0u); return (CC_REFRESH); } @@ -152,24 +143,24 @@ vi_paste_prev(EditLine *el, int c __attribute__((unused))) } -/* vi_prev_space_word(): +/* vi_prev_big_word(): * Vi move to the previous space delimited word * [B] */ protected el_action_t /*ARGSUSED*/ -vi_prev_space_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); - el->el_line.cursor = cv_prev_word(el, el->el_line.cursor, + el->el_line.cursor = cv_prev_word(el->el_line.cursor, el->el_line.buffer, el->el_state.argument, - cv__isword); + cv__isWord); - if (el->el_chared.c_vcmd.action & DELETE) { + if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); return (CC_REFRESH); } @@ -179,7 +170,7 @@ vi_prev_space_word(EditLine *el, int c __attribute__((unused))) /* vi_prev_word(): * Vi move to the previous word - * [B] + * [b] */ protected el_action_t /*ARGSUSED*/ @@ -189,12 +180,12 @@ vi_prev_word(EditLine *el, int c __attribute__((unused))) if (el->el_line.cursor == el->el_line.buffer) return (CC_ERROR); - el->el_line.cursor = cv_prev_word(el, el->el_line.cursor, + el->el_line.cursor = cv_prev_word(el->el_line.cursor, el->el_line.buffer, el->el_state.argument, - ce__isword); + cv__isword); - if (el->el_chared.c_vcmd.action & DELETE) { + if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); return (CC_REFRESH); } @@ -202,25 +193,23 @@ vi_prev_word(EditLine *el, int c __attribute__((unused))) } -/* vi_next_space_word(): +/* vi_next_big_word(): * Vi move to the next space delimited word * [W] */ protected el_action_t /*ARGSUSED*/ -vi_next_space_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) + if (el->el_line.cursor >= el->el_line.lastchar - 1) 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); + el->el_line.lastchar, el->el_state.argument, cv__isWord); if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action & DELETE) { + if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); return (CC_REFRESH); } @@ -237,16 +226,14 @@ protected el_action_t vi_next_word(EditLine *el, int c __attribute__((unused))) { - if (el->el_line.cursor == el->el_line.lastchar) + if (el->el_line.cursor >= el->el_line.lastchar - 1) return (CC_ERROR); el->el_line.cursor = cv_next_word(el, el->el_line.cursor, - el->el_line.lastchar, - el->el_state.argument, - ce__isword); + el->el_line.lastchar, el->el_state.argument, cv__isword); if (el->el_map.type == MAP_VI) - if (el->el_chared.c_vcmd.action & DELETE) { + if (el->el_chared.c_vcmd.action != NOP) { cv_delfini(el); return (CC_REFRESH); } @@ -261,19 +248,27 @@ vi_next_word(EditLine *el, int c __attribute__((unused))) protected el_action_t vi_change_case(EditLine *el, int c) { + int i; - if (el->el_line.cursor < el->el_line.lastchar) { - c = *el->el_line.cursor; + if (el->el_line.cursor >= el->el_line.lastchar) + 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); + *el->el_line.cursor = tolower(c); else if (islower(c)) - *el->el_line.cursor++ = toupper(c); - else - el->el_line.cursor++; + *el->el_line.cursor = toupper(c); + + if (++el->el_line.cursor >= el->el_line.lastchar) { + el->el_line.cursor--; + re_fastaddc(el); + break; + } re_fastaddc(el); - return (CC_NORM); } - return (CC_ERROR); + return CC_NORM; } @@ -304,11 +299,7 @@ vi_insert_at_bol(EditLine *el, int c __attribute__((unused))) { el->el_line.cursor = el->el_line.buffer; - el->el_chared.c_vcmd.ins = el->el_line.cursor; - - el->el_chared.c_undo.ptr = el->el_line.cursor; - el->el_chared.c_undo.action = DELETE; - + cv_undo(el); el->el_map.current = el->el_map.key; return (CC_CURSOR); } @@ -323,13 +314,13 @@ protected el_action_t vi_replace_char(EditLine *el, int c __attribute__((unused))) { + if (el->el_line.cursor >= el->el_line.lastchar) + return CC_ERROR; + el->el_map.current = el->el_map.key; el->el_state.inputmode = MODE_REPLACE_1; - el->el_chared.c_undo.action = CHANGE; - el->el_chared.c_undo.ptr = el->el_line.cursor; - el->el_chared.c_undo.isize = 0; - el->el_chared.c_undo.dsize = 0; - return (CC_NORM); + cv_undo(el); + return (CC_ARGHACK); } @@ -344,17 +335,14 @@ vi_replace_mode(EditLine *el, int c __attribute__((unused))) el->el_map.current = el->el_map.key; el->el_state.inputmode = MODE_REPLACE; - el->el_chared.c_undo.action = CHANGE; - el->el_chared.c_undo.ptr = el->el_line.cursor; - el->el_chared.c_undo.isize = 0; - el->el_chared.c_undo.dsize = 0; + cv_undo(el); return (CC_NORM); } /* vi_substitute_char(): * Vi replace character under the cursor and enter insert mode - * [r] + * [s] */ protected el_action_t /*ARGSUSED*/ @@ -376,6 +364,9 @@ protected el_action_t 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); (void) em_kill_line(el, 0); el->el_map.current = el->el_map.key; return (CC_REFRESH); @@ -391,6 +382,9 @@ protected el_action_t 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); (void) ed_kill_line(el, 0); el->el_map.current = el->el_map.key; return (CC_REFRESH); @@ -407,11 +401,7 @@ vi_insert(EditLine *el, int c __attribute__((unused))) { el->el_map.current = el->el_map.key; - - el->el_chared.c_vcmd.ins = el->el_line.cursor; - el->el_chared.c_undo.ptr = el->el_line.cursor; - el->el_chared.c_undo.action = DELETE; - + cv_undo(el); return (CC_NORM); } @@ -435,9 +425,7 @@ vi_add(EditLine *el, int c __attribute__((unused))) } else ret = CC_NORM; - el->el_chared.c_vcmd.ins = el->el_line.cursor; - el->el_chared.c_undo.ptr = el->el_line.cursor; - el->el_chared.c_undo.action = DELETE; + cv_undo(el); return (ret); } @@ -454,11 +442,7 @@ 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; - - /* Mark where insertion begins */ - el->el_chared.c_vcmd.ins = el->el_line.lastchar; - el->el_chared.c_undo.ptr = el->el_line.lastchar; - el->el_chared.c_undo.action = DELETE; + cv_undo(el); return (CC_CURSOR); } @@ -476,22 +460,22 @@ vi_delete_meta(EditLine *el, int c __attribute__((unused))) } -/* vi_end_word(): +/* vi_end_big_word(): * Vi move to the end of the current space delimited word * [E] */ protected el_action_t /*ARGSUSED*/ -vi_end_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); el->el_line.cursor = cv__endword(el->el_line.cursor, - el->el_line.lastchar, el->el_state.argument); + el->el_line.lastchar, el->el_state.argument, cv__isWord); - if (el->el_chared.c_vcmd.action & DELETE) { + if (el->el_chared.c_vcmd.action != NOP) { el->el_line.cursor++; cv_delfini(el); return (CC_REFRESH); @@ -500,22 +484,22 @@ vi_end_word(EditLine *el, int c __attribute__((unused))) } -/* vi_to_end_word(): +/* vi_end_word(): * Vi move to the end of the current word * [e] */ protected el_action_t /*ARGSUSED*/ -vi_to_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); el->el_line.cursor = cv__endword(el->el_line.cursor, - el->el_line.lastchar, el->el_state.argument); + el->el_line.lastchar, el->el_state.argument, cv__isword); - if (el->el_chared.c_vcmd.action & DELETE) { + if (el->el_chared.c_vcmd.action != NOP) { el->el_line.cursor++; cv_delfini(el); return (CC_REFRESH); @@ -532,100 +516,19 @@ protected el_action_t /*ARGSUSED*/ vi_undo(EditLine *el, int c __attribute__((unused))) { - char *cp, *kp; - char temp; - int i, size; - c_undo_t *un = &el->el_chared.c_undo; - -#ifdef DEBUG_UNDO - (void) fprintf(el->el_errfile, "Undo: %x \"%s\" +%d -%d\n", - un->action, un->buf, un->isize, un->dsize); -#endif - switch (un->action) { - case DELETE: - if (un->dsize == 0) - return (CC_NORM); - - (void) memcpy(un->buf, un->ptr, un->dsize); - for (cp = un->ptr; cp <= el->el_line.lastchar; cp++) - *cp = cp[un->dsize]; - - el->el_line.lastchar -= un->dsize; - el->el_line.cursor = un->ptr; - - un->action = INSERT; - un->isize = un->dsize; - un->dsize = 0; - break; + c_undo_t un = el->el_chared.c_undo; - case DELETE | INSERT: - size = un->isize - un->dsize; - if (size > 0) - i = un->dsize; - else - i = un->isize; - cp = un->ptr; - kp = un->buf; - while (i-- > 0) { - temp = *kp; - *kp++ = *cp; - *cp++ = temp; - } - if (size > 0) { - el->el_line.cursor = cp; - c_insert(el, size); - while (size-- > 0 && cp < el->el_line.lastchar) { - temp = *kp; - *kp++ = *cp; - *cp++ = temp; - } - } else if (size < 0) { - size = -size; - for (; cp <= el->el_line.lastchar; cp++) { - *kp++ = *cp; - *cp = cp[size]; - } - el->el_line.lastchar -= size; - } - el->el_line.cursor = un->ptr; - i = un->dsize; - un->dsize = un->isize; - un->isize = i; - break; - - case INSERT: - if (un->isize == 0) - return (CC_NORM); - - el->el_line.cursor = un->ptr; - c_insert(el, (int) un->isize); - (void) memcpy(un->ptr, un->buf, un->isize); - un->action = DELETE; - un->dsize = un->isize; - un->isize = 0; - break; + if (un.len == -1) + return CC_ERROR; - case CHANGE: - if (un->isize == 0) - return (CC_NORM); - - el->el_line.cursor = un->ptr; - size = (int) (el->el_line.cursor - el->el_line.lastchar); - if (size < (int)un->isize) - size = un->isize; - cp = un->ptr; - kp = un->buf; - for (i = 0; i < size; i++) { - temp = *kp; - *kp++ = *cp; - *cp++ = temp; - } - un->dsize = 0; - break; - - default: - return (CC_ERROR); - } + /* 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_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); } @@ -639,22 +542,12 @@ protected el_action_t /*ARGSUSED*/ vi_command_mode(EditLine *el, int c __attribute__((unused))) { - int size; /* [Esc] cancels pending action */ - el->el_chared.c_vcmd.ins = 0; el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.pos = 0; el->el_state.doingarg = 0; - size = el->el_chared.c_undo.ptr - el->el_line.cursor; - if (size < 0) - size = -size; - if (el->el_chared.c_undo.action == (INSERT | DELETE) || - el->el_chared.c_undo.action == DELETE) - el->el_chared.c_undo.dsize = size; - else - el->el_chared.c_undo.isize = size; el->el_state.inputmode = MODE_INSERT; el->el_map.current = el->el_map.alt; @@ -674,41 +567,37 @@ protected el_action_t vi_zero(EditLine *el, int c) { - if (el->el_state.doingarg) { - if (el->el_state.argument > 1000000) - return (CC_ERROR); - el->el_state.argument = - (el->el_state.argument * 10) + (c - '0'); - return (CC_ARGHACK); - } else { - el->el_line.cursor = el->el_line.buffer; - if (el->el_chared.c_vcmd.action & DELETE) { - cv_delfini(el); - return (CC_REFRESH); - } - return (CC_CURSOR); + if (el->el_state.doingarg) + return ed_argument_digit(el, 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_CURSOR); } /* vi_delete_prev_char(): * Vi move to previous character (backspace) - * [^H] + * [^H] in insert mode only */ protected el_action_t /*ARGSUSED*/ vi_delete_prev_char(EditLine *el, int c __attribute__((unused))) { + char *cp; - if (el->el_chared.c_vcmd.ins == 0) + cp = el->el_line.cursor; + if (cp <= el->el_line.buffer) return (CC_ERROR); - if (el->el_chared.c_vcmd.ins > - el->el_line.cursor - el->el_state.argument) - return (CC_ERROR); - - c_delbefore(el, el->el_state.argument); - el->el_line.cursor -= el->el_state.argument; + /* do the delete here so we dont mess up the undo and paste buffers */ + el->el_line.cursor = --cp; + for (; cp < el->el_line.lastchar; cp++) + cp[0] = cp[1]; + el->el_line.lastchar = cp - 1; return (CC_REFRESH); } @@ -829,16 +718,7 @@ protected el_action_t /*ARGSUSED*/ vi_next_char(EditLine *el, int c __attribute__((unused))) { - char ch; - - if (el_getc(el, &ch) != 1) - return (ed_end_of_file(el, 0)); - - el->el_search.chadir = CHAR_FWD; - el->el_search.chacha = ch; - - return (cv_csearch_fwd(el, ch, el->el_state.argument, 0)); - + return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 0); } @@ -850,15 +730,7 @@ protected el_action_t /*ARGSUSED*/ vi_prev_char(EditLine *el, int c __attribute__((unused))) { - char ch; - - if (el_getc(el, &ch) != 1) - return (ed_end_of_file(el, 0)); - - el->el_search.chadir = CHAR_BACK; - el->el_search.chacha = ch; - - return (cv_csearch_back(el, ch, el->el_state.argument, 0)); + return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 0); } @@ -870,13 +742,7 @@ protected el_action_t /*ARGSUSED*/ vi_to_next_char(EditLine *el, int c __attribute__((unused))) { - char ch; - - if (el_getc(el, &ch) != 1) - return (ed_end_of_file(el, 0)); - - return (cv_csearch_fwd(el, ch, el->el_state.argument, 1)); - + return cv_csearch(el, CHAR_FWD, -1, el->el_state.argument, 1); } @@ -888,12 +754,7 @@ protected el_action_t /*ARGSUSED*/ vi_to_prev_char(EditLine *el, int c __attribute__((unused))) { - char ch; - - if (el_getc(el, &ch) != 1) - return (ed_end_of_file(el, 0)); - - return (cv_csearch_back(el, ch, el->el_state.argument, 1)); + return cv_csearch(el, CHAR_BACK, -1, el->el_state.argument, 1); } @@ -906,14 +767,8 @@ protected el_action_t vi_repeat_next_char(EditLine *el, int c __attribute__((unused))) { - if (el->el_search.chacha == 0) - return (CC_ERROR); - - return (el->el_search.chadir == CHAR_FWD - ? cv_csearch_fwd(el, el->el_search.chacha, - el->el_state.argument, 0) - : cv_csearch_back(el, el->el_search.chacha, - el->el_state.argument, 0)); + return cv_csearch(el, el->el_search.chadir, el->el_search.chacha, + el->el_state.argument, el->el_search.chatflg); } @@ -925,11 +780,343 @@ protected el_action_t /*ARGSUSED*/ vi_repeat_prev_char(EditLine *el, int c __attribute__((unused))) { + el_action_t r; + int dir = el->el_search.chadir; - if (el->el_search.chacha == 0) - return (CC_ERROR); + r = cv_csearch(el, -dir, el->el_search.chacha, + el->el_state.argument, el->el_search.chatflg); + el->el_search.chadir = dir; + return r; +} + + +/* vi_match(): + * Vi go to matching () {} or [] + * [%] + */ +protected el_action_t +/*ARGSUSED*/ +vi_match(EditLine *el, int c __attribute__((unused))) +{ + const char match_chars[] = "()[]{}"; + char *cp; + int delta, i, count; + char o_ch, c_ch; + + *el->el_line.lastchar = '\0'; /* just in case */ + + 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; + c_ch = match_chars[delta ^ 1]; + count = 1; + delta = 1 - (delta & 1) * 2; + + for (cp = &el->el_line.cursor[i]; count; ) { + cp += delta; + if (cp < el->el_line.buffer || cp >= el->el_line.lastchar) + return CC_ERROR; + if (*cp == o_ch) + count++; + else if (*cp == c_ch) + count--; + } + + el->el_line.cursor = cp; + + if (el->el_chared.c_vcmd.action != NOP) { + /* NB posix says char under cursor should NOT be deleted + for -ve delta - this is different to netbsd vi. */ + if (delta > 0) + el->el_line.cursor++; + cv_delfini(el); + return (CC_REFRESH); + } + return (CC_CURSOR); +} + +/* vi_undo_line(): + * Vi undo all changes to line + * [U] + */ +protected el_action_t +/*ARGSUSED*/ +vi_undo_line(EditLine *el, int c __attribute__((unused))) +{ + + cv_undo(el); + return hist_get(el); +} + +/* vi_to_column(): + * Vi go to specified column + * [|] + * NB netbsd vi goes to screen column 'n', posix says nth character + */ +protected el_action_t +/*ARGSUSED*/ +vi_to_column(EditLine *el, int c __attribute__((unused))) +{ + + el->el_line.cursor = el->el_line.buffer; + el->el_state.argument--; + return ed_next_char(el, 0); +} + +/* vi_yank_end(): + * Vi yank to end of line + * [Y] + */ +protected el_action_t +/*ARGSUSED*/ +vi_yank_end(EditLine *el, int c __attribute__((unused))) +{ + + cv_yank(el, el->el_line.cursor, + el->el_line.lastchar - el->el_line.cursor); + return CC_REFRESH; +} + +/* vi_yank(): + * Vi yank + * [y] + */ +protected el_action_t +/*ARGSUSED*/ +vi_yank(EditLine *el, int c __attribute__((unused))) +{ + + return cv_action(el, YANK); +} + +/* vi_comment_out(): + * Vi comment out current command + * [c] + */ +protected el_action_t +/*ARGSUSED*/ +vi_comment_out(EditLine *el, int c __attribute__((unused))) +{ + + el->el_line.cursor = el->el_line.buffer; + c_insert(el, 1); + *el->el_line.cursor = '#'; + re_refresh(el); + return ed_newline(el, 0); +} + +/* vi_alias(): + * Vi include shell alias + * [@] + * NB: posix impiles that we should enter insert mode, however + * this is against historical precedent... + */ +protected el_action_t +/*ARGSUSED*/ +vi_alias(EditLine *el __attribute__((unused)), int c __attribute__((unused))) +{ +#ifdef __weak_extern + char alias_name[3]; + char *alias_text; + extern char *get_alias_text(const char *); + __weak_extern(get_alias_text); + + if (get_alias_text == 0) { + return CC_ERROR; + } + + alias_name[0] = '_'; + alias_name[2] = 0; + if (el_getc(el, &alias_name[1]) != 1) + return CC_ERROR; + + alias_text = get_alias_text(alias_name); + if (alias_text != NULL) + el_push(el, alias_text); + return CC_NORM; +#else + return CC_ERROR; +#endif +} + +/* vi_to_history_line(): + * Vi go to specified history file line. + * [G] + */ +protected el_action_t +/*ARGSUSED*/ +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, + EL_BUFSIZ); + el->el_history.last = el->el_history.buf + + (el->el_line.lastchar - el->el_line.buffer); + } + + /* Lack of a 'count' means oldest, not 1 */ + if (!el->el_state.doingarg) { + el->el_history.eventno = 0x7fffffff; + hist_get(el); + } else { + /* This is brain dead, all the rest of this code counts + * upwards going into the past. Here we need count in the + * other direction (to match the output of fc -l). + * I could change the world, but this seems to suffice. + */ + el->el_history.eventno = 1; + if (hist_get(el) == CC_ERROR) + return CC_ERROR; + el->el_history.eventno = 1 + el->el_history.ev.num + - el->el_state.argument; + if (el->el_history.eventno < 0) { + el->el_history.eventno = sv_event_no; + return CC_ERROR; + } + } + rval = hist_get(el); + if (rval == CC_ERROR) + el->el_history.eventno = sv_event_no; + return rval; +} + +/* vi_histedit(): + * Vi edit history line with vi + * [v] + */ +protected el_action_t +/*ARGSUSED*/ +vi_histedit(EditLine *el, int c __attribute__((unused))) +{ + int fd; + pid_t pid; + int st; + char tempfile[] = "/tmp/histedit.XXXXXXXXXX"; + char *cp; + + if (el->el_state.doingarg) { + if (vi_to_history_line(el, 0) == CC_ERROR) + return CC_ERROR; + } + + fd = mkstemp(tempfile); + if (fd < 0) + return CC_ERROR; + cp = el->el_line.buffer; + write(fd, cp, el->el_line.lastchar - cp +0u); + write(fd, "\n", 1); + pid = fork(); + switch (pid) { + case -1: + close(fd); + unlink(tempfile); + return CC_ERROR; + case 0: + close(fd); + execlp("vi", "vi", tempfile, 0); + exit(0); + /*NOTREACHED*/ + default: + while (waitpid(pid, &st, 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; + break; + } + + close(fd); + unlink(tempfile); + /* return CC_REFRESH; */ + return ed_newline(el, 0); +} + +/* vi_history_word(): + * Vi append word from previous input line + * [_] + * Who knows where this one came from! + * '_' in vi means 'entire current line', so 'cc' is a synonym for 'c_' + */ +protected el_action_t +/*ARGSUSED*/ +vi_history_word(EditLine *el, int c __attribute__((unused))) +{ + const char *wp = HIST_FIRST(el); + const char *wep, *wsp; + int len; + char *cp; + const char *lim; + + if (wp == NULL) + return CC_ERROR; + + wep = wsp = 0; + do { + while (isspace((unsigned char)*wp)) + wp++; + if (*wp == 0) + break; + wsp = wp; + while (*wp && !isspace((unsigned char)*wp)) + wp++; + wep = wp; + } 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; + if (el->el_line.cursor < el->el_line.lastchar) + el->el_line.cursor++; + c_insert(el, len + 1); + cp = el->el_line.cursor; + lim = el->el_line.limit; + if (cp < lim) + *cp++ = ' '; + while (wsp < wep && cp < lim) + *cp++ = *wsp++; + el->el_line.cursor = cp; + + el->el_map.current = el->el_map.key; + return CC_REFRESH; +} + +/* vi_redo(): + * Vi redo last non-motion command + * [.] + */ +protected el_action_t +/*ARGSUSED*/ +vi_redo(EditLine *el, int c __attribute__((unused))) +{ + c_redo_t *r = &el->el_chared.c_redo; + + if (!el->el_state.doingarg && r->count) { + el->el_state.doingarg = 1; + el->el_state.argument = r->count; + } + + el->el_chared.c_vcmd.pos = el->el_line.cursor; + el->el_chared.c_vcmd.action = r->action; + if (r->pos != r->buf) { + if (r->pos + 1 > r->lim) + /* sanity */ + r->pos = r->lim - 1; + r->pos[0] = 0; + el_push(el, r->buf); + } - return el->el_search.chadir == CHAR_BACK ? - cv_csearch_fwd(el, el->el_search.chacha, el->el_state.argument, 0) : - cv_csearch_back(el, el->el_search.chacha, el->el_state.argument, 0); + el->el_state.thiscmd = r->cmd; + el->el_state.thisch = r->ch; + return (*el->el_map.func[r->cmd])(el, r->ch); } diff --git a/configure.in b/configure.in index a4b38778363..3bee418a270 100644 --- a/configure.in +++ b/configure.in @@ -1872,6 +1872,22 @@ else fi AC_SUBST(TERMCAP_LIB) +# for libedit 2.6.7 +case "${host}" in + *-*-solaris2*) + AC_DEFINE_UNQUOTED(SUNOS, 1, [macro for libedit-2.6.7, current platform is solaris-2]) + ;; +esac + +LIBEDIT_LOBJECTS="" +AC_CHECK_FUNC(strunvis, ,[LIBEDIT_LOBJECTS="$LIBEDIT_LOBJECTS unvis.o"]) +AC_CHECK_FUNC(strvis, ,[LIBEDIT_LOBJECTS="$LIBEDIT_LOBJECTS vis.o"]) +AC_CHECK_FUNC(strlcpy, ,[LIBEDIT_LOBJECTS="$LIBEDIT_LOBJECTS strlcpy.o"]) +AC_CHECK_FUNC(strlcat, ,[LIBEDIT_LOBJECTS="$LIBEDIT_LOBJECTS strlcat.o"]) +AC_CHECK_FUNC(fgetln, ,[LIBEDIT_LOBJECTS="$LIBEDIT_LOBJECTS fgetln.o"]) +AC_SUBST(LIBEDIT_LOBJECTS) +enable_readline="yes" + # End of readline/libedit stuff ######################################################################### @@ -2339,10 +2355,10 @@ then readline_topdir="cmd-line-utils" readline_basedir="libedit" readline_dir="$readline_topdir/$readline_basedir" - readline_link="\$(top_builddir)/cmd-line-utils/libedit/liblibedit.a" + readline_link="\$(top_builddir)/cmd-line-utils/libedit/libedit.a" readline_h_ln_cmd="\$(LN) -s \$(top_builddir)/cmd-line-utils/libedit/readline readline" compile_libedit=yes - AC_DEFINE_UNQUOTED(HAVE_HIST_ENTRY) + AC_DEFINE_UNQUOTED(HAVE_HIST_ENTRY, 1) AC_DEFINE_UNQUOTED(USE_LIBEDIT_INTERFACE, 1) elif test "$with_readline" = "yes" then diff --git a/myisam/mi_key.c b/myisam/mi_key.c index 8f5f0e829ef..043dd7c6884 100644 --- a/myisam/mi_key.c +++ b/myisam/mi_key.c @@ -25,9 +25,12 @@ #define CHECK_KEYS -#define FIX_LENGTH if (length > char_length) \ - char_length= my_charpos(cs, pos, pos+length, char_length); \ - set_if_smaller(char_length,length); \ +#define FIX_LENGTH \ + do { \ + if (length > char_length) \ + char_length= my_charpos(cs, pos, pos+length, char_length); \ + set_if_smaller(char_length,length); \ + } while(0) static int _mi_put_key_in_record(MI_INFO *info,uint keynr,byte *record); @@ -157,7 +160,7 @@ uint _mi_make_key(register MI_INFO *info, uint keynr, uchar *key, FIX_LENGTH; memcpy((byte*) key, pos, char_length); if (length > char_length) - bfill(key+char_length, length-char_length, ' '); + cs->cset->fill(cs, key+char_length, length-char_length, ' '); key+= length; } _mi_dpointer(info,key,filepos); @@ -267,7 +270,7 @@ uint _mi_pack_key(register MI_INFO *info, uint keynr, uchar *key, uchar *old, FIX_LENGTH; memcpy((byte*) key, pos, char_length); if (length > char_length) - bfill(key+char_length, length-char_length, ' '); + cs->cset->fill(cs,key+char_length, length-char_length, ' '); key+= length; k_length-=length; } diff --git a/mysql-test/mysql-test-run.sh b/mysql-test/mysql-test-run.sh index 58d7af75284..454dc7b327b 100644 --- a/mysql-test/mysql-test-run.sh +++ b/mysql-test/mysql-test-run.sh @@ -367,10 +367,12 @@ while test $# -gt 0; do VALGRIND=`which valgrind` # this will print an error if not found # Give good warning to the user and stop if [ -z "$VALGRIND" ] ; then - $ECHO "You need to have the 'valgrind' program in your PATH to run mysql-test-run with option --valgrind. Valgrind's home page is http://developer.kde.org/~sewardj ." + $ECHO "You need to have the 'valgrind' program in your PATH to run mysql-test-run with option --valgrind. Valgrind's home page is http://valgrind.kde.org ." exit 1 fi - VALGRIND="$VALGRIND --tool=memcheck --alignment=8 --leak-check=yes --num-callers=16" + # >=2.1.2 requires the --tool option, some versions write to stdout, some to stderr + valgrind --help 2>&1 | grep "\-\-tool" > /dev/null && VALGRIND="$VALGRIND --tool=memcheck" + VALGRIND="$VALGRIND --alignment=8 --leak-check=yes --num-callers=16" EXTRA_MASTER_MYSQLD_OPT="$EXTRA_MASTER_MYSQLD_OPT --skip-safemalloc --skip-bdb" EXTRA_SLAVE_MYSQLD_OPT="$EXTRA_SLAVE_MYSQLD_OPT --skip-safemalloc --skip-bdb" SLEEP_TIME_AFTER_RESTART=10 diff --git a/mysql-test/ndb/ndb_config_2_node.ini b/mysql-test/ndb/ndb_config_2_node.ini index 03a94bf5a94..a395b300df4 100644 --- a/mysql-test/ndb/ndb_config_2_node.ini +++ b/mysql-test/ndb/ndb_config_2_node.ini @@ -1,28 +1,28 @@ -[DB DEFAULT] -NoOfReplicas: 2 -MaxNoOfConcurrentOperations: CHOOSE_MaxNoOfConcurrentOperations -DataMemory: CHOOSE_DataMemory -IndexMemory: CHOOSE_IndexMemory -Diskless: CHOOSE_Diskless -TimeBetweenWatchDogCheck: 30000 -FileSystemPath: CHOOSE_FILESYSTEM - -[DB] +[ndbd default] +NoOfReplicas= 2 +MaxNoOfConcurrentOperations= CHOOSE_MaxNoOfConcurrentOperations +DataMemory= CHOOSE_DataMemory +IndexMemory= CHOOSE_IndexMemory +Diskless= CHOOSE_Diskless +TimeBetweenWatchDogCheck= 30000 +FileSystemPath= CHOOSE_FILESYSTEM + +[ndbd] HostName: CHOOSE_HOSTNAME_1 -[DB] +[ndbd] HostName: CHOOSE_HOSTNAME_2 -[MGM] -PortNumber: CHOOSE_PORT_MGM +[ndb_mgmd] +PortNumber= CHOOSE_PORT_MGM -[API] +[mysqld] -[API] +[mysqld] -[API] +[mysqld] -[API] +[mysqld] -[TCP DEFAULT] -PortNumber: CHOOSE_PORT_TRANSPORTER +[tcp default] +PortNumber= CHOOSE_PORT_TRANSPORTER diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index ef5ec012078..38fc8e17d14 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -412,6 +412,36 @@ select c as c_a from t1 where c='б'; c_a б drop table t1; +create table t1 ( +c char(10) character set utf8, +unique key a (c(1)) +) engine=bdb; +insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); +insert into t1 values ('aa'); +ERROR 23000: Duplicate entry 'aa' for key 1 +insert into t1 values ('aaa'); +ERROR 23000: Duplicate entry 'aaa' for key 1 +insert into t1 values ('б'); +insert into t1 values ('бб'); +ERROR 23000: Duplicate entry 'бÐ' for key 1 +insert into t1 values ('ббб'); +ERROR 23000: Duplicate entry 'бÐ' for key 1 +select c as c_all from t1 order by c; +c_all +a +b +c +d +e +f +б +select c as c_a from t1 where c='a'; +c_a +a +select c as c_a from t1 where c='б'; +c_a +б +drop table t1; create table t1 (c varchar(30) character set utf8 collate utf8_bin, unique(c(10))); insert into t1 values ('1'),('2'),('3'),('x'),('y'),('z'); insert into t1 values ('aaaaaaaaaa'); @@ -541,6 +571,36 @@ c_a б drop table t1; create table t1 ( +c char(10) character set utf8 collate utf8_bin, +unique key a (c(1)) +) engine=bdb; +insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); +insert into t1 values ('aa'); +ERROR 23000: Duplicate entry 'aa' for key 1 +insert into t1 values ('aaa'); +ERROR 23000: Duplicate entry 'aaa' for key 1 +insert into t1 values ('б'); +insert into t1 values ('бб'); +ERROR 23000: Duplicate entry 'бÐ' for key 1 +insert into t1 values ('ббб'); +ERROR 23000: Duplicate entry 'бÐ' for key 1 +select c as c_all from t1 order by c; +c_all +a +b +c +d +e +f +б +select c as c_a from t1 where c='a'; +c_a +a +select c as c_a from t1 where c='б'; +c_a +б +drop table t1; +create table t1 ( str varchar(255) character set utf8 not null, key str (str(2)) ) engine=myisam; @@ -570,3 +630,13 @@ select * from t1 where str='str'; str str drop table t1; +create table t1 ( +str varchar(255) character set utf8 not null, +key str (str(2)) +) engine=bdb; +INSERT INTO t1 VALUES ('str'); +INSERT INTO t1 VALUES ('str2'); +select * from t1 where str='str'; +str +str +drop table t1; diff --git a/mysql-test/r/func_set.result b/mysql-test/r/func_set.result index 4918617f85f..2431406c128 100644 --- a/mysql-test/r/func_set.result +++ b/mysql-test/r/func_set.result @@ -41,8 +41,7 @@ interval(null, 1, 10, 100) -1 drop table if exists t1,t2; create table t1 (id int(10) not null unique); -create table t2 (id int(10) not null primary key, -val int(10) not null); +create table t2 (id int(10) not null primary key, val int(10) not null); insert into t1 values (1),(2),(4); insert into t2 values (1,1),(2,1),(3,1),(4,2); select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id; @@ -56,3 +55,12 @@ id elt(two.val,'one','two') 2 one 4 two drop table t1,t2; +select find_in_set(binary 'a',binary 'A,B,C'); +find_in_set(binary 'a',binary 'A,B,C') +0 +select find_in_set('a',binary 'A,B,C'); +find_in_set('a',binary 'A,B,C') +0 +select find_in_set(binary 'a', 'A,B,C'); +find_in_set(binary 'a', 'A,B,C') +0 diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index f2727c91628..e42485a1548 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -234,6 +234,1011 @@ select * from t4 where a = 7 and b = 17 order by a; a b c d select * from t4 where a = 7 and b != 16 order by b; a b c d +select x1.a, x1.b from t2 x1, t2 x2 where x1.b = x2.b order by x1.a; +a b +1 10 +3 12 +5 14 +7 16 +9 18 +11 20 +13 22 +15 24 +17 26 +19 28 +21 30 +23 32 +25 34 +27 36 +29 38 +31 40 +33 42 +35 44 +37 46 +39 48 +41 50 +43 52 +45 54 +47 56 +49 58 +51 60 +53 62 +55 64 +57 66 +59 68 +61 70 +63 72 +65 74 +67 76 +69 78 +71 80 +73 82 +75 84 +77 86 +79 88 +81 90 +83 92 +85 94 +87 96 +89 98 +91 100 +93 102 +95 104 +97 106 +99 108 +101 110 +103 112 +105 114 +107 116 +109 118 +111 120 +113 122 +115 124 +117 126 +119 128 +121 130 +123 132 +125 134 +127 136 +129 138 +131 140 +133 142 +135 144 +137 146 +139 148 +141 150 +143 152 +145 154 +147 156 +149 158 +151 160 +153 162 +155 164 +157 166 +159 168 +161 170 +163 172 +165 174 +167 176 +169 178 +171 180 +173 182 +175 184 +177 186 +179 188 +181 190 +183 192 +185 194 +187 196 +189 198 +191 200 +193 202 +195 204 +197 206 +199 208 +201 210 +203 212 +205 214 +207 216 +209 218 +211 220 +213 222 +215 224 +217 226 +219 228 +221 230 +223 232 +225 234 +227 236 +229 238 +231 240 +233 242 +235 244 +237 246 +239 248 +241 250 +243 252 +245 254 +247 256 +249 258 +251 260 +253 262 +255 264 +257 266 +259 268 +261 270 +263 272 +265 274 +267 276 +269 278 +271 280 +273 282 +275 284 +277 286 +279 288 +281 290 +283 292 +285 294 +287 296 +289 298 +291 300 +293 302 +295 304 +297 306 +299 308 +301 310 +303 312 +305 314 +307 316 +309 318 +311 320 +313 322 +315 324 +317 326 +319 328 +321 330 +323 332 +325 334 +327 336 +329 338 +331 340 +333 342 +335 344 +337 346 +339 348 +341 350 +343 352 +345 354 +347 356 +349 358 +351 360 +353 362 +355 364 +357 366 +359 368 +361 370 +363 372 +365 374 +367 376 +369 378 +371 380 +373 382 +375 384 +377 386 +379 388 +381 390 +383 392 +385 394 +387 396 +389 398 +391 400 +393 402 +395 404 +397 406 +399 408 +401 410 +403 412 +405 414 +407 416 +409 418 +411 420 +413 422 +415 424 +417 426 +419 428 +421 430 +423 432 +425 434 +427 436 +429 438 +431 440 +433 442 +435 444 +437 446 +439 448 +441 450 +443 452 +445 454 +447 456 +449 458 +451 460 +453 462 +455 464 +457 466 +459 468 +461 470 +463 472 +465 474 +467 476 +469 478 +471 480 +473 482 +475 484 +477 486 +479 488 +481 490 +483 492 +485 494 +487 496 +489 498 +491 500 +493 502 +495 504 +497 506 +499 508 +501 510 +503 512 +505 514 +507 516 +509 518 +511 520 +513 522 +515 524 +517 526 +519 528 +521 530 +523 532 +525 534 +527 536 +529 538 +531 540 +533 542 +535 544 +537 546 +539 548 +541 550 +543 552 +545 554 +547 556 +549 558 +551 560 +553 562 +555 564 +557 566 +559 568 +561 570 +563 572 +565 574 +567 576 +569 578 +571 580 +573 582 +575 584 +577 586 +579 588 +581 590 +583 592 +585 594 +587 596 +589 598 +591 600 +593 602 +595 604 +597 606 +599 608 +601 610 +603 612 +605 614 +607 616 +609 618 +611 620 +613 622 +615 624 +617 626 +619 628 +621 630 +623 632 +625 634 +627 636 +629 638 +631 640 +633 642 +635 644 +637 646 +639 648 +641 650 +643 652 +645 654 +647 656 +649 658 +651 660 +653 662 +655 664 +657 666 +659 668 +661 670 +663 672 +665 674 +667 676 +669 678 +671 680 +673 682 +675 684 +677 686 +679 688 +681 690 +683 692 +685 694 +687 696 +689 698 +691 700 +693 702 +695 704 +697 706 +699 708 +701 710 +703 712 +705 714 +707 716 +709 718 +711 720 +713 722 +715 724 +717 726 +719 728 +721 730 +723 732 +725 734 +727 736 +729 738 +731 740 +733 742 +735 744 +737 746 +739 748 +741 750 +743 752 +745 754 +747 756 +749 758 +751 760 +753 762 +755 764 +757 766 +759 768 +761 770 +763 772 +765 774 +767 776 +769 778 +771 780 +773 782 +775 784 +777 786 +779 788 +781 790 +783 792 +785 794 +787 796 +789 798 +791 800 +793 802 +795 804 +797 806 +799 808 +801 810 +803 812 +805 814 +807 816 +809 818 +811 820 +813 822 +815 824 +817 826 +819 828 +821 830 +823 832 +825 834 +827 836 +829 838 +831 840 +833 842 +835 844 +837 846 +839 848 +841 850 +843 852 +845 854 +847 856 +849 858 +851 860 +853 862 +855 864 +857 866 +859 868 +861 870 +863 872 +865 874 +867 876 +869 878 +871 880 +873 882 +875 884 +877 886 +879 888 +881 890 +883 892 +885 894 +887 896 +889 898 +891 900 +893 902 +895 904 +897 906 +899 908 +901 910 +903 912 +905 914 +907 916 +909 918 +911 920 +913 922 +915 924 +917 926 +919 928 +921 930 +923 932 +925 934 +927 936 +929 938 +931 940 +933 942 +935 944 +937 946 +939 948 +941 950 +943 952 +945 954 +947 956 +949 958 +951 960 +953 962 +955 964 +957 966 +959 968 +961 970 +963 972 +965 974 +967 976 +969 978 +971 980 +973 982 +975 984 +977 986 +979 988 +981 990 +983 992 +985 994 +987 996 +989 998 +991 1000 +993 1002 +995 1004 +997 1006 +999 1008 +select a, b FROM t2 outer_table where +a = (select a from t2 where b = outer_table.b ) order by a; +a b +1 10 +3 12 +5 14 +7 16 +9 18 +11 20 +13 22 +15 24 +17 26 +19 28 +21 30 +23 32 +25 34 +27 36 +29 38 +31 40 +33 42 +35 44 +37 46 +39 48 +41 50 +43 52 +45 54 +47 56 +49 58 +51 60 +53 62 +55 64 +57 66 +59 68 +61 70 +63 72 +65 74 +67 76 +69 78 +71 80 +73 82 +75 84 +77 86 +79 88 +81 90 +83 92 +85 94 +87 96 +89 98 +91 100 +93 102 +95 104 +97 106 +99 108 +101 110 +103 112 +105 114 +107 116 +109 118 +111 120 +113 122 +115 124 +117 126 +119 128 +121 130 +123 132 +125 134 +127 136 +129 138 +131 140 +133 142 +135 144 +137 146 +139 148 +141 150 +143 152 +145 154 +147 156 +149 158 +151 160 +153 162 +155 164 +157 166 +159 168 +161 170 +163 172 +165 174 +167 176 +169 178 +171 180 +173 182 +175 184 +177 186 +179 188 +181 190 +183 192 +185 194 +187 196 +189 198 +191 200 +193 202 +195 204 +197 206 +199 208 +201 210 +203 212 +205 214 +207 216 +209 218 +211 220 +213 222 +215 224 +217 226 +219 228 +221 230 +223 232 +225 234 +227 236 +229 238 +231 240 +233 242 +235 244 +237 246 +239 248 +241 250 +243 252 +245 254 +247 256 +249 258 +251 260 +253 262 +255 264 +257 266 +259 268 +261 270 +263 272 +265 274 +267 276 +269 278 +271 280 +273 282 +275 284 +277 286 +279 288 +281 290 +283 292 +285 294 +287 296 +289 298 +291 300 +293 302 +295 304 +297 306 +299 308 +301 310 +303 312 +305 314 +307 316 +309 318 +311 320 +313 322 +315 324 +317 326 +319 328 +321 330 +323 332 +325 334 +327 336 +329 338 +331 340 +333 342 +335 344 +337 346 +339 348 +341 350 +343 352 +345 354 +347 356 +349 358 +351 360 +353 362 +355 364 +357 366 +359 368 +361 370 +363 372 +365 374 +367 376 +369 378 +371 380 +373 382 +375 384 +377 386 +379 388 +381 390 +383 392 +385 394 +387 396 +389 398 +391 400 +393 402 +395 404 +397 406 +399 408 +401 410 +403 412 +405 414 +407 416 +409 418 +411 420 +413 422 +415 424 +417 426 +419 428 +421 430 +423 432 +425 434 +427 436 +429 438 +431 440 +433 442 +435 444 +437 446 +439 448 +441 450 +443 452 +445 454 +447 456 +449 458 +451 460 +453 462 +455 464 +457 466 +459 468 +461 470 +463 472 +465 474 +467 476 +469 478 +471 480 +473 482 +475 484 +477 486 +479 488 +481 490 +483 492 +485 494 +487 496 +489 498 +491 500 +493 502 +495 504 +497 506 +499 508 +501 510 +503 512 +505 514 +507 516 +509 518 +511 520 +513 522 +515 524 +517 526 +519 528 +521 530 +523 532 +525 534 +527 536 +529 538 +531 540 +533 542 +535 544 +537 546 +539 548 +541 550 +543 552 +545 554 +547 556 +549 558 +551 560 +553 562 +555 564 +557 566 +559 568 +561 570 +563 572 +565 574 +567 576 +569 578 +571 580 +573 582 +575 584 +577 586 +579 588 +581 590 +583 592 +585 594 +587 596 +589 598 +591 600 +593 602 +595 604 +597 606 +599 608 +601 610 +603 612 +605 614 +607 616 +609 618 +611 620 +613 622 +615 624 +617 626 +619 628 +621 630 +623 632 +625 634 +627 636 +629 638 +631 640 +633 642 +635 644 +637 646 +639 648 +641 650 +643 652 +645 654 +647 656 +649 658 +651 660 +653 662 +655 664 +657 666 +659 668 +661 670 +663 672 +665 674 +667 676 +669 678 +671 680 +673 682 +675 684 +677 686 +679 688 +681 690 +683 692 +685 694 +687 696 +689 698 +691 700 +693 702 +695 704 +697 706 +699 708 +701 710 +703 712 +705 714 +707 716 +709 718 +711 720 +713 722 +715 724 +717 726 +719 728 +721 730 +723 732 +725 734 +727 736 +729 738 +731 740 +733 742 +735 744 +737 746 +739 748 +741 750 +743 752 +745 754 +747 756 +749 758 +751 760 +753 762 +755 764 +757 766 +759 768 +761 770 +763 772 +765 774 +767 776 +769 778 +771 780 +773 782 +775 784 +777 786 +779 788 +781 790 +783 792 +785 794 +787 796 +789 798 +791 800 +793 802 +795 804 +797 806 +799 808 +801 810 +803 812 +805 814 +807 816 +809 818 +811 820 +813 822 +815 824 +817 826 +819 828 +821 830 +823 832 +825 834 +827 836 +829 838 +831 840 +833 842 +835 844 +837 846 +839 848 +841 850 +843 852 +845 854 +847 856 +849 858 +851 860 +853 862 +855 864 +857 866 +859 868 +861 870 +863 872 +865 874 +867 876 +869 878 +871 880 +873 882 +875 884 +877 886 +879 888 +881 890 +883 892 +885 894 +887 896 +889 898 +891 900 +893 902 +895 904 +897 906 +899 908 +901 910 +903 912 +905 914 +907 916 +909 918 +911 920 +913 922 +915 924 +917 926 +919 928 +921 930 +923 932 +925 934 +927 936 +929 938 +931 940 +933 942 +935 944 +937 946 +939 948 +941 950 +943 952 +945 954 +947 956 +949 958 +951 960 +953 962 +955 964 +957 966 +959 968 +961 970 +963 972 +965 974 +967 976 +969 978 +971 980 +973 982 +975 984 +977 986 +979 988 +981 990 +983 992 +985 994 +987 996 +989 998 +991 1000 +993 1002 +995 1004 +997 1006 +999 1008 delete from t2; delete from t3; delete from t4; diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index 0523143f91d..98095930669 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -226,3 +226,18 @@ a b execute stmt1; a b deallocate prepare stmt1; +drop table t1; +prepare stmt1 from "select 1 into @var"; +execute stmt1; +execute stmt1; +prepare stmt1 from "create table t1 select 1 as i"; +execute stmt1; +drop table t1; +execute stmt1; +prepare stmt1 from "insert into t1 select i from t1"; +execute stmt1; +execute stmt1; +prepare stmt1 from "select * from t1 into outfile 'f1.txt'"; +execute stmt1; +deallocate prepare stmt1; +drop table t1; diff --git a/mysql-test/r/truncate.result b/mysql-test/r/truncate.result index d777bd184b2..74a6cb72cc6 100644 --- a/mysql-test/r/truncate.result +++ b/mysql-test/r/truncate.result @@ -31,4 +31,25 @@ SELECT * from t1; a 1 2 +delete from t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +a +3 +4 +drop table t1; +create temporary table t1 (a integer auto_increment primary key); +insert into t1 (a) values (NULL),(NULL); +truncate table t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +a +1 +2 +delete from t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +a +3 +4 drop table t1; diff --git a/mysql-test/r/variables.result b/mysql-test/r/variables.result index 41ea95cf933..5d3f32cdd55 100644 --- a/mysql-test/r/variables.result +++ b/mysql-test/r/variables.result @@ -436,3 +436,19 @@ SELECT @@global.session.key_buffer_size; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key_buffer_size' at line 1 SELECT @@global.local.key_buffer_size; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'key_buffer_size' at line 1 +set @tstlw = @@log_warnings; +show global variables like 'log_warnings'; +Variable_name Value +log_warnings 1 +set global log_warnings = 0; +show global variables like 'log_warnings'; +Variable_name Value +log_warnings 0 +set global log_warnings = 42; +show global variables like 'log_warnings'; +Variable_name Value +log_warnings 42 +set global log_warnings = @tstlw; +show global variables like 'log_warnings'; +Variable_name Value +log_warnings 1 diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test index 83055d05830..4624f2ec78c 100644 --- a/mysql-test/t/ctype_utf8.test +++ b/mysql-test/t/ctype_utf8.test @@ -294,6 +294,30 @@ select c as c_a from t1 where c='a'; select c as c_a from t1 where c='б'; drop table t1; +# +# Bug 4531: unique key prefix interacts poorly with utf8 +# Check BDB, case insensitive collation +# +--disable_warnings +create table t1 ( +c char(10) character set utf8, +unique key a (c(1)) +) engine=bdb; +--enable_warnings +insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); +--error 1062 +insert into t1 values ('aa'); +--error 1062 +insert into t1 values ('aaa'); +insert into t1 values ('б'); +--error 1062 +insert into t1 values ('бб'); +--error 1062 +insert into t1 values ('ббб'); +select c as c_all from t1 order by c; +select c as c_a from t1 where c='a'; +select c as c_a from t1 where c='б'; +drop table t1; # # Bug 4521: unique key prefix interacts poorly with utf8 @@ -393,6 +417,31 @@ select c as c_a from t1 where c='a'; select c as c_a from t1 where c='б'; drop table t1; +# +# Bug 4531: unique key prefix interacts poorly with utf8 +# Check BDB, binary collation +# +--disable_warnings +create table t1 ( +c char(10) character set utf8 collate utf8_bin, +unique key a (c(1)) +) engine=bdb; +--enable_warnings +insert into t1 values ('a'),('b'),('c'),('d'),('e'),('f'); +--error 1062 +insert into t1 values ('aa'); +--error 1062 +insert into t1 values ('aaa'); +insert into t1 values ('б'); +--error 1062 +insert into t1 values ('бб'); +--error 1062 +insert into t1 values ('ббб'); +select c as c_all from t1 order by c; +select c as c_a from t1 where c='a'; +select c as c_a from t1 where c='б'; +drop table t1; + # Bug#4594: column index make = failed for gbk, but like works # Check MYISAM @@ -429,3 +478,18 @@ INSERT INTO t1 VALUES ('str'); INSERT INTO t1 VALUES ('str2'); select * from t1 where str='str'; drop table t1; + +# the same for BDB +# + +--disable_warnings +create table t1 ( + str varchar(255) character set utf8 not null, + key str (str(2)) +) engine=bdb; +--enable_warnings +INSERT INTO t1 VALUES ('str'); +INSERT INTO t1 VALUES ('str2'); +select * from t1 where str='str'; +drop table t1; + diff --git a/mysql-test/t/func_set.test b/mysql-test/t/func_set.test index 03843fd3da5..d669739bcb4 100644 --- a/mysql-test/t/func_set.test +++ b/mysql-test/t/func_set.test @@ -31,11 +31,19 @@ drop table if exists t1,t2; --enable_warnings create table t1 (id int(10) not null unique); -create table t2 (id int(10) not null primary key, -val int(10) not null); +create table t2 (id int(10) not null primary key, val int(10) not null); insert into t1 values (1),(2),(4); insert into t2 values (1,1),(2,1),(3,1),(4,2); select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id; select one.id, elt(two.val,'one','two') from t1 one, t2 two where two.id=one.id order by one.id; drop table t1,t2; + +# +# Bug4340: find_in_set is case insensitive even on binary operators +# + +select find_in_set(binary 'a',binary 'A,B,C'); +select find_in_set('a',binary 'A,B,C'); +select find_in_set(binary 'a', 'A,B,C'); + diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index ea2a70e1837..a24891ab814 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -206,6 +206,10 @@ select * from t4 where a = 7 and b = 16 order by a; select * from t4 where a = 7 and b = 17 order by a; select * from t4 where a = 7 and b != 16 order by b; +select x1.a, x1.b from t2 x1, t2 x2 where x1.b = x2.b order by x1.a; +select a, b FROM t2 outer_table where +a = (select a from t2 where b = outer_table.b ) order by a; + # # update records # diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 9d23c795e05..8b9704f2a06 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -209,7 +209,7 @@ drop table t1; # # Bug#4912 "mysqld crashs in case a statement is executed a second time": -# negation elimination should and prepared statemens +# negation elimination should work once and not break prepared statements # create table t1(a varchar(2), b varchar(3)); @@ -217,4 +217,26 @@ prepare stmt1 from "select a, b from t1 where (not (a='aa' and b < 'zzz'))"; execute stmt1; execute stmt1; deallocate prepare stmt1; +drop table t1; + +# +# Bug#5034 "prepared "select 1 into @arg15", second execute crashes +# server". +# Check that descendands of select_result can be reused in prepared +# statements or are correctly created and deleted on each execute +# +prepare stmt1 from "select 1 into @var"; +execute stmt1; +execute stmt1; +prepare stmt1 from "create table t1 select 1 as i"; +execute stmt1; +drop table t1; +execute stmt1; +prepare stmt1 from "insert into t1 select i from t1"; +execute stmt1; +execute stmt1; +prepare stmt1 from "select * from t1 into outfile 'f1.txt'"; +execute stmt1; +deallocate prepare stmt1; +drop table t1; diff --git a/mysql-test/t/truncate.test b/mysql-test/t/truncate.test index 434a1907e42..b7ec506ecf1 100644 --- a/mysql-test/t/truncate.test +++ b/mysql-test/t/truncate.test @@ -26,7 +26,7 @@ drop table t1; truncate non_existing_table; # -# test autoincrement with TRUNCATE +# test autoincrement with TRUNCATE; verifying difference with DELETE # create table t1 (a integer auto_increment primary key); @@ -34,5 +34,19 @@ insert into t1 (a) values (NULL),(NULL); truncate table t1; insert into t1 (a) values (NULL),(NULL); SELECT * from t1; +delete from t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; drop table t1; +# Verifying that temp tables are handled the same way + +create temporary table t1 (a integer auto_increment primary key); +insert into t1 (a) values (NULL),(NULL); +truncate table t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +delete from t1; +insert into t1 (a) values (NULL),(NULL); +SELECT * from t1; +drop table t1; diff --git a/mysql-test/t/variables.test b/mysql-test/t/variables.test index 60ebeb045f5..a480ecb570a 100644 --- a/mysql-test/t/variables.test +++ b/mysql-test/t/variables.test @@ -324,3 +324,14 @@ SELECT @@global.global.key_buffer_size; SELECT @@global.session.key_buffer_size; --error 1064 SELECT @@global.local.key_buffer_size; + +# BUG#5135: cannot turn on log_warnings with SET in 4.1 (and 4.0) +set @tstlw = @@log_warnings; +show global variables like 'log_warnings'; +set global log_warnings = 0; +show global variables like 'log_warnings'; +set global log_warnings = 42; +show global variables like 'log_warnings'; +set global log_warnings = @tstlw; +show global variables like 'log_warnings'; + diff --git a/ndb/include/util/Properties.hpp b/ndb/include/util/Properties.hpp index 2c30f7f7e3c..df8e2887001 100644 --- a/ndb/include/util/Properties.hpp +++ b/ndb/include/util/Properties.hpp @@ -55,7 +55,7 @@ public: static const char delimiter = ':'; static const char version[]; - Properties(); + Properties(bool case_insensitive= false); Properties(const Properties &); Properties(const Property *, int len); virtual ~Properties(); diff --git a/ndb/src/common/mgmcommon/ConfigInfo.cpp b/ndb/src/common/mgmcommon/ConfigInfo.cpp index a9a8441abfb..0f0d6568383 100644 --- a/ndb/src/common/mgmcommon/ConfigInfo.cpp +++ b/ndb/src/common/mgmcommon/ConfigInfo.cpp @@ -30,6 +30,15 @@ /**************************************************************************** * Section names ****************************************************************************/ + +const ConfigInfo::AliasPair +ConfigInfo::m_sectionNameAliases[]={ + {"API", "MYSQLD"}, + {"DB", "NDBD"}, + {"MGM", "NDB_MGMD"}, + {0, 0} +}; + const char* ConfigInfo::m_sectionNames[]={ "SYSTEM", @@ -1854,14 +1863,13 @@ const int ConfigInfo::m_NoOfParams = sizeof(m_ParamInfo) / sizeof(ParamInfo); ****************************************************************************/ static void require(bool v) { if(!v) abort();} -ConfigInfo::ConfigInfo() { +ConfigInfo::ConfigInfo() + : m_info(true), m_systemDefaults(true) +{ int i; Properties *section; const Properties *oldpinfo; - m_info.setCaseInsensitiveNames(true); - m_systemDefaults.setCaseInsensitiveNames(true); - { Uint64 tmp_uint64; require(InitConfigFileParser::convertStringToUint64(RNIL_STRING, tmp_uint64)); @@ -1879,8 +1887,7 @@ ConfigInfo::ConfigInfo() { // Create new section if it did not exist if (!m_info.getCopy(param._section, §ion)) { - Properties newsection; - newsection.setCaseInsensitiveNames(true); + Properties newsection(true); m_info.put(param._section, &newsection); } @@ -1888,7 +1895,7 @@ ConfigInfo::ConfigInfo() { m_info.getCopy(param._section, §ion); // Create pinfo (parameter info) entry - Properties pinfo; + Properties pinfo(true); pinfo.put("Id", param._paramId); pinfo.put("Fname", param._fname); pinfo.put("Description", param._description); @@ -1944,8 +1951,7 @@ ConfigInfo::ConfigInfo() { if(param._type != ConfigInfo::SECTION){ Properties * p; if(!m_systemDefaults.getCopy(param._section, &p)){ - p = new Properties(); - p->setCaseInsensitiveNames(true); + p = new Properties(true); } if(param._default != UNDEFINED && param._default != MANDATORY){ @@ -2013,7 +2019,8 @@ const Properties * ConfigInfo::getInfo(const char * section) const { const Properties * p; if(!m_info.get(section, &p)){ - warning("getInfo", section); + return 0; + // warning("getInfo", section); } return p; } @@ -2022,7 +2029,8 @@ const Properties * ConfigInfo::getDefaults(const char * section) const { const Properties * p; if(!m_systemDefaults.get(section, &p)){ - warning("getDefaults", section); + return 0; + //warning("getDefaults", section); } return p; } @@ -2093,6 +2101,14 @@ ConfigInfo::isSection(const char * section) const { return false; } +const char* +ConfigInfo::getAlias(const char * section) const { + for (int i = 0; m_sectionNameAliases[i].name != 0; i++) + if(!strcasecmp(section, m_sectionNameAliases[i].alias)) + return m_sectionNameAliases[i].name; + return 0; +} + bool ConfigInfo::verify(const Properties * section, const char* fname, Uint64 value) const { @@ -2848,7 +2864,7 @@ fixDepricated(InitConfigFileParser::Context & ctx, const char * data){ * Transform old values to new values * Transform new values to old values (backward compatible) */ - Properties tmp; + Properties tmp(true); Properties::Iterator it(ctx.m_currentSection); for (name = it.first(); name != NULL; name = it.next()) { const DepricationTransform * p = &f_deprication[0]; @@ -2980,8 +2996,8 @@ add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, { Uint32 i; Properties * props= ctx.m_config; - Properties p_connections; - Properties p_connections2; + Properties p_connections(true); + Properties p_connections2(true); for (i = 0;; i++){ const Properties * tmp; @@ -3001,8 +3017,8 @@ add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, Uint32 nNodes; ctx.m_userProperties.get("NoOfNodes", &nNodes); - Properties p_db_nodes; - Properties p_api_mgm_nodes; + Properties p_db_nodes(true); + Properties p_api_mgm_nodes(true); Uint32 i_db= 0, i_api_mgm= 0, n; for (i= 0, n= 0; n < nNodes; i++){ @@ -3028,7 +3044,7 @@ add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, if(!p_connections2.get("", nodeId1+nodeId2<<16, &dummy)) { ConfigInfo::ConfigRuleSection s; s.m_sectionType= BaseString("TCP"); - s.m_sectionData= new Properties; + s.m_sectionData= new Properties(true); char buf[16]; snprintf(buf, sizeof(buf), "%u", nodeId1); s.m_sectionData->put("NodeId1", buf); @@ -3045,7 +3061,7 @@ add_node_connections(Vector<ConfigInfo::ConfigRuleSection>§ions, if(!p_db_nodes.get("", j, &nodeId2)) break; ConfigInfo::ConfigRuleSection s; s.m_sectionType= BaseString("TCP"); - s.m_sectionData= new Properties; + s.m_sectionData= new Properties(true); char buf[16]; snprintf(buf, sizeof(buf), "%u", nodeId1); s.m_sectionData->put("NodeId1", buf); @@ -3066,7 +3082,7 @@ static bool add_server_ports(Vector<ConfigInfo::ConfigRuleSection>§ions, { #if 0 Properties * props= ctx.m_config; - Properties computers; + Properties computers(true); Uint32 port_base = NDB_BASE_PORT+2; Uint32 nNodes; diff --git a/ndb/src/common/mgmcommon/ConfigInfo.hpp b/ndb/src/common/mgmcommon/ConfigInfo.hpp index 250426e0cec..50190082e3f 100644 --- a/ndb/src/common/mgmcommon/ConfigInfo.hpp +++ b/ndb/src/common/mgmcommon/ConfigInfo.hpp @@ -61,6 +61,11 @@ public: const char* _max; }; + struct AliasPair{ + const char * name; + const char * alias; + }; + /** * Entry for one section rule */ @@ -100,6 +105,7 @@ public: * @note Result is not defined if section/name are wrong! */ bool verify(const Properties* secti, const char* fname, Uint64 value) const; + const char* getAlias(const char*) const; bool isSection(const char*) const; const char* getDescription(const Properties * sec, const char* fname) const; @@ -123,6 +129,7 @@ private: static const ParamInfo m_ParamInfo[]; static const int m_NoOfParams; + static const AliasPair m_sectionNameAliases[]; static const char* m_sectionNames[]; static const int m_noOfSectionNames; diff --git a/ndb/src/common/mgmcommon/InitConfigFileParser.cpp b/ndb/src/common/mgmcommon/InitConfigFileParser.cpp index 3dfb910b4a3..833a2efab9d 100644 --- a/ndb/src/common/mgmcommon/InitConfigFileParser.cpp +++ b/ndb/src/common/mgmcommon/InitConfigFileParser.cpp @@ -42,10 +42,10 @@ InitConfigFileParser::~InitConfigFileParser() { // Read Config File //**************************************************************************** InitConfigFileParser::Context::Context(const ConfigInfo * info) - : m_configValues(1000, 20) { + : m_configValues(1000, 20), m_userProperties(true) { - m_config = new Properties(); - m_defaults = new Properties(); + m_config = new Properties(true); + m_defaults = new Properties(true); } InitConfigFileParser::Context::~Context(){ @@ -113,10 +113,10 @@ InitConfigFileParser::parseConfig(FILE * file) { snprintf(ctx.fname, sizeof(ctx.fname), section); free(section); ctx.type = InitConfigFileParser::DefaultSection; ctx.m_sectionLineno = ctx.m_lineno; - ctx.m_currentSection = new Properties(); + ctx.m_currentSection = new Properties(true); ctx.m_userDefaults = NULL; - ctx.m_currentInfo = m_info->getInfo(ctx.fname); - ctx.m_systemDefaults = m_info->getDefaults(ctx.fname); + require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0); + require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0); continue; } @@ -134,10 +134,10 @@ InitConfigFileParser::parseConfig(FILE * file) { free(section); ctx.type = InitConfigFileParser::Section; ctx.m_sectionLineno = ctx.m_lineno; - ctx.m_currentSection = new Properties(); + ctx.m_currentSection = new Properties(true); ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults); - ctx.m_currentInfo = m_info->getInfo(ctx.fname); - ctx.m_systemDefaults = m_info->getDefaults(ctx.fname); + require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0); + require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0); continue; } @@ -176,8 +176,8 @@ InitConfigFileParser::parseConfig(FILE * file) { ctx.type = InitConfigFileParser::Section; ctx.m_currentSection = tmp[j].m_sectionData; ctx.m_userDefaults = getSection(ctx.fname, ctx.m_defaults); - ctx.m_currentInfo = m_info->getInfo(ctx.fname); - ctx.m_systemDefaults = m_info->getDefaults(ctx.fname); + require((ctx.m_currentInfo = m_info->getInfo(ctx.fname)) != 0); + require((ctx.m_systemDefaults = m_info->getDefaults(ctx.fname)) != 0); if(!storeSection(ctx)) return 0; } @@ -218,6 +218,8 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) { char tmpLine[MAX_LINE_LENGTH]; char fname[MAX_LINE_LENGTH], rest[MAX_LINE_LENGTH]; char* t; + const char *separator_list[]= {":", "=", 0}; + const char *separator= 0; if (ctx.m_currentSection == NULL){ ctx.reportError("Value specified outside section"); @@ -229,7 +231,14 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) { // ************************************* // Check if a separator exists in line // ************************************* - if (!strchr(tmpLine, ':')) { + for(int i= 0; separator_list[i] != 0; i++) { + if(strchr(tmpLine, separator_list[i][0])) { + separator= separator_list[i]; + break; + } + } + + if (separator == 0) { ctx.reportError("Parse error"); return false; } @@ -237,13 +246,13 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) { // ******************************************* // Get pointer to substring before separator // ******************************************* - t = strtok(tmpLine, ":"); + t = strtok(tmpLine, separator); // ***************************************** // Count number of tokens before separator // ***************************************** if (sscanf(t, "%120s%120s", fname, rest) != 1) { - ctx.reportError("Multiple names before \':\'"); + ctx.reportError("Multiple names before \'%c\'", separator[0]); return false; } if (!ctx.m_currentInfo->contains(fname)) { @@ -471,8 +480,24 @@ InitConfigFileParser::parseSectionHeader(const char* line) const { tmp[0] = ' '; trim(tmp); + // Convert section header to upper + for(int i= strlen(tmp)-1; i >= 0; i--) + tmp[i]= toupper(tmp[i]); + + // Get the correct header name if an alias + { + const char *tmp_alias= m_info->getAlias(tmp); + if (tmp_alias) { + free(tmp); + tmp= strdup(tmp_alias); + } + } + // Lookup token among sections - if(!m_info->isSection(tmp)) return NULL; + if(!m_info->isSection(tmp)) { + free(tmp); + return NULL; + } if(m_info->getInfo(tmp)) return tmp; free(tmp); @@ -487,16 +512,20 @@ char* InitConfigFileParser::parseDefaultSectionHeader(const char* line) const { static char token1[MAX_LINE_LENGTH], token2[MAX_LINE_LENGTH]; - int no = sscanf(line, "[%120[A-Za-z] %120[A-Za-z]]", token1, token2); + int no = sscanf(line, "[%120[A-Z_a-z] %120[A-Z_a-z]]", token1, token2); // Not correct no of tokens if (no != 2) return NULL; // Not correct keyword at end - if (!strcmp(token2, "DEFAULT") == 0) return NULL; + if (!strcasecmp(token2, "DEFAULT") == 0) return NULL; + + const char *token1_alias= m_info->getAlias(token1); + if (token1_alias == 0) + token1_alias= token1; - if(m_info->getInfo(token1)){ - return strdup(token1); + if(m_info->getInfo(token1_alias)){ + return strdup(token1_alias); } // Did not find section diff --git a/ndb/src/common/util/Properties.cpp b/ndb/src/common/util/Properties.cpp index 8db7b075d1b..80fb0027830 100644 --- a/ndb/src/common/util/Properties.cpp +++ b/ndb/src/common/util/Properties.cpp @@ -56,7 +56,7 @@ class PropertiesImpl { PropertiesImpl(const PropertiesImpl &); // Not implemented PropertiesImpl& operator=(const PropertiesImpl&); // Not implemented public: - PropertiesImpl(Properties *); + PropertiesImpl(Properties *, bool case_insensitive); PropertiesImpl(Properties *, const PropertiesImpl &); ~PropertiesImpl(); @@ -69,6 +69,7 @@ public: bool m_insensitive; int (* compare)(const char *s1, const char *s2); + void setCaseInsensitiveNames(bool value); void grow(int sizeToAdd); PropertyImpl * get(const char * name) const; @@ -113,9 +114,9 @@ Property::~Property(){ /** * Methods for Properties */ -Properties::Properties(){ +Properties::Properties(bool case_insensitive){ parent = 0; - impl = new PropertiesImpl(this); + impl = new PropertiesImpl(this, case_insensitive); } Properties::Properties(const Properties & org){ @@ -124,7 +125,7 @@ Properties::Properties(const Properties & org){ } Properties::Properties(const Property * anArray, int arrayLen){ - impl = new PropertiesImpl(this); + impl = new PropertiesImpl(this, false); put(anArray, arrayLen); } @@ -479,13 +480,12 @@ Properties::unpack(const Uint32 * buf, Uint32 bufLen){ /** * Methods for PropertiesImpl */ -PropertiesImpl::PropertiesImpl(Properties * p){ +PropertiesImpl::PropertiesImpl(Properties * p, bool case_insensitive){ this->properties = p; items = 0; size = 25; content = new PropertyImpl * [size]; - this->m_insensitive = false; - this->compare = strcmp; + setCaseInsensitiveNames(case_insensitive); } PropertiesImpl::PropertiesImpl(Properties * p, const PropertiesImpl & org){ @@ -506,6 +506,15 @@ PropertiesImpl::~PropertiesImpl(){ delete [] content; } +void +PropertiesImpl::setCaseInsensitiveNames(bool value){ + m_insensitive = value; + if(value) + compare = strcasecmp; + else + compare = strcmp; +} + void PropertiesImpl::grow(int sizeToAdd){ PropertyImpl ** newContent = new PropertyImpl * [size + sizeToAdd]; @@ -523,9 +532,11 @@ PropertiesImpl::get(const char * name) const { return 0; } - for(unsigned int i = 0; i<tmp->items; i++) + for(unsigned int i = 0; i<tmp->items; i++) { if((* compare)(tmp->content[i]->name, short_name) == 0) return tmp->content[i]; + } + return 0; } @@ -1110,11 +1121,7 @@ Properties::getCopy(const char * name, Uint32 no, Properties ** value) const { void Properties::setCaseInsensitiveNames(bool value){ - impl->m_insensitive = value; - if(value) - impl->compare = strcasecmp; - else - impl->compare = strcmp; + impl->setCaseInsensitiveNames(value); } bool diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index 141a0be0eff..c90ed1822f1 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -682,12 +682,12 @@ CommandInterpreter::executeShow(char* parameters) } ndbout << ndb_nodes - << " NDB Node(s)" + << " [ndbd] node(s)" << endl; for(i=0; i < state->no_of_nodes; i++) { if(state->node_states[i].node_type == NDB_MGM_NODE_TYPE_NDB) { - ndbout << "DB node:\t" << state->node_states[i].node_id; + ndbout << "[ndbd]\t\tid=" << state->node_states[i].node_id; if(state->node_states[i].version != 0) { ndbout << " (Version: " << getMajor(state->node_states[i].version) << "." @@ -707,12 +707,12 @@ CommandInterpreter::executeShow(char* parameters) ndbout << endl; ndbout << mgm_nodes - << " MGM Node(s)" + << " [ndb_mgmd] node(s)" << endl; for(i=0; i < state->no_of_nodes; i++) { if(state->node_states[i].node_type == NDB_MGM_NODE_TYPE_MGM) { - ndbout << "MGM node:\t" << state->node_states[i].node_id; + ndbout << "[ndb_mgmd]\tid=" << state->node_states[i].node_id; if(state->node_states[i].version != 0) { ndbout << " (Version: " << getMajor(state->node_states[i].version) << "." @@ -728,12 +728,12 @@ CommandInterpreter::executeShow(char* parameters) ndbout << endl; ndbout << api_nodes - << " API Node(s)" + << " [mysqld] node(s)" << endl; for(i=0; i < state->no_of_nodes; i++) { if(state->node_states[i].node_type == NDB_MGM_NODE_TYPE_API) { - ndbout << "API node:\t" << state->node_states[i].node_id; + ndbout << "[mysqld]\tid=" << state->node_states[i].node_id; if(state->node_states[i].version != 0) { ndbout << " (Version: " << getMajor(state->node_states[i].version) << "." diff --git a/sql/field.cc b/sql/field.cc index 96f4fa8fd86..bbb91fc534d 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4382,7 +4382,7 @@ void Field_string::sql_type(String &res) const (field_length > 3 && (table->db_options_in_use & HA_OPTION_PACK_RECORD) ? - (has_charset() ? "varchar" : "varbinary") : + (has_charset() ? "varchar" : "varbinary") : (has_charset() ? "char" : "binary")), (int) field_length / charset()->mbmaxlen); res.length(length); @@ -4401,6 +4401,22 @@ char *Field_string::pack(char *to, const char *from, uint max_length) } +char *Field_string::pack_key(char *to, const char *from, uint max_length) +{ + int length=min(field_length,max_length); + uint char_length= (field_charset->mbmaxlen > 1) ? + max_length/field_charset->mbmaxlen : max_length; + if (length > char_length) + char_length= my_charpos(field_charset, from, from+length, char_length); + set_if_smaller(length, char_length); + while (length && from[length-1] == ' ') + length--; + *to= (uchar)length; + memcpy(to+1, from, length); + return to+1+length; +} + + const char *Field_string::unpack(char *to, const char *from) { uint length= (uint) (uchar) *from++; @@ -4564,6 +4580,24 @@ char *Field_varstring::pack(char *to, const char *from, uint max_length) } +char *Field_varstring::pack_key(char *to, const char *from, uint max_length) +{ + uint length=uint2korr(from); + uint char_length= (field_charset->mbmaxlen > 1) ? + max_length/field_charset->mbmaxlen : max_length; + from+=HA_KEY_BLOB_LENGTH; + if (length > char_length) + char_length= my_charpos(field_charset, from, from+length, char_length); + set_if_smaller(length, char_length); + *to++= (char) (length & 255); + if (max_length > 255) + *to++= (char) (length >> 8); + if (length) + memcpy(to, from, length); + return to+length; +} + + const char *Field_varstring::unpack(char *to, const char *from) { uint length; @@ -5139,16 +5173,17 @@ char *Field_blob::pack_key(char *to, const char *from, uint max_length) char *save=ptr; ptr=(char*) from; uint32 length=get_length(); // Length of from string - if (length > max_length) - length=max_length; + uint char_length= (field_charset->mbmaxlen > 1) ? + max_length/field_charset->mbmaxlen : max_length; + if (length) + get_ptr((char**) &from); + if (length > char_length) + char_length= my_charpos(field_charset, from, from+length, char_length); + set_if_smaller(length, char_length); *to++= (uchar) length; if (max_length > 255) // 2 byte length *to++= (uchar) (length >> 8); - if (length) - { - get_ptr((char**) &from); - memcpy(to, from, length); - } + memcpy(to, from, length); ptr=save; // Restore org row pointer return to+length; } diff --git a/sql/field.h b/sql/field.h index 843961e64c3..eaf90ddc0ff 100644 --- a/sql/field.h +++ b/sql/field.h @@ -917,6 +917,7 @@ public: void sort_string(char *buff,uint length); void sql_type(String &str) const; char *pack(char *to, const char *from, uint max_length=~(uint) 0); + char *pack_key(char *to, const char *from, uint max_length); const char *unpack(char* to, const char *from); int pack_cmp(const char *a,const char *b,uint key_length); int pack_cmp(const char *b,uint key_length); @@ -965,6 +966,7 @@ public: void set_key_image(char *buff,uint length, CHARSET_INFO *cs); void sql_type(String &str) const; char *pack(char *to, const char *from, uint max_length=~(uint) 0); + char *pack_key(char *to, const char *from, uint max_length); const char *unpack(char* to, const char *from); int pack_cmp(const char *a, const char *b, uint key_length); int pack_cmp(const char *b, uint key_length); diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index 1a11f0d3073..80b8c21fa0c 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -2013,10 +2013,12 @@ int ha_ndbcluster::rnd_init(bool scan) DBUG_ENTER("rnd_init"); DBUG_PRINT("enter", ("scan: %d", scan)); // Check if scan is to be restarted - if (cursor && scan) + if (cursor) + { + if (!scan) + DBUG_RETURN(1); cursor->restart(); - else - DBUG_RETURN(1); + } index_init(table->primary_key); DBUG_RETURN(0); } diff --git a/sql/item_func.cc b/sql/item_func.cc index c90a70a6bb6..adcba34d56b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1435,30 +1435,43 @@ longlong Item_func_find_in_set::val_int() int diff; if ((diff=buffer->length() - find->length()) >= 0) { - const char *f_pos=find->ptr(); - const char *f_end=f_pos+find->length(); - const char *str=buffer->ptr(); - const char *end=str+diff+1; - const char *real_end=str+buffer->length(); - uint position=1; - do + my_wc_t wc; + CHARSET_INFO *cs= cmp_collation.collation; + const char *str_begin= buffer->ptr(); + const char *str_end= buffer->ptr(); + const char *real_end= str_end+buffer->length(); + const uchar *find_str= (const uchar *) find->ptr(); + uint find_str_len= find->length(); + int position= 0; + while (1) { - const char *pos= f_pos; - while (pos != f_end) + int symbol_len; + if ((symbol_len= cs->cset->mb_wc(cs, &wc, (uchar*) str_end, + (uchar*) real_end)) > 0) { - if (my_toupper(cmp_collation.collation,*str) != - my_toupper(cmp_collation.collation,*pos)) - goto not_found; - str++; - pos++; + const char *substr_end= str_end + symbol_len; + bool is_last_item= (substr_end == real_end); + if (wc == (my_wc_t) separator || is_last_item) + { + position++; + if (is_last_item) + str_end= substr_end; + if (!my_strnncoll(cs, (const uchar *) str_begin, + str_end - str_begin, + find_str, find_str_len)) + return (longlong) position; + else + str_begin= substr_end; + } + str_end= substr_end; } - if (str == real_end || str[0] == separator) - return (longlong) position; - not_found: - while (str < end && str[0] != separator) - str++; - position++; - } while (++str <= end); + else if (str_end - str_begin == 0 && + find_str_len == 0 && + wc == (my_wc_t) separator) + return (longlong) ++position; + else + return (longlong) 0; + } } return 0; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9b40768f0da..4ef41e62f32 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4241,7 +4241,7 @@ Disable with --skip-isam.", OPT_ARG, 0, 0, 0, 0, 0, 0}, {"log-warnings", 'W', "Log some non-critical warnings to the error log file. Use this option twice or --log-warnings=2 if you also want 'Aborted connections' warnings.", (gptr*) &global_system_variables.log_warnings, - (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, + (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, ~0L, 0, 0, 0}, {"low-priority-updates", OPT_LOW_PRIORITY_UPDATES, "INSERT/DELETE/UPDATE has lower priority than selects.", @@ -4551,7 +4551,7 @@ replicating a LOAD DATA INFILE command.", NO_ARG, 0, 0, 0, 0, 0, 0}, {"warnings", 'W', "Deprecated; use --log-warnings instead.", (gptr*) &global_system_variables.log_warnings, - (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, 0, + (gptr*) &max_system_variables.log_warnings, 0, GET_ULONG, OPT_ARG, 1, 0, ~0L, 0, 0, 0}, { "back_log", OPT_BACK_LOG, "The number of outstanding connection requests MySQL can have. This comes into play when the main MySQL thread gets very many connection requests in a very short time.", diff --git a/sql/sql_class.cc b/sql/sql_class.cc index aecb2ef6522..26e2cebb909 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -708,6 +708,12 @@ void select_result::send_error(uint errcode,const char *err) ::send_error(thd, errcode, err); } + +void select_result::cleanup() +{ + /* do nothing */ +} + static String default_line_term("\n",default_charset_info); static String default_escaped("\\",default_charset_info); static String default_field_term("\t",default_charset_info); @@ -813,6 +819,32 @@ void select_to_file::send_error(uint errcode,const char *err) } +bool select_to_file::send_eof() +{ + int error= test(end_io_cache(&cache)); + if (my_close(file,MYF(MY_WME))) + error= 1; + if (!error) + ::send_ok(thd,row_count); + file= -1; + return error; +} + + +void select_to_file::cleanup() +{ + /* In case of error send_eof() may be not called: close the file here. */ + if (file >= 0) + { + (void) end_io_cache(&cache); + (void) my_close(file,MYF(0)); + file= -1; + } + path[0]= '\0'; + row_count= 0; +} + + select_to_file::~select_to_file() { if (file >= 0) @@ -1063,18 +1095,6 @@ err: } -bool select_export::send_eof() -{ - int error=test(end_io_cache(&cache)); - if (my_close(file,MYF(MY_WME))) - error=1; - if (!error) - ::send_ok(thd,row_count); - file= -1; - return error; -} - - /*************************************************************************** ** Dump of select to a binary file ***************************************************************************/ @@ -1128,18 +1148,6 @@ err: } -bool select_dump::send_eof() -{ - int error=test(end_io_cache(&cache)); - if (my_close(file,MYF(MY_WME))) - error=1; - if (!error) - ::send_ok(thd,row_count); - file= -1; - return error; -} - - select_subselect::select_subselect(Item_subselect *item_arg) { item= item_arg; @@ -1306,6 +1314,13 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u) } +void select_dumpvar::cleanup() +{ + vars.empty(); + row_count=0; +} + + Item_arena::Item_arena(THD* thd) :free_list(0), state((int)INITIALIZED) @@ -1410,6 +1425,21 @@ void Statement::restore_backup_statement(Statement *stmt, Statement *backup) } +void Statement::end_statement() +{ + /* Cleanup SQL processing state to resuse this statement in next query. */ + lex_end(lex); + delete lex->result; + lex->result= 0; + free_items(free_list); + free_list= 0; + /* + Don't free mem_root, as mem_root is freed in the end of dispatch_command + (once for any command). + */ +} + + void Item_arena::set_n_backup_item_arena(Item_arena *set, Item_arena *backup) { backup->set_item_arena(this); diff --git a/sql/sql_class.h b/sql/sql_class.h index 713609b3d32..198e06bb3bd 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -551,6 +551,12 @@ public: void restore_backup_statement(Statement *stmt, Statement *backup); /* return class type */ virtual Type type() const; + + /* + Cleanup statement parse state (parse tree, lex) after execution of + a non-prepared SQL statement. + */ + void end_statement(); }; @@ -1033,10 +1039,13 @@ public: ~Disable_binlog(); }; + /* Used to hold information about file and file structure in exchainge via non-DB file (...INTO OUTFILE..., ...LOAD DATA...) + XXX: We never call destructor for objects of this class. */ + class sql_exchange :public Sql_alloc { public: @@ -1046,7 +1055,6 @@ public: bool dumpfile; ulong skip_lines; sql_exchange(char *name,bool dumpfile_flag); - ~sql_exchange() {} }; #include "log_event.h" @@ -1077,6 +1085,11 @@ public: virtual void send_error(uint errcode,const char *err); virtual bool send_eof()=0; virtual void abort() {} + /* + Cleanup instance of this class for next execution of a prepared + statement/stored procedure. + */ + virtual void cleanup(); }; @@ -1103,6 +1116,8 @@ public: ~select_to_file(); bool send_fields(List<Item> &list, uint flag) { return 0; } void send_error(uint errcode,const char *err); + bool send_eof(); + void cleanup(); }; @@ -1115,7 +1130,6 @@ public: ~select_export(); int prepare(List<Item> &list, SELECT_LEX_UNIT *u); bool send_data(List<Item> &items); - bool send_eof(); }; @@ -1124,7 +1138,6 @@ public: select_dump(sql_exchange *ex) :select_to_file(ex) {} int prepare(List<Item> &list, SELECT_LEX_UNIT *u); bool send_data(List<Item> &items); - bool send_eof(); }; @@ -1149,6 +1162,8 @@ class select_insert :public select_result { bool send_data(List<Item> &items); void send_error(uint errcode,const char *err); bool send_eof(); + /* not implemented: select_insert is never re-used in prepared statements */ + void cleanup(); }; @@ -1449,4 +1464,5 @@ public: bool send_fields(List<Item> &list, uint flag) {return 0;} bool send_data(List<Item> &items); bool send_eof(); + void cleanup(); }; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index b76bad2805b..ffeeb98488a 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -607,17 +607,13 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) int error; DBUG_ENTER("mysql_truncate"); + bzero((char*) &create_info,sizeof(create_info)); /* If it is a temporary table, close and regenerate it */ if (!dont_send_ok && (table_ptr=find_temporary_table(thd,table_list->db, table_list->real_name))) { TABLE *table= *table_ptr; - HA_CREATE_INFO create_info; table->file->info(HA_STATUS_AUTO | HA_STATUS_NO_LOCK); - bzero((char*) &create_info,sizeof(create_info)); - create_info.auto_increment_value= table->file->auto_increment_value; - create_info.default_table_charset= table->table_charset; - db_type table_type=table->db_type; strmov(path,table->path); *table_ptr= table->next; // Unlink table from list @@ -659,8 +655,6 @@ int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) DBUG_RETURN(-1); } - bzero((char*) &create_info,sizeof(create_info)); - *fn_ext(path)=0; // Remove the .frm extension error= ha_create_table(path,&create_info,1) ? -1 : 0; query_cache_invalidate3(thd, table_list, 0); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 406bff6d273..4cbd11c6a15 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1465,6 +1465,13 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) DBUG_RETURN(0); } + +void select_insert::cleanup() +{ + /* select_insert/select_create are never re-used in prepared statement */ + DBUG_ASSERT(0); +} + select_insert::~select_insert() { if (table) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index ccbc015533b..fab047002ad 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1653,6 +1653,11 @@ void st_select_lex::print_limit(THD *thd, String *str) } +st_lex::st_lex() + :result(0) +{} + + /* Unlink first table from global table list and first table from outer select list (lex->select_lex) diff --git a/sql/sql_lex.h b/sql/sql_lex.h index da2c3fba097..7342902c086 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -633,7 +633,7 @@ typedef struct st_lex list of those tables after they are opened. */ TABLE_LIST *time_zone_tables_used; - st_lex() {} + st_lex(); inline void uncacheable(uint8 cause) { safe_to_cache_query= 0; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 66eebba74c9..f9e979d1fdf 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1967,8 +1967,6 @@ mysql_execute_command(THD *thd) else thd->send_explain_fields(result); res= mysql_explain_union(thd, &thd->lex->unit, result); - MYSQL_LOCK *save_lock= thd->lock; - thd->lock= (MYSQL_LOCK *)0; if (lex->describe & DESCRIBE_EXTENDED) { char buff[1024]; @@ -1980,20 +1978,19 @@ mysql_execute_command(THD *thd) ER_YES, str.ptr()); } result->send_eof(); - thd->lock= save_lock; + delete result; } else { - if (!result) + if (!result && !(result= new select_send())) { - if (!(result=new select_send())) - { - res= -1; - break; - } + res= -1; + break; } query_cache_store_query(thd, tables); - res=handle_select(thd, lex, result); + res= handle_select(thd, lex, result); + if (result != lex->result) + delete result; } } break; @@ -2708,23 +2705,24 @@ unsent_create_error: } - if (!(res=open_and_lock_tables(thd, tables))) + if (!(res= open_and_lock_tables(thd, tables)) && + (result= new select_insert(tables->table, &lex->field_list, + lex->duplicates))) { - if ((result=new select_insert(tables->table,&lex->field_list, - lex->duplicates))) - /* Skip first table, which is the table we are inserting in */ - lex->select_lex.table_list.first= (byte*) first_local_table->next; - /* - insert/replace from SELECT give its SELECT_LEX for SELECT, - and item_list belong to SELECT - */ - lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; - res=handle_select(thd,lex,result); - /* revert changes for SP */ - lex->select_lex.table_list.first= (byte*) first_local_table; - lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; + /* Skip first table, which is the table we are inserting in */ + lex->select_lex.table_list.first= (byte*) first_local_table->next; + /* + insert/replace from SELECT give its SELECT_LEX for SELECT, + and item_list belong to SELECT + */ + lex->select_lex.resolve_mode= SELECT_LEX::SELECT_MODE; + res= handle_select(thd, lex, result); + /* revert changes for SP */ + lex->select_lex.table_list.first= (byte*) first_local_table; + lex->select_lex.resolve_mode= SELECT_LEX::INSERT_MODE; + delete result; if (thd->net.report_error) - res= -1; + res= -1; } else res= -1; @@ -3904,8 +3902,8 @@ mysql_init_select(LEX *lex) select_lex->select_limit= HA_POS_ERROR; if (select_lex == &lex->select_lex) { + DBUG_ASSERT(lex->result == 0); lex->exchange= 0; - lex->result= 0; lex->proc_list.first= 0; } } @@ -4047,9 +4045,7 @@ void mysql_parse(THD *thd, char *inBuf, uint length) query_cache_abort(&thd->net); } thd->proc_info="freeing items"; - free_items(thd->free_list); /* Free strings used by items */ - thd->free_list= 0; - lex_end(lex); + thd->end_statement(); } DBUG_VOID_RETURN; } @@ -4074,10 +4070,7 @@ bool mysql_test_parse_for_slave(THD *thd, char *inBuf, uint length) if (!yyparse((void*) thd) && ! thd->is_fatal_error && all_tables_not_ok(thd,(TABLE_LIST*) lex->select_lex.table_list.first)) error= 1; /* Ignore question */ - free_items(thd->free_list); /* Free strings used by items */ - thd->free_list= 0; - lex_end(lex); - + thd->end_statement(); return error; } #endif diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 94b6ab103da..baff7bd604d 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1630,7 +1630,8 @@ int mysql_stmt_prepare(THD *thd, char *packet, uint packet_length, static void reset_stmt_for_execute(Prepared_statement *stmt) { THD *thd= stmt->thd; - SELECT_LEX *sl= stmt->lex->all_selects_list; + LEX *lex= stmt->lex; + SELECT_LEX *sl= lex->all_selects_list; for (; sl; sl= sl->next_select_in_list()) { @@ -1678,7 +1679,9 @@ static void reset_stmt_for_execute(Prepared_statement *stmt) unit->reinit_exec_mechanism(); } } - stmt->lex->current_select= &stmt->lex->select_lex; + lex->current_select= &lex->select_lex; + if (lex->result) + lex->result->cleanup(); } @@ -2053,6 +2056,7 @@ void Prepared_statement::setup_set_params() Prepared_statement::~Prepared_statement() { free_items(free_list); + delete lex->result; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 630a520066a..6fdc1c2bfc3 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -199,16 +199,10 @@ int handle_select(THD *thd, LEX *lex, select_result *result) res= 1; if (res) { - if (result) - { - result->send_error(0, NullS); - result->abort(); - } - else - send_error(thd, 0, NullS); + result->send_error(0, NullS); + result->abort(); res= 1; // Error sent to client } - delete result; DBUG_RETURN(res); } diff --git a/strings/my_vsnprintf.c b/strings/my_vsnprintf.c index 71b5f345fda..268f7d18f2a 100644 --- a/strings/my_vsnprintf.c +++ b/strings/my_vsnprintf.c @@ -33,17 +33,6 @@ length of result string */ -int my_snprintf(char* to, size_t n, const char* fmt, ...) -{ - int result; - va_list args; - va_start(args,fmt); - result= my_vsnprintf(to, n, fmt, args); - va_end(args); - return result; -} - - int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) { char *start=to, *end=to+n-1; @@ -141,6 +130,15 @@ int my_vsnprintf(char *to, size_t n, const char* fmt, va_list ap) return (uint) (to - start); } +int my_snprintf(char* to, size_t n, const char* fmt, ...) +{ + int result; + va_list args; + va_start(args,fmt); + result= my_vsnprintf(to, n, fmt, args); + va_end(args); + return result; +} #ifdef MAIN #define OVERRUN_SENTRY 250 diff --git a/support-files/Makefile.am b/support-files/Makefile.am index 196da3d8744..3b43f7b7911 100644 --- a/support-files/Makefile.am +++ b/support-files/Makefile.am @@ -22,6 +22,7 @@ EXTRA_DIST = mysql.spec.sh \ my-medium.cnf.sh \ my-large.cnf.sh \ my-huge.cnf.sh \ + my-innodb-heavy-4G \ mysql-log-rotate.sh \ mysql.server.sh \ binary-configure.sh \ @@ -34,6 +35,7 @@ pkgdata_DATA = my-small.cnf \ my-medium.cnf \ my-large.cnf \ my-huge.cnf \ + my-innodb-heavy-4G.cnf \ mysql-log-rotate \ mysql-@VERSION@.spec \ MySQL-shared-compat.spec @@ -44,6 +46,7 @@ CLEANFILES = my-small.cnf \ my-medium.cnf \ my-large.cnf \ my-huge.cnf \ + my-innodb-heavy-4G.cnf \ mysql.spec \ mysql-@VERSION@.spec \ mysql-log-rotate \ |