merge
This commit is contained in:
commit
a6c21a0791
@ -1117,3 +1117,5 @@ vio/test-sslclient
|
||||
vio/test-sslserver
|
||||
vio/viotest-ssl
|
||||
ndb/src/dummy.cpp
|
||||
innobase/mkinstalldirs
|
||||
mkinstalldirs
|
||||
|
@ -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"
|
||||
|
@ -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)
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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) ?
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
111
cmd-line-utils/readline/compat.c
Normal file
111
cmd-line-utils/readline/compat.c
Normal 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);
|
||||
}
|
@ -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, "e_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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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 },
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 ();
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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++)
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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];
|
||||
};
|
||||
|
@ -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 *));
|
||||
|
@ -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;
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
38
cmd-line-utils/readline/savestring.c
Normal file
38
cmd-line-utils/readline/savestring.c
Normal 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)));
|
||||
}
|
@ -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)
|
||||
{
|
||||
|
@ -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 */
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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));
|
||||
|
@ -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. */
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
10
configure.in
10
configure.in
@ -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
|
||||
|
@ -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)))
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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 */
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
21
mysql-test/include/federated.inc
Normal file
21
mysql-test/include/federated.inc
Normal 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;
|
11
mysql-test/include/federated_cleanup.inc
Normal file
11
mysql-test/include/federated_cleanup.inc
Normal 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
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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\_%';
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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
Loading…
x
Reference in New Issue
Block a user