Bash-4.2 distribution sources and documentation

This commit is contained in:
Chet Ramey
2011-11-22 19:11:26 -05:00
parent 30d188c293
commit 495aee441b
341 changed files with 108751 additions and 36060 deletions

View File

@@ -83,7 +83,7 @@ CSOURCES = $(srcdir)/readline.c $(srcdir)/funmap.c $(srcdir)/keymaps.c \
$(srcdir)/histfile.c $(srcdir)/nls.c $(srcdir)/search.c \
$(srcdir)/shell.c $(srcdir)/tilde.c $(srcdir)/savestring.c \
$(srcdir)/text.c $(srcdir)/misc.c $(srcdir)/compat.c \
$(srcdir)/mbutil.c
$(srcdir)/mbutil.c $(srcdir)/xfree.c
# The header files for this library.
HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h histlib.h \
@@ -97,7 +97,7 @@ TILDEOBJ = tilde.o
OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \
rltty.o complete.o bind.o isearch.o display.o signals.o \
util.o kill.o undo.o macro.o input.o callback.o terminal.o \
text.o nls.o misc.o $(HISTOBJ) $(TILDEOBJ) xmalloc.o compat.o
text.o nls.o misc.o $(HISTOBJ) $(TILDEOBJ) xmalloc.o xfree.o compat.o
# The texinfo files which document this library.
DOCSOURCE = doc/rlman.texinfo doc/rltech.texinfo doc/rluser.texinfo
@@ -123,9 +123,9 @@ libreadline.a: $(OBJECTS)
$(AR) $(ARFLAGS) $@ $(OBJECTS)
-test -n "$(RANLIB)" && $(RANLIB) $@
libhistory.a: $(HISTOBJ) xmalloc.o
libhistory.a: $(HISTOBJ) xmalloc.o xfree.o
$(RM) $@
$(AR) $(ARFLAGS) $@ $(HISTOBJ) xmalloc.o
$(AR) $(ARFLAGS) $@ $(HISTOBJ) xmalloc.o xfree.o
-test -n "$(RANLIB)" && $(RANLIB) $@
documentation: force
@@ -262,6 +262,7 @@ vi_mode.o: rldefs.h ${BUILD_DIR}/config.h rlconf.h
vi_mode.o: readline.h keymaps.h rltypedefs.h chardefs.h tilde.h
vi_mode.o: history.h ansi_stdlib.h rlstdc.h
xmalloc.o: ${BUILD_DIR}/config.h ansi_stdlib.h
xfree.o: ${BUILD_DIR}/config.h ansi_stdlib.h
bind.o: rlshell.h
histfile.o: rlshell.h
@@ -317,6 +318,7 @@ tilde.o: xmalloc.h
undo.o: xmalloc.h
util.o: xmalloc.h
vi_mode.o: xmalloc.h
xfree.o: xmalloc.h
xmalloc.o: xmalloc.h
complete.o: rlmbutil.h
@@ -359,6 +361,7 @@ tilde.o: tilde.c
undo.o: undo.c
util.o: util.c
vi_mode.o: vi_mode.c
xfree.o: xfree.c
xmalloc.o: xmalloc.c
histexpand.o: histexpand.c

View File

@@ -1,6 +1,6 @@
/* bind.c -- key binding and startup file support for the readline library. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -1424,6 +1424,7 @@ static const struct {
{ "blink-matching-paren", &rl_blink_matching_paren, V_SPECIAL },
{ "byte-oriented", &rl_byte_oriented, 0 },
{ "completion-ignore-case", &_rl_completion_case_fold, 0 },
{ "completion-map-case", &_rl_completion_case_map, 0 },
{ "convert-meta", &_rl_convert_meta_chars_to_ascii, 0 },
{ "disable-completion", &rl_inhibit_completion, 0 },
{ "echo-control-characters", &_rl_echo_control_chars, 0 },
@@ -1437,6 +1438,7 @@ static const struct {
{ "mark-modified-lines", &_rl_mark_modified_lines, 0 },
{ "mark-symlinked-directories", &_rl_complete_mark_symlink_dirs, 0 },
{ "match-hidden-files", &_rl_match_hidden_files, 0 },
{ "menu-complete-display-prefix", &_rl_menu_complete_prefix_first, 0 },
{ "meta-flag", &_rl_meta_flag, 0 },
{ "output-meta", &_rl_output_meta_chars, 0 },
{ "page-completions", &_rl_page_completions, 0 },
@@ -1449,7 +1451,7 @@ static const struct {
#if defined (VISIBLE_STATS)
{ "visible-stats", &rl_visible_stats, 0 },
#endif /* VISIBLE_STATS */
{ (char *)NULL, (int *)NULL }
{ (char *)NULL, (int *)NULL, 0 }
};
static int
@@ -1504,6 +1506,7 @@ static int sv_bell_style PARAMS((const char *));
static int sv_combegin PARAMS((const char *));
static int sv_dispprefix PARAMS((const char *));
static int sv_compquery PARAMS((const char *));
static int sv_compwidth PARAMS((const char *));
static int sv_editmode PARAMS((const char *));
static int sv_histsize PARAMS((const char *));
static int sv_isrchterm PARAMS((const char *));
@@ -1516,13 +1519,14 @@ static const struct {
} string_varlist[] = {
{ "bell-style", V_STRING, sv_bell_style },
{ "comment-begin", V_STRING, sv_combegin },
{ "completion-display-width", V_INT, sv_compwidth },
{ "completion-prefix-display-length", V_INT, sv_dispprefix },
{ "completion-query-items", V_INT, sv_compquery },
{ "editing-mode", V_STRING, sv_editmode },
{ "history-size", V_INT, sv_histsize },
{ "isearch-terminators", V_STRING, sv_isrchterm },
{ "keymap", V_STRING, sv_keymap },
{ (char *)NULL, 0 }
{ (char *)NULL, 0, (_rl_sv_func_t *)0 }
};
static int
@@ -1662,6 +1666,19 @@ sv_compquery (value)
return 0;
}
static int
sv_compwidth (value)
const char *value;
{
int nval = -1;
if (value && *value)
nval = atoi (value);
_rl_completion_columns = nval;
return 0;
}
static int
sv_histsize (value)
const char *value;
@@ -2268,6 +2285,11 @@ _rl_get_string_variable_value (name)
}
else if (_rl_stricmp (name, "comment-begin") == 0)
return (_rl_comment_begin ? _rl_comment_begin : RL_COMMENT_BEGIN_DEFAULT);
else if (_rl_stricmp (name, "completion-display-width") == 0)
{
sprintf (numbuf, "%d", _rl_completion_columns);
return (numbuf);
}
else if (_rl_stricmp (name, "completion-prefix-display-length") == 0)
{
sprintf (numbuf, "%d", _rl_completion_prefix_display_length);

View File

@@ -142,6 +142,15 @@ rl_callback_read_char ()
eof = _rl_nsearch_callback (_rl_nscxt);
return;
}
#if defined (VI_MODE)
else if (RL_ISSTATE (RL_STATE_VIMOTION))
{
eof = _rl_vi_domove_callback (_rl_vimvcxt);
/* Should handle everything, including cleanup, numeric arguments,
and turning off RL_STATE_VIMOTION */
return;
}
#endif
else if (RL_ISSTATE (RL_STATE_NUMERICARG))
{
eof = _rl_arg_callback (_rl_argcxt);

View File

@@ -1,6 +1,6 @@
/* complete.c -- filename completion for readline. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2011 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -119,9 +119,11 @@ static char **remove_duplicate_matches PARAMS((char **));
static void insert_match PARAMS((char *, int, int, char *));
static int append_to_match PARAMS((char *, int, int, int));
static void insert_all_matches PARAMS((char **, int, char *));
static int complete_fncmp PARAMS((const char *, int, const char *, int));
static void display_matches PARAMS((char **));
static int compute_lcd_of_matches PARAMS((char **, int, const char *));
static int postprocess_matches PARAMS((char ***, int));
static int complete_get_screenwidth PARAMS((void));
static char *make_quoted_replacement PARAMS((char *, int, char *));
@@ -157,10 +159,14 @@ int _rl_print_completions_horizontally;
#if defined (__MSDOS__) && !defined (__DJGPP__)
int _rl_completion_case_fold = 1;
#else
int _rl_completion_case_fold;
int _rl_completion_case_fold = 0;
#endif
/* If non-zero, don't match hidden files (filenames beginning with a `.' on
/* Non-zero means that `-' and `_' are equivalent when comparing filenames
for completion. */
int _rl_completion_case_map = 0;
/* If zero, don't match hidden files (filenames beginning with a `.' on
Unix) when doing filename completion. */
int _rl_match_hidden_files = 1;
@@ -170,6 +176,10 @@ int _rl_match_hidden_files = 1;
display prefix replaced with an ellipsis. */
int _rl_completion_prefix_display_length = 0;
/* The readline-private number of screen columns to use when displaying
matches. If < 0 or > _rl_screenwidth, it is ignored. */
int _rl_completion_columns = -1;
/* Global variables available to applications using readline. */
#if defined (VISIBLE_STATS)
@@ -185,6 +195,10 @@ int rl_visible_stats = 0;
after the `e' in `Makefile' won't result in `Makefilefile'. */
int _rl_skip_completed_text = 0;
/* If non-zero, menu completion displays the common prefix first in the
cycle of possible completions instead of the last. */
int _rl_menu_complete_prefix_first = 0;
/* If non-zero, then this is the address of a function to call when
completing on a directory name. The function is called with
the address of a string (the current directory name) as an arg. */
@@ -467,6 +481,14 @@ get_y_or_n (for_pager)
{
int c;
/* For now, disable pager in callback mode, until we later convert to state
driven functions. Have to wait until next major version to add new
state definition, since it will change value of RL_STATE_DONE. */
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
return 1;
#endif
for (;;)
{
RL_SETSTATE(RL_STATE_MOREINPUT);
@@ -829,7 +851,7 @@ print_filename (to_print, full_pathname, prefix_bytes)
if (path_isdir (new_full_pathname))
extension_char = '/';
free (new_full_pathname);
xfree (new_full_pathname);
to_print[-1] = c;
}
else
@@ -844,7 +866,7 @@ print_filename (to_print, full_pathname, prefix_bytes)
extension_char = '/';
}
free (s);
xfree (s);
if (extension_char)
{
putc (extension_char, rl_outstream);
@@ -1081,7 +1103,7 @@ remove_duplicate_matches (matches)
{
if (strcmp (matches[i], matches[i + 1]) == 0)
{
free (matches[i]);
xfree (matches[i]);
matches[i] = (char *)&dead_slot;
}
else
@@ -1099,7 +1121,7 @@ remove_duplicate_matches (matches)
temp_array[j] = (char *)NULL;
if (matches[0] != (char *)&dead_slot)
free (matches[0]);
xfree (matches[0]);
/* Place the lowest common denominator back in [0]. */
temp_array[0] = lowest_common;
@@ -1109,7 +1131,7 @@ remove_duplicate_matches (matches)
insert. */
if (j == 2 && strcmp (temp_array[0], temp_array[1]) == 0)
{
free (temp_array[1]);
xfree (temp_array[1]);
temp_array[1] = (char *)NULL;
}
return (temp_array);
@@ -1288,7 +1310,7 @@ postprocess_matches (matchesp, matching_filenames)
if (rl_ignore_completion_duplicates)
{
temp_matches = remove_duplicate_matches (matches);
free (matches);
xfree (matches);
matches = temp_matches;
}
@@ -1325,6 +1347,23 @@ postprocess_matches (matchesp, matching_filenames)
return (1);
}
static int
complete_get_screenwidth ()
{
int cols;
char *envcols;
cols = _rl_completion_columns;
if (cols >= 0 && cols <= _rl_screenwidth)
return cols;
envcols = getenv ("COLUMNS");
if (envcols && *envcols)
cols = atoi (envcols);
if (cols >= 0 && cols <= _rl_screenwidth)
return cols;
return _rl_screenwidth;
}
/* A convenience function for displaying a list of strings in
columnar format on readline's output stream. MATCHES is the list
of strings, in argv format, LEN is the number of strings in MATCHES,
@@ -1334,7 +1373,7 @@ rl_display_match_list (matches, len, max)
char **matches;
int len, max;
{
int count, limit, printed_len, lines;
int count, limit, printed_len, lines, cols;
int i, j, k, l, common_length, sind;
char *temp, *t;
@@ -1355,12 +1394,17 @@ rl_display_match_list (matches, len, max)
}
/* How many items of MAX length can we fit in the screen window? */
cols = complete_get_screenwidth ();
max += 2;
limit = _rl_screenwidth / max;
if (limit != 1 && (limit * max == _rl_screenwidth))
limit = cols / max;
if (limit != 1 && (limit * max == cols))
limit--;
/* Avoid a possible floating exception. If max > _rl_screenwidth,
/* If cols == 0, limit will end up -1 */
if (cols < _rl_screenwidth && limit < 0)
limit = 1;
/* Avoid a possible floating exception. If max > cols,
limit will be 0 and a divide-by-zero fault will result. */
if (limit == 0)
limit = 1;
@@ -1608,7 +1652,7 @@ insert_match (match, start, mtype, qc)
else
_rl_replace_text (replacement, start, end);
if (replacement != match)
free (replacement);
xfree (replacement);
}
}
@@ -1675,7 +1719,7 @@ append_to_match (text, delimiter, quote_char, nontrivial_match)
if (rl_point == rl_end && temp_string_index)
rl_insert_text (temp_string);
}
free (filename);
xfree (filename);
}
else
{
@@ -1711,7 +1755,7 @@ insert_all_matches (matches, point, qc)
rl_insert_text (rp);
rl_insert_text (" ");
if (rp != matches[i])
free (rp);
xfree (rp);
}
}
else
@@ -1720,7 +1764,7 @@ insert_all_matches (matches, point, qc)
rl_insert_text (rp);
rl_insert_text (" ");
if (rp != matches[0])
free (rp);
xfree (rp);
}
rl_end_undo_group ();
}
@@ -1735,8 +1779,8 @@ _rl_free_match_list (matches)
return;
for (i = 0; matches[i]; i++)
free (matches[i]);
free (matches);
xfree (matches[i]);
xfree (matches);
}
/* Complete the word at or before point.
@@ -1757,6 +1801,9 @@ rl_complete_internal (what_to_do)
int start, end, delimiter, found_quote, i, nontrivial_lcd;
char *text, *saved_line_buffer;
char quote_char;
#if 1
int tlen, mlen;
#endif
RL_SETSTATE(RL_STATE_COMPLETING);
@@ -1784,7 +1831,11 @@ rl_complete_internal (what_to_do)
/* nontrivial_lcd is set if the common prefix adds something to the word
being completed. */
nontrivial_lcd = matches && strcmp (text, matches[0]) != 0;
free (text);
#if 1
if (what_to_do == '!' || what_to_do == '@')
tlen = strlen (text);
#endif
xfree (text);
if (matches == 0)
{
@@ -1817,8 +1868,25 @@ rl_complete_internal (what_to_do)
case '!':
case '@':
/* Insert the first match with proper quoting. */
#if 0
if (*matches[0])
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
#else
if (what_to_do == TAB)
{
if (*matches[0])
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
}
else if (*matches[0] && matches[1] == 0)
/* should we perform the check only if there are multiple matches? */
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
else if (*matches[0]) /* what_to_do != TAB && multiple matches */
{
mlen = *matches[0] ? strlen (matches[0]) : 0;
if (mlen >= tlen)
insert_match (matches[0], start, matches[1] ? MULT_MATCH : SINGLE_MATCH, &quote_char);
}
#endif
/* If there are more matches, ring the bell to indicate.
If we are in vi mode, Posix.2 says to not ring the bell.
@@ -1872,7 +1940,7 @@ rl_complete_internal (what_to_do)
if (saved_line_buffer)
{
completion_changed_buffer = strcmp (rl_line_buffer, saved_line_buffer) != 0;
free (saved_line_buffer);
xfree (saved_line_buffer);
}
RL_UNSETSTATE(RL_STATE_COMPLETING);
@@ -1939,7 +2007,7 @@ rl_completion_matches (text, entry_function)
compute_lcd_of_matches (match_list, matches, text);
else /* There were no matches. */
{
free (match_list);
xfree (match_list);
match_list = (char **)NULL;
}
return (match_list);
@@ -2005,6 +2073,62 @@ rl_username_completion_function (text, state)
#endif /* !__WIN32__ && !__OPENNT */
}
/* Return non-zero if CONVFN matches FILENAME up to the length of FILENAME
(FILENAME_LEN). If _rl_completion_case_fold is set, compare without
regard to the alphabetic case of characters. CONVFN is the possibly-
converted directory entry; FILENAME is what the user typed. */
static int
complete_fncmp (convfn, convlen, filename, filename_len)
const char *convfn;
int convlen;
const char *filename;
int filename_len;
{
register char *s1, *s2;
int d, len;
/* Otherwise, if these match up to the length of filename, then
it is a match. */
if (_rl_completion_case_fold && _rl_completion_case_map)
{
/* Case-insensitive comparison treating _ and - as equivalent */
if (filename_len == 0)
return 1;
if (convlen < filename_len)
return 0;
s1 = (char *)convfn;
s2 = (char *)filename;
len = filename_len;
do
{
d = _rl_to_lower (*s1) - _rl_to_lower (*s2);
/* *s1 == [-_] && *s2 == [-_] */
if ((*s1 == '-' || *s1 == '_') && (*s2 == '-' || *s2 == '_'))
d = 0;
if (d != 0)
return 0;
s1++; s2++; /* already checked convlen >= filename_len */
}
while (--len != 0);
return 1;
}
else if (_rl_completion_case_fold)
{
if ((_rl_to_lower (convfn[0]) == _rl_to_lower (filename[0])) &&
(convlen >= filename_len) &&
(_rl_strnicmp (filename, convfn, filename_len) == 0))
return 1;
}
else
{
if ((convfn[0] == filename[0]) &&
(convlen >= filename_len) &&
(strncmp (filename, convfn, filename_len) == 0))
return 1;
}
return 0;
}
/* Okay, now we write the entry_function for filename completion. In the
general case. Note that completion in the shell is a little different
because of all the pathnames that must be followed when looking up the
@@ -2071,32 +2195,41 @@ rl_filename_completion_function (text, state)
/* We aren't done yet. We also support the "~user" syntax. */
/* Save the version of the directory that the user typed. */
users_dirname = savestring (dirname);
/* Save the version of the directory that the user typed, dequoting
it if necessary. */
if (rl_completion_found_quote && rl_filename_dequoting_function)
users_dirname = (*rl_filename_dequoting_function) (dirname, rl_completion_quote_character);
else
users_dirname = savestring (dirname);
if (*dirname == '~')
{
temp = tilde_expand (dirname);
free (dirname);
xfree (dirname);
dirname = temp;
}
/* We have saved the possibly-dequoted version of the directory name
the user typed. Now transform the directory name we're going to
pass to opendir(2). The directory rewrite hook modifies only the
directory name; the directory completion hook modifies both the
directory name passed to opendir(2) and the version the user
typed. Both the directory completion and rewrite hooks should perform
any necessary dequoting. The hook functions return 1 if they modify
the directory name argument. If either hook returns 0, it should
not modify the directory name pointer passed as an argument. */
if (rl_directory_rewrite_hook)
(*rl_directory_rewrite_hook) (&dirname);
/* The directory completion hook should perform any necessary
dequoting. */
if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))
else if (rl_directory_completion_hook && (*rl_directory_completion_hook) (&dirname))
{
free (users_dirname);
xfree (users_dirname);
users_dirname = savestring (dirname);
}
else if (rl_completion_found_quote && rl_filename_dequoting_function)
{
/* delete single and double quotes */
temp = (*rl_filename_dequoting_function) (users_dirname, rl_completion_quote_character);
free (users_dirname);
users_dirname = temp;
xfree (dirname);
dirname = savestring (users_dirname);
}
directory = opendir (dirname);
@@ -2105,7 +2238,7 @@ rl_filename_completion_function (text, state)
{
/* delete single and double quotes */
temp = (*rl_filename_dequoting_function) (filename, rl_completion_quote_character);
free (filename);
xfree (filename);
filename = temp;
}
filename_len = strlen (filename);
@@ -2147,22 +2280,8 @@ rl_filename_completion_function (text, state)
}
else
{
/* Otherwise, if these match up to the length of filename, then
it is a match. */
if (_rl_completion_case_fold)
{
if ((_rl_to_lower (convfn[0]) == _rl_to_lower (filename[0])) &&
(convlen >= filename_len) &&
(_rl_strnicmp (filename, convfn, filename_len) == 0))
break;
}
else
{
if ((convfn[0] == filename[0]) &&
(convlen >= filename_len) &&
(strncmp (filename, convfn, filename_len) == 0))
break;
}
if (complete_fncmp (convfn, convlen, filename, filename_len))
break;
}
}
@@ -2175,17 +2294,17 @@ rl_filename_completion_function (text, state)
}
if (dirname)
{
free (dirname);
xfree (dirname);
dirname = (char *)NULL;
}
if (filename)
{
free (filename);
xfree (filename);
filename = (char *)NULL;
}
if (users_dirname)
{
free (users_dirname);
xfree (users_dirname);
users_dirname = (char *)NULL;
}
@@ -2225,7 +2344,7 @@ rl_filename_completion_function (text, state)
temp = savestring (convfn);
if (convfn != dentry)
free (convfn);
xfree (convfn);
return (temp);
}
@@ -2304,14 +2423,14 @@ rl_old_menu_complete (count, invoking_key)
if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
{
rl_ding ();
rl_ding ();
FREE (matches);
matches = (char **)0;
FREE (orig_text);
orig_text = (char *)0;
completion_changed_buffer = 0;
RL_UNSETSTATE(RL_STATE_COMPLETING);
return (0);
completion_changed_buffer = 0;
RL_UNSETSTATE(RL_STATE_COMPLETING);
return (0);
}
RL_UNSETSTATE(RL_STATE_COMPLETING);
@@ -2340,7 +2459,10 @@ rl_old_menu_complete (count, invoking_key)
match_list_index += count;
if (match_list_index < 0)
match_list_index += match_list_size;
{
while (match_list_index < 0)
match_list_index += match_list_size;
}
else
match_list_index %= match_list_size;
@@ -2375,7 +2497,7 @@ rl_menu_complete (count, ignore)
static int full_completion = 0; /* set to 1 if menu completion should reinitialize on next call */
static int orig_start, orig_end;
static char quote_char;
static int delimiter;
static int delimiter, cstate;
/* The first time through, we generate the list of matches and set things
up to insert them. */
@@ -2428,14 +2550,14 @@ rl_menu_complete (count, ignore)
if (matches == 0 || postprocess_matches (&matches, matching_filenames) == 0)
{
rl_ding ();
rl_ding ();
FREE (matches);
matches = (char **)0;
FREE (orig_text);
orig_text = (char *)0;
completion_changed_buffer = 0;
RL_UNSETSTATE(RL_STATE_COMPLETING);
return (0);
completion_changed_buffer = 0;
RL_UNSETSTATE(RL_STATE_COMPLETING);
return (0);
}
RL_UNSETSTATE(RL_STATE_COMPLETING);
@@ -2483,6 +2605,11 @@ rl_menu_complete (count, ignore)
full_completion = 1;
return (0);
}
else if (_rl_menu_complete_prefix_first && match_list_size > 1)
{
rl_ding ();
return (0);
}
}
/* Now we have the list of matches. Replace the text between
@@ -2500,7 +2627,10 @@ rl_menu_complete (count, ignore)
match_list_index += count;
if (match_list_index < 0)
match_list_index += match_list_size;
{
while (match_list_index < 0)
match_list_index += match_list_size;
}
else
match_list_index %= match_list_size;

View File

@@ -12,7 +12,7 @@ This document describes the GNU History library
a programming tool that provides a consistent user interface for
recalling lines of previously typed input.
Copyright @copyright{} 1988--2009 Free Software Foundation, Inc.
Copyright @copyright{} 1988--2011 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice

View File

@@ -1,7 +1,7 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988-2007 Free Software Foundation, Inc.
Copyright (C) 1988-2011 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
@@ -426,6 +426,10 @@ The maximum number of history entries. This must be changed using
If non-zero, timestamps are written to the history file, so they can be
preserved between sessions. The default value is 0, meaning that
timestamps are not saved.
The current timestamp format uses the value of @var{history_comment_char}
to delimit timestamp entries in the history file. If that variable does
not have a value (the default), timestamps will not be written.
@end deftypevar
@deftypevar char history_expansion_char

View File

@@ -1,7 +1,7 @@
@ignore
This file documents the user interface to the GNU History library.
Copyright (C) 1988-2007 Free Software Foundation, Inc.
Copyright (C) 1988--2011 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
Permission is granted to make and distribute verbatim copies of this manual
@@ -299,6 +299,8 @@ writing the history file.
An event designator is a reference to a command line entry in the
history list.
Unless the reference is absolute, events are relative to the current
position in the history list.
@cindex history events
@table @asis
@@ -324,10 +326,15 @@ Refer to the command @var{n} lines back.
Refer to the previous command. This is a synonym for @samp{!-1}.
@item @code{!@var{string}}
Refer to the most recent command starting with @var{string}.
Refer to the most recent command
preceding the current position in the history list
starting with @var{string}.
@item @code{!?@var{string}[?]}
Refer to the most recent command containing @var{string}. The trailing
Refer to the most recent command
preceding the current position in the history list
containing @var{string}.
The trailing
@samp{?} may be omitted if the @var{string} is followed immediately by
a newline.

View File

@@ -13,7 +13,7 @@ This manual describes the GNU Readline Library
consistency of user interface across discrete programs which provide
a command line interface.
Copyright @copyright{} 1988--2009 Free Software Foundation, Inc.
Copyright @copyright{} 1988--2011 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice

View File

@@ -7,7 +7,7 @@ This document describes the GNU Readline Library, a utility for aiding
in the consistency of user interface across discrete programs that need
to provide a command line interface.
Copyright (C) 1988-2007 Free Software Foundation, Inc.
Copyright (C) 1988--2011 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice
@@ -1157,6 +1157,9 @@ of strings, in argv format, such as a list of completion matches.
is the length of the longest string in @code{matches}. This function uses
the setting of @code{print-completions-horizontally} to select how the
matches are displayed (@pxref{Readline Init File Syntax}).
When displaying completions, this function sets the number of columns used
for display to the value of @code{completion-display-width}, the value of
the environment variable @env{COLUMNS}, or the screen width, in that order.
@end deftypefun
The following are implemented as macros, defined in @code{chardefs.h}.
@@ -1714,18 +1717,20 @@ from the array must be freed.
@deftypevar {rl_icppfunc_t *} rl_directory_completion_hook
This function, if defined, is allowed to modify the directory portion
of filenames Readline completes. It is called with the address of a
string (the current directory name) as an argument, and may modify that string.
of filenames Readline completes.
It could be used to expand symbolic links or shell variables in pathnames.
It is called with the address of a string (the current directory name) as an
argument, and may modify that string.
If the string is replaced with a new string, the old value should be freed.
Any modified directory name should have a trailing slash.
The modified value will be displayed as part of the completion, replacing
The modified value will be used as part of the completion, replacing
the directory portion of the pathname the user typed.
It returns an integer that should be non-zero if the function modifies
its directory argument.
It could be used to expand symbolic links or shell variables in pathnames.
At the least, even if no other expansion is performed, this function should
remove any quote characters from the directory name, because its result will
be passed directly to @code{opendir()}.
The directory completion hook returns an integer that should be non-zero if
the function modifies its directory argument.
The function should not modify the directory argument if it returns 0.
@end deftypevar
@ignore
@@ -1737,7 +1742,7 @@ it only modifies the directory name used in @code{opendir}, not what is
displayed when the possible completions are printed or inserted. It is
called before rl_directory_completion_hook.
I'm not happy with how this worksyet, so it's undocumented.
I'm not happy with how this works yet, so it's undocumented.
@end deftypevar
@end ignore

View File

@@ -9,7 +9,7 @@ use these features. There is a document entitled "readline.texinfo"
which contains both end-user and programmer documentation for the
GNU Readline Library.
Copyright (C) 1988--2009 Free Software Foundation, Inc.
Copyright (C) 1988--2011 Free Software Foundation, Inc.
Authored by Brian Fox and Chet Ramey.
@@ -51,7 +51,7 @@ Command line editing is enabled by default when using an interactive shell,
unless the @option{--noediting} option is supplied at shell invocation.
Line editing is also used when using the @option{-e} option to the
@code{read} builtin command (@pxref{Bash Builtins}).
By default, the line editing commands are similar to those of emacs.
By default, the line editing commands are similar to those of Emacs.
A vi-style line editing interface is also available.
Line editing can be enabled at any time using the @option{-o emacs} or
@option{-o vi} options to the @code{set} builtin command
@@ -431,11 +431,27 @@ The string to insert at the beginning of the line when the
@code{insert-comment} command is executed. The default value
is @code{"#"}.
@item completion-display-width
@vindex completion-display-width
The number of screen columns used to display possible matches
when performing completion.
The value is ignored if it is less than 0 or greater than the terminal
screen width.
A value of 0 will cause matches to be displayed one per line.
The default value is -1.
@item completion-ignore-case
@vindex completion-ignore-case
If set to @samp{on}, Readline performs filename matching and completion
in a case-insensitive fashion.
The default value is @samp{off}.
@item completion-map-case
@vindex completion-map-case
If set to @samp{on}, and @var{completion-ignore-case} is enabled, Readline
treats hyphens (@samp{-}) and underscores (@samp{_}) as equivalent when
performing case-insensitive filename matching and completion.
@item completion-prefix-display-length
@vindex completion-prefix-display-length
The length in characters of the common prefix of a list of possible
@@ -570,10 +586,17 @@ The default is @samp{off}.
@vindex match-hidden-files
This variable, when set to @samp{on}, causes Readline to match files whose
names begin with a @samp{.} (hidden files) when performing filename
completion, unless the leading @samp{.} is
completion.
If set to @samp{off}, the leading @samp{.} must be
supplied by the user in the filename to be completed.
This variable is @samp{on} by default.
@item menu-complete-display-prefix
@vindex menu-complete-display-prefix
If set to @samp{on}, menu completion displays the common prefix of the
list of possible completions (which may be empty) before cycling through
the list. The default is @samp{off}.
@item output-meta
@vindex output-meta
If set to @samp{on}, Readline will display characters with the
@@ -1097,10 +1120,14 @@ as if the @samp{!@var{n}} history expansion had been specified.
@item yank-last-arg (M-. or M-_)
Insert last argument to the previous command (the last word of the
previous history entry). With an
argument, behave exactly like @code{yank-nth-arg}.
previous history entry).
With a numeric argument, behave exactly like @code{yank-nth-arg}.
Successive calls to @code{yank-last-arg} move back through the history
list, inserting the last argument of each line in turn.
list, inserting the last word (or the word specified by the argument to
the first call) of each line in turn.
Any numeric argument supplied to these successive calls determines
the direction to move through the history. A negative argument switches
the direction through the history (back or forward).
The history expansion facilities are used to extract the last argument,
as if the @samp{!$} history expansion had been specified.
@@ -1212,7 +1239,7 @@ Kill from point to the end of the current word, or if between
words, to the end of the next word.
Word boundaries are the same as @code{shell-forward-word}.
@item backward-kill-word ()
@item shell-backward-kill-word ()
Kill the word behind point.
Word boundaries are the same as @code{shell-backward-word}.
@end ifset
@@ -1298,6 +1325,9 @@ The default is filename completion.
@item possible-completions (M-?)
List the possible completions of the text before point.
When displaying completions, Readline sets the number of columns used
for display to the value of @code{completion-display-width}, the value of
the environment variable @env{COLUMNS}, or the screen width, in that order.
@item insert-completions (M-*)
Insert all completions of the text before point that would have
@@ -1579,7 +1609,7 @@ editing mode.
While the Readline library does not have a full set of @code{vi}
editing functions, it does contain enough to allow simple editing
of the line. The Readline @code{vi} mode behaves as specified in
the @sc{posix} 1003.2 standard.
the @sc{posix} standard.
@ifset BashFeatures
In order to switch interactively between @code{emacs} and @code{vi}
@@ -1733,7 +1763,7 @@ exit status of 124. If a shell function returns 124, and changes
the compspec associated with the command on which completion is being
attempted (supplied as the first argument when the function is executed),
programmable completion restarts from the beginning, with an
attempt to find a compspec for that command. This allows a set of
attempt to find a new compspec for that command. This allows a set of
completions to be built dynamically as completion is attempted, rather than
being loaded all at once.
@@ -1933,17 +1963,6 @@ User names. May also be specified as @option{-u}.
Names of all shell variables. May also be specified as @option{-v}.
@end table
@item -G @var{globpat}
The filename expansion pattern @var{globpat} is expanded to generate
the possible completions.
@item -W @var{wordlist}
The @var{wordlist} is split using the characters in the
@env{IFS} special variable as delimiters, and each resultant word
is expanded.
The possible completions are the members of the resultant list which
match the word being completed.
@item -C @var{command}
@var{command} is executed in a subshell environment, and its output is
used as the possible completions.
@@ -1954,13 +1973,9 @@ environment.
When it finishes, the possible completions are retrieved from the value
of the @env{COMPREPLY} array variable.
@item -X @var{filterpat}
@var{filterpat} is a pattern as used for filename expansion.
It is applied to the list of possible completions generated by the
preceding options and arguments, and each completion matching
@var{filterpat} is removed from the list.
A leading @samp{!} in @var{filterpat} negates the pattern; in this
case, any completion not matching @var{filterpat} is removed.
@item -G @var{globpat}
The filename expansion pattern @var{globpat} is expanded to generate
the possible completions.
@item -P @var{prefix}
@var{prefix} is added at the beginning of each possible completion
@@ -1969,6 +1984,21 @@ after all other options have been applied.
@item -S @var{suffix}
@var{suffix} is appended to each possible completion
after all other options have been applied.
@item -W @var{wordlist}
The @var{wordlist} is split using the characters in the
@env{IFS} special variable as delimiters, and each resultant word
is expanded.
The possible completions are the members of the resultant list which
match the word being completed.
@item -X @var{filterpat}
@var{filterpat} is a pattern as used for filename expansion.
It is applied to the list of possible completions generated by the
preceding options and arguments, and each completion matching
@var{filterpat} is removed from the list.
A leading @samp{!} in @var{filterpat} negates the pattern; in this
case, any completion not matching @var{filterpat} is removed.
@end table
The return value is true unless an invalid option is supplied, an option
@@ -1983,7 +2013,7 @@ an error occurs adding a completion specification.
@code{compopt} [-o @var{option}] [-DE] [+o @var{option}] [@var{name}]
@end example
Modify completion options for each @var{name} according to the
@var{option}s, or for the currently-execution completion if no @var{name}s
@var{option}s, or for the currently-executing completion if no @var{name}s
are supplied.
If no @var{option}s are given, display the completion options for each
@var{name} or the current completion.

View File

@@ -12,7 +12,7 @@ This manual describes the end user interface of the GNU Readline Library
consistency of user interface across discrete programs which provide
a command line interface.
Copyright @copyright{} 1988--2009 Free Software Foundation, Inc.
Copyright @copyright{} 1988--2011 Free Software Foundation, Inc.
Permission is granted to make and distribute verbatim copies of
this manual provided the copyright notice and this permission notice

View File

@@ -1,10 +1,10 @@
@ignore
Copyright (C) 1988-2009 Free Software Foundation, Inc.
Copyright (C) 1988-2011 Free Software Foundation, Inc.
@end ignore
@set EDITION 6.1
@set VERSION 6.1
@set UPDATED 9 October 2009
@set UPDATED-MONTH October 2009
@set EDITION 6.2
@set VERSION 6.2
@set UPDATED September 6 2010
@set UPDATED-MONTH September 2010
@set LASTCHANGE Fri Oct 9 12:57:58 EDT 2009
@set LASTCHANGE Mon Sep 6 22:07:10 EDT 2010

View File

@@ -1,6 +1,6 @@
/* funmap.c -- attach names to functions. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -148,6 +148,8 @@ static const FUNMAP default_funmap[] = {
{ "vi-append-mode", rl_vi_append_mode },
{ "vi-arg-digit", rl_vi_arg_digit },
{ "vi-back-to-indent", rl_vi_back_to_indent },
{ "vi-backward-bigword", rl_vi_bWord },
{ "vi-backward-word", rl_vi_bword },
{ "vi-bWord", rl_vi_bWord },
{ "vi-bword", rl_vi_bword },
{ "vi-change-case", rl_vi_change_case },
@@ -160,12 +162,15 @@ static const FUNMAP default_funmap[] = {
{ "vi-delete-to", rl_vi_delete_to },
{ "vi-eWord", rl_vi_eWord },
{ "vi-editing-mode", rl_vi_editing_mode },
{ "vi-end-bigword", rl_vi_eWord },
{ "vi-end-word", rl_vi_end_word },
{ "vi-eof-maybe", rl_vi_eof_maybe },
{ "vi-eword", rl_vi_eword },
{ "vi-fWord", rl_vi_fWord },
{ "vi-fetch-history", rl_vi_fetch_history },
{ "vi-first-print", rl_vi_first_print },
{ "vi-forward-bigword", rl_vi_fWord },
{ "vi-forward-word", rl_vi_fword },
{ "vi-fword", rl_vi_fword },
{ "vi-goto-mark", rl_vi_goto_mark },
{ "vi-insert-beg", rl_vi_insert_beg },

View File

@@ -1,6 +1,6 @@
/* histexpand.c -- history expansion. */
/* Copyright (C) 1989-2009 Free Software Foundation, Inc.
/* Copyright (C) 1989-2010 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
@@ -245,7 +245,7 @@ get_history_event (string, caller_index, delimiting_quote)
#define FAIL_SEARCH() \
do { \
history_offset = history_length; free (temp) ; return (char *)NULL; \
history_offset = history_length; xfree (temp) ; return (char *)NULL; \
} while (0)
/* If there is no search string, try to use the previous search string,
@@ -254,7 +254,7 @@ get_history_event (string, caller_index, delimiting_quote)
{
if (search_string)
{
free (temp);
xfree (temp);
temp = savestring (search_string);
}
else
@@ -285,7 +285,7 @@ get_history_event (string, caller_index, delimiting_quote)
search_match = history_find_word (entry->line, local_index);
}
else
free (temp);
xfree (temp);
return (entry->line);
}
@@ -508,7 +508,7 @@ postproc_subst_rhs ()
}
}
new[j] = '\0';
free (subst_rhs);
xfree (subst_rhs);
subst_rhs = new;
subst_rhs_len = j;
}
@@ -585,7 +585,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (event == 0)
{
*ret_string = hist_error (string, start, i, EVENT_NOT_FOUND);
free (result);
xfree (result);
return (-1);
}
@@ -599,7 +599,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (word_spec == (char *)&error_pointer)
{
*ret_string = hist_error (string, starting_index, i, BAD_WORD_SPEC);
free (result);
xfree (result);
return (-1);
}
@@ -632,8 +632,8 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
{
default:
*ret_string = hist_error (string, i+1, i+2, BAD_MODIFIER);
free (result);
free (temp);
xfree (result);
xfree (temp);
return -1;
case 'q':
@@ -658,7 +658,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
{
tstr++;
t = savestring (tstr);
free (temp);
xfree (temp);
temp = t;
}
break;
@@ -683,7 +683,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (tstr)
{
t = savestring (tstr);
free (temp);
xfree (temp);
temp = t;
}
break;
@@ -759,8 +759,8 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (subst_lhs_len == 0)
{
*ret_string = hist_error (string, starting_index, i, NO_PREV_SUBST);
free (result);
free (temp);
xfree (result);
xfree (temp);
return -1;
}
@@ -769,8 +769,8 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (subst_lhs_len > l_temp)
{
*ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
free (result);
free (temp);
xfree (result);
xfree (temp);
return (-1);
}
@@ -811,7 +811,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
temp + si + subst_lhs_len,
l_temp - (si + subst_lhs_len));
new_event[len] = '\0';
free (temp);
xfree (temp);
temp = new_event;
failed = 0;
@@ -847,8 +847,8 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
continue; /* don't want to increment i */
*ret_string = hist_error (string, starting_index, i, SUBST_FAILED);
free (result);
free (temp);
xfree (result);
xfree (temp);
return (-1);
}
}
@@ -869,7 +869,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
else
x = savestring (temp);
free (temp);
xfree (temp);
temp = x;
}
@@ -877,7 +877,7 @@ history_expand_internal (string, start, end_index_ptr, ret_string, current_line)
if (n >= result_len)
result = (char *)xrealloc (result, n + 2);
strcpy (result, temp);
free (temp);
xfree (temp);
*end_index_ptr = i;
*ret_string = result;
@@ -1064,7 +1064,7 @@ history_expand (hstring, output)
if (string[i] != history_expansion_char)
{
free (result);
xfree (result);
*output = savestring (string);
return (0);
}
@@ -1144,7 +1144,7 @@ history_expand (hstring, output)
strncpy (temp, string + quote, slen);
temp[slen - 1] = '\0';
ADD_STRING (temp);
free (temp);
xfree (temp);
}
else
ADD_CHAR (string[i]);
@@ -1157,7 +1157,7 @@ history_expand (hstring, output)
temp = (char *)xmalloc (l - i + 1);
strcpy (temp, string + i);
ADD_STRING (temp);
free (temp);
xfree (temp);
i = l;
}
else
@@ -1190,7 +1190,7 @@ history_expand (hstring, output)
temp = (char *)xmalloc (1 + strlen (result));
strcpy (temp, result);
ADD_STRING (temp);
free (temp);
xfree (temp);
}
i++;
break;
@@ -1201,9 +1201,9 @@ history_expand (hstring, output)
if (r < 0)
{
*output = temp;
free (result);
xfree (result);
if (string != hstring)
free (string);
xfree (string);
return -1;
}
else
@@ -1213,7 +1213,7 @@ history_expand (hstring, output)
modified++;
if (*temp)
ADD_STRING (temp);
free (temp);
xfree (temp);
}
only_printing = r == 1;
i = eindex;
@@ -1224,7 +1224,7 @@ history_expand (hstring, output)
*output = result;
if (string != hstring)
free (string);
xfree (string);
if (only_printing)
{
@@ -1405,8 +1405,8 @@ history_arg_extract (first, last, string)
}
for (i = 0; i < len; i++)
free (list[i]);
free (list);
xfree (list[i]);
xfree (list);
return (result);
}
@@ -1417,10 +1417,10 @@ history_tokenize_word (string, ind)
int ind;
{
register int i;
int delimiter;
int delimiter, nestdelim, delimopen;
i = ind;
delimiter = 0;
delimiter = nestdelim = 0;
if (member (string[i], "()\n"))
{
@@ -1442,13 +1442,21 @@ history_tokenize_word (string, ind)
return i;
}
else if ((peek == '&' && (string[i] == '>' || string[i] == '<')) ||
(peek == '>' && string[i] == '&') ||
(peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */
(peek == '(' && string[i] == '$')) /* ) */
(peek == '>' && string[i] == '&'))
{
i += 2;
return i;
}
/* XXX - separated out for later -- bash-4.2 */
else if ((peek == '(' && (string[i] == '>' || string[i] == '<')) || /* ) */
(peek == '(' && string[i] == '$')) /*)*/
{
i += 2;
delimopen = '(';
delimiter = ')';
nestdelim = 1;
goto get_word;
}
#if 0
else if (peek == '\'' && string[i] == '$')
{
@@ -1464,9 +1472,25 @@ history_tokenize_word (string, ind)
}
}
/* same code also used for $(...)/<(...)/>(...) above */
if (member (string[i], "!@?+*"))
{
int peek = string[i + 1];
if (peek == '(') /*)*/
{
/* Shell extended globbing patterns */
i += 2;
delimopen = '(';
delimiter = ')'; /* XXX - not perfect */
nestdelim = 1;
}
}
get_word:
/* Get word from string + i; */
if (member (string[i], HISTORY_QUOTE_CHARACTERS))
if (delimiter == 0 && member (string[i], HISTORY_QUOTE_CHARACTERS))
delimiter = string[i++];
for (; string[i]; i++)
@@ -1484,16 +1508,31 @@ history_tokenize_word (string, ind)
continue;
}
/* delimiter must be set and set to something other than a quote if
nestdelim is set, so these tests are safe. */
if (nestdelim && string[i] == delimopen)
{
nestdelim++;
continue;
}
if (nestdelim && string[i] == delimiter)
{
nestdelim--;
if (nestdelim == 0)
delimiter = 0;
continue;
}
if (delimiter && string[i] == delimiter)
{
delimiter = 0;
continue;
}
if (!delimiter && (member (string[i], history_word_delimiters)))
if (delimiter == 0 && (member (string[i], history_word_delimiters)))
break;
if (!delimiter && member (string[i], HISTORY_QUOTE_CHARACTERS))
if (delimiter == 0 && member (string[i], HISTORY_QUOTE_CHARACTERS))
delimiter = string[i];
}
@@ -1590,7 +1629,7 @@ freewords (words, start)
register int i;
for (i = start; words[i]; i++)
free (words[i]);
xfree (words[i]);
}
/* Find and return the word which contains the character at index IND
@@ -1614,8 +1653,8 @@ history_find_word (line, ind)
}
s = words[wind];
for (i = 0; i < wind; i++)
free (words[i]);
xfree (words[i]);
freewords (words, wind + 1);
free (words);
xfree (words);
return s;
}

View File

@@ -1,6 +1,6 @@
/* histfile.c - functions to manipulate the history file. */
/* Copyright (C) 1989-2009 Free Software Foundation, Inc.
/* Copyright (C) 1989-2010 Free Software Foundation, Inc.
This file contains the GNU History Library (History), a set of
routines for managing the text of previously typed lines.
@@ -126,8 +126,12 @@ history_filename (filename)
if (home == 0)
{
#if 0
home = ".";
home_len = 1;
#else
return (NULL);
#endif
}
else
home_len = strlen (home);
@@ -179,7 +183,7 @@ read_history_range (filename, from, to)
buffer = last_ts = (char *)NULL;
input = history_filename (filename);
file = open (input, O_RDONLY|O_BINARY, 0666);
file = input ? open (input, O_RDONLY|O_BINARY, 0666) : -1;
if ((file < 0) || (fstat (file, &finfo) == -1))
goto error_and_exit;
@@ -314,7 +318,7 @@ history_truncate_file (fname, lines)
buffer = (char *)NULL;
filename = history_filename (fname);
file = open (filename, O_RDONLY|O_BINARY, 0666);
file = filename ? open (filename, O_RDONLY|O_BINARY, 0666) : -1;
rv = 0;
/* Don't try to truncate non-regular files. */
@@ -413,7 +417,7 @@ history_truncate_file (fname, lines)
FREE (buffer);
free (filename);
xfree (filename);
return rv;
}
@@ -436,9 +440,10 @@ history_do_write (filename, nelements, overwrite)
mode = overwrite ? O_WRONLY|O_CREAT|O_TRUNC|O_BINARY : O_WRONLY|O_APPEND|O_BINARY;
#endif
output = history_filename (filename);
file = output ? open (output, mode, 0600) : -1;
rv = 0;
if ((file = open (output, mode, 0600)) == -1)
if (file == -1)
{
FREE (output);
return (errno);
@@ -515,7 +520,7 @@ mmap_error:
#else
if (write (file, buffer, buffer_size) < 0)
rv = errno;
free (buffer);
xfree (buffer);
#endif
}

View File

@@ -338,7 +338,7 @@ free_history_entry (hist)
FREE (hist->line);
FREE (hist->timestamp);
x = hist->data;
free (hist);
xfree (hist);
return (x);
}

View File

@@ -1,6 +1,6 @@
/* input.c -- character input functions for readline. */
/* Copyright (C) 1994-2009 Free Software Foundation, Inc.
/* Copyright (C) 1994-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -427,17 +427,19 @@ rl_read_key ()
/* If the user has an event function, then call it periodically. */
if (rl_event_hook)
{
while (rl_event_hook && rl_get_char (&c) == 0)
while (rl_event_hook)
{
(*rl_event_hook) ();
RL_CHECK_SIGNALS ();
if (rl_done) /* XXX - experimental */
return ('\n');
if (rl_gather_tyi () < 0) /* XXX - EIO */
{
rl_done = 1;
return ('\n');
}
RL_CHECK_SIGNALS ();
if (rl_get_char (&c) != 0)
break;
if (rl_done) /* XXX - experimental */
return ('\n');
(*rl_event_hook) ();
}
}
else

View File

@@ -104,6 +104,9 @@ _rl_scxt_alloc (type, flags)
cxt->save_undo_list = 0;
cxt->keymap = _rl_keymap;
cxt->okeymap = _rl_keymap;
cxt->history_pos = 0;
cxt->direction = 0;
@@ -336,10 +339,22 @@ _rl_isearch_dispatch (cxt, c)
return -1;
}
/* Translate the keys we do something with to opcodes. */
if (c >= 0 && _rl_keymap[c].type == ISFUNC)
/* If we are moving into a new keymap, modify cxt->keymap and go on.
This can be a problem if c == ESC and we want to terminate the
incremental search, so we check */
if (c >= 0 && cxt->keymap[c].type == ISKMAP && strchr (cxt->search_terminators, cxt->lastc) == 0)
{
f = _rl_keymap[c].function;
cxt->keymap = FUNCTION_TO_KEYMAP (cxt->keymap, c);
cxt->sflags |= SF_CHGKMAP;
/* XXX - we should probably save this sequence, so we can do
something useful if this doesn't end up mapping to a command. */
return 1;
}
/* Translate the keys we do something with to opcodes. */
if (c >= 0 && cxt->keymap[c].type == ISFUNC)
{
f = cxt->keymap[c].function;
if (f == rl_reverse_search_history)
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -1 : -2;
@@ -347,19 +362,27 @@ _rl_isearch_dispatch (cxt, c)
cxt->lastc = (cxt->sflags & SF_REVERSE) ? -2 : -1;
else if (f == rl_rubout)
cxt->lastc = -3;
else if (c == CTRL ('G'))
else if (c == CTRL ('G') || f == rl_abort)
cxt->lastc = -4;
else if (c == CTRL ('W')) /* XXX */
else if (c == CTRL ('W') || f == rl_unix_word_rubout) /* XXX */
cxt->lastc = -5;
else if (c == CTRL ('Y')) /* XXX */
else if (c == CTRL ('Y') || f == rl_yank) /* XXX */
cxt->lastc = -6;
}
/* If we changed the keymap earlier while translating a key sequence into
a command, restore it now that we've succeeded. */
if (cxt->sflags & SF_CHGKMAP)
{
cxt->keymap = cxt->okeymap;
cxt->sflags &= ~SF_CHGKMAP;
}
/* The characters in isearch_terminators (set from the user-settable
variable isearch-terminators) are used to terminate the search but
not subsequently execute the character as a command. The default
value is "\033\012" (ESC and C-J). */
if (strchr (cxt->search_terminators, cxt->lastc))
if (cxt->lastc > 0 && strchr (cxt->search_terminators, cxt->lastc))
{
/* ESC still terminates the search, but if there is pending
input or if input arrives within 0.1 seconds (on systems

View File

@@ -142,11 +142,11 @@ rl_discard_keymap (map)
case ISKMAP:
rl_discard_keymap ((Keymap)map[i].function);
free ((char *)map[i].function);
xfree ((char *)map[i].function);
break;
case ISMACR:
free ((char *)map[i].function);
xfree ((char *)map[i].function);
break;
}
}
@@ -158,5 +158,5 @@ rl_free_keymap (map)
Keymap map;
{
rl_discard_keymap (map);
free ((char *)map);
xfree ((char *)map);
}

View File

@@ -52,11 +52,6 @@ typedef struct _keymap_entry {
#define KEYMAP_SIZE 257
#define ANYOTHERKEY KEYMAP_SIZE-1
/* I wanted to make the above structure contain a union of:
union { rl_command_func_t *function; struct _keymap_entry *keymap; } value;
but this made it impossible for me to create a static array.
Maybe I need C lessons. */
typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE];
typedef KEYMAP_ENTRY *Keymap;

View File

@@ -147,7 +147,7 @@ _rl_copy_to_kill_ring (text, append)
strcat (new, old);
}
xfree (old);
free (text);
xfree (text);
rl_kill_ring[slot] = new;
}
else
@@ -601,7 +601,7 @@ rl_yank_nth_arg_internal (count, ignore, history_skip)
#endif /* VI_MODE */
rl_insert_text (arg);
free (arg);
xfree (arg);
rl_end_undo_group ();
return 0;
@@ -640,7 +640,7 @@ rl_yank_last_arg (count, key)
{
if (undo_needed)
rl_do_undo ();
if (count < 1)
if (count < 0) /* XXX - was < 1 */
direction = -direction;
history_skip += direction;
if (history_skip < 0)

View File

@@ -328,7 +328,7 @@ _rl_free_history_entry (entry)
FREE (entry->line);
FREE (entry->timestamp);
free (entry);
xfree (entry);
}
/* Perhaps put back the current line if it has changed. */
@@ -342,9 +342,9 @@ rl_maybe_replace_line ()
if (temp && ((UNDO_LIST *)(temp->data) != rl_undo_list))
{
temp = replace_history_entry (where_history (), rl_line_buffer, (histdata_t)rl_undo_list);
free (temp->line);
xfree (temp->line);
FREE (temp->timestamp);
free (temp);
xfree (temp);
}
return 0;
}
@@ -480,7 +480,7 @@ _rl_revert_all_lines ()
_rl_set_the_line ();
/* and clean up */
free (lbuf);
xfree (lbuf);
}
/* **************************************************************** */

View File

@@ -145,7 +145,7 @@ _rl_init_eightbit ()
_rl_output_meta_chars = 1;
break;
}
free (t);
xfree (t);
return (legal_lang_values[i] ? 1 : 0);
#endif /* !HAVE_SETLOCALE */

View File

@@ -0,0 +1,47 @@
/* posixselect.h -- wrapper for select(2) includes and definitions */
/* Copyright (C) 2009 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash 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 3 of the License, or
(at your option) any later version.
Bash 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.
You should have received a copy of the GNU General Public License
along with Bash. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _POSIXSELECT_H_
#define _POSIXSELECT_H_
#if defined (FD_SET) && !defined (HAVE_SELECT)
# define HAVE_SELECT 1
#endif
#if defined (HAVE_SELECT)
# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX)
# include <sys/time.h>
# endif
#endif /* HAVE_SELECT */
#if defined (HAVE_SYS_SELECT_H)
# include <sys/select.h>
#endif
#ifndef USEC_PER_SEC
# define USEC_PER_SEC 1000000
#endif
#define USEC_TO_TIMEVAL(us, tv) \
do { \
(tv).tv_sec = (us) / USEC_PER_SEC; \
(tv).tv_usec = (us) % USEC_PER_SEC; \
} while (0)
#endif /* _POSIXSELECT_H_ */

View File

@@ -382,7 +382,7 @@ readline_internal_setup ()
nprompt = _rl_strip_prompt (rl_prompt);
fprintf (_rl_out_stream, "%s", nprompt);
fflush (_rl_out_stream);
free (nprompt);
xfree (nprompt);
}
}
else
@@ -426,7 +426,7 @@ readline_internal_teardown (eof)
_rl_free_history_entry (entry);
strcpy (the_line, temp);
free (temp);
xfree (temp);
}
if (_rl_revert_all_at_newline)
@@ -629,7 +629,7 @@ void
_rl_keyseq_cxt_dispose (cxt)
_rl_keyseq_cxt *cxt;
{
free (cxt);
xfree (cxt);
}
void

View File

@@ -1,6 +1,6 @@
/* Readline.h -- the names of functions callable from within readline. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2011 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -39,9 +39,9 @@ extern "C" {
#endif
/* Hex-encoded Readline version number. */
#define RL_READLINE_VERSION 0x0600 /* Readline 6.0 */
#define RL_READLINE_VERSION 0x0602 /* Readline 6.2 */
#define RL_VERSION_MAJOR 6
#define RL_VERSION_MINOR 0
#define RL_VERSION_MINOR 2
/* Readline data structures. */
@@ -666,16 +666,24 @@ extern const char *rl_special_prefixes;
completing on a directory name. The function is called with
the address of a string (the current directory name) as an arg. It
changes what is displayed when the possible completions are printed
or inserted. */
or inserted. The directory completion hook should perform
any necessary dequoting. This function should return 1 if it modifies
the directory name pointer passed as an argument. If the directory
completion hook returns 0, it should not modify the directory name
pointer passed as an argument. */
extern rl_icppfunc_t *rl_directory_completion_hook;
/* If non-zero, this is the address of a function to call when completing
a directory name. This function takes the address of the directory name
to be modified as an argument. Unlike rl_directory_completion_hook, it
only modifies the directory name used in opendir(2), not what is displayed
when the possible completions are printed or inserted. It is called
before rl_directory_completion_hook. I'm not happy with how this works
yet, so it's undocumented. */
when the possible completions are printed or inserted. If set, it takes
precedence over rl_directory_completion_hook. The directory rewrite
hook should perform any necessary dequoting. This function has the same
return value properties as the directory_completion_hook.
I'm not happy with how this works yet, so it's undocumented. I'm trying
it in bash to see how well it goes. */
extern rl_icppfunc_t *rl_directory_rewrite_hook;
/* If non-zero, this is the address of a function to call when reading
@@ -805,30 +813,30 @@ extern int rl_inhibit_completion;
/* Possible state values for rl_readline_state */
#define RL_STATE_NONE 0x000000 /* no state; before first call */
#define RL_STATE_INITIALIZING 0x000001 /* initializing */
#define RL_STATE_INITIALIZED 0x000002 /* initialization done */
#define RL_STATE_TERMPREPPED 0x000004 /* terminal is prepped */
#define RL_STATE_READCMD 0x000008 /* reading a command key */
#define RL_STATE_METANEXT 0x000010 /* reading input after ESC */
#define RL_STATE_DISPATCHING 0x000020 /* dispatching to a command */
#define RL_STATE_MOREINPUT 0x000040 /* reading more input in a command function */
#define RL_STATE_ISEARCH 0x000080 /* doing incremental search */
#define RL_STATE_NSEARCH 0x000100 /* doing non-inc search */
#define RL_STATE_SEARCH 0x000200 /* doing a history search */
#define RL_STATE_NUMERICARG 0x000400 /* reading numeric argument */
#define RL_STATE_MACROINPUT 0x000800 /* getting input from a macro */
#define RL_STATE_MACRODEF 0x001000 /* defining keyboard macro */
#define RL_STATE_OVERWRITE 0x002000 /* overwrite mode */
#define RL_STATE_COMPLETING 0x004000 /* doing completion */
#define RL_STATE_SIGHANDLER 0x008000 /* in readline sighandler */
#define RL_STATE_UNDOING 0x010000 /* doing an undo */
#define RL_STATE_INPUTPENDING 0x020000 /* rl_execute_next called */
#define RL_STATE_TTYCSAVED 0x040000 /* tty special chars saved */
#define RL_STATE_CALLBACK 0x080000 /* using the callback interface */
#define RL_STATE_VIMOTION 0x100000 /* reading vi motion arg */
#define RL_STATE_MULTIKEY 0x200000 /* reading multiple-key command */
#define RL_STATE_VICMDONCE 0x400000 /* entered vi command mode at least once */
#define RL_STATE_REDISPLAYING 0x800000 /* updating terminal display */
#define RL_STATE_INITIALIZING 0x0000001 /* initializing */
#define RL_STATE_INITIALIZED 0x0000002 /* initialization done */
#define RL_STATE_TERMPREPPED 0x0000004 /* terminal is prepped */
#define RL_STATE_READCMD 0x0000008 /* reading a command key */
#define RL_STATE_METANEXT 0x0000010 /* reading input after ESC */
#define RL_STATE_DISPATCHING 0x0000020 /* dispatching to a command */
#define RL_STATE_MOREINPUT 0x0000040 /* reading more input in a command function */
#define RL_STATE_ISEARCH 0x0000080 /* doing incremental search */
#define RL_STATE_NSEARCH 0x0000100 /* doing non-inc search */
#define RL_STATE_SEARCH 0x0000200 /* doing a history search */
#define RL_STATE_NUMERICARG 0x0000400 /* reading numeric argument */
#define RL_STATE_MACROINPUT 0x0000800 /* getting input from a macro */
#define RL_STATE_MACRODEF 0x0001000 /* defining keyboard macro */
#define RL_STATE_OVERWRITE 0x0002000 /* overwrite mode */
#define RL_STATE_COMPLETING 0x0004000 /* doing completion */
#define RL_STATE_SIGHANDLER 0x0008000 /* in readline sighandler */
#define RL_STATE_UNDOING 0x0010000 /* doing an undo */
#define RL_STATE_INPUTPENDING 0x0020000 /* rl_execute_next called */
#define RL_STATE_TTYCSAVED 0x0040000 /* tty special chars saved */
#define RL_STATE_CALLBACK 0x0080000 /* using the callback interface */
#define RL_STATE_VIMOTION 0x0100000 /* reading vi motion arg */
#define RL_STATE_MULTIKEY 0x0200000 /* reading multiple-key command */
#define RL_STATE_VICMDONCE 0x0400000 /* entered vi command mode at least once */
#define RL_STATE_REDISPLAYING 0x0800000 /* updating terminal display */
#define RL_STATE_DONE 0x1000000 /* done; accepted line */

View File

@@ -1,7 +1,7 @@
/* rlprivate.h -- functions and variables global to the readline library,
but not intended for use by applications. */
/* Copyright (C) 1999-2009 Free Software Foundation, Inc.
/* Copyright (C) 1999-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -56,6 +56,7 @@
#define SF_REVERSE 0x01
#define SF_FOUND 0x02
#define SF_FAILED 0x04
#define SF_CHGKMAP 0x08
typedef struct __rl_search_context
{
@@ -79,6 +80,9 @@ typedef struct __rl_search_context
UNDO_LIST *save_undo_list;
Keymap keymap; /* used when dispatching commands in search string */
Keymap okeymap; /* original keymap */
int history_pos;
int direction;
@@ -120,7 +124,28 @@ typedef struct __rl_keyseq_context
int childval;
} _rl_keyseq_cxt;
/* fill in more as needed */
/* vi-mode commands that use result of motion command to define boundaries */
#define VIM_DELETE 0x01
#define VIM_CHANGE 0x02
#define VIM_YANK 0x04
/* various states for vi-mode commands that use motion commands. reflects
RL_READLINE_STATE */
#define VMSTATE_READ 0x01
#define VMSTATE_NUMARG 0x02
typedef struct __rl_vimotion_context
{
int op;
int state;
int flags; /* reserved */
_rl_arg_cxt ncxt;
int numeric_arg;
int start, end; /* rl_point, rl_end */
int key, motion; /* initial key, motion command */
} _rl_vimotion_cxt;
/* fill in more as needed */
/* `Generic' callback data and functions */
typedef struct __rl_callback_generic_arg
{
@@ -320,6 +345,7 @@ extern void _rl_set_cursor PARAMS((int, int));
/* text.c */
extern void _rl_fix_point PARAMS((int));
extern int _rl_replace_text PARAMS((const char *, int, int));
extern int _rl_forward_char_internal PARAMS((int));
extern int _rl_insert_char PARAMS((int, int));
extern int _rl_overwrite_char PARAMS((int, int));
extern int _rl_overwrite_rubout PARAMS((int, int));
@@ -366,6 +392,7 @@ extern void _rl_vi_reset_last PARAMS((void));
extern void _rl_vi_set_last PARAMS((int, int, int));
extern int _rl_vi_textmod_command PARAMS((int));
extern void _rl_vi_done_inserting PARAMS((void));
extern int _rl_vi_domove_callback PARAMS((_rl_vimotion_cxt *));
/*************************************************************************
* Undocumented private variables *
@@ -385,11 +412,14 @@ extern int _rl_complete_show_unmodified;
extern int _rl_complete_mark_directories;
extern int _rl_complete_mark_symlink_dirs;
extern int _rl_completion_prefix_display_length;
extern int _rl_completion_columns;
extern int _rl_print_completions_horizontally;
extern int _rl_completion_case_fold;
extern int _rl_completion_case_map;
extern int _rl_match_hidden_files;
extern int _rl_page_completions;
extern int _rl_skip_completed_text;
extern int _rl_menu_complete_prefix_first;
/* display.c */
extern int _rl_vis_botlin;
@@ -471,5 +501,6 @@ extern int _rl_undo_group_level;
/* vi_mode.c */
extern int _rl_vi_last_command;
extern _rl_vimotion_cxt *_rl_vimvcxt;
#endif /* _RL_PRIVATE_H_ */

View File

@@ -604,7 +604,7 @@ rl_prep_terminal (meta_flag)
/* Try to keep this function from being INTerrupted. */
_rl_block_sigint ();
tty = fileno (rl_instream);
tty = rl_instream ? fileno (rl_instream) : fileno (stdin);
if (get_tty_settings (tty, &tio) < 0)
{
@@ -678,7 +678,7 @@ rl_deprep_terminal ()
/* Try to keep this function from being interrupted. */
_rl_block_sigint ();
tty = fileno (rl_instream);
tty = rl_instream ? fileno (rl_instream) : fileno (stdout);
if (_rl_enable_keypad)
_rl_control_keypad (0);

View File

@@ -33,5 +33,9 @@ char *
savestring (s)
const char *s;
{
return ((char *)strcpy ((char *)xmalloc (1 + strlen (s)), (s)));
char *ret;
ret = (char *)xmalloc (strlen (s) + 1);
strcpy (ret, s);
return ret;
}

View File

@@ -211,7 +211,7 @@ _rl_nsearch_init (dir, pchar)
p = _rl_make_prompt_for_search (pchar ? pchar : ':');
rl_message ("%s", p, 0);
free (p);
xfree (p);
RL_SETSTATE(RL_STATE_NSEARCH);

View File

@@ -130,12 +130,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);
xfree (b);
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + 1);
sprintf (b, "%d", cols);
setenv ("COLUMNS", b, 1);
free (b);
xfree (b);
#else /* !HAVE_SETENV */
# if defined (HAVE_PUTENV)
b = (char *)xmalloc (INT_STRLEN_BOUND (int) + sizeof ("LINES=") + 1);

View File

@@ -131,6 +131,7 @@ static sighandler_cxt old_winch;
/* Called from RL_CHECK_SIGNALS() macro */
RETSIGTYPE
_rl_signal_handler (sig)
int sig;
{
_rl_caught_signal = 0; /* XXX */

View File

@@ -96,12 +96,12 @@ static char *term_string_buffer = (char *)NULL;
static int tcap_initialized;
#if !defined (__linux__)
#if !defined (__linux__) && !defined (NCURSES_VERSION)
# if defined (__EMX__) || defined (NEED_EXTERN_PC)
extern
# endif /* __EMX__ || NEED_EXTERN_PC */
char PC, *BC, *UP;
#endif /* __linux__ */
#endif /* !__linux__ && !NCURSES_VERSION */
/* Some strings to control terminal actions. These are output by tputs (). */
char *_rl_term_clreol;
@@ -350,9 +350,9 @@ rl_reset_screen_size ()
void
rl_resize_terminal ()
{
_rl_get_screen_size (fileno (rl_instream), 1);
if (_rl_echoing_p)
{
_rl_get_screen_size (fileno (rl_instream), 1);
if (CUSTOM_REDISPLAY_FUNC ())
rl_forced_update_display ();
else if (RL_ISSTATE(RL_STATE_REDISPLAYING) == 0)

View File

@@ -1,6 +1,6 @@
/* text.c -- text handling commands for readline. */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -150,7 +150,7 @@ rl_delete_text (from, to)
if (_rl_doing_an_undo == 0)
rl_add_undo (UNDO_DELETE, from, to, text);
else
free (text);
xfree (text);
rl_end -= diff;
rl_line_buffer[rl_end] = '\0';
@@ -265,11 +265,13 @@ rl_forward_byte (count, key)
if (count > 0)
{
int end = rl_point + count;
int end, lend;
end = rl_point + count;
#if defined (VI_MODE)
int lend = rl_end > 0 ? rl_end - (VI_COMMAND_MODE()) : rl_end;
lend = rl_end > 0 ? rl_end - (VI_COMMAND_MODE()) : rl_end;
#else
int lend = rl_end;
lend = rl_end;
#endif
if (end > lend)
@@ -287,6 +289,31 @@ rl_forward_byte (count, key)
return 0;
}
int
_rl_forward_char_internal (count)
int count;
{
int point;
#if defined (HANDLE_MULTIBYTE)
point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
#if defined (VI_MODE)
if (point >= rl_end && VI_COMMAND_MODE())
point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
#endif
if (rl_end < 0)
rl_end = 0;
#else
point = rl_point + count;
if (point > rl_end)
point = rl_end;
#endif
return (point);
}
#if defined (HANDLE_MULTIBYTE)
/* Move forward COUNT characters. */
int
@@ -309,20 +336,12 @@ rl_forward_char (count, key)
return 0;
}
point = _rl_find_next_mbchar (rl_line_buffer, rl_point, count, MB_FIND_NONZERO);
#if defined (VI_MODE)
if (point >= rl_end && VI_COMMAND_MODE())
point = _rl_find_prev_mbchar (rl_line_buffer, rl_end, MB_FIND_NONZERO);
#endif
point = _rl_forward_char_internal (count);
if (rl_point == point)
rl_ding ();
rl_point = point;
if (rl_end < 0)
rl_end = 0;
}
return 0;
@@ -752,7 +771,7 @@ _rl_insert_char (count, c)
string[i] = '\0';
rl_insert_text (string);
free (string);
xfree (string);
return 0;
}
@@ -779,7 +798,7 @@ _rl_insert_char (count, c)
count -= decreaser;
}
free (string);
xfree (string);
incoming_length = 0;
stored_count = 0;
#else /* !HANDLE_MULTIBYTE */
@@ -805,8 +824,9 @@ _rl_insert_char (count, c)
/* We are inserting a single character.
If there is pending input, then make a string of all of the
pending characters that are bound to rl_insert, and insert
them all. */
if (_rl_any_typein ())
them all. Don't do this if we're current reading input from
a macro. */
if ((RL_ISSTATE (RL_STATE_MACROINPUT) == 0) && _rl_any_typein ())
_rl_insert_typein (c);
else
{
@@ -1407,8 +1427,8 @@ rl_transpose_words (count, key)
/* I think that does it. */
rl_end_undo_group ();
free (word1);
free (word2);
xfree (word1);
xfree (word2);
return 0;
}
@@ -1467,7 +1487,7 @@ rl_transpose_chars (count, key)
rl_end_undo_group ();
#if defined (HANDLE_MULTIBYTE)
free (dummy);
xfree (dummy);
#endif
return 0;
@@ -1495,6 +1515,9 @@ _rl_char_search_internal (count, dir, schar)
int prepos;
#endif
if (dir == 0)
return -1;
pos = rl_point;
inc = (dir < 0) ? -1 : 1;
while (count)

View File

@@ -378,7 +378,7 @@ tilde_expand_word (filename)
{
dirname = glue_prefix_and_suffix (expansion, filename, user_len);
xfree (username);
free (expansion);
xfree (expansion);
return (dirname);
}
}
@@ -401,7 +401,7 @@ tilde_expand_word (filename)
if (expansion)
{
dirname = glue_prefix_and_suffix (expansion, filename, user_len);
free (expansion);
xfree (expansion);
}
}
/* If we don't have a failure hook, or if the failure hook did not

View File

@@ -1,6 +1,6 @@
/* util.c -- readline utility functions */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -366,41 +366,56 @@ _rl_strpbrk (string1, string2)
#if !defined (HAVE_STRCASECMP)
/* Compare at most COUNT characters from string1 to string2. Case
doesn't matter. */
doesn't matter (strncasecmp). */
int
_rl_strnicmp (string1, string2, count)
char *string1, *string2;
int count;
{
register char ch1, ch2;
register char *s1, *s2;
int d;
while (count)
if (count <= 0 || (string1 == string2))
return 0;
s1 = string1;
s2 = string2;
do
{
ch1 = *string1++;
ch2 = *string2++;
if (_rl_to_upper(ch1) == _rl_to_upper(ch2))
count--;
else
d = _rl_to_lower (*s1) - _rl_to_lower (*s2); /* XXX - cast to unsigned char? */
if (d != 0)
return d;
if (*s1++ == '\0')
break;
s2++;
}
return (count);
while (--count != 0)
return (0);
}
/* strcmp (), but caseless. */
/* strcmp (), but caseless (strcasecmp). */
int
_rl_stricmp (string1, string2)
char *string1, *string2;
{
register char ch1, ch2;
register char *s1, *s2;
int d;
while (*string1 && *string2)
s1 = string1;
s2 = string2;
if (s1 == s2)
return 0;
while ((d = _rl_to_lower (*s1) - _rl_to_lower (*s2)) == 0)
{
ch1 = *string1++;
ch2 = *string2++;
if (_rl_to_upper(ch1) != _rl_to_upper(ch2))
return (1);
if (*s1++ == '\0')
return 0;
s2++;
}
return (*string1 - *string2);
return (d);
}
#endif /* !HAVE_STRCASECMP */

View File

@@ -1,7 +1,7 @@
/* vi_mode.c -- A vi emulation mode for Bash.
Derived from code written by Jeff Sparkes (jsparkes@bnr.ca). */
/* Copyright (C) 1987-2009 Free Software Foundation, Inc.
/* Copyright (C) 1987-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
@@ -65,6 +65,8 @@
int _rl_vi_last_command = 'i'; /* default `.' puts you in insert mode */
_rl_vimotion_cxt *_rl_vimvcxt = 0;
/* Non-zero means enter insertion mode. */
static int _rl_vi_doing_insert;
@@ -128,6 +130,16 @@ static int _rl_vi_callback_change_char PARAMS((_rl_callback_generic_arg *));
static int _rl_vi_callback_char_search PARAMS((_rl_callback_generic_arg *));
#endif
static int rl_domove_read_callback PARAMS((_rl_vimotion_cxt *));
static int rl_domove_motion_callback PARAMS((_rl_vimotion_cxt *));
static int rl_vi_domove_getchar PARAMS((_rl_vimotion_cxt *));
static int vi_change_dispatch PARAMS((_rl_vimotion_cxt *));
static int vi_delete_dispatch PARAMS((_rl_vimotion_cxt *));
static int vi_yank_dispatch PARAMS((_rl_vimotion_cxt *));
static int vidomove_dispatch PARAMS((_rl_vimotion_cxt *));
void
_rl_vi_initialize_line ()
{
@@ -618,12 +630,16 @@ _rl_vi_append_forward (key)
if (MB_CUR_MAX == 1 || rl_byte_oriented)
rl_point++;
else
{
point = rl_point;
rl_forward_char (1, key);
if (point == rl_point)
rl_point = rl_end;
}
{
point = rl_point;
#if 0
rl_forward_char (1, key);
#else
rl_point = _rl_forward_char_internal (1);
#endif
if (point == rl_point)
rl_point = rl_end;
}
}
}
@@ -721,7 +737,7 @@ _rl_vi_done_inserting ()
_rl_vi_last_key_before_insert == 'a' ||
_rl_vi_last_key_before_insert == 'I' ||
_rl_vi_last_key_before_insert == 'A'))
_rl_vi_save_insert (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')
rl_end_undo_group ();
@@ -781,7 +797,7 @@ _rl_vi_change_mbchar_case (count)
if (MB_INVALIDCH (m))
wc = (wchar_t)rl_line_buffer[rl_point];
else if (MB_NULLWCH (m))
wc = L'\0';
wc = L'\0';
if (iswupper (wc))
wc = towlower (wc);
else if (iswlower (wc))
@@ -809,7 +825,7 @@ _rl_vi_change_mbchar_case (count)
rl_vi_check ();
}
else
rl_forward_char (1, 0);
rl_forward_char (1, 0);
}
return 0;
@@ -856,7 +872,7 @@ rl_vi_change_case (count, ignore)
_rl_insert_char (1, c);
rl_end_undo_group ();
rl_vi_check ();
}
}
else
rl_forward_char (1, c);
}
@@ -894,7 +910,7 @@ rl_vi_check ()
if (MB_CUR_MAX > 1 && rl_byte_oriented == 0)
rl_point = _rl_find_prev_mbchar (rl_line_buffer, rl_point, MB_FIND_NONZERO);
else
rl_point--;
rl_point--;
}
return (0);
}
@@ -910,113 +926,6 @@ rl_vi_column (count, key)
return (0);
}
int
rl_vi_domove (key, nextkey)
int key, *nextkey;
{
int c, save;
int old_end;
rl_mark = rl_point;
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (c < 0)
{
*nextkey = 0;
return -1;
}
*nextkey = c;
if (!member (c, vi_motion))
{
if (_rl_digit_p (c))
{
save = rl_numeric_arg;
rl_numeric_arg = _rl_digit_value (c);
rl_explicit_arg = 1;
RL_SETSTATE (RL_STATE_NUMERICARG|RL_STATE_VIMOTION);
rl_digit_loop1 ();
RL_UNSETSTATE (RL_STATE_VIMOTION);
rl_numeric_arg *= save;
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key (); /* real command */
RL_UNSETSTATE(RL_STATE_MOREINPUT);
if (c < 0)
{
*nextkey = 0;
return -1;
}
*nextkey = c;
}
else if (key == c && (key == 'd' || key == 'y' || key == 'c'))
{
rl_mark = rl_end;
rl_beg_of_line (1, c);
_rl_vi_last_motion = c;
return (0);
}
else
return (-1);
}
_rl_vi_last_motion = c;
/* Append a blank character temporarily so that the motion routines
work right at the end of the line. */
old_end = rl_end;
rl_line_buffer[rl_end++] = ' ';
rl_line_buffer[rl_end] = '\0';
_rl_dispatch (c, _rl_keymap);
/* Remove the blank that we added. */
rl_end = old_end;
rl_line_buffer[rl_end] = '\0';
if (rl_point > rl_end)
rl_point = rl_end;
/* No change in position means the command failed. */
if (rl_mark == rl_point)
return (-1);
/* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
word. If we are not at the end of the line, and we are on a
non-whitespace character, move back one (presumably to whitespace). */
if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
!whitespace (rl_line_buffer[rl_point]))
rl_point--;
/* If cw or cW, back up to the end of a word, so the behaviour of ce
or cE is the actual result. Brute-force, no subtlety. */
if (key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
{
/* Don't move farther back than where we started. */
while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
rl_point--;
/* Posix.2 says that if cw or cW moves the cursor towards the end of
the line, the character under the cursor should be deleted. */
if (rl_point == rl_mark)
rl_point++;
else
{
/* Move past the end of the word so that the kill doesn't
remove the last letter of the previous word. Only do this
if we are not at the end of the line. */
if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
rl_point++;
}
}
if (rl_mark < rl_point)
SWAP (rl_point, rl_mark);
return (0);
}
/* Process C as part of the current numeric argument. Return -1 if the
argument should be aborted, 0 if we should not read any more chars, and
1 if we should continue to read chars. */
@@ -1042,13 +951,13 @@ _rl_vi_arg_dispatch (c)
else
rl_numeric_arg = _rl_digit_value (c);
rl_explicit_arg = 1;
return 1;
return 1; /* keep going */
}
else
{
rl_clear_message ();
rl_stuff_char (key);
return 0;
return 0; /* done */
}
}
@@ -1076,28 +985,233 @@ rl_digit_loop1 ()
return (0);
}
int
rl_vi_delete_to (count, key)
int count, key;
static void
_rl_mvcxt_init (m, op, key)
_rl_vimotion_cxt *m;
int op, key;
{
int c, start_pos;
m->op = op;
m->state = m->flags = 0;
m->ncxt = 0;
m->numeric_arg = -1;
m->start = rl_point;
m->end = rl_end;
m->key = key;
m->motion = -1;
}
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
else if (vi_redoing)
rl_stuff_char (_rl_vi_last_motion);
static _rl_vimotion_cxt *
_rl_mvcxt_alloc (op, key)
int op, key;
{
_rl_vimotion_cxt *m;
start_pos = rl_point;
m = xmalloc (sizeof (_rl_vimotion_cxt));
_rl_mvcxt_init (m, op, key);
return m;
}
if (rl_vi_domove (key, &c))
static void
_rl_mvcxt_dispose (m)
_rl_vimotion_cxt *m;
{
xfree (m);
}
static int
rl_domove_motion_callback (m)
_rl_vimotion_cxt *m;
{
int c, save, r;
int old_end;
_rl_vi_last_motion = c = m->motion;
/* Append a blank character temporarily so that the motion routines
work right at the end of the line. */
old_end = rl_end;
rl_line_buffer[rl_end++] = ' ';
rl_line_buffer[rl_end] = '\0';
_rl_dispatch (c, _rl_keymap);
/* Remove the blank that we added. */
rl_end = old_end;
rl_line_buffer[rl_end] = '\0';
if (rl_point > rl_end)
rl_point = rl_end;
/* No change in position means the command failed. */
if (rl_mark == rl_point)
return (-1);
/* rl_vi_f[wW]ord () leaves the cursor on the first character of the next
word. If we are not at the end of the line, and we are on a
non-whitespace character, move back one (presumably to whitespace). */
if ((_rl_to_upper (c) == 'W') && rl_point < rl_end && rl_point > rl_mark &&
!whitespace (rl_line_buffer[rl_point]))
rl_point--;
/* If cw or cW, back up to the end of a word, so the behaviour of ce
or cE is the actual result. Brute-force, no subtlety. */
if (m->key == 'c' && rl_point >= rl_mark && (_rl_to_upper (c) == 'W'))
{
rl_ding ();
/* Don't move farther back than where we started. */
while (rl_point > rl_mark && whitespace (rl_line_buffer[rl_point]))
rl_point--;
/* Posix.2 says that if cw or cW moves the cursor towards the end of
the line, the character under the cursor should be deleted. */
if (rl_point == rl_mark)
rl_point++;
else
{
/* Move past the end of the word so that the kill doesn't
remove the last letter of the previous word. Only do this
if we are not at the end of the line. */
if (rl_point >= 0 && rl_point < (rl_end - 1) && !whitespace (rl_line_buffer[rl_point]))
rl_point++;
}
}
if (rl_mark < rl_point)
SWAP (rl_point, rl_mark);
#if defined (READLINE_CALLBACKS)
if (RL_ISSTATE (RL_STATE_CALLBACK))
(*rl_redisplay_function)(); /* make sure motion is displayed */
#endif
r = vidomove_dispatch (m);
return (r);
}
#define RL_VIMOVENUMARG() (RL_ISSTATE (RL_STATE_VIMOTION) && RL_ISSTATE (RL_STATE_NUMERICARG))
static int
rl_domove_read_callback (m)
_rl_vimotion_cxt *m;
{
int c, save;
c = m->motion;
if (member (c, vi_motion))
{
#if defined (READLINE_CALLBACKS)
/* If we just read a vi-mode motion command numeric argument, turn off
the `reading numeric arg' state */
if (RL_ISSTATE (RL_STATE_CALLBACK) && RL_VIMOVENUMARG())
RL_UNSETSTATE (RL_STATE_NUMERICARG);
#endif
/* Should do everything, including turning off RL_STATE_VIMOTION */
return (rl_domove_motion_callback (m));
}
else if (m->key == c && (m->key == 'd' || m->key == 'y' || m->key == 'c'))
{
rl_mark = rl_end;
rl_beg_of_line (1, c);
_rl_vi_last_motion = c;
RL_UNSETSTATE (RL_STATE_VIMOTION);
return (0);
}
#if defined (READLINE_CALLBACKS)
/* XXX - these need to handle rl_universal_argument bindings */
/* Reading vi motion char continuing numeric argument */
else if (_rl_digit_p (c) && RL_ISSTATE (RL_STATE_CALLBACK) && RL_VIMOVENUMARG())
{
return (_rl_vi_arg_dispatch (c));
}
/* Readine vi motion char starting numeric argument */
else if (_rl_digit_p (c) && RL_ISSTATE (RL_STATE_CALLBACK) && RL_ISSTATE (RL_STATE_VIMOTION) && (RL_ISSTATE (RL_STATE_NUMERICARG) == 0))
{
RL_SETSTATE (RL_STATE_NUMERICARG);
return (_rl_vi_arg_dispatch (c));
}
#endif
else if (_rl_digit_p (c))
{
/* This code path taken when not in callback mode */
save = rl_numeric_arg;
rl_numeric_arg = _rl_digit_value (c);
rl_explicit_arg = 1;
RL_SETSTATE (RL_STATE_NUMERICARG);
rl_digit_loop1 ();
rl_numeric_arg *= save;
c = rl_vi_domove_getchar (m);
if (c < 0)
{
m->motion = 0;
return -1;
}
m->motion = c;
return (rl_domove_motion_callback (m));
}
else
{
RL_UNSETSTATE (RL_STATE_VIMOTION);
RL_UNSETSTATE (RL_STATE_NUMERICARG);
return (1);
}
}
static int
rl_vi_domove_getchar (m)
_rl_vimotion_cxt *m;
{
int c;
RL_SETSTATE(RL_STATE_MOREINPUT);
c = rl_read_key ();
RL_UNSETSTATE(RL_STATE_MOREINPUT);
return c;
}
#if defined (READLINE_CALLBACKS)
int
_rl_vi_domove_callback (m)
_rl_vimotion_cxt *m;
{
int c, r;
m->motion = c = rl_vi_domove_getchar (m);
/* XXX - what to do if this returns -1? Should we return 1 for eof to
callback code? */
r = rl_domove_read_callback (m);
return ((r == 0) ? r : 1); /* normalize return values */
}
#endif
/* This code path taken when not in callback mode. */
int
rl_vi_domove (x, ignore)
int x, *ignore;
{
int r;
_rl_vimotion_cxt *m;
m = _rl_vimvcxt;
*ignore = m->motion = rl_vi_domove_getchar (m);
if (m->motion < 0)
{
m->motion = 0;
return -1;
}
return (rl_domove_read_callback (m));
}
static int
vi_delete_dispatch (m)
_rl_vimotion_cxt *m;
{
/* These are the motion commands that do not require adjusting the
mark. */
if (((strchr (" l|h^0bBFT`", c) == 0) && (rl_point >= start_pos)) &&
if (((strchr (" l|h^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
@@ -1106,34 +1220,61 @@ rl_vi_delete_to (count, key)
}
int
rl_vi_change_to (count, key)
rl_vi_delete_to (count, key)
int count, key;
{
int c, start_pos;
int c, r;
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_DELETE, key);
_rl_vimvcxt->start = rl_point;
rl_mark = rl_point;
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
{
_rl_vimvcxt->motion = '$';
r = rl_domove_motion_callback (_rl_vimvcxt);
}
else if (vi_redoing)
rl_stuff_char (_rl_vi_last_motion);
{
_rl_vimvcxt->motion = _rl_vi_last_motion;
r = rl_domove_motion_callback (_rl_vimvcxt);
}
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
RL_SETSTATE (RL_STATE_VIMOTION);
return (0);
}
#endif
else
r = rl_vi_domove (key, &c);
start_pos = rl_point;
if (rl_vi_domove (key, &c))
if (r < 0)
{
rl_ding ();
return -1;
r = -1;
}
_rl_mvcxt_dispose (_rl_vimvcxt);
_rl_vimvcxt = 0;
return r;
}
static int
vi_change_dispatch (m)
_rl_vimotion_cxt *m;
{
/* These are the motion commands that do not require adjusting the
mark. c[wW] are handled by special-case code in rl_vi_domove(),
and already leave the mark at the correct location. */
if (((strchr (" l|hwW^0bBFT`", c) == 0) && (rl_point >= start_pos)) &&
if (((strchr (" l|hwW^0bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
/* The cursor never moves with c[wW]. */
if ((_rl_to_upper (c) == 'W') && rl_point < start_pos)
rl_point = start_pos;
if ((_rl_to_upper (m->motion) == 'W') && rl_point < m->start)
rl_point = m->start;
if (vi_redoing)
{
@@ -1151,44 +1292,138 @@ rl_vi_change_to (count, key)
rl_begin_undo_group (); /* to make the `u' command work */
rl_kill_text (rl_point, rl_mark);
/* `C' does not save the text inserted for undoing or redoing. */
if (_rl_uppercase_p (key) == 0)
_rl_vi_doing_insert = 1;
rl_vi_start_inserting (key, rl_numeric_arg, rl_arg_sign);
if (_rl_uppercase_p (m->key) == 0)
_rl_vi_doing_insert = 1;
/* XXX -- TODO -- use m->numericarg? */
rl_vi_start_inserting (m->key, rl_numeric_arg, rl_arg_sign);
}
return (0);
}
int
rl_vi_change_to (count, key)
int count, key;
{
int c, r;
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_CHANGE, key);
_rl_vimvcxt->start = rl_point;
rl_mark = rl_point;
if (_rl_uppercase_p (key))
{
_rl_vimvcxt->motion = '$';
r = rl_domove_motion_callback (_rl_vimvcxt);
}
else if (vi_redoing)
{
_rl_vimvcxt->motion = _rl_vi_last_motion;
r = rl_domove_motion_callback (_rl_vimvcxt);
}
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
RL_SETSTATE (RL_STATE_VIMOTION);
return (0);
}
#endif
else
r = rl_vi_domove (key, &c);
if (r < 0)
{
rl_ding ();
r = -1; /* normalize return value */
}
_rl_mvcxt_dispose (_rl_vimvcxt);
_rl_vimvcxt = 0;
return r;
}
static int
vi_yank_dispatch (m)
_rl_vimotion_cxt *m;
{
/* These are the motion commands that do not require adjusting the
mark. */
if (((strchr (" l|h^0%bBFT`", m->motion) == 0) && (rl_point >= m->start)) &&
(rl_mark < rl_end))
rl_mark++;
rl_begin_undo_group ();
rl_kill_text (rl_point, rl_mark);
rl_end_undo_group ();
rl_do_undo ();
rl_point = m->start;
return (0);
}
int
rl_vi_yank_to (count, key)
int count, key;
{
int c, start_pos;
int c, r;
_rl_vimvcxt = _rl_mvcxt_alloc (VIM_YANK, key);
_rl_vimvcxt->start = rl_point;
rl_mark = rl_point;
if (_rl_uppercase_p (key))
rl_stuff_char ('$');
{
_rl_vimvcxt->motion = '$';
r = rl_domove_motion_callback (_rl_vimvcxt);
}
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
RL_SETSTATE (RL_STATE_VIMOTION);
return (0);
}
#endif
else
r = rl_vi_domove (key, &c);
start_pos = rl_point;
if (rl_vi_domove (key, &c))
if (r < 0)
{
rl_ding ();
return -1;
r = -1;
}
/* These are the motion commands that do not require adjusting the
mark. */
if (((strchr (" l|h^0%bBFT`", c) == 0) && (rl_point >= start_pos)) &&
(rl_mark < rl_end))
rl_mark++;
_rl_mvcxt_dispose (_rl_vimvcxt);
_rl_vimvcxt = 0;
rl_begin_undo_group ();
rl_kill_text (rl_point, rl_mark);
rl_end_undo_group ();
rl_do_undo ();
rl_point = start_pos;
return r;
}
return (0);
static int
vidomove_dispatch (m)
_rl_vimotion_cxt *m;
{
int r;
switch (m->op)
{
case VIM_DELETE:
r = vi_delete_dispatch (m);
break;
case VIM_CHANGE:
r = vi_change_dispatch (m);
break;
case VIM_YANK:
r = vi_yank_dispatch (m);
break;
default:
_rl_errmsg ("vidomove_dispatch: unknown operator %d", m->op);
r = 1;
break;
}
RL_UNSETSTATE (RL_STATE_VIMOTION);
return r;
}
int
@@ -1317,27 +1552,38 @@ rl_vi_char_search (count, key)
#endif
if (key == ';' || key == ',')
_rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
{
if (_rl_cs_orig_dir == 0)
return -1;
#if defined (HANDLE_MULTIBYTE)
if (_rl_vi_last_search_mblen == 0)
return -1;
#else
if (_rl_vi_last_search_char == 0)
return -1;
#endif
_rl_cs_dir = (key == ';') ? _rl_cs_orig_dir : -_rl_cs_orig_dir;
}
else
{
switch (key)
{
case 't':
_rl_cs_orig_dir = _rl_cs_dir = FTO;
break;
{
case 't':
_rl_cs_orig_dir = _rl_cs_dir = FTO;
break;
case 'T':
_rl_cs_orig_dir = _rl_cs_dir = BTO;
break;
case 'T':
_rl_cs_orig_dir = _rl_cs_dir = BTO;
break;
case 'f':
_rl_cs_orig_dir = _rl_cs_dir = FFIND;
break;
case 'f':
_rl_cs_orig_dir = _rl_cs_dir = FFIND;
break;
case 'F':
_rl_cs_orig_dir = _rl_cs_dir = BFIND;
break;
}
case 'F':
_rl_cs_orig_dir = _rl_cs_dir = BFIND;
break;
}
if (vi_redoing)
{
@@ -1345,12 +1591,12 @@ rl_vi_char_search (count, key)
}
#if defined (READLINE_CALLBACKS)
else if (RL_ISSTATE (RL_STATE_CALLBACK))
{
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_data->i1 = _rl_cs_dir;
_rl_callback_func = _rl_vi_callback_char_search;
return (0);
}
{
_rl_callback_data = _rl_callback_data_alloc (count);
_rl_callback_data->i1 = _rl_cs_dir;
_rl_callback_func = _rl_vi_callback_char_search;
return (0);
}
#endif
else
{
@@ -1401,7 +1647,7 @@ rl_vi_match (ignore, key)
pre = rl_point;
rl_forward_char (1, key);
if (pre == rl_point)
break;
break;
}
}
else
@@ -1430,7 +1676,7 @@ rl_vi_match (ignore, key)
{
pos = _rl_find_prev_mbchar (rl_line_buffer, pos, MB_FIND_ANY);
if (tmp == pos)
pos--;
pos--;
}
if (pos >= 0)
{
@@ -1678,8 +1924,8 @@ rl_vi_replace (count, key)
vi_replace_map[NEWLINE].function = rl_newline;
/* If the normal vi insertion keymap has ^H bound to erase, do the
same here. Probably should remove the assignment to RUBOUT up
there, but I don't think it will make a difference in real life. */
same here. Probably should remove the assignment to RUBOUT up
there, but I don't think it will make a difference in real life. */
if (vi_insertion_keymap[CTRL ('H')].type == ISFUNC &&
vi_insertion_keymap[CTRL ('H')].function == rl_rubout)
vi_replace_map[CTRL ('H')].function = rl_vi_overstrike_delete;

50
lib/readline/xfree.c Normal file
View File

@@ -0,0 +1,50 @@
/* xfree.c -- safe version of free that ignores attempts to free NUL */
/* Copyright (C) 1991-2010 Free Software Foundation, Inc.
This file is part of the GNU Readline Library (Readline), a library
for reading lines of text with interactive input and history editing.
Readline 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 3 of the License, or
(at your option) any later version.
Readline 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.
You should have received a copy of the GNU General Public License
along with Readline. If not, see <http://www.gnu.org/licenses/>.
*/
#define READLINE_LIBRARY
#if defined (HAVE_CONFIG_H)
#include <config.h>
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# include "ansi_stdlib.h"
#endif /* HAVE_STDLIB_H */
#include "xmalloc.h"
/* **************************************************************** */
/* */
/* Memory Deallocation. */
/* */
/* **************************************************************** */
/* Use this as the function to call when adding unwind protects so we
don't need to know what free() returns. */
void
xfree (string)
PTR_T string;
{
if (string)
free (string);
}

View File

@@ -77,13 +77,3 @@ xrealloc (pointer, bytes)
memory_error_and_abort ("xrealloc");
return (temp);
}
/* Use this as the function to call when adding unwind protects so we
don't need to know what free() returns. */
void
xfree (string)
PTR_T string;
{
if (string)
free (string);
}