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

merging from the main to a local branch

This commit is contained in:
Andrei Elkin
2009-02-13 18:20:36 +02:00
133 changed files with 4189 additions and 5321 deletions

View File

@ -2270,8 +2270,10 @@ extern "C" char **new_mysql_completion (const char *text, int start, int end);
if not. if not.
*/ */
#if defined(USE_NEW_READLINE_INTERFACE) || defined(USE_LIBEDIT_INTERFACE) #if defined(USE_NEW_READLINE_INTERFACE)
extern "C" char *no_completion(const char*,int) extern "C" char *no_completion(const char*,int)
#elif defined(USE_LIBEDIT_INTERFACE)
extern "C" int no_completion(const char*,int)
#else #else
extern "C" char *no_completion() extern "C" char *no_completion()
#endif #endif

View File

@ -4647,6 +4647,10 @@ void safe_connect(MYSQL* mysql, const char *name, const char *host,
int failed_attempts= 0; int failed_attempts= 0;
DBUG_ENTER("safe_connect"); DBUG_ENTER("safe_connect");
verbose_msg("Connecting to server %s:%d (socket %s) as '%s'"
", connection '%s', attempt %d ...",
host, port, sock, user, name, failed_attempts);
while(!mysql_real_connect(mysql, host,user, pass, db, port, sock, while(!mysql_real_connect(mysql, host,user, pass, db, port, sock,
CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS)) CLIENT_MULTI_STATEMENTS | CLIENT_REMEMBER_OPTIONS))
{ {
@ -4678,6 +4682,7 @@ void safe_connect(MYSQL* mysql, const char *name, const char *host,
} }
failed_attempts++; failed_attempts++;
} }
verbose_msg("... Connected.");
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
@ -7511,8 +7516,12 @@ int main(int argc, char **argv)
parse_args(argc, argv); parse_args(argc, argv);
log_file.open(opt_logdir, result_file_name, ".log"); log_file.open(opt_logdir, result_file_name, ".log");
verbose_msg("Logging to '%s'.", log_file.file_name());
if (opt_mark_progress) if (opt_mark_progress)
{
progress_file.open(opt_logdir, result_file_name, ".progress"); progress_file.open(opt_logdir, result_file_name, ".progress");
verbose_msg("Tracing progress in '%s'.", progress_file.file_name());
}
var_set_int("$PS_PROTOCOL", ps_protocol); var_set_int("$PS_PROTOCOL", ps_protocol);
var_set_int("$SP_PROTOCOL", sp_protocol); var_set_int("$SP_PROTOCOL", sp_protocol);
@ -7521,6 +7530,8 @@ int main(int argc, char **argv)
DBUG_PRINT("info",("result_file: '%s'", DBUG_PRINT("info",("result_file: '%s'",
result_file_name ? result_file_name : "")); result_file_name ? result_file_name : ""));
verbose_msg("Results saved in '%s'.",
result_file_name ? result_file_name : "");
if (mysql_server_init(embedded_server_arg_count, if (mysql_server_init(embedded_server_arg_count,
embedded_server_args, embedded_server_args,
(char**) embedded_server_groups)) (char**) embedded_server_groups))
@ -7591,6 +7602,7 @@ int main(int argc, char **argv)
open_file(opt_include); open_file(opt_include);
} }
verbose_msg("Start processing test commands from '%s' ...", cur_file->file_name);
while (!read_command(&command) && !abort_flag) while (!read_command(&command) && !abort_flag)
{ {
int current_line_inc = 1, processed = 0; int current_line_inc = 1, processed = 0;
@ -7908,6 +7920,7 @@ int main(int argc, char **argv)
log_file.close(); log_file.close();
start_lineno= 0; start_lineno= 0;
verbose_msg("... Done processing test commands.");
if (parsing_disabled) if (parsing_disabled)
die("Test ended with parsing disabled"); die("Test ended with parsing disabled");
@ -7958,6 +7971,7 @@ int main(int argc, char **argv)
if (!command_executed && result_file_name) if (!command_executed && result_file_name)
die("No queries executed but result file found!"); die("No queries executed but result file found!");
verbose_msg("Test has succeeded!");
timer_output(); timer_output();
/* Yes, if we got this far the test has suceeded! Sakila smiles */ /* Yes, if we got this far the test has suceeded! Sakila smiles */
cleanup_and_exit(0); cleanup_and_exit(0);

View File

@ -1,6 +1,4 @@
## Process this file with automake to create Makefile.in ## Process this file with automake to create Makefile.in
# Makefile for the GNU readline library.
# Copyright (C) 1994,1996,1997 Free Software Foundation, Inc.
ASRC = $(srcdir)/vi.c $(srcdir)/emacs.c $(srcdir)/common.c ASRC = $(srcdir)/vi.c $(srcdir)/emacs.c $(srcdir)/common.c
AHDR = vi.h emacs.h common.h AHDR = vi.h emacs.h common.h
@ -12,33 +10,23 @@ noinst_LIBRARIES = libedit.a
libedit_a_SOURCES = chared.c el.c history.c map.c prompt.c readline.c \ libedit_a_SOURCES = chared.c el.c history.c map.c prompt.c readline.c \
search.c tokenizer.c vi.c common.c emacs.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 \ hist.c key.c parse.c read.c refresh.c sig.c term.c \
tty.c help.c fcns.c tty.c help.c fcns.c filecomplete.c \
np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c \
EXTRA_libedit_a_SOURCES = np/unvis.c np/strlcpy.c np/vis.c np/strlcat.c \ np/fgetln.c
np/fgetln.c
libedit_a_LIBADD = @LIBEDIT_LOBJECTS@ libedit_a_LIBADD = @LIBEDIT_LOBJECTS@
libedit_a_DEPENDENCIES = @LIBEDIT_LOBJECTS@ libedit_a_DEPENDENCIES = @LIBEDIT_LOBJECTS@
noinst_HEADERS = readline/readline.h \ pkginclude_HEADERS = readline/readline.h
\
chared.h el.h el_term.h histedit.h key.h parse.h refresh.h sig.h \
sys.h tokenizer.h config.h hist.h map.h prompt.h read.h \
search.h tty.h libedit_term.h vis.h
EXTRA_DIST = makelist.sh np/unvis.c np/strlcpy.c np/vis.c np/vis.h np/strlcat.c np/fgetln.c noinst_HEADERS = chared.h el.h el_term.h histedit.h key.h parse.h refresh.h sig.h \
sys.h config.h hist.h map.h prompt.h read.h \
search.h tty.h filecomplete.h np/vis.h
EXTRA_DIST = makelist.sh
CLEANFILES = makelist common.h emacs.h vi.h fcns.h help.h fcns.c help.c CLEANFILES = makelist common.h emacs.h vi.h fcns.h help.h fcns.c help.c
# Make sure to include stuff from this directory first, to get right "config.h"
# Automake puts into DEFAULT_INCLUDES this source and corresponding
# build directory together with ../../include to let all make files
# find the central "config.h". This variable is used before INCLUDES
# above. But in automake 1.10 the order of these are changed. Put the
# includes of this directory into DEFS to always be sure it is first
# before DEFAULT_INCLUDES on the compile line.
DEFS = -DUNDEF_THREADS_HACK -DHAVE_CONFIG_H -DNO_KILL_INTR -I. -I$(srcdir)
SUFFIXES = .sh SUFFIXES = .sh
.sh: .sh:
@ -101,6 +89,4 @@ term.o: vi.h emacs.h common.h help.h fcns.h
tty.o: vi.h emacs.h common.h help.h fcns.h tty.o: vi.h emacs.h common.h help.h fcns.h
help.o: vi.h emacs.h common.h help.h fcns.h help.o: vi.h emacs.h common.h help.h fcns.h
fcns.o: vi.h emacs.h common.h help.h fcns.h fcns.o: vi.h emacs.h common.h help.h fcns.h
filecomplete.o: vi.h emacs.h common.h help.h fcns.h
# Don't update the files from bitkeeper
%::SCCS/s.%

View File

@ -0,0 +1,50 @@
An approximate method to merge from upstream is:
# Fetch latest from upstream (we also include some compat stuff)
$ CVS_RSH=ssh; export CVS_RSH
$ CVSROOT="anoncvs@stripped:/cvsroot"
$ cvs co -d libedit -P src/lib/libedit
$ mkdir libedit/np
$ for f in src/common/lib/libc/string/strlcat.c \
> src/common/lib/libc/string/strlcpy.c \
> src/include/vis.h \
> src/lib/libc/gen/unvis.c \
> src/lib/libc/gen/vis.c \
> src/tools/compat/fgetln.c
> do
> cvs co -P ${f}
> mv ${f} libedit/np
> done
$ rm -rf src
$ cd libedit
# Remove files we don't need/use
$ rm -rf CVS TEST Makefile shlib_version *.[0-9]
$ (cd readline; rm -rf CVS Makefile)
# Rename files to match our naming
$ mv makelist makelist.sh
$ mv term.h el_term.h
# Remove NetBSD-specific bits
$ for file in $(find . -type f)
> do
> cp ${file} ${file}.orig
> sed -e 's/#include "term.h"/#include "el_term.h"/g' \
> -e 's/sig_handler/el_sig_handler/g' \
> -e 's/isprint/el_isprint/g' \
> -e '/^__RCSID/d' \
> ${file}.orig >${file}
> rm ${file}.orig
> done
then merge remaining bits by hand. All MySQL-specific changes should be
marked with XXXMYSQL to make them easier to identify and merge. To generate
a 'clean' diff against upstream you can use the above commands but use
cvs co -D "2009/02/06 20:09:00" [..]
to fetch the baseline of most recent merge.
Please feed any fixes to Jonathan Perkin <jperkin@stripped> who will endeavour
to merge them upstream and keep diffs minimal.

View File

@ -1,269 +0,0 @@
/* $NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem 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.
*/
#include <sys/cdefs.h>
#include "compat.h"
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1992, 1993\n\
The Regents of the University of California. All rights reserved.\n");
#endif /* not lint */
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)test.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: test.c,v 1.9 2000/09/04 23:36:41 lukem Exp $");
#endif
#endif /* not lint && not SCCSID */
/*
* test.c: A little test program
*/
#include "sys.h"
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <sys/wait.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include "histedit.h"
#include "tokenizer.h"
static int continuation = 0;
static EditLine *el = NULL;
static u_char complete(EditLine *, int);
int main(int, char **);
static char *prompt(EditLine *);
static void sig(int);
static char *
prompt(EditLine *el)
{
static char a[] = "Edit$";
static char b[] = "Edit>";
return (continuation ? b : a);
}
static void
sig(int i)
{
(void) fprintf(stderr, "Got signal %d.\n", i);
el_reset(el);
}
static unsigned char
complete(EditLine *el, int ch)
{
DIR *dd = opendir(".");
struct dirent *dp;
const char* ptr;
const LineInfo *lf = el_line(el);
int len;
/*
* Find the last word
*/
for (ptr = lf->cursor - 1; !isspace(*ptr) && ptr > lf->buffer; ptr--)
continue;
len = lf->cursor - ++ptr;
for (dp = readdir(dd); dp != NULL; dp = readdir(dd)) {
if (len > strlen(dp->d_name))
continue;
if (strncmp(dp->d_name, ptr, len) == 0) {
closedir(dd);
if (el_insertstr(el, &dp->d_name[len]) == -1)
return (CC_ERROR);
else
return (CC_REFRESH);
}
}
closedir(dd);
return (CC_ERROR);
}
int
main(int argc, char *argv[])
{
int num;
const char *buf;
Tokenizer *tok;
int lastevent = 0, ncontinuation;
History *hist;
HistEvent ev;
(void) signal(SIGINT, sig);
(void) signal(SIGQUIT, sig);
(void) signal(SIGHUP, sig);
(void) signal(SIGTERM, sig);
hist = history_init(); /* Init the builtin history */
/* Remember 100 events */
history(hist, &ev, H_SETSIZE, 100);
tok = tok_init(NULL); /* Initialize the tokenizer */
/* Initialize editline */
el = el_init(*argv, stdin, stdout, stderr);
el_set(el, EL_EDITOR, "vi"); /* Default editor is vi */
el_set(el, EL_SIGNAL, 1); /* Handle signals gracefully */
el_set(el, EL_PROMPT, prompt); /* Set the prompt function */
/* Tell editline to use this history interface */
el_set(el, EL_HIST, history, hist);
/* Add a user-defined function */
el_set(el, EL_ADDFN, "ed-complete", "Complete argument", complete);
/* Bind tab to it */
el_set(el, EL_BIND, "^I", "ed-complete", NULL);
/*
* Bind j, k in vi command mode to previous and next line, instead
* of previous and next history.
*/
el_set(el, EL_BIND, "-a", "k", "ed-prev-line", NULL);
el_set(el, EL_BIND, "-a", "j", "ed-next-line", NULL);
/*
* Source the user's defaults file.
*/
el_source(el, NULL);
while ((buf = el_gets(el, &num)) != NULL && num != 0) {
int ac;
char **av;
#ifdef DEBUG
(void) fprintf(stderr, "got %d %s", num, buf);
#endif
if (!continuation && num == 1)
continue;
if (tok_line(tok, buf, &ac, &av) > 0)
ncontinuation = 1;
#if 0
if (continuation) {
/*
* Append to the right event in case the user
* moved around in history.
*/
if (history(hist, &ev, H_SET, lastevent) == -1)
err(1, "%d: %s\n", lastevent, ev.str);
history(hist, &ev, H_ADD , buf);
} else {
history(hist, &ev, H_ENTER, buf);
lastevent = ev.num;
}
#else
/* Simpler */
history(hist, &ev, continuation ? H_APPEND : H_ENTER, buf);
#endif
continuation = ncontinuation;
ncontinuation = 0;
if (strcmp(av[0], "history") == 0) {
int rv;
switch (ac) {
case 1:
for (rv = history(hist, &ev, H_LAST); rv != -1;
rv = history(hist, &ev, H_PREV))
(void) fprintf(stdout, "%4d %s",
ev.num, ev.str);
break;
case 2:
if (strcmp(av[1], "clear") == 0)
history(hist, &ev, H_CLEAR);
else
goto badhist;
break;
case 3:
if (strcmp(av[1], "load") == 0)
history(hist, &ev, H_LOAD, av[2]);
else if (strcmp(av[1], "save") == 0)
history(hist, &ev, H_SAVE, av[2]);
break;
badhist:
default:
(void) fprintf(stderr,
"Bad history arguments\n");
break;
}
} else if (el_parse(el, ac, av) == -1) {
switch (fork()) {
case 0:
execvp(av[0], av);
perror(av[0]);
_exit(1);
/*NOTREACHED*/
break;
case -1:
perror("fork");
break;
default:
if (wait(&num) == -1)
perror("wait");
(void) fprintf(stderr, "Exit %x\n", num);
break;
}
}
tok_reset(tok);
}
el_end(el);
tok_end(tok);
history_end(hist);
return (0);
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: chared.c,v 1.22 2004/08/13 12:10:38 mycroft Exp $ */ /* $NetBSD: chared.c,v 1.26 2009/02/06 12:45:25 sketch Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)chared.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* chared.c: Character editor utilities * chared.c: Character editor utilities
@ -40,6 +46,8 @@
#include <stdlib.h> #include <stdlib.h>
#include "el.h" #include "el.h"
private void ch__clearmacro (EditLine *);
/* value to leave unused in line buffer */ /* value to leave unused in line buffer */
#define EL_LEAVE 2 #define EL_LEAVE 2
@ -51,13 +59,13 @@ cv_undo(EditLine *el)
{ {
c_undo_t *vu = &el->el_chared.c_undo; c_undo_t *vu = &el->el_chared.c_undo;
c_redo_t *r = &el->el_chared.c_redo; c_redo_t *r = &el->el_chared.c_redo;
int size; unsigned int size;
/* Save entire line for undo */ /* Save entire line for undo */
size = el->el_line.lastchar - el->el_line.buffer; size = el->el_line.lastchar - el->el_line.buffer;
vu->len = size; vu->len = size;
vu->cursor = el->el_line.cursor - el->el_line.buffer; vu->cursor = el->el_line.cursor - el->el_line.buffer;
memcpy(vu->buf, el->el_line.buffer, (size_t)size); memcpy(vu->buf, el->el_line.buffer, size);
/* save command info for redo */ /* save command info for redo */
r->count = el->el_state.doingarg ? el->el_state.argument : 0; r->count = el->el_state.doingarg ? el->el_state.argument : 0;
@ -439,6 +447,8 @@ cv__endword(char *p, char *high, int n, int (*wtest)(int))
protected int protected int
ch_init(EditLine *el) ch_init(EditLine *el)
{ {
c_macro_t *ma = &el->el_chared.c_macro;
el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ); el->el_line.buffer = (char *) el_malloc(EL_BUFSIZ);
if (el->el_line.buffer == NULL) if (el->el_line.buffer == NULL)
return (-1); return (-1);
@ -479,11 +489,10 @@ ch_init(EditLine *el)
el->el_state.argument = 1; el->el_state.argument = 1;
el->el_state.lastcmd = ED_UNASSIGNED; el->el_state.lastcmd = ED_UNASSIGNED;
el->el_chared.c_macro.level = -1; ma->level = -1;
el->el_chared.c_macro.offset = 0; ma->offset = 0;
el->el_chared.c_macro.macro = (char **) el_malloc(EL_MAXMACRO * ma->macro = (char **) el_malloc(EL_MAXMACRO * sizeof(char *));
sizeof(char *)); if (ma->macro == NULL)
if (el->el_chared.c_macro.macro == NULL)
return (-1); return (-1);
return (0); return (0);
} }
@ -492,7 +501,7 @@ ch_init(EditLine *el)
* Reset the character editor * Reset the character editor
*/ */
protected void protected void
ch_reset(EditLine *el) ch_reset(EditLine *el, int mclear)
{ {
el->el_line.cursor = el->el_line.buffer; el->el_line.cursor = el->el_line.buffer;
el->el_line.lastchar = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer;
@ -513,9 +522,19 @@ ch_reset(EditLine *el)
el->el_state.argument = 1; el->el_state.argument = 1;
el->el_state.lastcmd = ED_UNASSIGNED; el->el_state.lastcmd = ED_UNASSIGNED;
el->el_chared.c_macro.level = -1;
el->el_history.eventno = 0; el->el_history.eventno = 0;
if (mclear)
ch__clearmacro(el);
}
private void
ch__clearmacro(el)
EditLine *el;
{
c_macro_t *ma = &el->el_chared.c_macro;
while (ma->level >= 0)
el_free((ptr_t)ma->macro[ma->level--]);
} }
/* ch_enlargebufs(): /* ch_enlargebufs():
@ -623,9 +642,9 @@ ch_end(EditLine *el)
el->el_chared.c_redo.cmd = ED_UNASSIGNED; el->el_chared.c_redo.cmd = ED_UNASSIGNED;
el_free((ptr_t) el->el_chared.c_kill.buf); el_free((ptr_t) el->el_chared.c_kill.buf);
el->el_chared.c_kill.buf = NULL; el->el_chared.c_kill.buf = NULL;
ch_reset(el, 1);
el_free((ptr_t) el->el_chared.c_macro.macro); el_free((ptr_t) el->el_chared.c_macro.macro);
el->el_chared.c_macro.macro = NULL; el->el_chared.c_macro.macro = NULL;
ch_reset(el);
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: chared.h,v 1.14 2004/08/13 12:10:39 mycroft Exp $ */ /* $NetBSD: chared.h,v 1.17 2006/03/06 21:11:56 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -48,7 +48,7 @@
#define EL_MAXMACRO 10 #define EL_MAXMACRO 10
/* /*
* This is a issue of basic "vi" look-and-feel. Defining VI_MOVE works * This is an issue of basic "vi" look-and-feel. Defining VI_MOVE works
* like real vi: i.e. the transition from command<->insert modes moves * like real vi: i.e. the transition from command<->insert modes moves
* the cursor. * the cursor.
* *
@ -116,11 +116,10 @@ typedef struct el_chared_t {
} el_chared_t; } el_chared_t;
#define STReof "^D\b\b"
#define STRQQ "\"\"" #define STRQQ "\"\""
#define isglob(a) (strchr("*[]?", (a)) != NULL) #define isglob(a) (strchr("*[]?", (a)) != NULL)
#define isword(a) (isprint(a)) #define isword(a) (el_isprint(a))
#define NOP 0x00 #define NOP 0x00
#define DELETE 0x01 #define DELETE 0x01
@ -161,7 +160,7 @@ protected int c_gets(EditLine *, char *, const char *);
protected int c_hpos(EditLine *); protected int c_hpos(EditLine *);
protected int ch_init(EditLine *); protected int ch_init(EditLine *);
protected void ch_reset(EditLine *); protected void ch_reset(EditLine *, int);
protected int ch_enlargebufs(EditLine *, size_t); protected int ch_enlargebufs(EditLine *, size_t);
protected void ch_end(EditLine *); protected void ch_end(EditLine *);

View File

@ -1,4 +1,4 @@
/* $NetBSD: common.c,v 1.16 2003/08/07 16:44:30 agc Exp $ */ /* $NetBSD: common.c,v 1.21 2008/09/30 08:37:42 aymeric Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)common.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* common.c: Common Editor functions * common.c: Common Editor functions
@ -130,7 +136,7 @@ ed_delete_prev_word(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
ed_delete_next_char(EditLine *el, int c __attribute__((__unused__))) ed_delete_next_char(EditLine *el, int c)
{ {
#ifdef notdef /* XXX */ #ifdef notdef /* XXX */
#define EL el->el_line #define EL el->el_line
@ -147,9 +153,8 @@ ed_delete_next_char(EditLine *el, int c __attribute__((__unused__)))
#ifdef KSHVI #ifdef KSHVI
return (CC_ERROR); return (CC_ERROR);
#else #else
term_overwrite(el, STReof, 4); /* then do an EOF */
/* then do a EOF */ term_writechar(el, c);
term__flush();
return (CC_EOF); return (CC_EOF);
#endif #endif
} else { } else {
@ -207,13 +212,13 @@ ed_move_to_end(EditLine *el, int c __attribute__((__unused__)))
el->el_line.cursor = el->el_line.lastchar; el->el_line.cursor = el->el_line.lastchar;
if (el->el_map.type == MAP_VI) { if (el->el_map.type == MAP_VI) {
#ifdef VI_MOVE
el->el_line.cursor--;
#endif
if (el->el_chared.c_vcmd.action != NOP) { if (el->el_chared.c_vcmd.action != NOP) {
cv_delfini(el); cv_delfini(el);
return (CC_REFRESH); return (CC_REFRESH);
} }
#ifdef VI_MOVE
el->el_line.cursor--;
#endif
} }
return (CC_CURSOR); return (CC_CURSOR);
} }
@ -609,7 +614,7 @@ protected el_action_t
ed_start_over(EditLine *el, int c __attribute__((__unused__))) ed_start_over(EditLine *el, int c __attribute__((__unused__)))
{ {
ch_reset(el); ch_reset(el, 0);
return (CC_REFRESH); return (CC_REFRESH);
} }
@ -904,7 +909,7 @@ ed_command(EditLine *el, int c __attribute__((__unused__)))
int tmplen; int tmplen;
tmplen = c_gets(el, tmpbuf, "\n: "); tmplen = c_gets(el, tmpbuf, "\n: ");
term__putc('\n'); term__putc(el, '\n');
if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1) if (tmplen < 0 || (tmpbuf[tmplen] = 0, parse_line(el, tmpbuf)) == -1)
term_beep(el); term_beep(el);

View File

@ -1,43 +0,0 @@
#ifndef __LIBEDIT_COMPATH_H
#define __LIBEDIT_COMPATH_H
#define __RCSID(x)
#define __COPYRIGHT(x)
#include "compat_conf.h"
#ifndef HAVE_VIS_H
/* string visual representation - may want to reimplement */
#define strvis(d,s,m) strcpy(d,s)
#define strunvis(d,s) strcpy(d,s)
#endif
#ifndef HAVE_FGETLN
#include "fgetln.h"
#endif
#ifndef HAVE_ISSETUGID
#define issetugid() (getuid()!=geteuid() || getegid()!=getgid())
#endif
#ifndef HAVE_STRLCPY
#include "strlcpy.h"
#endif
#if HAVE_SYS_CDEFS_H
#include <sys/cdefs.h>
#endif
#ifndef __P
#ifdef __STDC__
#define __P(x) x
#else
#define __P(x) ()
#endif
#endif
#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
#define __attribute__(A)
#endif
#endif

View File

@ -1,2 +0,0 @@
#include "my_config.h"

View File

@ -1,16 +1,2 @@
#include "my_config.h" #include "my_config.h"
#include "sys.h" #include "sys.h"
#if defined(LIBC_SCCS) && !defined(lint)
#define __RCSID(x)
#define __COPYRIGHT(x)
#endif
#define __RENAME(x)
#define _DIAGASSERT(x)
#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ < 8)
#define __attribute__(A)
#endif

View File

@ -1,619 +0,0 @@
.\" $NetBSD: editline.3,v 1.21 2001/04/02 18:29:49 wiz Exp $
.\"
.\" Copyright (c) 1997-1999 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
.\"
.\" 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.
.\"
.Dd November 12, 1999
.Os
.Dt EDITLINE 3
.Sh NAME
.Nm editline ,
.Nm el_init ,
.Nm el_end ,
.Nm el_reset ,
.Nm el_gets ,
.Nm el_getc ,
.Nm el_push ,
.Nm el_parse ,
.Nm el_set ,
.Nm el_source ,
.Nm el_resize ,
.Nm el_line ,
.Nm el_insertstr ,
.Nm el_deletestr ,
.Nm history_init ,
.Nm history_end ,
.Nm history
.Nd line editor and history functions
.Sh LIBRARY
.Lb libedit
.Sh SYNOPSIS
.Fd #include <histedit.h>
.Ft EditLine *
.Fn el_init "const char *prog" "FILE *fin" "FILE *fout" "FILE *ferr"
.Ft void
.Fn el_end "EditLine *e"
.Ft void
.Fn el_reset "EditLine *e"
.Ft const char *
.Fn el_gets "EditLine *e" "int *count"
.Ft int
.Fn el_getc "EditLine *e" "char *ch"
.Ft void
.Fn el_push "EditLine *e" "const char *str"
.Ft int
.Fn el_parse "EditLine *e" "int argc" "char *argv[]"
.Ft int
.Fn el_set "EditLine *e" "int op" "..."
.Ft int
.Fn el_get "EditLine *e" "int op" "void *result"
.Ft int
.Fn el_source "EditLine *e" "const char *file"
.Ft void
.Fn el_resize "EditLine *e"
.Ft const LineInfo *
.Fn el_line "EditLine *e"
.Ft int
.Fn el_insertstr "EditLine *e" "const char *str"
.Ft void
.Fn el_deletestr "EditLine *e" "int count"
.Ft History *
.Fn history_init
.Ft void
.Fn history_end "History *h"
.Ft int
.Fn history "History *h" "HistEvent *ev" "int op" "..."
.Sh DESCRIPTION
The
.Nm
library provides generic line editing and history functions,
similar to those found in
.Xr sh 1 .
.Pp
These functions are available in the
.Nm libedit
library (which needs the
.Nm libtermcap
library).
Programs should be linked with
.Fl ledit ltermcap .
.Sh LINE EDITING FUNCTIONS
The line editing functions use a common data structure,
.Fa EditLine ,
which is created by
.Fn el_init
and freed by
.Fn el_end .
.Pp
The following functions are available:
.Bl -tag -width 4n
.It Fn el_init
Initialise the line editor, and return a data structure
to be used by all other line editing functions.
.Fa prog
is the name of the invoking program, used when reading the
.Xr editrc 5
file to determine which settings to use.
.Fa fin ,
.Fa fout
and
.Fa ferr
are the input, output, and error streams (respectively) to use.
In this documentation, references to
.Dq the tty
are actually to this input/output stream combination.
.It Fn el_end
Clean up and finish with
.Fa e ,
assumed to have been created with
.Fn el_init .
.It Fn el_reset
Reset the tty and the parser.
This should be called after an error which may have upset the tty's
state.
.It Fn el_gets
Read a line from the tty.
.Fa count
is modified to contain the number of characters read.
Returns the line read if successful, or
.Dv NULL
if no characters were read or if an error occurred.
.It Fn el_getc
Read a character from the tty.
.Fa ch
is modified to contain the character read.
Returns the number of characters read if successful, -1 otherwise.
.It Fn el_push
Pushes
.Fa str
back onto the input stream.
This is used by the macro expansion mechanism.
Refer to the description of
.Ic bind
.Fl s
in
.Xr editrc 5
for more information.
.It Fn el_parse
Parses the
.Fa argv
array (which is
.Fa argc
elements in size)
to execute builtin
.Nm
commands.
If the command is prefixed with
.Dq prog:
then
.Fn el_parse
will only execute the command if
.Dq prog
matches the
.Fa prog
argument supplied to
.Fn el_init .
The return value is
-1 if the command is unknown,
0 if there was no error or
.Dq prog
didn't match, or
1 if the command returned an error.
Refer to
.Xr editrc 5
for more information.
.It Fn el_set
Set
.Nm
parameters.
.Fa op
determines which parameter to set, and each operation has its
own parameter list.
.Pp
The following values for
.Fa op
are supported, along with the required argument list:
.Bl -tag -width 4n
.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)"
Define prompt printing function as
.Fa f ,
which is to return a string that contains the prompt.
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)"
Define right side prompt printing function as
.Fa f ,
which is to return a string that contains the prompt.
.It Dv EL_TERMINAL , Fa "const char *type"
Define terminal type of the tty to be
.Fa type ,
or to
.Ev TERM
if
.Fa type
is
.Dv NULL .
.It Dv EL_EDITOR , Fa "const char *mode"
Set editing mode to
.Fa mode ,
which must be one of
.Dq emacs
or
.Dq vi .
.It Dv EL_SIGNAL , Fa "int flag"
If
.Fa flag
is non-zero,
.Nm
will install its own signal handler for the following signals when
reading command input:
.Dv SIGCONT ,
.Dv SIGHUP ,
.Dv SIGINT ,
.Dv SIGQUIT ,
.Dv SIGSTOP ,
.Dv SIGTERM ,
.Dv SIGTSTP ,
and
.Dv SIGWINCH .
Otherwise, the current signal handlers will be used.
.It Dv EL_BIND , Xo
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
Perform the
.Ic bind
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_ECHOTC , Xo
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
Perform the
.Ic echotc
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_SETTC , Xo
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
Perform the
.Ic settc
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_SETTY , Xo
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
Perform the
.Ic setty
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_TELLTC , Xo
.Fa "const char *" ,
.Fa "..." ,
.Dv NULL
.Xc
Perform the
.Ic telltc
builtin command.
Refer to
.Xr editrc 5
for more information.
.It Dv EL_ADDFN , Xo
.Fa "const char *name" ,
.Fa "const char *help" ,
.Fa "unsigned char (*func)(EditLine *e, int ch)
.Xc
Add a user defined function,
.Fn func ,
referred to as
.Fa name
which is invoked when a key which is bound to
.Fa name
is entered.
.Fa help
is a description of
.Fa name .
At invocation time,
.Fa ch
is the key which caused the invocation.
The return value of
.Fn func
should be one of:
.Bl -tag -width "CC_REDISPLAY"
.It Dv CC_NORM
Add a normal character.
.It Dv CC_NEWLINE
End of line was entered.
.It Dv CC_EOF
EOF was entered.
.It Dv CC_ARGHACK
Expecting further command input as arguments, do nothing visually.
.It Dv CC_REFRESH
Refresh display.
.It Dv CC_REFRESH_BEEP
Refresh display, and beep.
.It Dv CC_CURSOR
Cursor moved, so update and perform
.Dv CC_REFRESH.
.It Dv CC_REDISPLAY
Redisplay entire input line.
This is useful if a key binding outputs extra information.
.It Dv CC_ERROR
An error occurred.
Beep, and flush tty.
.It Dv CC_FATAL
Fatal error, reset tty to known state.
.El
.It Dv EL_HIST , Xo
.Fa "History *(*func)(History *, int op, ...)" ,
.Fa "const char *ptr"
.Xc
Defines which history function to use, which is usually
.Fn history .
.Fa ptr
should be the value returned by
.Fn history_init .
.It Dv EL_EDITMODE , Fa "int flag"
If
.Fa flag
is non-zero,
editing is enabled (the default).
Note that this is only an indication, and does not
affect the operation of
.Nm "" .
At this time, it is the caller's responsibility to
check this
(using
.Fn el_get )
to determine if editing should be enabled or not.
.El
.It Fn el_get
Get
.Nm
parameters.
.Fa op
determines which parameter to retrieve into
.Fa result .
.Pp
The following values for
.Fa op
are supported, along with actual type of
.Fa result :
.Bl -tag -width 4n
.It Dv EL_PROMPT , Fa "char *(*f)(EditLine *)"
Return a pointer to the function that displays the prompt.
.It Dv EL_RPROMPT , Fa "char *(*f)(EditLine *)"
Return a pointer to the function that displays the rightside prompt.
.It Dv EL_EDITOR , Fa "const char *"
Return the name of the editor, which will be one of
.Dq emacs
or
.Dq vi .
.It Dv EL_SIGNAL , Fa "int *"
Return non-zero if
.Nm
has installed private signal handlers (see
.Fn el_get
above).
.It Dv EL_EDITMODE, Fa "int *"
Return non-zero if editing is enabled.
.El
.It Fn el_source
Initialise
.Nm
by reading the contents of
.Fa file .
.Fn el_parse
is called for each line in
.Fa file .
If
.Fa file
is
.Dv NULL ,
try
.Pa $PWD/.editrc
then
.Pa $HOME/.editrc .
Refer to
.Xr editrc 5
for details on the format of
.Fa file .
.It Fn el_resize
Must be called if the terminal size changes.
If
.Dv EL_SIGNAL
has been set with
.Fn el_set ,
then this is done automatically.
Otherwise, it's the responsibility of the application to call
.Fn el_resize
on the appropriate occasions.
.It Fn el_line
Return the editing information for the current line in a
.Fa LineInfo
structure, which is defined as follows:
.Bd -literal
typedef struct lineinfo {
const char *buffer; /* address of buffer */
const char *cursor; /* address of cursor */
const char *lastchar; /* address of last character */
} LineInfo;
.Ed
.It Fn el_insertstr
Insert
.Fa str
into the line at the cursor.
Returns -1 if
.Fa str
is empty or won't fit, and 0 otherwise.
.It Fn el_deletestr
Delete
.Fa num
characters before the cursor.
.El
.Sh HISTORY LIST FUNCTIONS
The history functions use a common data structure,
.Fa History ,
which is created by
.Fn history_init
and freed by
.Fn history_end .
.Pp
The following functions are available:
.Bl -tag -width 4n
.It Fn history_init
Initialise the history list, and return a data structure
to be used by all other history list functions.
.It Fn history_end
Clean up and finish with
.Fa h ,
assumed to have been created with
.Fn history_init .
.It Fn history
Perform operation
.Fa op
on the history list, with optional arguments as needed by the
operation.
.Fa ev
is changed accordingly to operation.
The following values for
.Fa op
are supported, along with the required argument list:
.Bl -tag -width 4n
.It Dv H_SETSIZE , Fa "int size"
Set size of history to
.Fa size
elements.
.It Dv H_GETSIZE
Get number of events currently in history.
.It Dv H_END
Cleans up and finishes with
.Fa h ,
assumed to be created with
.Fn history_init .
.It Dv H_CLEAR
Clear the history.
.It Dv H_FUNC , Xo
.Fa "void *ptr" ,
.Fa "history_gfun_t first" ,
.Fa "history_gfun_t next" ,
.Fa "history_gfun_t last" ,
.Fa "history_gfun_t prev" ,
.Fa "history_gfun_t curr" ,
.Fa "history_sfun_t set" ,
.Fa "history_vfun_t clear" ,
.Fa "history_efun_t enter" ,
.Fa "history_efun_t add"
.Xc
Define functions to perform various history operations.
.Fa ptr
is the argument given to a function when it's invoked.
.It Dv H_FIRST
Return the first element in the history.
.It Dv H_LAST
Return the last element in the history.
.It Dv H_PREV
Return the previous element in the history.
.It Dv H_NEXT
Return the next element in the history.
.It Dv H_CURR
Return the current element in the history.
.It Dv H_SET
Set the cursor to point to the requested element.
.It Dv H_ADD , Fa "const char *str"
Append
.Fa str
to the current element of the history, or create an element with
.It Dv H_APPEND , Fa "const char *str"
Append
.Fa str
to the last new element of the history.
.It Dv H_ENTER , Fa "const char *str"
Add
.Fa str
as a new element to the history, and, if necessary,
removing the oldest entry to keep the list to the created size.
.It Dv H_PREV_STR , Fa "const char *str"
Return the closest previous event that starts with
.Fa str .
.It Dv H_NEXT_STR , Fa "const char *str"
Return the closest next event that starts with
.Fa str .
.It Dv H_PREV_EVENT , Fa "int e"
Return the previous event numbered
.Fa e .
.It Dv H_NEXT_EVENT , Fa "int e"
Return the next event numbered
.Fa e .
.It Dv H_LOAD , Fa "const char *file"
Load the history list stored in
.Fa file .
.It Dv H_SAVE , Fa "const char *file"
Save the history list to
.Fa file .
.El
.Pp
.Fn history
returns 0 if the operation
.Fa op
succeeds. Otherwise, -1 is returned and
.Fa ev
is updated to contain more details about the error.
.El
.\"XXX.Sh EXAMPLES
.\"XXX: provide some examples
.Sh SEE ALSO
.Xr editrc 5 ,
.Xr sh 1 ,
.Xr signal 3 ,
.Xr termcap 3
.Sh HISTORY
The
.Nm
library first appeared in
.Bx 4.4 .
.Dv CC_REDISPLAY
appeared in
.Nx 1.3 .
.Dv CC_REFRESH_BEEP ,
.Dv EL_EDITMODE
and the readline emulation appeared in
.Nx 1.4 .
.Dv EL_RPROMPT
appeared in
.Nx 1.5 .
.Sh AUTHORS
The
.Nm
library was written by Christos Zoulas.
Luke Mewburn wrote this manual and implemented
.Dv CC_REDISPLAY ,
.Dv CC_REFRESH_BEEP ,
.Dv EL_EDITMODE ,
and
.Dv EL_RPROMPT .
Jaromir Dolecek implemented the readline emulation.
.Sh BUGS
The tokenization functions are not publically defined in
.Fd <histedit.h>.
.Pp
At this time, it is the responsibility of the caller to
check the result of the
.Dv EL_EDITMODE
operation of
.Fn el_get
(after an
.Fn el_source
or
.Fn el_parse )
to determine if
.Nm
should be used for further input.
I.e.,
.Dv EL_EDITMODE
is purely an indication of the result of the most recent
.Xr editrc 5
.Ic edit
command.

View File

@ -1,491 +0,0 @@
.\" $NetBSD: editrc.5,v 1.11 2001/06/19 13:42:09 wiz Exp $
.\"
.\" Copyright (c) 1997-2000 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This file was contributed to The NetBSD Foundation by Luke Mewburn.
.\"
.\" 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.
.\"
.Dd November 8, 2000
.Os
.Dt EDITRC 5
.Sh NAME
.Nm editrc
.Nd configuration file for editline library
.Sh SYNOPSIS
.Nm
.Sh DESCRIPTION
The
.Nm
file defines various settings to be used by the
.Xr editline 3
library.
.Pp
The format of each line is:
.Dl [prog:]command [arg [...]]
.Pp
.Ar command
is one of the
.Xr editline 3
builtin commands.
Refer to
.Sx BUILTIN COMMANDS
for more information.
.Pp
.Ar prog
is the program name string that a program defines when it calls
.Xr el_init 3
to setup
.Xr editline 3 ,
which is usually
.Va argv[0] .
.Ar command
will be executed for any program which matches
.Ar prog .
.Pp
.Ar prog
may also be a
.Xr regex 3
style
regular expression, in which case
.Ar command
will be executed for any program that matches the regular expression.
.Pp
If
.Ar prog
is absent,
.Ar command
is executed for all programs.
.Sh BUILTIN COMMANDS
The
.Nm editline
library has some builtin commands, which affect the way
that the line editing and history functions operate.
These are based on similar named builtins present in the
.Xr tcsh 1
shell.
.Pp
The following builtin commands are available:
.Bl -tag -width 4n
.It Ic bind Xo
.Op Fl a
.Op Fl e
.Op Fl k
.Op Fl l
.Op Fl r
.Op Fl s
.Op Fl v
.Op Ar key Op Ar command
.Xc
Without options, list all bound keys, and the editor command to which
each is bound.
If
.Ar key
is supplied, show the bindings for
.Ar key .
If
.Ar key command
is supplied, bind
.Ar command
to
.Ar key .
Options include:
.Bl -tag -width 4n
.It Fl e
Bind all keys to the standard GNU Emacs-like bindings.
.It Fl v
Bind all keys to the standard
.Xr vi 1 -like
bindings.
.It Fl a
List or change key bindings in the
.Xr vi 1
mode alternate (command mode) key map.
.It Fl k
.Ar key
is interpreted as a symbolic arrow key name, which may be one of
.Sq up ,
.Sq down ,
.Sq left
or
.Sq right .
.It Fl l
List all editor commands and a short description of each.
.It Fl r
Remove a key's binding.
.It Fl s
.Ar command
is taken as a literal string and treated as terminal input when
.Ar key
is typed.
Bound keys in
.Ar command
are themselves reinterpreted, and this continues for ten levels of
interpretation.
.El
.Pp
.Ar command
may be one of the commands documented in
.Sx "EDITOR COMMANDS"
below, or another key.
.Pp
.Ar key
and
.Ar command
can contain control characters of the form
.Sm off
.Sq No ^ Ar character
.Sm on
.Po
e.g.
.Sq ^A
.Pc ,
and the following backslashed escape sequences:
.Pp
.Bl -tag -compact -offset indent -width 4n
.It Ic \ea
Bell
.It Ic \eb
Backspace
.It Ic \ee
Escape
.It Ic \ef
Formfeed
.It Ic \en
Newline
.It Ic \er
Carriage return
.It Ic \et
Horizontal tab
.It Ic \ev
Vertical tab
.Sm off
.It Sy \e Ar nnn
.Sm on
The ASCII character corresponding to the octal number
.Ar nnn .
.El
.Pp
.Sq \e
nullifies the special meaning of the following character,
if it has any, notably
.Sq \e
and
.Sq ^ .
.It Ic echotc Xo
.Op Fl sv
.Ar arg
.Ar ...
.Xc
Exercise terminal capabilities given in
.Ar arg Ar ... .
If
.Ar arg
is
.Sq baud ,
.Sq cols ,
.Sq lines ,
.Sq rows ,
.Sq meta or
.Sq tabs ,
the value of that capability is printed, with
.Dq yes
or
.Dq no
indicating that the terminal does or does not have that capability.
.Pp
.Fl s
returns an emptry string for non-existent capabilities, rather than
causing an error.
.Fl v
causes messages to be verbose.
.It Ic edit Op Li on | Li off
Enable or disable the
.Nm editline
functionality in a program.
.It Ic history
List the history.
.It Ic telltc
List the values of all the terminal capabilities (see
.Xr termcap 5 ).
.It Ic settc Ar cap Ar val
Set the terminal capability
.Ar cap
to
.Ar val ,
as defined in
.Xr termcap 5 .
No sanity checking is done.
.It Ic setty Xo
.Op Fl a
.Op Fl d
.Op Fl q
.Op Fl x
.Op Ar +mode
.Op Ar -mode
.Op Ar mode
.Xc
Control which tty modes that
.Nm
won't allow the user to change.
.Fl d ,
.Fl q
or
.Fl x
tells
.Ic setty
to act on the
.Sq edit ,
.Sq quote
or
.Sq execute
set of tty modes respectively; defaulting to
.Fl x .
.Pp
Without other arguments,
.Ic setty
lists the modes in the chosen set which are fixed on
.Po
.Sq +mode
.Pc
or off
.Po
.Sq -mode
.Pc .
.Fl a
lists all tty modes in the chosen set regardless of the setting.
With
.Ar +mode ,
.Ar -mode
or
.Ar mode ,
fixes
.Ar mode
on or off or removes control of
.Ar mode
in the chosen set.
.El
.Sh EDITOR COMMANDS
The following editor commands are available for use in key bindings:
.\" Section automatically generated with makelist
.Bl -tag -width 4n
.It Ic vi-paste-next
Vi paste previous deletion to the right of the cursor.
.It Ic vi-paste-prev
Vi paste previous deletion to the left of the cursor.
.It Ic vi-prev-space-word
Vi move to the previous space delimited word.
.It Ic vi-prev-word
Vi move to the previous word.
.It Ic vi-next-space-word
Vi move to the next space delimited word.
.It Ic vi-next-word
Vi move to the next word.
.It Ic vi-change-case
Vi change case of character under the cursor and advance one character.
.It Ic vi-change-meta
Vi change prefix command.
.It Ic vi-insert-at-bol
Vi enter insert mode at the beginning of line.
.It Ic vi-replace-char
Vi replace character under the cursor with the next character typed.
.It Ic vi-replace-mode
Vi enter replace mode.
.It Ic vi-substitute-char
Vi replace character under the cursor and enter insert mode.
.It Ic vi-substitute-line
Vi substitute entire line.
.It Ic vi-change-to-eol
Vi change to end of line.
.It Ic vi-insert
Vi enter insert mode.
.It Ic vi-add
Vi enter insert mode after the cursor.
.It Ic vi-add-at-eol
Vi enter insert mode at end of line.
.It Ic vi-delete-meta
Vi delete prefix command.
.It Ic vi-end-word
Vi move to the end of the current space delimited word.
.It Ic vi-to-end-word
Vi move to the end of the current word.
.It Ic vi-undo
Vi undo last change.
.It Ic vi-command-mode
Vi enter command mode (use alternative key bindings).
.It Ic vi-zero
Vi move to the beginning of line.
.It Ic vi-delete-prev-char
Vi move to previous character (backspace).
.It Ic vi-list-or-eof
Vi list choices for completion or indicate end of file if empty line.
.It Ic vi-kill-line-prev
Vi cut from beginning of line to cursor.
.It Ic vi-search-prev
Vi search history previous.
.It Ic vi-search-next
Vi search history next.
.It Ic vi-repeat-search-next
Vi repeat current search in the same search direction.
.It Ic vi-repeat-search-prev
Vi repeat current search in the opposite search direction.
.It Ic vi-next-char
Vi move to the character specified next.
.It Ic vi-prev-char
Vi move to the character specified previous.
.It Ic vi-to-next-char
Vi move up to the character specified next.
.It Ic vi-to-prev-char
Vi move up to the character specified previous.
.It Ic vi-repeat-next-char
Vi repeat current character search in the same search direction.
.It Ic vi-repeat-prev-char
Vi repeat current character search in the opposite search direction.
.It Ic em-delete-or-list
Delete character under cursor or list completions if at end of line.
.It Ic em-delete-next-word
Cut from cursor to end of current word.
.It Ic em-yank
Paste cut buffer at cursor position.
.It Ic em-kill-line
Cut the entire line and save in cut buffer.
.It Ic em-kill-region
Cut area between mark and cursor and save in cut buffer.
.It Ic em-copy-region
Copy area between mark and cursor to cut buffer.
.It Ic em-gosmacs-traspose
Exchange the two characters before the cursor.
.It Ic em-next-word
Move next to end of current word.
.It Ic em-upper-case
Uppercase the characters from cursor to end of current word.
.It Ic em-capitol-case
Capitalize the characters from cursor to end of current word.
.It Ic em-lower-case
Lowercase the characters from cursor to end of current word.
.It Ic em-set-mark
Set the mark at cursor.
.It Ic em-exchange-mark
Exchange the cursor and mark.
.It Ic em-universal-argument
Universal argument (argument times 4).
.It Ic em-meta-next
Add 8th bit to next character typed.
.It Ic em-toggle-overwrite
Switch from insert to overwrite mode or vice versa.
.It Ic em-copy-prev-word
Copy current word to cursor.
.It Ic em-inc-search-next
Emacs incremental next search.
.It Ic em-inc-search-prev
Emacs incremental reverse search.
.It Ic ed-end-of-file
Indicate end of file.
.It Ic ed-insert
Add character to the line.
.It Ic ed-delete-prev-word
Delete from beginning of current word to cursor.
.It Ic ed-delete-next-char
Delete character under cursor.
.It Ic ed-kill-line
Cut to the end of line.
.It Ic ed-move-to-end
Move cursor to the end of line.
.It Ic ed-move-to-beg
Move cursor to the beginning of line.
.It Ic ed-transpose-chars
Exchange the character to the left of the cursor with the one under it.
.It Ic ed-next-char
Move to the right one character.
.It Ic ed-prev-word
Move to the beginning of the current word.
.It Ic ed-prev-char
Move to the left one character.
.It Ic ed-quoted-insert
Add the next character typed verbatim.
.It Ic ed-digit
Adds to argument or enters a digit.
.It Ic ed-argument-digit
Digit that starts argument.
.It Ic ed-unassigned
Indicates unbound character.
.It Ic ed-tty-sigint
Tty interrupt character.
.It Ic ed-tty-dsusp
Tty delayed suspend character.
.It Ic ed-tty-flush-output
Tty flush output characters.
.It Ic ed-tty-sigquit
Tty quit character.
.It Ic ed-tty-sigtstp
Tty suspend character.
.It Ic ed-tty-stop-output
Tty disallow output characters.
.It Ic ed-tty-start-output
Tty allow output characters.
.It Ic ed-newline
Execute command.
.It Ic ed-delete-prev-char
Delete the character to the left of the cursor.
.It Ic ed-clear-screen
Clear screen leaving current line at the top.
.It Ic ed-redisplay
Redisplay everything.
.It Ic ed-start-over
Erase current line and start from scratch.
.It Ic ed-sequence-lead-in
First character in a bound sequence.
.It Ic ed-prev-history
Move to the previous history line.
.It Ic ed-next-history
Move to the next history line.
.It Ic ed-search-prev-history
Search previous in history for a line matching the current.
.It Ic ed-search-next-history
Search next in history for a line matching the current.
.It Ic ed-prev-line
Move up one line.
.It Ic ed-next-line
Move down one line.
.It Ic ed-command
Editline extended command.
.El
.\" End of section automatically generated with makelist
.Sh SEE ALSO
.Xr editline 3 ,
.Xr regex 3 ,
.Xr termcap 5
.Sh AUTHORS
The
.Nm editline
library was written by Christos Zoulas,
and this manual was written by Luke Mewburn,
with some sections inspired by
.Xr tcsh 1 .

View File

@ -1,4 +1,4 @@
/* $NetBSD: el.c,v 1.39 2004/07/08 00:51:36 christos Exp $ */ /* $NetBSD: el.c,v 1.47 2009/01/18 12:17:24 lukem Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)el.c 8.2 (Berkeley) 1/3/94";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* el.c: EditLine interface functions * el.c: EditLine interface functions
@ -58,9 +64,12 @@ el_init(const char *prog, FILE *fin, FILE *fout, FILE *ferr)
memset(el, 0, sizeof(EditLine)); memset(el, 0, sizeof(EditLine));
el->el_infd = fileno(fin); el->el_infile = fin;
el->el_outfile = fout; el->el_outfile = fout;
el->el_errfile = ferr; el->el_errfile = ferr;
el->el_infd = fileno(fin);
if ((el->el_prog = el_strdup(prog)) == NULL) { if ((el->el_prog = el_strdup(prog)) == NULL) {
el_free(el); el_free(el);
return NULL; return NULL;
@ -126,7 +135,7 @@ el_reset(EditLine *el)
{ {
tty_cookedmode(el); tty_cookedmode(el);
ch_reset(el); /* XXX: Do we want that? */ ch_reset(el, 0); /* XXX: Do we want that? */
} }
@ -136,29 +145,29 @@ el_reset(EditLine *el)
public int public int
el_set(EditLine *el, int op, ...) el_set(EditLine *el, int op, ...)
{ {
va_list va; va_list ap;
int rv = 0; int rv = 0;
if (el == NULL) if (el == NULL)
return (-1); return (-1);
va_start(va, op); va_start(ap, op);
switch (op) { switch (op) {
case EL_PROMPT: case EL_PROMPT:
case EL_RPROMPT: case EL_RPROMPT:
rv = prompt_set(el, va_arg(va, el_pfunc_t), op); rv = prompt_set(el, va_arg(ap, el_pfunc_t), op);
break; break;
case EL_TERMINAL: case EL_TERMINAL:
rv = term_set(el, va_arg(va, char *)); rv = term_set(el, va_arg(ap, char *));
break; break;
case EL_EDITOR: case EL_EDITOR:
rv = map_set_editor(el, va_arg(va, char *)); rv = map_set_editor(el, va_arg(ap, char *));
break; break;
case EL_SIGNAL: case EL_SIGNAL:
if (va_arg(va, int)) if (va_arg(ap, int))
el->el_flags |= HANDLE_SIGNALS; el->el_flags |= HANDLE_SIGNALS;
else else
el->el_flags &= ~HANDLE_SIGNALS; el->el_flags &= ~HANDLE_SIGNALS;
@ -167,6 +176,7 @@ el_set(EditLine *el, int op, ...)
case EL_BIND: case EL_BIND:
case EL_TELLTC: case EL_TELLTC:
case EL_SETTC: case EL_SETTC:
case EL_GETTC:
case EL_ECHOTC: case EL_ECHOTC:
case EL_SETTY: case EL_SETTY:
{ {
@ -174,7 +184,7 @@ el_set(EditLine *el, int op, ...)
int i; int i;
for (i = 1; i < 20; i++) for (i = 1; i < 20; i++)
if ((argv[i] = va_arg(va, char *)) == NULL) if ((argv[i] = va_arg(ap, char *)) == NULL)
break; break;
switch (op) { switch (op) {
@ -213,9 +223,9 @@ el_set(EditLine *el, int op, ...)
case EL_ADDFN: case EL_ADDFN:
{ {
char *name = va_arg(va, char *); char *name = va_arg(ap, char *);
char *help = va_arg(va, char *); char *help = va_arg(ap, char *);
el_func_t func = va_arg(va, el_func_t); el_func_t func = va_arg(ap, el_func_t);
rv = map_addfunc(el, name, help, func); rv = map_addfunc(el, name, help, func);
break; break;
@ -223,15 +233,15 @@ el_set(EditLine *el, int op, ...)
case EL_HIST: case EL_HIST:
{ {
hist_fun_t func = va_arg(va, hist_fun_t); hist_fun_t func = va_arg(ap, hist_fun_t);
ptr_t ptr = va_arg(va, char *); ptr_t ptr = va_arg(ap, char *);
rv = hist_set(el, func, ptr); rv = hist_set(el, func, ptr);
break; break;
} }
case EL_EDITMODE: case EL_EDITMODE:
if (va_arg(va, int)) if (va_arg(ap, int))
el->el_flags &= ~EDIT_DISABLED; el->el_flags &= ~EDIT_DISABLED;
else else
el->el_flags |= EDIT_DISABLED; el->el_flags |= EDIT_DISABLED;
@ -240,17 +250,17 @@ el_set(EditLine *el, int op, ...)
case EL_GETCFN: case EL_GETCFN:
{ {
el_rfunc_t rc = va_arg(va, el_rfunc_t); el_rfunc_t rc = va_arg(ap, el_rfunc_t);
rv = el_read_setfn(el, rc); rv = el_read_setfn(el, rc);
break; break;
} }
case EL_CLIENTDATA: case EL_CLIENTDATA:
el->el_data = va_arg(va, void *); el->el_data = va_arg(ap, void *);
break; break;
case EL_UNBUFFERED: case EL_UNBUFFERED:
rv = va_arg(va, int); rv = va_arg(ap, int);
if (rv && !(el->el_flags & UNBUFFERED)) { if (rv && !(el->el_flags & UNBUFFERED)) {
el->el_flags |= UNBUFFERED; el->el_flags |= UNBUFFERED;
read_prepare(el); read_prepare(el);
@ -262,7 +272,7 @@ el_set(EditLine *el, int op, ...)
break; break;
case EL_PREP_TERM: case EL_PREP_TERM:
rv = va_arg(va, int); rv = va_arg(ap, int);
if (rv) if (rv)
(void) tty_rawmode(el); (void) tty_rawmode(el);
else else
@ -270,12 +280,45 @@ el_set(EditLine *el, int op, ...)
rv = 0; rv = 0;
break; break;
case EL_SETFP:
{
FILE *fp;
int what;
what = va_arg(ap, int);
fp = va_arg(ap, FILE *);
rv = 0;
switch (what) {
case 0:
el->el_infile = fp;
el->el_infd = fileno(fp);
break;
case 1:
el->el_outfile = fp;
break;
case 2:
el->el_errfile = fp;
break;
default:
rv = -1;
break;
}
break;
}
case EL_REFRESH:
re_clear_display(el);
re_refresh(el);
term__flush(el);
break;
default: default:
rv = -1; rv = -1;
break; break;
} }
va_end(va); va_end(ap);
return (rv); return (rv);
} }
@ -284,90 +327,71 @@ el_set(EditLine *el, int op, ...)
* retrieve the editline parameters * retrieve the editline parameters
*/ */
public int public int
el_get(EditLine *el, int op, void *ret) el_get(EditLine *el, int op, ...)
{ {
va_list ap;
int rv; int rv;
if (el == NULL || ret == NULL) if (el == NULL)
return (-1); return -1;
va_start(ap, op);
switch (op) { switch (op) {
case EL_PROMPT: case EL_PROMPT:
case EL_RPROMPT: case EL_RPROMPT:
rv = prompt_get(el, (void *) &ret, op); rv = prompt_get(el, va_arg(ap, el_pfunc_t *), op);
break; break;
case EL_EDITOR: case EL_EDITOR:
rv = map_get_editor(el, (void *) &ret); rv = map_get_editor(el, va_arg(ap, const char **));
break; break;
case EL_SIGNAL: case EL_SIGNAL:
*((int *) ret) = (el->el_flags & HANDLE_SIGNALS); *va_arg(ap, int *) = (el->el_flags & HANDLE_SIGNALS);
rv = 0; rv = 0;
break; break;
case EL_EDITMODE: case EL_EDITMODE:
*((int *) ret) = (!(el->el_flags & EDIT_DISABLED)); *va_arg(ap, int *) = !(el->el_flags & EDIT_DISABLED);
rv = 0; rv = 0;
break; break;
case EL_TERMINAL: case EL_TERMINAL:
term_get(el, (const char **)ret); term_get(el, va_arg(ap, const char **));
rv = 0; rv = 0;
break; break;
#if 0 /* XXX */ case EL_GETTC:
case EL_BIND:
case EL_TELLTC:
case EL_SETTC:
case EL_ECHOTC:
case EL_SETTY:
{ {
const char *argv[20]; static char name[] = "gettc";
char *argv[20];
int i; int i;
for (i = 1; i < sizeof(argv) / sizeof(argv[0]); i++) for (i = 1; i < (int)(sizeof(argv) / sizeof(argv[0])); i++)
if ((argv[i] = va_arg(va, char *)) == NULL) if ((argv[i] = va_arg(ap, char *)) == NULL)
break; break;
switch (op) { switch (op) {
case EL_BIND: case EL_GETTC:
argv[0] = "bind"; argv[0] = name;
rv = map_bind(el, i, argv); rv = term_gettc(el, i, argv);
break;
case EL_TELLTC:
argv[0] = "telltc";
rv = term_telltc(el, i, argv);
break;
case EL_SETTC:
argv[0] = "settc";
rv = term_settc(el, i, argv);
break;
case EL_ECHOTC:
argv[0] = "echotc";
rv = term_echotc(el, i, argv);
break;
case EL_SETTY:
argv[0] = "setty";
rv = tty_stty(el, i, argv);
break; break;
default: default:
rv = -1; rv = -1;
EL_ABORT((el->errfile, "Bad op %d\n", op)); EL_ABORT((el->el_errfile, "Bad op %d\n", op));
break; break;
} }
break; break;
} }
#if 0 /* XXX */
case EL_ADDFN: case EL_ADDFN:
{ {
char *name = va_arg(va, char *); char *name = va_arg(ap, char *);
char *help = va_arg(va, char *); char *help = va_arg(ap, char *);
el_func_t func = va_arg(va, el_func_t); el_func_t func = va_arg(ap, el_func_t);
rv = map_addfunc(el, name, help, func); rv = map_addfunc(el, name, help, func);
break; break;
@ -375,31 +399,57 @@ el_get(EditLine *el, int op, void *ret)
case EL_HIST: case EL_HIST:
{ {
hist_fun_t func = va_arg(va, hist_fun_t); hist_fun_t func = va_arg(ap, hist_fun_t);
ptr_t ptr = va_arg(va, char *); ptr_t ptr = va_arg(ap, char *);
rv = hist_set(el, func, ptr); rv = hist_set(el, func, ptr);
} }
break; break;
#endif /* XXX */ #endif /* XXX */
case EL_GETCFN: case EL_GETCFN:
*((el_rfunc_t *)ret) = el_read_getfn(el); *va_arg(ap, el_rfunc_t *) = el_read_getfn(el);
rv = 0; rv = 0;
break; break;
case EL_CLIENTDATA: case EL_CLIENTDATA:
*((void **)ret) = el->el_data; *va_arg(ap, void **) = el->el_data;
rv = 0; rv = 0;
break; break;
case EL_UNBUFFERED: case EL_UNBUFFERED:
*((int *) ret) = (!(el->el_flags & UNBUFFERED)); *va_arg(ap, int *) = (!(el->el_flags & UNBUFFERED));
rv = 0; rv = 0;
break; break;
case EL_GETFP:
{
int what;
FILE **fpp;
what = va_arg(ap, int);
fpp = va_arg(ap, FILE **);
rv = 0;
switch (what) {
case 0:
*fpp = el->el_infile;
break;
case 1:
*fpp = el->el_outfile;
break;
case 2:
*fpp = el->el_errfile;
break;
default:
rv = -1;
break;
}
break;
}
default: default:
rv = -1; rv = -1;
break;
} }
va_end(ap);
return (rv); return (rv);
} }
@ -428,17 +478,17 @@ el_source(EditLine *el, const char *fname)
fp = NULL; fp = NULL;
if (fname == NULL) { if (fname == NULL) {
#ifdef HAVE_ISSETUGID
static const char elpath[] = "/.editrc"; static const char elpath[] = "/.editrc";
/* XXXMYSQL: Portability fix (for which platforms?) */
#ifdef MAXPATHLEN #ifdef MAXPATHLEN
char path[MAXPATHLEN]; char path[MAXPATHLEN];
#else #else
char path[4096]; char path[4096];
#endif #endif
#ifdef HAVE_ISSETUGID
if (issetugid()) if (issetugid())
return (-1); return (-1);
#endif
if ((ptr = getenv("HOME")) == NULL) if ((ptr = getenv("HOME")) == NULL)
return (-1); return (-1);
if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path)) if (strlcpy(path, ptr, sizeof(path)) >= sizeof(path))
@ -446,6 +496,14 @@ el_source(EditLine *el, const char *fname)
if (strlcat(path, elpath, sizeof(path)) >= sizeof(path)) if (strlcat(path, elpath, sizeof(path)) >= sizeof(path))
return (-1); return (-1);
fname = path; 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) if (fp == NULL)
fp = fopen(fname, "r"); fp = fopen(fname, "r");

View File

@ -1,4 +1,4 @@
/* $NetBSD: el.h,v 1.16 2003/10/18 23:48:42 christos Exp $ */ /* $NetBSD: el.h,v 1.17 2006/12/15 22:13:33 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -110,6 +110,7 @@ typedef struct el_state_t {
struct editline { struct editline {
char *el_prog; /* the program name */ char *el_prog; /* the program name */
FILE *el_infile; /* Stdio stuff */
FILE *el_outfile; /* Stdio stuff */ FILE *el_outfile; /* Stdio stuff */
FILE *el_errfile; /* Stdio stuff */ FILE *el_errfile; /* Stdio stuff */
int el_infd; /* Input file descriptor */ int el_infd; /* Input file descriptor */
@ -136,7 +137,8 @@ struct editline {
protected int el_editmode(EditLine *, int, const char **); protected int el_editmode(EditLine *, int, const char **);
#define el_isprint(x) ((unsigned char) (x) < 0x80 ? isprint(x) : 1) /* XXXMYSQL: Bug#23097 mysql can't insert korean on mysql prompt. */
#define el_isprint(x) ((unsigned char) (x) < 0x80 ? isprint(x) : 1)
#ifdef DEBUG #ifdef DEBUG
#define EL_ABORT(a) do { \ #define EL_ABORT(a) do { \

View File

@ -1,4 +1,4 @@
/* $NetBSD: term.h,v 1.15 2003/09/14 21:48:55 christos Exp $ */ /* $NetBSD: term.h,v 1.19 2008/09/10 15:45:37 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -81,25 +81,6 @@ typedef struct {
#define A_K_EN 5 #define A_K_EN 5
#define A_K_NKEYS 6 #define A_K_NKEYS 6
#ifdef _SUNOS
extern int tgetent(char *, const char *);
extern int tgetflag(char *);
extern int tgetnum(char *);
extern int tputs(const char *, int, int (*)(int));
extern char* tgoto(const char*, int, int);
extern char* tgetstr(char*, char**);
#endif
#if !HAVE_DECL_TGOTO
/*
'tgoto' is not declared in the system header files, this causes
problems on 64-bit systems. The function returns a 64 bit pointer
but caller see it as "int" and it's thus truncated to 32-bit
*/
extern char* tgoto(const char*, int, int);
#endif
protected void term_move_to_line(EditLine *, int); protected void term_move_to_line(EditLine *, int);
protected void term_move_to_char(EditLine *, int); protected void term_move_to_char(EditLine *, int);
protected void term_clear_EOL(EditLine *, int); protected void term_clear_EOL(EditLine *, int);
@ -119,10 +100,12 @@ protected void term_end(EditLine *);
protected void term_get(EditLine *, const char **); protected void term_get(EditLine *, const char **);
protected int term_set(EditLine *, const char *); protected int term_set(EditLine *, const char *);
protected int term_settc(EditLine *, int, const char **); protected int term_settc(EditLine *, int, const char **);
protected int term_gettc(EditLine *, int, char **);
protected int term_telltc(EditLine *, int, const char **); protected int term_telltc(EditLine *, int, const char **);
protected int term_echotc(EditLine *, int, const char **); protected int term_echotc(EditLine *, int, const char **);
protected int term__putc(int); protected void term_writec(EditLine *, int);
protected void term__flush(void); protected int term__putc(EditLine *, int);
protected void term__flush(EditLine *);
/* /*
* Easy access macros * Easy access macros
@ -134,6 +117,7 @@ protected void term__flush(void);
#define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL) #define EL_CAN_CEOL (EL_FLAGS & TERM_CAN_CEOL)
#define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB) #define EL_CAN_TAB (EL_FLAGS & TERM_CAN_TAB)
#define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME) #define EL_CAN_ME (EL_FLAGS & TERM_CAN_ME)
#define EL_CAN_UP (EL_FLAGS & TERM_CAN_UP)
#define EL_HAS_META (EL_FLAGS & TERM_HAS_META) #define EL_HAS_META (EL_FLAGS & TERM_HAS_META)
#define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS) #define EL_HAS_AUTO_MARGINS (EL_FLAGS & TERM_HAS_AUTO_MARGINS)
#define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS) #define EL_HAS_MAGIC_MARGINS (EL_FLAGS & TERM_HAS_MAGIC_MARGINS)

View File

@ -1,4 +1,4 @@
/* $NetBSD: emacs.c,v 1.19 2004/10/28 21:14:52 dsl Exp $ */ /* $NetBSD: emacs.c,v 1.21 2006/03/06 21:11:56 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)emacs.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* emacs.c: Emacs functions * emacs.c: Emacs functions
@ -45,15 +51,14 @@
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
em_delete_or_list(EditLine *el, int c __attribute__((__unused__))) em_delete_or_list(EditLine *el, int c)
{ {
if (el->el_line.cursor == el->el_line.lastchar) { if (el->el_line.cursor == el->el_line.lastchar) {
/* if I'm at the end */ /* if I'm at the end */
if (el->el_line.cursor == el->el_line.buffer) { if (el->el_line.cursor == el->el_line.buffer) {
/* and the beginning */ /* and the beginning */
term_overwrite(el, STReof, 4); /* then do a EOF */ term_writec(el, c); /* then do an EOF */
term__flush();
return (CC_EOF); return (CC_EOF);
} else { } else {
/* /*

View File

@ -1,3 +0,0 @@
#include <stdio.h>
char *fgetln(FILE *stream, size_t *len);

View File

@ -0,0 +1,558 @@
/* $NetBSD: filecomplete.c,v 1.13 2009/01/26 17:32:41 apb Exp $ */
/*-
* Copyright (c) 1997 The NetBSD Foundation, Inc.
* All rights reserved.
*
* This code is derived from software contributed to The NetBSD Foundation
* by Jaromir Dolecek.
*
* 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.
*
* 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.
*/
/* AIX requires this to be the first thing in the file. */
#if defined (_AIX) && !defined (__GNUC__)
#pragma alloca
#endif
#include "config.h"
/* XXXMYSQL */
#ifdef __GNUC__
# undef alloca
# define alloca(n) __builtin_alloca (n)
#else
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifndef _AIX
extern char *alloca ();
# endif
# endif
#endif
#if !defined(lint) && !defined(SCCSID)
#endif /* not lint && not SCCSID */
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <dirent.h>
#include <string.h>
#include <pwd.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include <fcntl.h>
#ifdef HAVE_VIS_H
#include <vis.h>
#else
#include "np/vis.h"
#endif
#ifdef HAVE_ALLOCA_H
#include <alloca.h>
#endif
#include "el.h"
#include "fcns.h" /* for EL_NUM_FCNS */
#include "histedit.h"
#include "filecomplete.h"
static char break_chars[] = { ' ', '\t', '\n', '"', '\\', '\'', '`', '@', '$',
'>', '<', '=', ';', '|', '&', '{', '(', '\0' };
/********************************/
/* completion functions */
/*
* does tilde expansion of strings of type ``~user/foo''
* if ``user'' isn't valid user name or ``txt'' doesn't start
* w/ '~', returns pointer to strdup()ed copy of ``txt''
*
* it's callers's responsibility to free() returned string
*/
char *
fn_tilde_expand(const char *txt)
{
struct passwd pwres, *pass;
char *temp;
size_t len = 0;
char pwbuf[1024];
if (txt[0] != '~')
return (strdup(txt));
temp = strchr(txt + 1, '/');
if (temp == NULL) {
temp = strdup(txt + 1);
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';
}
/* XXXMYSQL: use non-_r functions for now */
if (temp[0] == 0) {
pass = getpwuid(getuid());
} else {
pass = getpwnam(temp);
}
free(temp); /* value no more needed */
if (pass == NULL)
return (strdup(txt));
/* update pointer txt to point at string immedially following */
/* first slash */
txt += len;
temp = malloc(strlen(pass->pw_dir) + 1 + strlen(txt) + 1);
if (temp == NULL)
return NULL;
(void)sprintf(temp, "%s/%s", pass->pw_dir, txt);
return (temp);
}
/*
* return first found file name starting by the ``text'' or NULL if no
* such file can be found
* value of ``state'' is ignored
*
* it's caller's responsibility to free returned string
*/
char *
fn_filename_completion_function(const char *text, int state)
{
static DIR *dir = NULL;
static char *filename = NULL, *dirname = NULL, *dirpath = NULL;
static size_t filename_len = 0;
struct dirent *entry;
char *temp;
size_t len;
if (state == 0 || dir == NULL) {
temp = strrchr(text, '/');
if (temp) {
char *nptr;
temp++;
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 */
nptr = realloc(dirname, len + 1);
if (nptr == NULL) {
free(filename);
return NULL;
}
dirname = nptr;
(void)strncpy(dirname, text, len);
dirname[len] = '\0';
} else {
if (*text == 0)
filename = NULL;
else {
filename = strdup(text);
if (filename == NULL)
return NULL;
}
dirname = NULL;
}
if (dir != NULL) {
(void)closedir(dir);
dir = NULL;
}
/* support for ``~user'' syntax */
free(dirpath);
if (dirname == NULL && (dirname = strdup("./")) == NULL)
return NULL;
if (*dirname == '~')
dirpath = fn_tilde_expand(dirname);
else
dirpath = strdup(dirname);
if (dirpath == NULL)
return NULL;
dir = opendir(dirpath);
if (!dir)
return (NULL); /* cannot open the directory */
/* will be used in cycle */
filename_len = filename ? strlen(filename) : 0;
}
/* find the match */
while ((entry = readdir(dir)) != NULL) {
/* skip . and .. */
if (entry->d_name[0] == '.' && (!entry->d_name[1]
|| (entry->d_name[1] == '.' && !entry->d_name[2])))
continue;
if (filename_len == 0)
break;
/* otherwise, get first entry where first */
/* filename_len characters are equal */
if (entry->d_name[0] == filename[0]
#if HAVE_STRUCT_DIRENT_D_NAMLEN
&& entry->d_namlen >= filename_len
#else
&& strlen(entry->d_name) >= filename_len
#endif
&& strncmp(entry->d_name, filename,
filename_len) == 0)
break;
}
if (entry) { /* match found */
#if HAVE_STRUCT_DIRENT_D_NAMLEN
len = entry->d_namlen;
#else
len = strlen(entry->d_name);
#endif
temp = malloc(strlen(dirname) + len + 1);
if (temp == NULL)
return NULL;
(void)sprintf(temp, "%s%s", dirname, entry->d_name);
} else {
(void)closedir(dir);
dir = NULL;
temp = NULL;
}
return (temp);
}
static const char *
append_char_function(const char *name)
{
struct stat stbuf;
char *expname = *name == '~' ? fn_tilde_expand(name) : NULL;
const char *rs = " ";
if (stat(expname ? expname : name, &stbuf) == -1)
goto out;
if (S_ISDIR(stbuf.st_mode))
rs = "/";
out:
if (expname)
free(expname);
return rs;
}
/*
* returns list of completions for text given
* non-static for readline.
*/
char ** completion_matches(const char *, char *(*)(const char *, int));
char **
completion_matches(const char *text, char *(*genfunc)(const char *, int))
{
char **match_list = NULL, *retstr, *prevstr;
size_t match_list_len, max_equal, which, i;
size_t matches;
matches = 0;
match_list_len = 1;
while ((retstr = (*genfunc) (text, (int)matches)) != NULL) {
/* allow for list terminator here */
if (matches + 3 >= match_list_len) {
char **nmatch_list;
while (matches + 3 >= match_list_len)
match_list_len <<= 1;
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 NULL; /* nothing found */
/* find least denominator and insert it to match_list[0] */
which = 2;
prevstr = match_list[1];
max_equal = strlen(prevstr);
for (; which <= matches; which++) {
for (i = 0; i < max_equal &&
prevstr[i] == match_list[which][i]; i++)
continue;
max_equal = i;
}
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 */
match_list[matches + 1] = (char *) NULL;
return (match_list);
}
/*
* Sort function for qsort(). Just wrapper around strcasecmp().
*/
static int
_fn_qsort_string_compare(const void *i1, const void *i2)
{
const char *s1 = ((const char * const *)i1)[0];
const char *s2 = ((const char * const *)i2)[0];
return strcasecmp(s1, s2);
}
/*
* Display list of strings in columnar format on readline's output stream.
* 'matches' is list of strings, 'len' is number of strings in 'matches',
* 'max' is maximum length of string in 'matches'.
*/
void
fn_display_match_list (EditLine *el, char **matches, int len, int max)
{
int i, idx, limit, count;
int screenwidth = el->el_term.t_size.h;
/*
* Find out how many entries can be put on one line, count
* with two spaces between strings.
*/
limit = screenwidth / (max + 2);
if (limit == 0)
limit = 1;
/* how many lines of output */
count = len / limit;
if (count * limit < len)
count++;
/* Sort the items if they are not already sorted. */
qsort(&matches[1], (size_t)(len - 1), sizeof(char *),
_fn_qsort_string_compare);
idx = 1;
for(; count > 0; count--) {
for(i = 0; i < limit && matches[idx]; i++, idx++)
(void)fprintf(el->el_outfile, "%-*s ", max,
matches[idx]);
(void)fprintf(el->el_outfile, "\n");
}
}
/*
* Complete the word at or before point,
* 'what_to_do' says what to do with the completion.
* \t means do standard completion.
* `?' means list the possible completions.
* `*' means insert all of the possible completions.
* `!' means to do standard completion, and list all possible completions if
* there is more than one.
*
* Note: '*' support is not implemented
* '!' could never be invoked
*/
int
fn_complete(EditLine *el,
char *(*complet_func)(const char *, int),
char **(*attempted_completion_function)(const char *, int, int),
const char *word_break, const char *special_prefixes,
const char *(*app_func)(const char *), int query_items,
int *completion_type, int *over, int *point, int *end)
{
const LineInfo *li;
char *temp, **matches;
const char *ctemp;
size_t len;
int what_to_do = '\t';
int retval = CC_NORM;
if (el->el_state.lastcmd == el->el_state.thiscmd)
what_to_do = '?';
/* readline's rl_complete() has to be told what we did... */
if (completion_type != NULL)
*completion_type = what_to_do;
if (!complet_func)
complet_func = fn_filename_completion_function;
if (!app_func)
app_func = append_char_function;
/* We now look backwards for the start of a filename/variable word */
li = el_line(el);
ctemp = (const char *) li->cursor;
while (ctemp > li->buffer
&& !strchr(word_break, ctemp[-1])
&& (!special_prefixes || !strchr(special_prefixes, ctemp[-1]) ) )
ctemp--;
len = li->cursor - ctemp;
#if defined(__SSP__) || defined(__SSP_ALL__)
temp = malloc(len + 1);
#else
temp = alloca(len + 1);
#endif
(void)strncpy(temp, ctemp, len);
temp[len] = '\0';
/* these can be used by function called in completion_matches() */
/* or (*attempted_completion_function)() */
if (point != 0)
*point = li->cursor - li->buffer;
if (end != NULL)
*end = li->lastchar - li->buffer;
if (attempted_completion_function) {
int cur_off = li->cursor - li->buffer;
matches = (*attempted_completion_function) (temp,
(int)(cur_off - len), cur_off);
} else
matches = 0;
if (!attempted_completion_function ||
(over != NULL && !*over && !matches))
matches = completion_matches(temp, complet_func);
if (over != NULL)
*over = 0;
if (matches) {
int i;
int matches_num, maxlen, match_len, match_display=1;
retval = CC_REFRESH;
/*
* Only replace the completed string with common part of
* possible matches if there is possible completion.
*/
if (matches[0][0] != '\0') {
el_deletestr(el, (int) len);
el_insertstr(el, matches[0]);
}
if (what_to_do == '?')
goto display_matches;
if (matches[2] == NULL && strcmp(matches[0], matches[1]) == 0) {
/*
* We found exact match. Add a space after
* it, unless we do filename completion and the
* object is a directory.
*/
el_insertstr(el, (*app_func)(matches[0]));
} else if (what_to_do == '!') {
display_matches:
/*
* More than one match and requested to list possible
* matches.
*/
for(i=1, maxlen=0; matches[i]; i++) {
match_len = strlen(matches[i]);
if (match_len > maxlen)
maxlen = match_len;
}
matches_num = i - 1;
/* newline to get on next line from command line */
(void)fprintf(el->el_outfile, "\n");
/*
* If there are too many items, ask user for display
* confirmation.
*/
if (matches_num > query_items) {
(void)fprintf(el->el_outfile,
"Display all %d possibilities? (y or n) ",
matches_num);
(void)fflush(el->el_outfile);
if (getc(stdin) != 'y')
match_display = 0;
(void)fprintf(el->el_outfile, "\n");
}
if (match_display)
fn_display_match_list(el, matches, matches_num,
maxlen);
retval = CC_REDISPLAY;
} else if (matches[0][0]) {
/*
* There was some common match, but the name was
* not complete enough. Next tab will print possible
* completions.
*/
el_beep(el);
} else {
/* lcd is not a valid object - further specification */
/* is needed */
el_beep(el);
retval = CC_NORM;
}
/* free elements of array and the array itself */
for (i = 0; matches[i]; i++)
free(matches[i]);
free(matches);
matches = NULL;
}
#if defined(__SSP__) || defined(__SSP_ALL__)
free(temp);
#endif
return retval;
}
/*
* el-compatible wrapper around rl_complete; needed for key binding
*/
/* ARGSUSED */
unsigned char
_el_fn_complete(EditLine *el, int ch __attribute__((__unused__)))
{
return (unsigned char)fn_complete(el, NULL, NULL,
break_chars, NULL, NULL, 100,
NULL, NULL, NULL, NULL);
}

View File

@ -1,11 +1,11 @@
/* $NetBSD: fgetln.c,v 1.2 2003/12/10 01:30:27 lukem Exp $ */ /* $NetBSD: filecomplete.h,v 1.6 2008/04/29 06:53:01 martin Exp $ */
/*- /*-
* Copyright (c) 1998 The NetBSD Foundation, Inc. * Copyright (c) 1997 The NetBSD Foundation, Inc.
* All rights reserved. * All rights reserved.
* *
* This code is derived from software contributed to The NetBSD Foundation * This code is derived from software contributed to The NetBSD Foundation
* by Christos Zoulas. * by Jaromir Dolecek.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -15,13 +15,6 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@ -35,54 +28,17 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef _FILECOMPLETE_H_
#define _FILECOMPLETE_H_
#include <config.h> int fn_complete(EditLine *,
#include <stdio.h> char *(*)(const char *, int),
#include <stdlib.h> char **(*)(const char *, int, int),
#include <unistd.h> const char *, const char *, const char *(*)(const char *), int,
#include <errno.h> int *, int *, int *, int *);
#include <string.h>
void fn_display_match_list(EditLine *, char **, int, int);
char *fn_tilde_expand(const char *);
char *fn_filename_completion_function(const char *, int);
char * #endif
fgetln(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;
}

View File

@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)hist.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* hist.c: History access functions * hist.c: History access functions

View File

@ -1,4 +1,4 @@
/* $NetBSD: histedit.h,v 1.25 2003/12/05 13:37:48 lukem Exp $ */ /* $NetBSD: histedit.h,v 1.35 2009/02/05 19:15:44 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -41,11 +41,15 @@
#define _HISTEDIT_H_ #define _HISTEDIT_H_
#define LIBEDIT_MAJOR 2 #define LIBEDIT_MAJOR 2
#define LIBEDIT_MINOR 9 #define LIBEDIT_MINOR 11
#include <sys/types.h> #include <sys/types.h>
#include <stdio.h> #include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/* /*
* ==== Editing ==== * ==== Editing ====
*/ */
@ -88,7 +92,7 @@ void el_reset(EditLine *);
*/ */
const char *el_gets(EditLine *, int *); const char *el_gets(EditLine *, int *);
int el_getc(EditLine *, char *); int el_getc(EditLine *, char *);
void el_push(EditLine *, char *); void el_push(EditLine *, const char *);
/* /*
* Beep! * Beep!
@ -105,7 +109,8 @@ int el_parse(EditLine *, int, const char **);
* Low level editline access functions * Low level editline access functions
*/ */
int el_set(EditLine *, int, ...); int el_set(EditLine *, int, ...);
int el_get(EditLine *, int, void *); int el_get(EditLine *, int, ...);
unsigned char _el_fn_complete(EditLine *, int);
/* /*
* el_set/el_get parameters * el_set/el_get parameters
@ -128,8 +133,12 @@ int el_get(EditLine *, int, void *);
#define EL_CLIENTDATA 14 /* , void *); */ #define EL_CLIENTDATA 14 /* , void *); */
#define EL_UNBUFFERED 15 /* , int); */ #define EL_UNBUFFERED 15 /* , int); */
#define EL_PREP_TERM 16 /* , int); */ #define EL_PREP_TERM 16 /* , int); */
#define EL_GETTC 17 /* , const char *, ..., NULL); */
#define EL_GETFP 18 /* , int, FILE **); */
#define EL_SETFP 19 /* , int, FILE *); */
#define EL_REFRESH 20 /* , void); */
#define EL_BUILTIN_GETCFN (NULL) #define EL_BUILTIN_GETCFN (NULL)
/* /*
* Source named file or $PWD/.editrc or $HOME/.editrc * Source named file or $PWD/.editrc or $HOME/.editrc
@ -192,6 +201,7 @@ int history(History *, HistEvent *, int, ...);
#define H_CLEAR 19 /* , void); */ #define H_CLEAR 19 /* , void); */
#define H_SETUNIQUE 20 /* , int); */ #define H_SETUNIQUE 20 /* , int); */
#define H_GETUNIQUE 21 /* , void); */ #define H_GETUNIQUE 21 /* , void); */
#define H_DEL 22 /* , int); */
/* /*
@ -211,4 +221,8 @@ int tok_line(Tokenizer *, const LineInfo *,
int tok_str(Tokenizer *, const char *, int tok_str(Tokenizer *, const char *,
int *, const char ***); int *, const char ***);
#ifdef __cplusplus
}
#endif
#endif /* _HISTEDIT_H_ */ #endif /* _HISTEDIT_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: history.c,v 1.28 2004/11/27 18:31:45 christos Exp $ */ /* $NetBSD: history.c,v 1.33 2009/02/06 14:40:32 sketch Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)history.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* hist.c: History access functions * hist.c: History access functions
@ -40,7 +46,11 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#ifdef HAVE_VIS_H
#include <vis.h> #include <vis.h>
#else
#include "np/vis.h"
#endif
#include <sys/stat.h> #include <sys/stat.h>
static const char hist_cookie[] = "_HiStOrY_V2_\n"; static const char hist_cookie[] = "_HiStOrY_V2_\n";
@ -61,6 +71,7 @@ struct history {
history_gfun_t h_prev; /* Get the previous element */ history_gfun_t h_prev; /* Get the previous element */
history_gfun_t h_curr; /* Get the current element */ history_gfun_t h_curr; /* Get the current element */
history_sfun_t h_set; /* Set the current element */ history_sfun_t h_set; /* Set the current element */
history_sfun_t h_del; /* Set the given element */
history_vfun_t h_clear; /* Clear the history list */ history_vfun_t h_clear; /* Clear the history list */
history_efun_t h_enter; /* Add an element */ history_efun_t h_enter; /* Add an element */
history_efun_t h_add; /* Append to an element */ history_efun_t h_add; /* Append to an element */
@ -75,6 +86,7 @@ struct history {
#define HCLEAR(h, ev) (*(h)->h_clear)((h)->h_ref, ev) #define HCLEAR(h, ev) (*(h)->h_clear)((h)->h_ref, ev)
#define HENTER(h, ev, str) (*(h)->h_enter)((h)->h_ref, ev, str) #define HENTER(h, ev, str) (*(h)->h_enter)((h)->h_ref, ev, str)
#define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str) #define HADD(h, ev, str) (*(h)->h_add)((h)->h_ref, ev, str)
#define HDEL(h, ev, n) (*(h)->h_del)((h)->h_ref, ev, n)
#define h_strdup(a) strdup(a) #define h_strdup(a) strdup(a)
#define h_malloc(a) malloc(a) #define h_malloc(a) malloc(a)
@ -122,16 +134,18 @@ typedef struct history_t {
#define H_UNIQUE 1 /* Store only unique elements */ #define H_UNIQUE 1 /* Store only unique elements */
} history_t; } history_t;
private int history_def_first(ptr_t, HistEvent *);
private int history_def_last(ptr_t, HistEvent *);
private int history_def_next(ptr_t, HistEvent *); private int history_def_next(ptr_t, HistEvent *);
private int history_def_first(ptr_t, HistEvent *);
private int history_def_prev(ptr_t, HistEvent *); private int history_def_prev(ptr_t, HistEvent *);
private int history_def_last(ptr_t, HistEvent *);
private int history_def_curr(ptr_t, HistEvent *); private int history_def_curr(ptr_t, HistEvent *);
private int history_def_set(ptr_t, HistEvent *, const int n); private int history_def_set(ptr_t, HistEvent *, const int);
private void history_def_clear(ptr_t, HistEvent *);
private int history_def_enter(ptr_t, HistEvent *, const char *); private int history_def_enter(ptr_t, HistEvent *, const char *);
private int history_def_add(ptr_t, HistEvent *, const char *); private int history_def_add(ptr_t, HistEvent *, const char *);
private int history_def_del(ptr_t, HistEvent *, const int);
private int history_def_init(ptr_t *, HistEvent *, int); private int history_def_init(ptr_t *, HistEvent *, int);
private void history_def_clear(ptr_t, HistEvent *);
private int history_def_insert(history_t *, HistEvent *, const char *); private int history_def_insert(history_t *, HistEvent *, const char *);
private void history_def_delete(history_t *, HistEvent *, hentry_t *); private void history_def_delete(history_t *, HistEvent *, hentry_t *);
@ -353,6 +367,24 @@ history_def_add(ptr_t p, HistEvent *ev, const char *str)
} }
/* history_def_del():
* Delete element hp of the h list
*/
/* ARGSUSED */
private int
history_def_del(ptr_t p, HistEvent *ev __attribute__((__unused__)),
const int num)
{
history_t *h = (history_t *) p;
if (history_def_set(h, ev, num) != 0)
return (-1);
ev->str = strdup(h->cursor->ev.str);
ev->num = h->cursor->ev.num;
history_def_delete(h, ev, h->cursor);
return (0);
}
/* history_def_delete(): /* history_def_delete():
* Delete element hp of the h list * Delete element hp of the h list
*/ */
@ -364,6 +396,8 @@ history_def_delete(history_t *h,
HistEventPrivate *evp = (void *)&hp->ev; HistEventPrivate *evp = (void *)&hp->ev;
if (hp == &h->list) if (hp == &h->list)
abort(); abort();
if (h->cursor == hp)
h->cursor = hp->prev;
hp->prev->next = hp->next; hp->prev->next = hp->next;
hp->next->prev = hp->prev; hp->next->prev = hp->prev;
h_free((ptr_t) evp->str); h_free((ptr_t) evp->str);
@ -497,6 +531,7 @@ history_init(void)
h->h_clear = history_def_clear; h->h_clear = history_def_clear;
h->h_enter = history_def_enter; h->h_enter = history_def_enter;
h->h_add = history_def_add; h->h_add = history_def_add;
h->h_del = history_def_del;
return (h); return (h);
} }
@ -512,6 +547,8 @@ history_end(History *h)
if (h->h_next == history_def_next) if (h->h_next == history_def_next)
history_def_clear(h->h_ref, &ev); history_def_clear(h->h_ref, &ev);
h_free(h->h_ref);
h_free(h);
} }
@ -597,7 +634,7 @@ history_set_fun(History *h, History *nh)
if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL || if (nh->h_first == NULL || nh->h_next == NULL || nh->h_last == NULL ||
nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == NULL || nh->h_prev == NULL || nh->h_curr == NULL || nh->h_set == NULL ||
nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL || nh->h_enter == NULL || nh->h_add == NULL || nh->h_clear == NULL ||
nh->h_ref == NULL) { nh->h_del == NULL || nh->h_ref == NULL) {
if (h->h_next != history_def_next) { if (h->h_next != history_def_next) {
history_def_init(&h->h_ref, &ev, 0); history_def_init(&h->h_ref, &ev, 0);
h->h_first = history_def_first; h->h_first = history_def_first;
@ -609,6 +646,7 @@ history_set_fun(History *h, History *nh)
h->h_clear = history_def_clear; h->h_clear = history_def_clear;
h->h_enter = history_def_enter; h->h_enter = history_def_enter;
h->h_add = history_def_add; h->h_add = history_def_add;
h->h_del = history_def_del;
} }
return (-1); return (-1);
} }
@ -625,6 +663,7 @@ history_set_fun(History *h, History *nh)
h->h_clear = nh->h_clear; h->h_clear = nh->h_clear;
h->h_enter = nh->h_enter; h->h_enter = nh->h_enter;
h->h_add = nh->h_add; h->h_add = nh->h_add;
h->h_del = nh->h_del;
return (0); return (0);
} }
@ -676,8 +715,8 @@ history_load(History *h, const char *fname)
(void) strunvis(ptr, line); (void) strunvis(ptr, line);
line[sz] = c; line[sz] = c;
if (HENTER(h, &ev, ptr) == -1) { if (HENTER(h, &ev, ptr) == -1) {
i = -1; i = -1;
goto oomem; goto oomem;
} }
} }
oomem: oomem:
@ -841,6 +880,10 @@ history(History *h, HistEvent *ev, int fun, ...)
retval = HADD(h, ev, str); retval = HADD(h, ev, str);
break; break;
case H_DEL:
retval = HDEL(h, ev, va_arg(va, const int));
break;
case H_ENTER: case H_ENTER:
str = va_arg(va, const char *); str = va_arg(va, const char *);
if ((retval = HENTER(h, ev, str)) != -1) if ((retval = HENTER(h, ev, str)) != -1)
@ -925,6 +968,7 @@ history(History *h, HistEvent *ev, int fun, ...)
hf.h_clear = va_arg(va, history_vfun_t); hf.h_clear = va_arg(va, history_vfun_t);
hf.h_enter = va_arg(va, history_efun_t); hf.h_enter = va_arg(va, history_efun_t);
hf.h_add = va_arg(va, history_efun_t); hf.h_add = va_arg(va, history_efun_t);
hf.h_del = va_arg(va, history_sfun_t);
if ((retval = history_set_fun(h, &hf)) == -1) if ((retval = history_set_fun(h, &hf)) == -1)
he_seterrev(ev, _HE_PARAM_MISSING); he_seterrev(ev, _HE_PARAM_MISSING);

View File

@ -1,4 +1,4 @@
/* $NetBSD: key.c,v 1.15 2003/10/18 23:48:42 christos Exp $ */ /* $NetBSD: key.c,v 1.19 2006/03/23 20:22:51 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,14 +32,20 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)key.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* key.c: This module contains the procedures for maintaining * key.c: This module contains the procedures for maintaining
* the extended-key map. * the extended-key map.
* *
* An extended-key (key) is a sequence of keystrokes introduced * An extended-key (key) is a sequence of keystrokes introduced
* with an sequence introducer and consisting of an arbitrary * with a sequence introducer and consisting of an arbitrary
* number of characters. This module maintains a map (the el->el_key.map) * number of characters. This module maintains a map (the el->el_key.map)
* to convert these extended-key sequences into input strs * to convert these extended-key sequences into input strs
* (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE). * (XK_STR), editor functions (XK_CMD), or unix commands (XK_EXE).
@ -78,12 +84,12 @@ private int node_trav(EditLine *, key_node_t *, char *,
private int node__try(EditLine *, key_node_t *, const char *, private int node__try(EditLine *, key_node_t *, const char *,
key_value_t *, int); key_value_t *, int);
private key_node_t *node__get(int); private key_node_t *node__get(int);
private void node__free(key_node_t *);
private void node__put(EditLine *, key_node_t *); private void node__put(EditLine *, key_node_t *);
private int node__delete(EditLine *, key_node_t **, const char *); private int node__delete(EditLine *, key_node_t **, const char *);
private int node_lookup(EditLine *, const char *, key_node_t *, private int node_lookup(EditLine *, const char *, key_node_t *,
int); int);
private int node_enum(EditLine *, key_node_t *, int); private int node_enum(EditLine *, key_node_t *, int);
private int key__decode_char(char *, int, int);
#define KEY_BUFSIZ EL_BUFSIZ #define KEY_BUFSIZ EL_BUFSIZ
@ -103,7 +109,6 @@ key_init(EditLine *el)
return (0); return (0);
} }
/* key_end(): /* key_end():
* Free the key maps * Free the key maps
*/ */
@ -113,8 +118,7 @@ key_end(EditLine *el)
el_free((ptr_t) el->el_key.buf); el_free((ptr_t) el->el_key.buf);
el->el_key.buf = NULL; el->el_key.buf = NULL;
/* XXX: provide a function to clear the keys */ node__free(el->el_key.map);
el->el_key.map = NULL;
} }
@ -443,7 +447,7 @@ node__put(EditLine *el, key_node_t *ptr)
/* node__get(): /* node__get():
* Returns pointer to an key_node_t for ch. * Returns pointer to a key_node_t for ch.
*/ */
private key_node_t * private key_node_t *
node__get(int ch) node__get(int ch)
@ -461,7 +465,15 @@ node__get(int ch)
return (ptr); return (ptr);
} }
private void
node__free(key_node_t *k)
{
if (k == NULL)
return;
node__free(k->sibling);
node__free(k->next);
el_free((ptr_t) k);
}
/* node_lookup(): /* node_lookup():
* look for the str starting at node ptr. * look for the str starting at node ptr.
@ -483,7 +495,7 @@ node_lookup(EditLine *el, const char *str, key_node_t *ptr, int cnt)
/* If match put this char into el->el_key.buf. Recurse */ /* If match put this char into el->el_key.buf. Recurse */
if (ptr->ch == *str) { if (ptr->ch == *str) {
/* match found */ /* match found */
ncnt = key__decode_char(el->el_key.buf, cnt, ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt,
(unsigned char) ptr->ch); (unsigned char) ptr->ch);
if (ptr->next != NULL) if (ptr->next != NULL)
/* not yet at leaf */ /* not yet at leaf */
@ -537,7 +549,8 @@ node_enum(EditLine *el, key_node_t *ptr, int cnt)
return (-1); return (-1);
} }
/* put this char at end of str */ /* put this char at end of str */
ncnt = key__decode_char(el->el_key.buf, cnt, (unsigned char) ptr->ch); ncnt = key__decode_char(el->el_key.buf, KEY_BUFSIZ, cnt,
(unsigned char)ptr->ch);
if (ptr->next == NULL) { if (ptr->next == NULL) {
/* print this key and function */ /* print this key and function */
el->el_key.buf[ncnt + 1] = '"'; el->el_key.buf[ncnt + 1] = '"';
@ -568,9 +581,10 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
switch (ntype) { switch (ntype) {
case XK_STR: case XK_STR:
case XK_EXE: case XK_EXE:
(void) fprintf(el->el_outfile, fmt, key, (void) key__decode_str(val->str, unparsbuf,
key__decode_str(val->str, unparsbuf, sizeof(unparsbuf),
ntype == XK_STR ? "\"\"" : "[]")); ntype == XK_STR ? "\"\"" : "[]");
(void) fprintf(el->el_outfile, fmt, key, unparsbuf);
break; break;
case XK_CMD: case XK_CMD:
for (fp = el->el_map.help; fp->name; fp++) for (fp = el->el_map.help; fp->name; fp++)
@ -595,83 +609,97 @@ key_kprint(EditLine *el, const char *key, key_value_t *val, int ntype)
} }
#define ADDC(c) \
if (b < eb) \
*b++ = c; \
else \
b++
/* key__decode_char(): /* key__decode_char():
* Put a printable form of char in buf. * Put a printable form of char in buf.
*/ */
private int protected int
key__decode_char(char *buf, int cnt, int ch) key__decode_char(char *buf, int cnt, int off, int ch)
{ {
char *sb = buf + off;
char *eb = buf + cnt;
char *b = sb;
if (ch == 0) { if (ch == 0) {
buf[cnt++] = '^'; ADDC('^');
buf[cnt] = '@'; ADDC('@');
return (cnt); return b - sb;
} }
if (iscntrl(ch)) { if (iscntrl(ch)) {
buf[cnt++] = '^'; ADDC('^');
if (ch == '\177') if (ch == '\177')
buf[cnt] = '?'; ADDC('?');
else else
buf[cnt] = ch | 0100; ADDC(ch | 0100);
} else if (ch == '^') { } else if (ch == '^') {
buf[cnt++] = '\\'; ADDC('\\');
buf[cnt] = '^'; ADDC('^');
} else if (ch == '\\') { } else if (ch == '\\') {
buf[cnt++] = '\\'; ADDC('\\');
buf[cnt] = '\\'; ADDC('\\');
} else if (ch == ' ' || (el_isprint(ch) && !isspace(ch))) { } else if (ch == ' ' || (el_isprint(ch) && !isspace(ch))) {
buf[cnt] = ch; ADDC(ch);
} else { } else {
buf[cnt++] = '\\'; ADDC('\\');
buf[cnt++] = (((unsigned int) ch >> 6) & 7) + '0'; ADDC((((unsigned int) ch >> 6) & 7) + '0');
buf[cnt++] = (((unsigned int) ch >> 3) & 7) + '0'; ADDC((((unsigned int) ch >> 3) & 7) + '0');
buf[cnt] = (ch & 7) + '0'; ADDC((ch & 7) + '0');
} }
return (cnt); return b - sb;
} }
/* key__decode_str(): /* key__decode_str():
* Make a printable version of the ey * Make a printable version of the ey
*/ */
protected char * protected int
key__decode_str(const char *str, char *buf, const char *sep) key__decode_str(const char *str, char *buf, int len, const char *sep)
{ {
char *b; char *b = buf, *eb = b + len;
const char *p; const char *p;
b = buf; b = buf;
if (sep[0] != '\0') if (sep[0] != '\0') {
*b++ = sep[0]; ADDC(sep[0]);
if (*str == 0) { }
*b++ = '^'; if (*str == '\0') {
*b++ = '@'; ADDC('^');
if (sep[0] != '\0' && sep[1] != '\0') ADDC('@');
*b++ = sep[1]; if (sep[0] != '\0' && sep[1] != '\0') {
*b++ = 0; ADDC(sep[1]);
return (buf); }
goto done;
} }
for (p = str; *p != 0; p++) { for (p = str; *p != 0; p++) {
if (iscntrl((unsigned char) *p)) { if (iscntrl((unsigned char) *p)) {
*b++ = '^'; ADDC('^');
if (*p == '\177') if (*p == '\177') {
*b++ = '?'; ADDC('?');
else } else {
*b++ = *p | 0100; ADDC(*p | 0100);
}
} else if (*p == '^' || *p == '\\') { } else if (*p == '^' || *p == '\\') {
*b++ = '\\'; ADDC('\\');
*b++ = *p; ADDC(*p);
} else if (*p == ' ' || (el_isprint((unsigned char) *p) && } else if (*p == ' ' || (el_isprint((unsigned char) *p) &&
!isspace((unsigned char) *p))) { !isspace((unsigned char) *p))) {
*b++ = *p; ADDC(*p);
} else { } else {
*b++ = '\\'; ADDC('\\');
*b++ = (((unsigned int) *p >> 6) & 7) + '0'; ADDC((((unsigned int) *p >> 6) & 7) + '0');
*b++ = (((unsigned int) *p >> 3) & 7) + '0'; ADDC((((unsigned int) *p >> 3) & 7) + '0');
*b++ = (*p & 7) + '0'; ADDC((*p & 7) + '0');
} }
} }
if (sep[0] != '\0' && sep[1] != '\0') if (sep[0] != '\0' && sep[1] != '\0') {
*b++ = sep[1]; ADDC(sep[1]);
*b++ = 0; }
return (buf); /* should check for overflow */ done:
ADDC('\0');
if (b - buf >= len)
buf[len - 1] = '\0';
return b - buf;
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: key.h,v 1.8 2003/08/07 16:44:32 agc Exp $ */ /* $NetBSD: key.h,v 1.10 2006/03/23 20:22:51 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -74,6 +74,8 @@ protected int key_delete(EditLine *, const char *);
protected void key_print(EditLine *, const char *); protected void key_print(EditLine *, const char *);
protected void key_kprint(EditLine *, const char *, key_value_t *, protected void key_kprint(EditLine *, const char *, key_value_t *,
int); int);
protected char *key__decode_str(const char *, char *, const char *); protected int key__decode_str(const char *, char *, int,
const char *);
protected int key__decode_char(char *, int, int, int);
#endif /* _h_el_key */ #endif /* _h_el_key */

View File

@ -1,124 +0,0 @@
/* $NetBSD: term.h,v 1.12 2001/01/04 15:56:32 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 */

View File

@ -1,5 +1,5 @@
#!/bin/sh - #!/bin/sh -
# $NetBSD: makelist,v 1.8 2003/03/10 21:21:10 christos Exp $ # $NetBSD: makelist,v 1.11 2005/10/22 16:45:03 christos Exp $
# #
# Copyright (c) 1992, 1993 # Copyright (c) 1992, 1993
# The Regents of the University of California. All rights reserved. # The Regents of the University of California. All rights reserved.
@ -15,11 +15,7 @@
# 2. Redistributions in binary form must reproduce the above copyright # 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the # notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution. # documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software # 3. Neither the name of the University nor the names of its contributors
# 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 # may be used to endorse or promote products derived from this software
# without specific prior written permission. # without specific prior written permission.
# #
@ -68,6 +64,7 @@ case $FLAG in
/\(\):/ { /\(\):/ {
pr = substr($2, 1, 2); pr = substr($2, 1, 2);
if (pr == "vi" || pr == "em" || pr == "ed") { if (pr == "vi" || pr == "em" || pr == "ed") {
# XXXMYSQL: support CRLF
name = substr($2, 1, index($2,"(") - 1); name = substr($2, 1, index($2,"(") - 1);
# #
# XXX: need a space between name and prototype so that -fc and -fh # XXX: need a space between name and prototype so that -fc and -fh
@ -87,7 +84,7 @@ case $FLAG in
cat $FILES | $AWK ' cat $FILES | $AWK '
BEGIN { BEGIN {
printf("/* Automatically generated file, do not edit */\n"); printf("/* Automatically generated file, do not edit */\n");
printf("#include \"config.h\"\n#include \"el.h\"\n"); printf("#include \"sys.h\"\n#include \"el.h\"\n");
printf("private const struct el_bindings_t el_func_help[] = {\n"); printf("private const struct el_bindings_t el_func_help[] = {\n");
low = "abcdefghijklmnopqrstuvwxyz_"; low = "abcdefghijklmnopqrstuvwxyz_";
high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_"; high = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_";
@ -97,6 +94,7 @@ case $FLAG in
/\(\):/ { /\(\):/ {
pr = substr($2, 1, 2); pr = substr($2, 1, 2);
if (pr == "vi" || pr == "em" || pr == "ed") { if (pr == "vi" || pr == "em" || pr == "ed") {
# XXXMYSQL: support CRLF
name = substr($2, 1, index($2,"(") - 1); name = substr($2, 1, index($2,"(") - 1);
uname = ""; uname = "";
fname = ""; fname = "";
@ -117,13 +115,13 @@ case $FLAG in
printf(" \""); printf(" \"");
for (i = 2; i < NF; i++) for (i = 2; i < NF; i++)
printf("%s ", $i); printf("%s ", $i);
sub("\r", "", $i); # XXXMYSQL: support CRLF
sub("\r", "", $i);
printf("%s\" },\n", $i); printf("%s\" },\n", $i);
ok = 0; ok = 0;
} }
} }
END { END {
printf(" { NULL, 0, NULL }\n");
printf("};\n"); printf("};\n");
printf("\nprotected const el_bindings_t* help__get()"); printf("\nprotected const el_bindings_t* help__get()");
printf("{ return el_func_help; }\n"); printf("{ return el_func_help; }\n");
@ -144,6 +142,7 @@ case $FLAG in
# generate fcns.h from various .h files # generate fcns.h from various .h files
# #
# XXXMYSQL: use portable tr syntax
-fh) -fh)
cat $FILES | $AWK '/el_action_t/ { print $3 }' | \ cat $FILES | $AWK '/el_action_t/ { print $3 }' | \
sort | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | $AWK ' sort | tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ | $AWK '
@ -170,7 +169,7 @@ case $FLAG in
cat $FILES | $AWK '/el_action_t/ { print $3 }' | sort | $AWK ' cat $FILES | $AWK '/el_action_t/ { print $3 }' | sort | $AWK '
BEGIN { BEGIN {
printf("/* Automatically generated file, do not edit */\n"); printf("/* Automatically generated file, do not edit */\n");
printf("#include \"config.h\"\n#include \"el.h\"\n"); printf("#include \"sys.h\"\n#include \"el.h\"\n");
printf("private const el_func_t el_func[] = {"); printf("private const el_func_t el_func[] = {");
maxlen = 80; maxlen = 80;
needn = 1; needn = 1;
@ -220,6 +219,7 @@ case $FLAG in
/\(\):/ { /\(\):/ {
pr = substr($2, 1, 2); pr = substr($2, 1, 2);
if (pr == "vi" || pr == "em" || pr == "ed") { if (pr == "vi" || pr == "em" || pr == "ed") {
# XXXMYSQL: support CRLF
name = substr($2, 1, index($2, "(") - 1); name = substr($2, 1, index($2, "(") - 1);
fname = ""; fname = "";
for (i = 1; i <= length(name); i++) { for (i = 1; i <= length(name); i++) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: map.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $ */ /* $NetBSD: map.c,v 1.24 2006/04/09 01:36:51 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)map.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* map.c: Editor function definitions * map.c: Editor function definitions
@ -1118,11 +1124,12 @@ private void
map_print_key(EditLine *el, el_action_t *map, const char *in) map_print_key(EditLine *el, el_action_t *map, const char *in)
{ {
char outbuf[EL_BUFSIZ]; char outbuf[EL_BUFSIZ];
el_bindings_t *bp; el_bindings_t *bp, *ep;
if (in[0] == '\0' || in[1] == '\0') { if (in[0] == '\0' || in[1] == '\0') {
(void) key__decode_str(in, outbuf, ""); (void) key__decode_str(in, outbuf, sizeof(outbuf), "");
for (bp = el->el_map.help; bp->name != NULL; bp++) ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++)
if (bp->func == map[(unsigned char) *in]) { if (bp->func == map[(unsigned char) *in]) {
(void) fprintf(el->el_outfile, (void) fprintf(el->el_outfile,
"%s\t->\t%s\n", outbuf, bp->name); "%s\t->\t%s\n", outbuf, bp->name);
@ -1139,7 +1146,7 @@ map_print_key(EditLine *el, el_action_t *map, const char *in)
private void private void
map_print_some_keys(EditLine *el, el_action_t *map, int first, int last) map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
{ {
el_bindings_t *bp; el_bindings_t *bp, *ep;
char firstbuf[2], lastbuf[2]; char firstbuf[2], lastbuf[2];
char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ]; char unparsbuf[EL_BUFSIZ], extrabuf[EL_BUFSIZ];
@ -1148,39 +1155,47 @@ map_print_some_keys(EditLine *el, el_action_t *map, int first, int last)
lastbuf[0] = last; lastbuf[0] = last;
lastbuf[1] = 0; lastbuf[1] = 0;
if (map[first] == ED_UNASSIGNED) { if (map[first] == ED_UNASSIGNED) {
if (first == last) if (first == last) {
(void) key__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile, (void) fprintf(el->el_outfile,
"%-15s-> is undefined\n", "%-15s-> is undefined\n", unparsbuf);
key__decode_str(firstbuf, unparsbuf, STRQQ)); }
return; return;
} }
for (bp = el->el_map.help; bp->name != NULL; bp++) { ep = &el->el_map.help[el->el_map.nfunc];
for (bp = el->el_map.help; bp < ep; bp++) {
if (bp->func == map[first]) { if (bp->func == map[first]) {
if (first == last) { if (first == last) {
(void) key__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile, "%-15s-> %s\n", (void) fprintf(el->el_outfile, "%-15s-> %s\n",
key__decode_str(firstbuf, unparsbuf, STRQQ), unparsbuf, bp->name);
bp->name);
} else { } else {
(void) key__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) key__decode_str(lastbuf, extrabuf,
sizeof(extrabuf), STRQQ);
(void) fprintf(el->el_outfile, (void) fprintf(el->el_outfile,
"%-4s to %-7s-> %s\n", "%-4s to %-7s-> %s\n",
key__decode_str(firstbuf, unparsbuf, STRQQ), unparsbuf, extrabuf, bp->name);
key__decode_str(lastbuf, extrabuf, STRQQ),
bp->name);
} }
return; return;
} }
} }
#ifdef MAP_DEBUG #ifdef MAP_DEBUG
if (map == el->el_map.key) { if (map == el->el_map.key) {
(void) key__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile, (void) fprintf(el->el_outfile,
"BUG!!! %s isn't bound to anything.\n", "BUG!!! %s isn't bound to anything.\n", unparsbuf);
key__decode_str(firstbuf, unparsbuf, STRQQ));
(void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n", (void) fprintf(el->el_outfile, "el->el_map.key[%d] == %d\n",
first, el->el_map.key[first]); first, el->el_map.key[first]);
} else { } else {
(void) key__decode_str(firstbuf, unparsbuf,
sizeof(unparsbuf), STRQQ);
(void) fprintf(el->el_outfile, (void) fprintf(el->el_outfile,
"BUG!!! %s isn't bound to anything.\n", "BUG!!! %s isn't bound to anything.\n", unparsbuf);
key__decode_str(firstbuf, unparsbuf, STRQQ));
(void) fprintf(el->el_outfile, "el->el_map.alt[%d] == %d\n", (void) fprintf(el->el_outfile, "el->el_map.alt[%d] == %d\n",
first, el->el_map.alt[first]); first, el->el_map.alt[first]);
} }
@ -1237,7 +1252,7 @@ map_bind(EditLine *el, int argc, const char **argv)
char outbuf[EL_BUFSIZ]; char outbuf[EL_BUFSIZ];
const char *in = NULL; const char *in = NULL;
char *out = NULL; char *out = NULL;
el_bindings_t *bp; el_bindings_t *bp, *ep;
int cmd; int cmd;
int key; int key;
@ -1279,8 +1294,8 @@ map_bind(EditLine *el, int argc, const char **argv)
return (0); return (0);
case 'l': case 'l':
for (bp = el->el_map.help; bp->name != NULL; ep = &el->el_map.help[el->el_map.nfunc];
bp++) for (bp = el->el_map.help; bp < ep; bp++)
(void) fprintf(el->el_outfile, (void) fprintf(el->el_outfile,
"%s\n\t%s\n", "%s\n\t%s\n",
bp->name, bp->description); bp->name, bp->description);
@ -1367,7 +1382,7 @@ map_bind(EditLine *el, int argc, const char **argv)
break; break;
default: default:
EL_ABORT((el->el_errfile, "Bad XK_ type\n", ntype)); EL_ABORT((el->el_errfile, "Bad XK_ type %d\n", ntype));
break; break;
} }
return (0); return (0);
@ -1381,7 +1396,7 @@ protected int
map_addfunc(EditLine *el, const char *name, const char *help, el_func_t func) map_addfunc(EditLine *el, const char *name, const char *help, el_func_t func)
{ {
void *p; void *p;
int nf = el->el_map.nfunc + 2; int nf = el->el_map.nfunc + 1;
if (name == NULL || help == NULL || func == NULL) if (name == NULL || help == NULL || func == NULL)
return (-1); return (-1);
@ -1400,7 +1415,6 @@ map_addfunc(EditLine *el, const char *name, const char *help, el_func_t func)
el->el_map.help[nf].name = name; el->el_map.help[nf].name = name;
el->el_map.help[nf].func = nf; el->el_map.help[nf].func = nf;
el->el_map.help[nf].description = help; el->el_map.help[nf].description = help;
el->el_map.help[++nf].name = NULL;
el->el_map.nfunc++; el->el_map.nfunc++;
return (0); return (0);

View File

@ -1,4 +1,4 @@
/* $NetBSD: fgetln.c,v 1.1.1.1 1999/04/12 07:43:21 crooksa Exp $ */ /* $NetBSD: fgetln.c,v 1.9 2008/04/29 06:53:03 martin Exp $ */
/*- /*-
* Copyright (c) 1998 The NetBSD Foundation, Inc. * Copyright (c) 1998 The NetBSD Foundation, Inc.
@ -15,13 +15,6 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@ -36,17 +29,24 @@
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifdef HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#else
#include "config.h" #include "config.h"
#include <stdio.h> #endif
#if !HAVE_FGETLN
#include <stdlib.h> #include <stdlib.h>
#ifndef HAVE_NBTOOL_CONFIG_H
/* These headers are required, but included from nbtool_config.h */
#include <stdio.h>
#include <unistd.h> #include <unistd.h>
#include <errno.h> #include <errno.h>
#include <string.h> #include <string.h>
#endif
char * char *
fgetln(fp, len) fgetln(FILE *fp, size_t *len)
FILE *fp;
size_t *len;
{ {
static char *buf = NULL; static char *buf = NULL;
static size_t bufsiz = 0; static size_t bufsiz = 0;
@ -61,8 +61,8 @@ fgetln(fp, len)
if (fgets(buf, bufsiz, fp) == NULL) if (fgets(buf, bufsiz, fp) == NULL)
return NULL; return NULL;
*len = 0;
*len = 0;
while ((ptr = strchr(&buf[*len], '\n')) == NULL) { while ((ptr = strchr(&buf[*len], '\n')) == NULL) {
size_t nbufsiz = bufsiz + BUFSIZ; size_t nbufsiz = bufsiz + BUFSIZ;
char *nbuf = realloc(buf, nbufsiz); char *nbuf = realloc(buf, nbufsiz);
@ -76,13 +76,33 @@ fgetln(fp, len)
} else } else
buf = nbuf; buf = nbuf;
*len = bufsiz; if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) {
if (fgets(&buf[bufsiz], BUFSIZ, fp) == NULL) buf[bufsiz] = '\0';
*len = strlen(buf);
return buf; return buf;
}
*len = bufsiz;
bufsiz = nbufsiz; bufsiz = nbufsiz;
} }
*len = (ptr - buf) + 1; *len = (ptr - buf) + 1;
return buf; return buf;
} }
#endif
#ifdef TEST
int
main(int argc, char *argv[])
{
char *p;
size_t len;
while ((p = fgetln(stdin, &len)) != NULL) {
(void)printf("%zu %s", len, p);
free(p);
}
return 0;
}
#endif

View File

@ -1,59 +1,68 @@
/* $NetBSD: strlcat.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */
/* $OpenBSD: strlcat.c,v 1.10 2003/04/12 21:56:39 millert Exp $ */
/* /*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Permission to use, copy, modify, and distribute this software for any
* modification, are permitted provided that the following conditions * purpose with or without fee is hereby granted, provided that the above
* are met: * copyright notice and this permission notice appear in all copies.
* 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, * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* 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(_KERNEL) && !defined(_STANDALONE)
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#else
#include "config.h" #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 #endif
#if defined(LIBC_SCCS) && !defined(lint)
#endif /* LIBC_SCCS and not lint */
#ifdef _LIBC
#include "namespace.h"
#endif
#include <sys/types.h> #include <sys/types.h>
#include <assert.h>
#include <string.h> #include <string.h>
#ifdef _LIBC
# ifdef __weak_alias
__weak_alias(strlcat, _strlcat)
# endif
#endif
#else
#include <lib/libkern/libkern.h>
#endif /* !_KERNEL && !_STANDALONE */
#if !HAVE_STRLCAT
/* /*
* Appends src to string dst of size siz (unlike strncat, siz is the * 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 * full size of dst, not space left). At most siz-1 characters
* will be copied. Always NUL terminates (unless siz <= strlen(dst)). * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
* Returns strlen(initial dst) + strlen(src); if retval >= siz, * Returns strlen(src) + MIN(siz, strlen(initial dst)).
* truncation occurred. * If retval >= siz, truncation occurred.
*/ */
size_t strlcat(dst, src, siz) size_t
char *dst; strlcat(char *dst, const char *src, size_t siz)
const char *src;
size_t siz;
{ {
register char *d = dst; char *d = dst;
register const char *s = src; const char *s = src;
register size_t n = siz; size_t n = siz;
size_t dlen; size_t dlen;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
/* Find the end of dst and adjust bytes left but don't go past end */ /* Find the end of dst and adjust bytes left but don't go past end */
while (n-- != 0 && *d != '\0') while (n-- != 0 && *d != '\0')
d++; d++;
@ -73,3 +82,4 @@ size_t strlcat(dst, src, siz)
return(dlen + (s - src)); /* count does not include NUL */ return(dlen + (s - src)); /* count does not include NUL */
} }
#endif

View File

@ -1,59 +1,63 @@
/* $OpenBSD: strlcpy.c,v 1.4 1999/05/01 18:56:41 millert Exp $ */ /* $NetBSD: strlcpy.c,v 1.3 2007/06/04 18:19:27 christos Exp $ */
/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */
/* /*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com> * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
* All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Permission to use, copy, modify, and distribute this software for any
* modification, are permitted provided that the following conditions * purpose with or without fee is hereby granted, provided that the above
* are met: * copyright notice and this permission notice appear in all copies.
* 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, * THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
* THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
* 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(_KERNEL) && !defined(_STANDALONE)
#if HAVE_NBTOOL_CONFIG_H
#include "nbtool_config.h"
#else
#include "config.h" #include "config.h"
#endif
#if defined(LIBC_SCCS) && !defined(lint) #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 */ #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
#ifdef _LIBC
#include "namespace.h"
#endif
#include <sys/types.h> #include <sys/types.h>
#include <assert.h>
#include <string.h> #include <string.h>
#ifdef _LIBC
# ifdef __weak_alias
__weak_alias(strlcpy, _strlcpy)
# endif
#endif
#else
#include <lib/libkern/libkern.h>
#endif /* !_KERNEL && !_STANDALONE */
#if !HAVE_STRLCPY
/* /*
* Copy src to string dst of size siz. At most siz-1 characters * Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0). * will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred. * Returns strlen(src); if retval >= siz, truncation occurred.
*/ */
size_t strlcpy(dst, src, siz) size_t
char *dst; strlcpy(char *dst, const char *src, size_t siz)
const char *src;
size_t siz;
{ {
register char *d = dst; char *d = dst;
register const char *s = src; const char *s = src;
register size_t n = siz; size_t n = siz;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
/* Copy as many bytes as will fit */ /* Copy as many bytes as will fit */
if (n != 0 && --n != 0) { if (n != 0 && --n != 0) {
@ -73,3 +77,4 @@ size_t strlcpy(dst, src, siz)
return(s - src - 1); /* count does not include NUL */ return(s - src - 1); /* count does not include NUL */
} }
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $ */ /* $NetBSD: unvis.c,v 1.28 2005/09/13 01:44:09 christos Exp $ */
/*- /*-
* Copyright (c) 1989, 1993 * Copyright (c) 1989, 1993
@ -12,11 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -34,34 +30,30 @@
*/ */
#include "config.h" #include "config.h"
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
#if 0 #if 0
static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93"; static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93";
#else #else
__RCSID("$NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $");
#endif #endif
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#define __LIBC12_SOURCE__
#include <sys/types.h> #include <sys/types.h>
#include <assert.h> #include <assert.h>
#include <ctype.h> #include <ctype.h>
#include <stdio.h> #include <stdio.h>
#ifdef HAVE_VIS_H
#include <vis.h>
#else
#include "np/vis.h" #include "np/vis.h"
#endif
#ifdef __weak_alias #ifdef __weak_alias
__weak_alias(strunvis,_strunvis) __weak_alias(strunvis,_strunvis)
__weak_alias(unvis,_unvis)
#endif #endif
#ifdef __warn_references #if !HAVE_VIS
__warn_references(unvis,
"warning: reference to compatibility unvis(); include <vis.h> for correct reference")
#endif
#if !HAVE_VIS_H
/* /*
* decode driven by state machine * decode driven by state machine
*/ */
@ -72,30 +64,22 @@ __warn_references(unvis,
#define S_CTRL 4 /* control char started (^) */ #define S_CTRL 4 /* control char started (^) */
#define S_OCTAL2 5 /* octal digit 2 */ #define S_OCTAL2 5 /* octal digit 2 */
#define S_OCTAL3 6 /* octal digit 3 */ #define S_OCTAL3 6 /* octal digit 3 */
#define S_HEX1 7 /* hex digit */ #define S_HEX1 7 /* hex digit */
#define S_HEX2 8 /* hex digit 2 */ #define S_HEX2 8 /* hex digit 2 */
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
#define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10)) #define xtod(c) (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10))
/*
* unvis - decode characters previously encoded by vis
*/
int int
unvis(cp, c, astate, flag) unvis(cp, c, astate, flag)
char *cp; char *cp;
int c; int c;
int *astate, flag; int *astate, flag;
{ {
return __unvis13(cp, (int)c, astate, flag); unsigned char uc = (unsigned char)c;
}
/*
* unvis - decode characters previously encoded by vis
*/
int
__unvis13(cp, c, astate, flag)
char *cp;
int c;
int *astate, flag;
{
_DIAGASSERT(cp != NULL); _DIAGASSERT(cp != NULL);
_DIAGASSERT(astate != NULL); _DIAGASSERT(astate != NULL);
@ -105,7 +89,7 @@ __unvis13(cp, c, astate, flag)
|| *astate == S_HEX2) { || *astate == S_HEX2) {
*astate = S_GROUND; *astate = S_GROUND;
return (UNVIS_VALID); return (UNVIS_VALID);
} }
return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD); return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
} }
@ -116,7 +100,7 @@ __unvis13(cp, c, astate, flag)
if (c == '\\') { if (c == '\\') {
*astate = S_START; *astate = S_START;
return (0); return (0);
} }
if ((flag & VIS_HTTPSTYLE) && c == '%') { if ((flag & VIS_HTTPSTYLE) && c == '%') {
*astate = S_HEX1; *astate = S_HEX1;
return (0); return (0);
@ -193,7 +177,7 @@ __unvis13(cp, c, astate, flag)
} }
*astate = S_GROUND; *astate = S_GROUND;
return (UNVIS_SYNBAD); return (UNVIS_SYNBAD);
case S_META: case S_META:
if (c == '-') if (c == '-')
*astate = S_META1; *astate = S_META1;
@ -204,12 +188,12 @@ __unvis13(cp, c, astate, flag)
return (UNVIS_SYNBAD); return (UNVIS_SYNBAD);
} }
return (0); return (0);
case S_META1: case S_META1:
*astate = S_GROUND; *astate = S_GROUND;
*cp |= c; *cp |= c;
return (UNVIS_VALID); return (UNVIS_VALID);
case S_CTRL: case S_CTRL:
if (c == '?') if (c == '?')
*cp |= 0177; *cp |= 0177;
@ -219,23 +203,23 @@ __unvis13(cp, c, astate, flag)
return (UNVIS_VALID); return (UNVIS_VALID);
case S_OCTAL2: /* second possible octal digit */ case S_OCTAL2: /* second possible octal digit */
if (isoctal(c)) { if (isoctal(uc)) {
/* /*
* yes - and maybe a third * yes - and maybe a third
*/ */
*cp = (*cp << 3) + (c - '0'); *cp = (*cp << 3) + (c - '0');
*astate = S_OCTAL3; *astate = S_OCTAL3;
return (0); return (0);
} }
/* /*
* no - done with current sequence, push back passed char * no - done with current sequence, push back passed char
*/ */
*astate = S_GROUND; *astate = S_GROUND;
return (UNVIS_VALIDPUSH); return (UNVIS_VALIDPUSH);
case S_OCTAL3: /* third possible octal digit */ case S_OCTAL3: /* third possible octal digit */
*astate = S_GROUND; *astate = S_GROUND;
if (isoctal(c)) { if (isoctal(uc)) {
*cp = (*cp << 3) + (c - '0'); *cp = (*cp << 3) + (c - '0');
return (UNVIS_VALID); return (UNVIS_VALID);
} }
@ -243,27 +227,30 @@ __unvis13(cp, c, astate, flag)
* we were done, push back passed char * we were done, push back passed char
*/ */
return (UNVIS_VALIDPUSH); return (UNVIS_VALIDPUSH);
case S_HEX1: case S_HEX1:
if (isxdigit(c)) { if (isxdigit(uc)) {
*cp = xtod(c); *cp = xtod(uc);
*astate = S_HEX2; *astate = S_HEX2;
return (0); return (0);
} }
/* /*
* no - done with current sequence, push back passed char * no - done with current sequence, push back passed char
*/ */
*astate = S_GROUND; *astate = S_GROUND;
return (UNVIS_VALIDPUSH); return (UNVIS_VALIDPUSH);
case S_HEX2: case S_HEX2:
*astate = S_GROUND; *astate = S_GROUND;
if (isxdigit(c)) { if (isxdigit(uc)) {
*cp = xtod(c) | (*cp << 4); *cp = xtod(uc) | (*cp << 4);
return (UNVIS_VALID); return (UNVIS_VALID);
} }
return (UNVIS_VALIDPUSH); return (UNVIS_VALIDPUSH);
default:
/* default:
* decoder in unknown state - (probably uninitialized) /*
* decoder in unknown state - (probably uninitialized)
*/ */
*astate = S_GROUND; *astate = S_GROUND;
return (UNVIS_SYNBAD); return (UNVIS_SYNBAD);
@ -271,7 +258,7 @@ __unvis13(cp, c, astate, flag)
} }
/* /*
* strunvis - decode src into dst * strunvis - decode src into dst
* *
* Number of chars decoded into dst is returned, -1 on error. * Number of chars decoded into dst is returned, -1 on error.
* Dst is null terminated. * Dst is null terminated.
@ -291,8 +278,8 @@ strunvisx(dst, src, flag)
_DIAGASSERT(dst != NULL); _DIAGASSERT(dst != NULL);
while ((c = *src++) != '\0') { while ((c = *src++) != '\0') {
again: again:
switch (__unvis13(dst, c, &state, flag)) { switch (unvis(dst, c, &state, flag)) {
case UNVIS_VALID: case UNVIS_VALID:
dst++; dst++;
break; break;
@ -306,7 +293,7 @@ strunvisx(dst, src, flag)
return (-1); return (-1);
} }
} }
if (__unvis13(dst, c, &state, UNVIS_END) == UNVIS_VALID) if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID)
dst++; dst++;
*dst = '\0'; *dst = '\0';
return (dst - start); return (dst - start);

View File

@ -1,7 +1,6 @@
/* $NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $ */ /* $NetBSD: vis.c,v 1.38 2008/09/04 09:41:44 lukem Exp $ */
/*- /*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
* Copyright (c) 1989, 1993 * Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
* *
@ -13,11 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -34,21 +29,47 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
/*-
* Copyright (c) 1999, 2005 The NetBSD Foundation, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* 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 "config.h"
#if defined(LIBC_SCCS) && !defined(lint) #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 */ #endif /* LIBC_SCCS and not lint */
#include <sys/types.h> #include <sys/types.h>
#include <assert.h> #include <assert.h>
#ifdef HAVE_ALLOCA_H #ifdef HAVE_VIS_H
#include <alloca.h> #include <vis.h>
#else
#include "np/vis.h"
#endif #endif
#include <stdlib.h> #include <stdlib.h>
#include "np/vis.h"
#ifdef __weak_alias #ifdef __weak_alias
__weak_alias(strsvis,_strsvis) __weak_alias(strsvis,_strsvis)
__weak_alias(strsvisx,_strsvisx) __weak_alias(strsvisx,_strsvisx)
@ -58,63 +79,61 @@ __weak_alias(svis,_svis)
__weak_alias(vis,_vis) __weak_alias(vis,_vis)
#endif #endif
#if !HAVE_VIS_H #if !HAVE_VIS || !HAVE_SVIS
#include <ctype.h> #include <ctype.h>
#include <limits.h> #include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <assert.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') static char *do_svis(char *, int, int, int, const char *);
#undef BELL
#define BELL '\a'
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
#define iswhite(c) (c == ' ' || c == '\t' || c == '\n') #define iswhite(c) (c == ' ' || c == '\t' || c == '\n')
#define issafe(c) (c == '\b' || c == BELL || c == '\r') #define issafe(c) (c == '\b' || c == BELL || c == '\r')
#define xtoa(c) "0123456789abcdef"[c] #define xtoa(c) "0123456789abcdef"[c]
#define MAXEXTRAS 5 #define MAXEXTRAS 5
#define MAKEEXTRALIST(flag, extra, orig_str) \
do { \
const char *orig = orig_str; \
const char *o = orig; \
char *e; \
while (*o++) \
continue; \
extra = malloc((size_t)((o - orig) + MAXEXTRAS)); \
if (!extra) break; \
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)
char *MAKEEXTRALIST(unsigned int flag, const char *orig) /*
{ * This is do_hvis, for HTTP style (RFC 1808)
const char *o = orig; */
char *e, *extra; static char *
while (*o++) do_hvis(char *dst, int c, int flag, int nextc, const char *extra)
continue; {
extra = (char*) malloc((size_t)((o - orig) + MAXEXTRAS)); if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) {
assert(extra); *dst++ = '%';
for (o = orig, e = extra; (*e++ = *o++) != '\0';) *dst++ = xtoa(((unsigned int)c >> 4) & 0xf);
continue; *dst++ = xtoa((unsigned int)c & 0xf);
e--; } else {
if (flag & VIS_SP) *e++ = ' '; dst = do_svis(dst, c, flag, nextc, extra);
if (flag & VIS_TAB) *e++ = '\t'; }
if (flag & VIS_NL) *e++ = '\n'; return dst;
if ((flag & VIS_NOSLASH) == 0) *e++ = '\\';
*e = '\0';
return extra;
} }
/* /*
* This is HVIS, the macro of vis used to HTTP style (RFC 1808) * This is do_vis, the central code of vis.
*/
#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 * dst: Pointer to the destination buffer
* c: Character to encode * c: Character to encode
* flag: Flag word * flag: Flag word
@ -122,95 +141,103 @@ while (/*CONSTCOND*/0)
* extra: Pointer to the list of extra characters to be * extra: Pointer to the list of extra characters to be
* backslash-protected. * backslash-protected.
*/ */
#define SVIS(dst, c, flag, nextc, extra) \ static char *
do { \ do_svis(char *dst, int c, int flag, int nextc, const char *extra)
int isextra, isc; \ {
isextra = strchr(extra, c) != NULL; \ int isextra;
if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \ isextra = strchr(extra, c) != NULL;
((flag & VIS_SAFE) && issafe(c)))) { \ if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) ||
*dst++ = c; \ ((flag & VIS_SAFE) && issafe(c)))) {
break; \ *dst++ = c;
} \ return dst;
isc = 0; \ }
if (flag & VIS_CSTYLE) { \ if (flag & VIS_CSTYLE) {
switch (c) { \ switch (c) {
case '\n': \ case '\n':
isc = 1; *dst++ = '\\'; *dst++ = 'n'; \ *dst++ = '\\'; *dst++ = 'n';
break; \ return dst;
case '\r': \ case '\r':
isc = 1; *dst++ = '\\'; *dst++ = 'r'; \ *dst++ = '\\'; *dst++ = 'r';
break; \ return dst;
case '\b': \ case '\b':
isc = 1; *dst++ = '\\'; *dst++ = 'b'; \ *dst++ = '\\'; *dst++ = 'b';
break; \ return dst;
case BELL: \ case BELL:
isc = 1; *dst++ = '\\'; *dst++ = 'a'; \ *dst++ = '\\'; *dst++ = 'a';
break; \ return dst;
case '\v': \ case '\v':
isc = 1; *dst++ = '\\'; *dst++ = 'v'; \ *dst++ = '\\'; *dst++ = 'v';
break; \ return dst;
case '\t': \ case '\t':
isc = 1; *dst++ = '\\'; *dst++ = 't'; \ *dst++ = '\\'; *dst++ = 't';
break; \ return dst;
case '\f': \ case '\f':
isc = 1; *dst++ = '\\'; *dst++ = 'f'; \ *dst++ = '\\'; *dst++ = 'f';
break; \ return dst;
case ' ': \ case ' ':
isc = 1; *dst++ = '\\'; *dst++ = 's'; \ *dst++ = '\\'; *dst++ = 's';
break; \ return dst;
case '\0': \ case '\0':
isc = 1; *dst++ = '\\'; *dst++ = '0'; \ *dst++ = '\\'; *dst++ = '0';
if (isoctal(nextc)) { \ if (isoctal(nextc)) {
*dst++ = '0'; \ *dst++ = '0';
*dst++ = '0'; \ *dst++ = '0';
} \ }
} \ return dst;
} \ default:
if (isc) break; \ if (isgraph(c)) {
if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \ *dst++ = '\\'; *dst++ = c;
*dst++ = '\\'; \ return 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 (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \ *dst++ = '\\';
if (c & 0200) { \ *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0';
c &= 0177; *dst++ = 'M'; \ *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0';
} \ *dst++ = (c & 07) + '0';
if (iscntrl(c)) { \ } else {
*dst++ = '^'; \ if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\';
if (c == 0177) \ if (c & 0200) {
*dst++ = '?'; \ c &= 0177; *dst++ = 'M';
else \ }
*dst++ = c + '@'; \ if (iscntrl(c)) {
} else { \ *dst++ = '^';
*dst++ = '-'; *dst++ = c; \ if (c == 0177)
} \ *dst++ = '?';
} \ else
} while (/*CONSTCOND*/0) *dst++ = c + '@';
} else {
*dst++ = '-'; *dst++ = c;
}
}
return dst;
}
/* /*
* svis - visually encode characters, also encoding the characters * svis - visually encode characters, also encoding the characters
* pointed to by `extra' * pointed to by `extra'
*/ */
char * char *
svis(dst, c, flag, nextc, extra) svis(char *dst, int c, int flag, int nextc, const char *extra)
char *dst;
int c, flag, nextc;
const char *extra;
{ {
char *nextra, *to_be_freed; char *nextra = NULL;
_DIAGASSERT(dst != NULL); _DIAGASSERT(dst != NULL);
_DIAGASSERT(extra != NULL); _DIAGASSERT(extra != NULL);
nextra= to_be_freed= MAKEEXTRALIST(flag, extra); MAKEEXTRALIST(flag, nextra, extra);
if (!nextra) {
*dst = '\0'; /* can't create nextra, return "" */
return dst;
}
if (flag & VIS_HTTPSTYLE) if (flag & VIS_HTTPSTYLE)
HVIS(dst, c, flag, nextc, nextra); dst = do_hvis(dst, c, flag, nextc, nextra);
else else
SVIS(dst, c, flag, nextc, nextra); dst = do_svis(dst, c, flag, nextc, nextra);
free(nextra);
*dst = '\0'; *dst = '\0';
free(to_be_freed); return dst;
return(dst);
} }
@ -221,140 +248,146 @@ svis(dst, c, flag, nextc, extra)
* be encoded, too. These functions are useful e. g. to * be encoded, too. These functions are useful e. g. to
* encode strings in such a way so that they are not interpreted * encode strings in such a way so that they are not interpreted
* by a shell. * by a shell.
* *
* Dst must be 4 times the size of src to account for possible * Dst must be 4 times the size of src to account for possible
* expansion. The length of dst, not including the trailing NULL, * expansion. The length of dst, not including the trailing NULL,
* is returned. * is returned.
* *
* Strsvisx encodes exactly len bytes from src into dst. * Strsvisx encodes exactly len bytes from src into dst.
* This is useful for encoding a block of data. * This is useful for encoding a block of data.
*/ */
int int
strsvis(dst, src, flag, extra) strsvis(char *dst, const char *csrc, int flag, const char *extra)
char *dst;
const char *src;
int flag;
const char *extra;
{ {
char c; int c;
char *start; char *start;
char *nextra, *to_be_freed; char *nextra = NULL;
const unsigned char *src = (const unsigned char *)csrc;
_DIAGASSERT(dst != NULL); _DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL); _DIAGASSERT(src != NULL);
_DIAGASSERT(extra != NULL); _DIAGASSERT(extra != NULL);
nextra= to_be_freed= MAKEEXTRALIST(flag, extra); MAKEEXTRALIST(flag, nextra, extra);
if (!nextra) {
*dst = '\0'; /* can't create nextra, return "" */
return 0;
}
if (flag & VIS_HTTPSTYLE) { if (flag & VIS_HTTPSTYLE) {
for (start = dst; (c = *src++) != '\0'; /* empty */) for (start = dst; (c = *src++) != '\0'; /* empty */)
HVIS(dst, c, flag, *src, nextra); dst = do_hvis(dst, c, flag, *src, nextra);
} else { } else {
for (start = dst; (c = *src++) != '\0'; /* empty */) for (start = dst; (c = *src++) != '\0'; /* empty */)
SVIS(dst, c, flag, *src, nextra); dst = do_svis(dst, c, flag, *src, nextra);
} }
free(nextra);
*dst = '\0'; *dst = '\0';
free(to_be_freed);
return (dst - start); return (dst - start);
} }
int int
strsvisx(dst, src, len, flag, extra) strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra)
char *dst;
const char *src;
size_t len;
int flag;
const char *extra;
{ {
char c; unsigned char c;
char *start; char *start;
char *nextra, *to_be_freed; char *nextra = NULL;
const unsigned char *src = (const unsigned char *)csrc;
_DIAGASSERT(dst != NULL); _DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL); _DIAGASSERT(src != NULL);
_DIAGASSERT(extra != NULL); _DIAGASSERT(extra != NULL);
nextra= to_be_freed= MAKEEXTRALIST(flag, extra); MAKEEXTRALIST(flag, nextra, extra);
if (! nextra) {
*dst = '\0'; /* can't create nextra, return "" */
return 0;
}
if (flag & VIS_HTTPSTYLE) { if (flag & VIS_HTTPSTYLE) {
for (start = dst; len > 0; len--) { for (start = dst; len > 0; len--) {
c = *src++; c = *src++;
HVIS(dst, c, flag, len ? *src : '\0', nextra); dst = do_hvis(dst, c, flag,
len > 1 ? *src : '\0', nextra);
} }
} else { } else {
for (start = dst; len > 0; len--) { for (start = dst; len > 0; len--) {
c = *src++; c = *src++;
SVIS(dst, c, flag, len ? *src : '\0', nextra); dst = do_svis(dst, c, flag,
len > 1 ? *src : '\0', nextra);
} }
} }
free(nextra);
*dst = '\0'; *dst = '\0';
free(to_be_freed);
return (dst - start); return (dst - start);
} }
#endif
#if !HAVE_VIS
/* /*
* vis - visually encode characters * vis - visually encode characters
*/ */
char * char *
vis(dst, c, flag, nextc) vis(char *dst, int c, int flag, int nextc)
char *dst;
int c, flag, nextc;
{ {
char *extra, *to_be_freed; char *extra = NULL;
unsigned char uc = (unsigned char)c;
_DIAGASSERT(dst != NULL); _DIAGASSERT(dst != NULL);
extra= to_be_freed= MAKEEXTRALIST(flag, ""); MAKEEXTRALIST(flag, extra, "");
if (! extra) {
*dst = '\0'; /* can't create extra, return "" */
return dst;
}
if (flag & VIS_HTTPSTYLE) if (flag & VIS_HTTPSTYLE)
HVIS(dst, c, flag, nextc, extra); dst = do_hvis(dst, uc, flag, nextc, extra);
else else
SVIS(dst, c, flag, nextc, extra); dst = do_svis(dst, uc, flag, nextc, extra);
free(extra);
*dst = '\0'; *dst = '\0';
free(to_be_freed); return dst;
return (dst);
} }
/* /*
* strvis, strvisx - visually encode characters from src into dst * strvis, strvisx - visually encode characters from src into dst
* *
* Dst must be 4 times the size of src to account for possible * Dst must be 4 times the size of src to account for possible
* expansion. The length of dst, not including the trailing NULL, * expansion. The length of dst, not including the trailing NULL,
* is returned. * is returned.
* *
* Strvisx encodes exactly len bytes from src into dst. * Strvisx encodes exactly len bytes from src into dst.
* This is useful for encoding a block of data. * This is useful for encoding a block of data.
*/ */
int int
strvis(dst, src, flag) strvis(char *dst, const char *src, int flag)
char *dst;
const char *src;
int flag;
{ {
char *extra; char *extra = NULL;
int tmp; int rv;
extra= MAKEEXTRALIST(flag, ""); MAKEEXTRALIST(flag, extra, "");
tmp= strsvis(dst, src, flag, extra); if (!extra) {
*dst = '\0'; /* can't create extra, return "" */
return 0;
}
rv = strsvis(dst, src, flag, extra);
free(extra); free(extra);
return tmp; return rv;
} }
int int
strvisx(dst, src, len, flag) strvisx(char *dst, const char *src, size_t len, int flag)
char *dst;
const char *src;
size_t len;
int flag;
{ {
char *extra; char *extra = NULL;
int tmp; int rv;
extra= MAKEEXTRALIST(flag, ""); MAKEEXTRALIST(flag, extra, "");
tmp= strsvisx(dst, src, len, flag, extra); if (!extra) {
*dst = '\0'; /* can't create extra, return "" */
return 0;
}
rv = strsvisx(dst, src, len, flag, extra);
free(extra); free(extra);
return tmp; return rv;
} }
#endif #endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: vis.h,v 1.12 2002/03/23 17:39:05 christos Exp $ */ /* $NetBSD: vis.h,v 1.16 2005/09/13 01:44:32 christos Exp $ */
/*- /*-
* Copyright (c) 1990, 1993 * Copyright (c) 1990, 1993
@ -12,11 +12,7 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software * 3. Neither the name of the University nor the names of its contributors
* 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 * may be used to endorse or promote products derived from this software
* without specific prior written permission. * without specific prior written permission.
* *
@ -38,9 +34,7 @@
#ifndef _VIS_H_ #ifndef _VIS_H_
#define _VIS_H_ #define _VIS_H_
#ifdef HAVE_SYS_CDEFS_H #include <sys/types.h>
#include <sys/cdefs.h>
#endif
/* /*
* to select alternate encoding format * to select alternate encoding format
@ -78,6 +72,7 @@
*/ */
#define UNVIS_END 1 /* no more characters */ #define UNVIS_END 1 /* no more characters */
__BEGIN_DECLS
char *vis(char *, int, int, int); char *vis(char *, int, int, int);
char *svis(char *, int, int, int, const char *); char *svis(char *, int, int, int, const char *);
int strvis(char *, const char *, int); int strvis(char *, const char *, int);
@ -86,11 +81,7 @@ int strvisx(char *, const char *, size_t, int);
int strsvisx(char *, const char *, size_t, int, const char *); int strsvisx(char *, const char *, size_t, int, const char *);
int strunvis(char *, const char *); int strunvis(char *, const char *);
int strunvisx(char *, const char *, int); int strunvisx(char *, const char *, int);
#ifdef __LIBC12_SOURCE__
int unvis(char *, int, int *, int); int unvis(char *, int, int *, int);
int __unvis13(char *, int, int *, int); __END_DECLS
#else
int unvis(char *, int, int *, int) __RENAME(__unvis13);
#endif
#endif /* !_VIS_H_ */ #endif /* !_VIS_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.c,v 1.20 2003/12/05 13:37:48 lukem Exp $ */ /* $NetBSD: parse.c,v 1.22 2005/05/29 04:58:15 lukem Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)parse.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* parse.c: parse an editline extended command * parse.c: parse an editline extended command
@ -129,7 +135,7 @@ el_parse(EditLine *el, int argc, const char *argv[])
* the appropriate character or -1 if the escape is not valid * the appropriate character or -1 if the escape is not valid
*/ */
protected int protected int
parse__escape(const char **const ptr) parse__escape(const char **ptr)
{ {
const char *p; const char *p;
int c; int c;

View File

@ -1,4 +1,4 @@
/* $NetBSD: parse.h,v 1.5 2003/08/07 16:44:32 agc Exp $ */ /* $NetBSD: parse.h,v 1.6 2005/05/29 04:58:15 lukem Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -41,7 +41,7 @@
#define _h_el_parse #define _h_el_parse
protected int parse_line(EditLine *, const char *); protected int parse_line(EditLine *, const char *);
protected int parse__escape(const char ** const); protected int parse__escape(const char **);
protected char *parse__string(char *, const char *); protected char *parse__string(char *, const char *);
protected int parse_cmd(EditLine *, const char *); protected int parse_cmd(EditLine *, const char *);

View File

@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)prompt.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* prompt.c: Prompt printing functions * prompt.c: Prompt printing functions

View File

@ -1,4 +1,4 @@
/* $NetBSD: read.c,v 1.35 2005/03/09 23:55:02 christos Exp $ */ /* $NetBSD: read.c,v 1.43 2009/02/05 19:15:44 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)read.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* read.c: Clean this junk up! This is horrible code. * read.c: Clean this junk up! This is horrible code.
@ -50,6 +56,7 @@ private int read__fixio(int, int);
private int read_preread(EditLine *); private int read_preread(EditLine *);
private int read_char(EditLine *, char *); private int read_char(EditLine *, char *);
private int read_getcmd(EditLine *, el_action_t *, char *); private int read_getcmd(EditLine *, el_action_t *, char *);
private void read_pop(c_macro_t *);
/* read_init(): /* read_init():
* Initialize the read stuff * Initialize the read stuff
@ -205,7 +212,7 @@ read_preread(EditLine *el)
* Push a macro * Push a macro
*/ */
public void public void
el_push(EditLine *el, char *str) el_push(EditLine *el, const char *str)
{ {
c_macro_t *ma = &el->el_chared.c_macro; c_macro_t *ma = &el->el_chared.c_macro;
@ -216,7 +223,7 @@ el_push(EditLine *el, char *str)
ma->level--; ma->level--;
} }
term_beep(el); term_beep(el);
term__flush(); term__flush(el);
} }
@ -294,6 +301,19 @@ read_char(EditLine *el, char *cp)
return (num_read); return (num_read);
} }
/* read_pop():
* Pop a macro from the stack
*/
private void
read_pop(c_macro_t *ma)
{
int i;
el_free(ma->macro[0]);
for (i = ma->level--; i > 0; i--)
ma->macro[i - 1] = ma->macro[i];
ma->offset = 0;
}
/* el_getc(): /* el_getc():
* Read a character * Read a character
@ -304,26 +324,28 @@ el_getc(EditLine *el, char *cp)
int num_read; int num_read;
c_macro_t *ma = &el->el_chared.c_macro; c_macro_t *ma = &el->el_chared.c_macro;
term__flush(); term__flush(el);
for (;;) { for (;;) {
if (ma->level < 0) { if (ma->level < 0) {
if (!read_preread(el)) if (!read_preread(el))
break; break;
} }
if (ma->level < 0) if (ma->level < 0)
break; break;
if (ma->macro[ma->level][ma->offset] == '\0') { if (ma->macro[0][ma->offset] == '\0') {
el_free(ma->macro[ma->level--]); read_pop(ma);
ma->offset = 0;
continue; continue;
} }
*cp = ma->macro[ma->level][ma->offset++] & 0377;
if (ma->macro[ma->level][ma->offset] == '\0') { *cp = ma->macro[0][ma->offset++] & 0377;
if (ma->macro[0][ma->offset] == '\0') {
/* Needed for QuoteMode On */ /* Needed for QuoteMode On */
el_free(ma->macro[ma->level--]); read_pop(ma);
ma->offset = 0;
} }
return (1); return (1);
} }
@ -357,11 +379,11 @@ read_prepare(EditLine *el)
we have the wrong size. */ we have the wrong size. */
el_resize(el); el_resize(el);
re_clear_display(el); /* reset the display stuff */ re_clear_display(el); /* reset the display stuff */
ch_reset(el); ch_reset(el, 0);
re_refresh(el); /* print the prompt */ re_refresh(el); /* print the prompt */
if (el->el_flags & UNBUFFERED) if (el->el_flags & UNBUFFERED)
term__flush(); term__flush(el);
} }
protected void protected void
@ -438,7 +460,7 @@ el_gets(EditLine *el, int *nread)
else else
cp = el->el_line.lastchar; cp = el->el_line.lastchar;
term__flush(); term__flush(el);
while ((*el->el_read.read_char)(el, cp) == 1) { while ((*el->el_read.read_char)(el, cp) == 1) {
/* make sure there is space next character */ /* make sure there is space next character */
@ -478,7 +500,7 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
break; break;
} }
if ((unsigned int)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */ if ((unsigned int)cmdnum >= (unsigned int)el->el_map.nfunc) { /* BUG CHECK command */
#ifdef DEBUG_EDIT #ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"ERROR: illegal command from key 0%o\r\n", ch); "ERROR: illegal command from key 0%o\r\n", ch);
@ -570,7 +592,7 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
/* put (real) cursor in a known place */ /* put (real) cursor in a known place */
re_clear_display(el); /* reset the display stuff */ re_clear_display(el); /* reset the display stuff */
ch_reset(el); /* reset the input pointers */ ch_reset(el, 1); /* reset the input pointers */
re_refresh(el); /* print the prompt again */ re_refresh(el); /* print the prompt again */
break; break;
@ -581,7 +603,7 @@ el_gets(EditLine *el, int *nread)
"*** editor ERROR ***\r\n\n"); "*** editor ERROR ***\r\n\n");
#endif /* DEBUG_READ */ #endif /* DEBUG_READ */
term_beep(el); term_beep(el);
term__flush(); term__flush(el);
break; break;
} }
el->el_state.argument = 1; el->el_state.argument = 1;
@ -591,7 +613,7 @@ el_gets(EditLine *el, int *nread)
break; break;
} }
term__flush(); /* flush any buffered output */ term__flush(el); /* flush any buffered output */
/* make sure the tty is set up correctly */ /* make sure the tty is set up correctly */
if ((el->el_flags & UNBUFFERED) == 0) { if ((el->el_flags & UNBUFFERED) == 0) {
read_finish(el); read_finish(el);

View File

@ -1,4 +1,4 @@
/* $NetBSD: read.h,v 1.4 2004/02/27 14:52:18 christos Exp $ */ /* $NetBSD: read.h,v 1.6 2008/04/29 06:53:01 martin Exp $ */
/*- /*-
* Copyright (c) 2001 The NetBSD Foundation, Inc. * Copyright (c) 2001 The NetBSD Foundation, Inc.
@ -15,13 +15,6 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
/* $NetBSD: readline.h,v 1.12 2004/09/08 18:15:37 christos Exp $ */ /* $NetBSD: readline.h,v 1.24 2009/02/05 19:15:26 christos Exp $ */
/*- /*-
* Copyright (c) 1997 The NetBSD Foundation, Inc. * Copyright (c) 1997 The NetBSD Foundation, Inc.
@ -15,13 +15,6 @@
* 2. Redistributions in binary form must reproduce the above copyright * 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the * notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution. * 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 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@ -45,14 +38,14 @@
/* typedefs */ /* typedefs */
typedef int Function(const char *, int); typedef int Function(const char *, int);
typedef void VFunction(void); typedef void VFunction(void);
typedef void VCPFunction(char *);
typedef char *CPFunction(const char *, int); typedef char *CPFunction(const char *, int);
typedef char **CPPFunction(const char *, int, int); typedef char **CPPFunction(const char *, int, int);
typedef char *rl_compentry_func_t(const char *, int);
typedef void *histdata_t;
typedef struct _hist_entry { typedef struct _hist_entry {
const char *line; const char *line;
histdata_t *data; const char *data;
} HIST_ENTRY; } HIST_ENTRY;
typedef struct _keymap_entry { typedef struct _keymap_entry {
@ -73,7 +66,7 @@ typedef KEYMAP_ENTRY *Keymap;
#ifndef CTRL #ifndef CTRL
#include <sys/ioctl.h> #include <sys/ioctl.h>
#if defined(__GLIBC__) || defined(__MWERKS__) #if !defined(__sun__) && !defined(__hpux__)
#include <sys/ttydefaults.h> #include <sys/ttydefaults.h>
#endif #endif
#ifndef CTRL #ifndef CTRL
@ -102,8 +95,9 @@ extern int max_input_history;
extern char *rl_basic_word_break_characters; extern char *rl_basic_word_break_characters;
extern char *rl_completer_word_break_characters; extern char *rl_completer_word_break_characters;
extern char *rl_completer_quote_characters; extern char *rl_completer_quote_characters;
extern CPFunction *rl_completion_entry_function; extern Function *rl_completion_entry_function;
extern CPPFunction *rl_attempted_completion_function; extern CPPFunction *rl_attempted_completion_function;
extern int rl_attempted_completion_over;
extern int rl_completion_type; extern int rl_completion_type;
extern int rl_completion_query_items; extern int rl_completion_query_items;
extern char *rl_special_prefixes; extern char *rl_special_prefixes;
@ -122,11 +116,13 @@ extern KEYMAP_ENTRY_ARRAY emacs_standard_keymap,
emacs_ctlx_keymap; emacs_ctlx_keymap;
extern int rl_filename_completion_desired; extern int rl_filename_completion_desired;
extern int rl_ignore_completion_duplicates; extern int rl_ignore_completion_duplicates;
extern Function *rl_getc_function; extern int (*rl_getc_function)(FILE *);
extern VFunction *rl_redisplay_function; extern VFunction *rl_redisplay_function;
extern VFunction *rl_completion_display_matches_hook; extern VFunction *rl_completion_display_matches_hook;
extern VFunction *rl_prep_term_function; extern VFunction *rl_prep_term_function;
extern VFunction *rl_deprep_term_function; extern VFunction *rl_deprep_term_function;
extern int readline_echoing_p;
extern int _rl_print_completions_horizontally;
/* supported functions */ /* supported functions */
char *readline(const char *); char *readline(const char *);
@ -141,6 +137,7 @@ int history_is_stifled(void);
int where_history(void); int where_history(void);
HIST_ENTRY *current_history(void); HIST_ENTRY *current_history(void);
HIST_ENTRY *history_get(int); HIST_ENTRY *history_get(int);
HIST_ENTRY *remove_history(int);
int history_total_bytes(void); int history_total_bytes(void);
int history_set_pos(int); int history_set_pos(int);
HIST_ENTRY *previous_history(void); HIST_ENTRY *previous_history(void);
@ -168,7 +165,7 @@ void rl_reset_terminal(const char *);
int rl_bind_key(int, int (*)(int, int)); int rl_bind_key(int, int (*)(int, int));
int rl_newline(int, int); int rl_newline(int, int);
void rl_callback_read_char(void); void rl_callback_read_char(void);
void rl_callback_handler_install(const char *, VFunction *); void rl_callback_handler_install(const char *, VCPFunction *);
void rl_callback_handler_remove(void); void rl_callback_handler_remove(void);
void rl_redisplay(void); void rl_redisplay(void);
int rl_get_previous_history(int, int); int rl_get_previous_history(int, int);
@ -176,13 +173,24 @@ void rl_prep_terminal(int);
void rl_deprep_terminal(void); void rl_deprep_terminal(void);
int rl_read_init_file(const char *); int rl_read_init_file(const char *);
int rl_parse_and_bind(const char *); int rl_parse_and_bind(const char *);
int rl_variable_bind(const char *, const char *);
void rl_stuff_char(int); void rl_stuff_char(int);
int rl_add_defun(const char *, Function *, int); int rl_add_defun(const char *, Function *, int);
void rl_get_screen_size(int *, int *);
void rl_set_screen_size(int, int);
char *rl_filename_completion_function (const char *, int);
int _rl_abort_internal(void);
int _rl_qsort_string_compare(char **, char **);
char **rl_completion_matches(const char *, rl_compentry_func_t *);
void rl_forced_update_display(void);
int rl_set_prompt(const char *);
/* /*
* The following are not implemented * The following are not implemented
*/ */
int rl_kill_text(int, int);
Keymap rl_get_keymap(void); Keymap rl_get_keymap(void);
void rl_set_keymap(Keymap);
Keymap rl_make_bare_keymap(void); Keymap rl_make_bare_keymap(void);
int rl_generic_bind(int, const char *, const char *, Keymap); int rl_generic_bind(int, const char *, const char *, Keymap);
int rl_bind_key_in_map(int, Function *, Keymap); int rl_bind_key_in_map(int, Function *, Keymap);

View File

@ -1,4 +1,4 @@
/* $NetBSD: refresh.c,v 1.26 2003/08/07 16:44:33 agc Exp $ */ /* $NetBSD: refresh.c,v 1.28 2008/09/10 15:45:37 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)refresh.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* refresh.c: Lower level screen refreshing functions * refresh.c: Lower level screen refreshing functions
@ -49,6 +55,7 @@ private void re_update_line(EditLine *, char *, char *, int);
private void re_insert (EditLine *, char *, int, int, char *, int); private void re_insert (EditLine *, char *, int, int, char *, int);
private void re_delete(EditLine *, char *, int, int, int); private void re_delete(EditLine *, char *, int, int, int);
private void re_fastputc(EditLine *, int); private void re_fastputc(EditLine *, int);
private void re_clear_eol(EditLine *, int, int, int);
private void re__strncopy(char *, char *, size_t); private void re__strncopy(char *, char *, size_t);
private void re__copy_and_pad(char *, const char *, size_t); private void re__copy_and_pad(char *, const char *, size_t);
@ -315,9 +322,9 @@ re_goto_bottom(EditLine *el)
{ {
term_move_to_line(el, el->el_refresh.r_oldcv); term_move_to_line(el, el->el_refresh.r_oldcv);
term__putc('\n'); term__putc(el, '\n');
re_clear_display(el); re_clear_display(el);
term__flush(); term__flush(el);
} }
@ -340,7 +347,7 @@ re_insert(EditLine *el __attribute__((__unused__)),
ELRE_DEBUG(1, ELRE_DEBUG(1,
(__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n", (__F, "re_insert() starting: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, d)); num, dat, dlen, d));
ELRE_DEBUG(1, (__F, "s == \"%s\"n", s)); ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
/* open up the space for num chars */ /* open up the space for num chars */
if (num > 0) { if (num > 0) {
@ -353,7 +360,7 @@ re_insert(EditLine *el __attribute__((__unused__)),
ELRE_DEBUG(1, (__F, ELRE_DEBUG(1, (__F,
"re_insert() after insert: %d at %d max %d, d == \"%s\"\n", "re_insert() after insert: %d at %d max %d, d == \"%s\"\n",
num, dat, dlen, d)); num, dat, dlen, d));
ELRE_DEBUG(1, (__F, "s == \"%s\"n", s)); ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
/* copy the characters */ /* copy the characters */
for (a = d + dat; (a < d + dlen) && (num > 0); num--) for (a = d + dat; (a < d + dlen) && (num > 0); num--)
@ -362,7 +369,7 @@ re_insert(EditLine *el __attribute__((__unused__)),
ELRE_DEBUG(1, ELRE_DEBUG(1,
(__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n", (__F, "re_insert() after copy: %d at %d max %d, %s == \"%s\"\n",
num, dat, dlen, d, s)); num, dat, dlen, d, s));
ELRE_DEBUG(1, (__F, "s == \"%s\"n", s)); ELRE_DEBUG(1, (__F, "s == \"%s\"\n", s));
} }
@ -411,6 +418,32 @@ re__strncopy(char *a, char *b, size_t n)
*a++ = *b++; *a++ = *b++;
} }
/* re_clear_eol():
* Find the number of characters we need to clear till the end of line
* in order to make sure that we have cleared the previous contents of
* the line. fx and sx is the number of characters inserted or deleted
* int the first or second diff, diff is the difference between the
* number of characters between the new and old line.
*/
private void
re_clear_eol(EditLine *el, int fx, int sx, int diff)
{
ELRE_DEBUG(1, (__F, "re_clear_eol sx %d, fx %d, diff %d\n",
sx, fx, diff));
if (fx < 0)
fx = -fx;
if (sx < 0)
sx = -sx;
if (fx > diff)
diff = fx;
if (sx > diff)
diff = sx;
ELRE_DEBUG(1, (__F, "re_clear_eol %d\n", diff));
term_clear_EOL(el, diff);
}
/***************************************************************** /*****************************************************************
re_update_line() is based on finding the middle difference of each line re_update_line() is based on finding the middle difference of each line
@ -626,7 +659,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
fx = (nsb - nfd) - (osb - ofd); fx = (nsb - nfd) - (osb - ofd);
sx = (nls - nse) - (ols - ose); sx = (nls - nse) - (ols - ose);
ELRE_DEBUG(1, (__F, "\n")); ELRE_DEBUG(1, (__F, "fx %d, sx %d\n", fx, sx));
ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n", ELRE_DEBUG(1, (__F, "ofd %d, osb %d, ose %d, ols %d, oe %d\n",
ofd - old, osb - old, ose - old, ols - old, oe - old)); ofd - old, osb - old, ose - old, ols - old, oe - old));
ELRE_DEBUG(1, (__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n", ELRE_DEBUG(1, (__F, "nfd %d, nsb %d, nse %d, nls %d, ne %d\n",
@ -775,9 +808,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
* write (nsb-nfd) chars of new starting at nfd * write (nsb-nfd) chars of new starting at nfd
*/ */
term_overwrite(el, nfd, (nsb - nfd)); term_overwrite(el, nfd, (nsb - nfd));
ELRE_DEBUG(1, (__F, re_clear_eol(el, fx, sx, (oe - old) - (ne - new));
"cleareol %d\n", (oe - old) - (ne - new)));
term_clear_EOL(el, (oe - old) - (ne - new));
/* /*
* Done * Done
*/ */
@ -818,10 +849,7 @@ re_update_line(EditLine *el, char *old, char *new, int i)
ELRE_DEBUG(1, (__F, ELRE_DEBUG(1, (__F,
"but with nothing left to save\r\n")); "but with nothing left to save\r\n"));
term_overwrite(el, nse, (nls - nse)); term_overwrite(el, nse, (nls - nse));
ELRE_DEBUG(1, (__F, re_clear_eol(el, fx, sx, (oe - old) - (ne - new));
"cleareol %d\n", (oe - old) - (ne - new)));
if ((oe - old) - (ne - new) != 0)
term_clear_EOL(el, (oe - old) - (ne - new));
} }
} }
/* /*
@ -982,7 +1010,7 @@ re_refresh_cursor(EditLine *el)
/* now go there */ /* now go there */
term_move_to_line(el, v); term_move_to_line(el, v);
term_move_to_char(el, h); term_move_to_char(el, h);
term__flush(); term__flush(el);
} }
@ -993,7 +1021,7 @@ private void
re_fastputc(EditLine *el, int c) re_fastputc(EditLine *el, int c)
{ {
term__putc(c); term__putc(el, c);
el->el_display[el->el_cursor.v][el->el_cursor.h++] = c; el->el_display[el->el_cursor.v][el->el_cursor.h++] = c;
if (el->el_cursor.h >= el->el_term.t_size.h) { if (el->el_cursor.h >= el->el_term.t_size.h) {
/* if we must overflow */ /* if we must overflow */
@ -1020,12 +1048,12 @@ re_fastputc(EditLine *el, int c)
} }
if (EL_HAS_AUTO_MARGINS) { if (EL_HAS_AUTO_MARGINS) {
if (EL_HAS_MAGIC_MARGINS) { if (EL_HAS_MAGIC_MARGINS) {
term__putc(' '); term__putc(el, ' ');
term__putc('\b'); term__putc(el, '\b');
} }
} else { } else {
term__putc('\r'); term__putc(el, '\r');
term__putc('\n'); term__putc(el, '\n');
} }
} }
} }
@ -1065,7 +1093,7 @@ re_fastaddc(EditLine *el)
re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0')); re_fastputc(el, (int)(((((unsigned int)c) >> 3) & 7) + '0'));
re_fastputc(el, (c & 7) + '0'); re_fastputc(el, (c & 7) + '0');
} }
term__flush(); term__flush(el);
} }
@ -1104,7 +1132,7 @@ re_clear_lines(EditLine *el)
} else { } else {
term_move_to_line(el, el->el_refresh.r_oldcv); term_move_to_line(el, el->el_refresh.r_oldcv);
/* go to last line */ /* go to last line */
term__putc('\r'); /* go to BOL */ term__putc(el, '\r'); /* go to BOL */
term__putc('\n'); /* go to new line */ term__putc(el, '\n'); /* go to new line */
} }
} }

View File

@ -32,12 +32,17 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)search.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* search.c: History and character search functions * search.c: History and character search functions
*/ */
#include <sys/types.h>
#include <stdlib.h> #include <stdlib.h>
#if defined(REGEX) #if defined(REGEX)
#include <regex.h> #include <regex.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: sig.c,v 1.11 2003/08/07 16:44:33 agc Exp $ */ /* $NetBSD: sig.c,v 1.12 2008/09/10 15:45:37 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)sig.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* sig.c: Signal handling stuff. * sig.c: Signal handling stuff.
@ -51,15 +57,15 @@ private const int sighdl[] = {
- 1 - 1
}; };
private void sig_handler(int); private void el_sig_handler(int);
/* sig_handler(): /* el_sig_handler():
* This is the handler called for all signals * This is the handler called for all signals
* XXX: we cannot pass any data so we just store the old editline * XXX: we cannot pass any data so we just store the old editline
* state in a private variable * state in a private variable
*/ */
private void private void
sig_handler(int signo) el_sig_handler(int signo)
{ {
int i; int i;
sigset_t nset, oset; sigset_t nset, oset;
@ -73,7 +79,7 @@ sig_handler(int signo)
tty_rawmode(sel); tty_rawmode(sel);
if (ed_redisplay(sel, 0) == CC_REFRESH) if (ed_redisplay(sel, 0) == CC_REFRESH)
re_refresh(sel); re_refresh(sel);
term__flush(); term__flush(sel);
break; break;
case SIGWINCH: case SIGWINCH:
@ -154,7 +160,7 @@ sig_set(EditLine *el)
for (i = 0; sighdl[i] != -1; i++) { for (i = 0; sighdl[i] != -1; i++) {
el_signalhandler_t s; el_signalhandler_t s;
/* This could happen if we get interrupted */ /* This could happen if we get interrupted */
if ((s = signal(sighdl[i], sig_handler)) != sig_handler) if ((s = signal(sighdl[i], el_sig_handler)) != el_sig_handler)
el->el_signal[i] = s; el->el_signal[i] = s;
} }
sel = el; sel = el;

View File

@ -1,4 +1,4 @@
/* $NetBSD: sig.h,v 1.5 2003/08/07 16:44:33 agc Exp $ */ /* $NetBSD: sig.h,v 1.6 2008/07/12 15:27:14 christos Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -51,7 +51,6 @@
#define ALLSIGS \ #define ALLSIGS \
_DO(SIGINT) \ _DO(SIGINT) \
_DO(SIGTSTP) \ _DO(SIGTSTP) \
_DO(SIGSTOP) \
_DO(SIGQUIT) \ _DO(SIGQUIT) \
_DO(SIGHUP) \ _DO(SIGHUP) \
_DO(SIGTERM) \ _DO(SIGTERM) \

View File

@ -1,73 +0,0 @@
/* $NetBSD: strlcpy.c,v 1.14 2003/10/27 00:12:42 lukem Exp $ */
/* $OpenBSD: strlcpy.c,v 1.7 2003/04/12 21:56:39 millert Exp $ */
/*
* Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND TODD C. MILLER DISCLAIMS ALL
* WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL TODD C. MILLER BE LIABLE
* FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <config.h>
#include <sys/types.h>
#include <assert.h>
#include <string.h>
#ifdef _LIBC
# ifdef __weak_alias
__weak_alias(strlcpy, _strlcpy)
# endif
#endif
#if !HAVE_STRLCPY
/*
* 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
#ifdef _LIBC
_strlcpy(dst, src, siz)
#else
strlcpy(dst, src, siz)
#endif
char *dst;
const char *src;
size_t siz;
{
char *d = dst;
const char *s = src;
size_t n = siz;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
/* 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 */
}
#endif

View File

@ -1,2 +0,0 @@
size_t strlcpy(char *dst, const char *src, size_t size);
size_t strlcat(char *dst, const char *src, size_t size);

View File

@ -48,14 +48,14 @@
# define __attribute__(A) # define __attribute__(A)
#endif #endif
#ifndef __P
# define __P(x) x
#endif
#ifndef _DIAGASSERT #ifndef _DIAGASSERT
# define _DIAGASSERT(x) # define _DIAGASSERT(x)
#endif #endif
#ifndef SIZE_T_MAX
# define SIZE_T_MAX UINT_MAX
#endif
#ifndef __BEGIN_DECLS #ifndef __BEGIN_DECLS
# ifdef __cplusplus # ifdef __cplusplus
# define __BEGIN_DECLS extern "C" { # define __BEGIN_DECLS extern "C" {
@ -113,6 +113,25 @@ char *fgetln(FILE *fp, size_t *len);
#define REGEX /* Use POSIX.2 regular expression functions */ #define REGEX /* Use POSIX.2 regular expression functions */
#undef REGEXP /* Use UNIX V8 regular expression functions */ #undef REGEXP /* Use UNIX V8 regular expression functions */
#ifdef __SunOS
extern int tgetent(char *, const char *);
extern int tgetflag(char *);
extern int tgetnum(char *);
extern int tputs(const char *, int, int (*)(int));
extern char* tgoto(const char*, int, int);
extern char* tgetstr(char*, char**);
#endif
/* XXXMYSQL: Bug#10218 Command line recall rolls into segfault */
#if !HAVE_DECL_TGOTO
/*
'tgoto' is not declared in the system header files, this causes
problems on 64-bit systems. The function returns a 64 bit pointer
but caller see it as "int" and it's thus truncated to 32-bit
*/
extern char* tgoto(const char*, int, int);
#endif
#ifdef notdef #ifdef notdef
# undef REGEX # undef REGEX
# undef REGEXP # undef REGEXP

View File

@ -1,4 +1,4 @@
/* $NetBSD: term.c,v 1.40 2004/05/22 23:21:28 christos Exp $ */ /* $NetBSD: term.c,v 1.48 2009/02/06 20:08:13 sketch Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)term.c 8.2 (Berkeley) 4/30/95";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* term.c: Editor/termcap-curses interface * term.c: Editor/termcap-curses interface
@ -44,21 +50,28 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#if 0 /* TODO: do we need this */
#ifdef HAVE_TERMCAP_H
#include <termcap.h>
#endif
#endif
#ifdef HAVE_CURSES_H #ifdef HAVE_CURSES_H
# include <curses.h> #include <curses.h>
#elif HAVE_NCURSES_H #endif
# include <ncurses.h> #ifdef HAVE_NCURSES_H
#include <ncurses.h>
#endif #endif
/* Solaris's term.h does horrid things. */ /* Solaris's term.h does horrid things. */
#if (defined(HAVE_TERM_H) && !defined(_SUNOS)) #if (defined(HAVE_TERM_H) && !defined(__SunOS))
# include <term.h> #include <term.h>
#endif #endif
#include <sys/types.h> #include <sys/types.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
#ifdef _REENTRANT
#include <pthread.h>
#endif
#include "el.h" #include "el.h"
/* /*
@ -263,9 +276,13 @@ private int term_alloc_display(EditLine *);
private void term_alloc(EditLine *, const struct termcapstr *, const char *); private void term_alloc(EditLine *, const struct termcapstr *, const char *);
private void term_init_arrow(EditLine *); private void term_init_arrow(EditLine *);
private void term_reset_arrow(EditLine *); private void term_reset_arrow(EditLine *);
private int term_putc(int);
private void term_tputs(EditLine *, const char *, int);
#ifdef _REENTRANT
private FILE *term_outfile = NULL; /* XXX: How do we fix that? */ private pthread_mutex_t term_mutex = PTHREAD_MUTEX_INITIALIZER;
#endif
private FILE *term_outfile = NULL;
/* term_setflags(): /* term_setflags():
@ -313,7 +330,6 @@ term_setflags(EditLine *el)
#endif /* DEBUG_SCREEN */ #endif /* DEBUG_SCREEN */
} }
/* term_init(): /* term_init():
* Initialize the terminal stuff * Initialize the terminal stuff
*/ */
@ -339,7 +355,6 @@ term_init(EditLine *el)
if (el->el_term.t_val == NULL) if (el->el_term.t_val == NULL)
return (-1); return (-1);
(void) memset(el->el_term.t_val, 0, T_val * sizeof(int)); (void) memset(el->el_term.t_val, 0, T_val * sizeof(int));
term_outfile = el->el_outfile;
(void) term_set(el, NULL); (void) term_set(el, NULL);
term_init_arrow(el); term_init_arrow(el);
return (0); return (0);
@ -390,7 +405,8 @@ term_alloc(EditLine *el, const struct termcapstr *t, const char *cap)
* New string is shorter; no need to allocate space * New string is shorter; no need to allocate space
*/ */
if (clen <= tlen) { if (clen <= tlen) {
(void) strcpy(*str, cap); /* XXX strcpy is safe */ if (*str)
(void) strcpy(*str, cap); /* XXX strcpy is safe */
return; return;
} }
/* /*
@ -464,8 +480,12 @@ term_alloc_display(EditLine *el)
return (-1); return (-1);
for (i = 0; i < c->v; i++) { for (i = 0; i < c->v; i++) {
b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1)));
if (b[i] == NULL) if (b[i] == NULL) {
while (--i >= 0)
el_free((ptr_t) b[i]);
el_free((ptr_t) b);
return (-1); return (-1);
}
} }
b[c->v] = NULL; b[c->v] = NULL;
el->el_display = b; el->el_display = b;
@ -475,8 +495,12 @@ term_alloc_display(EditLine *el)
return (-1); return (-1);
for (i = 0; i < c->v; i++) { for (i = 0; i < c->v; i++) {
b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1))); b[i] = (char *) el_malloc((size_t) (sizeof(char) * (c->h + 1)));
if (b[i] == NULL) if (b[i] == NULL) {
while (--i >= 0)
el_free((ptr_t) b[i]);
el_free((ptr_t) b);
return (-1); return (-1);
}
} }
b[c->v] = NULL; b[c->v] = NULL;
el->el_vdisplay = b; el->el_vdisplay = b;
@ -542,12 +566,12 @@ term_move_to_line(EditLine *el, int where)
del--; del--;
} else { } else {
if ((del > 1) && GoodStr(T_DO)) { if ((del > 1) && GoodStr(T_DO)) {
(void) tputs(tgoto(Str(T_DO), del, del), term_tputs(el, tgoto(Str(T_DO), del,
del, term__putc); del), del);
del = 0; del = 0;
} else { } else {
for (; del > 0; del--) for (; del > 0; del--)
term__putc('\n'); term__putc(el, '\n');
/* because the \n will become \r\n */ /* because the \n will become \r\n */
el->el_cursor.h = 0; el->el_cursor.h = 0;
} }
@ -555,12 +579,11 @@ term_move_to_line(EditLine *el, int where)
} }
} else { /* del < 0 */ } else { /* del < 0 */
if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up))) if (GoodStr(T_UP) && (-del > 1 || !GoodStr(T_up)))
(void) tputs(tgoto(Str(T_UP), -del, -del), -del, term_tputs(el, tgoto(Str(T_UP), -del, -del), -del);
term__putc);
else { else {
if (GoodStr(T_up)) if (GoodStr(T_up))
for (; del < 0; del++) for (; del < 0; del++)
(void) tputs(Str(T_up), 1, term__putc); term_tputs(el, Str(T_up), 1);
} }
} }
el->el_cursor.v = where;/* now where is here */ el->el_cursor.v = where;/* now where is here */
@ -587,7 +610,7 @@ mc_again:
return; return;
} }
if (!where) { /* if where is first column */ if (!where) { /* if where is first column */
term__putc('\r'); /* do a CR */ term__putc(el, '\r'); /* do a CR */
el->el_cursor.h = 0; el->el_cursor.h = 0;
return; return;
} }
@ -595,12 +618,11 @@ mc_again:
if ((del < -4 || del > 4) && GoodStr(T_ch)) if ((del < -4 || del > 4) && GoodStr(T_ch))
/* go there directly */ /* go there directly */
(void) tputs(tgoto(Str(T_ch), where, where), where, term__putc); term_tputs(el, tgoto(Str(T_ch), where, where), where);
else { else {
if (del > 0) { /* moving forward */ if (del > 0) { /* moving forward */
if ((del > 4) && GoodStr(T_RI)) if ((del > 4) && GoodStr(T_RI))
(void) tputs(tgoto(Str(T_RI), del, del), term_tputs(el, tgoto(Str(T_RI), del, del), del);
del, term__putc);
else { else {
/* if I can do tabs, use them */ /* if I can do tabs, use them */
if (EL_CAN_TAB) { if (EL_CAN_TAB) {
@ -611,7 +633,7 @@ mc_again:
(el->el_cursor.h & 0370); (el->el_cursor.h & 0370);
i < (where & 0370); i < (where & 0370);
i += 8) i += 8)
term__putc('\t'); term__putc(el, '\t');
/* then tab over */ /* then tab over */
el->el_cursor.h = where & 0370; el->el_cursor.h = where & 0370;
} }
@ -631,8 +653,8 @@ mc_again:
} }
} else { /* del < 0 := moving backward */ } else { /* del < 0 := moving backward */
if ((-del > 4) && GoodStr(T_LE)) if ((-del > 4) && GoodStr(T_LE))
(void) tputs(tgoto(Str(T_LE), -del, -del), term_tputs(el, tgoto(Str(T_LE), -del, -del),
-del, term__putc); -del);
else { /* can't go directly there */ else { /* can't go directly there */
/* /*
* if the "cost" is greater than the "cost" * if the "cost" is greater than the "cost"
@ -643,12 +665,12 @@ mc_again:
(((unsigned int) where >> 3) + (((unsigned int) where >> 3) +
(where & 07))) (where & 07)))
: (-del > where)) { : (-del > where)) {
term__putc('\r'); /* do a CR */ term__putc(el, '\r'); /* do a CR */
el->el_cursor.h = 0; el->el_cursor.h = 0;
goto mc_again; /* and try again */ goto mc_again; /* and try again */
} }
for (i = 0; i < -del; i++) for (i = 0; i < -del; i++)
term__putc('\b'); term__putc(el, '\b');
} }
} }
} }
@ -673,7 +695,7 @@ term_overwrite(EditLine *el, const char *cp, int n)
return; return;
} }
do { do {
term__putc(*cp++); term__putc(el, *cp++);
el->el_cursor.h++; el->el_cursor.h++;
} while (--n); } while (--n);
@ -689,7 +711,7 @@ term_overwrite(EditLine *el, const char *cp, int n)
!= '\0') != '\0')
term_overwrite(el, &c, 1); term_overwrite(el, &c, 1);
else else
term__putc(' '); term__putc(el, ' ');
el->el_cursor.h = 1; el->el_cursor.h = 1;
} }
} else /* no wrap, but cursor stays on screen */ } else /* no wrap, but cursor stays on screen */
@ -723,19 +745,18 @@ term_deletechars(EditLine *el, int num)
if (GoodStr(T_DC)) /* if I have multiple delete */ if (GoodStr(T_DC)) /* if I have multiple delete */
if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more if ((num > 1) || !GoodStr(T_dc)) { /* if dc would be more
* expen. */ * expen. */
(void) tputs(tgoto(Str(T_DC), num, num), term_tputs(el, tgoto(Str(T_DC), num, num), num);
num, term__putc);
return; return;
} }
if (GoodStr(T_dm)) /* if I have delete mode */ if (GoodStr(T_dm)) /* if I have delete mode */
(void) tputs(Str(T_dm), 1, term__putc); term_tputs(el, Str(T_dm), 1);
if (GoodStr(T_dc)) /* else do one at a time */ if (GoodStr(T_dc)) /* else do one at a time */
while (num--) while (num--)
(void) tputs(Str(T_dc), 1, term__putc); term_tputs(el, Str(T_dc), 1);
if (GoodStr(T_ed)) /* if I have delete mode */ if (GoodStr(T_ed)) /* if I have delete mode */
(void) tputs(Str(T_ed), 1, term__putc); term_tputs(el, Str(T_ed), 1);
} }
@ -764,37 +785,35 @@ term_insertwrite(EditLine *el, char *cp, int num)
if (GoodStr(T_IC)) /* if I have multiple insert */ if (GoodStr(T_IC)) /* if I have multiple insert */
if ((num > 1) || !GoodStr(T_ic)) { if ((num > 1) || !GoodStr(T_ic)) {
/* if ic would be more expensive */ /* if ic would be more expensive */
(void) tputs(tgoto(Str(T_IC), num, num), term_tputs(el, tgoto(Str(T_IC), num, num), num);
num, term__putc);
term_overwrite(el, cp, num); term_overwrite(el, cp, num);
/* this updates el_cursor.h */ /* this updates el_cursor.h */
return; return;
} }
if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */ if (GoodStr(T_im) && GoodStr(T_ei)) { /* if I have insert mode */
(void) tputs(Str(T_im), 1, term__putc); term_tputs(el, Str(T_im), 1);
el->el_cursor.h += num; el->el_cursor.h += num;
do do
term__putc(*cp++); term__putc(el, *cp++);
while (--num); while (--num);
if (GoodStr(T_ip)) /* have to make num chars insert */ if (GoodStr(T_ip)) /* have to make num chars insert */
(void) tputs(Str(T_ip), 1, term__putc); term_tputs(el, Str(T_ip), 1);
(void) tputs(Str(T_ei), 1, term__putc); term_tputs(el, Str(T_ei), 1);
return; return;
} }
do { do {
if (GoodStr(T_ic)) /* have to make num chars insert */ if (GoodStr(T_ic)) /* have to make num chars insert */
(void) tputs(Str(T_ic), 1, term__putc); term_tputs(el, Str(T_ic), 1);
/* insert a char */
term__putc(*cp++); term__putc(el, *cp++);
el->el_cursor.h++; el->el_cursor.h++;
if (GoodStr(T_ip)) /* have to make num chars insert */ if (GoodStr(T_ip)) /* have to make num chars insert */
(void) tputs(Str(T_ip), 1, term__putc); term_tputs(el, Str(T_ip), 1);
/* pad the inserted char */ /* pad the inserted char */
} while (--num); } while (--num);
@ -810,10 +829,10 @@ term_clear_EOL(EditLine *el, int num)
int i; int i;
if (EL_CAN_CEOL && GoodStr(T_ce)) if (EL_CAN_CEOL && GoodStr(T_ce))
(void) tputs(Str(T_ce), 1, term__putc); term_tputs(el, Str(T_ce), 1);
else { else {
for (i = 0; i < num; i++) for (i = 0; i < num; i++)
term__putc(' '); term__putc(el, ' ');
el->el_cursor.h += num; /* have written num spaces */ el->el_cursor.h += num; /* have written num spaces */
} }
} }
@ -828,14 +847,14 @@ term_clear_screen(EditLine *el)
if (GoodStr(T_cl)) if (GoodStr(T_cl))
/* send the clear screen code */ /* send the clear screen code */
(void) tputs(Str(T_cl), Val(T_li), term__putc); term_tputs(el, Str(T_cl), Val(T_li));
else if (GoodStr(T_ho) && GoodStr(T_cd)) { else if (GoodStr(T_ho) && GoodStr(T_cd)) {
(void) tputs(Str(T_ho), Val(T_li), term__putc); /* home */ term_tputs(el, Str(T_ho), Val(T_li)); /* home */
/* clear to bottom of screen */ /* clear to bottom of screen */
(void) tputs(Str(T_cd), Val(T_li), term__putc); term_tputs(el, Str(T_cd), Val(T_li));
} else { } else {
term__putc('\r'); term__putc(el, '\r');
term__putc('\n'); term__putc(el, '\n');
} }
} }
@ -848,9 +867,9 @@ term_beep(EditLine *el)
{ {
if (GoodStr(T_bl)) if (GoodStr(T_bl))
/* what termcap says we should use */ /* what termcap says we should use */
(void) tputs(Str(T_bl), 1, term__putc); term_tputs(el, Str(T_bl), 1);
else else
term__putc('\007'); /* an ASCII bell; ^G */ term__putc(el, '\007'); /* an ASCII bell; ^G */
} }
@ -862,9 +881,9 @@ protected void
term_clear_to_bottom(EditLine *el) term_clear_to_bottom(EditLine *el)
{ {
if (GoodStr(T_cd)) if (GoodStr(T_cd))
(void) tputs(Str(T_cd), Val(T_li), term__putc); term_tputs(el, Str(T_cd), Val(T_li));
else if (GoodStr(T_ce)) else if (GoodStr(T_ce))
(void) tputs(Str(T_ce), Val(T_li), term__putc); term_tputs(el, Str(T_ce), Val(T_li));
} }
#endif #endif
@ -936,7 +955,7 @@ term_set(EditLine *el, const char *term)
Val(T_co) = tgetnum("co"); Val(T_co) = tgetnum("co");
Val(T_li) = tgetnum("li"); Val(T_li) = tgetnum("li");
for (t = tstr; t->name != NULL; t++) { for (t = tstr; t->name != NULL; t++) {
/* XXX: some systems tgetstr needs non const */ /* XXX: some systems' tgetstr needs non const */
term_alloc(el, t, tgetstr(strchr(t->name, *t->name), term_alloc(el, t, tgetstr(strchr(t->name, *t->name),
&area)); &area));
} }
@ -1220,26 +1239,62 @@ term_bind_arrow(EditLine *el)
} }
} }
/* term_putc():
* Add a character
*/
private int
term_putc(int c)
{
if (term_outfile == NULL)
return -1;
return fputc(c, term_outfile);
}
private void
term_tputs(EditLine *el, const char *cap, int affcnt)
{
#ifdef _REENTRANT
pthread_mutex_lock(&term_mutex);
#endif
term_outfile = el->el_outfile;
(void)tputs(cap, affcnt, term_putc);
#ifdef _REENTRANT
pthread_mutex_unlock(&term_mutex);
#endif
}
/* term__putc(): /* term__putc():
* Add a character * Add a character
*/ */
protected int protected int
term__putc(int c) term__putc(EditLine *el, int c)
{ {
return (fputc(c, term_outfile)); return fputc(c, el->el_outfile);
} }
/* term__flush(): /* term__flush():
* Flush output * Flush output
*/ */
protected void protected void
term__flush(void) term__flush(EditLine *el)
{ {
(void) fflush(term_outfile); (void) fflush(el->el_outfile);
}
/* term_writec():
* Write the given character out, in a human readable form
*/
protected void
term_writec(EditLine *el, int c)
{
char buf[8];
int cnt = key__decode_char(buf, sizeof(buf), 0, c);
buf[cnt] = '\0';
term_overwrite(el, buf, cnt);
term__flush(el);
} }
@ -1269,11 +1324,17 @@ term_telltc(EditLine *el, int argc __attribute__((__unused__)),
(void) fprintf(el->el_outfile, "\tIt %s magic margins\n", (void) fprintf(el->el_outfile, "\tIt %s magic margins\n",
EL_HAS_MAGIC_MARGINS ? "has" : "does not have"); EL_HAS_MAGIC_MARGINS ? "has" : "does not have");
for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++) for (t = tstr, ts = el->el_term.t_str; t->name != NULL; t++, ts++) {
const char *ub;
if (*ts && **ts) {
(void) key__decode_str(*ts, upbuf, sizeof(upbuf), "");
ub = upbuf;
} else {
ub = "(empty)";
}
(void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n", (void) fprintf(el->el_outfile, "\t%25s (%s) == %s\n",
t->long_name, t->long_name, t->name, ub);
t->name, *ts && **ts ? }
key__decode_str(*ts, upbuf, "") : "(empty)");
(void) fputc('\n', el->el_outfile); (void) fputc('\n', el->el_outfile);
return (0); return (0);
} }
@ -1292,7 +1353,7 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)),
const char *what, *how; const char *what, *how;
if (argv == NULL || argv[1] == NULL || argv[2] == NULL) if (argv == NULL || argv[1] == NULL || argv[2] == NULL)
return (-1); return -1;
what = argv[1]; what = argv[1];
how = argv[2]; how = argv[2];
@ -1307,7 +1368,7 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)),
if (ts->name != NULL) { if (ts->name != NULL) {
term_alloc(el, ts, how); term_alloc(el, ts, how);
term_setflags(el); term_setflags(el);
return (0); return 0;
} }
/* /*
* Do the numeric ones second * Do the numeric ones second
@ -1316,46 +1377,100 @@ term_settc(EditLine *el, int argc __attribute__((__unused__)),
if (strcmp(tv->name, what) == 0) if (strcmp(tv->name, what) == 0)
break; break;
if (tv->name != NULL) { if (tv->name != NULL)
if (tv == &tval[T_pt] || tv == &tval[T_km] || return -1;
tv == &tval[T_am] || tv == &tval[T_xn]) {
if (strcmp(how, "yes") == 0)
el->el_term.t_val[tv - tval] = 1;
else if (strcmp(how, "no") == 0)
el->el_term.t_val[tv - tval] = 0;
else {
(void) fprintf(el->el_errfile,
"settc: Bad value `%s'.\n", how);
return (-1);
}
term_setflags(el);
if (term_change_size(el, Val(T_li), Val(T_co)) == -1)
return (-1);
return (0);
} else {
long i;
char *ep;
i = strtol(how, &ep, 10); if (tv == &tval[T_pt] || tv == &tval[T_km] ||
if (*ep != '\0') { tv == &tval[T_am] || tv == &tval[T_xn]) {
(void) fprintf(el->el_errfile, if (strcmp(how, "yes") == 0)
"settc: Bad value `%s'.\n", how); el->el_term.t_val[tv - tval] = 1;
return (-1); else if (strcmp(how, "no") == 0)
} el->el_term.t_val[tv - tval] = 0;
el->el_term.t_val[tv - tval] = (int) i; else {
el->el_term.t_size.v = Val(T_co); (void) fprintf(el->el_errfile,
el->el_term.t_size.h = Val(T_li); "%s: Bad value `%s'.\n", argv[0], how);
if (tv == &tval[T_co] || tv == &tval[T_li]) return -1;
if (term_change_size(el, Val(T_li), Val(T_co))
== -1)
return (-1);
return (0);
} }
term_setflags(el);
if (term_change_size(el, Val(T_li), Val(T_co)) == -1)
return -1;
return 0;
} else {
long i;
char *ep;
i = strtol(how, &ep, 10);
if (*ep != '\0') {
(void) fprintf(el->el_errfile,
"%s: Bad value `%s'.\n", argv[0], how);
return -1;
}
el->el_term.t_val[tv - tval] = (int) i;
el->el_term.t_size.v = Val(T_co);
el->el_term.t_size.h = Val(T_li);
if (tv == &tval[T_co] || tv == &tval[T_li])
if (term_change_size(el, Val(T_li), Val(T_co))
== -1)
return -1;
return 0;
} }
return (-1);
} }
/* term_gettc():
* Get the current terminal characteristics
*/
protected int
/*ARGSUSED*/
term_gettc(EditLine *el, int argc __attribute__((__unused__)), char **argv)
{
const struct termcapstr *ts;
const struct termcapval *tv;
char *what;
void *how;
if (argv == NULL || argv[1] == NULL || argv[2] == NULL)
return (-1);
what = argv[1];
how = argv[2];
/*
* Do the strings first
*/
for (ts = tstr; ts->name != NULL; ts++)
if (strcmp(ts->name, what) == 0)
break;
if (ts->name != NULL) {
*(char **)how = el->el_term.t_str[ts - tstr];
return 0;
}
/*
* Do the numeric ones second
*/
for (tv = tval; tv->name != NULL; tv++)
if (strcmp(tv->name, what) == 0)
break;
if (tv->name == NULL)
return -1;
if (tv == &tval[T_pt] || tv == &tval[T_km] ||
tv == &tval[T_am] || tv == &tval[T_xn]) {
static char yes[] = "yes";
static char no[] = "no";
if (el->el_term.t_val[tv - tval])
*(char **)how = yes;
else
*(char **)how = no;
return 0;
} else {
*(int *)how = el->el_term.t_val[tv - tval];
return 0;
}
}
/* term_echotc(): /* term_echotc():
* Print the termcap string out with variable substitution * Print the termcap string out with variable substitution
*/ */
@ -1441,7 +1556,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
break; break;
} }
if (t->name == NULL) { if (t->name == NULL) {
/* XXX: some systems tgetstr needs non const */ /* XXX: some systems' tgetstr needs non const */
scap = tgetstr(strchr(*argv, **argv), &area); scap = tgetstr(strchr(*argv, **argv), &area);
} }
if (!scap || scap[0] == '\0') { if (!scap || scap[0] == '\0') {
@ -1494,7 +1609,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
*argv); *argv);
return (-1); return (-1);
} }
(void) tputs(scap, 1, term__putc); term_tputs(el, scap, 1);
break; break;
case 1: case 1:
argv++; argv++;
@ -1522,7 +1637,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
*argv); *argv);
return (-1); return (-1);
} }
(void) tputs(tgoto(scap, arg_cols, arg_rows), 1, term__putc); term_tputs(el, tgoto(scap, arg_cols, arg_rows), 1);
break; break;
default: default:
/* This is wrong, but I will ignore it... */ /* This is wrong, but I will ignore it... */
@ -1578,8 +1693,7 @@ term_echotc(EditLine *el, int argc __attribute__((__unused__)),
*argv); *argv);
return (-1); return (-1);
} }
(void) tputs(tgoto(scap, arg_cols, arg_rows), arg_rows, term_tputs(el, tgoto(scap, arg_cols, arg_rows), arg_rows);
term__putc);
break; break;
} }
return (0); return (0);

View File

@ -32,7 +32,13 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)tokenizer.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* tokenize.c: Bourne shell like tokenizer * tokenize.c: Bourne shell like tokenizer

View File

@ -1,54 +0,0 @@
/* $NetBSD: tokenizer.h,v 1.5 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.
*
* @(#)tokenizer.h 8.1 (Berkeley) 6/4/93
*/
/*
* tokenizer.h: Header file for tokenizer routines
*/
#ifndef _h_tokenizer
#define _h_tokenizer
typedef struct tokenizer Tokenizer;
Tokenizer *tok_init(const char *);
void tok_reset(Tokenizer *);
void tok_end(Tokenizer *);
int tok_line(Tokenizer *, const char *, int *, const char ***);
#endif /* _h_tokenizer */

View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.c,v 1.21 2004/08/13 12:10:39 mycroft Exp $ */ /* $NetBSD: tty.c,v 1.28 2009/02/06 19:53:23 sketch Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,18 +32,25 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)tty.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* tty.c: tty interface stuff * tty.c: tty interface stuff
*/ */
#include <assert.h> #include <assert.h>
#include <errno.h>
#include "tty.h" #include "tty.h"
#include "el.h" #include "el.h"
typedef struct ttymodes_t { typedef struct ttymodes_t {
const char *m_name; const char *m_name;
u_int m_value; unsigned int m_value;
int m_type; int m_type;
} ttymodes_t; } ttymodes_t;
@ -438,13 +445,12 @@ private const ttymodes_t ttymodes[] = {
#define tty_getty(el, td) tcgetattr((el)->el_infd, (td))
#define tty_setty(el, td) tcsetattr((el)->el_infd, TCSADRAIN, (td))
#define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1) #define tty__gettabs(td) ((((td)->c_oflag & TAB3) == TAB3) ? 0 : 1)
#define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8) #define tty__geteightbit(td) (((td)->c_cflag & CSIZE) == CS8)
#define tty__cooked_mode(td) ((td)->c_lflag & ICANON) #define tty__cooked_mode(td) ((td)->c_lflag & ICANON)
private int tty_getty(EditLine *, struct termios *);
private int tty_setty(EditLine *, int, const struct termios *);
private int tty__getcharindex(int); private int tty__getcharindex(int);
private void tty__getchar(struct termios *, unsigned char *); private void tty__getchar(struct termios *, unsigned char *);
private void tty__setchar(struct termios *, unsigned char *); private void tty__setchar(struct termios *, unsigned char *);
@ -453,6 +459,29 @@ private int tty_setup(EditLine *);
#define t_qu t_ts #define t_qu t_ts
/* tty_getty():
* Wrapper for tcgetattr to handle EINTR
*/
private int
tty_getty(EditLine *el, struct termios *t)
{
int rv;
while ((rv = tcgetattr(el->el_infd, t)) == -1 && errno == EINTR)
continue;
return rv;
}
/* tty_setty():
* Wrapper for tcsetattr to handle EINTR
*/
private int
tty_setty(EditLine *el, int action, const struct termios *t)
{
int rv;
while ((rv = tcsetattr(el->el_infd, action, t)) == -1 && errno == EINTR)
continue;
return rv;
}
/* tty_setup(): /* tty_setup():
* Get the tty parameters and initialize the editing state * Get the tty parameters and initialize the editing state
@ -514,7 +543,7 @@ tty_setup(EditLine *el)
el->el_tty.t_c[TS_IO][rst]; el->el_tty.t_c[TS_IO][rst];
} }
tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
if (tty_setty(el, &el->el_tty.t_ex) == -1) { if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
#ifdef DEBUG_TTY #ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"tty_setup: tty_setty: %s\n", "tty_setup: tty_setty: %s\n",
@ -522,8 +551,11 @@ tty_setup(EditLine *el)
#endif /* DEBUG_TTY */ #endif /* DEBUG_TTY */
return (-1); return (-1);
} }
} else }
#ifdef notdef
else
tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]); tty__setchar(&el->el_tty.t_ex, el->el_tty.t_c[EX_IO]);
#endif
el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask; el->el_tty.t_ed.c_iflag &= ~el->el_tty.t_t[ED_IO][MD_INP].t_clrmask;
el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask; el->el_tty.t_ed.c_iflag |= el->el_tty.t_t[ED_IO][MD_INP].t_setmask;
@ -1040,7 +1072,7 @@ tty_rawmode(EditLine *el)
} }
} }
} }
if (tty_setty(el, &el->el_tty.t_ed) == -1) { if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
#ifdef DEBUG_TTY #ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n", (void) fprintf(el->el_errfile, "tty_rawmode: tty_setty: %s\n",
strerror(errno)); strerror(errno));
@ -1065,7 +1097,7 @@ tty_cookedmode(EditLine *el)
if (el->el_flags & EDIT_DISABLED) if (el->el_flags & EDIT_DISABLED)
return (0); return (0);
if (tty_setty(el, &el->el_tty.t_ex) == -1) { if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ex) == -1) {
#ifdef DEBUG_TTY #ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, (void) fprintf(el->el_errfile,
"tty_cookedmode: tty_setty: %s\n", "tty_cookedmode: tty_setty: %s\n",
@ -1101,7 +1133,7 @@ tty_quotemode(EditLine *el)
el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask; el->el_tty.t_qu.c_lflag &= ~el->el_tty.t_t[QU_IO][MD_LIN].t_clrmask;
el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask; el->el_tty.t_qu.c_lflag |= el->el_tty.t_t[QU_IO][MD_LIN].t_setmask;
if (tty_setty(el, &el->el_tty.t_qu) == -1) { if (tty_setty(el, TCSADRAIN, &el->el_tty.t_qu) == -1) {
#ifdef DEBUG_TTY #ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n", (void) fprintf(el->el_errfile, "QuoteModeOn: tty_setty: %s\n",
strerror(errno)); strerror(errno));
@ -1122,7 +1154,7 @@ tty_noquotemode(EditLine *el)
if (el->el_tty.t_mode != QU_IO) if (el->el_tty.t_mode != QU_IO)
return (0); return (0);
if (tty_setty(el, &el->el_tty.t_ed) == -1) { if (tty_setty(el, TCSADRAIN, &el->el_tty.t_ed) == -1) {
#ifdef DEBUG_TTY #ifdef DEBUG_TTY
(void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n", (void) fprintf(el->el_errfile, "QuoteModeOff: tty_setty: %s\n",
strerror(errno)); strerror(errno));
@ -1193,10 +1225,14 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
st = len = st = len =
strlen(el->el_tty.t_t[z][m->m_type].t_name); strlen(el->el_tty.t_t[z][m->m_type].t_name);
} }
x = (el->el_tty.t_t[z][i].t_setmask & m->m_value) if (i != -1) {
? '+' : '\0'; x = (el->el_tty.t_t[z][i].t_setmask & m->m_value)
x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value) ? '+' : '\0';
? '-' : x; x = (el->el_tty.t_t[z][i].t_clrmask & m->m_value)
? '-' : x;
} else {
x = '\0';
}
if (x != '\0' || aflag) { if (x != '\0' || aflag) {
@ -1221,7 +1257,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
return (0); return (0);
} }
while (argv && (s = *argv++)) { while (argv && (s = *argv++)) {
char *p; const char *p;
switch (*s) { switch (*s) {
case '+': case '+':
case '-': case '-':
@ -1232,10 +1268,10 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
break; break;
} }
d = s; d = s;
if ((p = strchr(s, '=')) != NULL) p = strchr(s, '=');
*p++ = '\0';
for (m = ttymodes; m->m_name; m++) for (m = ttymodes; m->m_name; m++)
if (strcmp(m->m_name, d) == 0 && if ((p ? strncmp(m->m_name, d, (size_t)(p - d)) :
strcmp(m->m_name, d)) == 0 &&
(p == NULL || m->m_type == MD_CHAR)) (p == NULL || m->m_type == MD_CHAR))
break; break;
@ -1246,7 +1282,7 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
} }
if (p) { if (p) {
int c = ffs((int)m->m_value); int c = ffs((int)m->m_value);
int v = *p ? parse__escape((const char **const) &p) : int v = *++p ? parse__escape((const char **) &p) :
el->el_tty.t_vdisable; el->el_tty.t_vdisable;
assert(c-- != 0); assert(c-- != 0);
c = tty__getcharindex(c); c = tty__getcharindex(c);
@ -1269,6 +1305,17 @@ tty_stty(EditLine *el, int argc __attribute__((__unused__)), const char **argv)
break; break;
} }
} }
if (el->el_tty.t_mode == z) {
if (tty_setty(el, TCSADRAIN, tios) == -1) {
#ifdef DEBUG_TTY
(void) fprintf(el->el_errfile,
"tty_stty: tty_setty: %s\n", strerror(errno));
#endif /* DEBUG_TTY */
return (-1);
}
}
return (0); return (0);
} }

View File

@ -1,4 +1,4 @@
/* $NetBSD: tty.h,v 1.10 2003/08/07 16:44:34 agc Exp $ */ /* $NetBSD: tty.h,v 1.11 2005/06/01 11:37:52 lukem Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -450,8 +450,8 @@
typedef struct { typedef struct {
const char *t_name; const char *t_name;
u_int t_setmask; unsigned int t_setmask;
u_int t_clrmask; unsigned int t_clrmask;
} ttyperm_t[NN_IO][MD_NN]; } ttyperm_t[NN_IO][MD_NN];
typedef unsigned char ttychar_t[NN_IO][C_NCC]; typedef unsigned char ttychar_t[NN_IO][C_NCC];

View File

@ -1,311 +0,0 @@
/* $NetBSD: unvis.c,v 1.24 2003/08/07 16:42:59 agc 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. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <config.h>
#define __LIBC12_SOURCE__
#include <sys/types.h>
#include <assert.h>
#include <ctype.h>
#include <stdio.h>
#include <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
/*
* 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

View File

@ -1,4 +1,4 @@
/* $NetBSD: vi.c,v 1.20 2004/08/13 12:10:39 mycroft Exp $ */ /* $NetBSD: vi.c,v 1.28 2009/02/06 13:14:37 sketch Exp $ */
/*- /*-
* Copyright (c) 1992, 1993 * Copyright (c) 1992, 1993
@ -32,11 +32,17 @@
* SUCH DAMAGE. * SUCH DAMAGE.
*/ */
#include <config.h> #include "config.h"
#include <stdlib.h> #include <stdlib.h>
#include <unistd.h> #include <unistd.h>
#include <sys/wait.h> #include <sys/wait.h>
#if !defined(lint) && !defined(SCCSID)
#if 0
static char sccsid[] = "@(#)vi.c 8.1 (Berkeley) 6/4/93";
#else
#endif
#endif /* not lint && not SCCSID */
/* /*
* vi.c: Vi mode commands. * vi.c: Vi mode commands.
@ -64,8 +70,10 @@ cv_action(EditLine *el, int c)
el->el_line.lastchar - el->el_line.buffer); el->el_line.lastchar - el->el_line.buffer);
el->el_chared.c_vcmd.action = NOP; el->el_chared.c_vcmd.action = NOP;
el->el_chared.c_vcmd.pos = 0; el->el_chared.c_vcmd.pos = 0;
el->el_line.lastchar = el->el_line.buffer; if (!(c & YANK)) {
el->el_line.cursor = el->el_line.buffer; el->el_line.lastchar = el->el_line.buffer;
el->el_line.cursor = el->el_line.buffer;
}
if (c & INSERT) if (c & INSERT)
el->el_map.current = el->el_map.key; el->el_map.current = el->el_map.key;
@ -82,7 +90,6 @@ cv_action(EditLine *el, int c)
private el_action_t private el_action_t
cv_paste(EditLine *el, int c) cv_paste(EditLine *el, int c)
{ {
char *ptr;
c_kill_t *k = &el->el_chared.c_kill; c_kill_t *k = &el->el_chared.c_kill;
int len = k->last - k->buf; int len = k->last - k->buf;
@ -96,12 +103,12 @@ cv_paste(EditLine *el, int c)
if (!c && el->el_line.cursor < el->el_line.lastchar) if (!c && el->el_line.cursor < el->el_line.lastchar)
el->el_line.cursor++; el->el_line.cursor++;
ptr = el->el_line.cursor;
c_insert(el, len); c_insert(el, len);
if (el->el_line.cursor + len > el->el_line.lastchar) if (el->el_line.cursor + len > el->el_line.lastchar)
return (CC_ERROR); return (CC_ERROR);
(void) memcpy(ptr, k->buf, len +0u); (void) memcpy(el->el_line.cursor, k->buf, len +0u);
return (CC_REFRESH); return (CC_REFRESH);
} }
@ -592,13 +599,12 @@ vi_delete_prev_char(EditLine *el, int c __attribute__((__unused__)))
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_list_or_eof(EditLine *el, int c __attribute__((__unused__))) vi_list_or_eof(EditLine *el, int c)
{ {
if (el->el_line.cursor == el->el_line.lastchar) { if (el->el_line.cursor == el->el_line.lastchar) {
if (el->el_line.cursor == el->el_line.buffer) { if (el->el_line.cursor == el->el_line.buffer) {
term_overwrite(el, STReof, 4); /* then do a EOF */ term_writec(el, c); /* then do a EOF */
term__flush();
return (CC_EOF); return (CC_EOF);
} else { } else {
/* /*
@ -888,7 +894,7 @@ vi_yank(EditLine *el, int c)
/* vi_comment_out(): /* vi_comment_out():
* Vi comment out current command * Vi comment out current command
* [c] * [#]
*/ */
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
@ -905,18 +911,19 @@ vi_comment_out(EditLine *el, int c)
/* vi_alias(): /* vi_alias():
* Vi include shell alias * Vi include shell alias
* [@] * [@]
* NB: posix impiles that we should enter insert mode, however * NB: posix implies that we should enter insert mode, however
* this is against historical precedent... * this is against historical precedent...
*/ */
#ifdef __weak_reference
extern char *get_alias_text(const char *) __weak_reference(get_alias_text);
#endif
protected el_action_t protected el_action_t
/*ARGSUSED*/ /*ARGSUSED*/
vi_alias(EditLine *el, int c) vi_alias(EditLine *el, int c)
{ {
#ifdef __weak_extern #ifdef __weak_reference
char alias_name[3]; char alias_name[3];
char *alias_text; char *alias_text;
extern char *get_alias_text(const char *);
__weak_extern(get_alias_text);
if (get_alias_text == 0) { if (get_alias_text == 0) {
return CC_ERROR; return CC_ERROR;
@ -1014,7 +1021,7 @@ vi_histedit(EditLine *el, int c)
return CC_ERROR; return CC_ERROR;
case 0: case 0:
close(fd); close(fd);
execlp("vi", "vi", tempfile, (char *) NULL); execlp("vi", "vi", tempfile, (char *)NULL);
exit(0); exit(0);
/*NOTREACHED*/ /*NOTREACHED*/
default: default:

View File

@ -1,392 +0,0 @@
/* $NetBSD: vis.c,v 1.27 2004/02/26 23:01:15 enami 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.
*/
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
*
* 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.
*/
/* AIX requires this to be the first thing in the file. */
#if defined (_AIX) && !defined (__GNUC__)
#pragma alloca
#endif
#include <config.h>
#ifdef __GNUC__
# undef alloca
# define alloca(n) __builtin_alloca (n)
#else
# ifdef HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifndef _AIX
extern char *alloca ();
# endif
# endif
#endif
#include <sys/types.h>
#include <assert.h>
#include <vis.h>
#include <stdlib.h>
#ifdef __weak_alias
__weak_alias(strsvis,_strsvis)
__weak_alias(strsvisx,_strsvisx)
__weak_alias(strvis,_strvis)
__weak_alias(strvisx,_strvisx)
__weak_alias(svis,_svis)
__weak_alias(vis,_vis)
#endif
#if !HAVE_VIS || !HAVE_SVIS
#include <ctype.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#undef BELL
#define BELL '\a'
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_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; \
isextra = strchr(extra, c) != NULL; \
if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \
((flag & VIS_SAFE) && issafe(c)))) { \
*dst++ = c; \
break; \
} \
if (flag & VIS_CSTYLE) { \
switch (c) { \
case '\n': \
*dst++ = '\\'; *dst++ = 'n'; \
continue; \
case '\r': \
*dst++ = '\\'; *dst++ = 'r'; \
continue; \
case '\b': \
*dst++ = '\\'; *dst++ = 'b'; \
continue; \
case BELL: \
*dst++ = '\\'; *dst++ = 'a'; \
continue; \
case '\v': \
*dst++ = '\\'; *dst++ = 'v'; \
continue; \
case '\t': \
*dst++ = '\\'; *dst++ = 't'; \
continue; \
case '\f': \
*dst++ = '\\'; *dst++ = 'f'; \
continue; \
case ' ': \
*dst++ = '\\'; *dst++ = 's'; \
continue; \
case '\0': \
*dst++ = '\\'; *dst++ = '0'; \
if (isoctal(nextc)) { \
*dst++ = '0'; \
*dst++ = '0'; \
} \
continue; \
default: \
if (isgraph(c)) { \
*dst++ = '\\'; *dst++ = c; \
continue; \
} \
} \
} \
if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \
*dst++ = '\\'; \
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; \
*dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; \
*dst++ = (c & 07) + '0'; \
} else { \
if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \
if (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, csrc, flag, extra)
char *dst;
const char *csrc;
int flag;
const char *extra;
{
int c;
char *start;
char *nextra;
const unsigned char *src = (const unsigned char *)csrc;
_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, csrc, len, flag, extra)
char *dst;
const char *csrc;
size_t len;
int flag;
const char *extra;
{
int c;
char *start;
char *nextra;
const unsigned char *src = (const unsigned char *)csrc;
_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);
}
#endif
#if !HAVE_VIS
/*
* 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

View File

@ -1,92 +0,0 @@
/* $NetBSD: vis.h,v 1.15 2005/02/03 04:39:32 perry 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. 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_
#include <config.h>
/*
* 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 */
__BEGIN_DECLS
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);
#endif
__END_DECLS
#endif /* !_VIS_H_ */

View File

@ -621,7 +621,6 @@ C_MODE_END
*/ */
#define _VARARGS(X) X #define _VARARGS(X) X
#define _STATIC_VARARGS(X) X #define _STATIC_VARARGS(X) X
#define _PC(X) X
/* The DBUG_ON flag always takes precedence over default DBUG_OFF */ /* The DBUG_ON flag always takes precedence over default DBUG_OFF */
#if defined(DBUG_ON) && defined(DBUG_OFF) #if defined(DBUG_ON) && defined(DBUG_OFF)

View File

@ -0,0 +1,27 @@
# BUG #36763: TRUNCATE TABLE fails to replicate when stmt-based
# binlogging is not supported.
# This should always be logged as a statement, even when executed as a
# row-by-row deletion.
# $before_truncate A statement to execute (just) before issuing the
# TRUNCATE TABLE
eval CREATE TABLE t1 (a INT) ENGINE=$engine;
eval CREATE TABLE t2 (a INT) ENGINE=$engine;
INSERT INTO t2 VALUES (1),(2),(3);
let $binlog_start = query_get_value("SHOW MASTER STATUS", Position, 1);
if (`select length('$before_truncate') > 0`) {
eval $before_truncate;
}
--echo **** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
if (`select length('$before_truncate') > 0`) {
eval $before_truncate;
}
TRUNCATE TABLE t2;
source include/show_binlog_events.inc;
DROP TABLE t1,t2;

View File

@ -9,27 +9,8 @@
--source include/master-slave.inc --source include/master-slave.inc
let $format = STATEMENT; let $trunc_stmt = TRUNCATE TABLE;
let $stmt = TRUNCATE TABLE;
--source extra/rpl_tests/rpl_truncate_helper.test --source extra/rpl_tests/rpl_truncate_helper.test
let $format = MIXED; let $trunc_stmt = DELETE FROM;
let $stmt = TRUNCATE TABLE;
--source extra/rpl_tests/rpl_truncate_helper.test --source extra/rpl_tests/rpl_truncate_helper.test
let $format = ROW;
let $stmt = TRUNCATE TABLE;
--source extra/rpl_tests/rpl_truncate_helper.test
let $format = STATEMENT;
let $stmt = DELETE FROM;
--source extra/rpl_tests/rpl_truncate_helper.test
let $format = MIXED;
let $stmt = DELETE FROM;
--source extra/rpl_tests/rpl_truncate_helper.test
let $format = ROW;
let $stmt = DELETE FROM;
--source extra/rpl_tests/rpl_truncate_helper.test

View File

@ -1,47 +1,35 @@
connection slave; source include/reset_master_and_slave.inc;
STOP SLAVE;
source include/wait_for_slave_to_stop.inc;
connection master;
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
connection slave;
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
RESET SLAVE;
START SLAVE;
--echo **** On Master **** --echo **** On Master ****
connection master; connection master;
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
eval SET SESSION BINLOG_FORMAT=$format;
eval SET GLOBAL BINLOG_FORMAT=$format;
eval CREATE TABLE t1 (a INT, b LONG) ENGINE=$engine; eval CREATE TABLE t1 (a INT, b LONG) ENGINE=$engine;
INSERT INTO t1 VALUES (1,1), (2,2); INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
--echo **** On Slave ****
sync_slave_with_master; sync_slave_with_master;
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
--echo **** On Master **** --echo **** On Master ****
connection master; connection master;
eval $stmt t1; eval $trunc_stmt t1;
SELECT * FROM t1;
--echo **** On Slave ****
sync_slave_with_master; sync_slave_with_master;
# Should be empty
SELECT * FROM t1; let $diff_table_1=master:test.t1;
let $diff_table_2=slave:test.t1;
source include/diff_tables.inc;
--echo ==== Test using a table with delete triggers ====
--echo **** On Master **** --echo **** On Master ****
connection master; connection master;
DROP TABLE t1; SET @count := 1;
let $SERVER_VERSION=`select version()`; eval CREATE TABLE t2 (a INT, b LONG) ENGINE=$engine;
source include/show_binlog_events.inc; CREATE TRIGGER trg1 BEFORE DELETE ON t1 FOR EACH ROW SET @count := @count + 1;
sync_slave_with_master;
--echo **** On Master ****
connection master;
eval $trunc_stmt t1;
sync_slave_with_master;
let $diff_table_1=master:test.t2;
let $diff_table_2=slave:test.t2;
source include/diff_tables.inc;
connection master; connection master;
RESET MASTER; DROP TABLE t1,t2;
SET @@session.binlog_format= @old_session_binlog_format; sync_slave_with_master;
SET @@global.binlog_format= @old_global_binlog_format;

View File

@ -1,5 +1,5 @@
# #
# Run a query over and over until it suceeds ot timeout occurs # Run a query over and over until it succeeds ot timeout occurs
# #
@ -17,7 +17,7 @@ while ($mysql_errno)
if (!$counter) if (!$counter)
{ {
die("Waited too long for query to suceed"); --die "Waited too long for query to succeed";
} }
} }
enable_abort_on_error; enable_abort_on_error;

View File

@ -82,7 +82,7 @@
# Created: 2009-01-14 mleich # Created: 2009-01-14 mleich
# #
let $wait_counter= 50; let $wait_counter= 100;
if ($wait_timeout) if ($wait_timeout)
{ {
let $wait_counter= `SELECT $wait_timeout * 10`; let $wait_counter= `SELECT $wait_timeout * 10`;
@ -108,5 +108,6 @@ if (!$success)
{ {
--echo # Timeout in wait_until_count_sessions.inc --echo # Timeout in wait_until_count_sessions.inc
--echo # Number of sessions expected: $count_sessions found: $current_sessions --echo # Number of sessions expected: $count_sessions found: $current_sessions
SHOW PROCESSLIST;
} }

View File

@ -77,14 +77,29 @@ static void message(const char* fmt, ...)
static void die(const char* fmt, ...) static void die(const char* fmt, ...)
{ {
DWORD last_err= GetLastError();
va_list args; va_list args;
fprintf(stderr, "%s: FATAL ERROR, ", safe_process_name); fprintf(stderr, "%s: FATAL ERROR, ", safe_process_name);
va_start(args, fmt); va_start(args, fmt);
vfprintf(stderr, fmt, args); vfprintf(stderr, fmt, args);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
va_end(args); va_end(args);
if (int last_err= GetLastError()) if (last_err)
fprintf(stderr, "error: %d, %s\n", last_err, strerror(last_err)); {
char *message_text;
if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER
|FORMAT_MESSAGE_IGNORE_INSERTS, NULL, last_err , 0, (LPSTR)&message_text,
0, NULL))
{
fprintf(stderr,"error: %d, %s\n",last_err, message_text);
LocalFree(message_text);
}
else
{
/* FormatMessage failed, print error code only */
fprintf(stderr,"error:%d\n", last_err);
}
}
fflush(stderr); fflush(stderr);
exit(1); exit(1);
} }

View File

@ -45,8 +45,8 @@ BEGIN {
print "=======================================================\n"; print "=======================================================\n";
print " WARNING: Using mysql-test-run.pl version 1! \n"; print " WARNING: Using mysql-test-run.pl version 1! \n";
print "=======================================================\n"; print "=======================================================\n";
require "lib/v1/mysql-test-run.pl"; # Should use exec() here on *nix but this appears not to work on Windows
exit(1); exit(system($^X, "lib/v1/mysql-test-run.pl", @ARGV) >> 8);
} }
elsif ( $version == 2 ) elsif ( $version == 2 )
{ {
@ -107,6 +107,17 @@ our $default_vardir;
our $opt_vardir; # Path to use for var/ dir our $opt_vardir; # Path to use for var/ dir
my $path_vardir_trace; # unix formatted opt_vardir for trace files my $path_vardir_trace; # unix formatted opt_vardir for trace files
my $opt_tmpdir; # Path to use for tmp/ dir my $opt_tmpdir; # Path to use for tmp/ dir
my $opt_tmpdir_pid;
END {
if (defined $opt_tmpdir_pid and
$opt_tmpdir_pid == $$){
# Remove the tempdir this process has created
mtr_verbose("Removing tmpdir '$opt_tmpdir");
rmtree($opt_tmpdir);
}
}
my $path_config_file; # The generated config file, var/my.cnf my $path_config_file; # The generated config file, var/my.cnf
# Visual Studio produces executables in different sub-directories based on the # Visual Studio produces executables in different sub-directories based on the
@ -1066,8 +1077,11 @@ sub command_line_setup {
" creating a shorter one..."); " creating a shorter one...");
# Create temporary directory in standard location for temporary files # Create temporary directory in standard location for temporary files
$opt_tmpdir= tempdir( TMPDIR => 1, CLEANUP => 1 ); $opt_tmpdir= tempdir( TMPDIR => 1, CLEANUP => 0 );
mtr_report(" - using tmpdir: '$opt_tmpdir'\n"); mtr_report(" - using tmpdir: '$opt_tmpdir'\n");
# Remember pid that created dir so it's removed by correct process
$opt_tmpdir_pid= $$;
} }
} }
$opt_tmpdir =~ s,/+$,,; # Remove ending slash if any $opt_tmpdir =~ s,/+$,,; # Remove ending slash if any
@ -2860,9 +2874,6 @@ test case was executed:\n";
$result= 2; $result= 2;
} }
# Remove the .err file the check generated
unlink($err_file);
# Remove the .result file the check generated # Remove the .result file the check generated
unlink("$base_file.result"); unlink("$base_file.result");
@ -3480,6 +3491,7 @@ sub start_check_warnings ($$) {
mtr_add_arg($args, "--skip-safemalloc"); mtr_add_arg($args, "--skip-safemalloc");
mtr_add_arg($args, "--test-file=%s", "include/check-warnings.test"); mtr_add_arg($args, "--test-file=%s", "include/check-warnings.test");
mtr_add_arg($args, "--verbose");
if ( $opt_embedded_server ) if ( $opt_embedded_server )
{ {
@ -3569,10 +3581,9 @@ sub check_warnings ($) {
if ( $res == 62 ) { if ( $res == 62 ) {
# Test case was ok and called "skip" # Test case was ok and called "skip"
; # Remove the .err file the check generated
unlink($err_file);
} }
# Remove the .err file the check generated
unlink($err_file);
if ( keys(%started) == 0){ if ( keys(%started) == 0){
# All checks completed # All checks completed
@ -3594,8 +3605,6 @@ sub check_warnings ($) {
$result= 2; $result= 2;
} }
# Remove the .err file the check generated
unlink($err_file);
} }
elsif ( $proc eq $timeout_proc ) { elsif ( $proc eq $timeout_proc ) {
$tinfo->{comment}.= "Timeout $timeout_proc for ". $tinfo->{comment}.= "Timeout $timeout_proc for ".
@ -4479,6 +4488,7 @@ sub start_check_testcase ($$$) {
mtr_add_arg($args, "--result-file=%s", "$opt_vardir/tmp/$name.result"); mtr_add_arg($args, "--result-file=%s", "$opt_vardir/tmp/$name.result");
mtr_add_arg($args, "--test-file=%s", "include/check-testcase.test"); mtr_add_arg($args, "--test-file=%s", "include/check-testcase.test");
mtr_add_arg($args, "--verbose");
if ( $mode eq "before" ) if ( $mode eq "before" )
{ {
@ -4648,8 +4658,7 @@ sub start_mysqltest ($) {
elsif ( $opt_client_debugger ) elsif ( $opt_client_debugger )
{ {
debugger_arguments(\$args, \$exe, "client"); debugger_arguments(\$args, \$exe, "client");
} }
my $proc= My::SafeProcess->new my $proc= My::SafeProcess->new
( (

View File

@ -687,8 +687,8 @@ SUCCESS
truncate table t2; truncate table t2;
call p_verify_status_increment(4, 0, 4, 0); call p_verify_status_increment(4, 0, 4, 0);
SUCCESS ERROR
Expected commit increment: 4 actual: 2
commit; commit;
# There is nothing left to commit # There is nothing left to commit
call p_verify_status_increment(0, 0, 0, 0); call p_verify_status_increment(0, 0, 0, 0);
@ -854,8 +854,8 @@ SUCCESS
truncate table t3; truncate table t3;
call p_verify_status_increment(4, 4, 4, 4); call p_verify_status_increment(4, 4, 4, 4);
SUCCESS ERROR
Expected commit increment: 4 actual: 2
create view v1 as select * from t2; create view v1 as select * from t2;
call p_verify_status_increment(1, 0, 1, 0); call p_verify_status_increment(1, 0, 1, 0);
SUCCESS SUCCESS

View File

@ -531,3 +531,7 @@ SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) FROM t1;
MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE)
2 2
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1(a TEXT);
SELECT GROUP_CONCAT(a) AS st FROM t1 HAVING MATCH(st) AGAINST('test' IN BOOLEAN MODE);
ERROR HY000: Incorrect arguments to AGAINST
DROP TABLE t1;

View File

@ -164,7 +164,7 @@ Warnings:
Warning 1364 Field 'ssl_cipher' doesn't have a default value Warning 1364 Field 'ssl_cipher' doesn't have a default value
Warning 1364 Field 'x509_issuer' doesn't have a default value Warning 1364 Field 'x509_issuer' doesn't have a default value
Warning 1364 Field 'x509_subject' doesn't have a default value Warning 1364 Field 'x509_subject' doesn't have a default value
insert into mysql.db (host, db, user, select_priv) values insert into mysql.db (host, db, user, select_priv) values
('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y'); ('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y');
alter table mysql.db order by db asc; alter table mysql.db order by db asc;
flush privileges; flush privileges;
@ -264,7 +264,7 @@ drop user mysqltest_1@localhost;
SET NAMES koi8r; SET NAMES koi8r;
CREATE DATABASE <20><>; CREATE DATABASE <20><>;
USE <20><>; USE <20><>;
CREATE TABLE <20><><EFBFBD> (<28><><EFBFBD> int); CREATE TABLE <20><><EFBFBD> (<28><><EFBFBD> INT);
GRANT SELECT ON <20><>.* TO <20><><EFBFBD><EFBFBD>@localhost; GRANT SELECT ON <20><>.* TO <20><><EFBFBD><EFBFBD>@localhost;
SHOW GRANTS FOR <20><><EFBFBD><EFBFBD>@localhost; SHOW GRANTS FOR <20><><EFBFBD><EFBFBD>@localhost;
Grants for <20><><EFBFBD><EFBFBD>@localhost Grants for <20><><EFBFBD><EFBFBD>@localhost
@ -383,21 +383,21 @@ grant update (a) on mysqltest_1.t1 to mysqltest_3@localhost;
grant select (b) on mysqltest_1.t2 to mysqltest_3@localhost; grant select (b) on mysqltest_1.t2 to mysqltest_3@localhost;
grant select (c) on mysqltest_2.t1 to mysqltest_3@localhost; grant select (c) on mysqltest_2.t1 to mysqltest_3@localhost;
grant update (d) on mysqltest_2.t2 to mysqltest_3@localhost; grant update (d) on mysqltest_2.t2 to mysqltest_3@localhost;
SELECT * FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES SELECT * FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES
WHERE GRANTEE = '''mysqltest_3''@''localhost''' WHERE GRANTEE = '''mysqltest_3''@''localhost'''
ORDER BY TABLE_NAME,COLUMN_NAME,PRIVILEGE_TYPE; ORDER BY TABLE_NAME,COLUMN_NAME,PRIVILEGE_TYPE;
GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME PRIVILEGE_TYPE IS_GRANTABLE
'mysqltest_3'@'localhost' NULL mysqltest_1 t1 a UPDATE NO 'mysqltest_3'@'localhost' NULL mysqltest_1 t1 a UPDATE NO
'mysqltest_3'@'localhost' NULL mysqltest_2 t1 c SELECT NO 'mysqltest_3'@'localhost' NULL mysqltest_2 t1 c SELECT NO
'mysqltest_3'@'localhost' NULL mysqltest_1 t2 b SELECT NO 'mysqltest_3'@'localhost' NULL mysqltest_1 t2 b SELECT NO
'mysqltest_3'@'localhost' NULL mysqltest_2 t2 d UPDATE NO 'mysqltest_3'@'localhost' NULL mysqltest_2 t2 d UPDATE NO
SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES
WHERE GRANTEE = '''mysqltest_3''@''localhost''' WHERE GRANTEE = '''mysqltest_3''@''localhost'''
ORDER BY TABLE_NAME,PRIVILEGE_TYPE; ORDER BY TABLE_NAME,PRIVILEGE_TYPE;
GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE GRANTEE TABLE_CATALOG TABLE_SCHEMA TABLE_NAME PRIVILEGE_TYPE IS_GRANTABLE
SELECT * from INFORMATION_SCHEMA.SCHEMA_PRIVILEGES SELECT * from INFORMATION_SCHEMA.SCHEMA_PRIVILEGES
WHERE GRANTEE = '''mysqltest_3''@''localhost''' WHERE GRANTEE = '''mysqltest_3''@''localhost'''
ORDER BY TABLE_SCHEMA,PRIVILEGE_TYPE; ORDER BY TABLE_SCHEMA,PRIVILEGE_TYPE;
GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE GRANTEE TABLE_CATALOG TABLE_SCHEMA PRIVILEGE_TYPE IS_GRANTABLE
SELECT * from INFORMATION_SCHEMA.USER_PRIVILEGES SELECT * from INFORMATION_SCHEMA.USER_PRIVILEGES
WHERE GRANTEE = '''mysqltest_3''@''localhost''' WHERE GRANTEE = '''mysqltest_3''@''localhost'''
@ -884,11 +884,11 @@ flush privileges;
drop table t2; drop table t2;
drop table t1; drop table t1;
CREATE DATABASE mysqltest3; CREATE DATABASE mysqltest3;
use mysqltest3; USE mysqltest3;
CREATE TABLE t_nn (c1 INT); CREATE TABLE t_nn (c1 INT);
CREATE VIEW v_nn AS SELECT * FROM t_nn; CREATE VIEW v_nn AS SELECT * FROM t_nn;
CREATE DATABASE mysqltest2; CREATE DATABASE mysqltest2;
use mysqltest2; USE mysqltest2;
CREATE TABLE t_nn (c1 INT); CREATE TABLE t_nn (c1 INT);
CREATE VIEW v_nn AS SELECT * FROM t_nn; CREATE VIEW v_nn AS SELECT * FROM t_nn;
CREATE VIEW v_yn AS SELECT * FROM t_nn; CREATE VIEW v_yn AS SELECT * FROM t_nn;
@ -958,7 +958,7 @@ DROP TABLE mysqltest3.t_nn;
DROP DATABASE mysqltest3; DROP DATABASE mysqltest3;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'mysqltest_1'@'localhost'; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'mysqltest_1'@'localhost';
DROP USER 'mysqltest_1'@'localhost'; DROP USER 'mysqltest_1'@'localhost';
use test; USE test;
create user mysqltest1_thisisreallytoolong; create user mysqltest1_thisisreallytoolong;
ERROR HY000: String 'mysqltest1_thisisreallytoolong' is too long for user name (should be no longer than 16) ERROR HY000: String 'mysqltest1_thisisreallytoolong' is too long for user name (should be no longer than 16)
CREATE DATABASE mysqltest1; CREATE DATABASE mysqltest1;
@ -1196,16 +1196,16 @@ DROP DATABASE mysqltest1;
DROP DATABASE mysqltest2; DROP DATABASE mysqltest2;
DROP USER mysqltest_1@localhost; DROP USER mysqltest_1@localhost;
DROP USER mysqltest_2@localhost; DROP USER mysqltest_2@localhost;
use test; USE test;
CREATE TABLE t1 (f1 int, f2 int); CREATE TABLE t1 (f1 int, f2 int);
INSERT INTO t1 VALUES(1,1), (2,2); INSERT INTO t1 VALUES(1,1), (2,2);
CREATE DATABASE db27878; CREATE DATABASE db27878;
GRANT UPDATE(f1) ON t1 TO 'mysqltest_1'@'localhost'; GRANT UPDATE(f1) ON t1 TO 'mysqltest_1'@'localhost';
GRANT SELECT ON `test`.* TO 'mysqltest_1'@'localhost'; GRANT SELECT ON `test`.* TO 'mysqltest_1'@'localhost';
GRANT ALL ON db27878.* TO 'mysqltest_1'@'localhost'; GRANT ALL ON db27878.* TO 'mysqltest_1'@'localhost';
use db27878; USE db27878;
CREATE SQL SECURITY INVOKER VIEW db27878.v1 AS SELECT * FROM test.t1; CREATE SQL SECURITY INVOKER VIEW db27878.v1 AS SELECT * FROM test.t1;
use db27878; USE db27878;
UPDATE v1 SET f2 = 4; UPDATE v1 SET f2 = 4;
ERROR HY000: View 'db27878.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them ERROR HY000: View 'db27878.v1' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them
SELECT * FROM test.t1; SELECT * FROM test.t1;
@ -1217,7 +1217,7 @@ REVOKE SELECT ON `test`.* FROM 'mysqltest_1'@'localhost';
REVOKE ALL ON db27878.* FROM 'mysqltest_1'@'localhost'; REVOKE ALL ON db27878.* FROM 'mysqltest_1'@'localhost';
DROP USER mysqltest_1@localhost; DROP USER mysqltest_1@localhost;
DROP DATABASE db27878; DROP DATABASE db27878;
use test; USE test;
DROP TABLE t1; DROP TABLE t1;
# #
# Bug#33275 Server crash when creating temporary table mysql.user # Bug#33275 Server crash when creating temporary table mysql.user
@ -1355,6 +1355,6 @@ Warnings:
Warning 1403 There is no such grant defined for user 'userbug33464' on host 'localhost' on routine 'fn2' Warning 1403 There is no such grant defined for user 'userbug33464' on host 'localhost' on routine 'fn2'
DROP PROCEDURE sp3; DROP PROCEDURE sp3;
DROP USER 'userbug33464'@'localhost'; DROP USER 'userbug33464'@'localhost';
use test; USE test;
DROP DATABASE dbbug33464; DROP DATABASE dbbug33464;
SET @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators; SET @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators;

View File

@ -99,7 +99,7 @@ t2
t3 t3
t5 t5
v1 v1
select c,table_name from v1 select c,table_name from v1
inner join information_schema.TABLES v2 on (v1.c=v2.table_name) inner join information_schema.TABLES v2 on (v1.c=v2.table_name)
where v1.c like "t%"; where v1.c like "t%";
c table_name c table_name
@ -118,7 +118,7 @@ t4 t4
t2 t2 t2 t2
t3 t3 t3 t3
t5 t5 t5 t5
select c,table_name from v1 select c,table_name from v1
left join information_schema.TABLES v2 on (v1.c=v2.table_name) left join information_schema.TABLES v2 on (v1.c=v2.table_name)
where v1.c like "t%"; where v1.c like "t%";
c table_name c table_name
@ -197,7 +197,7 @@ a int(11) YES NULL
create view mysqltest.v1 (c) as select a from mysqltest.t1; create view mysqltest.v1 (c) as select a from mysqltest.t1;
grant select (a) on mysqltest.t1 to mysqltest_2@localhost; grant select (a) on mysqltest.t1 to mysqltest_2@localhost;
grant select on mysqltest.v1 to mysqltest_3; grant select on mysqltest.v1 to mysqltest_3;
select table_name, column_name, privileges from information_schema.columns select table_name, column_name, privileges from information_schema.columns
where table_schema = 'mysqltest' and table_name = 't1'; where table_schema = 'mysqltest' and table_name = 't1';
table_name column_name privileges table_name column_name privileges
t1 a select t1 a select
@ -275,7 +275,7 @@ begin
select * from t1; select * from t1;
select * from t2; select * from t2;
end| end|
select parameter_style, sql_data_access, dtd_identifier select parameter_style, sql_data_access, dtd_identifier
from information_schema.routines where routine_schema='test'; from information_schema.routines where routine_schema='test';
parameter_style sql_data_access dtd_identifier parameter_style sql_data_access dtd_identifier
SQL CONTAINS SQL NULL SQL CONTAINS SQL NULL
@ -560,7 +560,7 @@ drop view v1;
create table t1(a NUMERIC(5,3), b NUMERIC(5,1), c float(5,2), create table t1(a NUMERIC(5,3), b NUMERIC(5,1), c float(5,2),
d NUMERIC(6,4), e float, f DECIMAL(6,3), g int(11), h DOUBLE(10,3), d NUMERIC(6,4), e float, f DECIMAL(6,3), g int(11), h DOUBLE(10,3),
i DOUBLE); i DOUBLE);
select COLUMN_NAME,COLUMN_TYPE, CHARACTER_MAXIMUM_LENGTH, select COLUMN_NAME,COLUMN_TYPE, CHARACTER_MAXIMUM_LENGTH,
CHARACTER_OCTET_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE CHARACTER_OCTET_LENGTH, NUMERIC_PRECISION, NUMERIC_SCALE
from information_schema.columns where table_name= 't1'; from information_schema.columns where table_name= 't1';
COLUMN_NAME COLUMN_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE COLUMN_NAME COLUMN_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE
@ -621,7 +621,7 @@ TABLE_NAME= "vo";
CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION POSITION_IN_UNIQUE_CONSTRAINT REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION POSITION_IN_UNIQUE_CONSTRAINT REFERENCED_TABLE_SCHEMA REFERENCED_TABLE_NAME REFERENCED_COLUMN_NAME
drop view vo; drop view vo;
select TABLE_NAME,TABLE_TYPE,ENGINE select TABLE_NAME,TABLE_TYPE,ENGINE
from information_schema.tables from information_schema.tables
where table_schema='information_schema' limit 2; where table_schema='information_schema' limit 2;
TABLE_NAME TABLE_TYPE ENGINE TABLE_NAME TABLE_TYPE ENGINE
CHARACTER_SETS SYSTEM VIEW MEMORY CHARACTER_SETS SYSTEM VIEW MEMORY
@ -726,7 +726,7 @@ where table_schema="information_schema" and table_name="COLUMNS" and
column_type column_type
varchar(32) varchar(32)
varchar(32) varchar(32)
select TABLE_ROWS from information_schema.tables where select TABLE_ROWS from information_schema.tables where
table_schema="information_schema" and table_name="COLUMNS"; table_schema="information_schema" and table_name="COLUMNS";
TABLE_ROWS TABLE_ROWS
NULL NULL
@ -760,7 +760,7 @@ count(*)
drop view a2, a1; drop view a2, a1;
drop table t_crashme; drop table t_crashme;
select table_schema,table_name, column_name from select table_schema,table_name, column_name from
information_schema.columns information_schema.columns
where data_type = 'longtext'; where data_type = 'longtext';
table_schema table_name column_name table_schema table_name column_name
information_schema COLUMNS COLUMN_DEFAULT information_schema COLUMNS COLUMN_DEFAULT
@ -804,7 +804,7 @@ event last_executed datetime
event starts datetime event starts datetime
event ends datetime event ends datetime
SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES A SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES A
WHERE NOT EXISTS WHERE NOT EXISTS
(SELECT * FROM INFORMATION_SCHEMA.COLUMNS B (SELECT * FROM INFORMATION_SCHEMA.COLUMNS B
WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA
AND A.TABLE_NAME = B.TABLE_NAME); AND A.TABLE_NAME = B.TABLE_NAME);
@ -833,7 +833,7 @@ x_float NULL NULL
x_double_precision NULL NULL x_double_precision NULL NULL
drop table t1; drop table t1;
grant select on test.* to mysqltest_4@localhost; grant select on test.* to mysqltest_4@localhost;
SELECT TABLE_NAME, COLUMN_NAME, PRIVILEGES FROM INFORMATION_SCHEMA.COLUMNS SELECT TABLE_NAME, COLUMN_NAME, PRIVILEGES FROM INFORMATION_SCHEMA.COLUMNS
where COLUMN_NAME='TABLE_NAME'; where COLUMN_NAME='TABLE_NAME';
TABLE_NAME COLUMN_NAME PRIVILEGES TABLE_NAME COLUMN_NAME PRIVILEGES
COLUMNS TABLE_NAME select COLUMNS TABLE_NAME select
@ -1079,7 +1079,7 @@ BEGIN
SELECT 'foo' FROM DUAL; SELECT 'foo' FROM DUAL;
END | END |
ERROR 42000: Unknown database 'information_schema' ERROR 42000: Unknown database 'information_schema'
select ROUTINE_NAME from routines where ROUTINE_SCHEMA='information_schema'; select ROUTINE_NAME from routines where ROUTINE_SCHEMA='information_schema';
ROUTINE_NAME ROUTINE_NAME
grant all on information_schema.* to 'user1'@'localhost'; grant all on information_schema.* to 'user1'@'localhost';
ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema' ERROR 42000: Access denied for user 'root'@'localhost' to database 'information_schema'
@ -1634,7 +1634,7 @@ show events where Db= 'information_schema';
Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation Db Name Definer Time zone Type Execute at Interval value Interval field Starts Ends Status Originator character_set_client collation_connection Database Collation
use test; use test;
# #
# Bug#34166: Server crash in SHOW OPEN TABLES and prelocking # Bug#34166 Server crash in SHOW OPEN TABLES and prelocking
# #
drop table if exists t1; drop table if exists t1;
drop function if exists f1; drop function if exists f1;

View File

@ -0,0 +1,9 @@
show variables like 'ignore_builtin_innodb';
Variable_name Value
ignore_builtin_innodb ON
select PLUGIN_NAME from information_schema.plugins
where PLUGIN_NAME = "InnoDb";
PLUGIN_NAME
select ENGINE from information_schema.engines
where ENGINE = "InnoDB";
ENGINE

View File

@ -2025,7 +2025,6 @@ TABLE_SCHEMA = 'test' and TABLE_NAME='tm1';
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT
NULL test tm1 BASE TABLE NULL NULL NULL # # # # # # # # # # NULL # # Unable to open underlying table which is differently defined or of non-MyISAM ty NULL test tm1 BASE TABLE NULL NULL NULL # # # # # # # # # # NULL # # Unable to open underlying table which is differently defined or of non-MyISAM ty
DROP TABLE tm1; DROP TABLE tm1;
End of 5.1 tests
CREATE TABLE t1(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM; CREATE TABLE t1(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM;
CREATE TABLE t2(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM; CREATE TABLE t2(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM;
CREATE TABLE t3(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM; CREATE TABLE t3(C1 INT, C2 INT, KEY C1(C1), KEY C2(C2)) ENGINE=MYISAM;
@ -2041,4 +2040,67 @@ EXPLAIN SELECT COUNT(*) FROM t4;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
DROP TABLE t1, t2, t3, t4; DROP TABLE t1, t2, t3, t4;
CREATE TABLE t1(a INT, KEY(a));
INSERT INTO t1 VALUES(0),(1),(2),(3),(4);
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
CREATE TABLE m1(a INT, KEY(a)) ENGINE=MERGE UNION=(t1);
SELECT CARDINALITY FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA='test' AND TABLE_NAME='m1';
CARDINALITY
5
SELECT CARDINALITY FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA='test' AND TABLE_NAME='m1';
CARDINALITY
5
SELECT CARDINALITY FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA='test' AND TABLE_NAME='m1';
CARDINALITY
5
SELECT CARDINALITY FROM INFORMATION_SCHEMA.STATISTICS WHERE TABLE_SCHEMA='test' AND TABLE_NAME='m1';
CARDINALITY
5
DROP TABLE t1, m1;
#
# Bug #40675 MySQL 5.1 crash with index merge algorithm and Merge tables
#
# create MYISAM table t1 and insert values into it
CREATE TABLE t1(a INT);
INSERT INTO t1 VALUES(1);
# create MYISAM table t2 and insert values into it
CREATE TABLE t2(a INT, b INT, dummy CHAR(16) DEFAULT '', KEY(a), KEY(b));
INSERT INTO t2(a,b) VALUES
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),(0,0),
(1,2);
# Create the merge table t3
CREATE TABLE t3(a INT, b INT, dummy CHAR(16) DEFAULT '', KEY(a), KEY(b))
ENGINE=MERGE UNION=(t2) INSERT_METHOD=FIRST;
# Lock tables t1 and t3 for write
LOCK TABLES t1 WRITE, t3 WRITE;
# Insert values into the merge table t3
INSERT INTO t3(a,b) VALUES(1,2);
# select from the join of t2 and t3 (The merge table)
SELECT t3.a FROM t1,t3 WHERE t3.b=2 AND t3.a=1;
a
1
1
# Unlock the tables
UNLOCK TABLES;
# drop the created tables
DROP TABLE t1, t2, t3;
End of 5.1 tests End of 5.1 tests

View File

@ -375,7 +375,7 @@ update t2, t1 set t2.field=t1.field
where t1.id1=t2.id2 and 0=1; where t1.id1=t2.id2 and 0=1;
delete t1, t2 from t2 inner join t1 on t1.id1=t2.id2 delete t1, t2 from t2 inner join t1 on t1.id1=t2.id2
where 0=1; where 0=1;
delete t1, t2 from t2,t1 delete t1, t2 from t2,t1
where t1.id1=t2.id2 and 0=1; where t1.id1=t2.id2 and 0=1;
drop table t1,t2; drop table t1,t2;
CREATE TABLE t1 ( a int ); CREATE TABLE t1 ( a int );
@ -443,12 +443,12 @@ delete t1 from t1,t2 where t1.col1 < (select max(col1) from t1) and t1.col1 = t2
ERROR HY000: You can't specify target table 't1' for update in FROM clause ERROR HY000: You can't specify target table 't1' for update in FROM clause
drop table t1,t2; drop table t1,t2;
create table t1 ( create table t1 (
aclid bigint not null primary key, aclid bigint not null primary key,
status tinyint(1) not null status tinyint(1) not null
) engine = innodb; ) engine = innodb;
create table t2 ( create table t2 (
refid bigint not null primary key, refid bigint not null primary key,
aclid bigint, index idx_acl(aclid) aclid bigint, index idx_acl(aclid)
) engine = innodb; ) engine = innodb;
insert into t2 values(1,null); insert into t2 values(1,null);
delete t2, t1 from t2 left join t1 on (t2.aclid=t1.aclid) where t2.refid='1'; delete t2, t1 from t2 left join t1 on (t2.aclid=t1.aclid) where t2.refid='1';

View File

@ -215,7 +215,7 @@ COMMIT/*!*/;
# at # # at #
#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
BEGIN TRUNCATE TABLE t1
/*!*/; /*!*/;
# at # # at #
#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
@ -223,22 +223,6 @@ SET TIMESTAMP=1000000000/*!*/;
TRUNCATE TABLE t1 TRUNCATE TABLE t1
/*!*/; /*!*/;
# at # # at #
#010909 4:46:40 server id 1 end_log_pos # Xid = #
COMMIT/*!*/;
# at #
#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
BEGIN
/*!*/;
# at #
#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
TRUNCATE TABLE t1
/*!*/;
# at #
#010909 4:46:40 server id 1 end_log_pos # Xid = #
COMMIT/*!*/;
# at #
#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
BEGIN BEGIN
@ -347,17 +331,9 @@ COMMIT/*!*/;
# at # # at #
#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
BEGIN
/*!*/;
# at #
#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
TRUNCATE TABLE t1 TRUNCATE TABLE t1
/*!*/; /*!*/;
# at # # at #
#010909 4:46:40 server id 1 end_log_pos # Xid = #
COMMIT/*!*/;
# at #
#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
TRUNCATE TABLE t2 TRUNCATE TABLE t2
@ -473,17 +449,9 @@ ROLLBACK
# at # # at #
#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
BEGIN
/*!*/;
# at #
#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/;
TRUNCATE TABLE t1 TRUNCATE TABLE t1
/*!*/; /*!*/;
# at # # at #
#010909 4:46:40 server id 1 end_log_pos # Xid = #
COMMIT/*!*/;
# at #
#010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0 #010909 4:46:40 server id 1 end_log_pos # Query thread_id=# exec_time=# error_code=0
SET TIMESTAMP=1000000000/*!*/; SET TIMESTAMP=1000000000/*!*/;
TRUNCATE TABLE t2 TRUNCATE TABLE t2

View File

@ -1,3 +1,5 @@
set @max_allowed_packet=@@global.max_allowed_packet;
set @net_buffer_length=@@global.net_buffer_length;
set global max_allowed_packet=100; set global max_allowed_packet=100;
Warnings: Warnings:
Warning 1292 Truncated incorrect max_allowed_packet value: '100' Warning 1292 Truncated incorrect max_allowed_packet value: '100'
@ -23,3 +25,5 @@ len
select length(repeat('a',2000)); select length(repeat('a',2000));
length(repeat('a',2000)) length(repeat('a',2000))
2000 2000
set global max_allowed_packet=@max_allowed_packet;
set global net_buffer_length=@net_buffer_length;

View File

@ -375,6 +375,7 @@ id
show status like 'Qcache_queries_in_cache'; show status like 'Qcache_queries_in_cache';
Variable_name Value Variable_name Value
Qcache_queries_in_cache 1 Qcache_queries_in_cache 1
USE test;
DROP DATABASE bug30269; DROP DATABASE bug30269;
DROP USER 'bug30269'@'localhost'; DROP USER 'bug30269'@'localhost';
set GLOBAL query_cache_type=default; set GLOBAL query_cache_type=default;

View File

@ -1,12 +1,18 @@
set @start_read_only= @@global.read_only;
DROP TABLE IF EXISTS t1,t2,t3; DROP TABLE IF EXISTS t1,t2,t3;
grant CREATE, SELECT, DROP on *.* to test@localhost; grant CREATE, SELECT, DROP on *.* to test@localhost;
connect (con1,localhost,test,,test);
connection default;
set global read_only=0; set global read_only=0;
connection con1;
create table t1 (a int); create table t1 (a int);
insert into t1 values(1); insert into t1 values(1);
create table t2 select * from t1; create table t2 select * from t1;
connection default;
set global read_only=1; set global read_only=1;
create table t3 (a int); create table t3 (a int);
drop table t3; drop table t3;
connection con1;
select @@global.read_only; select @@global.read_only;
@@global.read_only @@global.read_only
1 1
@ -39,13 +45,18 @@ delete t1 from t1,t3 where t1.a=t3.a;
drop table t1; drop table t1;
insert into t1 values(1); insert into t1 values(1);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
connection default;
set global read_only=0; set global read_only=0;
lock table t1 write; lock table t1 write;
connection con1;
lock table t2 write; lock table t2 write;
connection default;
set global read_only=1; set global read_only=1;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
unlock tables ; unlock tables ;
send set global read_only=1;
set global read_only=1; set global read_only=1;
connection con1;
select @@global.read_only; select @@global.read_only;
@@global.read_only @@global.read_only
0 0
@ -53,13 +64,20 @@ unlock tables ;
select @@global.read_only; select @@global.read_only;
@@global.read_only @@global.read_only
1 1
connection default;
reap;
connection default;
set global read_only=0; set global read_only=0;
lock table t1 read; lock table t1 read;
connection con1;
lock table t2 read; lock table t2 read;
connection default;
set global read_only=1; set global read_only=1;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
unlock tables ; unlock tables ;
send set global read_only=1;
set global read_only=1; set global read_only=1;
connection con1;
select @@global.read_only; select @@global.read_only;
@@global.read_only @@global.read_only
0 0
@ -67,24 +85,35 @@ unlock tables ;
select @@global.read_only; select @@global.read_only;
@@global.read_only @@global.read_only
1 1
connection default;
reap;
connection default;
set global read_only=0; set global read_only=0;
BEGIN; BEGIN;
connection con1;
BEGIN; BEGIN;
connection default;
set global read_only=1; set global read_only=1;
ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction
ROLLBACK; ROLLBACK;
set global read_only=1; set global read_only=1;
connection con1;
select @@global.read_only; select @@global.read_only;
@@global.read_only @@global.read_only
1 1
ROLLBACK; ROLLBACK;
connection default;
set global read_only=0; set global read_only=0;
flush tables with read lock; flush tables with read lock;
set global read_only=1; set global read_only=1;
unlock tables; unlock tables;
connect (root2,localhost,root,,test);
connection default;
set global read_only=0; set global read_only=0;
flush tables with read lock; flush tables with read lock;
connection root2;
set global read_only=1; set global read_only=1;
connection default;
select @@global.read_only; select @@global.read_only;
@@global.read_only @@global.read_only
1 1
@ -94,6 +123,7 @@ ERROR 42S02: Unknown table 'ttt'
drop temporary table if exists ttt; drop temporary table if exists ttt;
Warnings: Warnings:
Note 1051 Unknown table 'ttt' Note 1051 Unknown table 'ttt'
connection default;
set global read_only=0; set global read_only=0;
drop table t1,t2; drop table t1,t2;
drop user test@localhost; drop user test@localhost;
@ -112,16 +142,20 @@ grant all on mysqltest_db2.* to `mysqltest_u1`@`%`;
create database mysqltest_db1; create database mysqltest_db1;
grant all on mysqltest_db1.* to `mysqltest_u1`@`%`; grant all on mysqltest_db1.* to `mysqltest_u1`@`%`;
flush privileges; flush privileges;
connect (con_bug27440,127.0.0.1,mysqltest_u1,,test,MASTER_MYPORT,);
connection con_bug27440;
create database mysqltest_db2; create database mysqltest_db2;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
show databases like '%mysqltest_db2%'; show databases like '%mysqltest_db2%';
Database (%mysqltest_db2%) Database (%mysqltest_db2%)
drop database mysqltest_db1; drop database mysqltest_db1;
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
disconnect con_bug27440;
connection default;
delete from mysql.user where User like 'mysqltest_%'; delete from mysql.user where User like 'mysqltest_%';
delete from mysql.db where User like 'mysqltest_%'; delete from mysql.db where User like 'mysqltest_%';
delete from mysql.tables_priv where User like 'mysqltest_%'; delete from mysql.tables_priv where User like 'mysqltest_%';
delete from mysql.columns_priv where User like 'mysqltest_%'; delete from mysql.columns_priv where User like 'mysqltest_%';
flush privileges; flush privileges;
drop database mysqltest_db1; drop database mysqltest_db1;
set global read_only=0; set global read_only= @start_read_only;

View File

@ -192,11 +192,11 @@ select (select a from t3 where a<t2.a*4 order by 1 desc limit 1), a from t2;
(select a from t3 where a<t2.a*4 order by 1 desc limit 1) a (select a from t3 where a<t2.a*4 order by 1 desc limit 1) a
3 1 3 1
7 2 7 2
select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
(select * from t2 where a>1) as tt; (select * from t2 where a>1) as tt;
(select t3.a from t3 where a<8 order by 1 desc limit 1) a (select t3.a from t3 where a<8 order by 1 desc limit 1) a
7 2 7 2
explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from explain extended select (select t3.a from t3 where a<8 order by 1 desc limit 1), a from
(select * from t2 where a>1) as tt; (select * from t2 where a>1) as tt;
id select_type table type possible_keys key key_len ref rows filtered Extra id select_type table type possible_keys key key_len ref rows filtered Extra
1 PRIMARY <derived3> system NULL NULL NULL NULL 1 100.00 1 PRIMARY <derived3> system NULL NULL NULL NULL 1 100.00
@ -2303,20 +2303,20 @@ drop table t1,t2;
CREATE TABLE t1 ( a int, b int ); CREATE TABLE t1 ( a int, b int );
CREATE TABLE t2 ( c int, d int ); CREATE TABLE t2 ( c int, d int );
INSERT INTO t1 VALUES (1,2), (2,3), (3,4); INSERT INTO t1 VALUES (1,2), (2,3), (3,4);
SELECT a AS abc, b FROM t1 outr WHERE b = SELECT a AS abc, b FROM t1 outr WHERE b =
(SELECT MIN(b) FROM t1 WHERE a=outr.a); (SELECT MIN(b) FROM t1 WHERE a=outr.a);
abc b abc b
1 2 1 2
2 3 2 3
3 4 3 4
INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b = INSERT INTO t2 SELECT a AS abc, b FROM t1 outr WHERE b =
(SELECT MIN(b) FROM t1 WHERE a=outr.a); (SELECT MIN(b) FROM t1 WHERE a=outr.a);
select * from t2; select * from t2;
c d c d
1 2 1 2
2 3 2 3
3 4 3 4
CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b = CREATE TABLE t3 SELECT a AS abc, b FROM t1 outr WHERE b =
(SELECT MIN(b) FROM t1 WHERE a=outr.a); (SELECT MIN(b) FROM t1 WHERE a=outr.a);
select * from t3; select * from t3;
abc b abc b
@ -2517,8 +2517,8 @@ INSERT INTO t1 VALUES ('ASM','American Samoa','Oceania','Polynesia',199.00,0,680
INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF'); INSERT INTO t1 VALUES ('ATF','French Southern territories','Antarctica','Antarctica',7780.00,0,0,NULL,0.00,NULL,'Terres australes françaises','Nonmetropolitan Territory of France','Jacques Chirac',NULL,'TF');
INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM'); INSERT INTO t1 VALUES ('UMI','United States Minor Outlying Islands','Oceania','Micronesia/Caribbean',16.00,0,0,NULL,0.00,NULL,'United States Minor Outlying Islands','Dependent Territory of the US','George W. Bush',NULL,'UM');
/*!40000 ALTER TABLE t1 ENABLE KEYS */; /*!40000 ALTER TABLE t1 ENABLE KEYS */;
SELECT DISTINCT Continent AS c FROM t1 outr WHERE SELECT DISTINCT Continent AS c FROM t1 outr WHERE
Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND Code <> SOME ( SELECT Code FROM t1 WHERE Continent = outr.Continent AND
Population < 200); Population < 200);
c c
Oceania Oceania
@ -2628,32 +2628,32 @@ select
count(distinct t2.userid) pass, count(distinct t2.userid) pass,
groupstuff.*, groupstuff.*,
count(t2.courseid) crse, count(t2.courseid) crse,
t1.categoryid, t1.categoryid,
t2.courseid, t2.courseid,
date_format(date, '%b%y') as colhead date_format(date, '%b%y') as colhead
from t2 from t2
join t1 on t2.courseid=t1.courseid join t1 on t2.courseid=t1.courseid
join join
( (
select select
t5.userid, t5.userid,
parentid, parentid,
parentgroup, parentgroup,
childid, childid,
groupname, groupname,
grouptypeid grouptypeid
from t5 from t5
join join
( (
select t4.id as parentid, select t4.id as parentid,
t4.name as parentgroup, t4.name as parentgroup,
t4.id as childid, t4.id as childid,
t4.name as groupname, t4.name as groupname,
t4.grouptypeid t4.grouptypeid
from t4 from t4
) as gin on t5.groupid=gin.childid ) as gin on t5.groupid=gin.childid
) as groupstuff on t2.userid = groupstuff.userid ) as groupstuff on t2.userid = groupstuff.userid
group by group by
groupstuff.groupname, colhead , t2.courseid; groupstuff.groupname, colhead , t2.courseid;
pass userid parentid parentgroup childid groupname grouptypeid crse categoryid courseid colhead pass userid parentid parentgroup childid groupname grouptypeid crse categoryid courseid colhead
1 5141 12 group2 12 group2 5 1 5 12 Aug04 1 5141 12 group2 12 group2 5 1 5 12 Aug04
@ -2929,9 +2929,9 @@ INSERT INTO t1 VALUES("0037", "1", "2005-12-06 12:18:56");
INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53"); INSERT INTO t1 VALUES("0037", "2", "2006-01-06 12:25:53");
INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50"); INSERT INTO t1 VALUES("0048", "1", "2006-01-06 12:37:50");
INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50"); INSERT INTO t1 VALUES("0059", "1", "2006-01-06 12:37:50");
select * from t1 r1 select * from t1 r1
where (r1.retailerID,(r1.changed)) in where (r1.retailerID,(r1.changed)) in
(SELECT r2.retailerId,(max(changed)) from t1 r2 (SELECT r2.retailerId,(max(changed)) from t1 r2
group by r2.retailerId); group by r2.retailerId);
retailerID statusID changed retailerID statusID changed
0026 2 2006-01-06 12:25:53 0026 2 2006-01-06 12:25:53
@ -2943,41 +2943,41 @@ create table t1(a int, primary key (a));
insert into t1 values (10); insert into t1 values (10);
create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b)); create table t2 (a int primary key, b varchar(32), c int, unique key b(c, b));
insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989'); insert into t2(a, c, b) values (1,10,'359'), (2,10,'35988'), (3,10,'35989');
explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
1 PRIMARY r const PRIMARY PRIMARY 4 const 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using where 2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using where
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10; ORDER BY t2.c DESC, t2.b DESC LIMIT 1) WHERE t1.a = 10;
a a b a a b
10 3 35989 10 3 35989
explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r explain SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 system PRIMARY NULL NULL NULL 1 1 PRIMARY t1 system PRIMARY NULL NULL NULL 1
1 PRIMARY r const PRIMARY PRIMARY 4 const 1 1 PRIMARY r const PRIMARY PRIMARY 4 const 1
2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using where 2 DEPENDENT SUBQUERY t2 range b b 40 NULL 2 Using where
SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r SELECT sql_no_cache t1.a, r.a, r.b FROM t1 LEFT JOIN t2 r
ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899' ON r.a = (SELECT t2.a FROM t2 WHERE t2.c = t1.a AND t2.b <= '359899'
ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10; ORDER BY t2.c, t2.b LIMIT 1) WHERE t1.a = 10;
a a b a a b
10 1 359 10 1 359
drop table t1,t2; drop table t1,t2;
CREATE TABLE t1 ( CREATE TABLE t1 (
field1 int NOT NULL, field1 int NOT NULL,
field2 int NOT NULL, field2 int NOT NULL,
field3 int NOT NULL, field3 int NOT NULL,
PRIMARY KEY (field1,field2,field3) PRIMARY KEY (field1,field2,field3)
); );
CREATE TABLE t2 ( CREATE TABLE t2 (
fieldA int NOT NULL, fieldA int NOT NULL,
fieldB int NOT NULL, fieldB int NOT NULL,
PRIMARY KEY (fieldA,fieldB) PRIMARY KEY (fieldA,fieldB)
); );
INSERT INTO t1 VALUES INSERT INTO t1 VALUES
(1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1); (1,1,1), (1,1,2), (1,2,1), (1,2,2), (1,2,3), (1,3,1);
@ -2991,14 +2991,14 @@ field1 field2 COUNT(*)
SELECT field1, field2 SELECT field1, field2
FROM t1 FROM t1
GROUP BY field1, field2 GROUP BY field1, field2
HAVING COUNT(*) >= ALL (SELECT fieldB HAVING COUNT(*) >= ALL (SELECT fieldB
FROM t2 WHERE fieldA = field1); FROM t2 WHERE fieldA = field1);
field1 field2 field1 field2
1 2 1 2
SELECT field1, field2 SELECT field1, field2
FROM t1 FROM t1
GROUP BY field1, field2 GROUP BY field1, field2
HAVING COUNT(*) < ANY (SELECT fieldB HAVING COUNT(*) < ANY (SELECT fieldB
FROM t2 WHERE fieldA = field1); FROM t2 WHERE fieldA = field1);
field1 field2 field1 field2
1 1 1 1
@ -3021,8 +3021,8 @@ a a IN (SELECT a FROM t1)
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1 (a DATETIME); CREATE TABLE t1 (a DATETIME);
INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25'); INSERT INTO t1 VALUES ('1998-09-23'), ('2003-03-25');
CREATE TABLE t2 AS SELECT CREATE TABLE t2 AS SELECT
(SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a (SELECT a FROM t1 WHERE a < '2000-01-01') AS sub_a
FROM t1 WHERE a > '2000-01-01'; FROM t1 WHERE a > '2000-01-01';
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -3188,7 +3188,7 @@ INSERT INTO t2 VALUES ( 6 );
CREATE TABLE t3 ( c3 integer ); CREATE TABLE t3 ( c3 integer );
INSERT INTO t3 VALUES ( 7 ); INSERT INTO t3 VALUES ( 7 );
INSERT INTO t3 VALUES ( 8 ); INSERT INTO t3 VALUES ( 8 );
SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2 SELECT c1,c2 FROM t1 LEFT JOIN t2 ON c1 = c2
WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL ); WHERE EXISTS (SELECT c3 FROM t3 WHERE c2 IS NULL );
c1 c2 c1 c2
2 NULL 2 NULL
@ -3231,20 +3231,20 @@ E1
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1(select_id BIGINT, values_id BIGINT); CREATE TABLE t1(select_id BIGINT, values_id BIGINT);
INSERT INTO t1 VALUES (1, 1); INSERT INTO t1 VALUES (1, 1);
CREATE TABLE t2 (select_id BIGINT, values_id BIGINT, CREATE TABLE t2 (select_id BIGINT, values_id BIGINT,
PRIMARY KEY(select_id,values_id)); PRIMARY KEY(select_id,values_id));
INSERT INTO t2 VALUES (0, 1), (0, 2), (0, 3), (1, 5); INSERT INTO t2 VALUES (0, 1), (0, 2), (0, 3), (1, 5);
SELECT values_id FROM t1 SELECT values_id FROM t1
WHERE values_id IN (SELECT values_id FROM t2 WHERE values_id IN (SELECT values_id FROM t2
WHERE select_id IN (1, 0)); WHERE select_id IN (1, 0));
values_id values_id
1 1
SELECT values_id FROM t1 SELECT values_id FROM t1
WHERE values_id IN (SELECT values_id FROM t2 WHERE values_id IN (SELECT values_id FROM t2
WHERE select_id BETWEEN 0 AND 1); WHERE select_id BETWEEN 0 AND 1);
values_id values_id
1 1
SELECT values_id FROM t1 SELECT values_id FROM t1
WHERE values_id IN (SELECT values_id FROM t2 WHERE values_id IN (SELECT values_id FROM t2
WHERE select_id = 0 OR select_id = 1); WHERE select_id = 0 OR select_id = 1);
values_id values_id
@ -3259,7 +3259,7 @@ drop table t1;
CREATE TABLE t1 (a int, b int); CREATE TABLE t1 (a int, b int);
CREATE TABLE t2 (c int, d int); CREATE TABLE t2 (c int, d int);
CREATE TABLE t3 (e int); CREATE TABLE t3 (e int);
INSERT INTO t1 VALUES INSERT INTO t1 VALUES
(1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40); (1,10), (2,10), (1,20), (2,20), (3,20), (2,30), (4,40);
INSERT INTO t2 VALUES INSERT INTO t2 VALUES
(2,10), (2,20), (4,10), (5,10), (3,20), (2,40); (2,10), (2,20), (4,10), (5,10), (3,20), (2,40);
@ -3322,7 +3322,7 @@ a
2 2
SELECT a FROM t1 GROUP BY a SELECT a FROM t1 GROUP BY a
HAVING a IN (SELECT c FROM t2 HAVING a IN (SELECT c FROM t2
WHERE MIN(b) < d AND WHERE MIN(b) < d AND
EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d)); EXISTS(SELECT e FROM t3 WHERE MAX(b)=e AND e <= d));
a a
2 2
@ -3373,7 +3373,7 @@ a
4 4
SELECT t1.a FROM t1 GROUP BY t1.a SELECT t1.a FROM t1 GROUP BY t1.a
HAVING t1.a > ALL(SELECT t2.c FROM t2 HAVING t1.a > ALL(SELECT t2.c FROM t2
WHERE EXISTS(SELECT t3.e FROM t3 WHERE EXISTS(SELECT t3.e FROM t3
WHERE SUM(t1.a+t2.c) < t3.e/4)); WHERE SUM(t1.a+t2.c) < t3.e/4));
ERROR HY000: Invalid use of group function ERROR HY000: Invalid use of group function
SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20; SELECT t1.a from t1 GROUP BY t1.a HAVING AVG(SUM(t1.b)) > 20;
@ -3486,7 +3486,7 @@ mid bigint(20) unsigned NOT NULL,
date date NOT NULL, date date NOT NULL,
PRIMARY KEY (id) PRIMARY KEY (id)
); );
INSERT INTO t2 VALUES INSERT INTO t2 VALUES
(1, 1, '2006-03-30'), (2, 2, '2006-04-06'), (3, 3, '2006-04-13'), (1, 1, '2006-03-30'), (2, 2, '2006-04-06'), (3, 3, '2006-04-13'),
(4, 2, '2006-04-20'), (5, 1, '2006-05-01'); (4, 2, '2006-04-20'), (5, 1, '2006-05-01');
SELECT *, SELECT *,
@ -3524,7 +3524,7 @@ i2 int(11) NOT NULL default '0',
t datetime NOT NULL default '0000-00-00 00:00:00', t datetime NOT NULL default '0000-00-00 00:00:00',
PRIMARY KEY (i1,i2,t) PRIMARY KEY (i1,i2,t)
); );
INSERT INTO t1 VALUES INSERT INTO t1 VALUES
(24,1,'2005-03-03 16:31:31'),(24,1,'2005-05-27 12:40:07'), (24,1,'2005-03-03 16:31:31'),(24,1,'2005-05-27 12:40:07'),
(24,1,'2005-05-27 12:40:08'),(24,1,'2005-05-27 12:40:10'), (24,1,'2005-05-27 12:40:08'),(24,1,'2005-05-27 12:40:10'),
(24,1,'2005-05-27 12:40:25'),(24,1,'2005-05-27 12:40:30'), (24,1,'2005-05-27 12:40:25'),(24,1,'2005-05-27 12:40:30'),
@ -3540,7 +3540,7 @@ PRIMARY KEY (i1)
INSERT INTO t2 VALUES (24,1,'2006-06-20 12:29:40'); INSERT INTO t2 VALUES (24,1,'2006-06-20 12:29:40');
EXPLAIN EXPLAIN
SELECT * FROM t1,t2 SELECT * FROM t1,t2
WHERE t1.t = (SELECT t1.t FROM t1 WHERE t1.t = (SELECT t1.t FROM t1
WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1 WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
ORDER BY t1.t DESC LIMIT 1); ORDER BY t1.t DESC LIMIT 1);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
@ -3548,7 +3548,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index 1 PRIMARY t1 index NULL PRIMARY 16 NULL 11 Using where; Using index
2 DEPENDENT SUBQUERY t1 range PRIMARY PRIMARY 16 NULL 5 Using where; Using index 2 DEPENDENT SUBQUERY t1 range PRIMARY PRIMARY 16 NULL 5 Using where; Using index
SELECT * FROM t1,t2 SELECT * FROM t1,t2
WHERE t1.t = (SELECT t1.t FROM t1 WHERE t1.t = (SELECT t1.t FROM t1
WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1 WHERE t1.t < t2.t AND t1.i2=1 AND t2.i1=t1.i1
ORDER BY t1.t DESC LIMIT 1); ORDER BY t1.t DESC LIMIT 1);
i1 i2 t i1 i2 t i1 i2 t i1 i2 t
@ -3557,22 +3557,22 @@ DROP TABLE t1, t2;
CREATE TABLE t1 (i INT); CREATE TABLE t1 (i INT);
(SELECT i FROM t1) UNION (SELECT i FROM t1); (SELECT i FROM t1) UNION (SELECT i FROM t1);
i i
SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS SELECT sql_no_cache * FROM t1 WHERE NOT EXISTS
( (
(SELECT i FROM t1) UNION (SELECT i FROM t1) UNION
(SELECT i FROM t1) (SELECT i FROM t1)
); );
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 'UNION 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 'UNION
(SELECT i FROM t1) (SELECT i FROM t1)
)' at line 3 )' at line 3
SELECT * FROM t1 SELECT * FROM t1
WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1))); WHERE NOT EXISTS (((SELECT i FROM t1) UNION (SELECT i FROM t1)));
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 'UNION (SELECT i FROM t1)))' at line 2 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 'UNION (SELECT i FROM t1)))' at line 2
explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12)) explain select ((select t11.i from t1 t11) union (select t12.i from t1 t12))
from t1; from t1;
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 'union (select t12.i from t1 t12)) 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 'union (select t12.i from t1 t12))
from t1' at line 1 from t1' at line 1
explain select * from t1 where not exists explain select * from t1 where not exists
((select t11.i from t1 t11) union (select t12.i from t1 t12)); ((select t11.i from t1 t11) union (select t12.i from t1 t12));
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 'union (select t12.i from t1 t12))' at line 2 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 'union (select t12.i from t1 t12))' at line 2
DROP TABLE t1; DROP TABLE t1;
@ -3591,9 +3591,9 @@ insert into t1 (a) select FLOOR(rand() * 100) from t1;
insert into t1 (a) select FLOOR(rand() * 100) from t1; insert into t1 (a) select FLOOR(rand() * 100) from t1;
insert into t1 (a) select FLOOR(rand() * 100) from t1; insert into t1 (a) select FLOOR(rand() * 100) from t1;
insert into t1 (a) select FLOOR(rand() * 100) from t1; insert into t1 (a) select FLOOR(rand() * 100) from t1;
SELECT a, SELECT a,
(SELECT REPEAT(' ',250) FROM t1 i1 (SELECT REPEAT(' ',250) FROM t1 i1
WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a WHERE i1.b=t1.a ORDER BY RAND() LIMIT 1) AS a
FROM t1 ORDER BY a LIMIT 5; FROM t1 ORDER BY a LIMIT 5;
a a a a
0 NULL 0 NULL
@ -3622,7 +3622,7 @@ COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b))
2 2 2 2
1 1 1 1
1 1 1 1
SELECT COUNT(DISTINCT t1.b), SELECT COUNT(DISTINCT t1.b),
(SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
FROM t1 GROUP BY t1.a; FROM t1 GROUP BY t1.a;
COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3) COUNT(DISTINCT t1.b) (SELECT COUNT(DISTINCT t1.b) union select 1 from DUAL where 12 < 3)
@ -3633,7 +3633,7 @@ SELECT (
SELECT ( SELECT (
SELECT COUNT(DISTINCT t1.b) SELECT COUNT(DISTINCT t1.b)
) )
) )
FROM t1 GROUP BY t1.a; FROM t1 GROUP BY t1.a;
( (
SELECT ( SELECT (
@ -3648,8 +3648,8 @@ SELECT (
SELECT ( SELECT (
SELECT COUNT(DISTINCT t1.b) SELECT COUNT(DISTINCT t1.b)
) )
) )
FROM t1 GROUP BY t1.a LIMIT 1) FROM t1 GROUP BY t1.a LIMIT 1)
FROM t1 t2 FROM t1 t2
GROUP BY t2.a; GROUP BY t2.a;
( (
@ -3657,7 +3657,7 @@ SELECT (
SELECT ( SELECT (
SELECT COUNT(DISTINCT t1.b) SELECT COUNT(DISTINCT t1.b)
) )
) )
FROM t1 GROUP BY t1.a LIMIT 1) FROM t1 GROUP BY t1.a LIMIT 1)
2 2
2 2
@ -3669,13 +3669,13 @@ PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
SET SESSION sort_buffer_size = 32 * 1024; SET SESSION sort_buffer_size = 32 * 1024;
Warnings: Warnings:
Warning 1292 Truncated incorrect sort_buffer_size value: '32768' Warning 1292 Truncated incorrect sort_buffer_size value: '32768'
SELECT SQL_NO_CACHE COUNT(*) SELECT SQL_NO_CACHE COUNT(*)
FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
FROM t1) t; FROM t1) t;
COUNT(*) COUNT(*)
3000 3000
SET SESSION sort_buffer_size = 8 * 1024 * 1024; SET SESSION sort_buffer_size = 8 * 1024 * 1024;
SELECT SQL_NO_CACHE COUNT(*) SELECT SQL_NO_CACHE COUNT(*)
FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
FROM t1) t; FROM t1) t;
COUNT(*) COUNT(*)
@ -3736,7 +3736,7 @@ sq
2 2
4 4
DEALLOCATE PREPARE stmt1; DEALLOCATE PREPARE stmt1;
SELECT f2, AVG(f21), SELECT f2, AVG(f21),
(SELECT t.f3 FROM t2 AS t WHERE t2.f2=t.f2 AND t.f3=MAX(t2.f3)) AS test (SELECT t.f3 FROM t2 AS t WHERE t2.f2=t.f2 AND t.f3=MAX(t2.f3)) AS test
FROM t2 GROUP BY f2; FROM t2 GROUP BY f2;
f2 AVG(f21) test f2 AVG(f21) test
@ -3744,12 +3744,12 @@ f2 AVG(f21) test
2 2.0000 2004-02-29 11:11:11 2 2.0000 2004-02-29 11:11:11
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL); CREATE TABLE t1 (a int, b INT, c CHAR(10) NOT NULL);
INSERT INTO t1 VALUES INSERT INTO t1 VALUES
(1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'), (1,1,'a'), (1,2,'b'), (1,3,'c'), (1,4,'d'), (1,5,'e'),
(2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'), (2,1,'f'), (2,2,'g'), (2,3,'h'), (3,4,'i'), (3,3,'j'),
(3,2,'k'), (3,1,'l'), (1,9,'m'); (3,2,'k'), (3,1,'l'), (1,9,'m');
SELECT a, MAX(b), SELECT a, MAX(b),
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b)) AS test
FROM t1 GROUP BY a; FROM t1 GROUP BY a;
a MAX(b) test a MAX(b) test
1 9 m 1 9 m
@ -3900,7 +3900,7 @@ COUNT(*) a (SELECT MIN(m) FROM t2 WHERE m = count(*))
2 2 2 2 2 2
3 3 3 3 3 3
1 4 1 1 4 1
SELECT COUNT(*), a SELECT COUNT(*), a
FROM t1 GROUP BY a FROM t1 GROUP BY a
HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1; HAVING (SELECT MIN(m) FROM t2 WHERE m = count(*)) > 1;
COUNT(*) a COUNT(*) a
@ -3931,7 +3931,7 @@ INSERT INTO t1 VALUES (1,1,0,'a'), (1,2,0,'b'), (1,3,0,'c'), (1,4,0,'d'),
(1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'), (1,5,0,'e'), (2,1,0,'f'), (2,2,0,'g'), (2,3,0,'h'), (3,4,0,'i'), (3,3,0,'j'),
(3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p'); (3,2,0,'k'), (3,1,0,'l'), (1,9,0,'m'), (1,0,10,'n'), (2,0,5,'o'), (3,0,7,'p');
SELECT a, MAX(b), SELECT a, MAX(b),
(SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.b=MAX(t1.b + 0)) as test
FROM t1 GROUP BY a; FROM t1 GROUP BY a;
a MAX(b) test a MAX(b) test
1 9 m 1 9 m
@ -3953,7 +3953,7 @@ a AVG(b) test
3 2.5000 NULL 3 2.5000 NULL
SELECT tt.a, SELECT tt.a,
(SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) (SELECT (SELECT c FROM t1 as t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test LIMIT 1) FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
FROM t1 as tt; FROM t1 as tt;
a test a test
1 n 1 n
@ -3975,7 +3975,7 @@ a test
SELECT tt.a, SELECT tt.a,
(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) (SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
LIMIT 1) LIMIT 1)
FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1) as test
FROM t1 as tt GROUP BY tt.a; FROM t1 as tt GROUP BY tt.a;
a test a test
1 n 1 n
@ -3984,7 +3984,7 @@ a test
SELECT tt.a, MAX( SELECT tt.a, MAX(
(SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a) (SELECT (SELECT t.c FROM t1 AS t WHERE t1.a=t.a AND t.d=MAX(t1.b + tt.a)
LIMIT 1) LIMIT 1)
FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test FROM t1 WHERE t1.a=tt.a GROUP BY a LIMIT 1)) as test
FROM t1 as tt GROUP BY tt.a; FROM t1 as tt GROUP BY tt.a;
a test a test
1 n 1 n
@ -4027,11 +4027,11 @@ COUNT(1)
1 1
SELECT SUM( (SELECT AVG( (SELECT t1.a FROM t2) ) FROM DUAL) ) FROM t1; SELECT SUM( (SELECT AVG( (SELECT t1.a FROM t2) ) FROM DUAL) ) FROM t1;
ERROR HY000: Invalid use of group function ERROR HY000: Invalid use of group function
SELECT SELECT
SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING t1.a < 12) ) FROM t2) ) SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING t1.a < 12) ) FROM t2) )
FROM t1; FROM t1;
ERROR HY000: Invalid use of group function ERROR HY000: Invalid use of group function
SELECT t1.a as XXA, SELECT t1.a as XXA,
SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) ) SUM( (SELECT AVG( (SELECT COUNT(*) FROM t1 t HAVING XXA < 12) ) FROM t2) )
FROM t1; FROM t1;
ERROR HY000: Invalid use of group function ERROR HY000: Invalid use of group function
@ -4048,25 +4048,25 @@ INSERT INTO t1 VALUES
(3,'FL'), (2,'GA'), (4,'FL'), (1,'GA'), (5,'NY'), (7,'FL'), (6,'NY'); (3,'FL'), (2,'GA'), (4,'FL'), (1,'GA'), (5,'NY'), (7,'FL'), (6,'NY');
CREATE TABLE t2 (id int NOT NULL, INDEX idx(id)); CREATE TABLE t2 (id int NOT NULL, INDEX idx(id));
INSERT INTO t2 VALUES (7), (5), (1), (3); INSERT INTO t2 VALUES (7), (5), (1), (3);
SELECT id, st FROM t1 SELECT id, st FROM t1
WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id); WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
id st id st
3 FL 3 FL
1 GA 1 GA
7 FL 7 FL
SELECT id, st FROM t1 SELECT id, st FROM t1
WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id) WHERE st IN ('GA','FL') AND EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
GROUP BY id; GROUP BY id;
id st id st
1 GA 1 GA
3 FL 3 FL
7 FL 7 FL
SELECT id, st FROM t1 SELECT id, st FROM t1
WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id); WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id);
id st id st
2 GA 2 GA
4 FL 4 FL
SELECT id, st FROM t1 SELECT id, st FROM t1
WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id) WHERE st IN ('GA','FL') AND NOT EXISTS(SELECT 1 FROM t2 WHERE t2.id=t1.id)
GROUP BY id; GROUP BY id;
id st id st
@ -4237,7 +4237,7 @@ a b
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1(a INT, b INT); CREATE TABLE t1(a INT, b INT);
INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4); INSERT INTO t1 VALUES (1,1), (1,2), (2,3), (2,4);
EXPLAIN EXPLAIN
SELECT a AS out_a, MIN(b) FROM t1 SELECT a AS out_a, MIN(b) FROM t1
WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a) WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
GROUP BY a; GROUP BY a;
@ -4246,7 +4246,7 @@ SELECT a AS out_a, MIN(b) FROM t1
WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a) WHERE b > (SELECT MIN(b) FROM t1 WHERE a = out_a)
GROUP BY a; GROUP BY a;
ERROR 42S22: Unknown column 'out_a' in 'where clause' ERROR 42S22: Unknown column 'out_a' in 'where clause'
EXPLAIN EXPLAIN
SELECT a AS out_a, MIN(b) FROM t1 t1_outer SELECT a AS out_a, MIN(b) FROM t1 t1_outer
WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a) WHERE b > (SELECT MIN(b) FROM t1 WHERE a = t1_outer.a)
GROUP BY a; GROUP BY a;
@ -4277,16 +4277,16 @@ Warnings:
Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1 Note 1276 Field or reference 'test.t1.a' of SELECT #2 was resolved in SELECT #1
Note 1003 select 2 AS `2` from `test`.`t1` where exists(select 1 AS `1` from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`)) Note 1003 select 2 AS `2` from `test`.`t1` where exists(select 1 AS `1` from `test`.`t2` where (`test`.`t1`.`a` = `test`.`t2`.`a`))
EXPLAIN EXTENDED EXPLAIN EXTENDED
SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION SELECT 2 FROM t1 WHERE EXISTS ((SELECT 1 FROM t2 WHERE t1.a=t2.a) UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a)); (SELECT 1 FROM t2 WHERE t1.a = t2.a));
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 'UNION 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 'UNION
(SELECT 1 FROM t2 WHERE t1.a = t2.a))' at line 2 (SELECT 1 FROM t2 WHERE t1.a = t2.a))' at line 2
DROP TABLE t1,t2; DROP TABLE t1,t2;
create table t1(f11 int, f12 int); create table t1(f11 int, f12 int);
create table t2(f21 int unsigned not null, f22 int, f23 varchar(10)); create table t2(f21 int unsigned not null, f22 int, f23 varchar(10));
insert into t1 values(1,1),(2,2), (3, 3); insert into t1 values(1,1),(2,2), (3, 3);
set session sort_buffer_size= 33*1024; set session sort_buffer_size= 33*1024;
select count(*) from t1 where f12 = select count(*) from t1 where f12 =
(select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1); (select f22 from t2 where f22 = f12 order by f21 desc, f22, f23 limit 1);
count(*) count(*)
3 3
@ -4327,12 +4327,12 @@ IF(
FROM t2 VPC, t4 a2, t2 a3 FROM t2 VPC, t4 a2, t2 a3
WHERE WHERE
VPC.f4 = a2.f10 AND a3.f2 = a4 VPC.f4 = a2.f10 AND a3.f2 = a4
LIMIT 1) IS NULL, LIMIT 1) IS NULL,
0, 0,
t3.f5 t3.f5
) )
) AS a6 ) AS a6
FROM FROM
t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4 t2, t3, t1 JOIN t2 a1 ON t1.f9 = a1.f4
GROUP BY a4; GROUP BY a4;
a4 f3 a6 a4 f3 a6
@ -4341,7 +4341,7 @@ a4 f3 a6
DROP TABLE t1, t2, t3, t4; DROP TABLE t1, t2, t3, t4;
create table t1 (a float(5,4) zerofill); create table t1 (a float(5,4) zerofill);
create table t2 (a float(5,4),b float(2,0)); create table t2 (a float(5,4),b float(2,0));
select t1.a from t1 where select t1.a from t1 where
t1.a= (select b from t2 limit 1) and not t1.a= (select b from t2 limit 1) and not
t1.a= (select a from t2 limit 1) ; t1.a= (select a from t2 limit 1) ;
a a
@ -4362,7 +4362,7 @@ Warnings:
Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,<exists>(select 1 AS `1` from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` having (<cache>(1) = <ref_null_helper>(1)))) Note 1003 select 1 AS `1` from `test`.`t1` where <in_optimizer>(1,<exists>(select 1 AS `1` from `test`.`t1` where (`test`.`t1`.`a` > 3) group by `test`.`t1`.`a` having (<cache>(1) = <ref_null_helper>(1))))
DROP TABLE t1; DROP TABLE t1;
End of 5.0 tests. End of 5.0 tests.
CREATE TABLE t1 (a int, b int); CREATE TABLE t1 (a INT, b INT);
INSERT INTO t1 VALUES (2,22),(1,11),(2,22); INSERT INTO t1 VALUES (2,22),(1,11),(2,22);
SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a; SELECT a FROM t1 WHERE (SELECT COUNT(b) FROM DUAL) > 0 GROUP BY a;
a a
@ -4385,22 +4385,22 @@ WHERE (SELECT COUNT(t0.b) FROM t1 t WHERE t.b>20) GROUP BY a;
ERROR HY000: Invalid use of group function ERROR HY000: Invalid use of group function
SET @@sql_mode=default; SET @@sql_mode=default;
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1 (s1 char(1)); CREATE TABLE t1 (s1 CHAR(1));
INSERT INTO t1 VALUES ('a'); INSERT INTO t1 VALUES ('a');
SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1); SELECT * FROM t1 WHERE _utf8'a' = ANY (SELECT s1 FROM t1);
s1 s1
a a
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE t1(c int, KEY(c)); CREATE TABLE t1(c INT, KEY(c));
CREATE TABLE t2(a int, b int); CREATE TABLE t2(a INT, b INT);
INSERT INTO t2 VALUES (1, 10), (2, NULL); INSERT INTO t2 VALUES (1, 10), (2, NULL);
INSERT INTO t1 VALUES (1), (3); INSERT INTO t1 VALUES (1), (3);
SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10); SELECT * FROM t2 WHERE b NOT IN (SELECT max(t.c) FROM t1, t1 t WHERE t.c>10);
a b a b
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1(pk int PRIMARY KEY, a int, INDEX idx(a)); CREATE TABLE t1(pk INT PRIMARY KEY, a INT, INDEX idx(a));
INSERT INTO t1 VALUES (1, 10), (3, 30), (2, 20); INSERT INTO t1 VALUES (1, 10), (3, 30), (2, 20);
CREATE TABLE t2(pk int PRIMARY KEY, a int, b int, INDEX idxa(a)); CREATE TABLE t2(pk INT PRIMARY KEY, a INT, b INT, INDEX idxa(a));
INSERT INTO t2 VALUES (2, 20, 700), (1, 10, 200), (4, 10, 100); INSERT INTO t2 VALUES (2, 20, 700), (1, 10, 200), (4, 10, 100);
SELECT * FROM t1 SELECT * FROM t1
WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b); WHERE EXISTS (SELECT DISTINCT a FROM t2 WHERE t1.a < t2.a ORDER BY b);
@ -4409,36 +4409,36 @@ pk a
3 30 3 30
2 20 2 20
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1 (a int, b int, PRIMARY KEY (a), KEY b (b)); CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), KEY b (b));
INSERT INTO t1 VALUES (1,NULL), (9,NULL); INSERT INTO t1 VALUES (1,NULL), (9,NULL);
CREATE TABLE t2 ( CREATE TABLE t2 (
a int, a INT,
b int, b INT,
c int, c INT,
d int, d INT,
PRIMARY KEY (a), PRIMARY KEY (a),
UNIQUE KEY b (b,c,d), UNIQUE KEY b (b,c,d),
KEY b_2 (b), KEY b_2 (b),
KEY c (c), KEY c (c),
KEY d (d) KEY d (d)
); );
INSERT INTO t2 VALUES INSERT INTO t2 VALUES
(43, 2, 11 ,30), (43, 2, 11 ,30),
(44, 2, 12 ,30), (44, 2, 12 ,30),
(45, 1, 1 ,10000), (45, 1, 1 ,10000),
(46, 1, 2 ,10000), (46, 1, 2 ,10000),
(556,1, 32 ,10000); (556,1, 32 ,10000);
CREATE TABLE t3 ( CREATE TABLE t3 (
a int, a INT,
b int, b INT,
c int, c INT,
PRIMARY KEY (a), PRIMARY KEY (a),
UNIQUE KEY b (b,c), UNIQUE KEY b (b,c),
KEY c (c), KEY c (c),
KEY b_2 (b) KEY b_2 (b)
); );
INSERT INTO t3 VALUES (1,1,1), (2,32,1); INSERT INTO t3 VALUES (1,1,1), (2,32,1);
explain explain
SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a; SELECT t1.a, (SELECT 1 FROM t2 WHERE t2.b=t3.c AND t2.c=t1.a ORDER BY t2.d LIMIT 1) AS incorrect FROM t1, t3 WHERE t3.b=t1.a;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t3 index b,b_2 b 10 NULL 2 Using index 1 PRIMARY t3 index b,b_2 b 10 NULL 2 Using index
@ -4479,7 +4479,7 @@ DELETE FROM v3;
DROP VIEW v1,v2,v3; DROP VIEW v1,v2,v3;
DROP TABLE t1,t2; DROP TABLE t1,t2;
# #
# BUG#37822: Correlated subquery with IN and IS UNKNOWN provides wrong result # Bug#37822 Correlated subquery with IN and IS UNKNOWN provides wrong result
# #
create table t1(id integer primary key, g integer, v integer, s char(1)); create table t1(id integer primary key, g integer, v integer, s char(1));
create table t2(id integer primary key, g integer, v integer, s char(1)); create table t2(id integer primary key, g integer, v integer, s char(1));

View File

@ -1,6 +1,6 @@
drop table if exists t1,t2; DROP TABLE IF EXISTS t1,t2;
CREATE TABLE t1 (x1 int); CREATE TABLE t1 (x1 INT);
ALTER TABLE t1 CHANGE x1 x2 int; ALTER TABLE t1 CHANGE x1 x2 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -8,7 +8,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x2 x1 int; ALTER TABLE t1 CHANGE x2 x1 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -16,7 +16,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x1 x2 int; ALTER TABLE t1 CHANGE x1 x2 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -24,7 +24,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x2 x1 int; ALTER TABLE t1 CHANGE x2 x1 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -32,7 +32,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x1 x2 int; ALTER TABLE t1 CHANGE x1 x2 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -40,7 +40,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x2 x1 int; ALTER TABLE t1 CHANGE x2 x1 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -48,7 +48,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x1 x2 int; ALTER TABLE t1 CHANGE x1 x2 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -56,7 +56,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x2 x1 int; ALTER TABLE t1 CHANGE x2 x1 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -64,7 +64,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x1 x2 int; ALTER TABLE t1 CHANGE x1 x2 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -72,7 +72,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x2 x1 int; ALTER TABLE t1 CHANGE x2 x1 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -80,7 +80,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x1 x2 int; ALTER TABLE t1 CHANGE x1 x2 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -88,7 +88,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x2 x1 int; ALTER TABLE t1 CHANGE x2 x1 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -96,7 +96,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x1 x2 int; ALTER TABLE t1 CHANGE x1 x2 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -104,7 +104,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x2 x1 int; ALTER TABLE t1 CHANGE x2 x1 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -112,7 +112,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x1 x2 int; ALTER TABLE t1 CHANGE x1 x2 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -120,7 +120,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x2 x1 int; ALTER TABLE t1 CHANGE x2 x1 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -128,7 +128,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x1 x2 int; ALTER TABLE t1 CHANGE x1 x2 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -136,7 +136,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x2 x1 int; ALTER TABLE t1 CHANGE x2 x1 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -144,7 +144,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x1 x2 int; ALTER TABLE t1 CHANGE x1 x2 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table
@ -152,7 +152,7 @@ t2 CREATE TABLE `t2` (
`xx` int(11) DEFAULT NULL `xx` int(11) DEFAULT NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1 ) ENGINE=MyISAM DEFAULT CHARSET=latin1
DROP TABLE t2; DROP TABLE t2;
ALTER TABLE t1 CHANGE x2 x1 int; ALTER TABLE t1 CHANGE x2 x1 INT;
CREATE TABLE t2 LIKE t1; CREATE TABLE t2 LIKE t1;
SHOW CREATE TABLE t2; SHOW CREATE TABLE t2;
Table Create Table Table Create Table

View File

@ -19,6 +19,24 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables 1 PRIMARY NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables
2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used 2 SUBQUERY NULL NULL NULL NULL NULL NULL NULL No tables used
DROP TABLE t1; DROP TABLE t1;
CREATE DATABASE `TESTDB`;
USE `TESTDB`;
CREATE FUNCTION test_fn() RETURNS INTEGER
BEGIN
DECLARE rId bigint;
RETURN rId;
END
//
CREATE FUNCTION test_fn2() RETURNS INTEGER
BEGIN
DECLARE rId bigint;
RETURN rId;
END
//
DROP FUNCTION `TESTDB`.`test_fn`;
DROP FUNCTION `testdb`.`test_fn2`;
USE test;
DROP DATABASE `TESTDB`;
End of 5.0 tests. End of 5.0 tests.
drop procedure if exists proc_1; drop procedure if exists proc_1;
create procedure proc_1() install plugin my_plug soname '\\root\\some_plugin.dll'; create procedure proc_1() install plugin my_plug soname '\\root\\some_plugin.dll';

View File

@ -379,9 +379,7 @@ master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # use `test`; COMMIT master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; TRUNCATE table t2 master-bin.000001 # Query # # use `test`; TRUNCATE table t2
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
@ -401,9 +399,7 @@ master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # use `test`; ROLLBACK master-bin.000001 # Query # # use `test`; ROLLBACK
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; TRUNCATE table t2 master-bin.000001 # Query # # use `test`; TRUNCATE table t2
master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1) master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F

View File

@ -346,9 +346,7 @@ master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (3,3)
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t2 master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t2
master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (a int, b int, primary key (a)) engine=innodb master-bin.000001 # Query # # use `test`; CREATE TABLE t2 (a int, b int, primary key (a)) engine=innodb
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (4,4) master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (4,4)
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; TRUNCATE table t2 master-bin.000001 # Query # # use `test`; TRUNCATE table t2
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (5,5) master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (5,5)
master-bin.000001 # Query # # use `test`; DROP TABLE t2 master-bin.000001 # Query # # use `test`; DROP TABLE t2
master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (6,6) master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (6,6)
@ -356,9 +354,7 @@ master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE t2 (a int, b in
master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (7,7) master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (7,7)
master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (8,8) master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (8,8)
master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (9,9) master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (9,9)
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; TRUNCATE table t2 master-bin.000001 # Query # # use `test`; TRUNCATE table t2
master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (10,10) master-bin.000001 # Query # # use `test`; INSERT INTO t1 values (10,10)
master-bin.000001 # Query # # use `test`; BEGIN master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO t2 values (100,100) master-bin.000001 # Query # # use `test`; INSERT INTO t2 values (100,100)

View File

@ -0,0 +1,63 @@
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
**** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
**** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
TRUNCATE TABLE t2;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
**** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
TRUNCATE TABLE t2;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
**** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
TRUNCATE TABLE t2;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;
CREATE TABLE t1 (a INT) ENGINE=InnoDB;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
INSERT INTO t2 VALUES (1),(2),(3);
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
**** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
TRUNCATE TABLE t2;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;

View File

@ -0,0 +1,12 @@
RESET MASTER;
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
CREATE TABLE t2 (a INT) ENGINE=MyISAM;
INSERT INTO t2 VALUES (1),(2),(3);
**** Truncate of empty table shall be logged
TRUNCATE TABLE t1;
TRUNCATE TABLE t2;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t2
DROP TABLE t1,t2;

View File

@ -220,3 +220,10 @@ Warning 1592 Statement is not safe to log in statement format.
Warning 1592 Statement is not safe to log in statement format. Warning 1592 Statement is not safe to log in statement format.
DROP PROCEDURE p1; DROP PROCEDURE p1;
DROP TABLE t1; DROP TABLE t1;
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (a VARCHAR(100), b VARCHAR(100));
INSERT INTO t1 VALUES ('a','b');
UPDATE t1 SET b = '%s%s%s%s%s%s%s%s%s%s%s%s%s%s' WHERE a = 'a' LIMIT 1;
Warnings:
Warning 1592 Statement is not safe to log in statement format.
DROP TABLE t1;

View File

@ -0,0 +1 @@
--loose-innodb

View File

@ -0,0 +1,29 @@
source include/have_log_bin.inc;
source include/have_innodb.inc;
# It is necessary to reset the master since otherwise the binlog test
# might show the wrong binary log. The default for SHOW BINLOG EVENTS
# is to show the first binary log, not the current one (which is
# actually a better idea).
RESET MASTER;
let $engine = InnoDB;
source extra/binlog_tests/binlog_truncate.test;
# Under transaction isolation level READ UNCOMMITTED and READ
# COMMITTED, InnoDB does not permit statement-based replication of
# row-deleting statement. In these cases, TRUNCATE TABLE should still
# be replicated as a statement.
let $before_truncate = SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
source extra/binlog_tests/binlog_truncate.test;
let $before_truncate = SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
source extra/binlog_tests/binlog_truncate.test;
let $before_truncate = SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
source extra/binlog_tests/binlog_truncate.test;
let $before_truncate = SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
source extra/binlog_tests/binlog_truncate.test;

View File

@ -0,0 +1,11 @@
source include/have_log_bin.inc;
# It is necessary to reset the master since otherwise the binlog test
# might show the wrong binary log. The default for SHOW BINLOG EVENTS
# is to show the first binary log, not the current one (which is
# actually a better idea).
RESET MASTER;
let $engine = MyISAM;
source extra/binlog_tests/binlog_truncate.test;

View File

@ -257,3 +257,17 @@ delimiter ;|
CALL p1(); CALL p1();
DROP PROCEDURE p1; DROP PROCEDURE p1;
DROP TABLE t1; DROP TABLE t1;
#
# Bug#42634: % character in query can cause mysqld signal 11 segfault
#
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (a VARCHAR(100), b VARCHAR(100));
INSERT INTO t1 VALUES ('a','b');
UPDATE t1 SET b = '%s%s%s%s%s%s%s%s%s%s%s%s%s%s' WHERE a = 'a' LIMIT 1;
DROP TABLE t1;

View File

@ -9,3 +9,5 @@
# Do not use any TAB characters for whitespace. # Do not use any TAB characters for whitespace.
# #
############################################################################## ##############################################################################
binlog_truncate_innodb : BUG#42643 2009-02-06 mats Changes to InnoDB requires to complete fix for BUG#36763

View File

@ -0,0 +1,98 @@
RESET MASTER;
DROP PROCEDURE IF EXISTS db_bug_13684.p;
DROP FUNCTION IF EXISTS db_bug_13684.f;
DROP TRIGGER IF EXISTS db_bug_13684.tr;
DROP VIEW IF EXISTS db_bug_13684.v;
DROP EVENT IF EXISTS db_bug_13684.e;
DROP TABLE IF EXISTS db_bug_13684.t;
DROP DATABASE IF EXISTS db_bug_13684;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS db_bug_13684.p
master-bin.000001 # Query # # use `test`; DROP FUNCTION IF EXISTS db_bug_13684.f
master-bin.000001 # Query # # use `test`; DROP TRIGGER IF EXISTS db_bug_13684.tr
master-bin.000001 # Query # # use `test`; DROP VIEW IF EXISTS db_bug_13684.v
master-bin.000001 # Query # # use `test`; DROP EVENT IF EXISTS db_bug_13684.e
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t
master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684
CREATE DATABASE db_bug_13684;
CREATE TABLE db_bug_13684.t (a int);
CREATE EVENT db_bug_13684.e
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
UPDATE db_bug_13684.t SET a = a + 1;
CREATE VIEW db_bug_13684.v
AS SELECT * FROM db_bug_13684.t;
CREATE TRIGGER db_bug_13684.tr BEFORE INSERT ON db_bug_13684.t
FOR EACH ROW BEGIN
END;
CREATE PROCEDURE db_bug_13684.p (OUT p1 INT)
BEGIN
END;
CREATE FUNCTION db_bug_13684.f (s CHAR(20))
RETURNS CHAR(50) DETERMINISTIC
RETURN s;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS db_bug_13684.p
master-bin.000001 # Query # # use `test`; DROP FUNCTION IF EXISTS db_bug_13684.f
master-bin.000001 # Query # # use `test`; DROP TRIGGER IF EXISTS db_bug_13684.tr
master-bin.000001 # Query # # use `test`; DROP VIEW IF EXISTS db_bug_13684.v
master-bin.000001 # Query # # use `test`; DROP EVENT IF EXISTS db_bug_13684.e
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t
master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684
master-bin.000001 # Query # # CREATE DATABASE db_bug_13684
master-bin.000001 # Query # # use `test`; CREATE TABLE db_bug_13684.t (a int)
master-bin.000001 # Query # # use `test`; CREATE EVENT db_bug_13684.e
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
UPDATE db_bug_13684.t SET a = a + 1
master-bin.000001 # Query # # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `db_bug_13684`.`v` AS SELECT * FROM db_bug_13684.t
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER db_bug_13684.tr BEFORE INSERT ON db_bug_13684.t
FOR EACH ROW BEGIN
END
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `db_bug_13684`.`p`(OUT p1 INT)
BEGIN
END
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `db_bug_13684`.`f`(s CHAR(20)) RETURNS char(50) CHARSET latin1
DETERMINISTIC
RETURN s
DROP PROCEDURE IF EXISTS db_bug_13684.p;
DROP FUNCTION IF EXISTS db_bug_13684.f;
DROP TRIGGER IF EXISTS db_bug_13684.tr;
DROP VIEW IF EXISTS db_bug_13684.v;
DROP EVENT IF EXISTS db_bug_13684.e;
DROP TABLE IF EXISTS db_bug_13684.t;
DROP DATABASE IF EXISTS db_bug_13684;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS db_bug_13684.p
master-bin.000001 # Query # # use `test`; DROP FUNCTION IF EXISTS db_bug_13684.f
master-bin.000001 # Query # # use `test`; DROP TRIGGER IF EXISTS db_bug_13684.tr
master-bin.000001 # Query # # use `test`; DROP VIEW IF EXISTS db_bug_13684.v
master-bin.000001 # Query # # use `test`; DROP EVENT IF EXISTS db_bug_13684.e
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t
master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684
master-bin.000001 # Query # # CREATE DATABASE db_bug_13684
master-bin.000001 # Query # # use `test`; CREATE TABLE db_bug_13684.t (a int)
master-bin.000001 # Query # # use `test`; CREATE EVENT db_bug_13684.e
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
UPDATE db_bug_13684.t SET a = a + 1
master-bin.000001 # Query # # use `test`; CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `db_bug_13684`.`v` AS SELECT * FROM db_bug_13684.t
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` TRIGGER db_bug_13684.tr BEFORE INSERT ON db_bug_13684.t
FOR EACH ROW BEGIN
END
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `db_bug_13684`.`p`(OUT p1 INT)
BEGIN
END
master-bin.000001 # Query # # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `db_bug_13684`.`f`(s CHAR(20)) RETURNS char(50) CHARSET latin1
DETERMINISTIC
RETURN s
master-bin.000001 # Query # # use `test`; DROP PROCEDURE IF EXISTS db_bug_13684.p
master-bin.000001 # Query # # use `test`; DROP FUNCTION IF EXISTS db_bug_13684.f
master-bin.000001 # Query # # use `test`; DROP TRIGGER IF EXISTS db_bug_13684.tr
master-bin.000001 # Query # # use `test`; DROP VIEW IF EXISTS db_bug_13684.v
master-bin.000001 # Query # # use `test`; DROP EVENT IF EXISTS db_bug_13684.e
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS db_bug_13684.t
master-bin.000001 # Query # # DROP DATABASE IF EXISTS db_bug_13684

View File

@ -963,9 +963,7 @@ master-bin.000001 # Xid 1 # #
master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; BEGIN
master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 't1, text 1') master-bin.000001 # Query 1 # use `test_rpl`; INSERT INTO t1 VALUES(1, 't1, text 1')
master-bin.000001 # Xid 1 # # master-bin.000001 # Xid 1 # #
master-bin.000001 # Query 1 # use `test_rpl`; BEGIN
master-bin.000001 # Query 1 # use `test_rpl`; TRUNCATE t1 master-bin.000001 # Query 1 # use `test_rpl`; TRUNCATE t1
master-bin.000001 # Xid 1 # #
master-bin.000001 # Query 1 # use `test_rpl`; BEGIN master-bin.000001 # Query 1 # use `test_rpl`; BEGIN
master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1 master-bin.000001 # Query 1 # use `test_rpl`; DELETE FROM t1
master-bin.000001 # Xid 1 # # master-bin.000001 # Xid 1 # #

View File

@ -511,6 +511,7 @@ master-bin.000001 # Query 1 # use `mysqltest1`; drop procedure foo
master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1 master-bin.000001 # Query 1 # use `mysqltest1`; drop function fn1
master-bin.000001 # Query 1 # drop database mysqltest1 master-bin.000001 # Query 1 # drop database mysqltest1
master-bin.000001 # Query 1 # drop user "zedjzlcsjhd"@127.0.0.1 master-bin.000001 # Query 1 # drop user "zedjzlcsjhd"@127.0.0.1
master-bin.000001 # Query 1 # use `test`; drop function if exists f1
master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
READS SQL DATA READS SQL DATA
begin begin
@ -526,12 +527,15 @@ master-bin.000001 # Query 1 # use `test`; create table t1 (a int)
master-bin.000001 # Query 1 # use `test`; insert into t1 (a) values (f1()) master-bin.000001 # Query 1 # use `test`; insert into t1 (a) values (f1())
master-bin.000001 # Query 1 # use `test`; drop view v1 master-bin.000001 # Query 1 # use `test`; drop view v1
master-bin.000001 # Query 1 # use `test`; drop function f1 master-bin.000001 # Query 1 # use `test`; drop function f1
master-bin.000001 # Query 1 # use `test`; DROP PROCEDURE IF EXISTS p1
master-bin.000001 # Query 1 # use `test`; DROP TABLE IF EXISTS t1 master-bin.000001 # Query 1 # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1(col VARCHAR(10)) master-bin.000001 # Query 1 # use `test`; CREATE TABLE t1(col VARCHAR(10))
master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(arg VARCHAR(10)) master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`(arg VARCHAR(10))
INSERT INTO t1 VALUES(arg) INSERT INTO t1 VALUES(arg)
master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES( NAME_CONST('arg',_latin1'test' COLLATE 'latin1_swedish_ci')) master-bin.000001 # Query 1 # use `test`; INSERT INTO t1 VALUES( NAME_CONST('arg',_latin1'test' COLLATE 'latin1_swedish_ci'))
master-bin.000001 # Query 1 # use `test`; DROP PROCEDURE p1 master-bin.000001 # Query 1 # use `test`; DROP PROCEDURE p1
master-bin.000001 # Query 1 # use `test`; DROP PROCEDURE IF EXISTS p1
master-bin.000001 # Query 1 # use `test`; DROP FUNCTION IF EXISTS f1
master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`() master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
SET @a = 1 SET @a = 1
master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) master-bin.000001 # Query 1 # use `test`; CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
@ -842,6 +846,9 @@ drop user "zedjzlcsjhd"@127.0.0.1
/*!*/; /*!*/;
use test/*!*/; use test/*!*/;
SET TIMESTAMP=t/*!*/; SET TIMESTAMP=t/*!*/;
drop function if exists f1
/*!*/;
SET TIMESTAMP=t/*!*/;
CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11)
READS SQL DATA READS SQL DATA
begin begin
@ -869,6 +876,9 @@ SET TIMESTAMP=t/*!*/;
drop function f1 drop function f1
/*!*/; /*!*/;
SET TIMESTAMP=t/*!*/; SET TIMESTAMP=t/*!*/;
DROP PROCEDURE IF EXISTS p1
/*!*/;
SET TIMESTAMP=t/*!*/;
DROP TABLE IF EXISTS t1 DROP TABLE IF EXISTS t1
/*!*/; /*!*/;
SET TIMESTAMP=t/*!*/; SET TIMESTAMP=t/*!*/;
@ -885,6 +895,12 @@ SET TIMESTAMP=t/*!*/;
DROP PROCEDURE p1 DROP PROCEDURE p1
/*!*/; /*!*/;
SET TIMESTAMP=t/*!*/; SET TIMESTAMP=t/*!*/;
DROP PROCEDURE IF EXISTS p1
/*!*/;
SET TIMESTAMP=t/*!*/;
DROP FUNCTION IF EXISTS f1
/*!*/;
SET TIMESTAMP=t/*!*/;
CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`() CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`()
SET @a = 1 SET @a = 1
/*!*/; /*!*/;

View File

@ -4,265 +4,43 @@ reset master;
reset slave; reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave; start slave;
STOP SLAVE; **** Resetting master and slave ****
DROP TABLE IF EXISTS t1; include/stop_slave.inc
DROP TABLE IF EXISTS t1;
RESET SLAVE; RESET SLAVE;
START SLAVE; RESET MASTER;
include/start_slave.inc
**** On Master **** **** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=STATEMENT;
SET GLOBAL BINLOG_FORMAT=STATEMENT;
CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2); INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master **** **** On Master ****
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SELECT * FROM t1; Comparing tables master:test.t1 and slave:test.t1
a b ==== Test using a table with delete triggers ====
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master **** **** On Master ****
DROP TABLE t1; SET @count := 1;
show binlog events from <binlog_start>; CREATE TABLE t2 (a INT, b LONG) ENGINE=MyISAM;
Log_name Pos Event_type Server_id End_log_pos Info CREATE TRIGGER trg1 BEFORE DELETE ON t1 FOR EACH ROW SET @count := @count + 1;
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=MIXED;
SET GLOBAL BINLOG_FORMAT=MIXED;
CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master **** **** On Master ****
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SELECT * FROM t1; Comparing tables master:test.t2 and slave:test.t2
a b DROP TABLE t1,t2;
**** On Slave **** **** Resetting master and slave ****
SELECT * FROM t1; include/stop_slave.inc
a b
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE; RESET SLAVE;
START SLAVE; RESET MASTER;
include/start_slave.inc
**** On Master **** **** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=ROW;
SET GLOBAL BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2); INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master ****
TRUNCATE TABLE t1;
SELECT * FROM t1;
a b
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=STATEMENT;
SET GLOBAL BINLOG_FORMAT=STATEMENT;
CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master **** **** On Master ****
DELETE FROM t1; DELETE FROM t1;
SELECT * FROM t1; Comparing tables master:test.t1 and slave:test.t1
a b ==== Test using a table with delete triggers ====
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master **** **** On Master ****
DROP TABLE t1; SET @count := 1;
show binlog events from <binlog_start>; CREATE TABLE t2 (a INT, b LONG) ENGINE=MyISAM;
Log_name Pos Event_type Server_id End_log_pos Info CREATE TRIGGER trg1 BEFORE DELETE ON t1 FOR EACH ROW SET @count := @count + 1;
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Query # # use `test`; DELETE FROM t1
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=MIXED;
SET GLOBAL BINLOG_FORMAT=MIXED;
CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master **** **** On Master ****
DELETE FROM t1; DELETE FROM t1;
SELECT * FROM t1; Comparing tables master:test.t2 and slave:test.t2
a b DROP TABLE t1,t2;
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Query # # use `test`; DELETE FROM t1
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=ROW;
SET GLOBAL BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master ****
DELETE FROM t1;
SELECT * FROM t1;
a b
**** On Slave ****
SELECT * FROM t1;
a b
3 3
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=MyISAM
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Query # # use `test`; COMMIT
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;

View File

@ -4,283 +4,43 @@ reset master;
reset slave; reset slave;
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
start slave; start slave;
STOP SLAVE; **** Resetting master and slave ****
DROP TABLE IF EXISTS t1; include/stop_slave.inc
DROP TABLE IF EXISTS t1;
RESET SLAVE; RESET SLAVE;
START SLAVE; RESET MASTER;
include/start_slave.inc
**** On Master **** **** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=STATEMENT;
SET GLOBAL BINLOG_FORMAT=STATEMENT;
CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,1), (2,2); INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master **** **** On Master ****
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SELECT * FROM t1; Comparing tables master:test.t1 and slave:test.t1
a b ==== Test using a table with delete triggers ====
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master **** **** On Master ****
DROP TABLE t1; SET @count := 1;
show binlog events from <binlog_start>; CREATE TABLE t2 (a INT, b LONG) ENGINE=InnoDB;
Log_name Pos Event_type Server_id End_log_pos Info CREATE TRIGGER trg1 BEFORE DELETE ON t1 FOR EACH ROW SET @count := @count + 1;
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=MIXED;
SET GLOBAL BINLOG_FORMAT=MIXED;
CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master **** **** On Master ****
TRUNCATE TABLE t1; TRUNCATE TABLE t1;
SELECT * FROM t1; Comparing tables master:test.t2 and slave:test.t2
a b DROP TABLE t1,t2;
**** On Slave **** **** Resetting master and slave ****
SELECT * FROM t1; include/stop_slave.inc
a b
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE; RESET SLAVE;
START SLAVE; RESET MASTER;
include/start_slave.inc
**** On Master **** **** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=ROW;
SET GLOBAL BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,1), (2,2); INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master ****
TRUNCATE TABLE t1;
SELECT * FROM t1;
a b
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; TRUNCATE TABLE t1
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=STATEMENT;
SET GLOBAL BINLOG_FORMAT=STATEMENT;
CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master **** **** On Master ****
DELETE FROM t1; DELETE FROM t1;
SELECT * FROM t1; Comparing tables master:test.t1 and slave:test.t1
a b ==== Test using a table with delete triggers ====
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master **** **** On Master ****
DROP TABLE t1; SET @count := 1;
show binlog events from <binlog_start>; CREATE TABLE t2 (a INT, b LONG) ENGINE=InnoDB;
Log_name Pos Event_type Server_id End_log_pos Info CREATE TRIGGER trg1 BEFORE DELETE ON t1 FOR EACH ROW SET @count := @count + 1;
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; DELETE FROM t1
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=MIXED;
SET GLOBAL BINLOG_FORMAT=MIXED;
CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master **** **** On Master ****
DELETE FROM t1; DELETE FROM t1;
SELECT * FROM t1; Comparing tables master:test.t2 and slave:test.t2
a b DROP TABLE t1,t2;
**** On Slave ****
SELECT * FROM t1;
a b
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; INSERT INTO t1 VALUES (1,1), (2,2)
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Query # # use `test`; DELETE FROM t1
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;
STOP SLAVE;
DROP TABLE IF EXISTS t1;
DROP TABLE IF EXISTS t1;
RESET SLAVE;
START SLAVE;
**** On Master ****
SET @old_session_binlog_format= @@session.binlog_format;
SET @old_global_binlog_format= @@global.binlog_format;
SET SESSION BINLOG_FORMAT=ROW;
SET GLOBAL BINLOG_FORMAT=ROW;
CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,1), (2,2);
SELECT * FROM t1;
a b
1 1
2 2
**** On Slave ****
INSERT INTO t1 VALUE (3,3);
SELECT * FROM t1;
a b
1 1
2 2
3 3
**** On Master ****
DELETE FROM t1;
SELECT * FROM t1;
a b
**** On Slave ****
SELECT * FROM t1;
a b
3 3
**** On Master ****
DROP TABLE t1;
show binlog events from <binlog_start>;
Log_name Pos Event_type Server_id End_log_pos Info
master-bin.000001 # Query # # use `test`; DROP TABLE IF EXISTS t1
master-bin.000001 # Query # # use `test`; CREATE TABLE t1 (a INT, b LONG) ENGINE=InnoDB
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Write_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; BEGIN
master-bin.000001 # Table_map # # table_id: # (test.t1)
master-bin.000001 # Delete_rows # # table_id: # flags: STMT_END_F
master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Query # # use `test`; DROP TABLE t1
RESET MASTER;
SET @@session.binlog_format= @old_session_binlog_format;
SET @@global.binlog_format= @old_global_binlog_format;

View File

@ -0,0 +1,115 @@
# BUG#13684:
# SP: DROP PROCEDURE|FUNCTION IF EXISTS not binlogged if routine
# does not exist
#
# There is an inconsistency with DROP DATABASE IF EXISTS, DROP
# TABLE IF EXISTS and DROP VIEW IF EXISTS: those are binlogged even
# if the DB or TABLE does not exist, whereas DROP PROCEDURE IF
# EXISTS does not. It would be nice or at least consistent if DROP
# PROCEDURE/STATEMENT worked the same too.
#
# Description:
# DROP PROCEDURE|FUNCTION IF EXISTS does not get binlogged whereas DROP
# DATABASE|TABLE|TRIGGER|... IF EXISTS do.
#
# Fixed DROP PROCEDURE|FUNCTION IF EXISTS by adding a call to
# write_bin_log in mysql_execute_command. Checked also if all
# documented "DROP (...) IF EXISTS" get binlogged. Left out DROP
# SERVER IF EXISTS because it seems that it only gets binlogged when
# using row event (see BUG#25705).
#
# TODO: add DROP SERVER IF EXISTS to the test case when its
# binlogging procedure gets fixed (BUG#25705). Furthermore, when
# logging in RBR format the events that get logged are effectively in
# RBR format and not in STATEMENT format meaning that one must needs
# to be extra careful when writing a test for it, or change the CREATE
# SERVER logging to always log as STATEMENT. You can quickly check this
# by enabling the flag below $fixed_bug_25705=1 and watch the diff on
# the STDOUT. More detail may be found on the generated reject file.
#
# Test is implemented as follows:
#
# i) test each "drop if exists" (DDL), found in MySQL 5.1 manual,
# on inexistent objects (except for DROP SERVER);
# ii) show binlog events;
# iii) create an object for each drop if exists statement;
# iv) issue "drop if exists" in existent objects.
# v) show binlog events;
#
# References:
# http://dev.mysql.com/doc/refman/5.1/en/sql-syntax-data-definition.html
#
--source include/have_log_bin.inc
RESET MASTER;
disable_warnings;
# test all "drop if exists" in manual with inexistent objects
DROP PROCEDURE IF EXISTS db_bug_13684.p;
DROP FUNCTION IF EXISTS db_bug_13684.f;
DROP TRIGGER IF EXISTS db_bug_13684.tr;
DROP VIEW IF EXISTS db_bug_13684.v;
DROP EVENT IF EXISTS db_bug_13684.e;
DROP TABLE IF EXISTS db_bug_13684.t;
DROP DATABASE IF EXISTS db_bug_13684;
let $fixed_bug_25705 = 0;
if($fixed_bug_25705)
{
DROP SERVER IF EXISTS s_bug_13684;
}
--source include/show_binlog_events.inc
# test drop with existing values
# create
CREATE DATABASE db_bug_13684;
CREATE TABLE db_bug_13684.t (a int);
CREATE EVENT db_bug_13684.e
ON SCHEDULE AT CURRENT_TIMESTAMP + INTERVAL 1 HOUR
DO
UPDATE db_bug_13684.t SET a = a + 1;
CREATE VIEW db_bug_13684.v
AS SELECT * FROM db_bug_13684.t;
CREATE TRIGGER db_bug_13684.tr BEFORE INSERT ON db_bug_13684.t
FOR EACH ROW BEGIN
END;
CREATE PROCEDURE db_bug_13684.p (OUT p1 INT)
BEGIN
END;
CREATE FUNCTION db_bug_13684.f (s CHAR(20))
RETURNS CHAR(50) DETERMINISTIC
RETURN s;
if($fixed_bug_25705)
{
CREATE SERVER s_bug_13684
FOREIGN DATA WRAPPER mysql
OPTIONS (USER 'Remote', HOST '192.168.1.106', DATABASE 'test');
}
--source include/show_binlog_events.inc
# drop existing
DROP PROCEDURE IF EXISTS db_bug_13684.p;
DROP FUNCTION IF EXISTS db_bug_13684.f;
DROP TRIGGER IF EXISTS db_bug_13684.tr;
DROP VIEW IF EXISTS db_bug_13684.v;
DROP EVENT IF EXISTS db_bug_13684.e;
DROP TABLE IF EXISTS db_bug_13684.t;
DROP DATABASE IF EXISTS db_bug_13684;
if($fixed_bug_25705)
{
DROP SERVER IF EXISTS s_bug_13684;
}
--source include/show_binlog_events.inc
enable_warnings;

View File

@ -1,7 +1,10 @@
# The server need to be started in $MYSQLTEST_VARDIR since it # The server need to be started in $MYSQLTEST_VARDIR since it
# uses ../../std_data/ # uses ../../std_data/
-- source include/uses_vardir.inc --source include/uses_vardir.inc
# Save the initial number of concurrent sessions
--source include/count_sessions.inc
# #
# This test is a bit tricky as we can't use backup table to overwrite an old # This test is a bit tricky as we can't use backup table to overwrite an old
@ -57,6 +60,9 @@ unlock tables;
connection con1; connection con1;
reap; reap;
drop table t5; drop table t5;
connection default;
disconnect con1;
disconnect con2;
remove_file $MYSQLTEST_VARDIR/tmp/t1.MYD; remove_file $MYSQLTEST_VARDIR/tmp/t1.MYD;
remove_file $MYSQLTEST_VARDIR/tmp/t2.MYD; remove_file $MYSQLTEST_VARDIR/tmp/t2.MYD;
remove_file $MYSQLTEST_VARDIR/tmp/t3.MYD; remove_file $MYSQLTEST_VARDIR/tmp/t3.MYD;
@ -68,6 +74,7 @@ remove_file $MYSQLTEST_VARDIR/tmp/t3.frm;
remove_file $MYSQLTEST_VARDIR/tmp/t4.frm; remove_file $MYSQLTEST_VARDIR/tmp/t4.frm;
remove_file $MYSQLTEST_VARDIR/tmp/t5.frm; remove_file $MYSQLTEST_VARDIR/tmp/t5.frm;
# End of 4.1 tests # End of 4.1 tests
# End of 5.0 tests # End of 5.0 tests
@ -87,4 +94,11 @@ DROP TABLE `t+1`;
RESTORE TABLE `t+1` FROM '../../tmp'; RESTORE TABLE `t+1` FROM '../../tmp';
SELECT * FROM `t+1`; SELECT * FROM `t+1`;
DROP TABLE `t+1`; DROP TABLE `t+1`;
#
remove_file $MYSQLTEST_VARDIR/tmp/t@002b1.frm;
remove_file $MYSQLTEST_VARDIR/tmp/t@002b1.MYD;
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc

View File

@ -1,3 +1,6 @@
# Save the initial number of concurrent sessions
--source include/count_sessions.inc
connect (con1,localhost,root,,); connect (con1,localhost,root,,);
connect (con2,localhost,root,,); connect (con2,localhost,root,,);
connection con1; connection con1;
@ -21,16 +24,18 @@ connection con2;
insert into t1 values (200000); insert into t1 values (200000);
connection con1; connection con1;
reap; reap;
connection default;
disconnect con1;
disconnect con2;
drop table t1; drop table t1;
# End of 4.1 tests # End of 4.1 tests
# #
# Bug #9897 Views: 'Check Table' crashes MySQL, with a view and a table # Bug#9897 Views: 'Check Table' crashes MySQL, with a view and a table
# in the statement # in the statement
# #
connection default;
Create table t1(f1 int); Create table t1(f1 int);
Create table t2(f1 int); Create table t2(f1 int);
Create view v1 as Select * from t1; Create view v1 as Select * from t1;
@ -38,11 +43,15 @@ Check Table v1,t2;
drop view v1; drop view v1;
drop table t1, t2; drop table t1, t2;
# #
# BUG#26325 - TEMPORARY TABLE "corrupt" after first read, according to CHECK # Bug#26325 TEMPORARY TABLE "corrupt" after first read, according to CHECK TABLE
# TABLE
# #
CREATE TEMPORARY TABLE t1(a INT); CREATE TEMPORARY TABLE t1(a INT);
CHECK TABLE t1; CHECK TABLE t1;
REPAIR TABLE t1; REPAIR TABLE t1;
DROP TABLE t1; DROP TABLE t1;
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc

View File

@ -6,6 +6,10 @@
-- source include/have_compress.inc -- source include/have_compress.inc
# Save the initial number of concurrent sessions
--source include/count_sessions.inc
connect (comp_con,localhost,root,,,,,COMPRESS); connect (comp_con,localhost,root,,,,,COMPRESS);
# Check compression turned on # Check compression turned on
@ -17,3 +21,10 @@ select * from information_schema.session_status where variable_name= 'COMPRESSIO
# Check compression turned on # Check compression turned on
SHOW STATUS LIKE 'Compression'; SHOW STATUS LIKE 'Compression';
connection default;
disconnect comp_con;
# Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc

View File

@ -454,3 +454,11 @@ INSERT INTO t1 VALUES('aaa15');
SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa16' IN BOOLEAN MODE) FROM t1; SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa16' IN BOOLEAN MODE) FROM t1;
SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) FROM t1; SELECT MATCH(a) AGAINST('aaa1* aaa14 aaa15 aaa16' IN BOOLEAN MODE) FROM t1;
DROP TABLE t1; DROP TABLE t1;
#
# BUG#36737 - having + full text operator crashes mysql
#
CREATE TABLE t1(a TEXT);
--error ER_WRONG_ARGUMENTS
SELECT GROUP_CONCAT(a) AS st FROM t1 HAVING MATCH(st) AGAINST('test' IN BOOLEAN MODE);
DROP TABLE t1;

View File

@ -3,6 +3,9 @@
# Grant tests not performed with embedded server # Grant tests not performed with embedded server
-- source include/not_embedded.inc -- source include/not_embedded.inc
# Save the initial number of concurrent sessions
--source include/count_sessions.inc
SET @old_log_bin_trust_function_creators= @@global.log_bin_trust_function_creators; SET @old_log_bin_trust_function_creators= @@global.log_bin_trust_function_creators;
SET GLOBAL log_bin_trust_function_creators = 1; SET GLOBAL log_bin_trust_function_creators = 1;
@ -81,7 +84,7 @@ delete from mysql.db where user='mysqltest_1';
delete from mysql.tables_priv where user='mysqltest_1'; delete from mysql.tables_priv where user='mysqltest_1';
delete from mysql.columns_priv where user='mysqltest_1'; delete from mysql.columns_priv where user='mysqltest_1';
flush privileges; flush privileges;
--error 1141 --error ER_NONEXISTING_GRANT
show grants for mysqltest_1@localhost; show grants for mysqltest_1@localhost;
# #
@ -119,15 +122,15 @@ drop table t1;
# #
# Test some error conditions # Test some error conditions
# #
--error 1221 --error ER_WRONG_USAGE
GRANT FILE on mysqltest.* to mysqltest_1@localhost; GRANT FILE on mysqltest.* to mysqltest_1@localhost;
select 1; # To test that the previous command didn't cause problems select 1; # To test that the previous command didn't cause problems
# #
# Bug #4898: User privileges depending on ORDER BY Settings of table db # Bug#4898 User privileges depending on ORDER BY Settings of table db
# #
insert into mysql.user (host, user) values ('localhost', 'test11'); insert into mysql.user (host, user) values ('localhost', 'test11');
insert into mysql.db (host, db, user, select_priv) values insert into mysql.db (host, db, user, select_priv) values
('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y'); ('localhost', 'a%', 'test11', 'Y'), ('localhost', 'ab%', 'test11', 'Y');
alter table mysql.db order by db asc; alter table mysql.db order by db asc;
flush privileges; flush privileges;
@ -139,7 +142,7 @@ delete from mysql.user where user='test11';
delete from mysql.db where user='test11'; delete from mysql.db where user='test11';
# #
# Bug#6123: GRANT USAGE inserts useless Db row # Bug#6123 GRANT USAGE inserts useless Db row
# #
create database mysqltest1; create database mysqltest1;
grant usage on mysqltest1.* to test6123 identified by 'magic123'; grant usage on mysqltest1.* to test6123 identified by 'magic123';
@ -148,7 +151,7 @@ delete from mysql.user where user='test6123';
drop database mysqltest1; drop database mysqltest1;
# #
# Test for 'drop user', 'revoke privileges, grant' # Test for 'drop user', 'revoke privileges, grant'
# #
create table t1 (a int); create table t1 (a int);
@ -163,7 +166,7 @@ grant select(a) on test.t1 to drop_user@localhost;
show grants for drop_user@localhost; show grants for drop_user@localhost;
# #
# Bug3086 # Bug#3086 SHOW GRANTS doesn't follow ANSI_QUOTES
# #
set sql_mode=ansi_quotes; set sql_mode=ansi_quotes;
show grants for drop_user@localhost; show grants for drop_user@localhost;
@ -181,7 +184,7 @@ show grants for drop_user@localhost;
revoke all privileges, grant option from drop_user@localhost; revoke all privileges, grant option from drop_user@localhost;
show grants for drop_user@localhost; show grants for drop_user@localhost;
drop user drop_user@localhost; drop user drop_user@localhost;
--error 1269 --error ER_REVOKE_GRANTS
revoke all privileges, grant option from drop_user@localhost; revoke all privileges, grant option from drop_user@localhost;
grant select(a) on test.t1 to drop_user1@localhost; grant select(a) on test.t1 to drop_user1@localhost;
@ -191,10 +194,10 @@ grant select on *.* to drop_user4@localhost;
# Drop user now implicitly revokes all privileges. # Drop user now implicitly revokes all privileges.
drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost,
drop_user4@localhost; drop_user4@localhost;
--error 1269 --error ER_REVOKE_GRANTS
revoke all privileges, grant option from drop_user1@localhost, drop_user2@localhost, revoke all privileges, grant option from drop_user1@localhost, drop_user2@localhost,
drop_user3@localhost, drop_user4@localhost; drop_user3@localhost, drop_user4@localhost;
--error 1396 --error ER_CANNOT_USER
drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost, drop user drop_user1@localhost, drop_user2@localhost, drop_user3@localhost,
drop_user4@localhost; drop_user4@localhost;
drop table t1; drop table t1;
@ -204,12 +207,12 @@ show grants for mysqltest_1@localhost;
drop user mysqltest_1@localhost; drop user mysqltest_1@localhost;
# #
# Bug #3403 Wrong encodin in SHOW GRANTS output # Bug#3403 Wrong encoding in SHOW GRANTS output
# #
SET NAMES koi8r; SET NAMES koi8r;
CREATE DATABASE <20><>; CREATE DATABASE <20><>;
USE <20><>; USE <20><>;
CREATE TABLE <20><><EFBFBD> (<28><><EFBFBD> int); CREATE TABLE <20><><EFBFBD> (<28><><EFBFBD> INT);
GRANT SELECT ON <20><>.* TO <20><><EFBFBD><EFBFBD>@localhost; GRANT SELECT ON <20><>.* TO <20><><EFBFBD><EFBFBD>@localhost;
SHOW GRANTS FOR <20><><EFBFBD><EFBFBD>@localhost; SHOW GRANTS FOR <20><><EFBFBD><EFBFBD>@localhost;
@ -230,7 +233,7 @@ DROP DATABASE
SET NAMES latin1; SET NAMES latin1;
# #
# Bug #5831: REVOKE ALL PRIVILEGES, GRANT OPTION does not revoke everything # Bug#5831 REVOKE ALL PRIVILEGES, GRANT OPTION does not revoke everything
# #
USE test; USE test;
CREATE TABLE t1 (a int ); CREATE TABLE t1 (a int );
@ -299,7 +302,7 @@ DROP DATABASE testdb9;
DROP DATABASE testdb10; DROP DATABASE testdb10;
# #
# Bug #6932: a problem with 'revoke ALL PRIVILEGES' # Bug#6932 a problem with 'revoke ALL PRIVILEGES'
# #
create table t1(a int, b int, c int, d int); create table t1(a int, b int, c int, d int);
@ -313,7 +316,7 @@ drop user grant_user@localhost;
drop table t1; drop table t1;
# #
# Bug#7391: Cross-database multi-table UPDATE security problem # Bug#7391 Cross-database multi-table UPDATE security problem
# #
create database mysqltest_1; create database mysqltest_1;
create database mysqltest_2; create database mysqltest_2;
@ -322,36 +325,36 @@ create table mysqltest_1.t2 select 1 b, 2 r;
create table mysqltest_2.t1 select 1 c, 2 s; create table mysqltest_2.t1 select 1 c, 2 s;
create table mysqltest_2.t2 select 1 d, 2 t; create table mysqltest_2.t2 select 1 d, 2 t;
#test the column privileges # test the column privileges
grant update (a) on mysqltest_1.t1 to mysqltest_3@localhost; grant update (a) on mysqltest_1.t1 to mysqltest_3@localhost;
grant select (b) on mysqltest_1.t2 to mysqltest_3@localhost; grant select (b) on mysqltest_1.t2 to mysqltest_3@localhost;
grant select (c) on mysqltest_2.t1 to mysqltest_3@localhost; grant select (c) on mysqltest_2.t1 to mysqltest_3@localhost;
grant update (d) on mysqltest_2.t2 to mysqltest_3@localhost; grant update (d) on mysqltest_2.t2 to mysqltest_3@localhost;
connect (conn1,localhost,mysqltest_3,,); connect (conn1,localhost,mysqltest_3,,);
connection conn1; connection conn1;
SELECT * FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES SELECT * FROM INFORMATION_SCHEMA.COLUMN_PRIVILEGES
WHERE GRANTEE = '''mysqltest_3''@''localhost''' WHERE GRANTEE = '''mysqltest_3''@''localhost'''
ORDER BY TABLE_NAME,COLUMN_NAME,PRIVILEGE_TYPE; ORDER BY TABLE_NAME,COLUMN_NAME,PRIVILEGE_TYPE;
SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES SELECT * FROM INFORMATION_SCHEMA.TABLE_PRIVILEGES
WHERE GRANTEE = '''mysqltest_3''@''localhost''' WHERE GRANTEE = '''mysqltest_3''@''localhost'''
ORDER BY TABLE_NAME,PRIVILEGE_TYPE; ORDER BY TABLE_NAME,PRIVILEGE_TYPE;
SELECT * from INFORMATION_SCHEMA.SCHEMA_PRIVILEGES SELECT * from INFORMATION_SCHEMA.SCHEMA_PRIVILEGES
WHERE GRANTEE = '''mysqltest_3''@''localhost''' WHERE GRANTEE = '''mysqltest_3''@''localhost'''
ORDER BY TABLE_SCHEMA,PRIVILEGE_TYPE; ORDER BY TABLE_SCHEMA,PRIVILEGE_TYPE;
SELECT * from INFORMATION_SCHEMA.USER_PRIVILEGES SELECT * from INFORMATION_SCHEMA.USER_PRIVILEGES
WHERE GRANTEE = '''mysqltest_3''@''localhost''' WHERE GRANTEE = '''mysqltest_3''@''localhost'''
ORDER BY TABLE_CATALOG,PRIVILEGE_TYPE; ORDER BY TABLE_CATALOG,PRIVILEGE_TYPE;
--error 1143 --error ER_COLUMNACCESS_DENIED_ERROR
update mysqltest_1.t1, mysqltest_1.t2 set q=10 where b=1; update mysqltest_1.t1, mysqltest_1.t2 set q=10 where b=1;
--error 1143 --error ER_COLUMNACCESS_DENIED_ERROR
update mysqltest_1.t2, mysqltest_2.t2 set d=20 where d=1; update mysqltest_1.t2, mysqltest_2.t2 set d=20 where d=1;
--error 1142 --error ER_TABLEACCESS_DENIED_ERROR
update mysqltest_1.t1, mysqltest_2.t2 set d=20 where d=1; update mysqltest_1.t1, mysqltest_2.t2 set d=20 where d=1;
--error 1142 --error ER_TABLEACCESS_DENIED_ERROR
update mysqltest_2.t1, mysqltest_1.t2 set c=20 where b=1; update mysqltest_2.t1, mysqltest_1.t2 set c=20 where b=1;
--error 1143 --error ER_COLUMNACCESS_DENIED_ERROR
update mysqltest_2.t1, mysqltest_2.t2 set d=10 where s=2; update mysqltest_2.t1, mysqltest_2.t2 set d=10 where s=2;
#the following two should work # the following two should work
update mysqltest_1.t1, mysqltest_2.t2 set a=10,d=10; update mysqltest_1.t1, mysqltest_2.t2 set a=10,d=10;
update mysqltest_1.t1, mysqltest_2.t1 set a=20 where c=20; update mysqltest_1.t1, mysqltest_2.t1 set a=20 where c=20;
connection master; connection master;
@ -362,7 +365,7 @@ revoke all on mysqltest_1.t2 from mysqltest_3@localhost;
revoke all on mysqltest_2.t1 from mysqltest_3@localhost; revoke all on mysqltest_2.t1 from mysqltest_3@localhost;
revoke all on mysqltest_2.t2 from mysqltest_3@localhost; revoke all on mysqltest_2.t2 from mysqltest_3@localhost;
#test the db/table level privileges # test the db/table level privileges
grant all on mysqltest_2.* to mysqltest_3@localhost; grant all on mysqltest_2.* to mysqltest_3@localhost;
grant select on *.* to mysqltest_3@localhost; grant select on *.* to mysqltest_3@localhost;
# Next grant is needed to trigger bug#7391. Do not optimize! # Next grant is needed to trigger bug#7391. Do not optimize!
@ -374,17 +377,17 @@ connection conn2;
use mysqltest_1; use mysqltest_1;
update mysqltest_2.t1, mysqltest_2.t2 set c=500,d=600; update mysqltest_2.t1, mysqltest_2.t2 set c=500,d=600;
# the following failed before, should fail now. # the following failed before, should fail now.
--error 1142 --error ER_TABLEACCESS_DENIED_ERROR
update mysqltest_1.t1, mysqltest_1.t2 set a=100,b=200; update mysqltest_1.t1, mysqltest_1.t2 set a=100,b=200;
use mysqltest_2; use mysqltest_2;
#the following used to succeed, it must fail now. # the following used to succeed, it must fail now.
--error 1142 --error ER_TABLEACCESS_DENIED_ERROR
update mysqltest_1.t1, mysqltest_1.t2 set a=100,b=200; update mysqltest_1.t1, mysqltest_1.t2 set a=100,b=200;
--error 1142 --error ER_TABLEACCESS_DENIED_ERROR
update mysqltest_2.t1, mysqltest_1.t2 set c=100,b=200; update mysqltest_2.t1, mysqltest_1.t2 set c=100,b=200;
--error 1142 --error ER_TABLEACCESS_DENIED_ERROR
update mysqltest_1.t1, mysqltest_2.t2 set a=100,d=200; update mysqltest_1.t1, mysqltest_2.t2 set a=100,d=200;
#lets see the result # lets see the result
connection master; connection master;
select t1.*,t2.* from mysqltest_1.t1,mysqltest_1.t2; select t1.*,t2.* from mysqltest_1.t1,mysqltest_1.t2;
select t1.*,t2.* from mysqltest_2.t1,mysqltest_2.t2; select t1.*,t2.* from mysqltest_2.t1,mysqltest_2.t2;
@ -396,6 +399,7 @@ delete from mysql.columns_priv where user="mysqltest_3";
flush privileges; flush privileges;
drop database mysqltest_1; drop database mysqltest_1;
drop database mysqltest_2; drop database mysqltest_2;
disconnect conn2;
# #
# just SHOW PRIVILEGES test # just SHOW PRIVILEGES test
@ -403,7 +407,7 @@ drop database mysqltest_2;
SHOW PRIVILEGES; SHOW PRIVILEGES;
# #
# Rights for renaming test (Bug #3270) # Rights for renaming test (Bug#3270)
# #
connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK); connect (root,localhost,root,,test,$MASTER_MYPORT,$MASTER_MYSOCK);
connection root; connection root;
@ -414,16 +418,18 @@ create table mysqltest.t1 (a int,b int,c int);
grant all on mysqltest.t1 to mysqltest_1@localhost; grant all on mysqltest.t1 to mysqltest_1@localhost;
connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK); connect (user1,localhost,mysqltest_1,,mysqltest,$MASTER_MYPORT,$MASTER_MYSOCK);
connection user1; connection user1;
-- error 1142 -- error ER_TABLEACCESS_DENIED_ERROR
alter table t1 rename t2; alter table t1 rename t2;
disconnect user1; disconnect user1;
connection root; connection root;
revoke all privileges on mysqltest.t1 from mysqltest_1@localhost; revoke all privileges on mysqltest.t1 from mysqltest_1@localhost;
delete from mysql.user where user=_binary'mysqltest_1'; delete from mysql.user where user=_binary'mysqltest_1';
drop database mysqltest; drop database mysqltest;
connection default;
disconnect root;
# #
# check all new table priveleges # check all new table privileges
# #
CREATE USER dummy@localhost; CREATE USER dummy@localhost;
CREATE DATABASE mysqltest; CREATE DATABASE mysqltest;
@ -488,7 +494,7 @@ REVOKE ALL PRIVILEGES, GRANT OPTION FROM dummy@localhost;
DROP USER dummy@localhost; DROP USER dummy@localhost;
DROP DATABASE mysqltest; DROP DATABASE mysqltest;
# #
# Bug #11330: Entry in tables_priv with host = '' causes crash # Bug#11330 Entry in tables_priv with host = '' causes crash
# #
connection default; connection default;
use mysql; use mysql;
@ -499,7 +505,7 @@ flush privileges;
use test; use test;
# #
# Bug #10892 user variables not auto cast for comparisons # Bug#10892 user variables not auto cast for comparisons
# Check that we don't get illegal mix of collations # Check that we don't get illegal mix of collations
# #
set @user123="non-existent"; set @user123="non-existent";
@ -518,18 +524,18 @@ show grants for root@localhost;
set names latin1; set names latin1;
# #
# Bug #15598 Server crashes in specific case during setting new password # Bug#15598 Server crashes in specific case during setting new password
# - Caused by a user with host '' # - Caused by a user with host ''
# #
create user mysqltest_7@; create user mysqltest_7@;
set password for mysqltest_7@ = password('systpass'); set password for mysqltest_7@ = password('systpass');
show grants for mysqltest_7@; show grants for mysqltest_7@;
drop user mysqltest_7@; drop user mysqltest_7@;
--error 1141 --error ER_NONEXISTING_GRANT
show grants for mysqltest_7@; show grants for mysqltest_7@;
# #
# Bug#14385: GRANT and mapping to correct user account problems # Bug#14385 GRANT and mapping to correct user account problems
# #
create database mysqltest; create database mysqltest;
use mysqltest; use mysqltest;
@ -545,7 +551,7 @@ flush privileges;
drop database mysqltest; drop database mysqltest;
# #
# Bug #27515: DROP previlege is not required for RENAME TABLE # Bug#27515 DROP previlege is not required for RENAME TABLE
# #
connection master; connection master;
create database db27515; create database db27515;
@ -556,7 +562,7 @@ grant insert, create on db27515.t2 to user27515@localhost;
connect (conn27515, localhost, user27515, , db27515); connect (conn27515, localhost, user27515, , db27515);
connection conn27515; connection conn27515;
--error 1142 --error ER_TABLEACCESS_DENIED_ERROR
rename table t1 to t2; rename table t1 to t2;
disconnect conn27515; disconnect conn27515;
@ -568,7 +574,7 @@ drop database db27515;
--echo End of 4.1 tests --echo End of 4.1 tests
# #
# Bug #16297 In memory grant tables not flushed when users's hostname is "" # Bug#16297 In memory grant tables not flushed when users's hostname is ""
# #
use test; use test;
create table t1 (a int); create table t1 (a int);
@ -585,11 +591,11 @@ create user mysqltest_8;
create user mysqltest_8@host8; create user mysqltest_8@host8;
# Try to create them again # Try to create them again
--error 1396 --error ER_CANNOT_USER
create user mysqltest_8@''; create user mysqltest_8@'';
--error 1396 --error ER_CANNOT_USER
create user mysqltest_8; create user mysqltest_8;
--error 1396 --error ER_CANNOT_USER
create user mysqltest_8@host8; create user mysqltest_8@host8;
select user, QUOTE(host) from mysql.user where user="mysqltest_8"; select user, QUOTE(host) from mysql.user where user="mysqltest_8";
@ -684,44 +690,43 @@ flush privileges;
show grants for mysqltest_8@''; show grants for mysqltest_8@'';
show grants for mysqltest_8; show grants for mysqltest_8;
drop user mysqltest_8@''; drop user mysqltest_8@'';
--error 1141 --error ER_NONEXISTING_GRANT
show grants for mysqltest_8@''; show grants for mysqltest_8@'';
show grants for mysqltest_8; show grants for mysqltest_8;
select * from information_schema.user_privileges select * from information_schema.user_privileges
where grantee like "'mysqltest_8'%"; where grantee like "'mysqltest_8'%";
drop user mysqltest_8; drop user mysqltest_8;
--replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT --replace_result $MASTER_MYSOCK MASTER_SOCKET $MASTER_MYPORT MASTER_PORT
--error 1045 --error ER_ACCESS_DENIED_ERROR
connect (conn6,localhost,mysqltest_8,,); connect (conn6,localhost,mysqltest_8,,);
connection master; connection master;
--error 1141 --error ER_NONEXISTING_GRANT
show grants for mysqltest_8; show grants for mysqltest_8;
drop user mysqltest_8@host8; drop user mysqltest_8@host8;
--error 1141 --error ER_NONEXISTING_GRANT
show grants for mysqltest_8@host8; show grants for mysqltest_8@host8;
# Restore the anonymous users. # Restore the anonymous users.
insert into mysql.user select * from t2; insert into mysql.user select * from t2;
flush privileges; flush privileges;
drop table t2; drop table t2;
drop table t1; drop table t1;
# #
# Bug#20214: Incorrect error when user calls SHOW CREATE VIEW on non # Bug#20214 Incorrect error when user calls SHOW CREATE VIEW on non
# privileged view # privileged view
# #
connection master; connection master;
CREATE DATABASE mysqltest3; CREATE DATABASE mysqltest3;
use mysqltest3; USE mysqltest3;
CREATE TABLE t_nn (c1 INT); CREATE TABLE t_nn (c1 INT);
CREATE VIEW v_nn AS SELECT * FROM t_nn; CREATE VIEW v_nn AS SELECT * FROM t_nn;
CREATE DATABASE mysqltest2; CREATE DATABASE mysqltest2;
use mysqltest2; USE mysqltest2;
CREATE TABLE t_nn (c1 INT); CREATE TABLE t_nn (c1 INT);
CREATE VIEW v_nn AS SELECT * FROM t_nn; CREATE VIEW v_nn AS SELECT * FROM t_nn;
@ -743,24 +748,18 @@ SHOW CREATE VIEW mysqltest2.v_nn;
--error ER_TABLEACCESS_DENIED_ERROR --error ER_TABLEACCESS_DENIED_ERROR
SHOW CREATE TABLE mysqltest2.v_nn; SHOW CREATE TABLE mysqltest2.v_nn;
# fail because of missing SHOW VIEW # fail because of missing SHOW VIEW
--error ER_TABLEACCESS_DENIED_ERROR --error ER_TABLEACCESS_DENIED_ERROR
SHOW CREATE VIEW mysqltest2.v_yn; SHOW CREATE VIEW mysqltest2.v_yn;
--error ER_TABLEACCESS_DENIED_ERROR --error ER_TABLEACCESS_DENIED_ERROR
SHOW CREATE TABLE mysqltest2.v_yn; SHOW CREATE TABLE mysqltest2.v_yn;
# succeed (despite of missing SELECT, having SHOW VIEW bails us out) # succeed (despite of missing SELECT, having SHOW VIEW bails us out)
SHOW CREATE TABLE mysqltest2.v_ny; SHOW CREATE TABLE mysqltest2.v_ny;
# succeed (despite of missing SELECT, having SHOW VIEW bails us out) # succeed (despite of missing SELECT, having SHOW VIEW bails us out)
SHOW CREATE VIEW mysqltest2.v_ny; SHOW CREATE VIEW mysqltest2.v_ny;
# fail because of missing (specific or generic) SELECT # fail because of missing (specific or generic) SELECT
--error ER_TABLEACCESS_DENIED_ERROR --error ER_TABLEACCESS_DENIED_ERROR
SHOW CREATE TABLE mysqltest3.t_nn; SHOW CREATE TABLE mysqltest3.t_nn;
@ -769,16 +768,12 @@ SHOW CREATE TABLE mysqltest3.t_nn;
--error ER_TABLEACCESS_DENIED_ERROR --error ER_TABLEACCESS_DENIED_ERROR
SHOW CREATE VIEW mysqltest3.t_nn; SHOW CREATE VIEW mysqltest3.t_nn;
# fail because of missing missing (specific or generic) SELECT (and SHOW VIEW) # fail because of missing missing (specific or generic) SELECT (and SHOW VIEW)
--error ER_TABLEACCESS_DENIED_ERROR --error ER_TABLEACCESS_DENIED_ERROR
SHOW CREATE VIEW mysqltest3.v_nn; SHOW CREATE VIEW mysqltest3.v_nn;
--error ER_TABLEACCESS_DENIED_ERROR --error ER_TABLEACCESS_DENIED_ERROR
SHOW CREATE TABLE mysqltest3.v_nn; SHOW CREATE TABLE mysqltest3.v_nn;
# succeed thanks to generic SELECT # succeed thanks to generic SELECT
SHOW CREATE TABLE mysqltest2.t_nn; SHOW CREATE TABLE mysqltest2.t_nn;
@ -786,17 +781,13 @@ SHOW CREATE TABLE mysqltest2.t_nn;
--error ER_WRONG_OBJECT --error ER_WRONG_OBJECT
SHOW CREATE VIEW mysqltest2.t_nn; SHOW CREATE VIEW mysqltest2.t_nn;
# succeed, have SELECT and SHOW VIEW # succeed, have SELECT and SHOW VIEW
SHOW CREATE VIEW mysqltest2.v_yy; SHOW CREATE VIEW mysqltest2.v_yy;
# succeed, have SELECT and SHOW VIEW # succeed, have SELECT and SHOW VIEW
SHOW CREATE TABLE mysqltest2.v_yy; SHOW CREATE TABLE mysqltest2.v_yy;
# clean-up
#clean-up
connection master; connection master;
# succeed, we're root # succeed, we're root
@ -809,38 +800,33 @@ SHOW CREATE TABLE mysqltest2.t_nn;
--error ER_WRONG_OBJECT --error ER_WRONG_OBJECT
SHOW CREATE VIEW mysqltest2.t_nn; SHOW CREATE VIEW mysqltest2.t_nn;
DROP VIEW mysqltest2.v_nn; DROP VIEW mysqltest2.v_nn;
DROP VIEW mysqltest2.v_yn; DROP VIEW mysqltest2.v_yn;
DROP VIEW mysqltest2.v_ny; DROP VIEW mysqltest2.v_ny;
DROP VIEW mysqltest2.v_yy; DROP VIEW mysqltest2.v_yy;
DROP TABLE mysqltest2.t_nn; DROP TABLE mysqltest2.t_nn;
DROP DATABASE mysqltest2; DROP DATABASE mysqltest2;
DROP VIEW mysqltest3.v_nn; DROP VIEW mysqltest3.v_nn;
DROP TABLE mysqltest3.t_nn; DROP TABLE mysqltest3.t_nn;
DROP DATABASE mysqltest3; DROP DATABASE mysqltest3;
disconnect mysqltest_1;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'mysqltest_1'@'localhost'; REVOKE ALL PRIVILEGES, GRANT OPTION FROM 'mysqltest_1'@'localhost';
DROP USER 'mysqltest_1'@'localhost'; DROP USER 'mysqltest_1'@'localhost';
# restore the original database # restore the original database
use test; USE test;
connection default;
disconnect master;
# #
# Bug #10668: CREATE USER does not enforce username length limit # Bug#10668 CREATE USER does not enforce username length limit
# #
--error ER_WRONG_STRING_LENGTH --error ER_WRONG_STRING_LENGTH
create user mysqltest1_thisisreallytoolong; create user mysqltest1_thisisreallytoolong;
# #
# Test for BUG#16899: Possible buffer overflow in handling of DEFINER-clause. # Test for Bug#16899 Possible buffer overflow in handling of DEFINER-clause.
# #
# These checks are intended to ensure that appropriate errors are risen when # These checks are intended to ensure that appropriate errors are risen when
# illegal user name or hostname is specified in user-clause of GRANT/REVOKE # illegal user name or hostname is specified in user-clause of GRANT/REVOKE
@ -848,7 +834,7 @@ create user mysqltest1_thisisreallytoolong;
# #
# #
# Bug #22369: Alter table rename combined with other alterations causes lost tables # Bug#22369 Alter table rename combined with other alterations causes lost tables
# #
CREATE DATABASE mysqltest1; CREATE DATABASE mysqltest1;
CREATE TABLE mysqltest1.t1 ( CREATE TABLE mysqltest1.t1 (
@ -968,7 +954,7 @@ REVOKE EXECUTE ON PROCEDURE t1 FROM some_user_name@1234567890abcdefghij123456789
# #
# BUG#23556: TRUNCATE TABLE still maps to DELETE # Bug#23556 TRUNCATE TABLE still maps to DELETE
# #
CREATE USER bug23556@localhost; CREATE USER bug23556@localhost;
CREATE DATABASE bug23556; CREATE DATABASE bug23556;
@ -1000,8 +986,12 @@ DROP TABLE t1;
USE test; USE test;
DROP DATABASE bug23556; DROP DATABASE bug23556;
DROP USER bug23556@localhost; DROP USER bug23556@localhost;
connection default;
disconnect bug23556;
# #
# Bug #6774: Replication fails with Wrong usage of DB GRANT and GLOBAL PRIVILEGES # Bug#6774 Replication fails with Wrong usage of DB GRANT and GLOBAL PRIVILEGES
# #
# Check if GRANT ... ON * ... fails when no database is selected # Check if GRANT ... ON * ... fails when no database is selected
connect (con1, localhost, root,,*NO-ONE*); connect (con1, localhost, root,,*NO-ONE*);
@ -1013,7 +1003,7 @@ connection default;
# #
# BUG#9504: Stored procedures: execute privilege doesn't make 'use database' # Bug#9504 Stored procedures: execute privilege doesn't make 'use database'
# okay. # okay.
# #
@ -1038,8 +1028,8 @@ CREATE PROCEDURE mysqltest2.p_inv() SQL SECURITY INVOKER
SELECT 1; SELECT 1;
CREATE FUNCTION mysqltest3.f_def() RETURNS INT SQL SECURITY DEFINER CREATE FUNCTION mysqltest3.f_def() RETURNS INT SQL SECURITY DEFINER
RETURN 1; RETURN 1;
CREATE FUNCTION mysqltest4.f_inv() RETURNS INT SQL SECURITY INVOKER CREATE FUNCTION mysqltest4.f_inv() RETURNS INT SQL SECURITY INVOKER
RETURN 1; RETURN 1;
@ -1095,7 +1085,7 @@ DROP USER mysqltest_1@localhost;
# #
# BUG#27337: Privileges are not restored properly. # Bug#27337 Privileges are not restored properly.
# #
# Actually, the patch for this bugs fixes two problems. So, here are two test # Actually, the patch for this bugs fixes two problems. So, here are two test
# cases. # cases.
@ -1157,7 +1147,7 @@ DROP DATABASE mysqltest2;
DROP USER mysqltest_1@localhost; DROP USER mysqltest_1@localhost;
# Test case 2: priveleges are not checked properly for prepared statements. # Test case 2: privileges are not checked properly for prepared statements.
# Prepare. # Prepare.
@ -1230,6 +1220,7 @@ EXECUTE stmt2;
--echo --echo
--echo ---> connection: default --echo ---> connection: default
--disconnect bug27337_con1
--disconnect bug27337_con2 --disconnect bug27337_con2
DROP DATABASE mysqltest1; DROP DATABASE mysqltest1;
@ -1239,21 +1230,21 @@ DROP USER mysqltest_1@localhost;
DROP USER mysqltest_2@localhost; DROP USER mysqltest_2@localhost;
# #
# Bug#27878: Unchecked privileges on a view referring to a table from another # Bug#27878 Unchecked privileges on a view referring to a table from another
# database. # database.
# #
use test; USE test;
CREATE TABLE t1 (f1 int, f2 int); CREATE TABLE t1 (f1 int, f2 int);
INSERT INTO t1 VALUES(1,1), (2,2); INSERT INTO t1 VALUES(1,1), (2,2);
CREATE DATABASE db27878; CREATE DATABASE db27878;
GRANT UPDATE(f1) ON t1 TO 'mysqltest_1'@'localhost'; GRANT UPDATE(f1) ON t1 TO 'mysqltest_1'@'localhost';
GRANT SELECT ON `test`.* TO 'mysqltest_1'@'localhost'; GRANT SELECT ON `test`.* TO 'mysqltest_1'@'localhost';
GRANT ALL ON db27878.* TO 'mysqltest_1'@'localhost'; GRANT ALL ON db27878.* TO 'mysqltest_1'@'localhost';
use db27878; USE db27878;
CREATE SQL SECURITY INVOKER VIEW db27878.v1 AS SELECT * FROM test.t1; CREATE SQL SECURITY INVOKER VIEW db27878.v1 AS SELECT * FROM test.t1;
connect (user1,localhost,mysqltest_1,,test); connect (user1,localhost,mysqltest_1,,test);
connection user1; connection user1;
use db27878; USE db27878;
--error 1356 --error 1356
UPDATE v1 SET f2 = 4; UPDATE v1 SET f2 = 4;
SELECT * FROM test.t1; SELECT * FROM test.t1;
@ -1264,7 +1255,7 @@ REVOKE SELECT ON `test`.* FROM 'mysqltest_1'@'localhost';
REVOKE ALL ON db27878.* FROM 'mysqltest_1'@'localhost'; REVOKE ALL ON db27878.* FROM 'mysqltest_1'@'localhost';
DROP USER mysqltest_1@localhost; DROP USER mysqltest_1@localhost;
DROP DATABASE db27878; DROP DATABASE db27878;
use test; USE test;
DROP TABLE t1; DROP TABLE t1;
--echo # --echo #
@ -1273,8 +1264,10 @@ DROP TABLE t1;
CREATE TEMPORARY TABLE mysql.user (id INT); CREATE TEMPORARY TABLE mysql.user (id INT);
FLUSH PRIVILEGES; FLUSH PRIVILEGES;
DROP TABLE mysql.user; DROP TABLE mysql.user;
# #
# Bug #33201 Crash occurs when granting update privilege on one column of a view # Bug#33201 Crash occurs when granting update privilege on one column of a view
# #
drop table if exists test; drop table if exists test;
drop function if exists test_function; drop function if exists test_function;
@ -1305,7 +1298,7 @@ SET PASSWORD FOR CURRENT_USER() = PASSWORD("");
--echo End of 5.0 tests --echo End of 5.0 tests
# #
# Bug#21432: Database/Table name limited to 64 bytes, not chars, problems with multi-byte # Bug#21432 Database/Table name limited to 64 bytes, not chars, problems with multi-byte
# #
set names utf8; set names utf8;
grant select on test.* to юзер_юзер@localhost; grant select on test.* to юзер_юзер@localhost;
@ -1317,7 +1310,7 @@ grant select on test.* to очень_длинный_юзер@localhost;
set names default; set names default;
# #
# Bug #20901 - CREATE privilege is enough to insert into a table # Bug#20901 CREATE privilege is enough to insert into a table
# #
create database mysqltest; create database mysqltest;
@ -1329,7 +1322,7 @@ create table t1 (i INT);
connect (user1,localhost,mysqltest,,mysqltest); connect (user1,localhost,mysqltest,,mysqltest);
connection user1; connection user1;
# show we don't have INSERT # show we don't have INSERT
--error 1142 --error ER_TABLEACCESS_DENIED_ERROR
insert into t1 values (1); insert into t1 values (1);
# show we have CREATE # show we have CREATE
create table t2 (i INT); create table t2 (i INT);
@ -1348,11 +1341,11 @@ insert into t2 values (1);
# CREATE IF NOT EXISTS...SELECT, t1 exists, no INSERT, must fail # CREATE IF NOT EXISTS...SELECT, t1 exists, no INSERT, must fail
--error 1142 --error ER_TABLEACCESS_DENIED_ERROR
create table if not exists t1 select * from t2; create table if not exists t1 select * from t2;
# CREATE IF NOT EXISTS...SELECT, no t3 yet, no INSERT, must fail # CREATE IF NOT EXISTS...SELECT, no t3 yet, no INSERT, must fail
--error 1142 --error ER_TABLEACCESS_DENIED_ERROR
create table if not exists t3 select * from t2; create table if not exists t3 select * from t2;
# CREATE IF NOT EXISTS...SELECT, t4 exists, have INSERT, must succeed # CREATE IF NOT EXISTS...SELECT, t4 exists, have INSERT, must succeed
@ -1366,7 +1359,7 @@ create table if not exists t5 select * from t2;
create table t6 select * from t2; create table t6 select * from t2;
# CREATE...SELECT, no t7 yet, no INSERT, must fail # CREATE...SELECT, no t7 yet, no INSERT, must fail
--error 1142 --error ER_TABLEACCESS_DENIED_ERROR
create table t7 select * from t2; create table t7 select * from t2;
# CREATE...SELECT, t4 exists, have INSERT, must still fail (exists) # CREATE...SELECT, t4 exists, have INSERT, must still fail (exists)
@ -1374,7 +1367,7 @@ create table t7 select * from t2;
create table t4 select * from t2; create table t4 select * from t2;
# CREATE...SELECT, t1 exists, no INSERT, must fail # CREATE...SELECT, t1 exists, no INSERT, must fail
--error 1142 --error ER_TABLEACCESS_DENIED_ERROR
create table t1 select * from t2; create table t1 select * from t2;
@ -1394,7 +1387,7 @@ use test;
# #
# Bug #16470 crash on grant if old grant tables # Bug#16470 crash on grant if old grant tables
# #
--echo FLUSH PRIVILEGES without procs_priv table. --echo FLUSH PRIVILEGES without procs_priv table.
RENAME TABLE mysql.procs_priv TO mysql.procs_gone; RENAME TABLE mysql.procs_priv TO mysql.procs_gone;
@ -1415,7 +1408,7 @@ FLUSH PRIVILEGES;
# #
# Bug#33464: DROP FUNCTION caused a crash. # Bug#33464 DROP FUNCTION caused a crash.
# #
CREATE DATABASE dbbug33464; CREATE DATABASE dbbug33464;
CREATE USER 'userbug33464'@'localhost'; CREATE USER 'userbug33464'@'localhost';
@ -1472,8 +1465,11 @@ DROP PROCEDURE sp3;
--error 0, ER_CANNOT_USER --error 0, ER_CANNOT_USER
DROP USER 'userbug33464'@'localhost'; DROP USER 'userbug33464'@'localhost';
use test; USE test;
DROP DATABASE dbbug33464; DROP DATABASE dbbug33464;
SET @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators; SET @@global.log_bin_trust_function_creators= @old_log_bin_trust_function_creators;
# Wait till we reached the initial number of concurrent sessions
--source include/wait_until_count_sessions.inc

Some files were not shown because too many files have changed in this diff Show More