From 49772d612981e84e8a803d2667b6162bb8b9313b Mon Sep 17 00:00:00 2001 From: "Andrey A. Chernov" Date: Tue, 28 Apr 1998 06:49:42 +0000 Subject: [PATCH] Merge local changes --- contrib/libreadline/ChangeLog | 403 -------------- contrib/libreadline/complete.c | 864 +++++++++++++++++------------ contrib/libreadline/doc/readline.3 | 127 ++++- contrib/libreadline/readline.3 | 127 ++++- contrib/libreadline/readline.h | 1 + contrib/libreadline/shell.c | 9 + contrib/libreadline/util.c | 62 +++ 7 files changed, 771 insertions(+), 822 deletions(-) delete mode 100644 contrib/libreadline/ChangeLog diff --git a/contrib/libreadline/ChangeLog b/contrib/libreadline/ChangeLog deleted file mode 100644 index 1cf0c004af56..000000000000 --- a/contrib/libreadline/ChangeLog +++ /dev/null @@ -1,403 +0,0 @@ -Tue Mar 23 14:36:51 1993 Brian Fox (bfox@eos.crseo.ucsb.edu) - - * readline.c (rl_copy): Changed name to rl_copy_text. - -Mon Mar 22 19:16:05 1993 Brian Fox (bfox@eos.crseo.ucsb.edu) - - * dispose_cmd.c, several other files. Declare dispose_xxx () as - "void". - - * builtins/hashcom.h: Make declarations of hashed_filenames be - "extern" to keep the SGI compiler happy. - - * readline.c (rl_initialize_everything): Assign values to - out_stream and in_stream immediately, since - output_character_function () can be called before - readline_internal () is called. - -Tue Dec 8 09:30:56 1992 Brian Fox (bfox@cubit) - - * readline.c (rl_init_terminal) Set PC from BC, not from *buffer. - -Mon Nov 30 09:35:47 1992 Brian Fox (bfox@cubit) - - * readline.c (invoking_keyseqs_in_map, rl_parse_and_bind) Allow - backslash to quote characters, such as backslash, double quote, - and space. Backslash quotes all character indiscriminately. - - * funmap.c (vi_keymap) Fix type in "vi-replace" declaration. - -Fri Nov 20 10:55:05 1992 Brian Fox (bfox@cubit) - - * readline.c (init_terminal_io, rl_prep_terminal): FINALLY! - Declare and use termcap variable `ospeed' when setting up terminal - parameters. - -Thu Oct 8 08:53:07 1992 Brian J. Fox (bfox@helios) - - * Makefile, this directory: Include (as links to the canonical - sources), tilde.c, tilde.h, posixstat.h and xmalloc.c. - -Tue Sep 29 13:07:21 1992 Brian J. Fox (bfox@helios) - - * readline.c (init_terminal_io) Don't set arrow keys if the key - sequences that represent them are already set. - - * readline.c (rl_function_of_keyseq) New function returns the first - function (or macro) found while searching a key sequence. - -Mon Sep 28 00:34:04 1992 Brian J. Fox (bfox@helios) - - * readline.c (LibraryVersion) New static char * contains current - version number. Version is at 2.0. - - * readline.c (rl_complete_internal): Incorporated clean changes - from gilmore (gnu@cygnus.com) to support quoted substrings within - completion functions. - - * readline.c (many locations) Added support for the _GO32_, - whatever that is. Patches supplied by Cygnus, typed in by hand, - with cleanups. - -Sun Aug 16 12:46:24 1992 Brian Fox (bfox@cubit) - - * readline.c (init_terminal_io): Find out the values of the keypad - arrows and bind them to appropriate RL functions if present. - -Mon Aug 10 18:13:24 1992 Brian Fox (bfox@cubit) - - * history.c (stifle_history): A negative argument to stifle - becomes zero. - -Tue Jul 28 09:28:41 1992 Brian Fox (bfox@cubit) - - * readline.c (rl_variable_bind): New local structure describes - booleans by name and address; code in rl_variable_bind () looks at - structure to set simple variables. - - * parens.c (rl_insert_close): New variable rl_blink_matching_paren - is non-zero if we want to blink the matching open when a close is - inserted. If FD_SET is defined, rl_blink_matching_paren defaults - to 1, else 0. If FD_SET is not defined, and - rl_blink_matching_paren is non-zero, the close character(s) are/is - simply inserted. - -Wed Jul 22 20:03:59 1992 Brian Fox (bfox@cubit) - - * history.c, readline.c, vi_mode.c: Cause the functions strchr () - and strrchr () to be used instead of index () and rindex () - throughout the source. - -Mon Jul 13 11:34:07 1992 Brian Fox (bfox@cubit) - - * readline.c: (rl_variable_bind) New variable "meta-flag" if "on" - means force the use of the 8th bit as Meta bit. Internal variable - is called meta_flag. - -Thu Jul 9 10:37:56 1992 Brian Fox (bfox@cubit) - - * history.c (get_history_event) Change INDEX to LOCAL_INDEX. If - compiling for the shell, allow shell metacharacters to separate - history tokens as they would for shell tokens. - -Sat Jul 4 19:29:12 1992 Brian Fox (bfox@cubit) - - * vi_keymap.c: According to Posix, TAB self-inserts instead of - doing completion. - - * vi_mode.c: (rl_vi_yank_arg) Enter VI insert mode after yanking - an arg from the previous line. - - * search.c: New file takes over vi style searching and implements - non-incremental searching the history. - - Makefile: Add search.c and search.o. - - funmap.c: Add names for non-incremental-forward-search-history and - non-incremental-reverse-search-history. - - readline.h: Add extern definitions for non-incremental searching. - - vi_mode.c: Remove old search code; add calls to code in search.c. - -Fri Jul 3 10:36:33 1992 Brian Fox (bfox@cubit) - - * readline.c (rl_delete_horizontal_space); New function deletes - all whitespace surrounding point. - - funmap.c: Add "delete-horizontal-space". - emacs_keymap.c: Put rl_delete_horizontal_space () on M-\. - - * readline.c (rl_set_signals, rl_clear_signals); New function - rl_set_sighandler () is either defined in a Posix way (if - HAVE_POSIX_SIGNALS is defined) or in a BSD way. Function is - called from rl_set_signals () and rl_clear_signals (). - -Fri May 8 12:50:15 1992 Brian Fox (bfox@cubit) - - * readline.c: (readline_default_bindings) Do comparisons with - _POSIX_VDISABLE casted to `unsigned char'. Change tty characters - to be unsigned char. - -Thu Apr 30 12:36:35 1992 Brian Fox (bfox@cubit) - - * readline.c: (rl_getc) Handle "read would block" error on - non-blocking IO streams. - - * readline.c: (rl_signal_handler): Unblock only the signal that we - have caught, not all signals. - -Sun Feb 23 03:33:09 1992 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c: Many functions. Use only the macros META_CHAR and - UNMETA to deal with meta characters. Prior to this, we used - numeric values and tests. - - * readline.c (rl_complete_internal) Report exactly the number of - possible completions, not the number + 1. - - * vi_mode.c (rl_do_move) Do not change the cursor position when - using `cw' or `cW'. - - * vi_mode.c (rl_vi_complete) Enter insert mode after completing - with `*' or `\'. - -Fri Feb 21 05:58:18 1992 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c (rl_dispatch) Increment rl_key_sequence_length for - meta characters that map onto ESC map. - -Mon Feb 10 01:41:35 1992 Brian Fox (bfox at gnuwest.fsf.org) - - * history.c (history_do_write) Build a buffer of all of the lines - to write and write them in one fell swoop (lower overhead than - calling write () for each line). Suggested by Peter Ho. - - * readline.c: Include hbullx20 as well as hpux for determining - USGr3ness. - - * readline.c (rl_unix_word_rubout) As per the "Now REMEMBER" - comment, pass arguments to rl_kill_text () in the correct order to - preserve prepending and appending of killed text. - - * readline.c (rl_search_history) malloc (), realloc (), and free - () SEARCH_STRING so that there are no static limits on searching. - - * vi_mode.c (rl_vi_subst) Don't forget to end the undo group. - -Fri Jan 31 14:51:02 1992 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c (rl_signal_handler): Zero the current history entry's - pointer after freeing the undo_list when SIGINT received. - Reformat a couple of functions. - -Sat Jan 25 13:47:35 1992 Brian Fox (bfox at bears) - - * readline.c (parser_if): free () TNAME after use. - -Tue Jan 21 01:01:35 1992 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c (rl_redisplay) and (rl_character_len): Display - Control characters as "^c" and Meta characters as "\234", instead - of "C-C" and "M-C". - -Sun Dec 29 10:59:00 1991 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c (init_terminal_io) Default to environment variables - LINES and COLUMNS before termcap entry values. If all else fails, - then assume 80x24 terminal. - -Sat Dec 28 16:33:11 1991 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c: If this machine is USG and it is hpux, then define - USGr3. - - * history.c: Cosmetic fixes. - -Thu Nov 21 00:10:12 1991 Brian Fox (bfox at gnuwest.fsf.org) - - * vi_mode.c: (rl_do_move) Place cursor at end of line, never at - next to last character. - -Thu Nov 14 05:08:01 1991 Brian Fox (bfox at gnuwest.fsf.org) - - * history.c (get_history_event) Non-anchored searches can have a - return index of greater than zero from get_history_event (). - -Fri Nov 1 07:02:13 1991 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c (rl_translate_keyseq) Make C-? translate to RUBOUT - unconditionally. - -Mon Oct 28 11:34:52 1991 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c; Use Posix directory routines and macros. - - * funmap.c; Add entry for call-last-kbd-macro. - - * readline.c (rl_prep_term); Use system EOF character on POSIX - systems also. - -Thu Oct 3 16:19:53 1991 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c; Make a distinction between having a TERMIOS tty - driver, and having POSIX signal handling. You might one without - the other. New defines used HAVE_POSIX_SIGNALS, and - TERMIOS_TTY_DRIVER. - -Tue Jul 30 22:37:26 1991 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c: rl_getc () If a call to read () returns without an - error, but with zero characters, the file is empty, so return EOF. - -Thu Jul 11 20:58:38 1991 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c: (rl_get_next_history, rl_get_previous_history) - Reallocate the buffer space if the line being moved to is longer - the the current space allocated. Amazing that no one has found - this bug until now. - -Sun Jul 7 02:37:05 1991 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c:(rl_parse_and_bind) Allow leading whitespace. - Make sure TERMIO and TERMIOS systems treat CR and NL - disctinctly. - -Tue Jun 25 04:09:27 1991 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c: Rework parsing conditionals to pay attention to the - prior states of the conditional stack. This makes $if statements - work correctly. - -Mon Jun 24 20:45:59 1991 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c: support for displaying key binding information - includes the functions rl_list_funmap_names (), - invoking_keyseqs_in_map (), rl_invoking_keyseqs (), - rl_dump_functions (), and rl_function_dumper (). - - funmap.c: support for same includes rl_funmap_names (). - - readline.c, funmap.c: no longer define STATIC_MALLOC. However, - update both version of xrealloc () to handle a null pointer. - -Thu Apr 25 12:03:49 1991 Brian Fox (bfox at gnuwest.fsf.org) - - * vi_mode.c (rl_vi_fword, fWord, etc. All functions use - the macro `isident()'. Fixed movement bug which prevents - continious movement through the text. - -Fri Jul 27 16:47:01 1990 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c (parser_if) Allow "$if term=foo" construct. - -Wed May 23 16:10:33 1990 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c (rl_dispatch) Correctly remember the last command - executed. Fixed typo in username_completion_function (). - -Mon Apr 9 19:55:48 1990 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c: username_completion_function (); For text passed in - with a leading `~', remember that this could be a filename (after - it is completed). - -Thu Apr 5 13:44:24 1990 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c: rl_search_history (): Correctly handle case of an - unfound search string, but a graceful exit (as with ESC). - - * readline.c: rl_restart_output (); The Apollo passes the address - of the file descriptor to TIOCSTART, not the descriptor itself. - -Tue Mar 20 05:38:55 1990 Brian Fox (bfox at gnuwest.fsf.org) - - * readline.c: rl_complete (); second call in a row causes possible - completions to be listed. - - * readline.c: rl_redisplay (), added prompt_this_line variable - which is the first character character following \n in prompt. - -Sun Mar 11 04:32:03 1990 Brian Fox (bfox at gnuwest.fsf.org) - - * Signals are now supposedly handled inside of SYSV compilation. - -Wed Jan 17 19:24:09 1990 Brian Fox (bfox at sbphy.ucsb.edu) - - * history.c: history_expand (); fixed overwriting memory error, - added needed argument to call to get_history_event (). - -Thu Jan 11 10:54:04 1990 Brian Fox (bfox at sbphy.ucsb.edu) - - * readline.c: added mark_modified_lines to control the - display of an asterisk on modified history lines. Also - added a user variable called mark-modified-lines to the - `set' command. - -Thu Jan 4 10:38:05 1990 Brian Fox (bfox at sbphy.ucsb.edu) - - * readline.c: start_insert (). Only use IC if we don't have an im - capability. - -Fri Sep 8 09:00:45 1989 Brian Fox (bfox at aurel) - - * readline.c: rl_prep_terminal (). Only turn on 8th bit - as meta-bit iff the terminal is not using parity. - -Sun Sep 3 08:57:40 1989 Brian Fox (bfox at aurel) - - * readline.c: start_insert (). Uses multiple - insertion call in cases where that makes sense. - - rl_insert (). Read type-ahead buffer for additional - keys that are bound to rl_insert, and insert them - all at once. Make insertion of single keys given - with an argument much more efficient. - -Tue Aug 8 18:13:57 1989 Brian Fox (bfox at aurel) - - * readline.c: Changed handling of EOF. readline () returns - (char *)EOF or consed string. The EOF character is read from the - tty, or if the tty doesn't have one, defaults to C-d. - - * readline.c: Added support for event driven programs. - rl_event_hook is the address of a function you want called - while Readline is waiting for input. - - * readline.c: Cleanup time. Functions without type declarations - do not use return with a value. - - * history.c: history_expand () has new variable which is the - characters to ignore immediately following history_expansion_char. - -Sun Jul 16 08:14:00 1989 Brian Fox (bfox at aurel) - - * rl_prep_terminal () - BSD version turns off C-s, C-q, C-y, C-v. - - * readline.c -- rl_prep_terminal () - SYSV version hacks readline_echoing_p. - BSD version turns on passing of the 8th bit for the duration - of reading the line. - -Tue Jul 11 06:25:01 1989 Brian Fox (bfox at aurel) - - * readline.c: new variable rl_tilde_expander. - If non-null, this contains the address of a function to call if - the standard meaning for expanding a tilde fails. The function is - called with the text sans tilde (as in "foo"), and returns a - malloc()'ed string which is the expansion, or a NULL pointer if - there is no expansion. - - * readline.h - new file chardefs.h - Separates things that only readline.c needs from the standard - header file publishing interesting things about readline. - - * readline.c: - readline_default_bindings () now looks at terminal chararacters - and binds those as well. - -Wed Jun 28 20:20:51 1989 Brian Fox (bfox at aurel) - - * Made readline and history into independent libraries. - diff --git a/contrib/libreadline/complete.c b/contrib/libreadline/complete.c index 552cb6c63802..985e8981eee6 100644 --- a/contrib/libreadline/complete.c +++ b/contrib/libreadline/complete.c @@ -75,6 +75,7 @@ extern char *tilde_expand (); extern char *rl_copy_text (); extern void _rl_abort_internal (); extern int _rl_qsort_string_compare (); +extern void _rl_replace_text (); extern Function *rl_last_func; extern int rl_editing_mode; @@ -88,19 +89,55 @@ extern int rl_display_fixed; char *filename_completion_function (); char **completion_matches (); +#if defined (VISIBLE_STATS) +# if !defined (X_OK) +# define X_OK 1 +# endif +static int stat_char (); +#endif + static char *rl_quote_filename (); static char *rl_strpbrk (); static char **remove_duplicate_matches (); -static void insert_text (); static void insert_match (); -static void append_to_match (); +static int append_to_match (); static void insert_all_matches (); static void display_matches (); static int compute_lcd_of_matches (); extern char *xmalloc (), *xrealloc (); +/* **************************************************************** */ +/* */ +/* Completion matching, from readline's point of view. */ +/* */ +/* **************************************************************** */ + +/* Variables known only to the readline library. */ + +/* If non-zero, non-unique completions always show the list of matches. */ +int _rl_complete_show_all = 0; + +/* If non-zero, completed directory names have a slash appended. */ +int _rl_complete_mark_directories = 1; + +/* If non-zero, completions are printed horizontally in alphabetical order, + like `ls -x'. */ +int _rl_print_completions_horizontally; + +/* Non-zero means that case is not significant in filename completion. */ +int _rl_completion_case_fold; + +/* Global variables available to applications using readline. */ + +#if defined (VISIBLE_STATS) +/* Non-zero means add an additional character to each filename displayed + during listing completion iff rl_filename_completion_desired which helps + to indicate the type of file being listed. */ +int rl_visible_stats = 0; +#endif /* VISIBLE_STATS */ + /* 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. */ @@ -109,34 +146,6 @@ Function *rl_directory_completion_hook = (Function *)NULL; /* Non-zero means readline completion functions perform tilde expansion. */ int rl_complete_with_tilde_expansion = 0; -/* If non-zero, non-unique completions always show the list of matches. */ -int _rl_complete_show_all = 0; - -/* If non-zero, completed directory names have a slash appended. */ -int _rl_complete_mark_directories = 1; - -#if defined (VISIBLE_STATS) -# if !defined (X_OK) -# define X_OK 1 -# endif - -static int stat_char (); - -/* Non-zero means add an additional character to each filename displayed - during listing completion iff rl_filename_completion_desired which helps - to indicate the type of file being listed. */ -int rl_visible_stats = 0; -#endif /* VISIBLE_STATS */ - -/* **************************************************************** */ -/* */ -/* Completion matching, from readline's point of view. */ -/* */ -/* **************************************************************** */ - -/* Local variable states what happened during the last completion attempt. */ -static int completion_changed_buffer; - /* Pointer to the generator function for completion_matches (). NULL means to use filename_completion_function (), the default filename completer. */ @@ -242,6 +251,17 @@ int rl_completion_append_character = ' '; /* If non-zero, inhibit completion (temporarily). */ int rl_inhibit_completion; +/* Variables local to this file. */ + +/* Local variable states what happened during the last completion attempt. */ +static int completion_changed_buffer; + +/*************************************/ +/* */ +/* Bindable completion functions */ +/* */ +/*************************************/ + /* Complete the word at or before point. You have supplied the function that does the initial simple matching selection algorithm (see completion_matches ()). The default is to do filename completion. */ @@ -274,6 +294,33 @@ rl_insert_completions (ignore, invoking_key) return (rl_complete_internal ('*')); } +/************************************/ +/* */ +/* Completion utility functions */ +/* */ +/************************************/ + +/* Find the first occurrence in STRING1 of any character from STRING2. + Return a pointer to the character in STRING1. */ +static char * +rl_strpbrk (string1, string2) + char *string1, *string2; +{ + register char *scan; + + for (; *string1; string1++) + { + for (scan = string2; *scan; scan++) + { + if (*string1 == *scan) + { + return (string1); + } + } + } + return ((char *)NULL); +} + /* The user must press "y" or "n". Non-zero return means "y" pressed. */ static int get_y_or_n () @@ -293,6 +340,63 @@ get_y_or_n () } } +#if defined (VISIBLE_STATS) +/* Return the character which best describes FILENAME. + `@' for symbolic links + `/' for directories + `*' for executables + `=' for sockets + `|' for FIFOs + `%' for character special devices + `#' for block special devices */ +static int +stat_char (filename) + char *filename; +{ + struct stat finfo; + int character, r; + +#if defined (HAVE_LSTAT) && defined (S_ISLNK) + r = lstat (filename, &finfo); +#else + r = stat (filename, &finfo); +#endif + + if (r == -1) + return (0); + + character = 0; + if (S_ISDIR (finfo.st_mode)) + character = '/'; +#if defined (S_ISCHR) + else if (S_ISCHR (finfo.st_mode)) + character = '%'; +#endif /* S_ISCHR */ +#if defined (S_ISBLK) + else if (S_ISBLK (finfo.st_mode)) + character = '#'; +#endif /* S_ISBLK */ +#if defined (S_ISLNK) + else if (S_ISLNK (finfo.st_mode)) + character = '@'; +#endif /* S_ISLNK */ +#if defined (S_ISSOCK) + else if (S_ISSOCK (finfo.st_mode)) + character = '='; +#endif /* S_ISSOCK */ +#if defined (S_ISFIFO) + else if (S_ISFIFO (finfo.st_mode)) + character = '|'; +#endif + else if (S_ISREG (finfo.st_mode)) + { + if (access (filename, X_OK) == 0) + character = '*'; + } + return (character); +} +#endif /* VISIBLE_STATS */ + /* Return the portion of PATHNAME that should be output when listing possible completions. If we are hacking filename completion, we are only interested in the basename, the portion following the @@ -309,26 +413,34 @@ printable_part (pathname) /* 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 1 if we printed an extension character, 0 if not. */ + 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) + { \ + 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; @@ -336,7 +448,6 @@ print_filename (to_print, full_pathname) { PUTX (*s); } - return 0; #else char *s, c, *new_full_pathname; int extension_char, slen, tlen; @@ -381,12 +492,13 @@ print_filename (to_print, full_pathname) free (s); if (extension_char) - putc (extension_char, rl_outstream); - return (extension_char != 0); + { + putc (extension_char, rl_outstream); + printed_len++; + } } - else - return 0; #endif /* VISIBLE_STATS */ + return printed_len; } static char * @@ -636,6 +748,125 @@ remove_duplicate_matches (matches) return (temp_array); } +/* Find the common prefix of the list of matches, and put it into + matches[0]. */ +static int +compute_lcd_of_matches (match_list, matches, text) + char **match_list; + int matches; + char *text; +{ + register int i, c1, c2, si; + int low; /* Count of max-matched characters. */ + + /* If only one match, just use that. Otherwise, compare each + member of the list with the next, finding out where they + stop matching. */ + if (matches == 1) + { + match_list[0] = match_list[1]; + match_list[1] = (char *)NULL; + return 1; + } + + for (i = 1, low = 100000; i < matches; i++) + { + if (_rl_completion_case_fold) + { + for (si = 0; + (c1 = _rl_to_lower(match_list[i][si])) && + (c2 = _rl_to_lower(match_list[i + 1][si])); + si++) + if (c1 != c2) + break; + } + else + { + for (si = 0; + (c1 = match_list[i][si]) && + (c2 = match_list[i + 1][si]); + si++) + if (c1 != c2) + break; + } + + if (low > si) + low = si; + } + + /* If there were multiple matches, but none matched up to even the + first character, and the user typed something, use that as the + value of matches[0]. */ + if (low == 0 && text && *text) + { + match_list[0] = xmalloc (strlen (text) + 1); + strcpy (match_list[0], text); + } + else + { + match_list[0] = xmalloc (low + 1); + strncpy (match_list[0], match_list[1], low); + match_list[0][low] = '\0'; + } + + return matches; +} + +static int +postprocess_matches (text, matchesp, matching_filenames) + char *text; + char ***matchesp; + int matching_filenames; +{ + char *t, **matches, **temp_matches; + int nmatch, i; + + matches = *matchesp; + + /* It seems to me that in all the cases we handle we would like + to ignore duplicate possiblilities. Scan for the text to + insert being identical to the other completions. */ + if (rl_ignore_completion_duplicates) + { + temp_matches = remove_duplicate_matches (matches); + free (matches); + matches = temp_matches; + } + + /* If we are matching filenames, then here is our chance to + do clever processing by re-examining the list. Call the + ignore function with the array as a parameter. It can + munge the array, deleting matches as it desires. */ + if (rl_ignore_some_completions_function && matching_filenames) + { + for (nmatch = 1; matches[nmatch]; nmatch++) + ; + (void)(*rl_ignore_some_completions_function) (matches); + if (matches == 0 || matches[0] == 0) + { + FREE (matches); + ding (); + *matchesp = (char **)0; + return 0; + } + else + { + /* If we removed some matches, recompute the common prefix. */ + for (i = 1; matches[i]; i++) + ; + if (i > 1 && i < nmatch) + { + t = matches[0]; + compute_lcd_of_matches (matches, i - 1, text); + FREE (t); + } + } + } + + *matchesp = matches; + return (1); +} + static void display_matches (matches) char **matches; @@ -718,25 +949,47 @@ display_matches (matches) if (rl_ignore_completion_duplicates == 0) qsort (matches + 1, len, sizeof (char *), _rl_qsort_string_compare); - /* Print the sorted items, up-and-down alphabetically, like ls. */ crlf (); - for (i = 1; i <= count; i++) + if (_rl_print_completions_horizontally == 0) { - for (j = 0, l = i; j < limit; j++) + /* Print the sorted items, up-and-down alphabetically, like ls. */ + for (i = 1; i <= count; i++) { - if (l > len || matches[l] == 0) - break; - else + for (j = 0, l = i; j < limit; j++) { - temp = printable_part (matches[l]); - printed_len = strlen (temp) + print_filename (temp, matches[l]); + if (l > len || matches[l] == 0) + break; + else + { + temp = printable_part (matches[l]); + printed_len = print_filename (temp, matches[l]); - if (j + 1 < limit) + if (j + 1 < limit) + for (k = 0; k < max - printed_len; k++) + putc (' ', rl_outstream); + } + l += count; + } + crlf (); + } + } + else + { + /* Print the sorted items, across alphabetically, like ls -x. */ + for (i = 1; matches[i]; i++) + { + temp = printable_part (matches[i]); + printed_len = print_filename (temp, matches[i]); + /* Have we reached the end of this line? */ + if (matches[i+1]) + { + if (i && (limit > 1) && (i % limit) == 0) + crlf (); + else for (k = 0; k < max - printed_len; k++) putc (' ', rl_outstream); } - l += count; } crlf (); } @@ -749,18 +1002,6 @@ display_matches (matches) #endif } -static void -insert_text (text, start, end) - char *text; - int start, end; -{ - rl_begin_undo_group (); - rl_delete_text (start, end + 1); - rl_point = start; - rl_insert_text (text); - rl_end_undo_group (); -} - static char * make_quoted_replacement (match, mtype, qc) char *match; @@ -833,7 +1074,7 @@ insert_match (match, start, mtype, qc) else if (qc && (*qc != oqc) && start && rl_line_buffer[start - 1] == oqc && replacement[0] != oqc) start--; - insert_text (replacement, start, rl_point - 1); + _rl_replace_text (replacement, start, rl_point - 1); if (replacement != match) free (replacement); } @@ -842,8 +1083,9 @@ insert_match (match, start, mtype, qc) /* Append any necessary closing quote and a separator character to the just-inserted match. If the user has specified that directories should be marked by a trailing `/', append one of those instead. The - default trailing character */ -static void + default trailing character is a space. Returns the number of characters + appended. */ +static int append_to_match (text, delimiter, quote_char) char *text; int delimiter, quote_char; @@ -883,6 +1125,8 @@ append_to_match (text, delimiter, quote_char) if (rl_point == rl_end) rl_insert_text (temp_string); } + + return (temp_string_index); } static void @@ -935,27 +1179,24 @@ int rl_complete_internal (what_to_do) int what_to_do; { - char **matches, **temp_matches; + char **matches; Function *our_func; - int start, end, delimiter, found_quote, nmatch, i; - char *text, *saved_line_buffer, *t; + int start, end, delimiter, found_quote, i; + char *text, *saved_line_buffer; char quote_char; - saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL; - - our_func = rl_completion_entry_function - ? rl_completion_entry_function - : (Function *)filename_completion_function; - /* Only the completion entry function can change these. */ rl_filename_completion_desired = 0; rl_filename_quoting_desired = 1; - rl_completion_type = what_to_do; + saved_line_buffer = rl_line_buffer ? savestring (rl_line_buffer) : (char *)NULL; + our_func = rl_completion_entry_function + ? rl_completion_entry_function + : (Function *)filename_completion_function; + /* We now look backwards for the start of a filename/variable word. */ end = rl_point; - found_quote = delimiter = 0; quote_char = '\0'; @@ -975,50 +1216,19 @@ rl_complete_internal (what_to_do) ding (); FREE (saved_line_buffer); free (text); - return 0; - } - - /* It seems to me that in all the cases we handle we would like - to ignore duplicate possiblilities. Scan for the text to - insert being identical to the other completions. */ - if (rl_ignore_completion_duplicates) - { - temp_matches = remove_duplicate_matches (matches); - free (matches); - matches = temp_matches; + return (0); } - /* If we are matching filenames, then here is our chance to - do clever processing by re-examining the list. Call the - ignore function with the array as a parameter. It can - munge the array, deleting matches as it desires. */ - if (rl_ignore_some_completions_function && - our_func == (Function *)filename_completion_function) + /* If we are matching filenames, our_func will have been set to + filename_completion_function */ + i = our_func == (Function *)filename_completion_function; + if (postprocess_matches (text, &matches, i) == 0) { - for (nmatch = 1; matches[nmatch]; nmatch++) - ; - (void)(*rl_ignore_some_completions_function) (matches); - if (matches == 0 || matches[0] == 0) - { - FREE (matches); - ding (); - FREE (saved_line_buffer); - FREE (text); - return 0; - } - else - { - /* If we removed some matches, recompute the common prefix. */ - for (i = 1; matches[i]; i++) - ; - if (i > 1 && i < nmatch) - { - t = matches[0]; - compute_lcd_of_matches (matches, i - 1, text); - FREE (t); - } - } + FREE (saved_line_buffer); + free (text); + return (0); } + free (text); switch (what_to_do) @@ -1081,191 +1291,11 @@ rl_complete_internal (what_to_do) return 0; } -#if defined (VISIBLE_STATS) -/* Return the character which best describes FILENAME. - `@' for symbolic links - `/' for directories - `*' for executables - `=' for sockets - `|' for FIFOs - `%' for character special devices - `#' for block special devices */ -static int -stat_char (filename) - char *filename; -{ - struct stat finfo; - int character, r; - -#if defined (HAVE_LSTAT) && defined (S_ISLNK) - r = lstat (filename, &finfo); -#else - r = stat (filename, &finfo); -#endif - - if (r == -1) - return (0); - - character = 0; - if (S_ISDIR (finfo.st_mode)) - character = '/'; -#if defined (S_ISCHR) - else if (S_ISCHR (finfo.st_mode)) - character = '%'; -#endif /* S_ISCHR */ -#if defined (S_ISBLK) - else if (S_ISBLK (finfo.st_mode)) - character = '#'; -#endif /* S_ISBLK */ -#if defined (S_ISLNK) - else if (S_ISLNK (finfo.st_mode)) - character = '@'; -#endif /* S_ISLNK */ -#if defined (S_ISSOCK) - else if (S_ISSOCK (finfo.st_mode)) - character = '='; -#endif /* S_ISSOCK */ -#if defined (S_ISFIFO) - else if (S_ISFIFO (finfo.st_mode)) - character = '|'; -#endif - else if (S_ISREG (finfo.st_mode)) - { - if (access (filename, X_OK) == 0) - character = '*'; - } - return (character); -} -#endif /* VISIBLE_STATS */ - -/* A completion function for usernames. - TEXT contains a partial username preceded by a random - character (usually `~'). */ -char * -username_completion_function (text, state) - int state; - char *text; -{ -#if defined (__GO32__) || defined (__WIN32__) - return (char *)NULL; -#else /* !__GO32__ */ - static char *username = (char *)NULL; - static struct passwd *entry; - static int namelen, first_char, first_char_loc; - char *value; - - if (state == 0) - { - FREE (username); - - first_char = *text; - first_char_loc = first_char == '~'; - - username = savestring (&text[first_char_loc]); - namelen = strlen (username); - setpwent (); - } - - while (entry = getpwent ()) - { - /* Null usernames should result in all users as possible completions. */ - if (namelen == 0 || (STREQN (username, entry->pw_name, namelen))) - break; - } - - if (entry == 0) - { - endpwent (); - return ((char *)NULL); - } - else - { - value = xmalloc (2 + strlen (entry->pw_name)); - - *value = *text; - - strcpy (value + first_char_loc, entry->pw_name); - - if (first_char == '~') - rl_filename_completion_desired = 1; - - return (value); - } -#endif /* !__GO32__ */ -} - -/* **************************************************************** */ -/* */ -/* Completion */ -/* */ -/* **************************************************************** */ - -/* Non-zero means that case is not significant in completion. */ -int completion_case_fold = 0; - -/* Find the common prefix of the list of matches, and put it into - matches[0]. */ -static int -compute_lcd_of_matches (match_list, matches, text) - char **match_list; - int matches; - char *text; -{ - register int i, c1, c2, si; - int low; /* Count of max-matched characters. */ - - /* If only one match, just use that. Otherwise, compare each - member of the list with the next, finding out where they - stop matching. */ - if (matches == 1) - { - match_list[0] = match_list[1]; - match_list[1] = (char *)NULL; - return 1; - } - - for (i = 1, low = 100000; i < matches; i++) - { - if (completion_case_fold) - { - for (si = 0; - (c1 = _rl_to_lower(match_list[i][si])) && - (c2 = _rl_to_lower(match_list[i + 1][si])); - si++) - if (c1 != c2) - break; - } - else - { - for (si = 0; - (c1 = match_list[i][si]) && - (c2 = match_list[i + 1][si]); - si++) - if (c1 != c2) - break; - } - - if (low > si) - low = si; - } - - /* If there were multiple matches, but none matched up to even the - first character, and the user typed something, use that as the - value of matches[0]. */ - if (low == 0 && text && *text) - { - match_list[0] = xmalloc (strlen (text) + 1); - strcpy (match_list[0], text); - } - else - { - match_list[0] = xmalloc (low + 1); - strncpy (match_list[0], match_list[1], low); - match_list[0][low] = '\0'; - } - - return matches; -} +/***************************************************************/ +/* */ +/* Application-callable completion match generator functions */ +/* */ +/***************************************************************/ /* Return an array of (char *) which is a list of completions for TEXT. If there are no completions, return a NULL pointer. @@ -1323,6 +1353,62 @@ completion_matches (text, entry_function) return (match_list); } +/* A completion function for usernames. + TEXT contains a partial username preceded by a random + character (usually `~'). */ +char * +username_completion_function (text, state) + int state; + char *text; +{ +#if defined (__GO32__) || defined (__WIN32__) + return (char *)NULL; +#else /* !__GO32__ */ + static char *username = (char *)NULL; + static struct passwd *entry; + static int namelen, first_char, first_char_loc; + char *value; + + if (state == 0) + { + FREE (username); + + first_char = *text; + first_char_loc = first_char == '~'; + + username = savestring (&text[first_char_loc]); + namelen = strlen (username); + setpwent (); + } + + while (entry = getpwent ()) + { + /* Null usernames should result in all users as possible completions. */ + if (namelen == 0 || (STREQN (username, entry->pw_name, namelen))) + break; + } + + if (entry == 0) + { + endpwent (); + return ((char *)NULL); + } + else + { + value = xmalloc (2 + strlen (entry->pw_name)); + + *value = *text; + + strcpy (value + first_char_loc, entry->pw_name); + + if (first_char == '~') + rl_filename_completion_desired = 1; + + return (value); + } +#endif /* !__GO32__ */ +} + /* 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 @@ -1421,10 +1507,20 @@ filename_completion_function (text, state) { /* Otherwise, if these match up to the length of filename, then it is a match. */ - if ((entry->d_name[0] == filename[0]) && - (((int)D_NAMLEN (entry)) >= filename_len) && - (strncmp (filename, entry->d_name, filename_len) == 0)) - break; + if (_rl_completion_case_fold) + { + if ((_rl_to_lower (entry->d_name[0]) == _rl_to_lower (filename[0])) && + (((int)D_NAMLEN (entry)) >= filename_len) && + (_rl_strnicmp (filename, entry->d_name, filename_len) == 0)) + break; + } + else + { + if ((entry->d_name[0] == filename[0]) && + (((int)D_NAMLEN (entry)) >= filename_len) && + (strncmp (filename, entry->d_name, filename_len) == 0)) + break; + } } } @@ -1487,74 +1583,120 @@ filename_completion_function (text, state) } } -/* A function for simple tilde expansion. */ +/* An initial implementation of a menu completion function a la tcsh. The + first time (if the last readline command was not rl_menu_complete), we + generate the list of matches. This code is very similar to the code in + rl_complete_internal -- there should be a way to combine the two. Then, + for each item in the list of matches, we insert the match in an undoable + fashion, with the appropriate character appended (this happens on the + second and subsequent consecutive calls to rl_menu_complete). When we + hit the end of the match list, we restore the original unmatched text, + ring the bell, and reset the counter to zero. */ int -rl_tilde_expand (ignore, key) - int ignore, key; +rl_menu_complete (count, ignore) + int count, ignore; { - register int start, end; - char *homedir, *temp; - int len; + Function *our_func; + int matching_filenames, found_quote; - end = rl_point; - start = end - 1; + static char *orig_text; + static char **matches = (char **)0; + static int match_list_index = 0; + static int match_list_size = 0; + static int orig_start, orig_end; + static char quote_char; + static int delimiter; - if (rl_point == rl_end && rl_line_buffer[rl_point] == '~') + /* The first time through, we generate the list of matches and set things + up to insert them. */ + if (rl_last_func != rl_menu_complete) { - homedir = tilde_expand ("~"); - insert_text (homedir, start, end); + /* Clean up from previous call, if any. */ + FREE (orig_text); + if (matches) + { + for (match_list_index = 0; matches[match_list_index]; match_list_index++) + free (matches[match_list_index]); + free (matches); + } + + match_list_index = match_list_size = 0; + matches = (char **)NULL; + + /* Only the completion entry function can change these. */ + rl_filename_completion_desired = 0; + rl_filename_quoting_desired = 1; + rl_completion_type = '%'; + + our_func = rl_completion_entry_function + ? rl_completion_entry_function + : (Function *)filename_completion_function; + + /* We now look backwards for the start of a filename/variable word. */ + orig_end = rl_point; + found_quote = delimiter = 0; + quote_char = '\0'; + + if (rl_point) + /* This (possibly) changes rl_point. If it returns a non-zero char, + we know we have an open quote. */ + quote_char = find_completion_word (&found_quote, &delimiter); + + orig_start = rl_point; + rl_point = orig_end; + + orig_text = rl_copy_text (orig_start, orig_end); + matches = gen_completion_matches (orig_text, orig_start, orig_end, + our_func, found_quote, quote_char); + + /* If we are matching filenames, our_func will have been set to + filename_completion_function */ + matching_filenames = our_func == (Function *)filename_completion_function; + if (matches == 0 || postprocess_matches (orig_text, &matches, matching_filenames) == 0) + { + ding (); + FREE (matches); + matches = (char **)0; + FREE (orig_text); + orig_text = (char *)0; + completion_changed_buffer = 0; + return (0); + } + + for (match_list_size = 0; matches[match_list_size]; match_list_size++) + ; + /* matches[0] is lcd if match_list_size > 1, but the circular buffer + code below should take care of it. */ + } + + /* Now we have the list of matches. Replace the text between + rl_line_buffer[orig_start] and rl_line_buffer[rl_point] with + matches[match_list_index], and add any necessary closing char. */ + + if (matches == 0 || match_list_size == 0) + { + ding (); + FREE (matches); + matches = (char **)0; + completion_changed_buffer = 0; return (0); } - else if (rl_line_buffer[start] != '~') + + match_list_index = (match_list_index + count) % match_list_size; + if (match_list_index < 0) + match_list_index += match_list_size; + + if (match_list_index == 0) { - for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--) - ; - start++; - } - - end = start; - do - end++; - while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end); - - if (whitespace (rl_line_buffer[end]) || end >= rl_end) - end--; - - /* If the first character of the current word is a tilde, perform - tilde expansion and insert the result. If not a tilde, do - nothing. */ - if (rl_line_buffer[start] == '~') - { - len = end - start + 1; - temp = xmalloc (len + 1); - strncpy (temp, rl_line_buffer + start, len); - temp[len] = '\0'; - homedir = tilde_expand (temp); - free (temp); - - insert_text (homedir, start, end); + ding (); + insert_match (orig_text, orig_start, MULT_MATCH, "e_char); + } + else + { + insert_match (matches[match_list_index], orig_start, SINGLE_MATCH, "e_char); + append_to_match (matches[match_list_index], delimiter, quote_char); } + completion_changed_buffer = 1; return (0); } - -/* Find the first occurrence in STRING1 of any character from STRING2. - Return a pointer to the character in STRING1. */ -static char * -rl_strpbrk (string1, string2) - char *string1, *string2; -{ - register char *scan; - - for (; *string1; string1++) - { - for (scan = string2; *scan; scan++) - { - if (*string1 == *scan) - { - return (string1); - } - } - } - return ((char *)NULL); -} diff --git a/contrib/libreadline/doc/readline.3 b/contrib/libreadline/doc/readline.3 index 8c5ae9399b1e..93b6e8cb5e2f 100644 --- a/contrib/libreadline/doc/readline.3 +++ b/contrib/libreadline/doc/readline.3 @@ -6,9 +6,9 @@ .\" Case Western Reserve University .\" chet@ins.CWRU.Edu .\" -.\" Last Change: Wed Feb 5 14:13:22 EST 1997 +.\" Last Change: Thu Feb 19 10:26:47 EST 1998 .\" -.TH READLINE 3 "1997 Feb 5" GNU +.TH READLINE 3 "1998 Feb 19" GNU .\" .\" File Name macro. This used to be `.PN', for Path Name, .\" but Sun doesn't seem to like that very much. @@ -159,7 +159,7 @@ command or the text of a macro and a key sequence to which it should be bound. The name may be specified in one of two ways: as a symbolic key name, possibly with \fIMeta\-\fP or \fIControl\-\fP prefixes, or as a key sequence. -When using the form \fBkeyname\fP:\fIfunction-name\fP or \fImacro\fP, +When using the form \fBkeyname\fP:\^\fIfunction-name\fP or \fImacro\fP, .I keyname is the name of a key spelled out in English. For example: .sp @@ -185,7 +185,7 @@ expressed on the right hand side (that is, to insert the text .I >&output into the line). .PP -In the second form, \fB"keyseq"\fP:\fIfunction\-name\fP or \fImacro\fP, +In the second form, \fB"keyseq"\fP:\^\fIfunction\-name\fP or \fImacro\fP, .B keyseq differs from .B keyname @@ -213,8 +213,9 @@ and .I "ESC [ 1 1 ~" is bound to insert the text .BR "Function Key 1" . -The full set of escape sequences is +The full set of GNU Emacs style escape sequences is .RS +.PD 0 .TP .B \eC\- control prefix @@ -234,11 +235,53 @@ literal " .B \e' literal ' .RE +.PD +.PP +In addition to the GNU Emacs style escape sequences, a second +set of backslash escapes is available: +.RS +.PD 0 +.TP +.B \ea +alert (bell) +.TP +.B \eb +backspace +.TP +.B \ed +delete +.TP +.B \ef +form feed +.TP +.B \en +newline +.TP +.B \er +carriage return +.TP +.B \et +horizontal tab +.TP +.B \ev +vertical tab +.TP +.B \e\fInnn\fP +the character whose ASCII code is the octal value \fInnn\fP +(one to three digits) +.TP +.B \ex\fInnn\fP +the character whose ASCII code is the hexadecimal value \fInnn\fP +(one to three digits) +.RE +.PD .PP When entering the text of a macro, single or double quotes should be used to indicate a macro definition. Unquoted text -is assumed to be a function name. Backslash -will quote any character in the macro text, including " and '. +is assumed to be a function name. +In the macro body, the backslash escapes described above are expanded. +Backslash will quote any other character in the macro text, +including " and '. .PP .B Bash allows the current readline key bindings to be displayed or modified @@ -288,6 +331,10 @@ This command is bound to in emacs mode and to .B # in vi command mode. +.TP +.B completion\-ignore\-case (Off) +If set to \fBOn\fP, readline performs filename matching and completion +in a case\-insensitive fashion. .TP .B completion\-query\-items (100) This determines when the user is queried about viewing @@ -346,7 +393,7 @@ the value of also affects the default keymap. .TP .B mark\-directories (On) -If set to \fBOn\fP, completed directory names have a slash +If set to \fBOn\fP, complete&output into the line). .PP -In the second form, \fB"keyseq"\fP:\fIfunction\-name\fP or \fImacro\fP, +In the second form, \fB"keyseq"\fP:\^\fIfunction\-name\fP or \fImacro\fP, .B keyseq differs from .B keyname @@ -213,8 +213,9 @@ and .I "ESC [ 1 1 ~" is bound to insert the text .BR "Function Key 1" . -The full set of escape sequences is +The full set of GNU Emacs style escape sequences is .RS +.PD 0 .TP .B \eC\- control prefix @@ -234,11 +235,53 @@ literal " .B \e' literal ' .RE +.PD +.PP +In addition to the GNU Emacs style escape sequences, a second +set of backslash escapes is available: +.RS +.PD 0 +.TP +.B \ea +alert (bell) +.TP +.B \eb +backspace +.TP +.B \ed +delete +.TP +.B \ef +form feed +.TP +.B \en +newline +.TP +.B \er +carriage return +.TP +.B \et +horizontal tab +.TP +.B \ev +vertical tab +.TP +.B \e\fInnn\fP +the character whose ASCII code is the octal value \fInnn\fP +(one to three digits) +.TP +.B \ex\fInnn\fP +the character whose ASCII code is the hexadecimal value \fInnn\fP +(one to three digits) +.RE +.PD .PP When entering the text of a macro, single or double quotes should be used to indicate a macro definition. Unquoted text -is assumed to be a function name. Backslash -will quote any character in the macro text, including " and '. +is assumed to be a function name. +In the macro body, the backslash escapes described above are expanded. +Backslash will quote any other character in the macro text, +including " and '. .PP .B Bash allows the current readline key bindings to be displayed or modified @@ -288,6 +331,10 @@ This command is bound to in emacs mode and to .B # in vi command mode. +.TP +.B completion\-ignore\-case (Off) +If set to \fBOn\fP, readline performs filename matching and completion +in a case\-insensitive fashion. .TP .B completion\-query\-items (100) This determines when the user is queried about viewing @@ -346,7 +393,7 @@ the value of also affects the default keymap. .TP .B mark\-directories (On) -If set to \fBOn\fP, completed directory names have a slash +If set to \fBOn\fP, complete +# endif # include #endif /* HAVE_UNISTD_H */ @@ -36,6 +39,12 @@ # include "ansi_stdlib.h" #endif /* HAVE_STDLIB_H */ +#if defined (HAVE_STRING_H) +# include +#else +# include +#endif /* !HAVE_STRING_H */ + extern char *xmalloc (), *xrealloc (); #if !defined (SHELL) diff --git a/contrib/libreadline/util.c b/contrib/libreadline/util.c index d96b29e8cdf8..fde012edb617 100644 --- a/contrib/libreadline/util.c +++ b/contrib/libreadline/util.c @@ -166,6 +166,58 @@ rl_extend_line_buffer (len) _rl_set_the_line (); } + +/* A function for simple tilde expansion. */ +int +rl_tilde_expand (ignore, key) + int ignore, key; +{ + register int start, end; + char *homedir, *temp; + int len; + + end = rl_point; + start = end - 1; + + if (rl_point == rl_end && rl_line_buffer[rl_point] == '~') + { + homedir = tilde_expand ("~"); + _rl_replace_text (homedir, start, end); + return (0); + } + else if (rl_line_buffer[start] != '~') + { + for (; !whitespace (rl_line_buffer[start]) && start >= 0; start--) + ; + start++; + } + + end = start; + do + end++; + while (whitespace (rl_line_buffer[end]) == 0 && end < rl_end); + + if (whitespace (rl_line_buffer[end]) || end >= rl_end) + end--; + + /* If the first character of the current word is a tilde, perform + tilde expansion and insert the result. If not a tilde, do + nothing. */ + if (rl_line_buffer[start] == '~') + { + len = end - start + 1; + temp = xmalloc (len + 1); + strncpy (temp, rl_line_buffer + start, len); + temp[len] = '\0'; + homedir = tilde_expand (temp); + free (temp); + + _rl_replace_text (homedir, start, end); + } + + return (0); +} + /* **************************************************************** */ /* */ /* String Utility Functions */ @@ -300,3 +352,13 @@ _rl_digit_value (c) { return (isdigit (c) ? c - '0' : c); } + +/* Backwards compatibility, now that savestring has been removed from + all `public' readline header files. */ +#undef _rl_savestring +char * +_rl_savestring (s) + char *s; +{ + return ((char *)strcpy (xmalloc (1 + (int)strlen (s)), (s))); +}