diff -rc2 bash-1.14.1/.patchlevel bash-1.14.2/.patchlevel *** bash-1.14.1/.patchlevel Fri Jul 1 11:21:54 1994 --- bash-1.14.2/.patchlevel Fri Aug 5 16:07:49 1994 *************** *** 1 **** ! 1 --- 1 ---- ! 2 diff -rc2 bash-1.14.1/CWRU/changelog bash-1.14.2/CWRU/changelog *** bash-1.14.1/CWRU/changelog Fri Jul 1 11:21:24 1994 --- bash-1.14.2/CWRU/changelog Fri Aug 5 15:01:06 1994 *************** *** 405,406 **** --- 405,786 ---- machines.h - add #undef HAVE_DIRENT_H to the ardent titan description + + 7/2 + --- + lib/readline/chardefs.h + - removed META_P define, renamed CTRL_P to CTRL_CHAR + + lib/readline/bind.c, lib/readline/isearch.c + - changed instances of CTRL_P to CTRL_CHAR + + lib/readline/search.c + - include before rldefs.h, if HAVE_UNISTD_H is defined + + lib/readline/readline.c + - declare PC, UP, and BC as extern rather than `local' to the + readline library + + 7/5 + --- + bashline.c + - implement command word completion inside of command substitution + with a new function: `command_subst_completion_function' + + subst.c + - new function to help with command subst completion: unclosed_pair + + lib/readline/complete.c + - new variable rl_filename_quoting_desired, which can be set to 0 + to inhibit the quoting of filenames after completion + + lib/readline/readline.h + - declare rl_filename_completion_desired and + rl_filename_quoting_desired + + builtins/bind.def + - don't save the old value of rl_outstream before initializing + readline -- it saves garbage values and screws up readline + + parse.y + - don't have private state telling whether or not readline has + been initialized -- use bash_readline_initialized like other + functions in bashline.c + + lib/readline/readline.c + - make the default 8-bit behavior be based on whether LC_CTYPE is + defined and its value (accept iso-8859-1 or iso_8859_1) + + 7/6 + --- + variables.c + - fix up the declaration of getenv() for convex machines + + 7/7 + --- + lib/readline/readline.c + - fixed up typos in the declaration of `savestring' + + lib/readline/history.c + - fixed an off-by-one error in the ADD_CHAR macro which caused one + extra character to be overwritten, causing the gnu malloc to abort + when that one character was at the end of an allocated block + - changed the ADD_STRING macro to avoid some unnecessary xreallocs + + lib/readline/display.c + - fixed a problem with move_cursor_relative -- function now returns + immediately if it has nothing to do + - fixed another problem with displaying prompts with invisible chars + + lib/readline/chardefs.h + - fixed the CTRL macro to be right (agree with the BSD kernel, for + example) + + cpp-Makefile + - fixed typo in the `install' recipe + + 7/8 + --- + support/srcdir + - fixed to handle srcdir when it begins with ./ or ../ to handle + $(srcdir) being a relative path better + + cpp-Makefile + - changed some include paths to $(BUILTIN_ABSSRC) when building in + `builtins' to handle $(srcdir) being a relative path + - change the `chmod' on bashbug to turn on read and execute for all + - added a couple of definitions to make it easier for a later + `configure' program + + support/mksysdefs + - added a -i option to specify an alternate set of directories to + search for include files + + lib/readline/bind.c + - in rl_read_init_file, when skipping whitespace at the start of + the line, decrement `i' so that we don't jump past the start + of the next line + + machines.h + - SCOv4 has a `robust' opendir that checks that you're actually + opening a directory + + 7/11 + ---- + lib/readline/complete.c + - make sure a word break character is unquoted before using it to + separate out the current word for completing + + machines.h + - new machine description: NetBSD on motorola m68k machines like + the hp300 + - undef HAVE_GETWD in the generic svr4 machine description, like + other svr4 descriptions + + lib/readline/rltty.c + - make sure to fflush (rl_outstream) after toggling the setting + of the keypad and meta key + + portbash/libc.sh + - add a test for OPENDIR_NOT_ROBUST + + support/getcppsyms.c + - output __svr4__ if we find __uxps__ (this makes the Fujitsu port of + SVR4 to the sparc build OK) + + 7/12 + ---- + lib/readline/display.c + - more display-related fixes when the prompt has invisible chars; + this time for screen updates when moving between screen lines + + lib/readline/readline.c, lib/readline/display.c + - changes to make readline work with terminals that have auto-wrap + from Per Bothner (new function _rl_update_final, term_xn changes, + some efficiency speedups, new function space_to_eol) + + 7/13 + ---- + lib/readline/display.c + - after moving up screen lines using term_up in _rl_move_vert, if + the new screen line is 0, _rl_last_c_pos needs to be adjusted + to take invisible characters into account. This was the source + of many bugs + + + 7/14 + ---- + documentation/Makefile + - change instances of `groff' to `${GROFF}', GROFF is set to + `groff' by default + + general.c, variables.c + - moved `qsort_string_compare' from variables.c to general.c + + general.h, variables.h + - moved declaration of `qsort_string_compare' from variables.h + to general.h + + alias.c, lib/readline/funmap.c + - moved qsort auxiliary functions after their use and added + forward declarations to avoid warnings from ANSI C compilers + + memalloc.h + - hpux_9 needs alloca declared as `extern void *' if __STDC__ + is defined + + support/mksysdefs + - removed HAVE_SHARED_LIBS entirely + - make a call to /bin/uname -X for SCO machines to avoid running + a different uname from the $PATH + + machines.h + - new descriptions: Intel i860 running SVR4, Tahoe running 4.3 BSD + - changed descriptions: Mips/RiscOS, DG AViiON, unknown machine + + jobs.c + - changes to how the shell handles foreground jobs dying of SIGINT: + an interactive shell using job control will no longer + act as if it received a SIGINT if the foreground job + dies from a SIGINT + + a non-interactive shell or shell without job control tries + to differentiate between SIGINTs it has seen (in + wait_sigint_handler) and a foreground job dying of a SIGINT + not sent from the keyboard, and runs the normal SIGINT code + only in the former case + + 7/15 + ---- + support/mksysdefs + - check for ${UNAME}${RELEASE} expanding to `SunOS4*' or `SunOS5*' + to set SYSDEF to SunOS4 or SunOS5, respectively. Apparently + this does not work for Solbourne + + 7/18 + ---- + + lib/readline/rltty.c + - if output is being flushed on termios systems, loop until the + FLUSHO bit is no longer set in the termios struct + + support/mksysdefs + - added a -A flag to force creation of ansi-Makefile + + machines.h + - new entry for Tandem machines running SVR3 + + 7/19 + ---- + lib/readline/rldefs.h + - include if HAVE_TERMCAP_H is defined + - use stuff if HAVE_TERMIO_H is defined and _POSIX_VERSION + is not defined + + lib/readline/rldefs.h, lib/readline/history.c + - include "config.h" if HAVE_CONFIG_H is defined + + lib/readline/{rldefs.h,signals.c,readline.c} + - WINSIZE_IN_IOCTL_H -> GWINSZ_IN_SYS_IOCTL for compatibility with + other GNU programs + + lib/readline/doc/Makefile + - fixed up to create the readline and history manuals in dvi and + ps format + + lib/readline/Makefile + - changes inspired by the standalone readline-2.0 distribution + + 7/20 + ---- + lib/readline/history.c + - new function, history_is_stifled (), returns history_stifled + - set history_state flags member in the history state functions + + lib/readline/history.h + - reorganized the function declarations, added missing declarations + - history_stifled is no longer exported by the library + - added a `flags' member to the HISTORY_STATE structure + + bashline.c + - use history_is_stifled () instead of history_stifled + + lib/readline/readline.c, lib/readline/vi_mode.c + - filled in correct argument declarations for functions called via + keymaps (count, key) + + lib/readline/complete.c + - efficiency improvement for compare_strings + + 7/21 + ---- + examples/dirfuncs + - new directory functions from ksh book, contributed by + Ken Konecki (kenk@wfg.com) + + machines.h + - hpux_8 and hpux_9 should both #undef HAVE_ALLOCA unless gcc is + being used + + 7/22 + ---- + bashline.c + - fixed up command_word_completion_function so that filenames with + leading tildes are completed correctly + + 7/26 + ---- + builtins/read.def + - if -r not given, make sure CTLESC is removed from input string + when reading \ + + lib/readline/readline.c + - new function bind_arrow_keys, which binds vt100/ansi arrow key + escape sequences after reading the termcap definition and the + inputrc file + - new function rl_yank_last_arg, which does what insert-last-arg + does in bash + + lib/readline/emacs_keymap.c + - remove default bindings to rl_arrow_keys for M-[ and M-O + - rl_yank_last_arg is now bound to `M-.' and `M-_' in + emacs_meta_keymap + + subst.c + - when performing process substitution on systems with /dev/fd, + make sure the child clears the slot in dev_fd_list it gets + from its parent so the file descriptor does not get closed + inappropriately if reallocated by, e.g., pipe(2) + + bashline.c + - removed insert_last_arg and the calls to bind in to `M-.' and `M-_'. + `insert-last-argument' is now bound to rl_yank_last_arg for + backwards compatibility + + lib/readline/funmap.c + - `yank-last-arg' is now a named command for rl_yank_last_arg + + + documentation/bash.1, documentation/readline.3 + - add description of yank-last-arg as one of the readline user + commands + + lib/readline/doc/rluser.texinfo + - added description of yank-last-arg + + builtins/getopts.def + - fixed a typo in the int-to-string code computing the value to set + OPTIND to: had '\0' instead of '0' + - made getopts handle the case where there are more than 9 dollar + variables (where rest_of_args is non-null) correctly + + 7/28 + ---- + lib/readline/display.c + - fixes to the display code for single-line-display in the presence + of prompts containing invisible characters + + lib/readline/readline.c + - if we are using horizontal scrolling and we have term_xn, decrement + the screenwidth by 1, since we won't be doing any line wrapping + + 7/31 + ---- + jobs.c + - new variable `freeze_jobs_list' to set when changes to the jobs + list or status of jobs in the list (other than calling something + like `jobs -n') are undesirable. This is set when execuing traps + on SIGCHLD + + 8/1 + --- + subst.c + - check that `~' is unquoted before performing tilde expansion in + an assignment statement + + 8/3 + --- + bracecomp.c + - keep brace completion from dumping core if there is only one + match + + lib/readline/chardefs.h + - add a define for digit_p, which returns the value of isdigit() + + lib/readline/readline.c + - added function equivalents for uppercase_p, lowercase_p, to_upper, + to_lower, pure_alphabetic, digit_p, and digit_value + - replaced calls to numeric () with calls to digit_p, removed + definition of numeric () + + lib/readline/history.c + - digit -> digit_p + + lib/readline/vi_mode.c + - replaced uses of the `isletter' define to use pure_alphabetic + from chartypes.h + - replaced uses of `numeric' with calls to digit_p + - added do...while(0) to `exchange' define + + + 8/4 + --- + execute_cmd.c + - make sure execute_function saves and restores the current loop + count with unwind_protect_int + + documentation/features.texi + - change the `Shell Command Line Options' section to `Invoking + Bash' to be closer to the GNU coding standards + + 8/5 + --- + builtins/read.def + - fixed up a memory leak and made behavior correct when no + variables given and backslash escaped at least one input char + - if we added CTLESC anywhere while reading the input string, + make sure we call dequote_string on each word of the input + before calling bind_variable with that string + + subst.c + - made an efficiency improvement to dequote_string -- don't + do anything when we see CTLESC, just `continue' the loop Only in bash-1.14.2/CWRU: sh-redirection-hack diff -rc2 bash-1.14.1/INSTALL bash-1.14.2/INSTALL *** bash-1.14.1/INSTALL Fri Jul 1 11:20:43 1994 --- bash-1.14.2/INSTALL Fri Jul 8 09:21:22 1994 *************** *** 18,22 **** 1. Type `make'. If you want to use GCC to compile bash, type ! `make CC=gcc CPPNAME="$(CC) -E"'. 2. Wait for the compilation to finish. --- 18,22 ---- 1. Type `make'. If you want to use GCC to compile bash, type ! `make CC=gcc CPPNAME='$(CC) -E''. 2. Wait for the compilation to finish. diff -rc2 bash-1.14.1/Makefile bash-1.14.2/Makefile *** bash-1.14.1/Makefile Fri Jul 1 11:20:43 1994 --- bash-1.14.2/Makefile Fri Jul 8 09:25:33 1994 *************** *** 3,7 **** # Makefile for Bash. # If your cpp doesn't like -P, just get rid of it (the -P, not cpp). ! # If you wish to use Gcc, then type `make CC=gcc CPPNAME="$(CC) -E"'. # If you wish to use GNU's Make, then change `MAKE'. # If you don't like the destination, then change `bindir'. --- 3,7 ---- # Makefile for Bash. # If your cpp doesn't like -P, just get rid of it (the -P, not cpp). ! # If you wish to use Gcc, then type `make CC=gcc CPPNAME='$(CC) -E''. # If you wish to use GNU's Make, then change `MAKE'. # If you don't like the destination, then change `bindir'. *************** *** 86,96 **** # existing bash-Makefile. ! DEFINES newversion mailable distribution architecture: bash-Makefile ! $(MAKE) -f bash-Makefile $(MFLAGS) $(MAKEARGS) bindir=$(bindir) $@ ! install uninstall: bash-Makefile ! $(MAKE) -f bash-Makefile $(MFLAGS) $(MAKEARGS) bindir=$(bindir) $@ ! ! tests bash.tar.Z tags documentation clone: bash-Makefile directory-frob $(MAKE) -f bash-Makefile $(MFLAGS) $(MAKEARGS) bindir=$(bindir) $@ --- 86,94 ---- # existing bash-Makefile. ! install uninstall newversion architecture: bash-Makefile ! $(MAKE) -f bash-Makefile $(MFLAGS) $(MAKEARGS) bindir=$(bindir) \ ! prefix=$(prefix) $@ ! tests DEFINES tags documentation: bash-Makefile directory-frob $(MAKE) -f bash-Makefile $(MFLAGS) $(MAKEARGS) bindir=$(bindir) $@ Only in bash-1.14.1: NEWS diff -rc2 bash-1.14.1/README bash-1.14.2/README *** bash-1.14.1/README Fri Jul 1 11:20:43 1994 --- bash-1.14.2/README Fri Jul 8 09:21:32 1994 *************** *** 12,16 **** To compile it, try typing `make'. Bash auto-configures the build process, so no intervention should be necessary. If you want to ! use gcc, type `make CC=gcc CPPNAME="$(CC) -E"'. You may want to read the file INSTALL in this directory for more --- 12,16 ---- To compile it, try typing `make'. Bash auto-configures the build process, so no intervention should be necessary. If you want to ! use gcc, type `make CC=gcc CPPNAME='$(CC) -E''. You may want to read the file INSTALL in this directory for more diff -rc2 bash-1.14.1/alias.c bash-1.14.2/alias.c *** bash-1.14.1/alias.c Fri Jul 1 11:20:48 1994 --- bash-1.14.2/alias.c Thu Jul 14 12:16:47 1994 *************** *** 28,31 **** --- 28,33 ---- #include "alias.h" + static int qsort_alias_compare (); + /* Non-zero means expand all words on the line. Otherwise, expand after first expansion if the expansion ends in a space. */ *************** *** 207,210 **** --- 209,219 ---- } + static void + sort_aliases (array) + ASSOC **array; + { + qsort (array, array_len ((char **)array), sizeof (ASSOC *), qsort_alias_compare); + } + static int qsort_alias_compare (as1, as2) *************** *** 219,229 **** } - static void - sort_aliases (array) - ASSOC **array; - { - qsort (array, array_len ((char **)array), sizeof (ASSOC *), qsort_alias_compare); - } - /* Return a sorted list of all defined aliases */ ASSOC ** --- 228,231 ---- diff -rc2 bash-1.14.1/bashline.c bash-1.14.2/bashline.c *** bash-1.14.1/bashline.c Fri Jul 1 11:20:48 1994 --- bash-1.14.2/bashline.c Wed Aug 3 10:32:45 1994 *************** *** 45,49 **** /* Functions bound to keys in Readline for Bash users. */ ! static void shell_expand_line (), insert_last_arg (); static void display_shell_version (), operate_and_get_next (); static void history_expand_line (), bash_ignore_filenames (); --- 45,49 ---- /* Functions bound to keys in Readline for Bash users. */ ! static void shell_expand_line (); static void display_shell_version (), operate_and_get_next (); static void history_expand_line (), bash_ignore_filenames (); *************** *** 58,61 **** --- 58,62 ---- static char *hostname_completion_function (); static char *command_word_completion_function (); + static char *command_subst_completion_function (); static void snarf_hosts_from_file (), add_host_name (); *************** *** 73,76 **** --- 74,78 ---- extern STRING_INT_ALIST word_token_alist[]; extern Function *rl_last_func; + extern int rl_filename_completion_desired; /* SPECIFIC_COMPLETION_FUNCTIONS specifies that we have individual *************** *** 131,135 **** rl_terminal_name = get_string_value ("TERM"); ! rl_instream = stdin, rl_outstream = stderr; rl_special_prefixes = "$@"; --- 133,138 ---- rl_terminal_name = get_string_value ("TERM"); ! rl_instream = stdin; ! rl_outstream = stderr; rl_special_prefixes = "$@"; *************** *** 146,152 **** rl_bind_key_in_map ('^', (Function *)history_expand_line, emacs_meta_keymap); ! rl_add_defun ("insert-last-argument", (Function *)insert_last_arg, -1); ! rl_bind_key_in_map ('.', (Function *)insert_last_arg, emacs_meta_keymap); ! rl_bind_key_in_map ('_', (Function *)insert_last_arg, emacs_meta_keymap); rl_add_defun --- 149,154 ---- rl_bind_key_in_map ('^', (Function *)history_expand_line, emacs_meta_keymap); ! /* Backwards compatibility. */ ! rl_add_defun ("insert-last-argument", rl_yank_last_arg, -1); rl_add_defun *************** *** 503,522 **** } - /* This is a K*rn shell style insert-last-arg function. The - difference is that Bash puts stuff into the history file before - expansion and file name generation, so we deal with exactly what the - user typed. Those wanting the other behavior, at least for the last - arg, can use `$_'. This also `knows' about how rl_yank_nth_arg treats - `$'. */ - static void - insert_last_arg (count, c) - int count, c; - { - if (rl_explicit_arg) - rl_yank_nth_arg (count, c); - else - rl_yank_nth_arg ('$', c); - } - /* The equivalent of the K*rn shell C-o operate-and-get-next-history-line editing command. */ --- 505,508 ---- *************** *** 544,548 **** where = where_history (); ! if ((history_stifled && (history_length >= max_input_history)) || (where >= history_length - 1)) saved_history_line_to_use = where; --- 530,534 ---- where = where_history (); ! if ((history_is_stifled () && (history_length >= max_input_history)) || (where >= history_length - 1)) saved_history_line_to_use = where; *************** *** 571,575 **** if (rl_explicit_arg) { ! command = (char *)xmalloc (strlen (VI_EDIT_COMMAND) + 8); sprintf (command, "%s %d", VI_EDIT_COMMAND, count); } --- 557,561 ---- if (rl_explicit_arg) { ! command = xmalloc (strlen (VI_EDIT_COMMAND) + 8); sprintf (command, "%s %d", VI_EDIT_COMMAND, count); } *************** *** 606,610 **** int in_command_position, ti; char **matches = (char **)NULL; ! char *command_separator_chars = ";|&{("; rl_ignore_some_completions_function = --- 592,596 ---- int in_command_position, ti; char **matches = (char **)NULL; ! char *command_separator_chars = ";|&{(`"; rl_ignore_some_completions_function = *************** *** 624,628 **** { /* Only do command completion at the start of a line when we ! are not prompting at top level. */ if (current_prompt_string == ps1_prompt) in_command_position++; --- 610,614 ---- { /* Only do command completion at the start of a line when we ! are prompting at the top level. */ if (current_prompt_string == ps1_prompt) in_command_position++; *************** *** 652,657 **** } /* Variable name? */ ! if (*text == '$') matches = completion_matches (text, variable_completion_function); --- 638,648 ---- } + /* Special handling for command substitution. XXX - this should handle + `$(' as well. */ + if (*text == '`' && unclosed_pair (rl_line_buffer, start, "`")) + matches = completion_matches (text, command_subst_completion_function); + /* Variable name? */ ! if (!matches && *text == '$') matches = completion_matches (text, variable_completion_function); *************** *** 712,718 **** free (hint); - hint = savestring (hint_text); - hint_len = strlen (hint); - mapping_over = 0; val = (char *)NULL; --- 703,706 ---- *************** *** 724,730 **** if (absolute_program (hint_text)) { if (filename_hint) free (filename_hint); ! filename_hint = savestring (hint_text); mapping_over = 4; istate = 0; --- 712,727 ---- if (absolute_program (hint_text)) { + /* Perform tilde expansion on what's passed, so we don't end up + passing filenames with tildes directly to stat(). */ + if (*hint_text == '~') + hint = tilde_expand (hint_text); + else + hint = savestring (hint_text); + hint_len = strlen (hint); + if (filename_hint) free (filename_hint); ! filename_hint = savestring (hint); ! mapping_over = 4; istate = 0; *************** *** 732,735 **** --- 729,735 ---- } + hint = savestring (hint_text); + hint_len = strlen (hint); + path = get_string_value ("PATH"); path_index = 0; *************** *** 819,823 **** } ! /* Repeatedly call filename_completion_function while we have members of PATH left. Question: should we stat each file? Answer: we call executable_file () on each file. */ --- 819,823 ---- } ! /* Repeatedly call filename_completion_funcname)); if (first_char_loc) --- 1025,1029 ---- else { ! char *value = xmalloc (2 + strlen (var->name)); if (first_char_loc) *************** *** 1005,1009 **** if (list && list[list_index]) { ! char *t = (char *)xmalloc (2 + strlen (list[list_index])); *t = first_char; --- 1067,1071 ---- if (list && list[list_index]) { ! char *t = xmalloc (2 + strlen (list[list_index])); *t = first_char; *************** *** 1635,1639 **** bash_complete_variable_internal ('?'); } - static void --- 1697,1700 ---- diff -rc2 bash-1.14.1/bracecomp.c bash-1.14.2/bracecomp.c *** bash-1.14.1/bracecomp.c Fri Jul 1 11:20:48 1994 --- bash-1.14.2/bracecomp.c Wed Aug 3 09:52:05 1994 *************** *** 65,69 **** if (real_start == real_end) ! return (savestring (array[real_start] + gcd_zero)); result = (char *) xmalloc (result_size = 1); --- 65,74 ---- if (real_start == real_end) ! { ! if (array[real_start]) ! return (savestring (array[real_start] + gcd_zero)); ! else ! return (savestring (array[0])); ! } result = (char *) xmalloc (result_size = 1); diff -rc2 bash-1.14.1/builtins/bind.def bash-1.14.2/builtins/bind.def *** bash-1.14.1/builtins/bind.def Fri Jul 1 11:20:55 1994 --- bash-1.14.2/builtins/bind.def Tue Jul 5 14:34:12 1994 *************** *** 79,82 **** --- 79,85 ---- initfile = map_name = fun_name = (char *)NULL; + if (!bash_readline_initialized) + initialize_readline (); + /* Cannot use unwind_protect_pointer () on "FILE *", it is only guaranteed to work for strings. */ *************** *** 84,90 **** old_rl_outstream = rl_outstream; rl_outstream = stdout; - - if (!bash_readline_initialized) - initialize_readline (); reset_internal_getopt (); --- 87,90 ---- diff -rc2 bash-1.14.1/builtins/getopts.def bash-1.14.2/builtins/getopts.def *** bash-1.14.1/builtins/getopts.def Fri Jul 1 11:20:58 1994 --- bash-1.14.2/builtins/getopts.def Tue Jul 26 20:12:03 1994 *************** *** 83,86 **** --- 83,87 ---- extern char *this_command_name; + extern WORD_LIST *rest_of_args; /* getopts_reset is magic code for when OPTIND is reset. N is the *************** *** 157,164 **** t = argv[0]; argv[0] = dollar_vars[0]; ! ret = getopt(argc, argv, optstr); argv[0] = t; } ! else { register int i; --- 158,165 ---- t = argv[0]; argv[0] = dollar_vars[0]; ! ret = getopt (argc, argv, optstr); argv[0] = t; } ! else if (rest_of_args == (WORD_LIST *)NULL) { register int i; *************** *** 167,170 **** --- 168,188 ---- ret = getopt (i, dollar_vars, optstr); } + else + { + register int i; + register WORD_LIST *words; + char **v; + + for (i = 0; dollar_vars[i]; i++); + for (words = rest_of_args; words; words = words->next, i++); + v = (char **)xmalloc ((i + 1) * sizeof (char *)); + for (i = 0; dollar_vars[i]; i++) + v[i] = dollar_vars[i]; + for (words = rest_of_args; words; words = words->next, i++) + v[i] = words->word->word; + v[i] = (char *)NULL; + ret = getopt (i, v, optstr); + free (v); + } if (special_error) *************** *** 184,188 **** do { ! numval[--i] = (n % 10) + '\0'; } while (n /= 10); --- 202,206 ---- do { ! numval[--i] = (n % 10) + '0'; } while (n /= 10); diff -rc2 bash-1.14.1/builtins/read.def bash-1.14.2/builtins/read.def *** bash-1.14.1/builtins/read.def Fri Jul 1 11:21:00 1994 --- bash-1.14.2/builtins/read.def Fri Aug 5 14:54:36 1994 *************** *** 121,127 **** if (pass_next) { ! if (c != '\n') input_string[i++] = c; - pass_next = 0; continue; --- 121,128 ---- if (pass_next) { ! if (c == '\n') ! i--; /* back up over the CTLESC */ ! else input_string[i++] = c; pass_next = 0; continue; *************** *** 162,169 **** { SHELL_VAR *var; if (saw_escape) ! dequote_string (input_string); ! var = bind_variable ("REPLY", input_string); var->attributes &= ~att_invisible; free (input_string); --- 163,176 ---- { SHELL_VAR *var; + char *t; if (saw_escape) ! { ! t = dequote_string (input_string); ! var = bind_variable ("REPLY", t); ! free (t); ! } ! else ! var = bind_variable ("REPLY", input_string); var->attributes &= ~att_invisible; free (input_string); *************** *** 172,175 **** --- 179,183 ---- { SHELL_VAR *var; + char *t; /* This code implements the Posix.2 spec for splitting the words read and assigning them to variables. If $IFS is unset, we *************** *** 181,185 **** while (list->next) { ! char *t, *e; varname = list->word->word; --- 189,193 ---- while (list->next) { ! char *e, *t1; varname = list->word->word; *************** *** 193,197 **** if (t) *e = '\0'; ! var = bind_variable (varname, t); } else --- 201,214 ---- if (t) *e = '\0'; ! /* Don't bother to remove the CTLESC unless we added one ! somewhere while reading the string. */ ! if (t && saw_escape) ! { ! t1 = dequote_string (t); ! var = bind_variable (varname, t1); ! free (t1); ! } ! else ! var = bind_variable (varname, t); } else *************** *** 210,214 **** } ! var = bind_variable (list->word->word, input_string); stupidly_hack_special_variables (list->word->word); var->attributes &= ~att_invisible; --- 227,238 ---- } ! if (saw_escape) ! { ! t = dequote_string (input_string); ! var = bind_variable (list->word->word, t); ! free (t); ! } ! else ! var = bind_variable (list->word->word, input_string); stupidly_hack_special_variables (list->word->word); var->attributes &= ~att_invisible; diff -rc2 bash-1.14.1/builtins/suspend.def bash-1.14.2/builtins/suspend.def *** bash-1.14.1/builtins/suspend.def Fri Jul 1 11:21:02 1994 --- bash-1.14.2/builtins/suspend.def Thu Aug 11 10:31:30 1994 *************** *** 46,51 **** int sig; { ! signal (SIGCONT, old_cont); ! signal (SIGTSTP, old_tstp); #if !defined (VOID_SIGHANDLER) return (0); --- 46,51 ---- int sig; { ! set_signal_handler (SIGCONT, old_cont); ! set_signal_handler (SIGTSTP, old_tstp); #if !defined (VOID_SIGHANDLER) return (0); *************** *** 78,83 **** do_suspend: ! old_cont = (SigHandler *)signal (SIGCONT, suspend_continue); ! old_tstp = (SigHandler *)signal (SIGTSTP, SIG_DFL); killpg (shell_pgrp, SIGTSTP); return (EXECUTION_SUCCESS); --- 78,83 ---- do_suspend: ! old_cont = (SigHandler *)set_signal_handler (SIGCONT, suspend_continue); ! old_tstp = (SigHandler *)set_signal_handler (SIGTSTP, SIG_DFL); killpg (shell_pgrp, SIGTSTP); return (EXECUTION_SUCCESS); diff -rc2 bash-1.14.1/builtins/ulimit.def bash-1.14.2/builtins/ulimit.def *** bash-1.14.1/builtins/ulimit.def Fri Jul 1 11:21:02 1994 --- bash-1.14.2/builtins/ulimit.def Sat Jul 2 20:10:41 1994 *************** *** 108,116 **** /* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */ ! #if defined (HAVE_RESOURCE) ! # if defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE) ! # define RLIMIT_NOFILE RLIMIT_OFILE ! # endif ! #endif #define LIMIT_HARD 0x01 --- 108,114 ---- /* Some systems use RLIMIT_NOFILE, others use RLIMIT_OFILE */ ! #if defined (HAVE_RESOURCE) && defined (RLIMIT_OFILE) && !defined (RLIMIT_NOFILE) ! # define RLIMIT_NOFILE RLIMIT_OFILE ! #endif /* HAVE_RESOURCE && RLIMIT_OFILE && !RLIMIT_NOFILE */ #define LIMIT_HARD 0x01 diff -rc2 bash-1.14.1/builtins/wait.def bash-1.14.2/builtins/wait.def *** bash-1.14.1/builtins/wait.def Fri Jul 1 11:21:03 1994 --- bash-1.14.2/builtins/wait.def Sat Jul 2 20:11:19 1994 *************** *** 90,94 **** else { ! builtin_error ("`%s' is not a pid or job spec", w); status = EXECUTION_FAILURE; goto return_status; --- 90,94 ---- else { ! builtin_error ("`%s' is not a pid or legal job spec", w); status = EXECUTION_FAILURE; goto return_status; diff -rc2 bash-1.14.1/cpp-Makefile bash-1.14.2/cpp-Makefile *** bash-1.14.1/cpp-Makefile Fri Jul 1 11:20:44 1994 --- bash-1.14.2/cpp-Makefile Fri Aug 12 13:40:49 1994 *************** *** 67,70 **** --- 67,72 ---- prefix = /usr/local + /**/#prefix = @prefix@ + exec_prefix = $(prefix) bindir = $(exec_prefix)/bin *************** *** 83,88 **** --- 85,94 ---- srcdir = . + /**/#srcdir = @srcdir@ + VPATH = .:$(srcdir) + /**/#incdir = @incdir@ + /* If you have purify, and want to use it, uncomment this definition or run the make as `make -f bash-Makefile bash PURIFY=purify'. */ *************** *** 358,362 **** $(MAKE) $(MFLAGS) target \ srcdir=$(BUILTIN_ABSSRC) CPPFLAGS='$(CPPFLAGS)' \ ! CFLAGS='$(CCFLAGS) '$(LIBINC_USAGE)' -I. -I$(srcdir)/$(DEFDIR)' \ LDFLAGS='$(LDFLAGS)' RANLIB='$(RANLIB)' AR='$(AR)' CC='$(CC)' \ RM='$(RM)' RL_LIBSRC='$(RL_ABSSRC)' \ --- 364,368 ---- $(MAKE) $(MFLAGS) target \ srcdir=$(BUILTIN_ABSSRC) CPPFLAGS='$(CPPFLAGS)' \ ! CFLAGS='$(CCFLAGS) '$(LIBINC_USAGE)' -I. -I$(BUILTIN_ABSSRC)' \ LDFLAGS='$(LDFLAGS)' RANLIB='$(RANLIB)' AR='$(AR)' CC='$(CC)' \ RM='$(RM)' RL_LIBSRC='$(RL_ABSSRC)' \ *************** *** 842,846 **** @($(LIBINC_DECL); cd $(ALLOC_LIBDIR) ; \ if [ ! -f Makefile ]; then cp $(ALLOC_ABSSRC)Makefile Makefile ; fi; \ ! $(MAKE) $(MFLAGS) \ CFLAGS='$(LIBRARY_CFLAGS) $(MALLOC_FLAGS)' \ CPPFLAGS='$(CPPFLAGS)' ALLOCA_SOURCE=$(ALLOCA_SOURCE) \ --- 848,852 ---- @($(LIBINC_DECL); cd $(ALLOC_LIBDIR) ; \ if [ ! -f Makefile ]; then cp $(ALLOC_ABSSRC)Makefile Makefile ; fi; \ ! $(MAKE) $(MFLAGS) CC='$(CC)' \ CFLAGS='$(LIBRARY_CFLAGS) $(MALLOC_FLAGS)' \ CPPFLAGS='$(CPPFLAGS)' ALLOCA_SOURCE=$(ALLOCA_SOURCE) \ *************** *** 1030,1034 **** @echo " ***************************************************" @echo " * *" ! @echo " * Making Bash-`cat $(srcdir)/.distribution`.`cat $(srcdir)/.patchlevel` for a $(Machine) running $(OS)." @echo " * *" @echo " ***************************************************" --- 1036,1040 ---- @echo " ***************************************************" @echo " * *" ! @echo " * Making Bash-`cat $(srcdir)/.distribution`.`cat $(srcdir)/.patchlevel` for a $(Machine) running $(OS)" @echo " * *" @echo " ***************************************************" *************** *** 1042,1046 **** -e "s:@PATCHLEVEL@:`cat $(srcdir)/.patchlevel`:" \ $(SUPPORT_SRC)bashbug.sh > $@ ! @chmod +x bashbug version.h: newversion.aux --- 1048,1052 ---- -e "s:@PATCHLEVEL@:`cat $(srcdir)/.patchlevel`:" \ $(SUPPORT_SRC)bashbug.sh > $@ ! @chmod a+rx bashbug version.h: newversion.aux *************** *** 1442,1446 **** $(INSTALL_PROGRAM) $(Program) $(bindir)/$(Program) -if [ -f $(bindir)/bashbug ]; \ ! then mv $(bindir)/bashbug $(bindir)$bashbug.old; \ fi $(INSTALL_PROGRAM) bashbug $(bindir)/bashbug --- 1448,1452 ---- $(INSTALL_PROGRAM) $(Program) $(bindir)/$(Program) -if [ -f $(bindir)/bashbug ]; \ ! then mv $(bindir)/bashbug $(bindir)/bashbug.old; \ fi $(INSTALL_PROGRAM) bashbug $(bindir)/bashbug diff -rc2 bash-1.14.1/documentation/Makefile bash-1.14.2/documentation/Makefile *** bash-1.14.1/documentation/Makefile Fri Jul 1 11:21:24 1994 --- bash-1.14.2/documentation/Makefile Thu Jul 14 12:12:59 1994 *************** *** 18,21 **** --- 18,24 ---- NROFF = nroff + # This should be a program that converts troff to postscript + GROFF = groff + HSUSER = ./../lib/readline/doc/hsuser.texinfo RLUSER = ./../lib/readline/doc/rluser.texinfo *************** *** 25,29 **** .1.ps: $(RM) $@ ! groff -man $< > $@ .1.txt: $(RM) $@ --- 28,33 ---- .1.ps: $(RM) $@ ! ${GROFF} -man $< > $@ ! .1.txt: $(RM) $@ *************** *** 32,36 **** .ms.ps: $(RM) $@ ! groff -ms $< > $@ .ms.txt: $(RM) $@ --- 36,41 ---- .ms.ps: $(RM) $@ ! ${GROFF} -ms $< > $@ ! .ms.txt: $(RM) $@ *************** *** 39,43 **** .3.ps: $(RM) $@ ! groff -man $< > $@ .3.txt: $(RM) $@ --- 44,49 ---- .3.ps: $(RM) $@ ! ${GROFF} -man $< > $@ ! .3.txt: $(RM) $@ diff -rc2 bash-1.14.1/documentation/article.ms bash-1.14.2/documentation/article.ms *** bash-1.14.1/documentation/article.ms Fri Jul 1 11:21:29 1994 --- bash-1.14.2/documentation/article.ms Mon Jul 18 17:05:29 1994 *************** *** 18,22 **** chet@po.cwru.edu .FS ! *This article is to appear in The Linux Journal. .FE .NH 1 --- 18,22 ---- chet@po.cwru.edu .FS ! *An earlier version of this article appeared in The Linux Journal. .FE .NH 1 *************** *** 37,41 **** features from the Korn shell (\fBksh\fP) and the C shell (\fBcsh\fP), described later in this article. It is ultimately intended to be a ! conformant implementation of the IEEE POSIX Shell and Tools specification (IEEE Working Group 1003.2). It offers functional improvements over sh for both interactive and programming use. --- 37,41 ---- features from the Korn shell (\fBksh\fP) and the C shell (\fBcsh\fP), described later in this article. It is ultimately intended to be a ! conformant implementation of the IEEE POSIX Shell and Utilities specification (IEEE Working Group 1003.2). It offers functional improvements over sh for both interactive and programming use. *************** *** 66,71 **** assigned to a working group in the 1003 series. .PP ! The POSIX Shell and Tools standard has been developed by IEEE Working ! Group 1003.2 (POSIX.2). It concentrates on the command interpreter interface and utility programs --- 66,76 ---- assigned to a working group in the 1003 series. .PP ! The POSIX Shell and Utilities standard has been developed by IEEE Working ! Group 1003.2 (POSIX.2).\(dd ! .FS ! \(ddIEEE, \fIIEEE Standard for Information Technology -- Portable ! Operating System Interface (POSIX) Part 2: Shell and Utilities\fP, ! 1992. ! .FE It concentrates on the command interpreter interface and utility programs *************** *** 139,142 **** --- 144,148 ---- have been standardized; \fIemacs\fP editing commands were left out due to objections. + .PP While POSIX.2 includes much of what the shell has traditionally provided, some important things have been omitted as being *************** *** 175,179 **** .PP The Korn Shell (\fBksh\fP) is a descendent of the Bourne shell written ! at AT&T Bell Laboratories by David Korn. It provides a number of useful features that POSIX and Bash have adopted. Many of the interactive facilities in POSIX.2 have their roots in the ksh: --- 181,185 ---- .PP The Korn Shell (\fBksh\fP) is a descendent of the Bourne shell written ! at AT&T Bell Laboratories by David Korn\(dg. It provides a number of useful features that POSIX and Bash have adopted. Many of the interactive facilities in POSIX.2 have their roots in the ksh: *************** *** 190,193 **** --- 196,203 ---- the ability to remove substrings from variables based on patterns, and shell arithmetic. + .FS + \(dgMorris Bolsky and David Korn, \fIThe KornShell Command and + Programming Language\fP, Prentice Hall, 1989. + .FE .B RANDOM expands to a random number each time it is referenced; assigning a *************** *** 220,229 **** Bash aliases allow a string to be substituted for a command name. They can be used to create a mnemonic for a \s-1UNIX\s+1 command ! name (\fBalias del=rm\fP), to expand a single word to a complex command ! (\fBalias news='xterm -g 80x45 -title trn -e trn -e -S1 -N &'\fP), or to ensure that a command is invoked with a basic set of options ! (\fBalias ls="/bin/ls -F"\fP). .PP ! The C shell (\fBcsh\fP), originally written by Bill Joy while at Berkeley, is widely used and quite popular for its interactive facilities. Bash includes a csh-compatible history expansion --- 230,239 ---- Bash aliases allow a string to be substituted for a command name. They can be used to create a mnemonic for a \s-1UNIX\s+1 command ! name (\f(CRalias del=rm\fP), to expand a single word to a complex command ! (\f(CRalias news='xterm -g 80x45 -title trn -e trn -e -S1 -N &'\fP), or to ensure that a command is invoked with a basic set of options ! (\f(CRalias ls="/bin/ls -F"\fP). .PP ! The C shell (\fBcsh\fP)\(dg, originally written by Bill Joy while at Berkeley, is widely used and quite popular for its interactive facilities. Bash includes a csh-compatible history expansion *************** *** 237,240 **** --- 247,254 ---- Tilde expansion has also been adopted by both the Korn Shell and POSIX.2. + .FS + \(dgBill Joy, An Introduction to the C Shell, \fIUNIX User's Supplementary + Documents\fP, University of California at Berkeley, 1986. + .FE .PP There were certain areas in which POSIX.2 felt standardization *************** *** 279,283 **** .PP Bash also implements the \*Q$(...)\*U command substitution syntax, ! which replaces the sh `...` construct. The \*Q$(...)\*U construct expands to the output of the command contained within the --- 293,297 ---- .PP Bash also implements the \*Q$(...)\*U command substitution syntax, ! which supersedes the sh `...` construct. The \*Q$(...)\*U construct expands to the output of the command contained within the *************** *** 287,293 **** is easier to nest. .PP ! The Bourne shell does not have such features as brace expansion, the ability ! to have a variable and a function with the same name, local variables in shell functions, the ability to enable and disable individual builtins or write a function to replace a builtin, or a means to --- 301,307 ---- is easier to nest. .PP ! The Bourne shell does not provide such features as brace expansion, the ability ! to define a variable and a function with the same name, local variables in shell functions, the ability to enable and disable individual builtins or write a function to replace a builtin, or a means to *************** *** 300,304 **** the results of expansion (ksh and the 4.4 BSD sh have fixed this as well). Useful behavior such as a means to abort ! execution of a script read with the \*Q.\*U command or automatically exporting variables in the shell's environment to children is also not present in the Bourne shell. Bash provides a much more powerful --- 314,319 ---- the results of expansion (ksh and the 4.4 BSD sh have fixed this as well). Useful behavior such as a means to abort ! execution of a script read with the \*Q.\*U command using the ! \fBreturn\fP builtin or automatically exporting variables in the shell's environment to children is also not present in the Bourne shell. Bash provides a much more powerful *************** *** 331,335 **** proper variables and functions for interactive and non-interactive shells or having the file read only for interactive shells, was ! considered too complex. Ease of use won out here. .NH 2 New Builtin Commands --- 346,353 ---- proper variables and functions for interactive and non-interactive shells or having the file read only for interactive shells, was ! considered too complex. Ease of use won out here. Interestingly, ! the next release of ksh will change to reading ! .B $ENV ! only for interactive shells. .NH 2 New Builtin Commands *************** *** 342,346 **** .I echo found in a user's search path rather than the Bash builtin, ! \*Qenable -n echo\*U suffices. The .B help builtin provides --- 360,364 ---- .I echo found in a user's search path rather than the Bash builtin, ! \f(CRenable -n echo\fP suffices. The .B help builtin provides *************** *** 409,414 **** .I readline library to read and edit lines when interactive. Readline is a ! powerful and flexible input facility that a user can configure to his ! tastes. It allows lines to be edited using either emacs or vi commands, where those commands are appropriate. The full capability of emacs is not present \- there is no way to execute --- 427,432 ---- .I readline library to read and edit lines when interactive. Readline is a ! powerful and flexible input facility that a user can configure to ! individual tastes. It allows lines to be edited using either emacs or vi commands, where those commands are appropriate. The full capability of emacs is not present \- there is no way to execute *************** *** 460,465 **** # edit the path "\eC-xp": "PATH=${PATH}\ee\eC-e\eC-a\eef\eC-f" ! # prepare to type a quoted word -- insert open and close double quotes ! # and move to just after the open quote "\eC-x\e"": "\e"\e"\eC-b" # Quote the current or previous word --- 478,483 ---- # edit the path "\eC-xp": "PATH=${PATH}\ee\eC-e\eC-a\eef\eC-f" ! # prepare to type a quoted word -- insert open and close double ! # quotes and move to just after the open quote "\eC-x\e"": "\e"\e"\eC-b" # Quote the current or previous word *************** *** 490,494 **** takes a single string and passes it directly to readline, which interprets the line as if it had just been read from the inputrc file. ! Both key bindings and variable assignments can appear in the string given to .B bind . --- 508,512 ---- takes a single string and passes it directly to readline, which interprets the line as if it had just been read from the inputrc file. ! Both key bindings and variable assignments may appear in the string given to .B bind . *************** *** 527,531 **** The value of .B $HISTFILE ! specifes the file where bash writes the command history on exit and reads it on startup. .B $HISTSIZE --- 545,549 ---- The value of .B $HISTFILE ! specifes the file where Bash writes the command history on exit and reads it on startup. .B $HISTSIZE *************** *** 603,610 **** .PP Since sh offers no convenient way to generate arbitrary strings that ! share a common prefix or suffix (pathname expansion requires that the filenames exist), Bash implements \fIbrace expansion\fP, a capability picked up from csh. ! Brace expansion is similar to pathname expansion, but the strings generated need not correspond to existing files. A brace expression consists of an optional --- 621,628 ---- .PP Since sh offers no convenient way to generate arbitrary strings that ! share a common prefix or suffix (filename expansion requires that the filenames exist), Bash implements \fIbrace expansion\fP, a capability picked up from csh. ! Brace expansion is similar to filename expansion, but the strings generated need not correspond to existing files. A brace expression consists of an optional *************** *** 619,622 **** --- 637,643 ---- ade ace abe .EE + .LP + As this example demonstrates, the results of brace expansion are not + sorted, as they are by filename expansion. .NH 2 Process Substitution *************** *** 732,735 **** --- 753,761 ---- $ /bin/pwd /net/share/sun4/local + $ cd .. + $ pwd + /usr + $ /bin/pwd + /usr .EE .LP *************** *** 781,785 **** standard. POSIX mode is entered when Bash is started with the .B -posix ! option. Future releases of Bash will make this an option to the \fBset\fP builtin, \fBset -o posix\fP. For compatibility with other GNU software that attempts to be POSIX.2 --- 807,811 ---- standard. POSIX mode is entered when Bash is started with the .B -posix ! option. This feature is also available as an option to the \fBset\fP builtin, \fBset -o posix\fP. For compatibility with other GNU software that attempts to be POSIX.2 *************** *** 787,794 **** .B $POSIXLY_CORRECT is set when Bash is started or assigned a value during execution. - Future versions will accept .B $POSIX_PEDANTIC ! as well, to be compatible, paradoxically, with some older ! GNU utilities. When Bash is started in POSIX mode, for example, it sources the file named by the value of --- 813,818 ---- .B $POSIXLY_CORRECT is set when Bash is started or assigned a value during execution. .B $POSIX_PEDANTIC ! is accepted as well, to be compatible with some older GNU utilities. When Bash is started in POSIX mode, for example, it sources the file named by the value of *************** *** 797,806 **** reserved words to be aliased. .NH 1 ! Future Plans .PP ! There are several features that will be introduced in the next version of Bash, version 1.14, and a number under consideration for future releases. This section will briefly detail the new ! features planned for version 1.14 and describe several features that may appear in later versions. .NH 2 --- 821,830 ---- reserved words to be aliased. .NH 1 ! New Features and Future Plans .PP ! There are several features introduced in the current version of Bash, version 1.14, and a number under consideration for future releases. This section will briefly detail the new ! features in version 1.14 and describe several features that may appear in later versions. .NH 2 *************** *** 831,840 **** history substitution has been extended. .PP ! Several of the features described earlier as appearing in future ! releases, such as .B "set -o posix" and .B $POSIX_PEDANTIC , ! are present in version 1.14. There is a new shell variable, .B OSTYPE , --- 855,863 ---- history substitution has been extended. .PP ! Several of the features described earlier, such as .B "set -o posix" and .B $POSIX_PEDANTIC , ! are new in version 1.14. There is a new shell variable, .B OSTYPE , *************** *** 934,939 **** .B $HISTCONTROL have been applied, would not be placed onto the history list. The ! shell pattern-matching capabilities could also be available when specifying ! the contents of .B $HISTIGNORE . .PP --- 957,962 ---- .B $HISTCONTROL have been applied, would not be placed onto the history list. The ! shell pattern-matching capabilities could also be available when ! specifying the contents of .B $HISTIGNORE . .PP *************** *** 982,986 **** specified and incomplete; subsequent descriptions have not helped much. The grammar presented in Bourne's paper describing ! the shell distributed with the Seventh Edition of \s-1UNIX\s+1 is so far off that it does not allow the command \f(CWwho|wc\fP. In fact, as Tom Duff states: --- 1005,1009 ---- specified and incomplete; subsequent descriptions have not helped much. The grammar presented in Bourne's paper describing ! the shell distributed with the Seventh Edition of \s-1UNIX\s+1\(dg is so far off that it does not allow the command \f(CWwho|wc\fP. In fact, as Tom Duff states: *************** *** 988,995 **** Nobody really knows what the Bourne shell's grammar is. Even examination of the source code is ! little help.\(dg .FS ! \(dgTom Duff, \*QRc \- A Shell for Plan 9 and \s-1UNIX\s+1 systems\*U, Proc. ! of the Summer 1990 EUUG Conf., London, July, 1990, pp. 21-33 .FE .LP --- 1011,1023 ---- Nobody really knows what the Bourne shell's grammar is. Even examination of the source code is ! little help.\(dd ! .FS ! \(dgS. R. Bourne, \*QUNIX Time-Sharing System: The UNIX Shell\*U, ! \fIBell System Technical Journal\fP, 57(6), July-August, 1978, pp. 1971-1990. ! .FE .FS ! \(ddTom Duff, \*QRc \- A Shell for Plan 9 and \s-1UNIX\s+1 systems\*U, ! \fIProc. of the Summer 1990 EUUG Conference\fP, London, July, 1990, ! pp. 21-33. .FE .LP *************** *** 1040,1044 **** .I prep.ai.mit.edu:/pub/gnu and from other GNU software mirror sites. The current version is in ! .I bash-1.13.5.tar.gz in that directory. Use .I archie --- 1068,1072 ---- .I prep.ai.mit.edu:/pub/gnu and from other GNU software mirror sites. The current version is in ! .I bash-1.14.1.tar.gz in that directory. Use .I archie *************** *** 1057,1067 **** systems. It is included as /bin/sh and /bin/bash on several Linux distributions (more about the difference in a moment), and as contributed ! software in BSDI's BSD/386\(dg and FreeBSD. .FS ! \(dg BSD/386 is a trademark of Berkeley Software Design, Inc. .FE .PP The Linux distribution deserves special mention. There are two ! Bash configurations included in the standard distribution: a \*Qnormal\*U configuration, in which all of the standard features are included, and a \*Qminimal\*U configuration, which omits job --- 1085,1095 ---- systems. It is included as /bin/sh and /bin/bash on several Linux distributions (more about the difference in a moment), and as contributed ! software in BSDI's BSD/386* and FreeBSD. .FS ! *BSD/386 is a trademark of Berkeley Software Design, Inc. .FE .PP The Linux distribution deserves special mention. There are two ! configurations included in the standard Bash distribution: a \*Qnormal\*U configuration, in which all of the standard features are included, and a \*Qminimal\*U configuration, which omits job diff -rc2 bash-1.14.1/documentation/bash.1 bash-1.14.2/documentation/bash.1 *** bash-1.14.1/documentation/bash.1 Fri Jul 1 11:21:24 1994 --- bash-1.14.2/documentation/bash.1 Tue Jul 26 14:47:59 1994 *************** *** 7,15 **** .\" chet@ins.CWRU.Edu .\" ! .\" Last Change: Mon Jun 13 20:05:33 EDT 1994 .\" .\" bash_builtins, strip all but Built-Ins section .if \n(zZ=1 .ig zZ ! .TH BASH 1 "1994 June 13" GNU .\" .\" There's some problem with having a `@' --- 7,15 ---- .\" chet@ins.CWRU.Edu .\" ! .\" Last Change: Wed Jul 20 16:13:25 EDT 1994 .\" .\" bash_builtins, strip all but Built-Ins section .if \n(zZ=1 .ig zZ ! .TH BASH 1 "1994 July 26" GNU .\" .\" There's some problem with having a `@' *************** *** 374,377 **** --- 374,380 ---- \fIword\fP is omitted, the \fBfor\fP command executes \fIlist\fP once for each positional parameter that is set (see + .SM + .B PARAMETERS + below). .TP \fBselect\fP \fIname\fP [ \fBin\fP \fIword\fP; ] \fBdo\fP \fIlist\fP ; \fBdone\fP *************** *** 2875,2878 **** --- 2878,2887 ---- inserts the \fIn\fPth word from the end of the previous command. .TP + .B + yank\-last\-arg (M\-.\^, M\-_\^) + Insert the last argument to the previous command (the last word on + the previous line). With an argument, + behave exactly like @code{yank-nth-arg}. + .TP .B shell\-expand\-line (M\-C\-e) Expand the line the way the shell does when it reads it. This *************** *** 2890,2899 **** .TP .B insert\-last\-argument (M\-.\^, M\-_\^) ! Insert the last argument to the previous command (the last word on ! the previous line). With an argument ! .IR n , ! insert the \fIn\fPth word from the previous command (the words ! in the previous command begin with word 0). A negative argument ! inserts the \fIn\fPth word from the end of the previous command. .TP .B operate-and-get-next (C\-o) --- 2899,2903 ---- .TP .B insert\-last\-argument (M\-.\^, M\-_\^) ! A synonym for \fByank\-last\-arg\fP. .TP .B operate-and-get-next (C\-o) *************** *** 5270,5276 **** \fIBash Features\fP, Brian Fox and Chet Ramey .TP ! \fIThe Gnu Readline Library\fP, Brian Fox .TP ! \fIThe Gnu History Library\fP, Brian Fox .TP \fIA System V Compatible Implementation of 4.2\s-1BSD\s+1 Job Control\fP, David Lennert --- 5274,5280 ---- \fIBash Features\fP, Brian Fox and Chet Ramey .TP ! \fIThe Gnu Readline Library\fP, Brian Fox and Chet Ramey .TP ! \fIThe Gnu History Library\fP, Brian Fox and Chet Ramey .TP \fIA System V Compatible Implementation of 4.2\s-1BSD\s+1 Job Control\fP, David Lennert diff -rc2 bash-1.14.1/documentation/readline.3 bash-1.14.2/documentation/readline.3 *** bash-1.14.1/documentation/readline.3 Fri Jul 1 11:21:25 1994 --- bash-1.14.2/documentation/readline.3 Tue Jul 26 14:48:09 1994 *************** *** 7,13 **** .\" chet@ins.CWRU.Edu .\" ! .\" Last Change: Mon Jun 13 20:06:14 EDT 1994 .\" ! .TH READLINE 3 "1994 June 13" GNU .\" .\" File Name macro. This used to be `.PN', for Path Name, --- 7,13 ---- .\" chet@ins.CWRU.Edu .\" ! .\" Last Change: Wed Jul 20 16:13:11 EDT 1994 .\" ! .TH READLINE 3 "1994 July 26" GNU .\" .\" File Name macro. This used to be `.PN', for Path Name, *************** *** 79,82 **** --- 79,84 ---- .ft .fi + .LP + .nf .ft B int rl_macro_bind (keyseq, macro, keymap) *************** *** 738,741 **** --- 740,749 ---- in the previous command begin with word 0). A negative argument inserts the \fIn\fPth word from the end of the previous command. + .TP + .B + yank\-last\-arg (M\-.\^, M\-_\^) + Insert the last argument to the previous command (the last word on + the previous line). With an argument, + behave exactly like @code{yank-nth-arg}. .PD .SS Commands for Changing Text *************** *** 1165,1171 **** .PD 0 .TP ! \fIThe Gnu Readline Library\fP, Brian Fox .TP ! \fIThe Gnu History Library\fP, Brian Fox .TP \fIbash\fP(1) --- 1173,1179 ---- .PD 0 .TP ! \fIThe Gnu Readline Library\fP, Brian Fox and Chet Ramey .TP ! \fIThe Gnu History Library\fP, Brian Fox and Chet Ramey .TP \fIbash\fP(1) diff -rc2 bash-1.14.1/execute_cmd.c bash-1.14.2/execute_cmd.c *** bash-1.14.1/execute_cmd.c Fri Jul 1 11:20:48 1994 --- bash-1.14.2/execute_cmd.c Thu Aug 4 12:55:04 1994 *************** *** 1905,1908 **** --- 1905,1909 ---- unwind_protect_int (variable_context); + unwind_protect_int (loop_level); unwind_protect_int (return_catch_flag); unwind_protect_jmp_buf (return_catch); diff -rc2 bash-1.14.1/general.c bash-1.14.2/general.c *** bash-1.14.1/general.c Fri Jul 1 11:20:44 1994 --- bash-1.14.2/general.c Tue Jul 26 20:04:32 1994 *************** *** 308,315 **** Function *function; { ! while (list) { ! (*function) (list); ! list = list->next; ! } } --- 308,316 ---- Function *function; { ! while (list) ! { ! (*function) (list); ! list = list->next; ! } } *************** *** 320,327 **** Function *function; { ! while (words) { ! (*function)(words->word->word); ! words = words->next; ! } } --- 321,329 ---- Function *function; { ! while (words) ! { ! (*function)(words->word->word); ! words = words->next; ! } } *************** *** 377,389 **** register GENERIC_LIST *temp = *list; ! while (temp) { ! if ((*comparer) (temp, arg)) { ! if (prev) prev->next = temp->next; ! else *list = temp->next; ! return (temp); } - prev = temp; - temp = temp->next; - } return ((GENERIC_LIST *)&global_error_list); } --- 379,395 ---- register GENERIC_LIST *temp = *list; ! while (temp) ! { ! if ((*comparer) (temp, arg)) ! { ! if (prev) ! prev->next = temp->next; ! else ! *list = temp->next; ! return (temp); ! } ! prev = temp; ! temp = temp->next; } return ((GENERIC_LIST *)&global_error_list); } *************** *** 447,450 **** --- 453,469 ---- } + /* Comparison routine for use with qsort() on arrays of strings. */ + int + qsort_string_compare (s1, s2) + register char **s1, **s2; + { + int result; + + if ((result = **s1 - **s2) == 0) + result = strcmp (*s1, *s2); + + return (result); + } + /* Append LIST2 to LIST1. Return the header of the list. */ GENERIC_LIST * *************** *** 473,477 **** char *start = string; ! while (*string && (whitespace (*string) || *string == '\n')) string++; if (string != start) --- 492,497 ---- char *start = string; ! while (*string && (whitespace (*string) || *string == '\n')) ! string++; if (string != start) *************** *** 653,662 **** if (*string++ == '.') { ! if ((!*string) || *string == '/') return (1); ! if (*string++ == '.') ! if (!*string || *string == '/') ! return (1); } return (0); --- 673,681 ---- if (*string++ == '.') { ! if (!*string || *string == '/') return (1); ! if (*string == '.' && (string[1] == '\0' || string[1] == '/')) ! return (1); } return (0); *************** *** 679,687 **** char *string; { ! char *p = (char *)strrchr (string, '/'); if (!absolute_pathname (string)) return (string); if (p) return (++p); --- 698,707 ---- char *string; { ! char *p; if (!absolute_pathname (string)) return (string); + p = (char *)strrchr (string, '/'); if (p) return (++p); *************** *** 713,717 **** char *current_dir = xmalloc (2 + MAXPATHLEN + strlen (file)); int dlen; ! if (!getwd (current_dir)) { report_error (current_dir); --- 733,737 ---- char *current_dir = xmalloc (2 + MAXPATHLEN + strlen (file)); int dlen; ! if (getwd (current_dir) == 0) { report_error (current_dir); diff -rc2 bash-1.14.1/general.h bash-1.14.2/general.h *** bash-1.14.1/general.h Fri Jul 1 11:20:51 1994 --- bash-1.14.2/general.h Thu Jul 14 12:20:36 1994 *************** *** 185,188 **** --- 185,189 ---- extern GENERIC_LIST *list_append (); extern int list_length (); + extern int qsort_string_compare (); extern int find_name_in_list __P((char *, char **)); diff -rc2 bash-1.14.1/input.c bash-1.14.2/input.c *** bash-1.14.1/input.c Fri Jul 1 11:20:47 1994 --- bash-1.14.2/input.c Wed Aug 10 12:39:02 1994 *************** *** 46,49 **** --- 46,52 ---- void free_buffered_stream (); + extern int interactive_shell; + + int bash_input_fd_changed; /* This provides a way to map from a file descriptor to the buffer associated with that file descriptor, rather than just the other *************** *** 128,133 **** int nfd; ! if (fd > 0 && bash_input.type == st_bstream && ! bash_input.location.buffered_fd == fd) { /* Sync the stream so we can re-read from the new file descriptor. We --- 131,136 ---- int nfd; ! if (fd > 0 && ((bash_input.type == st_bstream && bash_input.location.buffered_fd == fd) || ! (interactive_shell == 0 && default_buffered_input == fd))) { /* Sync the stream so we can re-read from the new file descriptor. We *************** *** 158,164 **** /* Reinitialize bash_input.location. */ ! bash_input.location.buffered_fd = nfd; ! fd_to_buffered_stream (nfd); ! close_buffered_fd (fd); /* XXX */ if (default_buffered_input == fd) default_buffered_input = nfd; --- 161,179 ---- /* Reinitialize bash_input.location. */ ! if (bash_input.type == st_bstream) ! { ! bash_input.location.buffered_fd = nfd; ! fd_to_buffered_stream (nfd); ! close_buffered_fd (fd); /* XXX */ ! } ! else ! /* If the current input type is not a buffered stream, but the shell ! is not interactive and therefore using a buffered stream to read ! input (e.g. with an `eval exec 3>output' inside a script), note ! that the input fd has been changed. pop_stream() looks at this ! value and adjusts the input fd to the new value of ! default_buffered_input accordingly. */ ! bash_input_fd_changed++; ! if (default_buffered_input == fd) default_buffered_input = nfd; diff -rc2 bash-1.14.1/jobs.c bash-1.14.2/jobs.c *** bash-1.14.1/jobs.c Fri Jul 1 11:20:47 1994 --- bash-1.14.2/jobs.c Thu Aug 11 12:53:51 1994 *************** *** 192,195 **** --- 192,201 ---- #endif + /* Set this to non-zero whenever you don't want the jobs list to change at + all: no jobs deleted and no status change notifications. This is used, + for example, when executing SIGCHLD traps, which may run arbitrary + commands. */ + static int freeze_jobs_list; + #if !defined (_POSIX_VERSION) *************** *** 479,483 **** sigset_t set, oset; ! if (!job_slots) return; --- 485,489 ---- sigset_t set, oset; ! if (!job_slots || freeze_jobs_list) return; *************** *** 497,502 **** int job_index; { ! register JOB *temp = jobs[job_index]; if (job_index == current_job || job_index == previous_job) reset_current (); --- 503,512 ---- int job_index; { ! register JOB *temp; ! ! if (freeze_jobs_list) ! return; + temp = jobs[job_index]; if (job_index == current_job || job_index == previous_job) reset_current (); *************** *** 985,989 **** } ! if (!pid) { /* In the child. Give this child the right process group, set the --- 995,999 ---- } ! if (pid == 0) { /* In the child. Give this child the right process group, set the *************** *** 1310,1314 **** for (i = 0; i < job_slots; i++) if (jobs[i] && (JOBSTATE (i) == JRUNNING) && ! !(jobs[i]->flags & J_FOREGROUND)) { count++; --- 1320,1324 ---- for (i = 0; i < job_slots; i++) if (jobs[i] && (JOBSTATE (i) == JRUNNING) && ! (jobs[i]->flags & J_FOREGROUND) == 0) { count++; *************** *** 1324,1328 **** for (i = 0; i < job_slots; i++) if (jobs[i] && (JOBSTATE (i) == JRUNNING) && ! !(jobs[i]->flags & J_FOREGROUND)) { pid_t pid = last_pid (i); --- 1334,1338 ---- for (i = 0; i < job_slots; i++) if (jobs[i] && (JOBSTATE (i) == JRUNNING) && ! (jobs[i]->flags & J_FOREGROUND) == 0) { pid_t pid = last_pid (i); *************** *** 1349,1352 **** --- 1359,1364 ---- } + static int wait_sigint_received = 0; + /* Handle SIGINT while we are waiting for children in a script to exit. The `wait' builtin should be interruptible, but all others should be *************** *** 1365,1371 **** } /* Otherwise effectively ignore the SIGINT and allow the running job to be killed. */ - /* XXX - should this set interrupt_state if job control is not enabled? */ #if !defined (VOID_SIGHANDLER) return (0); --- 1377,1383 ---- } + wait_sigint_received = 1; /* XXX - should this be interrupt_state? */ /* Otherwise effectively ignore the SIGINT and allow the running job to be killed. */ #if !defined (VOID_SIGHANDLER) return (0); *************** *** 1407,1410 **** --- 1419,1423 ---- /* This is possibly a race condition -- should it go in stop_pipeline? */ + wait_sigint_received = 0; if (!job_control) old_sigint_handler = set_signal_handler (SIGINT, wait_sigint_handler); *************** *** 1555,1558 **** --- 1568,1574 ---- notify_and_cleanup () { + if (freeze_jobs_list) + return; + if (interactive) notify_of_job_status (); *************** *** 1852,1858 **** then kill the process group associated with PID. */ int ! kill_pid (pid, signal, group) pid_t pid; ! int signal, group; { register PROCESS *p; --- 1868,1874 ---- then kill the process group associated with PID. */ int ! kill_pid (pid, sig, group) pid_t pid; ! int sig, group; { register PROCESS *p; *************** *** 1877,1903 **** do { ! kill (p->pid, signal); ! if (!p->running && (signal == SIGTERM || signal == SIGHUP)) kill (p->pid, SIGCONT); p = p->next; ! } while (p != jobs[job]->pipe); } else { ! result = killpg (jobs[job]->pgrp, signal); if (p && (JOBSTATE (job) == JSTOPPED) && ! (signal == SIGTERM || signal == SIGHUP)) killpg (jobs[job]->pgrp, SIGCONT); } } else ! { ! result = killpg (pid, signal); ! } } else ! { ! result = kill (pid, signal); ! } UNBLOCK_CHILD (oset); return (result); --- 1893,1917 ---- do { ! kill (p->pid, sig); ! if (p->running == 0 && (sig == SIGTERM || sig == SIGHUP)) kill (p->pid, SIGCONT); p = p->next; ! } ! while (p != jobs[job]->pipe); } else { ! result = killpg (jobs[job]->pgrp, sig); if (p && (JOBSTATE (job) == JSTOPPED) && ! (sig == SIGTERM || sig == SIGHUP)) killpg (jobs[job]->pgrp, SIGCONT); } } else ! result = killpg (pid, sig); } else ! result = kill (pid, sig); ! UNBLOCK_CHILD (oset); return (result); *************** *** 2014,2022 **** last_stopped_job = NO_JOB; ! /* If the foreground job is killed by SIGINT, we ! need to perform some special handling. */ if ((WTERMSIG (jobs[job]->pipe->status) == SIGINT) && ! (jobs[job]->flags & J_FOREGROUND)) { /* If SIGINT is trapped, set the exit status so that the trap handler can see it. */ --- 2028,2050 ---- last_stopped_job = NO_JOB; ! /* If the foreground job is killed by SIGINT when ! job control is not active, we need to perform ! some special handling. */ ! /* The check of wait_sigint_received is a way to ! determine if the SIGINT came from the keyboard ! (in which case the shell has already seen it, ! and wait_sigint_received is non-zero, because ! keyboard signals are sent to process groups) ! or via kill(2) to the foreground process by ! another process (or itself). If the shell did ! receive the SIGINT, it needs to perform normal ! SIGINT processing. */ if ((WTERMSIG (jobs[job]->pipe->status) == SIGINT) && ! (jobs[job]->flags & J_FOREGROUND) && ! (jobs[job]->flags & J_JOBCONTROL) == 0 && ! wait_sigint_received) { + wait_sigint_received = 0; + /* If SIGINT is trapped, set the exit status so that the trap handler can see it. */ *************** *** 2027,2071 **** /* If the signal is trapped, let the trap handler get it no matter what and simply return if ! the trap handler returns. */ ! if (maybe_call_trap_handler (SIGINT) == 0) { ! /* If it isn't trapped, and the job was ! started with job control enabled, let the ! shell know that the signal occurred. */ ! if (jobs[job]->flags & J_JOBCONTROL) ! sigint_sighandler (SIGINT); ! else ! { ! /* No job control. ! wait_sigint_handler () has already ! seen SIGINT and allowed the wait ! builtin to jump out. We need to ! call the original SIGINT handler. */ ! if (old_sigint_handler != ! INVALID_SIGNAL_HANDLER) ! { ! SigHandler *temp_handler; ! temp_handler = old_sigint_handler; ! restore_sigint_handler (); ! (*temp_handler) (SIGINT); ! } ! } } } - /* maybe_call_trap_handler may cause dead jobs to be - removed from the job table because of a call to - execute_command. Watch out for this, even though - the code below is not executed. */ - #if 0 - /* The job exited for some reason other than SIGINT. - If the `foreground' job exits, we may need to - reset the SIGINT signal handler back to what - it is normally. */ - /* XXX - why are we doing this? Doesn't wait_for - do this? */ - if ((jobs[job]->flags & J_FOREGROUND) && - !(jobs[job]->flags & J_JOBCONTROL)) - restore_sigint_handler (); - #endif } } --- 2055,2076 ---- /* If the signal is trapped, let the trap handler get it no matter what and simply return if ! the trap handler returns. ! maybe_call_trap_handler may cause dead jobs ! to be removed from the job table because of ! a call to execute_command. Watch out for ! this. */ ! if (maybe_call_trap_handler (SIGINT) == 0 && ! old_sigint_handler != INVALID_SIGNAL_HANDLER) { ! /* wait_sigint_handler () has already ! seen SIGINT and allowed the wait ! builtin to jump out. We need to ! call the original SIGINT handler. */ ! SigHandler *temp_handler; ! temp_handler = old_sigint_handler; ! restore_sigint_handler (); ! (*temp_handler) (SIGINT); } } } } *************** *** 2108,2111 **** --- 2113,2117 ---- unwind_protect_int (last_made_pid); unwind_protect_int (interrupt_immediately); + unwind_protect_int (freeze_jobs_list); unwind_protect_pointer (the_pipeline); *************** *** 2118,2121 **** --- 2124,2128 ---- the_pipeline = (PROCESS *)NULL; restore_default_signal (SIGCHLD); + freeze_jobs_list = 1; while (children_exited--) { *************** *** 2470,2474 **** { initialize_job_signals (); ! signal (SIGCONT, old_cont); kill (getpid (), SIGCONT); --- 2477,2481 ---- { initialize_job_signals (); ! set_signal_handler (SIGCONT, old_cont); kill (getpid (), SIGCONT); diff -rc2 bash-1.14.1/lib/readline/Makefile bash-1.14.2/lib/readline/Makefile *** bash-1.14.1/lib/readline/Makefile Fri Jul 1 11:21:11 1994 --- bash-1.14.2/lib/readline/Makefile Wed Jul 20 16:35:17 1994 *************** *** 5,38 **** #################################################################### - # This Makefile is hand made from a template file, found in - # ../template. Each library must provide several Makefile - # targets: `all', `clean', `documentation', `install', and - # `what-tar'. The `what-tar' target reports the names of the - # files that need to be included in a tarfile to build the full - # code and documentation for this library. - - # Please note that the values for INCLUDES, CC, AR, RM, CP, - # RANLIB, and selfdir are passed in from ../Makefile, and do - # not need to be defined here. srcdir = . VPATH = .:$(srcdir) ! # Here is a rule for making .o files from .c files that doesn't force ! # the type of the machine (like -sun3) into the flags. ! .c.o: ! $(CC) -c $(CFLAGS) $(INCLUDES) $(LOCAL_DEFINES) $(CPPFLAGS) $< - # # See the file STANDALONE for the -D defines that readline understands ! # ! LOCAL_DEFINES = $(LOCAL_INCLUDES) ! ! # Some systems need to define this (like older NeXT systems) in order ! # to prevent namespace conflicts. ! CFLAGS = # -DSTATIC_MALLOC ! # For libraries which include headers from other libraries. LOCAL_INCLUDES = -I. -I.. # The name of the main library target. LIBRARY_NAME = libreadline.a --- 5,33 ---- #################################################################### srcdir = . VPATH = .:$(srcdir) ! INSTALL = install -c ! INSTALL_PROGRAM = ${INSTALL} ! INSTALL_DATA = ${INSTALL} -m 644 ! ! RANLIB = ranlib ! AR = ar ! RM = rm ! CP = cp ! MV = mv # See the file STANDALONE for the -D defines that readline understands ! DEFS = # For libraries which include headers from other libraries. LOCAL_INCLUDES = -I. -I.. + CPPFLAGS = $(DEFS) $(LOCAL_INCLUDES) + + # Here is a rule for making .o files from .c files that doesn't force + # the type of the machine (like -sun3) into the flags. + .c.o: + $(CC) -c $(CPPFLAGS) $(CFLAGS) $< + # The name of the main library target. LIBRARY_NAME = libreadline.a *************** *** 48,52 **** # The header files for this library. HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h \ ! posixstat.h tilde.h OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \ --- 43,47 ---- # The header files for this library. HSOURCES = readline.h rldefs.h chardefs.h keymaps.h history.h \ ! posixstat.h tilde.h rlconf.h OBJECTS = readline.o vi_mode.o funmap.o keymaps.o parens.o search.o \ *************** *** 81,86 **** documentation: force ! -mkdir doc (if [ -d doc ]; then cd doc; $(MAKE) $(MFLAGS); fi) force: --- 76,82 ---- documentation: force ! [ ! -d doc ] && mkdir doc (if [ -d doc ]; then cd doc; $(MAKE) $(MFLAGS); fi) + force: *************** *** 88,101 **** # always returns TRUE unless there really was an error installing the # include files. ! install: ! if [ -r $(incdir)/readline ]; then \ ! :; \ ! else \ ! mkdir $(incdir)/readline && chmod a+r $(incdir)/readline; \ ! fi ! $(CP) readline.h keymaps.h chardefs.h history.h $(incdir)/readline/ ! -mv $(bindir)/libreadline.a $(bindir)/libreadline.old ! cp libreadline.a $(bindir)/libreadline.a ! if [ -f "$(RANLIB)" ]; then $(RANLIB) -t $(bindir)/libreadline.a; fi clean: --- 84,101 ---- # always returns TRUE unless there really was an error installing the # include files. ! install: installdirs libreadline.a ! ${INSTALL_DATA} readline.h keymaps.h chardefs.h history.h \ ! $(incdir)/readline ! -${MV} $(libdir)/libreadline.a $(libdir)/libreadline.old ! ${INSTALL_DATA} libreadline.a $(bindir)/libreadline.a ! [ -f "$(RANLIB)" ] && $(RANLIB) -t $(bindir)/libreadline.a ! ! installdirs: ! [ ! -d $(incdir)/readline ] && { \ ! mkdir $(incdir)/readline && chmod chmod 755 $(incdir)/readline; } ! ! uninstall: ! cd $(incdir)/readline && ${RM} -f ${INSTALLED_HEADERS} ! cd $(libdir) && ${RM} -f libreadline.a libreadline.old clean: *************** *** 103,106 **** --- 103,112 ---- (if [ -d doc ]; then cd doc; $(MAKE) $(MFLAGS) $@; fi) + tags: force + etags $(CSOURCES) $(HSOURCES) + + TAGS: force + ctags -x $(CSOURCES) $(HSOURCES) > $@ + readline: readline.h rldefs.h chardefs.h readline: $(OBJECTS) *************** *** 108,111 **** --- 114,119 ---- $(LOCAL_INCLUDES) -DTEST -o readline readline.c vi_mode.o funmap.o \ keymaps.o -ltermcap + + realclean distclean mostlyclean: clean # Dependencies diff -rc2 bash-1.14.1/lib/readline/STANDALONE bash-1.14.2/lib/readline/STANDALONE *** bash-1.14.1/lib/readline/STANDALONE Fri Jul 1 11:21:15 1994 --- bash-1.14.2/lib/readline/STANDALONE Tue Jul 19 11:27:15 1994 *************** *** 6,10 **** HAVE_UNISTD_H exists HAVE_STDLIB_H exists - HAVE_GETPW_DECLS declarations for the getpw functions are in HAVE_VARARGS_H exists and is usable HAVE_STRING_H exists --- 6,9 ---- *************** *** 20,25 **** System-specific options: ! WINSIZE_IN_IOCTL_H need to include for TIOCGWINSZ ! HAVE_GETPW_DECLS the getpw* functions are declared in HAVE_STRCASECMP the strcasecmp and strncasecmp functions are available --- 19,25 ---- System-specific options: ! GWINSZ_IN_SYS_IOCTL need to include for TIOCGWINSZ ! HAVE_GETPW_DECLS the getpw* functions are declared in and cannot ! be redeclared without compiler errors HAVE_STRCASECMP the strcasecmp and strncasecmp functions are available diff -rc2 bash-1.14.1/lib/readline/bind.c bash-1.14.2/lib/readline/bind.c *** bash-1.14.1/lib/readline/bind.c Fri Jul 1 11:21:16 1994 --- bash-1.14.2/lib/readline/bind.c Wed Jul 20 17:04:37 1994 *************** *** 516,520 **** /* Skip leading whitespace. */ while (*line && whitespace (*line)) ! line++; /* If the line is not a comment, then parse it. */ --- 516,523 ---- /* Skip leading whitespace. */ while (*line && whitespace (*line)) ! { ! line++; ! i--; ! } /* If the line is not a comment, then parse it. */ *************** *** 1172,1177 **** /* Print the names of functions known to Readline. */ void ! rl_list_funmap_names (ignore) ! int ignore; { register int i; --- 1175,1180 ---- /* Print the names of functions known to Readline. */ void ! rl_list_funmap_names (count, ignore) ! int count, ignore; { register int i; *************** *** 1217,1221 **** char *keyname = (char *)xmalloc (5); ! if (CTRL_P (key)) sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key))); else if (key == RUBOUT) --- 1220,1224 ---- char *keyname = (char *)xmalloc (5); ! if (CTRL_CHAR (key)) sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key))); else if (key == RUBOUT) *************** *** 1262,1266 **** if (key == ESC) sprintf (keyname, "\\e"); ! else if (CTRL_P (key)) sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key))); else if (key == RUBOUT) --- 1265,1269 ---- if (key == ESC) sprintf (keyname, "\\e"); ! else if (CTRL_CHAR (key)) sprintf (keyname, "\\C-%c", to_lower (UNCTRL (key))); else if (key == RUBOUT) diff -rc2 bash-1.14.1/lib/readline/chardefs.h bash-1.14.2/lib/readline/chardefs.h *** bash-1.14.1/lib/readline/chardefs.h Fri Jul 1 11:21:11 1994 --- bash-1.14.2/lib/readline/chardefs.h Wed Aug 3 10:45:14 1994 *************** *** 42,45 **** --- 42,46 ---- /* Some character stuff. */ #define control_character_threshold 0x020 /* Smaller than this is control. */ + #define control_character_mask 0x1f /* 0x20 - 1 */ #define meta_character_threshold 0x07f /* Larger than this is Meta. */ #define control_character_bit 0x40 /* 0x000000, must be off. */ *************** *** 47,52 **** #define largest_char 255 /* Largest character value. */ #define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char) ! #define CTRL(c) ((c) & (~control_character_bit)) #define META(c) ((c) | meta_character_bit) --- 48,55 ---- #define largest_char 255 /* Largest character value. */ + #define CTRL_CHAR(c) ((c) < control_character_threshold) #define META_CHAR(c) ((c) > meta_character_threshold && (c) <= largest_char) ! ! #define CTRL(c) ((c) & control_character_mask) #define META(c) ((c) | meta_character_bit) *************** *** 57,64 **** --- 60,69 ---- #define lowercase_p(c) (((c) > ('a' - 1) && (c) < ('z' + 1))) #define uppercase_p(c) (((c) > ('A' - 1) && (c) < ('Z' + 1))) + #define digit_p(c) ((c) >= '0' && (c) <= '9') */ #define lowercase_p(c) (islower(c)) #define uppercase_p(c) (isupper(c)) + #define digit_p(x) (isdigit (x)) #define pure_alphabetic(c) (lowercase_p(c) || uppercase_p(c)) *************** *** 73,79 **** # define to_lower(c) (isupper(c) ? tolower(c) : (c)) #endif - - #define CTRL_P(c) ((c) < control_character_threshold) - #define META_P(c) ((c) > meta_character_threshold) #ifndef digit_value --- 78,81 ---- diff -rc2 bash-1.14.1/lib/readline/complete.c bash-1.14.2/lib/readline/complete.c *** bash-1.14.1/lib/readline/complete.c Fri Jul 1 11:21:16 1994 --- bash-1.14.2/lib/readline/complete.c Tue Jul 26 13:59:57 1994 *************** *** 227,230 **** --- 227,237 ---- int rl_filename_completion_desired = 0; + /* Non-zero means that the results of the matches are to be quoted using + double quotes (or an application-specific quoting mechanism) if the + filename contains any characters in rl_word_break_chars. This is + ALWAYS non-zero on entry, and can only be changed within a completion + entry finder function. */ + int rl_filename_quoting_desired = 1; + /* This function, if defined, is called by the completer when real filename completion is done, after all the matching names have been *************** *** 381,386 **** our_func = (Function *)filename_completion_function; ! /* Only the completion entry function can change this. */ rl_filename_completion_desired = 0; /* We now look backwards for the start of a filename/variable word. */ --- 388,394 ---- our_func = (Function *)filename_completion_function; ! /* Only the completion entry function can change these. */ rl_filename_completion_desired = 0; + rl_filename_quoting_desired = 1; /* We now look backwards for the start of a filename/variable word. */ *************** *** 454,458 **** #endif /* SHELL */ ! /* Convoluted code, but it avoids an n2 algorithm with calls to char_is_quoted. */ break; --- 462,466 ---- #endif /* SHELL */ ! /* Convoluted code, but it avoids an n^2 algorithm with calls to char_is_quoted. */ break; *************** *** 460,466 **** } ! /* If we are at a word break, then advance past it. */ scan = rl_line_buffer[rl_point]; if (strchr (rl_completer_word_break_characters, scan)) { /* If the character that caused the word break was a quoting --- 468,479 ---- } ! /* If we are at an unquoted word break, then advance past it. */ scan = rl_line_buffer[rl_point]; + #if defined (SHELL) + if ((found_quote == 0 || char_is_quoted (rl_line_buffer, rl_point) == 0) && + strchr (rl_completer_word_break_characters, scan)) + #else if (strchr (rl_completer_word_break_characters, scan)) + #endif { /* If the character that caused the word break was a quoting *************** *** 603,612 **** should_quote = matches[0] && rl_completer_quote_characters && ! rl_filename_completion_desired; #if defined (SHELL) ! should_quote = should_quote && (!quote_char || quote_char == '"'); #else ! should_quote = should_quote && !quote_char; #endif --- 616,627 ---- should_quote = matches[0] && rl_completer_quote_characters && ! rl_filename_completion_desired && ! rl_filename_quoting_desired; + if (should_quote) #if defined (SHELL) ! should_quote = should_quote && (!quote_char || quote_char == '"'); #else ! should_quote = should_quote && !quote_char; #endif *************** *** 945,949 **** char **s1, **s2; { ! return (strcmp (*s1, *s2)); } --- 960,970 ---- char **s1, **s2; { ! int result; ! ! result = **s1 - **s2; ! if (result == 0) ! result = strcmp (*s1, *s2); ! ! return result; } diff -rc2 bash-1.14.1/lib/readline/display.c bash-1.14.2/lib/readline/display.c *** bash-1.14.1/lib/readline/display.c Fri Jul 1 11:21:17 1994 --- bash-1.14.2/lib/readline/display.c Thu Aug 11 14:41:42 1994 *************** *** 56,60 **** extern char *term_up, *term_dc, *term_cr, *term_IC; extern int screenheight, screenwidth, screenchars; ! extern int terminal_can_insert; extern void _rl_output_some_chars (); --- 56,60 ---- extern char *term_up, *term_dc, *term_cr, *term_IC; extern int screenheight, screenwidth, screenchars; ! extern int terminal_can_insert, term_xn; extern void _rl_output_some_chars (); *************** *** 71,75 **** void _rl_move_vert (); ! static void update_line (), clear_to_eol (); static void delete_chars (), insert_some_chars (); --- 71,75 ---- void _rl_move_vert (); ! static void update_line (), clear_to_eol (), space_to_eol (); static void delete_chars (), insert_some_chars (); *************** *** 93,102 **** update_line and the code that calls it makes a multiple line, ! automatically wrapping line update. Carefull attention needs ! to be paid to the vertical position variables. ! ! handling of terminals with autowrap on (incl. DEC braindamage) ! could be improved a bit. Right now I just cheat and decrement ! screenwidth by one. */ /* Keep two buffers; one which reflects the current contents of the --- 93,98 ---- update_line and the code that calls it makes a multiple line, ! automatically wrapping line update. Careful attention needs ! to be paid to the vertical position variables. */ /* Keep two buffers; one which reflects the current contents of the *************** *** 322,330 **** if (rl_display_prompt == rl_prompt) { ! int local_len = strlen (local_prompt); if (local_prompt_prefix && forced_display) _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix)); ! if (local_prompt) strncpy (line + out, local_prompt, local_len); out += local_len; --- 318,326 ---- if (rl_display_prompt == rl_prompt) { ! int local_len = local_prompt ? strlen (local_prompt) : 0; if (local_prompt_prefix && forced_display) _rl_output_some_chars (local_prompt_prefix, strlen (local_prompt_prefix)); ! if (local_len > 0) strncpy (line + out, local_prompt, local_len); out += local_len; *************** *** 416,420 **** { int total_screen_chars = screenchars; ! int nleft, cursor_linenum, pos; if (!rl_display_fixed || forced_display) --- 412,416 ---- { int total_screen_chars = screenchars; ! int nleft, cursor_linenum, pos, changed_screen_line; if (!rl_display_fixed || forced_display) *************** *** 431,439 **** (screenwidth + wrap_offset) chars, the rest of the lines have screenwidth chars. */ ! nleft = out - screenwidth - wrap_offset; ! if (nleft > 0) ! inv_botlin = 1 + nleft / screenwidth; ! else ! inv_botlin = 0; /* The first line is at character position 0 in the buffer. The --- 427,432 ---- (screenwidth + wrap_offset) chars, the rest of the lines have screenwidth chars. */ ! nleft = out - wrap_offset + term_xn - 1; ! inv_botlin = (nleft > 0) ? nleft / screenwidth : 0; /* The first line is at character position 0 in the buffer. The *************** *** 453,457 **** update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum, screenwidth + W_OFFSET(linenum, visible_wrap_offset), ! screenwidth + W_OFFSET(linenum, wrap_offset)); /* If this is the line with the prompt, we might need to --- 446,451 ---- update_line (VIS_LINE(linenum), INV_LINE(linenum), linenum, screenwidth + W_OFFSET(linenum, visible_wrap_offset), ! screenwidth + W_OFFSET(linenum, wrap_offset), ! inv_botlin); /* If this is the line with the prompt, we might need to *************** *** 471,475 **** /* Since the new first line is now visible, save its length. */ if (linenum == 0) ! visible_first_line_len = _rl_last_c_pos; } --- 465,469 ---- /* Since the new first line is now visible, save its length. */ if (linenum == 0) ! visible_first_line_len = (inv_botlin > 0) ? screenwidth : out - wrap_offset; } *************** *** 492,501 **** /* Move the cursor where it should be. */ /* Which line? */ ! nleft = c_pos - screenwidth - wrap_offset; ! if (nleft >= 0) ! cursor_linenum = 1 + nleft / screenwidth; ! else ! cursor_linenum = 0; ! _rl_move_vert (cursor_linenum); /* We have to reprint the prompt if it contains invisible --- 486,505 ---- /* Move the cursor where it should be. */ /* Which line? */ ! nleft = c_pos - wrap_offset - term_xn + 1; ! cursor_linenum = (nleft > 0) ? nleft / screenwidth : 0; ! ! /* CHANGED_SCREEN_LINE is set to 1 if we have moved to a ! different screen line during this redisplay. */ ! changed_screen_line = _rl_last_v_pos != cursor_linenum; ! if (changed_screen_line) ! { ! _rl_move_vert (cursor_linenum); ! /* If we moved up to the line with the prompt using term_up, ! the physical cursor position on the screen stays the same, ! but the buffer position needs to be adjusted to account ! for invisible characters. */ ! if (cursor_linenum == 0 && wrap_offset) ! _rl_last_c_pos += wrap_offset; ! } /* We have to reprint the prompt if it contains invisible *************** *** 504,508 **** nleft = visible_length + wrap_offset; if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 && ! _rl_last_c_pos < nleft && local_prompt) { if (term_cr) --- 508,512 ---- nleft = visible_length + wrap_offset; if (cursor_linenum == 0 && wrap_offset > 0 && _rl_last_c_pos > 0 && ! _rl_last_c_pos <= nleft && local_prompt) { if (term_cr) *************** *** 515,518 **** --- 519,524 ---- in the buffer? */ pos = L_OFFSET(cursor_linenum, wrap_offset); + /* nleft == number of characters in the line buffer between the + start of the line and the cursor position. */ nleft = c_pos - pos; *************** *** 522,528 **** if (wrap_offset && cursor_linenum == 0 && nleft < _rl_last_c_pos) { - /* XXX - I'm not sure yet why the -1 is necessary - XXX */ - if (nleft < _rl_last_c_pos - 1) - nleft -= wrap_offset; backspace (_rl_last_c_pos - nleft); _rl_last_c_pos = nleft; --- 528,531 ---- *************** *** 535,552 **** else /* Do horizontal scrolling. */ { ! int lmargin; /* Always at top line. */ _rl_last_v_pos = 0; ! /* If the display position of the cursor would be off the edge ! of the screen, start the display of this line at an offset that ! leaves the cursor on the screen. */ ! if (c_pos - last_lmargin > screenwidth - 2) ! lmargin = (c_pos / (screenwidth / 3) - 2) * (screenwidth / 3); ! else if (c_pos - last_lmargin < 1) ! lmargin = ((c_pos - 1) / (screenwidth / 3)) * (screenwidth / 3); else ! lmargin = last_lmargin; /* If the first character on the screen isn't the first character --- 538,586 ---- else /* Do horizontal scrolling. */ { ! #define M_OFFSET(margin, offset) ((margin) == 0 ? offset : 0) ! int lmargin, ndisp, nleft, phys_c_pos, t; /* Always at top line. */ _rl_last_v_pos = 0; ! /* Compute where in the buffer the displayed line should start. This ! will be LMARGIN. */ ! ! /* The number of characters that will be displayed before the cursor. */ ! ndisp = c_pos - wrap_offset; ! nleft = visible_length + wrap_offset; ! /* Where the new cursor position will be on the screen. This can be ! longer than SCREENWIDTH; if it is, lmargin will be adjusted. */ ! phys_c_pos = c_pos - (last_lmargin ? last_lmargin : wrap_offset); ! t = screenwidth / 3; ! ! /* If the number of characters had already exceeded the screenwidth, ! last_lmargin will be > 0. */ ! ! /* If the number of characters to be displayed is more than the screen ! width, compute the starting offset so that the cursor is about ! two-thirds of the way across the screen. */ ! if (phys_c_pos > screenwidth - 2) ! { ! lmargin = c_pos - (2 * t); ! if (lmargin < 0) ! lmargin = 0; ! /* If the left margin would be in the middle of a prompt with ! invisible characters, don't display the prompt at all. */ ! if (wrap_offset && lmargin > 0 && lmargin < nleft) ! lmargin = nleft; ! } ! else if (ndisp < screenwidth - 2) /* XXX - was -1 */ ! lmargin = 0; ! else if (phys_c_pos < 1) ! { ! /* If we are moving back towards the beginning of the line and ! the last margin is no longer correct, compute a new one. */ ! lmargin = ((c_pos - 1) / t) * t; /* XXX */ ! if (wrap_offset && lmargin > 0 && lmargin < nleft) ! lmargin = nleft; ! } else ! lmargin = last_lmargin; /* If the first character on the screen isn't the first character *************** *** 555,566 **** line[lmargin] = '<'; ! if (lmargin + screenwidth < out) ! line[lmargin + screenwidth - 1] = '>'; if (!rl_display_fixed || forced_display || lmargin != last_lmargin) { forced_display = 0; ! update_line (&visible_line[last_lmargin], &invisible_line[lmargin], ! 0, screenwidth, screenwidth); _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]); --- 589,624 ---- line[lmargin] = '<'; ! /* If SCREENWIDTH characters starting at LMARGIN do not encompass ! the whole line, indicate that with a special characters at the ! right edge of the screen. If LMARGIN is 0, we need to take the ! wrap offset into account. */ ! t = lmargin + M_OFFSET (lmargin, wrap_offset) + screenwidth; ! if (t < out) ! line[t - 1] = '>'; if (!rl_display_fixed || forced_display || lmargin != last_lmargin) { forced_display = 0; ! update_line (&visible_line[last_lmargin], ! &invisible_line[lmargin], ! 0, ! screenwidth + visible_wrap_offset, ! screenwidth + (lmargin ? 0 : wrap_offset), ! 0); ! ! /* If the visible new line is shorter than the old, but the number ! of invisible characters is greater, and we are at the end of ! the new line, we need to clear to eol. */ ! t = _rl_last_c_pos - M_OFFSET (lmargin, wrap_offset); ! if ((M_OFFSET (lmargin, wrap_offset) > visible_wrap_offset) && ! (_rl_last_c_pos == out) && ! t < visible_first_line_len) ! { ! nleft = screenwidth - t; ! clear_to_eol (nleft); ! } ! visible_first_line_len = out - lmargin - M_OFFSET (lmargin, wrap_offset); ! if (visible_first_line_len > screenwidth) ! visible_first_line_len = screenwidth; _rl_move_cursor_relative (c_pos - lmargin, &invisible_line[lmargin]); *************** *** 576,580 **** invisible_line = temp; rl_display_fixed = 0; ! visible_wrap_offset = wrap_offset; } } --- 634,644 ---- invisible_line = temp; rl_display_fixed = 0; ! /* If we are displaying on a single line, and last_lmargin is > 0, we ! are not displaying any invisible characters, so set visible_wrap_offset ! to 0. */ ! if (_rl_horizontal_scroll_mode && last_lmargin) ! visible_wrap_offset = 0; ! else ! visible_wrap_offset = wrap_offset; } } *************** *** 597,601 **** Could be made even smarter, but this works well enough */ static void ! update_line (old, new, current_line, omax, nmax) register char *old, *new; int current_line, omax, nmax; --- 661,665 ---- Could be made even smarter, but this works well enough */ static void ! update_line (old, new, current_line, omax, nmax, inv_botlin) register char *old, *new; int current_line, omax, nmax; *************** *** 604,607 **** --- 668,690 ---- int temp, lendiff, wsatend, od, nd; + /* If we're at the right edge of a terminal that supports xn, we're + ready to wrap around, so do so. This fixes problems with knowing + the exact cursor position and cut-and-paste with certain terminal + emulators. In this calculation, TEMP is the physical screen + position of the cursor. */ + temp = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset); + if (temp == screenwidth && term_xn && !_rl_horizontal_scroll_mode + && _rl_last_v_pos == current_line - 1) + { + if (new[0]) + putc (new[0], rl_outstream); + else + putc (' ', rl_outstream); + _rl_last_c_pos = 1; /* XXX */ + _rl_last_v_pos++; + if (old[0]) + old[0] = new[0]; + } + /* Find first difference. */ for (ofd = old, nfd = new; *************** *** 657,661 **** lendiff = strlen (local_prompt); ! if (current_line == 0 && lendiff > visible_length && _rl_last_c_pos > 0 && (ofd - old) >= lendiff && term_cr) { --- 740,745 ---- lendiff = strlen (local_prompt); ! if (current_line == 0 && !_rl_horizontal_scroll_mode && ! lendiff > visible_length && _rl_last_c_pos > 0 && (ofd - old) >= lendiff && term_cr) { *************** *** 674,711 **** if (lendiff > 0) { ! if (terminal_can_insert) { ! /* Sometimes it is cheaper to print the characters rather than ! use the terminal's capabilities. */ ! if ((2 * temp) < lendiff && !term_IC) { ! _rl_output_some_chars (nfd, temp); ! _rl_last_c_pos += temp; } else { ! if (*ols) ! { ! insert_some_chars (nfd, lendiff); ! _rl_last_c_pos += lendiff; ! } ! else ! { ! /* At the end of a line the characters do not have to ! be "inserted". They can just be placed on the screen. */ ! _rl_output_some_chars (nfd, lendiff); ! _rl_last_c_pos += lendiff; ! } ! temp = nls - nfd; ! /* Copy (new) chars to screen from first diff to last match. */ ! if ((temp - lendiff) > 0) ! { ! _rl_output_some_chars (&nfd[lendiff], temp - lendiff); ! _rl_last_c_pos += temp - lendiff; ! } } } else ! { /* cannot insert chars, write to EOL */ _rl_output_some_chars (nfd, temp); _rl_last_c_pos += temp; --- 758,797 ---- if (lendiff > 0) { ! /* Non-zero if we're increasing the number of lines. */ ! int gl = current_line >= _rl_vis_botlin && inv_botlin > _rl_vis_botlin; ! /* Sometimes it is cheaper to print the characters rather than ! use the terminal's capabilities. If we're growing the number ! of lines, make sure we actually cause the new line to wrap ! around on auto-wrapping terminals. */ ! if (terminal_can_insert && ((2 * temp) >= lendiff || term_IC) && (!term_xn || !gl)) { ! /* If lendiff > visible_length and _rl_last_c_pos == 0 and ! _rl_horizontal_scroll_mode == 1, inserting the characters with ! term_IC or term_ic will screw up the screen because of the ! invisible characters. We need to just draw them. */ ! if (*ols && (!_rl_horizontal_scroll_mode || _rl_last_c_pos > 0 || ! lendiff <= visible_length)) { ! insert_some_chars (nfd, lendiff); ! _rl_last_c_pos += lendiff; } else { ! /* At the end of a line the characters do not have to ! be "inserted". They can just be placed on the screen. */ ! _rl_output_some_chars (nfd, lendiff); ! _rl_last_c_pos += lendiff; ! } ! /* Copy (new) chars to screen from first diff to last match. */ ! temp = nls - nfd; ! if ((temp - lendiff) > 0) ! { ! _rl_output_some_chars (nfd + lendiff, temp - lendiff); ! _rl_last_c_pos += temp - lendiff; } } else ! { ! /* cannot insert chars, write to EOL */ _rl_output_some_chars (nfd, temp); _rl_last_c_pos += temp; *************** *** 717,720 **** --- 803,813 ---- if (term_dc && (2 * temp) >= -lendiff) { + /* If all we're doing is erasing the invisible characters in the + prompt string, don't bother. It screws up the assumptions + about what's on the screen. */ + if (_rl_horizontal_scroll_mode && _rl_last_c_pos == 0 && + -lendiff == visible_wrap_offset) + lendiff = 0; + if (lendiff) delete_chars (-lendiff); /* delete (diff) characters */ *************** *** 736,740 **** _rl_last_c_pos += temp; } ! clear_to_eol ((oe - old) - (ne - new)); } } --- 829,837 ---- _rl_last_c_pos += temp; } ! lendiff = (oe - old) - (ne - new); ! if (term_xn && current_line < inv_botlin) ! space_to_eol (lendiff); ! else ! clear_to_eol (lendiff); } } *************** *** 777,790 **** register int i; /* It may be faster to output a CR, and then move forwards instead of moving backwards. */ ! if (CR_FASTER (new, _rl_last_c_pos)) { tputs (term_cr, 1, _rl_output_character_function); _rl_last_c_pos = 0; } - if (_rl_last_c_pos == new) return; - if (_rl_last_c_pos < new) { --- 874,894 ---- register int i; + /* If we don't have to do anything, then return. */ + if (_rl_last_c_pos == new) return; + /* It may be faster to output a CR, and then move forwards instead of moving backwards. */ ! /* i == current physical cursor position. */ ! i = _rl_last_c_pos - W_OFFSET(_rl_last_v_pos, visible_wrap_offset); ! if (CR_FASTER (new, _rl_last_c_pos) || (term_xn && i == screenwidth)) { + #if defined (__MSDOS__) + putc ('\r', rl_outstream); + #else tputs (term_cr, 1, _rl_output_character_function); + #endif /* !__MSDOS__ */ _rl_last_c_pos = 0; } if (_rl_last_c_pos < new) { *************** *** 812,816 **** #endif /* HACK_TERMCAP_MOTION */ } ! else backspace (_rl_last_c_pos - new); _rl_last_c_pos = new; --- 916,920 ---- #endif /* HACK_TERMCAP_MOTION */ } ! else if (_rl_last_c_pos != new) backspace (_rl_last_c_pos - new); _rl_last_c_pos = new; *************** *** 981,995 **** else #endif /* !__GO32__ */ ! { ! register int i; ! /* Do one more character space. */ ! count++; ! for (i = 0; i < count; i++) ! putc (' ', rl_outstream); ! backspace (count); ! } } --- 1085,1103 ---- else #endif /* !__GO32__ */ ! space_to_eol (count); ! } ! /* Clear to the end of the line using spaces. COUNT is the minimum ! number of character spaces to clear, */ ! static void ! space_to_eol (count) ! int count; ! { ! register int i; ! for (i = 0; i < count; i++) ! putc (' ', rl_outstream); ! _rl_last_c_pos += count; } *************** *** 1066,1070 **** #else /* !_GO32 */ ! if (count > screenwidth) return; --- 1174,1178 ---- #else /* !_GO32 */ ! if (count > screenwidth) /* XXX */ return; *************** *** 1082,1084 **** --- 1190,1268 ---- } #endif /* !__GO32__ */ + } + + void + _rl_update_final () + { + int full_lines; + + full_lines = 0; + if (_rl_vis_botlin && visible_line[screenwidth * _rl_vis_botlin] == 0) + { + _rl_vis_botlin--; + full_lines = 1; + } + _rl_move_vert (_rl_vis_botlin); + if (full_lines && term_xn) + { + /* Remove final line-wrap flag in xterm. */ + char *last_line; + last_line = &visible_line[screenwidth * _rl_vis_botlin]; + _rl_move_cursor_relative (screenwidth - 1, last_line); + clear_to_eol (0); + putc (last_line[screenwidth - 1], rl_outstream); + } + _rl_vis_botlin = 0; + crlf (); + fflush (rl_outstream); + rl_display_fixed++; + } + + /* Move to the start of the current line. */ + static void + cr () + { + if (term_cr) + { + tputs (term_cr, 1, _rl_output_character_function); + _rl_last_c_pos = 0; + } + } + + /* Redisplay the current line after a SIGWINCH is received. */ + void + _rl_redisplay_after_sigwinch () + { + char *t, *oldp; + + /* Clear the current line and put the cursor at column 0. Make sure + the right thing happens if we have wrapped to a new screen line. */ + if (term_cr) + { + tputs (term_cr, 1, _rl_output_character_function); + _rl_last_c_pos = 0; + if (term_clreol) + tputs (term_clreol, 1, _rl_output_character_function); + else + { + space_to_eol (screenwidth); + tputs (term_cr, 1, _rl_output_character_function); + } + if (_rl_last_v_pos > 0) + _rl_move_vert (0); + } + else + crlf (); + + /* Redraw only the last line of a multi-line prompt. */ + t = strrchr (rl_display_prompt, '\n'); + if (t) + { + oldp = rl_display_prompt; + rl_display_prompt = ++t; + rl_forced_update_display (); + rl_display_prompt = oldp; + } + else + rl_forced_update_display (); } diff -rc2 bash-1.14.1/lib/readline/doc/Makefile bash-1.14.2/lib/readline/doc/Makefile *** bash-1.14.1/lib/readline/doc/Makefile Fri Jul 1 11:21:13 1994 --- bash-1.14.2/lib/readline/doc/Makefile Sun Aug 7 01:21:21 1994 *************** *** 6,15 **** TEX = tex - DVIOBJ = history.dvi - INFOBJ = history.info ! all: $(DVIOBJ) $(INFOBJ) ! history.dvi: hist.texinfo hsuser.texinfo hstech.texinfo $(TEX) hist.texinfo $(TEXINDEX) hist.?? --- 6,29 ---- TEX = tex ! RLSRC = rlman.texinfo rluser.texinfo rltech.texinfo ! HISTSRC = hist.texinfo hsuser.texinfo hstech.texinfo ! DVIOBJ = readline.dvi history.dvi ! INFOOBJ = readline.info history.info ! PSOBJ = readline.ps history.ps ! ! all: info dvi ! ! readline.dvi: $(RLSRC) ! $(TEX) rlman.texinfo ! $(TEXINDEX) rlman.?? ! $(TEX) rlman.texinfo ! mv rlman.dvi readline.dvi ! ! readline.info: $(RLSRC) ! makeinfo rlman.texinfo ! ! history.dvi: ${HISTSRC} $(TEX) hist.texinfo $(TEXINDEX) hist.?? *************** *** 17,25 **** mv hist.dvi history.dvi ! history.info: hist.texinfo hsuser.texinfo hstech.texinfo makeinfo hist.texinfo ! ./texinfo.tex: $(DOC_SUPPORT)texinfo.tex ! ln -s $(DOC_SUPPORT)texinfo.tex . $(TEXINDEX): --- 31,47 ---- mv hist.dvi history.dvi ! history.info: ${HISTSRC} makeinfo hist.texinfo ! readline.ps: readline.dvi ! dvips -D 300 -o $@ readline.dvi ! ! history.ps: history.dvi ! dvips -D 300 -o $@ history.dvi ! ! info: $(INFOOBJ) ! dvi: $(DVIOBJ) ! ps: $(PSOBJ) ! $(TEXINDEX): diff -rc2 bash-1.14.1/lib/readline/doc/hist.texinfo bash-1.14.2/lib/readline/doc/hist.texinfo *** bash-1.14.1/lib/readline/doc/hist.texinfo Fri Jul 1 11:21:14 1994 --- bash-1.14.2/lib/readline/doc/hist.texinfo Wed Jul 20 15:25:05 1994 *************** *** 1,10 **** \input texinfo @c -*-texinfo-*- ! @comment %**start of header (This is for running Texinfo on a region.) @setfilename history.info ! @settitle GNU Readline Library ! @comment %**end of header (This is for running Texinfo on a region.) ! @synindex vr fn @setchapternewpage odd @ifinfo This document describes the GNU History library, a programming tool that --- 1,19 ---- \input texinfo @c -*-texinfo-*- ! @c %**start of header (This is for running Texinfo on a region.) @setfilename history.info ! @settitle GNU History Library ! @c %**end of header (This is for running Texinfo on a region.) ! @setchapternewpage odd + @ignore + last change: Wed Jul 20 09:57:17 EDT 1994 + @end ignore + + @set EDITION 2.0 + @set VERSION 2.0 + @set UPDATED 20 July 1994 + @set UPDATE-MONTH July 1994 + @ifinfo This document describes the GNU History library, a programming tool that *************** *** 38,52 **** @titlepage @sp 10 ! @center @titlefont{GNU History Library} ! @center Brian Fox ! @center Free Software Foundation ! @center Version 1.1 ! @center April 1991 ! ! @c Include the Distribution inside the titlepage environment so ! @c that headings are turned off. @page - This document describes the GNU History library, a programming tool that provides a consistent user interface for recalling lines of previously --- 47,57 ---- @titlepage @sp 10 ! @title GNU History Library ! @subtitle Edition @value{EDITION}, for @code{History Library} Version @value{VERSION}. ! @subtitle @value{UPDATE-MONTH} ! @author Brian Fox, Free Software Foundation ! @author Chet Ramey, Case Western Reserve University @page This document describes the GNU History library, a programming tool that provides a consistent user interface for recalling lines of previously *************** *** 92,95 **** --- 97,102 ---- @end ifinfo + @syncodeindex fn vr + @include hsuser.texinfo @include hstech.texinfo *************** *** 102,106 **** @appendix Function and Variable Index @printindex vr - @contents @bye --- 109,113 ---- @appendix Function and Variable Index @printindex vr + @contents @bye Only in bash-1.14.2/lib/readline/doc: history.dvi Only in bash-1.14.2/lib/readline/doc: history.info Only in bash-1.14.2/lib/readline/doc: history.ps diff -rc2 bash-1.14.1/lib/readline/doc/hstech.texinfo bash-1.14.2/lib/readline/doc/hstech.texinfo *** bash-1.14.1/lib/readline/doc/hstech.texinfo Fri Jul 1 11:21:14 1994 --- bash-1.14.2/lib/readline/doc/hstech.texinfo Wed Aug 3 10:26:51 1994 *************** *** 3,7 **** Copyright (C) 1988, 1991 Free Software Foundation, Inc. ! Authored by Brian Fox. Permission is granted to make and distribute verbatim copies of this manual --- 3,7 ---- Copyright (C) 1988, 1991 Free Software Foundation, Inc. ! Authored by Brian Fox and Chet Ramey. Permission is granted to make and distribute verbatim copies of this manual *************** *** 27,32 **** @chapter Programming with GNU History ! This chapter describes how to interface the GNU History Library with ! programs that you write. It should be considered a technical guide. For information on the interactive use of GNU History, @pxref{Using History Interactively}. --- 27,33 ---- @chapter Programming with GNU History ! This chapter describes how to interface programs that you write ! with the GNU History Library. ! It should be considered a technical guide. For information on the interactive use of GNU History, @pxref{Using History Interactively}. *************** *** 43,72 **** @section Introduction to History ! Many programs read input from the user a line at a time. The GNU history library is able to keep track of those lines, associate arbitrary data with ! each line, and utilize information from previous lines in making up new ones. ! The programmer using the History library has available to him functions ! for remembering lines on a history stack, associating arbitrary data ! with a line, removing lines from the stack, searching through the stack for a line containing an arbitrary text string, and referencing any line ! on the stack directly. In addition, a history @dfn{expansion} function ! is available which provides for a consistent user interface across many different programs. ! The end-user using programs written with the History library has the ! benifit of a consistent user interface, with a set of well-known commands for manipulating the text of previous lines and using that text in new commands. The basic history manipulation commands are similar to ! the history substitution used by @code{Csh}. If the programmer desires, he can use the Readline library, which includes some history manipulation by default, and has the added ! advantage of Emacs style command line editing. @node History Storage @section History Storage @example typedef struct _hist_entry @{ --- 44,76 ---- @section Introduction to History ! Many programs read input from the user a line at a time. The GNU History library is able to keep track of those lines, associate arbitrary data with ! each line, and utilize information from previous lines in composing new ones. ! The programmer using the History library has available functions ! for remembering lines on a history list, associating arbitrary data ! with a line, removing lines from the list, searching through the list for a line containing an arbitrary text string, and referencing any line ! in the list directly. In addition, a history @dfn{expansion} function ! is available which provides for a consistent user interface across different programs. ! The user using programs written with the History library has the ! benefit of a consistent user interface with a set of well-known commands for manipulating the text of previous lines and using that text in new commands. The basic history manipulation commands are similar to ! the history substitution provided by @code{csh}. If the programmer desires, he can use the Readline library, which includes some history manipulation by default, and has the added ! advantage of command line editing. @node History Storage @section History Storage + The history list is an array of history entries. A history entry is + declared as follows: + @example typedef struct _hist_entry @{ *************** *** 76,79 **** --- 80,105 ---- @end example + The history list itself might therefore be declared as + + @example + HIST_ENTRY **the_history_list; + @end example + + The state of the History library is encapsulated into a single structure: + + @example + /* A structure used to pass the current state of the history stuff around. */ + typedef struct _hist_state @{ + HIST_ENTRY **entries; /* Pointer to the entries themselves. */ + int offset; /* The location pointer within this array. */ + int length; /* Number of elements within this array. */ + int size; /* Number of slots allocated to this array. */ + int flags; + @} HISTORY_STATE; + @end example + + If the flags member includes @code{HS_STIFLED}, the history has been + stifled. + @node History Functions @section History Functions *************** *** 82,239 **** present in GNU History. ! @defun {void using_history} () Begin a session in which the history functions might be used. This ! just initializes the interactive variables. ! @end defun ! @defun {void add_history} (char *string) Place @var{string} at the end of the history list. The associated data field (if any) is set to @code{NULL}. ! @end defun ! ! @defun {int where_history} () ! Returns the number which says what history element we are now looking ! at. ! @end defun ! ! @defun {int history_set_pos} (int pos) ! Set the position in the history list to @var{pos}. ! @end defun ! @defun {int history_search_pos} (char *string, int direction, int pos) ! Search for @var{string} in the history list, starting at @var{pos}, an ! absolute index into the list. @var{direction}, if negative, says to search ! backwards from @var{pos}, else forwards. Returns the absolute index of ! the history element where @var{string} was found, or -1 otherwise. ! @end defun ! ! @defun {HIST_ENTRY *remove_history} (); ! Remove history element @var{which} from the history. The removed ! element is returned to you so you can free the line, data, and containing structure. ! @end defun ! @defun {void stifle_history} (int max) ! Stifle the history list, remembering only @var{max} number of entries. ! @end defun ! @defun {int unstifle_history} (); Stop stifling the history. This returns the previous amount the ! history was stifled by. The value is positive if the history was stifled, negative if it wasn't. ! @end defun ! @defun {int read_history} (char *filename) Add the contents of @var{filename} to the history list, a line at a time. If @var{filename} is @code{NULL}, then read from @file{~/.history}. Returns 0 if successful, or errno if not. ! @end defun ! @defun {int read_history_range} (char *filename, int from, int to) Read a range of lines from @var{filename}, adding them to the history list. ! Start reading at the @var{from}'th line and end at the @var{to}'th. If @var{from} is zero, start at the beginning. If @var{to} is less than @var{from}, then read until the end of the file. If @var{filename} is @code{NULL}, then read from @file{~/.history}. Returns 0 if successful, or @code{errno} if not. ! @end defun ! @defun {int write_history} (char *filename) ! Append the current history to @var{filename}. If @var{filename} is ! @code{NULL}, then append the history list to @file{~/.history}. Values returned are as in @code{read_history ()}. ! @end defun ! @defun {int append_history} (int nelements, char *filename) ! Append @var{nelement} entries to @var{filename}. The entries appended ! are from the end of the list minus @var{nelements} up to the end of the ! list. ! @end defun ! @defun {HIST_ENTRY *replace_history_entry} () ! Make the history entry at @var{which} have @var{line} and @var{data}. ! This returns the old entry so you can dispose of the data. In the case ! of an invalid @var{which}, a @code{NULL} pointer is returned. ! @end defun ! @defun {HIST_ENTRY *current_history} () ! Return the history entry at the current position, as determined by ! @code{history_offset}. If there is no entry there, return a @code{NULL} ! pointer. ! @end defun ! @defun {HIST_ENTRY *previous_history} () ! Back up @var{history_offset} to the previous history entry, and return a ! pointer to that entry. If there is no previous entry, return a ! @code{NULL} pointer. ! @end defun ! ! @defun {HIST_ENTRY *next_history} () ! Move @code{history_offset} forward to the next history entry, and return ! the a pointer to that entry. If there is no next entry, return a ! @code{NULL} pointer. ! @end defun ! ! @defun {HIST_ENTRY **history_list} () ! Return a @code{NULL} terminated array of @code{HIST_ENTRY} which is the ! current input history. Element 0 of this list is the beginning of time. ! If there is no history, return @code{NULL}. ! @end defun ! @defun {int history_search} (char *string, int direction) ! Search the history for @var{string}, starting at @code{history_offset}. ! If @var{direction} < 0, then the search is through previous entries, ! else through subsequent. If @var{string} is found, then ! @code{current_history ()} is the history entry, and the value of this ! function is the offset in the line of that history entry that the ! @var{string} was found in. Otherwise, nothing is changed, and a -1 is ! returned. ! @end defun ! ! @defun {int history_expand} (char *string, char **output) Expand @var{string}, placing the result into @var{output}, a pointer ! to a string. Returns: @table @code @item 0 If no expansions took place (or, if the only change in the text was the de-slashifying of the history expansion ! character), @item 1 ! if expansions did take place, or @item -1 ! if there was an error in expansion. @end table If an error ocurred in expansion, then @var{output} contains a descriptive error message. ! @end defun ! @defun {char *history_arg_extract} (int first, int last, char *string) Extract a string segment consisting of the @var{first} through @var{last} ! arguments present in @var{string}. Arguments are broken up as in ! the GNU Bash shell. ! @end defun ! @defun {int history_total_bytes} (); ! Return the number of bytes that the primary history entries are using. ! This just adds up the lengths of @code{the_history->lines}. ! @end defun @node History Variables @section History Variables ! This section describes the variables in GNU History that are externally ! visible. ! @defvar {int history_base} ! For convenience only. You set this when interpreting history commands. ! It is the logical offset of the first history element. ! @end defvar @node History Programming Example @section History Programming Example ! The following snippet of code demonstrates simple use of the GNU History ! Library. @smallexample --- 108,408 ---- present in GNU History. ! @menu ! * Initializing History and State Management:: Functions to call when you ! want to use history in a ! program. ! * History List Management:: Functions used to manage the list ! of history entries. ! * Information About the History List:: Functions returning information about ! the history list. ! * Moving Around the History List:: Functions used to change the position ! in the history list. ! * Searching the History List:: Functions to search the history list ! for entries containing a string. ! * Managing the History File:: Functions that read and write a file ! containing the history list. ! * History Expansion:: Functions to perform csh-like history ! expansion. ! @end menu ! ! @node Initializing History and State Management ! @subsection Initializing History and State Management ! ! This section describes functions used to initialize and manage ! the state of the History library when you want to use the history ! functions in your program. ! ! @deftypefun void using_history () Begin a session in which the history functions might be used. This ! initializes the interactive variables. ! @end deftypefun ! ! @deftypefun {HISTORY_STATE *} history_get_history_state () ! Return a structure describing the current state of the input history. ! @end deftypefun ! @deftypefun void history_set_history_state (HISTORY_STATE *state) ! Set the state of the history list according to @var{state}. ! @end deftypefun ! ! @node History List Management ! @subsection History List Management ! ! These functions manage individual entries on the history list, or set ! parameters managing the list itself. ! ! @deftypefun void add_history (char *string) Place @var{string} at the end of the history list. The associated data field (if any) is set to @code{NULL}. ! @end deftypefun ! @deftypefun {HIST_ENTRY *} remove_history (int which) ! Remove history entry at offset @var{which} from the history. The ! removed element is returned so you can free the line, data, and containing structure. ! @end deftypefun ! ! @deftypefun {HIST_ENTRY *} replace_history_entry (int which, char *line, char *data) ! Make the history entry at offset @var{which} have @var{line} and @var{data}. ! This returns the old entry so you can dispose of the data. In the case ! of an invalid @var{which}, a @code{NULL} pointer is returned. ! @end deftypefun ! @deftypefun void stifle_history (int max) ! Stifle the history list, remembering only the last @var{max} entries. ! @end deftypefun ! @deftypefun int unstifle_history () Stop stifling the history. This returns the previous amount the ! history was stifled. The value is positive if the history was stifled, negative if it wasn't. ! @end deftypefun ! ! @deftypefun int history_is_stifled () ! Returns non-zero if the history is stifled, zero if it is not. ! @end deftypefun ! ! @node Information About the History List ! @subsection Information About the History List ! ! These functions return information about the entire history list or ! individual list entries. ! ! @deftypefun {HIST_ENTRY **} history_list () ! Return a @code{NULL} terminated array of @code{HIST_ENTRY} which is the ! current input history. Element 0 of this list is the beginning of time. ! If there is no history, return @code{NULL}. ! @end deftypefun ! @deftypefun int where_history () ! Returns the offset of the current history element. ! @end deftypefun ! ! @deftypefun {HIST_ENTRY *} current_history () ! Return the history entry at the current position, as determined by ! @code{where_history ()}. If there is no entry there, return a @code{NULL} ! pointer. ! @end deftypefun ! ! @deftypefun {HIST_ENTRY *} history_get (int offset) ! Return the history entry at position @var{offset}, starting from ! @code{history_base}. If there is no entry there, or if @var{offset} ! is greater than the history length, return a @code{NULL} pointer. ! @end deftypefun ! ! @deftypefun int history_total_bytes () ! Return the number of bytes that the primary history entries are using. ! This function returns the sum of the lengths of all the lines in the ! history. ! @end deftypefun ! ! @node Moving Around the History List ! @subsection Moving Around the History List ! ! These functions allow the current index into the history list to be ! set or changed. ! ! @deftypefun int history_set_pos (int pos) ! Set the position in the history list to @var{pos}, an absolute index ! into the list. ! @end deftypefun ! ! @deftypefun {HIST_ENTRY *} previous_history () ! Back up the current history offset to the previous history entry, and ! return a pointer to that entry. If there is no previous entry, return ! a @code{NULL} pointer. ! @end deftypefun ! ! @deftypefun {HIST_ENTRY *} next_history () ! Move the current history offset forward to the next history entry, and ! return the a pointer to that entry. If there is no next entry, return ! a @code{NULL} pointer. ! @end deftypefun ! ! @node Searching the History List ! @subsection Searching the History List ! @cindex History Searching ! ! These functions allow searching of the history list for entries containing ! a specific string. Searching may be performed both forward and backward ! from the current history position. The search may be @dfn{anchored}, ! meaning that the string must match at the beginning of the history entry. ! @cindex anchored search ! ! @deftypefun int history_search (char *string, int direction) ! Search the history for @var{string}, starting at the current history ! offset. If @var{direction} < 0, then the search is through previous entries, ! else through subsequent. If @var{string} is found, then ! the current history index is set to that history entry, and the value ! returned is the offset in the line of the entry where ! @var{string} was found. Otherwise, nothing is changed, and a -1 is ! returned. ! @end deftypefun ! ! @deftypefun int history_search_prefix (char *string, int direction) ! Search the history for @var{string}, starting at the current history ! offset. The search is anchored: matching lines must begin with ! @var{string}. If @var{direction} < 0, then the search is through previous ! entries, else through subsequent. If @var{string} is found, then the ! current history index is set to that entry, and the return value is 0. ! Otherwise, nothing is changed, and a -1 is returned. ! @end deftypefun ! ! @deftypefun int history_search_pos (char *string, int direction, int pos) ! Search for @var{string} in the history list, starting at @var{pos}, an ! absolute index into the list. If @var{direction} is negative, the search ! proceeds backward from @var{pos}, otherwise forward. Returns the absolute ! index of the history element where @var{string} was found, or -1 otherwise. ! @end deftypefun ! ! @node Managing the History File ! @subsection Managing the History File ! ! The History library can read the history from and write it to a file. ! This section documents the functions for managing a history file. ! ! @deftypefun int read_history (char *filename) Add the contents of @var{filename} to the history list, a line at a time. If @var{filename} is @code{NULL}, then read from @file{~/.history}. Returns 0 if successful, or errno if not. ! @end deftypefun ! @deftypefun int read_history_range (char *filename, int from, int to) Read a range of lines from @var{filename}, adding them to the history list. ! Start reading at line @var{from} and end at @var{to}. If @var{from} is zero, start at the beginning. If @var{to} is less than @var{from}, then read until the end of the file. If @var{filename} is @code{NULL}, then read from @file{~/.history}. Returns 0 if successful, or @code{errno} if not. ! @end deftypefun ! @deftypefun int write_history (char *filename) ! Write the current history to @var{filename}, overwriting @var{filename} ! if necessary. If @var{filename} is ! @code{NULL}, then write the history list to @file{~/.history}. Values returned are as in @code{read_history ()}. ! @end deftypefun ! @deftypefun int append_history (int nelements, char *filename) ! Append the last @var{nelements} of the history list to @var{filename}. ! @end deftypefun ! @deftypefun int history_truncate_file (char *filename, int nlines) ! Truncate the history file @var{filename}, leaving only the last ! @var{nlines} lines. ! @end deftypefun ! @node History Expansion ! @subsection History Expansion ! These functions implement @code{csh}-like history expansion. ! @deftypefun int history_expand (char *string, char **output) Expand @var{string}, placing the result into @var{output}, a pointer ! to a string (@pxref{History Interaction}). Returns: @table @code @item 0 If no expansions took place (or, if the only change in the text was the de-slashifying of the history expansion ! character); @item 1 ! if expansions did take place; @item -1 ! if there was an error in expansion; ! @item 2 ! if the returned line should only be displayed, but not executed, ! as with the @code{:p} modifier (@pxref{Modifiers}). @end table If an error ocurred in expansion, then @var{output} contains a descriptive error message. ! @end deftypefun ! @deftypefun {char *} history_arg_extract (int first, int last, char *string) Extract a string segment consisting of the @var{first} through @var{last} ! arguments present in @var{string}. Arguments are broken up as in Bash. ! @end deftypefun ! @deftypefun {char *} get_history_event (char *string, int *cindex, int qchar) ! Returns the text of the history event beginning at @var{string} + ! @var{*cindex}. @var{*cindex} is modified to point to after the event ! specifier. At function entry, @var{cindex} points to the index into ! @var{string} where the history event specification begins. @var{qchar} ! is a character that is allowed to end the event specification in addition ! to the ``normal'' terminating characters. ! @end deftypefun ! ! @deftypefun {char **} history_tokenize (char *string) ! Return an array of tokens parsed out of @var{string}, much as the ! shell might. The tokens are split on white space and on the ! characters @code{()<>;&|$}, and shell quoting conventions are ! obeyed. ! @end deftypefun @node History Variables @section History Variables ! This section describes the externally visible variables exported by ! the GNU History Library. ! @deftypevar int history_base ! The logical offset of the first entry in the history list. ! @end deftypevar ! ! @deftypevar int history_length ! The number of entries currently stored in the history list. ! @end deftypevar ! ! @deftypevar int max_input_history ! The maximum number of history entries. This must be changed using ! @code{stifle_history ()}. ! @end deftypevar ! ! @deftypevar char history_expansion_char ! The character that starts a history event. The default is @samp{!}. ! @end deftypevar ! ! @deftypevar char history_subst_char ! The character that invokes word substitution if found at the start of ! a line. The default is @samp{^}. ! @end deftypevar ! ! @deftypevar char history_comment_char ! During tokenization, if this character is seen as the first character ! of a word, then it and all subsequent characters up to a newline are ! ignored, suppressing history expansion for the remainder of the line. ! This is disabled by default. ! @end deftypevar ! ! @deftypevar {char *} history_no_expand_chars ! The list of characters which inhibit history expansion if found immediately ! following @var{history_expansion_char}. The default is whitespace and ! @samp{=}. ! @end deftypevar @node History Programming Example @section History Programming Example ! The following program demonstrates simple use of the GNU History Library. @smallexample *************** *** 241,252 **** @{ char line[1024], *t; ! int done = 0; line[0] = 0; while (!done) @{ ! fprintf (stdout, "history%% "); ! t = gets (line); if (!t) --- 410,429 ---- @{ char line[1024], *t; ! int len, done = 0; line[0] = 0; + using_history (); while (!done) @{ ! printf ("history$ "); ! fflush (stdout); ! t = fgets (line, sizeof (line) - 1, stdin); ! if (t && *t) ! @{ ! len = strlen (t); ! if (t[len - 1] == '\n') ! t[len - 1] = '\0'; ! @} if (!t) *************** *** 258,292 **** int result; - using_history (); - result = history_expand (line, &expansion); - strcpy (line, expansion); - free (expansion); if (result) ! fprintf (stderr, "%s\n", line); ! if (result < 0) ! continue; ! add_history (line); @} ! if (strcmp (line, "quit") == 0) done = 1; ! if (strcmp (line, "save") == 0) write_history (0); ! if (strcmp (line, "read") == 0) read_history (0); ! if (strcmp (line, "list") == 0) @{ ! register HIST_ENTRY **the_list = history_list (); register int i; if (the_list) for (i = 0; the_list[i]; i++) ! fprintf (stdout, "%d: %s\n", ! i + history_base, the_list[i]->line); @} ! if (strncmp (line, "delete", strlen ("delete")) == 0) @{ int which; ! if ((sscanf (line + strlen ("delete"), "%d", &which)) == 1) @{ HIST_ENTRY *entry = remove_history (which); --- 435,473 ---- int result; result = history_expand (line, &expansion); if (result) ! fprintf (stderr, "%s\n", expansion); ! if (result < 0 || result == 2) ! @{ ! free (expansion); ! continue; ! @} ! add_history (expansion); ! strncpy (line, expansion, sizeof (line) - 1); ! free (expansion); @} ! if (strcmp (line, "quit") == 0) ! done = 1; ! else if (strcmp (line, "save") == 0) ! write_history ("history_file"); ! else if (strcmp (line, "read") == 0) ! read_history ("history_file"); ! else if (strcmp (line, "list") == 0) @{ ! register HIST_ENTRY **the_list; register int i; + the_list = history_list (); if (the_list) for (i = 0; the_list[i]; i++) ! printf ("%d: %s\n", i + history_base, the_list[i]->line); @} ! else if (strncmp (line, "delete", 6) == 0) @{ int which; ! if ((sscanf (line + 6, "%d", &which)) == 1) @{ HIST_ENTRY *entry = remove_history (which); diff -rc2 bash-1.14.1/lib/readline/doc/hsuser.texinfo bash-1.14.2/lib/readline/doc/hsuser.texinfo *** bash-1.14.1/lib/readline/doc/hsuser.texinfo Fri Jul 1 11:21:14 1994 --- bash-1.14.2/lib/readline/doc/hsuser.texinfo Thu Jul 21 15:47:19 1994 *************** *** 49,54 **** The History library provides a history expansion feature that is similar ! to the history expansion in @code{csh}. The following text describes ! the syntax used to manipulate the history information. History expansion takes place in two parts. The first is to determine --- 49,54 ---- The History library provides a history expansion feature that is similar ! to the history expansion provided by @code{csh}. The following text ! describes the syntax used to manipulate the history information. History expansion takes place in two parts. The first is to determine *************** *** 73,76 **** --- 73,77 ---- An event designator is a reference to a command line entry in the history list. + @cindex history events @table @asis *************** *** 87,91 **** @item @code{!-n} ! Refer to the command line @var{n} lines back. @item @code{!string} --- 88,92 ---- @item @code{!-n} ! Refer to the command @var{n} lines back. @item @code{!string} Only in bash-1.14.2/lib/readline/doc: readline.dvi Only in bash-1.14.2/lib/readline/doc: readline.info Only in bash-1.14.2/lib/readline/doc: readline.info-1 Only in bash-1.14.2/lib/readline/doc: readline.info-2 Only in bash-1.14.2/lib/readline/doc: readline.ps diff -rc2 bash-1.14.1/lib/readline/doc/rlman.texinfo bash-1.14.2/lib/readline/doc/rlman.texinfo *** bash-1.14.1/lib/readline/doc/rlman.texinfo Fri Jul 1 11:21:13 1994 --- bash-1.14.2/lib/readline/doc/rlman.texinfo Mon Jul 25 22:36:56 1994 *************** *** 7,10 **** --- 7,19 ---- @setchapternewpage odd + @ignore + last change: Thu Jul 21 16:02:40 EDT 1994 + @end ignore + + @set EDITION 2.0 + @set VERSION 2.0 + @set UPDATED 21 July 1994 + @set UPDATE-MONTH July 1994 + @ifinfo This document describes the GNU Readline Library, a utility which aids *************** *** 36,46 **** @end ifinfo ! @titlepage @sp 10 ! @center @titlefont{GNU Readline Library} ! @center Brian Fox ! @center Free Software Foundation ! @center Version 1.1 ! @center April 1991 @page --- 45,55 ---- @end ifinfo ! @titlepage @sp 10 ! @title GNU Readline Library ! @subtitle Edition @value{EDITION}, for @code{Readline Library} Version @value{VERSION}. ! @subtitle @value{UPDATE-MONTH} ! @author Brian Fox, Free Software Foundation ! @author Chet Ramey, Case Western Reserve University @page *************** *** 101,103 **** @contents @bye - --- 110,111 ---- diff -rc2 bash-1.14.1/lib/readline/doc/rltech.texinfo bash-1.14.2/lib/readline/doc/rltech.texinfo *** bash-1.14.1/lib/readline/doc/rltech.texinfo Fri Jul 1 11:21:13 1994 --- bash-1.14.2/lib/readline/doc/rltech.texinfo Sun Aug 7 01:15:53 1994 *************** *** 9,13 **** to provide a command line interface. ! Copyright (C) 1988 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of --- 9,13 ---- to provide a command line interface. ! Copyright (C) 1988, 1994 Free Software Foundation, Inc. Permission is granted to make and distribute verbatim copies of *************** *** 36,54 **** @chapter Programming with GNU Readline ! This manual describes the interface between the GNU Readline Library and ! user programs. If you are a programmer, and you wish to include the ! features found in GNU Readline in your own programs, such as completion, ! line editing, and interactive history manipulation, this documentation ! is for you. @menu ! * Default Behaviour:: Using the default behaviour of Readline. * Custom Functions:: Adding your own functions to Readline. * Custom Completers:: Supplanting or supplementing Readline's completion functions. @end menu ! @node Default Behaviour ! @section Default Behaviour Many programs provide a command line interface, such as @code{mail}, --- 36,58 ---- @chapter Programming with GNU Readline ! This chapter describes the interface between the GNU Readline Library and ! other programs. If you are a programmer, and you wish to include the ! features found in GNU Readline ! such as completion, line editing, and interactive history manipulation ! in your own programs, this section is for you. @menu ! * Basic Behavior:: Using the default behavior of Readline. * Custom Functions:: Adding your own functions to Readline. + * Readline Variables:: Variables accessible to custom + functions. + * Readline Convenience Functions:: Functions which Readline supplies to + aid in writing your own * Custom Completers:: Supplanting or supplementing Readline's completion functions. @end menu ! @node Basic Behavior ! @section Basic Behavior Many programs provide a command line interface, such as @code{mail}, *************** *** 56,65 **** Readline is sufficient. This section describes how to use Readline in the simplest way possible, perhaps to replace calls in your code to ! @code{gets ()}. ! @findex readline () @cindex readline, function ! The function @code{readline} prints a prompt and then reads and returns ! a single line of text from the user. The line which @code{readline ()} returns is allocated with @code{malloc ()}; you should @code{free ()} the line when you are done with it. The declaration for @code{readline} --- 60,69 ---- Readline is sufficient. This section describes how to use Readline in the simplest way possible, perhaps to replace calls in your code to ! @code{gets()} or @code{fgets ()}. ! @findex readline @cindex readline, function ! The function @code{readline ()} prints a prompt and then reads and returns ! a single line of text from the user. The line @code{readline} returns is allocated with @code{malloc ()}; you should @code{free ()} the line when you are done with it. The declaration for @code{readline} *************** *** 70,85 **** @end example So, one might say @example @code{char *line = readline ("Enter a line: ");} @end example in order to read a line of text from the user. ! The line which is returned has the final newline removed, so only the ! text of the line remains. ! ! If readline encounters an @code{EOF} while reading the line, and the line is empty at that point, then @code{(char *)NULL} is returned. ! Otherwise, the line is ended just as if a newline was typed. If you want the user to be able to get at the line later, (with --- 74,90 ---- @end example + @noindent So, one might say @example @code{char *line = readline ("Enter a line: ");} @end example + @noindent in order to read a line of text from the user. + The line returned has the final newline removed, so only the + text remains. ! If @code{readline} encounters an @code{EOF} while reading the line, and the line is empty at that point, then @code{(char *)NULL} is returned. ! Otherwise, the line is ended just as if a newline had been typed. If you want the user to be able to get at the line later, (with *************** *** 91,100 **** @end example For full details on the GNU History Library, see the associated manual. ! It is polite to avoid saving empty lines on the history list, since it ! is rare than someone has a burning need to reuse a blank line. Here is a function which usefully replaces the standard @code{gets ()} library ! function: @example --- 96,106 ---- @end example + @noindent For full details on the GNU History Library, see the associated manual. ! It is preferable to avoid saving empty lines on the history list, since ! users rarely have a burning need to reuse a blank line. Here is a function which usefully replaces the standard @code{gets ()} library ! function, and has the advantage of no static buffer to overflow: @example *************** *** 104,112 **** /* Read a string, and return a pointer to it. Returns NULL on EOF. */ char * ! do_gets () @{ /* If the buffer has already been allocated, return the memory to the free pool. */ ! if (line_read != (char *)NULL) @{ free (line_read); --- 110,118 ---- /* Read a string, and return a pointer to it. Returns NULL on EOF. */ char * ! rl_gets () @{ /* If the buffer has already been allocated, return the memory to the free pool. */ ! if (line_read) @{ free (line_read); *************** *** 125,146 **** @end example ! The above code gives the user the default behaviour of @key{TAB} ! completion: completion on file names. If you do not want readline to complete on filenames, you can change the binding of the @key{TAB} key with @code{rl_bind_key ()}. - @findex rl_bind_key () @example @code{int rl_bind_key (int @var{key}, int (*@var{function})());} @end example ! @code{rl_bind_key ()} takes 2 arguments; @var{key} is the character that you want to bind, and @var{function} is the address of the function to ! run when @var{key} is pressed. Binding @key{TAB} to @code{rl_insert ()} ! makes @key{TAB} just insert itself. ! @code{rl_bind_key ()} returns non-zero if @var{key} is not a valid ASCII character code (between 0 and 255). @example @code{rl_bind_key ('\t', rl_insert);} --- 131,151 ---- @end example ! This function gives the user the default behaviour of @key{TAB} ! completion: completion on file names. If you do not want Readline to complete on filenames, you can change the binding of the @key{TAB} key with @code{rl_bind_key ()}. @example @code{int rl_bind_key (int @var{key}, int (*@var{function})());} @end example ! @code{rl_bind_key ()} takes two arguments: @var{key} is the character that you want to bind, and @var{function} is the address of the function to ! call when @var{key} is pressed. Binding @key{TAB} to @code{rl_insert ()} ! makes @key{TAB} insert itself. @code{rl_bind_key ()} returns non-zero if @var{key} is not a valid ASCII character code (between 0 and 255). + Thus, to disable the default @key{TAB} behavior, the following suffices: @example @code{rl_bind_key ('\t', rl_insert);} *************** *** 150,171 **** might write a function called @code{initialize_readline ()} which performs this and other desired initializations, such as installing ! custom completers, etc. @node Custom Functions @section Custom Functions ! Readline provides a great many functions for manipulating the text of ! the line. But it isn't possible to anticipate the needs of all programs. This section describes the various functions and variables ! defined in within the Readline library which allow a user program to add customized functionality to Readline. @menu * The Function Type:: C declarations to make code readable. - * Function Naming:: How to give a function you write a name. - * Keymaps:: Making keymaps. - * Binding Keys:: Changing Keymaps. * Function Writing:: Variables and calling conventions. - * Allowing Undoing:: How to make your functions undoable. @end menu --- 155,172 ---- might write a function called @code{initialize_readline ()} which performs this and other desired initializations, such as installing ! custom completers (@pxref{Custom Completers}). @node Custom Functions @section Custom Functions ! Readline provides many functions for manipulating the text of ! the line, but it isn't possible to anticipate the needs of all programs. This section describes the various functions and variables ! defined within the Readline library which allow a user program to add customized functionality to Readline. @menu * The Function Type:: C declarations to make code readable. * Function Writing:: Variables and calling conventions. @end menu *************** *** 173,178 **** @subsection The Function Type ! For the sake of readabilty, we declare a new type of object, called ! @dfn{Function}. A @code{Function} is a C language function which returns an @code{int}. The type declaration for @code{Function} is: --- 174,179 ---- @subsection The Function Type ! For readabilty, we declare a new type of object, called ! @dfn{Function}. A @code{Function} is a C function which returns an @code{int}. The type declaration for @code{Function} is: *************** *** 187,194 **** @code{int (*)()func;} ! we have @code{Function *func;} @node Function Naming @subsection Naming a Function --- 188,320 ---- @code{int (*)()func;} ! @noindent ! we may write @code{Function *func;} + @noindent + Similarly, there are + + @example + typedef void VFunction (); + typedef char *CPFunction (); @r{and} + typedef char **CPPFunction (); + @end example + + @noindent + for functions returning no value, @code{pointer to char}, and + @code{pointer to pointer to char}, respectively. + + @node Function Writing + @subsection Writing a New Function + + In order to write new functions for Readline, you need to know the + calling conventions for keyboard-invoked functions, and the names of the + variables that describe the current state of the line read so far. + + The calling sequence for a command @code{foo} looks like + + @example + @code{foo (int count, int key)} + @end example + + @noindent + where @var{count} is the numeric argument (or 1 if defaulted) and + @var{key} is the key that invoked this function. + + It is completely up to the function as to what should be done with the + numeric argument. Some functions use it as a repeat count, some + as a flag, and others to choose alternate behavior (refreshing the current + line as opposed to refreshing the screen, for example). Some choose to + ignore it. In general, if a + function uses the numeric argument as a repeat count, it should be able + to do something useful with both negative and positive arguments. + At the very least, it should be aware that it can be passed a + negative argument. + + @node Readline Variables + @section Readline Variables + + These variables are available to function writers. + + @deftypevar {char *} rl_line_buffer + This is the line gathered so far. You are welcome to modify the + contents of the line, but see @ref{Allowing Undoing}. + @end deftypevar + + @deftypevar int rl_point + The offset of the current cursor position in @code{rl_line_buffer} + (the @emph{point}). + @end deftypevar + + @deftypevar int rl_end + The number of characters present in @code{rl_line_buffer}. When + @code{rl_point} is at the end of the line, @code{rl_point} and + @code{rl_end} are equal. + @end deftypevar + + @deftypevar int rl_mark + The mark (saved position) in the current line. If set, the mark + and point define a @emph{region}. + @end deftypevar + + @deftypevar int rl_done + Setting this to a non-zero value causes Readline to return the current + line immediately. + @end deftypevar + + @deftypevar int rl_pending_input + Setting this to a value makes it the next keystroke read. This is a + way to stuff a single character into the input stream. + @end deftypevar + + @deftypevar {char *} rl_prompt + The prompt Readline uses. This is set from the argument to + @code{readline ()}, and should not be assigned to directly. + @end deftypevar + + @deftypevar {char *} rl_terminal_name + The terminal type, used for initialization. + @end deftypevar + + @deftypevar {char *} rl_readline_name + This variable is set to a unique name by each application using Readline. + The value allows conditional parsing of the inputrc file + (@pxref{Conditional Init Constructs}). + @end deftypevar + + @deftypevar {FILE *} rl_instream + The stdio stream from which Readline reads input. + @end deftypevar + + @deftypevar {FILE *} rl_outstream + The stdio stream to which Readline performs output. + @end deftypevar + + @deftypevar {Function *} rl_startup_hook + If non-zero, this is the address of a function to call just + before @code{readline} prints the first prompt. + @end deftypevar + + @deftypevar {Function *} rl_event_hook + If non-zero, this is the address of a function to call periodically + when readline is waiting for terminal input. + @end deftypevar + + @node Readline Convenience Functions + @section Readline Convenience Functions + + @menu + * Function Naming:: How to give a function you write a name. + * Keymaps:: Making keymaps. + * Binding Keys:: Changing Keymaps. + * Associating Function Names and Bindings:: Translate function names to + key sequences. + * Allowing Undoing:: How to make your functions undoable. + * Redisplay:: Functions to control line display. + * Modifying Text:: Functions to modify @code{rl_line_buffer}. + * Utility Functions:: Generally useful functions and hooks. + @end menu + @node Function Naming @subsection Naming a Function *************** *** 208,221 **** well. Readline provides a function for doing that: ! @defun rl_add_defun (char *name, Function *function, int key) Add @var{name} to the list of named functions. Make @var{function} be the function that gets called. If @var{key} is not -1, then bind it to @var{function} using @code{rl_bind_key ()}. ! @end defun Using this function alone is sufficient for most applications. It is the recommended way to add a few functions to the default functions that ! Readline has built in already. If you need to do more or different ! things than adding a function to Readline, you may need to use the underlying functions described below. --- 334,347 ---- well. Readline provides a function for doing that: ! @deftypefun int rl_add_defun (char *name, Function *function, int key) Add @var{name} to the list of named functions. Make @var{function} be the function that gets called. If @var{key} is not -1, then bind it to @var{function} using @code{rl_bind_key ()}. ! @end deftypefun Using this function alone is sufficient for most applications. It is the recommended way to add a few functions to the default functions that ! Readline has built in. If you need to do something other ! than adding a function to Readline, you may need to use the underlying functions described below. *************** *** 228,367 **** Readline which keymap to use. ! @defun {Keymap rl_make_bare_keymap} () Returns a new, empty keymap. The space for the keymap is allocated with @code{malloc ()}; you should @code{free ()} it when you are done. ! @end defun ! @defun {Keymap rl_copy_keymap} (Keymap map) Return a new keymap which is a copy of @var{map}. ! @end defun ! @defun {Keymap rl_make_keymap} () Return a new keymap with the printing characters bound to rl_insert, the lowercase Meta characters bound to run their equivalents, and the Meta digits bound to produce numeric arguments. ! @end defun @node Binding Keys @subsection Binding Keys ! You associate keys with functions through the keymap. Here are ! functions for doing that. ! @defun {int rl_bind_key} (int key, Function *function) ! Binds @var{key} to @var{function} in the currently selected keymap. Returns non-zero in the case of an invalid @var{key}. ! @end defun ! @defun {int rl_bind_key_in_map} (int key, Function *function, Keymap map) Bind @var{key} to @var{function} in @var{map}. Returns non-zero in the case of an invalid @var{key}. ! @end defun ! @defun {int rl_unbind_key} (int key) ! Make @var{key} do nothing in the currently selected keymap. Returns non-zero in case of error. ! @end defun ! @defun {int rl_unbind_key_in_map} (int key, Keymap map) ! Make @var{key} be bound to the null function in @var{map}. Returns non-zero in case of error. ! @end defun ! @defun rl_generic_bind (int type, char *keyseq, char *data, Keymap map) Bind the key sequence represented by the string @var{keyseq} to the arbitrary pointer @var{data}. @var{type} says what kind of data is pointed to by ! @var{data}; right now this can be a function (@code{ISFUNC}), a macro (@code{ISMACR}), or a keymap (@code{ISKMAP}). This makes new keymaps as ! necessary. The initial place to do bindings is in @var{map}. ! @end defun ! @node Function Writing ! @subsection Writing a New Function ! ! In order to write new functions for Readline, you need to know the ! calling conventions for keyboard invoked functions, and the names of the ! variables that describe the current state of the line gathered so far. ! ! @defvar {char *rl_line_buffer} ! This is the line gathered so far. You are welcome to modify the ! contents of this, but see Undoing, below. ! @end defvar ! ! @defvar {int rl_point} ! The offset of the current cursor position in @var{rl_line_buffer}. ! @end defvar ! ! @defvar {int rl_end} ! The number of characters present in @code{rl_line_buffer}. When ! @code{rl_point} is at the end of the line, then @code{rl_point} and ! @code{rl_end} are equal. ! @end defvar ! ! The calling sequence for a command @code{foo} looks like ! ! @example ! @code{foo (int count, int key)} ! @end example ! ! where @var{count} is the numeric argument (or 1 if defaulted) and ! @var{key} is the key that invoked this function. ! ! It is completely up to the function as to what should be done with the ! numeric argument; some functions use it as a repeat count, other ! functions as a flag, and some choose to ignore it. In general, if a ! function uses the numeric argument as a repeat count, it should be able ! to do something useful with a negative argument as well as a positive ! argument. At the very least, it should be aware that it can be passed a ! negative argument. @node Allowing Undoing @subsection Allowing Undoing ! Supporting the undo command is a painless thing to do, and makes your ! functions much more useful to the end user. It is certainly easy to try something if you know you can undo it. I could use an undo function for the stock market. ! If your function simply inserts text once, or deletes text once, and it ! calls @code{rl_insert_text ()} or @code{rl_delete_text ()} to do it, then ! undoing is already done for you automatically, and you can safely skip ! this section. If you do multiple insertions or multiple deletions, or any combination of these operations, you should group them together into one operation. ! This can be done with @code{rl_begin_undo_group ()} and @code{rl_end_undo_group ()}. ! @defun rl_begin_undo_group () Begins saving undo information in a group construct. The undo information usually comes from calls to @code{rl_insert_text ()} and ! @code{rl_delete_text ()}, but they could be direct calls to @code{rl_add_undo ()}. ! @end defun ! @defun rl_end_undo_group () Closes the current undo group started with @code{rl_begin_undo_group ! ()}. There should be exactly one call to @code{rl_end_undo_group ()} ! for every call to @code{rl_begin_undo_group ()}. ! @end defun Finally, if you neither insert nor delete text, but directly modify the ! existing text (e.g. change its case), you call @code{rl_modifying ()} once, just before you modify the text. You must supply the indices of the text range that you are going to modify. ! @defun rl_modifying (int start, int end) Tell Readline to save the text between @var{start} and @var{end} as a ! single undo unit. It is assumed that subsequent to this call you will ! modify that range of text in some way. ! @end defun @subsection An Example ! Here is a function which changes lowercase characters to the uppercase ! equivalents, and uppercase characters to the lowercase equivalents. If this function was bound to @samp{M-c}, then typing @samp{M-c} would ! change the case of the character under point. Typing @samp{10 M-c} would change the case of the following 10 characters, leaving the cursor on the last character changed. --- 354,676 ---- Readline which keymap to use. ! @deftypefun Keymap rl_make_bare_keymap () Returns a new, empty keymap. The space for the keymap is allocated with @code{malloc ()}; you should @code{free ()} it when you are done. ! @end deftypefun ! @deftypefun Keymap rl_copy_keymap (Keymap map) Return a new keymap which is a copy of @var{map}. ! @end deftypefun ! @deftypefun Keymap rl_make_keymap () Return a new keymap with the printing characters bound to rl_insert, the lowercase Meta characters bound to run their equivalents, and the Meta digits bound to produce numeric arguments. ! @end deftypefun ! ! @deftypefun void rl_discard_keymap (Keymap keymap) ! Free the storage associated with @var{keymap}. ! @end deftypefun ! ! Readline has several internal keymaps. These functions allow you to ! change which keymap is active. ! ! @deftypefun Keymap rl_get_keymap () ! Returns the currently active keymap. ! @end deftypefun ! ! @deftypefun void rl_set_keymap (Keymap keymap) ! Makes @var{keymap} the currently active keymap. ! @end deftypefun ! ! @deftypefun Keymap rl_get_keymap_by_name (char *name) ! Return the keymap matching @var{name}. @var{name} is one which would ! be supplied in a @code{set keymap} inputrc line (@pxref{Readline Init File}). ! @end deftypefun @node Binding Keys @subsection Binding Keys ! You associate keys with functions through the keymap. Readline has ! several internal keymaps: @code{emacs_standard_keymap}, ! @code{emacs_meta_keymap}, @code{emacs_ctlx_keymap}, ! @code{vi_movement_keymap}, and @code{vi_insertion_keymap}. ! @code{emacs_standard_keymap} is the default, and the examples in ! this manual assume that. ! ! These functions manage key bindings. ! @deftypefun int rl_bind_key (int key, Function *function) ! Binds @var{key} to @var{function} in the currently active keymap. Returns non-zero in the case of an invalid @var{key}. ! @end deftypefun ! @deftypefun int rl_bind_key_in_map (int key, Function *function, Keymap map) Bind @var{key} to @var{function} in @var{map}. Returns non-zero in the case of an invalid @var{key}. ! @end deftypefun ! @deftypefun int rl_unbind_key (int key) ! Bind @var{key} to the null function in the currently active keymap. Returns non-zero in case of error. ! @end deftypefun ! @deftypefun int rl_unbind_key_in_map (int key, Keymap map) ! Bind @var{key} to the null function in @var{map}. Returns non-zero in case of error. ! @end deftypefun ! @deftypefun int rl_generic_bind (int type, char *keyseq, char *data, Keymap map) Bind the key sequence represented by the string @var{keyseq} to the arbitrary pointer @var{data}. @var{type} says what kind of data is pointed to by ! @var{data}; this can be a function (@code{ISFUNC}), a macro (@code{ISMACR}), or a keymap (@code{ISKMAP}). This makes new keymaps as ! necessary. The initial keymap in which to do bindings is @var{map}. ! @end deftypefun ! @deftypefun int rl_parse_and_bind (char *line) ! Parse @var{line} as if it had been read from the @code{inputrc} file and ! perform any key bindings and variable assignments found ! (@pxref{Readline Init File}). ! @end deftypefun ! ! @deftypefun int rl_read_init_file (char *filename) ! Read keybindings and variable assignments from @var{filename} ! (@pxref{Readline Init File}). ! @end deftypefun ! ! @node Associating Function Names and Bindings ! @subsection Associating Function Names and Bindings ! ! These functions allow you to find out what keys invoke named functions ! and the functions invoked by a particular key sequence. ! ! @deftypefun {Function *} rl_named_function (char *name) ! Return the function with name @var{name}. ! @end deftypefun ! ! @deftypefun {Function *} rl_function_of_keyseq (char *keyseq, Keymap map, int *type) ! Return the function invoked by @var{keyseq} in keymap @var{map}. ! If @var{map} is NULL, the current keymap is used. If @var{type} is ! not NULL, the type of the object is returned in it (one of @code{ISFUNC}, ! @code{ISKMAP}, or @code{ISMACR}). ! @end deftypefun ! ! @deftypefun {char **} rl_invoking_keyseqs (Function *function) ! Return an array of strings representing the key sequences used to ! invoke @var{function} in the current keymap. ! @end deftypefun ! ! @deftypefun {char **} rl_invoking_keyseqs_in_map (Function *function, Keymap map) ! Return an array of strings representing the key sequences used to ! invoke @var{function} in the keymap @var{map}. ! @end deftypefun ! ! @deftypefun void rl_function_dumper (int readable) ! Print the readline function names and the key sequences currently ! bound to them to @code{rl_outstream}. If @var{readable} is non-zero, ! the list is formatted in such a way that it can be made part of an ! @code{inputrc} file and re-read. ! @end deftypefun ! ! @deftypefun void rl_list_funmap_names () ! Print the names of all bindable Readline functions to @code{rl_outstream}. ! @end deftypefun @node Allowing Undoing @subsection Allowing Undoing ! Supporting the undo command is a painless thing, and makes your ! functions much more useful. It is certainly easy to try something if you know you can undo it. I could use an undo function for the stock market. ! If your function simply inserts text once, or deletes text once, and ! uses @code{rl_insert_text ()} or @code{rl_delete_text ()} to do it, then ! undoing is already done for you automatically. If you do multiple insertions or multiple deletions, or any combination of these operations, you should group them together into one operation. ! This is done with @code{rl_begin_undo_group ()} and @code{rl_end_undo_group ()}. ! The types of events that can be undone are: ! ! @example ! enum undo_code @{ UNDO_DELETE, UNDO_INSERT, UNDO_BEGIN, UNDO_END @}; ! @end example ! ! Notice that @code{UNDO_DELETE} means to insert some text, and ! @code{UNDO_INSERT} means to delete some text. That is, the undo code ! tells undo what to undo, not how to undo it. @code{UNDO_BEGIN} and ! @code{UNDO_END} are tags added by @code{rl_begin_undo_group ()} and ! @code{rl_end_undo_group ()}. ! ! @deftypefun int rl_begin_undo_group () Begins saving undo information in a group construct. The undo information usually comes from calls to @code{rl_insert_text ()} and ! @code{rl_delete_text ()}, but could be the result of calls to @code{rl_add_undo ()}. ! @end deftypefun ! @deftypefun int rl_end_undo_group () Closes the current undo group started with @code{rl_begin_undo_group ! ()}. There should be one call to @code{rl_end_undo_group ()} ! for each call to @code{rl_begin_undo_group ()}. ! @end deftypefun ! ! @deftypefun void rl_add_undo (enum undo_code what, int start, int end, char *text) ! Remember how to undo an event (according to @var{what}). The affected ! text runs from @var{start} to @var{end}, and encompasses @var{text}. ! @end deftypefun ! ! @deftypefun void free_undo_list () ! Free the existing undo list. ! @end deftypefun ! ! @deftypefun int rl_do_undo () ! Undo the first thing on the undo list. Returns @code{0} if there was ! nothing to undo, non-zero if something was undone. ! @end deftypefun Finally, if you neither insert nor delete text, but directly modify the ! existing text (e.g., change its case), call @code{rl_modifying ()} once, just before you modify the text. You must supply the indices of the text range that you are going to modify. ! @deftypefun int rl_modifying (int start, int end) Tell Readline to save the text between @var{start} and @var{end} as a ! single undo unit. It is assumed that you will subsequently modify ! that text. ! @end deftypefun ! ! @node Redisplay ! @subsection Redisplay ! ! @deftypefun int rl_redisplay () ! Change what's displayed on the screen to reflect the current contents ! of @code{rl_line_buffer}. ! @end deftypefun ! ! @deftypefun int rl_forced_update_display () ! Force the line to be updated and redisplayed, whether or not ! Readline thinks the screen display is correct. ! @end deftypefun ! ! @deftypefun int rl_on_new_line () ! Tell the update routines that we have moved onto a new (empty) line, ! usually after ouputting a newline. ! @end deftypefun ! ! @deftypefun int rl_reset_line_state () ! Reset the display state to a clean state and redisplay the current line ! starting on a new line. ! @end deftypefun ! ! @deftypefun int rl_message (va_alist) ! The arguments are a string as would be supplied to @code{printf}. The ! resulting string is displayed in the @dfn{echo area}. The echo area ! is also used to display numeric arguments and search strings. ! @end deftypefun ! ! @deftypefun int rl_clear_message () ! Clear the message in the echo area. ! @end deftypefun ! ! @node Modifying Text ! @subsection Modifying Text ! ! @deftypefun int rl_insert_text (char *text) ! Insert @var{text} into the line at the current cursor position. ! @end deftypefun ! ! @deftypefun int rl_delete_text (int start, int end) ! Delete the text between @var{start} and @var{end} in the current line. ! @end deftypefun ! ! @deftypefun {char *} rl_copy_text (int start, int end) ! Return a copy of the text between @var{start} and @var{end} in ! the current line. ! @end deftypefun ! ! @deftypefun int rl_kill_text (int start, int end) ! Copy the text between @var{start} and @var{end} in the current line ! to the kill ring, appending or prepending to the last kill if the ! last command was a kill command. The text is deleted. ! If @var{start} is less than @var{end}, ! the text is appended, otherwise prepended. If the last command was ! not a kill, a new kill ring slot is used. ! @end deftypefun ! ! @node Utility Functions ! @subsection Utility Functions ! ! @deftypefun int rl_read_key () ! Return the next character available. This handles input inserted into ! the input stream via @var{pending input} (@pxref{Readline Variables}) ! and @code{rl_stuff_char ()}, macros, and characters read from the keyboard. ! @end deftypefun ! ! @deftypefun int rl_stuff_char (int c) ! Insert @var{c} into the Readline input stream. It will be "read" ! before Readline attempts to read characters from the terminal with ! @code{rl_read_key ()}. ! @end deftypefun ! ! @deftypefun int rl_initialize () ! Initialize or re-initialize Readline's internal state. ! @end deftypefun ! ! @deftypefun int rl_reset_terminal (char *terminal_name) ! Reinitialize Readline's idea of the terminal settings using ! @var{terminal_name} as the terminal type (e.g., @code{vt100}). ! @end deftypefun ! ! @deftypefun int alphabetic (int c) ! Return 1 if @var{c} is an alphabetic character. ! @end deftypefun ! ! @deftypefun int numeric (int c) ! Return 1 if @var{c} is a numeric character. ! @end deftypefun ! ! @deftypefun int ding () ! Ring the terminal bell, obeying the setting of @code{bell-style}. ! @end deftypefun ! ! The following are implemented as macros, defined in @code{chartypes.h}. ! ! @deftypefun int uppercase_p (int c) ! Return 1 if @var{c} is an uppercase alphabetic character. ! @end deftypefun ! ! @deftypefun int lowercase_p (int c) ! Return 1 if @var{c} is a lowercase alphabetic character. ! @end deftypefun ! ! @deftypefun int digit_p (int c) ! Return 1 if @var{c} is a numeric character. ! @end deftypefun ! ! @deftypefun int to_upper (int c) ! If @var{c} is a lowercase alphabetic character, return the corresponding ! uppercase character. ! @end deftypefun ! ! @deftypefun int to_lower (int c) ! If @var{c} is an uppercase alphabetic character, return the corresponding ! lowercase character. ! @end deftypefun ! ! @deftypefun int digit_value (int c) ! If @var{c} is a number, return the value it represents. ! @end deftypefun @subsection An Example ! Here is a function which changes lowercase characters to their uppercase ! equivalents, and uppercase characters to lowercase. If this function was bound to @samp{M-c}, then typing @samp{M-c} would ! change the case of the character under point. Typing @samp{M-1 0 M-c} would change the case of the following 10 characters, leaving the cursor on the last character changed. *************** *** 369,379 **** @example /* Invert the case of the COUNT following characters. */ invert_case_line (count, key) int count, key; @{ ! register int start, end; start = rl_point; if (count < 0) @{ --- 678,692 ---- @example /* Invert the case of the COUNT following characters. */ + int invert_case_line (count, key) int count, key; @{ ! register int start, end, i; start = rl_point; + if (rl_point >= rl_end) + return (0); + if (count < 0) @{ *************** *** 391,395 **** end = rl_end; else if (end < 0) ! end = -1; if (start > end) --- 704,711 ---- end = rl_end; else if (end < 0) ! end = 0; ! ! if (start == end) ! return (0); if (start > end) *************** *** 400,419 **** @} ! if (start == end) ! return; ! ! /* Tell readline that we are modifying the line, so save the undo ! information. */ rl_modifying (start, end); ! for (; start != end; start += direction) @{ ! if (uppercase_p (rl_line_buffer[start])) ! rl_line_buffer[start] = to_lower (rl_line_buffer[start]); ! else if (lowercase_p (rl_line_buffer[start])) ! rl_line_buffer[start] = to_upper (rl_line_buffer[start]); @} /* Move point to on top of the last character changed. */ ! rl_point = end - direction; @} @end example --- 716,733 ---- @} ! /* Tell readline that we are modifying the line, so it will save ! the undo information. */ rl_modifying (start, end); ! for (i = start; i != end; i++) @{ ! if (uppercase_p (rl_line_buffer[i])) ! rl_line_buffer[i] = to_lower (rl_line_buffer[i]); ! else if (lowercase_p (rl_line_buffer[i])) ! rl_line_buffer[i] = to_upper (rl_line_buffer[i]); @} /* Move point to on top of the last character changed. */ ! rl_point = (direction == 1) ? end - 1 : start; ! return (0); @} @end example *************** *** 424,430 **** Typically, a program that reads commands from the user has a way of disambiguating commands and data. If your program is one of these, then ! it can provide completion for either commands, or data, or both commands ! and data. The following sections describe how your program and Readline ! cooperate to provide this service to end users. @menu --- 738,744 ---- Typically, a program that reads commands from the user has a way of disambiguating commands and data. If your program is one of these, then ! it can provide completion for commands, data, or both. ! The following sections describe how your program and Readline ! cooperate to provide this service. @menu *************** *** 439,450 **** In order to complete some text, the full list of possible completions ! must be available. That is to say, it is not possible to accurately ! expand a partial word without knowing what all of the possible words ! that make sense in that context are. The GNU Readline library provides ! the user interface to completion, and additionally, two of the most common ! completion functions; filename and username. For completing other types of text, you must write your own completion function. This section ! describes exactly what those functions must do, and provides an example ! function. There are three major functions used to perform completion: --- 753,763 ---- In order to complete some text, the full list of possible completions ! must be available. That is, it is not possible to accurately ! expand a partial word without knowing all of the possible words ! which make sense in that context. The Readline library provides ! the user interface to completion, and two of the most common ! completion functions: filename and username. For completing other types of text, you must write your own completion function. This section ! describes exactly what such functions must do, and provides an example. There are three major functions used to perform completion: *************** *** 453,462 **** @item The user-interface function @code{rl_complete ()}. This function is ! called interactively with the same calling conventions as other ! functions in readline intended for interactive use; i.e. @var{count}, ! and @var{invoking-key}. It isolates the word to be completed and calls @code{completion_matches ()} to generate a list of possible completions. ! It then either lists the possible completions or actually performs the ! completion, depending on which behaviour is desired. @item --- 766,776 ---- @item The user-interface function @code{rl_complete ()}. This function is ! called with the same arguments as other Readline ! functions intended for interactive use: @var{count} and ! @var{invoking_key}. It isolates the word to be completed and calls @code{completion_matches ()} to generate a list of possible completions. ! It then either lists the possible completions, inserts the possible ! completions, or actually performs the ! completion, depending on which behavior is desired. @item *************** *** 471,497 **** arguments to the generator function are @var{text} and @var{state}. @var{text} is the partial word to be completed. @var{state} is zero the ! first time the function is called, and a positive non-zero integer for ! each subsequent call. When the generator function returns @code{(char ! *)NULL} this signals @code{completion_matches ()} that there are no more ! possibilities left. @end enumerate ! @defun rl_complete (int ignore, int invoking_key) Complete the word at or before point. You have supplied the function that does the initial simple matching selection algorithm (see @code{completion_matches ()}). The default is to do filename completion. ! @end defun ! ! Note that @code{rl_complete ()} has the identical calling conventions as ! any other key-invokable function; this is because by default it is bound ! to the @samp{TAB} key. ! @defvar {Function *rl_completion_entry_function} This is a pointer to the generator function for @code{completion_matches ()}. If the value of @code{rl_completion_entry_function} is ! @code{(Function *)NULL} then the default filename generator function is ! used, namely @code{filename_entry_function ()}. ! @end defvar @node Completion Functions --- 785,812 ---- arguments to the generator function are @var{text} and @var{state}. @var{text} is the partial word to be completed. @var{state} is zero the ! first time the function is called, allowing the generator to perform ! any necessary initialization, and a positive non-zero integer for ! each subsequent call. When the generator function returns ! @code{(char *)NULL} this signals @code{completion_matches ()} that there are ! no more possibilities left. Usually the generator function computes the ! list of possible completions when @var{state} is zero, and returns them ! one at a time on subsequent calls. Each string the generator function ! returns as a match must be allocated with @code{malloc()}; Readline ! frees the strings when it has finished with them. @end enumerate ! @deftypefun int rl_complete (int ignore, int invoking_key) Complete the word at or before point. You have supplied the function that does the initial simple matching selection algorithm (see @code{completion_matches ()}). The default is to do filename completion. ! @end deftypefun ! @deftypevar {Function *} rl_completion_entry_function This is a pointer to the generator function for @code{completion_matches ()}. If the value of @code{rl_completion_entry_function} is ! @code{(Function *)NULL} then the default filename generator function, ! @code{filename_entry_function ()}, is used. ! @end deftypevar @node Completion Functions *************** *** 501,526 **** Readline. ! @defun rl_complete_internal (int what_to_do) Complete the word at or before point. @var{what_to_do} says what to do with the completion. A value of @samp{?} means list the possible completions. @samp{TAB} means do standard completion. @samp{*} means ! insert all of the possible completions. ! @end defun ! @defun rl_complete (int ignore, int invoking_key) Complete the word at or before point. You have supplied the function that does the initial simple matching selection algorithm (see ! @code{completion_matches ()}). The default is to do filename ! completion. This just calls @code{rl_complete_internal ()} with an ! argument of @samp{TAB}. ! @end defun ! @defun rl_possible_completions () List the possible completions. See description of @code{rl_complete ! ()}. This just calls @code{rl_complete_internal ()} with an argument of @samp{?}. ! @end defun ! @defun {char **completion_matches} (char *text, char *(*entry_function) ()) Returns an array of @code{(char *)} which is a list of completions for @var{text}. If there are no completions, returns @code{(char **)NULL}. --- 816,850 ---- Readline. ! @deftypefun int rl_complete_internal (int what_to_do) Complete the word at or before point. @var{what_to_do} says what to do with the completion. A value of @samp{?} means list the possible completions. @samp{TAB} means do standard completion. @samp{*} means ! insert all of the possible completions. @samp{!} means to display ! all of the possible completions, if there is more than one, as well as ! performing partial completion. ! @end deftypefun ! @deftypefun int rl_complete (int ignore, int invoking_key) Complete the word at or before point. You have supplied the function that does the initial simple matching selection algorithm (see ! @code{completion_matches ()} and @code{rl_completion_entry_function}). ! The default is to do filename ! completion. This calls @code{rl_complete_internal ()} with an ! argument depending on @var{invoking_key}. ! @end deftypefun ! @deftypefun int rl_possible_completions (int count, int invoking_key)) List the possible completions. See description of @code{rl_complete ! ()}. This calls @code{rl_complete_internal ()} with an argument of @samp{?}. ! @end deftypefun ! @deftypefun int rl_insert_completions (int count, int invoking_key)) ! Insert the list of possible completions into the line, deleting the ! partially-completed word. See description of @code{rl_complete ()}. ! This calls @code{rl_complete_internal ()} with an argument of @samp{*}. ! @end deftypefun ! ! @deftypefun {char **} completion_matches (char *text, CPFunction *entry_func) Returns an array of @code{(char *)} which is a list of completions for @var{text}. If there are no completions, returns @code{(char **)NULL}. *************** *** 529,613 **** terminated with a @code{NULL} pointer. ! @var{entry_function} is a function of two args, and returns a @code{(char *)}. The first argument is @var{text}. The second is a state argument; it is zero on the first call, and non-zero on subsequent ! calls. It returns a @code{NULL} pointer to the caller when there are ! no more matches. ! @end defun ! @defun {char *filename_completion_function} (char *text, int state) A generator function for filename completion in the general case. Note ! that completion in the Bash shell is a little different because of all ! the pathnames that must be followed when looking up the completion for a ! command. ! @end defun ! @defun {char *username_completion_function} (char *text, int state) A completion generator for usernames. @var{text} contains a partial ! username preceded by a random character (usually @samp{~}). ! @end defun @node Completion Variables @subsection Completion Variables ! @defvar {Function *rl_completion_entry_function} A pointer to the generator function for @code{completion_matches ()}. @code{NULL} means to use @code{filename_entry_function ()}, the default filename completer. ! @end defvar ! @defvar {Function *rl_attempted_completion_function} A pointer to an alternative function to create matches. The function is called with @var{text}, @var{start}, and @var{end}. @var{start} and @var{end} are indices in @code{rl_line_buffer} saying what the boundaries of @var{text} are. If this function exists and ! returns @code{NULL} then @code{rl_complete ()} will call the value of @code{rl_completion_entry_function} to generate matches, otherwise the array of strings returned will be used. ! @end defvar ! @defvar {int rl_completion_query_items} Up to this many items will be displayed in response to a possible-completions call. After that, we ask the user if she is sure she wants to see them all. The default value is 100. ! @end defvar ! @defvar {char *rl_basic_word_break_characters} The basic list of characters that signal a break between words for the ! completer routine. The contents of this variable is what breaks words ! in the Bash shell, i.e. " \t\n\"\\'`@@$><=;|&@{(". ! @end defvar ! @defvar {char *rl_completer_word_break_characters} The list of characters that signal a break between words for ! @code{rl_complete_internal ()}. The default list is the contents of @code{rl_basic_word_break_characters}. ! @end defvar ! @defvar {char *rl_special_prefixes} The list of characters that are word break characters, but should be left in @var{text} when it is passed to the completion function. Programs can use this to help determine what kind of completing to do. ! @end defvar ! @defvar {int rl_ignore_completion_duplicates} If non-zero, then disallow duplicates in the matches. Default is 1. ! @end defvar ! @defvar {int rl_filename_completion_desired} Non-zero means that the results of the matches are to be treated as filenames. This is @emph{always} zero on entry, and can only be changed ! within a completion entry generator function. ! @end defvar ! @defvar {Function *rl_ignore_some_completions_function} This function, if defined, is called by the completer when real filename completion is done, after all the matching names have been generated. ! It is passed a @code{NULL} terminated array of @code{(char *)} known as ! @var{matches} in the code. The 1st element (@code{matches[0]}) is the ! maximal substring that is common to all matches. This function can ! re-arrange the list of matches as required, but each deleted element of ! the array must be @code{free()}'d. ! @end defvar @node A Short Completion Example --- 853,970 ---- terminated with a @code{NULL} pointer. ! @var{entry_func} is a function of two args, and returns a @code{(char *)}. The first argument is @var{text}. The second is a state argument; it is zero on the first call, and non-zero on subsequent ! calls. @var{entry_func} returns a @code{NULL} pointer to the caller ! when there are no more matches. ! @end deftypefun ! @deftypefun {char *} filename_completion_function (char *text, int state) A generator function for filename completion in the general case. Note ! that completion in Bash is a little different because of all ! the pathnames that must be followed when looking up completions for a ! command. The Bash source is a useful reference for writing custom ! completion functions. ! @end deftypefun ! @deftypefun {char *} username_completion_function (char *text, int state) A completion generator for usernames. @var{text} contains a partial ! username preceded by a random character (usually @samp{~}). As with all ! completion generators, @var{state} is zero on the first call and non-zero ! for subsequent calls. ! @end deftypefun @node Completion Variables @subsection Completion Variables ! @deftypevar {Function *} rl_completion_entry_function A pointer to the generator function for @code{completion_matches ()}. @code{NULL} means to use @code{filename_entry_function ()}, the default filename completer. ! @end deftypevar ! @deftypevar {CPPFunction *} rl_attempted_completion_function A pointer to an alternative function to create matches. The function is called with @var{text}, @var{start}, and @var{end}. @var{start} and @var{end} are indices in @code{rl_line_buffer} saying what the boundaries of @var{text} are. If this function exists and ! returns @code{NULL}, or if this variable is set to @code{NULL}, then ! @code{rl_complete ()} will call the value of @code{rl_completion_entry_function} to generate matches, otherwise the array of strings returned will be used. ! @end deftypevar ! @deftypevar int rl_completion_query_items Up to this many items will be displayed in response to a possible-completions call. After that, we ask the user if she is sure she wants to see them all. The default value is 100. ! @end deftypevar ! @deftypevar {char *} rl_basic_word_break_characters The basic list of characters that signal a break between words for the ! completer routine. The default value of this variable is the characters ! which break words for completion in Bash, i.e., ! @code{" \t\n\"\\'`@@$><=;|&@{("}. ! @end deftypevar ! @deftypevar {char *} rl_completer_word_break_characters The list of characters that signal a break between words for ! @code{rl_complete_internal ()}. The default list is the value of @code{rl_basic_word_break_characters}. ! @end deftypevar ! ! @deftypevar {char *} rl_completer_quote_characters ! List of characters which can be used to quote a substring of the line. ! Completion occurs on the entire substring, and within the substring ! @code{rl_completer_word_break_characters} are treated as any other character, ! unless they also appear within this list. ! @end deftypevar ! @deftypevar {char *} rl_special_prefixes The list of characters that are word break characters, but should be left in @var{text} when it is passed to the completion function. Programs can use this to help determine what kind of completing to do. ! For instance, Bash sets this variable to "$@@" so that it can complete ! shell variables and hostnames. ! @end deftypevar ! @deftypevar int rl_ignore_completion_duplicates If non-zero, then disallow duplicates in the matches. Default is 1. ! @end deftypevar ! @deftypevar int rl_filename_completion_desired Non-zero means that the results of the matches are to be treated as filenames. This is @emph{always} zero on entry, and can only be changed ! within a completion entry generator function. If it is set to a non-zero ! value, directory names have a slash appended and Readline attempts to ! quote completed filenames if they contain any embedded word break ! characters. ! @end deftypevar ! ! @deftypevar int rl_filename_quoting_desired ! Non-zero means that the results of the matches are to be quoted using ! double quotes (or an application-specific quoting mechanism) if the ! completed filename contains any characters in ! @code{rl_completer_word_break_chars}. This is @emph{always} non-zero ! on entry, and can only be changed within a completion entry generator ! function. ! @end deftypevar ! @deftypevar {Function *} rl_ignore_some_completions_function This function, if defined, is called by the completer when real filename completion is done, after all the matching names have been generated. ! It is passed a @code{NULL} terminated array of matches. ! The first element (@code{matches[0]}) is the ! maximal substring common to all matches. This function can ! re-arrange the list of matches as required, but each element deleted ! from the array must be freed. ! @end deftypevar ! ! @deftypevar {Function *} 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. It could be used ! to expand symbolic links or shell variables in pathnames. ! @end deftypevar @node A Short Completion Example *************** *** 616,620 **** Here is a small application demonstrating the use of the GNU Readline library. It is called @code{fileman}, and the source code resides in ! @file{readline/examples/fileman.c}. This sample application provides completion of command names, line editing features, and access to the history list. --- 973,977 ---- Here is a small application demonstrating the use of the GNU Readline library. It is called @code{fileman}, and the source code resides in ! @file{examples/fileman.c}. This sample application provides completion of command names, line editing features, and access to the history list. *************** *** 627,632 **** #include - #include - #include #include #include --- 984,987 ---- *************** *** 634,637 **** --- 989,998 ---- #include + #include + #include + + extern char *getwd (); + extern char *xmalloc (); + /* The names of functions that actually do the manipulation. */ int com_list (), com_view (), com_rename (), com_stat (), com_pwd (); *************** *** 642,648 **** typedef struct @{ ! char *name; /* User printable name of the function. */ ! Function *func; /* Function to call to do the job. */ ! char *doc; /* Documentation for this function. */ @} COMMAND; --- 1003,1009 ---- typedef struct @{ ! char *name; /* User printable name of the function. */ ! Function *func; /* Function to call to do the job. */ ! char *doc; /* Documentation for this function. */ @} COMMAND; *************** *** 662,706 **** @}; /* The name of this program, as taken from argv[0]. */ char *progname; /* When non-zero, this global means the user is done using this program. */ ! int done = 0; ! @page main (argc, argv) int argc; char **argv; @{ progname = argv[0]; ! initialize_readline (); /* Bind our completer. */ /* Loop reading and executing lines until the user quits. */ ! while (!done) @{ - char *line; - line = readline ("FileMan: "); if (!line) ! @{ ! done = 1; /* Encountered EOF at top level. */ ! @} ! else ! @{ ! /* Remove leading and trailing whitespace from the line. ! Then, if there is anything left, add it to the history list ! and execute it. */ ! stripwhite (line); ! if (*line) ! @{ ! add_history (line); ! execute_line (line); ! @} @} ! if (line) ! free (line); @} exit (0); --- 1023,1077 ---- @}; + /* Forward declarations. */ + char *stripwhite (); + COMMAND *find_command (); + /* The name of this program, as taken from argv[0]. */ char *progname; /* When non-zero, this global means the user is done using this program. */ ! int done; ! ! char * ! dupstr (s) ! int s; ! @{ ! char *r; ! ! r = xmalloc (strlen (s) + 1); ! strcpy (r, s); ! return (r); ! @} ! main (argc, argv) int argc; char **argv; @{ + char *line, *s; + progname = argv[0]; ! initialize_readline (); /* Bind our completer. */ /* Loop reading and executing lines until the user quits. */ ! for ( ; done == 0; ) @{ line = readline ("FileMan: "); if (!line) ! break; ! /* Remove leading and trailing whitespace from the line. ! Then, if there is anything left, add it to the history list ! and execute it. */ ! s = stripwhite (line); ! ! if (*s) ! @{ ! add_history (s); ! execute_line (s); @} ! free (line); @} exit (0); *************** *** 708,724 **** /* Execute a command line. */ execute_line (line) char *line; @{ register int i; ! COMMAND *find_command (), *command; char *word; /* Isolate the command word. */ i = 0; ! while (line[i] && !whitespace (line[i])) i++; ! word = line; if (line[i]) --- 1079,1098 ---- /* Execute a command line. */ + int execute_line (line) char *line; @{ register int i; ! COMMAND *command; char *word; /* Isolate the command word. */ i = 0; ! while (line[i] && whitespace (line[i])) i++; + word = line + i; ! while (line[i] && !whitespace (line[i])) ! i++; if (line[i]) *************** *** 730,734 **** @{ fprintf (stderr, "%s: No such command for FileMan.\n", word); ! return; @} --- 1104,1108 ---- @{ fprintf (stderr, "%s: No such command for FileMan.\n", word); ! return (-1); @} *************** *** 740,744 **** /* Call the function. */ ! (*(command->func)) (word); @} --- 1114,1118 ---- /* Call the function. */ ! return ((*(command->func)) (word)); @} *************** *** 758,781 **** @} ! /* Strip whitespace from the start and end of STRING. */ stripwhite (string) char *string; @{ ! register int i = 0; ! ! while (whitespace (string[i])) ! i++; ! ! if (i) ! strcpy (string, string + i); ! i = strlen (string) - 1; ! while (i > 0 && whitespace (string[i])) ! i--; ! ! string[++i] = '\0'; @} ! @page /* **************************************************************** */ /* */ --- 1132,1157 ---- @} ! /* Strip whitespace from the start and end of STRING. Return a pointer ! into STRING. */ ! char * stripwhite (string) char *string; @{ ! register char *s, *t; ! for (s = string; whitespace (*s); s++) ! ; ! ! if (*s == 0) ! return (s); ! ! t = s + strlen (s) - 1; ! while (t > s && whitespace (*t)) ! t--; ! *++t = '\0'; ! return s; @} ! /* **************************************************************** */ /* */ *************** *** 784,787 **** --- 1160,1166 ---- /* **************************************************************** */ + char *command_generator (); + char **fileman_completion (); + /* Tell the GNU Readline library how to complete. We want to try to complete on command names if this is the first word in the line, or on filenames *************** *** 789,799 **** initialize_readline () @{ - char **fileman_completion (); - /* Allow conditional parsing of the ~/.inputrc file. */ rl_readline_name = "FileMan"; /* Tell the completer that we want a crack first. */ ! rl_attempted_completion_function = (Function *)fileman_completion; @} --- 1168,1176 ---- initialize_readline () @{ /* Allow conditional parsing of the ~/.inputrc file. */ rl_readline_name = "FileMan"; /* Tell the completer that we want a crack first. */ ! rl_attempted_completion_function = (CPPFunction *)fileman_completion; @} *************** *** 808,812 **** @{ char **matches; - char *command_generator (); matches = (char **)NULL; --- 1185,1188 ---- *************** *** 847,851 **** if (strncmp (name, text, len) == 0) ! return (name); @} --- 1223,1227 ---- if (strncmp (name, text, len) == 0) ! return (dupstr(name)); @} *************** *** 853,857 **** return ((char *)NULL); @} ! @page /* **************************************************************** */ /* */ --- 1229,1233 ---- return ((char *)NULL); @} ! /* **************************************************************** */ /* */ *************** *** 869,876 **** @{ if (!arg) ! arg = "*"; sprintf (syscom, "ls -FClg %s", arg); ! system (syscom); @} --- 1245,1252 ---- @{ if (!arg) ! arg = ""; sprintf (syscom, "ls -FClg %s", arg); ! return (system (syscom)); @} *************** *** 879,886 **** @{ if (!valid_argument ("view", arg)) ! return; ! sprintf (syscom, "cat %s | more", arg); ! system (syscom); @} --- 1255,1262 ---- @{ if (!valid_argument ("view", arg)) ! return 1; ! sprintf (syscom, "more %s", arg); ! return (system (syscom)); @} *************** *** 889,892 **** --- 1265,1269 ---- @{ too_dangerous ("rename"); + return (1); @} *************** *** 897,915 **** if (!valid_argument ("stat", arg)) ! return; if (stat (arg, &finfo) == -1) @{ perror (arg); ! return; @} printf ("Statistics for `%s':\n", arg); ! printf ("%s has %d link%s, and is %d bytes in length.\n", arg, ! finfo.st_nlink, (finfo.st_nlink == 1) ? "" : "s", finfo.st_size); ! printf (" Created on: %s", ctime (&finfo.st_ctime)); ! printf (" Last access at: %s", ctime (&finfo.st_atime)); ! printf ("Last modified at: %s", ctime (&finfo.st_mtime)); @} --- 1274,1296 ---- if (!valid_argument ("stat", arg)) ! return (1); if (stat (arg, &finfo) == -1) @{ perror (arg); ! return (1); @} printf ("Statistics for `%s':\n", arg); ! printf ("%s has %d link%s, and is %d byte%s in length.\n", arg, ! finfo.st_nlink, ! (finfo.st_nlink == 1) ? "" : "s", ! finfo.st_size, ! (finfo.st_size == 1) ? "" : "s"); ! printf ("Inode Last Change at: %s", ctime (&finfo.st_ctime)); ! printf (" Last access at: %s", ctime (&finfo.st_atime)); ! printf (" Last modified at: %s", ctime (&finfo.st_mtime)); ! return (0); @} *************** *** 918,921 **** --- 1299,1303 ---- @{ too_dangerous ("delete"); + return (1); @} *************** *** 957,960 **** --- 1339,1343 ---- printf ("\n"); @} + return (0); @} *************** *** 964,970 **** @{ if (chdir (arg) == -1) ! perror (arg); com_pwd (""); @} --- 1347,1357 ---- @{ if (chdir (arg) == -1) ! @{ ! perror (arg); ! return 1; ! @} com_pwd (""); + return (0); @} *************** *** 973,981 **** char *ignore; @{ ! char dir[1024]; ! (void) getwd (dir); printf ("Current directory is %s\n", dir); @} --- 1360,1374 ---- char *ignore; @{ ! char dir[1024], *s; ! s = getwd (dir); ! if (s == 0) ! @{ ! printf ("Error getting pwd: %s\n", dir); ! return 1; ! @} printf ("Current directory is %s\n", dir); + return 0; @} *************** *** 985,988 **** --- 1378,1382 ---- @{ done = 1; + return (0); @} diff -rc2 bash-1.14.1/lib/readline/doc/rluser.texinfo bash-1.14.2/lib/readline/doc/rluser.texinfo *** bash-1.14.1/lib/readline/doc/rluser.texinfo Fri Jul 1 11:21:13 1994 --- bash-1.14.2/lib/readline/doc/rluser.texinfo Sun Jul 31 18:34:11 1994 *************** *** 50,54 **** available for binding * Readline vi Mode:: A short description of how to make Readline ! behave line the vi editor. @end menu --- 50,54 ---- available for binding * Readline vi Mode:: A short description of how to make Readline ! behave like the vi editor. @end menu *************** *** 165,168 **** --- 165,171 ---- @subsection Readline Killing Commands + @cindex Killing text + @cindex Yanking text + @dfn{Killing} text means to delete the text from the line, but to save it away for later use, usually by @dfn{yanking} (re-inserting) *************** *** 178,181 **** --- 181,185 ---- typed line is available to be yanked back later, when you are typing another line. + @cindex Kill ring Here is the list of commands for killing text. *************** *** 237,241 **** --- 241,250 ---- of keybindings. You can customize programs that use Readline by putting commands in an @dfn{init} file in your home directory. The name of this + @ifset BashFeatures file is taken from the value of the shell variable @code{INPUTRC}. If + @end ifset + @ifclear BashFeatures + file is taken from the value of the environment variable @code{INPUTRC}. If + @end ifclear that variable is unset, the default is @file{~/.inputrc}. *************** *** 615,618 **** --- 624,632 ---- inserts the @var{n}th word from the end of the previous command. + @item yank-last-arg (M-., M-_) + Insert last argument to the previous command (the last word on the + previous line). With an + argument, behave exactly like @code{yank-nth-arg}. + @end ftable *************** *** 731,735 **** @item complete (TAB) Attempt to do completion on the text before the cursor. This is ! implementation defined. Generally, if you are typing a filename argument, you can do filename completion; if you are typing a command, you can do command completion, if you are typing in a symbol to GDB, you --- 745,749 ---- @item complete (TAB) Attempt to do completion on the text before the cursor. This is ! application-specific. Generally, if you are typing a filename argument, you can do filename completion; if you are typing a command, you can do command completion, if you are typing in a symbol to GDB, you *************** *** 819,827 **** @item insert-last-argument (M-., M-_) ! Insert the last argument to the previous command (the last word on ! the previous line). With an argument @var{n}, ! insert the @var{n}th word from the previous command (the words ! in the previous command begin with word 0). A negative argument ! inserts the @var{n}th word from the end of the previous command. @item operate-and-get-next (C-o) --- 833,837 ---- @item insert-last-argument (M-., M-_) ! A synonym for @code{yank-last-arg}. @item operate-and-get-next (C-o) diff -rc2 bash-1.14.1/lib/readline/emacs_keymap.c bash-1.14.2/lib/readline/emacs_keymap.c *** bash-1.14.1/lib/readline/emacs_keymap.c Fri Jul 1 11:21:12 1994 --- bash-1.14.2/lib/readline/emacs_keymap.c Tue Jul 26 13:07:56 1994 *************** *** 378,382 **** { ISFUNC, (Function *)0x0 }, /* Meta-, */ { ISFUNC, rl_digit_argument }, /* Meta-- */ ! { ISFUNC, (Function *)0x0 }, /* Meta-. */ { ISFUNC, (Function *)0x0 }, /* Meta-/ */ --- 378,382 ---- { ISFUNC, (Function *)0x0 }, /* Meta-, */ { ISFUNC, rl_digit_argument }, /* Meta-- */ ! { ISFUNC, rl_yank_last_arg}, /* Meta-. */ { ISFUNC, (Function *)0x0 }, /* Meta-/ */ *************** *** 431,440 **** /* Some more punctuation. */ ! { ISFUNC, rl_arrow_keys }, /* Meta-[ */ { ISFUNC, rl_delete_horizontal_space }, /* Meta-\ */ ! { ISFUNC, (Function *)0x0 }, /* Meta-] */ ! { ISFUNC, (Function *)0x0 }, /* Meta-^ */ ! { ISFUNC, (Function *)0x0 }, /* Meta-_ */ ! { ISFUNC, (Function *)0x0 }, /* Meta-` */ /* Lowercase alphabet. */ --- 431,440 ---- /* Some more punctuation. */ ! { ISFUNC, (Function *)0x0 }, /* Meta-[ */ /* was rl_arrow_keys */ { ISFUNC, rl_delete_horizontal_space }, /* Meta-\ */ ! { ISFUNC, (Function *)0x0 }, /* Meta-] */ ! { ISFUNC, (Function *)0x0 }, /* Meta-^ */ ! { ISFUNC, rl_yank_last_arg }, /* Meta-_ */ ! { ISFUNC, (Function *)0x0 }, /* Meta-` */ /* Lowercase alphabet. */ *************** *** 453,457 **** { ISFUNC, (Function *)0x0 }, /* Meta-m */ { ISFUNC, rl_noninc_forward_search }, /* Meta-n */ ! { ISFUNC, rl_arrow_keys }, /* Meta-o */ { ISFUNC, rl_noninc_reverse_search }, /* Meta-p */ { ISFUNC, (Function *)0x0 }, /* Meta-q */ --- 453,457 ---- { ISFUNC, (Function *)0x0 }, /* Meta-m */ { ISFUNC, rl_noninc_forward_search }, /* Meta-n */ ! { ISFUNC, (Function *)0x0 }, /* Meta-o */ /* was rl_arrow_keys */ { ISFUNC, rl_noninc_reverse_search }, /* Meta-p */ { ISFUNC, (Function *)0x0 }, /* Meta-q */ diff -rc2 bash-1.14.1/lib/readline/examples/Inputrc bash-1.14.2/lib/readline/examples/Inputrc *** bash-1.14.1/lib/readline/examples/Inputrc Fri Jul 1 11:21:15 1994 --- bash-1.14.2/lib/readline/examples/Inputrc Tue Jul 26 13:00:35 1994 *************** *** 20,23 **** --- 20,29 ---- "\e[D": backward-char + # alternate arrow key prefix + "\eOA": previous-history + "\eOB": next-history + "\eOC": forward-char + "\eOD": backward-char + # Under Xterm in Bash, we bind local Function keys to do something useful. $if Bash *************** *** 54,57 **** --- 60,64 ---- "\C-xg": "get \M-?" "\C-xt": "put \M-?" + "\M-.": yank-last-arg $endif diff -rc2 bash-1.14.1/lib/readline/examples/fileman.c bash-1.14.2/lib/readline/examples/fileman.c *** bash-1.14.1/lib/readline/examples/fileman.c Fri Jul 1 11:21:14 1994 --- bash-1.14.2/lib/readline/examples/fileman.c Sun Jul 31 18:39:48 1994 *************** *** 4,9 **** #include - #include - #include #include #include --- 4,7 ---- *************** *** 11,14 **** --- 9,18 ---- #include + #include + #include + + extern char *getwd (); + extern char *xmalloc (); + /* The names of functions that actually do the manipulation. */ int com_list (), com_view (), com_rename (), com_stat (), com_pwd (); *************** *** 39,47 **** }; /* The name of this program, as taken from argv[0]. */ char *progname; /* When non-zero, this global means the user is done using this program. */ ! int done = 0; char * --- 43,55 ---- }; + /* Forward declarations. */ + char *stripwhite (); + COMMAND *find_command (); + /* The name of this program, as taken from argv[0]. */ char *progname; /* When non-zero, this global means the user is done using this program. */ ! int done; char * *************** *** 51,55 **** char *r; ! r = (char *)xmalloc (strlen (s) + 1); strcpy (r, s); return (r); --- 59,63 ---- char *r; ! r = xmalloc (strlen (s) + 1); strcpy (r, s); return (r); *************** *** 60,63 **** --- 68,73 ---- char **argv; { + char *line, *s; + progname = argv[0]; *************** *** 65,94 **** /* Loop reading and executing lines until the user quits. */ ! while (!done) { - char *line; - line = readline ("FileMan: "); if (!line) ! { ! done = 1; /* Encountered EOF at top level. */ ! } ! else ! { ! /* Remove leading and trailing whitespace from the line. ! Then, if there is anything left, add it to the history list ! and execute it. */ ! stripwhite (line); ! ! if (*line) ! { ! add_history (line); ! execute_line (line); ! } ! } ! if (line) ! free (line); } exit (0); --- 75,97 ---- /* Loop reading and executing lines until the user quits. */ ! for ( ; done == 0; ) { line = readline ("FileMan: "); if (!line) ! break; ! ! /* Remove leading and trailing whitespace from the line. ! Then, if there is anything left, add it to the history list ! and execute it. */ ! s = stripwhite (line); ! ! if (*s) ! { ! add_history (s); ! execute_line (s); ! } ! free (line); } exit (0); *************** *** 96,112 **** /* Execute a command line. */ execute_line (line) char *line; { register int i; ! COMMAND *find_command (), *command; char *word; /* Isolate the command word. */ i = 0; ! while (line[i] && !whitespace (line[i])) i++; ! word = line; if (line[i]) --- 99,118 ---- /* Execute a command line. */ + int execute_line (line) char *line; { register int i; ! COMMAND *command; char *word; /* Isolate the command word. */ i = 0; ! while (line[i] && whitespace (line[i])) i++; + word = line + i; ! while (line[i] && !whitespace (line[i])) ! i++; if (line[i]) *************** *** 118,122 **** { fprintf (stderr, "%s: No such command for FileMan.\n", word); ! return; } --- 124,128 ---- { fprintf (stderr, "%s: No such command for FileMan.\n", word); ! return (-1); } *************** *** 128,132 **** /* Call the function. */ ! (*(command->func)) (word); } --- 134,138 ---- /* Call the function. */ ! return ((*(command->func)) (word)); } *************** *** 146,167 **** } ! /* Strip whitespace from the start and end of STRING. */ stripwhite (string) char *string; { ! register int i = 0; ! ! while (whitespace (string[i])) ! i++; ! ! if (i) ! strcpy (string, string + i); ! i = strlen (string) - 1; ! while (i > 0 && whitespace (string[i])) ! i--; ! ! string[++i] = '\0'; } --- 152,175 ---- } ! /* Strip whitespace from the start and end of STRING. Return a pointer ! into STRING. */ ! char * stripwhite (string) char *string; { ! register char *s, *t; ! for (s = string; whitespace (*s); s++) ! ; ! ! if (*s == 0) ! return (s); ! ! t = s + strlen (s) - 1; ! while (t > s && whitespace (*t)) ! t--; ! *++t = '\0'; ! return s; } *************** *** 172,175 **** --- 180,186 ---- /* **************************************************************** */ + char *command_generator (); + char **fileman_completion (); + /* Tell the GNU Readline library how to complete. We want to try to complete on command names if this is the first word in the line, or on filenames *************** *** 177,187 **** initialize_readline () { - char **fileman_completion (); - /* Allow conditional parsing of the ~/.inputrc file. */ rl_readline_name = "FileMan"; /* Tell the completer that we want a crack first. */ ! rl_attempted_completion_function = (Function *)fileman_completion; } --- 188,196 ---- initialize_readline () { /* Allow conditional parsing of the ~/.inputrc file. */ rl_readline_name = "FileMan"; /* Tell the completer that we want a crack first. */ ! rl_attempted_completion_function = (CPPFunction *)fileman_completion; } *************** *** 196,200 **** { char **matches; - char *command_generator (); matches = (char **)NULL; --- 205,208 ---- *************** *** 235,239 **** if (strncmp (name, text, len) == 0) ! return (dupstr(name)); } --- 243,247 ---- if (strncmp (name, text, len) == 0) ! return (dupstr(name)); } *************** *** 257,264 **** { if (!arg) ! arg = "*"; sprintf (syscom, "ls -FClg %s", arg); ! system (syscom); } --- 265,272 ---- { if (!arg) ! arg = ""; sprintf (syscom, "ls -FClg %s", arg); ! return (system (syscom)); } *************** *** 267,274 **** { if (!valid_argument ("view", arg)) ! return; ! sprintf (syscom, "cat %s | more", arg); ! system (syscom); } --- 275,282 ---- { if (!valid_argument ("view", arg)) ! return 1; ! sprintf (syscom, "more %s", arg); ! return (system (syscom)); } *************** *** 277,280 **** --- 285,289 ---- { too_dangerous ("rename"); + return (1); } *************** *** 285,303 **** if (!valid_argument ("stat", arg)) ! return; if (stat (arg, &finfo) == -1) { perror (arg); ! return; } printf ("Statistics for `%s':\n", arg); ! printf ("%s has %d link%s, and is %d bytes in length.\n", arg, ! finfo.st_nlink, (finfo.st_nlink == 1) ? "" : "s", finfo.st_size); ! printf (" Created on: %s", ctime (&finfo.st_ctime)); ! printf (" Last access at: %s", ctime (&finfo.st_atime)); ! printf ("Last modified at: %s", ctime (&finfo.st_mtime)); } --- 294,316 ---- if (!valid_argument ("stat", arg)) ! return (1); if (stat (arg, &finfo) == -1) { perror (arg); ! return (1); } printf ("Statistics for `%s':\n", arg); ! printf ("%s has %d link%s, and is %d byte%s in length.\n", arg, ! finfo.st_nlink, ! (finfo.st_nlink == 1) ? "" : "s", ! finfo.st_size, ! (finfo.st_size == 1) ? "" : "s"); ! printf ("Inode Last Change at: %s", ctime (&finfo.st_ctime)); ! printf (" Last access at: %s", ctime (&finfo.st_atime)); ! printf (" Last modified at: %s", ctime (&finfo.st_mtime)); ! return (0); } *************** *** 306,309 **** --- 319,323 ---- { too_dangerous ("delete"); + return (1); } *************** *** 319,326 **** { if (!*arg || (strcmp (arg, commands[i].name) == 0)) ! { ! printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc); ! printed++; ! } } --- 333,340 ---- { if (!*arg || (strcmp (arg, commands[i].name) == 0)) ! { ! printf ("%s\t\t%s.\n", commands[i].name, commands[i].doc); ! printed++; ! } } *************** *** 330,348 **** for (i = 0; commands[i].name; i++) ! { ! /* Print in six columns. */ ! if (printed == 6) ! { ! printed = 0; ! printf ("\n"); ! } ! ! printf ("%s\t", commands[i].name); ! printed++; ! } if (printed) ! printf ("\n"); } } --- 344,363 ---- for (i = 0; commands[i].name; i++) ! { ! /* Print in six columns. */ ! if (printed == 6) ! { ! printed = 0; ! printf ("\n"); ! } ! ! printf ("%s\t", commands[i].name); ! printed++; ! } if (printed) ! printf ("\n"); } + return (0); } *************** *** 352,358 **** { if (chdir (arg) == -1) ! perror (arg); com_pwd (""); } --- 367,377 ---- { if (chdir (arg) == -1) ! { ! perror (arg); ! return 1; ! } com_pwd (""); + return (0); } *************** *** 361,369 **** char *ignore; { ! char dir[1024]; ! (void) getwd (dir); printf ("Current directory is %s\n", dir); } --- 380,394 ---- char *ignore; { ! char dir[1024], *s; ! s = getwd (dir); ! if (s == 0) ! { ! printf ("Error getting pwd: %s\n", dir); ! return 1; ! } printf ("Current directory is %s\n", dir); + return 0; } *************** *** 373,376 **** --- 398,402 ---- { done = 1; + return (0); } *************** *** 380,385 **** { fprintf (stderr, ! "%s: Too dangerous for me to distribute. Write it yourself.\n", ! caller); } --- 406,411 ---- { fprintf (stderr, ! "%s: Too dangerous for me to distribute. Write it yourself.\n", ! caller); } *************** *** 398,406 **** return (1); } - - - /* - * Local variables: - * compile-command: "cc -g -I../.. -L.. -o fileman fileman.c -lreadline -ltermcap" - * end: - */ --- 424,425 ---- Only in bash-1.14.2/lib/readline/examples: histexamp.c diff -rc2 bash-1.14.1/lib/readline/examples/manexamp.c bash-1.14.2/lib/readline/examples/manexamp.c *** bash-1.14.1/lib/readline/examples/manexamp.c Fri Jul 1 11:21:14 1994 --- bash-1.14.2/lib/readline/examples/manexamp.c Tue Jul 26 12:51:42 1994 *************** *** 16,24 **** /* Read a string, and return a pointer to it. Returns NULL on EOF. */ char * ! do_gets () { /* If the buffer has already been allocated, return the memory to the free pool. */ ! if (line_read != (char *)NULL) { free (line_read); --- 16,24 ---- /* Read a string, and return a pointer to it. Returns NULL on EOF. */ char * ! rl_gets () { /* If the buffer has already been allocated, return the memory to the free pool. */ ! if (line_read) { free (line_read); *************** *** 36,40 **** } - /* **************************************************************** */ /* */ --- 36,39 ---- *************** *** 93,96 **** rl_point = end - direction; } - --- 92,94 ---- diff -rc2 bash-1.14.1/lib/readline/funmap.c bash-1.14.2/lib/readline/funmap.c *** bash-1.14.1/lib/readline/funmap.c Fri Jul 1 11:41:32 1994 --- bash-1.14.2/lib/readline/funmap.c Tue Jul 26 13:01:17 1994 *************** *** 41,44 **** --- 41,46 ---- #include "readline.h" + static int qsort_string_compare (); + FUNMAP **funmap = (FUNMAP **)NULL; static int funmap_size = 0; *************** *** 102,105 **** --- 104,108 ---- { "transpose-chars", rl_transpose_chars }, { "transpose-words", rl_transpose_words }, + { "tty-status", rl_tty_status }, { "undo", rl_undo_command }, { "universal-argument", rl_universal_argument }, *************** *** 108,111 **** --- 111,115 ---- { "upcase-word", rl_upcase_word }, { "yank", rl_yank }, + { "yank-last-arg", rl_yank_last_arg }, { "yank-nth-arg", rl_yank_nth_arg }, { "yank-pop", rl_yank_pop }, *************** *** 194,210 **** } - /* Stupid comparison routine for qsort () ing strings. */ - static int - qsort_string_compare (s1, s2) - register char **s1, **s2; - { - int r; - - r = **s1 - **s2; - if (r == 0) - r = strcmp (*s1, *s2); - return r; - } - /* Produce a NULL terminated array of known function names. The array is sorted. The array itself is allocated, but not the strings inside. --- 198,201 ---- *************** *** 238,241 **** --- 229,245 ---- qsort (result, result_index, sizeof (char *), qsort_string_compare); return (result); + } + + /* Stupid comparison routine for qsort () ing strings. */ + static int + qsort_string_compare (s1, s2) + register char **s1, **s2; + { + int r; + + r = **s1 - **s2; + if (r == 0) + r = strcmp (*s1, *s2); + return r; } diff -rc2 bash-1.14.1/lib/readline/history.c bash-1.14.2/lib/readline/history.c *** bash-1.14.1/lib/readline/history.c Fri Jul 1 11:21:12 1994 --- bash-1.14.2/lib/readline/history.c Wed Aug 3 10:52:57 1994 *************** *************** *** 74,79 **** #endif ! #ifndef digit ! #define digit(c) ((c) >= '0' && (c) <= '9') #endif --- 78,83 ---- #endif ! #ifndef digit_p ! #define digit_p(c) ((c) >= '0' && (c) <= '9') #endif *************** *** 119,123 **** /* Non-zero means that we have enforced a limit on the amount of history that we save. */ ! int history_stifled = 0; /* If HISTORY_STIFLED is non-zero, then this is the maximum number of --- 123,127 ---- /* Non-zero means that we have enforced a limit on the amount of history that we save. */ ! static int history_stifled = 0; /* If HISTORY_STIFLED is non-zero, then this is the maximum number of *************** *** 170,173 **** --- 174,180 ---- state->length = history_length; state->size = history_size; + state->flags = 0; + if (history_stifled) + state->flags |= HS_STIFLED; return (state); *************** *** 183,186 **** --- 190,195 ---- history_length = state->length; history_size = state->size; + if (state->flags & HS_STIFLED) + history_stifled = 1; } *************** *** 492,495 **** --- 501,510 ---- } + int + history_is_stifled () + { + return (history_stifled); + } + /* Return the string that should be used in the place of this filename. This only matters when you don't specify the *************** *** 924,931 **** } ! if (digit (string[i])) { /* Get the extent of the digits and compute the value. */ ! for (which = 0; digit (string[i]); i++) which = (which * 10) + digit_value (string[i]); --- 939,946 ---- } ! if (digit_p (string[i])) { /* Get the extent of the digits and compute the value. */ ! for (which = 0; digit_p (string[i]); i++) which = (which * 10) + digit_value (string[i]); *************** *** 1493,1497 **** n = strlen (temp); if (n > result_len) ! result = xrealloc (result, n + 1); strcpy (result, temp); free (temp); --- 1508,1512 ---- n = strlen (temp); if (n > result_len) ! result = xrealloc (result, n + 2); strcpy (result, temp); free (temp); *************** *** 1520,1525 **** int sl = strlen (s); \ j += sl; \ ! while (j >= result_len) \ ! result = xrealloc (result, result_len += 128); \ strcpy (result + j - sl, s); \ } \ --- 1535,1544 ---- int sl = strlen (s); \ j += sl; \ ! if (j >= result_len) \ ! { \ ! while (j >= result_len) \ ! result_len += 128; \ ! result = xrealloc (result, result_len); \ ! } \ strcpy (result + j - sl, s); \ } \ *************** *** 1529,1533 **** do \ { \ ! if (j >= result_len) \ result = xrealloc (result, result_len += 64); \ result[j++] = c; \ --- 1548,1552 ---- do \ { \ ! if (j >= result_len - 1) \ result = xrealloc (result, result_len += 64); \ result[j++] = c; \ *************** *** 1809,1815 **** else if (spec[i] == '^') first = 1; ! else if (digit (spec[i]) && expecting_word_spec) { ! for (first = 0; digit (spec[i]); i++) first = (first * 10) + digit_value (spec[i]); } --- 1828,1834 ---- else if (spec[i] == '^') first = 1; ! else if (digit_p (spec[i]) && expecting_word_spec) { ! for (first = 0; digit_p (spec[i]); i++) first = (first * 10) + digit_value (spec[i]); } *************** *** 1828,1834 **** i++; ! if (digit (spec[i])) { ! for (last = 0; digit (spec[i]); i++) last = (last * 10) + digit_value (spec[i]); } --- 1847,1853 ---- i++; ! if (digit_p (spec[i])) { ! for (last = 0; digit_p (spec[i]); i++) last = (last * 10) + digit_value (spec[i]); } diff -rc2 bash-1.14.1/lib/readline/history.h bash-1.14.2/lib/readline/history.h *** bash-1.14.1/lib/readline/history.h Fri Jul 1 11:21:11 1994 --- bash-1.14.2/lib/readline/history.h Sat Aug 6 22:52:46 1994 *************** *** 2,6 **** /* The structure used to store a history entry. */ ! typedef struct { char *line; char *data; --- 2,6 ---- /* The structure used to store a history entry. */ ! typedef struct _hist_entry { char *line; char *data; *************** *** 8,21 **** /* A structure used to pass the current state of the history stuff around. */ ! typedef struct _hist_entry { HIST_ENTRY **entries; /* Pointer to the entries themselves. */ int offset; /* The location pointer within this array. */ int length; /* Number of elements within this array. */ int size; /* Number of slots allocated to this array. */ } HISTORY_STATE; ! /* For convenience only. You set this when interpreting history commands. ! It is the logical offset of the first history element. */ ! extern int history_base; /* Begin a session in which the history functions might be used. This --- 8,23 ---- /* A structure used to pass the current state of the history stuff around. */ ! typedef struct _hist_state { HIST_ENTRY **entries; /* Pointer to the entries themselves. */ int offset; /* The location pointer within this array. */ int length; /* Number of elements within this array. */ int size; /* Number of slots allocated to this array. */ + int flags; } HISTORY_STATE; ! /* Flag values for the `flags' member of HISTORY_STATE. */ ! #define HS_STIFLED 0x01 ! ! /* Initialization and state management. */ /* Begin a session in which the history functions might be used. This *************** *** 29,50 **** extern void history_set_history_state (); /* Place STRING at the end of the history list. The associated data field (if any) is set to NULL. */ extern void add_history (); - /* Returns the number which says what history element we are now - looking at. */ - extern int where_history (); - - /* Set the position in the history list to POS. */ - int history_set_pos (); - - /* Search for STRING in the history list, starting at POS, an - absolute index into the list. DIR, if negative, says to search - backwards from POS, else forwards. - Returns the absolute index of the history element where STRING - was found, or -1 otherwise. */ - extern int history_search_pos (); - /* A reasonably useless function, only here for completeness. WHICH is the magic number that tells us which element to delete. The --- 31,40 ---- extern void history_set_history_state (); + /* Manage the history list. */ + /* Place STRING at the end of the history list. The associated data field (if any) is set to NULL. */ extern void add_history (); /* A reasonably useless function, only here for completeness. WHICH is the magic number that tells us which element to delete. The *************** *** 52,55 **** --- 42,50 ---- extern HIST_ENTRY *remove_history (); + /* Make the history entry at WHICH have LINE and DATA. This returns + the old entry so you can dispose of the data. In the case of an + invalid WHICH, a NULL pointer is returned. */ + extern HIST_ENTRY *replace_history_entry (); + /* Stifle the history list, remembering only MAX number of entries. */ extern void stifle_history (); *************** *** 60,93 **** extern int unstifle_history (); ! /* Add the contents of FILENAME to the history list, a line at a time. ! If FILENAME is NULL, then read from ~/.history. Returns 0 if ! successful, or errno if not. */ ! extern int read_history (); ! /* Read a range of lines from FILENAME, adding them to the history list. ! Start reading at the FROM'th line and end at the TO'th. If FROM ! is zero, start at the beginning. If TO is less than FROM, read ! until the end of the file. If FILENAME is NULL, then read from ! ~/.history. Returns 0 if successful, or errno if not. */ ! extern int read_history_range (); ! /* Append the current history to FILENAME. If FILENAME is NULL, ! then append the history list to ~/.history. Values returned ! are as in read_history (). */ ! extern int write_history (); ! ! /* Append NELEMENT entries to FILENAME. The entries appended are from ! the end of the list minus NELEMENTs up to the end of the list. */ ! int append_history (); ! ! /* Make the history entry at WHICH have LINE and DATA. This returns ! the old entry so you can dispose of the data. In the case of an ! invalid WHICH, a NULL pointer is returned. */ ! extern HIST_ENTRY *replace_history_entry (); /* Return the history entry at the current position, as determined by history_offset. If there is no entry there, return a NULL pointer. */ HIST_ENTRY *current_history (); /* Back up history_offset to the previous history entry, and return a pointer to that entry. If there is no previous entry, return --- 55,89 ---- extern int unstifle_history (); ! /* Return 1 if the history is stifled, 0 if it is not. */ ! extern int history_is_stifled (); ! /* Information about the history list. */ ! /* Return a NULL terminated array of HIST_ENTRY which is the current input ! history. Element 0 of this list is the beginning of time. If there ! is no history, return NULL. */ ! extern HIST_ENTRY **history_list (); + /* Returns the number which says what history element we are now + looking at. */ + extern int where_history (); + /* Return the history entry at the current position, as determined by history_offset. If there is no entry there, return a NULL pointer. */ HIST_ENTRY *current_history (); + /* Return the history entry which is logically at OFFSET in the history + array. OFFSET is relative to history_base. */ + extern HIST_ENTRY *history_get (); + + /* Return the number of bytes that the primary history entries are using. + This just adds up the lengths of the_history->lines. */ + extern int history_total_bytes (); + + /* Moving around the history list. */ + + /* Set the position in the history list to POS. */ + int history_set_pos (); + /* Back up history_offset to the previous history entry, and return a pointer to that entry. If there is no previous entry, return *************** *** 100,111 **** extern HIST_ENTRY *next_history (); ! /* Return a NULL terminated array of HIST_ENTRY which is the current input ! history. Element 0 of this list is the beginning of time. If there ! is no history, return NULL. */ ! extern HIST_ENTRY **history_list (); ! ! /* Return the history entry which is logically at OFFSET in the history ! array. OFFSET is relative to history_base. */ ! extern HIST_ENTRY *history_get (); /* Search the history for STRING, starting at history_offset. --- 96,100 ---- extern HIST_ENTRY *next_history (); ! /* Searching the history list. */ /* Search the history for STRING, starting at history_offset. *************** *** 117,120 **** --- 106,148 ---- extern int history_search (); + /* Search the history for STRING, starting at history_offset. + The search is anchored: matching lines must begin with string. */ + extern int history_search_prefix (); + + /* Search for STRING in the history list, starting at POS, an + absolute index into the list. DIR, if negative, says to search + backwards from POS, else forwards. + Returns the absolute index of the history element where STRING + was found, or -1 otherwise. */ + extern int history_search_pos (); + + /* Managing the history file. */ + + /* Add the contents of FILENAME to the history list, a line at a time. + If FILENAME is NULL, then read from ~/.history. Returns 0 if + successful, or errno if not. */ + extern int read_history (); + + /* Read a range of lines from FILENAME, adding them to the history list. + Start reading at the FROM'th line and end at the TO'th. If FROM + is zero, start at the beginning. If TO is less than FROM, read + until the end of the file. If FILENAME is NULL, then read from + ~/.history. Returns 0 if successful, or errno if not. */ + extern int read_history_range (); + + /* Write the current history to FILENAME. If FILENAME is NULL, + then write the history list to ~/.history. Values returned + are as in read_history (). */ + extern int write_history (); + + /* Append NELEMENT entries to FILENAME. The entries appended are from + the end of the list minus NELEMENTs up to the end of the list. */ + int append_history (); + + /* Truncate the history file, leaving only the last NLINES lines. */ + extern int history_truncate_file (); + + /* History expansion. */ + /* Expand the string STRING, placing the result into OUTPUT, a pointer to a string. Returns: *************** *** 125,128 **** --- 153,157 ---- 1) If expansions did take place -1) If there was an error in expansion. + 2) If the returned line should just be printed. If an error ocurred in expansion, then OUTPUT contains a descriptive *************** *** 130,137 **** extern int history_expand (); - /* Return an array of tokens, much as the shell might. The tokens are - parsed out of STRING. */ - extern char **history_tokenize (); - /* Extract a string segment consisting of the FIRST through LAST arguments present in STRING. Arguments are broken up as in --- 159,162 ---- *************** *** 139,148 **** extern char *history_arg_extract (); ! /* Return the number of bytes that the primary history entries are using. ! This just adds up the lengths of the_history->lines. */ ! extern int history_total_bytes (); /* Exported history variables. */ ! extern int history_stifled; extern int history_length; extern int max_input_history; --- 164,177 ---- extern char *history_arg_extract (); ! /* Return the text of the history event beginning at the current ! offset into STRING. */ ! extern char *get_history_event (); ! ! /* Return an array of tokens, much as the shell might. The tokens are ! parsed out of STRING. */ ! extern char **history_tokenize (); /* Exported history variables. */ ! extern int history_base; extern int history_length; extern int max_input_history; *************** *** 151,153 **** extern char history_comment_char; extern char *history_no_expand_chars; - extern int history_base; --- 180,181 ---- diff -rc2 bash-1.14.1/lib/readline/isearch.c bash-1.14.2/lib/readline/isearch.c *** bash-1.14.1/lib/readline/isearch.c Fri Jul 1 11:21:15 1994 --- bash-1.14.2/lib/readline/isearch.c Sat Jul 2 20:13:47 1994 *************** *** 250,254 **** default: ! if (CTRL_P (c) || META_CHAR (c) || c == RUBOUT) { rl_execute_next (c); --- 250,254 ---- default: ! if (CTRL_CHAR (c) || META_CHAR (c) || c == RUBOUT) { rl_execute_next (c); diff -rc2 bash-1.14.1/lib/readline/readline.c bash-1.14.2/lib/readline/readline.c *** bash-1.14.1/lib/readline/readline.c Fri Jul 1 11:43:00 1994 --- bash-1.14.2/lib/readline/readline.c Fri Aug 12 13:47:46 1994 *************** *** 54,60 **** #include "rldefs.h" ! #if defined (WINSIZE_IN_IOCTL_H) # include ! #endif /* WINSIZE_IN_IOCTL_H */ /* Some standard library routines. */ --- 54,60 ---- #include "rldefs.h" ! #if defined (GWINSZ_IN_SYS_IOCTL) || (defined (VSTATUS) && !defined (SunOS4)) # include ! #endif /* GWINSZ_IN_SYS_IOCTL || VSTATUS */ /* Some standard library routines. */ *************** *** 75,78 **** --- 75,79 ---- /* External redisplay functions and variables from display.c */ extern void _rl_move_vert (); + extern void _rl_update_final (); extern void _rl_erase_at_end_of_line (); *************** *** 81,84 **** --- 82,86 ---- extern int _rl_vis_botlin; extern int _rl_last_c_pos; + extern int _rl_horizontal_scroll_mode; extern int rl_display_fixed; extern char *rl_display_prompt; *************** *** 107,110 **** --- 109,113 ---- static int init_terminal_io (); static void start_using_history (); + static void bind_arrow_keys (); #if !defined (__GO32__) *************** *** 225,228 **** --- 228,235 ---- #define DEFAULT_BUFFER_SIZE 256 + /* Forward declarations used by the display and termcap code. */ + int term_xn; + int screenwidth, screenheight, screenchars; + /* **************************************************************** */ *************** *** 915,918 **** --- 922,927 ---- rl_initialize () { + char *t; + /* If we have never been called before, initialize the terminal and data structures. */ *************** *** 931,934 **** --- 940,953 ---- rl_done = 0; + /* Check for LC_CTYPE and use its value to decide the defaults for + 8-bit character input and output. */ + t = getenv ("LC_CTYPE"); + if (t && (strcmp (t, "iso-8859-1") == 0 || strcmp (t, "iso_8859_1") == 0)) + { + _rl_meta_flag = 1; + _rl_convert_meta_chars_to_ascii = 0; + _rl_output_meta_chars = 1; + } + /* Tell the history routines what is going on. */ start_using_history (); *************** *** 983,990 **** --- 1002,1019 ---- rl_read_init_file ((char *)NULL); + /* XXX */ + if (_rl_horizontal_scroll_mode && term_xn) + { + screenwidth--; + screenchars -= screenheight; + } + /* Override the effect of any `set keymap' assignments in the inputrc file. */ rl_set_keymap_from_edit_mode (); + /* Try to bind a common arrow key prefix, if not already bound. */ + bind_arrow_keys (); + /* If the completion parser's default word break characters haven't been set yet, then do so now. */ *************** *** 1002,1005 **** --- 1031,1079 ---- } + static void + bind_arrow_keys_internal () + { + Function *f; + + f = rl_function_of_keyseq ("\033[A", _rl_keymap, (int *)NULL); + if (!f || f == rl_do_lowercase_version) + { + _rl_bind_if_unbound ("\033[A", rl_get_previous_history); + _rl_bind_if_unbound ("\033[B", rl_get_next_history); + _rl_bind_if_unbound ("\033[C", rl_forward); + _rl_bind_if_unbound ("\033[D", rl_backward); + } + + f = rl_function_of_keyseq ("\033OA", _rl_keymap, (int *)NULL); + if (!f || f == rl_do_lowercase_version) + { + _rl_bind_if_unbound ("\033OA", rl_get_previous_history); + _rl_bind_if_unbound ("\033OB", rl_get_next_history); + _rl_bind_if_unbound ("\033OC", rl_forward); + _rl_bind_if_unbound ("\033OD", rl_backward); + } + } + + /* Try and bind the common arrow key prefix after giving termcap and + the inputrc file a chance to bind them and create `real' keymaps + for the arrow key prefix. */ + static void + bind_arrow_keys () + { + Keymap xkeymap; + + xkeymap = _rl_keymap; + + _rl_keymap = emacs_standard_keymap; + bind_arrow_keys_internal (); + + #if defined (VI_MODE) + _rl_keymap = vi_movement_keymap; + bind_arrow_keys_internal (); + #endif + + _rl_keymap = xkeymap; + } + /* **************************************************************** */ *************** *** 1027,1031 **** } c = UNMETA (c); ! if (numeric (c)) { if (rl_explicit_arg) --- 1101,1105 ---- } c = UNMETA (c); ! if (digit_p (c)) { if (rl_explicit_arg) *************** *** 1104,1109 **** #if !defined (__linux__) ! char PC; ! char *BC, *UP; #endif /* __linux__ */ --- 1178,1183 ---- #if !defined (__linux__) ! /* If this causes problems, add back the `extern'. */ ! /*extern*/ char PC, *BC, *UP; #endif /* __linux__ */ *************** *** 1112,1117 **** char *term_pc; - int screenwidth, screenheight, screenchars; - /* Non-zero if we determine that the terminal can do character insertion. */ int terminal_can_insert = 0; --- 1186,1189 ---- *************** *** 1216,1220 **** #endif ! screenwidth--; screenchars = screenwidth * screenheight; --- 1288,1293 ---- #endif ! if (!term_xn) ! screenwidth--; screenchars = screenwidth * screenheight; *************** *** 1293,1297 **** term_forward_char = (char *)NULL; #endif /* HACK_TERMCAP_MOTION */ ! terminal_can_insert = 0; return; #else /* !__GO32__ */ --- 1366,1370 ---- term_forward_char = (char *)NULL; #endif /* HACK_TERMCAP_MOTION */ ! terminal_can_insert = term_xn = 0; return; #else /* !__GO32__ */ *************** *** 1351,1354 **** --- 1424,1429 ---- screenwidth = screenheight = 0; + term_xn = tgetflag ("am") && tgetflag ("xn"); + _rl_set_screen_size (tty, 0); *************** *** 1452,1455 **** --- 1527,1542 ---- } + rl_tty_status (count, key) + int count, key; + { + #if defined (TIOCSTAT) + ioctl (1, TIOCSTAT, (char *)0); + rl_refresh_line (); + #else + ding (); + #endif + return 0; + } + /* **************************************************************** */ *************** *** 1469,1473 **** int c; { ! if (pure_alphabetic (c) || (numeric (c))) return (1); --- 1556,1560 ---- int c; { ! if (pure_alphabetic (c) || (digit_p (c))) return (1); *************** *** 1478,1489 **** } - /* Return non-zero if C is a numeric character. */ - int - numeric (c) - int c; - { - return (c >= '0' && c <= '9'); - } - /* Ring the terminal bell. */ int --- 1565,1568 ---- *************** *** 1520,1524 **** /* How to abort things. */ ! rl_abort () { ding (); --- 1599,1604 ---- /* How to abort things. */ ! rl_abort (count, key) ! int count, key; { ding (); *************** *** 1684,1689 **** /* Move forward COUNT characters. */ ! rl_forward (count) ! int count; { if (count < 0) --- 1764,1769 ---- /* Move forward COUNT characters. */ ! rl_forward (count, key) ! int count, key; { if (count < 0) *************** *** 1710,1715 **** /* Move backward COUNT characters. */ ! rl_backward (count) ! int count; { if (count < 0) --- 1790,1795 ---- /* Move backward COUNT characters. */ ! rl_backward (count, key) ! int count, key; { if (count < 0) *************** *** 1729,1733 **** /* Move to the beginning of the line. */ ! rl_beg_of_line () { rl_point = 0; --- 1809,1814 ---- /* Move to the beginning of the line. */ ! rl_beg_of_line (count, key) ! int count, key; { rl_point = 0; *************** *** 1736,1740 **** /* Move to the end of the line. */ ! rl_end_of_line () { rl_point = rl_end; --- 1817,1822 ---- /* Move to the end of the line. */ ! rl_end_of_line (count, key) ! int count, key; { rl_point = rl_end; *************** *** 1743,1748 **** /* Move forward a word. We do what Emacs does. */ ! rl_forward_word (count) ! int count; { int c; --- 1825,1830 ---- /* Move forward a word. We do what Emacs does. */ ! rl_forward_word (count, key) ! int count, key; { int c; *************** *** 1785,1790 **** /* Move backward a word. We do what Emacs does. */ ! rl_backward_word (count) ! int count; { int c; --- 1867,1872 ---- /* Move backward a word. We do what Emacs does. */ ! rl_backward_word (count, key) ! int count, key; { int c; *************** *** 1871,1875 **** the prompt and the current input line. Given a numeric arg, redraw only the current line. */ ! rl_clear_screen () { if (rl_explicit_arg) --- 1953,1958 ---- the prompt and the current input line. Given a numeric arg, redraw only the current line. */ ! rl_clear_screen (count, key) ! int count, key; { if (rl_explicit_arg) *************** *** 2012,2028 **** /* Insert the next typed character verbatim. */ ! rl_quoted_insert (count) ! int count; { int c; c = rl_read_key (); ! return (rl_insert (count, c)); ! } /* Insert a tab character. */ ! rl_tab_insert (count) ! int count; { return (rl_insert (count, '\t')); --- 2095,2110 ---- /* Insert the next typed character verbatim. */ ! rl_quoted_insert (count, key) ! int count, key; { int c; c = rl_read_key (); ! return (rl_insert (count, c)); } /* Insert a tab character. */ ! rl_tab_insert (count, key) ! int count, key; { return (rl_insert (count, '\t')); *************** *** 2044,2054 **** if (readline_echoing_p) ! { ! _rl_move_vert (_rl_vis_botlin); ! _rl_vis_botlin = 0; ! crlf (); ! fflush (out_stream); ! rl_display_fixed++; ! } return 0; } --- 2126,2130 ---- if (readline_echoing_p) ! _rl_update_final (); return 0; } *************** *** 2077,2082 **** /* Rubout the character behind point. */ ! rl_rubout (count) ! int count; { if (count < 0) --- 2153,2158 ---- /* Rubout the character behind point. */ ! rl_rubout (count, key) ! int count, key; { if (count < 0) *************** *** 2177,2181 **** /* This does what C-w does in Unix. We can't prevent people from using behaviour that they expect. */ ! rl_unix_word_rubout () { if (!rl_point) --- 2253,2258 ---- /* This does what C-w does in Unix. We can't prevent people from using behaviour that they expect. */ ! rl_unix_word_rubout (count, key) ! int count, key; { if (!rl_point) *************** *** 2202,2206 **** into the line at all, and if you aren't, then you know what you are doing. */ ! rl_unix_line_discard () { if (!rl_point) --- 2279,2284 ---- into the line at all, and if you aren't, then you know what you are doing. */ ! rl_unix_line_discard (count, key) ! int count, key; { if (!rl_point) *************** *** 2237,2242 **** /* Uppercase the word at point. */ ! rl_upcase_word (count) ! int count; { return (rl_change_case (count, UpCase)); --- 2315,2320 ---- /* Uppercase the word at point. */ ! rl_upcase_word (count, key) ! int count, key; { return (rl_change_case (count, UpCase)); *************** *** 2244,2249 **** /* Lowercase the word at point. */ ! rl_downcase_word (count) ! int count; { return (rl_change_case (count, DownCase)); --- 2322,2327 ---- /* Lowercase the word at point. */ ! rl_downcase_word (count, key) ! int count, key; { return (rl_change_case (count, DownCase)); *************** *** 2251,2256 **** /* Upcase the first letter, downcase the rest. */ ! rl_capitalize_word (count) ! int count; { return (rl_change_case (count, CapCase)); --- 2329,2334 ---- /* Upcase the first letter, downcase the rest. */ ! rl_capitalize_word (count, key) ! int count, key; { return (rl_change_case (count, CapCase)); *************** *** 2324,2329 **** /* Transpose the words at point. */ ! rl_transpose_words (count) ! int count; { char *word1, *word2; --- 2402,2407 ---- /* Transpose the words at point. */ ! rl_transpose_words (count, key) ! int count, key; { char *word1, *word2; *************** *** 2384,2389 **** /* Transpose the characters at point. If point is at the end of the line, then transpose the characters before point. */ ! rl_transpose_chars (count) ! int count; { char dummy[2]; --- 2462,2467 ---- /* Transpose the characters at point. If point is at the end of the line, then transpose the characters before point. */ ! rl_transpose_chars (count, key) ! int count, key; { char dummy[2]; *************** *** 2523,2526 **** --- 2601,2605 ---- /* Begin a group. Subsequent undos are undone as an atomic operation. */ + int rl_begin_undo_group () { *************** *** 2530,2533 **** --- 2609,2613 ---- /* End an undo group started with rl_begin_undo_group (). */ + int rl_end_undo_group () { *************** *** 2559,2563 **** /* Revert the current line to its previous state. */ ! rl_revert_line () { if (!rl_undo_list) --- 2639,2645 ---- /* Revert the current line to its previous state. */ ! int ! rl_revert_line (count, key) ! int count, key; { if (!rl_undo_list) *************** *** 2572,2577 **** /* Do some undoing of things that were done. */ ! rl_undo_command (count) ! int count; { if (count < 0) --- 2654,2660 ---- /* Do some undoing of things that were done. */ ! int ! rl_undo_command (count, key) ! int count, key; { if (count < 0) *************** *** 2685,2689 **** /* Meta-< goes to the start of the history. */ ! rl_beginning_of_history () { return (rl_get_previous_history (1 + where_history ())); --- 2768,2773 ---- /* Meta-< goes to the start of the history. */ ! rl_beginning_of_history (count, key) ! int count, key; { return (rl_get_previous_history (1 + where_history ())); *************** *** 2691,2695 **** /* Meta-> goes to the end of the history. (The current line). */ ! rl_end_of_history () { maybe_replace_line (); --- 2775,2780 ---- /* Meta-> goes to the end of the history. (The current line). */ ! rl_end_of_history (count, key) ! int count, key; { maybe_replace_line (); *************** *** 2700,2705 **** /* Move down to the next history line. */ ! rl_get_next_history (count) ! int count; { HIST_ENTRY *temp = (HIST_ENTRY *)NULL; --- 2785,2790 ---- /* Move down to the next history line. */ ! rl_get_next_history (count, key) ! int count, key; { HIST_ENTRY *temp = (HIST_ENTRY *)NULL; *************** *** 2745,2750 **** /* Get the previous item out of our interactive history, making it the current line. If there is no previous history, just ding. */ ! rl_get_previous_history (count) ! int count; { HIST_ENTRY *old_temp = (HIST_ENTRY *)NULL; --- 2830,2835 ---- /* Get the previous item out of our interactive history, making it the current line. If there is no previous history, just ding. */ ! rl_get_previous_history (count, key) ! int count, key; { HIST_ENTRY *old_temp = (HIST_ENTRY *)NULL; *************** *** 2827,2831 **** /* Exchange the position of mark and point. */ ! rl_exchange_mark_and_point () { if (rl_mark > rl_end) --- 2912,2917 ---- /* Exchange the position of mark and point. */ ! rl_exchange_mark_and_point (count, key) ! int count, key; { if (rl_mark > rl_end) *************** *** 2974,2979 **** /* Delete the word at point, saving the text in the kill ring. */ ! rl_kill_word (count) ! int count; { int orig_point = rl_point; --- 3060,3065 ---- /* Delete the word at point, saving the text in the kill ring. */ ! rl_kill_word (count, key) ! int count, key; { int orig_point = rl_point; *************** *** 3013,3018 **** /* Kill from here to the end of the line. If DIRECTION is negative, kill back to the line start instead. */ ! rl_kill_line (direction) ! int direction; { int orig_point = rl_point; --- 3099,3104 ---- /* Kill from here to the end of the line. If DIRECTION is negative, kill back to the line start instead. */ ! rl_kill_line (direction, ignore) ! int direction, ignore; { int orig_point = rl_point; *************** *** 3032,3037 **** /* Kill backwards to the start of the line. If DIRECTION is negative, kill forwards to the line end instead. */ ! rl_backward_kill_line (direction) ! int direction; { int orig_point = rl_point; --- 3118,3123 ---- /* Kill backwards to the start of the line. If DIRECTION is negative, kill forwards to the line end instead. */ ! rl_backward_kill_line (direction, ignore) ! int direction, ignore; { int orig_point = rl_point; *************** *** 3155,3158 **** --- 3241,3257 ---- } + /* Yank the last argument from the previous history line. This `knows' + how rl_yank_nth_arg treats a count of `$'. With an argument, this + behaves the same as rl_yank_nth_arg. */ + int + rl_yank_last_arg (count, key) + int count, key; + { + if (rl_explicit_arg) + return (rl_yank_nth_arg (count, key)); + else + return (rl_yank_nth_arg ('$', key)); + } + /* How to toggle back and forth between editing modes. */ rl_vi_editing_mode (count, key) *************** *** 3254,3263 **** /* Backwards compatibilty, now that savestring has been removed from all `public' readline header files. */ savestring (s) char *s; { ! return ((char *)strcpy (xmalloc (1 + (int)strlen (x)), (x))); } #endif #if defined (STATIC_MALLOC) --- 3353,3420 ---- /* Backwards compatibilty, now that savestring has been removed from all `public' readline header files. */ + char * savestring (s) char *s; { ! return ((char *)strcpy (xmalloc (1 + (int)strlen (s)), (s))); } #endif + + /* Function equivalents for the macros defined in chartypes.h. */ + #undef uppercase_p + int + uppercase_p (c) + int c; + { + return (isupper (c)); + } + + #undef lowercase_p + int + lowercase_p (c) + int c; + { + return (islower (c)); + } + + #undef pure_alphabetic + int + pure_alphabetic (c) + int c; + { + return (isupper (c) || islower (c)); + } + + #undef digit_p + int + digit_p (c) + int c; + { + return (isdigit (c)); + } + + #undef to_lower + int + to_lower (c) + int c; + { + return (isupper (c) ? tolower (c) : c); + } + + #undef to_upper + int + to_upper (c) + int c; + { + return (islower (c) ? toupper (c) : c); + } + + #undef digit_value + int + digit_value (c) + int c; + { + return (isdigit (c) ? c - '0' : c); + } #if defined (STATIC_MALLOC) diff -rc2 bash-1.14.1/lib/readline/readline.h bash-1.14.2/lib/readline/readline.h *** bash-1.14.1/lib/readline/readline.h Fri Jul 1 11:21:10 1994 --- bash-1.14.2/lib/readline/readline.h Tue Jul 26 15:35:40 1994 *************** *** 52,56 **** rl_restart_output (), rl_re_read_init_file (), rl_dump_functions (), rl_delete_horizontal_space (), rl_history_search_forward (), ! rl_history_search_backward (), rl_tty_status (); /* `Public' utility functions. */ --- 52,56 ---- rl_restart_output (), rl_re_read_init_file (), rl_dump_functions (), rl_delete_horizontal_space (), rl_history_search_forward (), ! rl_history_search_backward (), rl_tty_status (), rl_yank_last_arg (); /* `Public' utility functions. */ *************** *** 215,218 **** --- 215,230 ---- extern int rl_show_star; + /* Non-zero means that the results of the matches are to be treated + as filenames. This is ALWAYS zero on entry, and can only be changed + within a completion entry finder function. */ + extern int rl_filename_completion_desired; + + /* Non-zero means that the results of the matches are to be quoted using + double quotes (or an application-specific quoting mechanism) if the + filename contains any characters in rl_word_break_chars. This is + ALWAYS non-zero on entry, and can only be changed within a completion + entry finder function. */ + extern int rl_filename_quoting_desired; + /* Non-zero means to suppress normal filename completion after the user-specified completion function has been called. */ *************** *** 270,273 **** --- 282,289 ---- #define RL_PROMPT_START_IGNORE '\001' #define RL_PROMPT_END_IGNORE '\002' + + #if !defined (savestring) + extern char *savestring (); /* XXX backwards compatibility */ + #endif #endif /* _READLINE_H_ */ diff -rc2 bash-1.14.1/lib/readline/rldefs.h bash-1.14.2/lib/readline/rldefs.h *** bash-1.14.1/lib/readline/rldefs.h Fri Jul 1 11:21:15 1994 --- bash-1.14.2/lib/readline/rldefs.h Tue Jul 19 12:10:48 1994 *************** *** 27,30 **** --- 27,34 ---- #define _RLDEFS_H + #if defined (HAVE_CONFIG_H) + # include "config.h" + #endif + #if !defined (PRAGMA_ALLOCA) # include "memalloc.h" *************** *** 35,41 **** /* #define USE_XON_XOFF */ ! #if defined (__linux__) # include ! #endif /* __linux__ */ /* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */ --- 39,45 ---- /* #define USE_XON_XOFF */ ! #if defined (__linux__) || defined (HAVE_TERMCAP_H) # include ! #endif /* __linux__ || HAVE_TERMCAP_H */ /* Some USG machines have BSD signal handling (sigblock, sigsetmask, etc.) */ *************** *** 46,50 **** /* System V machines use termio. */ #if !defined (_POSIX_VERSION) ! # if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || defined (DGUX) # undef NEW_TTY_DRIVER # define TERMIO_TTY_DRIVER --- 50,55 ---- /* System V machines use termio. */ #if !defined (_POSIX_VERSION) ! # if defined (USG) || defined (hpux) || defined (Xenix) || defined (sgi) || \ ! defined (DGUX) || defined (HAVE_TERMIO_H) # undef NEW_TTY_DRIVER # define TERMIO_TTY_DRIVER *************** *** 53,57 **** # define TCOON 1 # endif ! # endif /* USG || hpux || Xenix || sgi || DUGX */ #endif /* !_POSIX_VERSION */ --- 58,62 ---- # define TCOON 1 # endif ! # endif /* USG || hpux || Xenix || sgi || DUGX || HAVE_TERMIO_H */ #endif /* !_POSIX_VERSION */ *************** *** 165,169 **** defined (__BSD_4_4__) || defined (FreeBSD) || defined (_386BSD) || \ defined (AIX) ! # define WINSIZE_IN_IOCTL_H #endif --- 170,174 ---- defined (__BSD_4_4__) || defined (FreeBSD) || defined (_386BSD) || \ defined (AIX) ! # define GWINSZ_IN_SYS_IOCTL #endif diff -rc2 bash-1.14.1/lib/readline/rltty.c bash-1.14.2/lib/readline/rltty.c *** bash-1.14.1/lib/readline/rltty.c Fri Jul 1 11:21:16 1994 --- bash-1.14.2/lib/readline/rltty.c Mon Aug 15 08:19:12 1994 *************** *** 365,368 **** --- 365,374 ---- static TIOTYPE otio; + #if defined (FLUSHO) + # define OUTPUT_BEING_FLUSHED(tp) (tp->c_lflag & FLUSHO) + #else + # define OUTPUT_BEING_FLUSHED(tp) 0 + #endif + static int get_tty_settings (tty, tiop) *************** *** 377,382 **** #endif ! while (GETATTR (tty, tiop) < 0) { if (errno != EINTR) return -1; --- 383,392 ---- #endif ! /* Keep looping if output is being flushed after a ^O (or whatever ! the flush character is). */ ! while (GETATTR (tty, tiop) < 0 || OUTPUT_BEING_FLUSHED (tiop)) { + if (OUTPUT_BEING_FLUSHED (tiop)) + continue; if (errno != EINTR) return -1; *************** *** 456,459 **** --- 466,477 ---- tiop->c_cc[VTIME] = 0; + #if defined (FLUSHO) + if (OUTPUT_BEING_FLUSHED (tiop)) + { + tiop->c_lflag &= ~FLUSHO; + otio.c_lflag &= ~FLUSHO; + } + #endif + /* Turn off characters that we need on Posix systems with job control, just to be sure. This includes ^Y and ^V. This should not really *************** *** 506,509 **** --- 524,528 ---- control_meta_key (1); control_keypad (1); + fflush (rl_outstream); terminal_prepped = 1; *************** *** 525,528 **** --- 544,551 ---- block_sigint (); + control_meta_key (0); + control_keypad (0); + fflush (rl_outstream); + if (set_tty_settings (tty, &otio) < 0) { *************** *** 531,536 **** } - control_meta_key (0); - control_keypad (0); terminal_prepped = 0; --- 554,557 ---- diff -rc2 bash-1.14.1/lib/readline/signals.c bash-1.14.2/lib/readline/signals.c *** bash-1.14.1/lib/readline/signals.c Fri Jul 1 11:21:17 1994 --- bash-1.14.2/lib/readline/signals.c Thu Aug 11 14:55:12 1994 *************** *** 51,57 **** #include "rldefs.h" ! #if defined (WINSIZE_IN_IOCTL_H) # include ! #endif /* WINSIZE_IN_IOCTL_H */ /* Some standard library routines. */ --- 51,57 ---- #include "rldefs.h" ! #if defined (GWINSZ_IN_SYS_IOCTL) # include ! #endif /* GWINSZ_IN_SYS_IOCTL */ /* Some standard library routines. */ *************** *** 59,72 **** #include "history.h" - static void cr (); - extern int readline_echoing_p; extern int rl_pending_input; - extern char *term_cr; - extern int _rl_meta_flag; - extern int _rl_output_character_function (); - extern void free_undo_list (); --- 59,66 ---- *************** *** 108,114 **** { _rl_set_screen_size (fileno (rl_instream), 1); ! ! cr (); /* was crlf () */ ! rl_forced_update_display (); } --- 102,106 ---- { _rl_set_screen_size (fileno (rl_instream), 1); ! _rl_redisplay_after_sigwinch (); } *************** *** 277,286 **** #if defined (SIGTSTP) ! signal (SIGTSTP, old_tstp); #endif #if defined (SIGTTOU) ! signal (SIGTTOU, old_ttou); ! signal (SIGTTIN, old_ttin); #endif /* SIGTTOU */ --- 269,278 ---- #if defined (SIGTSTP) ! rl_set_sighandler (SIGTSTP, old_tstp); #endif #if defined (SIGTTOU) ! rl_set_sighandler (SIGTTOU, old_ttou); ! rl_set_sighandler (SIGTTIN, old_ttin); #endif /* SIGTTOU */ *************** *** 288,303 **** #if defined (SIGWINCH) ! signal (SIGWINCH, old_sigwinch); #endif return 0; - } - - /* Move to the start of the current line. */ - static void - cr () - { - if (term_cr) - tputs (term_cr, 1, _rl_output_character_function); } #endif /* HANDLE_SIGNALS */ --- 280,287 ---- #if defined (SIGWINCH) ! rl_set_sighandler (SIGWINCH, old_sigwinch); #endif return 0; } #endif /* HANDLE_SIGNALS */ diff -rc2 bash-1.14.1/lib/readline/vi_mode.c bash-1.14.2/lib/readline/vi_mode.c *** bash-1.14.1/lib/readline/vi_mode.c Fri Jul 1 11:21:11 1994 --- bash-1.14.2/lib/readline/vi_mode.c Wed Aug 3 11:20:32 1994 *************** *** 51,60 **** #include "history.h" ! #ifndef digit ! #define digit(c) ((c) >= '0' && (c) <= '9') ! #endif ! ! #ifndef isletter ! #define isletter(c) (((c) >= 'A' && (c) <= 'Z') || ((c) >= 'a' && (c) <= 'z')) #endif --- 51,56 ---- #include "history.h" ! #ifndef digit_p ! #define digit_p(c) ((c) >= '0' && (c) <= '9') #endif *************** *** 64,76 **** #ifndef member ! #define member(c, s) ((c) ? (char *)strchr ((s), (c)) : 0) #endif #ifndef isident ! #define isident(c) ((isletter(c) || digit(c) || c == '_')) #endif #ifndef exchange ! #define exchange(x, y) {int temp = x; x = y; y = temp;} #endif --- 60,72 ---- #ifndef member ! #define member(c, s) ((c) ? (char *)strchr ((s), (c)) != (char *)NULL : 0) #endif #ifndef isident ! #define isident(c) ((pure_alphabetic (c) || digit_p (c) || c == '_')) #endif #ifndef exchange ! #define exchange(x, y) do {int temp = x; x = y; y = temp;} while (0) #endif *************** *** 158,162 **** int c; { ! return (member (c, vi_textmod) != (char *)NULL); } --- 154,158 ---- int c; { ! return (member (c, vi_textmod)); } *************** *** 181,186 **** /* Yank the nth arg from the previous line into this line at point. */ ! rl_vi_yank_arg (count) ! int count; { /* Readline thinks that the first word on a line is the 0th, while vi --- 177,182 ---- /* Yank the nth arg from the previous line into this line at point. */ ! rl_vi_yank_arg (count, key) ! int count, key; { /* Readline thinks that the first word on a line is the 0th, while vi *************** *** 509,513 **** } ! rl_vi_insert_beg () { rl_beg_of_line (); --- 505,510 ---- } ! rl_vi_insert_beg (count, key) ! int count, key; { rl_beg_of_line (); *************** *** 516,520 **** } ! rl_vi_append_mode () { if (rl_point < rl_end) --- 513,518 ---- } ! rl_vi_append_mode (count, key) ! int count, key; { if (rl_point < rl_end) *************** *** 524,528 **** } ! rl_vi_append_eol () { rl_end_of_line (); --- 522,527 ---- } ! rl_vi_append_eol (count, key) ! int count, key; { rl_end_of_line (); *************** *** 542,546 **** /* Switching from one mode to the other really just involves switching keymaps. */ ! rl_vi_insertion_mode () { _rl_keymap = vi_insertion_keymap; --- 541,546 ---- /* Switching from one mode to the other really just involves switching keymaps. */ ! rl_vi_insertion_mode (count, key) ! int count, key; { _rl_keymap = vi_insertion_keymap; *************** *** 564,568 **** } ! rl_vi_movement_mode () { if (rl_point > 0) --- 564,569 ---- } ! rl_vi_movement_mode (count, key) ! int count, key; { if (rl_point > 0) *************** *** 642,646 **** } ! rl_vi_column (count) { if (count > rl_end) --- 643,648 ---- } ! rl_vi_column (count, key) ! int count, key; { if (count > rl_end) *************** *** 664,668 **** if (!member (c, vi_motion)) { ! if (digit (c)) { save = rl_numeric_arg; --- 666,670 ---- if (!member (c, vi_motion)) { ! if (digit_p (c)) { save = rl_numeric_arg; *************** *** 759,763 **** c = UNMETA (c); ! if (numeric (c)) { if (rl_explicit_arg) --- 761,765 ---- c = UNMETA (c); ! if (digit_p (c)) { if (rl_explicit_arg) *************** *** 868,873 **** } ! rl_vi_delete (count) ! int count; { int end; --- 870,875 ---- } ! rl_vi_delete (count, key) ! int count, key; { int end; *************** *** 893,897 **** /* Turn the current line into a comment in shell history. A K*rn shell style function. */ ! rl_vi_comment () { rl_beg_of_line (); --- 895,900 ---- /* Turn the current line into a comment in shell history. A K*rn shell style function. */ ! rl_vi_comment (count, key) ! int count, key; { rl_beg_of_line (); *************** *** 907,911 **** } ! rl_vi_first_print () { return (rl_back_to_indent ()); --- 910,915 ---- } ! rl_vi_first_print (count, key) ! int count, key; { return (rl_back_to_indent ()); *************** *** 1028,1032 **** /* Match brackets */ ! rl_vi_match () { int count = 1, brack, pos; --- 1032,1037 ---- /* Match brackets */ ! rl_vi_match (ignore, key) ! int ignore, key; { int count = 1, brack, pos; diff -rc2 bash-1.14.1/machines.h bash-1.14.2/machines.h *** bash-1.14.1/machines.h Fri Jul 1 11:20:50 1994 --- bash-1.14.2/machines.h Sat Aug 13 14:46:26 1994 *************** *** 102,106 **** YP which bites us when Sun free ()'s an already free ()'ed address. When Sun fixes their YP, we can start using our winning malloc again. */ ! /* #undef USE_GNU_MALLOC */ /* Most Sun systems have signal handler functions that are void. */ --- 102,106 ---- YP which bites us when Sun free ()'s an already free ()'ed address. When Sun fixes their YP, we can start using our winning malloc again. */ ! #undef USE_GNU_MALLOC /* Most Sun systems have signal handler functions that are void. */ *************** *** 124,143 **** # endif /* !HAVE_GCC */ # define HAVE_STRERROR - /* The following are only available thru the BSD compatability lib. */ # undef HAVE_GETWD # undef HAVE_SETLINEBUF ! # else /* !SunOS5 */ ! # if defined (SunOS4) ! # define M_OS "SunOS4" ! # define SYSDEP_CFLAGS -DBSD_GETPGRP -DOPENDIR_NOT_ROBUST -DTERMIOS_LDISC \ ! -DINT_GROUPS_ARRAY ! # define HAVE_DIRENT ! # else /* !SunOS4 */ ! # if !defined (sparc) && !defined (__sparc__) ! # undef VOID_SIGHANDLER ! # endif /* !sparc */ ! # define M_OS "SunOS3" ! # endif /* !SunOS4 */ ! # endif /* !SunOS5 */ # if defined (mc68010) --- 124,144 ---- # endif /* !HAVE_GCC */ # define HAVE_STRERROR # undef HAVE_GETWD # undef HAVE_SETLINEBUF ! # endif /* SunOS5 */ ! ! # if defined (SunOS4) ! # define M_OS "SunOS4" ! # define SYSDEP_CFLAGS -DBSD_GETPGRP -DOPENDIR_NOT_ROBUST -DTERMIOS_LDISC \ ! -DINT_GROUPS_ARRAY ! # define HAVE_DIRENT ! # endif /* SunOS4 */ ! ! # if !defined (SunOS4) && !defined (SunOS5) ! # define M_OS "SunOS3" ! # if !defined (sparc) && !defined (__sparc__) ! # undef VOID_SIGHANDLER ! # endif /* !sparc */ ! # endif /* !SunOS4 && !SunOS5 */ # if defined (mc68010) *************** *** 230,233 **** --- 231,248 ---- #endif /* vax && !ultrix */ + /* ************************ */ + /* */ + /* Tahoe 4.3 BSD */ + /* */ + /* ************************ */ + #if defined (tahoe) + # define M_MACHINE "tahoe" + # define M_OS "Bsd" + # define HAVE_SETLINEBUF + # define HAVE_SYS_SIGLIST + # define HAVE_GETGROUPS + # define HAVE_VFPRINTF + #endif /* tahoe */ + /* **************************************************************** */ /* */ *************** *** 448,452 **** * Use `$(CC) -E' instead of `/lib/cpp' in Makefile. */ ! #if defined (mips) && !defined (M_MACHINE) # if defined (MIPSEB) --- 463,467 ---- * Use `$(CC) -E' instead of `/lib/cpp' in Makefile. */ ! #if defined (mips) && (!defined (M_MACHINE) || defined (RiscOS)) # if defined (MIPSEB) *************** *** 625,629 **** # define HAVE_GETGROUPS # if defined (USGr4_2) ! # define SYSDEP_CFLAGS -DUSGr4 -DUSGr4_2 # else # define SYSDEP_CFLAGS -DUSGr4 --- 640,644 ---- # define HAVE_GETGROUPS # if defined (USGr4_2) ! # define SYSDEP_CFLAGS -DUSGr4 -DUSGr4_2 -DNO_SBRK_DECL # else # define SYSDEP_CFLAGS -DUSGr4 *************** *** 702,711 **** # define M_MACHINE "i386" # define M_OS "SCO" ! # define SCO_CFLAGS -DUSG -DUSGr3 -DNO_DEV_TTY_JOB_CONTROL -DPGRP_PIPE \ ! -DOPENDIR_NOT_ROBUST # if defined (SCOv4) # define SYSDEP_CFLAGS SCO_CFLAGS # else /* !SCOv4 */ ! # define SYSDEP_CFLAGS SCO_CFLAGS -DBROKEN_SIGSUSPEND # endif /* !SCOv4 */ # define HAVE_VFPRINTF --- 717,725 ---- # define M_MACHINE "i386" # define M_OS "SCO" ! # define SCO_CFLAGS -DUSG -DUSGr3 -DNO_DEV_TTY_JOB_CONTROL -DPGRP_PIPE # if defined (SCOv4) # define SYSDEP_CFLAGS SCO_CFLAGS # else /* !SCOv4 */ ! # define SYSDEP_CFLAGS SCO_CFLAGS -DBROKEN_SIGSUSPEND -DOPENDIR_NOT_ROBUST # endif /* !SCOv4 */ # define HAVE_VFPRINTF *************** *** 735,739 **** # define USE_TERMCAP_EMULATION # define SYSDEP_CFLAGS -D_BSD - # define SYSDEP_LDFLAGS # define REQUIRED_LIBRARIES -lbsd # endif /* OSF/1 */ --- 749,752 ---- *************** *** 966,969 **** --- 979,1002 ---- #endif /* NeXT */ + /* ********************** */ + /* */ + /* m68k NetBSD */ + /* */ + /* ********************** */ + #if defined (m68k) && defined (__NetBSD__) + # include + # define M_MACHINE MACHINE + # define M_OS "NetBSD" + /* os/netbsd.h */ + # define SYSDEP_CFLAGS -DOPENDIR_NOT_ROBUST -DINT_GROUPS_ARRAY + # define HAVE_SYS_SIGLIST + # define HAVE_SETLINEBUF + # define HAVE_GETGROUPS + # define HAVE_VFPRINTF + # define HAVE_STRERROR + # define VOID_SIGHANDLER + # define HAVE_DIRENT + #endif /* m68k && __NetBSD__ */ + /* ************************ */ /* */ *************** *** 1066,1070 **** # if defined (HPUX_8) # define M_OS "hpux_8" ! # undef HAVE_ALLOCA # undef HAVE_GETWD # undef USE_GNU_MALLOC --- 1099,1105 ---- # if defined (HPUX_8) # define M_OS "hpux_8" ! # if !defined (__GNUC__) ! # undef HAVE_ALLOCA ! # endif # undef HAVE_GETWD # undef USE_GNU_MALLOC *************** *** 1077,1085 **** # define M_OS "hpux_9" # if !defined (__GNUC__) ! # define REQUIRED_LIBRARIES -lPW ! # undef USE_GNU_MALLOC # endif - # undef HAVE_RESOURCE # undef HAVE_GETWD # define HPUX_CFLAGS -DNO_SBRK_DECL -DHAVE_SOCKETS -DHAVE_GETHOSTNAME # endif /* HPUX_9 */ --- 1112,1120 ---- # define M_OS "hpux_9" # if !defined (__GNUC__) ! # undef HAVE_ALLOCA # endif # undef HAVE_GETWD + # undef USE_GNU_MALLOC + # undef HAVE_RESOURCE # define HPUX_CFLAGS -DNO_SBRK_DECL -DHAVE_SOCKETS -DHAVE_GETHOSTNAME # endif /* HPUX_9 */ *************** *** 1196,1199 **** --- 1231,1258 ---- /* ************************ */ + /* */ + /* Intel i860 -- SVR4 */ + /* */ + /* ************************ */ + #if defined (__i860) && defined (USGr4) && !defined (M_MACHINE) + # define M_MACHINE "i860" + # define M_OS "USG" + # define HAVE_DIRENT + # define HAVE_SYS_SIGLIST + # define HAVE_VFPRINTF + # define VOID_SIGHANDLER + # define HAVE_GETGROUPS + # if !defined (HAVE_GCC) && !defined (HAVE_ALLOCA_H) + # undef HAVE_ALLOCA + # endif /* !HAVE_GCC && !HAVE_ALLOCA_H */ + # if defined (USGr4_2) + # define SYSDEP_CFLAGS -DUSGr4 -DUSGr4_2 + # else + # define SYSDEP_CFLAGS -DUSGr4 + # endif /* ! USGr4_2 */ + # undef HAVE_GETWD + #endif /* __i860 && USGr4 */ + + /* ************************ */ /* */ /* Xenix286 */ *************** *** 1482,1485 **** --- 1541,1545 ---- # endif # undef HAVE_BCOPY + # undef HAVE_GETWD # undef USE_GNU_MALLOC #endif /* sparc && __svr4__ */ *************** *** 1595,1599 **** /* DG/UX comes standard with Gcc. */ #if defined (__DGUX__) || defined (DGUX) ! # define M_OS "USG" # if !defined (_M88KBCS_TARGET) # define M_MACHINE "AViiON" --- 1655,1659 ---- /* DG/UX comes standard with Gcc. */ #if defined (__DGUX__) || defined (DGUX) ! # define M_OS "DGUX" # if !defined (_M88KBCS_TARGET) # define M_MACHINE "AViiON" *************** *** 1605,1609 **** # undef HAVE_RESOURCE # endif /* _M88KBCS_TARGET */ ! # define SYSDEP_CFLAGS MACHINE_CFLAGS -D_DGUX_SOURCE -DPGRP_PIPE # define HAVE_GCC # define HAVE_FIXED_INCLUDES --- 1665,1669 ---- # undef HAVE_RESOURCE # endif /* _M88KBCS_TARGET */ ! # define SYSDEP_CFLAGS MACHINE_CFLAGS -D_DGUX_SOURCE -DPGRP_PIPE -DUSG # define HAVE_GCC # define HAVE_FIXED_INCLUDES *************** *** 1907,1910 **** --- 1967,1988 ---- /* ************************ */ /* */ + /* Tandem running SVR3 */ + /* */ + /* ************************ */ + #if defined (tandem) && !defined (M_MACHINE) + # define M_MACHINE "tandem" + # define M_OS "USG" + # define SYSDEP_CFLAGS -DUSGr3 + # define HAVE_VFPRINTF + # define VOID_SIGHANDLER + /* Alloca requires either Gcc or cc with libPW.a */ + # if !defined (HAVE_GCC) + # define REQUIRED_LIBRARIES -lPW + # endif /* !HAVE_GCC */ + # undef HAVE_GETWD + #endif /* Tandem running SVR3 */ + + /* ************************ */ + /* */ /* PCS Cadmus System */ /* */ *************** *** 1930,1934 **** /* Use this entry for your machine if it isn't represented here. It ! is loosely based on a Vax running 4.3 Bsd. */ #if !defined (M_MACHINE) --- 2008,2012 ---- /* Use this entry for your machine if it isn't represented here. It ! is loosely based on a Vax running 4.3 BSD. */ #if !defined (M_MACHINE) *************** *** 1946,1962 **** # define HAVE_SYS_SIGLIST /* Undef HAVE_ALLOCA if you are not using Gcc, and neither your library nor compiler has a version of alloca (). In that case, we will use our version of alloca () in alloca.c */ ! /* #undef HAVE_ALLOCA */ /* Undef USE_GNU_MALLOC if there appear to be library conflicts, or if you especially desire to use your OS's version of malloc () and friends. We reccommend against this because GNU Malloc has debugging code built in. */ ! # define USE_GNU_MALLOC /* Define USE_GNU_TERMCAP if you want to use the GNU termcap library instead of your system termcap library. */ ! /* #define USE_GNU_TERMCAP */ /* Define HAVE_SETLINEBUF if your machine has the setlinebuf () --- 2024,2048 ---- # define HAVE_SYS_SIGLIST + /* Undef HAVE_GETWD if your C library does not provide a working version + of getwd(). */ + /* # undef HAVE_GETWD */ + + /* Undef HAVE_GETCWD if your C library does not provide a working version + of getcwd(). */ + /* # undef HAVE_GETCWD */ + /* Undef HAVE_ALLOCA if you are not using Gcc, and neither your library nor compiler has a version of alloca (). In that case, we will use our version of alloca () in alloca.c */ ! /* # undef HAVE_ALLOCA */ /* Undef USE_GNU_MALLOC if there appear to be library conflicts, or if you especially desire to use your OS's version of malloc () and friends. We reccommend against this because GNU Malloc has debugging code built in. */ ! /* # undef USE_GNU_MALLOC */ /* Define USE_GNU_TERMCAP if you want to use the GNU termcap library instead of your system termcap library. */ ! /* # define USE_GNU_TERMCAP */ /* Define HAVE_SETLINEBUF if your machine has the setlinebuf () *************** *** 2004,2009 **** MEMMOVE_MISSING - the system does not have memmove(3) MKFIFO_MISSING - named pipes do not work or mkfifo(3) is missing - NEED_SYS_PARAM - MAXPATHLEN is defined in . This is - used by maxpath.h NO_DEV_TTY_JOB_CONTROL - system can't do job control on /dev/tty NO_SBRK_DECL - don't declare sbrk as extern char *sbrk() in --- 2090,2093 ---- *************** *** 2030,2053 **** /* Define HAVE_STRERROR if your system supplies a definition for strerror () in the C library, or a macro in a header file. */ ! /* #define HAVE_STRERROR */ ! /* Define HAVE_STRCASECMPif your system supplies definitions for the caseless ! string comparison functions strcasecmp and strncasemp in libc or one of ! the system header files. */ ! /* #define HAVE_STRCASECMP */ /* Define HAVE_DIRENT if you have the dirent library and a definition of struct dirent. If not, the BSD directory reading library and struct direct are assumed. */ ! /* #define HAVE_DIRENT */ /* If your system does not supply /usr/lib/libtermcap.a, but includes the termcap routines as a part of the curses library, then define this. This is the case on some System V machines. */ ! /* #define USE_TERMCAP_EMULATION */ /* Define VOID_SIGHANDLER if your system's signal () returns a pointer to a function returning void. */ ! /* #define VOID_SIGHANDLER */ /* Define EXTRA_LIB_SEARCH_PATH if your required libraries (or standard) --- 2114,2137 ---- /* Define HAVE_STRERROR if your system supplies a definition for strerror () in the C library, or a macro in a header file. */ ! /* # define HAVE_STRERROR */ ! /* Define HAVE_STRCASECMP if your system supplies definitions for the ! casel-insensitive string comparison functions strcasecmp and strncasemp ! in the C library or one of the system header files. */ ! /* # define HAVE_STRCASECMP */ /* Define HAVE_DIRENT if you have the dirent library and a definition of struct dirent. If not, the BSD directory reading library and struct direct are assumed. */ ! /* # define HAVE_DIRENT */ /* If your system does not supply /usr/lib/libtermcap.a, but includes the termcap routines as a part of the curses library, then define this. This is the case on some System V machines. */ ! /* # define USE_TERMCAP_EMULATION */ /* Define VOID_SIGHANDLER if your system's signal () returns a pointer to a function returning void. */ ! /* # define VOID_SIGHANDLER */ /* Define EXTRA_LIB_SEARCH_PATH if your required libraries (or standard) *************** *** 2055,2059 **** example, some machines require /usr/ucblib in the ld search path so that they can use -lucb. */ ! /* #define EXTRA_LIB_SEARCH_PATH /usr/ucblib */ /* Define SEARCH_LIB_NEEDS_SPACE if your native ld requires a space after --- 2139,2143 ---- example, some machines require /usr/ucblib in the ld search path so that they can use -lucb. */ ! /* # define EXTRA_LIB_SEARCH_PATH /usr/ucblib */ /* Define SEARCH_LIB_NEEDS_SPACE if your native ld requires a space after *************** *** 2065,2073 **** -Llib/readline -lreadline */ ! /* #define SEARCH_LIB_NEEDS_SPACE */ /* Define LD_HAS_NO_DASH_L if your ld can't grok the -L flag in any way, or if it cannot grok the -l flag, or both. */ ! /* #define LD_HAS_NO_DASH_L */ # if defined (LD_HAS_NO_DASH_L) # undef SEARCH_LIB_NEEDS_SPACE --- 2149,2158 ---- -Llib/readline -lreadline */ ! /* # define SEARCH_LIB_NEEDS_SPACE */ /* Define LD_HAS_NO_DASH_L if your ld can't grok the -L flag in any way, or if it cannot grok the -l flag, or both. */ ! /* # define LD_HAS_NO_DASH_L */ ! # if defined (LD_HAS_NO_DASH_L) # undef SEARCH_LIB_NEEDS_SPACE diff -rc2 bash-1.14.1/memalloc.h bash-1.14.2/memalloc.h *** bash-1.14.1/memalloc.h Fri Jul 1 11:20:54 1994 --- bash-1.14.2/memalloc.h Thu Jul 14 12:42:52 1994 *************** *** 48,52 **** --- 48,56 ---- # endif /* !IBMESA */ # else + # if defined (hpux_9) && defined (__STDC__) + extern void *alloca (); + # else extern char *alloca (); + # endif # endif /* !HAVE_ALLOCA_H */ #endif /* !__GNUC__ */ diff -rc2 bash-1.14.1/parse.y bash-1.14.2/parse.y *** bash-1.14.1/parse.y Fri Jul 1 11:20:45 1994 --- bash-1.14.2/parse.y Wed Aug 10 12:25:44 1994 *************** *** 61,64 **** --- 61,70 ---- extern char *shell_name, *current_host_name; extern Function *last_shell_builtin, *this_shell_builtin; + #if defined (READLINE) + extern int bash_readline_initialized; + #endif + #if defined (BUFFERED_INPUT) + extern int bash_input_fd_changed; + #endif /* **************************************************************** */ *************** *** 799,804 **** int current_readline_line_index = 0; - static int readline_initialized_yet = 0; - static int yy_readline_get () --- 805,808 ---- *************** *** 809,817 **** int line_len; ! if (!readline_initialized_yet) ! { ! initialize_readline (); ! readline_initialized_yet = 1; ! } #if defined (JOB_CONTROL) --- 813,818 ---- int line_len; ! if (!bash_readline_initialized) ! initialize_readline (); #if defined (JOB_CONTROL) *************** *** 1007,1010 **** --- 1008,1013 ---- pop_stream () { + int temp; + if (!stream_list) EOF_Reached = 1; *************** *** 1024,1030 **** #if defined (BUFFERED_INPUT) /* If we have a buffered stream, restore buffers[fd]. */ ! /* XXX - what about default_buffered_input? - XXX */ if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0) ! buffers[bash_input.location.buffered_fd] = saver->bstream; #endif /* BUFFERED_INPUT */ --- 1027,1046 ---- #if defined (BUFFERED_INPUT) /* If we have a buffered stream, restore buffers[fd]. */ ! /* If the input file descriptor was changed while this was on the ! save stack, update the buffered fd to the new file descriptor and ! re-establish the buffer <-> bash_input fd correspondence. */ if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0) ! { ! if (bash_input_fd_changed) ! { ! bash_input_fd_changed = 0; ! if (default_buffered_input >= 0) ! { ! bash_input.location.buffered_fd = default_buffered_input; ! saver->bstream->b_fd = default_buffered_input; ! } ! } ! buffers[bash_input.location.buffered_fd] = saver->bstream; ! } #endif /* BUFFERED_INPUT */ *************** *** 1396,1400 **** if (i + 2 > shell_input_line_size) ! shell_input_line = (char *) xrealloc (shell_input_line, shell_input_line_size += 256); --- 1412,1416 ---- if (i + 2 > shell_input_line_size) ! shell_input_line = xrealloc (shell_input_line, shell_input_line_size += 256); diff -rc2 bash-1.14.1/portbash/libc.sh bash-1.14.2/portbash/libc.sh *** bash-1.14.1/portbash/libc.sh Fri Jul 1 11:21:53 1994 --- bash-1.14.2/portbash/libc.sh Mon Jul 11 12:08:11 1994 *************** *** 142,146 **** fi ! rm -f x.c x.o a.out pgrp.o ! echo "#define SYSDEP_CFLAGS $BC $UIDT $SL $PG $R4" exit 0 --- 142,172 ---- fi ! touch not_a_directory ! if [ -f /usr/include/dirent.h ]; then ! d='' ! else ! d='' ! fi ! ! cat > x.c << EOF ! /* ! * exit 0 if opendir does not check whether its argument is a directory ! */ ! ! #include $d ! DIR *dir; ! ! main() ! { ! dir = opendir("not_a_directory"); ! exit (dir == 0); ! } ! EOF ! ! if ${CC} x.c > /dev/null 2>&1 && ./a.out ; then ! OD='-DOPENDIR_NOT_ROBUST' ! fi ! ! rm -f x.c x.o a.out pgrp.o not_a_directory ! echo "#define SYSDEP_CFLAGS $BC $UIDT $SL $PG $R4 $OD" exit 0 diff -rc2 bash-1.14.1/siglist.h bash-1.14.2/siglist.h *** bash-1.14.1/siglist.h Fri Jul 1 11:20:52 1994 --- bash-1.14.2/siglist.h Thu Aug 11 17:01:40 1994 *************** *** 28,34 **** #endif /* Solaris || USGr4_2 || drs6000 || amiga || Minix */ ! #if !defined (Solaris) && !defined (Linux) && !defined (__BSD_4_4__) && !defined (Minix) && !defined (NetBSD) extern char *sys_siglist[]; ! #endif /* !Solaris && !Linux && !__BSD_4_4__ && !Minix && !NetBSD */ #if !defined (strsignal) && !defined (Solaris) --- 28,35 ---- #endif /* Solaris || USGr4_2 || drs6000 || amiga || Minix */ ! #if !defined (Solaris) && !defined (Linux) && !defined (__BSD_4_4__) && \ ! !defined (Minix) && !defined (NetBSD) && !defined (FreeBSD) extern char *sys_siglist[]; ! #endif /* !Solaris && !Linux && !__BSD_4_4__ && !Minix && !NetBSD && !FreeBSD */ #if !defined (strsignal) && !defined (Solaris) diff -rc2 bash-1.14.1/subst.c bash-1.14.2/subst.c *** bash-1.14.1/subst.c Fri Jul 1 11:20:46 1994 --- bash-1.14.2/subst.c Tue Aug 9 10:25:50 1994 *************** *** 89,93 **** static WORD_LIST *word_list_split (); static char *quote_string (); ! static int unquoted_substring (), unquoted_glob_pattern_p (); static void quote_list (), dequote_list (); static int do_assignment_internal (); --- 89,94 ---- static WORD_LIST *word_list_split (); static char *quote_string (); ! static int unquoted_substring (), unquoted_member (); ! static int unquoted_glob_pattern_p (); static void quote_list (), dequote_list (); static int do_assignment_internal (); *************** *** 741,744 **** --- 742,796 ---- } + #if defined (READLINE) + int + unclosed_pair (string, eindex, openstr) + char *string; + int eindex; + char *openstr; + { + int i, pass_next, openc, c, olen; + char *temp, *s; + + olen = strlen (openstr); + for (i = pass_next = openc = 0; i <= eindex; i++) + { + if (pass_next) + { + pass_next = 0; + if (i >= eindex) /* XXX was if (i >= eindex - 1) */ + return 0; + continue; + } + else if (STREQN (string + i, openstr, olen)) + { + openc = 1 - openc; + i += olen - 1; + } + else if (string[i] == '\'') + { + i++; + temp = string_extract_single_quoted (string, &i); + free (temp); + if (i > eindex) + return 0; + } + else if (string[i] == '"') + { + i++; + temp = string_extract_double_quoted (string, &i); + free (temp); + if (i > eindex) + return 0; + } + else if (string[i] == '\\') + { + pass_next = 1; + continue; + } + } + return (openc); + } + #endif /* READLINE */ + /* Extract the name of the variable to bind to from the assignment string. */ char * *************** *** 1067,1071 **** break; else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"') ! saw_quote = 1; } --- 1119,1123 ---- break; else if (string[i] == '\'' || string[i] == '\\' || string[i] == '"') ! saw_quote = 1; } *************** *** 1112,1116 **** if (expand && temp[0]) { ! if (strchr (temp, '~')) temp = tilde_expand (temp); else --- 1164,1168 ---- if (expand && temp[0]) { ! if (strchr (temp, '~') && unquoted_member ('~', temp)) temp = tilde_expand (temp); else *************** *** 1184,1192 **** srclen = strlen (source); if (srclen >= (int)(*size - *indx)) ! { ! n = (*indx + srclen); n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE); target = xrealloc (target, (*size = n)); ! } FASTCOPY (source, target + *indx, srclen); --- 1236,1244 ---- srclen = strlen (source); if (srclen >= (int)(*size - *indx)) ! { ! n = srclen + *indx; n = (n + DEFAULT_ARRAY_SIZE) - (n % DEFAULT_ARRAY_SIZE); target = xrealloc (target, (*size = n)); ! } FASTCOPY (source, target + *indx, srclen); *************** *** 1665,1671 **** /* **************************************************************** */ ! /* */ ! /* Hacking Process Substitution */ ! /* */ /* **************************************************************** */ --- 1717,1723 ---- /* **************************************************************** */ ! /* */ ! /* Hacking Process Substitution */ ! /* */ /* **************************************************************** */ *************** *** 1973,1978 **** #if defined (HAVE_DEV_FD) ! /* Make sure we close the parent's end of the pipe. */ close (parent_pipe_fd); #endif /* HAVE_DEV_FD */ --- 2025,2033 ---- #if defined (HAVE_DEV_FD) ! /* Make sure we close the parent's end of the pipe and clear the slot ! in the fd list so it is not closed later, if reallocated by, for ! instance, pipe(2). */ close (parent_pipe_fd); + dev_fd_list[parent_pipe_fd] = 0; #endif /* HAVE_DEV_FD */ *************** *** 2473,2477 **** /* Values for the local variable quoted_state. */ ! #define UNQUOTED 0 #define PARTIALLY_QUOTED 1 #define WHOLLY_QUOTED 2 --- 2528,2532 ---- /* Values for the local variable quoted_state. */ ! #define UNQUOTED 0 #define PARTIALLY_QUOTED 1 #define WHOLLY_QUOTED 2 *************** *** 3331,3335 **** { while (istring_index + 1 >= istring_size) ! istring_size += DEFAULT_ARRAY_SIZE; istring = xrealloc (istring, istring_size); } --- 3386,3390 ---- { while (istring_index + 1 >= istring_size) ! istring_size += DEFAULT_ARRAY_SIZE; istring = xrealloc (istring, istring_size); } *************** *** 3551,3556 **** } - #if defined (NOTDEF) - /* Currently unused. */ /* Return 1 if CHARACTER appears in an unquoted portion of STRING. Return 0 otherwise. */ --- 3606,3609 ---- *************** *** 3598,3602 **** return (0); } - #endif /* NOTDEF */ /* Return 1 if SUBSTR appears in an unquoted portion of STRING. */ --- 3651,3654 ---- *************** *** 3639,3644 **** sindex = tindex; ! if (temp) ! free (temp); break; --- 3691,3695 ---- sindex = tindex; ! FREE (temp); break; *************** *** 3789,3793 **** { /* Found an assignment statement, add this word to end of ! varlist (vp). */ if (!varlist) varlist = vp = lp; --- 3840,3844 ---- { /* Found an assignment statement, add this word to end of ! varlist (vp). */ if (!varlist) varlist = vp = lp; *************** *** 3863,3867 **** tlist = separate_out_assignments (tlist); if (!tlist) ! { if (varlist) { --- 3914,3918 ---- tlist = separate_out_assignments (tlist); if (!tlist) ! { if (varlist) { *************** *** 3875,3879 **** } return ((WORD_LIST *)NULL); ! } } --- 3926,3930 ---- } return ((WORD_LIST *)NULL); ! } } *************** *** 3916,3920 **** /* Add TLIST to the list of words to be freed after brace ! expansion has been performed. */ tlist->next = disposables; disposables = tlist; --- 3967,3971 ---- /* Add TLIST to the list of words to be freed after brace ! expansion has been performed. */ tlist->next = disposables; disposables = tlist; *************** *** 3965,3973 **** if (expanded == &expand_word_error || expanded == &expand_word_fatal) ! { /* By convention, each time this error is returned, tlist->word->word has already been freed. */ ! tlist->word->word = (char *)NULL; ! /* Dispose our copy of the original list. */ dispose_words (orig_list); --- 4016,4024 ---- if (expanded == &expand_word_error || expanded == &expand_word_fatal) ! { /* By convention, each time this error is returned, tlist->word->word has already been freed. */ ! tlist->word->word = (char *)NULL; ! /* Dispose our copy of the original list. */ dispose_words (orig_list); *************** *** 4498,4502 **** history_control = 2; else if (strcmp (temp, "ignoreboth") == 0) ! history_control = 3; } } --- 4549,4553 ---- history_control = 2; else if (strcmp (temp, "ignoreboth") == 0) ! history_control = 3; } } diff -rc2 bash-1.14.1/support/getcppsyms.c bash-1.14.2/support/getcppsyms.c *** bash-1.14.1/support/getcppsyms.c Fri Jul 1 11:21:30 1994 --- bash-1.14.2/support/getcppsyms.c Sun Aug 7 00:01:58 1994 *************** *** 154,159 **** #endif /* __m88k */ #if defined (__uxpm__) ! printf (" -DUSGr4 -Du370"); #endif /* __uxpm__ */ #if defined (alliant) printf (" -Dalliant"); --- 154,162 ---- #endif /* __m88k */ #if defined (__uxpm__) ! printf (" -DUSGr4 -Du370 -D__uxpm__"); #endif /* __uxpm__ */ + #if defined (__uxps__) + printf (" -D__svr4__ -D__uxps__"); + #endif /* __uxps__ */ #if defined (alliant) printf (" -Dalliant"); diff -rc2 bash-1.14.1/support/mksysdefs bash-1.14.2/support/mksysdefs *** bash-1.14.1/support/mksysdefs Fri Jul 1 11:21:29 1994 --- bash-1.14.2/support/mksysdefs Sat Aug 13 14:25:43 1994 *************** *** 5,11 **** # by looking at random files. ! case "$1" in ! -s) shift; srcdir=$1; shift ;; ! esac if [ -n "$1" ]; then --- 5,20 ---- # by looking at random files. ! # Removes any inherited definitions. ! SYSDEF= ! MAKE_ANSI= ! ! while [ $# -gt 0 ]; do ! case "$1" in ! -s) shift; srcdir=$1; shift ;; ! -i) shift; incdir="$1"; shift ;; ! -A) shift; MAKE_ANSI=true ;; ! *) break ;; ! esac ! done if [ -n "$1" ]; then *************** *** 28,41 **** echo "# define _SYSDEFS_H_" >>$sysdefs ! # Removes any inherited definitions. ! SHLIB= ! SYSDEF= ! MAKE_ANSI= ! ! if [ -f /usr/bin/uname ] || [ -f /bin/uname ]; then UNAME=`uname` UNAME_R=`uname -r 2>/dev/null` UNAME_M=`uname -m 2>/dev/null` UNAME_V=`uname -v 2>/dev/null` RELEASE=`expr "$UNAME_R" : '[^0-9]*\([0-9]*\)'` RELEASE=`expr "$RELEASE" + 0` --- 37,48 ---- echo "# define _SYSDEFS_H_" >>$sysdefs ! # was if [ -f /usr/bin/uname ] || [ -f /bin/uname ] ! if ( uname >/dev/null 2>&1 ) 2>/dev/null ! then UNAME=`uname` UNAME_R=`uname -r 2>/dev/null` UNAME_M=`uname -m 2>/dev/null` UNAME_V=`uname -v 2>/dev/null` + UNAME_S=`uname -s 2>/dev/null` RELEASE=`expr "$UNAME_R" : '[^0-9]*\([0-9]*\)'` RELEASE=`expr "$RELEASE" + 0` *************** *** 45,50 **** # check for versions of SunOS case "${UNAME}${RELEASE}" in ! SunOS4) SYSDEF=SunOS4 ;; ! SunOS5) SYSDEF=SunOS5 ;; esac --- 52,57 ---- # check for versions of SunOS case "${UNAME}${RELEASE}" in ! SunOS4*) SYSDEF=SunOS4 ;; ! SunOS5*) SYSDEF=SunOS5 ;; esac *************** *** 61,73 **** # Test for shared libraries (this is pretty sVr4ish). if [ -f /usr/ccs/lib/libc.so ]; then - SHLIB=-DHAVE_SHARED_LIBS - echo "" >>$sysdefs - echo "#if !defined (HAVE_SHARED_LIBS)" >>$sysdefs - echo "# define HAVE_SHARED_LIBS" >>$sysdefs - echo "#endif /* HAVE_SHARED_LIBS */" >>$sysdefs - SYSDEF=USGr4 fi # another check for SVR4 on 386 or 486 machines case "${UNAME_M}:${UNAME}:${UNAME_R}" in --- 68,80 ---- # Test for shared libraries (this is pretty sVr4ish). if [ -f /usr/ccs/lib/libc.so ]; then SYSDEF=USGr4 fi + # Some versions of i386 SVR4.2 make `uname' equivalent to `uname -n', which + # is contrary to all other versions of uname + if [ -n "$UNAME" ] && [ "$UNAME_S" != "$UNAME" ] && [ "$UNAME_S" = UNIX_SV ]; then + UNAME=UNIX_SV + fi + # another check for SVR4 on 386 or 486 machines case "${UNAME_M}:${UNAME}:${UNAME_R}" in *************** *** 171,182 **** elif [ -f /bin/fxc.info ]; then SYSDEF="alliant" - else - if [ -f /shlib/libc_s ]; then - SHLIB=-DHAVE_SHARED_LIBS - echo "" >>$sysdefs - echo "#if !defined (HAVE_SHARED_LIBS)" >>$sysdefs - echo "# define HAVE_SHARED_LIBS" >>$sysdefs - echo "#endif /* HAVE_SHARED_LIBS */" >>$sysdefs - fi fi fi --- 178,181 ---- *************** *** 228,232 **** # What release of SCO Unix is this? if [ "$SYSDEF" = "" -a -f /bin/uname ]; then ! case `uname -X 2>/dev/null | grep '^Release' 2>/dev/null` in *3.2v4.*) SCOREL=SCOv4 ;; *) SCOREL= ;; --- 227,231 ---- # What release of SCO Unix is this? if [ "$SYSDEF" = "" -a -f /bin/uname ]; then ! case `/bin/uname -X 2>/dev/null | grep '^Release' 2>/dev/null` in *3.2v4.*) SCOREL=SCOv4 ;; *) SCOREL= ;; *************** *** 244,251 **** # Default to cadmus for unknown SysVish systems # ! if [ -f /unix ]; then ! if [ "$SYSDEF" = "" ]; then ! SYSDEF="cadmus" ! fi fi --- 243,248 ---- # Default to cadmus for unknown SysVish systems # ! if [ -f /unix ] && [ "$SYSDEF" = "" ]; then ! SYSDEF="cadmus" fi *************** *** 262,269 **** # Add any other directories where include files are found to this list or # create another case ! case "$SYSDEF" in ! RISCos*) dirlist="/bsd43/usr/include";; ! *) dirlist="/usr/include /usr/include/bsd /usr/include/ansi" ;; ! esac # Code fragment to be executed to find a particular include file. Make sure --- 259,270 ---- # Add any other directories where include files are found to this list or # create another case ! if [ -n "$incdir" ]; then ! dirlist="$incdir" ! else ! case "$SYSDEF" in ! RISCos*) dirlist="/bsd43/usr/include";; ! *) dirlist="/usr/include /usr/include/bsd /usr/include/ansi" ;; ! esac ! fi # Code fragment to be executed to find a particular include file. Make sure *************** *** 435,462 **** echo "#endif /* HAVE_BISON */" >>$sysdefs fi ! ! # If the user is using a recent Bash already, let's compile with that ! # as the $SHELL for Make. # ! # I stopped doing this because "make install" mv's the existing shell to ! # a new name before copying the new shell over. Since the existing shell ! # is moved, there is no shell to do the "cp" command! ! # BashVersion= ! # ! # if [ "$BASH" != "" ]; then ! # if [ -f "$BASH" ]; then ! # BashVersion=`$BASH -norc -c 'echo $BASH_VERSION' 2>/dev/null` ! # fi ! # ! # if [ `expr $BashVersion \> 1.10 2>/dev/null` = "1" ]; then ! # echo "" >>$sysdefs ! # echo "#define MAKE_SHELL $BASH" >>$sysdefs ! # echo "Bash will be compiled with \$SHELL = $BASH!" ! # fi ! # fi # If this system's cpp might not like `/**/#' in cpp-Makefile, make an # alternate ansi-style cpp-Makefile. ! if [ "$MAKE_ANSI" = "true" ]; then grep -v '/\*\*/' ${srcdir}/cpp-Makefile >ansi-Makefile fi --- 436,470 ---- echo "#endif /* HAVE_BISON */" >>$sysdefs fi ! ! # Functions to test for a la autoconf ! # getwd ! # getcwd ! # strchr ! # strcasecmp ! # getgroups ! # setlinebuf ! # strerror ! # vfprintf ! # bcopy ! # getdtablesize ! # setdtablesize ! # alloca ! # gethostname ! # memmove (missing) ! # mkfifo (missing) # ! # Other things to test ! # opendir robustness ! # dup2 working ! # void sighandler ! # sys_siglist[] ! # uid_t, gid_t ! # have_getpw_decls ! # reversed setvbuf args ! # int getgroups # If this system's cpp might not like `/**/#' in cpp-Makefile, make an # alternate ansi-style cpp-Makefile. ! if [ -n "$MAKE_ANSI" ]; then grep -v '/\*\*/' ${srcdir}/cpp-Makefile >ansi-Makefile fi diff -rc2 bash-1.14.1/support/srcdir bash-1.14.2/support/srcdir *** bash-1.14.1/support/srcdir Fri Jul 1 11:21:31 1994 --- bash-1.14.2/support/srcdir Fri Aug 5 17:20:32 1994 *************** *** 6,10 **** case "$1" in ! '.') pwd ;; *) echo "$1" ;; esac --- 6,11 ---- case "$1" in ! '.'|./) pwd ;; ! ./*|..*) echo `pwd`/"$1" ;; *) echo "$1" ;; esac diff -rc2 bash-1.14.1/test.c bash-1.14.2/test.c *** bash-1.14.1/test.c Fri Jul 1 11:20:47 1994 --- bash-1.14.2/test.c Wed Aug 10 15:52:36 1994 *************** *** 135,138 **** --- 135,139 ---- static int argc; /* The number of arguments present in ARGV. */ static char **argv; /* The argument list. */ + static int noeval; static int isint (); *************** *** 182,186 **** { int fd; ! if (isint (path + 9, &fd)) return (fstat (fd, finfo)); else --- 183,187 ---- { int fd; ! if (isint (path + 8, &fd)) return (fstat (fd, finfo)); else *************** *** 1120,1123 **** --- 1121,1125 ---- test_exit (SHELL_BOOLEAN (FALSE)); + noeval = 0; value = posixtest (); diff -rc2 bash-1.14.1/tests/misc/gotest bash-1.14.2/tests/misc/gotest *** bash-1.14.1/tests/misc/gotest Fri Jul 1 11:21:49 1994 --- bash-1.14.2/tests/misc/gotest Tue Jul 26 16:54:05 1994 *************** *** 19,23 **** if [ "$OPTIND" -gt 1 ] then ! shift $[$OPTIND - 1] fi --- 19,23 ---- if [ "$OPTIND" -gt 1 ] then ! shift $(( $OPTIND - 1 )) fi diff -rc2 bash-1.14.1/tests/run-all bash-1.14.2/tests/run-all *** bash-1.14.1/tests/run-all Fri Jul 1 11:21:43 1994 --- bash-1.14.2/tests/run-all Fri Jul 8 09:23:30 1994 *************** *** 9,12 **** --- 9,13 ---- case $x in $0) ;; + *.orig|*~) ;; *) echo $x ; sh $x ;; esac diff -rc2 bash-1.14.1/variables.c bash-1.14.2/variables.c *** bash-1.14.1/variables.c Fri Jul 1 11:20:44 1994 --- bash-1.14.2/variables.c Thu Jul 14 12:27:36 1994 *************** *** 102,105 **** --- 102,106 ---- static void initialize_dynamic_variables (); static void sbrand (); /* set bash random number generator. */ + static int qsort_var_comp (); /* Make VAR be auto-exported. VAR is a pointer to a SHELL_VAR. */ *************** *** 482,485 **** --- 483,493 ---- } + void + sort_variables (array) + SHELL_VAR **array; + { + qsort (array, array_len ((char **)array), sizeof (SHELL_VAR *), qsort_var_comp); + } + static int qsort_var_comp (var1, var2) *************** *** 494,504 **** } - void - sort_variables (array) - SHELL_VAR **array; - { - qsort (array, array_len ((char **)array), sizeof (SHELL_VAR *), qsort_var_comp); - } - /* Create a NULL terminated array of all the shell variables in TABLE. */ static SHELL_VAR ** --- 502,505 ---- *************** *** 1631,1647 **** } - /* Stupid comparison routine for qsort () ing strings. */ - int - qsort_string_compare (s1, s2) - register char **s1, **s2; - { - int result; - - if ((result = **s1 - **s2) == 0) - result = strcmp (*s1, *s2); - - return (result); - } - /* Sort ARRAY, a null terminated array of pointers to strings. */ void --- 1632,1635 ---- *************** *** 1774,1778 **** char * getenv (name) ! #if defined (Linux) || defined (__bsdi__) const char *name; #else --- 1762,1766 ---- char * getenv (name) ! #if defined (Linux) || defined (__bsdi__) || defined (convex) const char *name; #else diff -rc2 bash-1.14.1/variables.h bash-1.14.2/variables.h *** bash-1.14.1/variables.h Fri Jul 1 11:20:50 1994 --- bash-1.14.2/variables.h Thu Jul 14 12:20:48 1994 *************** *** 80,84 **** extern int assignment __P((char *)); extern int variable_in_context __P((SHELL_VAR *)); - extern int qsort_string_compare __P((char **, char **)); extern int assign_in_env __P((char *)); extern int unbind_variable __P((char *)); --- 80,83 ----