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 ! !