This commit is contained in:
tulin@dl145b.mysql.com 2005-07-19 21:56:10 +02:00
commit a6c21a0791
195 changed files with 6600 additions and 2377 deletions

View File

@ -1117,3 +1117,5 @@ vio/test-sslclient
vio/test-sslserver
vio/viotest-ssl
ndb/src/dummy.cpp
innobase/mkinstalldirs
mkinstalldirs

View File

@ -48,10 +48,9 @@ global_warnings="-Wimplicit -Wreturn-type -Wswitch -Wtrigraphs -Wcomment -W -Wch
c_warnings="$global_warnings -Wunused"
cxx_warnings="$global_warnings -Woverloaded-virtual -Wsign-promo -Wreorder -Wctor-dtor-privacy -Wnon-virtual-dtor"
base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-raid --with-openssl --with-raid --with-big-tables"
max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-raid --with-openssl --with-raid --with-embedded-server --with-big-tables"
max_no_es_configs="$max_leave_isam_configs --without-isam"
max_configs="$max_no_es_configs --with-embedded-server"
base_max_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-openssl --with-big-tables --with-blackhole-storage-engine --with-federated-storage-engine"
max_leave_isam_configs="--with-innodb --with-berkeley-db --with-ndbcluster --with-archive-storage-engine --with-federated-storage-engine --with-blackhole-storage-engine --with-openssl --with-embedded-server --with-big-tables"
max_configs="$base_max_configs --with-embedded-server"
path=`dirname $0`
. "$path/check-cpu"

View File

@ -1,21 +1,21 @@
#!/bin/sh
# Create MySQL autotools infrastructure
aclocal || (echo "Can't execute aclocal" && exit 1)
autoheader || (echo "Can't execute autoheader" && exit 1)
die() { echo "$@"; exit 1; }
aclocal || die "Can't execute aclocal"
autoheader || die "Can't execute autoheader"
# --force means overwrite ltmain.sh script if it already exists
# Added glibtoolize reference to make native OSX autotools work
if [ -f /usr/bin/glibtoolize ] ; then
glibtoolize --automake --force \
|| (echo "Can't execute glibtoolize" && exit 1)
glibtoolize --automake --force || die "Can't execute glibtoolize"
else
libtoolize --automake --force \
|| (echo "Can't execute libtoolize" && exit 1)
libtoolize --automake --force || die "Can't execute libtoolize"
fi
# --add-missing instructs automake to install missing auxiliary files
# and --force to overwrite them if they already exist
automake --add-missing --force \
|| (echo "Can't execute automake" && exit 1)
autoconf || (echo "Can't execute autoconf" && exit 1)
automake --add-missing --force || die "Can't execute automake"
autoconf || die "Can't execute autoconf"
(cd storage/bdb/dist && sh s_all)
(cd storage/innobase && aclocal && autoheader && aclocal && automake && autoconf)

View File

@ -6,6 +6,6 @@ path=`dirname $0`
extra_flags="$pentium_cflags $debug_cflags $max_cflags"
c_warnings="$c_warnings $debug_extra_warnings"
cxx_warnings="$cxx_warnings $debug_extra_warnings"
extra_configs="$pentium_configs $debug_configs $max_no_es_configs"
extra_configs="$pentium_configs $debug_configs $base_max_configs"
. "$path/FINISH.sh"

View File

@ -451,10 +451,6 @@ SOURCE=..\mysys\my_symlink2.c
# End Source File
# Begin Source File
SOURCE=..\mysys\my_tempnam.c
# End Source File
# Begin Source File
SOURCE=..\libmysql\my_time.c
# End Source File
# Begin Source File

View File

@ -436,10 +436,6 @@ SOURCE=..\mysys\my_symlink2.c
# End Source File
# Begin Source File
SOURCE=..\mysys\my_tempnam.c
# End Source File
# Begin Source File
SOURCE=..\mysys\my_thr_init.c
# End Source File
# Begin Source File

View File

@ -419,10 +419,6 @@ SOURCE=..\mysys\my_symlink2.c
# End Source File
# Begin Source File
SOURCE=..\mysys\my_tempnam.c
# End Source File
# Begin Source File
SOURCE=..\mysys\my_thr_init.c
# End Source File
# Begin Source File

View File

@ -406,10 +406,6 @@ SOURCE=..\mysys\my_symlink2.c
# End Source File
# Begin Source File
SOURCE=..\mysys\my_tempnam.c
# End Source File
# Begin Source File
SOURCE=..\mysys\my_thr_init.c
# End Source File
# Begin Source File

View File

@ -533,10 +533,6 @@ SOURCE=.\my_sync.c
# End Source File
# Begin Source File
SOURCE=.\my_tempnam.c
# End Source File
# Begin Source File
SOURCE=.\my_thr_init.c
# End Source File
# Begin Source File

View File

@ -526,10 +526,6 @@ SOURCE=.\my_sync.c
# End Source File
# Begin Source File
SOURCE=.\my_tempnam.c
# End Source File
# Begin Source File
SOURCE=.\my_thr_init.c
# End Source File
# Begin Source File

View File

@ -44,7 +44,7 @@
#include <locale.h>
#endif
const char *VER= "14.11";
const char *VER= "14.12";
/* Don't try to make a nice table if the data is too big */
#define MAX_COLUMN_LENGTH 1024
@ -340,16 +340,15 @@ static sig_handler mysql_end(int sig);
int main(int argc,char *argv[])
{
char buff[80];
char *defaults, *extra_defaults;
char *emb_argv[3];
int emb_argc= 1;
char *defaults, *extra_defaults, *group_suffix;
char *emb_argv[4];
int emb_argc;
emb_argv[0]= argv[0];
get_defaults_files(argc, argv, &defaults, &extra_defaults);
if (defaults)
emb_argv[emb_argc++]= defaults;
if (extra_defaults)
emb_argv[emb_argc++]= extra_defaults;
/* Get --defaults-xxx args for mysql_server_init() */
emb_argc= get_defaults_options(argc, argv, &defaults, &extra_defaults,
&group_suffix)+1;
memcpy((char*) emb_argv, (char*) argv, emb_argc * sizeof(*argv));
emb_argv[emb_argc]= 0;
MY_INIT(argv[0]);
DBUG_ENTER("main");
@ -2060,6 +2059,7 @@ static void end_tee()
return;
}
static int
com_ego(String *buffer,char *line)
{
@ -2071,8 +2071,10 @@ com_ego(String *buffer,char *line)
return result;
}
static char *fieldtype2str(enum enum_field_types type) {
switch(type) {
static const char *fieldtype2str(enum enum_field_types type)
{
switch (type) {
case FIELD_TYPE_BIT: return "BIT";
case FIELD_TYPE_BLOB: return "BLOB";
case FIELD_TYPE_DATE: return "DATE";

View File

@ -1212,7 +1212,7 @@ static uint get_table_structure(char *table, char *db)
opt_quoted_table= quote_name(table, table_buff2, 0);
if (opt_order_by_primary)
order_by = primary_key_fields(opt_quoted_table);
order_by = primary_key_fields(result_table);
if (!opt_xml && !mysql_query_with_error_report(sock, 0, query_buff))
{
@ -1272,7 +1272,7 @@ static uint get_table_structure(char *table, char *db)
/* Create temp table by selecting from the view */
my_snprintf(query_buff, sizeof(query_buff),
"CREATE TEMPORARY TABLE %s SELECT * FROM %s WHERE 0",
"CREATE TEMPORARY TABLE %s SELECT * FROM %s WHERE 0",
result_table, result_table);
if (mysql_query_with_error_report(sock, 0, query_buff))
{
@ -1391,7 +1391,7 @@ static uint get_table_structure(char *table, char *db)
fprintf(sql_file, "\n--\n-- Table structure for table %s\n--\n\n",
result_table);
if (opt_drop)
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n",result_table);
fprintf(sql_file, "DROP TABLE IF EXISTS %s;\n", result_table);
if (!opt_xml)
fprintf(sql_file, "CREATE TABLE %s (\n", result_table);
else
@ -2782,6 +2782,7 @@ static const char *check_if_ignore_table(const char *table_name)
or if there is some failure. It is better to continue to dump
the table unsorted, rather than exit without dumping the data.
*/
static char *primary_key_fields(const char *table_name)
{
MYSQL_RES *res = NULL;
@ -2818,11 +2819,13 @@ static char *primary_key_fields(const char *table_name)
}
/* Build the ORDER BY clause result */
if (result_length) {
if (result_length)
{
char *end;
/* result (terminating \0 is already in result_length) */
result = my_malloc(result_length + 10, MYF(MY_WME));
if (!result) {
if (!result)
{
fprintf(stderr, "Error: Not enough memory to store ORDER BY clause\n");
goto cleanup;
}

View File

@ -3393,10 +3393,10 @@ static void run_query_display_metadata(MYSQL_FIELD *field, uint num_fields,
int10_to_str((int) field->type, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->length, buff, 10);
longlong10_to_str((unsigned int) field->length, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
int10_to_str((int) field->max_length, buff, 10);
longlong10_to_str((unsigned int) field->max_length, buff, 10);
dynstr_append(ds, buff);
dynstr_append_mem(ds, "\t", 1);
dynstr_append_mem(ds, (char*) (IS_NOT_NULL(field->flags) ?

View File

@ -478,7 +478,7 @@ el_gets(EditLine *el, int *nread)
#endif /* DEBUG_READ */
break;
}
if ((uint)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
if ((unsigned int)cmdnum >= el->el_map.nfunc) { /* BUG CHECK command */
#ifdef DEBUG_EDIT
(void) fprintf(el->el_errfile,
"ERROR: illegal command from key 0%o\r\n", ch);

View File

@ -1,7 +1,7 @@
Basic Installation
==================
These are installation instructions for Readline-4.3.
These are installation instructions for Readline-5.0.
The simplest way to compile readline is:

View File

@ -17,7 +17,8 @@ libreadline_a_SOURCES = readline.c funmap.c keymaps.c \
callback.c terminal.c xmalloc.c \
history.c histsearch.c histexpand.c \
histfile.c nls.c search.c \
shell.c tilde.c misc.c text.c mbutil.c
shell.c tilde.c misc.c text.c mbutil.c \
compat.c savestring.c
pkginclude_HEADERS = readline.h chardefs.h keymaps.h \
history.h tilde.h rlmbutil.h rltypedefs.h rlprivate.h \

View File

@ -1,7 +1,7 @@
Introduction
============
This is the Gnu Readline library, version 4.3.
This is the Gnu Readline library, version 5.0.
The Readline library provides a set of functions for use by applications
that allow users to edit command lines as they are typed in. Both

View File

@ -19,8 +19,13 @@
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (__TANDEM)
# include <floss.h>
#endif
#include "config_readline.h"
#include <stdio.h>
@ -146,6 +151,34 @@ rl_bind_key_in_map (key, function, map)
return (result);
}
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
now, this is always used to attempt to bind the arrow keys, hence the
check for rl_vi_movement_mode. */
int
rl_bind_key_if_unbound_in_map (key, default_func, kmap)
int key;
rl_command_func_t *default_func;
Keymap kmap;
{
char keyseq[2];
keyseq[0] = (unsigned char)key;
keyseq[1] = '\0';
return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap));
}
int
rl_bind_key_if_unbound (key, default_func)
int key;
rl_command_func_t *default_func;
{
char keyseq[2];
keyseq[0] = (unsigned char)key;
keyseq[1] = '\0';
return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
}
/* Make KEY do nothing in the currently selected keymap.
Returns non-zero in case of error. */
int
@ -197,10 +230,31 @@ rl_unbind_command_in_map (command, map)
return (rl_unbind_function_in_map (func, map));
}
/* Bind the key sequence represented by the string KEYSEQ to
FUNCTION, starting in the current keymap. This makes new
keymaps as necessary. */
int
rl_bind_keyseq (keyseq, function)
const char *keyseq;
rl_command_func_t *function;
{
return (rl_generic_bind (ISFUNC, keyseq, (char *)function, _rl_keymap));
}
/* Bind the key sequence represented by the string KEYSEQ to
FUNCTION. This makes new keymaps as necessary. The initial
place to do bindings is in MAP. */
int
rl_bind_keyseq_in_map (keyseq, function, map)
const char *keyseq;
rl_command_func_t *function;
Keymap map;
{
return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
}
/* Backwards compatibility; equivalent to rl_bind_keyseq_in_map() */
int
rl_set_key (keyseq, function, map)
const char *keyseq;
rl_command_func_t *function;
@ -209,6 +263,40 @@ rl_set_key (keyseq, function, map)
return (rl_generic_bind (ISFUNC, keyseq, (char *)function, map));
}
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
now, this is always used to attempt to bind the arrow keys, hence the
check for rl_vi_movement_mode. */
int
rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, kmap)
const char *keyseq;
rl_command_func_t *default_func;
Keymap kmap;
{
rl_command_func_t *func;
if (keyseq)
{
func = rl_function_of_keyseq (keyseq, kmap, (int *)NULL);
#if defined (VI_MODE)
if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
#else
if (!func || func == rl_do_lowercase_version)
#endif
return (rl_bind_keyseq_in_map (keyseq, default_func, kmap));
else
return 1;
}
return 0;
}
int
rl_bind_keyseq_if_unbound (keyseq, default_func)
const char *keyseq;
rl_command_func_t *default_func;
{
return (rl_bind_keyseq_if_unbound_in_map (keyseq, default_func, _rl_keymap));
}
/* Bind the key sequence represented by the string KEYSEQ to
the string of characters MACRO. This makes new keymaps as
necessary. The initial place to do bindings is in MAP. */
@ -346,7 +434,7 @@ rl_translate_keyseq (seq, array, len)
{
register int i, c, l, temp;
for (i = l = 0; (c = seq[i]); i++)
for (i = l = 0; c = seq[i]; i++)
{
if (c == '\\')
{
@ -678,7 +766,7 @@ _rl_read_file (filename, sizep)
/* Re-read the current keybindings file. */
int
rl_re_read_init_file (count, ignore)
int count __attribute__((unused)), ignore __attribute__((unused));
int count, ignore;
{
int r;
r = rl_read_init_file ((const char *)NULL);
@ -900,7 +988,7 @@ parser_if (args)
/* Invert the current parser state if there is anything on the stack. */
static int
parser_else (args)
char *args __attribute__((unused));
char *args;
{
register int i;
@ -910,9 +998,15 @@ parser_else (args)
return 0;
}
#if 0
/* Check the previous (n - 1) levels of the stack to make sure that
we haven't previously turned off parsing. */
for (i = 0; i < if_stack_depth - 1; i++)
#else
/* Check the previous (n) levels of the stack to make sure that
we haven't previously turned off parsing. */
for (i = 0; i < if_stack_depth; i++)
#endif
if (if_stack[i] == 1)
return 0;
@ -925,7 +1019,7 @@ parser_else (args)
_rl_parsing_conditionalized_out from the stack. */
static int
parser_endif (args)
char *args __attribute__((unused));
char *args;
{
if (if_stack_depth)
_rl_parsing_conditionalized_out = if_stack[--if_stack_depth];
@ -1048,7 +1142,7 @@ rl_parse_and_bind (string)
{
int passc = 0;
for (i = 1; (c = string[i]); i++)
for (i = 1; c = string[i]; i++)
{
if (passc)
{
@ -1124,7 +1218,7 @@ rl_parse_and_bind (string)
{
int delimiter = string[i++], passc;
for (passc = 0; (c = string[i]); i++)
for (passc = 0; c = string[i]; i++)
{
if (passc)
{
@ -1159,7 +1253,7 @@ rl_parse_and_bind (string)
}
/* If this is a new-style key-binding, then do the binding with
rl_set_key (). Otherwise, let the older code deal with it. */
rl_bind_keyseq (). Otherwise, let the older code deal with it. */
if (*string == '"')
{
char *seq;
@ -1198,7 +1292,7 @@ rl_parse_and_bind (string)
rl_macro_bind (seq, &funname[1], _rl_keymap);
}
else
rl_set_key (seq, rl_named_function (funname), _rl_keymap);
rl_bind_keyseq (seq, rl_named_function (funname));
free (seq);
return 0;
@ -1279,10 +1373,11 @@ static struct {
{ "prefer-visible-bell", &_rl_prefer_visible_bell, V_SPECIAL },
{ "print-completions-horizontally", &_rl_print_completions_horizontally, 0 },
{ "show-all-if-ambiguous", &_rl_complete_show_all, 0 },
{ "show-all-if-unmodified", &_rl_complete_show_unmodified, 0 },
#if defined (VISIBLE_STATS)
{ "visible-stats", &rl_visible_stats, 0 },
#endif /* VISIBLE_STATS */
{ (char *)NULL, (int *)NULL, 0 }
{ (char *)NULL, (int *)NULL }
};
static int
@ -1351,7 +1446,7 @@ static struct {
{ "editing-mode", V_STRING, sv_editmode },
{ "isearch-terminators", V_STRING, sv_isrchterm },
{ "keymap", V_STRING, sv_keymap },
{ (char *)NULL, 0, 0 }
{ (char *)NULL, 0 }
};
static int
@ -1626,8 +1721,7 @@ rl_set_keymap_from_edit_mode ()
#endif /* VI_MODE */
}
const char *
char *
rl_get_keymap_name_from_edit_mode ()
{
if (rl_editing_mode == emacs_mode)
@ -1637,7 +1731,7 @@ rl_get_keymap_name_from_edit_mode ()
return "vi";
#endif /* VI_MODE */
else
return "nope";
return "none";
}
/* **************************************************************** */
@ -1649,7 +1743,7 @@ rl_get_keymap_name_from_edit_mode ()
/* Each of the following functions produces information about the
state of keybindings and functions known to Readline. The info
is always printed to rl_outstream, and in such a way that it can
be read back in (i.e., passed to rl_parse_and_bind (). */
be read back in (i.e., passed to rl_parse_and_bind ()). */
/* Print the names of functions known to Readline. */
void
@ -1872,7 +1966,7 @@ rl_function_dumper (print_readably)
fprintf (rl_outstream, "\n");
for (i = 0; (name = names[i]); i++)
for (i = 0; name = names[i]; i++)
{
rl_command_func_t *function;
char **invokers;
@ -1932,7 +2026,7 @@ rl_function_dumper (print_readably)
the output in such a way that it can be read back in. */
int
rl_dump_functions (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
@ -2012,7 +2106,7 @@ rl_macro_dumper (print_readably)
int
rl_dump_macros (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
@ -2102,7 +2196,7 @@ rl_variable_dumper (print_readably)
the output in such a way that it can be read back in. */
int
rl_dump_variables (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
if (rl_dispatching)
fprintf (rl_outstream, "\r\n");
@ -2111,28 +2205,6 @@ rl_dump_variables (count, key)
return (0);
}
/* Bind key sequence KEYSEQ to DEFAULT_FUNC if KEYSEQ is unbound. Right
now, this is always used to attempt to bind the arrow keys, hence the
check for rl_vi_movement_mode. */
void
_rl_bind_if_unbound (keyseq, default_func)
const char *keyseq;
rl_command_func_t *default_func;
{
rl_command_func_t *func;
if (keyseq)
{
func = rl_function_of_keyseq (keyseq, _rl_keymap, (int *)NULL);
#if defined (VI_MODE)
if (!func || func == rl_do_lowercase_version || func == rl_vi_movement_mode)
#else
if (!func || func == rl_do_lowercase_version)
#endif
rl_set_key (keyseq, default_func, _rl_keymap);
}
}
/* Return non-zero if any members of ARRAY are a substring in STRING. */
static int
substring_member_of_array (string, array)

View File

@ -129,7 +129,7 @@ rl_callback_read_char ()
if (in_handler == 0 && rl_linefunc)
_rl_callback_newline ();
}
if (rl_pending_input)
if (rl_pending_input || _rl_pushed_input_available ())
eof = readline_internal_char ();
else
break;

View File

@ -77,7 +77,11 @@
# define isxdigit(c) (isdigit((c)) || ((c) >= 'a' && (c) <= 'f') || ((c) >= 'A' && (c) <= 'F'))
#endif
#define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
#if defined (CTYPE_NON_ASCII)
# define NON_NEGATIVE(c) 1
#else
# define NON_NEGATIVE(c) ((unsigned char)(c) == (c))
#endif
/* Some systems define these; we want our definitions. */
#undef ISPRINT

View File

@ -0,0 +1,111 @@
/* compat.c -- backwards compatibility functions. */
/* Copyright (C) 2000 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#include <stdio.h>
#include "rlstdc.h"
#include "rltypedefs.h"
extern void rl_free_undo_list PARAMS((void));
extern int rl_maybe_save_line PARAMS((void));
extern int rl_maybe_unsave_line PARAMS((void));
extern int rl_maybe_replace_line PARAMS((void));
extern int rl_crlf PARAMS((void));
extern int rl_ding PARAMS((void));
extern int rl_alphabetic PARAMS((int));
extern char **rl_completion_matches PARAMS((const char *, rl_compentry_func_t *));
extern char *rl_username_completion_function PARAMS((const char *, int));
extern char *rl_filename_completion_function PARAMS((const char *, int));
/* Provide backwards-compatible entry points for old function names. */
void
free_undo_list ()
{
rl_free_undo_list ();
}
int
maybe_replace_line ()
{
return rl_maybe_replace_line ();
}
int
maybe_save_line ()
{
return rl_maybe_save_line ();
}
int
maybe_unsave_line ()
{
return rl_maybe_unsave_line ();
}
int
ding ()
{
return rl_ding ();
}
int
crlf ()
{
return rl_crlf ();
}
int
alphabetic (c)
int c;
{
return rl_alphabetic (c);
}
char **
completion_matches (s, f)
const char *s;
rl_compentry_func_t *f;
{
return rl_completion_matches (s, f);
}
char *
username_completion_function (s, i)
const char *s;
int i;
{
return rl_username_completion_function (s, i);
}
char *
filename_completion_function (s, i)
const char *s;
int i;
{
return rl_filename_completion_function (s, i);
}

View File

@ -1,6 +1,6 @@
/* complete.c -- filename completion for readline. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
@ -26,7 +26,7 @@
#include <sys/types.h>
#include <fcntl.h>
#if defined (HAVE_SYS_FILE_H)
#include <sys/file.h>
# include <sys/file.h>
#endif
#if defined (HAVE_UNISTD_H)
@ -97,12 +97,16 @@ rl_compdisp_func_t *rl_completion_display_matches_hook = (rl_compdisp_func_t *)N
static int stat_char PARAMS((char *));
#endif
static int path_isdir PARAMS((const char *));
static char *rl_quote_filename PARAMS((char *, int, char *));
static void set_completion_defaults PARAMS((int));
static int get_y_or_n PARAMS((int));
static int _rl_internal_pager PARAMS((int));
static char *printable_part PARAMS((char *));
static int fnwidth PARAMS((const char *));
static int fnprint PARAMS((const char *));
static int print_filename PARAMS((char *, char *));
static char **gen_completion_matches PARAMS((char *, int, int, rl_compentry_func_t *, int, int));
@ -128,6 +132,10 @@ static char *make_quoted_replacement PARAMS((char *, int, char *));
/* If non-zero, non-unique completions always show the list of matches. */
int _rl_complete_show_all = 0;
/* If non-zero, non-unique completions show the list of matches, unless it
is not possible to do partial completion and modify the line. */
int _rl_complete_show_unmodified = 0;
/* If non-zero, completed directory names have a slash appended. */
int _rl_complete_mark_directories = 1;
@ -212,7 +220,12 @@ const char *rl_basic_quote_characters = "\"'";
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
const char *rl_completer_word_break_characters = (const char *)NULL;
/*const*/ char *rl_completer_word_break_characters = (/*const*/ char *)NULL;
/* Hook function to allow an application to set the completion word
break characters before readline breaks up the line. Allows
position-dependent word break characters. */
rl_cpvfunc_t *rl_completion_word_break_hook = (rl_cpvfunc_t *)NULL;
/* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring
@ -280,6 +293,19 @@ int rl_completion_suppress_append = 0;
default is a space. */
int rl_completion_append_character = ' ';
/* If non-zero, the completion functions don't append any closing quote.
This is set to 0 by rl_complete_internal and may be changed by an
application-specific completion function. */
int rl_completion_suppress_quote = 0;
/* Set to any quote character readline thinks it finds before any application
completion function is called. */
int rl_completion_quote_character;
/* Set to a non-zero value if readline found quoting anywhere in the word to
be completed; set before any application completion function is called. */
int rl_completion_found_quote;
/* If non-zero, a slash will be appended to completed filenames that are
symbolic links to directory names, subject to the value of the
mark-directories variable (which is user-settable). This exists so
@ -318,6 +344,8 @@ rl_complete (ignore, invoking_key)
return (rl_complete_internal ('?'));
else if (_rl_complete_show_all)
return (rl_complete_internal ('!'));
else if (_rl_complete_show_unmodified)
return (rl_complete_internal ('@'));
else
return (rl_complete_internal (TAB));
}
@ -325,14 +353,14 @@ rl_complete (ignore, invoking_key)
/* List the possible completions. See description of rl_complete (). */
int
rl_possible_completions (ignore, invoking_key)
int ignore __attribute__((unused)), invoking_key __attribute__((unused));
int ignore, invoking_key;
{
return (rl_complete_internal ('?'));
}
int
rl_insert_completions (ignore, invoking_key)
int ignore __attribute__((unused)), invoking_key __attribute__((unused));
int ignore, invoking_key;
{
return (rl_complete_internal ('*'));
}
@ -350,6 +378,8 @@ rl_completion_mode (cfunc)
return '?';
else if (_rl_complete_show_all)
return '!';
else if (_rl_complete_show_unmodified)
return '@';
else
return TAB;
}
@ -370,7 +400,7 @@ set_completion_defaults (what_to_do)
rl_filename_completion_desired = 0;
rl_filename_quoting_desired = 1;
rl_completion_type = what_to_do;
rl_completion_suppress_append = 0;
rl_completion_suppress_append = rl_completion_suppress_quote = 0;
/* The completion entry function may optionally change this. */
rl_completion_mark_symlink_dirs = _rl_complete_mark_symlink_dirs;
@ -421,6 +451,15 @@ _rl_internal_pager (lines)
return 0;
}
static int
path_isdir (filename)
const char *filename;
{
struct stat finfo;
return (stat (filename, &finfo) == 0 && S_ISDIR (finfo.st_mode));
}
#if defined (VISIBLE_STATS)
/* Return the character which best describes FILENAME.
`@' for symbolic links
@ -518,53 +557,140 @@ printable_part (pathname)
return ++temp;
}
/* Compute width of STRING when displayed on screen by print_filename */
static int
fnwidth (string)
const char *string;
{
int width, pos;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps;
int left, w;
size_t clen;
wchar_t wc;
left = strlen (string) + 1;
memset (&ps, 0, sizeof (mbstate_t));
#endif
width = pos = 0;
while (string[pos])
{
if (CTRL_CHAR (*string) || *string == RUBOUT)
{
width += 2;
pos++;
}
else
{
#if defined (HANDLE_MULTIBYTE)
clen = mbrtowc (&wc, string + pos, left - pos, &ps);
if (MB_INVALIDCH (clen))
{
width++;
pos++;
memset (&ps, 0, sizeof (mbstate_t));
}
else if (MB_NULLWCH (clen))
break;
else
{
pos += clen;
w = wcwidth (wc);
width += (w >= 0) ? w : 1;
}
#else
width++;
pos++;
#endif
}
}
return width;
}
static int
fnprint (to_print)
const char *to_print;
{
int printed_len;
const char *s;
#if defined (HANDLE_MULTIBYTE)
mbstate_t ps;
const char *end;
size_t tlen;
end = to_print + strlen (to_print) + 1;
memset (&ps, 0, sizeof (mbstate_t));
#endif
printed_len = 0;
s = to_print;
while (*s)
{
if (CTRL_CHAR (*s))
{
putc ('^', rl_outstream);
putc (UNCTRL (*s), rl_outstream);
printed_len += 2;
s++;
#if defined (HANDLE_MULTIBYTE)
memset (&ps, 0, sizeof (mbstate_t));
#endif
}
else if (*s == RUBOUT)
{
putc ('^', rl_outstream);
putc ('?', rl_outstream);
printed_len += 2;
s++;
#if defined (HANDLE_MULTIBYTE)
memset (&ps, 0, sizeof (mbstate_t));
#endif
}
else
{
#if defined (HANDLE_MULTIBYTE)
tlen = mbrlen (s, end - s, &ps);
if (MB_INVALIDCH (tlen))
{
tlen = 1;
memset (&ps, 0, sizeof (mbstate_t));
}
else if (MB_NULLWCH (tlen))
break;
fwrite (s, 1, tlen, rl_outstream);
s += tlen;
#else
putc (*s, rl_outstream);
s++;
#endif
printed_len++;
}
}
return printed_len;
}
/* Output TO_PRINT to rl_outstream. If VISIBLE_STATS is defined and we
are using it, check for and output a single character for `special'
filenames. Return the number of characters we output. */
#define PUTX(c) \
do { \
if (CTRL_CHAR (c)) \
{ \
putc ('^', rl_outstream); \
putc (UNCTRL (c), rl_outstream); \
printed_len += 2; \
} \
else if (c == RUBOUT) \
{ \
putc ('^', rl_outstream); \
putc ('?', rl_outstream); \
printed_len += 2; \
} \
else \
{ \
putc (c, rl_outstream); \
printed_len++; \
} \
} while (0)
static int
print_filename (to_print, full_pathname)
char *to_print, *full_pathname;
{
int printed_len = 0;
#if !defined (VISIBLE_STATS)
char *s;
for (s = to_print; *s; s++)
{
PUTX (*s);
}
#else
int printed_len, extension_char, slen, tlen;
char *s, c, *new_full_pathname;
int extension_char, slen, tlen;
for (s = to_print; *s; s++)
{
PUTX (*s);
}
extension_char = 0;
printed_len = fnprint (to_print);
if (rl_filename_completion_desired && rl_visible_stats)
#if defined (VISIBLE_STATS)
if (rl_filename_completion_desired && (rl_visible_stats || _rl_complete_mark_directories))
#else
if (rl_filename_completion_desired && _rl_complete_mark_directories)
#endif
{
/* If to_print != full_pathname, to_print is the basename of the
path passed. In this case, we try to expand the directory
@ -591,7 +717,13 @@ print_filename (to_print, full_pathname)
new_full_pathname[slen] = '/';
strcpy (new_full_pathname + slen + 1, to_print);
extension_char = stat_char (new_full_pathname);
#if defined (VISIBLE_STATS)
if (rl_visible_stats)
extension_char = stat_char (new_full_pathname);
else
#endif
if (path_isdir (new_full_pathname))
extension_char = '/';
free (new_full_pathname);
to_print[-1] = c;
@ -599,7 +731,13 @@ print_filename (to_print, full_pathname)
else
{
s = tilde_expand (full_pathname);
extension_char = stat_char (s);
#if defined (VISIBLE_STATS)
if (rl_visible_stats)
extension_char = stat_char (s);
else
#endif
if (path_isdir (s))
extension_char = '/';
}
free (s);
@ -609,14 +747,14 @@ print_filename (to_print, full_pathname)
printed_len++;
}
}
#endif /* VISIBLE_STATS */
return printed_len;
}
static char *
rl_quote_filename (s, rtype, qcp)
char *s;
int rtype __attribute__((unused));
int rtype;
char *qcp;
{
char *r;
@ -649,19 +787,32 @@ _rl_find_completion_word (fp, dp)
int *fp, *dp;
{
int scan, end, found_quote, delimiter, pass_next, isbrk;
char quote_char;
char quote_char, *brkchars;
end = rl_point;
found_quote = delimiter = 0;
quote_char = '\0';
brkchars = 0;
if (rl_completion_word_break_hook)
brkchars = (*rl_completion_word_break_hook) ();
if (brkchars == 0)
brkchars = rl_completer_word_break_characters;
if (rl_completer_quote_characters)
{
/* We have a list of characters which can be used in pairs to
quote substrings for the completer. Try to find the start
of an unclosed quoted substring. */
/* FOUND_QUOTE is set so we know what kind of quotes we found. */
#if defined (HANDLE_MULTIBYTE)
for (scan = pass_next = 0; scan < end;
scan = ((MB_CUR_MAX == 1 || rl_byte_oriented)
? (scan + 1)
: _rl_find_next_mbchar (rl_line_buffer, scan, 1, MB_FIND_ANY)))
#else
for (scan = pass_next = 0; scan < end; scan++)
#endif
{
if (pass_next)
{
@ -719,7 +870,7 @@ _rl_find_completion_word (fp, dp)
{
scan = rl_line_buffer[rl_point];
if (strchr (rl_completer_word_break_characters, scan) == 0)
if (strchr (brkchars, scan) == 0)
continue;
/* Call the application-specific function to tell us whether
@ -747,9 +898,9 @@ _rl_find_completion_word (fp, dp)
if (rl_char_is_quoted_p)
isbrk = (found_quote == 0 ||
(*rl_char_is_quoted_p) (rl_line_buffer, rl_point) == 0) &&
strchr (rl_completer_word_break_characters, scan) != 0;
strchr (brkchars, scan) != 0;
else
isbrk = strchr (rl_completer_word_break_characters, scan) != 0;
isbrk = strchr (brkchars, scan) != 0;
if (isbrk)
{
@ -784,6 +935,9 @@ gen_completion_matches (text, start, end, our_func, found_quote, quote_char)
{
char **matches, *temp;
rl_completion_found_quote = found_quote;
rl_completion_quote_character = quote_char;
/* If the user wants to TRY to complete, but then wants to give
up and use the default completion function, they set the
variable rl_attempted_completion_function. */
@ -887,6 +1041,7 @@ compute_lcd_of_matches (match_list, matches, text)
{
register int i, c1, c2, si;
int low; /* Count of max-matched characters. */
char *dtext; /* dequoted TEXT, if needed */
#if defined (HANDLE_MULTIBYTE)
int v;
mbstate_t ps1, ps2;
@ -978,6 +1133,26 @@ compute_lcd_of_matches (match_list, matches, text)
the user typed in the face of multiple matches differing in case. */
if (_rl_completion_case_fold)
{
/* We're making an assumption here:
IF we're completing filenames AND
the application has defined a filename dequoting function AND
we found a quote character AND
the application has requested filename quoting
THEN
we assume that TEXT was dequoted before checking against
the file system and needs to be dequoted here before we
check against the list of matches
FI */
dtext = (char *)NULL;
if (rl_filename_completion_desired &&
rl_filename_dequoting_function &&
rl_completion_found_quote &&
rl_filename_quoting_desired)
{
dtext = (*rl_filename_dequoting_function) (text, rl_completion_quote_character);
text = dtext;
}
/* sort the list to get consistent answers. */
qsort (match_list+1, matches, sizeof(char *), (QSFUNC *)_rl_qsort_string_compare);
@ -997,6 +1172,8 @@ compute_lcd_of_matches (match_list, matches, text)
else
/* otherwise, just use the text the user typed. */
strncpy (match_list[0], text, low);
FREE (dtext);
}
else
strncpy (match_list[0], match_list[1], low);
@ -1201,7 +1378,7 @@ display_matches (matches)
for (max = 0, i = 1; matches[i]; i++)
{
temp = printable_part (matches[i]);
len = strlen (temp);
len = fnwidth (temp);
if (len > max)
max = len;
@ -1336,7 +1513,8 @@ append_to_match (text, delimiter, quote_char, nontrivial_match)
struct stat finfo;
temp_string_index = 0;
if (quote_char && rl_point && rl_line_buffer[rl_point - 1] != quote_char)
if (quote_char && rl_point && rl_completion_suppress_quote == 0 &&
rl_line_buffer[rl_point - 1] != quote_char)
temp_string[temp_string_index++] = quote_char;
if (delimiter)
@ -1447,7 +1625,9 @@ _rl_free_match_list (matches)
TAB means do standard completion.
`*' means insert all of the possible completions.
`!' means to do standard completion, and list all possible completions if
there is more than one. */
there is more than one.
`@' means to do standard completion, and list all possible completions if
there is more than one and partial completion is not possible. */
int
rl_complete_internal (what_to_do)
int what_to_do;
@ -1466,7 +1646,6 @@ rl_complete_internal (what_to_do)
our_func = rl_completion_entry_function
? rl_completion_entry_function
: rl_filename_completion_function;
/* We now look backwards for the start of a filename/variable word. */
end = rl_point;
found_quote = delimiter = 0;
@ -1514,6 +1693,7 @@ rl_complete_internal (what_to_do)
{
case TAB:
case '!':
case '@':
/* Insert the first match with proper quoting. */
if (*matches[0])
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
@ -1533,6 +1713,12 @@ rl_complete_internal (what_to_do)
display_matches (matches);
break;
}
else if (what_to_do == '@')
{
if (nontrivial_lcd == 0)
display_matches (matches);
break;
}
else if (rl_editing_mode != vi_mode)
rl_ding (); /* There are other matches remaining. */
}
@ -1610,7 +1796,7 @@ rl_completion_matches (text, entry_function)
match_list = (char **)xmalloc ((match_list_size + 1) * sizeof (char *));
match_list[1] = (char *)NULL;
while ((string = (*entry_function) (text, matches)))
while (string = (*entry_function) (text, matches))
{
if (matches + 1 == match_list_size)
match_list = (char **)xrealloc
@ -1660,7 +1846,7 @@ rl_username_completion_function (text, state)
setpwent ();
}
while ((entry = getpwent ()))
while (entry = getpwent ())
{
/* Null usernames should result in all users as possible completions. */
if (namelen == 0 || (STREQN (username, entry->pw_name, namelen)))
@ -1897,7 +2083,7 @@ rl_filename_completion_function (text, state)
ring the bell, and reset the counter to zero. */
int
rl_menu_complete (count, ignore)
int count, ignore __attribute__((unused));
int count, ignore;
{
rl_compentry_func_t *our_func;
int matching_filenames, found_quote;

View File

@ -4,9 +4,9 @@ dnl
dnl report bugs to chet@po.cwru.edu
dnl
dnl Process this file with autoconf to produce a configure script.
AC_REVISION([for Readline 4.3, version 2.45, from autoconf version] AC_ACVERSION)
AC_REVISION([for Readline 5.0, version 2.52, from autoconf version] AC_ACVERSION)
AC_INIT(readline, 4.3, bug-readline@gnu.org)
AC_INIT(readline, 5.0-rc1, bug-readline@gnu.org)
dnl make sure we are using a recent autoconf version
AC_PREREQ(2.50)
@ -16,7 +16,7 @@ AC_CONFIG_AUX_DIR(./support)
AC_CONFIG_HEADERS(config.h)
dnl update the value of RL_READLINE_VERSION in readline.h when this changes
LIBVERSION=4.3
LIBVERSION=5.0
AC_CANONICAL_HOST
@ -31,12 +31,18 @@ if test "$opt_curses" = "yes"; then
fi
dnl option parsing for optional features
opt_multibyte=yes
opt_static_libs=yes
opt_shared_libs=yes
AC_ARG_ENABLE(multibyte, AC_HELP_STRING([--enable-multibyte], [enable multibyte characters if OS supports them]), opt_multibyte=$enableval)
AC_ARG_ENABLE(shared, AC_HELP_STRING([--enable-shared], [build shared libraries [[default=YES]]]), opt_shared_libs=$enableval)
AC_ARG_ENABLE(static, AC_HELP_STRING([--enable-static], [build static libraries [[default=YES]]]), opt_static_libs=$enableval)
if test $opt_multibyte = no; then
AC_DEFINE(NO_MULTIBYTE_SUPPORT)
fi
echo ""
echo "Beginning configuration for readline-$LIBVERSION for ${host_cpu}-${host_vendor}-${host_os}"
echo ""
@ -72,6 +78,8 @@ AC_TYPE_SIGNAL
AC_TYPE_SIZE_T
AC_CHECK_TYPE(ssize_t, int)
AC_HEADER_STDC
AC_HEADER_STAT
AC_HEADER_DIRENT
@ -90,6 +98,7 @@ BASH_SYS_REINSTALL_SIGHANDLERS
BASH_FUNC_POSIX_SETJMP
BASH_FUNC_LSTAT
BASH_FUNC_STRCOLL
BASH_FUNC_CTYPE_NONASCII
BASH_CHECK_GETPW_FUNCS

View File

@ -1,6 +1,6 @@
/* display.c -- readline redisplay facility. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
@ -119,7 +119,7 @@ int _rl_suppress_redisplay = 0;
/* The stuff that gets printed out before the actual text of the line.
This is usually pointing to rl_prompt. */
const char *rl_display_prompt = (char *)NULL;
char *rl_display_prompt = (char *)NULL;
/* Pseudo-global variables declared here. */
/* The visible cursor position. If you print some text, adjust this. */
@ -176,12 +176,15 @@ static int prompt_invis_chars_first_line;
static int prompt_last_screen_line;
static int prompt_physical_chars;
/* Expand the prompt string S and return the number of visible
characters in *LP, if LP is not null. This is currently more-or-less
a placeholder for expansion. LIP, if non-null is a place to store the
index of the last invisible character in the returned string. NIFLP,
if non-zero, is a place to store the number of invisible characters in
the first prompt line. */
the first prompt line. The previous are used as byte counts -- indexes
into a character buffer. */
/* Current implementation:
\001 (^A) start non-visible characters
@ -191,19 +194,25 @@ static int prompt_last_screen_line;
\002 are assumed to be `visible'. */
static char *
expand_prompt (pmt, lp, lip, niflp)
expand_prompt (pmt, lp, lip, niflp, vlp)
char *pmt;
int *lp, *lip, *niflp;
int *lp, *lip, *niflp, *vlp;
{
char *r, *ret, *p;
int l, rl, last, ignoring, ninvis, invfl;
int l, rl, last, ignoring, ninvis, invfl, ind, pind, physchars;
/* Short-circuit if we can. */
if (strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
if ((MB_CUR_MAX <= 1 || rl_byte_oriented) && strchr (pmt, RL_PROMPT_START_IGNORE) == 0)
{
r = savestring (pmt);
if (lp)
*lp = strlen (r);
if (lip)
*lip = 0;
if (niflp)
*niflp = 0;
if (vlp)
*vlp = lp ? *lp : strlen (r);
return r;
}
@ -212,7 +221,7 @@ expand_prompt (pmt, lp, lip, niflp)
invfl = 0; /* invisible chars in first line of prompt */
for (rl = ignoring = last = ninvis = 0, p = pmt; p && *p; p++)
for (rl = ignoring = last = ninvis = physchars = 0, p = pmt; p && *p; p++)
{
/* This code strips the invisible character string markers
RL_PROMPT_START_IGNORE and RL_PROMPT_END_IGNORE */
@ -229,13 +238,35 @@ expand_prompt (pmt, lp, lip, niflp)
}
else
{
*r++ = *p;
if (!ignoring)
rl++;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
pind = p - pmt;
ind = _rl_find_next_mbchar (pmt, pind, 1, MB_FIND_NONZERO);
l = ind - pind;
while (l--)
*r++ = *p++;
if (!ignoring)
rl += ind - pind;
else
ninvis += ind - pind;
p--; /* compensate for later increment */
}
else
ninvis++;
if (rl == _rl_screenwidth)
#endif
{
*r++ = *p;
if (!ignoring)
rl++; /* visible length byte counter */
else
ninvis++; /* invisible chars byte counter */
}
if (rl >= _rl_screenwidth)
invfl = ninvis;
if (ignoring == 0)
physchars++;
}
}
@ -249,6 +280,8 @@ expand_prompt (pmt, lp, lip, niflp)
*lip = last;
if (niflp)
*niflp = invfl;
if (vlp)
*vlp = physchars;
return ret;
}
@ -260,7 +293,7 @@ _rl_strip_prompt (pmt)
{
char *ret;
ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL);
ret = expand_prompt (pmt, (int *)NULL, (int *)NULL, (int *)NULL, (int *)NULL);
return ret;
}
@ -304,7 +337,8 @@ rl_expand_prompt (prompt)
/* The prompt is only one logical line, though it might wrap. */
local_prompt = expand_prompt (prompt, &prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line);
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)0;
return (prompt_visible_length);
}
@ -314,13 +348,15 @@ rl_expand_prompt (prompt)
t = ++p;
local_prompt = expand_prompt (p, &prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line);
(int *)NULL,
(int *)NULL);
c = *t; *t = '\0';
/* The portion of the prompt string up to and including the
final newline is now null-terminated. */
local_prompt_prefix = expand_prompt (prompt, &prompt_prefix_length,
(int *)NULL,
&prompt_invis_chars_first_line);
&prompt_invis_chars_first_line,
&prompt_physical_chars);
*t = c;
return (prompt_prefix_length);
}
@ -379,8 +415,8 @@ rl_redisplay ()
register int in, out, c, linenum, cursor_linenum;
register char *line;
int c_pos, inv_botlin, lb_botlin, lb_linenum;
int newlines, lpos, temp;
const char *prompt_this_line;
int newlines, lpos, temp, modmark;
char *prompt_this_line;
#if defined (HANDLE_MULTIBYTE)
wchar_t wc;
size_t wc_bytes;
@ -409,10 +445,12 @@ rl_redisplay ()
/* Mark the line as modified or not. We only do this for history
lines. */
modmark = 0;
if (_rl_mark_modified_lines && current_history () && rl_undo_list)
{
line[out++] = '*';
line[out] = '\0';
modmark = 1;
}
/* If someone thought that the redisplay was handled, but the currently
@ -466,7 +504,7 @@ rl_redisplay ()
}
}
pmtlen = strlen (prompt_this_line);
prompt_physical_chars = pmtlen = strlen (prompt_this_line);
temp = pmtlen + out + 2;
if (temp >= line_size)
{
@ -525,7 +563,12 @@ rl_redisplay ()
/* inv_lbreaks[i] is where line i starts in the buffer. */
inv_lbreaks[newlines = 0] = 0;
#if 0
lpos = out - wrap_offset;
#else
lpos = prompt_physical_chars + modmark;
#endif
#if defined (HANDLE_MULTIBYTE)
memset (_rl_wrapped_line, 0, vis_lbsize);
#endif
@ -544,15 +587,13 @@ rl_redisplay ()
prompt_invis_chars_first_line variable could be made into an array
saying how many invisible characters there are per line, but that's
probably too much work for the benefit gained. How many people have
prompts that exceed two physical lines? */
prompts that exceed two physical lines?
Additional logic fix from Edward Catmur <ed@catmur.co.uk> */
temp = ((newlines + 1) * _rl_screenwidth) +
#if 0
((newlines == 0) ? prompt_invis_chars_first_line : 0) +
#else
((newlines == 0 && local_prompt_prefix == 0) ? prompt_invis_chars_first_line : 0) +
#endif
((newlines == 1) ? wrap_offset : 0);
((local_prompt_prefix == 0) ? ((newlines == 0) ? prompt_invis_chars_first_line
: ((newlines == 1) ? wrap_offset : 0))
: ((newlines == 0) ? wrap_offset :0));
inv_lbreaks[++newlines] = temp;
lpos -= _rl_screenwidth;
}
@ -584,7 +625,7 @@ rl_redisplay ()
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
if (wc_bytes == (size_t)-1 || wc_bytes == (size_t)-2)
if (MB_INVALIDCH (wc_bytes))
{
/* Byte sequence is invalid or shortened. Assume that the
first byte represents a character. */
@ -593,12 +634,12 @@ rl_redisplay ()
wc_width = 1;
memset (&ps, 0, sizeof (mbstate_t));
}
else if (wc_bytes == (size_t)0)
else if (MB_NULLWCH (wc_bytes))
break; /* Found '\0' */
else
{
temp = wcwidth (wc);
wc_width = (temp < 0) ? 1 : temp;
wc_width = (temp >= 0) ? temp : 1;
}
}
#endif
@ -788,7 +829,7 @@ rl_redisplay ()
#define VIS_LLEN(l) ((l) > _rl_vis_botlin ? 0 : (vis_lbreaks[l+1] - vis_lbreaks[l]))
#define INV_LLEN(l) (inv_lbreaks[l+1] - inv_lbreaks[l])
#define VIS_CHARS(line) (visible_line + vis_lbreaks[line])
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? (char*)"" : VIS_CHARS(line)
#define VIS_LINE(line) ((line) > _rl_vis_botlin) ? "" : VIS_CHARS(line)
#define INV_LINE(line) (invisible_line + inv_lbreaks[line])
/* For each line in the buffer, do the updating display. */
@ -829,7 +870,7 @@ rl_redisplay ()
_rl_move_vert (linenum);
_rl_move_cursor_relative (0, tt);
_rl_clear_to_eol
((linenum == _rl_vis_botlin) ? (int)strlen (tt) : _rl_screenwidth);
((linenum == _rl_vis_botlin) ? strlen (tt) : _rl_screenwidth);
}
}
_rl_vis_botlin = inv_botlin;
@ -865,7 +906,7 @@ rl_redisplay ()
#endif
_rl_output_some_chars (local_prompt, nleft);
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
_rl_last_c_pos = _rl_col_width(local_prompt, 0, nleft);
_rl_last_c_pos = _rl_col_width (local_prompt, 0, nleft);
else
_rl_last_c_pos = nleft;
}
@ -1067,12 +1108,12 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
memset (&ps, 0, sizeof (mbstate_t));
ret = mbrtowc (&wc, new, MB_CUR_MAX, &ps);
if (ret == (size_t)-1 || ret == (size_t)-2)
if (MB_INVALIDCH (ret))
{
tempwidth = 1;
ret = 1;
}
else if (ret == 0)
else if (MB_NULLWCH (ret))
tempwidth = 0;
else
tempwidth = wcwidth (wc);
@ -1089,7 +1130,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
ret = mbrtowc (&wc, old, MB_CUR_MAX, &ps);
if (ret != 0 && bytes != 0)
{
if (ret == (size_t)-1 || ret == (size_t)-2)
if (MB_INVALIDCH (ret))
memmove (old+bytes, old+1, strlen (old+1));
else
memmove (old+bytes, old+ret, strlen (old+ret));
@ -1124,18 +1165,37 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
memset (&ps_new, 0, sizeof(mbstate_t));
memset (&ps_old, 0, sizeof(mbstate_t));
new_offset = old_offset = 0;
for (ofd = old, nfd = new;
(ofd - old < omax) && *ofd &&
_rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
/* See if the old line is a subset of the new line, so that the
only change is adding characters. */
temp = (omax < nmax) ? omax : nmax;
if (memcmp (old, new, temp) == 0)
{
old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
ofd = old + old_offset;
nfd = new + new_offset;
ofd = old + temp;
nfd = new + temp;
}
else
{
memset (&ps_new, 0, sizeof(mbstate_t));
memset (&ps_old, 0, sizeof(mbstate_t));
if (omax == nmax && STREQN (new, old, omax))
{
ofd = old + omax;
nfd = new + nmax;
}
else
{
new_offset = old_offset = 0;
for (ofd = old, nfd = new;
(ofd - old < omax) && *ofd &&
_rl_compare_chars(old, old_offset, &ps_old, new, new_offset, &ps_new); )
{
old_offset = _rl_find_next_mbchar (old, old_offset, 1, MB_FIND_ANY);
new_offset = _rl_find_next_mbchar (new, new_offset, 1, MB_FIND_ANY);
ofd = old + old_offset;
nfd = new + new_offset;
}
}
}
}
else
@ -1167,8 +1227,11 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
memset (&ps_old, 0, sizeof (mbstate_t));
memset (&ps_new, 0, sizeof (mbstate_t));
#if 0
/* On advice from jir@yamato.ibm.com */
_rl_adjust_point (old, ols - old, &ps_old);
_rl_adjust_point (new, nls - new, &ps_new);
#endif
if (_rl_compare_chars (old, ols - old, &ps_old, new, nls - new, &ps_new) == 0)
break;
@ -1322,7 +1385,7 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
insert_some_chars (nfd, lendiff, col_lendiff);
_rl_last_c_pos += col_lendiff;
}
else if (*ols == 0)
else if (*ols == 0 && lendiff > 0)
{
/* At the end of a line the characters do not have to
be "inserted". They can just be placed on the screen. */
@ -1345,10 +1408,14 @@ update_line (old, new, current_line, omax, nmax, inv_botlin)
if ((temp - lendiff) > 0)
{
_rl_output_some_chars (nfd + lendiff, temp - lendiff);
#if 0
_rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff) - col_lendiff;
#else
#if 1
/* XXX -- this bears closer inspection. Fixes a redisplay bug
reported against bash-3.0-alpha by Andreas Schwab involving
multibyte characters and prompt strings with invisible
characters, but was previously disabled. */
_rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-col_lendiff);
#else
_rl_last_c_pos += _rl_col_width (nfd+lendiff, 0, temp-lendiff);
#endif
}
}
@ -1424,12 +1491,13 @@ rl_on_new_line ()
/* Tell the update routines that we have moved onto a new line with the
prompt already displayed. Code originally from the version of readline
distributed with CLISP. */
distributed with CLISP. rl_expand_prompt must have already been called
(explicitly or implicitly). This still doesn't work exactly right. */
int
rl_on_new_line_with_prompt ()
{
int prompt_size, i, l, real_screenwidth, newlines;
char *prompt_last_line;
char *prompt_last_line, *lprompt;
/* Initialize visible_line and invisible_line to ensure that they can hold
the already-displayed prompt. */
@ -1438,8 +1506,9 @@ rl_on_new_line_with_prompt ()
/* Make sure the line structures hold the already-displayed prompt for
redisplay. */
strcpy (visible_line, rl_prompt);
strcpy (invisible_line, rl_prompt);
lprompt = local_prompt ? local_prompt : rl_prompt;
strcpy (visible_line, lprompt);
strcpy (invisible_line, lprompt);
/* If the prompt contains newlines, take the last tail. */
prompt_last_line = strrchr (rl_prompt, '\n');
@ -1474,6 +1543,8 @@ rl_on_new_line_with_prompt ()
vis_lbreaks[newlines] = l;
visible_wrap_offset = 0;
rl_display_prompt = rl_prompt; /* XXX - make sure it's set */
return 0;
}
@ -1508,8 +1579,15 @@ _rl_move_cursor_relative (new, data)
#if defined (HANDLE_MULTIBYTE)
/* If we have multibyte characters, NEW is indexed by the buffer point in
a multibyte string, but _rl_last_c_pos is the display position. In
this case, NEW's display position is not obvious. */
if ((MB_CUR_MAX == 1 || rl_byte_oriented ) && _rl_last_c_pos == new) return;
this case, NEW's display position is not obvious and must be
calculated. */
if (MB_CUR_MAX == 1 || rl_byte_oriented)
{
if (_rl_last_c_pos == new)
return;
}
else if (_rl_last_c_pos == _rl_col_width (data, 0, new))
return;
#else
if (_rl_last_c_pos == new) return;
#endif
@ -1592,11 +1670,7 @@ _rl_move_cursor_relative (new, data)
#endif
{
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
tputs (_rl_term_cr, 1, _rl_output_character_function);
for (i = 0; i < new; i++)
putc (data[i], rl_outstream);
}
_rl_backspace (_rl_last_c_pos - _rl_col_width (data, 0, new));
else
_rl_backspace (_rl_last_c_pos - new);
}
@ -1734,7 +1808,6 @@ rl_message (va_alist)
int
rl_message (format, arg1, arg2)
char *format;
int arg1, arg2;
{
sprintf (msg_buf, format, arg1, arg2);
msg_buf[sizeof(msg_buf) - 1] = '\0'; /* overflow? */
@ -1763,10 +1836,14 @@ rl_reset_line_state ()
return 0;
}
/* These are getting numerous enough that it's time to create a struct. */
static char *saved_local_prompt;
static char *saved_local_prefix;
static int saved_last_invisible;
static int saved_visible_length;
static int saved_invis_chars_first_line;
static int saved_physical_chars;
void
rl_save_prompt ()
@ -1775,9 +1852,12 @@ rl_save_prompt ()
saved_local_prefix = local_prompt_prefix;
saved_last_invisible = prompt_last_invisible;
saved_visible_length = prompt_visible_length;
saved_invis_chars_first_line = prompt_invis_chars_first_line;
saved_physical_chars = prompt_physical_chars;
local_prompt = local_prompt_prefix = (char *)0;
prompt_last_invisible = prompt_visible_length = 0;
prompt_invis_chars_first_line = prompt_physical_chars = 0;
}
void
@ -1790,6 +1870,8 @@ rl_restore_prompt ()
local_prompt_prefix = saved_local_prefix;
prompt_last_invisible = saved_last_invisible;
prompt_visible_length = saved_visible_length;
prompt_invis_chars_first_line = saved_invis_chars_first_line;
prompt_physical_chars = saved_physical_chars;
}
char *
@ -1822,6 +1904,7 @@ _rl_make_prompt_for_search (pchar)
prompt_last_invisible = saved_last_invisible;
prompt_visible_length = saved_visible_length + 1;
}
return pmt;
}
@ -1997,9 +2080,8 @@ static void
redraw_prompt (t)
char *t;
{
const char *oldp;
char *oldl, *oldlprefix;
int oldlen, oldlast, oldplen, oldninvis;
char *oldp, *oldl, *oldlprefix;
int oldlen, oldlast, oldplen, oldninvis, oldphyschars;
/* Geez, I should make this a struct. */
oldp = rl_display_prompt;
@ -2009,11 +2091,13 @@ redraw_prompt (t)
oldplen = prompt_prefix_length;
oldlast = prompt_last_invisible;
oldninvis = prompt_invis_chars_first_line;
oldphyschars = prompt_physical_chars;
rl_display_prompt = t;
local_prompt = expand_prompt (t, &prompt_visible_length,
&prompt_last_invisible,
&prompt_invis_chars_first_line);
&prompt_invis_chars_first_line,
&prompt_physical_chars);
local_prompt_prefix = (char *)NULL;
rl_forced_update_display ();
@ -2024,6 +2108,7 @@ redraw_prompt (t)
prompt_prefix_length = oldplen;
prompt_last_invisible = oldlast;
prompt_invis_chars_first_line = oldninvis;
prompt_physical_chars = oldphyschars;
}
/* Redisplay the current line after a SIGWINCH is received. */
@ -2133,7 +2218,7 @@ _rl_col_width (str, start, end)
while (point < start)
{
tmp = mbrlen (str + point, max, &ps);
if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2)
if (MB_INVALIDCH ((size_t)tmp))
{
/* In this case, the bytes are invalid or too short to compose a
multibyte character, so we assume that the first byte represents
@ -2145,8 +2230,8 @@ _rl_col_width (str, start, end)
effect of mbstate is undefined. */
memset (&ps, 0, sizeof (mbstate_t));
}
else if (tmp == 0)
break; /* Found '\0' */
else if (MB_NULLWCH (tmp))
break; /* Found '\0' */
else
{
point += tmp;
@ -2162,7 +2247,7 @@ _rl_col_width (str, start, end)
while (point < end)
{
tmp = mbrtowc (&wc, str + point, max, &ps);
if ((size_t)tmp == (size_t)-1 || (size_t)tmp == (size_t)-2)
if (MB_INVALIDCH ((size_t)tmp))
{
/* In this case, the bytes are invalid or too short to compose a
multibyte character, so we assume that the first byte represents
@ -2177,8 +2262,8 @@ _rl_col_width (str, start, end)
effect of mbstate is undefined. */
memset (&ps, 0, sizeof (mbstate_t));
}
else if (tmp == 0)
break; /* Found '\0' */
else if (MB_NULLWCH (tmp))
break; /* Found '\0' */
else
{
point += tmp;
@ -2193,4 +2278,3 @@ _rl_col_width (str, start, end)
return width;
}
#endif /* HANDLE_MULTIBYTE */

View File

@ -129,6 +129,7 @@ static FUNMAP default_funmap[] = {
{ "tty-status", rl_tty_status },
{ "undo", rl_undo_command },
{ "universal-argument", rl_universal_argument },
{ "unix-filename-rubout", rl_unix_filename_rubout },
{ "unix-line-discard", rl_unix_line_discard },
{ "unix-word-rubout", rl_unix_word_rubout },
{ "upcase-word", rl_upcase_word },

View File

@ -1,6 +1,6 @@
/* histexpand.c -- history expansion. */
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1989-2004 Free Software Foundation, Inc.
This file contains the GNU History Library (the Library), a set of
routines for managing the text of previously typed lines.
@ -50,6 +50,8 @@
#define HISTORY_WORD_DELIMITERS " \t\n;&()|<>"
#define HISTORY_QUOTE_CHARACTERS "\"'`"
#define slashify_in_quotes "\\`\"$"
typedef int _hist_search_func_t PARAMS((const char *, int));
extern int rl_byte_oriented; /* declared in mbutil.c */
@ -63,6 +65,8 @@ static int subst_rhs_len;
static char *get_history_word_specifier PARAMS((char *, char *, int *));
static char *history_find_word PARAMS((char *, int));
static int history_tokenize_word PARAMS((const char *, int));
static char *history_substring PARAMS((const char *, int, int));
static char *quote_breaks PARAMS((char *));
@ -83,14 +87,14 @@ char history_comment_char = '\0';
/* The list of characters which inhibit the expansion of text if found
immediately following history_expansion_char. */
const char *history_no_expand_chars = " \t\n\r=";
char *history_no_expand_chars = " \t\n\r=";
/* If set to a non-zero value, single quotes inhibit history expansion.
The default is 0. */
int history_quotes_inhibit_expansion = 0;
/* Used to split words by history_tokenize_internal. */
const char *history_word_delimiters = HISTORY_WORD_DELIMITERS;
char *history_word_delimiters = HISTORY_WORD_DELIMITERS;
/* If set, this points to a function that is called to verify that a
particular history expansion should be performed. */
@ -199,7 +203,7 @@ get_history_event (string, caller_index, delimiting_quote)
}
/* Only a closing `?' or a newline delimit a substring search string. */
for (local_index = i; (c = string[i]); i++)
for (local_index = i; c = string[i]; i++)
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
{
@ -209,8 +213,8 @@ get_history_event (string, caller_index, delimiting_quote)
memset (&ps, 0, sizeof (mbstate_t));
/* These produce warnings because we're passing a const string to a
function that takes a non-const string. */
_rl_adjust_point (string, i, &ps);
if ((v = _rl_get_char_len (string + i, &ps)) > 1)
_rl_adjust_point ((char *)string, i, &ps);
if ((v = _rl_get_char_len ((char *)string + i, &ps)) > 1)
{
i += v - 1;
continue;
@ -515,7 +519,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
char *current_line; /* for !# */
{
int i, n, starting_index;
int substitute_globally, want_quotes, print_only;
int substitute_globally, subst_bywords, want_quotes, print_only;
char *event, *temp, *result, *tstr, *t, c, *word_spec;
int result_len;
#if defined (HANDLE_MULTIBYTE)
@ -597,19 +601,25 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
FREE (word_spec);
/* Perhaps there are other modifiers involved. Do what they say. */
want_quotes = substitute_globally = print_only = 0;
want_quotes = substitute_globally = subst_bywords = print_only = 0;
starting_index = i;
while (string[i] == ':')
{
c = string[i + 1];
if (c == 'g')
if (c == 'g' || c == 'a')
{
substitute_globally = 1;
i++;
c = string[i + 1];
}
else if (c == 'G')
{
subst_bywords = 1;
i++;
c = string[i + 1];
}
switch (c)
{
@ -681,7 +691,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
case 's':
{
char *new_event;
int delimiter, failed, si, l_temp;
int delimiter, failed, si, l_temp, ws, we;
if (c == 's')
{
@ -758,33 +768,67 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
}
/* Find the first occurrence of THIS in TEMP. */
si = 0;
/* Substitute SUBST_RHS for SUBST_LHS in TEMP. There are three
cases to consider:
1. substitute_globally == subst_bywords == 0
2. substitute_globally == 1 && subst_bywords == 0
3. substitute_globally == 0 && subst_bywords == 1
In the first case, we substitute for the first occurrence only.
In the second case, we substitute for every occurrence.
In the third case, we tokenize into words and substitute the
first occurrence of each word. */
si = we = 0;
for (failed = 1; (si + subst_lhs_len) <= l_temp; si++)
if (STREQN (temp+si, subst_lhs, subst_lhs_len))
{
int len = subst_rhs_len - subst_lhs_len + l_temp;
new_event = (char *)xmalloc (1 + len);
strncpy (new_event, temp, si);
strncpy (new_event + si, subst_rhs, subst_rhs_len);
strncpy (new_event + si + subst_rhs_len,
temp + si + subst_lhs_len,
l_temp - (si + subst_lhs_len));
new_event[len] = '\0';
free (temp);
temp = new_event;
{
/* First skip whitespace and find word boundaries if
we're past the end of the word boundary we found
the last time. */
if (subst_bywords && si > we)
{
for (; temp[si] && whitespace (temp[si]); si++)
;
ws = si;
we = history_tokenize_word (temp, si);
}
failed = 0;
if (STREQN (temp+si, subst_lhs, subst_lhs_len))
{
int len = subst_rhs_len - subst_lhs_len + l_temp;
new_event = (char *)xmalloc (1 + len);
strncpy (new_event, temp, si);
strncpy (new_event + si, subst_rhs, subst_rhs_len);
strncpy (new_event + si + subst_rhs_len,
temp + si + subst_lhs_len,
l_temp - (si + subst_lhs_len));
new_event[len] = '\0';
free (temp);
temp = new_event;
if (substitute_globally)
{
si += subst_rhs_len;
l_temp = strlen (temp);
substitute_globally++;
continue;
}
else
break;
}
failed = 0;
if (substitute_globally)
{
/* Reported to fix a bug that causes it to skip every
other match when matching a single character. Was
si += subst_rhs_len previously. */
si += subst_rhs_len - 1;
l_temp = strlen (temp);
substitute_globally++;
continue;
}
else if (subst_bywords)
{
si = we;
l_temp = strlen (temp);
continue;
}
else
break;
}
}
if (substitute_globally > 1)
{
@ -877,7 +921,7 @@ history_expand (hstring, output)
char **output;
{
register int j;
int i, r, l, passc, cc, modified, eindex, only_printing;
int i, r, l, passc, cc, modified, eindex, only_printing, dquote;
char *string;
/* The output string, and its length. */
@ -940,7 +984,7 @@ history_expand (hstring, output)
/* `!' followed by one of the characters in history_no_expand_chars
is NOT an expansion. */
for (i = 0; string[i]; i++)
for (i = dquote = 0; string[i]; i++)
{
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
@ -982,9 +1026,19 @@ history_expand (hstring, output)
else
break;
}
/* XXX - at some point, might want to extend this to handle
double quotes as well. */
else if (history_quotes_inhibit_expansion && string[i] == '\'')
/* Shell-like quoting: allow backslashes to quote double quotes
inside a double-quoted string. */
else if (dquote && string[i] == '\\' && cc == '"')
i++;
/* More shell-like quoting: if we're paying attention to single
quotes and letting them quote the history expansion character,
then we need to pay attention to double quotes, because single
quotes are not special inside double-quoted strings. */
else if (history_quotes_inhibit_expansion && string[i] == '"')
{
dquote = 1 - dquote;
}
else if (dquote == 0 && history_quotes_inhibit_expansion && string[i] == '\'')
{
/* If this is bash, single quotes inhibit history expansion. */
i++;
@ -997,6 +1051,7 @@ history_expand (hstring, output)
if (cc == '\'' || cc == history_expansion_char)
i++;
}
}
if (string[i] != history_expansion_char)
@ -1008,7 +1063,7 @@ history_expand (hstring, output)
}
/* Extract and perform the substitution. */
for (passc = i = j = 0; i < l; i++)
for (passc = dquote = i = j = 0; i < l; i++)
{
int tchar = string[i];
@ -1059,11 +1114,16 @@ history_expand (hstring, output)
ADD_CHAR (tchar);
break;
case '"':
dquote = 1 - dquote;
ADD_CHAR (tchar);
break;
case '\'':
{
/* If history_quotes_inhibit_expansion is set, single quotes
inhibit history expansion. */
if (history_quotes_inhibit_expansion)
if (dquote == 0 && history_quotes_inhibit_expansion)
{
int quote, slen;
@ -1158,7 +1218,9 @@ history_expand (hstring, output)
if (only_printing)
{
#if 0
add_history (result);
#endif
return (2);
}
@ -1221,7 +1283,10 @@ get_history_word_specifier (spec, from, caller_index)
if (spec[i] == '-')
first = 0;
else if (spec[i] == '^')
first = 1;
{
first = 1;
i++;
}
else if (_rl_digit_p (spec[i]) && expecting_word_spec)
{
for (first = 0; _rl_digit_p (spec[i]); i++)
@ -1336,7 +1401,103 @@ history_arg_extract (first, last, string)
return (result);
}
#define slashify_in_quotes "\\`\"$"
static int
history_tokenize_word (string, ind)
const char *string;
int ind;
{
register int i;
int delimiter;
i = ind;
delimiter = 0;
if (member (string[i], "()\n"))
{
i++;
return i;
}
if (member (string[i], "<>;&|$"))
{
int peek = string[i + 1];
if (peek == string[i] && peek != '$')
{
if (peek == '<' && string[i + 2] == '-')
i++;
i += 2;
return i;
}
else
{
if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
(peek == '>' && string[i] == '&') ||
(peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */
(peek == '(' && string[i] == '$')) /* ) */
{
i += 2;
return i;
}
}
if (string[i] != '$')
{
i++;
return i;
}
}
/* Get word from string + i; */
if (member (string[i], HISTORY_QUOTE_CHARACTERS))
delimiter = string[i++];
for (; string[i]; i++)
{
if (string[i] == '\\' && string[i + 1] == '\n')
{
i++;
continue;
}
if (string[i] == '\\' && delimiter != '\'' &&
(delimiter != '"' || member (string[i], slashify_in_quotes)))
{
i++;
continue;
}
if (delimiter && string[i] == delimiter)
{
delimiter = 0;
continue;
}
if (!delimiter && (member (string[i], history_word_delimiters)))
break;
if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS))
delimiter = string[i];
}
return i;
}
static char *
history_substring (string, start, end)
const char *string;
int start, end;
{
register int len;
register char *result;
len = end - start;
result = (char *)xmalloc (len + 1);
strncpy (result, string + start, len);
result[len] = '\0';
return result;
}
/* Parse STRING into tokens and return an array of strings. If WIND is
not -1 and INDP is not null, we also want the word surrounding index
@ -1349,7 +1510,6 @@ history_tokenize_internal (string, wind, indp)
{
char **result;
register int i, start, result_index, size;
int len, delimiter;
/* If we're searching for a string that's not part of a word (e.g., " "),
make sure we set *INDP to a reasonable value. */
@ -1360,8 +1520,6 @@ history_tokenize_internal (string, wind, indp)
exactly where the shell would split them. */
for (i = result_index = size = 0, result = (char **)NULL; string[i]; )
{
delimiter = 0;
/* Skip leading whitespace. */
for (; string[i] && whitespace (string[i]); i++)
;
@ -1369,88 +1527,30 @@ history_tokenize_internal (string, wind, indp)
return (result);
start = i;
if (member (string[i], "()\n"))
i = history_tokenize_word (string, start);
/* If we have a non-whitespace delimiter character (which would not be
skipped by the loop above), use it and any adjacent delimiters to
make a separate field. Any adjacent white space will be skipped the
next time through the loop. */
if (i == start && history_word_delimiters)
{
i++;
goto got_token;
while (string[i] && member (string[i], history_word_delimiters))
i++;
}
if (member (string[i], "<>;&|$"))
{
int peek = string[i + 1];
if (peek == string[i] && peek != '$')
{
if (peek == '<' && string[i + 2] == '-')
i++;
i += 2;
goto got_token;
}
else
{
if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
((peek == '>') && (string[i] == '&')) ||
((peek == '(') && (string[i] == '$')))
{
i += 2;
goto got_token;
}
}
if (string[i] != '$')
{
i++;
goto got_token;
}
}
/* Get word from string + i; */
if (member (string[i], HISTORY_QUOTE_CHARACTERS))
delimiter = string[i++];
for (; string[i]; i++)
{
if (string[i] == '\\' && string[i + 1] == '\n')
{
i++;
continue;
}
if (string[i] == '\\' && delimiter != '\'' &&
(delimiter != '"' || member (string[i], slashify_in_quotes)))
{
i++;
continue;
}
if (delimiter && string[i] == delimiter)
{
delimiter = 0;
continue;
}
if (!delimiter && (member (string[i], history_word_delimiters)))
break;
if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS))
delimiter = string[i];
}
got_token:
/* If we are looking for the word in which the character at a
particular index falls, remember it. */
if (indp && wind != -1 && wind >= start && wind < i)
*indp = result_index;
len = i - start;
if (result_index + 2 >= size)
result = (char **)xrealloc (result, ((size += 10) * sizeof (char *)));
result[result_index] = (char *)xmalloc (1 + len);
strncpy (result[result_index], string + start, len);
result[result_index][len] = '\0';
result[++result_index] = (char *)NULL;
result[result_index++] = history_substring (string, start, i);
result[result_index] = (char *)NULL;
}
return (result);

View File

@ -1,6 +1,6 @@
/* histfile.c - functions to manipulate the history file. */
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1989-2003 Free Software Foundation, Inc.
This file contains the GNU History Library (the Library), a set of
routines for managing the text of previously typed lines.
@ -23,14 +23,19 @@
/* The goal is to make the implementation transparent, so that you
don't have to know what data types are used, just what functions
you can call. I think I have done that. */
#define READLINE_LIBRARY
#if defined (__TANDEM)
# include <floss.h>
#endif
#include "config_readline.h"
#include <stdio.h>
#include <sys/types.h>
#ifndef _MINIX
#if ! defined (_MINIX) && defined (HAVE_SYS_FILE_H)
# include <sys/file.h>
#endif
#include "posixstat.h"
@ -50,7 +55,7 @@
# undef HAVE_MMAP
#endif
#ifdef HAVE_MMAP
#ifdef HISTORY_USE_MMAP
# include <sys/mman.h>
# ifdef MAP_FILE
@ -65,7 +70,7 @@
# define MAP_FAILED ((void *)-1)
# endif
#endif /* HAVE_MMAP */
#endif /* HISTORY_USE_MMAP */
/* If we're compiling for __EMX__ (OS/2) or __CYGWIN__ (cygwin32 environment
on win 95/98/nt), we want to open files with O_BINARY mode so that there
@ -91,6 +96,13 @@ extern int errno;
#include "rlshell.h"
#include "xmalloc.h"
/* If non-zero, we write timestamps to the history file in history_do_write() */
int history_write_timestamps = 0;
/* Does S look like the beginning of a history timestamp entry? Placeholder
for more extensive tests. */
#define HIST_TIMESTAMP_START(s) (*(s) == history_comment_char)
/* Return the string that should be used in the place of this
filename. This only matters when you don't specify the
filename to read_history (), or write_history (). */
@ -149,13 +161,20 @@ read_history_range (filename, from, to)
const char *filename;
int from, to;
{
register char *line_start, *line_end;
char *input, *buffer, *bufend;
register char *line_start, *line_end, *p;
char *input, *buffer, *bufend, *last_ts;
int file, current_line, chars_read;
struct stat finfo;
size_t file_size;
#if defined (EFBIG)
int overflow_errno = EFBIG;
#elif defined (EOVERFLOW)
int overflow_errno = EOVERFLOW;
#else
int overflow_errno = EIO;
#endif
buffer = (char *)NULL;
buffer = last_ts = (char *)NULL;
input = history_filename (filename);
file = open (input, O_RDONLY|O_BINARY, 0666);
@ -167,37 +186,42 @@ read_history_range (filename, from, to)
/* check for overflow on very large files */
if (file_size != finfo.st_size || file_size + 1 < file_size)
{
#if defined (EFBIG)
errno = EFBIG;
#elif defined (EOVERFLOW)
errno = EOVERFLOW;
#endif
errno = overflow_errno;
goto error_and_exit;
}
#ifdef HAVE_MMAP
#ifdef HISTORY_USE_MMAP
/* We map read/write and private so we can change newlines to NULs without
affecting the underlying object. */
buffer = (char *)mmap (0, file_size, PROT_READ|PROT_WRITE, MAP_RFLAGS, file, 0);
if ((void *)buffer == MAP_FAILED)
goto error_and_exit;
{
errno = overflow_errno;
goto error_and_exit;
}
chars_read = file_size;
#else
buffer = (char *)malloc (file_size + 1);
if (buffer == 0)
goto error_and_exit;
{
errno = overflow_errno;
goto error_and_exit;
}
chars_read = read (file, buffer, file_size);
#endif
if (chars_read < 0)
{
error_and_exit:
chars_read = errno;
if (errno != 0)
chars_read = errno;
else
chars_read = EIO;
if (file >= 0)
close (file);
FREE (input);
#ifndef HAVE_MMAP
#ifndef HISTORY_USE_MMAP
FREE (buffer);
#endif
@ -218,8 +242,12 @@ read_history_range (filename, from, to)
for (line_start = line_end = buffer; line_end < bufend && current_line < from; line_end++)
if (*line_end == '\n')
{
current_line++;
line_start = line_end + 1;
p = line_end + 1;
/* If we see something we think is a timestamp, continue with this
line. We should check more extensively here... */
if (HIST_TIMESTAMP_START(p) == 0)
current_line++;
line_start = p;
}
/* If there are lines left to gobble, then gobble them now. */
@ -229,7 +257,22 @@ read_history_range (filename, from, to)
*line_end = '\0';
if (*line_start)
add_history (line_start);
{
if (HIST_TIMESTAMP_START(line_start) == 0)
{
add_history (line_start);
if (last_ts)
{
add_history_time (last_ts);
last_ts = NULL;
}
}
else
{
last_ts = line_start;
current_line--;
}
}
current_line++;
@ -240,7 +283,7 @@ read_history_range (filename, from, to)
}
FREE (input);
#ifndef HAVE_MMAP
#ifndef HISTORY_USE_MMAP
FREE (buffer);
#else
munmap (buffer, file_size);
@ -257,7 +300,7 @@ history_truncate_file (fname, lines)
const char *fname;
int lines;
{
char *buffer, *filename, *bp;
char *buffer, *filename, *bp, *bp1; /* bp1 == bp+1 */
int file, chars_read, rv;
struct stat finfo;
size_t file_size;
@ -320,11 +363,14 @@ history_truncate_file (fname, lines)
}
/* Count backwards from the end of buffer until we have passed
LINES lines. */
for (bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
LINES lines. bp1 is set funny initially. But since bp[1] can't
be a comment character (since it's off the end) and *bp can't be
both a newline and the history comment character, it should be OK. */
for (bp1 = bp = buffer + chars_read - 1; lines && bp > buffer; bp--)
{
if (*bp == '\n')
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
lines--;
bp1 = bp;
}
/* If this is the first line, then the file contains exactly the
@ -333,11 +379,14 @@ history_truncate_file (fname, lines)
the current value of i and 0. Otherwise, write from the start of
this line until the end of the buffer. */
for ( ; bp > buffer; bp--)
if (*bp == '\n')
{
bp++;
break;
}
{
if (*bp == '\n' && HIST_TIMESTAMP_START(bp1) == 0)
{
bp++;
break;
}
bp1 = bp;
}
/* Write only if there are more lines in the file than we want to
truncate to. */
@ -372,9 +421,9 @@ history_do_write (filename, nelements, overwrite)
register int i;
char *output;
int file, mode, rv;
#ifdef HISTORY_USE_MMAP
size_t cursize;
#ifdef HAVE_MMAP
mode = overwrite ? O_RDWR|O_CREAT|O_TRUNC|O_BINARY : O_RDWR|O_APPEND|O_BINARY;
#else
mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
@ -388,7 +437,7 @@ history_do_write (filename, nelements, overwrite)
return (errno);
}
#ifdef HAVE_MMAP
#ifdef HISTORY_USE_MMAP
cursize = overwrite ? 0 : lseek (file, 0, SEEK_END);
#endif
@ -406,10 +455,18 @@ history_do_write (filename, nelements, overwrite)
the_history = history_list ();
/* Calculate the total number of bytes to write. */
for (buffer_size = 0, i = history_length - nelements; i < history_length; i++)
buffer_size += 1 + strlen (the_history[i]->line);
#if 0
buffer_size += 2 + HISTENT_BYTES (the_history[i]);
#else
{
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
buffer_size += strlen (the_history[i]->timestamp) + 1;
buffer_size += strlen (the_history[i]->line) + 1;
}
#endif
/* Allocate the buffer, and fill it. */
#ifdef HAVE_MMAP
#ifdef HISTORY_USE_MMAP
if (ftruncate (file, buffer_size+cursize) == -1)
goto mmap_error;
buffer = (char *)mmap (0, buffer_size, PROT_READ|PROT_WRITE, MAP_WFLAGS, file, cursize);
@ -434,12 +491,18 @@ mmap_error:
for (j = 0, i = history_length - nelements; i < history_length; i++)
{
if (history_write_timestamps && the_history[i]->timestamp && the_history[i]->timestamp[0])
{
strcpy (buffer + j, the_history[i]->timestamp);
j += strlen (the_history[i]->timestamp);
buffer[j++] = '\n';
}
strcpy (buffer + j, the_history[i]->line);
j += strlen (the_history[i]->line);
buffer[j++] = '\n';
}
#ifdef HAVE_MMAP
#ifdef HISTORY_USE_MMAP
if (msync (buffer, buffer_size, 0) != 0 || munmap (buffer, buffer_size) != 0)
rv = errno;
#else

View File

@ -1,6 +1,6 @@
/* History.c -- standalone history library */
/* history.c -- standalone history library */
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1989-2003 Free Software Foundation, Inc.
This file contains the GNU History Library (the Library), a set of
routines for managing the text of previously typed lines.
@ -50,6 +50,8 @@
/* The number of slots to increase the_history by. */
#define DEFAULT_HISTORY_GROW_SIZE 50
static char *hist_inittime PARAMS((void));
/* **************************************************************** */
/* */
/* History Functions */
@ -121,14 +123,15 @@ using_history ()
}
/* Return the number of bytes that the primary history entries are using.
This just adds up the lengths of the_history->lines. */
This just adds up the lengths of the_history->lines and the associated
timestamps. */
int
history_total_bytes ()
{
register int i, result;
for (i = result = 0; the_history && the_history[i]; i++)
result += strlen (the_history[i]->line);
result += HISTENT_BYTES (the_history[i]);
return (result);
}
@ -204,6 +207,40 @@ history_get (offset)
: the_history[local_index];
}
time_t
history_get_time (hist)
HIST_ENTRY *hist;
{
char *ts;
time_t t;
if (hist == 0 || hist->timestamp == 0)
return 0;
ts = hist->timestamp;
if (ts[0] != history_comment_char)
return 0;
t = (time_t) atol (ts + 1); /* XXX - should use strtol() here */
return t;
}
static char *
hist_inittime ()
{
time_t t;
char ts[64], *ret;
t = (time_t) time ((time_t *)0);
#if defined (HAVE_VSNPRINTF) /* assume snprintf if vsnprintf exists */
snprintf (ts, sizeof (ts) - 1, "X%lu", (unsigned long) t);
#else
sprintf (ts, "X%lu", (unsigned long) t);
#endif
ret = savestring (ts);
ret[0] = history_comment_char;
return ret;
}
/* Place STRING at the end of the history list. The data field
is set to NULL. */
void
@ -223,10 +260,7 @@ add_history (string)
/* If there is something in the slot, then remove it. */
if (the_history[0])
{
free (the_history[0]->line);
free (the_history[0]);
}
(void) free_history_entry (the_history[0]);
/* Copy the rest of the entries, moving down one slot. */
for (i = 0; i < history_length; i++)
@ -258,10 +292,41 @@ add_history (string)
temp->line = savestring (string);
temp->data = (char *)NULL;
temp->timestamp = hist_inittime ();
the_history[history_length] = (HIST_ENTRY *)NULL;
the_history[history_length - 1] = temp;
}
/* Change the time stamp of the most recent history entry to STRING. */
void
add_history_time (string)
const char *string;
{
HIST_ENTRY *hs;
hs = the_history[history_length - 1];
FREE (hs->timestamp);
hs->timestamp = savestring (string);
}
/* Free HIST and return the data so the calling application can free it
if necessary and desired. */
histdata_t
free_history_entry (hist)
HIST_ENTRY *hist;
{
histdata_t x;
if (hist == 0)
return ((histdata_t) 0);
FREE (hist->line);
FREE (hist->timestamp);
x = hist->data;
free (hist);
return (x);
}
/* Make the history entry at WHICH have LINE and DATA. This returns
the old entry so you can dispose of the data. In the case of an
invalid WHICH, a NULL pointer is returned. */
@ -281,6 +346,7 @@ replace_history_entry (which, line, data)
temp->line = savestring (line);
temp->data = data;
temp->timestamp = savestring (old_value->timestamp);
the_history[which] = temp;
return (old_value);
@ -325,10 +391,7 @@ stifle_history (max)
{
/* This loses because we cannot free the data. */
for (i = 0, j = history_length - max; i < j; i++)
{
free (the_history[i]->line);
free (the_history[i]);
}
free_history_entry (the_history[i]);
history_base = i;
for (j = 0, i = history_length - max; j < max; i++, j++)
@ -370,8 +433,7 @@ clear_history ()
/* This loses because we cannot free the data. */
for (i = 0; i < history_length; i++)
{
free (the_history[i]->line);
free (the_history[i]);
free_history_entry (the_history[i]);
the_history[i] = (HIST_ENTRY *)NULL;
}

View File

@ -1,5 +1,5 @@
/* History.h -- the names of functions that you can call in history. */
/* Copyright (C) 1989, 1992 Free Software Foundation, Inc.
/* history.h -- the names of functions that you can call in history. */
/* Copyright (C) 1989-2003 Free Software Foundation, Inc.
This file contains the GNU History Library (the Library), a set of
routines for managing the text of previously typed lines.
@ -26,6 +26,8 @@
extern "C" {
#endif
#include <time.h> /* XXX - for history timestamp code */
#if defined READLINE_LIBRARY
# include "rlstdc.h"
# include "rltypedefs.h"
@ -43,9 +45,13 @@ typedef char *histdata_t;
/* The structure used to store a history entry. */
typedef struct _hist_entry {
char *line;
char *timestamp; /* char * rather than time_t for read/write */
histdata_t data;
} HIST_ENTRY;
/* Size of the history-library-managed space in history entry HS. */
#define HISTENT_BYTES(hs) (strlen ((hs)->line) + strlen ((hs)->timestamp))
/* A structure used to pass the current state of the history stuff around. */
typedef struct _hist_state {
HIST_ENTRY **entries; /* Pointer to the entries themselves. */
@ -76,11 +82,19 @@ extern void history_set_history_state PARAMS((HISTORY_STATE *));
The associated data field (if any) is set to NULL. */
extern void add_history PARAMS((const char *));
/* Change the timestamp associated with the most recent history entry to
STRING. */
extern void add_history_time PARAMS((const char *));
/* A reasonably useless function, only here for completeness. WHICH
is the magic number that tells us which element to delete. The
elements are numbered from 0. */
extern HIST_ENTRY *remove_history PARAMS((int));
/* Free the history entry H and return any application-specific data
associated with it. */
extern histdata_t free_history_entry PARAMS((HIST_ENTRY *));
/* Make the history entry at WHICH have LINE and DATA. This returns
the old entry so you can dispose of the data. In the case of an
invalid WHICH, a NULL pointer is returned. */
@ -119,6 +133,10 @@ extern HIST_ENTRY *current_history PARAMS((void));
array. OFFSET is relative to history_base. */
extern HIST_ENTRY *history_get PARAMS((int));
/* Return the timestamp associated with the HIST_ENTRY * passed as an
argument */
extern time_t history_get_time PARAMS((HIST_ENTRY *));
/* Return the number of bytes that the primary history entries are using.
This just adds up the lengths of the_history->lines. */
extern int history_total_bytes PARAMS((void));
@ -225,12 +243,14 @@ extern int history_length;
extern int history_max_entries;
extern char history_expansion_char;
extern char history_subst_char;
extern const char *history_word_delimiters;
extern char *history_word_delimiters;
extern char history_comment_char;
extern const char *history_no_expand_chars;
extern char *history_no_expand_chars;
extern char *history_search_delimiter_chars;
extern int history_quotes_inhibit_expansion;
extern int history_write_timestamps;
/* Backwards compatibility */
extern int max_input_history;

View File

@ -75,11 +75,11 @@ history_search_internal (string, direction, anchored)
if (string == 0 || *string == '\0')
return (-1);
if (!history_length || ((i == history_length) && !reverse))
if (!history_length || ((i >= history_length) && !reverse))
return (-1);
if (reverse && (i == history_length))
i--;
if (reverse && (i >= history_length))
i = history_length - 1;
#define NEXT_LINE() do { if (reverse) i--; else i++; } while (0)

View File

@ -21,6 +21,10 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (__TANDEM)
# include <floss.h>
#endif
#include "config_readline.h"
#include <sys/types.h>
@ -152,6 +156,12 @@ _rl_unget_char (key)
return (0);
}
int
_rl_pushed_input_available ()
{
return (push_index != pop_index);
}
/* If a character is available to be read, then read it and stuff it into
IBUFFER. Otherwise, just return. Returns number of characters read
(0 if none available) and -1 on error (EIO). */
@ -160,7 +170,7 @@ rl_gather_tyi ()
{
int tty;
register int tem, result;
int chars_avail;
int chars_avail, k;
char input;
#if defined(HAVE_SELECT)
fd_set readfds, exceptfds;
@ -200,6 +210,11 @@ rl_gather_tyi ()
fcntl (tty, F_SETFL, tem);
if (chars_avail == -1 && errno == EAGAIN)
return 0;
if (chars_avail == 0) /* EOF */
{
rl_stuff_char (EOF);
return (0);
}
}
#endif /* O_NDELAY */
@ -223,7 +238,12 @@ rl_gather_tyi ()
if (result != -1)
{
while (chars_avail--)
rl_stuff_char ((*rl_getc_function) (rl_instream));
{
k = (*rl_getc_function) (rl_instream);
rl_stuff_char (k);
if (k == NEWLINE || k == RETURN)
break;
}
}
else
{
@ -385,7 +405,7 @@ rl_read_key ()
else
{
/* If input is coming from a macro, then use that. */
if ((c = _rl_next_macro_key ()))
if (c = _rl_next_macro_key ())
return (c);
/* If the user has an event function, then call it periodically. */

View File

@ -68,7 +68,7 @@ static char *prev_line_found;
static char *last_isearch_string;
static int last_isearch_string_len;
static const char *default_isearch_terminators = "\033\012";
static char *default_isearch_terminators = "\033\012";
/* Search backwards through the history looking for a string which is typed
interactively. Start with the current line. */
@ -96,7 +96,7 @@ rl_forward_search_history (sign, key)
static void
rl_display_search (search_string, reverse_p, where)
char *search_string;
int reverse_p, where __attribute__((unused));
int reverse_p, where;
{
char *message;
int msglen, searchlen;
@ -144,7 +144,7 @@ rl_display_search (search_string, reverse_p, where)
backwards. */
static int
rl_search_history (direction, invoking_key)
int direction, invoking_key __attribute__((unused));
int direction, invoking_key;
{
/* The string that the user types in to search for. */
char *search_string;
@ -184,7 +184,7 @@ rl_search_history (direction, invoking_key)
/* The list of characters which terminate the search, but are not
subsequently executed. If the variable isearch-terminators has
been set, we use that value, otherwise we use ESC and C-J. */
const char *isearch_terminators;
char *isearch_terminators;
RL_SETSTATE(RL_STATE_ISEARCH);
orig_point = rl_point;

View File

@ -62,11 +62,13 @@ rl_make_bare_keymap ()
keymap[i].function = (rl_command_func_t *)NULL;
}
#if 0
for (i = 'A'; i < ('Z' + 1); i++)
{
keymap[i].type = ISFUNC;
keymap[i].function = rl_do_lowercase_version;
}
#endif
return (keymap);
}
@ -77,8 +79,9 @@ rl_copy_keymap (map)
Keymap map;
{
register int i;
Keymap temp = rl_make_bare_keymap ();
Keymap temp;
temp = rl_make_bare_keymap ();
for (i = 0; i < KEYMAP_SIZE; i++)
{
temp[i].type = map[i].type;
@ -107,12 +110,8 @@ rl_make_keymap ()
newmap[CTRL('H')].function = rl_rubout;
#if KEYMAP_SIZE > 128
/* Printing characters in some 8-bit character sets. */
for (i = 128; i < 160; i++)
newmap[i].function = rl_insert;
/* ISO Latin-1 printing characters should self-insert. */
for (i = 160; i < 256; i++)
/* Printing characters in ISO Latin-1 and some 8-bit character sets. */
for (i = 128; i < 256; i++)
newmap[i].function = rl_insert;
#endif /* KEYMAP_SIZE > 128 */

View File

@ -77,7 +77,7 @@ static int rl_yank_nth_arg_internal PARAMS((int, int, int));
of kill material. */
int
rl_set_retained_kills (num)
int num __attribute__((unused));
int num;
{
return 0;
}
@ -294,7 +294,7 @@ rl_backward_kill_line (direction, ignore)
/* Kill the whole line, no matter where point is. */
int
rl_kill_full_line (count, ignore)
int count __attribute__((unused)), ignore __attribute__((unused));
int count, ignore;
{
rl_begin_undo_group ();
rl_point = 0;
@ -312,7 +312,7 @@ rl_kill_full_line (count, ignore)
using behaviour that they expect. */
int
rl_unix_word_rubout (count, key)
int count, key __attribute__((unused));
int count, key;
{
int orig_point;
@ -337,6 +337,47 @@ rl_unix_word_rubout (count, key)
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
/* This deletes one filename component in a Unix pathname. That is, it
deletes backward to directory separator (`/') or whitespace. */
int
rl_unix_filename_rubout (count, key)
int count, key;
{
int orig_point, c;
if (rl_point == 0)
rl_ding ();
else
{
orig_point = rl_point;
if (count <= 0)
count = 1;
while (count--)
{
c = rl_line_buffer[rl_point - 1];
while (rl_point && (whitespace (c) || c == '/'))
{
rl_point--;
c = rl_line_buffer[rl_point - 1];
}
while (rl_point && (whitespace (c) == 0) && c != '/')
{
rl_point--;
c = rl_line_buffer[rl_point - 1];
}
}
rl_kill_text (orig_point, rl_point);
if (rl_editing_mode == emacs_mode)
rl_mark = rl_point;
}
return 0;
}
@ -348,7 +389,7 @@ rl_unix_word_rubout (count, key)
doing. */
int
rl_unix_line_discard (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
if (rl_point == 0)
rl_ding ();
@ -385,7 +426,7 @@ region_kill_internal (delete)
/* Copy the text in the region to the kill ring. */
int
rl_copy_region_to_kill (count, ignore)
int count __attribute__((unused)), ignore __attribute__((unused));
int count, ignore;
{
return (region_kill_internal (0));
}
@ -393,7 +434,7 @@ rl_copy_region_to_kill (count, ignore)
/* Kill the text between the point and mark. */
int
rl_kill_region (count, ignore)
int count __attribute__((unused)), ignore __attribute__((unused));
int count, ignore;
{
int r, npoint;
@ -458,7 +499,7 @@ rl_copy_backward_word (count, key)
/* Yank back the last killed text. This ignores arguments. */
int
rl_yank (count, ignore)
int count __attribute__((unused)), ignore __attribute__((unused));
int count, ignore;
{
if (rl_kill_ring == 0)
{
@ -477,7 +518,7 @@ rl_yank (count, ignore)
yank back some other text. */
int
rl_yank_pop (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
int l, n;

View File

@ -190,7 +190,7 @@ _rl_kill_kbd_macro ()
re-executing the existing macro. */
int
rl_start_kbd_macro (ignore1, ignore2)
int ignore1 __attribute__((unused)), ignore2 __attribute__((unused));
int ignore1, ignore2;
{
if (RL_ISSTATE (RL_STATE_MACRODEF))
{
@ -215,7 +215,7 @@ rl_start_kbd_macro (ignore1, ignore2)
that many times, counting the definition as the first time. */
int
rl_end_kbd_macro (count, ignore)
int count, ignore __attribute__((unused));
int count, ignore;
{
if (RL_ISSTATE (RL_STATE_MACRODEF) == 0)
{
@ -235,7 +235,7 @@ rl_end_kbd_macro (count, ignore)
COUNT says how many times to execute it. */
int
rl_call_last_kbd_macro (count, ignore)
int count, ignore __attribute__((unused));
int count, ignore;
{
if (current_macro == 0)
_rl_abort_internal ();

View File

@ -1,6 +1,6 @@
/* mbutil.c -- readline multibyte character utility functions */
/* Copyright (C) 2001 Free Software Foundation, Inc.
/* Copyright (C) 2001-2004 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
@ -90,12 +90,12 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
/* if this is true, means that seed was not pointed character
started byte. So correct the point and consume count */
if (seed < point)
count --;
count--;
while (count > 0)
{
tmp = mbrtowc (&wc, string+point, strlen(string + point), &ps);
if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
if (MB_INVALIDCH ((size_t)tmp))
{
/* invalid bytes. asume a byte represents a character */
point++;
@ -103,9 +103,8 @@ _rl_find_next_mbchar_internal (string, seed, count, find_non_zero)
/* reset states. */
memset(&ps, 0, sizeof(mbstate_t));
}
else if (tmp == (size_t)0)
/* found '\0' char */
break;
else if (MB_NULLWCH (tmp))
break; /* found wide '\0' */
else
{
/* valid bytes */
@ -158,7 +157,7 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero)
while (point < seed)
{
tmp = mbrtowc (&wc, string + point, length - point, &ps);
if ((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
if (MB_INVALIDCH ((size_t)tmp))
{
/* in this case, bytes are invalid or shorted to compose
multibyte char, so assume that the first byte represents
@ -167,8 +166,12 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero)
/* clear the state of the byte sequence, because
in this case effect of mbstate is undefined */
memset(&ps, 0, sizeof (mbstate_t));
/* Since we're assuming that this byte represents a single
non-zero-width character, don't forget about it. */
prev = point;
}
else if (tmp == 0)
else if (MB_NULLWCH (tmp))
break; /* Found '\0' char. Can this happen? */
else
{
@ -194,7 +197,7 @@ _rl_find_prev_mbchar_internal (string, seed, find_non_zero)
if it couldn't parse a complete multibyte character. */
int
_rl_get_char_len (src, ps)
const char *src;
char *src;
mbstate_t *ps;
{
size_t tmp;
@ -203,14 +206,16 @@ _rl_get_char_len (src, ps)
if (tmp == (size_t)(-2))
{
/* shorted to compose multibyte char */
memset (ps, 0, sizeof(mbstate_t));
if (ps)
memset (ps, 0, sizeof(mbstate_t));
return -2;
}
else if (tmp == (size_t)(-1))
{
/* invalid to compose multibyte char */
/* initialize the conversion state */
memset (ps, 0, sizeof(mbstate_t));
if (ps)
memset (ps, 0, sizeof(mbstate_t));
return -1;
}
else if (tmp == (size_t)0)
@ -223,9 +228,12 @@ _rl_get_char_len (src, ps)
return 1. Otherwise return 0. */
int
_rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2)
char *buf1, *buf2;
mbstate_t *ps1, *ps2;
int pos1, pos2;
char *buf1;
int pos1;
mbstate_t *ps1;
char *buf2;
int pos2;
mbstate_t *ps2;
{
int i, w1, w2;
@ -249,7 +257,7 @@ _rl_compare_chars (buf1, pos1, ps1, buf2, pos2, ps2)
it returns -1 */
int
_rl_adjust_point(string, point, ps)
const char *string;
char *string;
int point;
mbstate_t *ps;
{
@ -266,7 +274,7 @@ _rl_adjust_point(string, point, ps)
while (pos < point)
{
tmp = mbrlen (string + pos, length - pos, ps);
if((size_t)(tmp) == (size_t)-1 || (size_t)(tmp) == (size_t)-2)
if (MB_INVALIDCH ((size_t)tmp))
{
/* in this case, bytes are invalid or shorted to compose
multibyte char, so assume that the first byte represents
@ -274,8 +282,11 @@ _rl_adjust_point(string, point, ps)
pos++;
/* clear the state of the byte sequence, because
in this case effect of mbstate is undefined */
memset (ps, 0, sizeof (mbstate_t));
if (ps)
memset (ps, 0, sizeof (mbstate_t));
}
else if (MB_NULLWCH (tmp))
pos++;
else
pos += tmp;
}
@ -308,8 +319,8 @@ _rl_is_mbchar_matched (string, seed, end, mbchar, length)
#undef _rl_find_next_mbchar
int
_rl_find_next_mbchar (string, seed, count, flags)
char *string __attribute__((unused));
int seed, count, flags __attribute__((unused));
char *string;
int seed, count, flags;
{
#if defined (HANDLE_MULTIBYTE)
return _rl_find_next_mbchar_internal (string, seed, count, flags);
@ -324,8 +335,8 @@ _rl_find_next_mbchar (string, seed, count, flags)
#undef _rl_find_prev_mbchar
int
_rl_find_prev_mbchar (string, seed, flags)
char *string __attribute__((unused));
int seed, flags __attribute__((unused));
char *string;
int seed, flags;
{
#if defined (HANDLE_MULTIBYTE)
return _rl_find_prev_mbchar_internal (string, seed, flags);

View File

@ -1,6 +1,6 @@
/* misc.c -- miscellaneous bindable readline functions. */
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
@ -155,7 +155,7 @@ rl_digit_loop ()
/* Add the current digit to the argument in progress. */
int
rl_digit_argument (ignore, key)
int ignore __attribute__((unused)), key;
int ignore, key;
{
rl_execute_next (key);
return (rl_digit_loop ());
@ -185,7 +185,7 @@ _rl_init_argument ()
dispatch on it. If the key is the abort character then abort. */
int
rl_universal_argument (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
rl_numeric_arg *= 4;
return (rl_digit_loop ());
@ -251,6 +251,8 @@ rl_maybe_unsave_line ()
{
if (_rl_saved_line_for_history)
{
/* Can't call with `1' because rl_undo_list might point to an undo
list from a history entry, as in rl_replace_from_history() below. */
rl_replace_line (_rl_saved_line_for_history->line, 0);
rl_undo_list = (UNDO_LIST *)_rl_saved_line_for_history->data;
_rl_free_history_entry (_rl_saved_line_for_history);
@ -272,6 +274,13 @@ rl_maybe_save_line ()
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
_rl_saved_line_for_history->data = (char *)rl_undo_list;
}
else if (STREQ (rl_line_buffer, _rl_saved_line_for_history->line) == 0)
{
free (_rl_saved_line_for_history->line);
_rl_saved_line_for_history->line = savestring (rl_line_buffer);
_rl_saved_line_for_history->data = (char *)rl_undo_list; /* XXX possible memleak */
}
return 0;
}
@ -296,7 +305,7 @@ _rl_history_set_point ()
rl_point = rl_end;
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
if (rl_editing_mode == vi_mode && _rl_keymap != vi_insertion_keymap)
rl_point = 0;
#endif /* VI_MODE */
@ -307,8 +316,10 @@ _rl_history_set_point ()
void
rl_replace_from_history (entry, flags)
HIST_ENTRY *entry;
int flags __attribute__((unused)); /* currently unused */
int flags; /* currently unused */
{
/* Can't call with `1' because rl_undo_list might point to an undo list
from a history entry, just like we're setting up here. */
rl_replace_line (entry->line, 0);
rl_undo_list = (UNDO_LIST *)entry->data;
rl_point = rl_end;
@ -332,7 +343,7 @@ rl_replace_from_history (entry, flags)
/* Meta-< goes to the start of the history. */
int
rl_beginning_of_history (count, key)
int count __attribute__((unused)), key;
int count, key;
{
return (rl_get_previous_history (1 + where_history (), key));
}
@ -340,7 +351,7 @@ rl_beginning_of_history (count, key)
/* Meta-> goes to the end of the history. (The current line). */
int
rl_end_of_history (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
rl_maybe_replace_line ();
using_history ();
@ -433,6 +444,7 @@ rl_get_previous_history (count, key)
rl_replace_from_history (temp, 0);
_rl_history_set_point ();
}
return 0;
}
@ -444,7 +456,7 @@ rl_get_previous_history (count, key)
/* How to toggle back and forth between editing modes. */
int
rl_vi_editing_mode (count, key)
int count __attribute__((unused)), key;
int count, key;
{
#if defined (VI_MODE)
_rl_set_insert_mode (RL_IM_INSERT, 1); /* vi mode ignores insert mode */
@ -457,7 +469,7 @@ rl_vi_editing_mode (count, key)
int
rl_emacs_editing_mode (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
rl_editing_mode = emacs_mode;
_rl_set_insert_mode (RL_IM_INSERT, 1); /* emacs mode default is insert mode */
@ -468,7 +480,7 @@ rl_emacs_editing_mode (count, key)
/* Function for the rest of the library to use to set insert/overwrite mode. */
void
_rl_set_insert_mode (im, force)
int im, force __attribute__((unused));
int im, force;
{
#ifdef CURSOR_MODE
_rl_set_cursor (im, force);
@ -481,7 +493,7 @@ _rl_set_insert_mode (im, force)
mode. A negative or zero explicit argument selects insert mode. */
int
rl_overwrite_mode (count, key)
int count, key __attribute__((unused));
int count, key;
{
if (rl_explicit_arg == 0)
_rl_set_insert_mode (rl_insert_mode ^ 1, 0);

View File

@ -73,6 +73,23 @@ static char *normalize_codeset PARAMS((char *));
static char *find_codeset PARAMS((char *, size_t *));
#endif /* !HAVE_SETLOCALE */
static char *_rl_get_locale_var PARAMS((const char *));
static char *
_rl_get_locale_var (v)
const char *v;
{
char *lspec;
lspec = sh_get_env_value ("LC_ALL");
if (lspec == 0 || *lspec == 0)
lspec = sh_get_env_value (v);
if (lspec == 0 || *lspec == 0)
lspec = sh_get_env_value ("LANG");
return lspec;
}
/* Check for LC_ALL, LC_CTYPE, and LANG and use the first with a value
to decide the defaults for 8-bit character input and output. Returns
1 if we set eight-bit mode. */
@ -82,10 +99,21 @@ _rl_init_eightbit ()
/* If we have setlocale(3), just check the current LC_CTYPE category
value, and go into eight-bit mode if it's not C or POSIX. */
#if defined (HAVE_SETLOCALE)
char *t;
char *lspec, *t;
/* Set the LC_CTYPE locale category from environment variables. */
t = setlocale (LC_CTYPE, "");
lspec = _rl_get_locale_var ("LC_CTYPE");
/* Since _rl_get_locale_var queries the right environment variables,
we query the current locale settings with setlocale(), and, if
that doesn't return anything, we set lspec to the empty string to
force the subsequent call to setlocale() to define the `native'
environment. */
if (lspec == 0 || *lspec == 0)
lspec = setlocale (LC_CTYPE, (char *)NULL);
if (lspec == 0)
lspec = "";
t = setlocale (LC_CTYPE, lspec);
if (t && *t && (t[0] != 'C' || t[1]) && (STREQ (t, "POSIX") == 0))
{
_rl_meta_flag = 1;
@ -103,9 +131,8 @@ _rl_init_eightbit ()
/* We don't have setlocale. Finesse it. Check the environment for the
appropriate variables and set eight-bit mode if they have the right
values. */
lspec = sh_get_env_value ("LC_ALL");
if (lspec == 0) lspec = sh_get_env_value ("LC_CTYPE");
if (lspec == 0) lspec = sh_get_env_value ("LANG");
lspec = _rl_get_locale_var ("LC_CTYPE");
if (lspec == 0 || (t = normalize_codeset (lspec)) == 0)
return (0);
for (i = 0; t && legal_lang_values[i]; i++)

View File

@ -21,6 +21,10 @@
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#if defined (__TANDEM)
# include <floss.h>
#endif
#include "rlconf.h"
#include "config_readline.h"

View File

@ -25,7 +25,11 @@
#if defined (HAVE_DIRENT_H)
# include <dirent.h>
# define D_NAMLEN(d) (strlen ((d)->d_name))
# if defined (HAVE_STRUCT_DIRENT_D_NAMLEN)
# define D_NAMLEN(d) ((d)->d_namlen)
# else
# define D_NAMLEN(d) (strlen ((d)->d_name))
# endif /* !HAVE_STRUCT_DIRENT_D_NAMLEN */
#else
# if defined (HAVE_SYS_NDIR_H)
# include <sys/ndir.h>
@ -42,11 +46,11 @@
# define D_NAMLEN(d) ((d)->d_namlen)
#endif /* !HAVE_DIRENT_H */
#if defined (STRUCT_DIRENT_HAS_D_INO) && !defined (STRUCT_DIRENT_HAS_D_FILENO)
#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (HAVE_STRUCT_DIRENT_D_FILENO)
# define d_fileno d_ino
#endif
#if defined (_POSIX_SOURCE) && (!defined (STRUCT_DIRENT_HAS_D_INO) || defined (BROKEN_DIRENT_D_INO))
#if defined (_POSIX_SOURCE) && (!defined (HAVE_STRUCT_DIRENT_D_INO) || defined (BROKEN_DIRENT_D_INO))
/* Posix does not require that the d_ino field be present, and some
systems do not provide it. */
# define REAL_DIR_ENTRY(dp) 1

View File

@ -66,11 +66,11 @@
#include "xmalloc.h"
#ifndef RL_LIBRARY_VERSION
# define RL_LIBRARY_VERSION "4.3"
# define RL_LIBRARY_VERSION "5.0"
#endif
#ifndef RL_READLINE_VERSION
# define RL_READLINE_VERSION 0x0403
# define RL_READLINE_VERSION 0x0500
#endif
extern void _rl_free_history_entry PARAMS((HIST_ENTRY *));
@ -83,6 +83,7 @@ static void bind_arrow_keys_internal PARAMS((Keymap));
static void bind_arrow_keys PARAMS((void));
static void readline_default_bindings PARAMS((void));
static void reset_default_bindings PARAMS((void));
/* **************************************************************** */
/* */
@ -345,7 +346,7 @@ readline_internal_setup ()
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode)
rl_vi_insertion_mode (1, 0);
rl_vi_insertion_mode (1, 'i');
#endif /* VI_MODE */
if (rl_pre_input_hook)
@ -648,7 +649,21 @@ _rl_dispatch_subseq (key, map, got_subseq)
the function. The recursive call to _rl_dispatch_subseq has
already taken care of pushing any necessary input back onto
the input queue with _rl_unget_char. */
r = _rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key));
{
#if 0
r = _rl_dispatch (ANYOTHERKEY, FUNCTION_TO_KEYMAP (map, key));
#else
/* XXX - experimental code -- might never be executed. Save
for later. */
Keymap m = FUNCTION_TO_KEYMAP (map, key);
int type = m[ANYOTHERKEY].type;
func = m[ANYOTHERKEY].function;
if (type == ISFUNC && func == rl_do_lowercase_version)
r = _rl_dispatch (_rl_to_lower (key), map);
else
r = _rl_dispatch (ANYOTHERKEY, m);
#endif
}
else if (r && map[ANYOTHERKEY].function)
{
/* We didn't match (r is probably -1), so return something to
@ -682,6 +697,7 @@ _rl_dispatch_subseq (key, map, got_subseq)
}
#if defined (VI_MODE)
if (rl_editing_mode == vi_mode && _rl_keymap == vi_movement_keymap &&
key != ANYOTHERKEY &&
_rl_vi_textmod_command (key))
_rl_vi_set_last (key, rl_numeric_arg, rl_arg_sign);
#endif
@ -836,7 +852,7 @@ readline_initialize_everything ()
/* If the completion parser's default word break characters haven't
been set yet, then do so now. */
if (rl_completer_word_break_characters == (char *)NULL)
rl_completer_word_break_characters = rl_basic_word_break_characters;
rl_completer_word_break_characters = (char *)rl_basic_word_break_characters;
}
/* If this system allows us to look at the values of the regular
@ -848,6 +864,15 @@ readline_default_bindings ()
rl_tty_set_default_bindings (_rl_keymap);
}
/* Reset the default bindings for the terminal special characters we're
interested in back to rl_insert and read the new ones. */
static void
reset_default_bindings ()
{
rl_tty_unset_default_bindings (_rl_keymap);
rl_tty_set_default_bindings (_rl_keymap);
}
/* Bind some common arrow key sequences in MAP. */
static void
bind_arrow_keys_internal (map)
@ -859,25 +884,25 @@ bind_arrow_keys_internal (map)
_rl_keymap = map;
#if defined (__MSDOS__)
_rl_bind_if_unbound ("\033[0A", rl_get_previous_history);
_rl_bind_if_unbound ("\033[0B", rl_backward_char);
_rl_bind_if_unbound ("\033[0C", rl_forward_char);
_rl_bind_if_unbound ("\033[0D", rl_get_next_history);
rl_bind_keyseq_if_unbound ("\033[0A", rl_get_previous_history);
rl_bind_keyseq_if_unbound ("\033[0B", rl_backward_char);
rl_bind_keyseq_if_unbound ("\033[0C", rl_forward_char);
rl_bind_keyseq_if_unbound ("\033[0D", rl_get_next_history);
#endif
_rl_bind_if_unbound ("\033[A", rl_get_previous_history);
_rl_bind_if_unbound ("\033[B", rl_get_next_history);
_rl_bind_if_unbound ("\033[C", rl_forward_char);
_rl_bind_if_unbound ("\033[D", rl_backward_char);
_rl_bind_if_unbound ("\033[H", rl_beg_of_line);
_rl_bind_if_unbound ("\033[F", rl_end_of_line);
rl_bind_keyseq_if_unbound ("\033[A", rl_get_previous_history);
rl_bind_keyseq_if_unbound ("\033[B", rl_get_next_history);
rl_bind_keyseq_if_unbound ("\033[C", rl_forward_char);
rl_bind_keyseq_if_unbound ("\033[D", rl_backward_char);
rl_bind_keyseq_if_unbound ("\033[H", rl_beg_of_line);
rl_bind_keyseq_if_unbound ("\033[F", rl_end_of_line);
_rl_bind_if_unbound ("\033OA", rl_get_previous_history);
_rl_bind_if_unbound ("\033OB", rl_get_next_history);
_rl_bind_if_unbound ("\033OC", rl_forward_char);
_rl_bind_if_unbound ("\033OD", rl_backward_char);
_rl_bind_if_unbound ("\033OH", rl_beg_of_line);
_rl_bind_if_unbound ("\033OF", rl_end_of_line);
rl_bind_keyseq_if_unbound ("\033OA", rl_get_previous_history);
rl_bind_keyseq_if_unbound ("\033OB", rl_get_next_history);
rl_bind_keyseq_if_unbound ("\033OC", rl_forward_char);
rl_bind_keyseq_if_unbound ("\033OD", rl_backward_char);
rl_bind_keyseq_if_unbound ("\033OH", rl_beg_of_line);
rl_bind_keyseq_if_unbound ("\033OF", rl_end_of_line);
_rl_keymap = xkeymap;
}

View File

@ -1,6 +1,6 @@
/* Readline.h -- the names of functions callable from within readline. */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
@ -40,9 +40,9 @@ extern "C" {
#endif
/* Hex-encoded Readline version number. */
#define RL_READLINE_VERSION 0x0403 /* Readline 4.3 */
#define RL_VERSION_MAJOR 4
#define RL_VERSION_MINOR 3
#define RL_READLINE_VERSION 0x0500 /* Readline 5.0 */
#define RL_VERSION_MAJOR 5
#define RL_VERSION_MINOR 0
/* Readline data structures. */
@ -160,6 +160,7 @@ extern int rl_kill_line PARAMS((int, int));
extern int rl_backward_kill_line PARAMS((int, int));
extern int rl_kill_full_line PARAMS((int, int));
extern int rl_unix_word_rubout PARAMS((int, int));
extern int rl_unix_filename_rubout PARAMS((int, int));
extern int rl_unix_line_discard PARAMS((int, int));
extern int rl_copy_region_to_kill PARAMS((int, int));
extern int rl_kill_region PARAMS((int, int));
@ -258,6 +259,8 @@ extern int rl_vi_check PARAMS((void));
extern int rl_vi_domove PARAMS((int, int *));
extern int rl_vi_bracktype PARAMS((int));
extern void rl_vi_start_inserting PARAMS((int, int, int));
/* VI-mode pseudo-bindable commands, used as utility functions. */
extern int rl_vi_fWord PARAMS((int, int));
extern int rl_vi_bWord PARAMS((int, int));
@ -290,12 +293,20 @@ extern int rl_bind_key PARAMS((int, rl_command_func_t *));
extern int rl_bind_key_in_map PARAMS((int, rl_command_func_t *, Keymap));
extern int rl_unbind_key PARAMS((int));
extern int rl_unbind_key_in_map PARAMS((int, Keymap));
extern int rl_bind_key_if_unbound PARAMS((int, rl_command_func_t *));
extern int rl_bind_key_if_unbound_in_map PARAMS((int, rl_command_func_t *, Keymap));
extern int rl_unbind_function_in_map PARAMS((rl_command_func_t *, Keymap));
extern int rl_unbind_command_in_map PARAMS((const char *, Keymap));
extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_bind_keyseq PARAMS((const char *, rl_command_func_t *));
extern int rl_bind_keyseq_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_bind_keyseq_if_unbound PARAMS((const char *, rl_command_func_t *));
extern int rl_bind_keyseq_if_unbound_in_map PARAMS((const char *, rl_command_func_t *, Keymap));
extern int rl_generic_bind PARAMS((int, const char *, char *, Keymap));
extern int rl_variable_bind PARAMS((const char *, const char *));
/* Backwards compatibility, use rl_bind_keyseq_in_map instead. */
extern int rl_set_key PARAMS((const char *, rl_command_func_t *, Keymap));
/* Backwards compatibility, use rl_generic_bind instead. */
extern int rl_macro_bind PARAMS((const char *, const char *, Keymap));
@ -329,7 +340,7 @@ extern void rl_set_keymap PARAMS((Keymap));
extern Keymap rl_get_keymap PARAMS((void));
/* Undocumented; used internally only. */
extern void rl_set_keymap_from_edit_mode PARAMS((void));
extern const char *rl_get_keymap_name_from_edit_mode PARAMS((void));
extern char *rl_get_keymap_name_from_edit_mode PARAMS((void));
/* Functions for manipulating the funmap, which maps command names to functions. */
extern int rl_add_funmap_entry PARAMS((const char *, rl_command_func_t *));
@ -358,7 +369,7 @@ extern int rl_clear_message PARAMS((void));
extern int rl_reset_line_state PARAMS((void));
extern int rl_crlf PARAMS((void));
#if (defined (__STDC__) || defined (__cplusplus)) && defined (USE_VARARGS) && defined (PREFER_STDARG)
#if defined (USE_VARARGS) && defined (PREFER_STDARG)
extern int rl_message (const char *, ...) __attribute__((__format__ (printf, 1, 2)));
#else
extern int rl_message ();
@ -384,13 +395,14 @@ extern char *rl_copy_text PARAMS((int, int));
extern void rl_prep_terminal PARAMS((int));
extern void rl_deprep_terminal PARAMS((void));
extern void rl_tty_set_default_bindings PARAMS((Keymap));
extern void rl_tty_unset_default_bindings PARAMS((Keymap));
extern int rl_reset_terminal PARAMS((const char *));
extern void rl_resize_terminal PARAMS((void));
extern void rl_set_screen_size PARAMS((int, int));
extern void rl_get_screen_size PARAMS((int *, int *));
extern const char *rl_get_termcap PARAMS((const char *));
extern char *rl_get_termcap PARAMS((const char *));
/* Functions for character input. */
extern int rl_stuff_char PARAMS((int));
@ -603,7 +615,12 @@ extern const char *rl_basic_word_break_characters;
/* The list of characters that signal a break between words for
rl_complete_internal. The default list is the contents of
rl_basic_word_break_characters. */
extern const char *rl_completer_word_break_characters;
extern /*const*/ char *rl_completer_word_break_characters;
/* Hook function to allow an application to set the completion word
break characters before readline breaks up the line. Allows
position-dependent word break characters. */
extern rl_cpvfunc_t *rl_completion_word_break_hook;
/* List of characters which can be used to quote a substring of the line.
Completion occurs on the entire substring, and within the substring
@ -687,6 +704,11 @@ extern int rl_attempted_completion_over;
functions. */
extern int rl_completion_type;
/* Up to this many items will be displayed in response to a
possible-completions call. After that, we ask the user if she
is sure she wants to see them all. The default value is 100. */
extern int rl_completion_query_items;
/* Character appended to completed words when at the end of the line. The
default is a space. Nothing is added if this is '\0'. */
extern int rl_completion_append_character;
@ -695,10 +717,18 @@ extern int rl_completion_append_character;
rl_completion_append_character will not be appended. */
extern int rl_completion_suppress_append;
/* Up to this many items will be displayed in response to a
possible-completions call. After that, we ask the user if she
is sure she wants to see them all. The default value is 100. */
extern int rl_completion_query_items;
/* Set to any quote character readline thinks it finds before any application
completion function is called. */
extern int rl_completion_quote_character;
/* Set to a non-zero value if readline found quoting anywhere in the word to
be completed; set before any application completion function is called. */
extern int rl_completion_found_quote;
/* If non-zero, the completion functions don't append any closing quote.
This is set to 0 by rl_complete_internal and may be changed by an
application-specific completion function. */
extern int rl_completion_suppress_quote;
/* If non-zero, a slash will be appended to completed filenames that are
symbolic links to directory names, subject to the value of the
@ -749,6 +779,7 @@ extern int rl_inhibit_completion;
#define RL_STATE_SIGHANDLER 0x08000 /* in readline sighandler */
#define RL_STATE_UNDOING 0x10000 /* doing an undo */
#define RL_STATE_INPUTPENDING 0x20000 /* rl_execute_next called */
#define RL_STATE_TTYCSAVED 0x40000 /* tty special chars saved */
#define RL_STATE_DONE 0x80000 /* done; accepted line */
@ -785,6 +816,12 @@ struct readline_state {
int catchsigs;
int catchsigwinch;
/* search state */
/* completion state */
/* options state */
/* reserved for future expansion, so the struct size doesn't change */
char reserved[64];
};

View File

@ -32,10 +32,6 @@
#include "rlstdc.h"
#if !defined(__attribute__) && (defined(__cplusplus) || !defined(__GNUC__) || __GNUC__ == 2 && __GNUC_MINOR__ <8)
#define __attribute__(A)
#endif
#if defined (_POSIX_VERSION) && !defined (TERMIOS_MISSING)
# define TERMIOS_TTY_DRIVER
#else
@ -81,7 +77,7 @@ extern int _rl_stricmp PARAMS((char *, char *));
extern int _rl_strnicmp PARAMS((char *, char *, int));
#endif
#if defined (HAVE_STRPBRK)
#if defined (HAVE_STRPBRK) && !defined (HAVE_MULTIBYTE)
# define _rl_strpbrk(a,b) strpbrk((a),(b))
#else
extern char *_rl_strpbrk PARAMS((const char *, const char *));

View File

@ -35,11 +35,18 @@
#if defined (HAVE_WCTYPE_H) && defined (HAVE_WCHAR_H)
# include <wchar.h>
# include <wctype.h>
# if defined (HAVE_MBSRTOWCS) /* system is supposed to support XPG5 */
# if defined (HAVE_MBSRTOWCS) && defined (HAVE_MBRTOWC) && defined (HAVE_MBRLEN) && defined (HAVE_WCWIDTH)
/* system is supposed to support XPG5 */
# define HANDLE_MULTIBYTE 1
# endif
#endif
/* If we don't want multibyte chars even on a system that supports them, let
the configuring user turn multibyte support off. */
#if defined (NO_MULTIBYTE_SUPPORT)
# undef HANDLE_MULTIBYTE
#endif
/* Some systems, like BeOS, have multibyte encodings but lack mbstate_t. */
#if HANDLE_MULTIBYTE && !defined (HAVE_MBSTATE_T)
# define wcsrtombs(dest, src, len, ps) (wcsrtombs) (dest, src, len, 0)
@ -82,14 +89,17 @@ extern int _rl_find_next_mbchar PARAMS((char *, int, int, int));
#ifdef HANDLE_MULTIBYTE
extern int _rl_compare_chars PARAMS((char *, int, mbstate_t *, char *, int, mbstate_t *));
extern int _rl_get_char_len PARAMS((const char *, mbstate_t *));
extern int _rl_adjust_point PARAMS((const char *, int, mbstate_t *));
extern int _rl_get_char_len PARAMS((char *, mbstate_t *));
extern int _rl_adjust_point PARAMS((char *, int, mbstate_t *));
extern int _rl_read_mbchar PARAMS((char *, int));
extern int _rl_read_mbstring PARAMS((int, char *, int));
extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
#define MB_INVALIDCH(x) ((x) == (size_t)-1 || (x) == (size_t)-2)
#define MB_NULLWCH(x) ((x) == 0)
#else /* !HANDLE_MULTIBYTE */
#undef MB_LEN_MAX
@ -101,6 +111,9 @@ extern int _rl_is_mbchar_matched PARAMS((char *, int, int, char *, int));
#define _rl_find_prev_mbchar(b, i, f) (((i) == 0) ? (i) : ((i) - 1))
#define _rl_find_next_mbchar(b, i1, i2, f) ((i1) + (i2))
#define MB_INVALIDCH(x) (0)
#define MB_NULLWCH(x) (0)
#endif /* !HANDLE_MULTIBYTE */
extern int rl_byte_oriented;

View File

@ -1,7 +1,7 @@
/* rlprivate.h -- functions and variables global to the readline library,
but not intended for use by applications. */
/* Copyright (C) 1999 Free Software Foundation, Inc.
/* Copyright (C) 1999-2004 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
@ -73,7 +73,7 @@ extern int rl_set_retained_kills PARAMS((int));
extern void _rl_set_screen_size PARAMS((int, int));
/* undo.c */
extern int _rl_fix_last_undo_of_type PARAMS((unsigned int, int, int));
extern int _rl_fix_last_undo_of_type PARAMS((int, int, int));
/* util.c */
extern char *_rl_savestring PARAMS((const char *));
@ -103,7 +103,6 @@ extern int readline_internal_char PARAMS((void));
#endif /* READLINE_CALLBACKS */
/* bind.c */
extern void _rl_bind_if_unbound PARAMS((const char *, rl_command_func_t *));
/* complete.c */
extern char _rl_find_completion_word PARAMS((int *, int *));
@ -131,6 +130,7 @@ extern int _rl_input_available PARAMS((void));
extern int _rl_input_queued PARAMS((int));
extern void _rl_insert_typein PARAMS((int));
extern int _rl_unget_char PARAMS((int));
extern int _rl_pushed_input_available PARAMS((void));
/* macro.c */
extern void _rl_with_macro_input PARAMS((char *));
@ -219,6 +219,7 @@ extern const char *_rl_possible_meta_prefixes[];
/* complete.c */
extern int _rl_complete_show_all;
extern int _rl_complete_show_unmodified;
extern int _rl_complete_mark_directories;
extern int _rl_complete_mark_symlink_dirs;
extern int _rl_print_completions_horizontally;
@ -230,7 +231,7 @@ extern int _rl_page_completions;
extern int _rl_vis_botlin;
extern int _rl_last_c_pos;
extern int _rl_suppress_redisplay;
extern const char *rl_display_prompt;
extern char *rl_display_prompt;
/* isearch.c */
extern char *_rl_isearch_terminators;
@ -261,16 +262,16 @@ extern procenv_t readline_top_level;
/* terminal.c */
extern int _rl_enable_keypad;
extern int _rl_enable_meta;
extern const char *_rl_term_clreol;
extern const char *_rl_term_clrpag;
extern const char *_rl_term_im;
extern const char *_rl_term_ic;
extern const char *_rl_term_ei;
extern const char *_rl_term_DC;
extern const char *_rl_term_up;
extern const char *_rl_term_dc;
extern const char *_rl_term_cr;
extern const char *_rl_term_IC;
extern char *_rl_term_clreol;
extern char *_rl_term_clrpag;
extern char *_rl_term_im;
extern char *_rl_term_ic;
extern char *_rl_term_ei;
extern char *_rl_term_DC;
extern char *_rl_term_up;
extern char *_rl_term_dc;
extern char *_rl_term_cr;
extern char *_rl_term_IC;
extern int _rl_screenheight;
extern int _rl_screenwidth;
extern int _rl_screenchars;
@ -281,4 +282,7 @@ extern int _rl_term_autowrap;
extern int _rl_doing_an_undo;
extern int _rl_undo_group_level;
/* vi_mode.c */
extern int _rl_vi_last_command;
#endif /* _RL_PRIVATE_H_ */

View File

@ -37,7 +37,7 @@
#endif
#ifndef __attribute__
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8)
# define __attribute__(x)
# endif
#endif

View File

@ -184,6 +184,8 @@ static int set_tty_settings PARAMS((int, TIOTYPE *));
static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
static void
save_tty_chars (tiop)
TIOTYPE *tiop;
@ -398,6 +400,9 @@ static int set_tty_settings PARAMS((int, TIOTYPE *));
static void prepare_terminal_settings PARAMS((int, TIOTYPE, TIOTYPE *));
static void set_special_char PARAMS((Keymap, TIOTYPE *, int, rl_command_func_t));
static void _rl_bind_tty_special_chars PARAMS((Keymap, TIOTYPE));
#if defined (FLUSHO)
# define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO)
#else
@ -650,7 +655,10 @@ rl_prep_terminal (meta_flag)
otio = tio;
rl_tty_unset_default_bindings (_rl_keymap);
save_tty_chars (&otio);
RL_SETSTATE(RL_STATE_TTYCSAVED);
_rl_bind_tty_special_chars (_rl_keymap, tio);
prepare_terminal_settings (meta_flag, otio, &tio);
@ -709,7 +717,7 @@ rl_deprep_terminal ()
int
rl_restart_output (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
int fildes = fileno (rl_outstream);
#if defined (TIOCSTART)
@ -742,7 +750,7 @@ rl_restart_output (count, key)
int
rl_stop_output (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
int fildes = fileno (rl_instream);
@ -774,6 +782,83 @@ rl_stop_output (count, key)
/* */
/* **************************************************************** */
#define SET_SPECIAL(sc, func) set_special_char(kmap, &ttybuff, sc, func)
#if defined (NEW_TTY_DRIVER)
static void
set_special_char (kmap, tiop, sc, func)
Keymap kmap;
TIOTYPE *tiop;
int sc;
rl_command_func_t *func;
{
if (sc != -1 && kmap[(unsigned char)sc].type == ISFUNC)
kmap[(unsigned char)sc].function = func;
}
#define RESET_SPECIAL(c) \
if (c != -1 && kmap[(unsigned char)c].type == ISFUNC)
kmap[(unsigned char)c].function = rl_insert;
static void
_rl_bind_tty_special_chars (kmap, ttybuff)
Keymap kmap;
TIOTYPE ttybuff;
{
if (ttybuff.flags & SGTTY_SET)
{
SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
}
# if defined (TIOCGLTC)
if (ttybuff.flags & LTCHARS_SET)
{
SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
}
# endif /* TIOCGLTC */
}
#else /* !NEW_TTY_DRIVER */
static void
set_special_char (kmap, tiop, sc, func)
Keymap kmap;
TIOTYPE *tiop;
int sc;
rl_command_func_t *func;
{
unsigned char uc;
uc = tiop->c_cc[sc];
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC)
kmap[uc].function = func;
}
/* used later */
#define RESET_SPECIAL(uc) \
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
kmap[uc].function = rl_insert;
static void
_rl_bind_tty_special_chars (kmap, ttybuff)
Keymap kmap;
TIOTYPE ttybuff;
{
SET_SPECIAL (VERASE, rl_rubout);
SET_SPECIAL (VKILL, rl_unix_line_discard);
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
SET_SPECIAL (VLNEXT, rl_quoted_insert);
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
SET_SPECIAL (VWERASE, rl_unix_word_rubout);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
}
#endif /* !NEW_TTY_DRIVER */
/* Set the system's default editing characters to their readline equivalents
in KMAP. Should be static, now that we have rl_tty_set_default_bindings. */
void
@ -781,63 +866,13 @@ rltty_set_default_bindings (kmap)
Keymap kmap;
{
TIOTYPE ttybuff;
int tty = fileno (rl_instream);
int tty;
static int called = 0;
#if defined (NEW_TTY_DRIVER)
#define SET_SPECIAL(sc, func) \
do \
{ \
int ic; \
ic = sc; \
if (ic != -1 && kmap[(unsigned char)ic].type == ISFUNC) \
kmap[(unsigned char)ic].function = func; \
} \
while (0)
tty = fileno (rl_instream);
if (get_tty_settings (tty, &ttybuff) == 0)
{
if (ttybuff.flags & SGTTY_SET)
{
SET_SPECIAL (ttybuff.sgttyb.sg_erase, rl_rubout);
SET_SPECIAL (ttybuff.sgttyb.sg_kill, rl_unix_line_discard);
}
# if defined (TIOCGLTC)
if (ttybuff.flags & LTCHARS_SET)
{
SET_SPECIAL (ttybuff.ltchars.t_werasc, rl_unix_word_rubout);
SET_SPECIAL (ttybuff.ltchars.t_lnextc, rl_quoted_insert);
}
# endif /* TIOCGLTC */
}
#else /* !NEW_TTY_DRIVER */
#define SET_SPECIAL(sc, func) \
do \
{ \
unsigned char uc; \
uc = ttybuff.c_cc[sc]; \
if (uc != (unsigned char)_POSIX_VDISABLE && kmap[uc].type == ISFUNC) \
kmap[uc].function = func; \
} \
while (0)
if (get_tty_settings (tty, &ttybuff) == 0)
{
SET_SPECIAL (VERASE, rl_rubout);
SET_SPECIAL (VKILL, rl_unix_line_discard);
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
SET_SPECIAL (VLNEXT, rl_quoted_insert);
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
SET_SPECIAL (VWERASE, rl_unix_word_rubout);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
}
#endif /* !NEW_TTY_DRIVER */
_rl_bind_tty_special_chars (kmap, ttybuff);
}
/* New public way to set the system default editing chars to their readline
@ -849,6 +884,30 @@ rl_tty_set_default_bindings (kmap)
rltty_set_default_bindings (kmap);
}
/* Rebind all of the tty special chars that readline worries about back
to self-insert. Call this before saving the current terminal special
chars with save_tty_chars(). This only works on POSIX termios or termio
systems. */
void
rl_tty_unset_default_bindings (kmap)
Keymap kmap;
{
/* Don't bother before we've saved the tty special chars at least once. */
if (RL_ISSTATE(RL_STATE_TTYCSAVED) == 0)
return;
RESET_SPECIAL (_rl_tty_chars.t_erase);
RESET_SPECIAL (_rl_tty_chars.t_kill);
# if defined (VLNEXT) && defined (TERMIOS_TTY_DRIVER)
RESET_SPECIAL (_rl_tty_chars.t_lnext);
# endif /* VLNEXT && TERMIOS_TTY_DRIVER */
# if defined (VWERASE) && defined (TERMIOS_TTY_DRIVER)
RESET_SPECIAL (_rl_tty_chars.t_werase);
# endif /* VWERASE && TERMIOS_TTY_DRIVER */
}
#if defined (HANDLE_SIGNALS)
#if defined (NEW_TTY_DRIVER)

View File

@ -61,22 +61,22 @@
#endif /* !NEW_TTY_DRIVER && !_POSIX_VDISABLE */
typedef struct _rl_tty_chars {
char t_eof;
char t_eol;
char t_eol2;
char t_erase;
char t_werase;
char t_kill;
char t_reprint;
char t_intr;
char t_quit;
char t_susp;
char t_dsusp;
char t_start;
char t_stop;
char t_lnext;
char t_flush;
char t_status;
unsigned char t_eof;
unsigned char t_eol;
unsigned char t_eol2;
unsigned char t_erase;
unsigned char t_werase;
unsigned char t_kill;
unsigned char t_reprint;
unsigned char t_intr;
unsigned char t_quit;
unsigned char t_susp;
unsigned char t_dsusp;
unsigned char t_start;
unsigned char t_stop;
unsigned char t_lnext;
unsigned char t_flush;
unsigned char t_status;
} _RL_TTY_CHARS;
#endif /* _RLTTY_H_ */

View File

@ -1,6 +1,6 @@
/* rltypedefs.h -- Type declarations for readline functions. */
/* Copyright (C) 2000 Free Software Foundation, Inc.
/* Copyright (C) 2000-2004 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
@ -79,6 +79,12 @@ typedef void rl_voidfunc_t PARAMS((void));
typedef void rl_vintfunc_t PARAMS((int));
typedef void rl_vcpfunc_t PARAMS((char *));
typedef void rl_vcppfunc_t PARAMS((char **));
typedef char *rl_cpvfunc_t PARAMS((void));
typedef char *rl_cpifunc_t PARAMS((int));
typedef char *rl_cpcpfunc_t PARAMS((char *));
typedef char *rl_cpcppfunc_t PARAMS((char **));
#endif /* _RL_FUNCTION_TYPEDEF */
#ifdef __cplusplus

View File

@ -0,0 +1,38 @@
/* savestring.c */
/* Copyright (C) 1998,2003 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
The GNU Readline Library is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2, or
(at your option) any later version.
The GNU Readline Library is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty
of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
The GNU General Public License is often shipped with GNU software, and
is generally kept in a file called COPYING or LICENSE. If you do not
have a copy of the license, write to the Free Software Foundation,
59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#include "xmalloc.h"
/* Backwards compatibility, now that savestring has been removed from
all `public' readline header files. */
char *
savestring (s)
const char *s;
{
return ((char *)strcpy ((char *)xmalloc (1 + strlen (s)), (s)));
}

View File

@ -80,8 +80,13 @@ static void
make_history_line_current (entry)
HIST_ENTRY *entry;
{
rl_replace_line (entry->line, 0);
#if 0
rl_replace_line (entry->line, 1);
rl_undo_list = (UNDO_LIST *)entry->data;
#else
_rl_replace_text (entry->line, 0, rl_end);
_rl_fix_point (1);
#endif
if (_rl_saved_line_for_history)
_rl_free_history_entry (_rl_saved_line_for_history);
@ -187,6 +192,11 @@ noninc_search (dir, pchar)
saved_point = rl_point;
saved_mark = rl_mark;
/* Clear the undo list, since reading the search string should create its
own undo list, and the whole list will end up being freed when we
finish reading the search string. */
rl_undo_list = 0;
/* Use the line buffer to read the search string. */
rl_line_buffer[0] = 0;
rl_end = rl_point = 0;
@ -294,7 +304,7 @@ noninc_search (dir, pchar)
code calls this, KEY will be `?'. */
int
rl_noninc_forward_search (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
noninc_search (1, (key == '?') ? '?' : 0);
return 0;
@ -304,7 +314,7 @@ rl_noninc_forward_search (count, key)
calls this, KEY will be `/'. */
int
rl_noninc_reverse_search (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
noninc_search (-1, (key == '/') ? '/' : 0);
return 0;
@ -314,7 +324,7 @@ rl_noninc_reverse_search (count, key)
for. If there is no saved search string, abort. */
int
rl_noninc_forward_search_again (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
if (!noninc_search_string)
{
@ -329,7 +339,7 @@ rl_noninc_forward_search_again (count, key)
for. If there is no saved search string, abort. */
int
rl_noninc_reverse_search_again (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
if (!noninc_search_string)
{

View File

@ -124,6 +124,7 @@ sh_set_lines_and_columns (lines, cols)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);
sprintf (b, "LINES=%d", lines);
putenv (b);
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("COLUMNS=") + 1);
sprintf (b, "COLUMNS=%d", cols);
putenv (b);
@ -132,9 +133,12 @@ sh_set_lines_and_columns (lines, cols)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
sprintf (b, "%d", lines);
setenv ("LINES", b, 1);
free (b);
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
sprintf (b, "%d", cols);
setenv ("COLUMNS", b, 1);
free (b);
# endif /* HAVE_SETENV */
#endif /* !HAVE_PUTENV */
}

View File

@ -71,6 +71,10 @@ typedef struct { SigHandler *sa_handler; int sa_mask, sa_flags; } sighandler_cxt
# define sigemptyset(m)
#endif /* !HAVE_POSIX_SIGNALS */
#ifndef SA_RESTART
# define SA_RESTART 0
#endif
static SigHandler *rl_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
static void rl_maybe_set_sighandler PARAMS((int, SigHandler *, sighandler_cxt *));
@ -83,6 +87,8 @@ int rl_catch_signals = 1;
/* If non-zero, readline will install a signal handler for SIGWINCH. */
#ifdef SIGWINCH
int rl_catch_sigwinch = 1;
#else
int rl_catch_sigwinch = 0; /* for the readline state struct in readline.c */
#endif
static int signals_set_flag;
@ -231,7 +237,7 @@ rl_set_sighandler (sig, handler, ohandler)
struct sigaction act;
act.sa_handler = handler;
act.sa_flags = 0; /* XXX - should we set SA_RESTART for SIGWINCH? */
act.sa_flags = (sig == SIGWINCH) ? SA_RESTART : 0;
sigemptyset (&act.sa_mask);
sigemptyset (&ohandler->sa_mask);
sigaction (sig, &act, &old_handler);

View File

@ -82,41 +82,40 @@ static int tcap_initialized;
# if defined (__EMX__) || defined (NEED_EXTERN_PC)
extern
# endif /* __EMX__ || NEED_EXTERN_PC */
char PC;
char *BC, *UP;
char PC, *BC, *UP;
#endif /* __linux__ */
/* Some strings to control terminal actions. These are output by tputs (). */
const char *_rl_term_clreol;
const char *_rl_term_clrpag;
const char *_rl_term_cr;
const char *_rl_term_backspace;
const char *_rl_term_goto;
const char *_rl_term_pc;
char *_rl_term_clreol;
char *_rl_term_clrpag;
char *_rl_term_cr;
char *_rl_term_backspace;
char *_rl_term_goto;
char *_rl_term_pc;
/* Non-zero if we determine that the terminal can do character insertion. */
int _rl_terminal_can_insert = 0;
/* How to insert characters. */
const char *_rl_term_im;
const char *_rl_term_ei;
const char *_rl_term_ic;
const char *_rl_term_ip;
const char *_rl_term_IC;
char *_rl_term_im;
char *_rl_term_ei;
char *_rl_term_ic;
char *_rl_term_ip;
char *_rl_term_IC;
/* How to delete characters. */
const char *_rl_term_dc;
const char *_rl_term_DC;
char *_rl_term_dc;
char *_rl_term_DC;
#if defined (HACK_TERMCAP_MOTION)
char *_rl_term_forward_char;
#endif /* HACK_TERMCAP_MOTION */
/* How to go up a line. */
const char *_rl_term_up;
char *_rl_term_up;
/* A visible bell; char if the terminal can be made to flash the screen. */
static const char *_rl_visible_bell;
static char *_rl_visible_bell;
/* Non-zero means the terminal can auto-wrap lines. */
int _rl_term_autowrap;
@ -126,30 +125,30 @@ static int term_has_meta;
/* The sequences to write to turn on and off the meta key, if this
terminal has one. */
static const char *_rl_term_mm;
static const char *_rl_term_mo;
static char *_rl_term_mm;
static char *_rl_term_mo;
/* The key sequences output by the arrow keys, if this terminal has any. */
static const char *_rl_term_ku;
static const char *_rl_term_kd;
static const char *_rl_term_kr;
static const char *_rl_term_kl;
static char *_rl_term_ku;
static char *_rl_term_kd;
static char *_rl_term_kr;
static char *_rl_term_kl;
/* How to initialize and reset the arrow keys, if this terminal has any. */
static const char *_rl_term_ks;
static const char *_rl_term_ke;
static char *_rl_term_ks;
static char *_rl_term_ke;
/* The key sequences sent by the Home and End keys, if any. */
static const char *_rl_term_kh;
static const char *_rl_term_kH;
static const char *_rl_term_at7; /* @7 */
static char *_rl_term_kh;
static char *_rl_term_kH;
static char *_rl_term_at7; /* @7 */
/* Insert key */
static const char *_rl_term_kI;
static char *_rl_term_kI;
/* Cursor control */
static const char *_rl_term_vs; /* very visible */
static const char *_rl_term_ve; /* normal */
static char *_rl_term_vs; /* very visible */
static char *_rl_term_ve; /* normal */
static void bind_termcap_arrow_keys PARAMS((Keymap));
@ -295,7 +294,7 @@ rl_resize_terminal ()
struct _tc_string {
const char *tc_var;
const char **tc_value;
char **tc_value;
};
/* This should be kept sorted, just in case we decide to change the
@ -343,14 +342,10 @@ get_term_capabilities (bp)
char **bp;
{
#if !defined (__DJGPP__) /* XXX - doesn't DJGPP have a termcap library? */
register unsigned int i;
register int i;
for (i = 0; i < NUM_TC_STRINGS; i++)
# if defined(__LCC__) || defined(__MWERKS__)
*(tc_strings[i].tc_value) = tgetstr ((char *)tc_strings[i].tc_var, bp);
# else
*(tc_strings[i].tc_value) = tgetstr (tc_strings[i].tc_var, bp);
# endif
#endif
tcap_initialized = 1;
}
@ -432,8 +427,8 @@ _rl_init_terminal_io (terminal_name)
tgoto if _rl_term_IC or _rl_term_DC is defined, but just in case we
change that later... */
PC = '\0';
BC = (char*)(_rl_term_backspace = "\b");
UP = (char*)_rl_term_up;
BC = _rl_term_backspace = "\b";
UP = _rl_term_up;
return 0;
}
@ -443,8 +438,8 @@ _rl_init_terminal_io (terminal_name)
/* Set up the variables that the termcap library expects the application
to provide. */
PC = _rl_term_pc ? *_rl_term_pc : 0;
BC = (char*)_rl_term_backspace;
UP = (char*)_rl_term_up;
BC = _rl_term_backspace;
UP = _rl_term_up;
if (!_rl_term_cr)
_rl_term_cr = "\r";
@ -488,22 +483,22 @@ bind_termcap_arrow_keys (map)
xkeymap = _rl_keymap;
_rl_keymap = map;
_rl_bind_if_unbound (_rl_term_ku, rl_get_previous_history);
_rl_bind_if_unbound (_rl_term_kd, rl_get_next_history);
_rl_bind_if_unbound (_rl_term_kr, rl_forward);
_rl_bind_if_unbound (_rl_term_kl, rl_backward);
rl_bind_keyseq_if_unbound (_rl_term_ku, rl_get_previous_history);
rl_bind_keyseq_if_unbound (_rl_term_kd, rl_get_next_history);
rl_bind_keyseq_if_unbound (_rl_term_kr, rl_forward_char);
rl_bind_keyseq_if_unbound (_rl_term_kl, rl_backward_char);
_rl_bind_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
_rl_bind_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
rl_bind_keyseq_if_unbound (_rl_term_kh, rl_beg_of_line); /* Home */
rl_bind_keyseq_if_unbound (_rl_term_at7, rl_end_of_line); /* End */
_rl_keymap = xkeymap;
}
const char *
char *
rl_get_termcap (cap)
const char *cap;
{
register unsigned int i;
register int i;
if (tcap_initialized == 0)
return ((char *)NULL);

View File

@ -1,6 +1,6 @@
/* text.c -- text handling commands for readline. */
/* Copyright (C) 1987-2002 Free Software Foundation, Inc.
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
@ -168,6 +168,9 @@ _rl_fix_point (fix_mark_too)
}
#undef _RL_FIX_POINT
/* Replace the contents of the line buffer between START and END with
TEXT. The operation is undoable. To replace the entire line in an
undoable mode, use _rl_replace_text(text, 0, rl_end); */
int
_rl_replace_text (text, start, end)
const char *text;
@ -400,7 +403,7 @@ rl_backward (count, key)
/* Move to the beginning of the line. */
int
rl_beg_of_line (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
rl_point = 0;
return 0;
@ -409,7 +412,7 @@ rl_beg_of_line (count, key)
/* Move to the end of the line. */
int
rl_end_of_line (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
rl_point = rl_end;
return 0;
@ -506,7 +509,7 @@ rl_backward_word (count, key)
/* Clear the current line. Numeric argument to C-l does this. */
int
rl_refresh_line (ignore1, ignore2)
int ignore1 __attribute__((unused)), ignore2 __attribute__((unused));
int ignore1, ignore2;
{
int curr_line;
@ -545,7 +548,7 @@ rl_clear_screen (count, key)
int
rl_arrow_keys (count, c)
int count, c __attribute__((unused));
int count, c;
{
int ch;
@ -799,13 +802,10 @@ _rl_overwrite_char (count, c)
k = _rl_read_mbstring (c, mbkey, MB_LEN_MAX);
#endif
rl_begin_undo_group ();
for (i = 0; i < count; i++)
{
rl_begin_undo_group ();
if (rl_point < rl_end)
rl_delete (1, c);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_insert_text (mbkey);
@ -813,9 +813,12 @@ _rl_overwrite_char (count, c)
#endif
_rl_insert_char (1, c);
rl_end_undo_group ();
if (rl_point < rl_end)
rl_delete (1, c);
}
rl_end_undo_group ();
return 0;
}
@ -830,7 +833,7 @@ rl_insert (count, c)
/* Insert the next typed character verbatim. */
int
rl_quoted_insert (count, key)
int count, key __attribute__((unused));
int count, key;
{
int c;
@ -852,7 +855,7 @@ rl_quoted_insert (count, key)
/* Insert a tab character. */
int
rl_tab_insert (count, key)
int count, key __attribute__((unused));
int count, key;
{
return (_rl_insert_char (count, '\t'));
}
@ -862,7 +865,7 @@ rl_tab_insert (count, key)
meaning in the future. */
int
rl_newline (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
rl_done = 1;
@ -875,7 +878,8 @@ rl_newline (count, key)
if (rl_editing_mode == vi_mode)
{
_rl_vi_done_inserting ();
_rl_vi_reset_last ();
if (_rl_vi_textmod_command (_rl_vi_last_command) == 0) /* XXX */
_rl_vi_reset_last ();
}
#endif /* VI_MODE */
@ -895,7 +899,7 @@ rl_newline (count, key)
is special cased. */
int
rl_do_lowercase_version (ignore1, ignore2)
int ignore1 __attribute__((unused)), ignore2 __attribute__((unused));
int ignore1, ignore2;
{
return 0;
}
@ -933,9 +937,12 @@ _rl_overwrite_rubout (count, key)
rl_delete_text (opoint, rl_point);
/* Emacs puts point at the beginning of the sequence of spaces. */
opoint = rl_point;
_rl_insert_char (l, ' ');
rl_point = opoint;
if (rl_point < rl_end)
{
opoint = rl_point;
_rl_insert_char (l, ' ');
rl_point = opoint;
}
rl_end_undo_group ();
@ -1087,7 +1094,7 @@ rl_rubout_or_delete (count, key)
/* Delete all spaces and tabs around point. */
int
rl_delete_horizontal_space (count, ignore)
int count __attribute__((unused)), ignore __attribute__((unused));
int count, ignore;
{
int start = rl_point;
@ -1128,9 +1135,9 @@ rl_delete_or_show_completions (count, key)
A K*rn shell style function. */
int
rl_insert_comment (count, key)
int count __attribute__((unused)), key;
int count, key;
{
const char *rl_comment_text;
char *rl_comment_text;
int rl_comment_len;
rl_beg_of_line (1, key);
@ -1167,7 +1174,7 @@ rl_insert_comment (count, key)
/* Uppercase the word at point. */
int
rl_upcase_word (count, key)
int count, key __attribute__((unused));
int count, key;
{
return (rl_change_case (count, UpCase));
}
@ -1175,7 +1182,7 @@ rl_upcase_word (count, key)
/* Lowercase the word at point. */
int
rl_downcase_word (count, key)
int count, key __attribute__((unused));
int count, key;
{
return (rl_change_case (count, DownCase));
}
@ -1183,7 +1190,7 @@ rl_downcase_word (count, key)
/* Upcase the first letter, downcase the rest. */
int
rl_capitalize_word (count, key)
int count, key __attribute__((unused));
int count, key;
{
return (rl_change_case (count, CapCase));
}
@ -1308,7 +1315,7 @@ rl_transpose_words (count, key)
then transpose the characters before point. */
int
rl_transpose_chars (count, key)
int count, key __attribute__((unused));
int count, key;
{
#if defined (HANDLE_MULTIBYTE)
char *dummy;
@ -1480,14 +1487,14 @@ _rl_char_search (count, fdir, bdir)
int
rl_char_search (count, key)
int count, key __attribute__((unused));
int count, key;
{
return (_rl_char_search (count, FFIND, BFIND));
}
int
rl_backward_char_search (count, key)
int count, key __attribute__((unused));
int count, key;
{
return (_rl_char_search (count, BFIND, FFIND));
}
@ -1513,7 +1520,7 @@ _rl_set_mark_at_pos (position)
/* A bindable command to set the mark. */
int
rl_set_mark (count, key)
int count, key __attribute__((unused));
int count, key;
{
return (_rl_set_mark_at_pos (rl_explicit_arg ? count : rl_point));
}
@ -1521,7 +1528,7 @@ rl_set_mark (count, key)
/* Exchange the position of mark and point. */
int
rl_exchange_point_and_mark (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
if (rl_mark > rl_end)
rl_mark = -1;

View File

@ -19,6 +19,8 @@
along with Readline; see the file COPYING. If not, write to the Free
Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */
#define READLINE_LIBRARY
#include "config_readline.h"
#if defined (HAVE_UNISTD_H)
@ -188,7 +190,7 @@ tilde_expand (string)
int result_size, result_index;
result_index = result_size = 0;
if ((result = strchr(string, '~')))
if (result = strchr (string, '~'))
result = (char *)xmalloc (result_size = (strlen (string) + 16));
else
result = (char *)xmalloc (result_size = (strlen (string) + 1));

View File

@ -169,8 +169,7 @@ rl_do_undo ()
int
_rl_fix_last_undo_of_type (type, start, end)
unsigned int type;
int start, end;
int type, start, end;
{
UNDO_LIST *rl;
@ -228,7 +227,7 @@ rl_modifying (start, end)
/* Revert the current line to its previous state. */
int
rl_revert_line (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
if (!rl_undo_list)
rl_ding ();
@ -243,7 +242,7 @@ rl_revert_line (count, key)
/* Do some undoing of things that were done. */
int
rl_undo_command (count, key)
int count, key __attribute__((unused));
int count, key;
{
if (count < 0)
return 0; /* Nothing to do. */

View File

@ -96,14 +96,14 @@ _rl_abort_internal ()
int
rl_abort (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
return (_rl_abort_internal ());
}
int
rl_tty_status (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
#if defined (TIOCSTAT)
ioctl (1, TIOCSTAT, (char *)0);
@ -153,7 +153,7 @@ rl_extend_line_buffer (len)
/* A function for simple tilde expansion. */
int
rl_tilde_expand (ignore, key)
int ignore __attribute__((unused)), key __attribute__((unused));
int ignore, key;
{
register int start, end;
char *homedir, *temp;
@ -248,7 +248,7 @@ _rl_strpbrk (string1, string2)
{
v = _rl_get_char_len (string1, &ps);
if (v > 1)
string += v - 1; /* -1 to account for auto-increment in loop */
string1 += v - 1; /* -1 to account for auto-increment in loop */
}
#endif
}

View File

@ -1,7 +1,7 @@
/* vi_mode.c -- A vi emulation mode for Bash.
Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
/* Copyright (C) 1987, 1989, 1992 Free Software Foundation, Inc.
/* Copyright (C) 1987-2004 Free Software Foundation, Inc.
This file is part of the GNU Readline Library, a library for
reading lines of text with interactive input and history editing.
@ -61,6 +61,8 @@
#define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0)
#endif
int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
/* Non-zero means enter insertion mode. */
static int _rl_vi_doing_insert;
@ -81,7 +83,6 @@ static int vi_continued_command;
static char *vi_insert_buffer;
static int vi_insert_buffer_size;
static int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
static int _rl_vi_last_repeat = 1;
static int _rl_vi_last_arg_sign = 1;
static int _rl_vi_last_motion;
@ -109,7 +110,7 @@ static int rl_digit_loop1 PARAMS((void));
void
_rl_vi_initialize_line ()
{
register unsigned int i;
register int i;
for (i = 0; i < sizeof (vi_mark_chars) / sizeof (int); i++)
vi_mark_chars[i] = -1;
@ -133,6 +134,16 @@ _rl_vi_set_last (key, repeat, sign)
_rl_vi_last_arg_sign = sign;
}
/* A convenience function that calls _rl_vi_set_last to save the last command
information and enters insertion mode. */
void
rl_vi_start_inserting (key, repeat, sign)
int key, repeat, sign;
{
_rl_vi_set_last (key, repeat, sign);
rl_vi_insertion_mode (1, key);
}
/* Is the command C a VI mode text modification command? */
int
_rl_vi_textmod_command (c)
@ -156,7 +167,7 @@ _rl_vi_stuff_insert (count)
puts you back into insert mode. */
int
rl_vi_redo (count, c)
int count, c __attribute__((unused));
int count, c;
{
int r;
@ -195,7 +206,7 @@ rl_vi_undo (count, key)
/* Yank the nth arg from the previous line into this line at point. */
int
rl_vi_yank_arg (count, key)
int count, key __attribute__((unused));
int count, key;
{
/* Readline thinks that the first word on a line is the 0th, while vi
thinks the first word on a line is the 1st. Compensate. */
@ -276,7 +287,7 @@ rl_vi_search (count, key)
/* Completion, from vi's point of view. */
int
rl_vi_complete (ignore, key)
int ignore __attribute__((unused)), key;
int ignore, key;
{
if ((rl_point < rl_end) && (!whitespace (rl_line_buffer[rl_point])))
{
@ -295,21 +306,18 @@ rl_vi_complete (ignore, key)
rl_complete (0, key);
if (key == '*' || key == '\\')
{
_rl_vi_set_last (key, 1, rl_arg_sign);
rl_vi_insertion_mode (1, key);
}
rl_vi_start_inserting (key, 1, rl_arg_sign);
return (0);
}
/* Tilde expansion for vi mode. */
int
rl_vi_tilde_expand (ignore, key)
int ignore __attribute__((unused)), key;
int ignore, key;
{
rl_tilde_expand (0, key);
_rl_vi_set_last (key, 1, rl_arg_sign); /* XXX */
rl_vi_insertion_mode (1, key);
rl_vi_start_inserting (key, 1, rl_arg_sign);
return (0);
}
@ -377,7 +385,7 @@ rl_vi_end_word (count, key)
/* Move forward a word the way that 'W' does. */
int
rl_vi_fWord (count, ignore)
int count, ignore __attribute__((unused));
int count, ignore;
{
while (count-- && rl_point < (rl_end - 1))
{
@ -394,7 +402,7 @@ rl_vi_fWord (count, ignore)
int
rl_vi_bWord (count, ignore)
int count, ignore __attribute__((unused));
int count, ignore;
{
while (count-- && rl_point > 0)
{
@ -418,7 +426,7 @@ rl_vi_bWord (count, ignore)
int
rl_vi_eWord (count, ignore)
int count, ignore __attribute__((unused));
int count, ignore;
{
while (count-- && rl_point < (rl_end - 1))
{
@ -427,7 +435,8 @@ rl_vi_eWord (count, ignore)
/* Move to the next non-whitespace character (to the start of the
next word). */
while (++rl_point < rl_end && whitespace (rl_line_buffer[rl_point]));
while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
rl_point++;
if (rl_point && rl_point < rl_end)
{
@ -448,7 +457,7 @@ rl_vi_eWord (count, ignore)
int
rl_vi_fword (count, ignore)
int count, ignore __attribute__((unused));
int count, ignore;
{
while (count-- && rl_point < (rl_end - 1))
{
@ -474,7 +483,7 @@ rl_vi_fword (count, ignore)
int
rl_vi_bword (count, ignore)
int count, ignore __attribute__((unused));
int count, ignore;
{
while (count-- && rl_point > 0)
{
@ -513,7 +522,7 @@ rl_vi_bword (count, ignore)
int
rl_vi_eword (count, ignore)
int count, ignore __attribute__((unused));
int count, ignore;
{
while (count-- && rl_point < rl_end - 1)
{
@ -538,7 +547,7 @@ rl_vi_eword (count, ignore)
int
rl_vi_insert_beg (count, key)
int count __attribute__((unused)), key;
int count, key;
{
rl_beg_of_line (1, key);
rl_vi_insertion_mode (1, key);
@ -547,7 +556,7 @@ rl_vi_insert_beg (count, key)
int
rl_vi_append_mode (count, key)
int count __attribute__((unused)), key;
int count, key;
{
if (rl_point < rl_end)
{
@ -567,7 +576,7 @@ rl_vi_append_mode (count, key)
int
rl_vi_append_eol (count, key)
int count __attribute__((unused)), key;
int count, key;
{
rl_end_of_line (1, key);
rl_vi_append_mode (1, key);
@ -577,7 +586,7 @@ rl_vi_append_eol (count, key)
/* What to do in the case of C-d. */
int
rl_vi_eof_maybe (count, c)
int count __attribute__((unused)), c __attribute__((unused));
int count, c;
{
return (rl_newline (1, '\n'));
}
@ -588,7 +597,7 @@ rl_vi_eof_maybe (count, c)
switching keymaps. */
int
rl_vi_insertion_mode (count, key)
int count __attribute__((unused)), key;
int count, key;
{
_rl_keymap = vi_insertion_keymap;
_rl_vi_last_key_before_insert = key;
@ -638,7 +647,7 @@ _rl_vi_done_inserting ()
}
else
{
if (_rl_vi_last_key_before_insert == 'i' && rl_undo_list)
if ((_rl_vi_last_key_before_insert == 'i' || _rl_vi_last_key_before_insert == 'a') && rl_undo_list)
_rl_vi_save_insert (rl_undo_list);
/* XXX - Other keys probably need to be checked. */
else if (_rl_vi_last_key_before_insert == 'C')
@ -651,7 +660,7 @@ _rl_vi_done_inserting ()
int
rl_vi_movement_mode (count, key)
int count __attribute__((unused)), key;
int count, key;
{
if (rl_point > 0)
rl_backward_char (1, key);
@ -678,7 +687,8 @@ _rl_vi_change_mbchar_case (count)
int count;
{
wchar_t wc;
char mb[MB_LEN_MAX];
char mb[MB_LEN_MAX+1];
int mblen;
mbstate_t ps;
memset (&ps, 0, sizeof (mbstate_t));
@ -701,7 +711,9 @@ _rl_vi_change_mbchar_case (count)
/* Vi is kind of strange here. */
if (wc)
{
wctomb (mb, wc);
mblen = wcrtomb (mb, wc, &ps);
if (mblen >= 0)
mb[mblen] = '\0';
rl_begin_undo_group ();
rl_delete (1, 0);
rl_insert_text (mb);
@ -718,14 +730,15 @@ _rl_vi_change_mbchar_case (count)
int
rl_vi_change_case (count, ignore)
int count, ignore __attribute__((unused));
int count, ignore;
{
char c = 0;
int c, p;
/* Don't try this on an empty line. */
if (rl_point >= rl_end)
return (0);
c = 0;
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
return (_rl_vi_change_mbchar_case (count));
@ -747,8 +760,11 @@ rl_vi_change_case (count, ignore)
/* Vi is kind of strange here. */
if (c)
{
p = rl_point;
rl_begin_undo_group ();
rl_delete (1, c);
rl_vi_delete (1, c);
if (rl_point < p) /* Did we retreat at EOL? */
rl_point++;
_rl_insert_char (1, c);
rl_end_undo_group ();
rl_vi_check ();
@ -761,12 +777,14 @@ rl_vi_change_case (count, ignore)
int
rl_vi_put (count, key)
int count __attribute__((unused)), key;
int count, key;
{
if (!_rl_uppercase_p (key) && (rl_point + 1 <= rl_end))
rl_point = _rl_find_next_mbchar (rl_line_buffer, rl_point, 1, MB_FIND_NONZERO);
rl_yank (1, key);
while (count--)
rl_yank (1, key);
rl_backward_char (1, key);
return (0);
}
@ -814,6 +832,7 @@ rl_vi_domove (key, nextkey)
{
save = rl_numeric_arg;
rl_numeric_arg = _rl_digit_value (c);
rl_explicit_arg = 1;
rl_digit_loop1 ();
rl_numeric_arg *= save;
RL_SETSTATE(RL_STATE_MOREINPUT);
@ -941,7 +960,7 @@ rl_digit_loop1 ()
int
rl_vi_delete_to (count, key)
int count __attribute__((unused)), key;
int count, key;
{
int c;
@ -1012,8 +1031,7 @@ rl_vi_change_to (count, key)
/* `C' does not save the text inserted for undoing or redoing. */
if (_rl_uppercase_p (key) == 0)
_rl_vi_doing_insert = 1;
_rl_vi_set_last (key, count, rl_arg_sign);
rl_vi_insertion_mode (1, key);
rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign);
}
return (0);
@ -1021,7 +1039,7 @@ rl_vi_change_to (count, key)
int
rl_vi_yank_to (count, key)
int count __attribute__((unused)), key;
int count, key;
{
int c, save = rl_point;
@ -1077,7 +1095,7 @@ rl_vi_delete (count, key)
int
rl_vi_back_to_indent (count, key)
int count __attribute__((unused)), key;
int count, key;
{
rl_beg_of_line (1, key);
while (rl_point < rl_end && whitespace (rl_line_buffer[rl_point]))
@ -1087,7 +1105,7 @@ rl_vi_back_to_indent (count, key)
int
rl_vi_first_print (count, key)
int count __attribute__((unused)), key;
int count, key;
{
return (rl_vi_back_to_indent (1, key));
}
@ -1156,7 +1174,7 @@ rl_vi_char_search (count, key)
/* Match brackets */
int
rl_vi_match (ignore, key)
int ignore __attribute__((unused)), key;
int ignore, key;
{
int count = 1, brack, pos, tmp, pre;
@ -1262,14 +1280,14 @@ rl_vi_bracktype (c)
/* XXX - think about reading an entire mbchar with _rl_read_mbchar and
inserting it in one bunch instead of the loop below (like in
rl_vi_char_search or _rl_vi_change_mbchar_case. Set c to mbchar[0]
rl_vi_char_search or _rl_vi_change_mbchar_case). Set c to mbchar[0]
for test against 033 or ^C. Make sure that _rl_read_mbchar does
this right. */
int
rl_vi_change_char (count, key)
int count, key __attribute__((unused));
int count, key;
{
int c;
int c, p;
if (vi_redoing)
c = _rl_vi_last_replacement;
@ -1283,11 +1301,11 @@ rl_vi_change_char (count, key)
if (c == '\033' || c == CTRL ('C'))
return -1;
rl_begin_undo_group ();
while (count-- && rl_point < rl_end)
{
rl_begin_undo_group ();
rl_delete (1, c);
p = rl_point;
rl_vi_delete (1, c);
#if defined (HANDLE_MULTIBYTE)
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
while (_rl_insert_char (1, c))
@ -1298,12 +1316,14 @@ rl_vi_change_char (count, key)
}
else
#endif
_rl_insert_char (1, c);
if (count == 0)
rl_backward_char (1, c);
rl_end_undo_group ();
{
if (rl_point < p) /* Did we retreat at EOL? */
rl_point++;
_rl_insert_char (1, c);
}
}
rl_end_undo_group ();
return (0);
}
@ -1313,7 +1333,7 @@ rl_vi_subst (count, key)
{
/* If we are redoing, rl_vi_change_to will stuff the last motion char */
if (vi_redoing == 0)
rl_stuff_char ((key == 'S') ? 'c' : ' '); /* `S' == `cc', `s' == `c ' */
rl_stuff_char ((key == 'S') ? 'c' : 'l'); /* `S' == `cc', `s' == `cl' */
return (rl_vi_change_to (count, 'c'));
}
@ -1370,7 +1390,7 @@ rl_vi_overstrike_delete (count, key)
int
rl_vi_replace (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
int i;
@ -1431,7 +1451,7 @@ rl_vi_possible_completions()
/* Functions to save and restore marks. */
int
rl_vi_set_mark (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
int ch;
@ -1451,7 +1471,7 @@ rl_vi_set_mark (count, key)
int
rl_vi_goto_mark (count, key)
int count __attribute__((unused)), key __attribute__((unused));
int count, key;
{
int ch;

View File

@ -1,7 +1,7 @@
dnl -*- ksh -*-
dnl Process this file with autoconf to produce a configure script.
AC_PREREQ(2.58)dnl Minimum Autoconf version required.
AC_PREREQ(2.57)dnl Minimum Autoconf version required.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
@ -13,7 +13,7 @@ AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
DOT_FRM_VERSION=6
# See the libtool docs for information on how to do shared lib versions.
SHARED_LIB_VERSION=14:0:0
SHARED_LIB_VERSION=15:0:0
# ndb version
NDB_VERSION_MAJOR=5
@ -1966,7 +1966,7 @@ AC_LANG_CPLUSPLUS
if test "$ac_cv_prog_gxx" = "yes" -a "$with_other_libc" = "no"
then
CXXFLAGS=`echo "$CXXFLAGS -Werror" | sed -e 's/-fbranch-probabilities//; s/-Wall//; s/-Wcheck//'`
CXXFLAGS=`echo "$CXXFLAGS -Werror" | sed -e 's/-fbranch-probabilities//; s/-Wall//; s/-ansi//; s/-pedantic//; s/-Wcheck//'`
fi
AC_TRY_COMPILE(
@ -2001,7 +2001,7 @@ AC_LANG_SAVE
AC_LANG_CPLUSPLUS
if test "$ac_cv_prog_gxx" = "yes" -a "$with_other_libc" = "no"
then
CXXFLAGS=`echo "$CXXFLAGS -Werror" | sed -e 's/-fbranch-probabilities//; s/-Wall//; s/-Wcheck//'`
CXXFLAGS=`echo "$CXXFLAGS -Werror" | sed -e 's/-fbranch-probabilities//; s/-Wall//; s/-ansi//; s/-pedantic//; s/-Wcheck//'`
fi
AC_TRY_COMPILE(
[#undef inline
@ -2034,7 +2034,7 @@ AC_LANG_SAVE
AC_LANG_CPLUSPLUS
if test "$ac_cv_prog_gxx" = "yes" -a "$with_other_libc" = "no"
then
CXXFLAGS=`echo "$CXXFLAGS -Werror" | sed -e 's/-fbranch-probabilities//; s/-Wall//; s/-Wcheck//'`
CXXFLAGS=`echo "$CXXFLAGS -Werror" | sed -e 's/-fbranch-probabilities//; s/-Wall//; s/-ansi//; s/-pedantic//; s/-Wcheck//'`
fi
AC_TRY_COMPILE(
[#undef inline

View File

@ -1,3 +1,4 @@
/* Copyright (C) 2000 MySQL AB
This program is free software; you can redistribute it and/or modify
@ -23,8 +24,10 @@
#include <my_global.h>
#include <my_sys.h>
#include <m_string.h>
#include <my_getopt.h>
const char *config_file="my"; /* Default config file */
uint verbose= 0, opt_defaults_file_used= 0;
const char *default_dbug_option="d:t:o,/tmp/my_print_defaults.trace";
@ -48,6 +51,10 @@ static struct my_option my_long_options[] =
"Read this file after the global /etc config file and before the config file in the users home directory.",
(gptr*) &defaults_extra_file, (gptr*) &defaults_extra_file, 0, GET_STR,
REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"defaults-group-suffix", 'g',
"In addition to the given groups, read also groups with this suffix",
(gptr*) &defaults_group_suffix, (gptr*) &defaults_group_suffix,
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"extra-file", 'e',
"Synonym for --defaults-extra-file.",
(gptr*) &defaults_extra_file, (gptr*) &defaults_extra_file, 0, GET_STR,
@ -127,37 +134,32 @@ static int get_options(int *argc,char ***argv)
return 0;
}
int main(int argc, char **argv)
{
int count, error;
char **load_default_groups, *tmp_arguments[3],
**argument, **arguments;
char *defaults, *extra_defaults;
int count, error, args_used;
char **load_default_groups, *tmp_arguments[6];
char **argument, **arguments, **org_argv;
char *defaults, *extra_defaults, *group_suffix;
MY_INIT(argv[0]);
get_defaults_files(argc, argv, &defaults, &extra_defaults);
org_argv= argv;
args_used= get_defaults_options(argc, argv, &defaults, &extra_defaults,
&group_suffix);
/*
** Check out the args
*/
if (!(load_default_groups=(char**) my_malloc((argc+2)*sizeof(char*),
/* Copy defaults-xxx arguments & program name */
count=args_used+1;
arguments= tmp_arguments;
memcpy((char*) arguments, (char*) org_argv, count * sizeof(*org_argv));
arguments[count]= 0;
/* Check out the args */
if (!(load_default_groups=(char**) my_malloc((argc+1)*sizeof(char*),
MYF(MY_WME))))
exit(1);
if (get_options(&argc,&argv))
exit(1);
for (count=0; *argv ; argv++,count++)
load_default_groups[count]= *argv;
load_default_groups[count]=0;
count=0;
arguments=tmp_arguments;
arguments[count++]=my_progname;
if (extra_defaults)
arguments[count++]= extra_defaults;
if (defaults)
arguments[count++]= defaults;
arguments[count]= 0;
memcpy((char*) load_default_groups, (char*) argv, (argc + 1) * sizeof(*argv));
if ((error= load_defaults(config_file, (const char **) load_default_groups,
&count, &arguments)))

View File

@ -175,7 +175,7 @@ register char **argv[];
case 'I':
case '?':
help=1; /* Help text written */
printf("%s Ver 1.3 for %s at %s\n",my_progname,SYSTEM_TYPE,
printf("%s Ver 1.4 for %s at %s\n",my_progname,SYSTEM_TYPE,
MACHINE_TYPE);
if (version)
break;
@ -1048,23 +1048,25 @@ FILE *in,*out;
}
static int convert_file(rep,name)
REPLACE *rep;
my_string name;
static int convert_file(REPLACE *rep, my_string name)
{
int error;
FILE *in,*out;
char dir_buff[FN_REFLEN],*tempname;
char dir_buff[FN_REFLEN], tempname[FN_REFLEN];
File temp_file;
DBUG_ENTER("convert_file");
if (!(in=my_fopen(name,O_RDONLY,MYF(MY_WME))))
DBUG_RETURN(1);
dirname_part(dir_buff,name);
tempname=my_tempnam(dir_buff,"PR",MYF(MY_WME));
if (!(out=my_fopen(tempname,(int) (O_WRONLY | O_CREAT),
MYF(MY_WME))))
if ((temp_file= create_temp_file(tempname, dir_buff, "PR", O_WRONLY,
MYF(MY_WME))) < 0)
{
my_fclose(in,MYF(0));
DBUG_RETURN(1);
}
if (!(out= my_fdopen(temp_file, tempname, O_WRONLY, MYF(MY_WME))))
{
(*free)(tempname);
my_fclose(in,MYF(0));
DBUG_RETURN(1);
}
@ -1076,7 +1078,6 @@ my_string name;
my_redel(name,tempname,MYF(MY_WME | MY_LINK_WARNING));
else
my_delete(tempname,MYF(MY_WME));
(*free)(tempname);
if (!silent && ! error)
{
if (updated)

View File

@ -353,6 +353,9 @@ inline double ulonglong2double(ulonglong value)
#ifndef DEFAULT_HOME_ENV
#define DEFAULT_HOME_ENV MYSQL_HOME
#endif
#ifndef DEFAULT_GROUP_SUFFIX_ENV
#define DEFAULT_GROUP_SUFFIX_ENV MYSQL_GROUP_SUFFIX
#endif
/* File name handling */

View File

@ -53,6 +53,7 @@ extern uint bitmap_get_first(const MY_BITMAP *map);
extern uint bitmap_get_first_set(const MY_BITMAP *map);
extern uint bitmap_bits_set(const MY_BITMAP *map);
extern void bitmap_free(MY_BITMAP *map);
extern void bitmap_set_above(MY_BITMAP *map, uint from_byte, uint use_bit);
extern void bitmap_set_prefix(MY_BITMAP *map, uint prefix_size);
extern void bitmap_intersect(MY_BITMAP *map, const MY_BITMAP *map2);
extern void bitmap_subtract(MY_BITMAP *map, const MY_BITMAP *map2);

View File

@ -263,7 +263,7 @@ extern my_bool NEAR my_disable_locking,NEAR my_disable_async_io,
extern char wild_many,wild_one,wild_prefix;
extern const char *charsets_dir;
extern char *defaults_extra_file;
extern const char *defaults_instance;
extern const char *defaults_group_suffix;
extern my_bool timed_mutexes;
@ -553,7 +553,6 @@ extern gptr my_once_alloc(uint Size,myf MyFlags);
extern void my_once_free(void);
extern char *my_once_strdup(const char *src,myf myflags);
extern char *my_once_memdup(const char *src, uint len, myf myflags);
extern my_string my_tempnam(const char *dir,const char *pfx,myf MyFlags);
extern File my_open(const char *FileName,int Flags,myf MyFlags);
extern File my_register_filename(File fd, const char *FileName,
enum file_type type_of_file,
@ -785,8 +784,9 @@ extern void reset_root_defaults(MEM_ROOT *mem_root, uint block_size,
extern char *strdup_root(MEM_ROOT *root,const char *str);
extern char *strmake_root(MEM_ROOT *root,const char *str,uint len);
extern char *memdup_root(MEM_ROOT *root,const char *str,uint len);
extern void get_defaults_files(int argc, char **argv,
char **defaults, char **extra_defaults);
extern int get_defaults_options(int argc, char **argv,
char **defaults, char **extra_defaults,
char **group_suffix);
extern int load_defaults(const char *conf_file, const char **groups,
int *argc, char ***argv);
extern int modify_defaults_file(const char *file_location, const char *option,

View File

@ -35,14 +35,26 @@ extern "C" {
/* defines used by myisam-funktions */
/* The following defines can be increased if necessary */
#define MI_MAX_KEY 64 /* Max allowed keys */
#define MI_MAX_KEY_SEG 16 /* Max segments for key */
#define MI_MAX_KEY_LENGTH 1000
/*
There is a hard limit for the maximum number of keys as there are only
8 bits in the index file header for the number of keys in a table.
This means that 0..255 keys can exist for a table. The idea of
MI_MAX_POSSIBLE_KEY is to ensure that one can use myisamchk & tools on
a MyISAM table for which one has more keys than MyISAM is normally
compiled for. If you don't have this, you will get a core dump when
running myisamchk compiled for 128 keys on a table with 255 keys.
*/
#define MI_MAX_POSSIBLE_KEY 255 /* For myisam_chk */
#define MI_MAX_POSSIBLE_KEY_BUFF (1024+6+6) /* For myisam_chk */
/*
The following defines can be increased if necessary.
BUT: MI_MAX_KEY must be <= MI_MAX_POSSIBLE_KEY.
*/
#define MI_MAX_KEY 64 /* Max allowed keys */
#define MI_MAX_KEY_SEG 16 /* Max segments for key */
#define MI_MAX_KEY_LENGTH 1000
#define MI_MAX_KEY_BUFF (MI_MAX_KEY_LENGTH+MI_MAX_KEY_SEG*6+8+8)
#define MI_MAX_POSSIBLE_KEY_BUFF (1024+6+6) /* For myisam_chk */
#define MI_MAX_POSSIBLE_KEY 64 /* For myisam_chk */
#define MI_MAX_MSG_BUF 1024 /* used in CHECK TABLE, REPAIR TABLE */
#define MI_NAME_IEXT ".MYI"
#define MI_NAME_DEXT ".MYD"
@ -56,6 +68,63 @@ extern "C" {
#define mi_portable_sizeof_char_ptr 8
/*
In the following macros '_keyno_' is 0 .. keys-1.
If there can be more keys than bits in the key_map, the highest bit
is for all upper keys. They cannot be switched individually.
This means that clearing of high keys is ignored, setting one high key
sets all high keys.
*/
#define MI_KEYMAP_BITS (8 * SIZEOF_LONG_LONG)
#define MI_KEYMAP_HIGH_MASK (ULL(1) << (MI_KEYMAP_BITS - 1))
#define mi_get_mask_all_keys_active(_keys_) \
(((_keys_) < MI_KEYMAP_BITS) ? \
((ULL(1) << (_keys_)) - ULL(1)) : \
(~ ULL(0)))
#if MI_MAX_KEY > MI_KEYMAP_BITS
#define mi_is_key_active(_keymap_,_keyno_) \
(((_keyno_) < MI_KEYMAP_BITS) ? \
test((_keymap_) & (ULL(1) << (_keyno_))) : \
test((_keymap_) & MI_KEYMAP_HIGH_MASK))
#define mi_set_key_active(_keymap_,_keyno_) \
(_keymap_)|= (((_keyno_) < MI_KEYMAP_BITS) ? \
(ULL(1) << (_keyno_)) : \
MI_KEYMAP_HIGH_MASK)
#define mi_clear_key_active(_keymap_,_keyno_) \
(_keymap_)&= (((_keyno_) < MI_KEYMAP_BITS) ? \
(~ (ULL(1) << (_keyno_))) : \
(~ (ULL(0))) /*ignore*/ )
#else
#define mi_is_key_active(_keymap_,_keyno_) \
test((_keymap_) & (ULL(1) << (_keyno_)))
#define mi_set_key_active(_keymap_,_keyno_) \
(_keymap_)|= (ULL(1) << (_keyno_))
#define mi_clear_key_active(_keymap_,_keyno_) \
(_keymap_)&= (~ (ULL(1) << (_keyno_)))
#endif
#define mi_is_any_key_active(_keymap_) \
test((_keymap_))
#define mi_is_all_keys_active(_keymap_,_keys_) \
((_keymap_) == mi_get_mask_all_keys_active(_keys_))
#define mi_set_all_keys_active(_keymap_,_keys_) \
(_keymap_)= mi_get_mask_all_keys_active(_keys_)
#define mi_clear_all_keys_active(_keymap_) \
(_keymap_)= 0
#define mi_intersect_keys_active(_to_,_from_) \
(_to_)&= (_from_)
#define mi_is_any_intersect_keys_active(_keymap1_,_keys_,_keymap2_) \
((_keymap1_) & (_keymap2_) & \
mi_get_mask_all_keys_active(_keys_))
#define mi_copy_keys_active(_to_,_maxkeys_,_from_) \
(_to_)= (mi_get_mask_all_keys_active(_maxkeys_) & \
(_from_))
/* Param to/from mi_info */
typedef struct st_mi_isaminfo /* Struct from h_info */

View File

@ -396,7 +396,7 @@ unsigned int STDCALL mysql_warning_count(MYSQL *mysql);
const char * STDCALL mysql_info(MYSQL *mysql);
unsigned long STDCALL mysql_thread_id(MYSQL *mysql);
const char * STDCALL mysql_character_set_name(MYSQL *mysql);
int STDCALL mysql_set_character_set(MYSQL *mysql, char *csname);
int STDCALL mysql_set_character_set(MYSQL *mysql, const char *csname);
MYSQL * STDCALL mysql_init(MYSQL *mysql);
my_bool STDCALL mysql_ssl_set(MYSQL *mysql, const char *key,

View File

@ -62,17 +62,45 @@ enum thr_lock_type { TL_IGNORE=-1,
/* Abort new lock request with an error */
TL_WRITE_ONLY};
enum enum_thr_lock_result { THR_LOCK_SUCCESS= 0, THR_LOCK_ABORTED= 1,
THR_LOCK_WAIT_TIMEOUT= 2, THR_LOCK_DEADLOCK= 3 };
extern ulong max_write_lock_count;
extern ulong table_lock_wait_timeout;
extern my_bool thr_lock_inited;
extern enum thr_lock_type thr_upgraded_concurrent_insert_lock;
typedef struct st_thr_lock_data {
/*
A description of the thread which owns the lock. The address
of an instance of this structure is used to uniquely identify the thread.
*/
typedef struct st_thr_lock_info
{
pthread_t thread;
ulong thread_id;
ulong n_cursors;
} THR_LOCK_INFO;
/*
Lock owner identifier. Globally identifies the lock owner within the
thread and among all the threads. The address of an instance of this
structure is used as id.
*/
typedef struct st_thr_lock_owner
{
THR_LOCK_INFO *info;
} THR_LOCK_OWNER;
typedef struct st_thr_lock_data {
THR_LOCK_OWNER *owner;
struct st_thr_lock_data *next,**prev;
struct st_thr_lock *lock;
pthread_cond_t *cond;
enum thr_lock_type type;
ulong thread_id;
void *status_param; /* Param to status functions */
void *debug_print_param;
} THR_LOCK_DATA;
@ -102,13 +130,18 @@ extern LIST *thr_lock_thread_list;
extern pthread_mutex_t THR_LOCK_lock;
my_bool init_thr_lock(void); /* Must be called once/thread */
#define thr_lock_owner_init(owner, info_arg) (owner)->info= (info_arg)
void thr_lock_info_init(THR_LOCK_INFO *info);
void thr_lock_init(THR_LOCK *lock);
void thr_lock_delete(THR_LOCK *lock);
void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data,
void *status_param);
int thr_lock(THR_LOCK_DATA *data,enum thr_lock_type lock_type);
enum enum_thr_lock_result thr_lock(THR_LOCK_DATA *data,
THR_LOCK_OWNER *owner,
enum thr_lock_type lock_type);
void thr_unlock(THR_LOCK_DATA *data);
int thr_multi_lock(THR_LOCK_DATA **data,uint count);
enum enum_thr_lock_result thr_multi_lock(THR_LOCK_DATA **data,
uint count, THR_LOCK_OWNER *owner);
void thr_multi_unlock(THR_LOCK_DATA **data,uint count);
void thr_abort_locks(THR_LOCK *lock);
void thr_abort_locks_for_thread(THR_LOCK *lock, pthread_t thread);

View File

@ -84,6 +84,7 @@ CLEANFILES = $(target_libadd) $(SHLIBOBJS) \
DEFS = -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
-DDATADIR="\"$(MYSQLDATAdir)\"" \
-DDEFAULT_HOME_ENV=MYSQL_HOME \
-DDEFAULT_GROUP_SUFFIX_ENV=MYSQL_GROUP_SUFFIX \
-DSHAREDIR="\"$(MYSQLSHAREdir)\"" $(target_defs)
# The automatic dependencies miss this

View File

@ -1511,39 +1511,6 @@ void STDCALL mysql_get_character_set_info(MYSQL *mysql, MY_CHARSET_INFO *csinfo)
csinfo->dir = charsets_dir;
}
int STDCALL mysql_set_character_set(MYSQL *mysql, char *cs_name)
{
struct charset_info_st *cs;
const char *save_csdir= charsets_dir;
if (mysql->options.charset_dir)
charsets_dir= mysql->options.charset_dir;
if ((cs= get_charset_by_csname(cs_name, MY_CS_PRIMARY, MYF(0))))
{
char buff[MY_CS_NAME_SIZE + 10];
charsets_dir= save_csdir;
sprintf(buff, "SET NAMES %s", cs_name);
if (!mysql_query(mysql, buff))
{
mysql->charset= cs;
}
}
else
{
char cs_dir_name[FN_REFLEN];
get_charsets_dir(cs_dir_name);
mysql->net.last_errno= CR_CANT_READ_CHARSET;
strmov(mysql->net.sqlstate, unknown_sqlstate);
my_snprintf(mysql->net.last_error, sizeof(mysql->net.last_error) - 1,
ER(mysql->net.last_errno), cs_name, cs_dir_name);
}
charsets_dir= save_csdir;
return mysql->net.last_errno;
}
uint STDCALL mysql_thread_safe(void)
{
#ifdef THREAD

View File

@ -150,5 +150,5 @@ EXPORTS
mysql_server_end
mysql_set_character_set
mysql_get_character_set_info
get_defaults_files
get_defaults_options
modify_defaults_file

View File

@ -158,7 +158,7 @@ EXPORTS
mysql_stmt_attr_get
mysql_stmt_attr_set
mysql_stmt_field_count
get_defaults_files
get_defaults_options
my_charset_bin
my_charset_same
modify_defaults_file

View File

@ -0,0 +1,21 @@
--source ./include/have_federated_db.inc
source ./include/master-slave.inc;
# remote table creation
connection slave;
--replicate-ignore-db=federated
stop slave;
--disable_warnings
# at this point, we are connected to master
DROP DATABASE IF EXISTS federated;
--enable_warnings
CREATE DATABASE federated;
connection master;
--disable_warnings
DROP DATABASE IF EXISTS federated;
--enable_warnings
CREATE DATABASE federated;

View File

@ -0,0 +1,11 @@
connection master;
--disable_warnings
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
--enable_warnings
connection slave;
--disable_warnings
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
--enable_warnings

View File

@ -9785,6 +9785,20 @@ DROP TABLE t1;
DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
CREATE TABLE t1(c1 varchar(10)) default character set = eucjpms;
insert into t1 values(_ucs2 0x00F7);
insert into t1 values(_eucjpms 0xA1E0);
insert into t1 values(_ujis 0xA1E0);
insert into t1 values(_sjis 0x8180);
insert into t1 values(_cp932 0x8180);
SELECT HEX(c1) FROM t1;
HEX(c1)
A1E0
A1E0
A1E0
A1E0
A1E0
DROP TABLE t1;
SET collation_connection='eucjpms_japanese_ci';
create table t1 select repeat('a',4000) a;
delete from t1;

View File

@ -7,41 +7,47 @@ start slave;
stop slave;
DROP DATABASE IF EXISTS federated;
CREATE DATABASE federated;
DROP DATABASE IF EXISTS federated;
CREATE DATABASE federated;
DROP TABLE IF EXISTS federated.t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default ''
)
DEFAULT CHARSET=latin1;
DROP DATABASE IF EXISTS federated;
CREATE DATABASE federated;
DROP TABLE IF EXISTS federated.t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default ''
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:@/too/many/items/federated/t1';
ERROR HY000: Can't create table 'connection string is not in the correct format' (errno: 0)
ERROR HY000: Can't create federated table. The data source connection string 'mysql://root@127.0.0.1:@/too/many/items/federated/t1' is not in the correct format
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default ''
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1';
ERROR HY000: Can't create table 'connection string is not in the correct format' (errno: 0)
ERROR HY000: Can't create federated table. The data source connection string 'mysql://root@127.0.0.1' is not in the correct format
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default ''
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t3';
ERROR HY000: Error running query on master: foreign table 't3' does not exist!
ERROR HY000: Can't create federated table. Foreign data src error : ': 1146 : Table 'federated.t3' doesn't exist'
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default ''
)
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://user:pass@127.0.0.1:SLAVE_PORT/federated/t1';
ERROR 08S01: Error connecting to master: unable to connect to database 'federated' on host '127.0.0.1 as user 'user' !
ERROR HY000: Unable to connect to foreign data source - database ' database federated username user hostname 127.0.0.1'!
DROP TABLE IF EXISTS federated.t1;
Warnings:
Note 1051 Unknown table 't1'
@ -124,18 +130,14 @@ CREATE TABLE federated.t1 (
`name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0',
`created` datetime default '2004-04-04 04:04:04',
PRIMARY KEY (`id`),
KEY `name` (`name`),
KEY `other_key` (`other`))
PRIMARY KEY (`id`))
DEFAULT CHARSET=latin1;
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL auto_increment,
`name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0',
`created` datetime default '2004-04-04 04:04:04',
PRIMARY KEY (`id`),
KEY `name` (`name`),
KEY `other_key` (`other`))
PRIMARY KEY (`id`))
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
INSERT INTO federated.t1 (name, other) VALUES ('First Name', 11111);
@ -169,9 +171,8 @@ id name other created
SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name';
id name other created
6 Sixth Name 66666 2004-04-04 04:04:04
SELECT * FROM federated.t1 WHERE other = 44444;
SELECT * FROM federated.t1 WHERE name = 'Sixth Name' AND other = 44444;
id name other created
4 Fourth Name 44444 2004-04-04 04:04:04
SELECT * FROM federated.t1 WHERE name like '%th%';
id name other created
3 Third Name 33333 2004-04-04 04:04:04
@ -257,6 +258,154 @@ DELETE FROM federated.t1;
SELECT * FROM federated.t1 WHERE id = 5;
id name other created
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL auto_increment,
`name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0',
`created` datetime NOT NULL,
PRIMARY KEY (`id`),
key name(`name`),
key other(`other`),
key created(`created`))
DEFAULT CHARSET=latin1;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL auto_increment,
`name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0',
`created` datetime NOT NULL,
PRIMARY KEY (`id`),
key name(`name`),
key other(`other`),
key created(`created`))
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
INSERT INTO federated.t1 (name, other, created)
VALUES ('First Name', 11111, '2004-01-01 01:01:01');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Second Name', 22222, '2004-01-23 02:43:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Third Name', 33333, '2004-02-14 02:14:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Fourth Name', 44444, '2003-04-05 00:00:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Fifth Name', 55555, '2001-02-02 02:02:02');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Sixth Name', 66666, '2005-06-06 15:30:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Seventh Name', 77777, '2003-12-12 18:32:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Eigth Name', 88888, '2005-03-12 11:00:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Ninth Name', 99999, '2005-03-12 11:00:01');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Tenth Name', 101010, '2005-03-12 12:00:01');
SELECT * FROM federated.t1;
id name other created
1 First Name 11111 2004-01-01 01:01:01
2 Second Name 22222 2004-01-23 02:43:00
3 Third Name 33333 2004-02-14 02:14:00
4 Fourth Name 44444 2003-04-05 00:00:00
5 Fifth Name 55555 2001-02-02 02:02:02
6 Sixth Name 66666 2005-06-06 15:30:00
7 Seventh Name 77777 2003-12-12 18:32:00
8 Eigth Name 88888 2005-03-12 11:00:00
9 Ninth Name 99999 2005-03-12 11:00:01
10 Tenth Name 101010 2005-03-12 12:00:01
SELECT * FROM federated.t1 WHERE id = 5;
id name other created
5 Fifth Name 55555 2001-02-02 02:02:02
SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name';
id name other created
6 Sixth Name 66666 2005-06-06 15:30:00
SELECT * FROM federated.t1 WHERE other = 44444;
id name other created
4 Fourth Name 44444 2003-04-05 00:00:00
SELECT * FROM federated.t1 WHERE name like '%th%';
id name other created
3 Third Name 33333 2004-02-14 02:14:00
4 Fourth Name 44444 2003-04-05 00:00:00
5 Fifth Name 55555 2001-02-02 02:02:02
6 Sixth Name 66666 2005-06-06 15:30:00
7 Seventh Name 77777 2003-12-12 18:32:00
8 Eigth Name 88888 2005-03-12 11:00:00
9 Ninth Name 99999 2005-03-12 11:00:01
10 Tenth Name 101010 2005-03-12 12:00:01
UPDATE federated.t1 SET name = '3rd name' WHERE id = 3;
SELECT * FROM federated.t1 WHERE name = '3rd name';
id name other created
3 3rd name 33333 2004-02-14 02:14:00
UPDATE federated.t1 SET name = 'Third name' WHERE name = '3rd name';
SELECT * FROM federated.t1 WHERE name = 'Third name';
id name other created
3 Third name 33333 2004-02-14 02:14:00
SELECT * FROM federated.t1 ORDER BY id DESC;
id name other created
10 Tenth Name 101010 2005-03-12 12:00:01
9 Ninth Name 99999 2005-03-12 11:00:01
8 Eigth Name 88888 2005-03-12 11:00:00
7 Seventh Name 77777 2003-12-12 18:32:00
6 Sixth Name 66666 2005-06-06 15:30:00
5 Fifth Name 55555 2001-02-02 02:02:02
4 Fourth Name 44444 2003-04-05 00:00:00
3 Third name 33333 2004-02-14 02:14:00
2 Second Name 22222 2004-01-23 02:43:00
1 First Name 11111 2004-01-01 01:01:01
SELECT * FROM federated.t1 ORDER BY name;
id name other created
8 Eigth Name 88888 2005-03-12 11:00:00
5 Fifth Name 55555 2001-02-02 02:02:02
1 First Name 11111 2004-01-01 01:01:01
4 Fourth Name 44444 2003-04-05 00:00:00
9 Ninth Name 99999 2005-03-12 11:00:01
2 Second Name 22222 2004-01-23 02:43:00
7 Seventh Name 77777 2003-12-12 18:32:00
6 Sixth Name 66666 2005-06-06 15:30:00
10 Tenth Name 101010 2005-03-12 12:00:01
3 Third name 33333 2004-02-14 02:14:00
SELECT * FROM federated.t1 ORDER BY name DESC;
id name other created
3 Third name 33333 2004-02-14 02:14:00
10 Tenth Name 101010 2005-03-12 12:00:01
6 Sixth Name 66666 2005-06-06 15:30:00
7 Seventh Name 77777 2003-12-12 18:32:00
2 Second Name 22222 2004-01-23 02:43:00
9 Ninth Name 99999 2005-03-12 11:00:01
4 Fourth Name 44444 2003-04-05 00:00:00
1 First Name 11111 2004-01-01 01:01:01
5 Fifth Name 55555 2001-02-02 02:02:02
8 Eigth Name 88888 2005-03-12 11:00:00
SELECT * FROM federated.t1 ORDER BY name ASC;
id name other created
8 Eigth Name 88888 2005-03-12 11:00:00
5 Fifth Name 55555 2001-02-02 02:02:02
1 First Name 11111 2004-01-01 01:01:01
4 Fourth Name 44444 2003-04-05 00:00:00
9 Ninth Name 99999 2005-03-12 11:00:01
2 Second Name 22222 2004-01-23 02:43:00
7 Seventh Name 77777 2003-12-12 18:32:00
6 Sixth Name 66666 2005-06-06 15:30:00
10 Tenth Name 101010 2005-03-12 12:00:01
3 Third name 33333 2004-02-14 02:14:00
SELECT * FROM federated.t1 GROUP BY other;
id name other created
1 First Name 11111 2004-01-01 01:01:01
2 Second Name 22222 2004-01-23 02:43:00
3 Third name 33333 2004-02-14 02:14:00
4 Fourth Name 44444 2003-04-05 00:00:00
5 Fifth Name 55555 2001-02-02 02:02:02
6 Sixth Name 66666 2005-06-06 15:30:00
7 Seventh Name 77777 2003-12-12 18:32:00
8 Eigth Name 88888 2005-03-12 11:00:00
9 Ninth Name 99999 2005-03-12 11:00:01
10 Tenth Name 101010 2005-03-12 12:00:01
DELETE FROM federated.t1 WHERE id = 5;
SELECT * FROM federated.t1 WHERE id = 5;
id name other created
DELETE FROM federated.t1;
SELECT * FROM federated.t1 WHERE id = 5;
id name other created
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL auto_increment,
`name` varchar(32),
@ -303,15 +452,14 @@ UPDATE federated.t1
SET name = 'Fourth Name', other = 'four four four'
WHERE name IS NULL AND other IS NULL;
UPDATE federated.t1 SET other = 'two two two two' WHERE name = 'Second Name';
UPDATE federated.t1 SET other = 'seven seven' WHERE name like 'Sec%';
UPDATE federated.t1 SET other = 'seven seven' WHERE name = 'Seventh Name';
UPDATE federated.t1 SET other = 'seven seven' WHERE name like 'Sev%';
UPDATE federated.t1 SET name = 'Tenth Name' WHERE other like 'fee fie%';
SELECT * FROM federated.t1 WHERE name IS NULL OR other IS NULL ;
id name other
SELECT * FROM federated.t1;
id name other
1 First Name 11111
2 Second Name seven seven
2 Second Name two two two two
3 Third Name 33333
4 Fourth Name four four four
5 Fifth Name 55555
@ -418,6 +566,360 @@ id name bincol floatval other
3 third g 22.22 2222
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int NOT NULL auto_increment,
`col1` int(10) NOT NULL DEFAULT 0,
`col2` varchar(64) NOT NULL DEFAULT '',
`col3` int(20) NOT NULL,
`col4` int(40) NOT NULL,
primary key (`id`, `col1`, `col2`, `col3`, `col4`),
key col1(col1),
key col2(col2),
key col3(col3),
key col4(col4));
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int NOT NULL auto_increment,
`col1` int(10) NOT NULL DEFAULT 0,
`col2` varchar(64) NOT NULL DEFAULT '',
`col3` int(20) NOT NULL,
`col4` int(40) NOT NULL,
primary key (`id`, `col1`, `col2`, `col3`, `col4`),
key col1(col1),
key col2(col2),
key col3(col3),
key col4(col4))
ENGINE="FEDERATED"
COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (1, 'one One', 11, 1111);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (2, 'Two two', 22, 2222);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (3, 'three Three', 33, 33333);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (4, 'fourfourfour', 444, 4444444);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (5, 'five 5 five five 5', 5, 55555);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (6, 'six six Sixsix', 6666, 6);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (7, 'seven Sevenseven', 77777, 7777);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (8, 'eight eight eight', 88888, 88);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (9, 'nine Nine', 999999, 999999);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (10, 'Tenth ten TEN', 1010101, 1010);
SELECT * FROM federated.t1 WHERE col2 = 'two two';
id col1 col2 col3 col4
2 2 Two two 22 2222
SELECT * FROM federated.t1 WHERE col2 = 'two Two';
id col1 col2 col3 col4
2 2 Two two 22 2222
SELECT * FROM federated.t1 WHERE id = 3;
id col1 col2 col3 col4
3 3 three Three 33 33333
SELECT * FROM federated.t1 WHERE id = 3 AND col1 = 3;
id col1 col2 col3 col4
3 3 three Three 33 33333
SELECT * FROM federated.t1 WHERE id = 4 AND col1 = 4 AND col2 = 'Two two';
id col1 col2 col3 col4
SELECT * FROM federated.t1 WHERE id = 4 AND col1 = 4 AND col2 = 'fourfourfour';
id col1 col2 col3 col4
4 4 fourfourfour 444 4444444
SELECT * FROM federated.t1 WHERE id = 5 AND col2 = 'five 5 five five 5'
AND col3 = 5;
id col1 col2 col3 col4
5 5 five 5 five five 5 5 55555
SELECT * FROM federated.t1 WHERE id = 5 AND col2 = 'five 5 five five 5'
AND col3 = 5
AND col4 = 55555;
id col1 col2 col3 col4
5 5 five 5 five five 5 5 55555
SELECT * FROM federated.t1 WHERE id = 5
AND col2 = 'Two two' AND col3 = 22
AND col4 = 33;
id col1 col2 col3 col4
SELECT * FROM federated.t1 WHERE id = 5
AND col2 = 'five 5 five five 5' AND col3 = 5
AND col4 = 55555;
id col1 col2 col3 col4
5 5 five 5 five five 5 5 55555
SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'five 5 five five 5')
OR (col2 = 'three Three' AND col3 = 33);
id col1 col2 col3 col4
5 5 five 5 five five 5 5 55555
3 3 three Three 33 33333
SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'Two two')
OR (col2 = 444 AND col3 = 4444444);
id col1 col2 col3 col4
SELECT * FROM federated.t1 WHERE id = 1
OR col1 = 10
OR col2 = 'Two two'
OR col3 = 33
OR col4 = 4444444;
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
3 3 three Three 33 33333
4 4 fourfourfour 444 4444444
10 10 Tenth ten TEN 1010101 1010
SELECT * FROM federated.t1 WHERE id > 5;
id col1 col2 col3 col4
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
8 8 eight eight eight 88888 88
9 9 nine Nine 999999 999999
10 10 Tenth ten TEN 1010101 1010
SELECT * FROM federated.t1 WHERE id >= 5;
id col1 col2 col3 col4
5 5 five 5 five five 5 5 55555
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
8 8 eight eight eight 88888 88
9 9 nine Nine 999999 999999
10 10 Tenth ten TEN 1010101 1010
SELECT * FROM federated.t1 WHERE id < 5;
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
3 3 three Three 33 33333
4 4 fourfourfour 444 4444444
SELECT * FROM federated.t1 WHERE id <= 5;
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
3 3 three Three 33 33333
4 4 fourfourfour 444 4444444
5 5 five 5 five five 5 5 55555
SELECT * FROM federated.t1 WHERE id != 5;
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
3 3 three Three 33 33333
4 4 fourfourfour 444 4444444
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
8 8 eight eight eight 88888 88
9 9 nine Nine 999999 999999
10 10 Tenth ten TEN 1010101 1010
SELECT * FROM federated.t1 WHERE id > 3 AND id < 7;
id col1 col2 col3 col4
4 4 fourfourfour 444 4444444
5 5 five 5 five five 5 5 55555
6 6 six six Sixsix 6666 6
SELECT * FROM federated.t1 WHERE id > 3 AND id <= 7;
id col1 col2 col3 col4
4 4 fourfourfour 444 4444444
5 5 five 5 five five 5 5 55555
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
SELECT * FROM federated.t1 WHERE id >= 3 AND id <= 7;
id col1 col2 col3 col4
3 3 three Three 33 33333
4 4 fourfourfour 444 4444444
5 5 five 5 five five 5 5 55555
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
SELECT * FROM federated.t1 WHERE id < 3 AND id <= 7;
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
SELECT * FROM federated.t1 WHERE id < 3 AND id > 7;
id col1 col2 col3 col4
SELECT * FROM federated.t1 WHERE id < 3 OR id > 7;
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
8 8 eight eight eight 88888 88
9 9 nine Nine 999999 999999
10 10 Tenth ten TEN 1010101 1010
SELECT * FROM federated.t1 WHERE col2 = 'three Three';
id col1 col2 col3 col4
3 3 three Three 33 33333
SELECT * FROM federated.t1 WHERE col2 > 'one';
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
3 3 three Three 33 33333
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
10 10 Tenth ten TEN 1010101 1010
SELECT * FROM federated.t1 WHERE col2 LIKE 's%';
id col1 col2 col3 col4
7 7 seven Sevenseven 77777 7777
6 6 six six Sixsix 6666 6
SELECT * FROM federated.t1 WHERE col2 LIKE 'si%';
id col1 col2 col3 col4
6 6 six six Sixsix 6666 6
SELECT * FROM federated.t1 WHERE col2 LIKE 'se%';
id col1 col2 col3 col4
7 7 seven Sevenseven 77777 7777
SELECT * FROM federated.t1 WHERE col2 NOT LIKE 'e%';
id col1 col2 col3 col4
1 1 one One 11 1111
2 2 Two two 22 2222
3 3 three Three 33 33333
4 4 fourfourfour 444 4444444
5 5 five 5 five five 5 5 55555
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
9 9 nine Nine 999999 999999
10 10 Tenth ten TEN 1010101 1010
SELECT * FROM federated.t1 WHERE col2 <> 'one One';
id col1 col2 col3 col4
4 4 fourfourfour 444 4444444
5 5 five 5 five five 5 5 55555
8 8 eight eight eight 88888 88
9 9 nine Nine 999999 999999
2 2 Two two 22 2222
3 3 three Three 33 33333
6 6 six six Sixsix 6666 6
7 7 seven Sevenseven 77777 7777
10 10 Tenth ten TEN 1010101 1010
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` varchar(128) NOT NULL DEFAULT '',
`col3` varchar(20) NOT NULL DEFAULT '',
`col4` varchar(40) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`, `col4`),
key 3key(`col2`,`col3`,`col4`),
key 2key (`col3`,`col4`),
key col4(col4));
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` varchar(128) NOT NULL DEFAULT '',
`col3` varchar(20) NOT NULL DEFAULT '',
`col4` varchar(40) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`, `col4`),
key 3key(`col2`,`col3`,`col4`),
key 2key (`col3`,`col4`),
key col4(col4))
ENGINE="FEDERATED"
COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('aaaa', 'aaaaaaaaaaaaaaaaaaa', 'ababababab', 'acacacacacacacac');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('bbbb', 'bbbbbbbbbbbbbbbbbbb', 'bababababa', 'bcbcbcbcbcbcbcbc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('cccc', 'ccccccccccccccccccc', 'cacacacaca', 'cbcbcbcbcbcbcbcb');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('dddd', 'ddddddddddddddddddd', 'dadadadada', 'dcdcdcdcdcdcdcdc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('eeee', 'eeeeeeeeeeeeeeeeeee', 'eaeaeaeaea', 'ecececececececec');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('ffff', 'fffffffffffffffffff', 'fafafafafa', 'fcfcfcfcfcfcfcfc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('gggg', 'ggggggggggggggggggg', 'gagagagaga', 'gcgcgcgcgcgcgcgc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('hhhh', 'hhhhhhhhhhhhhhhhhhh', 'hahahahaha', 'hchchchchchchchc');
SELECT * FROM federated.t1 WHERE col1 = 'cccc';
col1 col2 col3 col4
cccc ccccccccccccccccccc cacacacaca cbcbcbcbcbcbcbcb
SELECT * FROM federated.t1 WHERE col2 = 'eeeeeeeeeeeeeeeeeee';
col1 col2 col3 col4
eeee eeeeeeeeeeeeeeeeeee eaeaeaeaea ecececececececec
SELECT * FROM federated.t1 WHERE col3 = 'bababababa';
col1 col2 col3 col4
bbbb bbbbbbbbbbbbbbbbbbb bababababa bcbcbcbcbcbcbcbc
SELECT * FROM federated.t1 WHERE col1 = 'gggg' AND col2 = 'ggggggggggggggggggg';
col1 col2 col3 col4
gggg ggggggggggggggggggg gagagagaga gcgcgcgcgcgcgcgc
SELECT * FROM federated.t1 WHERE col1 = 'gggg' AND col3 = 'gagagagaga';
col1 col2 col3 col4
gggg ggggggggggggggggggg gagagagaga gcgcgcgcgcgcgcgc
SELECT * FROM federated.t1 WHERE col1 = 'ffff' AND col4 = 'fcfcfcfcfcfcfcfc';
col1 col2 col3 col4
ffff fffffffffffffffffff fafafafafa fcfcfcfcfcfcfcfc
SELECT * FROM federated.t1 WHERE col1 > 'bbbb';
col1 col2 col3 col4
cccc ccccccccccccccccccc cacacacaca cbcbcbcbcbcbcbcb
dddd ddddddddddddddddddd dadadadada dcdcdcdcdcdcdcdc
eeee eeeeeeeeeeeeeeeeeee eaeaeaeaea ecececececececec
ffff fffffffffffffffffff fafafafafa fcfcfcfcfcfcfcfc
gggg ggggggggggggggggggg gagagagaga gcgcgcgcgcgcgcgc
hhhh hhhhhhhhhhhhhhhhhhh hahahahaha hchchchchchchchc
SELECT * FROM federated.t1 WHERE col1 >= 'bbbb';
col1 col2 col3 col4
bbbb bbbbbbbbbbbbbbbbbbb bababababa bcbcbcbcbcbcbcbc
cccc ccccccccccccccccccc cacacacaca cbcbcbcbcbcbcbcb
dddd ddddddddddddddddddd dadadadada dcdcdcdcdcdcdcdc
eeee eeeeeeeeeeeeeeeeeee eaeaeaeaea ecececececececec
ffff fffffffffffffffffff fafafafafa fcfcfcfcfcfcfcfc
gggg ggggggggggggggggggg gagagagaga gcgcgcgcgcgcgcgc
hhhh hhhhhhhhhhhhhhhhhhh hahahahaha hchchchchchchchc
SELECT * FROM federated.t1 WHERE col1 < 'bbbb';
col1 col2 col3 col4
aaaa aaaaaaaaaaaaaaaaaaa ababababab acacacacacacacac
SELECT * FROM federated.t1 WHERE col1 <= 'bbbb';
col1 col2 col3 col4
aaaa aaaaaaaaaaaaaaaaaaa ababababab acacacacacacacac
bbbb bbbbbbbbbbbbbbbbbbb bababababa bcbcbcbcbcbcbcbc
SELECT * FROM federated.t1 WHERE col1 <> 'bbbb';
col1 col2 col3 col4
aaaa aaaaaaaaaaaaaaaaaaa ababababab acacacacacacacac
cccc ccccccccccccccccccc cacacacaca cbcbcbcbcbcbcbcb
dddd ddddddddddddddddddd dadadadada dcdcdcdcdcdcdcdc
eeee eeeeeeeeeeeeeeeeeee eaeaeaeaea ecececececececec
ffff fffffffffffffffffff fafafafafa fcfcfcfcfcfcfcfc
gggg ggggggggggggggggggg gagagagaga gcgcgcgcgcgcgcgc
hhhh hhhhhhhhhhhhhhhhhhh hahahahaha hchchchchchchchc
SELECT * FROM federated.t1 WHERE col1 LIKE 'b%';
col1 col2 col3 col4
bbbb bbbbbbbbbbbbbbbbbbb bababababa bcbcbcbcbcbcbcbc
SELECT * FROM federated.t1 WHERE col4 LIKE '%b%';
col1 col2 col3 col4
bbbb bbbbbbbbbbbbbbbbbbb bababababa bcbcbcbcbcbcbcbc
cccc ccccccccccccccccccc cacacacaca cbcbcbcbcbcbcbcb
SELECT * FROM federated.t1 WHERE col1 NOT LIKE 'c%';
col1 col2 col3 col4
aaaa aaaaaaaaaaaaaaaaaaa ababababab acacacacacacacac
bbbb bbbbbbbbbbbbbbbbbbb bababababa bcbcbcbcbcbcbcbc
dddd ddddddddddddddddddd dadadadada dcdcdcdcdcdcdcdc
eeee eeeeeeeeeeeeeeeeeee eaeaeaeaea ecececececececec
ffff fffffffffffffffffff fafafafafa fcfcfcfcfcfcfcfc
gggg ggggggggggggggggggg gagagagaga gcgcgcgcgcgcgcgc
hhhh hhhhhhhhhhhhhhhhhhh hahahahaha hchchchchchchchc
SELECT * FROM federated.t1 WHERE col4 NOT LIKE '%c%';
col1 col2 col3 col4
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` int(8) NOT NULL DEFAULT 0,
`col3` varchar(8) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`));
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` varchar(8) NOT NULL DEFAULT '',
`col3` varchar(8) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`))
ENGINE="FEDERATED"
DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
INSERT INTO federated.t1 VALUES ('a00', '110', 'cc0');
INSERT INTO federated.t1 VALUES ('aaa', '111', 'ccc');
INSERT INTO federated.t1 VALUES ('bbb', '222', 'yyy');
INSERT INTO federated.t1 VALUES ('ccc', '111', 'zzz');
INSERT INTO federated.t1 VALUES ('ccd', '112', 'zzzz');
SELECT col3 FROM federated.t1 WHERE (
(col1 = 'aaa' AND col2 >= '111') OR col1 > 'aaa') AND
(col1 < 'ccc' OR ( col1 = 'ccc' AND col2 <= '111'));
col3
ccc
yyy
zzz
SELECT col3 FROM federated.t1 WHERE (
(col1 = 'aaa' AND col2 >= '111') OR col1 > 'aaa') AND
(col1 < 'ccc' OR ( col1 = 'ccc' AND col2 <= '111'));
col3
ccc
yyy
zzz
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int,
`name` varchar(32),
`floatval` float,
@ -494,30 +996,6 @@ ENGINE="FEDERATED"
DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1';
INSERT INTO federated.t1 VALUES (3,3,3),(1,1,1),(2,2,2),(4,4,4);
EXPLAIN SELECT * FROM federated.t1 ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using filesort
EXPLAIN SELECT * FROM federated.t1 ORDER BY b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using filesort
EXPLAIN SELECT * FROM federated.t1 ORDER BY c;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using filesort
EXPLAIN SELECT a FROM federated.t1 ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using filesort
EXPLAIN SELECT b FROM federated.t1 ORDER BY b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using filesort
EXPLAIN SELECT a,b FROM federated.t1 ORDER BY b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using filesort
EXPLAIN SELECT a,b FROM federated.t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000
EXPLAIN SELECT a,b,c FROM federated.t1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (i1 int, i2 int, i3 int, i4 int, i5 int, i6 int, i7 int, i8
int, i9 int, i10 int, i11 int, i12 int, i13 int, i14 int, i15 int, i16 int, i17
@ -906,13 +1384,6 @@ INSERT INTO federated.t1 (name, country_id, other) VALUES ('Lenz', 2, 22222);
INSERT INTO federated.t1 (name, country_id, other) VALUES ('Marizio', 3, 33333);
INSERT INTO federated.t1 (name, country_id, other) VALUES ('Monty', 4, 33333);
INSERT INTO federated.t1 (name, country_id, other) VALUES ('Sanja', 5, 33333);
EXPLAIN SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1, federated.countries WHERE
federated.t1.country_id = federated.countries.id;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE countries ALL PRIMARY NULL NULL NULL 5
1 SIMPLE t1 ref country_id country_id 4 federated.countries.id 120
SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1, federated.countries WHERE
@ -923,13 +1394,6 @@ Lenz 2 22222 Germany
Marizio 3 33333 Italy
Monty 4 33333 Finland
Sanja 5 33333 Ukraine
EXPLAIN SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1 INNER JOIN federated.countries ON
federated.t1.country_id = federated.countries.id;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE countries ALL PRIMARY NULL NULL NULL 5
1 SIMPLE t1 ref country_id country_id 4 federated.countries.id 120
SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1 INNER JOIN federated.countries ON
@ -940,14 +1404,6 @@ Lenz 2 22222 Germany
Marizio 3 33333 Italy
Monty 4 33333 Finland
Sanja 5 33333 Ukraine
EXPLAIN SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1 INNER JOIN federated.countries ON
federated.t1.country_id = federated.countries.id
WHERE federated.t1.name = 'Monty';
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE countries ALL PRIMARY NULL NULL NULL 5
1 SIMPLE t1 ref country_id country_id 4 federated.countries.id 120 Using where
SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1 INNER JOIN federated.countries ON
@ -955,13 +1411,6 @@ federated.t1.country_id = federated.countries.id
WHERE federated.t1.name = 'Monty';
name country_id other country
Monty 4 33333 Finland
EXPLAIN SELECT federated.t1.*, federated.countries.country
FROM federated.t1 LEFT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id
ORDER BY federated.countries.id;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using temporary; Using filesort
1 SIMPLE countries eq_ref PRIMARY PRIMARY 4 federated.t1.country_id 1
SELECT federated.t1.*, federated.countries.country
FROM federated.t1 LEFT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id
@ -972,13 +1421,6 @@ id country_id name other country
3 3 Marizio 33333 Italy
4 4 Monty 33333 Finland
5 5 Sanja 33333 Ukraine
EXPLAIN SELECT federated.t1.*, federated.countries.country
FROM federated.t1 LEFT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id
ORDER BY federated.countries.country;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ALL NULL NULL NULL NULL 10000 Using temporary; Using filesort
1 SIMPLE countries eq_ref PRIMARY PRIMARY 4 federated.t1.country_id 1
SELECT federated.t1.*, federated.countries.country
FROM federated.t1 LEFT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id
@ -989,13 +1431,6 @@ id country_id name other country
1 1 Kumar 11111 India
3 3 Marizio 33333 Italy
5 5 Sanja 33333 Ukraine
EXPLAIN SELECT federated.t1.*, federated.countries.country
FROM federated.t1 RIGHT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id
ORDER BY federated.t1.country_id;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE countries ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
1 SIMPLE t1 ref country_id country_id 4 federated.countries.id 120
SELECT federated.t1.*, federated.countries.country
FROM federated.t1 RIGHT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id
@ -1007,6 +1442,21 @@ id country_id name other country
4 4 Monty 33333 Finland
5 5 Sanja 33333 Ukraine
DROP TABLE federated.countries;
OPTIMIZE TABLE federated.t1;
Table Op Msg_type Msg_text
federated.t1 optimize status OK
REPAIR TABLE federated.t1;
Table Op Msg_type Msg_text
federated.t1 repair status OK
REPAIR TABLE federated.t1 QUICK;
Table Op Msg_type Msg_text
federated.t1 repair status OK
REPAIR TABLE federated.t1 EXTENDED;
Table Op Msg_type Msg_text
federated.t1 repair status OK
REPAIR TABLE federated.t1 USE_FRM;
Table Op Msg_type Msg_text
federated.t1 repair status OK
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
DROP TABLE IF EXISTS federated.t1;

View File

@ -119,7 +119,7 @@ c char(1) character set latin1 collate latin1_danish_ci
insert into t1 values ('A','B','C');
insert into t1 values ('a','c','c');
select * from t1 where a in (b);
ERROR HY000: Illegal mix of collations (latin1_general_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation ' IN '
ERROR HY000: Illegal mix of collations (latin1_general_ci,IMPLICIT) and (latin1_swedish_ci,IMPLICIT) for operation '='
select * from t1 where a in (b,c);
ERROR HY000: Illegal mix of collations (latin1_general_ci,IMPLICIT), (latin1_swedish_ci,IMPLICIT), (latin1_danish_ci,IMPLICIT) for operation ' IN '
select * from t1 where 'a' in (a,b,c);
@ -193,3 +193,26 @@ select * from t1 where a in (NULL, 'aa');
a
aa
drop table t1;
CREATE TABLE t1 (a int PRIMARY KEY);
INSERT INTO t1 VALUES (44), (45), (46);
SELECT * FROM t1 WHERE a IN (45);
a
45
SELECT * FROM t1 WHERE a NOT IN (0, 45);
a
44
46
SELECT * FROM t1 WHERE a NOT IN (45);
a
44
46
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a NOT IN (45);
SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` <> 45)
SELECT * FROM v1;
a
44
46
DROP VIEW v1;
DROP TABLE t1;

View File

@ -48,6 +48,7 @@ TABLE_PRIVILEGES
COLUMN_PRIVILEGES
TABLE_CONSTRAINTS
KEY_COLUMN_USAGE
TRIGGERS
columns_priv
db
func
@ -77,6 +78,7 @@ c table_name
TABLES TABLES
TABLE_PRIVILEGES TABLE_PRIVILEGES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TRIGGERS TRIGGERS
tables_priv tables_priv
time_zone time_zone
time_zone_leap_second time_zone_leap_second
@ -94,6 +96,7 @@ c table_name
TABLES TABLES
TABLE_PRIVILEGES TABLE_PRIVILEGES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TRIGGERS TRIGGERS
tables_priv tables_priv
time_zone time_zone
time_zone_leap_second time_zone_leap_second
@ -111,6 +114,7 @@ c table_name
TABLES TABLES
TABLE_PRIVILEGES TABLE_PRIVILEGES
TABLE_CONSTRAINTS TABLE_CONSTRAINTS
TRIGGERS TRIGGERS
tables_priv tables_priv
time_zone time_zone
time_zone_leap_second time_zone_leap_second
@ -153,7 +157,7 @@ c varchar(64) utf8_general_ci NO select,insert,update,references
select * from information_schema.COLUMNS where table_name="t1"
and column_name= "a";
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME ORDINAL_POSITION COLUMN_DEFAULT IS_NULLABLE DATA_TYPE CHARACTER_MAXIMUM_LENGTH CHARACTER_OCTET_LENGTH NUMERIC_PRECISION NUMERIC_SCALE CHARACTER_SET_NAME COLLATION_NAME COLUMN_TYPE COLUMN_KEY EXTRA PRIVILEGES COLUMN_COMMENT
NULL mysqltest t1 a 1 NULL YES int NULL NULL 11 0 NULL NULL int(11) select,insert,update,references
NULL mysqltest t1 a 1 NULL YES int NULL NULL 10 NULL NULL NULL int(11) select,insert,update,references
show columns from mysqltest.t1 where field like "%a%";
Field Type Null Key Default Extra
a int(11) YES NULL
@ -298,6 +302,9 @@ show create function sub2;
Function sql_mode Create Function
sub2 CREATE FUNCTION `test`.`sub2`(i int) RETURNS int(11)
return i+1
show function status like "sub2";
Db Name Type Definer Modified Created Security_type Comment
test sub2 FUNCTION mysqltest_1@localhost # # DEFINER
drop function sub2;
show create procedure sel2;
Procedure sql_mode Create Procedure
@ -520,7 +527,7 @@ c float(5,2) NULL NULL 5 2
d decimal(6,4) NULL NULL 6 4
e float NULL NULL 12 NULL
f decimal(6,3) NULL NULL 6 3
g int(11) NULL NULL 11 0
g int(11) NULL NULL 10 NULL
h double(10,3) NULL NULL 10 3
i double NULL NULL 22 NULL
drop table t1;
@ -577,6 +584,7 @@ Tables_in_information_schema (T%)
TABLES
TABLE_PRIVILEGES
TABLE_CONSTRAINTS
TRIGGERS
create database information_schema;
ERROR HY000: Can't create database 'information_schema'; database exists
use information_schema;
@ -585,6 +593,7 @@ Tables_in_information_schema (T%) Table_type
TABLES TEMPORARY
TABLE_PRIVILEGES TEMPORARY
TABLE_CONSTRAINTS TEMPORARY
TRIGGERS TEMPORARY
create table t1(a int);
ERROR 42S02: Unknown table 't1' in information_schema
use test;
@ -596,6 +605,7 @@ Tables_in_information_schema (T%)
TABLES
TABLE_PRIVILEGES
TABLE_CONSTRAINTS
TRIGGERS
select table_name from tables where table_name='user';
table_name
user
@ -690,7 +700,7 @@ CREATE TABLE t_crashme ( f1 BIGINT);
CREATE VIEW a1 (t_CRASHME) AS SELECT f1 FROM t_crashme GROUP BY f1;
CREATE VIEW a2 AS SELECT t_CRASHME FROM a1;
count(*)
100
101
drop view a2, a1;
drop table t_crashme;
select table_schema,table_name, column_name from
@ -701,6 +711,8 @@ information_schema COLUMNS COLUMN_TYPE
information_schema ROUTINES ROUTINE_DEFINITION
information_schema ROUTINES SQL_MODE
information_schema VIEWS VIEW_DEFINITION
information_schema TRIGGERS ACTION_CONDITION
information_schema TRIGGERS ACTION_STATEMENT
select table_name, column_name, data_type from information_schema.columns
where data_type = 'datetime';
table_name column_name data_type
@ -709,6 +721,7 @@ TABLES UPDATE_TIME datetime
TABLES CHECK_TIME datetime
ROUTINES CREATED datetime
ROUTINES LAST_ALTERED datetime
TRIGGERS CREATED datetime
SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES A
WHERE NOT EXISTS
(SELECT * FROM INFORMATION_SCHEMA.COLUMNS B
@ -755,8 +768,71 @@ delete from mysql.db where user='mysqltest_4';
flush privileges;
SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;
table_schema count(*)
information_schema 15
information_schema 16
mysql 17
create table t1 (i int, j int);
create trigger trg1 before insert on t1 for each row
begin
if new.j > 10 then
set new.j := 10;
end if;
end|
create trigger trg2 before update on t1 for each row
begin
if old.i % 2 = 0 then
set new.j := -1;
end if;
end|
create trigger trg3 after update on t1 for each row
begin
if new.j = -1 then
set @fired:= "Yes";
end if;
end|
show triggers;
Trigger Event Table Statement Timing Created
trg1 INSERT t1
begin
if new.j > 10 then
set new.j := 10;
end if;
end BEFORE NULL
trg2 UPDATE t1
begin
if old.i % 2 = 0 then
set new.j := -1;
end if;
end BEFORE NULL
trg3 UPDATE t1
begin
if new.j = -1 then
set @fired:= "Yes";
end if;
end AFTER NULL
select * from information_schema.triggers;
TRIGGER_CATALOG TRIGGER_SCHEMA TRIGGER_NAME EVENT_MANIPULATION EVENT_OBJECT_CATALOG EVENT_OBJECT_SCHEMA EVENT_OBJECT_TABLE ACTION_ORDER ACTION_CONDITION ACTION_STATEMENT ACTION_ORIENTATION ACTION_TIMING ACTION_REFERENCE_OLD_TABLE ACTION_REFERENCE_NEW_TABLE ACTION_REFERENCE_OLD_ROW ACTION_REFERENCE_NEW_ROW CREATED
NULL test trg1 INSERT NULL test t1 0 NULL
begin
if new.j > 10 then
set new.j := 10;
end if;
end ROW BEFORE NULL NULL OLD NEW NULL
NULL test trg2 UPDATE NULL test t1 0 NULL
begin
if old.i % 2 = 0 then
set new.j := -1;
end if;
end ROW BEFORE NULL NULL OLD NEW NULL
NULL test trg3 UPDATE NULL test t1 0 NULL
begin
if new.j = -1 then
set @fired:= "Yes";
end if;
end ROW AFTER NULL NULL OLD NEW NULL
drop trigger trg1;
drop trigger trg2;
drop trigger trg3;
drop table t1;
create database mysqltest;
create table mysqltest.t1 (f1 int, f2 int);
create table mysqltest.t2 (f1 int);
@ -841,3 +917,26 @@ drop procedure p2;
show create database information_schema;
Database Create Database
information_schema CREATE DATABASE `information_schema` /*!40100 DEFAULT CHARACTER SET utf8 */
create table t1(f1 LONGBLOB, f2 LONGTEXT);
select column_name,data_type,CHARACTER_OCTET_LENGTH,
CHARACTER_MAXIMUM_LENGTH
from information_schema.columns
where table_name='t1';
column_name data_type CHARACTER_OCTET_LENGTH CHARACTER_MAXIMUM_LENGTH
f1 longblob 4294967295 4294967295
f2 longtext 4294967295 4294967295
drop table t1;
create table t1(f1 tinyint, f2 SMALLINT, f3 mediumint, f4 int,
f5 BIGINT, f6 BIT, f7 bit(64));
select column_name, NUMERIC_PRECISION, NUMERIC_SCALE
from information_schema.columns
where table_name='t1';
column_name NUMERIC_PRECISION NUMERIC_SCALE
f1 3 NULL
f2 5 NULL
f3 7 NULL
f4 10 NULL
f5 19 NULL
f6 1 NULL
f7 64 NULL
drop table t1;

View File

@ -16,11 +16,13 @@ TABLE_PRIVILEGES
COLUMN_PRIVILEGES
TABLE_CONSTRAINTS
KEY_COLUMN_USAGE
TRIGGERS
show tables from INFORMATION_SCHEMA like 'T%';
Tables_in_information_schema (T%)
TABLES
TABLE_PRIVILEGES
TABLE_CONSTRAINTS
TRIGGERS
create database `inf%`;
use `inf%`;
show tables;

View File

@ -577,3 +577,15 @@ id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 10 Using filesort
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (a INT(10) NOT NULL, b INT(10) NOT NULL);
INSERT INTO t1 VALUES (1, 1);
INSERT INTO t1 VALUES (1, 2);
SELECT a, b, a AS c, COUNT(*) AS count FROM t1 GROUP BY a, b, c WITH ROLLUP;
a b c count
1 1 1 1
1 1 NULL 1
1 2 1 1
1 2 NULL 1
1 NULL NULL 2
NULL NULL NULL 2
DROP TABLE t1;

View File

@ -775,3 +775,28 @@ ERROR 42000: You have an error in your SQL syntax; check the manual that corresp
select ? 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 '? from t1' at line 1
drop table t1;
prepare stmt from "select @@time_zone";
execute stmt;
@@time_zone
SYSTEM
set @@time_zone:='Japan';
execute stmt;
@@time_zone
Japan
prepare stmt from "select @@tx_isolation";
execute stmt;
@@tx_isolation
REPEATABLE-READ
set transaction isolation level read committed;
execute stmt;
@@tx_isolation
READ-COMMITTED
set transaction isolation level serializable;
execute stmt;
@@tx_isolation
SERIALIZABLE
set @@tx_isolation=default;
execute stmt;
@@tx_isolation
REPEATABLE-READ
deallocate prepare stmt;

View File

@ -744,3 +744,27 @@ a b
1 3
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (name varchar(15) NOT NULL, KEY idx(name));
INSERT INTO t1 VALUES ('Betty'), ('Anna');
SELECT * FROM t1;
name
Anna
Betty
DELETE FROM t1 WHERE name NOT LIKE 'A%a';
SELECT * FROM t1;
name
Anna
DROP TABLE t1;
CREATE TABLE t1 (a int, KEY idx(a));
INSERT INTO t1 VALUES (NULL), (1), (2), (3);
SELECT * FROM t1;
a
NULL
1
2
3
DELETE FROM t1 WHERE NOT(a <=> 2);
SELECT * FROM t1;
a
2
DROP TABLE t1;

View File

@ -69,12 +69,12 @@ master-bin.000002 346 Query 1 434 use `test`; insert into t1 values (1)
master-bin.000002 434 Query 1 510 use `test`; drop table t1
show binary logs;
Log_name File_size
master-bin.000001 0
master-bin.000001 1389
master-bin.000002 510
start slave;
show binary logs;
Log_name File_size
slave-bin.000001 0
slave-bin.000001 1559
slave-bin.000002 348
show binlog events in 'slave-bin.000001' from 4;
Log_name Pos Event_type Server_id End_log_pos Info

View File

@ -27,8 +27,8 @@ insert into t2 values (34),(67),(123);
flush logs;
show binary logs;
Log_name File_size
master-bin.000001 0
master-bin.000002 0
master-bin.000001 592
master-bin.000002 363
master-bin.000003 98
create table t3 select * from temp_table;
select * from t3;
@ -43,12 +43,12 @@ start slave;
purge master logs to 'master-bin.000002';
show master logs;
Log_name File_size
master-bin.000002 0
master-bin.000002 363
master-bin.000003 407
purge binary logs to 'master-bin.000002';
show binary logs;
Log_name File_size
master-bin.000002 0
master-bin.000002 363
master-bin.000003 407
purge master logs before now();
show binary logs;
@ -74,8 +74,8 @@ count(*)
create table t4 select * from temp_table;
show binary logs;
Log_name File_size
master-bin.000003 0
master-bin.000004 0
master-bin.000003 4185
master-bin.000004 4190
master-bin.000005 2032
show master status;
File Position Binlog_Do_DB Binlog_Ignore_DB

View File

@ -237,7 +237,7 @@ select * from t1;
a
10
delete from t1;
drop trigger t1.trg;
drop trigger trg;
insert into t1 values (1);
select * from t1;
a
@ -248,7 +248,7 @@ master-bin.000002 # Query 1 # use `mysqltest1`; delete from t1
master-bin.000002 # Query 1 # use `mysqltest1`; create trigger trg before insert on t1 for each row set new.a= 10
master-bin.000002 # Query 1 # use `mysqltest1`; insert into t1 values (1)
master-bin.000002 # Query 1 # use `mysqltest1`; delete from t1
master-bin.000002 # Query 1 # use `mysqltest1`; drop trigger t1.trg
master-bin.000002 # Query 1 # use `mysqltest1`; drop trigger trg
master-bin.000002 # Query 1 # use `mysqltest1`; insert into t1 values (1)
select * from t1;
a

View File

@ -2746,3 +2746,42 @@ WHERE
COUNT(*)
4
drop table t1,t2,t3;
create table t1 (f1 int);
insert into t1 values (1),(NULL);
create table t2 (f2 int, f3 int, f4 int);
create index idx1 on t2 (f4);
insert into t2 values (1,2,3),(2,4,6);
select A.f2 from t1 left join t2 A on A.f2 = f1 where A.f3=(select min(f3)
from t2 C where A.f4 = C.f4) or A.f3 IS NULL;
f2
1
NULL
drop table t1,t2;
create table t2 (a tinyint unsigned);
create index t2i on t2(a);
insert into t2 values (0), (254), (255);
explain select * from t2 where a > -1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index t2i t2i 2 NULL 3 Using where; Using index
select * from t2 where a > -1;
a
0
254
255
drop table t2;
CREATE TABLE t1 (a int, b int, c int);
INSERT INTO t1
SELECT 50, 3, 3 FROM DUAL
WHERE NOT EXISTS
(SELECT * FROM t1 WHERE a = 50 AND b = 3);
SELECT * FROM t1;
a b c
50 3 3
INSERT INTO t1
SELECT 50, 3, 3 FROM DUAL
WHERE NOT EXISTS
(SELECT * FROM t1 WHERE a = 50 AND b = 3);
SELECT * FROM t1;
a b c
50 3 3
DROP TABLE t1;

View File

@ -212,3 +212,27 @@ REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1@localhost;
drop function bug_9503;
use test;
drop database mysqltest;
use test;
select current_user();
current_user()
root@localhost
select user();
user()
root@localhost
create procedure bug7291_0 () sql security invoker select current_user(), user();
create procedure bug7291_1 () sql security definer call bug7291_0();
create procedure bug7291_2 () sql security invoker call bug7291_0();
grant execute on procedure bug7291_0 to user1@localhost;
grant execute on procedure bug7291_1 to user1@localhost;
grant execute on procedure bug7291_2 to user1@localhost;
call bug7291_2();
current_user() user()
user1@localhost user1@localhost
call bug7291_1();
current_user() user()
root@localhost user1@localhost
drop procedure bug7291_1;
drop procedure bug7291_2;
drop procedure bug7291_0;
REVOKE ALL PRIVILEGES, GRANT OPTION FROM user1@localhost;
drop user user1@localhost;

View File

@ -2657,16 +2657,22 @@ end|
call avg ()|
drop procedure avg|
drop procedure if exists bug6129|
set @@sql_mode = 'traditional'|
create procedure bug6129(mode text)
select @@sql_mode = mode|
call bug6129(@@sql_mode)|
@@sql_mode = mode
1
set @@sql_mode = ''|
call bug6129(@@sql_mode)|
@@sql_mode = mode
0
set @old_mode= @@sql_mode;
set @@sql_mode= "";
create procedure bug6129()
select @@sql_mode|
call bug6129()|
@@sql_mode
set @@sql_mode= "NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO"|
call bug6129()|
@@sql_mode
NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO
set @@sql_mode= "NO_ZERO_IN_DATE"|
call bug6129()|
@@sql_mode
NO_ZERO_IN_DATE
set @@sql_mode=@old_mode;
drop procedure bug6129|
drop procedure if exists bug9856|
create procedure bug9856()
@ -3079,4 +3085,18 @@ one 1
delete from t1|
drop procedure bug9565_sub|
drop procedure bug9565|
drop procedure if exists bug9538|
create procedure bug9538()
set @@sort_buffer_size = 1000000|
set @x = @@sort_buffer_size|
set @@sort_buffer_size = 2000000|
select @@sort_buffer_size|
@@sort_buffer_size
2000000
call bug9538()|
select @@sort_buffer_size|
@@sort_buffer_size
1000000
set @@sort_buffer_size = @x|
drop procedure bug9538|
drop table t1,t2;

View File

@ -47,6 +47,13 @@ select * from mysql.time_zone_name;
ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'time_zone_name'
select Name, convert_tz('2004-11-30 12:00:00', Name, 'UTC') from mysql.time_zone_name;
ERROR 42000: SELECT command denied to user 'mysqltest_1'@'localhost' for table 'time_zone_name'
drop table t1, t2;
create table t1 (a int, b datetime);
create table t2 (a int, b varchar(40));
update t1 set b = '2005-01-01 10:00';
update t1 set b = convert_tz(b, 'UTC', 'UTC');
update t1 join t2 on (t1.a = t2.a) set t1.b = '2005-01-01 10:00' where t2.b = 'foo';
update t1 join t2 on (t1.a = t2.a) set t1.b = convert_tz('2005-01-01 10:00','UTC','UTC') where t2.b = 'foo';
delete from mysql.user where user like 'mysqltest\_%';
delete from mysql.db where user like 'mysqltest\_%';
delete from mysql.tables_priv where user like 'mysqltest\_%';

View File

@ -12,13 +12,13 @@ insert into t1 values (1);
select @a;
@a
1
drop trigger t1.trg;
drop trigger trg;
create trigger trg before insert on t1 for each row set @a:=new.i;
insert into t1 values (123);
select @a;
@a
123
drop trigger t1.trg;
drop trigger trg;
drop table t1;
create table t1 (i int not null, j int);
create trigger trg before insert on t1 for each row
@ -33,7 +33,7 @@ select * from t1|
i j
1 10
2 3
drop trigger t1.trg|
drop trigger trg|
drop table t1|
create table t1 (i int not null primary key);
create trigger trg after insert on t1 for each row
@ -43,7 +43,7 @@ insert into t1 values (2),(3),(4),(5);
select @a;
@a
2:3:4:5
drop trigger t1.trg;
drop trigger trg;
drop table t1;
create table t1 (aid int not null primary key, balance int not null default 0);
insert into t1 values (1, 1000), (2,3000);
@ -65,7 +65,7 @@ Too big change for aid = 2
aid balance
1 1500
2 3000
drop trigger t1.trg|
drop trigger trg|
drop table t1|
create table t1 (i int);
insert into t1 values (1),(2),(3),(4);
@ -76,7 +76,7 @@ update t1 set i=3;
select @total_change;
@total_change
2
drop trigger t1.trg;
drop trigger trg;
drop table t1;
create table t1 (i int);
insert into t1 values (1),(2),(3),(4);
@ -87,7 +87,7 @@ delete from t1 where i <= 3;
select @del_sum;
@del_sum
6
drop trigger t1.trg;
drop trigger trg;
drop table t1;
create table t1 (i int);
insert into t1 values (1),(2),(3),(4);
@ -97,7 +97,7 @@ delete from t1 where i <> 0;
select @del;
@del
1
drop trigger t1.trg;
drop trigger trg;
drop table t1;
create table t1 (i int, j int);
create trigger trg1 before insert on t1 for each row
@ -137,9 +137,9 @@ i j
1 20
2 -1
3 20
drop trigger t1.trg1;
drop trigger t1.trg2;
drop trigger t1.trg3;
drop trigger trg1;
drop trigger trg2;
drop trigger trg3;
drop table t1;
create table t1 (id int not null primary key, data int);
create trigger t1_bi before insert on t1 for each row
@ -197,7 +197,7 @@ select * from t2;
event
INSERT INTO t1 id=1 data='one'
INSERT INTO t1 id=2 data='two'
drop trigger t1.t1_ai;
drop trigger t1_ai;
create trigger t1_bi before insert on t1 for each row
begin
if exists (select id from t3 where id=new.fk) then
@ -271,6 +271,7 @@ id copy
3 NULL
drop table t1, t2;
create table t1 (i int);
create table t3 (i int);
create trigger trg before insert on t1 for each row set @a:= old.i;
ERROR HY000: There is no OLD row in on INSERT trigger
create trigger trg before delete on t1 for each row set @a:= new.i;
@ -292,14 +293,19 @@ create trigger trg after insert on t1 for each row set @a:=1;
ERROR HY000: Trigger already exists
create trigger trg2 before insert on t1 for each row set @a:=1;
ERROR HY000: Trigger already exists
drop trigger t1.trg;
drop trigger t1.trg;
create trigger trg before insert on t3 for each row set @a:=1;
ERROR HY000: Trigger already exists
create trigger trg2 before insert on t3 for each row set @a:=1;
drop trigger trg2;
drop trigger trg;
drop trigger trg;
ERROR HY000: Trigger does not exist
create view v1 as select * from t1;
create trigger trg before insert on v1 for each row set @a:=1;
ERROR HY000: 'test.v1' is not BASE TABLE
drop view v1;
drop table t1;
drop table t3;
create temporary table t1 (i int);
create trigger trg before insert on t1 for each row set @a:=1;
ERROR HY000: Trigger's 't1' is view or temporary table
@ -307,7 +313,7 @@ drop table t1;
create table t1 (x1col char);
create trigger tx1 before insert on t1 for each row set new.x1col = 'x';
insert into t1 values ('y');
drop trigger t1.tx1;
drop trigger tx1;
drop table t1;
create table t1 (i int) engine=myisam;
insert into t1 values (1), (2);
@ -318,8 +324,8 @@ delete from t1;
select @del_before, @del_after;
@del_before @del_after
3 3
drop trigger t1.trg1;
drop trigger t1.trg2;
drop trigger trg1;
drop trigger trg2;
drop table t1;
create table t1 (a int);
create trigger trg1 before insert on t1 for each row set new.a= 10;
@ -336,6 +342,15 @@ create table t1 (i int);
create trigger trg1 before insert on t1 for each row set @a:= 1;
drop database mysqltest;
use test;
create database mysqltest;
create table mysqltest.t1 (i int);
create trigger trg1 before insert on mysqltest.t1 for each row set @a:= 1;
ERROR HY000: Trigger in wrong schema
use mysqltest;
create trigger test.trg1 before insert on t1 for each row set @a:= 1;
ERROR HY000: Trigger in wrong schema
drop database mysqltest;
use test;
create table t1 (i int, j int default 10, k int not null, key (k));
create table t2 (i int);
insert into t1 (i, k) values (1, 1);
@ -549,7 +564,7 @@ i k
1 1
2 2
alter table t1 add primary key (i);
drop trigger t1.bi;
drop trigger bi;
insert into t1 values (2, 4) on duplicate key update k= k + 10;
ERROR 42S22: Unknown column 'bt' in 'NEW'
select * from t1;
@ -578,5 +593,5 @@ create trigger t1_bu before update on t1 for each row set new.col1= bug5893();
drop function bug5893;
update t1 set col2 = 4;
ERROR 42000: FUNCTION test.bug5893 does not exist
drop trigger t1.t1_bu;
drop trigger t1_bu;
drop table t1;

View File

@ -240,3 +240,14 @@ update t1, t2 set t1.a = t2.a where t2.b = t1.b;
show warnings;
Level Code Message
drop table t1, t2;
create table t1(f1 int, f2 int);
create table t2(f3 int, f4 int);
create index idx on t2(f3);
insert into t1 values(1,0),(2,0);
insert into t2 values(1,1),(2,2);
UPDATE t1 SET t1.f2=(SELECT MAX(t2.f4) FROM t2 WHERE t2.f3=t1.f1);
select * from t1;
f1 f2
1 1
2 2
drop table t1,t2;

View File

@ -1245,7 +1245,7 @@ select * from v1;
s1
select * from t1;
s1
drop trigger t1.t1_bi;
drop trigger t1_bi;
drop view v1;
drop table t1;
create table t1 (s1 tinyint);
@ -1831,6 +1831,31 @@ select * from v1;
t
01:00
drop view v1;
create table t1 (a timestamp default now());
create table t2 (b timestamp default now());
create view v1 as select a,b,t1.a < now() from t1,t2 where t1.a < now();
SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select sql_no_cache `test`.`t1`.`a` AS `a`,`test`.`t2`.`b` AS `b`,(`test`.`t1`.`a` < now()) AS `t1.a < now()` from (`test`.`t1` join `test`.`t2`) where (`test`.`t1`.`a` < now())
drop view v1;
drop table t1, t2;
CREATE TABLE t1 ( a varchar(50) );
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = CURRENT_USER();
SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select sql_no_cache `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = current_user())
DROP VIEW v1;
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = VERSION();
SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = version())
DROP VIEW v1;
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a = DATABASE();
SHOW CREATE VIEW v1;
View Create View
v1 CREATE ALGORITHM=UNDEFINED VIEW `test`.`v1` AS select sql_no_cache `test`.`t1`.`a` AS `a` from `test`.`t1` where (`test`.`t1`.`a` = database())
DROP VIEW v1;
DROP TABLE t1;
CREATE TABLE t1 (col1 time);
CREATE TABLE t2 (col1 time);
CREATE VIEW v1 AS SELECT CONVERT_TZ(col1,'GMT','MET') FROM t1;

View File

@ -346,6 +346,18 @@ DROP TABLE t2;
DROP TABLE t3;
DROP TABLE t4;
#Test bug#11717
CREATE TABLE t1(c1 varchar(10)) default character set = eucjpms;
insert into t1 values(_ucs2 0x00F7);
insert into t1 values(_eucjpms 0xA1E0);
insert into t1 values(_ujis 0xA1E0);
insert into t1 values(_sjis 0x8180);
insert into t1 values(_cp932 0x8180);
SELECT HEX(c1) FROM t1;
DROP TABLE t1;
SET collation_connection='eucjpms_japanese_ci';
-- source include/ctype_filesort.inc

View File

@ -1,19 +1,7 @@
--source include/have_federated_db.inc
source include/master-slave.inc;
# remote table creation
source include/federated.inc;
connection slave;
--replicate-ignore-db=federated
stop slave;
--disable_warnings
# at this point, we are connected to master
DROP DATABASE IF EXISTS federated;
--enable_warnings
CREATE DATABASE federated;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default ''
@ -21,14 +9,10 @@ CREATE TABLE federated.t1 (
DEFAULT CHARSET=latin1;
connection master;
--disable_warnings
DROP DATABASE IF EXISTS federated;
--enable_warnings
CREATE DATABASE federated;
DROP TABLE IF EXISTS federated.t1;
# test too many items (malformed) in the comment string url
--error 1005
eval CREATE TABLE federated.t1 (
--error 1432
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default ''
)
@ -36,8 +20,8 @@ eval CREATE TABLE federated.t1 (
COMMENT='mysql://root@127.0.0.1:@/too/many/items/federated/t1';
# test not enough items (malformed) in the comment string url
--error 1005
eval CREATE TABLE federated.t1 (
--error 1432
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default ''
)
@ -46,7 +30,7 @@ eval CREATE TABLE federated.t1 (
# test non-existant table
--replace_result $SLAVE_MYPORT SLAVE_PORT
--error 1219
--error 1434
eval CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default ''
@ -56,7 +40,7 @@ eval CREATE TABLE federated.t1 (
# test bad user/password
--replace_result $SLAVE_MYPORT SLAVE_PORT
--error 1218
--error 1429
eval CREATE TABLE federated.t1 (
`id` int(20) NOT NULL,
`name` varchar(32) NOT NULL default ''
@ -150,12 +134,9 @@ CREATE TABLE federated.t1 (
`name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0',
`created` datetime default '2004-04-04 04:04:04',
PRIMARY KEY (`id`),
KEY `name` (`name`),
KEY `other_key` (`other`))
PRIMARY KEY (`id`))
DEFAULT CHARSET=latin1;
connection master;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE federated.t1 (
@ -163,9 +144,7 @@ eval CREATE TABLE federated.t1 (
`name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0',
`created` datetime default '2004-04-04 04:04:04',
PRIMARY KEY (`id`),
KEY `name` (`name`),
KEY `other_key` (`other`))
PRIMARY KEY (`id`))
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
@ -184,8 +163,84 @@ INSERT INTO federated.t1 (name, other) VALUES ('Tenth Name', 101010);
SELECT * FROM federated.t1;
# with PRIMARY KEY index_read_idx
SELECT * FROM federated.t1 WHERE id = 5;
# with regular key index_read -> index_read_idx
SELECT * FROM federated.t1 WHERE name = 'Sixth Name';
SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name';
SELECT * FROM federated.t1 WHERE name = 'Sixth Name' AND other = 44444;
SELECT * FROM federated.t1 WHERE name like '%th%';
UPDATE federated.t1 SET name = '3rd name' WHERE id = 3;
SELECT * FROM federated.t1 WHERE name = '3rd name';
UPDATE federated.t1 SET name = 'Third name' WHERE name = '3rd name';
SELECT * FROM federated.t1 WHERE name = 'Third name';
# rnd_post, ::position
SELECT * FROM federated.t1 ORDER BY id DESC;
SELECT * FROM federated.t1 ORDER BY name;
SELECT * FROM federated.t1 ORDER BY name DESC;
SELECT * FROM federated.t1 ORDER BY name ASC;
SELECT * FROM federated.t1 GROUP BY other;
# ::delete_row
DELETE FROM federated.t1 WHERE id = 5;
SELECT * FROM federated.t1 WHERE id = 5;
# ::delete_all_rows
DELETE FROM federated.t1;
SELECT * FROM federated.t1 WHERE id = 5;
# previous test, but this time with indexes
connection slave;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int(20) NOT NULL auto_increment,
`name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0',
`created` datetime NOT NULL,
PRIMARY KEY (`id`),
key name(`name`),
key other(`other`),
key created(`created`))
DEFAULT CHARSET=latin1;
connection master;
DROP TABLE IF EXISTS federated.t1;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE federated.t1 (
`id` int(20) NOT NULL auto_increment,
`name` varchar(32) NOT NULL default '',
`other` int(20) NOT NULL default '0',
`created` datetime NOT NULL,
PRIMARY KEY (`id`),
key name(`name`),
key other(`other`),
key created(`created`))
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
INSERT INTO federated.t1 (name, other, created)
VALUES ('First Name', 11111, '2004-01-01 01:01:01');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Second Name', 22222, '2004-01-23 02:43:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Third Name', 33333, '2004-02-14 02:14:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Fourth Name', 44444, '2003-04-05 00:00:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Fifth Name', 55555, '2001-02-02 02:02:02');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Sixth Name', 66666, '2005-06-06 15:30:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Seventh Name', 77777, '2003-12-12 18:32:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Eigth Name', 88888, '2005-03-12 11:00:00');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Ninth Name', 99999, '2005-03-12 11:00:01');
INSERT INTO federated.t1 (name, other, created)
VALUES ('Tenth Name', 101010, '2005-03-12 12:00:01');
# basic select
SELECT * FROM federated.t1;
# with PRIMARY KEY index_read_idx
SELECT * FROM federated.t1 WHERE id = 5;
# with regular key index_read -> index_read_idx
# regular and PRIMARY KEY index_read_idx
SELECT * FROM federated.t1 WHERE id = 6 and name = 'Sixth Name';
# with regular key index_read -> index_read_idx
@ -211,7 +266,6 @@ SELECT * FROM federated.t1 WHERE id = 5;
# ::delete_all_rows
DELETE FROM federated.t1;
SELECT * FROM federated.t1 WHERE id = 5;
connection slave;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
@ -253,8 +307,7 @@ SET name = 'Fourth Name', other = 'four four four'
WHERE name IS NULL AND other IS NULL;
UPDATE federated.t1 SET other = 'two two two two' WHERE name = 'Second Name';
UPDATE federated.t1 SET other = 'seven seven' WHERE name like 'Sec%';
UPDATE federated.t1 SET other = 'seven seven' WHERE name = 'Seventh Name';
UPDATE federated.t1 SET other = 'seven seven' WHERE name like 'Sev%';
UPDATE federated.t1 SET name = 'Tenth Name' WHERE other like 'fee fie%';
SELECT * FROM federated.t1 WHERE name IS NULL OR other IS NULL ;
SELECT * FROM federated.t1;
@ -338,6 +391,201 @@ SELECT * FROM federated.t1 WHERE name='third';
SELECT * FROM federated.t1 WHERE other=2222;
SELECT * FROM federated.t1 WHERE name='third' and other=2222;
# more multi-column indexes, in the primary key
connection slave;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`id` int NOT NULL auto_increment,
`col1` int(10) NOT NULL DEFAULT 0,
`col2` varchar(64) NOT NULL DEFAULT '',
`col3` int(20) NOT NULL,
`col4` int(40) NOT NULL,
primary key (`id`, `col1`, `col2`, `col3`, `col4`),
key col1(col1),
key col2(col2),
key col3(col3),
key col4(col4));
connection master;
DROP TABLE IF EXISTS federated.t1;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE federated.t1 (
`id` int NOT NULL auto_increment,
`col1` int(10) NOT NULL DEFAULT 0,
`col2` varchar(64) NOT NULL DEFAULT '',
`col3` int(20) NOT NULL,
`col4` int(40) NOT NULL,
primary key (`id`, `col1`, `col2`, `col3`, `col4`),
key col1(col1),
key col2(col2),
key col3(col3),
key col4(col4))
ENGINE="FEDERATED"
COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (1, 'one One', 11, 1111);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (2, 'Two two', 22, 2222);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (3, 'three Three', 33, 33333);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (4, 'fourfourfour', 444, 4444444);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (5, 'five 5 five five 5', 5, 55555);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (6, 'six six Sixsix', 6666, 6);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (7, 'seven Sevenseven', 77777, 7777);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (8, 'eight eight eight', 88888, 88);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (9, 'nine Nine', 999999, 999999);
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES (10, 'Tenth ten TEN', 1010101, 1010);
SELECT * FROM federated.t1 WHERE col2 = 'two two';
SELECT * FROM federated.t1 WHERE col2 = 'two Two';
SELECT * FROM federated.t1 WHERE id = 3;
SELECT * FROM federated.t1 WHERE id = 3 AND col1 = 3;
SELECT * FROM federated.t1 WHERE id = 4 AND col1 = 4 AND col2 = 'Two two';
SELECT * FROM federated.t1 WHERE id = 4 AND col1 = 4 AND col2 = 'fourfourfour';
SELECT * FROM federated.t1 WHERE id = 5 AND col2 = 'five 5 five five 5'
AND col3 = 5;
SELECT * FROM federated.t1 WHERE id = 5 AND col2 = 'five 5 five five 5'
AND col3 = 5
AND col4 = 55555;
SELECT * FROM federated.t1 WHERE id = 5
AND col2 = 'Two two' AND col3 = 22
AND col4 = 33;
SELECT * FROM federated.t1 WHERE id = 5
AND col2 = 'five 5 five five 5' AND col3 = 5
AND col4 = 55555;
SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'five 5 five five 5')
OR (col2 = 'three Three' AND col3 = 33);
SELECT * FROM federated.t1 WHERE (id = 5 AND col2 = 'Two two')
OR (col2 = 444 AND col3 = 4444444);
SELECT * FROM federated.t1 WHERE id = 1
OR col1 = 10
OR col2 = 'Two two'
OR col3 = 33
OR col4 = 4444444;
SELECT * FROM federated.t1 WHERE id > 5;
SELECT * FROM federated.t1 WHERE id >= 5;
SELECT * FROM federated.t1 WHERE id < 5;
SELECT * FROM federated.t1 WHERE id <= 5;
SELECT * FROM federated.t1 WHERE id != 5;
SELECT * FROM federated.t1 WHERE id > 3 AND id < 7;
SELECT * FROM federated.t1 WHERE id > 3 AND id <= 7;
SELECT * FROM federated.t1 WHERE id >= 3 AND id <= 7;
SELECT * FROM federated.t1 WHERE id < 3 AND id <= 7;
SELECT * FROM federated.t1 WHERE id < 3 AND id > 7;
SELECT * FROM federated.t1 WHERE id < 3 OR id > 7;
SELECT * FROM federated.t1 WHERE col2 = 'three Three';
SELECT * FROM federated.t1 WHERE col2 > 'one';
SELECT * FROM federated.t1 WHERE col2 LIKE 's%';
SELECT * FROM federated.t1 WHERE col2 LIKE 'si%';
SELECT * FROM federated.t1 WHERE col2 LIKE 'se%';
SELECT * FROM federated.t1 WHERE col2 NOT LIKE 'e%';
SELECT * FROM federated.t1 WHERE col2 <> 'one One';
# more multi-column indexes, in the primary key
connection slave;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` varchar(128) NOT NULL DEFAULT '',
`col3` varchar(20) NOT NULL DEFAULT '',
`col4` varchar(40) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`, `col4`),
key 3key(`col2`,`col3`,`col4`),
key 2key (`col3`,`col4`),
key col4(col4));
connection master;
DROP TABLE IF EXISTS federated.t1;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` varchar(128) NOT NULL DEFAULT '',
`col3` varchar(20) NOT NULL DEFAULT '',
`col4` varchar(40) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`, `col4`),
key 3key(`col2`,`col3`,`col4`),
key 2key (`col3`,`col4`),
key col4(col4))
ENGINE="FEDERATED"
COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('aaaa', 'aaaaaaaaaaaaaaaaaaa', 'ababababab', 'acacacacacacacac');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('bbbb', 'bbbbbbbbbbbbbbbbbbb', 'bababababa', 'bcbcbcbcbcbcbcbc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('cccc', 'ccccccccccccccccccc', 'cacacacaca', 'cbcbcbcbcbcbcbcb');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('dddd', 'ddddddddddddddddddd', 'dadadadada', 'dcdcdcdcdcdcdcdc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('eeee', 'eeeeeeeeeeeeeeeeeee', 'eaeaeaeaea', 'ecececececececec');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('ffff', 'fffffffffffffffffff', 'fafafafafa', 'fcfcfcfcfcfcfcfc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('gggg', 'ggggggggggggggggggg', 'gagagagaga', 'gcgcgcgcgcgcgcgc');
INSERT INTO federated.t1 (col1, col2, col3, col4)
VALUES ('hhhh', 'hhhhhhhhhhhhhhhhhhh', 'hahahahaha', 'hchchchchchchchc');
SELECT * FROM federated.t1 WHERE col1 = 'cccc';
SELECT * FROM federated.t1 WHERE col2 = 'eeeeeeeeeeeeeeeeeee';
SELECT * FROM federated.t1 WHERE col3 = 'bababababa';
SELECT * FROM federated.t1 WHERE col1 = 'gggg' AND col2 = 'ggggggggggggggggggg';
SELECT * FROM federated.t1 WHERE col1 = 'gggg' AND col3 = 'gagagagaga';
SELECT * FROM federated.t1 WHERE col1 = 'ffff' AND col4 = 'fcfcfcfcfcfcfcfc';
SELECT * FROM federated.t1 WHERE col1 > 'bbbb';
SELECT * FROM federated.t1 WHERE col1 >= 'bbbb';
SELECT * FROM federated.t1 WHERE col1 < 'bbbb';
SELECT * FROM federated.t1 WHERE col1 <= 'bbbb';
SELECT * FROM federated.t1 WHERE col1 <> 'bbbb';
SELECT * FROM federated.t1 WHERE col1 LIKE 'b%';
SELECT * FROM federated.t1 WHERE col4 LIKE '%b%';
SELECT * FROM federated.t1 WHERE col1 NOT LIKE 'c%';
SELECT * FROM federated.t1 WHERE col4 NOT LIKE '%c%';
connection slave;
DROP TABLE IF EXISTS federated.t1;
CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` int(8) NOT NULL DEFAULT 0,
`col3` varchar(8) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`));
connection master;
DROP TABLE IF EXISTS federated.t1;
--replace_result $SLAVE_MYPORT SLAVE_PORT
eval CREATE TABLE federated.t1 (
`col1` varchar(8) NOT NULL DEFAULT '',
`col2` varchar(8) NOT NULL DEFAULT '',
`col3` varchar(8) NOT NULL DEFAULT '',
primary key (`col1`, `col2`, `col3`))
ENGINE="FEDERATED"
DEFAULT CHARSET=latin1
COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
INSERT INTO federated.t1 VALUES ('a00', '110', 'cc0');
INSERT INTO federated.t1 VALUES ('aaa', '111', 'ccc');
INSERT INTO federated.t1 VALUES ('bbb', '222', 'yyy');
INSERT INTO federated.t1 VALUES ('ccc', '111', 'zzz');
INSERT INTO federated.t1 VALUES ('ccd', '112', 'zzzz');
# let's see what the foreign database says
connection slave;
SELECT col3 FROM federated.t1 WHERE (
(col1 = 'aaa' AND col2 >= '111') OR col1 > 'aaa') AND
(col1 < 'ccc' OR ( col1 = 'ccc' AND col2 <= '111'));
connection master;
SELECT col3 FROM federated.t1 WHERE (
(col1 = 'aaa' AND col2 >= '111') OR col1 > 'aaa') AND
(col1 < 'ccc' OR ( col1 = 'ccc' AND col2 <= '111'));
# test NULLs
connection slave;
DROP TABLE IF EXISTS federated.t1;
@ -422,14 +670,6 @@ eval CREATE TABLE federated.t1 (
COMMENT='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
INSERT INTO federated.t1 VALUES (3,3,3),(1,1,1),(2,2,2),(4,4,4);
EXPLAIN SELECT * FROM federated.t1 ORDER BY a;
EXPLAIN SELECT * FROM federated.t1 ORDER BY b;
EXPLAIN SELECT * FROM federated.t1 ORDER BY c;
EXPLAIN SELECT a FROM federated.t1 ORDER BY a;
EXPLAIN SELECT b FROM federated.t1 ORDER BY b;
EXPLAIN SELECT a,b FROM federated.t1 ORDER BY b;
EXPLAIN SELECT a,b FROM federated.t1;
EXPLAIN SELECT a,b,c FROM federated.t1;
connection slave;
DROP TABLE IF EXISTS federated.t1;
@ -862,32 +1102,16 @@ INSERT INTO federated.t1 (name, country_id, other) VALUES ('Monty', 4, 33333);
INSERT INTO federated.t1 (name, country_id, other) VALUES ('Sanja', 5, 33333);
#inner join
EXPLAIN SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1, federated.countries WHERE
federated.t1.country_id = federated.countries.id;
SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1, federated.countries WHERE
federated.t1.country_id = federated.countries.id;
EXPLAIN SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1 INNER JOIN federated.countries ON
federated.t1.country_id = federated.countries.id;
SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1 INNER JOIN federated.countries ON
federated.t1.country_id = federated.countries.id;
EXPLAIN SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1 INNER JOIN federated.countries ON
federated.t1.country_id = federated.countries.id
WHERE federated.t1.name = 'Monty';
SELECT federated.t1.name AS name, federated.t1.country_id AS country_id,
federated.t1.other AS other, federated.countries.country AS country
FROM federated.t1 INNER JOIN federated.countries ON
@ -895,32 +1119,17 @@ federated.t1.country_id = federated.countries.id
WHERE federated.t1.name = 'Monty';
#left join
EXPLAIN SELECT federated.t1.*, federated.countries.country
FROM federated.t1 LEFT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id
ORDER BY federated.countries.id;
SELECT federated.t1.*, federated.countries.country
FROM federated.t1 LEFT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id
ORDER BY federated.countries.id;
EXPLAIN SELECT federated.t1.*, federated.countries.country
FROM federated.t1 LEFT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id
ORDER BY federated.countries.country;
SELECT federated.t1.*, federated.countries.country
FROM federated.t1 LEFT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id
ORDER BY federated.countries.country;
#right join
EXPLAIN SELECT federated.t1.*, federated.countries.country
FROM federated.t1 RIGHT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id
ORDER BY federated.t1.country_id;
SELECT federated.t1.*, federated.countries.country
FROM federated.t1 RIGHT JOIN federated.countries
ON federated.t1.country_id = federated.countries.id
@ -928,14 +1137,11 @@ ORDER BY federated.t1.country_id;
DROP TABLE federated.countries;
connection master;
--disable_warnings
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
--enable_warnings
# optimize and repair tests
OPTIMIZE TABLE federated.t1;
REPAIR TABLE federated.t1;
REPAIR TABLE federated.t1 QUICK;
REPAIR TABLE federated.t1 EXTENDED;
REPAIR TABLE federated.t1 USE_FRM;
connection slave;
--disable_warnings
DROP TABLE IF EXISTS federated.t1;
DROP DATABASE IF EXISTS federated;
--enable_warnings
source include/federated_cleanup.inc;

View File

@ -101,3 +101,21 @@ create table t1 (a char(20) character set binary);
insert into t1 values ('aa'), ('bb');
select * from t1 where a in (NULL, 'aa');
drop table t1;
#
# Bug #11885: WHERE condition with NOT IN (one element)
#
CREATE TABLE t1 (a int PRIMARY KEY);
INSERT INTO t1 VALUES (44), (45), (46);
SELECT * FROM t1 WHERE a IN (45);
SELECT * FROM t1 WHERE a NOT IN (0, 45);
SELECT * FROM t1 WHERE a NOT IN (45);
CREATE VIEW v1 AS SELECT * FROM t1 WHERE a NOT IN (45);
SHOW CREATE VIEW v1;
SELECT * FROM v1;
DROP VIEW v1;
DROP TABLE t1;

View File

@ -157,6 +157,8 @@ select ROUTINE_NAME, ROUTINE_DEFINITION from information_schema.ROUTINES;
show create procedure sel2;
show create function sub1;
show create function sub2;
--replace_column 5 # 6 #
show function status like "sub2";
connection default;
disconnect user1;
drop function sub2;
@ -505,6 +507,41 @@ flush privileges;
#
SELECT table_schema, count(*) FROM information_schema.TABLES GROUP BY TABLE_SCHEMA;
#
# TRIGGERS table test
#
create table t1 (i int, j int);
delimiter |;
create trigger trg1 before insert on t1 for each row
begin
if new.j > 10 then
set new.j := 10;
end if;
end|
create trigger trg2 before update on t1 for each row
begin
if old.i % 2 = 0 then
set new.j := -1;
end if;
end|
create trigger trg3 after update on t1 for each row
begin
if new.j = -1 then
set @fired:= "Yes";
end if;
end|
delimiter ;|
show triggers;
select * from information_schema.triggers;
drop trigger trg1;
drop trigger trg2;
drop trigger trg3;
drop table t1;
#
# Bug #10964 Information Schema:Authorization check on privilege tables is improper
#
@ -569,3 +606,19 @@ drop procedure p2;
# Bug #9434 SHOW CREATE DATABASE information_schema;
#
show create database information_schema;
#
# Bug #11057 information_schema: columns table has some questionable contents
#
create table t1(f1 LONGBLOB, f2 LONGTEXT);
select column_name,data_type,CHARACTER_OCTET_LENGTH,
CHARACTER_MAXIMUM_LENGTH
from information_schema.columns
where table_name='t1';
drop table t1;
create table t1(f1 tinyint, f2 SMALLINT, f3 mediumint, f4 int,
f5 BIGINT, f6 BIT, f7 bit(64));
select column_name, NUMERIC_PRECISION, NUMERIC_SCALE
from information_schema.columns
where table_name='t1';
drop table t1;

View File

@ -266,3 +266,13 @@ EXPLAIN SELECT type FROM v1 GROUP BY type WITH ROLLUP;
DROP VIEW v1;
DROP TABLE t1;
# Test for bug #11543: ROLLUP query with a repeated column in GROUP BY
#
CREATE TABLE t1 (a INT(10) NOT NULL, b INT(10) NOT NULL);
INSERT INTO t1 VALUES (1, 1);
INSERT INTO t1 VALUES (1, 2);
SELECT a, b, a AS c, COUNT(*) AS count FROM t1 GROUP BY a, b, c WITH ROLLUP;
DROP TABLE t1;

View File

@ -811,3 +811,20 @@ select ??;
select ? from t1;
--enable_ps_protocol
drop table t1;
#
# Bug#9359 "Prepared statements take snapshot of system vars at PREPARE
# time"
#
prepare stmt from "select @@time_zone";
execute stmt;
set @@time_zone:='Japan';
execute stmt;
prepare stmt from "select @@tx_isolation";
execute stmt;
set transaction isolation level read committed;
execute stmt;
set transaction isolation level serializable;
execute stmt;
set @@tx_isolation=default;
execute stmt;
deallocate prepare stmt;

View File

@ -553,3 +553,26 @@ SELECT a,b FROM v1 WHERE a < 2 and b=3;
DROP VIEW v1;
DROP TABLE t1;
#
# Bug #11853: DELETE statement with a NOT (LIKE/<=>) where condition
# for an indexed attribute
#
CREATE TABLE t1 (name varchar(15) NOT NULL, KEY idx(name));
INSERT INTO t1 VALUES ('Betty'), ('Anna');
SELECT * FROM t1;
DELETE FROM t1 WHERE name NOT LIKE 'A%a';
SELECT * FROM t1;
DROP TABLE t1;
CREATE TABLE t1 (a int, KEY idx(a));
INSERT INTO t1 VALUES (NULL), (1), (2), (3);
SELECT * FROM t1;
DELETE FROM t1 WHERE NOT(a <=> 2);
SELECT * FROM t1;
DROP TABLE t1;

View File

@ -249,7 +249,7 @@ select * from t1;
connection master;
delete from t1;
drop trigger t1.trg;
drop trigger trg;
insert into t1 values (1);
select * from t1;
--replace_column 2 # 5 #

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