From 96f66efe6fccbd914d3c92a45405af9a7cf25704 Mon Sep 17 00:00:00 2001 From: Chet Ramey Date: Thu, 9 Jul 2015 15:47:46 -0400 Subject: [PATCH] bash-4.4 alpha release --- CWRU/changelog | 8959 +++++++++++++++++++++++++++++++++++- NEWS | 128 + builtins/wait.def | 1 + jobs.c | 12 + jobs.h | 2 + lib/readline/COPYING | 675 ++- lib/readline/ansi_stdlib.h | 55 +- lib/readline/doc/fdl.texi | 507 +- lib/readline/posixdir.h | 72 +- lib/readline/posixjmp.h | 47 +- lib/readline/posixselect.h | 48 +- lib/readline/posixstat.h | 143 +- lib/readline/tilde.c | 507 +- lib/readline/tilde.h | 81 +- nojobs.c | 7 + support/mkconffiles | 0 support/mkversion.sh | 0 support/rlvers.sh | 0 support/shobj-conf | 0 tests/coproc.tests | 5 +- tests/trap.right | 1 - tests/trap.tests | 1 + y.tab.c | 8598 ++++++++++++++++++++++++++++++++++ y.tab.h | 174 + 24 files changed, 20009 insertions(+), 14 deletions(-) mode change 120000 => 100644 CWRU/changelog mode change 120000 => 100644 lib/readline/COPYING mode change 120000 => 100644 lib/readline/ansi_stdlib.h mode change 120000 => 100644 lib/readline/doc/fdl.texi mode change 120000 => 100644 lib/readline/posixdir.h mode change 120000 => 100644 lib/readline/posixjmp.h mode change 120000 => 100644 lib/readline/posixselect.h mode change 120000 => 100644 lib/readline/posixstat.h mode change 120000 => 100644 lib/readline/tilde.c mode change 120000 => 100644 lib/readline/tilde.h mode change 100644 => 100755 support/mkconffiles mode change 100644 => 100755 support/mkversion.sh mode change 100644 => 100755 support/rlvers.sh mode change 100644 => 100755 support/shobj-conf create mode 100644 y.tab.c create mode 100644 y.tab.h diff --git a/CWRU/changelog b/CWRU/changelog deleted file mode 120000 index d2d81b302..000000000 --- a/CWRU/changelog +++ /dev/null @@ -1 +0,0 @@ -CWRU.chlog \ No newline at end of file diff --git a/CWRU/changelog b/CWRU/changelog new file mode 100644 index 000000000..6b15257b2 --- /dev/null +++ b/CWRU/changelog @@ -0,0 +1,8958 @@ + 2/14/2011 + --------- +[bash-4.2 released] + + 2/15 + ---- +lib/glob/gmisc.c + - fix wmatchlen and umatchlen to avoid going past the end of the + string on an incomplete bracket expression that ends with a + NUL. Partial fix for bug reported by Clark Wang + + 2/16 + ---- +subst.h + - new string extract flag value: SX_WORD. Used when calling + extract_dollar_brace_string to skip over the word in + ${param op word} from parameter_brace_expand + +subst.c + - change parameter_brace_expand to add SX_WORD to flags passed to + extract_dollar_brace_string + - change parameter_brace_expand to use SX_POSIXEXP for all non-posix + word expansion operators that treat single quotes as special, not + just % and # + - change extract_dollar_brace_string to initialize dolbrace_state to + DOLBRACE_WORD if SX_WORD flag supplied and we shouldn't use + DOLBRACE_QUOTE. Fixes bug reported by Juergen Daubert + +doc/{bash.1,bashref.texi} + - document the exact expansions here strings undergo + + 2/17 + ---- +lib/readline/vi_mode.c + - make sure that `dd', `cc', and `yy' call vidomove_dispatch from + rl_domove_read_callback. Fixes bug reported by Clark Wang + + +lib/readline/callback.c + - make sure _rl_internal_char_cleanup is called after the + vi-motion callbacks (rl_vi_domove_callback) in rl_callback_read_char. + Companion to above fix + +doc/{bash.1,bashref.texi} + - make sure that the text describing the rhs of the == and =~ + operators to [[ states that only the quoted portion of the pattern + is matched as a string + + 2/18 + ---- +lib/glob/gmisc.c + - better fix for umatchlen/wmatchlen: keep track of the number of + characters in a bracket expression as the value to increase + matchlen by if the bracket expression is not well-formed. Fixes + bug reported by Clark Wang + +subst.c + - change expand_string_for_rhs so that it sets the W_NOSPLIT2 flag + in the word flags. We will not perform word splitting or quote + removal on the result, so we do not want to add quoted nulls if + we see "" or ''. Fixes bug reported by Mike Frysinger + + + 2/19 + ---- +variables.c + - new function, int chkexport(name), checks whether variable NAME is + exported and remakes the export environment if necessary. Returns + 1 if NAME is exported and 0 if not + - call chkexport(name) to get tzset to look at the right variable in + the environment when modifying TZ in sv_tz. Don't call tzset if + chkexport doesn't indicate that the variable is exported + +variables.h + - new extern declaration for chkexport + + +{parse.y,builtins/printf.def} + - call sv_tz before calling localtime() when formatting time strings + in prompt strings or using printf. Fixes bug reported by + Dennis Williamson + +execute_cmd.c + - modify fix of 2/9 to add casts when those variables are passed to + functions; some compilers throw errors instead of warnings. Report + and fix from Joachim Schmitz + +support/shobj-conf + - add a stanza for nsk on the Tandem from Joachim Schmitz + + +{shell,lib/readline/shell}.c + - Tandem systems should use getpwnam (getlogin()); for some reason + they don't do well with using getuid(). Fix from Joachim Schmitz + + + 3/1 + --- +variables.c + - make sure that the return value from find_variable is non-null + before trying to use it in chkexport. Fixes bug reported by + Evangelos Foutras + + 3/3 + --- +parse.y + - when adding $$ to the current token buffer in read_token_word(), + don't xmalloc a buffer for two characters and then strcpy it, just + copy the characters directly into the token buffer. Fix from + Michael Whitten + +execute_cmd.c + - fix expand_word_unsplit to add the W_NOSPLIT2 flag to the word to + be expanded, so "" doesn't add CTLNUL. Similar to fix of 2/18 to + expand_string_for_rhs. Fixes bug reported by Nathanael D. Noblet + and Matthias Klose + +parse.y + - fix extended_glob case of read_token_word to allocate an extra + space in the buffer for the next character read after the extended + glob specification if it's a CTLESC or CTLNUL. Report and fix from + Michael Witten + - fix shell expansions case of read_token_word to allocate an extra + space in the buffer for the next character read after the shell + expansion if it's a CTLESC or CTLNUL. Report and fix from + Michael Witten + - TENTATIVE: fix read_token_word to reduce the amount of buffer space + required to hold the translated and double-quoted value of $"..." + strings. Report and fix from Michael Witten + - change code around got_character and got_escaped_character labels to + make sure that we call RESIZE_MALLOCED_BUFFER before adding the + CTLESC before a CTLESC or CTLNUL, and before adding the character if + we're not adding a CTLESC. Report and fix from + Michael Witten + +subst.c + - new param flags value, PF_ASSIGNRHS, mirrors W_ASSIGNRHS, noting that + parameter expansion is on rhs of assignment statement. That inhibits + word splitting + - change param_expand to call string_list_dollar_at with quoted == 1 + if PF_ASSIGNRHS is set, so it will quote IFS characters in the + positional parameter before separating them with the first char of + $IFS. This keeps the rhs from being split inappropriately. Fixes + bug reported by Andres Perera + + 3/4 + --- +lib/readline/bind.c + - add a missing free of `names' in rl_function_dumper. Bug report + and fix from Michael Snyder + + 3/5 + --- +lib/readline/rltty.c + - change rl_deprep_terminal so it uses fileno (stdin) for the tty fd + if rl_instream is not set, like rl_prep_terminal + + 3/6 + --- +lib/readline/display.c + - fix rl_message to use a dynamically-allocated buffer instead of a + fixed-size buffer of 128 chars for the `local message prompt'. Bug + report and fix from Micah Cowan + + 3/7 + --- +jobs.c + - add sentinel to wait_sigint_handler so it only sets wait_sigint_received + if waiting_for_child is non-zero; otherwise, it restores the old + SIGINT handler and sends itself the SIGINT + - set waiting_for_child around the calls to waitchld that use it to + synchronously wait for a process + - change logic that decides whether or not the child process blocked + or handled SIGINT based on whether or not waitpid returns -1/EINTR + and the shell receives a SIGINT and the child does not exit. If + the child later exits due to SIGINT, cancel the assumoption that it + was handled + - instead of testing whether or not the child exited due to SIGINT + when deciding whether the shell should act on a SIGINT it received + while waiting, test whether or not we think the child caught + SIGINT. If it did, we let it go (unless the shell has it trapped); + if it did not catch it, the shell acts on the SIGINT. Fix from + Linus Torvalds , bug report originally + from Oleg Nesterov + + 3/8 + --- +shell.c + - initialize no_line_editing to 1 if READLINE is not defined -- we + can't have line editing without readline + + 3/12 + ---- +lib/readline/signals.c + - add SIGHUP to the set of signals readline handles + +lib/readline/doc/rltech.texi + - document that SIGHUP is now part of the set of signals readline + handles + +lib/readline/input.c + - if _rl_caught_signal indicates that read() was interrupted by a + SIGHUP or SIGTERM, return READERR or EOF as appropriate + - call rl_event_hook, if it's set, if call to read in rl_getc + returns -1/EINTR. If rl_event_hook doesn't do anything, this + continues the loop as before. This handles the other fatal + signals + +execute_cmd.c + - add a couple of QUIT; calls to execute_disk_command and + execute_simple_command to improve responsiveness to interrupts + and fatal signals + +input.c + - rearrange getc_with_restart so that the return values from read() + are handled right + +parse.y + - don't need to set terminate_immediately in yy_stream_get, since + getc_with_restart checks for terminating signals itself + - since readline returns READERR on SIGHUP or SIGTERM, don't need + to set terminate_immediately. Still doesn't handle other + signals well -- will have to check that some more + +bashline.c + - new function, bash_event_hook, for rl_event_hook. Just checks for + terminating signals and acts on them using CHECK_TERMSIG. + - set rl_event_hook to bash_event_hook + +builtins/read.def + - take out setting terminate_immediately; add calls to CHECK_TERMSIG + after read calls + +doc/{bash.1,bashref.texi} + - move the text describing the effect of negative subscripts used to + reference indexed array elements to the paragraphs describing + ${parameter[subscript]}, since that's where they are implemented. + Pointed out by Christopher F. A. Johnson + +arrayfunc.[ch],subst.c + - array_expand_index now takes a new first argument: a SHELL_VAR * + of the array variable being subscripted. Can be used later to fully + implement negative subscripts + + 3/14 + ---- +lib/glob/glob.c + - fix mbskipname to not turn the directory entry name into a wide char + string if the conversion of the pattern to a wide char string fails + - fix mbskipname to call skipname if either the pattern or the filename + can't be converted into a wide-char string + +lib/glob/xmbsrtowcs.c + - fix xdupmbstowcs2 to handle return value of 0 from mbsnrtowcs and + short-circuit with failure in that case. Fixes bug reported by + Roman Rakus + + 3/15 + ---- +bashline.c + - new variable, bash_filename_quote_characters to store the value + assigned to rl_filename_quote_characters so it can be restored + if changed. + - change bashline_reset and attempt_shell_completion to restore + rl_filename_quote_characters if not set to default + + 3/22 + ---- +lib/glob/glob.c + - wdequote_pathname falls back to udequote_pathname if xdupmbstowcs + fails to convert the pathname to a wide-character string + +lib/glob/xmbsrtowcs.c + - xdupmbstowcs2: change to fix problem with leading '\\' (results in + nms == 0, which causes it to short-circuit with failure right + away). Fixes bug pointed out by Werner Fink + - xdupmbstowcs2: compensate for mbsnrtowcs returning 0 by taking the + next single-byte character and going on + - xdupmbstowcs2: change memory allocation to increase by WSBUF_INC + bytes; try to avoid calls to realloc (even if they don't actually + result in more memory being allocated) + + 3/24 + ---- +doc/{bash.1,bashref.texi} + - slightly modify BASH_SUBSHELL description based on complaint from + Sam Liddicott + + 3/25 + ---- +trap.c + - change free_trap_strings to not call free_trap_string for signals + that are being ignored, like reset_or_restore_signal_handlers. + Fixes bug reported by Satoshi Takahashi + + 3/26 + ---- +lib/readline/rltypedefs.h + - remove old Function/VFunction/CPFunction/CPPFunction typedefs as + suggested by Tom Tromey + +lib/readline/rlstdc.h + - move defines for USE_VARARGS/PREFER_STDARG/PREFER_VARARGS from + config.h.in to here because declaration of rl_message in + readline.h uses the defines. This makes it hard for another packages + to use after the header files are installed, since config.h is not + one of the installed files. Suggested by Tom Tromey + + + 3/27 + ---- +print_cmd.c + - change indirection_string from a static buffer to a dynamic one + managed by indirection_level_string(), so we don't end up truncating + PS4. Suggested by Dennis Williamson + +lib/readline/shell.c + - change sh_set_lines_and_columns to use static buffers instead of + allocating the buffers to pass to setenv/putenv + +lib/readline/terminal.c + - change _rl_get_screen_size to not call sh_set_lines_and_columns if + ignore_env == 0 + - _rl_sigwinch_resize_terminal: new function to just retrieve terminal + size, ignoring environment + +lib/readline/rlprivate.h + - new external declaration for _rl_sigwinch_resize_terminal() (currently + unused) + +lib/readline/signals.c + - rl_sigwinch_handler: set _rl_caught_signal to SIGWINCH + - rl_sigwinch_handler: don't immediately call rl_resize_terminal; just + leave _rl_caught_signal set for RL_CHECK_SIGNALS to handle + - _rl_signal_handler: call rl_resize_terminal if sig == SIGWINCH. + Should fix hang when sending multiple repeated SIGWINCH reported by + Henning Bekel + + 3/29 + ---- +lib/sh/snprintf.c + - include math.h for any defines for isinf/isnan + - use code from gnulib documentation to implement isinf/isnan if they + are not defined + +configure.in + - don't check for isinf or isnan; c99 says they're macros anyway + +config.h.in + - remove defines for ISINF_IN_LIBC and ISNAN_IN_LIBC, no longer used + by snprintf.c + + 4/2 + --- +braces.c + - brace_gobbler: fix to understand double-quoted command substitution, + since the shell understands unquoted comsubs. Fixes bug reported + by Michael Whitten + +lib/readline/display.c + - include on MDOS + - get and set screen size using DJGPP-specific calls on MSDOS + - move cursor up clear screen using DJGPP-specific calls + - don't call tputs on DJGPP; there is no good terminfo support + +lib/readline/terminal.c + - include on MDOS + - get and set screen size using DJGPP-specific calls on MSDOS + - use DJGPP-specific initialization on MSDOS, zeroing all the + _rl_term_* variables + - don't call tputs on DJGPP; there is no good terminfo support + DJGPP support from Eli Zaretskii + + 4/6 + --- + +config-top.h + - change DEFAULT_PATH_VALUE to something more useful and modern + + 4/8 + --- +tests/printf2.sub + - make sure LC_ALL and LC_CTYPE are set so LANG assignment takes effect. + Reported by Cedric Arbogast + + 4/11 + ---- +include/chartypes.h + - fix a couple of dicey defines (though ones that don't cause any + compiler warnings) in IN_CTYPE_DOMAIN + +doc/{bashref.texi,bash.1} + - add note referring to duplicating file descriptors in sections + describing redirecting stdout and stderr and appending to stdout + and stderr. Suggested by Matthew Dinger + +pcomplete.c + - it_init_helptopics: new function to support completing on help topics, + not just builtins + - it_helptopics: new programmable completion list of help topics + - build list of helptopic completions in gen_action_completions on + demand + +pcomplete.h + - new extern declaration for it_helptopics + +builtins/complete.def + - the `helptopic' action now maps to CA_HELPTOPIC intead of CA_BUILTIN, + since there are more help topics than just builtins. Suggested by + Clark Wang + + 4/12 + ---- +print_cmd.c + - fix print_arith_for_command to add a call to PRINT_DEFERRED_HEREDOCS + before ending the body of the command, so heredocs get attached to + the right command instead of to the loop. From gentoo bug 363371 + http://bugs.gentoo.org/show_bug.cgi?id=363371 + +execute_cmd.c + - change coproc_pidchk to unset the appropriate shell variables when + the (currently single) known coproc pid terminates + - cleanup and new functions to fully support multiple coprocesses when + and if I decide to go there + + 4/13 + ---- +print_cmd.c + - fix print_group_command to add a call to PRINT_DEFERRED_HEREDOCS + after call to make_command_string_internal before printing closing + `}' + - fix make_command_string_internal to add a call to + PRINT_DEFERRED_HEREDOCS after recursive call to + make_command_string_internal in case cm_subshell before printing + closing `)' + + 4/14 + ---- +print_cmd.c + - change overlapping strcpy in named_function_string to memmove + +sig.h + - UNBLOCK_SIGNAL: convenience define, same as UNBLOCK_CHILD, just + restores an old signal mask + +trap.c + - set_signal: instead of setting the signal handler to SIG_IGN while + installing the new trap handler, block the signal and unblock it + after the new handler is installed. Fixes bug reported by Roman + Rakus + + 4/15 + ---- +doc/{bash.1,bashref.texi} + - make it clear that enabling monitor mode means that all jobs run in + separate process groups + + 4/18 + ---- +builtins/fc.def + - update fix of 4/15/2010 to not take saved_command_line_count into + account when stepping down the history list to make sure that + last_hist indexes something that is valid. Fixes bug reported by + + + 4/19 + ---- +builtins/fc.def + - fc_gethnum: make sure the calculation to decide the last history + entry is exactly the same as fc_builtin. Fixes bug uncovered by + fix of 4/18 to stop seg fault + + 4/22 + ---- +lib/readline/terminal.c + - change _rl_enable_meta_key to set a flag indicating that it sent the + enable-meta sequence + - _rl_disable_meta_key: new function to turn off meta mode after we + turned it on with _rl_enable_meta_key + +lib/readline/rlprivate.h + - extern declaration for _rl_disable_meta_key + +configure.in + - if not cross-compiling, set CFLAGS_FOR_BUILD from any CFLAGS inherited + from the environment. Fixes HP/UX build problem reported by + "Daniel Richard G." + + 4/26 + ---- +config-top.h + - define MULTIPLE_COPROCS to 0 so the code is still disabled but easy + to enable via configure option or editing this file + + 4/29 + ---- +lib/sh/eaccess.c + - freebsd provides faccessat, with the same misfeature as their eaccess + and access implementations (X_OK returns true for uid==0 regardless + of the actual file permissions), so reorganize code to check the + file permissions as with eaccess. Report and fix from Johan Hattne + + + 5/2 + --- +doc/{bash.1,bashref.texi} + - add forward reference to `Pattern Matching' from `Pathname + Expansion', suggested by Greg Wooledge + + 5/5 + --- +pcomplib.c + - the bash_completion project now distributes over 200 completions + for various programs, with no end in sight, so increase the value + of COMPLETE_HASH_BUCKETS from 32 to 128 + +pathexp.c + - quote_string_for_globbing: make sure CTLESC quoting CTLESC is + translated into \ even if the flags include QGLOB_REGEXP. + We don't want to process the second CTLESC as a quote character. + Fixes bug reported by Shawn Bohrer + + 5/6 + --- +builtins/printf.def + - change PRETURN to not call fflush if ferror(stdout) is true + - if a call to one of the stdio functions or printstr leaves + ferror(stdout) true, and PRETURN is going to be called, let PRETURN + print the error message rather than doubling up the messages. Fixes + problem reported by Roman Rakus + + 5/9 + --- +doc/{bash.1,bashref.texi} + - add note to the effect that lists inside compound command can be + terminated by newlines as well as semicolons. Suggested by + Roman Byshko + + 5/10 + ---- +subst.c + - remove_quoted_nulls: fix problem that caused it to skip over the + character after a CTLNUL, which had the effect of skipping every + other of a series of CTLNULs. Fixes bug reported by + Marten Wikstrom + + 5/11 + ---- +subst.c + - extract_process_subst: add SX_COMMAND flag to call to + extract_delimited_string, since we're expanding the same sort of + command as command substitution. Fixes bug reported in Ubuntu + bug 779848 + + 5/12 + ---- +configure.in + - set the prefer_shared and prefer_static variables appropriately + depending on the value of $opt_static_link + +aclocal.m4 + - AC_LIB_LINKFLAGS_BODY: change to not prefer shared versions of the + libraries it's searching for if the prefer_shared variable is "no". + Fixes problem reported by Cedric Arbogast + + 5/13 + ---- +lib/readline/readline.c + - _rl_internal_teardown: add call to _rl_disable_meta_key to make the + meta key active only for the duration of the call to readline() + - _rl_internal_setup: move call to _rl_enable_meta_key here from + readline_initialize_everything so the meta key is active only for + the duration of the call to readline(). Suggestion from Miroslav + Lichvar + +builtins/help.def + - help_builtin: change strncmp to strcmp so that `help read' no longer + matches `readonly'. Suggested by Clark Wang + +config.h.in + - add define for GLIBC21, checked using jm_GLIBC21 as part of the tests + for libintl + +lib/malloc/malloc.c + - internal_free: don't use the cached value of memtop when deciding + whether or not to adjust the break and give memory back to the kernel + when using the GNU C library, since glibc uses sbrk for its own + internal purposes. From Debian bug 614815, reported by Samuel + Thibault + +aclocal.m4 + - BASH_STRUCT_WEXITSTATUS_OFFSET: change AC_RUN_IFELSE to AC_TRY_RUN + to avoid warning about not using AC_LANG_SOURCE + + 5/14 + ---- +bashline.[ch] + - two new functions, bashline_set_event_hook and bashline_reset_event_hook, + to set rl_event_hook to bash_event_hook and back to NULL, respectively + - don't set rl_event_hook unconditionally + +sig.c + - termsig_sighandler: if the shell is currently interactive and + readline is active, call bashline_set_event_hook to cause + termsig_handler to be called via bash_event_hook when the shell + returns from the signal handler + + 5/15 + ---- +lib/readline/display.c + - _rl_col_width: Mac OS X has a bug in wcwidth: it does not return 0 + for UTF-8 combining characters. Added workaround dependent on + MACOSX. Fixes problem pointed out by Thomas De Contes + + + 5/16 + ---- +lib/readline/rlmbutil.h + - WCWIDTH: wrapper for wcwidth that returns 0 for Unicode combining + characters on systems where wcwidth is broken (e.g., Mac OS X). + +lib/readline/{complete,display,mbutil}.c + - use WCWIDTH instead of wcwidth + + 5/17 + ---- +lib/readline/display.c + - update_line: after computing ofd and nfd, see whether the next + character in ofd is a zero-width combining character. If it is, + back ofd and nfd up one, so the base characters no longer compare + as equivalent. Fixes problem reported by Keith Winstein + + +lib/readline/nls.c + - _rl_utf8locale: new flag variable, set to non-zero if the current + locale is UTF-8 + - utf8locale(): new function, returns 1 if the passed lspec (or the + current locale) indicates that the locale is UTF-8. Called from + _rl_init_eightbit + +lib/readline/rlprivate.h + - extern declaration for _rl_utf8locale + +locale.c + - locale_utf8locale: new flag variable, set to non-zero if the current + locale is UTF-8 (currently unused) + - locale_isutf8(): new function, returns 1 if the passed lspec (or the + current locale) indicates that the locale is UTF-8. Should be called + whenever the locale or LC_CTYPE value is modified + +aclocal.m4 + - BASH_WCWIDTH_BROKEN: new test for whether or not wcwidth returns + zero-width characters like unicode combining characters as having + display length 1; define WCWIDTH_BROKEN in this case + +config.h.in + - WCWIDTH_BROKEN: new define + +lib/readline/rlmbutil.h + - change WCWIDTH macro to use _rl_utf8locale and the full range of + Unicode combining characters (U+0300-U+036F) + + 5/19 + ---- +lib/readline/rlprivate.h + - _rl_search_context: new member, prevc, will hold character read + prior to lastc + +lib/readline/isearch.c + - _rl_isearch_dispatch: if the character causes us to index into + another keymap, save that character in cxt->prevc + - _rl_isearch_dispatch: if we index into another keymap, but don't + find a function that's special to i-search, and the character that + caused us to index into that keymap would have terminated the + search, push back cxt->prevc and cxt->lastc to make it appear as + if `prevc' terminated the search, and execute lastc as a command. + We have to push prevc back so we index into the same keymap before + we read lastc. Fixes bug report from Davor Cubranic + + + 5/20 + ---- +expr.c + - expr_bind_variable: pay attention to the return value from + bind_variable and check whether or not we should error out due to + a readonly or noassign variable. Fixes bug reported by Eric + Blake + + 5/26 + ---- + +lib/readline/search.c + - include histlib.h for ANCHORED_SEARCH defines + - rl_history_search_flags: new variable, holds ANCHORED_SEARCH flag for + the duration of a history search + - rl_history_search_reinit: takes a new flags variable, defines whether + or not the search is anchored; assigned to rl_history_search_flags + - rl_history_serarch_reinit: if ANCHORED_SEARCH flag passed, add ^ to + beginning of search string; otherwise search string is unmodified + - rl_history_search_internal: set rl_point appropriately based on + whether or not rl_history_search_flags includes ANCHORED_SEARCH + - rl_history_substr_search_forward: new function, for non-anchored + substring search forward through history for string of characters + preceding rl_point + - rl_history_substr_search_backward: new function, for non-anchored + substring search backward through history for string of characters + preceding rl_point. Original code from Niraj Kulkarni + + +lib/readline/readline.h + - extern declarations for rl_history_substr_search_{for,back}ward + +lib/readline/funmap.c + - history-substring-search-forward: new bindable command, invokes + rl_history_substr_search_forward + - history-substring-search-backward: new bindable command, invokes + rl_history_substr_search_backward + +lib/readline/doc/{rluser.texi,readline.3} + - document history-substring-search-forward and + history-substring-search-backward + + 5/27 + ---- +{nojobs,jobs}.c + - add support for DONT_REPORT_SIGTERM so that the shell doesn't print + a message when a job exits due to SIGTERM since that's the default + signal sent by the kill builtin. Suggested by Marc Herbert + + +config-top.h + - DONT_REPORT_SIGTERM: new user-modifiable setting. Commented out + by default + + 5/28 + ---- +lib/readline/bind.c + - _rl_skip_to_delim: skip to a closing double quote or other delimiter, + allowing backslash to quote any character, including the delimiter + - rl_parse_and_bind: call _rl_skip_to_delim instead of using inline + code + - rl_parse_and_bind: allow quoted strings as the values of string + variables. Variable values without double quotes have trailing + whitespace removed (which still allows embedded whitespace, for + better or worse). Fixes problem with string variables not matching + in `set' command if values happen to have trailing spaces or tabs + (debian bash bug #602762), but introduces slight incompatibility. + + 5/29 + ---- +doc/{bash.1,bashref.texi} + - clarify unset description to specify that without options, a + variable, then a shell function if there is no variable by that + name, is unset. Fixes discrepancy reported by Mu Qiao + + + 6/4 + ---- +doc/{bash.1,bashref.texi} + - clarify description of LINES and COLUMNS (and checkwinsize shopt + option) to make it clear that only interactive shells set a + handler for SIGWINCH and update LINES and COLUMNS. Original + report submitted by Jonathan Nieder + +arrayfunc.c + - expand_compound_array_assignment: defer expansion of words between + parens when performing compound assignmnt to an associative array + variable + - assign_compound_array_list: perform the same expansions when doing + a compound array assignment to an associative array variable as + when doing a straight array index assignment. The idea is that + foo=( [ind1]=bar [ind2]=quux) + is the same as + foo[ind1]=bar ; foo[ind2]=quux + + This fixes problems with double-expansion and quote removal being + performed on the array indices + + 6/13 + ---- +doc/{bash.1,bashref.texi} + - Add a little text to make it clear that the locale determines how + range expressions in glob patterns are handled. + + + 6/21 + ---- +builtins/read.def + - display a message and return error status if -a is used with an + existing associative array. Fixes bug reported by Curtis Doty + + + 6/24 + ---- +{jobs,nojobs}.c + - non-interactive shells now react to the setting of checkwinsize + and set LINES and COLUMNS after a foreground job exits. From a + suggestion by Leslie Rhorer + +doc/{bash.1,bashref.texi} + - checkwinsize: remove language saying that only interactive shells + check the window size after each command + +lib/readline/histfile.c + - history_backupfile: new file, creates a backup history file name + given a filename (appending `-') + - history_do_write: when overwriting the history file, back it up + before writing. Restore backup file on a write error. Suggested + by chkno@chkno.net + +bashline.c + - find_cmd_name: two new arguments, return the start and end of the + actual text string used to find the command name, without taking + whitespace into account + - attempt_shell_completion: small changes to make sure that completion + attempted at the beginning of a non-empty line does not find a + programmable completion, even if the command name starts at point + - attempt_shell_completion: small change to make sure that completion + does not find a progcomp when in whitespace before the command + name + - attempt_shell_completion: small change to make sure that completion + does not find a progcomp when point is at the first character of a + command name, even when there is leading whitespace (similar to + above). Fixes problems noted by Ville Skytta + +subst.c + - brace_expand_word_list: since the individual strings in the strvec + returned by brace_expand are already allocated, don't copy them to + newly-allocated memory when building the WORD_LIST, just use them + intact + +locale.c + - locale_mb_cur_max: cache value of MB_CUR_MAX when we set or change + the locale to avoid a function call every time we need to read it + +shell.h + - new struct to save shell_input_line and associated variables: + shell_input_line_state_t + - add members of sh_parser_state_t to save and restore token and the + size of the token buffer + +parse.y + - {save,restore}_input_line_state: new functions to save and restore + shell_input_line and associated variables + - {save,restore}_parser_state: add code to save and restore the token + and token buffer size + - xparse_dolparen: call save_ and restore_input_line_state to avoid + problems with overwriting shell_input_line when we recursively + call the parser to parse a command substitution. Fixes bug + reported by Rui Santos + +include/shmbutil.h + - use locale_mb_cur_max instead of MB_CUR_MAX in ADVANCE_CHAR and + similar macros + +lib/glob/smatch.c + - rangecmp,rangecmp_wc: change to take an additional argument, which + forces the use of strcoll/wscoll when non-zero. If it's 0, a new + variable `glob_asciirange' controls whether or not we use strcoll/ + wscoll. If glob_asciirange is non-zero, we use straight + C-locale-like ordering. Suggested by Aharon Robbins + + + 6/30 + ---- +execute_cmd.c + - execute_pipeline: make sure the lastpipe code is protected by + #ifdef JOB_CONTROL. Fixes problem reported by Thomas Cort + + + 7/2 + --- +lib/readline/complete.c + - EXPERIMENTAL: remove setting of _rl_interrupt_immediately around + completion functions that touch the file system. Idea from Jan + Kratochvil and the GDB development + team + +lib/readline/signals.c + - rl_signal_handler: if we're in callback mode, don't interrupt + immediately on a SIGWINCH + + 7/3 + --- +bashline.c + - set_directory_hook: and its siblings are a new set of functions to + set, save, and restore the appropriate directory completion hook + - change callers to use {set,save,restore}_directory_hook instead of + manipulating rl_directory_rewrite_hook directly + - dircomplete_expand: new variable, defaults to 0, if non-zero causes + directory names to be word-expanded during word and filename + completion + - change {set,save,restore}_directory_hook to look at dircomplete_expand + and change rl_directory_completion_hook or rl_directory_rewrite_hook + appropriately + +bashline.h + - extern declaration for set_directory_hook so shopt code can use it + + 7/6 + --- +builtins/shopt.def + - globasciiranges: new settable shopt option, makes glob ranges act + as if in the C locale (so b no longer comes between A and B). + Suggested by Aharon Robbins + + 7/7 + --- +doc/{bash.1,bashref.texi} + - document new `globasciiranges' shopt option + + 7/8 + --- +builtins/shopt.def + - direxpand: new settable option, makes filename completion expand + variables in directory names like bash-4.1 did. + - shopt_set_complete_direxpand: new function, does the work for the + above by calling set_directory_hook + +doc/{bash.1,bashref.texi} + - document new `direxpand' shopt option + + 7/15 + ---- +lib/readline/isearch.c + - _rl_isearch_dispatch: when adding character to search string, use + cxt->lastc (which we use in the switch statement) instead of c, + since lastc can be modified earlier in the function + + 7/18 + ---- +lib/readline/rlprivate.h + - _rl_search_context: add another member to save previous value of + (multibyte) lastc: pmb is to mb as prevc is to lastc + +lib/readline/isearch.c: + - _rl_isearch_dispatch: if a key sequence indexes into a new keymap, + but doesn't find any bound function (k[ind].function == 0) or is + bound to self-insert (k[ind].function == rl_insert), back up and + insert the previous character (the one that caused the index into a + new keymap) and arrange things so the current character is the next + one read, so both of them end up in the search string. Fixes bug + reported by Clark Wang + - _rl_isearch_dispatch: a couple of efficiency improvements when adding + characters to the isearch string + + 7/24 + ---- +lib/readline/isearch.c + - _rl_isearch_dispatch: save and restore cxt->mb and cxt->pmb + appropriately when in a multibyte locale + +doc/{bash.1,bashref.texi} + - correct description of {x}>file (and other redirection operators + that allocate a file descriptor) to note the the fd range is + greater than or equal to 10. Fixes problem reported by + Christian Ullrich + +lib/readline/signals.c + - rl_signal_handler: don't interrupt immediately if in callback mode + +lib/readline/callback.c + - rl_callback_read_char: install signal handlers only when readline + has control in callback mode, so readline's signal handlers aren't + called when the application is active (e.g., between the calls to + rl_callback_handler_install and rl_callback_read_char). If the + readline signal handlers only set a flag, which the application + doesn't know about, the signals will effectively be ignored until + the next time the application calls into the readline callback + interface. Fixes problem of calling unsafe functions from signal + handlers when in callback mode reported by Jan Kratochvil + + +execute_cmd.c + - fix_assignment_words: when in Posix mode, the `command' builtin + doesn't change whether or not the command name it protects is an + assignment builtin. One or more instances of `command' + preceding `export', for instance, doesn't make `export' treat its + assignment statement arguments differently. Posix interpretation + #351 + +doc/{bash.1,bashref.texi} + - document new Posix-mode behavior of `command' when preceding builtins + that take assignment statements as arguments + +builtins/printf.def + - printstr: if fieldwidth or precision are < 0 or > INT_MAX when + supplied explicitly (since we take care of the `-' separately), + clamp at INT_MAX like when using getint(). Fixes issue reported + by Ralph Coredroy + + 7/25 + ---- +lib/readline/chardefs.h + - isxdigit: don't define if compiling with c++; declared as a c++ + template function. Fixes bug reported by Miroslav Lichvar + + +builtins/printf.def + - getint: if garglist == 0, return whatever getintmax returns (0). + Fixes bug reported by Ralph Coredroy + + 7/28 + ---- +doc/{bash.1,bashref.texi} + - minor changes to the descriptions of the cd and pushd builtins + +lib/sh/zread.c + - zsyncfd: change variable holding return value from lseek to + off_t. Bug report and fix from Gregory Margo + + 8/1 + --- +expr.c + - don't check for division by 0 when in a context where no evaluation + is taking place. Fixes bug reported by dnade.ext@orange-ftgroup.com + + 8/6 + --- +execute_cmd.c + - execute_command_internal: the parent branch of the subshell code + (where the child calls execute_in_subshell) should not close all + open FIFOs with unlink_fifo_list if it's part of a shell function + that's still executing. Fixes bug reported by Maarten Billemont + + + 8/9 + --- +builtins/common.c + - get_exitstat: return EX_BADUSAGE (2) on a non-numeric argument + +builtins/return.def + - return_builtin: just call get_exitstat to get the return status, + let it handle proper parsing and handling of arguments. Fixes + issue most recently raised by Linda Walsh . + Reverses change from 9/11/2008 (see above) + + 8/16 + ---- +doc/{bash.1,bashref.texi} + - clean up `set -e' language to make it clearer that any failure of + a compound command will cause the shell to exit, not just subshells + and brace commands + + 8/17 + ---- +configure.in + - make the various XXX_FOR_BUILD variables `precious' to autoconf to + avoid stale data + - change how CC_FOR_BUILD is initialized when cross-compiling and not, + but do not change behavior + - initialize CFLAGS_FOR_BUILD to -g when cross-compiling + - initialize LIBS_FOR_BUILD to $(LIBS) when not cross-compiling, empty + when cross-compiling + - create AUTO_CFLAGS variable to hold basic CFLAGS defaults; used when + CFLAGS not inherited from environment (like effect of old + auto_cflags variable) + - substitute LIBS_FOR_BUILD into output Makefiles + [changes inspired by bug report from Nathan Phillip Brink + -- gentoo bug 378941] + +builtins/Makefile.in + - substitute LIBS_FOR_BUILD from configure, not strictly initialized + to $(LIBS) + + 8/27 + ---- +doc/{bash.1,bashref.texi} + - minor changes to the here string description to clarify the + expansions performed on the word + +support/shobj-conf + - handle compilation on Lion (Mac OS X 10.7/darwin11) with changes + to darwin stanzas. Fixes readline bug reported by Vincent + Sheffer + +lib/sh/strtrans.c + - ansic_wshouldquote: check a string with multi-byte characters for + characters that needs to be backslash-octal escaped for $'...' + - ansic_shouldquote: if is_basic fails for one character, let + ansic_wshouldquote examine the rest of the string and return what + it returns. From a patch sent by Roman Rakus + + 8/30 + ---- +lib/sh/strtrans.c + - ansic_quote: changes to quote (or not) multibyte characters. New + code converts them to wide characters and uses iswprint to check + valid wide chars. From a patch sent by Roman Rakus + + + 9/7 + --- +lib/sh/shquote.c + - sh_backslash_quote: change to be table-driven so we can use a + different table if we want to + - sh_backslash_quote: takes a second char table[256] argument; + +externs.h + - sh_backslash_quote: add second argument to function prototype + +bashline.c,braces.c,parse.y,builtins/printf.def + - change callers of sh_backslash_quote to add second argument + +bashline.c + - filename_bstab: table of characters to pass to sh_backslash_quote; + characters with value 1 will be backslash-quoted + - set_filename_bstab: turn on characters in filename backslash-quote + table according to passed string argument + - call set_filename_bstab every time rl_filename_quote_characters is + assigned a value + - bash_quote_filename: call sh_backslash_quote with filename_bstab + as second argument. This allows other characters in filenames to + be quoted without quoting, for instance, a dollar sign in a shell + variable reference + + 9/8 + --- +bashline.c + - complete_fullquote: new variable, controls table passed to + sh_backslash_quote. If non-zero (the default), the standard set + of shell metacharacters -- as in bash versions up to and including + bash-4.2 -- gets backslash-quoted by the completion code. If zero, + sh_backslash_quote gets the table with the characters in the + variable reference removed, which means they are removed from the + set of characters to be quoted in filenames + + 9/10 + ---- +bashline.c + - bash_filename_stat_hook: new function, designed to expand variable + references in filenames before readline passes them to stat(2) + to determine whether or not they are a directory + + 9/15 + ---- +builtins/declare.def + - if assign_array_element fails due to a bad (or empty) subscript, mark + it as an assignment error and don't attempt any further processing + of that declaration. Fixes segfault bug reported by Diego Augusto + Molina + + 9/19 + ---- +expr.c + - exppower: replace the simple exponentiation algorithm with an + implementation of exponentiation by squaring. Inspired by report + from Nicolas ARGYROU + +bashline.c + - bash_quote_filename: check for rtext being non-null before + dereferencing it + - set_saved_history: operate_and_get_next assumes that the previous + line was added to the history, even when the history is stifled and + at the max number of entries. If it wasn't, make sure the history + number is incremented properly. Partial fix for bug reported by + gregrwm + +doc/{bash.1,bashref.texi},lib/readline/doc/{hsuser,rluser}.texi + - minor editorial changes inspired by suggestions from + Roger Zauner + + 9/20 + ---- +lib/intl/localealias.c + - read_alias_file: close resource leak (fp) when returning on error + + 9/22 + ---- +execute_command.c + - execute_intern_function: implement Posix interpretation 383 by making + it an error to define a function with the same name as a special + builtin when in Posix mode. + http://austingroupbugs.net/view.php?id=383#c692 + + 9/25 + ---- +doc/{bash.1,bashref.texi} + - formatting and some content changes from Benno Schulenberg + + - document new posix-mode behavior from interp 383 change of 9/22 + + 9/30 + ---- +execute_cmd.c + - shell_execve: add strerror to error message about executable file + that shell can't execute as a shell script. From suggestion by + daysleeper + + 10/1 + ---- +bashhist.c + - maybe_add_history: act as if literal_history is set when parser_state + includes PST_HEREDOC, so we save the bodies of here-documents just + as they were entered. Fixes bug reported by Jonathan Wakely + + - bash_add_history: make sure that the second and subsequent lines of + a here document don't have extra newlines or other delimiting + chars added, since they have the trailing newline preserved, when + `lithist' is set and history_delimiting_chars isn't called + +execute_cmd.c + - execute_command_internal: avoid fd exhaustion caused by using + process substitution in loops inside shell functions by using + copy_fifo_list and close_new_fifos (). Fixes debian bash bug + 642504 + +lib/readline/complete.c + - new variable, rl_filename_stat_hook, used by append_to_match. If + filename completion is desired, and rl_filename_stat_hook points + to a function, call that function to expand the filename in an + application-specific way before calling stat. + +bashline.c + - bash_default_completion: if variable completion returns a single + match, use bash_filename_stat_hook and file_isdir to determine + whether or not the variable name expands to a directory. If it + does, set the filename_append_character to `/'. This is not + perfect, so we will see how it works out. Adds functionality + requested by Peter Toft and Patrick Pfeifer + + - rl_filename_stat_hook: assigned bash_filename_stat_hook, so things + like $HOME/Downloads (after completion) have a slash appended. + In general, this causes the stat hook to be called whenever + filename completion is appended. Adds functionality requested by + Patrick Pfeifer + +lib/readline/readline.h + - new extern declaration for rl_filename_stat_hook + +lib/readline/doc/rltech.texi + - rl_directory_rewrite_hook: now documented + - rl_filename_stat_hook: document + +pcomplete.c + - gen_action_completions: in the CA_DIRECTORY case, turn off + rl_filename_completion_desired if it was off before we called + rl_filename_completion_function and we didn't get any matches. + Having it on causes readline to quote the matches as if they + were filenames. Adds functionality requested by many, + including Clark Wang + +assoc.[ch] + - assoc_replace: new function, takes the same arguments as + assoc_insert, but returns the old data instead of freeing it + - assoc_insert: if the object returned by hash_insert doesn't have + the same value for its key as the key passed as an argument, we + are overwriting an existing value. In this case, we can free the + key. Fixes bug reported by David Parks + + 10/5 + ---- +print_cmd.c + - indirection_level_string: small change to only re-enable `x' + option after calling decode_prompt_string if it was on before. In + normal mode, it will be, but John Reiser + has a novel use for that code in conjunction with a pre-loaded + shared library that traces system call usage in shell scripts + + 10/10 + ----- +Makefile.in + - Fix from Mike Frysinger to avoid trying to + build y.tab.c and y.tab.h with two separate runs of yacc if + parse.y changes. Problem with parallel makes + - Fix from Mike Frysinger to avoid subdirectory + builds each trying to make version.h (and all its dependencies) + +lib/sh/Makefile.in + - remove some dependencies on version.h where it doesn't make sense + +variables.c + - initialize_shell_variables: while reading the environment, a shell + running in posix mode now checks for SHELLOPTS being readonly (it + gets set early on in main()) before trying to assign to it. It + saves an error message and the variable gets parsed as it should. + Fixes bug reported by Len Giambrone + + 10/14 + ----- +doc/{bash.1,bashref.texi} + - add to the "duplicating file descriptors" description that >&word + doesn't redirect stdout and stderr if word expands to `-' + - add to the "appending standard output and standard error" + description a note that >&word, where word is a number or `-', + causes other redirection operators to apply for sh and Posix + compatibility reasons. Suggested by Greg Wooledge + + + 10/15 + ----- +pcomplete.c + - change pcomp_filename_completion_function to only run the filename + dequoting function in the cases (as best as it can figure) where + readline won't do it via rl_filename_completion_function. Based + on reports from + + 10/19 + ----- +bashline.c + - attempt_shell_completion: add call to set_directory_hook() to make + sure the rewrite functions are correct. It's cheap and doesn't + hurt + - command_word_completion_function: if completing a command name that + starts with `.' or `..', temporarily suppress the effects of the + `direxpand' option and restore the correct value after calling + rl_filename_completion_function. If it's enabled, the directory + name will be rewritten and no longer match `./' or `../'. Fixes + problem reported by Michael Kalisz + + 10/22 + ----- +builtins/history.def + - push_history: make sure remember_on_history is enabled before we + try to delete the last history entry -- the `history -s' command + might not have been saved. Fixes bug reported by + lester@vmw-les.eng.vmware.com + +lib/readline/complete.c + - rl_callback_read_char: add calls to a macro CALLBACK_READ_RETURN + instead of straight return; add same call at end of function. + Placeholder for future work in deinstalling signal handlers when + readline is not active + + 10/25 + ----- +expr.c + - exp2: catch arithmetic overflow when val1 == INTMAX_MIN and val2 == -1 + for DIV and MOD and avoid SIGFPE. Bug report and pointer to fix + from Jaak Ristioja + - expassign: same changes for arithmetic overflow for DIV and MOD + + 10/28 + ----- +subst.c + - parameter_brace_expand: allow pattern substitution when there is an + expansion of the form ${var/} as a no-op: replacing nothing with + nothing + - parameter_brace_patsub: don't need to check for PATSUB being NULL; + it never is + +flags.c + - if STRICT_POSIX is defined, initialize history_expansion to 0, since + history expansion (and its treatment of ! within double quotes) is + not a conforming posix environment. From austin-group issue 500 + +lib/readline/histexpand.c + - history_expand: when processing a string within double quotes + (DQUOTE == 1), make the closing double quote inhibit history + expansion, as if the word were outside double quotes. In effect, + we assume that the double quote is followed by a character in + history_no_expand_chars. tcsh and csh seem to do this. This + answers a persistent complaint about history expansion + + 10/29 + ----- +make_cmd.c + - make_arith_for_command: use skip_to_delim to find the next `;' + when breaking the string between the double parens into three + separate components instead of a simple character loop. Fixes + bug reported by Dan Douglas + + 11/2 + ---- +Makefile.in + - make libbuiltins.a depend on builtext.h to serialize its creation + and avoid conflict between multiple invocations of mkbuiltins. + Fix from Mike Frysinger + + 11/5 + ---- +findcmd.c + - user_command_matches: if stat(".", ...) returns -1, set st_dev + and st_ino fields in dotinfo to 0 to avoid same_file matches + - find_user_command_in_path: check stat(2) return the same way + +lib/glob/glob.c + - glob_vector: don't call strlen(pat) without checking pat == 0 + - glob_dir_to_array: make sure to free `result' and all allocated + members before returning error due to malloc failure + - glob_vector: make sure to free `nextname' and `npat' on errors + (mostly when setting lose = 1) + - glob_vector: if flags & GX_MATCHDIRS but not GX_ALLDIRS, make + sure we free `subdir' + - glob_filename: when expanding ** (GX_ALLDIRS), make sure we + free temp_results (return value from glob_vector) + +lib/glob/xmbsrtowcs.c + - xdupmbstowcs: fix call to realloc to use sizeof (char *) instead + of sizeof (char **) when assigning idxtmp + +execute_cmd.c + - print_index_and_element: return 0 right away if L == 0 + - is_dirname: fix memory leak by freeing `temp' + - time_command: don't try to deref NULL `command' when assigning + to `posix_time' + - shell_execve: null-terminate `sample' after READ_SAMPLE_BUF so it's + terminated for functions that expect that + +builtins/read.def + - read_builtin: don't call bind_read_variable with a potentially-null + string + +pcomplete.c + - gen_command_matches: don't call dispose_word_desc with a NULL arg + - gen_compspec_completions: fix memory leak by freeing `ret' before + calling gen_action_completions (tcs, ...). happens when + performing directory completion as default and no completions + have been generated + - gen_progcomp_completions: make sure to set foundp to 0 whenever + returning NULL + - it_init_aliases: fix memory leak by freeing alias_list before + returning + +bashline.c + - command_word_completion_function: don't call restore_tilde with a + NULL directory_part argument + - bash_directory_expansion: bugfix: don't throw away results of + rl_directory_rewrite_hook if it's set and returns non-zero + - bind_keyseq_to_unix_command: free `kseq' before returning error + +arrayfunc.c + - assign_array_element_internal: make sure `akey' is freed if non-null + before returning error + - assign_compound_array_list: free `akey' before returning error + - array_value_internal: free `akey' before returning error + - unbind_array_element: free `akey' before returning error + +subst.c + - array_length_reference: free `akey' before returning error in case + of expand_assignment_string_to_string error + - array_length_reference: free `akey' after call to assoc_reference + - skip_to_delim: if skipping process and command substitution, free + return value from extract_process_subst + - parameter_brace_substring: free `val' (vtype == VT_VARIABLE) before + returning if verify_substring_values fails + - parameter_brace_expand: remove two duplicate lines that allocate + ret in parameter_brace_substring case + - parameter_brace_expand: convert `free (name); name = xmalloc (...)' + to use `xrealloc (name, ...)' + - parameter_brace_expand: free `name' before returning when handling + ${!PREFIX*} expansion + - split_at_delims: fix memory leak by freeing `d2' before returning + +redir.c + - redirection_error: free `filename' if the redirection operator is + REDIR_VARASSIGN by assigning allocname + +eval.c + - send_pwd_to_eterm: fix memory leak by freeing value returned by + get_working_directory() + +builtins/cd.def + - change_to_directory: fix memory leak by freeing return value from + resetpwd() + - cd_builtin: fix memory leak by freeing value returned by dirspell() + - cd_builtin: fix memory leak by freeing `directory' if appropriate + before overwriting with return value from resetpwd() + +builtins/type.def + - describe_command: free `full_path' before overwriting it with return + value from sh_makepath + +builtins/complete.def + - compgen_builtin: fix memory leak by calling strlist_dispose (sl) + before overwriting sl with return value from completions_to_stringlist + +builtins/hash.def + - list_hashed_filename_targets: fix memory leak by freeing `target' + +make_cmd.c + - make_arith_for_command: free `init', `test', and `step' before + returning error on parse error + +jobs.c + - initialize_job_control: don't call move_to_high_fd if shell_tty == -1 + +general.c + - check_dev_tty: don't call close with an fd < 0 + - legal_number: deal with NULL `string' argument, return invalid + +lib/sh/fmtulong.c + - fmtulong: if the `base' argument is invalid, make sure we index + buf by `len-1' at maximum + +print_cmd.c + - print_deferred_heredocs: don't try to dereference a NULL `cstring' + - cprintf: make sure to call va_end (args) + +variables.c + - push_dollar_vars: fix call to xrealloc to use sizeof (WORD_LIST *) + instead of sizeof (WORD_LIST **) + +lib/sh/zmapfd.c + - zmapfd: if read returns error, free result and return -1 immediately + instead of trying to reallocate it + + 11/6 + ---- +execute_cmd.c + - cpl_reap: rewrote to avoid using pointer after freeing it; now builds + new coproc list on the fly while traversing the old one and sets the + right values for coproc_list when done + + 11/12 + ----- +builtins/set.def + - if neither -f nor -v supplied, don't allow a readonly function to + be implicitly unset. Fixes bug reported by Jens Schmidt + + +lib/readline/callback.c + - change CALLBACK_READ_RETURN to clear signal handlers before returning + from rl_callback_read_char so readline's signal handlers aren't + installed when readline doesn't have control. Idea from Jan + Kratochvil and the GDB development + team + +pcomplete.h + - COPT_NOQUOTE: new complete/compgen option value + +builtins/complete.def + - noquote: new complete/compgen option; will be used to disable + filename completion quoting + +pcomplete.c + - pcomp_set_readline_variables: pay attention to COPT_NOQUOTE; turns + of rl_filename_quoting_desired if set; turns it on if unset (value + is inverted, since default is on) + +doc/bash.1,lib/readline/doc/rluser.texi + - document new -o noquote option to complete/compgen/compopt + +pathexp.c + - quote_string_for_globbing: if QGLOB_REGEXP, make sure characters + between brackets in an ERE bracket expression are not inappropriately + quoted with backslashes. This is a pretty substantial change, + should be stressed when opening bash up for alpha and beta tests. + Fixes bug pointed out by Stephane Chazleas + + +doc/{bash.1,bashref.texi} + - document that regexp matches can be inconsistent when quoting + characters in bracket expressions, since usual quoting characters + lose their meaning within brackets + - note that regular expression matching when the pattern is stored + in a shell variable which is quoted for expansion causes string + matching + +redir.h + - RX_SAVEFD: new flag value; notes that a redirection denotes an + fd used to save another even if it's not >= SHELL_FD_BASE + +redir.c + - do_redirection_internal: when deciding whether or not to reset the + close-on-exec flag on a restored file descriptor, trust the value + of redirect->flags & RX_SAVCLEXEC even if the fd is < SHELL_FD_BASE + if the RX_SAVEFD flag is set + - add_undo_redirect: set the RX_SAVEFD flag if the file descriptor + limit is such that the shell can't duplicate to a file descriptor + >= 10. Fixes a limitation that tripped a coreutils test reported + by Paul Eggert + + 11/19 + ----- +doc/{bash.1,bashref.texi},lib/readline/doc/hsuser.texi + - make it clear that bash runs HISTFILESIZE=$HISTSIZE after reading + the startup files + - make it clear that bash runs HISTSIZE=500 after reading the + startup files + - make it clear that setting HISTSIZE=0 causes commands to not be + saved in the history list + - make it clear that setting HISTFILESIZE=0 causes the history file + to be truncated to zero size + +variables.c + - sv_histsize: change so setting HISTSIZE to a value less than 0 + causes the history to be `unstifled' + - sv_histsize: change so setting HISTFILESIZE to a value less than 0 + results in no file truncation + - make it clear that numeric values less than 0 for HISTFILESIZE or + HISTSIZE inhibit the usual functions + + 11/23 + ----- +parse.y + - save_input_line_state: add missing `return ls' at the end, since the + function is supposed to return its argument. Pointed out by + Andreas Schwab + +builtins/read.def + - skip over NUL bytes in input, as most modern shells seem to. Bug + report by Matthew Story + +lib/readline/vi_mode.c + - rl_vi_replace: set _rl_vi_last_key_before_insert to invoking key + + 11/25 + ----- +builtins/read.def + - read_builtin: if xrealloc returns same pointer as first argument, + don't bother with the remove_unwind_protect/add_unwind_protect pair + - read_builtin: set a flag (`reading') around calls to zread/zreadc + and readline() + - sigalrm: change to set flag (`sigalrm_seen') and only longjmp if + currently in read(2) (reading != 0) + - CHECK_ALRM: new macro, checks sigalrm_seen and longjmps if non-zero, + behavior of old SIGALRM catching function + - read_builtin: call CHECK_ALRM in appropriate places while reading + line of input. Fixes bug reported by Pierre Gaston + + +lib/readline/vi_mode.c + - rl_vi_replace: initialize characters before printing characters in + vi_replace_keymap to their default values in vi_insertion_keymap, + since we're supposed to be in insert mode replacing characters + - rl_vi_replace: call rl_vi_start_inserting to set last command to + `R' for undo + - rl_vi_replace: set _rl_vi_last_key_before_insert to `R' for future + use by _rl_vi_done_inserting + - vi_save_insert_buffer: new function, broke out code that copies text + into vi_insert_buffer from _rl_vi_save_insert + - _rl_vi_save_replace: new function, saves text modified by + rl_vi_replace (using current point and vi_replace_count to figure + it out) to vi_replace_buffer + - _rl_vi_save_insert: call vi_save_insert_buffer + - _rl_vi_done_inserting: if _rl_vi_last_key_before_insert == 'R', call + _rl_vi_save_replace to save text modified in replace mode (uses + vi_save_insert_buffer) + - _rl_vi_replace_insert: new function, replaces the number of chars + in vi_insert_buffer after rl_point with contents ov vi_insert_buffer + - rl_vi_redo: call _rl_vi_replace_insert if last command == 'R' and + there's something in vi_insert_buffer. Fixes bug with `.' not + redoing the most recent `R' command, reported by Geoff Clare + in readline area on savannah + + 11/26 + ----- +lib/readline/rlprivate.h + - RL_SIG_RECEIVED(): evaluate to non-zero if there is a pending signal + to be handled + - RL_SIGINT_RECEIVED(): evaluate to non-zero if there is a pending + SIGINT to be handled + +lib/readline/complete.c + - remove all mention of _rl_interrupt_immediately + - rl_completion_matches: check RL_SIG_RECEIVED after each call to + the entry function, call RL_CHECK_SIGNALS if true to handle the + signal + - rl_completion_matches: if RL_SIG_RECEIVED evaluates to true, free + and zero out the match_list this function allocated + - rl_completion_matches: if the completion entry function is + rl_filename_completion_function, free the contents of match_list, + because that function does not keep state and will not free the + entries; avoids possible memory leak pointed out by + Garrett Cooper + - gen_completion_matches: if RL_SIG_RECEIVED evalutes to true after + calling rl_attempted_completion_function, free the returned match + list and handle the signal with RL_CHECK_SIGNALS; avoids + possible memory leak pointed out by Garrett Cooper + + - gen_completion_matches: if RL_SIG_RECEIVED evaluates to true after + calling rl_completion_matches, free the returned match list and + handle the signal with RL_CHECK_SIGNALS + +lib/readline/util.c + - rl_settracefp: new utility function to set the tracing FILE * + +lib/readline/signals.c + - _rl_sigcleanup: pointer to a function that will be called with the + signal and a void * argument from _rl_handle_signal + - _rl_sigcleanarg: void * that the rest of the code can set to have + passed to the signal cleanup function + - _rl_handle_signal: if _rl_sigcleanup set, call as + (*_rl_sigcleanup) (sig, _rl_sigcleanarg) + +lib/readline/rlprivate.h + - extern declarations for _rl_sigcleanup and _rl_sigcleanarg + +lib/readline/complete.c + - _rl_complete_sigcleanup: signal cleanup function for completion code; + calls _rl_free_match_list on _rl_sigcleanarg if signal == SIGINT + - rl_complete_internal: before calling display_matches if what_to_do + == `?', set _rl_sigcleanup to _rl_complete_sigcleanup so the match + list gets freed on SIGINT; avoids possible memory leak pointed out + by Garrett Cooper + - rl_complete_internal: in default switch case, call _rl_free_match_list + before returning to avoid memory leak + +doc/bashref.texi + - start at a set of examples for the =~ regular expression matching + operator, touching on keeping the pattern in a shell variable and + quoting portions of the pattern to remove their special meaning + + 12/1 + ---- +lib/glob/gmisc.c + - extglob_pattern: new function, returns 1 if pattern passed as an + argument looks like an extended globbing pattern + +lib/glob/glob.c + - skipname: return 0 immediately if extglob_pattern returns non-zero, + let the extended globbing code do the right thing with skipping + names beginning with a `.' + - mbskipname: return 0 immediately if extglob_pattern returns non-zero, + let the extended globbing code do the right thing with skipping + names beginning with a `.'. Fixes bug reported by Yongzhi Pan + + + 12/2 + ---- +lib/glob/smatch.c + - patscan, patscan_wc: no longer static so other parts of the glob + library can use them, renamed to glob_patscan, glob_patscan_wc + +lib/glob/glob.c + - extern declarations for glob_patscan, glob_patscan_wc + - wchkname: new function, does skipname on wchar_t pattern and dname, + old body of mbskipname after converting to wide chars + - extglob_skipname: new function, checks all subpatterns in an extglob + pattern to determine whether or not a filename should be skipped. + Calls skipname for each subpattern. Dname is only skipped if all + subpatterns indicate it should be. Better fix for bug reported by + Yongzhi Pan + - wextglob_skipname: wide-char version of extglob_skipname, calls + wchkname instead of calling back into mbskipname for each + subpattern to avoid problems with char/wchar_t mismatch + - skipname: call extglob_skipname if extglob_pattern returns non-zero + - mbskipname: call wextglob_skipname if extglob_pattern returns non-zero + - mbskipname: short-circuit immediately if no multibyte chars in + pattern or filename + +execute_cmd.c + - execute_cond_node: added parens to patmatch assignment statement to + make intent clearer + + 12/3 + ---- +configure.in,config.h.in + - check for imaxdiv, define HAVE_IMAXDIV if present + +expr.c + - expassign, exp2: use imaxdiv if available. Doesn't help with checks + for overflow from 10/25 + + 12/6 + ---- +lib/readline/complete.c + - compute_lcd_of_matches: if we're ignoring case in the matches, only + use what the user typed as the lcd if it matches the first match + (after sorting) up to the length of what was typed (if what the + user typed is longer than the shortest of the possible matches, use + the shortest common length of the matches instead). If it doesn't + match, use the first of the list of matches, as if case were not + being ignored. Fixes bug reported by Clark Wang + + + 12/7 + ---- +builtins/cd.def + - cd_builtin: add code to return error in case cd has more than one + non-option argument, conditional on CD_COMPLAINS define (which is + not defined anywhere) + +doc/{bash.1,bashref.texi} + - note that additional arguments to cd following the directory name + are ignored. Suggested by Vaclav Hanzl + + 12/10 + ----- +lib/readline/input.c + - rl_read_key: don't need to increment key sequence length here; doing + it leads to an off-by-one error + +lib/readline/macro.c + - rl_end_kbd_macro: after off-by-one error with rl_key_sequence_length + fixed, can decrement current_macro_index by rl_key_sequence_length + (length of key sequence that closes keyboard macro) + +lib/readline/readline.c + - _rl_dispatch_subseq: fix extra increment of rl_key_sequence_length + when ESC maps to a new keymap and we're converting meta characters + to ESC+key + - _rl_dispatch_subseq: better increment of rl_key_sequence_length + before we dispatch to a function in the ISFUNC case (where the + second increment above should have happened) + - rl_executing_keyseq: the full key sequence that ended up executing + a readline command. Available to the calling application, maintained + by _rl_dispatch_subseq, indexed by rl_key_sequence_length + - rl_executing_key: the key that was bound to the currently-executing + readline command. Same as the `key' argument to the function + +lib/readline/readline.h + - rl_executing_keyseq: extern declaration + - rl_executing_key: extern declaration + - rl_key_sequence_length: declaration moved here from rlprivate.h, + now part of public interface + +lib/readline/rlprivate.h + - new extern declaration for _rl_executing_keyseq_size, buffer size + for rl_executing_keyseq + +lib/readline/doc/rltech.texi + - documented new variables: rl_executing_key, rl_executing_keyseq, + rl_key_sequence_length + + 12/13 + ----- +bashline.c + - bash_execute_unix_command: replace ad-hoc code that searches + cmd_xmap for correct command with call to rl_function_of_keyseq + using rl_executing_keyseq; now supports key sequences longer + than two characters. Fixes bug reported by Michael Kazior + + + 12/15 + ----- +make_cmd.c + - make_function_def: don't null out source_file before calling + make_command so it can be used later on when the function definition + is executed + +execute_cmd.c + - execute_intern_function: second argument is now FUNCTION_DEF * + instead of COMMAND * + - execute_command_internal: call execute_intern_function with the + new second argument (the entire FUNCTION_DEF instead of just the + command member) + - execute_intern_function: if DEBUGGER is defined, call + bind_function_def before calling bind_function, just like + make_function_def does (might be able to take out the call in + make_function_def depending on what the debugger does with it). + Fixes bug reported by + +expr.c + - more minor changes to cases of INTMAX_MIN % -1 and INTMAX_MIN / 1; + fix typos and logic errors + + 12/16 + ----- +bashline.c + - find_cmd_start: change flags to remove SD_NOSKIPCMD so it skips over + command substitutions and doesn't treat them as command separators + - attempt_shell_completion: instead of taking first return from + find_cmd_name as command name to use for programmable completion, + use loop to skip over assignment statements. Fixes problem reported + by Raphael Droz + - attempt_shell_completion: if we don't find a command name but the + command line is non-empty, assume the other words are all assignment + statements and flag that point is in a command position so we can + do command name completion + - attempt_shell_completion: if the word being completed is the first + word following a series of assignment statements, and the + command line is non-empty, flag that point is in a command position + so we can do command name completion + +lib/readline/history.c + - history_get_time: atol -> strtol + + 12/18 + ----- +parse.y + - parser_in_command_position: external interface to the + command_token_position macro for use by other parts of the shell, + like the completion mechanism + +externs.h + - extern declaration for parser_in_command_position + + 12/19 + ----- + +builtins/read.def + - read_builtin: make sure all calls to bind_read_variable are passed + a non-null string. Fixes bug reported by Dan Douglas + + +bashline.c + - attempt_shell_completion: mark that we're in a command position if + we're at the start of the line and the parser is ready to accept + a reserved word or command name. Feature most recently suggested + by Peng Yu + + 12/21 + ----- +lib/readline/bind.c + - _rl_escchar: return the character that would be backslash-escaped + to denote the control character passed as an argument ('\n' -> 'n') + - _rl_isescape: return 1 if character passed is one that has a + backslash escape + - _rl_untranslate_macro_value: new second argument: use_escapes, if + non-zero translate to backslash escapes where possible instead of + using straight \C-x for control character `x'. Change callers + - _rl_untranslate_macro_value: now global + +lib/readline/rlprivate.h + - _rl_untranslate_macro_value: extern declaration + +lib/readline/{macro.c,readline.h} + - rl_print_last_kbd_macro: new bindable function, inspired by patch + from Mitchel Humpherys + +lib/readline/funmap.c + - print-last-kbd-macro: new bindable command, bound to + rl_print_last_kbd_macro + +lib/readline/doc/{rluser.texi,readline.3},doc/bash.1 + - print-last-kbd-macro: document. + +lib/readline/text.c + - _rl_insert_next: if we're defining a macro, make sure the key gets + added to the macro text (should really audit calls to rl_read_key() + and make sure the right thing is happening for all of them) + +bashline.[ch] + - print_unix_command_map: new function, prints all bound commands in + cmd_xmap using rl_macro_dumper in a reusable format + +builtins/bind.def + - new -X option: print all keysequences bound to Unix commands using + print_unix_command_map. Feature suggested by Dennis Williamson + (2/2011) + +doc/{bash.1,bashref.texi} + - document new `bind -X' option + + 12/24 + ----- + +doc/{bash.1,bashref.texi} + - add a couple of sentences to the description of the case modification + operators making it clearer that each character of parameter is + tested against the pattern, and that the pattern should only attempt + to match a single character. Suggested by Bill Gradwohl + + + 12/28 + ----- +shell.c + - init_noninteractive: instead of calling set_job_control(0) to + unconditionally turn off job control, turn on job control if + forced_interactive or jobs_m_flag is set + - shell_initialize: call initialize_job_control with jobs_m_flag as + argument so `bash -m script' enables job control while running the + script + +jobs.c + - initialize_job_control: if the `force' argument is non-zero, turn on + job control even if the shell is not currently interactive + (interactive == 0) + + 12/29 + ----- + +flags.h + - new extern declaration for jobs_m_flag + +builtins/{cd,set}.def,doc/{bash.1,bashref.texi} + - added text clarifying the descriptions of cd -L and -P, suggested by + Padraig Brady + - slight change to the description of `set -P' about resolving symbolic + links + +lib/readline/doc/rluser.texi + - Added an example to the programmable completion section: _comp_cd, + a completion function for cd, with additional verbiage. Text + includes a reference to the bash_completion project + + 1/1/2012 + -------- +jobs.c + - set_job_status_and_cleanup: note that a job is stopped due to + SIGTSTP (any_tstped) if job_control is set; there's no need to + test interactive + + 1/5 + --- +quit.h + - LASTSIG(): new macro, expands to signal number of last terminating + signal received (terminating_signal or SIGINT) + +trap.c + - first_pending_trap: returns lowest signal number with a trap pending + - trapped_signal_received: set to the last trapped signal the shell + received in trap_handler(); reset to 0 in run_pending_traps + +builtins/read.def + - read_builtin: changes to posix-mode (posixly_correct != 0) to make + `read' interruptible by a trapped signal. After the trap runs, + read returns 128+sig and does not assign the partially-read line + to the named variable(s). From an austin-group discussion started + by David Korn + + 1/11 + ---- +doc/{bash.1,bashref.texi} + - slight changes to the descriptions of the compat32 and compat40 shell + options to clarify their meaning + + 1/12 + ---- +lib/readline/{colors.[ch],parse-colors.[ch]} + - new files, part of color infrastructure support + +Makefile.in,lib/readline/Makefile.in + - arrange to have colors.o and parse-colors.o added to readline + library + +{configure,config.h}.in + - check for stdbool.h, define HAVE_STDBOOL_H if found + + 1/14 + ---- +lib/readline/bind.c + - colored_stats: new bindable variable, enables using colors to + indicate file type when listing completions + +lib/readline/complete.c + - _rl_colored_stats: new variable, controlled by colored-stats bindable + variable + - colored_stat_start, colored_stat_end: new functions to set and reset + the terminal color appropriately depending on the type of the + filename to be printed + - print_filename: changes to print colors if `colored-stats' variable + set. Changes contributed by Raphael Droz + + +lib/readline/readline.c + - rl_initialize_everything: add call to _rl_parse_colors to parse + color values out of $LS_COLORS. May have to add to rl_initialize + to make more dynamic if LS_COLORS changes (which doesn't happen + very often, if at all) + +lib/readline/rlprivate.h + - _rl_colored_stats: new extern declaration + +lib/readline/doc/{readline.3,rluser.texi},doc/bash.1 + - colored-stats: document new bindable readline variable + +lib/readline/colors.c + - _rl_print_color_indicator: call rl_filename_stat_hook before calling + lstat/stat so we can get color indicators for stuff like + $HOME/Applications + +lib/readline/complete.c + - stat_char: call rl_filename_stat_hook before calling lstat/stat + +findcmd.[ch],execute_cmd.c + - search_for_command: now takes a second `flags' argument; changed + header function prototype and callers + - search_for_command: if (flags & 1), put the command found in $PATH + into the command hash table (previous default behavior) + +execute_cmd.c + - is_dirname: call search_for_command with flags argument of 0 so it + doesn't try to put something in the command hash table + +bashline.c + - bash_command_name_stat_hook: a hook function for readline's + filename_stat_hook that does $PATH searching the same way that + execute_cmd.c:execute_disk_command() does it, and rewrites the + passed filename if found. Does not put names into command hash + table. This allows command name completion to take advantage + of `visible-stats' and `colored-stats' settings. + - executable_completion: new function, calls the directory completion + hook to expand the filename before calling executable_file or + executable_or_directory; change command_word_completion_function to + call executable_completion. This allows $HOME/bin/[TAB] to do + command completion and display alternatives + + 1/17 + ---- +pcomplete.c + - gen_command_matches: now takes a new second argument: the command + name as deciphered by the programmable completion code and used + to look up the compspec; changed callers (gen_compspec_completions) + - gen_shell_function_matches: now takes a new second argument: the + command that originally caused the completion function to be + invoked; changed callers (gen_compspec_completions)) + - build_arg_list: now takes a new second argument: the command name + corresponding to the current compspec; changed callers + (gen_command_matches, gen_shell_function_matches) + - build_arg_list: now uses `cmd' argument to create $1 passed to + invoked command or shell function + - gen_compspec_completions: if we skipped a null command at the + beginning of the line (e.g., for completing `>'), add a new word for + it at the beginning of the word list and increment nw and cw + appropriately. This is all a partial fix for the shortcoming + pointed out by Sung Pae + + 1/18 + ---- + +{configure,config.h}.in + - new check: check for AUDIT_USER_TTY defined in , + define HAVE_DECL_AUDIT_USER_TTY if both are found + +lib/readline/rlconf.h + - ENABLE_TTY_AUDIT_SUPPORT: new define, allows use of the Linux kernel + tty auditing system if it's available and enabled + +lib/readline/util.c + - _rl_audit_tty: new function, send a string to the kernel tty audit + system + +lib/readline/rlprivate.h + - _rl_audit_tty: new extern declaration + +lib/readline/readline.c + - readline: call _rl_audit_tty with line to be returned before returning + it if the Linux tty audit system is available and it's been enabled + in rlconf.h Original patch from Miroslav Trmac; recent request + from Miroslav Lichvar + + 1/21 + ---- + +lib/readline/readline.c: + - _rl_dispatch_subseq: add an inter-character timeout for multi-char + key sequences. Suggested by . Still needs + work to make a user-settable variable + +parse.y + - shell_getc: make code that uses the pop_alias dependent on ALIAS + define + +variables.h + - sv_tz: extern define should only depend on HAVE_TZSET + +expr.c + - expr_streval: if ARRAY_VARS is not defined, set lvalue->ind to -1; + move assignment to `ind' inside define + - expr_bind_array_element: declaration and uses need to be #ifdef + ARRAY_VARS + +arrayfunc.h + - AV_ALLOWALL, AV_QUOTED, AV_USEIND: define to 0 if ARRAY_VARS not + defined; used in subst.c unconditionally + +sig.h + - make the signal blocking functions not dependent on JOB_CONTROL + +sig.c + - sigprocmask: make the replacement definition not dependent on + JOB_CONTROL + +trap.c + - use BLOCK_SIGNAL/UNBLOCK_SIGNAL instead of code dependent on + HAVE_POSIX_SIGNALS and BSD signals + + 1/24 + ---- + +print_cmd.c + - print_redirection_list: change the conditions under which + r_duplicating_output_word is mapped to r_err_and_out to more or + less match those used in redir.c. Fixes bug pointed out by + Dan Douglas + + + 1/29 + ---- +lib/readline/signals.c + - _rl_block_sigwinch,_rl_release_sigwinch: don't compile in bodies + unless SIGWINCH is defined. Fixes bug reported by Pierre Muller + + +doc/{bash.1,bashref.texi} + - small modifications to the introduction to the REDIRECTION section + to describe how redirections can modify file handles + - small modification to the section describing base#n to make it + clearer that n can be denoted using non-numerics. From a posting + by Linda Walsh + + 2/2 + --- +builtins/printf.def + - printf_builtin: make sure vbuf is intialized and non-null when -v + is supplied, since other parts of the code assume that it's not + null (e.g., bind_printf_variable()). Fixes bug reported by Jim + Avera + + 2/4 + --- +lib/readline/undo.c + - _rl_free_undo_list: new function, old body of rl_free_undo_list, + frees undo entries in UNDO_LIST * passed as argument + - rl_free_undo_list: call _rl_free_undo_list + +lib/readline/rlprivate.h + - _rl_free_undo_list: new extern declaration + - _rl_keyseq_timeout: new extern declaration (see below) + +lib/readline/misc.c + - rl_clear_history: new function. Clears the history list and frees + all associated data similar to history.c:clear_history(), but + takes rl_undo_list into account and frees and UNDO_LISTs saved as + `data' members of a history list entry + +lib/readline/doc/rltech.texi + - rl_clear_history: documented + +lib/readline/readline.c + - _rl_keyseq_timeout: new variable to hold intra-key timeout value + from 1/21 fix; specified in milliseconds. Default value is 500 + - _rl_dispatch_subseq: change to use _rl_keyseq_timeout as intra-key + timeout if it's greater than 0; no timeout if <= 0 + - _rl_dispatch_subseq: don't check for queued keyboard input if we have + pushed or pending input, or if we're reading input from a macro + +lib/readline/bind.c + - keyseq-timeout: new bindable variable, shadows _rl_keyseq_timeout + - string_varlist: add keyseq-timeout + - sv_seqtimeout: new function to modify value of _rl_keyseq_timeout; + clamps negative values at 0 for now + - _rl_get_string_variable_value: return value for keyseq-timeout + +doc/bash.1,lib/readline/doc/{rluser.texi,readline.3} + - keyseq-timeout: documented + +lib/readline/isearch.c + - _rl_isearch_dispatch: modification to fix from 7/18 to not use + cxt->keymap and cxt->okeymap, since by the time this code is + executed, they are equal. Use `f' to check for rl_insert or + unbound func + - _rl_isearch_dispatch: if we're switching keymaps, not in + callback mode, and don't have pending or pushed input, use + _rl_input_queued to resolve a potentially ambiguous key sequence. + Suggested by Roger Zauner + - _rl_isearch_dispatch: if we have changed keymaps and resolved to + an editing function (not self-insert), make sure we stuff the + right characters back onto the input after changing the keymap + back so the right editing function is executed after the search + is terminated. Rest of fix for bug reported by Roger Zauner + + + 2/5 + --- +builtins/gen-helpfiles.c + - new file: reads struct builtin and writes the long docs to files + in the `helpdirs' subdirectory. The filename is given in the + previously-unused `handle' member of the struct builtin. Links + with `tmpbuiltins.o', which is created by Makefile to have the + right long documentation. When not cross-compiling, gets the + right #defines based on configuration options from config.h instead + of trying to parse conditional parts of def files. Fixes + shortcoming pointed out by Andreas Schwab + +builtins/Makefile.in + - tmpbuiltins.c: new generated file, created to enable creation of + separate helpfiles based on correct #defines instead of trying to + parse conditional parts of def files + - gen-helpfiles: new program to generate helpfiles, links with + tmpbuiltins.o + - HELPFILES_TARGET: new target, substituted by configure to `helpdoc' + if separate helpfiles requested + - targets: new target, libbuiltins.a and $(HELPFILES_TARGET) + - CREATED_OBJECTS: new variable, holds created object files for + make clean; changed make clean to remove created objects + - helpdoc: changed to call gen-helpfiles instead of mkbuiltins + +Makefile.in + - when building libbuiltins.a, recursively call make with `targets' + argument to make sure separate helpfiles get built + +configure.in + - substitute `helpdoc' as value of HELPFILES_TARGET if + --enable-separate-helpfiles supplied as configure argument + +builtins/mkbuiltins.c + - `-nofunctions': new argument, causes mkbuiltins to not write value + for function implementing a particular builtin to struct builtin + and to write document file name to `handle' member of struct builtin + - no longer writes separate helpfiles; that is left to gen-helpfiles + + 2/8 + --- +subst.c + - make sure last_command_exit_value is set to a non-zero value before + any calls to report_error, since `-e' set will short-circuit + report_error. Fixes bug reported by Ewan Mellor + + +variables.c + - make_local_array_variable: added second argument; if non-zero, + function will return an existing local associative array variable + instead of insisting on an indexed array + +variable.h,subst.c + - make_local_array_variable: changed prototype and caller + +builtins/declare.def + - declare_internal: add second arg to call to make_local_array_variable; + making_array_special, which indicates we're processing an + assignment like declare a[b]=c. Fixes seg fault resulting from + a being an already-declared local associative array variable in a + function. Ubuntu bash bug 928900. + + 2/14 + ---- + +execute_cmd.c + - execute_command_internal: if redirections into or out of a loop fail, + don't try to free ofifo_list unless saved_fifo is non-zero. It's + only valid if saved_fifo is set + + 2/15 + ---- +{arrayfunc,braces,variables}.c + - last_command_exit_value: make sure it's set before any calls to + report_error, since -e will cause that to exit the shell + +builtins/common.c + - get_job_by_name: call internal_error instead of report_error so this + doesn't exit the shell + + 2/18 + ---- +builtins/evalstring.c + - parse_and_execute: make sure the file descriptor to be redirected to + is 1 before calling cat_file. One fix for bug reported by Dan Douglas + + +parse.y + - read_token_word: don't return NUMBER if a string of all digits + resolves to a number that overflows the bounds of an intmax_t. + Other fix for bug reported by Dan Douglas + + 2/19 + ---- +lib/sh/strtrans.c + - ansicstr: use 0x7f as the boundary for characters that translate + directly from ASCII to unicode (\u and \U escapes) instead of + UCHAR_MAX, since everything >= 0x80 requires more than one byte. + Bug and fix from John Kearney + +builtins/printf.def + - tescape: ditto for printf \u and \U escape sequences + + 2/20 + ---- +lib/sh/unicode.c + - u32toutf8: fix to handle encodings up to six bytes long correctly + (though technically UTF-8 only has characters up to 4 bytes long). + Report and fix from John Kearney + - u32toutf8: first argument is now an unsigned 32-bit quantity, + changed callers (u32cconv) to pass c instead of wc + - u32reset: new function, resets local static state to uninitialized + (locale information, currently) + +locale.c + - call u32reset whenever LC_CTYPE/LC_ALL/LANG is changed to reset the + cached locale information used by u32cconv. From a report from + John Kearney + + 2/21 + ---- +doc/{bash,builtins}.1 + - minor changes from Bjarni Ingi Gislason + +lib/sh/unicode.c + - u32cconv: only assume you can directly call wctomb on the passed + value if __STDC_ISO_10646__ is defined and the value is <= + 0x7fffffff + - stub_charset: return locale as default instead of "ASCII", let + rest of code decide what to do with it + +lib/readline/parens.c + - _rl_enable_paren_matching: make paren matching work in vi insert + mode. Bug report from + + 2/22 + ---- +lib/sh/shquote.c + - sh_backslash_quote: quote tilde in places where it would be + expanded. From a report from John Kearney + + 2/23 + ---- +execute_cmd.c + - execute_pipeline: wrap the discard_unwind_frame call in #ifdef + JOB_CONTROL, since the frame is only created if JOB_CONTROL is + defined. Bug and fix from Doug Kehn + + 2/25 + ---- +error.c + - report_error: make sure last_command_exit_value is non-zero before + we call exit_shell, since the exit trap may reference it. Call + exit_shell with last_command_exit_value to allow exit statuses + other than 1 + +unicode.c + - stub_charset: use local static buffer to hold charset, don't change + value returned by get_locale_var. Based on idea and code from + John Kearney + - u32toutf16: function to convert unsigned 32-bit value (unicode) to + UTF-16. From John Kearney + - u32cconv: call u32toutf16 if __STDC_ISO_10646__ defined and wchar_t + is two bytes, send result to wcstombs, return if not encoding error. + From John Kearney + - u32cconv: return UTF-8 conversion if iconv conversion to local + charset is unsupported + + 3/2 + --- +lib/readline/complete.c + - print_filename: if there is no directory hook, but there is a stat + hook, and we want to append a slash to directories, call the stat + hook before calling path_isdir on the expanded directory name. + Report and pointer to fix from Steve Rago + + 3/3 + --- +builtins/evalstring.c + - parse_and_execute: fix to change of 2/18: make sure the file + descriptor being redirected to is 0 before calling cat_file when + we see something like $(< file). Real fix for bug reported by + Dan Douglas + +subst.c + - parameter_brace_patsub: run the replacement string through quote + removal even if the expansion is within double quotes, because + the parser and string extract functions treat the quotes and + backslashes as special. If they're treated as special, quote + removal should remove them (this is the Posix position and + compatible with ksh93). THIS IS NOT BACKWARDS COMPATIBLE. + + 3/4 + --- +lib/readline/complete.c + - rl_menu_complete: fix to make show-all-if-ambiguous and + menu-complete-display-prefix work together if both are set. Fix + from Sami Pietila + + 3/5 + --- +bashline.c + - dircomplete_expand_relpath: new variable, if non-zero, means that + `shopt -s direxpand' should expand relative pathnames. Zero by + default, not user-settable yet + - bash_directory_completion_hook: if we have a relative pathname that + isn't changed by canonicalization or spell checking after being + appended to $PWD, then don't change what the user typed. Controlled + by dircomplete_expand_relpath + + 3/7 + --- +m4/timespec.m4 + - new macros, cribbed from gnulib and coreutils: find out whether we + have `struct timespec' and what file includes it + +m4/stat-time.m4 + - new macros, cribbed from gnulib and coreutils: find out whether the + mtime/atime/ctime/etctime fields of struct stat are of type + struct timespec, and what the name is + +include/stat-time.h + - new file, cribbed from gnulib, with additions from coreutils: include + the right file to get the struct timespec define, or provide our own + replacement. Provides a bunch of inline functions to turn the + appropriate members of struct stat into `struct timespec' values, + zeroing out the tv_nsec field if necessary + +test.c + - include "stat-time.h" for the nanosecond timestamp resolution stuff + - stat_mtime: new function, returns struct stat and the mod time + normalized into a `struct timespec' for the filename passed as the + first argument + - filecomp: call stat_mtime instead of sh_stat for each filename + argument to get the mtime as a struct timespec + - filecomp: call timespec_cmp instead of using a straight arithmetic + comparison for the -nt and -ot operators, using timespec returned by + stat_mtime. Added functionality requested by by Werner Fink + for systems that can support it + + 3/10 + ---- +include/posixdir.h + - REAL_DIR_ENTRY: remove dependency on _POSIX_SOURCE, only use feature + test macros to decide whether dirent.d_ino is present and usable; + define D_INO_AVAILABLE. Report and fix from Fabrizion Gennari + + - D_FILENO_AVAILABLE: define if we can use dirent.d_fileno + +lib/sh/getcwd.c + - use D_FILENO_AVAILABLE to decide whether or not to compile in + _path_checkino and whether or not to call it. Report and initial + fix from Fabrizion Gennari + +lib/readline/signals.c + - make sure all occurrences of SIGWINCH are protected by #ifdef + +sig.c + - make sure all occurrences of SIGCHLD are protected by #ifdef + +nojobs.c + - make sure SA_RESTART is defined to 0 if the OS doesn't define it + +version.c + - show_shell_version: don't use string literals in printf, use %s. + Has added benefit of removing newline from string to be translated + +trap.c + - queue_sigchld_trap: new function, increments the number of pending + SIGCHLD signals by the argument, which is by convention the number + of children reaped in a call to waitchld() + +trap.h + - queue_sigchld_trap: new extern declaration + +jobs.c + - waitchld: if called from the SIGCHLD signal handler (sigchld > 0), + then call queue_sigchld_trap to avoid running the trap in a signal + handler context. Report and original fix from Siddhesh Poyarekar + + +lib/sh/unicode.c + - u32tocesc: take an unsigned 32-bit quantity and encode it using + ISO C99 string notation (\u/\U) + - u32cconv: call u32tocesc as a fallback instead of u32cchar + - u32cconv: call u32tocesc if iconv cannot convert the character. + Maybe do the same thing if iconv_open fails + - u32reset: call iconv_close on localconv if u32init == 1 + + 3/11 + ---- +config-top.h + - CHECKWINSIZE_DEFAULT: new define, set to initial value of + check_window_size (shopt checkwinsize): 0 for off, 1 for on. + Default is 0 + +{jobs,nojobs}.c + - check_window_size: default initial value to CHECKWINSIZE_DEFAULT + + 3/13 + ---- +doc/bashref.texi + - change text referring to the copying restrictions to that + recommended by the FSF (no Front-Cover Texts and no Back-Cover + Texts) + +lib/readline/doc/{history,rlman,rluserman}.texi + - change text referring to the copying restrictions to that + recommended by the FSF (no Front-Cover Texts and no Back-Cover + Texts) + + 3/15 + ---- +array.c + - LASTREF_START: new macro to set the starting position for an array + traversal to `lastref' if that's valid, and to the start of the array + if not. Used in array_reference, array_insert, array_remove + - array_remove: try to be a little smarter with lastref instead of + unconditionally invalidating it + + 3/16 + ---- +array.c + - array_insert: fix memory leak by deleting element to be added in the + case of an error + + 3/18 + ---- +lib/sh/mbschr.c + - mbschr: don't call mbrlen unless is_basic is false; devolves to a + straight character-by-character run through the string + + 3/19 + ---- +stringlib.c + - substring: use memcpy instead of strncpy, since we know the length + and are going to add our own NUL terminator + + 3/20 + ---- +subst.c + - parameter_brace_expand_rhs: if expand_string_for_rhs returns a quoted + null string (a list with one element for which + QUOTED_NULL(list->word->word) returns true), return the quoted null + and set the flags in the returned word to indicate it. Fixes bug + reported by Mark Edgar + +lib/sh/tmpfile.c + - use random(3) instead of get_random_number to avoid perturbing the + random sequence you get using $RANDOM. Bug report and fix from + Jurij Mihelic + + 3/21 + ---- +config-top.h + - OPTIMIZE_SEQUENTIAL_ARRAY_ASSIGNMENT: define to 1 to optimize + sequential indexed array assignment patterns. Defined to 1 by + default + +array.c + - array_insert: if OPTIMIZE_SEQUENTIAL_ARRAY_ASSIGNMENT is defined, + start the search at lastref (see change from 3/15) + + 3/27 + ---- +print_cmd.c + - debug_print_word_list: new debugging function, prints a word list + preceded by an optional string and using a caller-specified + separator + + 4/1 + --- +command.h + - W_ASSNGLOBAL: new flag, set to indicate declare -g + +execute_cmd.c + - fix_assignment_words: note that we have a -g argument to an assignment + builtin and set the W_ASSNGLOBAL flag in the variable word + +subst.c + - dump_word_flags: print out W_ASSNGLOBAL if present + - do_assignment_internal: only set ASS_MKLOCAL if W_ASSIGNARG is set + and W_ASSNGLOBAL is not. Don't want to create a local variable even + if variable_context is non-zero if ASSNGLOBAL is set. Fixes bug + reported by Bill Gradwohl + + 4/7 + --- +lib/readline/readline.c + - _rl_dispatch_subseq: make the `keyseq-timeout' variable apply to + ESC processing when in vi mode. After hitting ESC, readline will + wait up to _rl_keyseq_timeout*1000 microseconds (if set) for + additional input before dispatching on the ESC and switching to + command/movement mode. Completes timeout work suggested by + ; this prompted by report from Barry Downes + + +lib/sh/shmbchar.c + - sh_mbsnlen: new function, returns the number of (possibly multibyte) + characters in a passed string with a passed length, examining at most + maxlen (third argument) bytes + +externs.h + - sh_mbsnlen: extern declaration for new function + +shell.c + - exit_shell: call maybe_save_shell_history if remember_on_history is + set, not just in interactive shells. That means the history is + saved if history is enabled, regardless of whether or not the shell + is interactive + +doc/{bash.1,bashref.texi} + - TMOUT: fix description to make it explicit that TMOUT is the timeout + period for a complete line of input, not just any input. Fixes + problem reported in Ubuntu bug 957303: + https://bugs.launchpad.net/ubuntu/+source/bash/+bug/957303 + - HISTFILE: document change to write history list to history file in + any shell with history enabled, not just interactive shells. This + seems to be more logical behavior. Suggested by Greg Wooledge + + + 4/12 + ---- +lib/readline/colors.h + - only include stdbool.h if HAVE_STDBOOL_H is defined + - if HAVE_STDBOOL_H is not defined, provide enough definition for the + library to use `bool', `true', and `false' + +lib/readline/parse-colors.[ch] + - don't try to include at all; rely on colors.h to do it + +lib/sh/snprintf.c + - vsnprintf_internal: only treat '0' as a flag to indicate zero padding + if `.' hasn't been encountered ((flags&PF_DOT) == 0); otherwise treat + it as the first digit of a precision specifier. Fixes bug reported + by Petr Sumbera + + 4/15 + ---- +lib/sh/snprintf.c + - vsnprintf_internal: if the '0' and '-' flags both occur, the '0' + flag is ignored -- Posix. Start of a series of fixes based on + tests and patches from Petr Sumbera + - PUT_PLUS: make sure PF_PLUS flag is specified before putting the `+' + - vsnprintf_internal: when '+' is read as a flag, don't set right- + justify flag if the LADJUST (`-') flag has already been supplied + - floating: make sure to output space padding before the `+', zero + padding after + - exponent: make sure to output space padding before the `+', zero + padding after + - exponent: only subtract one from the width for the decimal point + if we're really going to print one + - floating: use presence of PF_PLUS flag to decide whether to account + for the `+' in the padded field width. Ditto for exponent() + + 4/16 + ---- +lib/sh/snprintf.c + - vsnprint_internal: only reduce precision by 1 when processing the `g' + format if it's > 0. A precision of 0 should stay 0; otherwise it + gets set to -1 (NOT_FOUND) and converted to the default + - number, lnumber: if an explicit precision is supplied, turn off the + zero-padding flag and set the pad character back to space + - number, lnumber: only account for a `+' when performing the field + width calculation if the coversion is base 10; we don't add a `+' + for other bases + + 4/18 + ---- +tests/printf3.sub + - try using "perl -e 'print time'" to get the current time in seconds + since the epoch if "date +%s" is not available (solaris 8-10) + + 4/19 + ---- +tests/run-printf + - use cat -v instead of relying on diff -a being available to convert + control characters to ascii and avoid the dreaded "Binary files + /tmp/xx and printf.right differ" + + 4/20 + ---- +lib/sh/strftime.c + - incoporated new version from Aharon Robbins + + 4/22 + ---- +doc/{bash.1,bashref.texi} + - slight change to the description of /dev/tcp and /dev/udp + +subst.c + - match_wpattern: logic fix to the calculation of `simple' (was |=, + needs to be &=). Bug report from Mike Frysinger , + fix from Andreas Schwab + +bashline.c + - bash_filename_stat_hook: add code from bash_directory_completion_hook + that performs pathname canonicalization in the same way that cd and + other builtins will do + + 4/25 + ---- +execute_cmd.c + - execute_pipeline: change the call to move_to_high_fd to make it use + getdtablesize() and to not stomp on existing open file descriptors, + like the fd the shell is using to read a script. Bug report from + Greg Wooledge + + 5/6 + --- +subst.c + - expand_word_internal: case '$': after calling param_expand and + setting had_quoted_null, set TEMP to null. The code that builds the + returned string at the end of the function will take care of making + and returning a quoted null string if there's nothing else in + ISTRING. If there is, the quoted null should just go away. Part of + fix for bug reported by Ruediger Kuhlmann + - expand_word_internal: when processing ISTRING to build return value, + only set W_HASQUOTEDNULL in the returned word flags if the word is + a quoted null string AND had_quoted_null is set. Rest of fix + + 5/9 + --- +variables.c + - bind_variable_internal: if we get an array variable here (implicit + assignment to index 0), call make_array_variable_value, which + dummies up a fake SHELL_VAR * from array[0]. This matters when + we're appending and have to use the current value + - bind_variable_internal: after computing the new value, treat assoc + variables with higher precedence than simple array variables; it + might be that a variable has both attributes set + +arrayfunc.c + - bind_array_var_internal: break code out that handles creating the + new value to be assigned to an array variable index into a new + function, make_array_variable_value. This handles creating a + dummy SHELL_VAR * for implicit array[0] assignment. Fixes bug + reported by Dan Douglas + +arrayfunc.h + - make_array_variable_value: new extern declaration + + 5/19 + ---- +variables.c + - bind_int_variable: if an assignment statement like x=y comes in + from the expression evaluator, and x is an array, handle it like + x[0]=y. Fixes bug reported by Dan Douglas + + 5/24 + ---- + +braces.c + - mkseq: handle possible overflow and break the sequence generating + loop if it occurs. Fixes OpenSUSE bug 763591: + https://bugzilla.novell.com/show_bug.cgi?id=763591 + + 5/25 + ---- +Makefile.in + - LDFLAGS_FOR_BUILD: add to compilation recipes for build tools + buildversion, mksignames, mksyntax + - LDFLAGS_FOR_BUILD: add to compilation recipes for test tools + recho, zecho, printenv, xcase + +builtins/Makefile.in + - LDFLAGS_FOR_BUILD: add to compilation recipes for build tools + gen-helpfiles, psize.aux + +variables.c + - bind_int_variable: if LHS is a simple variable name without an array + reference, but resolves to an array variable, call + bind_array_variable with index 0 to make x=1 equivalent to x[0]=1. + Fixes bug reported by Dan Douglas + + 5/27 + ---- +subst.c + - expand_word_internal: make sure has_dollar_at doesn't get reset before + recursive calls to param_expand or expand_word_internal, since it has + to save state of what came before. Use temp variable and make sure + has_dollar_at is incremented if recursive call processes "$@". + Fixes bug reported by gregrwm and + supplemented by Dan Douglas + +doc/{bash.1,bashref.texi} + - changes to the description of substring expansion inspired by + suggestions from Bill Gradwohl + +doc/bashref.texi + - added substring expansion examples inspired by suggestions from + Bill Gradwohl + +variables.c + - find_shell_variable: search for a variable in the list of shell + contexts, ignore the temporary environment + - find_variable_tempenv: search for a variable in the list of shell + contexts, force search of the temporary environment + - find_variable_notempenv: search for a variable in the list of shell + contexts, don't force search of the temporary environment + +variables.h + - find_shell_variable: extern declaration + - find_variable_tempenv: extern declaration + - find_variable_notempenv: extern declaration + +arrayfunc.c + - bind_array_variable: call find_shell_variable instead of calling + var_lookup directly + +findcmd.c + - search_for_command: call find_variable_tempenv instead of + find_variable_internal directly + - _find_user_command_internal: call find_variable_tempenv instead of + find_variable_internal directly + +builtins/setattr.def + - set_var_attribute: call find_variable_notempenv instead of + find_variable_internal directly + - show_name_attributes: call find_variable_tempenv instead of + find_variable_internal directly + + 6/1 + --- +sig.c + - termsig_handler: don't try to save the shell history on a terminating + signal any more, since it just causes too many problems on Linux + systems using glibc and glibc malloc + +lib/readline/vi_mode.c + - rl_vi_change_to: change to correctly redo `cc', since `c' is not a vi + motion character. From Red Hat bug 813289 + - rl_vi_delete_to: change to correctly redo `dd', since `d' is not a vi + motion character + - rl_vi_yank_to: change to correctly redo `yy', since `y' is not a vi + motion character + + 6/4 + --- +lib/sh/mktime.c + - current versions of VMS do not need to include . Fix from + John E. Malmberg + + 6/5 + --- +lib/sh/eaccess.c + - sh_stat: instead of using a static buffer to do the DEV_FD_PREFIX + translation, use a dynamically-allocated buffer that we keep + resizing. Fixes potential security hole reported by David Leverton + + + 6/5 + --- +braces.c + - expand_seqterm: check errno == ERANGE after calling strtoimax for + rhs and incr. Part of a set of fixes from Scott McMillan + + - expand_seqterm: incr now of type `intmax_t', which changes + arguments to mkseq + - mkseq: a better fix for detecting overflow and underflow since it's + undefined in C and compilers `optimize' out overflow checks. Uses + ADDOVERFLOW and SUBOVERFLOW macros + - mkseq: use sh_imaxabs (new macro) instead of abs() for intmax_t + variables + - mkseq: don't allow incr to be converted to -INTMAX_MIN + - mkseq: make sure that strvec_create isn't called with a size argument + greater than INT_MAX, since it only takes an int + + 6/6 + --- +braces.c + - mkseq: try and be smarter about not overallocating elements in + the return array if the increment is not 1 or -1 + + 6/7 + --- +parse.y + - history_delimiting_chars: if the parser says we're in the middle of + a compound assignment (PST_COMPASSIGN), just return a space to avoid + adding a stray semicolon to the history entry. Fixes bug reported + by "Davide Brini" + + 6/8 + --- +bashline.c + - bash_directory_completion_hook: don't attempt spelling correction + on the directory name unless the direxpand option is set and we are + going to replace the directory name with the corrected one in the + readline line. Suggested by Linda Walsh + +lib/sh/shquote.c + - sh_backslash_quote: now takes a third argument: flags. If non-zero, + tildes are not backslash-escaped. Have to handle both printf %q, + where they should be escaped, and filename completion, where they + should not when used as usernames + +externs.h + - sh_backslash_quote: declaration now takes a third argument + +builtins/printf.def + - printf_builtin: call sh_backslash_quote with 1 as third argument + so tildes get escaped + +{bashline,bracecomp}.c + - call sh_backslash_quote with 0 as third argument so tildes are not + escaped in completed words + +doc/bash.1 + - add `coproc' to the list of reserved words. From a report by + Jens Schweikhardt + + 6/10 + ---- +execute_cmd.c + - line_number_for_err_trap: now global, so parse_and_execute can save + and restore it with unwind-protect + +builtins/evalstring.c + - parse_prologue: save and restore line_number_for_err_trap along + with line_number + - restore_lastcom: new function, unwind-protect to restore + the_printed_command_except_trap + - parse_prologue: use restore_lastcom to save and restore the value + of the_printed_command_except_trap around calls to parse_and_execute + (eval/source/.) + + 6/15 + ---- +lib/readline/complete.c + - complete_fncmp: change filename comparison code to understand + multibyte characters, even when doing case-sensitive or case-mapping + comparisons. Fixes problem reported by Nikolay Shirokovskiy + + + 6/20 + ---- +builtins/mapfile.def + - mapfile: move the line count increment and check for having read + the specified number of lines to the end of the loop to avoid + reading an additional line with zgetline. Fixes bug reported by + Dan Douglas + + 6/21 + ---- + +execute_cmd.c + - execute_pipeline: make sure `lastpipe_flag' is initialized to 0 on + all systems, since it's tested later in the function. Fixes bug + reported by John E. Malmberg + + 6/22 + ---- +mailcheck.c + - file_mod_date_changed: return 0 right away if mailstat() does not + return success. Fixes bug with using uninitialized values reported + by szymon.kalasz@uj.edu.pl + +builtins/set.def + - the `monitor' option is not available when the shell is compiled + without job control, since the underlying `m' flag is not available + +nojobs.c + - job_control: now declared as int variable, initialized to 0, never + modified + +jobs.h + - job_control: extern declaration no longer dependent on JOB_CONTROL + +execute_cmd.c + - execute_pipeline: made necessary changes so `lastpipe' shell option + is now available in all shells, even those compiled without + JOB_CONTROL defined + + 6/23 + ---- +lib/glob/glob.c + - glob_filename: check for interrupts before returning if glob_vector + returns NULL or an error. Bug reported by Serge van den Boom + , fix from Andreas Schwab + - call run_pending_traps after each call to QUIT or test of + interrupt_state, like we do in mainline shell code + - glob_vector: don't call QUIT; in `if (lose)' code block; just free + memory, return NULL, and let callers deal with interrupt_state or + other signals and traps + + 6/25 + ---- +lib/readline/input.c + - rl_read_key: restructure the loop that calls the event hook a little, + so that the hook is called only after rl_gather_tyi returns no input, + and any pending input is returned first. This results in better + efficiency for processing pending input without calling the hook + on every input character as bash-4.1 did. From a report from + Max Horn + + 6/26 + ---- +trap.c + - signal_is_pending: return TRUE if SIG argument has been received and + a trap is waiting to execute + +trap.h + - signal_is_pending: extern declaration + +lib/glob/glob.c + - glob_vector: check for pending SIGINT trap each time through the loop, + just like we check for interrupt_state or terminating_signal, and + set `lose = 1' so we clean up after ourselves and interrupt the + operation before running the trap. This may require a change later, + maybe call run_pending_traps and do that if run_pending_traps returns? + +variables.c + - sv_histtimefmt: set history_comment_character to default (`#') if + it's 0 when we're turning on history timestamps. The history code + uses the history comment character to prefix timestamps, and + leaving it at 0 effectively removes them from the history. From a + report to help-bash by Dennis Williamson + + 6/27 + ---- +lib/readline/signals.c + - rl_maybe_restore_sighandler: new function, sets handler for SIG to + HANDLER->sa_handler only if it's not SIG_IGN. Needs to be called + on same signals set using rl_maybe_set_sighandler, which does not + override an existing SIG_IGN handler (SIGALRM is ok since it does + the check inline; doesn't mess with SIGWINCH) + + 6/30 + ---- +variables.h + - additional defines for the new `nameref' variable attribute + (att_nameref): nameref_p, nameref_cell, var_setref + +variables.c + - find_variable_nameref: resolve SHELL_VAR V through chain of namerefs + - find_variable_last_nameref: resolve variable NAME until last in a + chain of possibly more than one nameref starting at shell_variables + - find_global_variable_last_nameref: resolve variable NAME until last + in a chain of possibly more than one nameref starting at + global_variables + - find_nameref_at_context: resolve SHELL_VAR V through chain of namerefs + in a specific variable context (usually a local variable hash table) + - find_variable_nameref_context: resolve SHELL_VAR V through chain of + namerefs following a chain of varible contexts + - find_variable_last_nameref_context: resolve SHELL_VAR V as in + find_variable_last_context, but return the final nameref instead of + what the final nameref resolves to + - find_variable_tempenv, find_variable_notempenv, find_global_variable, + find_shell_variable, find_variable: modified to follow namerefs + - find_global_variable_noref: look up a global variable without following + any namerefs + - find_variable_noref: look up a shell variable without following any + namerefs + - bind_variable_internal: modify to follow a chain of namerefs in the + global variables table; change to handle assignments to a nameref by + following nameref chain + - bind_variable: modify to follow chain of namerefs when binding to a + local variable + - unbind_variable: changes to unset nameref variables (unsets both + nameref and variable it resolves to) + +subst.c + - parameter_brace_expand_word: change to handle expanding nameref whose + value is x[n] + - parameter_brace_expand_indir: change to expand in ksh93-compatible + way if variable to be indirected is nameref and a simple (non-array) + expansion + - param_expand: change to expand $foo where foo is a nameref whose value + is x[n] + +execute_cmd.c + - execute_for_command: changes to implement ksh93 semantics when index + variable is a nameref + +builtins/setattr.def + - show_var_attributes: change to add `n' to flags list if att_nameref + is set + +builtins/set.def + - unset_builtin: changes to error messages to follow nameref variables + +builtins/declare.def + - document new -n option + - declare_internal: new `-n' and `+n' options + - declare_internal: handle declare -n var[=value] and + declare +n var[=value] for existing and non-existant variables. + Enforce restriction that nameref variables cannot be arrays. + Implement semi-peculiar ksh93 semantics for typeset +n ref=value + + 7/5 + --- +variables.c + - unbind_variable: unset whatever a nameref resolves to, leaving the + nameref variable itself alone + - unbind_nameref: new function, unsets a nameref variable, not the + variable it references + +variables.h + - unbind_nameref: extern declaration + +builtins/set.def + - unset_builtin: modify to add -n option, which calls unbind_nameref + leaving unbind_variable for the usual case. This required slight + changes and additions to the test suite + +doc/{bash.1,bashref.texi} + - document namerefs and typeset/declare/local/unset -n + + 7/13 + ---- +lib/sh/casemod.c + - include shmbchar.h for is_basic and supporting pieces + - sh_casemod: use _to_wupper and _to_wlower to convert wide character + case instead of TOUPPER and TOLOWER. Fixes bug reported by + Dennis Williamson , fix from + Andreas Schwab + - cval: short-circuit and return ascii value if is_basic tests true + - sh_casemod: short-circuit and use non-multibyte case modification + and toggling code if is_basic tests true + +lib/readline/signals.c + - _rl_{block,release}_sigint: remove the code that actually blocks and + releases the signals, since we defer signal handling until calls to + RL_CHECK_SIGNALS() + +lib/readline/{callback,readline,util}.c + - if HAVE_POSIX_SIGSETJMP is defined, use sigsetjmp/siglongjmp without + saving and restoring the signal mask instead of setjmp/longjmp + +lib/readline/rltty.c + - prepare_terminal_settings: don't mess with IXOFF setting if + USE_XON_XOFF defined + +doc/{bash.1,bashref.texi} + - add some text to the description of set -e clarifying its effect + on shell functions and shell function execution. Suggested by + Rainer Blome + +bashline.c + - edit_and_execute_command: increment current_command_line_count before + adding partial line to command history (for command-oriented-history + because of rl_newline at beginning of function), then reset it to 0 + before adding the dummy history entry to make sure the dummy entry + doesn't get added to previous incomplete command. Partial fix for + problem reported by Peng Yu + + 7/24 + ---- +configure.in + - interix: define RECYCLES_PIDS. Based on a report from Michael + Haubenwallner + + 7/26 + ---- +jobs.c + - make_child: call bgp_delete on the newly-created pid unconditionally. + Some systems reuse pids before cycling through an entire set of + CHILD_MAX/_SC_CHILD_MAX unique pids. This is no longer dependent + on RECYCLES_PIDS. Based on a report from Michael Haubenwallner + + +support/shobj-conf + - Mac OS X: drop MACOSX_DEPLOYMENT_TARGET=10.3 from the LDFLAGS. We + can finally kill Panther + + 7/28 + ---- +subst.c + - command_substitute: make sure last_made_pid gets reset if make_child + fails + +execute_cmd.c + - execute_command_internal: case cm_simple: decide whether or not to + wait_for a child if already_making_children is non-zero, indicates + that there is an unwaited-for child. More of fix for bug report + from Michael Haubenwallner + +jobs.c + - make_child: call delete_old_job (new_pid) unconditionally, don't + bother to check whether or not pid wrap occurred. Rest of fix for + bug report from Michael Haubenwallner + + + 7/29 + ---- +shell.c + - subshell_exit: new function, exits the shell (via call to sh_exit()) + after calling any defined exit trap + +externs.h + - subshell_exit: new extern declaration + +execute_cmd.c + - execute_command_internal: make sure to call subshell_exit for + {} group commands executed asynchronously (&). Part of fix for + EXIT trap bug reported by Maarten Billemont + +sig.c + - reset_terminating_signals: make sure to set termsigs_initialized back + to 0, so a subsequent call to initialize_terminating_signals works + right. Rest of fix for bug reported by Maarten Billemont + + +{execute_cmd,general,jobs,mailcheck,mksyntax,test}.c +builtins/{cd,fc,pushd,ulimit}.def +lib/malloc/getpagesize.h +lib/sh/{clktck,fpurge,inet_aton,mailstat,oslib,pathcanon,pathphys,spell,strerror}.c + - make inclusion of dependent on HAVE_SYS_PARAM_H + consistently + + 8/6 + --- +lib/readline/histexpand.c + - history_expand_internal: now takes an additional argument saying + whether the history expansion occurs within a quoted string, set to + the open quote character + - history_expand_internal: use new argument instead of checking prev + char and initializing quoted_search_delimiter, pass qc directly to + get_history_event, where it allows a matching quote to terminate a + string defining an event + - history_expand: change single-quote handling code so that if + history_quotes_inhibit_expansion is 0, single quotes are treated + like double quotes + - history_expand: change call to history_expand_internal to pass new + argument of `"' if double-quoted string, `'' if single-quoted string; + this lets history_expand decide what is a quoted string and what + is not + + 8/7 + --- +configure.in + - AC_CANONICAL_BUILD: invoke for later use + +lib/readline/macro.c + - _rl_prev_macro_key: new function, inverse of _rl_next_macro_key: + backs up the index into the current macro by 1 + +lib/readline/rlprivate.h + - _rl_prev_macro_key: extern declaration + + +lib/readline/readline.c + - _rl_dispatch_subseq, _rl_subseq_result: don't call _rl_unget_char + if we're currently reading from a macro; call _rl_prev_macro_key + instead. Fixes bug reported by Clark Wang + + 8/13 + ---- +builtins/evalstring.c + - evalstring(): new function, wrapper around parse_and_execute. + make sure we handle cases where parse_and_execute can call `return' + and short-circuit without cleaning up properly. We call + parse_and_execute_cleanup() then jump to the previous-saved return + location + +builtins/common.h + - extern declaration for evalstring() + +builtins/eval.def + - eval_builtin: make sure we handle `eval " ... return"' in contexts + where `return' is valid by calling evalstring(). Fixes bug with + `eval return' in sourced files reported by Clark Wang + + +trap.c + - run_pending_traps: call evalstring instead of parse_and_execute. + XXX - still needs to handle saving and restoring token state in the + presence of `return'; could use unwind_protects for that + +builtins/mapfile.def + - run_callback: call evalstring instead of parse_and_execute + + 8/15 + ---- +bashline.c + - bash_filename_stat_hook: make sure we don't free local_dirname + before using it to canonicalize any expanded filename. Make sure + it always points to *dirname and only free it if we're replacing + it. + +lib/readline/complete.c + - append_to_match: make sure we call rl_filename_stat_hook with + newly-allocated memory to avoid problems with freeing it twice + + 8/17 + ---- +variables.c,config-top.h + - if ARRAY_EXPORT is defined to 1 when variables.c is compiled, the + code that allows indexed arrays to be exported is enabled and + included + + 8/19 + ---- +shell.c + - call start_debugger from main() only if dollar_vars[1] != 0 (close + enough to a non-interactive shell, since we can be interactive with + -i while running a shell script). Fixes oddity reported by + Techlive Zheng + + 8/20 + ---- +arrayfunc.c + - quote_array_assignment_chars: don't bother quoting if the word has + not been marked as an assignment (W_ASSIGNMENT) + - quote_array_assignment_chars: turn on W_NOGLOB in the word flags + so assignment statements don't undergo globbing. Partial fix for + problems reported by Dan Douglas + + 8/21 + ---- +command.h + - W_NOBRACE: new word flag that means to inhibit brace expansion + +subst.c + - brace_expand_word_list: suppress brace expansion for words with + W_NOBRACE flag + + 8/22 + ---- +builtins/read.def + - read_builtin: don't call dequote_string on what we've read, even if + we saw an escape character, unless (input_string && *input_string). + We may have escaped an IFS whitespace character. Fixes seg fault + reported by + +execute_cmd.c + - execute_command_internal: set the_printed_command_except trap when + about to execute a ( ... ) user subshell. For now, set it only if + ERR is trapped; can relax that later. Fixes bug reported by + Mike Frysinger + + 8/23 + ---- +jobs.c + - remove references to first_pid and pid_wrap, since we're not using + them for anything anymore + + 8/24 + ---- +subst.c + - changes for W_NOBRACE everywhere appropriate: so it can be displayed + for debugging, and passed out of expand_word_internal + +doc/{bash.1,bashref.texi} + - small changes to make it clearer that the = and == operators are + equivalent, and will cause pattern matching when used with [[. + From a question from Michal Soltys + +doc/bashref.texi + - some small formatting changes from Karl Berry + + 8/27 + ---- +lib/readline/doc/{history,rlman,rluserman}.texi + - some small formatting changes from Karl Berry + +arrayfunc.c + - assign_array_element_internal, assign_compound_array_list, + unbind_array_element, array_value_internal: changes to make + assignment statements to negative indices (a[-1]=2) and unsetting + array elements using negative indices (unset 'a[-1]') work. + From suggestions by Dennis Williamson + and Chris F. A. Johnson + +subst.c + - array_length_reference: changes to make length references to array + elements using negative indices (${#a[-1]}) work + + 8/28 + ---- +doc/{bash.1,bashref.texi} + - document new treatment of negative indices to indexed arrays when + assigning, referencing, calculating length, and unsetting + + 8/29 + ---- +shell.c + - show_shell_usage: add -l to list of shell invocation options (short + for --login). From Red Hat bug 852469 + +configure.ac + - renamed from configure.in, as latest autoconf versions want. Patches + Stefano Lattarini + +MANIFEST,Makefile.in,doc/bashref.texi,support/mkconffiles + - configure.in -> configure.ac + + 9/1 + --- + +parse.y + - read_token_word: allow words like {array[ind]} to be valid redirection + words for constructs like {x} + +lib/readline/display.c + - update_line: if the first difference between the old and new lines + is completely before any invisible characters in the prompt, we + should not adjust _rl_last_c_pos, since it's before any invisible + characters. Fixed in two places + - prompt_modechar: return a character indicating the editing mode: + emacs (@), vi command (:), or vi insert (+) + - _rl_reset_prompt: new function, just calls rl_expand_prompt. Will be + inlined, placeholder for more changes + - expand_prompt: if show-mode-in-prompt is enabled, add a character to + the front of the prompt indicating the editing mode, adjusting the + various variables as appropriate to keep track of the number of + visible characters and number of screen positions + +lib/readline/bind.c + - show-mode-in-prompt: new bindable boolean variable, shadowed by + _rl_show_mode_in_prompt variable + - hack_special_boolean_var: call _rl_reset_prompt when toggling or + setting show-mode-in-prompt + +lib/readline/readline.c + - readline_internal_setup: make sure the correct vi mode keymap is set + before expanding the prompt string for the first time + +lib/readline/misc.c + - rl_emacs_editing_mode: make sure to call _rl_reset_prompt if we're + showing the editing mode in the prompt + +lib/readline/rlprivate.h + - _rl_reset_prompt, _rl_show_mode_in_prompt: extern declarations + +lib/readline/vi_mode.c + - rl_vi_insertion_mode: call _rl_reset_prompt + - rl_vi_movement_mode: call _rl_reset_prompt. Finishes changes for + showing mode in prompt string, originally requested by Miroslav + Koskar and most recently by Jordan Michael + Ziegler + +doc/bash.1,lib/readline/doc/{readline.3,rluser.texi} + - document new show-mode-in-prompt variable, off by default + + 9/3 + --- + +jobs.c + - set_childmax: new function, external mechanism for other parts of + the shell to set js.c_childmax, the number of saved exited child + statuses to remember +jobs.h + - set_childmax: extern declaration + +variables.c + - CHILD_MAX: new special variable, with sv_childmax function to + run when it changes. Setting CHILD_MAX to a value greater than + zero but less than some maximum (currently 8192) sets the number of + exited child statuses to remember. set_childmax (jobs.c) ensures + that the number does not drop below the posix-mandated minimum + (CHILD_MAX) + +doc/{bash.1,bashref.texi} + - CHILD_MAX: document new meaning and action when variable is set + + 9/5 + --- +redir.c + - redir_varassign: call stupidly_hack_special_variables after + assigning fd number to specified variable, so we can use constructs + like {BASH_XTRACEFD}>foo. Suggested by Pierre Gaston + + + 9/8 + --- +expr.c + - readtok: invalidate previous contents of `curlval' before freeing + and reallocating tokstr (which, chances are, will get the same + pointer as before and render curlval inconsistent). Fixes other + bug reported by Dan Douglas + + 9/9 + --- +lib/readline/complete.c + - rl_username_completion_function: protect call to setpwent() with + #ifdef (HAVE_GETPWENT)/#endif. Fixes bug reported by + Gerd Hofmann + +lib/readline/display.c + - rl_message: second and subsequent calls to rl_message can result in + local_prompt being overwritten with new values (e.g., from the + successive calls displaying the incremental search string). Need + to free before overwriting if it's not the same as the value saved + in saved_local_prompt. Fixes memory leak reported by + Wouter Vermaelen + +lib/readline/{terminal.c,rlprivate.h} + - move CUSTOM_REDISPLAY_FUNC and CUSTOM_INPUT_FUNC defines from + terminal.c to rlprivate.h so other files can use them + +expr.c + - expr_streval: if noeval is non-zero, just return 0 right away, + short-circuiting evaluation completely. readtok will leave curtok + set correctly without re-entering the evaluator at all. Rest of + fix for bug reported by Dan Douglas + + 9/11 + ---- + +parse.y + - parse_comsub: make sure the `reserved word ok in this context' flag + is preserved after we read `do' followed by whitespace. Fixes bug + reported by Benoit Vaugon + + 9/13 + ---- +configure.ac,config.h.in + - enable-direxpand-default: new configure option, turns the `direxpand' + shell option on by default + +bashline.c + - dircomplete_expand, dircomplete_expand_relpath: initialize to 1 if + DIRCOMPLETE_EXPAND_DEFAULT is defined and non-zero + +doc/bashref.texi + - enable-direxpand-default: document new configure option + + 9/14 + ---- +shell.c + - --protected: make option valid only when wordexp is compiled into + the shell. Fix from Roman Rakus + +configure.ac + - HP NonStop (*-nsk*): compile --without-bash-malloc. Change from + Joachim Schmitz + + 9/16 + ---- +subst.c,execute_cmd.c,lib/glob/sm_loop.c,lib/sh/shquote.c + - minor code cleanups from Joachim Schmitz + +lib/readline/colors.h + - workaround for HP NonStop compiler issue with from + Joachim Schmitz + + 9/17 + ---- +builtins/printf.def + - printf_builtin: handle localtime returning NULL, as can happen when + encountering overflow. Bug report and initial fix from + Eduardo A. Bustamante López + +doc/{bash.1,bashref.texi} + - emphasize that brace expansion using character ranges ({a..c}) acts + as if the C locale were in use. Prompted by message from + Marcel Giannelia + + 9/20 + ---- +lib/sh/wcsnwidth.c + - wcsnwidth: new function, variant of wcwidth, returns the number of + wide characters from a string that will be displayed to not exceed + a specified max column position + + 9/21 + ---- +builtins/help.def + - show_builtin_command_help: break code that displays the short-doc + for each builtin in two columns into a new function: dispcolumn + - wdispcolumn: multibyte-char version of dispcolumn; uses wide + chars and printf "%ls" format. Fixes problem reported by + Nguyá»n Thái Ngá»c Duy + + 9/22 + ---- +execute_cmd.c + - execute_disk_command: before running the command-not-found hook, + call kill_current_pipeline() to make sure we don't add processes + to an existing pipeline or wait for processes erroneously + + 9/23 + ---- +lib/readline/input.c + - rl_input_available_hook: new hook function, called from + _rl_input_available (or _rl_input_queued) to return whether or not + input is available wherever the input source is + +lib/readline/doc/rltech.texi + - rl_input_available_hook: document + + 9/27 + ---- +lib/glob/sm_loop.c: + - GMATCH: after one or more `*', an instance of ?(x) can match zero or + 1 times (unlike ?, which has to match one character). The old code + failed if it didn't match at least once. Fixes `a*?(x)' bug. + - GMATCH: if we hit the end of the search string, but not the end of + the pattern, and the rest of the pattern is something that can + match the NUL at the end of the search string, we should successfully + match. Fixes `a*!(x)' bug reported by + + 10/2 + ---- +command.h + - add c_lock member to coproc structure for future use to tell who is + manipulating it + +execute_cmd.c + - execute_coproc: block SIGCHLD while parent is forking coproc + process and adding pid to sh_coproc struct to avoid race condition + where child is reaped before the pid is assigned and the coproc is + never marked as having died. Fixes race condition identified by + Davide Baldini + - add assignments to c_lock member of struct coproc in various + functions that manipulate it; was used to identify race condition + - coproc_pidchk: don't call coproc_dispose to avoid using malloc and + other functions in a signal handler context + - coproc_dispose: call BLOCK_SIGNAL/UNBLOCK_SIGNAL for SIGCHLD while + manipulating the sh_coproc struct + + 10/6 + ---- +lib/readline/complete.c + - rl_display_match_list: if printing completions horizontally, don't + bother with spacing calculations if limit == 1, which means we are + printing one completion per line no matter what. Fixes bug + reported by David Kaasen + + 10/7 + ---- +builtins/declare.def + - declare_internal: add error checking for nameref attribute and + variable assignments: self-references, attempts to make an array + variable a nameref + +subst.c + - parameter_brace_expand: handle parameter_brace_expand_word returning + &expand_param_fatal or &expand_param_error and return the appropriate + error value + - parameter_brace_expand_word: if a nameref variable's value is not a + valid identifier, return an error + - param_expand: if a nameref variable's value is not a valid identifier, + return an error + +test.c + - unary_operator: add new -R variable, returns true if variable is set + and has the nameref attribute. From ksh93 + +builtins/test.def + - add -R to description of conditional commands for help test + +doc/{bash.1,bashref.texi} + - document new -R unary conditional operator + + 10/13 + ----- +trap.c + - check_signals_and_traps: new function, convenience function for the + rest of the shell to check for pending terminating and interrupt + signals, and to check for and process any pending traps + - any_signals_trapped: new function, returns non-zero if any signals + are trapped and -1 if not + +trap.h + - extern declaration for check_signals_and_traps + +bashline.c + - bashline_reset: make sure we reset the event hook + - bash_event_hook: call check_signals_and_traps instead of just + checking for terminating signals so we can run pending traps and + react to interrupts, and reset the event hook when we're done + + + 10/14 + ----- +trap.c + - trap_handler: if executing in a readline signal handler context, + call bashline_set_event_hook to install bash_event_hook to process + the signal (if bash cares about it) + +sig.c + - sigint_sighandler: call bashline_set_event_hook to set the event + hook if we're executing in a readline signal handler context + +lib/readline/input.c + - rl_getc: call RL_CHECK_SIGNALS if read returns -1/EINTR and the caught + signal is SIGINT or SIGQUIT rather than waiting until the next time + around the loop + - rl_getc: call rl_event_hook after calling RL_CHECK_SIGNALS to allow + an application signal handler to set the event hook in its own + signal handler (e.g., like bash trap_handler or sigint_sighandler) + + +parse.y + - yy_readline_get: don't set interrupt_immediately before we call + readline(). Inspired by report from lanshun zhou + + +input.c + - getc_with_restart: add call to run_pending_traps after call to + CHECK_TERMSIG + +lib/sh/zread.c + - zread: call check_signals_and_traps if read() returns -1/EINTR + instead of just ignoring the EINTR and deferring handling any + signal that generated it + +builtins/mapfile.def + - mapfile: don't set interrupt_immediately before calling zgetline() + (which uses zread internally) + +builtins/read.def + - read_builtin: don't set interrupt_immediately before calling zread + (moved code around so that it was only being set right around calls + to zread to avoid signal handler conflicts). Inspired by report + from lanshun zhou + - edit_line: don't set interrupt_immediately around call to readline() + - include shmbutil.h + - read_builtin: don't call read_mbchar unless is_basic(c) returns + false for the character we just read + + 10/15 + ----- +sig.c + - throw_to_top_level: if interrupt_state is non-zero, make sure that + last_command_exit_value reflects 128+SIGINT if it's not already + greater than 128 + + 10/20 + ----- +builtins/wait.def + - WAIT_RETURN: set wait_signal_received back to 0 for the potential + next call to wait + +quit.h + - CHECK_WAIT_INTR: macro to check whether trap_handler handled a + signal and set wait_signal_received; longjmp to wait_intr_buf in + that case + +jobs.c + - wait_for, waitchld: call CHECK_WAIT_INTR at the same places we call + CHECK_TERMSIG to check for terminating signals + - wait_sigint_handler: don't longjmp out of the wait builtin unless + interrupt_immediately is set; otherwise just SIGRETURN from the + handler + - wait_sigint_handler: if interrupt_immediately not set, but we are + executing in the wait builtin and SIGINT is not trapped, treat it + as a `normally received' SIGINT: restore the signal handler and + send SIGINT to ourselves + - waitchld: when in posix mode and running SIGCHLD traps, don't longjmp + to wait_intr_buf (and let wait be interrupted) if we're running from + a signal handler. Wait for CHECK_WAIT_INTR to do the longjmp. + run_pending_traps will run the SIGCHLD trap later + +nojobs.c + - reap_zombie_children, wait_for_single_pid, wait_for: call + CHECK_WAIT_INTR where we call CHECK_TERMSIG + - wait_sigint_handler: don't longjmp out of the wait builtin unless + interrupt_immediately is set; otherwise just SIGRETURN from the + handler + +trap.c + - trap_handler: make sure wait_signal_received is set if the wait + builtin is executing, and only longjmp if interrupt_immediately is + set. This whole set of fixes was prompted by report from + lanshun zhou + + 10/24 + ----- +lib/glob/glob.c + - glob_filename: only check directory_name for globbing chars if + it's of non-zero length + +lib/sh/strchrnul.c + - new simpler implementation + +subst.c + - command_substitute: call set_shellopts after turning off errexit + in subshells so it's reflected in $SHELLOPTS + + 11/7 + ---- +builtins/evalstring.c + - parse_and_execute: treat ERREXIT case like reader_loop does: set + variable_context to 0 before longjmping back to top_level. Don't + run the unwind-protect context to avoid side effects from popping + function contexts. Part of fix for problem reported by Nikolai + Kondrashov + +execute_cmd.c + - execute_simple_command: call unlink_fifo_list only if this is the + last element of a pipeline (or not in a pipeline), rather than for + every child. Fixes difference in behavior between /dev/fd and + FIFOs reported by Zev Weiss + - execute_null_command: do the same thing in the parent branch after + make_child + + 11/14 + ----- +subst.c + - parameter_brace_expand: a variable is null if it's special ($@, $*), + the expansion occurs within double quotes, and the expansion turns + into a quoted null. Fixes debian bug 692447 reported by + Matrosov Dmitriy + +jobs.c + - run_sigchld_trap: make sure `running_trap' sentinel is set + appropriately + - waitchld: only run the sigchld trap if we're not in a signal + handler, not running a trap, and executing the wait builtin. + Otherwise, queue for later handling. We still run one instance + of the trap handler per exited child. Bulk of fix for bug + reported by Elliott Forney + +trap.c + - queue_sigchld_trap: set catch_flag so run_pending_traps notices, + and set trapped_signal_received for completeness. Rest of fix + for bug reported by Elliott Forney + +lib/malloc/malloc.c + - block_signals: renamed to _malloc_block_signals, made public + - unblock_signals: renamed to _malloc_unblock_signals, made public + +lib/malloc/imalloc.h + - extern declarations for _malloc_{un,}block_signals + +lib/malloc/table.c + - mregister_alloc, mregister_free: block signals around table + manipulation + + 11/15 + ----- +trap.c + - run_pending_traps: set SIG_INPROGRESS flag around calls to + run_sigchld_handler so other parts of the shell know that the + SIGCHLD trap handler is executing + - run_pending_traps: if we get a situation where we are looking at + running a SIGCHLD trap but the trap string is IMPOSSIBLE_TRAP_HANDLER + and the SIG_INPROGRESS flag is set, just skip it. This is possible + if run_pending_traps is called from a SIGCHLD trap handler run by + run_sigchld_trap + +doc/bash.1,lib/readline/doc/{rluser.texi,readline.3} + - corrected description of the effect of `set history-size 0'. Report + from Vesa-Matti J Kari + +include/stdc.h + - CPP_STRING: new define, replaces __STRING + +lib/malloc/{malloc.c,imalloc.h} + - replace __STRING with CPP_STRING + + 11/16 + ----- +lib/readline/bind.c + - sv_histsize: if argument evaluates to a value < 0, unstifle the + history + + 11/22 + ----- +redir.c + - do_redirection_internal: if we have REDIR_VARASSIGN set in the + redirection flags and we set up `redirector' using fcntl or dup2, + don't add a redirect to make sure it stays open. Let the + script programmer manage the file handle. Fixes bug reported by + Sam Liddicott + + 11/24 + ----- +jobs.c + - wait_for_any_job: new function, waits for an unspecified background + job to exit and returns its exit status. Returns -1 on no background + jobs or no children or other errors. Calls wait_for with new + sentinel value ANY_PID + - wait_for: changes to handle argument of ANY_PID: don't look up or + try to modify the child struct, only go through the wait loop once. + Return -1 if waitpid returns no children + +jobs.h + - ANY_PID: new define + +builtins/wait.def + - new option: -n. Means to wait for the next job and return its exit + status. Returns 127 if there are no background jobs (or no + children). Feature most recently requested by Elliott Forney + + +doc/{bash.1,bashref.texi} + - document new `wait -n' option + +execute_cmd.c + - execute_command_internal: save make_command_string () result in a + temp variable before calling savestring() on it; avoids evaluating + make_command_string() result twice. Fix from John E. Malmberg + + + 11/28 + ----- + +builtins/declare.def + - declare_internal: if an array variable is declared using `declare -a' + or `declare -A', but not assigned a value, set the `invisible' + attribute so the variable does not show up as set. Fix for bug + about variable initialization reported by Tim Friske + +builtins/{mapfile,read}.def + - after calling find_or_make_array_variable, make sure the invisible + flag is turned off, in case the variable was declared previously + using `declare -a' or `declare -A'. Side effect of above change to + declare_internal + +subst.c + - shell_expand_word_list: handle the W_ASSNGLOBAL flag and put -g into + the list of options passed to make_internal_declare as appropriate. + Fix for bug reported by Tim Friske + + 11/30 + ----- +test.c + - unary_op: make sure -v and -n check that the variable is not marked + as invisible before calling var_isset. Fix for bug reported by Tim + Friske + + 12/2 + ---- +subst.c + - process_substitute: turn off the `expanding_redir' flag, which + controls whether or not variables.c:find_variable_internal uses the + temporary environment to find variables. We want to use the + temp environment, since we don't have to worry about order of + evaluation in a subshell. Fixes bug reported by Andrey Borzenkov + + + 12/4 + ---- +lib/glob/glob.c + - glob_filename: changes to avoid null filenames and multiple entries + returned for patterns like **/** (globstar enabled). Fixes bug + reported by Ulf Magnusson + + 12/10 + ----- +lib/glob/glob.c + - glob_filename: finish up a series of changes to make globstar-style + globbing more efficient, avoid more duplicate filenames, and be more + compatible with other shells that implement it + o collapse a sequence of **/**/** to one ** + o note when the directory name is all ** or ends in ** so we + can treat it specially when the filename is ** + All inspired by report from Andrey Borzenkov + +lib/sh/zread.c + - zreadn: new function, like zread, but takes an additional argument + saying how many bytes to read into the local buffer. Can be used to + implement `read -N' without so many one-byte calls to zreadc. Code + from Mike Frysinger + + 12/12 + ----- +lib/glob/sm_loop.c + - PATSCAN (glob_patscan): if passed string already points to end of + pattern, return NULL immediately. Fixes problem with + extglob_skipname reported by Raphaël Droz + + 12/13 + ----- +execute_cmd.c + - execute_coproc: handle the command's exit status being inverted + (an oversight). Fixes bug reported by DJ Mills + and Andreas Schwab + + 12/14 + ----- +lib/readline/readline.c + - bind_arrow_keys_internal: add MINGW key bindings for Home, End, + Delete, and Insert keys. Fix from Pierre Muller + + +builtins/printf.def + - printf_builtin: '%()T' conversion: if there is no argument supplied, + behave as if -1 had been supplied (current time). ksh93-like feature + suggested by Clark Wang + +doc/{bash.1,bashref.texi} + - document new printf %()T default argument behavior + + 12/15 + ----- +lib/readline/display.c + - displaying_prompt_first_line: new variable, indicates whether or + not the first line of output is displaying the prompt. Always true + in normal mode, sometimes false in horizontal scrolling mode + - rl_redisplay: set displaying_prompt_first_line to true unless we + are in horizontal mode; set to false in horizontal mode if the left + margin of the displayed line is greater than the end of the prompt + string + - rl_redisplay: when in horizontal scroll mode, don't adjust + _rl_last_c_pos by the wrap offset unless the line is displaying + a prompt containing invisible chars + - update line: don't adjust _rl_last_c_pos by the wrap offset unless + the line is displaying a prompt containing invisible chars + - update_line: if shrinking the line by reducing the number of + displayed characters, but we have already moved the cursor to the + beginning of the line where the first difference starts, don't + try to delete characters + +builtins/read.def + - unbuffered_read: set to 2 if invoked as `read -N' + - if unbuffered_read is set to 2, compute the number of chars we + need to read and read that many with zreadn. Posix mode still + uses zreadintr. Code from Mike Frysinger + +doc/{bash.1,bashref.texi} + - read: make it clear that if read times out, it saves any input + read to that point into the variable arguments. Report from + Fiedler Roman + +subst.c + - command_substitute: change direct assignment of exit_immediately_on_error + to use change_flag ('e', FLAG_OFF) instead + +flags.c + - use errexit_flag as the variable modified by changes to the -e + option, reflect those changes to exit_immediately_on_error + +execute_cmd.c + - execute_builtin: new global variable, builtin_ignoring_errexit, set + to 0 by default and set to 1 if eval/source/command executing in a + context where -e should be ignored + - execute_builtin: set exit_immediately_on_error to errextit_flag + after executing eval/source/command in a context where -e should + be ignored + +flags.c + - if builtin_ignoring_errexit is set, changes to errexit_flag are + not reflected in the setting of exit_immediately_on_error. Fixes + bug reported by Robert Schiele + + 12/23 + ----- +include/posixjmp.h + - setjmp_nosigs: new define, call setjmp in such a way that it will + not manipulate the signal mask + +{expr,test,trap}.c + - setjmp_nosigs: call instead of setjmp; don't need to manipulate + signal mask + +builtins/read.def + - read_builtin: setjmp_nosigs: call instead of setjmp; don't need + to manipulate signal mask + +builtins/evalstring.c: + - parse_and_execute: setjmp_nosigs: call instead of setjmp; don't need + to manipulate signal mask + - parse_string: setjmp_nosigs: call instead of setjmp; don't need + to manipulate signal mask + - parse_and_execute: save and restore the signal mask if we get a + longjmp that doesn't cause us to return or exit (case DISCARD) + + 12/24 + ----- +general.c + - bash_tilde_expand: only set interrupt_immediately if there are no + signals trapped; we want to jump to top level if interrupted but + not run any trap commands + + 12/25 + ----- +jobs.c + - run_sigchld_trap: no longer set interrupt_immediately before calling + parse_and_execute, even if this is no longer run in a signal handler + context + +input.c + - getc_with_restart: add call to QUIT instead of CHECK_TERMSIG + +parse.y + - yy_stream_get: now that getc_with_restart calls QUIT, don't need to + set interrupt_immediately (already had call to run_pending_traps) + +execute_cmd.c + - execute_subshell_builtin_or_function,execute_function,execute_in_subshell: + setjmp_nosigs: call instead of setjmp when saving return_catch; don't + need to manipulate signal mask + - execute_subshell_builtin_or_function,execute_in_subshell: + setjmp_nosigs: call instead of setjmp where appropriate when saving + top_level; don't need to manipulate signal mask if we're going to + exit right away + +subst.c + - command_substitute: setjmp_nosigs: call instead of setjmp when saving + return_catch; don't need to manipulate signal mask + - command_substitute: setjmp_nosigs: call instead of setjmp where + appropriate when saving top_level; don't need to manipulate signal + mask if we're going to exit right away + +trap.c + - run_exit_trap: setjmp_nosigs: call instead of setjmp when saving + return_catch; don't need to manipulate signal mask + - run_exit_trap: setjmp_nosigs: call instead of setjmp where + appropriate when saving top_level; don't need to manipulate signal + mask if we're going to exit right away + - _run_trap_internal: setjmp_nosigs: call instead of setjmp when saving + return_catch; don't need to manipulate signal mask + +builtins/evalfile.c + - _evalfile: setjmp_nosigs: call instead of setjmp when saving + return_catch; don't need to manipulate signal mask + +builtins/evalstring.c + - evalstring: setjmp_nosigs: call instead of setjmp when saving + return_catch; don't need to manipulate signal mask + +shell.c + - main: setjmp_nosigs: call instead of setjmp where appropriate when + saving top_level; don't need to manipulate signal mask if we're + going to exit right away + - run_one_command: setjmp_nosigs: call instead of setjmp where + appropriate when saving top_level; don't need to manipulate signal + mask if we're going to exit right away + - run_wordexp: setjmp_nosigs: call instead of setjmp where + appropriate when saving top_level; don't need to manipulate signal + mask if we're going to exit right away + +eval.c + - reader_loop: save and restore the signal mask if we get a longjmp + that doesn't cause us to return or exit (case DISCARD) + + 12/26 + ----- +parse.y + - shell_input_line_{index,size,len}: now of type size_t; in some cases + the unsigned property makes a difference + - STRING_SAVER: saved_line_{size,index} now of type size_t + - shell_getc: don't allow shell_input_line to grow larger than SIZE_MAX; + lines longer than that are truncated until read sees a newline; + addresses theoretical buffer overflow described by Paul Eggert + + - set_line_mbstate: size_t changes like shell_getc + - shell_getc: if shell_input_line is larger than 32K, free it and + start over to avoid large memory allocations sticking around + +variables.c + - bind_global_variable: new function, binds value to a variable in + the global shell_variables table + +variables.h + - bind_global_variable: new extern declaration + +builtins/declare.def + - declare_internal: if -g given with name=value, but variable is not + found in the global variable table, make sure to call + bind_global_variable so the variable is created and modified at + global scope. Fixes a bug where declare -g x=y could modify `x' + at a previous function scope + +command.h + - W_ASSIGNARRAY: new word flag, compound indexed array assignment + +subst.h + - ASS_MKGLOBAL: new assignment flag, forcing global assignment even in + a function context, used by declare -g + +execute_cmd.c + - fix_assignment_words: set W_ASSIGNARRAY flag if -a option given to + declaration builtin + +subst.c + - do_assignment_internal: explicitly handle case where we are + executing in a function and we want to create a global array or + assoc variable + - shell_expand_word_list: call make_internal_declare if -a option + given to declaration builtin (W_ASSIGNARRAY); handle -g option with + it (W_ASSNGLOBAL). Fixes inconsistency noticed by Vicente Couce + Diaz , where declare -ag foo=(bar) could modify + array variable foo at previous function scope, not global scope + + 12/27 + ----- +bashline.c + - Minix needs the third argument to tputs to be a void funtion taking + an int argument, not an int-returning function. Fix from + John E. Malmberg as part of VMS bash port + + 12/29 + ----- +configure.ac,version.c,patchlevel.h + - bash-4.3-devel: new version, new shell compatibility level (43) + +subst.c + - parameter_brace_patsub: put the bash-4.2 code back in from the + change of 3/3 that runs the replacement string through quote + removal, make it dependent on shell_compatibility_level <= 42 + +builtins/shopt.def + - compat42: new shopt option + - set_compatibility_level: change logic to set and unset various + compat variables and shell_compatibility_level + +COMPAT + - new documentation for bash-4.3 compatibility changes + +doc/{bash.1,bashref.texi} + - compat42: document new shopt option + +builtins/shopt.def + - set_compatibility_opts: new function, sets the various shopt + compat variables based on the value of shell_compatibility_level + +builtins/common.h + - set_compatibility_opts: new extern declaration + +variables.c + - BASH_COMPAT: new special variable; sets the shell compatibility + level. Accepts values in decimal (4.2) or integer (42) form; + Unsetting variable, setting it to empty string, or setting it to + out-of-range value sets the shell's compatibility level to the + default for the current version. Valid values are 3.1/31 through + the current version + - sv_shcompat: new function implementing logic for BASH_COMPAT + +variables.h + - sv_shcompat: new extern declaration + +doc/{bash.1,bashref.texi} + - BASH_COMPAT: description of new variable + +lib/readline/complete.c + - _rl_colored_stats: default back to 0 for 4.3 release branch + + 1/5/2013 + -------- +quit.h + - remove spurious call to itrace in CHECK_WAIT_INTR + +bashline.c + - bash_event_hook: if we're going to jump to top_level, make sure we + clean up after readline() by calling rl_cleanup_after_signal(). + Fixes bug reported against devel branch by Raphaël Droz + + - bash_event_hook: reset the event hook before checking for signals + or traps in case we longjmp + +doc/{bash.1,bashref.texi} + - small additions to the set -e section to make it more clear that + contexts where -e is ignored extend to compound commands as well + as shell functions + +lib/readline/readline.h + - rl_signal_event_hook: new extern declaration + +lib/readline/input.c + - rl_signal_event_hook: new variable, hook function to call when a + function (currently just read(2)) is interrupted by a signal and + not restarted + - rl_getc: call rl_signal_event_hook instead of rl_event_hook + +lib/readline/doc/rltech.texi + - rl_signal_event_hook: document new function + +bashline.c + - changes to set rl_signal_event_hook instead of rl_event_hook + +lib/readline/readline.h + - change readline version numbers to 6.3 + + 1/6 + --- +doc/{bash.1,bashref.texi} + - a couple of changes to the descriptions of the ERR trap and its + effects based on a message from Rob Nagler + + 1/9 + --- +expr.c + - expassign: invalidate curlval before freeing and NULLing tokstr to + avoid aliasing issues. Fixes bug reported by Eduardo A. Bustamante + López and Dan Douglas + +braces.c + - array_concat: don't be so aggressive in trying to short-circuit. We + can only short-circuit if we have a single-element array where the + element is an empty string (array[0] == "" array[1] = 0x0). Existing + practice requires us to replicate arrays and prefix or append empty + strings. Fixes bug reported by Eduardo A. Bustamante López + + + 1/11 + ---- +execute_cmd.c + - execute_builtin: since mapfile uses evalstring() to run its callbacks + internally, just like eval, so it needs to handle the case where the + temp environment given to mapfile persists throughout the entire + set of callback commands. This might be a problem with trap also, but + trap isn't run in the same way. Fixes bug reported by Dan Douglas + + + 1/13 + ---- +redir.c + - redirection_error: before expanding the redirection word (if + expandable_redirection_filename returns true), disable command + substitution during expansion. Fixes bug reported by Dan Douglas + + +subst.c + - expand_word_internal: case '\\': if the next character is an IFS + character, and the expansion occurs within double quotes, and the + character is not one for which backslash retains its meaning, add + the (escaped) '\' and the (escaped) character. Fixes bug reported + by Dan Douglas + + 1/15 + ---- +builtins/cd.def + - cd_builtin: make sure call to internal_getopt handles -e option. + Fixes bug reported by + + 1/17 + ---- +subst.c + - expand_word_list_internal: make sure tempenv_assign_error is + initialized to 0 + +execute_cmd.c + - execute_simple_command: make sure tempenv_assign_error is reset to 0 + after it's tested to see if an error should force the shell to exit. + Fixes problem where a the failure of a tempenv assignment preceding + a non-special builtin `sticks' and causes the next special builtin + to exit the shell. From a discussion on bug-bash started by + douxin + + 1/20 + ---- +subst.c + - parameter_brace_expand_rhs: call stupidly_hack_special_variables + after assigning with ${param[:]=word} even if IFS is changing. + Suggested by Dan Douglas [TENTATIVE, needs work + on IFS side effects] + +command.h + - W_GLOBEXP (which was unused) is now W_SPLITSPACE (which isn't used + yet) + +{execute_cmd,subst,variables}.c + - removed all code that mentioned W_GLOBEXP + - removed mention of gnu_argv_flags and code that set it + + 1/22 + ---- +subst.c + - param_expand: set W_SPLITSPACE if we expand (unquoted) $* and + IFS is unset or null so we can be sure to split this on spaces + no matter what happens with IFS later + - expand_word_internal: note that param_expand returns W_SPLITSPACE + in the returned word flags and keep track of that state with + `split_on_spaces' + + 1/23 + ---- +subst.c + - expand_word_internal: if split_on_spaces is non-zero, make sure + we split `istring' on spaces and return the resultant word. The + previous expansions should have quoted spaces in the positional + parameters where necessary. Suggested by Dan Douglas + + +execute_cmd.c + - execute_command_internal: make sure any subshell forked to run a + group command or user subshell at the end of a pipeline runs any + EXIT trap it sets. Fixes debian bash bug 698411 + http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=698411 + +subst.c + - shell_expand_word_list: fix code that creates args for and calls + make_internal_declare to avoid calling it twice (missing `else' + in 12/26 change) + - do_assignment_internal: fix code from 12/26 change to fix problem + where an existing assoc variable could be converted to an array + without checking `mkassoc' + + 1/24 + ---- +builtins/evalfile.c + - _evalfile: add missing `close (fd)' calls before returning to + avoid fd leaks. Bug and fix from Roman Rakus + + 1/25 + ---- +builtins/read.def + - read_builtin: don't try to play tricks with the top of the unwind- + protect stack after read gets a SIGALRM; save input_string to new + memory, run the stack, then restore input_string and assign the + variables. Part of fix for bug reported by konsolebox + ; the rest of the fix is with the changes in + trap and signal handling and doing away with interrupt_immediately + + 1/26 + ---- +redir.c + - redirection_expand, write_here_string, write_here_document: before + calling any of the word expansion functions, after setting + expanding_redir to 1 (which bypasses the temp environment in the + variable lookup functions), call sv_ifs to reset the cached IFS- + related variables set by subst.c:setifs(). This ensures that + redirections will not get any IFS values that are set in the + temporary environment, as Posix specifies. Then, after the word + expansions, after resetting expanding_redir to 0, call sv_ifs + again to make sure the cached IFS values are set from any + assignments in the temporary environment. We force executing_builtin + to 1 to `fool' the variable lookup functions into using any temp + environment, then reset it to its old value after sv_ifs returns. + This is what allows read() to use the (cached) IFS variables set + in the temp environment. Fixes inconsistency reported by Dan Douglas + + + 1/29 + ---- +lib/readline/display.c + - update_line: fix off-by-one error when updating vis_lbreaks array + in a multibyte locale that occurs when moving multibyte chars from + one line down to another. Bug report and fix from Egmont + Koblinger + + 1/30 + ---- +configure.ac + - changed version to 4.3-alpha + +redir.c + - redir_open: handle open returning -1/EINTR, which seems to happen + a lot with FIFOs and SIGCHLD, and call QUIT to handle other + signals that can interrupt open(2). Bug report and initial fix + from Mike Frysinger + + 1/31 + ---- +subst.c + - parameter_brace_expand: make sure to propagate the PF_ASSIGNRHS flag + to parameter_brace_expand_word + - parameter_brace_expand_word: make sure that if the PF_ASSIGNRHS flag + is set and we are expanding ${a[@]} or ${a[*]} we set quoted to + include Q_DOUBLE_QUOTES before calling array_value_internal, mirroring + what we do for $@ and $*. Fixes inconsistency reported by Dan + Douglas + +configure.ac + - use AC_CHECK_TOOL instead of AC_CHECK_PROG to check for ar, since it + will find $host-prefixed versions of utilities. Report and fix from + Mike Frysinger + +builtins/setattr.def + - set_var_attribute: check whether bind_variable (called when the + variable whose attributes are being modified is found in the temp + environment) just modified a read-only global variable, and don't + bother marking the temporary variable for propagation if so. The + propagation is superfluous and will result in a strange error + message + + 2/2 + --- +variables.c + - initialize_shell_variables: don't try to import function definitions + with invalid names from the environment if already in posix mode, + but create them as (invisible) exported variables so they pass + through the environment. Print an error message so user knows + what's wrong. Fixes bug reported by Tomas Trnka + + 2/9 + --- + +builtins/read.def + - sigalrm_seen, alrmbuf: now global so the rest of the shell (trap.c) + can use them + - sigalrm: just sets flag, no longer longjmps to alrmbuf; problem was + longjmp without manipulating signal mask, leaving SIGALRM blocked + +quit.h + - move CHECK_ALRM macro here from builtins/read.def so trap.c: + check_signals() can call it + +trap.c + - check_signals: add call to CHECK_ALRM before QUIT + - check_signals_and_traps: call check_signals() instead of including + CHECK_ALRM and QUIT inline. Integrating check for read builtin's + SIGALRM (where zread call to check_signals_and_traps can see it) + fixes problem reported by Mike Frysinger + + 2/12 + ---- +lib/glob/xmbsrtowcs.c + - xdupmbstowcs2: fixed but where end of string was not handled + correctly, causing loop to go past end of string in a bunch of cases. + Fixes bug reported by "Dashing" + + + 2/13 + ---- +builtins/pushd.def + - popd_builtin: treat any argument that isn't -n or of the form + [-+][[:digit:]]* as an error. Fixes problem reported by Bruce + Korb + + 2/14 + ---- +configure.ac + - add check for sig_atomic_t; already a placeholder for it in + config.h.in + + 2/15 + ---- +subst.c + - do_compound_assignment: don't call assign_compound_array_list with + a NULL variable in case make_local_xxx_variable returns NULL + (it will if you try to shadow a readonly or noassign variable). + Fixes bug reported by Richard Tollerton + + 2/16 + ---- +variables.c + - make_local_variable: print error messager if an attempt is made to + create a local variable shadowing a `noassign' variable. Previously + we just silently refused to do it + +trap.[ch] + - get_original_signal: now global so rest of the shell can use it + +sig.c + - initialize_shell_signals: install a signal handler for SIGTERM + that does nothing except set a sigterm_received flag instead of + ignoring it with SIG_IGN, as long as SIGTERM is not ignored when + the shell is started. Use get_original_signal early to get the + original handler, since we will do that later anyway + - set_signal_handler: if installing sigterm_sighandler as the SIGTERM + handler, make sure to add SA_RESTART flag to make it as close to + SIG_IGN as possible + +sig.h + - sigterm_sighandler: new extern declaration + +quit.h + - RESET_SIGTERM: set sigterm_receved to 0 + - CHECK_SIGTERM: check sigterm_received; if it's non-zero, treat it + as a fatal signal and call termsig_handler to exit the shell + +jobs.c + - make_child: call RESET_SIGTERM just before fork() so we can detect + if the child process received a SIGTERM before it's able to change + the signal handler back to what it was when the shell started + (presumably SIG_DFL). Only has effect if the shell installed + sigterm_sighandler for SIGTERM, interactive shells that were not + started with SIG_IGN as the SIGTERM handler + - make_child: call RESET_SIGTERM in the parent after fork() so the + rest of the shell won't react to it + +execute_cmd.c + - execute_simple_command: call CHECK_SIGTERM after make_child in child + to catch SIGTERM received after fork() and before restoring old + signal handlers + - execute_disk_command: call CHECK_SIGTERM after make_child in child + process after restoring old signal handlers and again just before + calling shell_execve. Fixes race condition observed by + Padraig Brady when testing with his `timeout' + program + +lib/readline/display.c + - open_some_spaces: new function, subset of insert_some_chars that just + opens up a specified number of spaces to be overwritten + - insert_some_spaces: now just calls to open_some_spaces followed by + _rl_output_some_chars + - update_line: use col_temp instead of recalculating it using + _rl_col_width in the case where we use more columns with fewer bytes + - update_line: use open_some_spaces and then output the right number + of chars instead of trying to print new characters then overwrite + existing characters in two separate calls. This includes removing + some dodgy code and making things simpler. Fix from Egmont + Koblinger + - use new variable `bytes_to_insert' instead of overloading temp in + some code blocks (nls - nfd, bytes that comprise the characters + different in the new line from the old) + + 2/18 + ---- +redir.c + - do_redirection_internal: add undoable redirection for the implicit + close performed by the <&n- and >&n- redirections. Fixes bug + reported by Stephane Chazelas + + 2/19 + ---- +sig.c + - termsig_handler: an interactive shell killed by SIGHUP and keeping + command history will try to save the shell history before exiting. + This is an attempt to preserve the save-history-when-the-terminal- + window-is-closed behavior + + 2/21 + ---- +braces.c + - brace_expand: if a sequence expansion fails (e.g. because the + integers overflow), treat that expansion as a simple string, including + the braces, and try to process any remainder of the string. The + remainder may include brace expansions. Derived from SuSE bug + 804551 example (https://bugzilla.novell.com/show_bug.cgi?id=804551) + + 2/23 + ---- +{quit,sig}.h,sig.c + - sigterm_received declaration now in sig.h; type is sig_atomic_t + - sigwinch_received type now sig_atomic_t + - sig.h includes bashtypes.h and if SIG_DFL not defined + (same logic as trap.h) to pick up sig_atomic_t + +unwind_prot.c + - include sig.h before quit.h (reverse order) + + 2/27 + ---- +builtins/shopt.def + - reset_shopt_options: make sure check_window_size is reset to the + default from config.h, not unconditionally to 0 + +jobs.[ch] + - last_made_pid, last_asynchronous_pid: now volatile. Change from SuSE + +jobs.c + - wait_for: if we're using sigaction to install a handler for SIGCHLD, + make sure we specify SA_RESTART + +lib/{tilde,readline}/shell.c + - get_home_dir: instead of looking in the password file every time, + look once and cache the result + +sig.[ch] + - sigwinch_received, sigterm_received: now `volatile' qualified + +sig.c,quit.h + - interrupt_state,terminating_signal: now sig_atomic_t + + 3/1 + --- +MANIFEST,examples/* + - removed around 120 files without FSF copyrights; requested by + Karl Berry in early January + + 3/2 + --- +lib/malloc/malloc.c + - morecore: only check whether SIGCHLD is trapped if SIGCHLD is defined + +doc/bashref.texi + - Fixed most of the examples in the GNU Parallel section to use better + shell idioms following complaints on bug-bash; added a couple of + examples and smoothed out the text + +quit.h + - include "sig.h" for sig_atomic_t + +lib/readline/display.c + - update_line: when inserting one or more characters at the end of + the display line in a non-multibyte environment, just write from the + first difference to the end of the line and return. We don't have + to adjust _rl_last_c_pos. This is needed to adjust from the old + two-part copy to a single call to _rl_output_some_chars (change of + 2/16) + + 3/4 + --- +Makefile.in,doc/Makefile.in + - PACKAGE_TARNAME, docdir: new variables substituted by autoconf + - OTHER_DOCS,OTHER_INSTALLED_DOCS: new variables with auxiliary + documentation files to be installed into $(docdir) + - install: add new rule to install $(OTHER_DOCS) + - uninstall: add new rule to uninstall $(docdir)/$(OTHER_INSTALLED_DOCS) + +doc/bash.1 + - add URL to `POSIX' file in `SEE ALSO' section; put pointer to that + section in --posix and set -o posix descriptions + +examples/ + - removed around 110 examples at the request of the FSF due to copyright + issues + + 3/5 + --- +builtins/setattr.def + - readonly: modified help text slightly to make it clearer that + functions aren't changed or displayed unless the -f option is given. + Report from + + 3/9 + --- +include/typemax.h + - SIZE_MAX: define to 65535 (Posix minimum maximum) if not defined + +parse.y + - include "typemax.h" for possible SIZE_MAX definition, make sure we + include it after shell.h + +{braces,expr}.c + - include "typemax.h" for possible INTMAX_MIN and INTMAX_MAX definitions + + 3/10 + ---- +bashline.c + - bash_default_completion: make sure completion type of `!' (same as + TAB but with show-all-if-ambiguous set) and glob-word-completion + sets rl_filename_completion_desired to 0 so extra backslashes don't + get inserted by `quoting' the completion. We can't kill all the + matches because show-all-if-ambiguous needs them. Bug report from + Marcel (Felix) Giannelia + +[bash-4.3-alpha frozen] + + 3/14 + ---- +general.c + - trim_pathname: use memmove instead of memcpy since the source and + destination pathnames may overlap. Report and fix from Matthew + Riley + + 3/18 + ---- +configure.ac + - socklen_t is defined as `unsigned int' if configure can't find it + + 3/20 + ---- +lib/readline/complete.c + - S_ISVTX: since it's not defined on all platforms (Minix), make sure + its use is protected with #ifdef + + 3/21 + ---- +doc/{bash.1,bashref.texi} + - Added mention of ${!name[@]} and ${!name[*]} expansions to get all + indices of an array. Suggested by Jonathan Leffler + + + 3/24 + ---- +subst.h + - SD_IGNOREQUOTE: new define for skip_to_delim; if set, means that + single quotes (for now) will be treated as ordinary characters + +subst.c + - skip_to_delim: handle SD_IGNOREQUOTE. no callers use it for now + + 3/25 + ---- +support/config.{guess,sub} + - updated to versions from autoconf-2.69 + + 3/31 + ---- +lib/sh/shquote.c + - sh_single_quote: short-circuit quoting a single "'" instead of + creating a long string with empty single-quoted strings + +parser.h + - DOLBRACE_QUOTE2: new define, like DOLBRACE_QUOTE, but need to single- + quote results of $'...' expansion because quote removal will be + done later. Right now this is only done for ${word/pat/rep} + +parse.y + - parse_matched_pair: set state to DOLBRACE_QUOTE2 for pattern + substitution word expansion so we don't treat single quote specially + in the pattern or replacement string + - parse_matched_pair: if we're parsing a dollar-brace word expansion + (${...}) and we're not treating single quote specially within + double quotes, single-quote the translation of $'...' ansi-c + escaped strings. Original report and fix from Eduardo A. + Bustamante López + +subst.c + - extract_dollar_brace_string: ${word/pat/rep} scanning now sets the + DOLBRACE_QUOTE2 flag instead of DOLBRACE_QUOTE so we don't treat + single quotes specially within a double-quoted string + +execute_cmd.c + - fix_assignment_words: skip over assignment statements preceding a + command word before trying to figure out whether or not assignment + statements following a possible declaration command should be + treated specially. Fixes bug reported by Dan Douglas + + + 4/4 + --- +lib/readline/readline.c + - _rl_dispatch_subseq: only call _rl_vi_set_last (and check whether + the key is a text modification command) if the key sequence length + is 1. That keeps the arrow keys from setting the last command + when called in vi command mode. Fixes bug reported by Ian A. + Watson + + 4/6 + --- +lib/readline/bind.c + - rl_parse_and_bind: when parsing a double-quoted string as the value + of a variable, make sure we skip past the leading double quote. + Fix from Andreas Schwab + +variables.c + - hash_lookup: set new local variable last_table_searched to the table + a successful lookup appears in; tested in make_local_variable to + solve the problem below + - make_local_variable: if we find a variable with the tempenv flag + set at the same `level' as variable_context', but not found in the + temporary_env (temp environment preceding the builtin), return it. + The temp environment preceding the function call has already been + merged (in execute_function) into the list of variable contexts the + function sees as shell_variables by the time this is called. Fixes + inconsistency pointed out by Dan Douglas + +subst.c + - expand_arith_string: expanded out contents of expand_string, + expand_string_internal, expand_string_if_necessary to create a + WORD_DESC and call call_expand_word_internal() on it directly. + We don't want process substitution to be performed ( 1<(2) ) should + mean something different in an arithmetic expression context. + It doesn't work to just turn on the DQUOTE flag, since that means + that things like ${x["expression"]} are not expanded correctly. + Fixes problem pointed out by Dan Douglas + + 4/13 + ---- +subst.c + - process_substitute: run the EXIT trap before exiting, as other + shells seem to. Fixes problem pointed out by Dan Douglas + + +lib/readline/readline.c + - readline_internal_setup: call rl_vi_insertion_mode to enter vi + mode instead of rl_vi_insert_mode to avoid resetting the saved last + command information. Posix says that `.' can repeat a command + that was entered on a previous line so we need to save the info. + Fixes bug reported by Ian A. Watson + + 4/14 + ---- +lib/readline/complete.c + - rl_completion_matches: make sure xrealloc returns something non-null + (can happen when interrupted by a signal) before trying to add + matches to match_list + +subst.c + - array_remove_pattern: return NULL right away if array_variable_part + returns an invisible variable + - array_length_reference: handle array_variable_part returning an + invisible variable + - get_var_and_type: handle array_variable_part returning an invisible + variable + + 4/15 + ---- +execute_cmd.c + - execute_command_internal: make sure to run the EXIT trap for group + commands anywhere in pipelines, not just at the end. From a point + raised by Andreas Schwab + +variables.c + - bind_int_variable: make sure invisible flag is unset. Fixes problems + like "declare -ai a; : $(( a[4]=4 ));" + +arrayfunc.c + - array_variable_part: return variable even if invisible flag set, + callers must handle invisible vars + + 4/18 + ---- +builtins/set.def + - unset_builtin: if -n flag given, call unset_nameref instead of + unset_variable + +variables.c + - find_variable_nameref: print warning message if nameref circular + reference detected, return NULL and let caller deal with it + +builtins/declare.def + - declare_builtin: only disallow global references at this point if + we are at the global scope + + 5/16 + ---- +configure.ac + - update release status to beta + + 5/23 + ---- +trap.c + - run_pending_traps: save and restore pipeline around calls to + evalstring() in case we get a trap while running a trap. Have to + figure out the recursive running traps issue elsewhere. Fixes + bug reported by Roman Rakus + - run_pending_traps: make sure to set running_trap to the appropriate + signal value when running a trap command + - run_pending_traps: short-circuit immediately if running_trap set + when invoked. Could change this later to only skip if it would + run the same trap as currently being run (running_trap == sig + 1) + +configure.ac + - add warning if bison not found + +lib/readline/doc/rltech.texi + - new section with an example program illustrating the callback + interface. Suggested by Peng Yu + +examples/loadables/Makefile.in + - remove references to `cut' and `getconf', which were removed in + early March + + 5/28 + ---- +lib/sh/pathphys.c + - sh_realpath: correct inverted two arguments to call to sh_makepath. + Report and fix from Julien Thomas + + 6/7 + --- +execute_cmd.c + - executing_line_number: the else clauses that are conditional on + various options being defined can simply be if clauses -- they are + mutually exclusive and all have `return' in the body. Fixes bug + reported by Flavio Medeiros + + 6/25 + ---- +lib/readline/readline.c + - readline_internal_setup: only sent the meta-key enable string to the + terminal if we've been told to use one and the terminal has been + successfully initialized (RL_ISSTATE (RL_STATE_TERMPREPPED) != 0). + Suggested by Dan Mick + +lib/readline/signals.c + - _rl_signal_handler: call any defined signal hook after calling + rl_resize_terminal when handling a SIGWINCH. We already have called + the original SIGWINCH handler but will not be resending the signal + to ourselves + + 6/27 + ---- +lib/readline/doc/history.3, doc/bash.1 + - fix description of the `$' modifier to note that it expands to the + last *word*, which is not always the last argument. Report from + ariyetz@gmail.com via gnu.org RT + + 6/29 + ---- +lib/glob/smatch.c + - glob_asciiranges: initialize to value of GLOBASCII_DEFAULT instead + of 0 (0 if not defined) + +configure.ac,config.h.in + - --enable-glob-asciiranges-default: new option, controls the value of + GLOBASCII_DEFAULT; use it to turn globasciiranges shopt option on + by default + +doc/bashref.texi + - document new --enable-glob-asciiranges-default configure option + +variables.c + - assign_in_env: implement += value appending semantics for assignments + preceding command names + + 7/4 + --- +expr.c + - set lasttok = NUM in all of the functions that result in a number, + even if it's a boolean, to avoid errors with constructs like + 1 * x = 1, which should be an asignment error. Fixes problem + pointed out by Dan Douglas + +parse.y + - decode_prompt_string: don't bother to call strcpy if + polite_directory_format returns its argument unchanged. It's not + necessary and Mac OS X 10.9 aborts because of a supposed overlapping + string copy. Bug and fix from simon@hitzemann.org + +subst.c + - parameter_brace_find_indir: new function, code from + parameter_brace_expand_indir that looks up the indirectly-referenced + variable, but does not expand it + - parameter_brace_expand_indir: call parameter_brace_find_indir to + look up indirected variable reference + - get_var_and_type: call parameter_brace_find_indir if it looks like we + are trying to manipulate an indirect variable reference like + ${!b%%foo}. This makes a difference if !b references an array + variable. Bug report from Dan Douglas + + 7/6 + --- +lib/sh/casemod.c + - sh_modcase: make sure argument passed to is_basic is <= UCHAR_MAX, + since cval can convert something to a wchar_t greater than UCHAR_MAX. + Fixes bug reported by Tomasz Tomasik + + 7/8 + --- +lib/readline/history.c + - add_history_time: if history_length == 0, referencing history_length + - 1 will result in an array bounds error, so make history_length be + at least 1 before going on. Fixes bug reported by Geng Sheng Liu + + +builtins/setattr.def + - show_func_attributes: display definition (if NODEFS argument is 0) and + attributes for a particular function; used by `declare -fp name' + +builtins/declare.def + - declare_internal: call show_func_attributes if -f supplied with -p. + Fixes inconsistency observed by Linda Walsh + +builtins/common.h + - new extern declaration for show_func_attributes + +builtins/read.def + - read_builtin: check the first supplied variable name for validity + before attempting to read any input, since we know we will have to + at least use that one. Don't check any other names yet. Suggested + by jidanni@jidanni.org + + 7/10 + ---- +redir.c + - do_redirection_internal: when closing a file descriptor with + r_close_this ([n]<&-) count close errors as redirection errors if + errno ends up as EIO or ENOSPC. Originally reported back in April + 2012 by Andrey Zaitsev + + 7/11 + ---- +redir.c + - do_redirection_internal: before calling check_bash_input, make sure + that we don't call check_bash_input for an asynchronous process that + is replacing stdin with something else. The seek backwards affects + the parent process as well, since parents and children share the + file pointer. Fixes problem originally reported in March 2013 by + Martin Jackson + + 7/13 + ---- +doc/{bash.1,bashref.texi} + - slight change to add a description of `shopt -o' suggested by Bruce + Korb + + 7/19 + ---- +lib/readline/histfile.c + - history_do_write: if close returns < 0, make sure we restore the + backup history file and return a non-zero value + - history_truncate_file: if write or close return < 0, make sure we + return a non-zero value + +[bash-4.3-beta frozen] + + 7/21 + ---- +lib/readline/isearch.c + - rl_display_search: now takes an entire search context flags word as + the second argument, instead of just reverse flag; changed callers + - rl_display_search: if the search has failed, add `failed ' to the + beginning of the search prompt + - _rl_isearch_dispatch: if the search has failed, display the entire + search string with an indication that the search failed but with the + last matching line. Suggested by jidanni@jidanni.org + +command.h + - W_ASSIGNINT: new word flag; used internally for make_internal_declare + and set by fix_assignment_words + +execute_cmd.c + - fix_assignment_words: set W_ASSIGNINT if compound assignment and -i + given as option. We don't do anything with the value yet + +subst.c + - shell_expand_word_list: rework the way the option list that is + passed to make_internal_declare is created + + 8/1 + --- +doc/{bash.1,bashref.texi} + - minor changes to description of $! based on a report from Chris + Down + +arrayfunc.c + - assign_array_element_internal: before trying to get an array's max + index to process a negative subscript, make sure the array exists. + Bug report from Geir Hauge + + 8/2 + --- +arrayfunc.c + - assign_array_element_internal: before using array_max_index() when + processing a negative subscript, make sure the variable is an array. + if it's not, use 0 as array_max_index assuming it's a string. + Fixes bug report from Geir Hauge + + 8/3 + --- +Makefile.in + - pcomplete.o: add dependency on $(DEFDIR)/builtext.h. Suggested by + Curtis Doty + + 8/5 + --- +lib/glob/sm_loop.c + - strcompare: short-circuit and return FNM_NOMATCH if the lengths of the + pattern and string (pe - p and se - s, respectively) are not equal + - strcompare: don't bother trying to set *pe or *se to '\0' if that's + what they already are. Fixes bug reported by Geir Hauge + + + 8/6 + --- +doc/{bash.1,bashref.texi},builtins/hash.def,lib/readline/doc/rluser.texi + - minor typo changes from Geir Hauge + +bultins/help.def + - show_longdoc: avoid trying to translate the empty string because it + often translates to some boilerplate about the project and + translation. Report and fix from Geir Hauge + + 8/8 + --- +builtins/help.def + - help_builtin: try two passes through the list of help topics for each + argument: one doing exact string matching and one, if the first pass + fails to find a match, doing string prefix matching like previous + versions. This prevents `help read' from matching both `read' and + `readonly', but allows `help r' to match everything beginning with + `r'. Inspired by report from Geir Hauge + + 8/13 + ---- +builtins/fc.def + - fc_builtin,fc_gethnum: calculate `real' end of the history list and + use it if -0 is specified as the beginning or end of the history + range to list. Doesn't work for fc -e or fc -s by design. Feature + requested by Mike Fied + + 8/16 + ---- +trap.c + - _run_trap_internal: use {save,restore}_parser_state instead of + {save,restore}_token_state. It's more comprehensive + + 8/23 + ---- +doc/bash.1 + - disown: remove repeated text. Report and fix from Thomas Hood + + + 8/25 + ---- +lib/readline/rltty.c + - set_special_char: fix prototype (last arg is rl_command_func_t *) + +sig.c + - set_signal_handler: return oact.sa_handler only if sigaction + succeeds; if it doesn't, return SIG_DFL (reasonable default). From + https://bugzilla.redhat.com/show_bug.cgi?id=911404 + +bashline.c + - attempt_shell_completion: fix to skip assignment statements preceding + command name even if there are no programmable completions defined. + From https://bugzilla.redhat.com/show_bug.cgi?id=994659 + - attempt_shell_completion: if still completing command word following + assignment statements, do command completion even if programmable + completion defined for partial command name entered so far + + 8/26 + ---- +pcomplete.c + - pcomp_filename_completion_function: make sure rl_filename_dequoting_function + is non-NULL before trying to call it. Bug and fix from + Andreas Schwab + +bashline.c + - bash_command_name_stat_hook: if *name is not something we're going + to look up in $PATH (absolute_program(*name) != 0), just call the + usual bash_filename_stat_hook and return those results. This makes + completions like $PWD/exam[TAB] add a trailing slash + + 9/2 + --- +builtins/read.def + - read_builtin: before comparing what we read to the delim, make sure + we are not supposed to be ignoring the delimiter (read -N). We + set the delim to -1, but it's possible to read a character whose + int value ends up being between -1 and -128. Fixes bug + reported by Stephane Chazelas + +doc/{bash.1,bashref.texi} + - word splitting: crib some language from Posix to make it clear that + characters in IFS are treated as field *terminators*, not field + *separators*. Addresses issue raised by DJ Mills + + +lib/readline/{util.c,rldefs.h} + - _rl_stricmp,_rl_strnicmp: now take const char * string arguments; + changed prototype declarations + + 9/5 + --- +doc/{bash.1,bashref.texi} + - [[: modify description of pattern matching to make it clear that the + match is performed as if the extglob option were enabled. From Red + Hat bug https://bugzilla.redhat.com/show_bug.cgi?id=1002078 + + 9/12 + ---- +lib/readline/isearch.c + - _rl_isearch_dispatch: if we read an ESC and it's supposed to + terminate the search, make sure we check for typeahead with + _rl_pushed_input_available, since installing a hook function causes + typeahead to be collected in `ibuffer' (input.c). If there is any, + make sure we still use the ESC as a prefix character. Bug and fix + from Mike Miller + + 9/16 + ---- +builtins/{caller,cd,kill,pushd,wait}.def + - builtin_usage(): make sure call to this sets return status to + EX_USAGE + + 9/18 + ---- +terminal.c + - rl_change_environment: new application-settable variable; if non- + zero (the default), readline will modify LINES and COLUMNS in the + environment when it handles SIGWINCH + - _rl_get_screen_size: if rl_change_environment is non-zero, use setenv + to modify LINES and COLUMNS environment variables + +readline.h + - rl_change_environment: new extern declaration for applications + + 9/22 + ---- +configure.ac + - relstatus: bumped version to bash-4.3-beta2 + + 9/24 + ---- + +lib/readline/readline.c + - bind_arrow_keys_internal: added more key bindings for the numeric key + pad arrow keys on mingw32. Patch from Pierre Muller + + + 10/19 + ----- + +bashline.c + - maybe_restore_tilde: version of restore_tilde that honors `direxpand'; + calls restore_tilde after saving directory expansion hook if + necessary. Report from Andreas Schwab + +builtins/cd.def + - -@: new option, allows cd to use `extended attributes' present in + NFSv4, ZFS; idea taken from ksh93. Attributes associated with a + file are presented as a directory containing the attributes as + individual files. Original patch contributed by Cedric Blancher + + + 10/20 + ----- +aclocal.m4 + - BASH_CHECK_MULTIBYTE: check for wcwidth being broken with unicode + combining characters needs a value to use when cross-compiling. + Bug report from Bert Sutherland + +doc/{bash.1,bashref.texi} + - document new -@ option to cd builtin + + 10/28 + ----- +lib/glob/{{gmisc,glob}.c,glob.h} + - extglob_pattern renamed to extglob_pattern_p, declared in glob.h + +subst.c + - expand_word_internal: typo fix: case to fix " $@\ " bug in bash-4.2 + had a typo (& isexp instead of &&) + + 10/29 + ----- +input.c + - getc_with_restart: make sure local_index and local_bufused are + reset to 0 before returning EOF, in case we are running an interactive + shell without line editing and ignoreeof is set. Report and fix + from Yong Zhang + +lib/readline/search.c + - _rl_nsearch_init: take out extra third argument to rl_message; it + only matches prototype (and maybe format) in cases where + PREFER_STDARG and USE_VARARGS are both undefined, which is rare + + 10/31 + ----- +subst.c + - process_substitute: when opening the named pipe in the child, open + without O_NONBLOCK to avoid race conditions. Happens often on AIX. + Bug report and fix from Michael Haubenwallner + + +builtins/ulimit.def + - RLIMIT_NTHR: if RLIMIT_PTHREAD is not defined, but RLIMIT_NTHR is, + use RLIMIT_NTHR (NetBSD) + + 11/5 + ---- +locale.c + - set_default_locale_vars,set_locale_var: if TEXTDOMAINDIR has been + set, and default_dir has a non-null value, call bindtextdomain(3) + when TEXTDOMAIN is assigned a value. Fixes problem reported by + Michael Arlt + + 11/6 + ---- +builtins/cd.def + - cdxattr: only create synthetic pathname in `buf' if NDIRP argument + is non-null + - change_to_directory: if we have specified -@ and cdxattr returns + failure, fail immediately. Fixes bug reported by Joshuah Hurst + + + 11/12 + ----- +redir.c + - print_redirection: change r_err_and_out (&>) and its append form, + r_append_err_and_out (&>>) cases to separate redirection operator + from filename by a space, in case we have a process substitution. + Fixes bug reported by admn ombres + + 11/15 + ----- +execute_cmd.c + - execute_simple_command: don't close process substitution fds until + we are finished executing any current shell function. Partial fix + for bug reported by John Dawson + +support/shobj-conf + - add support for Darwin 13 (Mac OS X 10.9, Mavericks). Based on a + report by Ludwig Schwardt + + 11/20 + ----- +[bash-4.3-rc1 frozen] + + 11/24 + ----- +builtins/printf.def + - bind_printf_variable: make sure that the variable assigned to is + no longer marked as invisible. Fixes bug reported by NBaH + + + 11/28 + ----- +jobs.c + - delete_old_job: fix off-by-one error in job index in call to + internal_warning. Bug report from Peter Cordes + + 11/30 + ----- +doc/bashref.texi + - add string to description of special parameters with name of + special parameter prefixed by a $, so you can search for $#, + for instance + + 12/2 + ---- +lib/readline/{histexpand.c + - get_history_event: account for current_history() possibly returning + NULL. Report and fix from Pankaj Sharma + + + 12/11 + ----- + +lib/readline/parse-colors.c + - get_funky_string: don't call abort if we see something we can't + parse; just return an error + - _rl_parse_colors: if we encounter an error while parsing $LS_COLORS + we need to leave _rl_color_ext_list as NULL after freeing its + elements, then turn off _rl_colored_stats. Report and fix from Martin + Wesdorp + + 12/13 + ----- + +lib/readline/parse-colors.c + - _rl_parse_colors: if we encounter an unrecognized prefix, throw an + error but try to recover and go on to the next specification + +variables.c + - make_local_variable: for new variables this function creates, set + the att_invisible attribute. All callers from declare_internal. + Indirectly, this is a fix for bug with `declare -n var; var=foo;' + reported by Pierre Gaston + - bind_variable: if assigning to nameref variable that doesn't have + a value yet (e.g., with `declare -n var; var=foo'), don't try to + use the unset name. Fixes a segfault reported by Pierre Gaston + + +execute_cmd.c + - execute_command_internal: make sure last_command_exit_value is set + to 0 after any command executed in the background. Fixes bug + reported by Martin Kealey + + 12/17 + ----- +support/config.{guess,sub} + - updated to latest versions from git + + 12/19 + ----- +parse.y + - struct STRING_SAVER: now has a new `flags' element, to identify the + caller: alias expansion, double-paren parsing, or parse_and_execute + - push_string: now sets flags to PSH_ALIAS if `ap' argument is non-NULL + - push_string: now doesn't attempt to call strlen on a NULL string to + set shell_input_line_size + - parser_expanding_alias, parser_save_alias, parser_restore_alias: new + functions to provide an external interface to push_string and + pop_string; parser_save_alias sets flags element to PSH_SOURCE (could + be renamed PSH_EXTERN someday) + - shell_getc: when yy_getc returns '\0', instead of just testing + whether the pushed_string_list is not-empty before popping it, don't + pop if if the saved string has flags PSH_SOURCE, indicating that + parse_and_execute set it before setting bash_input to the string. + We should continue reading to the end of that string before popping + back to a potential alias. Partial solution for the problem of aliases + with embedded newlines containing `.' commands being executed out of + order reported by Andrew Martin + - shell_getc: when yy_getc returns '\0' and there is a saved string of + type PSH_SOURCE, restart the read without popping the string stack + if we have not read to the end of bash_input.location.string. Rest + of fix for out-of-order execution problem + +externs.h + - parser_expanding_alias, parser_save_alias, parser_restore_alias: new + extern function declarations + +builtins/evalstring.c + - pe_prologue: if the parser is expanding an alias, make sure to add + an unwind-protect to restore the alias; undoes the work that will be + performed by parse_and_execute/parse_string + - parse_and_execute,parse_string: after calling push_stream to save + bash_input, check whether or not the parser is currently expanding + an alias (parser_expanding_alias() != 0). If it is, we want to save + that string in the pushed_string_list, which we do with + parser_save_alias. + + 12/23 + ----- +execute_cmd.c + - execute_for_command: make sure to set line_number before expanding + the word list, so expansion errors have the right line number. + From a report from Ben Okopnik + +expr.c + - exp2: save token pointer before calling readtok(), arrange to use + saved token pointer when printing error token on a division by 0 + error + + 12/27 + ----- +lib/readline/display.c + - rl_redisplay: when calculating effects of invisible characters in a + prompt that is split across physical screen lines to set the indices + of linebreaks, don't bother testing local_prompt_prefix (line 751). + That prefix doesn't matter when calculating prompt visible and + invisible characters. Fixes problem reported by Jinesh Choksi + + +Makefile.in + - install: make sure to use $(DESTDIR) when installing OTHER_DOCS. + Report and fix from Matthias Klose + +doc/texinfo.tex + - updated to version of 2013-09-11 + + 12/28 + ----- +lib/readline/undo.c + - rl_do_undo: if we are undoing from a history entry (rl_undo_list == + current_history()->data), make sure the change to rl_line_buffer is + reflected in the history entry. We use the guts of + rl_maybe_replace_line to do the work. Fixes problem reported by + gregrwm + + 12/30 + ----- +sig.c + - sigint_sighandler: if we get a SIGINT (and this signal handler is + installed) while the wait builtin is running, note that we received + it in the same way as jobs.c:wait_sigint_handler and return. The + various wait_for functions will look for that with CHECK_WAIT_INTR. + This fixes the wait builtin not being interruptible in an interactive + job control shell + + 12/31 + ----- +trap.c + - set_signal_hard_ignored: rename set_signal_ignored to this, since it + both sets original_signals[sig] and sets the HARD_IGNORE flag + - set_signal_ignored: new function, now just sets original_signals[sig] + +trap.h + - set_signal_hard_ignored: new external declaration + +sig.c + - initialize_terminating_signals: call set_signal_hard_ignored instead + of set_signal_ignored for signals with disposition SIG_IGN when the + shell starts + +execute_cmd.c + - setup_async_signals: make sure we get the original dispositions for + SIGINT and SIGQUIT before starting the subshell, and don't call + set_signal_ignored because that sets original_signals[sig]. If we + don't, subsequent attempts to reset handling using trap will fail + because it thinks the original dispositions were SIG_IGN. Posix + interpretation 751 (http://austingroupbugs.net/view.php?id=751) + + 1/2/2014 + -------- +lib/sh/stringvec.c + - strvec_mcreate, strvec_mresize: versions of create and resize that + use malloc and realloc, respectively, instead of xmalloc/xrealloc + +braces.c + - expand_amble,mkseq: use strvec_mcreate/strvec_mresize so we can + catch and handle memory allocation failures instead of aborting + with the xmalloc/xrealloc interface + +lib/sh/strdup.c + - strdup replacement function for ancient systems that don't have it + +lib/sh/itos.c + - mitos: new function, itos that uses strdup instead of savestring + +externs.h + - strvec_mcreate/strvec_mresize: new extern declarations + - mitos: new extern declaration + +configure.ac + - bash version moved to 4.3-rc2 + + 1/6 + --- +doc/bash.1,lib/readline/doc/{rluser.texi,readline.3} + - separate the description of what happens when readline reads the + tty EOF character from the description of delete-char, leaving a + note in the delete-char description about common binding for ^D. + From suggestion by Parke + +lib/readline/doc/{version.texi,history.3,*.texi} + - updated email addresses and copyright dates + + 1/7 + --- +variables.c + - delete_var: new function, just removes a variable from a hash table + and frees it, without doing anything else + - make_variable_value: if we are trying to assign to a nameref variable, + return NULL if the value is null or the empty string or not a valid + identifier + +variables.h + - delete_var: new extern declaration + +subst.h + - ASS_NAMEREF: new define for assignments, means assigning to a nameref + variable + +builtins/declare.def + - declare_internal: if we are creating and assigning to a nameref + variable, make sure the value is a valid variable name (checks done + by make_variable_value via bind_variable_value) and display an + error message, deleting the variable we just created, if it is not. + Fixes bug reported by Peggy Russell + + 1/9 + --- +builtins/declare.def + - declare_internal: turning on nameref attribute for an existing + variable turns off -i/-l/-u/-c attributes (essentially the ones + that cause evaluation at assignment time) for ksh93 compat + +builtins/setattr.def + - show_name_attributes: if asked to display attributes and values for + a nameref variable, don't follow the nameref chain to the end. More + ksh93 compat + + 1/10 + ---- +trap.c + - _run_trap_internal: use {save,restore}_parser_state instead of + {save,restore}_token_state, like in run_pending_traps(); don't + need to save and restore last_command_exit_value as a result + - _run_trap_internal: call {save,restore}_pipeline like in + run_pending_traps() + - run_pending_traps: since we no longer run traps in a signal handler + context, do not block and unblock the trapped signal while the + trap is executing + - run_pending_traps: allow recursive invocations (basically, running + traps from a trap handler) with only a warning if the shell is + compiled in debug mode. If a caller doesn't want this to happen, + it should test running_trap > 0. signal_in_progress (sig) only works + for the signals the shell handles specially + +bashline.c + - bash_event_hook: make sure we clean up readline if interrupt_state + is set, not only when SIGINT is not trapped. check_signals_and_traps + will call check_signals, which calls QUIT, which will longjmp back + to top_level, running the interrupt trap along the way. Fixes the + problem of signal handlers being reset out from under readline, and + not being set properly the next time readline is called, because + signals_set_flag is still set to 1. XXX - might need to do this + for other signals too? + + 1/11 + ---- +subst.h + - SD_GLOB: new define for skip_to_delim; means we are scanning a + glob pattern. + +subst.c + - skip_to_delim: if flags include SD_GLOB, assume we are scanning a + glob pattern. Currently only used to skip bracket expressions + which may contain one of the delimiters + + 1/12 + ---- +subst.c + - parameter_brace_expand: when expanding $@ as part of substring + expansion, pattern substitution, or case modification, don't turn + on the QUOTED_NULL flag. The code that constructs the word to be + returned from expand_word_internal expects a different code path + when $@ is being expanded. Fixes bug reported by Theodoros + V. Kalamatianos + + 1/19 + ---- +subst.c + - list_dequote_escapes: new function; analogue of list_quote_escapes + +pathexp.c + - quote_string_for_globbing: fix case where unescaped ^A is last char + in string; need to pass it through unaltered instead of turning it + into a bare backslash + - quote_string_for_globbing: when quoting for regexp matching in [[, + don't treat backslash as a quote character; quote the backslash as + any other character. Part of investigation into reports from + Eduardo A. Bustamante López + + 1/25 + ---- +builtins/gen-helpfiles.c + - write_helpfiles: add prototype + - make sure to #undef xmalloc/xfree/xrealloc/free if USING_BASH_MALLOC + is defined. the code does not use them, and we don't link against + xmalloc.o. Report from Linda Walsh + +Makefile.in + - variables.o: add dependency on builtins/builtext.h; helps with + parallel builds. Report from Linda Walsh + +support/shobj-conf + - darwin: combine the stanzas into one that will not require them to + be updated on each Mac OS X release. Report and fix from Max Horn + + + 1/27 + ---- +support/shobj-conf + - darwin: changed the install_name embedded into the shared library + to contain only the major version number, not the minor one. The + idea is that the minor versions should all be API/ABI compatible, + and it is better to link automatically with the latest one. Idea + from Max Horn + + 1/29 + ---- +[bash-4.3-rc2 released] + + 1/30 + ---- +lib/readline/readline.h + - rl_clear_history, rl_free_keymap: add extern declarations. Report + from Hiroo Hayashi + +general.c + - include trap.h for any_signals_trapped() prototype + +lib/sh/unicode.c + - include for sprintf prototype + + 1/31 + ---- +execute_cmd.c + - execute_simple_command: only posix-mode shells should exit on an + assignment failure in the temporary environment preceding a special + builtin. This is what the documentation and code comments have + always said + - execute_simple_command: make sure redirection errors, word expansion + errors, and assignment errors to Posix special builtins cause a + non-interactive posix mode shell to exit. Previously the shell + would not exit if the failed special builtin was on the LHS of || + or && + +pathexp.c + - quote_string_for_globbing: when quoting a regular expression + (QGLOB_REGEXP), allow an unquoted backslash to pass through + unaltered. Don't use it as a quote character or quote it. More + investigation from 1/24 and report by Mike Frysinger + + - quote_string_for_globbing: when quoting a regular expression + (QGLOB_REGEXP), turn CTLESC CTLESC into CTLESC without adding a + backslash to quote it. We should not have to quote it because it is + not a character special to EREs. More investigation from 1/24 + +lib/glob/glob.c + - glob_testdir: now takes a second flags argument (currently unused); + changed prototype and callers + + 2/1 + --- +lib/glob/glob.c + - glob_testdir: if flags argument includes GX_ALLDIRS (globstar), use + lstat so we skip symlinks when traversing the directory tree. + Originally reported by Chris Down + + 2/2 + --- +lib/readline/undo.c + - rl_do_undo: make sure CUR is non-zero before dereferencing it to + check cur->data against rl_undo_list. Report and fix from + Andreas Schwab + +doc/{bash.1,bashref.texi} + - added slight clarifying language to the description of $*, + describing what happens when the expansion is not within double + quotes + + 2/4 + --- +test.c + - unary_test: add code to -v case so that it interprets `bare' array + references (foo[1]) and returns true if that index has a value + + 2/5 + --- +trap.c + - restore_default_signal: fix SIGCHLD special case for SIG_TRAPPED flag + off but SIG_INPROGRESS mode set and handler IMPOSSIBLE_TRAP_HANDLER; + continue with resetting handler in this case. maybe_set_sigchld_trap + will check these things before resetting sigchld trap from + run_sigchld_trap. Fixes (apparently long-standing?) problem reported + by Alexandru Damian + + 2/6 + --- +lib/sh/strtrans.c + - ansic_quote: fixed a bug when copying a printable character that + consumes more than one byte; byte counter was not being incremented. + Bug report from jidanni@jidanni.org + + 2/7 + --- +input.c + - getc_with_restart: if read(2) returns -1/EINTR and interrupt_state or + terminating_signal is set (which means QUIT; will longjmp out of this + function), make sure the local buffer variables are zeroed out to + avoid reading past the end of the buffer on the next call. Bug report + from Dan Jacobson + + 2/9 + --- +bashline.c + - command_word_completion_function: if a directory in $PATH contains + quote characters, we need to quote them before passing the candidate + path to rl_filename_completion_function, which performs dequoting on + the pathname it's passed. Fixes bug reported by Ilyushkin Nikita + + + 2/11 + ---- +parse.y + - xparse_dolparen: save and restore shell_eof_token around call to + parse_string, intead of just leaving it set to ')' + - shell_getc: when -v is set, only print the command line when + shell_eof_token is 0, so we don't print it multiple times when + recursively entering the parser to parse $(...) commands. Fixes + bug reported by Greg Wooledge + +[changed release status to 4.3-release] + + 2/13 + ---- +lib/sh/strtrans.c + - ansic_quote: handle case where mbrtowc reports that the multibyte + sequence is incomplete or invalid. Fixes bug reported by + Eduardo A. Bustamante López + + 2/14 + ---- +variables.c + - find_variable_nameref_context: fix a problem that caused the loop + to go one context too close to the global context. In some cases, + simple variable assignment would set a variable in the global + context instead of a local context. Bug report from + Geir Hauge + + 2/26 + ---- +[bash-4.3 released] + + 2/27 + ---- +aclocal.m4 + - broken wcwidth check: fix typo reported by David Michael + + + 2/28 + ---- +support/bashbug.sh + - add ${BUGADDR} to error message printed if sending mail fails + +trap.c + - _run_trap_internal: don't call {save,restore}_pipeline if running + DEBUG trap; run_debug_trap calls them itself. Fixes bug reported + by Moe Tunes + +test.c + - unary_test: fix 'R' case by using find_variable_noref instead of + find_variable + - test_unop: add back missing 'R' case. Fixes bug reported by + NBaH + + 3/2 + --- +jobs.c + - end_job_control: if job control is active, we changed the terminal's + process group, so make sure we restore it. Fixes bug reported by + Eduardo A. Bustamante López + + 3/7 + --- +pcomplete.c + - pcomp_curtxt: new variable, holds the original text to be completed + as passed to the programmable completion code + - pcomp_filename_completion_function: if we are running compgen + (presumably in a shell function completion) and performing readline + completion, check the word being completed. If it's not empty, but + the original word passed to the programmable completion code is an + empty string (""), call a dequoting function if one is available. + This compensates for an assumption in bash-completion. Reported by + Albert Shih + +lib/readline/readline.c + - _rl_dispatch_subseq: when deciding whether or not to set vi mode's + idea of the last command, use whether or not the dispatching keymap + is vi_movement_keymap instead of the key sequence length. The `c', + `d', and `y' commands all take motion commands as `arguments' and + will produce key sequences longer than 1 character. The arrow keys + will end up dispatching out of a different keymap, so the test will + prevent arrow keys from setting the last command (the problem in + bash-4.2). Bug report from Daan van Rossum + +lib/readline/vi_mode.c + - _rl_vi_motion_command: convenience function to test whether a key is + a vi-mode motion command + +lib/readline/rlprivate.h + - _rl_vi_motion_command: extern declaration + +parse.y + - parse_matched_pair: we should not skip processing single quotes in + posix mode if dolbrace_state == DOLBRACE_QUOTE2 (pattern + substitution). Fixes bug reported by David Sines + + + 3/10 + ---- +lib/readline/readline.c + - _rl_dispatch_callback: treat a return value of -1 as the end of + a command dispatch sequence if the current context doesn't + indicate that we're reading a multi-key sequence + ((cxt->flags & KSEQ_SUBSEQ) == 0). Turn off the multikey flag + and free the context chain in this case. Fixes one bug reported + by Felix Yan to bug-readline list + - _rl_dispatch_callback: treat a return value of > 0 the same as 0 + and return from the function, since only values < 0 cause us to + simulate recursion. Rest of fix for bug tracked down by + Anatol Pomozov + + 3/11 + ---- + +execute_cmd.c + - execute_in_subshell: if a longjmp occurs, set result to + EXECUTION_FAILURE only if last_command_exit_value == EXECUTION_SUCCESS; + use value of last_command_exit_value otherwise. Fixes cosmetic + issue reported by Dennis Lambe Jr. + +doc/bash.1 + - shell-kill-word and shell-backward-kill-word should be documented + as unbound by default. Report from Oliver Hartley + + +trap.c + - run_pending_traps: save value of $? before running trap commands in + trap_saved_exit_value, like run_exit_trap + - _run_trap_internal: save value of $? before running trap commands in + trap_saved_exit_value, like run_exit_trap + +builtins/common.c + - get_exitstat: when running `return' in a trap action, and it is not + supplied an argument, use the saved exit status in + trap_saved_exit_value. Fixes Posix problem reported by + Eduardo A. Bustamante López + + 3/13 + ---- +lib/sh/shquote.c + - sh_contains_quotes: new function, returns true if a given string + contains any of the shell quote characters (single quote, double + quote, or backslash) + +externs.h + - sh_contains_quotes: new extern declaration + +pcomplete.c + - pcomp_filename_completion_function: more changes for the benefit of + bash-completion: if the argument is not the same as the original + argument passed to the programmable completion code (pcomp_curtxt), + and we are being run by compgen as part of a completion, dequote the + argument as bash-completion expects. Fix for the complete-word- + with-quoted-special-chars problem with bash-completion + + 3/17 + ---- +execute_cmd.c + - execute_intern_function: when in posix mode, make defining a function + with the same name as a special builtin a fatal error only when the + shell is not interactive. Interactive shells display an error + message and go on. From a discussion with Doug McIlroy + + + 3/18 + ---- +arrayfunc.c + - assign_compound_array_list: when using expand_assignment_string_to_string + to expand the value in a ( [x]=y ) compound assignment, make sure + that we convert 0x0 to "" when expanding [x]= so it doesn't appear as + if the index is unset. Fixes bug reported by Geir Hauge + + +builtins/common.c + - get_exitstat: update fix of 3/11 to allow the DEBUG trap to use the + current value of $? instead of the value it had before the trap + action was run. This is one reason the DEBUG trap exists, and + extended debug mode uses it. Might want to do this only in Posix + mode + +doc/{bash.1,bashref.texi} + - return: add language cribbed from Posix saying what happens when + return is run without an argument from a trap, including the DEBUG + trap exception + + 3/19 + ---- +lib/glob/gmisc.c + - extglob_pattern_p: make sure ?(patlist) is flagged as an extglob + pattern + +lib/glob/glob.c + - extglob_skipname: rewrite to handle patterns that begin but do not + end with an extglob pattern; change test for easy case and loop + through patterns accordingly. Fixes problem with matching filenames + with a leading dot reported by Stephane Chazelas + + - wextglob_skipname: make analogous changes + + 3/20 + ---- +Makefile.in + - pass -DDEBUG down to builds in readline and history directories + +lib/readline/util.c + - _rl_trace and related functions are now only compiled in if DEBUG + is defined + +lib/readline/Makefile.in + - substitute @DEBUG@ and pass -DDEBUG, if necessary, to compilation + in LOCAL_CFLAGS + + 3/21 + ---- +parse.y + - shell_getc: when checking whether or not to reallocate + shell_input_line to add trailing newline, don't try to subtract from + shell_input_line_size. size_t is unsigned, so if its value is less + than 3 (like, say, 2), size-3 is a very large number and the string + will not be reallocated. Use len+3 > size instead of len > size-3. + Fixes bug reported in + https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1295467 + + 3/27 + ---- +lib/readline/display.c + - _rl_clean_up_for_exit: don't bother to call _rl_move_vert to whatever + readline thinks the last displayed line is if it's 0. Two reasons: a + minor optimization, and it protects against unwanted moving if this + function is called twice, as it is when ^C is pressed. Fixes bug + reported by Egmont Koblinger + + 3/28 + ---- +bashline.c + - invalid_completion: new function, used to identify attempts to + complete words that are syntax errors + - attempt_shell_completion: if invalid_completion returns true for a + word in a command position, punt on all completions. Fixes cosmetic + issue reported by Uwe Storbeck + - attempt_shell_completion: add clause so that in_command_position + remains set to 1 for an empty word following a command separator like + (, &, or | + +lib/readline/kill.c + - rl_yank, rl_yank_nth_arg_internal: don't return -1 from bindable + functions, return 1 instead + +lib/readline/text.c + - rl_rubout, _rl_rubout_char, rl_delete, rl_change_case, + rl_transpose_chars, rl_transpose_words, _rl_set_mark_at_pos, + rl_exchange_point_and_mark, _rl_insert_next, _rl_char_search, + _rl_char_search_internal: + don't return -1 from bindable functions, return 1 instead + +lib/readline/vi_mode.c + - rl_vi_end_word, rl_vi_rubout, rl_vi_delete, rl_vi_char_search, + rl_vi_match, _rl_vi_set_mark, _rl_vi_goto_mark: + don't return -1 from bindable functions, return 1 instead + +lib/readline/macro.c + - rl_start_kbd_macro, rl_end_kbd_macro: + don't return -1 from bindable functions, return 1 instead + +builtins/setattr.def + - set_var_attribute: honor setting of no_invisible_vars when setting + att_invisible on a variable + - include "../flags.h" for no_invisible_vars + +builtins/declare.def + - declare_internal: honor setting of no_invisible_vars when setting + att_invisible on a variable + - include "../flags.h" for no_invisible_vars + +Makefile.in,builtins/Makefile.in + - make sure declare.o and setattr.o depend on flags.h + +execute_cmd.c + - decpoint: new function, returns locale's decimal point or `.' default + - mkfmt: use decpoint() to get decimal point instead of unconditionally + using `.'. Fixes bug reported by Andrey Tataranovich + in debian bug 741669 + + 4/10 + ---- +lib/readline/rltypedefs.h + - add back old Function/VFunction/etc typedefs, since other packages + (python, samba) use them. Mark as deprecated using gcc and clang + attributes. Report and fix from Max Horn + + 4/14 + ---- +jobs.c + - run_sigchld_trap: unwind-protect value of this_shell_builtin, since + it matters in some cases whether or not we are running `wait' or + `eval'. Fixes bug reported by Eduardo A. Bustamante López + + + 4/18 + ---- +shell.h + - sh_parser_state_t: add `need_here_doc' flags member, since + xparse_dolparen (via parse_command) sets it to 0 + +parse.y + - gather_here_documents: make sure need_here_doc is > 0, since we + don't want to just decrement it forever if it ends up < 0. Partial + fix for bug reported by Jared Yanovich + - {save,restore}_parser_state: save and restore need_here_doc flag. + Rest of fix for bug reported by Jared Yanovich + + 4/19 + ---- +subst.c + - cond_expand_word: since we are not supposed to be performing word + splitting here, set expand_no_split_dollar_star to 1 in addition to + setting W_NOSPLIT2 + - expand_word_internal: if we have a case where we have an unquoted + $@ but we are in a case where we don't want to split (W_NOSPLIT2), + make sure we return a list consisting of a single word with the + arguments separated by spaces and don't do word splitting. Fixes + bug reported by Greg Wooledge from an IRC + discussion + +builtins/hash.def + - print_portable_hash_info: single-quote pathnames and hashed filenames + that contain shell metacharacters. Fixes bug reported by + in debian bash bug #739853 + + 4/20 + ---- +lib/readline/display.c + - When using horizontal scrolling, the redisplay code erases too much + of the line containing successful results, so make sure we only + erase to the end of the line after making sure we move the cursor + to the end. Fixes bug reported by + + 4/23 + ---- +{bashhist,bashline}.c +builtins{bind,help,type}.def +lib/glob/glob.c, lib/intl/{loadmsgcat,localealias}.c,lib/sh/mktime.c + - fixes to memory leaks uncovered by coverity scan + + 4/24 + ---- +{bashhist,subst,redir,assoc,jobs,array,trap}.c +lib/intl/l10flist.c +builtins/complete.def + - fixes to memory leaks and other resource usage problems uncovered by + coverity scan + +redir.c + - do_redirection_internal: if dup2 fails (presumably because of a + resource limit), close the file descriptor we opened before returning + error + + 4/25 + ---- +config-top.h + - DEFAULT_BASHRC: new define with the name of the default shell + startup file + +bashline.c + - bash_directory_completion_matches: don't dequote the directory name. + If rl_completion_found_quote is non-zero, readline will dequote the + filename itself. Fixes bug reported by Clark Wang + + + 4/27 + ---- +subst.c + - parameter_brace_expand_rhs: if parameter_brace_find_indir returns + NULL or "", or if it returns something that is not a valid identifier, + report an error and return &expand_wdesc_error so the error can + propagate up. Fixes bug reported by Andre Holzhey + + + 4/29 + ---- +subst.c + - parameter_brace_substring: don't short-circuit right away if the + value is NULL but we are looking at the positional parameters. Part + of fix for bug reported by Pierre Gaston + - pos_params: if there are no positional parameters, only short-circuit + if we are looking for $1 and above. Rest of fix for bug reported + by Pierre Gaston + +subst.h + - SD_NOPROCSUB: new flag for skip_to_delim, means to not allow any + process subsitutions (should not have overloaded SD_NOSKIPCMD) + +subst.c + - skip_to_delim: honor SD_NOPROCSUB flag + +make_cmd.c + - make_arith_for_expr: set W_NOPROCSUB flag in the created word + - make_arith_for_command: set SD_NOPROCSUB in the flags argument to + skip_to_delim so we don't treat <( or >( as a process substitution + (we won't evaluate them in eval_arith_for_expr anyway). Fixes + bug reported by Pierre Gaston + + 5/1 + --- +lib/glob/gmisc.c + - glob_dirscan: new function, takes a pattern and a directory separator + argument and advances the pattern to the last occurrence of the + separator. Like strrchr, but understands extended glob patterns and + uses glob_patscan to skip over them + +lib/glob/glob.c + - extglob_skipname: if the extended globbing pattern is invalid, don't + skip the name + - glob_filename: if there is a slash in the pattern to be matched, and + extglob is enabled, use glob_dirscan to find the real last occurrence + of `/' to avoid being confused by slashes in extglob patterns. Fix + for bug reported by Pierre Gaston + + 5/6 + --- +variables.c + - make_local_variable: only set the att_invisible attribute if + no_invisible_vars isn't set + - find_variable_for_assignment: new function, intended to be called by + code that eventually wants to assign a value to the variable; will not + skip invisible variables; currently identical to find_variable + - find_variable_no_invisible: new function, finds the first visible + instance of variable with a given name in the variable context chain; + eventually will be used to replace find_variable; separate right now + for testing + +variables.h + - find_variable_for_assignment: extern declaration + - find_variable_no_invisible: extern declaration + + 5/7 + --- +variables.c + - make_local_variable: don't clear `invisible' attribute if we are + returning an existing local variable at the right context. Let the + upper layers do that. Fixes bug reported by Dan Douglas + + + 5/8 + --- +lib/readline/input.c + - rl_getc: call RL_CHECK_SIGNALS if a read(2) is interrupted (-1/EINTR) + by SIGALRM or SIGVTALRM (placeholder for non-keyboard-generated + signals of interest) + +builtins/read.def + - edit_line: call bashline_set_event_hook and + bashline_reset_event_hook around call to readline(), so the right + signal handling happens + - read_builtin: make sure we add an unwind_protect call to + bashline_reset_event_hook. These changes fix bug reported in + https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1317476 + +bashline.c + - bash_event_hook: make sure we clean up the readline state by calling + rl_cleanup_after_signal if sigalrm_seen is non-zero. The read builtin + sets this when it times out + + 5/12 + ---- +doc/{bash.1,bashref.texi} + - clarify language to make it clear that changing attributes of a + nameref variable (e.g., export), actually changes the attributes of + the referenced variable. Fixes omission noted by Jeff Haemer + + +arrayfunc.c + - bind_array_var_internal: make sure ENTRY no longer has invisible + attribute before returning. Fixes bug reported by Geir Hauge + + + 5/22 + ---- +execute_cmd.c + - shell_execve: if execve fails and we return 127 or 126, make sure to + set last_command_exit_value if a call to file_error or report_error + causes the shell to exit. This ensures that the shell exits with + the right value. + + 6/6 + --- +shell.c + - drop_priv_mode: print an error message on setuid() failure, optionally + exit if errno == EAGAIN, as it can be on Linux when RLIMIT_NPROC for + the target user is exceeded. + +config-top.h + - EXIT_ON_SETUID_FAILURE: new settable define, will cause the shell to + exit if setuid fails with errno == EAGAIN + + 6/10 + ---- +parse.y + - time_command_acceptable: fix so time is accepted everywhere the + grammar is looking for a `compound_list'. Fixes bug reported by + Dale Worley + + 6/12 + ---- +subst.c + - clear_fifo_list: new function, clears FDs associated with open pipes + in current FIFO list without closing the file descriptors. Can + possibly be used when shell_execve fails and the shell jumps back + to top_level and we don't want the shell to close the open FIFOs + each time through the read-execute loop. Bug reported by Harald + Koenig + + + 6/16 + ---- +builtins/shopt.def + - compat42: make sure the `compat42' option sets the correct variable + for compatibility level. Fixes bug reported by Ondrej Oprala + + +support/bashbug.sh + - fix typo when echoing $USAGE. Report from Shantanu Kulkarni + + +execute_cmd.c + - shell_execve: before longjmp back to subshell_top_level, clear out the + FIFO fd list by calling clear_fifo_list so the FDs (which we inherited + from our parent) aren't closed every time through the read-eval loop. + Fix for bug reported by Harald Koenig + + 6/18 + ---- +subst.c + - extract_process_subst: add additional argument: xflags, allow callers to + pass flags like extract_command_subst + - extract_process_subst: call xparse_dolparen like command substitution + to avoid problems when parsing commands constructs with embedded open + parens. Fixes bug reported by Tim Friske + +subst.h + - extract_process_subst: modified prototype for extern declaration + + 6/19 + ---- +execute_cmd.c + - execute_pipeline: if running with lastpipe enabled, make sure that we + check whether or not the job id is valid using INVALID_JOB before + calling job_exit_status. the jobs list can get frozen and unfrozen in + the presence of nested pipelines and loops and wait_for can clear a + job table entry. Fixes bug reported by + +jobs.c + - freeze_jobs_list: now returns old value of jobs_list_frozen; unused at + current time + +jobs.h + - freeze_jobs_list: change return value + + 6/20 + ---- +lib/glob/smatch.c + - MEMCHR: single-byte and wide character defines (memchr/wmemchr) + +lib/glob/sm_loop.c + - GMATCH: when the wildcards are the last element of the pattern, make + sure they do not match a string containing a `/' if FNM_PATHNAME is + set in FLAGS + - GMATCH: when recursively calling GMATCH after we see a `*', don't + try to consume the rest of the pattern with `*' if FNM_PATHNAME is + set in FLAGS, just consume up to the next slash and then see whether + or not the rest of the pattern matches. Fixes bug reported by Ian + Kelling + - GMATCH: when processing `*' in the pattern, after skipping consecutive + wildcards, if we hit a literal `/' in the pattern and we're looking + for a pathname, skip characters in the string until we find a `/' + (no slash means the match fails), and try to match the rest of the + pattern against the portion of the string after the next `/'. Picked + up from gnulib/glibc + +pathexp.c + - split_ignorespec: since split_ignorespec gets globbing patterns, + make sure we call skip_to_delim with the SD_GLOB flag so delimiters + that occur within bracket expressions don't delimit the pattern. + Fixes problem with [[:digit:]] in GLOBIGNORE reported by Ian Kelling + + +unwind_prot.c + - unwind_protect_tag_on_stack: new function, returns 1 if unwind-protect + frame corresponding to `tag' argument is on unwind-protect stack + +unwind_prot.h + - unwind_protect_tag_on_stack: extern declaration + + 6/30 + ---- +lib/readline/misc.c + - _rl_revert_all_lines: set entry->data to 0 after assigning it to + rl_undo_list to avoid pointer aliasing problems that would result + in entry->line being freed by an undo. The subsequent free would + be a double free. Report and fix from Jared Yanovich + + +subst.c + - command_substitute: other shells do not appear to inherit the -v + option when reading and executing command substitutions. Reported + by Ondrej Oprala + + 7/1 + --- +config-top.h + - CHECKHASH_DEFAULT: new define that supplies the default value for + check_hashed_filenames (`checkhash' shopt option); still 0 by default + +findcmd.c + - check_hashed_filenames: initialize using CHECKHASH_DEFAULT + +lib/readline/histexpand.c + - history_expand: double quotes can inhibit recognition of the history + comment character if history_quotes_inhibit_expansion is non-zero + +lib/readline/doc/{history.3,hstech.texi} + - history_quotes_inhibit_expansion: expand definition to note that it + inhibits scanning for the history comment character as well; correct + typo to make it clear that it only works on double-quoted strings + +lib/sh/zgetline.c + - add new fourth argument: DELIM, allows delimiter to be something + other than newline (if DELIM != '\n', UNBUFFERED_READ should be + non-zero) + - UNBUFFERED_READ is now fifth argument + - check character against DELIM rather than strictly newline + +externs.h + - zgetline: change function prototype for extern declaration + +builtins/mapfile.def + - mapfile: change calling sequence for zgetline calls + - mapfile_builtin: new -d option: DELIM, like in read builtin + - mapfile_builtin: pass `delim' to mapfile() as new argument; default + to '\n' unless -d option supplied + - mapfile: take new DELIM argument, pass to zgetline + - mapfile: if DELIM != '\n', set unbuffered_read to 1 + +doc/{bash.1,bashref.texi} + - mapfile: document new `-d DELIM' option + + 7/5 + --- +lib/readline/histfile.c + - history_truncate_file: if there is an error writing the truncated + history list back to the history file, use the same strategy as + history_do_write: create a backup file, rename the history file to + the backup file, and restore the original history file from the + backup file name if the write or the close fails. Suggestion from + Chen Gang to bug-readline + +execute_cmd.c + - evalnest, evalnest_max: new variables establishing maximum number of + recursive `eval' calls; current max is 4096 + - execute_builtin: unwind-protect value of evalnest around calls to + eval builtin. Suggested by Oliver Morais + - {initialize_subshell,execute_subshell_builtin_or_function}: reset + evalnest to 0 in a subshell + +builtins/setattr.def + - show_name_attributes: show a variable's attributes even if it's + invisible (don't show any value since it has none). This means that + declare -p var will display VAR's attributes even when var marked + as invisible. Feature request from Peggy Russell + + - show_var_attributes: don't print assignment if array or assoc + attribute is set but variable marked as invisible + +tests/array.right + - special note: changed all declare -a output tests because the shell + will no longer print out values for invisible array variables. This + is a change, but one for correctness: + + declare -a foo='()' + and + declare -a foo + are not equivalent + + 7/22 + ---- +subst.c + - parameter_brace_expand: after calling parameter_brace_expand_indir, + turn off the W_ARRAYIND flag in the word it returns, because there + is no way for it to return the index that should be used, and the + rest of the function assumes that IND is valid if W_ARRAYIND is set. + Fixes bug reported by Corentin Peuvrel + + 8/2 + --- +parse.y + - read_token_word: if we read a character that will end a command + substitution, don't skip over quoted newlines when we read an + additional character to figure out whether it's a two-character + token. This lets the higher layers deal with quoted newlines after + the command substitution. Fixes bug reported by EmanueL Czirai + + + 8/11 + ---- +execute_cmd.c + - execute_pipeline: check whether lastpipe_jid corresponds to a valid + job before calling append_process, for the same reason as fix from + 6/19. Fixes bug reported by + + 8/12 + ---- +lib/sh/unicode.c + - stub_charset: use strncpy instead of strcpy because we are copying + into a local fixed-length buffer. Fixes vulnerability reported by + + +execute_cmd.c + - execute_pipeline: if we don't call append_process, call + wait_for_single_pid to get the status of `lastpid', since that will + check the status of already-reaped processes. Fixes spurious error + message about non-existent process from fix of 8/11 + + 8/15 + ---- +jobs.c + - running_in_background: new variable, keeps track of whether or not we + are running in the background (not perfect yet) + - initialize_job_control: even if we are not turning on job control, + get the terminal pgrp so we can use it later + - {set_job_control,initialize_job_control}: set running_in_background + to 1 if terminal pgrp != shell pgrp + - {stop_pipeline,make_child,wait_for}: if we are running in the + background, don't mess with the terminal's process group; assume that + the parent shell will do that. Fixes bug reprted by Greg Wooledge + + +shell.c + - shell_reinitialize: reset running_in_background back to 0 + + 8/24 + ---- +execute_cmd.c + - {execute_connection,execute_command_internal}: make sure that + asynchronous commands always set $? to 0 and are not affected by the + command's exit status being inverted using `!'. Fixes bug reported + by Vincent Lefevre + +lib/readline/display.c + - rl_message: call vsnprintf with full msg_bufsiz, since it counts + one fewer than the buffer length passed as an argument. Bug report + and fix from Dylan Cali + + 8/26 + ---- +builtins/evalstring.c + - evalstring: if CURRENT_TOKEN == yacc_EOF, reset it to newline. This + is instead of calling reset_parser(); that might still be needed. + Fixes bug with eval and a subsequent statement ending with EOF + reported by + +pcomplete.c + - filter_stringlist: when extglob is on, a leading ! in the filter + pattern should be left alone when it introduces a !(pat) pattern; + otherwise it messes up the pattern. Fixes bug reported by David + Korn + + 8/27 + ---- +doc/{bash.1,bashref.texi} + - clarify the behavior of bash when given the -c option, since $0 is + technically not a positional parameter. Bug reported by Stephane + Chazelas + + 8/28 + ---- +lib/readline/history.c + - add_history: use history_max_entries (if history is stifled) or + DEFAULT_HISTORY_INITIAL_SIZE if not (new define, defaults to 502) + to size the initial allocation of the history array. Assumption + is that this will reduce the number of allocations + + 8/29 + ---- +execute_command.c: + - sourcenest, sourcenest_max: new variables used to track level of + sourced files and (maybe) one day catch infinite source recursion + - execute_builtin: if current source level exceeds sourcenest_max, + trigger an error and jump back to the top level + - {initialize_subshell,execute_subshell_builtin_or_function}: reset + sourcenest to 0 in a subshell + + 9/2 + --- +variables.c + - bind_variable: if a nameref expands to an array reference, make + sure that assign_array_element gets called (maybe even + recursively) instead of bind_variable_internal, so invalid variable + names (like arr[0]) don't get created. Fixes bug reported by + + + 9/3 + --- +execute_cmd.c + - evalnest_max,sourcenest_max: initialize from EVALNEST_MAX and + SOURCENEST_MAX, respectively. Feature suggested by + + +config-top.h + - define EVALNEST_MAX and SOURCENEST_MAX to 0 + + 9/6 + --- +bashline.c + - find_cmd_start: fix to (crudely) deal with >| token; even though + skip_to_delim finds `|' as a delimiter, we call it again and use + what the second call finds. Fixes bug reported by Dan Jacobson + + +findcmd.c + - find_in_path_element: if in posix mode, do not expand a literal + tilde in a $PATH element + +doc/bashref.texi + - add change to tilde expansion in $PATH elements to posix mode + description + +builtins/common.h + - ISHELP: new define for builtins that do their own option parsing + and don't use internal_getopt(); checks whether argument is --help + - CHECK_HELPOPT: convenience define to help builtins that do their + own option parsing to check for --help with one line of code + - CASE_HELPOPT: convenience define to help builtins that use + internal_getopt() check for --help with one line of code + +builtins/help.def + - builtin_help: new function, prints out --help output for current + builtin + +builtins/{kill,let,pushd}.def + - add CHECK_HELPOPT to builtins that use ISOPTION; call builtin_help + and return EX_USAGE (kill/let/pushd/popd/dirs) + +builtins/{caller,fg_bg}.def + - use CHECK_HELPOPT to recognize --help, since these builtins perform + checks that can cause them to return before calling no_options + (caller/fg/bg) + +builtins/{exit,return}.def + - use CHECK_HELPOPT to recognize --help before calling get_exitstat() + (return/exit/logout) + +builtins/{break,shift}.def + - use CHECK_HELPOPT to recognize --help before any other checks + (break/continue/shift) + +builtins/bashgetopt.h + - GETOPT_EOF: convenience define + - GETOPT_HELP: new define, to indicate internal_getopt saw --help + +builtins/bashgetopt.c + - internal_getopt: return GETOPT_HELP for --help + +builtins/common.c + - no_options: recognize --help, call builtin_help and return 2 + (builtin/eval/source/./times) + +builtins/command.def + - use CASE_HELPOPT() to handle --help after calling internal_getopt() + (command) + +builtins/{colon,echo,test}.def + - do not recognize --help (:/true/false/echo/test) + + 9/8 + --- +sig.c + - termsig_sighandler: if readline is active now, set the bashline event + hook. Old code just set it for interactive shells. Part of fix for + bug reported by + +bashline.c + - bash_event_hook: call rl_cleanup_after_signal if terminating_signal + is non-zero, since check_signals_and_traps() will cause the shell to + exit if it is and we want to clean up the readline state first. Rest + of fix for bug reported by + + 9/9 + --- +jobs.c + - waitchld: when running the wait builtin in posix mode, with a trap set + on SIGCHLD, use queue_sigchld_trap instead of trap_handler (SIGCHLD), + otherwise you will lose SIGCHLDs when children_exited > 1. Fixes bug + reported by + +builtins/read.def + - read_builtin: if we are changing the tty settings, call + initialize_terminating_signals so we have a chance to catch all + terminating signals and potentially clean up the terminal before + exiting + - read_builtin: tty_modified: new variable, set to 1 if we change the + terminal attributes and have to call ttyrestore() to restore them + - if one of the `reads' returns -1/EINTR due to a terminating signal, + and we have modified the terminal, call ttyrestore before calling + CHECK_TERMSIG + - ttyrestore: set tty_modified to 0 when called + + 9/10 + ---- +builtins/read.def + - termsave: now global to file so other functions can use it + - read_tty_cleanup: if tty_modified is non-zero, call ttycleanup to + restore old terminal settings and turn off tty_modified + +sig.c + - termsig_handler: call read_tty_cleanup if currently executing read + builtin; it does the right thing. Final piece of fix for bug reported + by Jan Rome + + 9/11 + ---- +general.c + - printable_filename: general function to return a printable + representation of a string (presumed to be a filename) + +general.h + - extern declaration for printable_filename + +execute_cmd.c + - execute_disk_command: use printable_filename + +builtins/{bind,cd,enable,hash,source}.def + - use printable_filename as appropriate when printing error messages. + From a suggestion by Vincent Lefevre + +builtins/bind.def + - use CASE_HELPOPT() to handle --help after calling internal_getopt() + (bind) + + 9/12 + ---- +builtins/common.h + - SEVAL_FUNCDEF: new flag for parse_and_execute; it means that we only + accept a single function definition command, as when we are importing + functions from the environment + - SEVAL_ONECMD: new flag for parse_and_execute; for future use + +builtins/evalstring.c + - parse_and_execute: if the SEVAL_FUNCDEF flag is set, disallow anything + but a function definition command + +variables.c + - initialize_shell_variables: don't allow functions with invalid names + to be imported from the environment, even though we still allow them + to be defined + - initialize_shell_variables: when importing function definitions from + the environment, call parse_and_execute with the SEVAL_FUNCDEF flag + to force the command to be just a function definition + +subst.c + - param_expand: when expanding a $name variable expansion, make sure that + the variable is visible and set before following the nameref chain + - param_expand: when expanding a $name variable expansion and following the + nameref chain, make sure the resulting variable is visible and set + before using it + + 9/13 + ---- +variables.c + - initialize_shell_variables: when importing function definitions from + environment, use SEVAL_ONECMD flag for parse_and_execute. Part of + CVE-2014-6271 + +builtins/evalstring.c + - parse_and_execute: if SEVAL_ONECMD flag set, return immediately after + calling execute_command_internal. Final piece for fix for bug + reported by Stephane Chazelas . Part of + CVE-2014-6271 + + 9/24 + ---- +parse.y + - reset_parser: reset eol_ungetc_lookahead to 0 here, since we don't want + shell_getc returning it on the next call. Fixes problem reported by + Tavis Ormandy and Michal Zalewski + . Potentially part of CVE-2014-6271; fix for + CVE-2014-7169 + + 9/25 + ---- +parse.y + - push_heredoc: new function, pushes a here-doc redirection onto + redir_stack handling overflow of redir_stack. Exits on overflow. + Original fix from Florian Weimer . Fix for + CVE-2014-7186 + - change straight assignments to redir_stack to call push_redir + - add one to size of word_lineno stack to avoid off-by-one error + below in read_token_word. Overflow just results in line numbers + being wrong. Fix for CVE-2014-7187 + + 9/27 + ---- +{execute_cmd,trap}.c + - changes to make minimal-config builds work again, mostly missing + #ifdefs for optional features + +builtins/common.c + - builtin_help: dummy version to be included if HELP_BUILTIN not + defined, for minimal-config builds + +variables.c + - initialize_shell_variables: incorporated patches from Florian + Weimer to change the strings bash looks + for when importing shell functions from the environment. It + adds a prefix (BASH_FUNC_) and a suffix (%%) to the name to + mark it as having been created by bash as an exported function. + Fix for remote attacks part of CVE-2014-6271 and CVE-2014-7169 + - mk_env_string: takes new argument, indicating whether we are + constructing a function + - mk_env_string: encodes function names as described above, so + initialize_shell_variables can find them + + 9/28 + ---- +copy_cmd.c + - copy_redirects: before calling savestring on here_doc_eof, make + sure it's not NULL (it could have been the result of a here + document delimited by EOF or EOS). Fixes bug reported by + Michal Zalewski . Fix for CVE-2014-6277 + +make_cmd.c + - make_redirection: initialize here_doc_eof member to NULL. Rest of + fix for CVE-2014-6277 + + 9/29 + ---- +parse.y + - current_input_line_state: return a sh_input_line_state_t containing + the current shell_input_line and its index and size variables + +shell.h + - current_input_line_state: extern declaration + +builtins/evalstring.c + - parse_and_execute: call reset_parser() before returning if + SEVAL_ONECMD set. Fixes bug reported by Michal Zalewski + and designated CVE-2014-6278 + - parse_and_execute: if we parse a function definition when + SEVAL_FUNCDEF is set, but don't consume the entire passed string, + throw an error, reset the parser, and return. Part of fix for + CVE-2014-6278 + - parse_and_execute: if parsing the shell function definition when + SEVAL_FUNCDEF is set transforms the function name (e.g., if it + begins with a newline or begins or ends with whitespace), throw + an error, reset the parser, and return. Fixes bug reported by + Eric Kobrin + + 10/2 + ---- +jobs.c + - bgp_prune: don't do anything if bgpids.npid == 0 or bgpids.list == NULL. + This can happen if something gets run before the job control framework + is initialized. Bug report from + + 10/3 + ---- +parse.y + - xparse_dolparen: don't set token_to_read to newline after calling + parse_string() and cleaning up when the shell is not interactive. This + makes the parser think it's ok to read new commands even if it's not in + a state where that should be possible. Underlying fix for bug reported + by Michal Zalewski and designated CVE-6278 + - parser_remaining_input: new function, returns the portion of + shell_input_line that hasn't yet been read + - current_input_line_state: removed + +shell.h + - parser_remaining_input: extern declaration + - current_input_line_state: removed + +builtins/evalstring.c + - parse_and_execute: change code that checks whether parse_command has + consumed the entire passed string when SEVAL_FUNCDEF is used to use + parser_remaining_input instead of messing around with (new) + current_input_line_state. Part of fix for CVE-2014-6278 + +variables.c + - initialize_shell_variables: if we don't call parse_and_execute, free + the temporary string, since parse_and_execute won't. Report and fix + from Eric Kobrin + + 10/4 + ---- +print_cmd.c + - print_function_def: when in posix mode, print shell function + definitions as posix specifies them, without the leading + `function' keyword + +general.c + - exportable_function_name: return 1 if the passed string can be + added to the environment as an exported function name. Currently + prohibits function names containing `/' and `=' from being + exported + +general.h + - exportable_function_name: extern declaration + +builtins/setattr.def + - set_or_show_attributes: if exporting a function with export -f, + call exportable_function_name to determine whether the function + should be exported; don't export function if it returns 0 + + 10/7 + ---- +builtins/setattr.def + - set_or_show_attributes: don't show identifiers that are invisible + and imported from the environment, since that combination of + attributes means that the imported variable is not a valid shell + identifier. Report from Stephane Chazelas + + + 10/8 + ---- +shell.c + - shell_initialize: set new variable should_be_restricted, which + says whether or not the shell will be a restricted one based on the + shell name; use in calls to initialize_shell_variables (to inhibit + importing shell functions) and initialize_shell_options (to inhibit + parsing $SHELLOPTS) and initialize_bashopts (to inhibit parsing + $BASHOPTS). Report from + + 10/12 + ----- +execute_cmd.c + - execute_function: unwind-protect loop_level, set loop_level to 0 + when entering a function so break and continue in functions don't + break loops running outside of the function. Fix picked up from + dash via Herbert Xu + + 10/13 + ----- +doc/Makefile.in + - bashref.pdf: create using texi2dvi --pdf rather than postprocessing + the dvi file, so we have PDF bookmarks and links. Fix from + Siep Kroonenberg + + 10/14 + ----- +subst.h + - Q_ARITH: new quoting flag. Semantics are per Posix's spec for + arithmetic expansion: act as if string is quoted, but don't treat + double quotes specially (in this case, they will be removed by quote + removal) + - Q_ARRAYSUB: new quoting flag, indicates we are expanding an indexed + array subscript + +subst.c + - expand_arith_string: if we are not expanding the string, but we saw + a quote with Q_ARITH specified as one of quoting flags, perform + quote removal even if Q_DOUBLE_QUOTES is specified + - param_expand: change calls to expand_arith_string for $[ and $(( + cases to specify Q_ARITH. Now $(( "$x" )) and $(( "x" )) work if x + has a value that evaluates to a valid number, as Posix specifies + - expand_word_internal: add test for quoted&Q_ARITH to the tilde case, + so we continue to perform tilde expansion in arithmetic contexts + - expand_word_internal: if quoted&Q_ARITH, continue processing when we + see a `"', acting as if the double quote isn't present (already + Q_DOUBLE_QUOTED) + +arrayfunc.c + - array_expand_index: pass Q_DOUBLE_QUOTED|Q_ARITH|Q_ARRAYSUB as quoted + argument in call to expand_arith_string. This inhibits word + splitting (Q_DOUBLE_QUOTED) while discarding double quotes (Q_ARITH), + identical to the quote flags passed while expanding $(( )) and $[ ]. + Q_ARRAYSUB reserved for future use. Fixes problem reported by + Stephane Chazelas + + 10/16 + ----- +subst.c + - parameter_brace_expand_word: if the PF_ASSIGNRHS flag is set and we + are expanding what looks like an array subscripted with @ or *, + make sure the variable we're expanding is actually an array before + we add Q_DOUBLE_QUOTES to the flags. If we don't, things like + scalar[@] will remain quoted. Fixes ubuntu bug 1381567 + https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1381567 + + 10/17 + ----- +{jobs,nojobs}.c + - get_original_tty_job_signals: get original signal dispostions for + SIGTSTP, SIGTTIN, SIGTTOU before we start manipulating them in + make_child + - default_tty_job_signals: make sure we set SIGTSTP, SIGTTIN, or + SIGTTOU to SIG_IGN if they were ignored at shell startup instead of + unconditionally setting them to SIG_DFL. Fixes bug reported by + idallen@idallen.ca + +jobs.h + - get_original_tty_job_signals: extern declaration + +trap.c + - initialize_traps: add call to get_original_tty_job_signals + + 10/22 + ----- +subst.c + - expand_string_for_rhs: when expanding in this context (rhs of a word + expansion or pattern removal), we don't perform word splitting, so + we don't want to split $* if IFS is empty. Fixes bug reported by + Stephane Chazelas + + 10/23 + ----- +subst.c + - param_expand: when expanding $* in a pattern context where the + expansion is quoted (Q_PATQUOTE), don't quote the expansion -- + the outer quotes don't make the characters in the expansion of + $* special. Posix interp 221. Reported by Stephane Chazelas + + + 10/28 + ----- +lib/readline/bind.c + - enable-bracketed-paste: new bindable variable, enables support for + a terminal's `bracketed paste mode'. Code contributed by + Daniel Colascione + +doc/bash.1,lib/readline/doc/{readline.3,rluser.texi} + - enable-bracketed-paste: add description + +lib/readline/{readline.c,rlprivate.h} + - _rl_enable_bracketed_paste: declarations + - #defines for use by bracketed paste implementation + +lib/readline/rltty.c + - rl_prep_terminal: send BRACK_PASTE_INIT string to terminal if we + are supposed to enable bracketed-paste mode; change terminal_prepped + to indicate we sent that string and need to clean up + - rl_deprep_terminal: if terminal_prepped indicates we sent the + bracketed-paste mode init string to the terminal, send the cleanup + string before restoring the terminal modes + +lib/readline/kill.c + - rl_bracketed_paste_begin: function to read bracketed paste until + BRACK_PASTE_SUFF; discard the suffix, and insert the rest of the + paste as a single (undoable) object. Bound to BRACK_PASTE_PREF + +lib/readline/funmap.c + - bracketed-paste-begin: new bindable command, executes + rl_bracketed_paste_begin + +lib/readline/readline.c + - bind_bracketed_paste_prefix: new function, sets up to recognize + the bracketed paste prefix sequence (BRACK_PASTE_PREF) in emacs + keymap and vi insertion keymap + - readline_initialize_everything: call bind_bracketed_paste_prefix + + 11/1 + ---- +builtins/ulimit.def + - RLIMIT_POSIXLOCKS: now synonym for RLIMIT_LOCKS + - -k: new option: RLIMIT_KQUEUES, max kqueues allocated for this + process + - -P: new option: RLIMIT_NPTS, max number of pseudoterminals available + to this process + +doc/{bash.1,bashref.texi} + - document `ulimit -k' option + - document `ulimit -P' option + +parse.y + - `timespec list_terminator' production: if the list terminator is `;' + set last_read_token to `;' to allow things like `time ; command' to + time null commands and not throw a syntax error. Patch from + Piotr Grzybowski + - `BANG list_terminator' production: do the same thing + +variables.c + - sv_optind: use find_shell_variable and get_variable_value so we can + have the variable's context in the case we need to do something + when we are restoring a previous variable context's value + +builtins/getopt.h + - sh_getopt_state_t: struct to save sh_getopt's internal state so we + can restore it around function calls in the event that we have a + local copy of OPTIND + +builtins/getopt.[ch] + - sh_getopt_{save,restore}_istate: new functions to save and restore + getopt's internal state + - sh_getopt_{alloc,dispose}_istate: new functions to allocate and + deallocate sh_getopt_istate_t objects + +execute_cmd.c + - maybe_restore_getopt_state: restore sh_getopt state after executing + function body iff the funtion declared a local copy of OPTIND + - execute_function: save sh_getopt state before executing function body + - execute_function: note in getopt_state->flags whether or not the + function declared a local copy of OPTIND; used by + maybe_restore_getopt_state + - execute_function: maybe restore sh_getopt state before returning via + call to maybe_restore_getopt_state. Fixes bugs with getopts and + state between calls reported in 2011 by Bernd Eggink + and in 2014 by Oyvind Hvidsten + + +configure.ac + - enable-function-import: new option, controls whether function imports + are included. Enabled by default. Patch from David Galos + + +config.h.in + - FUNCTION_IMPORT: define controlled by enable-function-import above + +variables.c + - initialize_shell_variables: include code to import function + definitions from the environment if FUNCTION_IMPORT is defined + +doc/bashref.texi + - --enable_function-import: document new configuration option + + 11/5 + ---- +lib/readline/history.c + - history_lines_read_from_file: new variable, set by read_history and + read_history_range to the actual number of lines read from the + history file. The value is valid immediately after a call to one + of those functions + - history_lines_written_to_file: new variable, set by write_history, + history_do_write, and history_truncate_file to the actual number of + lines written to the history file. The value is valid immediately + after a call to one of those functions + +variables.c + - sv_histsize: set history_lines_in_file after history_truncate_file() + only if hmax < history_lines_in_file (lines we've already read); a + cosmetic change only + +bashhist.c + - load_history: set history_lines_in_file after read_history() from + history_lines_read_from_file, since read_history reads all of the + lines from the history file even if it's more than $HISTSIZE + - maybe_save_shell_history: after calling write_history(), set + history_lines_in_file to history_lines_written_to_file, since we + can assume that we read everyhing we just wrote + +builtins/history.def + - history_builtin: after calling read_history (history -r), set the + new value of history_lines_in_file, for the same reason as above + - history_builtin: after calling read_history_range (history -n), set + history_lines_in_file from history_lines_read_from_file + + 11/6 + ---- +lib/readline/histfile.c + - history_truncate_file: since we move the old file to a backup copy + before truncating, make sure the new file is owned by the same uid + as the old + - history_do_write: use chown in the same way as history_truncate_file + + 11/12 + ----- +lib/readline/display.c + - expand_prompt: takes a new `flags' argument; only one flag defined + so far: PMT_MULTILINE + - expand_prompt: changed all callers to add new flags argument + - rl_expand_prompt, redraw_prompt: make sure to set PMT_MULTILINE in + FLAGS argument to expand_prompt if expanding parts of a prompt + containing embedded newlines + - expand_prompt: only add mode char to last line of a prompt with + embedded newlines, so mode indicator doesn't get lost and gets + updated properly. Fixes problem reported by Renlin Li + + + 11/13 + ----- + +lib/readline/display.c + - prompt_modestr: changed prompt_modechar to return a string denoting + the editing mode; default strings for emacs and both vi modes are + #defines in this file. prompt_modestr takes an argument in which + it returns the length of the mode string + - expand_prompt: if expanding mode strings in the prompt, get the + mode string to use and add it at the beginning of the prompt string, + before expanding it. This will allow future work allowing the mode + string to contain invisible characters + + 11/15 + ----- +lib/readline/rlprivate.h + - _rl_{emacs,vi_cmd,vi_ins}_mode_str: extern declarations for + variables to hold current values of user-settable mode strings; + variables to hold lengths + +lib/readline/rlconf.h + - defines for default values of the mode strings for each editing mode + and keymap + +lib/readline/display.c + - _rl_{emacs,vi_cmd,vi_ins}_mode_str: new variables to hold values of + user-settable mode strings + - _rl_{emacs,vi_cmd,vi_ins}_modestr_len: new variables to hold lengths + of corresponding mode string variables + - prompt_modestr: return appropriate user-settable mode string + variables + +lib/readline/bind.c + - {emacs,vi-ins,vi-cmd}-mode-string: new user-settable mode string + variables + - sv_{emacs,viins,vicmd}_modestr: variable handling functions for user- + settable mode string variables. Non-null values are run through + rl_translate_keyseq so users can include invisible character + sequences in the mode strings; null values restore the default + - _rl_get_string_variable_value: handle values for new user-settable + mode string variables. Original code contributed by Dylan Cali + + +lib/readline/doc/rluser.texi + - {emacs,vi-ins,vi-cmd}-mode-string: document, including the fact that + you can use \1 and \2 to bracket sequences of non-printing + characters + + 11/16 + ----- +lib/readline/history.c + - add_history: replace loop that copies history list down one item + with call to memmove to take advantage of whatever efficiencies + libc can offer. Won't be any slower than current loop + +lib/readline/display.c + - rl_redraw_prompt_last_line: new function, calls redraw_prompt if + the prompt contains multiple lines; calls rl_forced_update_display + if not + +lib/readline/readline.h + - rl_redraw_prompt_last_line: extern declaration, undocumented in + texinfo manual until I get it a little more work + +bashline.c + - bash_execute_unix_command: instead of unconditionally calling + rl_forced_update_display, call rl_redraw_prompt_last_line if we + cleared the last line before executing the command. This keeps + commands that don't display any other output but just manipulate + the contents of the line buffer from redisplaying the prompt lines + before the last newline multiple times. Fixes bug reported by + Jesper Nygards and Rob Foehl + . This means that commands that display output + will *only* display the final line of the prompt + - bash_execute_unix_command: if the command returns 124, we redraw + the line unconditionally, including all lines of the prompt + + 11/18 + ----- +builtins/mapfile.def + - mapfile_builtin: don't allow a valid array reference through to + mapfile(), since it will just create a shell variable with that name. + Bug and fix from Eduardo A. Bustamante López + + 11/19 + ----- +lib/readline/complete.c + - _rl_colored_completion_prefix: new variable, if non-zero, and color + support is compiled in, and the $LS_COLORS variable exists and + contains color definitions, display any common prefix of a set of + completions in blue when displaying all the possible completions. + Doesn't work with menu-complete, which inserts possible completions + inline + - colored_prefix_start(), colored_prefix_end(): new functions, used to + bracket colored completion prefixes + - fnprint: if prefix_bytes is non-zero, and _rl_colored_completion_prefix + is > 0, display the first PREFIX_BYTES bytes of the word bracketed + by calls to colored_prefix_start and colored_prefix_end + - print_filename: if _rl_colored_completion_prefix is > 0, compute the + length in bytes of the common prefix and pass that to fnprint + +lib/readline/readline.c + - readline_initialize_everything: initialize the colors from $LS_COLORS + if _rl_colored_completion_prefix is non-zero + +lib/readline/colors.c + - _rl_print_prefix_color: new function, changes text color to that + defined for the common prefix of a set of possible completions + (currently cyan, same as directories); currently uses C_PREFIX, + defined in colors.h as C_DIR + +lib/readline/colors.h + - _rl_print_prefix_color: new extern declaration + +lib/readline/bind.c + - colored-completion-prefix: new bindable variable, if set, common + prefix of a set of possible completions is displayed in color. + Feature requested by several, most recently by Richard Neill + (in a slightly different form) and + Duy Nguyen + + 11/20 + ----- +builtins/printf.def + - printf_builtin: allow null (empty) format strings supplied with + -v var to set `var' to the empty string. That is, printf -v var "" + is now the same as var="". Change suggested by Mike Frysinger + + +pathexp.h + - FNMATCH_NOCASEGLOB: macro to decide whether or not to pass + FNM_CASEFOLD flag to strmatch depending on whether glob_ignore_case + is set; analogout to FNMATCH_IGNCASE + +pathexp.c + - glob_name_is_acceptable: use FNMATCH_NOCASEMATCH to determine flags + passed to strmatch; if nocaseglob is used to generate glob matches, + it should be used to generate ignored matches + + 11/21 + ----- +pcomplete.c + - filter_stringlist: the call to strmatch now honors the setting of + nocasematch. Feature request from Ville Skytta + back in 2010 + +doc/bash.1,lib/readline/doc/rluser.texi + - complete -X: document that filtering the list of possible completions + honors the nocasematch option when performing matching + +lib/glob/gmisc.c + - include chartypes.h and strmatch.h for new defines + - match_pattern_{wchar,char}: now take new third FLAGS argument, flags + have same meanings as strmatch(); intent is to handle case + insensitive comparisons under same conditions as strmatch + - FOLD: imported case-folding define from sm_loop.c; wide and single- + byte character versions + - match_pattern_{wchar,char}: use FOLD when comparing characters to + honor FNM_CASEFOLD if set in FLAGS argument + +externs.h + - match_pattern_{wchar,char}: updated extern declarations + +subst.c + - match_{upattern,wpattern}: update strmatch/wcsmatch calls to include + FNMATCH_IGNCASE in flags argument + - match_{upattern,wpattern}: update match_pattern_{char,wchar} calls + to include FNMATCH_IGNCASE in flags argument (consistent with calls + to strmatch). This makes pattern substitution word expansion honor + nocasematch shell option. Feature requested by Davide Baldini + + - match_wpattern: make sure to fold case if necessary when doing simple + matching + +doc/{bash.1,bashref.texi} + - pattern substitution: updated description to include honoring setting + of nocasematch when performing matching + +subst.c + - expand_word_internal: optimize handling of "$@" idiom by calling + list_rest_of_args() and quote_list() directly at the top of the + function instead of going through normal code path + - cached_quoted_dollar_at: WORD_LIST of quoted positional parameters, + used by same code above that optimizes "$@"; if non-null we just + return a copy of the list; if null, we save a copy of the list we + create + - invalidate_cached_quoted_dollar_at: convenience function to allow + other parts of the shell (e.g., remember_args()) to destroy the + cached list of quoted positional parameter when the positional + parameters change + +builtins/common.c + - remember_args: call invalidate_cached_quoted_dollar_at() + +builtins/shift.def + - shift_builtin: call invalidate_cached_quoted_dollar_at after modifying + dollar_vars[] + +builtins/source.def + - maybe_pop_dollar_vars: call invalidate_cached_quoted_dollar_at just + to be safe + + 11/23 + ----- +builtins/evalfile.c + - _evalfile: return -1 if errno == ENOENT and the flags don't include + FEVAL_ENOENTOK. If we print an error message we should return an + error + - force_execute_file: new function, reads and executes commands from + a file but returns an error if file doesn't exist + +builtins/common.h + - force_execute_file: new extern declaration + +shell.c + - main: call start_debugger even if dollar_vars[1] == 0 if the shell + isn't interactive (interactive_shell == 0) + - start_debugger: call force_execute_file instead of maybe_execute_file; + turn off debugging mode if it returns value < 0 + + 11/24 + ----- +hashlib.h + - DEFAULT_HASH_BUCKETS: doubled to 128, cost in memory use is small but + changes traversal order when not sorting results + + 11/25 + ----- +doc/{bash.1,bashref.texi} + - make it clearer, by breaking it out into a separate paragraph, that + referencing an array without a subscript is equivalent to referencing + it with subscript 0 + - add text saying that referencing any variable using a valid subscript + is OK + + 11/28 + ----- + +arrayfunc.c + - bind_array_variable, bind_assoc_variable: allow binding value to a + readonly variable if the ASS_FORCE flag is set in the FLAGS + argument + +subst.h + - ASS_FORCE: new assignment flag; means to allow assignment even if + variable is marked readonly + +builtins/declare.def + - when assigning a value to an array or assoc variable using + something like `declare -r foo=bar' where foo is an existing array + variable, pass the ASS_FORCE to assign_array_var_from_string so + the assignment is allowed. Fixes debian bug 765759 + http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765759 + +builtins/setattr.def + - var_attribute_string: new function to return (as argument) a char + array with attribute flag values for a given variable; returns the + length of the array + +lib/sh/shquote.c + - sh_quote_reusable: function returning a version of its string + argument that is quoted for reuse + +externs.h + - sh_quote_reusable: extern declaration + +builtins/common.h + - MAX_ATTRIBUTES: define used to size arrays for attribute flag + characters + - var_attribute_string: new extern function declaration + +subst.c + - array_remove_pattern: fixed a bug where `var' instead of `v' was + tested for invisible attribute + - get_var_and_type: fill in a valid *VARP if returning VT_VARIABLE + because callers may need to use it + - parameter_brace_transform: family of functions to implement the new + mksh-inspired ${param@spec} transformation word expansions. Some + of the operators transform the (expanded) value of the parameter, + the rest expand to information about the parameter itself + (array_transform, parameter_list_transform, list_transform, + string_transform, pos_params_assignment, array_var_assignment, + string_var_assignment) + - parameter_brace_expand: changes to parse the new `@' word expansion + operator and call parameter_brace_transform appropriately + - parameter_brace_expand: make sure we handle ${#@} as we have before + even in the presence of the new `@' operator + +variables.c + - push_temp_var: make sure to call bind_variable_internal with the + ASS_FORCE flag so we override readonly variables created with + something like `tempvar=foo declare -r foo'. + - bind_variable_internal: honor ASS_FORCE flag to allow binding even + if a variable is readonly + +execute_cmd.c + - struct func_array_state: new state to save state of BASH_LINENO, + BASH_SOURCE, and FUNCNAME during function execution so it can be + restored on a jump to top level + - restore_funcarray_state: new function to restore func_array_state + - execute_function: fill in func_array_state variable, add unwind- + protect to restore it on jump to top level, call explicitly at + end of function if subshell != 0 (may not be necessary, but safe + for now). Fixes bug with local assignments to FUNCNAME reported + by Arfrever Frehtes Taifersar Arahesis + + 11/29 + ----- +arrayfunc.c + - assign_compound_array_list: turn off ASS_APPEND flag when processing + each individual assignment inside the parens in var+=(...). The + outer += should not affect assignments to existing subscripts; + those should be treated like usual assignments unless += supplied + inside the parens. Bug report from Maarten Billemont + , fix from Eduardo A. Bustamante López + + +config.h.in + - HAVE_PSELECT: define if pselect(2) available + +configure.ac + - check for pselect(2), define HAVE_PSELECT if found + +lib/readline/input.c + - rl_getc: use pselect(2) to wait for input ready on readline's + input fd or for a signal to arrive, will handle SIGWINCH (which + does not interrupt read(2)) and thus allow resize to happen without + having to wait to read more input. Only works if pselect available + and returns -1/EINTR on a signal even if the signal was installed + with SA_RESTART. From a suggestion from Egmont Koblinger + + + 12/3 + ---- +variables.c + - flush_temporary_env: new function, disposes all temp variables in + temporary_env hash table + - bind_variable: only try to update a temporary variable's value in the + temporary env if the value argument is not null. Fixes bug reported + by + +variables.h + - flush_temporary_env: new extern declaration + +subst.c + - command_substitute: if running command substitution as part of + expanding a redirection (expanding_redir == 1), flush any temporary + environment we've inherited as part of this command, since we are not + supposed to have access to the temporary environment. Since + expanding_redir only controls access to the temporary environment for + variable lookup and binding, we can turn it off in the subshell + + 12/4 + ---- +builtins/printf.def + - printstr: make sure a missing precision specifier after a `.' is + treated as 0, as printf(3) specifies. Fixes ubuntu bash bug + 1399087 (https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1399087) + + 12/5 + ---- +subst.c + - skip_to_delim: if scanning past process substitution (skipcmd == 1, + noprocsub == 0), use extract_delimited_string instead of + extract_process_subst, which was changed a while back (bash-4.3.23) + to use xparse_dolparen. xparse_dolparen complains if the command + or process substitution is unterminated, since it runs the parser, + which is not what we want here. Command substitution does the same + thing. Fixes bug reported by Daniel Kahn Gillmor + as Debian bash bug 771968 + (https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=771968) + + 12/6 + ---- +subst.c + - command_substitute: short-circuit without forking on a command string + that consists entirely of s and newlines + +jobs.c + - make_child: changes to allow interrupts through if fork fails and + we are sleeping for `forksleep' seconds + - waitchld: make things a little more resilient if CHILD ends up NULL + + 12/12 + ----- +lib/readline/complete.c + - rl_display_match_list: when calculating common prefix to display in + color, make sure we correctly handle a common prefix with a trailing + `/' as we do when checking whether or not to add an ellipis. + printable_part() doesn't return the whole pathname if it ends in a + slash, to avoid printing null strings, so we have to make sure we + have the entire prefix + +lib/readline/complete.c + - _rl_complete_display_matches_interrupt: new variable, set to 1 by + _rl_complete_sigcleanup to let rl_display_match_list know it has + freed the match list + - display_matches: check for signals during the printing loops with + RL_SIG_RECEIVED(), return immediately if there is a pending signal + (might not want to do this if it's SIGWINCH -- CHECK) + - rl_complete_internal: if _rl_complete_display_matches_interrupt + set after calling display_matches, just null out `matches' since + it's already been freed and call any application-set signal hook + + 12/14 + ----- +parse.y + - time_command_acceptable: if the token before a newline is `|', + return 0, since it's not really valid to time inside a pipeline. + Only handles a single newline but allows things like + echo a | + time cat + to invoke /usr/bin/time, which is probably enough to catch the + stray carriage return. Fixes bug reported by Andre Majorel + + +builtins/declare.def + - declare_internal: don't try to perform compound assignments unless + the WORD_DESC has flags including W_COMPASSIGN (maybe should check + W_ASSIGNMENT as well), avoiding unexpected evaluation if a word + is of the form (word) and is assigned to an array variable like so: + declare -x var=$value. Bug reported by Stephane Chazelas + . Will eventually be contingent on + compatibility level > 43, but not there yet. TENTATIVE + + 12/15 + ----- +lib/sh/Makefile.in + - add missing dependencies for shmatch.o. Pointed out by Sergey + Mikhailov + + 12/16 + ----- +{execute_cmd,subst}.c + - W_ASSIGNINT: remove, not used any more + +execute_cmd.c + - fix_assignment_words: don't look for `-i' option and set W_ASSIGNINT + flag any more; doing things a different way + - shell_expand_word_list: instead of using W_ASSIGNINT flag, since it + doesn't take into account all options that can transform values on + assignment (-l/-u/-c can also), go through option arguments looking + for options that need special handling and add them to the `opts' + array for make_internal_declare to use. Fixes bug with constructs + like `declare -al foo=(UPONE UPTWO UPTHREE)' not being lowercased on + assignment reported by Linda Walsh + + + + 12/18 + ----- +lib/readline/readline.c + - rl_internal_char: when we read EOF on a non-empty line, check for + signals and invoke any readline signal handling and any application- + installed signal hook + + 12/20 + ----- +lib/readline/readline.c + - rl_internal_char: if we read EOF on a non-empty line, set c to + _rl_eof_char the first time through. If we read EOF the next time, + return EOF from readline(). If callbacks are defined, this returns + EOF immediately, since lastc isn't available. Fix for problem + most recently identified by Jiri Kukacka , + it has come up in the past + + 12/21 + ----- +builtins/declare.def + - declare_internal: keep track of whether or not an assignment statement + argument to declare is an array subscript assignment; need to + differentiate assignments from straight declarations (declare a[4]) + which are accepted for backwards compatibility + - assignment statements like declare a[2]=foo are now treated as + straight subscript assignment statements if a already exists as an + array variable + - declare foo='(1 2 3)' is treated as an assignment to foo[0] if foo + exists and is an array, just as it would be if it were an assignment + statement and `declare' was not present. All this from a proposal + by Stephane Chazelas + + 12/22 + ----- +builtins/read.def + - read_tty_modified: function to tell the rest of the shell if the + read builtin has modified the tty + - read_builtin: make sure to initialize terminating signals before + installing a SIGALRM signal handler in case we modify the tty as + well as ask for a timeout; the subsequent call to + initialize_terminating_signals would overwrite the read-builtin- + local SIGALRM handler + +builtins/common.h + - read_tty_modified: new extern declaration + +shell.c + - exit_shell: if read_tty_modified() returns true, call read_tty_cleanup + to undo the terminal modifications. Extension of previous fixes; + fixes bug with read -s reported by Richard W. Marsden + + + + 12/23 + ----- +builtins/setattr.def + - show_var_attributes: call print_array_assignment and print_assoc_assignment + with a `not quoted' flag so the assignment statements are not + surrounded by single quotes. Caused changes to a lot of test output + + 12/29 + ----- +lib/readline/complete.c + - stat_char: Windows doesn't handle X_OK flag to access(2); use file + extensions to determine whether or not a file is executable. Bug + report and fix from Eli Zaretskii + +configure.ac + - changed version to bash-4.4-devel + +lib/readline/readline.h + - changed version to readline-6.4 + + 12/30 + ----- +readline.h + - struct readline_state: fix types of `ignorefunc' and `attemptfunc' + members + +lib/sh/shquote.c,externs.h + - sh_contains_shell_metas, sh_contains_quotes: now take `const char *' + as parameter + +stringlib.c,externs.h + - strcreplace: `text' argument now `const char *' + +pathexp.[ch] + - quote_globbing_chars: `string' argument now `const char *', accompanying + changes to function local variables + +pcomplete.c + - preproc_filterpat: `text' argument now `const char *' + - filter_stringlist: `text' argument now `const char *' + + 12/31 + ----- +builtins/evalstring.c + - should_suppress_fork: new function, broke code that decides whether + to turn on CMD_NO_FORK flag out of parse_and_execute into a separate + function + +execute_cmd.c + - execute_command_internal: AND_AND, OR_OR: call should_suppress_fork + for the RHS of && and ||, make `make' invocations marginally more + efficient + +flags.c + - get_current_flags: returns a bitmap of all single-letter shell + options with a non-zero value meaning option is enabled + - set_current_flags: set current single-letter options from a passed + bitmap, which has presumably been initialized with get_current_flags + +flags.h + - {get,set}_current_flags: new extern declarations + +builtins/declare.def + - declare_internal: if invoked as `local', interpret name argument of + `-' to mean to save (and restore at shell return) single-letter + shell options + +variables.c + - push_func_var: if we encounter `-' as the name of a local variable, + take the value and call set_current_flags on it to restore old + flag settings + +builtins/set.def + - get_current_options: returns a bitmap of all shell options settable + with `set', with a non-zero value meaning option is enabled + - set_current_options: set current shell options from a passed + bitmap, which has presumably been initialized with get_current_options + + + 1/1/2015 + -------- +lib/readline/parens.c + - _rl_blink_matching_paren: initialize to 0 whether or not select(2) is + available. Inconsistency reported by Mark Karpov + + +builtins/declare.def + - declare_internal: use get_current_options instead of + get_current_flags, so `local -' can be generalized + +variables.c + - push_func_var: use set_current_options instead of set_current_flags + so `local -' can be generalized + +doc/{bash.1,bashref.texi} + - document new `local -' feature; originally inspired by Robert Elz + describing feature in NetBSD sh + + 1/3 + --- +lib/readline/{complete,funmap,kill,histfile,util} +lib/readline/readline.h +lib/tilde/tilde.c + - fixes for filename- and evironment-related issues on Windows. Fixes + from Eli Zaretskii + - Windows can paste to the console from the clipboard like Cygwin + - Windows uses $APPDATA as a pseudo-$HOME + +lib/readline/input.c + - rl_getc: use _getch on Windows to avoid being overridden by a getch + ncurses function + - win32_isatty: replace Windows isatty(3) with a function that does + additional checks, sinces Windows isatty returns non-zero for + every character device. From Eli Zaretskii + +lib/readline/display.c + - delete_chars: if compiled with ncurses on Windows, this code can + work, so build it in if NCURSES_VERSION defined + - open_some_spaces: ditto + + 1/6 + --- +doc/{bash.1,bashref.texi} + - minor grammar and typo corrections from TonyMc + + 1/8 + --- +sig.c + - throw_to_top_level: only attempt to run the interrupt trap if SIGINT + is trapped -- minor optimization + - throw_to_top_level: if we are running a trap, call run_trap_cleanup + to turn off the sigmodes flags + +trap.c + - _run_trap_internal: temporarily suppress pending SIGINTs while running + one of the traps the shell handles internally (e.g., ERR). Fixes bug + reported by Keith Thompson + + 1/10 + ---- +bashhist.c + - bash_history_inhibit_expansion: use skip_to_delim with the history + expansion character to see whether or not the instance of the + history expansion character should be skipped because, for instance, + it is in a command substitution. Fixes issue reported by + Zigmund.Ozean@zig-home.localdomain + + 1/14 + ---- +lib/readline/isearch.c + - _rl_isearch_dispatch: if we are in a multibyte locale, make sure to + use _rl_find_prev_mbchar when trying to delete characters from the + search string, instead of just chopping off the previous byte. + Fixes bug reported by Kyrylo Shpytsya + +lib/readline/complete.c + - rl_filename_completion_function: if we tilde-expand `dirname', make + sure we use the expanded result instead of throwing it away for the + quote-removed `users_dirname', which still has any leading tilde. + Fixes bug reported by Dave Rutherford + +execute_cmd.c + - select_query: if the read builtin doesn't return anything in REPLY, + return NULL (failure). Fixes bug reported by Etherial Raine + + +builtins/read.def + - read_builtin: if REPLY has the readonly or noassign attribute, return + failure + + 1/16 + ---- +redir.c + - redir_open: if open() returns -1/EINTR, check traps as well as + using QUIT to handle signals + + 1/18 + ---- +jobs.c + - wait_for: make sure queue_sigchld is set to 1 before unblocking + SIGCHLD if MUST_UNBLOCK_CHLD is defined + + 1/19 + ---- +pcomplete.h + - new progcomp option: COPT_NOSORT, means to not sort list of possible + completions + +pcomplete.c + - pcomp_set_readline_variables: if COPT_NOSORT set in compspec flags, + set rl_sort_completion_duplicates to 0 + +builtins/complete.def + - _compopt: new option value: -o nosort, sets COPT_NOSORT in compspec + option flags. Provides new -o nosort option for complete and compgen + +bashline.c + - attempt_shell_completion: make sure rl_sort_completion_matches is + set to 1 before completion is attempted; allow a compspec to turn + it off + +lib/readline/kill.c + - rl_vi_yank_pop: new function, vi-mode version of yank-pop. Original + code from Ian Kelling + +lib/readline/funmap.c + - `vi-yank-pop': bindable name mapped to rl_vi_yank_pop + +lib/readline/readline.h + - rl_vi_yank_pop: extern declaration + + 1/21 + ---- +lib/sh/shquote.c + - sh_backslash_quote: change to understand and handle multibyte + characters, using is_basic, COPY_CHAR_P. See + https://bugzilla.redhat.com/show_bug.cgi?id=1184320 for original + report + + 1/23 + ---- +include/posixjmp.h + - use setjmp_sigs instead of redefined setjmp, it fails on Cygwin. + Report from Eric Blake + +builtins/wait.def,shell.c + - use setjmp_sigs instead of setjmp call, since setjmp no longer + redefined to something known + +include/chartypes.h, lib/readline/chardefs.h + - make sure all ctype.h macros are called with unsigned char args, + casting to make sure + +lib/sh/casemod.c + - sh_modcase: don't assume that the upper and lower case versions of a + character are the same width, so don't try to do the conversion in + place: convert and copy the converted characters one or more at a + time to the returned string + - sh_modcase: since upper and lower case versions of same character + may have different widths in some locales, don't shortcut and assume + that we can do single-byte case modification (toupper) with a + single-byte input character (e.g., `i'). Fix for problem reported + by Stephane Chazelas + + 1/31 + ---- +lib/readline/histfile.c + - history_truncate_file, history_do_write: if the first rename(2) + of the history file to the backup file fails, set the backup file + name to NULL to prevent any later attempts to restore the + original. Report from Jonathan Hankins + - history_do_write: don't attempt to back up non-regular files. + Report from Jonathan Hankins + + 2/2 + --- +trap.c + - run_interrupt_trap: now takes an argument indicating whether or not + it was called just before a longjmp to top_level; change callers + - run_interrupt_trap: if running a trap and we are being called before + a longjmp to top_level, call run_trap_cleanup on running trap so + a QUIT call while running a DEBUG trap, for instance, doesn't leave + sigmodes[DEBUG_TRAP] including SIG_INPROGRESS. Fixes bug reported + by Chih-Chieh Chou + +sig.c + - throw_to_top_level: change call to run_interrupt_trap to pass arg 1 + - termsig_handler: change call to run_interrupt_trap + +trap.h + - run_interrupt_trap: update extern prototype declaration + + 2/4 + --- +lib/readline/histfile.c + - histfile_backup, histfile_restore: new functions to back up and restore + history file to `filename-', following (one level of) symlinks through + so we don't rename the symlink itself. From a suggestion by + Jonathan Hankins + +assoc.c + - assoc_to_assign: if an index happens to be `@' or `*', make sure it's + double-quoted. Bug report from Greg Wooledge + + 2/5 + --- +lib/readline/bind.c + - rl_bind_key: if we are rebinding a key that is not bound to a + function or a macro, construct a key sequence and pass it to + rl_bind_keyseq. Make sure that '\' when it is used as a key is + changed to "\\" so it can survive rl_translate_keyseq. Fixes + https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=776743 + + 2/8 + --- +include/posixjmp.h + - _rl_longjmp, sh_longjmp: new defines, expand to siglongjmp or longjmp + depending on autoconf results, used to avoid redefining longjmp, + remove _OPENNT conditional code. Report from Eric Blake + + +{bashjmp,quit}.h,{execute_cmd,expr,jobs,sig,trap}.c,builtins/{evalstring.c,return.def} + - change calls to longjmp to use sh_longjmp + +lib/readline/util.c + - change calls to longjmp to use _rl_longjmp + + 2/18 + ---- +variables.c + - bind_int_variable: make sure `v' is non-null before making it visible + + 2/19 + ---- +arrayfunc.c + - assign_array_var_from_word_list: after assignment, mark variable as no + longer invisible + - assign_array_var_from_string: after assignment, mark variable as no + longer invisible + +builtins/declare.def + - declare_internal: add warning if an attempt is made to use a quoted + compound assignment as an argument to declare (declare -a foo='( 1 2 )'); + backwards compatible with bash-4.3. Still a tentative change + + 2/20 + ---- +lib/glob/smatch.c + - is_wcclass: check malloc() return value, return -1 if it fails + Report from Tobias Stoeckmann + +lib/sh/shmatch.c + - sh_regmatch: check malloc() return value, handle NULL value if it + fails. Report from Tobias Stoeckmann + + 2/22 + ---- +lib/readline/doc/rltech.texi + - rl_callback_handler_install: note that the handler function should + free the line it receives, as with readline. Suggested by + Ulf Magnusson + - Readline Signal Handling: note that application needs to clean up + readline's terminal state if it wants to handle a signal before + the line handler restores it. Suggested by Ulf Magnusson + + + 2/24 + ---- +lib/readline/histfile.c + - history_do_write,history_truncate_file: if the write fails, make sure + to set history_lines_written_to_file to 0 so we don't lose those + history entries + + 2/27 + ---- +execute_cmd.c + - execute_function: unwind-protect the value of line_number_for_err_trap, + so a function that returns a non-zero value and triggers an ERR trap + has the right value for LINENO. Any simple command in the function + body can change it. Bug report from Paul Donohue + + 3/5 + --- +lib/sh/shquote.c + - sh_backslash_quote: cast `c' to `unsigned char' before using as + index into backslash_table. Report and fix from + alexeyv.90@gmail.com + +arrayfunc.[ch] + - valid_array_reference: added second `flags' argument for future use; + currently unused + +parse.y,{redir,subst,variables,test}.c +builtins/{declare,printf,read,set}.def + - valid_array_reference: changed callers + + 3/7 + --- +lib/readline/signals.c + - _rl_handle_signal: if readline gets a SIGTSTP or SIGTTIN, block + SIGTTOU so a backgrounded readline can reset the terminal settings + appropriately, otherwise the terminal state and readline's idea + of it can get messed up. Original report from Dave Wysochanski + and Dave Anderson + +trap.c + - run_pending_traps: don't allow recursive SIGWINCH trap invocations; + they're wasteful and trying to handle a stream of signals while a + user resizes the terminal can lead to malloc errors trying to save + and restore the_pipeline multiple times. Problem reported most + recently by Martin M. S. Pederson (Fedora bash bug 1197768 + https://bugzilla.redhat.com/show_bug.cgi?id=1197768) + - reset_or_restore_signal_handlers: set pending_traps to 0 for all + signals when forking a child. TENTATIVE fix + +jobs.c + - {save,restore}_pipeline: block SIGCHLD while manipulating the_pipeline + like cleanup_the_pipeline does. XXX - may not be necessary + +lib/readline/display.c + - rl_redisplay: fixed case where multibyte character in the prompt + (e.g., \u03bb) in the last screen column causes problems with line + wrapping because the newline marker is put in the middle of the + multibyte char. Most recently reported on Ubuntu by + + +pathexp.c + - quote_string_for_globbing: if a bracket expression doesn't have a + closing right bracket, rescan it from just after the opening + bracket without treating it as a bracket expression. Bug report + from Stephane Chazelas + + 3/9 + --- +subst.c + - process_substitute: keep the last pipeline created to run a process + substitution in LAST_PROCSUB_CHILD; discard it when another one is + created + +jobs.[ch] + - discard_pipeline: now global, so process_substitute can call it + +jobs.c + - last_procsub_child: new variable, set and modified only by the process + substitution code + - find_pipeline: if the requested pid is in LAST_PROCSUB_CHILD, return + it; analogous to the way this code handles the_pipeline + - waitchld: if we find a child via find_pipeline that is a part of the + last process substitution child, mark that child appropriately. If + the child is dead, add it to the bgp list. This and the previous + change allow waiting for the most recent process substitution (the + one corresponding to $!). Original report from Stephane Chazelas + + + 3/10 + ---- +arrayfunc.c + - unbind_array_element: make sure skipsubscript() doesn't try to parse + embedded quotes in the subscript, since this has already been through + one round of word expansion before calling the unset builtin. (This + function is only called by the unset builtin). Fixes bug reported by + + + 3/17 + ---- +jobs.c + - waitchld: move code that adds the last process substitution pid to + the bgpids array from waitchld (where it can call malloc in a signal + handler context) to cleanup_dead_jobs + + 3/19 + ---- +subst.c + - parameter_brace_expand: if expanding an array in a context where word + splitting will not take place (W_ASSIGNRHS only for now), make sure + to pass the double-quoted flag to chk_atstar so we don't get the + unquoted $* behavior, which will cause unwanted word splitting. + Fixes bug reported by isabella parakiss + +arrayfunc.c + - unbind_array_element: don't assume that caller will check and pass + only array variables; don't allow non-array variables to be unset + using the `@' or `*' subscripts and don't allow any subscripts other + than 0; return -2 in those cases + - unbind_array_element: unset a non-array variable if passed a subscript + of `0' (e.g., `unbind "scalar[0]"'). This is new functionality that + parallels the ${scalar[0]} expansion + +builtins/set.def + - unset_builtin: don't check whether a variable is an array if it's + referenced using array syntax (scalar[0]); pass it to + unbind_array_element anyway and check the result. This means that + `unset scalar' and `unset scalar[0]' are equivalent + + 3/20 + ---- +builtins/set.def + - set_builtin: make `-i' an invalid option, unconditionally for now. + From a bug-bash discussion started by Peng Yu + + 3/21 + ---- +lib/readline/colors.c + - _rl_print_color_indicator: handle dangling symlinks (C_ORPHAN) and + the `target' specifier for links (dereference S_ISLNK if the target + exists). Bug report and fix from andreas@stapelspeicher.org + +{arrayfunc,subst}.c + - add code to save and restore this_command_name in places that set + this_command_name to NULL to prevent error messages from arithmetic + evaluation. Fixes bug reported by brian.carpenter@gmail.com + +builtins/mapfile.def + - do_chop: remove a new DELIM argument from the line, instead of + unconditionally removing newline + - mapfile: if -d delim is supplied and we are breaking fields at DELIM, + remove DELIM if the -t option is supplied by passing DELIM to do_chop(). + Suggested by Geir Hauge + +doc/{bash.1,bashref.texi} + - mapfile: document new -t option behavior, defaults are the same + +builtins/alias.def + - print_alias: if the first character of an alias name is `-', add a + `-- ' after `alias' to avoid option errors when trying to reuse the + output. Bug report and fix on savannah from Pasha Bolokhov + + + 3/22 + ---- +builtins/declare.def + - declare_internal: if creating a variable does not return a valid + variable in VAR, check for null variable before dereferencing it. + This happens with nameref variables referencing variables set to + the empty string. + Fixes bug reported by Arthur200000 + + 3/23 + ---- +doc/{bash.1,bashref.texi} + - INVOCATION: add language to make it clear that non-interactive login + shells execute ~/.bash_logout if they run the `exit' builtin. From a + question from Christoph Anton Mitterer + + 4/6 + --- +subst.c + - process_substitute: increment and decrement subshell_level around + calls to parse_and_execute, as in command substitution, so + $BASH_SUBSHELL gets new values in the subshell. Fixes inconsistency + pointed out by Peng Yu + +doc/{bash.1,bashref.texi} + - read: add clarifying text to note that the -N option does not split + on $IFS, but does retain backslash as an escape character subject + to -r. Report from isabella parakiss + +builtins/declare.def + - declare_internal: unless it's the last statement in a {...} block, + NEXT_VARIABLE must be protected by braces. Bug introduced in patch + from 3/22, reported by Eduardo A. Bustamante López + + + 4/7 + --- +parse.y + - shell_getc: if bash is reading input from a string that ends with an + unquoted backslash, add another backslash instead of a newline, since + the backslash and newline will disappear in normal processing. Fixes + bug with `bash -c 'eval \\; echo y' ' skipping the eval command and + setting incorrect exit status, and `bash -ic 'eval \\; echo y' ' + seeing EOF on empty line and exiting before the echo. Keep track of + backslash state with last_was_backslash; set in char reading loop. + Fixes bug reported by Eduardo A. Bustamante López + + 4/8 + --- +shell.c + - main: check for $INSIDE_EMACS as well as $EMACS when deciding whether + or not bash is being run in a GNU emacs shell window. Don't bother + checking whether $TERM is unset because variable initialization sets + it to `dumb' if unset. Fixes from Paul Eggert + +parse.y + - push_token: new function, rotates current_token through last_read_token, + saving old values like yylex() does, sets current_token to argument + +evalfile.c + - _evalfile: if current_token is yacc_EOF, push a newline as the value + of current_token instead, using push_token(). yacc_EOF can result if + sourced file doesn't end with a newline but does end with an unescaped + backslash. Fixes bug reported by Pedro Gimeno + + +lib/readline/histfile.c + - use PARAMS(x) instead of __P(x). Bug reported by Evan Gates + + + 4/9 + --- +execute_cmd.c + - execute_simple_command: if we haven't already forked, and we have + created FIFOs, turn off the no-fork optimization in the simple + command's flags. Originally reported to savannah by Kuang-che Wu as + https://savannah.gnu.org/support/index.php?108732 + + 4/10 + ---- +trap.c + - trap_if_untrapped: new function, sets a trap on a signal if that + signal is not already trapped + - maybe_set_debug_trap: new function, sets DEBUG trap to command string + argument only if it's not already trapped + +trap.h + - maybe_set_debug_trap: new extern declaration + + +builtins/source.def + - source_builtin: if the -T option isn't set, use maybe_set_debug_trap + in the unwind-protect instead of unconditionally restoring the old + trap string. That means if the sourced file changes the DEBUG trap, + that new trap will persist instead of being undone when the old + value is restored. Fixes bug reported by Scott Bronson + + +builtins/evalstring.c + - parse_string: before we jump to top_level, if we are at the `bottom' + of the parse_and_execute stack (parse_and_execute_level == 0), call + top_level_cleanup() before jumping so the right cleanup happens (e.g., + cleaning up redirections and other state). Fixes bug reported by + Sam Liddicott + + 4/15 + ---- +jobs.c + - delete_job: only add J_ASYNC (and not J_FOREGROUND) jobs to the + bgpids array, since Posix says shells only need to save the status + of async jobs. Report and fix from John Fremlin + + 4/17 + ---- +pcomplib.c + - COMPLETE_HASH_BUCKETS: increase to 256 since bash-completion is + over 300 completions by now + +variables.c + - VARIABLES_HASH_BUCKETS: constant used to size shell variables hash + table instead of relying on hash library default. Used in calls + to hash_create in create_variable_tables(), push_temp_var(), and + push_func_var(). Currently set to 1024 because why not? From a + discussion starting at + https://lists.gnu.org/archive/html/bug-bash/2015-04/msg00089.html + - initialize_shell_variables: if FUNCTION_IMPORT is not defined, the + nested conditional compilation causes syntax errors. Bug and fix + from Eric Blake + +configure.ac + - function-import: fix typo, assign to correct variable. Found as the + result of a report by Eric Blake + +shell.c + - open_shell_script: check whether or not file argument is a + directory before opening; Posix says that implementations may open + a directory with O_RDONLY. Bug report from + Eduardo A. Bustamante López + + 4/19 + ---- +ulimit.def + - fix typo in limits[] declaration of `k' + + 4/20 + ---- +configure.ac + - add template definitions set by AC_USE_SYSTEM_EXTENSIONS from a report + from Andreas Schwab + +variables.c + - FUNCTIONS_HASH_BUCKETS: constant used to size the hash tables used for + shell functions and the text of shell function definitions. Initially + set to 512, even though it's a really rare case that someone has more + than around 150 functions, even with bash-completion + + 4/21 + ---- +shell.c + - main: malloc_set_register: change arg to 0 to disable keeping track of + allocations and frees in table; change to 1 for malloc debugging on + demand. Table is too small to keep effective track of allocations on + a modern system, need to use something like valgrind + + 4/22 + ---- +shell.c + - main: move cmd_init() (initialize word desc and word list object + caches) after startup files are read so the cache doesn't get filled + up with semi-permanent storage for shell functions and variables + +execute_cmd.c + - execute_function: use maybe_set_debug_trap in the same way as source + builtin change from 4/10 to allow functions to reset a DEBUG trap + when set -T not in effect. From a report by Peng Yu + + + 4/23 + ---- +execute_cmd.c + - execute_disk_command: don't overwrite value of subshell_environment + by assigning SUBSHELL_FORK; just OR in SUBSHELL_FORK so something + like SUBSHELL_ASYNC or SUBSHELL_PIPE is preserved + +jobs.c + - wait_for: don't call give_terminal_to if running in a subshell + environment, not just if running_in_background is set; don't want + shell functions waiting for a process to complete in a pipeline to + give the terminal to the wrong process group. Part of fix for bug + reported by Valentin Bajrami + - make_child: child process should not try to give the terminal to the + pipeline_pgrp if running as part of a pipeline (SUBSHELL_PIPE in + subshell_environment); functions in execute_cmd.c don't set that + flag until after make_child returns and the child process is running. + Rest of fix for bug reported by Valentin Bajrami + + + 4/24 + ---- +redir.c + - redirection_error: if the redirection involves {varname}, only use + `varname' in the error message if the error code is < 0 (one of the + internal redirection errors, like ambiguous or bad variable name); + otherwise the issue is probably with the filename and should be treated + as usual. Fixes problem reported by Dr. David Alan Gilbert + + +configure.ac,config.h.in + - sys/ioctl.h: add check in AC_CHECK_HEADERS macro, define HAVE_SYS_IOCTL_H + +lib/readline/{rltty,terminal}.c + - sys/ioctl.h: include unconditionally for ioctl declaration, avoid + issues with `implicit declaration' warnings. Issue originally + raised on gdb list by Chen Gang + + 4/27 + ---- +lib/malloc/table.c + - mem_table: now a circular buffer showing the state of the last + REG_TABLE_SIZE allocations rather than a hash table that quickly + fills up + +builtins/declare.def + - typeset_builtin: add -n to list of supported options. Omission + reported by Valentin Bajrami + +unwind_prot.c + - use object caches instead of malloc/free to allocate and deallocate + unwind-protect elements + - uwp_init: initialize unwind-protect element object cache + +unwind_prot.h + - uwp_init: extern declaration + +shell.c + - main: call uwp_init right after calling cmd_init -- initialize all the + object caches at the same place + +lib/malloc/table.[ch] + - mlocation_table: new table to keep track of allocation locations by + file and line, functions to initialize table, record an allocation, + and dump the table to stderr + - mregister_alloc: call mlocation_register_alloc to record the location + (source file/line) for each allocation to pinpoint malloc hot spots + by number of calls. More detail than gprof + +parse.y + - set_line_mbstate: replace free/xmalloc pair with xrealloc call + - read_token_word: call alloc_word_desc instead of xmalloc so we can take + advantage of the WORD_DESC cache + + 4/28 + ---- +execute_cmd.c + - execute_simple_command: if command execution fails because the command + is a directory, and the `autocd' option is set, add a `--' argument + to the constructed `cd' command to protect against command names with + the same name as options to `cd'. Report and fix from + isabella parakiss + + 4/30 + ---- +jobs.c + - printable_job_status, j_strsignal: change calls to strcpy and sprintf + that write to retcode_name_buffer to use strncpy and snprintf to + avoid buffer overflows caused by malicious translations. Bug and fix + from Trammell Hudson + + 5/1 + --- +strtrans.c + - ansicstr: make sure the buffer is at least 12 bytes to ensure enough + space for any eventual call to u32cesc for one multibyte char + + 5/4 + --- +jobs.c + - wait_for: if an interactive shell is running a loop and waiting for + a non-builtin command to exit, and the command exits due to SIGINT, + act as if the shell received the SIGINT as well and break the loop. + This matches the behavior when the shell is running a builtin command + in a loop, and when running a non-builtin command outside a loop, and + seems more broadly useful than running the trap handler over and over + again. Report originally from Kaz Kylheku + +builtins/set.def + - unset_builtin: use different variables for keeping the state of the + -f and -v options than the loop uses to decide whether or not to + treat a name as a function or a variable. Fixes problem with + unset_function setting `sticking' after you unset a function when + invoked with no options. Bug report from Dreamcat4 + + +shell.c + - open_shell_script: set running_shell_script to 1, set to 0 in every + other case (new variable) + - main: when checking whether or not to call start_debugger, test + running_shell_script instead of dollar_vars[1]. The goal is to not + invoke the debugger for interactive shells but allow it to run for + things like `bash --debugger -i /tmp/script'. Problem reported by + Rocky Bernstein + +lib/readline/histexpand.c + - history_event_delimiter_chars: new (as yet undocumented) variable + containing by default characters that can delimit a history event + specifier without requiring a `:': "^$*%-" as the documentation has + always said. Fixes bug reported by Anders Granlund + + + 5/10 + ---- +lib/glob/gmisc.c + - match_pattern_char, match_pattern_wchar: if passed an empty string, + return a match if the first character of the pattern is `*' + +subst.c + - pat_subst: change to allow empty strings to be replaced as long as + pattern matches empty string. Report and fix from isabella parakiss + + + 5/12 + ---- +lib/sh/strtrans.c + - ansic_wshouldquote: make behavior consistent in the event of an + invalid multibyte sequence: return 1 to the caller so the string + will be $'...' quoted + +builtins/cd.def + - cd_builtin: print the right error message even if printable_filename + changes errno (e.g., EILSEQ) + +lib/sh/shquote.c + - sh_backslash_quote: in multibyte locales, even if is_basic does not + return true, backslash-quote an ASCII character that backslash_table + says should be quoted. Part of fix for bug reported by Igor + Bogomazov + +bashline.c + - directory_exists: new function, dequotes the string argument, removes + any trailing slash, and returns true if the result is a valid + existing filename + - bash_filename_stat_hook,bash_directory_completion_hook: use + directory_exists instead of calling lstat/stat on the quoted + directory name. Rest of fix for bug reported by Igor Bogomazov + + + 5/15 + ---- +aclocal.m4 + - BASH_CHECK_MULTIBYTE: when checking for locale_charset, add $LIBINTL + to $LIBS. If we're using the included lib/intl/libintl.a, it will + include a version of locale_charset + + 5/17 + ---- +lib/readline/bind.c + - sv_isrchterm: make sure we check for v[end] == 0 while in the loop + looking for whitespace. Bug report and fix from Sergio Durigan + Junior + +lib/sh/shmbchar.c + - mbstrlen,mbsmbchar: move calculation of MB_CUR_MAX out of loop; + calculate it once at beginning + +lib/sh/mbscmp.c + - mbscmp: move calculation of MB_CUR_MAX out of loop; calculate it once + at beginning + +lib/sh/mbscasecmp.c + - mbscasecmp: move calculation of MB_CUR_MAX out of loop; calculate it + once at beginning + +lib/sh/shquote.c + - sh_backslash_quote: move calculation of MB_CUR_MAX out of loop; + calculate it once at beginning + +lib/sh/casemod.c + - sh_modcase: move calculation of MB_CUR_MAX out of loop; calculate it + once at beginning + +subst.c + - expand_word_internal: move calculation of MB_CUR_MAX out of loops; + calculate it once at beginning of function (XXX should use + locale_mb_cur_max) + + 5/22 + ---- +lib/readline/rlmbutil.h + - _rl_wcwidth: new function, short-circuits wcwidth calls for ASCII + printable characters, returns 1 for those + - WCWIDTH: call _rl_wcwidth instead of wcwidth + +lib/readline/display.c + - rl_redisplay: move calculation of MB_CUR_MAX out of loop; calculate + it once at beginning. Report and patch from Ole Laursen + + + 5/24 + ---- +lib/readline/text.c + - rl_insert: change to attempt to batch-insert pending typeahead (not + pushed input or input from a macro) that maps to rl_insert. An + attempt to suppress redisplay until readline reads all typeahead -- + pasted input, for instance. Inspired by report from Ole Laursen + . XXX - need to make this a bindable + variable; already controlled by _rl_optimize_typeahead + +lib/readline/rlprivate.h + - _rl_optimize_typeahead: extern declaration + +lib/readline/doc/{hstech.texi,history.3} + - next_history: clarify under what circumstances the history offset is + incremented; suggestion from Glenn Golden + +print_cmd.c + - print_arith_command: should be compiled in if either DPAREN_ARITHMETIC + or ARITH_FOR_COMMAND is defined. Report from Flavio Medeiros + + +flags.c + - change_flag: new variable verbose_flag, set when `v' flag modified; + sets value of echo_input_at_read correspondingly + +flags.h + - verbose_flag: new extern declaration + +shell.c + - long_options: --verbose now sets verbose_flag + - main: set echo_input_at_read from verbose_flag after parsing any + long options + +builtins/fc.def + - fc_builtin: don't unwind-protect echo_input_at_read directly; set it + to 1 before calling fc_execute_file as before, and reset it to value + of global verbose_flag using set_verbose_flag called from an + unwind_protect. Report from isabella parakiss + +builtins/shopt.def + - shopt_set_debug_mode: new function, called when the extdebug shell + option changes. Right now, it sets function_trace_mode when extdebug + is enabled, and turns off when extdebug is disabled. The + documentation has always said that shopt does this. Report from + Peng Yu + + 5/27 + ---- +findcmd.[ch] + - add support for EXECIGNORE shell variable, list of extglob patterns + that prevent matching filenames from being identified as executable + files + +variables.c + - EXECIGNORE: arrange for findcmd.c:setup_exec_ignore to be called when + $EXECIGNORE changes + +variables.h + - sv_execignore: extern declaration + +doc/{bash.1,bashref.texi} + - document EXECIGNORE variable + + 5/28 + ---- +lib/readline/callback.c + - rl_callback_sigcleanup: new function, cleans up and unsets any state + rl_callback_read_char uses. Intended to be used after a signal + +lib/readline/signals.c + - _rl_handle_signal: call rl_callback_sigcleanup on SIGINT. Fixes bug + reported to python group by Martin Panter + +lib/readline/isearch.c + - _rl_isearch_cleanup: now a public function so rl_callback_cleanup can + call it + +lib/readline/search.c + - _rl_nsearch_cleanup: now a public function so rl_callback_cleanup can + call it + +lib/readline/rlprivate.h + - _rl_[in]search_cleanup: extern declarations + +lib/readline/readline.h + - rl_callback_sigcleanup: new extern declaration + +lib/readline/doc/rltech.texi + - rl_callback_sigcleanup: documented + +lib/readline/readline.h + - bump readline version to 7.0 due to addition of rl_callback_sigcleanup + + 5/29 + ---- +builtins/declare.def + - declare_internal: if we are trying to change attributes or value for + a nameref variable whose value points to an unset variable, make + sure we create a new variable whose name is the value of the nameref + variable. That is, + + declare -n foo=bar + unset foo # unsets bar + declare -i foo + + should create a (invisible) variable named `bar' with the integer + attribute. Fixes problem reported by Greg Wooledge + + +builtins/set.def + - unset_builtin: if we find a nameref variable when we look it up with + find_variable (the returned variable has a name different from what + we looked up), make sure we use that new name for the rest of the + function rather than rely on unbind_variable to do the same thing as + find_variable. Fixes problem reported by Greg Wooledge + + - unset_builtin: if we try to unset a nameref variable whose value is + not a set variable, make sure we don't try to unset the nameref + itself, but rather the variable it points to. This ensures that the + following always works as it should + + declare -n foo=bar + unset foo # unsets bar and leaves foo unchanged + +lib/readline/funmap.c + - vi-insertion-mode: make sure it maps to rl_vi_insert_mode, which is + actually what the `i' keybinding in vi_movement_keymap maps to. + Cosmetic fix from isabella parakiss + + 6/2 + --- +general.c + - conf_standard_path: moved get_standard_path here from command.def; made + public function + +general.h + - conf_standard_path: extern declaration + + + 6/3 + --- +parse.y + - parse_matched_pair: make sure that command substitution constructs + within ${...} expansions are parsed as such using parse_comsub, so + the P_FIRSTCLOSE flag doesn't stop parsing if a right brace appears + within the comsub. Report from Christos Zoulas + +findcmd.c + - search_for_command: take two new flags for FLAGS arg: CMDSRCH_STDPATH, + which means use the command -p path, and CMDSRCH_TEMPENV, currently + unused. Existing flag value of 1 now CMDSRCH_HASH + - search_for_command: don't set `path' to NULL if it wasn't found in + the temporary environment; we can use it later + - search_for_command: look for the hashed file if temp_path == 0, not + if we set path back to 0 (or path lookup failed) + - search_for_command: just call find_user_command_in_path with a + pathlist argument that's set depending on the flags passed + - find_in_path: new function, just calls find_user_command_in_path at + this point + - search_for_command: don't put non-existent files into the hash table + +findcmd.h + - CMDSRCH_*: new flags for search_for_command + - find_in_path: extern declaration + +execute_cmd.c + - execute_disk_command: check for CMD_STDPATH and call search_for_command + with CMDSRCH_STDPATH if it's set + +builtins/command.def + - command_builtin: if -p given without -v or -V, set the CMD_STDPATH + flag in the simple command we construct from the rest of the + argument list. This fixes the command -p cmd issue with changing + $PATH for the duration of `cmd's execution reported by + + +builtins/common.h + - CDESC_STDPATH: new flag for describe_command; means to use standard + path for command -pv or -pV + +builtins/command.def + - command_builtin: if -p given with -v or -V, pass the CDESC_STDPATH + flag to describe_command + +builtins/type.def + - describe_command: if given the CDESC_STDPATH flag, use find_in_path + with the conf_standard_path() result. Since `all' will never be on + with this flag, at least not yet, we can allocate and free the path + list. Fixes the bug of a temporary environment value for PATH + preceding a `command -pv' or `command -pV' persisting when the + command finishes and means we use fewer unwind-protects + + 6/4 + --- +Makefile.in (plus other Makefile.ins) + - VPATH: remove `.' from VPATH value. It's not needed any more and it + trips a GNU make 4.1 bug on Cygwin. Report and fix from Eric Blake + + +lib/readline/histfile.c + - history_tempfile: new function, takes history file name as template + and creates a temp file name including the PID + - history_truncate_file, history_do_write: instead of creating backup + and restoring it on failure, use history_tempfile to create a temp + file name, write to it, then rename to original history filename + (handling symlinks using history_restore()). Original report and + patch from Russell Stuart + +doc/{bash.1,bashref.texi} + - ulimit: clarify that -c and -f are in increments of 512 bytes when + in posix mode. Fix from Robin Johnson via + + + 6/9 + --- +execute_cmd.c + - execute_in_subshell: don't call restore_default_signal for the exit + trap, reset_signal_handlers already does the right thing and keeps + the trap string around; no need to kill trap string. Bug report + from Miroslav Koskar + + 6/11 + ---- +nojobs.c + - find_proc_slot: now takes pid as an argument to avoid finding old + procs when pids wrap around + - add_pid: pass pid to find_proc_slot to avoid multiple instances of + the same pid in the list when pids wrap around. Fixes bug reported + by Roy Keene + +execute_cmd.c + - REAP: test for job_control == 0 also to determine whether or not + to call reap_dead_jobs, since shells without job control enabled + don't report on background process status + +doc/bash.1,lib/readline/doc/hsuser.texi + - history: clarify documentation of -a option to note that it will not + append the same line to the history file more than once. Fixes + problem reported by Reuben Thomas + + 6/12 + ---- +execute_cmd.c + - execute_in_subshell: don't bother decrementing subshell_level before + this returns; the caller will just exit. This means that + $BASH_SUBSHELL will have consistent values in the subshell and any + subsequent exit trap. Fixes bug reported by Miroslav Koskar + + - shell_execve: before longjmp to subshell_top_level, call reset_parser + to free up any input line and stack of pushed strings + +parse.y + - mk_alexpansion: if the last character of the alias is a shell + metacharacter, don't add a space to the string following the alias + value, since that will change the meaning of the command. THIS IS + NOT BACKWARDS COMPATIBLE AND MAY REQUIRE REVERTING. Inspired by an + email message from Jilles Tjoelker to austin + group + + 6/13 + ---- +subst.c + - dequote_string: don't turn strings consisting of a single CTLESC + into empty strings; return them unmodified. The idea is that there + is nothing to quote. This means that something like + c=$'\001' + x=$c + results in x containing '\001' when IFS=$'\001'. See if this will + cause problems by adding a debugging statement in the code + + 6/15 + ---- +parse.y + - CHECK_FOR_RESERVED_WORD: don't return ESAC when you read `esac' + after a `|' while in a case pattern list (parser_state & PST_CASEPAT). + This is Posix grammar rule 4 + (http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_10_02) + + 6/16 + ---- +jobs.c + - wait_for: make sure we queue SIGCHLD signals if a SIGCHLD trap + handler is running (signal_in_progress or IMPOSSIBLE_TRAP_HANDLER), + since we allow recursive trap invocations now + - wait_for: make sure we treat SIGCHLD as trapped if the trap handler + is set to IMPOSSIBLE_TRAP_HANDLER so we don't miss signals during + calls to run_sigchld_trap() + +trap.c + - run_pending_traps: since we allow recursive trap handler invocations, + make sure we set pending_traps[SIGCHLD] to 0 while we mark the + signal handler in progress (SIG_INPROGRESS) and don't reset it to 0 + after run_sigchld_trap returns in case more SIGCHLDs have been + queued while it's running + + 6/22 + ---- +lib/readline/readline.c + - _rl_dispatch_subseq: if we shadowed any function, not just self- + insert, bind that function to the key we shadowed and dispatch on it. + This preserves and dispatches off the original key, not ANYOTHERKEY, + and makes sure we are dispatching from a keymap with the right key + binding. Fixes bug reported by Carlos Pita + + + 6/23 + ---- +bashline.c + - attempt_shell_completion: don't read past the end of rl_line_buffer + while skipping assignment statements before command names. Fix for + bug reported by Hanno Böck + +lib/readline/parens.c + - _rl_enable_paren_matching: make paren matching work in vi insert + mode. Really, this time. Bug report from Carlos Pita + + + 6/29 + ---- +parse.y + - parse_comsub: when starting to parse a word, make sure that we set + lex_rwlen to 0 along with lex_wlen if we are in a position where we + can read a reserved word. Fixes bug reported by Nathan Neulinger + + + 6/30 + ---- +sig.h + - include unconditionally and rely on guards in sig.h to + keep from including it more than once. Irix 6.5 defines SIG_DFL + in other files and defeats the test of SIG_DFL. Fixes bug + reported by Klaus Ziegler + +alias.c + - ALIAS_HASH_BUCKETS: table size increased to 64 + + 7/7 + --- + +{jobs,nojobs}.c + - wait_sigint_cleanup: new function, to be called by longjmp targets + for wait_intr_buf. Performs any necessary cleanup of internal waitchld + state before going back to top level + +jobs.h + - wait_sigint_cleanup: new extern declaration + +builtins/wait.def + - wait_builtin: call wait_sigint_cleanup after longjmp back to + wait_intr_buf on interrupt + +[bash-4.4-alpha frozen] + diff --git a/NEWS b/NEWS index 544882e4a..8cad1839a 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,134 @@ This is a terse description of the new features added to bash-4.4 since the release of bash-4.3. As always, the manual page (doc/bash.1) is the place to look for complete descriptions. +1. New Features in Bash + +a. There is now a settable configuration #define that will cause the shell + to exit if the shell is running setuid without the -p option and setuid + to the real uid fails. + +b. Command and process substitutions now turn off the `-v' option when + executing, as other shells seem to do. + +c. The default value for the `checkhash' shell option may now be set at + compile time with a #define. + +d. The `mapfile' builtin now has a -d option to use an arbitrary character + as the record delimiter, and a -t option to strip the delimiter as + supplied with -d. + +e. The maximum number of nested recursive calls to `eval' is now settable in + config-top.h; the default is no limit. + +f. The `-p' option to declare and similar builtins will display attributes for + named variables even when those variables have not been assigned values + (which are technically unset). + +g. The maximum number of nested recursive calls to `source' is now settable + in config-top.h; the default is no limit. + +h. All builtin commands recognize the `--help' option and print a usage + summary. + +i. Bash does not allow function names containing `/' and `=' to be exported. + +j. The `ulimit' builtin has new -k (kqueues) and -P (pseudoterminals) options. + +k. The shell now allows `time ; othercommand' to time null commands. + +l. There is a new `--enable-function-import' configuration option to allow + importing shell functions from the environment; import is enabled by + default. + +m. `printf -v var ""' will now set `var' to the empty string, as if `var=""' + had been executed. + +n. GLOBIGNORE, the pattern substitution word expansion, and programmable + completion match filtering now honor the value of the `nocasematch' option. + +o. There is a new ${parameter@spec} family of operators to transform the + value of `parameter'. + +p. Bash no longer attempts to perform compound assignment if a variable on the + rhs of an assignment statement argument to `declare' has the form of a + compound assignment (e.g., w='(word)' ; declare foo=$w); compound + assignments are accepted if the variable was already declared as an array, + but with a warning. + +q. The declare builtin no longer displays array variables using the compound + assignment syntax with quotes; that will generate warnings when re-used as + input, and isn't necessary. + +r. Executing the rhs of && and || will no longer cause the shell to fork if + it's not necessary. + +s. The `local' builtin takes a new argument: `-', which will cause it to save + and the single-letter shell options and restore their previous values at + function return. + +t. `complete' and `compgen' have a new `-o nosort' option, which forces + readline to not sort the completion matches. + +u. Bash now allows waiting for the most recent process substitution, since it + appears as $!. + +v. The `unset' builtin now unsets a scalar variable if it is subscripted with + a `0', analogous to the ${var[0]} expansion. + +w. `set -i' is no longer valid, as in other shells. + +x. BASH_SUBSHELL is now updated for process substitution and group commands + in pipelines, and is available with the same value when running any exit + trap. + +y. Bash now checks $INSIDE_EMACS as well as $EMACS when deciding whether or + not bash is being run in a GNU Emacs shell window. + +z. Bash now treats SIGINT received when running a non-builtin command in a + loop the way it has traditionally treated running a builtin command: + running any trap handler and breaking out of the loop. + +aa. New variable: EXECIGNORE; a colon-separate list of patterns that will + cause matching filenames to be ignored when searching for commands. + +bb. Aliases whose value ends in a shell metacharacter now expand in a way to + allow them to be `pasted' to the next token, which can potentially change + the meaning of a command (e.g., turning `&' into `&&'). + +2. New Features in Readline + +a. The history truncation code now uses the same error recovery mechansim as + the history writing code, and restores the old version of the history file + on error. The error recovery mechanism handles symlinked history files. + +b. There is a new bindable variable, `enable-bracketed-paste', which enables + support for a terminal's bracketed paste mode. + +c. The editing mode indicators can now be strings and are user-settable + (new `emacs-mode-string', `vi-cmd-mode-string' and `vi-ins-mode-string' + variables). Mode strings can contain invisible character sequences. + Setting mode strings to null strings restores the defaults. + +d. Prompt expansion adds the mode string to the last line of a multi-line + prompt (one with embedded newlines). + +e. There is a new bindable variable, `colored-completion-prefix', which, if + set, causes the common prefix of a set of possible completions to be + displayed in color. + +f. There is a new bindable command `vi-yank-pop', a vi-mode version of emacs- + mode yank-pop. + +g. The redisplay code underwent several efficiency improvements for multibyte + locales. + +h. The insert-char function attempts to batch-insert all pending typeahead + that maps to self-insert, as long as it is coming from the terminal. + +i. rl_callback_sigcleanup: a new application function that can clean up and + unset any state set by readline's callback mode. Intended to be used + after a signal. + ------------------------------------------------------------------------------- This is a terse description of the new features added to bash-4.3 since the release of bash-4.2. As always, the manual page (doc/bash.1) is diff --git a/builtins/wait.def b/builtins/wait.def index 77c8b784b..17412f8b6 100644 --- a/builtins/wait.def +++ b/builtins/wait.def @@ -136,6 +136,7 @@ wait_builtin (list) { last_command_exit_signal = wait_signal_received; status = 128 + wait_signal_received; + wait_sigint_cleanup (); WAIT_RETURN (status); } diff --git a/jobs.c b/jobs.c index 82553d1ea..52b10ebd3 100644 --- a/jobs.c +++ b/jobs.c @@ -2301,6 +2301,14 @@ static int wait_sigint_received; static int child_caught_sigint; static int waiting_for_child; +/* Clean up state after longjmp to wait_intr_buf */ +void +wait_sigint_cleanup () +{ + queue_sigchld = 0; + waiting_for_child = 0; +} + static void restore_sigint_handler () { @@ -3317,6 +3325,10 @@ waitchld (wpid, block) #if 0 if (wpid != -1 && block) itrace("waitchld: blocking waitpid returns %d", pid); +#endif +#if 0 +if (wpid != -1) + itrace("waitchld: %s waitpid returns %d", block?"blocking":"non-blocking", pid); #endif /* WCONTINUED may be rejected by waitpid as invalid even when defined */ if (wcontinued && pid < 0 && errno == EINVAL) diff --git a/jobs.h b/jobs.h index abbeb7e91..a296f811b 100644 --- a/jobs.h +++ b/jobs.h @@ -221,6 +221,8 @@ extern int wait_for __P((pid_t)); extern int wait_for_job __P((int)); extern int wait_for_any_job __P((void)); +extern void wait_sigint_cleanup __P((void)); + extern void notify_and_cleanup __P((void)); extern void reap_dead_jobs __P((void)); extern int start_job __P((int, int)); diff --git a/lib/readline/COPYING b/lib/readline/COPYING deleted file mode 120000 index 7d29222e4..000000000 --- a/lib/readline/COPYING +++ /dev/null @@ -1 +0,0 @@ -../../COPYING \ No newline at end of file diff --git a/lib/readline/COPYING b/lib/readline/COPYING new file mode 100644 index 000000000..94a9ed024 --- /dev/null +++ b/lib/readline/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/lib/readline/ansi_stdlib.h b/lib/readline/ansi_stdlib.h deleted file mode 120000 index 0bfba502e..000000000 --- a/lib/readline/ansi_stdlib.h +++ /dev/null @@ -1 +0,0 @@ -../../include/ansi_stdlib.h \ No newline at end of file diff --git a/lib/readline/ansi_stdlib.h b/lib/readline/ansi_stdlib.h new file mode 100644 index 000000000..7dc2ee0cf --- /dev/null +++ b/lib/readline/ansi_stdlib.h @@ -0,0 +1,54 @@ +/* ansi_stdlib.h -- An ANSI Standard stdlib.h. */ +/* A minimal stdlib.h containing extern declarations for those functions + that bash uses. */ + +/* Copyright (C) 1993 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#if !defined (_STDLIB_H_) +#define _STDLIB_H_ 1 + +/* String conversion functions. */ +extern int atoi (); + +extern double atof (); +extern double strtod (); + +/* Memory allocation functions. */ +/* Generic pointer type. */ +#ifndef PTR_T + +#if defined (__STDC__) +# define PTR_T void * +#else +# define PTR_T char * +#endif + +#endif /* PTR_T */ + +extern PTR_T malloc (); +extern PTR_T realloc (); +extern void free (); + +/* Other miscellaneous functions. */ +extern void abort (); +extern void exit (); +extern char *getenv (); +extern void qsort (); + +#endif /* _STDLIB_H */ diff --git a/lib/readline/doc/fdl.texi b/lib/readline/doc/fdl.texi deleted file mode 120000 index 68e5eb548..000000000 --- a/lib/readline/doc/fdl.texi +++ /dev/null @@ -1 +0,0 @@ -../../../doc/fdl.texi \ No newline at end of file diff --git a/lib/readline/doc/fdl.texi b/lib/readline/doc/fdl.texi new file mode 100644 index 000000000..8805f1a47 --- /dev/null +++ b/lib/readline/doc/fdl.texi @@ -0,0 +1,506 @@ +@c The GNU Free Documentation License. +@center Version 1.3, 3 November 2008 + +@c This file is intended to be included within another document, +@c hence no sectioning command or @node. + +@display +Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc. +@uref{http://fsf.org/} + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +@end display + +@enumerate 0 +@item +PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document @dfn{free} in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of ``copyleft'', which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +@item +APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The ``Document'', below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as ``you''. You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A ``Modified Version'' of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A ``Secondary Section'' is a named appendix or a front-matter section +of the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The ``Invariant Sections'' are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The ``Cover Texts'' are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A ``Transparent'' copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not ``Transparent'' is called ``Opaque''. + +Examples of suitable formats for Transparent copies include plain +@sc{ascii} without markup, Texinfo input format, La@TeX{} input +format, @acronym{SGML} or @acronym{XML} using a publicly available +@acronym{DTD}, and standard-conforming simple @acronym{HTML}, +PostScript or @acronym{PDF} designed for human modification. Examples +of transparent image formats include @acronym{PNG}, @acronym{XCF} and +@acronym{JPG}. Opaque formats include proprietary formats that can be +read and edited only by proprietary word processors, @acronym{SGML} or +@acronym{XML} for which the @acronym{DTD} and/or processing tools are +not generally available, and the machine-generated @acronym{HTML}, +PostScript or @acronym{PDF} produced by some word processors for +output purposes only. + +The ``Title Page'' means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, ``Title Page'' means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +The ``publisher'' means any person or entity that distributes copies +of the Document to the public. + +A section ``Entitled XYZ'' means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as ``Acknowledgements'', +``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' +of such a section when you modify the Document means that it remains a +section ``Entitled XYZ'' according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +@item +VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + +@item +COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + +@item +MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +@enumerate A +@item +Use in the Title Page (and on the covers, if any) a title distinct +from that of the Document, and from those of previous versions +(which should, if there were any, be listed in the History section +of the Document). You may use the same title as a previous version +if the original publisher of that version gives permission. + +@item +List on the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified +Version, together with at least five of the principal authors of the +Document (all of its principal authors, if it has fewer than five), +unless they release you from this requirement. + +@item +State on the Title page the name of the publisher of the +Modified Version, as the publisher. + +@item +Preserve all the copyright notices of the Document. + +@item +Add an appropriate copyright notice for your modifications +adjacent to the other copyright notices. + +@item +Include, immediately after the copyright notices, a license notice +giving the public permission to use the Modified Version under the +terms of this License, in the form shown in the Addendum below. + +@item +Preserve in that license notice the full lists of Invariant Sections +and required Cover Texts given in the Document's license notice. + +@item +Include an unaltered copy of this License. + +@item +Preserve the section Entitled ``History'', Preserve its Title, and add +to it an item stating at least the title, year, new authors, and +publisher of the Modified Version as given on the Title Page. If +there is no section Entitled ``History'' in the Document, create one +stating the title, year, authors, and publisher of the Document as +given on its Title Page, then add an item describing the Modified +Version as stated in the previous sentence. + +@item +Preserve the network location, if any, given in the Document for +public access to a Transparent copy of the Document, and likewise +the network locations given in the Document for previous versions +it was based on. These may be placed in the ``History'' section. +You may omit a network location for a work that was published at +least four years before the Document itself, or if the original +publisher of the version it refers to gives permission. + +@item +For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve +the Title of the section, and preserve in the section all the +substance and tone of each of the contributor acknowledgements and/or +dedications given therein. + +@item +Preserve all the Invariant Sections of the Document, +unaltered in their text and in their titles. Section numbers +or the equivalent are not considered part of the section titles. + +@item +Delete any section Entitled ``Endorsements''. Such a section +may not be included in the Modified Version. + +@item +Do not retitle any existing section to be Entitled ``Endorsements'' or +to conflict in title with any Invariant Section. + +@item +Preserve any Warranty Disclaimers. +@end enumerate + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled ``Endorsements'', provided it contains +nothing but endorsements of your Modified Version by various +parties---for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + +@item +COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled ``History'' +in the various original documents, forming one section Entitled +``History''; likewise combine any sections Entitled ``Acknowledgements'', +and any sections Entitled ``Dedications''. You must delete all +sections Entitled ``Endorsements.'' + +@item +COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + +@item +AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an ``aggregate'' if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + +@item +TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled ``Acknowledgements'', +``Dedications'', or ``History'', the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + +@item +TERMINATION + +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. + +@item +FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +@uref{http://www.gnu.org/copyleft/}. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License ``or any later version'' applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +@item +RELICENSING + +``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the +site means any set of copyrightable works thus published on the MMC +site. + +``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +``Incorporate'' means to publish or republish a Document, in whole or +in part, as part of another Document. + +An MMC is ``eligible for relicensing'' if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole +or in part into the MMC, (1) had no cover texts or invariant sections, +and (2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + +@end enumerate + +@page +@heading ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +@smallexample +@group + Copyright (C) @var{year} @var{your name}. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GNU + Free Documentation License''. +@end group +@end smallexample + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the ``with@dots{}Texts.'' line with this: + +@smallexample +@group + with the Invariant Sections being @var{list their titles}, with + the Front-Cover Texts being @var{list}, and with the Back-Cover Texts + being @var{list}. +@end group +@end smallexample + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + +@c Local Variables: +@c ispell-local-pdict: "ispell-dict" +@c End: + diff --git a/lib/readline/posixdir.h b/lib/readline/posixdir.h deleted file mode 120000 index 8b1638454..000000000 --- a/lib/readline/posixdir.h +++ /dev/null @@ -1 +0,0 @@ -../../include/posixdir.h \ No newline at end of file diff --git a/lib/readline/posixdir.h b/lib/readline/posixdir.h new file mode 100644 index 000000000..0921c5d75 --- /dev/null +++ b/lib/readline/posixdir.h @@ -0,0 +1,71 @@ +/* posixdir.h -- Posix directory reading includes and defines. */ + +/* Copyright (C) 1987,1991,2012 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* This file should be included instead of or . */ + +#if !defined (_POSIXDIR_H_) +#define _POSIXDIR_H_ + +#if defined (HAVE_DIRENT_H) +# include +# if defined (HAVE_STRUCT_DIRENT_D_NAMLEN) +# define D_NAMLEN(d) ((d)->d_namlen) +# else +# define D_NAMLEN(d) (strlen ((d)->d_name)) +# endif /* !HAVE_STRUCT_DIRENT_D_NAMLEN */ +#else +# if defined (HAVE_SYS_NDIR_H) +# include +# endif +# if defined (HAVE_SYS_DIR_H) +# include +# endif +# if defined (HAVE_NDIR_H) +# include +# endif +# if !defined (dirent) +# define dirent direct +# endif /* !dirent */ +# define D_NAMLEN(d) ((d)->d_namlen) +#endif /* !HAVE_DIRENT_H */ + +/* The bash code fairly consistenly uses d_fileno; make sure it's available */ +#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (HAVE_STRUCT_DIRENT_D_FILENO) +# define d_fileno d_ino +#endif + +/* Posix does not require that the d_ino field be present, and some + systems do not provide it. */ +#if !defined (HAVE_STRUCT_DIRENT_D_INO) || defined (BROKEN_DIRENT_D_INO) +# define REAL_DIR_ENTRY(dp) 1 +#else +# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) +#endif /* _POSIX_SOURCE */ + +#if defined (HAVE_STRUCT_DIRENT_D_INO) && !defined (BROKEN_DIRENT_D_INO) +# define D_INO_AVAILABLE +#endif + +/* Signal the rest of the code that it can safely use dirent.d_fileno */ +#if defined (D_INO_AVAILABLE) || defined (HAVE_STRUCT_DIRENT_D_FILENO) +# define D_FILENO_AVAILABLE 1 +#endif + +#endif /* !_POSIXDIR_H_ */ diff --git a/lib/readline/posixjmp.h b/lib/readline/posixjmp.h deleted file mode 120000 index b4d3ee74b..000000000 --- a/lib/readline/posixjmp.h +++ /dev/null @@ -1 +0,0 @@ -../../include/posixjmp.h \ No newline at end of file diff --git a/lib/readline/posixjmp.h b/lib/readline/posixjmp.h new file mode 100644 index 000000000..9c7e99ed4 --- /dev/null +++ b/lib/readline/posixjmp.h @@ -0,0 +1,46 @@ +/* posixjmp.h -- wrapper for setjmp.h with changes for POSIX systems. */ + +/* Copyright (C) 1987,1991-2015 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _POSIXJMP_H_ +#define _POSIXJMP_H_ + +#include + +/* This *must* be included *after* config.h */ + +#if defined (HAVE_POSIX_SIGSETJMP) +# define procenv_t sigjmp_buf + +# define setjmp_nosigs(x) sigsetjmp((x), 0) +# define setjmp_sigs(x) sigsetjmp((x), 1) + +# define _rl_longjmp(x, n) siglongjmp((x), (n)) +# define sh_longjmp(x, n) siglongjmp((x), (n)) +#else +# define procenv_t jmp_buf + +# define setjmp_nosigs setjmp +# define setjmp_sigs setjmp + +# define _rl_longjmp(x, n) longjmp((x), (n)) +# define sh_longjmp(x, n) longjmp((x), (n)) +#endif + +#endif /* _POSIXJMP_H_ */ diff --git a/lib/readline/posixselect.h b/lib/readline/posixselect.h deleted file mode 120000 index 56a0a2c69..000000000 --- a/lib/readline/posixselect.h +++ /dev/null @@ -1 +0,0 @@ -../../include/posixselect.h \ No newline at end of file diff --git a/lib/readline/posixselect.h b/lib/readline/posixselect.h new file mode 100644 index 000000000..da6a1ace0 --- /dev/null +++ b/lib/readline/posixselect.h @@ -0,0 +1,47 @@ +/* posixselect.h -- wrapper for select(2) includes and definitions */ + +/* Copyright (C) 2009 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +#ifndef _POSIXSELECT_H_ +#define _POSIXSELECT_H_ + +#if defined (FD_SET) && !defined (HAVE_SELECT) +# define HAVE_SELECT 1 +#endif + +#if defined (HAVE_SELECT) +# if !defined (HAVE_SYS_SELECT_H) || !defined (M_UNIX) +# include +# endif +#endif /* HAVE_SELECT */ +#if defined (HAVE_SYS_SELECT_H) +# include +#endif + +#ifndef USEC_PER_SEC +# define USEC_PER_SEC 1000000 +#endif + +#define USEC_TO_TIMEVAL(us, tv) \ +do { \ + (tv).tv_sec = (us) / USEC_PER_SEC; \ + (tv).tv_usec = (us) % USEC_PER_SEC; \ +} while (0) + +#endif /* _POSIXSELECT_H_ */ diff --git a/lib/readline/posixstat.h b/lib/readline/posixstat.h deleted file mode 120000 index c6164b792..000000000 --- a/lib/readline/posixstat.h +++ /dev/null @@ -1 +0,0 @@ -../../include/posixstat.h \ No newline at end of file diff --git a/lib/readline/posixstat.h b/lib/readline/posixstat.h new file mode 100644 index 000000000..3eb7f2906 --- /dev/null +++ b/lib/readline/posixstat.h @@ -0,0 +1,142 @@ +/* posixstat.h -- Posix stat(2) definitions for systems that + don't have them. */ + +/* Copyright (C) 1987,1991 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Bash is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Bash is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Bash. If not, see . +*/ + +/* This file should be included instead of . + It relies on the local sys/stat.h to work though. */ +#if !defined (_POSIXSTAT_H_) +#define _POSIXSTAT_H_ + +#include + +#if defined (STAT_MACROS_BROKEN) +# undef S_ISBLK +# undef S_ISCHR +# undef S_ISDIR +# undef S_ISFIFO +# undef S_ISREG +# undef S_ISLNK +#endif /* STAT_MACROS_BROKEN */ + +/* These are guaranteed to work only on isc386 */ +#if !defined (S_IFDIR) && !defined (S_ISDIR) +# define S_IFDIR 0040000 +#endif /* !S_IFDIR && !S_ISDIR */ +#if !defined (S_IFMT) +# define S_IFMT 0170000 +#endif /* !S_IFMT */ + +/* Posix 1003.1 5.6.1.1 file types */ + +/* Some Posix-wannabe systems define _S_IF* macros instead of S_IF*, but + do not provide the S_IS* macros that Posix requires. */ + +#if defined (_S_IFMT) && !defined (S_IFMT) +#define S_IFMT _S_IFMT +#endif +#if defined (_S_IFIFO) && !defined (S_IFIFO) +#define S_IFIFO _S_IFIFO +#endif +#if defined (_S_IFCHR) && !defined (S_IFCHR) +#define S_IFCHR _S_IFCHR +#endif +#if defined (_S_IFDIR) && !defined (S_IFDIR) +#define S_IFDIR _S_IFDIR +#endif +#if defined (_S_IFBLK) && !defined (S_IFBLK) +#define S_IFBLK _S_IFBLK +#endif +#if defined (_S_IFREG) && !defined (S_IFREG) +#define S_IFREG _S_IFREG +#endif +#if defined (_S_IFLNK) && !defined (S_IFLNK) +#define S_IFLNK _S_IFLNK +#endif +#if defined (_S_IFSOCK) && !defined (S_IFSOCK) +#define S_IFSOCK _S_IFSOCK +#endif + +/* Test for each symbol individually and define the ones necessary (some + systems claiming Posix compatibility define some but not all). */ + +#if defined (S_IFBLK) && !defined (S_ISBLK) +#define S_ISBLK(m) (((m)&S_IFMT) == S_IFBLK) /* block device */ +#endif + +#if defined (S_IFCHR) && !defined (S_ISCHR) +#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR) /* character device */ +#endif + +#if defined (S_IFDIR) && !defined (S_ISDIR) +#define S_ISDIR(m) (((m)&S_IFMT) == S_IFDIR) /* directory */ +#endif + +#if defined (S_IFREG) && !defined (S_ISREG) +#define S_ISREG(m) (((m)&S_IFMT) == S_IFREG) /* file */ +#endif + +#if defined (S_IFIFO) && !defined (S_ISFIFO) +#define S_ISFIFO(m) (((m)&S_IFMT) == S_IFIFO) /* fifo - named pipe */ +#endif + +#if defined (S_IFLNK) && !defined (S_ISLNK) +#define S_ISLNK(m) (((m)&S_IFMT) == S_IFLNK) /* symbolic link */ +#endif + +#if defined (S_IFSOCK) && !defined (S_ISSOCK) +#define S_ISSOCK(m) (((m)&S_IFMT) == S_IFSOCK) /* socket */ +#endif + +/* + * POSIX 1003.1 5.6.1.2 File Modes + */ + +#if !defined (S_IRWXU) +# if !defined (S_IREAD) +# define S_IREAD 00400 +# define S_IWRITE 00200 +# define S_IEXEC 00100 +# endif /* S_IREAD */ + +# if !defined (S_IRUSR) +# define S_IRUSR S_IREAD /* read, owner */ +# define S_IWUSR S_IWRITE /* write, owner */ +# define S_IXUSR S_IEXEC /* execute, owner */ + +# define S_IRGRP (S_IREAD >> 3) /* read, group */ +# define S_IWGRP (S_IWRITE >> 3) /* write, group */ +# define S_IXGRP (S_IEXEC >> 3) /* execute, group */ + +# define S_IROTH (S_IREAD >> 6) /* read, other */ +# define S_IWOTH (S_IWRITE >> 6) /* write, other */ +# define S_IXOTH (S_IEXEC >> 6) /* execute, other */ +# endif /* !S_IRUSR */ + +# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR) +# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP) +# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH) +#endif /* !S_IRWXU */ + +/* These are non-standard, but are used in builtins.c$symbolic_umask() */ +#define S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH) +#define S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH) +#define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH) + +#endif /* _POSIXSTAT_H_ */ diff --git a/lib/readline/tilde.c b/lib/readline/tilde.c deleted file mode 120000 index 439ceedeb..000000000 --- a/lib/readline/tilde.c +++ /dev/null @@ -1 +0,0 @@ -../tilde/tilde.c \ No newline at end of file diff --git a/lib/readline/tilde.c b/lib/readline/tilde.c new file mode 100644 index 000000000..3788eba62 --- /dev/null +++ b/lib/readline/tilde.c @@ -0,0 +1,506 @@ +/* tilde.c -- Tilde expansion code (~/foo := $HOME/foo). */ + +/* Copyright (C) 1988-2009 Free Software Foundation, Inc. + + This file is part of the GNU Readline Library (Readline), a library + for reading lines of text with interactive input and history editing. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if defined (HAVE_CONFIG_H) +# include +#endif + +#if defined (HAVE_UNISTD_H) +# ifdef _MINIX +# include +# endif +# include +#endif + +#if defined (HAVE_STRING_H) +# include +#else /* !HAVE_STRING_H */ +# include +#endif /* !HAVE_STRING_H */ + +#if defined (HAVE_STDLIB_H) +# include +#else +# include "ansi_stdlib.h" +#endif /* HAVE_STDLIB_H */ + +#include +#if defined (HAVE_PWD_H) +#include +#endif + +#include "tilde.h" + +#if defined (TEST) || defined (STATIC_MALLOC) +static void *xmalloc (), *xrealloc (); +#else +# include "xmalloc.h" +#endif /* TEST || STATIC_MALLOC */ + +#if !defined (HAVE_GETPW_DECLS) +# if defined (HAVE_GETPWUID) +extern struct passwd *getpwuid PARAMS((uid_t)); +# endif +# if defined (HAVE_GETPWNAM) +extern struct passwd *getpwnam PARAMS((const char *)); +# endif +#endif /* !HAVE_GETPW_DECLS */ + +#if !defined (savestring) +#define savestring(x) strcpy ((char *)xmalloc (1 + strlen (x)), (x)) +#endif /* !savestring */ + +#if !defined (NULL) +# if defined (__STDC__) +# define NULL ((void *) 0) +# else +# define NULL 0x0 +# endif /* !__STDC__ */ +#endif /* !NULL */ + +/* If being compiled as part of bash, these will be satisfied from + variables.o. If being compiled as part of readline, they will + be satisfied from shell.o. */ +extern char *sh_get_home_dir PARAMS((void)); +extern char *sh_get_env_value PARAMS((const char *)); + +/* The default value of tilde_additional_prefixes. This is set to + whitespace preceding a tilde so that simple programs which do not + perform any word separation get desired behaviour. */ +static const char *default_prefixes[] = + { " ~", "\t~", (const char *)NULL }; + +/* The default value of tilde_additional_suffixes. This is set to + whitespace or newline so that simple programs which do not + perform any word separation get desired behaviour. */ +static const char *default_suffixes[] = + { " ", "\n", (const char *)NULL }; + +/* If non-null, this contains the address of a function that the application + wants called before trying the standard tilde expansions. The function + is called with the text sans tilde, and returns a malloc()'ed string + which is the expansion, or a NULL pointer if the expansion fails. */ +tilde_hook_func_t *tilde_expansion_preexpansion_hook = (tilde_hook_func_t *)NULL; + +/* If non-null, this contains the address of a function to call if the + standard meaning for expanding a tilde fails. The function is called + with the text (sans tilde, as in "foo"), and returns a malloc()'ed string + which is the expansion, or a NULL pointer if there is no expansion. */ +tilde_hook_func_t *tilde_expansion_failure_hook = (tilde_hook_func_t *)NULL; + +/* When non-null, this is a NULL terminated array of strings which + are duplicates for a tilde prefix. Bash uses this to expand + `=~' and `:~'. */ +char **tilde_additional_prefixes = (char **)default_prefixes; + +/* When non-null, this is a NULL terminated array of strings which match + the end of a username, instead of just "/". Bash sets this to + `:' and `=~'. */ +char **tilde_additional_suffixes = (char **)default_suffixes; + +static int tilde_find_prefix PARAMS((const char *, int *)); +static int tilde_find_suffix PARAMS((const char *)); +static char *isolate_tilde_prefix PARAMS((const char *, int *)); +static char *glue_prefix_and_suffix PARAMS((char *, const char *, int)); + +/* Find the start of a tilde expansion in STRING, and return the index of + the tilde which starts the expansion. Place the length of the text + which identified this tilde starter in LEN, excluding the tilde itself. */ +static int +tilde_find_prefix (string, len) + const char *string; + int *len; +{ + register int i, j, string_len; + register char **prefixes; + + prefixes = tilde_additional_prefixes; + + string_len = strlen (string); + *len = 0; + + if (*string == '\0' || *string == '~') + return (0); + + if (prefixes) + { + for (i = 0; i < string_len; i++) + { + for (j = 0; prefixes[j]; j++) + { + if (strncmp (string + i, prefixes[j], strlen (prefixes[j])) == 0) + { + *len = strlen (prefixes[j]) - 1; + return (i + *len); + } + } + } + } + return (string_len); +} + +/* Find the end of a tilde expansion in STRING, and return the index of + the character which ends the tilde definition. */ +static int +tilde_find_suffix (string) + const char *string; +{ + register int i, j, string_len; + register char **suffixes; + + suffixes = tilde_additional_suffixes; + string_len = strlen (string); + + for (i = 0; i < string_len; i++) + { +#if defined (__MSDOS__) + if (string[i] == '/' || string[i] == '\\' /* || !string[i] */) +#else + if (string[i] == '/' /* || !string[i] */) +#endif + break; + + for (j = 0; suffixes && suffixes[j]; j++) + { + if (strncmp (string + i, suffixes[j], strlen (suffixes[j])) == 0) + return (i); + } + } + return (i); +} + +/* Return a new string which is the result of tilde expanding STRING. */ +char * +tilde_expand (string) + const char *string; +{ + char *result; + int result_size, result_index; + + result_index = result_size = 0; + if (result = strchr (string, '~')) + result = (char *)xmalloc (result_size = (strlen (string) + 16)); + else + result = (char *)xmalloc (result_size = (strlen (string) + 1)); + + /* Scan through STRING expanding tildes as we come to them. */ + while (1) + { + register int start, end; + char *tilde_word, *expansion; + int len; + + /* Make START point to the tilde which starts the expansion. */ + start = tilde_find_prefix (string, &len); + + /* Copy the skipped text into the result. */ + if ((result_index + start + 1) > result_size) + result = (char *)xrealloc (result, 1 + (result_size += (start + 20))); + + strncpy (result + result_index, string, start); + result_index += start; + + /* Advance STRING to the starting tilde. */ + string += start; + + /* Make END be the index of one after the last character of the + username. */ + end = tilde_find_suffix (string); + + /* If both START and END are zero, we are all done. */ + if (!start && !end) + break; + + /* Expand the entire tilde word, and copy it into RESULT. */ + tilde_word = (char *)xmalloc (1 + end); + strncpy (tilde_word, string, end); + tilde_word[end] = '\0'; + string += end; + + expansion = tilde_expand_word (tilde_word); + xfree (tilde_word); + + len = strlen (expansion); +#ifdef __CYGWIN__ + /* Fix for Cygwin to prevent ~user/xxx from expanding to //xxx when + $HOME for `user' is /. On cygwin, // denotes a network drive. */ + if (len > 1 || *expansion != '/' || *string != '/') +#endif + { + if ((result_index + len + 1) > result_size) + result = (char *)xrealloc (result, 1 + (result_size += (len + 20))); + + strcpy (result + result_index, expansion); + result_index += len; + } + xfree (expansion); + } + + result[result_index] = '\0'; + + return (result); +} + +/* Take FNAME and return the tilde prefix we want expanded. If LENP is + non-null, the index of the end of the prefix into FNAME is returned in + the location it points to. */ +static char * +isolate_tilde_prefix (fname, lenp) + const char *fname; + int *lenp; +{ + char *ret; + int i; + + ret = (char *)xmalloc (strlen (fname)); +#if defined (__MSDOS__) + for (i = 1; fname[i] && fname[i] != '/' && fname[i] != '\\'; i++) +#else + for (i = 1; fname[i] && fname[i] != '/'; i++) +#endif + ret[i - 1] = fname[i]; + ret[i - 1] = '\0'; + if (lenp) + *lenp = i; + return ret; +} + +#if 0 +/* Public function to scan a string (FNAME) beginning with a tilde and find + the portion of the string that should be passed to the tilde expansion + function. Right now, it just calls tilde_find_suffix and allocates new + memory, but it can be expanded to do different things later. */ +char * +tilde_find_word (fname, flags, lenp) + const char *fname; + int flags, *lenp; +{ + int x; + char *r; + + x = tilde_find_suffix (fname); + if (x == 0) + { + r = savestring (fname); + if (lenp) + *lenp = 0; + } + else + { + r = (char *)xmalloc (1 + x); + strncpy (r, fname, x); + r[x] = '\0'; + if (lenp) + *lenp = x; + } + + return r; +} +#endif + +/* Return a string that is PREFIX concatenated with SUFFIX starting at + SUFFIND. */ +static char * +glue_prefix_and_suffix (prefix, suffix, suffind) + char *prefix; + const char *suffix; + int suffind; +{ + char *ret; + int plen, slen; + + plen = (prefix && *prefix) ? strlen (prefix) : 0; + slen = strlen (suffix + suffind); + ret = (char *)xmalloc (plen + slen + 1); + if (plen) + strcpy (ret, prefix); + strcpy (ret + plen, suffix + suffind); + return ret; +} + +/* Do the work of tilde expansion on FILENAME. FILENAME starts with a + tilde. If there is no expansion, call tilde_expansion_failure_hook. + This always returns a newly-allocated string, never static storage. */ +char * +tilde_expand_word (filename) + const char *filename; +{ + char *dirname, *expansion, *username; + int user_len; + struct passwd *user_entry; + + if (filename == 0) + return ((char *)NULL); + + if (*filename != '~') + return (savestring (filename)); + + /* A leading `~/' or a bare `~' is *always* translated to the value of + $HOME or the home directory of the current user, regardless of any + preexpansion hook. */ + if (filename[1] == '\0' || filename[1] == '/') + { + /* Prefix $HOME to the rest of the string. */ + expansion = sh_get_env_value ("HOME"); +#if defined (_WIN32) + if (expansion == 0) + expansion = sh_get_env_value ("APPDATA"); +#endif + + /* If there is no HOME variable, look up the directory in + the password database. */ + if (expansion == 0) + expansion = sh_get_home_dir (); + + return (glue_prefix_and_suffix (expansion, filename, 1)); + } + + username = isolate_tilde_prefix (filename, &user_len); + + if (tilde_expansion_preexpansion_hook) + { + expansion = (*tilde_expansion_preexpansion_hook) (username); + if (expansion) + { + dirname = glue_prefix_and_suffix (expansion, filename, user_len); + xfree (username); + xfree (expansion); + return (dirname); + } + } + + /* No preexpansion hook, or the preexpansion hook failed. Look in the + password database. */ + dirname = (char *)NULL; +#if defined (HAVE_GETPWNAM) + user_entry = getpwnam (username); +#else + user_entry = 0; +#endif + if (user_entry == 0) + { + /* If the calling program has a special syntax for expanding tildes, + and we couldn't find a standard expansion, then let them try. */ + if (tilde_expansion_failure_hook) + { + expansion = (*tilde_expansion_failure_hook) (username); + if (expansion) + { + dirname = glue_prefix_and_suffix (expansion, filename, user_len); + xfree (expansion); + } + } + /* If we don't have a failure hook, or if the failure hook did not + expand the tilde, return a copy of what we were passed. */ + if (dirname == 0) + dirname = savestring (filename); + } +#if defined (HAVE_GETPWENT) + else + dirname = glue_prefix_and_suffix (user_entry->pw_dir, filename, user_len); +#endif + + xfree (username); +#if defined (HAVE_GETPWENT) + endpwent (); +#endif + return (dirname); +} + + +#if defined (TEST) +#undef NULL +#include + +main (argc, argv) + int argc; + char **argv; +{ + char *result, line[512]; + int done = 0; + + while (!done) + { + printf ("~expand: "); + fflush (stdout); + + if (!gets (line)) + strcpy (line, "done"); + + if ((strcmp (line, "done") == 0) || + (strcmp (line, "quit") == 0) || + (strcmp (line, "exit") == 0)) + { + done = 1; + break; + } + + result = tilde_expand (line); + printf (" --> %s\n", result); + free (result); + } + exit (0); +} + +static void memory_error_and_abort (); + +static void * +xmalloc (bytes) + size_t bytes; +{ + void *temp = (char *)malloc (bytes); + + if (!temp) + memory_error_and_abort (); + return (temp); +} + +static void * +xrealloc (pointer, bytes) + void *pointer; + int bytes; +{ + void *temp; + + if (!pointer) + temp = malloc (bytes); + else + temp = realloc (pointer, bytes); + + if (!temp) + memory_error_and_abort (); + + return (temp); +} + +static void +memory_error_and_abort () +{ + fprintf (stderr, "readline: out of virtual memory\n"); + abort (); +} + +/* + * Local variables: + * compile-command: "gcc -g -DTEST -o tilde tilde.c" + * end: + */ +#endif /* TEST */ diff --git a/lib/readline/tilde.h b/lib/readline/tilde.h deleted file mode 120000 index 6fea2aeaa..000000000 --- a/lib/readline/tilde.h +++ /dev/null @@ -1 +0,0 @@ -../tilde/tilde.h \ No newline at end of file diff --git a/lib/readline/tilde.h b/lib/readline/tilde.h new file mode 100644 index 000000000..e26dd0476 --- /dev/null +++ b/lib/readline/tilde.h @@ -0,0 +1,80 @@ +/* tilde.h: Externally available variables and function in libtilde.a. */ + +/* Copyright (C) 1992-2009 Free Software Foundation, Inc. + + This file contains the Readline Library (Readline), a set of + routines for providing Emacs style line input to programs that ask + for it. + + Readline is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Readline is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Readline. If not, see . +*/ + +#if !defined (_TILDE_H_) +# define _TILDE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* A function can be defined using prototypes and compile on both ANSI C + and traditional C compilers with something like this: + extern char *func PARAMS((char *, char *, int)); */ + +#if !defined (PARAMS) +# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus) +# define PARAMS(protos) protos +# else +# define PARAMS(protos) () +# endif +#endif + +typedef char *tilde_hook_func_t PARAMS((char *)); + +/* If non-null, this contains the address of a function that the application + wants called before trying the standard tilde expansions. The function + is called with the text sans tilde, and returns a malloc()'ed string + which is the expansion, or a NULL pointer if the expansion fails. */ +extern tilde_hook_func_t *tilde_expansion_preexpansion_hook; + +/* If non-null, this contains the address of a function to call if the + standard meaning for expanding a tilde fails. The function is called + with the text (sans tilde, as in "foo"), and returns a malloc()'ed string + which is the expansion, or a NULL pointer if there is no expansion. */ +extern tilde_hook_func_t *tilde_expansion_failure_hook; + +/* When non-null, this is a NULL terminated array of strings which + are duplicates for a tilde prefix. Bash uses this to expand + `=~' and `:~'. */ +extern char **tilde_additional_prefixes; + +/* When non-null, this is a NULL terminated array of strings which match + the end of a username, instead of just "/". Bash sets this to + `:' and `=~'. */ +extern char **tilde_additional_suffixes; + +/* Return a new string which is the result of tilde expanding STRING. */ +extern char *tilde_expand PARAMS((const char *)); + +/* Do the work of tilde expansion on FILENAME. FILENAME starts with a + tilde. If there is no expansion, call tilde_expansion_failure_hook. */ +extern char *tilde_expand_word PARAMS((const char *)); + +/* Find the portion of the string beginning with ~ that should be expanded. */ +extern char *tilde_find_word PARAMS((const char *, int, int *)); + +#ifdef __cplusplus +} +#endif + +#endif /* _TILDE_H_ */ diff --git a/nojobs.c b/nojobs.c index 467adf482..a456115a2 100644 --- a/nojobs.c +++ b/nojobs.c @@ -86,6 +86,8 @@ extern int wait_signal_received; volatile pid_t last_made_pid = NO_PID; volatile pid_t last_asynchronous_pid = NO_PID; +static int queue_sigchld, waiting_for_child; /* dummy declarations */ + /* Call this when you start making children. */ int already_making_children = 0; @@ -704,6 +706,11 @@ wait_for_background_pids () cleanup_dead_jobs (); } +void +wait_sigint_cleanup () +{ +} + /* Make OLD_SIGINT_HANDLER the SIGINT signal handler. */ #define INVALID_SIGNAL_HANDLER (SigHandler *)wait_for_background_pids static SigHandler *old_sigint_handler = INVALID_SIGNAL_HANDLER; diff --git a/support/mkconffiles b/support/mkconffiles old mode 100644 new mode 100755 diff --git a/support/mkversion.sh b/support/mkversion.sh old mode 100644 new mode 100755 diff --git a/support/rlvers.sh b/support/rlvers.sh old mode 100644 new mode 100755 diff --git a/support/shobj-conf b/support/shobj-conf old mode 100644 new mode 100755 diff --git a/tests/coproc.tests b/tests/coproc.tests index f61f26a1d..d347eb749 100644 --- a/tests/coproc.tests +++ b/tests/coproc.tests @@ -29,10 +29,9 @@ read LINE <&${REFLECT[0]} echo $LINE -exec 2>$TMPOUT # catch stray job termination messages -kill $REFLECT_PID +{ sleep 1; kill $REFLECT_PID; } & wait $REFLECT_PID >$TMPOUT 2>&1 || echo "coproc.tests: REFLECT: status $?" -grep -q 'Terminated.*coproc.*REFLECT' < $TMPOUT || { +grep 'Terminated.*coproc.*REFLECT' < $TMPOUT >/dev/null 2>&1 || { echo "coproc.tests: wait for REFLECT failed" >&2 } rm -f $TMPOUT diff --git a/tests/trap.right b/tests/trap.right index 8941e1ccf..1f68d3318 100644 --- a/tests/trap.right +++ b/tests/trap.right @@ -100,5 +100,4 @@ trap -- 'echo caught a child death' SIGCHLD trap -- 'echo exiting' EXIT trap -- 'echo aborting' SIGABRT trap -- 'echo caught a child death' SIGCHLD -trap -- '' SIGUSR2 exiting diff --git a/tests/trap.tests b/tests/trap.tests index 5d8b06c0a..4176df085 100644 --- a/tests/trap.tests +++ b/tests/trap.tests @@ -62,6 +62,7 @@ echo $? # hmmm...should this set the handling to SIG_IGN for children, too? trap '' USR2 ./trap1.sub +trap - USR2 # test ERR trap ./trap2.sub diff --git a/y.tab.c b/y.tab.c new file mode 100644 index 000000000..2a848e8ef --- /dev/null +++ b/y.tab.c @@ -0,0 +1,8598 @@ +/* A Bison parser, made by GNU Bison 3.0.4. */ + +/* Bison implementation for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +/* C LALR(1) parser skeleton written by Richard Stallman, by + simplifying the original so-called "semantic" parser. */ + +/* All symbols defined below should begin with yy or YY, to avoid + infringing on user name space. This should be done even for local + variables, as they might otherwise be expanded by user macros. + There are some unavoidable exceptions within include files to + define necessary library symbols; they are noted "INFRINGES ON + USER NAME SPACE" below. */ + +/* Identify Bison output. */ +#define YYBISON 1 + +/* Bison version. */ +#define YYBISON_VERSION "3.0.4" + +/* Skeleton name. */ +#define YYSKELETON_NAME "yacc.c" + +/* Pure parsers. */ +#define YYPURE 0 + +/* Push parsers. */ +#define YYPUSH 0 + +/* Pull parsers. */ +#define YYPULL 1 + + + + +/* Copy the first part of user declarations. */ +#line 21 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:339 */ + +#include "config.h" + +#include "bashtypes.h" +#include "bashansi.h" + +#include "filecntl.h" + +#if defined (HAVE_UNISTD_H) +# include +#endif + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#include +#include "chartypes.h" +#include + +#include "memalloc.h" + +#include "bashintl.h" + +#define NEED_STRFTIME_DECL /* used in externs.h */ + +#include "shell.h" +#include "typemax.h" /* SIZE_MAX if needed */ +#include "trap.h" +#include "flags.h" +#include "parser.h" +#include "mailcheck.h" +#include "test.h" +#include "builtins.h" +#include "builtins/common.h" +#include "builtins/builtext.h" + +#include "shmbutil.h" + +#if defined (READLINE) +# include "bashline.h" +# include +#endif /* READLINE */ + +#if defined (HISTORY) +# include "bashhist.h" +# include +#endif /* HISTORY */ + +#if defined (JOB_CONTROL) +# include "jobs.h" +#endif /* JOB_CONTROL */ + +#if defined (ALIAS) +# include "alias.h" +#else +typedef void *alias_t; +#endif /* ALIAS */ + +#if defined (PROMPT_STRING_DECODE) +# ifndef _MINIX +# include +# endif +# include +# if defined (TM_IN_SYS_TIME) +# include +# include +# endif /* TM_IN_SYS_TIME */ +# include "maxpath.h" +#endif /* PROMPT_STRING_DECODE */ + +#define RE_READ_TOKEN -99 +#define NO_EXPANSION -100 + +#ifdef DEBUG +# define YYDEBUG 1 +#else +# define YYDEBUG 0 +#endif + +#if defined (HANDLE_MULTIBYTE) +# define last_shell_getc_is_singlebyte \ + ((shell_input_line_index > 1) \ + ? shell_input_line_property[shell_input_line_index - 1] \ + : 1) +# define MBTEST(x) ((x) && last_shell_getc_is_singlebyte) +#else +# define last_shell_getc_is_singlebyte 1 +# define MBTEST(x) ((x)) +#endif + +#if defined (EXTENDED_GLOB) +extern int extended_glob; +#endif + +extern int eof_encountered; +extern int no_line_editing, running_under_emacs; +extern int current_command_number; +extern int sourcelevel, parse_and_execute_level; +extern int posixly_correct; +extern int last_command_exit_value; +extern pid_t last_command_subst_pid; +extern char *shell_name, *current_host_name; +extern char *dist_version; +extern int patch_level; +extern int dump_translatable_strings, dump_po_strings; +extern sh_builtin_func_t *last_shell_builtin, *this_shell_builtin; +#if defined (BUFFERED_INPUT) +extern int bash_input_fd_changed; +#endif + +extern int errno; +/* **************************************************************** */ +/* */ +/* "Forward" declarations */ +/* */ +/* **************************************************************** */ + +#ifdef DEBUG +static void debug_parser __P((int)); +#endif + +static int yy_getc __P((void)); +static int yy_ungetc __P((int)); + +#if defined (READLINE) +static int yy_readline_get __P((void)); +static int yy_readline_unget __P((int)); +#endif + +static int yy_string_get __P((void)); +static int yy_string_unget __P((int)); +static void rewind_input_string __P((void)); +static int yy_stream_get __P((void)); +static int yy_stream_unget __P((int)); + +static int shell_getc __P((int)); +static void shell_ungetc __P((int)); +static void discard_until __P((int)); + +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) +static void push_string __P((char *, int, alias_t *)); +static void pop_string __P((void)); +static void free_string_list __P((void)); +#endif + +static char *read_a_line __P((int)); + +static int reserved_word_acceptable __P((int)); +static int yylex __P((void)); + +static void push_heredoc __P((REDIRECT *)); +static char *mk_alexpansion __P((char *)); +static int alias_expand_token __P((char *)); +static int time_command_acceptable __P((void)); +static int special_case_tokens __P((char *)); +static int read_token __P((int)); +static char *parse_matched_pair __P((int, int, int, int *, int)); +static char *parse_comsub __P((int, int, int, int *, int)); +#if defined (ARRAY_VARS) +static char *parse_compound_assignment __P((int *)); +#endif +#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND) +static int parse_dparen __P((int)); +static int parse_arith_cmd __P((char **, int)); +#endif +#if defined (COND_COMMAND) +static void cond_error __P((void)); +static COND_COM *cond_expr __P((void)); +static COND_COM *cond_or __P((void)); +static COND_COM *cond_and __P((void)); +static COND_COM *cond_term __P((void)); +static int cond_skip_newlines __P((void)); +static COMMAND *parse_cond_command __P((void)); +#endif +#if defined (ARRAY_VARS) +static int token_is_assignment __P((char *, int)); +static int token_is_ident __P((char *, int)); +#endif +static int read_token_word __P((int)); +static void discard_parser_constructs __P((int)); + +static char *error_token_from_token __P((int)); +static char *error_token_from_text __P((void)); +static void print_offending_line __P((void)); +static void report_syntax_error __P((char *)); + +static void handle_eof_input_unit __P((void)); +static void prompt_again __P((void)); +#if 0 +static void reset_readline_prompt __P((void)); +#endif +static void print_prompt __P((void)); + +#if defined (HANDLE_MULTIBYTE) +static void set_line_mbstate __P((void)); +static char *shell_input_line_property = NULL; +#else +# define set_line_mbstate() +#endif + +extern int yyerror __P((const char *)); + +#ifdef DEBUG +extern int yydebug; +#endif + +/* Default prompt strings */ +char *primary_prompt = PPROMPT; +char *secondary_prompt = SPROMPT; + +/* PROMPT_STRING_POINTER points to one of these, never to an actual string. */ +char *ps1_prompt, *ps2_prompt; + +/* Handle on the current prompt string. Indirectly points through + ps1_ or ps2_prompt. */ +char **prompt_string_pointer = (char **)NULL; +char *current_prompt_string; + +/* Non-zero means we expand aliases in commands. */ +int expand_aliases = 0; + +/* If non-zero, the decoded prompt string undergoes parameter and + variable substitution, command substitution, arithmetic substitution, + string expansion, process substitution, and quote removal in + decode_prompt_string. */ +int promptvars = 1; + +/* If non-zero, $'...' and $"..." are expanded when they appear within + a ${...} expansion, even when the expansion appears within double + quotes. */ +int extended_quote = 1; + +/* The number of lines read from input while creating the current command. */ +int current_command_line_count; + +/* The number of lines in a command saved while we run parse_and_execute */ +int saved_command_line_count; + +/* The token that currently denotes the end of parse. */ +int shell_eof_token; + +/* The token currently being read. */ +int current_token; + +/* The current parser state. */ +int parser_state; + +/* Variables to manage the task of reading here documents, because we need to + defer the reading until after a complete command has been collected. */ +#define HEREDOC_MAX 16 + +static REDIRECT *redir_stack[HEREDOC_MAX]; +int need_here_doc; + +/* Where shell input comes from. History expansion is performed on each + line when the shell is interactive. */ +static char *shell_input_line = (char *)NULL; +static size_t shell_input_line_index; +static size_t shell_input_line_size; /* Amount allocated for shell_input_line. */ +static size_t shell_input_line_len; /* strlen (shell_input_line) */ + +/* Either zero or EOF. */ +static int shell_input_line_terminator; + +/* The line number in a script on which a function definition starts. */ +static int function_dstart; + +/* The line number in a script on which a function body starts. */ +static int function_bstart; + +/* The line number in a script at which an arithmetic for command starts. */ +static int arith_for_lineno; + +/* The decoded prompt string. Used if READLINE is not defined or if + editing is turned off. Analogous to current_readline_prompt. */ +static char *current_decoded_prompt; + +/* The last read token, or NULL. read_token () uses this for context + checking. */ +static int last_read_token; + +/* The token read prior to last_read_token. */ +static int token_before_that; + +/* The token read prior to token_before_that. */ +static int two_tokens_ago; + +static int global_extglob; + +/* The line number in a script where the word in a `case WORD', `select WORD' + or `for WORD' begins. This is a nested command maximum, since the array + index is decremented after a case, select, or for command is parsed. */ +#define MAX_CASE_NEST 128 +static int word_lineno[MAX_CASE_NEST+1]; +static int word_top = -1; + +/* If non-zero, it is the token that we want read_token to return + regardless of what text is (or isn't) present to be read. This + is reset by read_token. If token_to_read == WORD or + ASSIGNMENT_WORD, yylval.word should be set to word_desc_to_read. */ +static int token_to_read; +static WORD_DESC *word_desc_to_read; + +static REDIRECTEE source; +static REDIRECTEE redir; + +#line 374 "y.tab.c" /* yacc.c:339 */ + +# ifndef YY_NULLPTR +# if defined __cplusplus && 201103L <= __cplusplus +# define YY_NULLPTR nullptr +# else +# define YY_NULLPTR 0 +# endif +# endif + +/* Enabling verbose error messages. */ +#ifdef YYERROR_VERBOSE +# undef YYERROR_VERBOSE +# define YYERROR_VERBOSE 1 +#else +# define YYERROR_VERBOSE 0 +#endif + +/* In a future release of Bison, this section will be replaced + by #include "y.tab.h". */ +#ifndef YY_YY_Y_TAB_H_INCLUDED +# define YY_YY_Y_TAB_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + IF = 258, + THEN = 259, + ELSE = 260, + ELIF = 261, + FI = 262, + CASE = 263, + ESAC = 264, + FOR = 265, + SELECT = 266, + WHILE = 267, + UNTIL = 268, + DO = 269, + DONE = 270, + FUNCTION = 271, + COPROC = 272, + COND_START = 273, + COND_END = 274, + COND_ERROR = 275, + IN = 276, + BANG = 277, + TIME = 278, + TIMEOPT = 279, + TIMEIGN = 280, + WORD = 281, + ASSIGNMENT_WORD = 282, + REDIR_WORD = 283, + NUMBER = 284, + ARITH_CMD = 285, + ARITH_FOR_EXPRS = 286, + COND_CMD = 287, + AND_AND = 288, + OR_OR = 289, + GREATER_GREATER = 290, + LESS_LESS = 291, + LESS_AND = 292, + LESS_LESS_LESS = 293, + GREATER_AND = 294, + SEMI_SEMI = 295, + SEMI_AND = 296, + SEMI_SEMI_AND = 297, + LESS_LESS_MINUS = 298, + AND_GREATER = 299, + AND_GREATER_GREATER = 300, + LESS_GREATER = 301, + GREATER_BAR = 302, + BAR_AND = 303, + yacc_EOF = 304 + }; +#endif +/* Tokens. */ +#define IF 258 +#define THEN 259 +#define ELSE 260 +#define ELIF 261 +#define FI 262 +#define CASE 263 +#define ESAC 264 +#define FOR 265 +#define SELECT 266 +#define WHILE 267 +#define UNTIL 268 +#define DO 269 +#define DONE 270 +#define FUNCTION 271 +#define COPROC 272 +#define COND_START 273 +#define COND_END 274 +#define COND_ERROR 275 +#define IN 276 +#define BANG 277 +#define TIME 278 +#define TIMEOPT 279 +#define TIMEIGN 280 +#define WORD 281 +#define ASSIGNMENT_WORD 282 +#define REDIR_WORD 283 +#define NUMBER 284 +#define ARITH_CMD 285 +#define ARITH_FOR_EXPRS 286 +#define COND_CMD 287 +#define AND_AND 288 +#define OR_OR 289 +#define GREATER_GREATER 290 +#define LESS_LESS 291 +#define LESS_AND 292 +#define LESS_LESS_LESS 293 +#define GREATER_AND 294 +#define SEMI_SEMI 295 +#define SEMI_AND 296 +#define SEMI_SEMI_AND 297 +#define LESS_LESS_MINUS 298 +#define AND_GREATER 299 +#define AND_GREATER_GREATER 300 +#define LESS_GREATER 301 +#define GREATER_BAR 302 +#define BAR_AND 303 +#define yacc_EOF 304 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +union YYSTYPE +{ +#line 329 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:355 */ + + WORD_DESC *word; /* the word that we read. */ + int number; /* the number that we read. */ + WORD_LIST *word_list; + COMMAND *command; + REDIRECT *redirect; + ELEMENT element; + PATTERN_LIST *pattern; + +#line 522 "y.tab.c" /* yacc.c:355 */ +}; + +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + +int yyparse (void); + +#endif /* !YY_YY_Y_TAB_H_INCLUDED */ + +/* Copy the second part of user declarations. */ + +#line 539 "y.tab.c" /* yacc.c:358 */ + +#ifdef short +# undef short +#endif + +#ifdef YYTYPE_UINT8 +typedef YYTYPE_UINT8 yytype_uint8; +#else +typedef unsigned char yytype_uint8; +#endif + +#ifdef YYTYPE_INT8 +typedef YYTYPE_INT8 yytype_int8; +#else +typedef signed char yytype_int8; +#endif + +#ifdef YYTYPE_UINT16 +typedef YYTYPE_UINT16 yytype_uint16; +#else +typedef unsigned short int yytype_uint16; +#endif + +#ifdef YYTYPE_INT16 +typedef YYTYPE_INT16 yytype_int16; +#else +typedef short int yytype_int16; +#endif + +#ifndef YYSIZE_T +# ifdef __SIZE_TYPE__ +# define YYSIZE_T __SIZE_TYPE__ +# elif defined size_t +# define YYSIZE_T size_t +# elif ! defined YYSIZE_T +# include /* INFRINGES ON USER NAME SPACE */ +# define YYSIZE_T size_t +# else +# define YYSIZE_T unsigned int +# endif +#endif + +#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) + +#ifndef YY_ +# if defined YYENABLE_NLS && YYENABLE_NLS +# if ENABLE_NLS +# include /* INFRINGES ON USER NAME SPACE */ +# define YY_(Msgid) dgettext ("bison-runtime", Msgid) +# endif +# endif +# ifndef YY_ +# define YY_(Msgid) Msgid +# endif +#endif + +#ifndef YY_ATTRIBUTE +# if (defined __GNUC__ \ + && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \ + || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C +# define YY_ATTRIBUTE(Spec) __attribute__(Spec) +# else +# define YY_ATTRIBUTE(Spec) /* empty */ +# endif +#endif + +#ifndef YY_ATTRIBUTE_PURE +# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__)) +#endif + +#ifndef YY_ATTRIBUTE_UNUSED +# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__)) +#endif + +#if !defined _Noreturn \ + && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112) +# if defined _MSC_VER && 1200 <= _MSC_VER +# define _Noreturn __declspec (noreturn) +# else +# define _Noreturn YY_ATTRIBUTE ((__noreturn__)) +# endif +#endif + +/* Suppress unused-variable warnings by "using" E. */ +#if ! defined lint || defined __GNUC__ +# define YYUSE(E) ((void) (E)) +#else +# define YYUSE(E) /* empty */ +#endif + +#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__ +/* Suppress an incorrect diagnostic about yylval being uninitialized. */ +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \ + _Pragma ("GCC diagnostic push") \ + _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\ + _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"") +# define YY_IGNORE_MAYBE_UNINITIALIZED_END \ + _Pragma ("GCC diagnostic pop") +#else +# define YY_INITIAL_VALUE(Value) Value +#endif +#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN +# define YY_IGNORE_MAYBE_UNINITIALIZED_END +#endif +#ifndef YY_INITIAL_VALUE +# define YY_INITIAL_VALUE(Value) /* Nothing. */ +#endif + + +#if ! defined yyoverflow || YYERROR_VERBOSE + +/* The parser invokes alloca or malloc; define the necessary symbols. */ + +# ifdef YYSTACK_USE_ALLOCA +# if YYSTACK_USE_ALLOCA +# ifdef __GNUC__ +# define YYSTACK_ALLOC __builtin_alloca +# elif defined __BUILTIN_VA_ARG_INCR +# include /* INFRINGES ON USER NAME SPACE */ +# elif defined _AIX +# define YYSTACK_ALLOC __alloca +# elif defined _MSC_VER +# include /* INFRINGES ON USER NAME SPACE */ +# define alloca _alloca +# else +# define YYSTACK_ALLOC alloca +# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS +# include /* INFRINGES ON USER NAME SPACE */ + /* Use EXIT_SUCCESS as a witness for stdlib.h. */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# endif +# endif +# endif + +# ifdef YYSTACK_ALLOC + /* Pacify GCC's 'empty if-body' warning. */ +# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0) +# ifndef YYSTACK_ALLOC_MAXIMUM + /* The OS might guarantee only one guard page at the bottom of the stack, + and a page size can be as small as 4096 bytes. So we cannot safely + invoke alloca (N) if N exceeds 4096. Use a slightly smaller number + to allow for a few compiler-allocated temporary stack slots. */ +# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ +# endif +# else +# define YYSTACK_ALLOC YYMALLOC +# define YYSTACK_FREE YYFREE +# ifndef YYSTACK_ALLOC_MAXIMUM +# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM +# endif +# if (defined __cplusplus && ! defined EXIT_SUCCESS \ + && ! ((defined YYMALLOC || defined malloc) \ + && (defined YYFREE || defined free))) +# include /* INFRINGES ON USER NAME SPACE */ +# ifndef EXIT_SUCCESS +# define EXIT_SUCCESS 0 +# endif +# endif +# ifndef YYMALLOC +# define YYMALLOC malloc +# if ! defined malloc && ! defined EXIT_SUCCESS +void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# ifndef YYFREE +# define YYFREE free +# if ! defined free && ! defined EXIT_SUCCESS +void free (void *); /* INFRINGES ON USER NAME SPACE */ +# endif +# endif +# endif +#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ + + +#if (! defined yyoverflow \ + && (! defined __cplusplus \ + || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) + +/* A type that is properly aligned for any stack member. */ +union yyalloc +{ + yytype_int16 yyss_alloc; + YYSTYPE yyvs_alloc; +}; + +/* The size of the maximum gap between one aligned stack and the next. */ +# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) + +/* The size of an array large to enough to hold all stacks, each with + N elements. */ +# define YYSTACK_BYTES(N) \ + ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ + + YYSTACK_GAP_MAXIMUM) + +# define YYCOPY_NEEDED 1 + +/* Relocate STACK from its old location to the new one. The + local variables YYSIZE and YYSTACKSIZE give the old and new number of + elements in the stack, and YYPTR gives the new location of the + stack. Advance YYPTR to a properly aligned location for the next + stack. */ +# define YYSTACK_RELOCATE(Stack_alloc, Stack) \ + do \ + { \ + YYSIZE_T yynewbytes; \ + YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \ + Stack = &yyptr->Stack_alloc; \ + yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ + yyptr += yynewbytes / sizeof (*yyptr); \ + } \ + while (0) + +#endif + +#if defined YYCOPY_NEEDED && YYCOPY_NEEDED +/* Copy COUNT objects from SRC to DST. The source and destination do + not overlap. */ +# ifndef YYCOPY +# if defined __GNUC__ && 1 < __GNUC__ +# define YYCOPY(Dst, Src, Count) \ + __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src))) +# else +# define YYCOPY(Dst, Src, Count) \ + do \ + { \ + YYSIZE_T yyi; \ + for (yyi = 0; yyi < (Count); yyi++) \ + (Dst)[yyi] = (Src)[yyi]; \ + } \ + while (0) +# endif +# endif +#endif /* !YYCOPY_NEEDED */ + +/* YYFINAL -- State number of the termination state. */ +#define YYFINAL 116 +/* YYLAST -- Last index in YYTABLE. */ +#define YYLAST 638 + +/* YYNTOKENS -- Number of terminals. */ +#define YYNTOKENS 61 +/* YYNNTS -- Number of nonterminals. */ +#define YYNNTS 38 +/* YYNRULES -- Number of rules. */ +#define YYNRULES 167 +/* YYNSTATES -- Number of states. */ +#define YYNSTATES 334 + +/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned + by yylex, with out-of-bounds checking. */ +#define YYUNDEFTOK 2 +#define YYMAXUTOK 304 + +#define YYTRANSLATE(YYX) \ + ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) + +/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM + as returned by yylex, without out-of-bounds checking. */ +static const yytype_uint8 yytranslate[] = +{ + 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 51, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 49, 2, + 59, 60, 2, 2, 2, 56, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, + 55, 2, 54, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 57, 53, 58, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 48, 52 +}; + +#if YYDEBUG + /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ +static const yytype_uint16 yyrline[] = +{ + 0, 382, 382, 393, 402, 417, 427, 429, 433, 439, + 445, 451, 457, 463, 469, 475, 481, 487, 493, 499, + 505, 511, 517, 523, 530, 537, 544, 551, 558, 565, + 571, 577, 583, 589, 595, 601, 607, 613, 619, 625, + 631, 637, 643, 649, 655, 661, 667, 673, 679, 685, + 691, 697, 705, 707, 709, 713, 717, 728, 730, 734, + 736, 738, 754, 756, 760, 762, 764, 766, 768, 770, + 772, 774, 776, 778, 780, 784, 789, 794, 799, 804, + 809, 814, 819, 826, 831, 836, 841, 848, 853, 858, + 863, 868, 873, 880, 885, 890, 897, 900, 903, 907, + 909, 940, 947, 952, 969, 974, 991, 998, 1000, 1002, + 1007, 1011, 1015, 1019, 1021, 1023, 1027, 1028, 1032, 1034, + 1036, 1038, 1042, 1044, 1046, 1048, 1050, 1052, 1056, 1058, + 1067, 1075, 1076, 1082, 1083, 1090, 1094, 1096, 1098, 1105, + 1107, 1109, 1113, 1114, 1117, 1119, 1121, 1125, 1126, 1135, + 1148, 1164, 1179, 1181, 1183, 1190, 1193, 1197, 1199, 1205, + 1211, 1230, 1252, 1254, 1277, 1281, 1283, 1285 +}; +#endif + +#if YYDEBUG || YYERROR_VERBOSE || 0 +/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. + First, the terminals, then, starting at YYNTOKENS, nonterminals. */ +static const char *const yytname[] = +{ + "$end", "error", "$undefined", "IF", "THEN", "ELSE", "ELIF", "FI", + "CASE", "ESAC", "FOR", "SELECT", "WHILE", "UNTIL", "DO", "DONE", + "FUNCTION", "COPROC", "COND_START", "COND_END", "COND_ERROR", "IN", + "BANG", "TIME", "TIMEOPT", "TIMEIGN", "WORD", "ASSIGNMENT_WORD", + "REDIR_WORD", "NUMBER", "ARITH_CMD", "ARITH_FOR_EXPRS", "COND_CMD", + "AND_AND", "OR_OR", "GREATER_GREATER", "LESS_LESS", "LESS_AND", + "LESS_LESS_LESS", "GREATER_AND", "SEMI_SEMI", "SEMI_AND", + "SEMI_SEMI_AND", "LESS_LESS_MINUS", "AND_GREATER", "AND_GREATER_GREATER", + "LESS_GREATER", "GREATER_BAR", "BAR_AND", "'&'", "';'", "'\\n'", + "yacc_EOF", "'|'", "'>'", "'<'", "'-'", "'{'", "'}'", "'('", "')'", + "$accept", "inputunit", "word_list", "redirection", + "simple_command_element", "redirection_list", "simple_command", + "command", "shell_command", "for_command", "arith_for_command", + "select_command", "case_command", "function_def", "function_body", + "subshell", "coproc", "if_command", "group_command", "arith_command", + "cond_command", "elif_clause", "case_clause", "pattern_list", + "case_clause_sequence", "pattern", "list", "compound_list", "list0", + "list1", "simple_list_terminator", "list_terminator", "newline_list", + "simple_list", "simple_list1", "pipeline_command", "pipeline", + "timespec", YY_NULLPTR +}; +#endif + +# ifdef YYPRINT +/* YYTOKNUM[NUM] -- (External) token number corresponding to the + (internal) symbol number NUM (which must be that of a token). */ +static const yytype_uint16 yytoknum[] = +{ + 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 301, 302, 303, 38, + 59, 10, 304, 124, 62, 60, 45, 123, 125, 40, + 41 +}; +# endif + +#define YYPACT_NINF -205 + +#define yypact_value_is_default(Yystate) \ + (!!((Yystate) == (-205))) + +#define YYTABLE_NINF -1 + +#define yytable_value_is_error(Yytable_value) \ + 0 + + /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing + STATE-NUM. */ +static const yytype_int16 yypact[] = +{ + 308, -28, -205, 6, -1, 37, -205, -205, 57, 558, + 18, 358, 54, 45, -205, 251, 583, -205, 102, 104, + 35, 107, 80, 112, 127, 140, 146, 147, -205, -205, + 153, 154, -205, -205, 188, -205, -205, 196, -205, 219, + -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, + -205, 17, 23, -205, -19, 358, -205, -205, 185, 408, + -205, 144, 51, 166, 189, 207, 133, 28, 196, 219, + 211, -205, -205, -205, -205, -205, 201, 184, 220, 226, + 81, 227, 126, 233, 234, 241, 242, 245, 246, 249, + 142, 255, 148, 256, 257, 259, 266, 267, -205, -205, + -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, + -205, -205, -205, -205, 243, 240, -205, -205, -205, -205, + 219, -205, -205, -205, -205, -205, 458, 458, -205, -205, + -205, -205, -205, -205, -205, 299, -205, 68, -205, 61, + -205, -205, -205, -205, 72, -205, -205, 244, 41, 219, + 219, -205, -205, -205, -205, -205, -205, -205, -205, -205, + -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, + -205, -205, -205, -205, -205, -205, -205, -205, -205, -205, + -205, -205, -205, -205, -205, 408, 408, 63, 63, 508, + 508, 179, -205, -205, -205, -205, -205, -205, 60, -205, + 155, -205, 287, 252, 74, 108, -205, 286, -205, 300, + 302, -205, 219, -205, 219, 41, -205, -205, -19, -19, + -205, -205, -205, 307, 408, 408, 408, 408, 408, 313, + 159, -205, -4, -205, -205, 312, -205, 161, -205, 265, + -205, -205, -205, -205, -205, -205, 314, 408, 161, 270, + -205, -205, 41, 219, -205, 332, 336, -205, -205, -205, + 87, 87, 87, -205, -205, -205, -205, 178, 11, -205, + -205, 315, -43, 327, 298, -205, -205, -205, 110, -205, + 342, 306, 343, 319, -205, 299, -205, -205, -205, -205, + -205, -205, -205, -205, -205, -32, 346, -205, -205, -205, + 113, -205, -205, -205, -205, -205, -205, 118, 137, -205, + -205, -205, 408, -205, -205, 363, 321, -205, -205, -205, + -205, -205, 408, 367, 325, -205, -205, 374, 333, -205, + -205, -205, -205, -205 +}; + + /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. + Performed when YYTABLE does not specify something else to do. Zero + means the default is an error. */ +static const yytype_uint8 yydefact[] = +{ + 0, 0, 147, 0, 0, 0, 147, 147, 0, 0, + 0, 0, 165, 52, 53, 0, 0, 111, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, + 0, 0, 147, 147, 0, 54, 57, 59, 164, 60, + 64, 74, 68, 65, 62, 70, 63, 69, 71, 72, + 73, 0, 149, 156, 157, 0, 4, 131, 0, 0, + 147, 147, 0, 147, 0, 0, 147, 52, 106, 102, + 0, 145, 144, 146, 161, 158, 166, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 14, 23, + 38, 32, 47, 29, 41, 35, 44, 26, 50, 51, + 20, 17, 8, 9, 0, 0, 1, 52, 58, 55, + 61, 142, 143, 2, 147, 147, 150, 151, 147, 147, + 160, 159, 147, 148, 130, 132, 141, 0, 147, 0, + 147, 147, 147, 147, 0, 147, 147, 0, 0, 104, + 103, 112, 167, 147, 16, 25, 40, 34, 49, 31, + 43, 37, 46, 28, 22, 19, 12, 13, 15, 24, + 39, 33, 48, 30, 42, 36, 45, 27, 21, 18, + 10, 11, 110, 101, 56, 0, 0, 154, 155, 0, + 0, 0, 147, 147, 147, 147, 147, 147, 0, 147, + 0, 147, 0, 0, 0, 0, 147, 0, 147, 0, + 0, 147, 99, 98, 105, 0, 152, 153, 163, 162, + 147, 147, 107, 0, 0, 0, 134, 135, 133, 0, + 116, 147, 0, 147, 147, 0, 6, 0, 147, 0, + 85, 86, 147, 147, 147, 147, 0, 0, 0, 0, + 66, 67, 0, 100, 96, 0, 0, 109, 136, 137, + 138, 139, 140, 95, 122, 124, 126, 117, 0, 93, + 128, 0, 0, 0, 0, 75, 7, 147, 0, 76, + 0, 0, 0, 0, 87, 0, 147, 88, 97, 108, + 147, 123, 125, 127, 94, 0, 0, 147, 77, 78, + 0, 147, 147, 83, 84, 89, 90, 0, 113, 147, + 129, 118, 119, 147, 147, 0, 0, 147, 147, 147, + 115, 120, 121, 0, 0, 81, 82, 0, 0, 114, + 79, 80, 91, 92 +}; + + /* YYPGOTO[NTERM-NUM]. */ +static const yytype_int16 yypgoto[] = +{ + -205, -205, 183, -36, -23, -50, 364, -205, -7, -205, + -205, -205, -205, -205, -204, -205, -205, -205, -205, -205, + -205, 84, -205, 167, -205, 128, -202, -6, -205, 52, + -205, -46, -48, -205, -119, 24, -33, -205 +}; + + /* YYDEFGOTO[NTERM-NUM]. */ +static const yytype_int16 yydefgoto[] = +{ + -1, 34, 237, 35, 36, 120, 37, 38, 39, 40, + 41, 42, 43, 44, 213, 45, 46, 47, 48, 49, + 50, 223, 229, 230, 231, 272, 57, 58, 134, 135, + 123, 74, 59, 51, 52, 136, 54, 55 +}; + + /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If + positive, shift that token. If negative, reduce the rule whose + number is the opposite. If YYTABLE_NINF, syntax error. */ +static const yytype_uint16 yytable[] = +{ + 64, 65, 69, 119, 246, 269, 249, 187, 188, 130, + 296, 254, 137, 139, 118, 144, 142, 297, 148, 150, + 294, 296, 270, 56, 53, 61, 114, 115, 309, 128, + 62, 2, 60, 119, 129, 75, 3, 270, 4, 5, + 6, 7, 282, 283, 2, 118, 10, 133, 288, 3, + 70, 4, 5, 6, 7, 271, 124, 125, 17, 10, + 149, 100, 133, 63, 101, 140, 216, 217, 121, 122, + 271, 17, 126, 127, 233, 199, 185, 186, 76, 131, + 189, 190, 200, 66, 184, 32, 206, 33, 242, 197, + 198, 102, 133, 207, 204, 205, 124, 125, 32, 214, + 33, 71, 72, 73, 77, 215, 104, 156, 141, 105, + 157, 133, 133, 119, 184, 327, 328, 234, 201, 133, + 192, 193, 244, 133, 301, 133, 191, 313, 98, 208, + 99, 243, 317, 103, 202, 203, 106, 158, 107, 209, + 210, 212, 319, 221, 224, 225, 226, 227, 228, 232, + 53, 53, 160, 108, 238, 161, 218, 219, 247, 133, + 247, 133, 253, 252, 133, 245, 109, 302, 170, 133, + 314, 171, 110, 111, 174, 318, 119, 175, 184, 112, + 113, 236, 162, 268, 220, 221, 222, 276, 116, 132, + 278, 277, 147, 235, 138, 239, 247, 247, 172, 264, + 265, 266, 286, 145, 176, 71, 72, 73, 212, 53, + 53, 71, 72, 73, 255, 256, 143, 184, 291, 292, + 293, 146, 117, 14, 15, 16, 152, 273, 274, 300, + 151, 18, 19, 20, 21, 22, 280, 281, 307, 23, + 24, 25, 26, 27, 153, 212, 154, 15, 16, 312, + 30, 31, 155, 159, 18, 19, 20, 21, 22, 163, + 164, 322, 23, 24, 25, 26, 27, 165, 166, 247, + 247, 167, 168, 30, 31, 169, 258, 259, 260, 261, + 262, 173, 177, 178, 308, 179, 78, 79, 80, 81, + 82, 311, 180, 181, 83, 315, 316, 84, 85, 285, + 183, 182, 240, 321, 211, 86, 87, 323, 324, 1, + 241, 2, 236, 329, 257, 250, 3, 251, 4, 5, + 6, 7, 263, 279, 8, 9, 10, 275, 287, 284, + 11, 12, 192, 193, 13, 14, 15, 16, 17, 289, + 290, 270, 298, 18, 19, 20, 21, 22, 194, 195, + 196, 23, 24, 25, 26, 27, 299, 303, 305, 28, + 29, 2, 30, 31, 304, 32, 3, 33, 4, 5, + 6, 7, 310, 68, 8, 9, 10, 306, 325, 326, + 11, 12, 330, 331, 13, 14, 15, 16, 17, 332, + 248, 333, 320, 18, 19, 20, 21, 22, 267, 295, + 0, 23, 24, 25, 26, 27, 0, 0, 71, 72, + 73, 2, 30, 31, 0, 32, 3, 33, 4, 5, + 6, 7, 0, 0, 8, 9, 10, 0, 0, 0, + 11, 12, 0, 0, 13, 14, 15, 16, 17, 0, + 0, 0, 0, 18, 19, 20, 21, 22, 0, 0, + 0, 23, 24, 25, 26, 27, 0, 0, 0, 133, + 0, 2, 30, 31, 0, 32, 3, 33, 4, 5, + 6, 7, 0, 0, 8, 9, 10, 0, 0, 0, + 11, 12, 0, 0, 13, 14, 15, 16, 17, 0, + 0, 0, 0, 18, 19, 20, 21, 22, 0, 0, + 0, 23, 24, 25, 26, 27, 0, 0, 0, 0, + 0, 2, 30, 31, 0, 32, 3, 33, 4, 5, + 6, 7, 0, 0, 8, 9, 10, 0, 0, 0, + 0, 0, 0, 0, 13, 14, 15, 16, 17, 0, + 0, 0, 0, 18, 19, 20, 21, 22, 0, 0, + 0, 23, 24, 25, 26, 27, 0, 0, 0, 133, + 0, 2, 30, 31, 0, 32, 3, 33, 4, 5, + 6, 7, 0, 0, 0, 0, 10, 0, 0, 0, + 0, 0, 0, 0, 67, 14, 15, 16, 17, 0, + 0, 0, 0, 18, 19, 20, 21, 22, 0, 0, + 0, 23, 24, 25, 26, 27, 0, 0, 0, 0, + 0, 0, 30, 31, 0, 32, 0, 33, 88, 89, + 90, 91, 92, 0, 0, 0, 93, 0, 0, 94, + 95, 0, 0, 0, 0, 0, 0, 96, 97 +}; + +static const yytype_int16 yycheck[] = +{ + 6, 7, 9, 39, 206, 9, 208, 126, 127, 55, + 53, 215, 60, 61, 37, 63, 62, 60, 66, 69, + 9, 53, 26, 51, 0, 26, 32, 33, 60, 48, + 31, 3, 26, 69, 53, 11, 8, 26, 10, 11, + 12, 13, 244, 245, 3, 68, 18, 51, 252, 8, + 32, 10, 11, 12, 13, 59, 33, 34, 30, 18, + 67, 26, 51, 26, 29, 14, 185, 186, 51, 52, + 59, 30, 49, 50, 14, 14, 124, 125, 24, 55, + 128, 129, 21, 26, 120, 57, 14, 59, 14, 21, + 138, 56, 51, 21, 142, 143, 33, 34, 57, 149, + 59, 50, 51, 52, 59, 153, 26, 26, 57, 29, + 29, 51, 51, 149, 150, 317, 318, 57, 57, 51, + 33, 34, 14, 51, 14, 51, 132, 14, 26, 57, + 26, 57, 14, 26, 140, 141, 56, 56, 26, 145, + 146, 148, 5, 6, 192, 193, 194, 195, 196, 197, + 126, 127, 26, 26, 200, 29, 189, 190, 206, 51, + 208, 51, 212, 211, 51, 57, 26, 57, 26, 51, + 57, 29, 26, 26, 26, 57, 212, 29, 214, 26, + 26, 26, 56, 231, 5, 6, 7, 26, 0, 4, + 238, 237, 59, 199, 50, 201, 244, 245, 56, 40, + 41, 42, 248, 14, 56, 50, 51, 52, 215, 185, + 186, 50, 51, 52, 220, 221, 50, 253, 40, 41, + 42, 14, 26, 27, 28, 29, 25, 233, 234, 277, + 19, 35, 36, 37, 38, 39, 242, 243, 286, 43, + 44, 45, 46, 47, 60, 252, 26, 28, 29, 297, + 54, 55, 26, 26, 35, 36, 37, 38, 39, 26, + 26, 309, 43, 44, 45, 46, 47, 26, 26, 317, + 318, 26, 26, 54, 55, 26, 224, 225, 226, 227, + 228, 26, 26, 26, 290, 26, 35, 36, 37, 38, + 39, 297, 26, 26, 43, 301, 302, 46, 47, 247, + 60, 58, 15, 309, 60, 54, 55, 313, 314, 1, + 58, 3, 26, 319, 7, 15, 8, 15, 10, 11, + 12, 13, 9, 58, 16, 17, 18, 15, 58, 15, + 22, 23, 33, 34, 26, 27, 28, 29, 30, 7, + 4, 26, 15, 35, 36, 37, 38, 39, 49, 50, + 51, 43, 44, 45, 46, 47, 58, 15, 15, 51, + 52, 3, 54, 55, 58, 57, 8, 59, 10, 11, + 12, 13, 26, 9, 16, 17, 18, 58, 15, 58, + 22, 23, 15, 58, 26, 27, 28, 29, 30, 15, + 207, 58, 308, 35, 36, 37, 38, 39, 231, 271, + -1, 43, 44, 45, 46, 47, -1, -1, 50, 51, + 52, 3, 54, 55, -1, 57, 8, 59, 10, 11, + 12, 13, -1, -1, 16, 17, 18, -1, -1, -1, + 22, 23, -1, -1, 26, 27, 28, 29, 30, -1, + -1, -1, -1, 35, 36, 37, 38, 39, -1, -1, + -1, 43, 44, 45, 46, 47, -1, -1, -1, 51, + -1, 3, 54, 55, -1, 57, 8, 59, 10, 11, + 12, 13, -1, -1, 16, 17, 18, -1, -1, -1, + 22, 23, -1, -1, 26, 27, 28, 29, 30, -1, + -1, -1, -1, 35, 36, 37, 38, 39, -1, -1, + -1, 43, 44, 45, 46, 47, -1, -1, -1, -1, + -1, 3, 54, 55, -1, 57, 8, 59, 10, 11, + 12, 13, -1, -1, 16, 17, 18, -1, -1, -1, + -1, -1, -1, -1, 26, 27, 28, 29, 30, -1, + -1, -1, -1, 35, 36, 37, 38, 39, -1, -1, + -1, 43, 44, 45, 46, 47, -1, -1, -1, 51, + -1, 3, 54, 55, -1, 57, 8, 59, 10, 11, + 12, 13, -1, -1, -1, -1, 18, -1, -1, -1, + -1, -1, -1, -1, 26, 27, 28, 29, 30, -1, + -1, -1, -1, 35, 36, 37, 38, 39, -1, -1, + -1, 43, 44, 45, 46, 47, -1, -1, -1, -1, + -1, -1, 54, 55, -1, 57, -1, 59, 35, 36, + 37, 38, 39, -1, -1, -1, 43, -1, -1, 46, + 47, -1, -1, -1, -1, -1, -1, 54, 55 +}; + + /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing + symbol of state STATE-NUM. */ +static const yytype_uint8 yystos[] = +{ + 0, 1, 3, 8, 10, 11, 12, 13, 16, 17, + 18, 22, 23, 26, 27, 28, 29, 30, 35, 36, + 37, 38, 39, 43, 44, 45, 46, 47, 51, 52, + 54, 55, 57, 59, 62, 64, 65, 67, 68, 69, + 70, 71, 72, 73, 74, 76, 77, 78, 79, 80, + 81, 94, 95, 96, 97, 98, 51, 87, 88, 93, + 26, 26, 31, 26, 88, 88, 26, 26, 67, 69, + 32, 50, 51, 52, 92, 96, 24, 59, 35, 36, + 37, 38, 39, 43, 46, 47, 54, 55, 35, 36, + 37, 38, 39, 43, 46, 47, 54, 55, 26, 26, + 26, 29, 56, 26, 26, 29, 56, 26, 26, 26, + 26, 26, 26, 26, 88, 88, 0, 26, 65, 64, + 66, 51, 52, 91, 33, 34, 49, 50, 48, 53, + 92, 96, 4, 51, 89, 90, 96, 93, 50, 93, + 14, 57, 92, 50, 93, 14, 14, 59, 93, 69, + 66, 19, 25, 60, 26, 26, 26, 29, 56, 26, + 26, 29, 56, 26, 26, 26, 26, 26, 26, 26, + 26, 29, 56, 26, 26, 29, 56, 26, 26, 26, + 26, 26, 58, 60, 64, 93, 93, 95, 95, 93, + 93, 88, 33, 34, 49, 50, 51, 21, 93, 14, + 21, 57, 88, 88, 93, 93, 14, 21, 57, 88, + 88, 60, 69, 75, 66, 93, 95, 95, 97, 97, + 5, 6, 7, 82, 93, 93, 93, 93, 93, 83, + 84, 85, 93, 14, 57, 88, 26, 63, 92, 88, + 15, 58, 14, 57, 14, 57, 87, 93, 63, 87, + 15, 15, 93, 66, 75, 88, 88, 7, 90, 90, + 90, 90, 90, 9, 40, 41, 42, 84, 93, 9, + 26, 59, 86, 88, 88, 15, 26, 92, 93, 58, + 88, 88, 87, 87, 15, 90, 92, 58, 75, 7, + 4, 40, 41, 42, 9, 86, 53, 60, 15, 58, + 93, 14, 57, 15, 58, 15, 58, 93, 88, 60, + 26, 88, 93, 14, 57, 88, 88, 14, 57, 5, + 82, 88, 93, 88, 88, 15, 58, 87, 87, 88, + 15, 58, 15, 58 +}; + + /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ +static const yytype_uint8 yyr1[] = +{ + 0, 61, 62, 62, 62, 62, 63, 63, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 65, 65, 65, 66, 66, 67, 67, 68, + 68, 68, 68, 68, 69, 69, 69, 69, 69, 69, + 69, 69, 69, 69, 69, 70, 70, 70, 70, 70, + 70, 70, 70, 71, 71, 71, 71, 72, 72, 72, + 72, 72, 72, 73, 73, 73, 74, 74, 74, 75, + 75, 76, 77, 77, 77, 77, 77, 78, 78, 78, + 79, 80, 81, 82, 82, 82, 83, 83, 84, 84, + 84, 84, 85, 85, 85, 85, 85, 85, 86, 86, + 87, 88, 88, 89, 89, 89, 90, 90, 90, 90, + 90, 90, 91, 91, 92, 92, 92, 93, 93, 94, + 94, 94, 95, 95, 95, 95, 95, 96, 96, 96, + 96, 96, 97, 97, 97, 98, 98, 98 +}; + + /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ +static const yytype_uint8 yyr2[] = +{ + 0, 2, 2, 1, 2, 1, 1, 2, 2, 2, + 3, 3, 3, 3, 2, 3, 3, 2, 3, 3, + 2, 3, 3, 2, 3, 3, 2, 3, 3, 2, + 3, 3, 2, 3, 3, 2, 3, 3, 2, 3, + 3, 2, 3, 3, 2, 3, 3, 2, 3, 3, + 2, 2, 1, 1, 1, 1, 2, 1, 2, 1, + 1, 2, 1, 1, 1, 1, 5, 5, 1, 1, + 1, 1, 1, 1, 1, 6, 6, 7, 7, 10, + 10, 9, 9, 7, 7, 5, 5, 6, 6, 7, + 7, 10, 10, 6, 7, 6, 5, 6, 4, 1, + 2, 3, 2, 3, 3, 4, 2, 5, 7, 6, + 3, 1, 3, 4, 6, 5, 1, 2, 4, 4, + 5, 5, 2, 3, 2, 3, 2, 3, 1, 3, + 2, 1, 2, 3, 3, 3, 4, 4, 4, 4, + 4, 1, 1, 1, 1, 1, 1, 0, 2, 1, + 2, 2, 4, 4, 3, 3, 1, 1, 2, 2, + 2, 2, 4, 4, 1, 1, 2, 3 +}; + + +#define yyerrok (yyerrstatus = 0) +#define yyclearin (yychar = YYEMPTY) +#define YYEMPTY (-2) +#define YYEOF 0 + +#define YYACCEPT goto yyacceptlab +#define YYABORT goto yyabortlab +#define YYERROR goto yyerrorlab + + +#define YYRECOVERING() (!!yyerrstatus) + +#define YYBACKUP(Token, Value) \ +do \ + if (yychar == YYEMPTY) \ + { \ + yychar = (Token); \ + yylval = (Value); \ + YYPOPSTACK (yylen); \ + yystate = *yyssp; \ + goto yybackup; \ + } \ + else \ + { \ + yyerror (YY_("syntax error: cannot back up")); \ + YYERROR; \ + } \ +while (0) + +/* Error token number */ +#define YYTERROR 1 +#define YYERRCODE 256 + + + +/* Enable debugging if requested. */ +#if YYDEBUG + +# ifndef YYFPRINTF +# include /* INFRINGES ON USER NAME SPACE */ +# define YYFPRINTF fprintf +# endif + +# define YYDPRINTF(Args) \ +do { \ + if (yydebug) \ + YYFPRINTF Args; \ +} while (0) + +/* This macro is provided for backward compatibility. */ +#ifndef YY_LOCATION_PRINT +# define YY_LOCATION_PRINT(File, Loc) ((void) 0) +#endif + + +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ +do { \ + if (yydebug) \ + { \ + YYFPRINTF (stderr, "%s ", Title); \ + yy_symbol_print (stderr, \ + Type, Value); \ + YYFPRINTF (stderr, "\n"); \ + } \ +} while (0) + + +/*----------------------------------------. +| Print this symbol's value on YYOUTPUT. | +`----------------------------------------*/ + +static void +yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +{ + FILE *yyo = yyoutput; + YYUSE (yyo); + if (!yyvaluep) + return; +# ifdef YYPRINT + if (yytype < YYNTOKENS) + YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); +# endif + YYUSE (yytype); +} + + +/*--------------------------------. +| Print this symbol on YYOUTPUT. | +`--------------------------------*/ + +static void +yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) +{ + YYFPRINTF (yyoutput, "%s %s (", + yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]); + + yy_symbol_value_print (yyoutput, yytype, yyvaluep); + YYFPRINTF (yyoutput, ")"); +} + +/*------------------------------------------------------------------. +| yy_stack_print -- Print the state stack from its BOTTOM up to its | +| TOP (included). | +`------------------------------------------------------------------*/ + +static void +yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop) +{ + YYFPRINTF (stderr, "Stack now"); + for (; yybottom <= yytop; yybottom++) + { + int yybot = *yybottom; + YYFPRINTF (stderr, " %d", yybot); + } + YYFPRINTF (stderr, "\n"); +} + +# define YY_STACK_PRINT(Bottom, Top) \ +do { \ + if (yydebug) \ + yy_stack_print ((Bottom), (Top)); \ +} while (0) + + +/*------------------------------------------------. +| Report that the YYRULE is going to be reduced. | +`------------------------------------------------*/ + +static void +yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule) +{ + unsigned long int yylno = yyrline[yyrule]; + int yynrhs = yyr2[yyrule]; + int yyi; + YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", + yyrule - 1, yylno); + /* The symbols being reduced. */ + for (yyi = 0; yyi < yynrhs; yyi++) + { + YYFPRINTF (stderr, " $%d = ", yyi + 1); + yy_symbol_print (stderr, + yystos[yyssp[yyi + 1 - yynrhs]], + &(yyvsp[(yyi + 1) - (yynrhs)]) + ); + YYFPRINTF (stderr, "\n"); + } +} + +# define YY_REDUCE_PRINT(Rule) \ +do { \ + if (yydebug) \ + yy_reduce_print (yyssp, yyvsp, Rule); \ +} while (0) + +/* Nonzero means print parse trace. It is left uninitialized so that + multiple parsers can coexist. */ +int yydebug; +#else /* !YYDEBUG */ +# define YYDPRINTF(Args) +# define YY_SYMBOL_PRINT(Title, Type, Value, Location) +# define YY_STACK_PRINT(Bottom, Top) +# define YY_REDUCE_PRINT(Rule) +#endif /* !YYDEBUG */ + + +/* YYINITDEPTH -- initial size of the parser's stacks. */ +#ifndef YYINITDEPTH +# define YYINITDEPTH 200 +#endif + +/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only + if the built-in stack extension method is used). + + Do not make this value too large; the results are undefined if + YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) + evaluated with infinite-precision integer arithmetic. */ + +#ifndef YYMAXDEPTH +# define YYMAXDEPTH 10000 +#endif + + +#if YYERROR_VERBOSE + +# ifndef yystrlen +# if defined __GLIBC__ && defined _STRING_H +# define yystrlen strlen +# else +/* Return the length of YYSTR. */ +static YYSIZE_T +yystrlen (const char *yystr) +{ + YYSIZE_T yylen; + for (yylen = 0; yystr[yylen]; yylen++) + continue; + return yylen; +} +# endif +# endif + +# ifndef yystpcpy +# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE +# define yystpcpy stpcpy +# else +/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in + YYDEST. */ +static char * +yystpcpy (char *yydest, const char *yysrc) +{ + char *yyd = yydest; + const char *yys = yysrc; + + while ((*yyd++ = *yys++) != '\0') + continue; + + return yyd - 1; +} +# endif +# endif + +# ifndef yytnamerr +/* Copy to YYRES the contents of YYSTR after stripping away unnecessary + quotes and backslashes, so that it's suitable for yyerror. The + heuristic is that double-quoting is unnecessary unless the string + contains an apostrophe, a comma, or backslash (other than + backslash-backslash). YYSTR is taken from yytname. If YYRES is + null, do not copy; instead, return the length of what the result + would have been. */ +static YYSIZE_T +yytnamerr (char *yyres, const char *yystr) +{ + if (*yystr == '"') + { + YYSIZE_T yyn = 0; + char const *yyp = yystr; + + for (;;) + switch (*++yyp) + { + case '\'': + case ',': + goto do_not_strip_quotes; + + case '\\': + if (*++yyp != '\\') + goto do_not_strip_quotes; + /* Fall through. */ + default: + if (yyres) + yyres[yyn] = *yyp; + yyn++; + break; + + case '"': + if (yyres) + yyres[yyn] = '\0'; + return yyn; + } + do_not_strip_quotes: ; + } + + if (! yyres) + return yystrlen (yystr); + + return yystpcpy (yyres, yystr) - yyres; +} +# endif + +/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message + about the unexpected token YYTOKEN for the state stack whose top is + YYSSP. + + Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is + not large enough to hold the message. In that case, also set + *YYMSG_ALLOC to the required number of bytes. Return 2 if the + required number of bytes is too large to store. */ +static int +yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg, + yytype_int16 *yyssp, int yytoken) +{ + YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]); + YYSIZE_T yysize = yysize0; + enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; + /* Internationalized format string. */ + const char *yyformat = YY_NULLPTR; + /* Arguments of yyformat. */ + char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; + /* Number of reported tokens (one for the "unexpected", one per + "expected"). */ + int yycount = 0; + + /* There are many possibilities here to consider: + - If this state is a consistent state with a default action, then + the only way this function was invoked is if the default action + is an error action. In that case, don't check for expected + tokens because there are none. + - The only way there can be no lookahead present (in yychar) is if + this state is a consistent state with a default action. Thus, + detecting the absence of a lookahead is sufficient to determine + that there is no unexpected or expected token to report. In that + case, just report a simple "syntax error". + - Don't assume there isn't a lookahead just because this state is a + consistent state with a default action. There might have been a + previous inconsistent state, consistent state with a non-default + action, or user semantic action that manipulated yychar. + - Of course, the expected token list depends on states to have + correct lookahead information, and it depends on the parser not + to perform extra reductions after fetching a lookahead from the + scanner and before detecting a syntax error. Thus, state merging + (from LALR or IELR) and default reductions corrupt the expected + token list. However, the list is correct for canonical LR with + one exception: it will still contain any token that will not be + accepted due to an error action in a later state. + */ + if (yytoken != YYEMPTY) + { + int yyn = yypact[*yyssp]; + yyarg[yycount++] = yytname[yytoken]; + if (!yypact_value_is_default (yyn)) + { + /* Start YYX at -YYN if negative to avoid negative indexes in + YYCHECK. In other words, skip the first -YYN actions for + this state because they are default actions. */ + int yyxbegin = yyn < 0 ? -yyn : 0; + /* Stay within bounds of both yycheck and yytname. */ + int yychecklim = YYLAST - yyn + 1; + int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; + int yyx; + + for (yyx = yyxbegin; yyx < yyxend; ++yyx) + if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR + && !yytable_value_is_error (yytable[yyx + yyn])) + { + if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) + { + yycount = 1; + yysize = yysize0; + break; + } + yyarg[yycount++] = yytname[yyx]; + { + YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]); + if (! (yysize <= yysize1 + && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + } + } + } + + switch (yycount) + { +# define YYCASE_(N, S) \ + case N: \ + yyformat = S; \ + break + YYCASE_(0, YY_("syntax error")); + YYCASE_(1, YY_("syntax error, unexpected %s")); + YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s")); + YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s")); + YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s")); + YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s")); +# undef YYCASE_ + } + + { + YYSIZE_T yysize1 = yysize + yystrlen (yyformat); + if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM)) + return 2; + yysize = yysize1; + } + + if (*yymsg_alloc < yysize) + { + *yymsg_alloc = 2 * yysize; + if (! (yysize <= *yymsg_alloc + && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM)) + *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM; + return 1; + } + + /* Avoid sprintf, as that infringes on the user's name space. + Don't have undefined behavior even if the translation + produced a string with the wrong number of "%s"s. */ + { + char *yyp = *yymsg; + int yyi = 0; + while ((*yyp = *yyformat) != '\0') + if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount) + { + yyp += yytnamerr (yyp, yyarg[yyi++]); + yyformat += 2; + } + else + { + yyp++; + yyformat++; + } + } + return 0; +} +#endif /* YYERROR_VERBOSE */ + +/*-----------------------------------------------. +| Release the memory associated to this symbol. | +`-----------------------------------------------*/ + +static void +yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) +{ + YYUSE (yyvaluep); + if (!yymsg) + yymsg = "Deleting"; + YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + YYUSE (yytype); + YY_IGNORE_MAYBE_UNINITIALIZED_END +} + + + + +/* The lookahead symbol. */ +int yychar; + +/* The semantic value of the lookahead symbol. */ +YYSTYPE yylval; +/* Number of syntax errors so far. */ +int yynerrs; + + +/*----------. +| yyparse. | +`----------*/ + +int +yyparse (void) +{ + int yystate; + /* Number of tokens to shift before error messages enabled. */ + int yyerrstatus; + + /* The stacks and their tools: + 'yyss': related to states. + 'yyvs': related to semantic values. + + Refer to the stacks through separate pointers, to allow yyoverflow + to reallocate them elsewhere. */ + + /* The state stack. */ + yytype_int16 yyssa[YYINITDEPTH]; + yytype_int16 *yyss; + yytype_int16 *yyssp; + + /* The semantic value stack. */ + YYSTYPE yyvsa[YYINITDEPTH]; + YYSTYPE *yyvs; + YYSTYPE *yyvsp; + + YYSIZE_T yystacksize; + + int yyn; + int yyresult; + /* Lookahead token as an internal (translated) token number. */ + int yytoken = 0; + /* The variables used to return semantic value and location from the + action routines. */ + YYSTYPE yyval; + +#if YYERROR_VERBOSE + /* Buffer for error messages, and its allocated size. */ + char yymsgbuf[128]; + char *yymsg = yymsgbuf; + YYSIZE_T yymsg_alloc = sizeof yymsgbuf; +#endif + +#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) + + /* The number of symbols on the RHS of the reduced rule. + Keep to zero when no symbol should be popped. */ + int yylen = 0; + + yyssp = yyss = yyssa; + yyvsp = yyvs = yyvsa; + yystacksize = YYINITDEPTH; + + YYDPRINTF ((stderr, "Starting parse\n")); + + yystate = 0; + yyerrstatus = 0; + yynerrs = 0; + yychar = YYEMPTY; /* Cause a token to be read. */ + goto yysetstate; + +/*------------------------------------------------------------. +| yynewstate -- Push a new state, which is found in yystate. | +`------------------------------------------------------------*/ + yynewstate: + /* In all cases, when you get here, the value and location stacks + have just been pushed. So pushing a state here evens the stacks. */ + yyssp++; + + yysetstate: + *yyssp = yystate; + + if (yyss + yystacksize - 1 <= yyssp) + { + /* Get the current used size of the three stacks, in elements. */ + YYSIZE_T yysize = yyssp - yyss + 1; + +#ifdef yyoverflow + { + /* Give user a chance to reallocate the stack. Use copies of + these so that the &'s don't force the real ones into + memory. */ + YYSTYPE *yyvs1 = yyvs; + yytype_int16 *yyss1 = yyss; + + /* Each stack pointer address is followed by the size of the + data in use in that stack, in bytes. This used to be a + conditional around just the two extra args, but that might + be undefined if yyoverflow is a macro. */ + yyoverflow (YY_("memory exhausted"), + &yyss1, yysize * sizeof (*yyssp), + &yyvs1, yysize * sizeof (*yyvsp), + &yystacksize); + + yyss = yyss1; + yyvs = yyvs1; + } +#else /* no yyoverflow */ +# ifndef YYSTACK_RELOCATE + goto yyexhaustedlab; +# else + /* Extend the stack our own way. */ + if (YYMAXDEPTH <= yystacksize) + goto yyexhaustedlab; + yystacksize *= 2; + if (YYMAXDEPTH < yystacksize) + yystacksize = YYMAXDEPTH; + + { + yytype_int16 *yyss1 = yyss; + union yyalloc *yyptr = + (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); + if (! yyptr) + goto yyexhaustedlab; + YYSTACK_RELOCATE (yyss_alloc, yyss); + YYSTACK_RELOCATE (yyvs_alloc, yyvs); +# undef YYSTACK_RELOCATE + if (yyss1 != yyssa) + YYSTACK_FREE (yyss1); + } +# endif +#endif /* no yyoverflow */ + + yyssp = yyss + yysize - 1; + yyvsp = yyvs + yysize - 1; + + YYDPRINTF ((stderr, "Stack size increased to %lu\n", + (unsigned long int) yystacksize)); + + if (yyss + yystacksize - 1 <= yyssp) + YYABORT; + } + + YYDPRINTF ((stderr, "Entering state %d\n", yystate)); + + if (yystate == YYFINAL) + YYACCEPT; + + goto yybackup; + +/*-----------. +| yybackup. | +`-----------*/ +yybackup: + + /* Do appropriate processing given the current state. Read a + lookahead token if we need one and don't already have one. */ + + /* First try to decide what to do without reference to lookahead token. */ + yyn = yypact[yystate]; + if (yypact_value_is_default (yyn)) + goto yydefault; + + /* Not known => get a lookahead token if don't already have one. */ + + /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */ + if (yychar == YYEMPTY) + { + YYDPRINTF ((stderr, "Reading a token: ")); + yychar = yylex (); + } + + if (yychar <= YYEOF) + { + yychar = yytoken = YYEOF; + YYDPRINTF ((stderr, "Now at end of input.\n")); + } + else + { + yytoken = YYTRANSLATE (yychar); + YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); + } + + /* If the proper action on seeing token YYTOKEN is to reduce or to + detect an error, take that action. */ + yyn += yytoken; + if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) + goto yydefault; + yyn = yytable[yyn]; + if (yyn <= 0) + { + if (yytable_value_is_error (yyn)) + goto yyerrlab; + yyn = -yyn; + goto yyreduce; + } + + /* Count tokens shifted since error; after three, turn off error + status. */ + if (yyerrstatus) + yyerrstatus--; + + /* Shift the lookahead token. */ + YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); + + /* Discard the shifted token. */ + yychar = YYEMPTY; + + yystate = yyn; + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + goto yynewstate; + + +/*-----------------------------------------------------------. +| yydefault -- do the default action for the current state. | +`-----------------------------------------------------------*/ +yydefault: + yyn = yydefact[yystate]; + if (yyn == 0) + goto yyerrlab; + goto yyreduce; + + +/*-----------------------------. +| yyreduce -- Do a reduction. | +`-----------------------------*/ +yyreduce: + /* yyn is the number of a rule to reduce with. */ + yylen = yyr2[yyn]; + + /* If YYLEN is nonzero, implement the default value of the action: + '$$ = $1'. + + Otherwise, the following line sets YYVAL to garbage. + This behavior is undocumented and Bison + users should not rely upon it. Assigning to YYVAL + unconditionally makes the parser a bit smaller, and it avoids a + GCC warning that YYVAL may be used uninitialized. */ + yyval = yyvsp[1-yylen]; + + + YY_REDUCE_PRINT (yyn); + switch (yyn) + { + case 2: +#line 383 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + /* Case of regular command. Discard the error + safety net,and return the command just parsed. */ + global_command = (yyvsp[-1].command); + eof_encountered = 0; + /* discard_parser_constructs (0); */ + if (parser_state & PST_CMDSUBST) + parser_state |= PST_EOFTOKEN; + YYACCEPT; + } +#line 1921 "y.tab.c" /* yacc.c:1646 */ + break; + + case 3: +#line 394 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + /* Case of regular command, but not a very + interesting one. Return a NULL command. */ + global_command = (COMMAND *)NULL; + if (parser_state & PST_CMDSUBST) + parser_state |= PST_EOFTOKEN; + YYACCEPT; + } +#line 1934 "y.tab.c" /* yacc.c:1646 */ + break; + + case 4: +#line 403 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + /* Error during parsing. Return NULL command. */ + global_command = (COMMAND *)NULL; + eof_encountered = 0; + /* discard_parser_constructs (1); */ + if (interactive && parse_and_execute_level == 0) + { + YYACCEPT; + } + else + { + YYABORT; + } + } +#line 1953 "y.tab.c" /* yacc.c:1646 */ + break; + + case 5: +#line 418 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + /* Case of EOF seen by itself. Do ignoreeof or + not. */ + global_command = (COMMAND *)NULL; + handle_eof_input_unit (); + YYACCEPT; + } +#line 1965 "y.tab.c" /* yacc.c:1646 */ + break; + + case 6: +#line 428 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.word_list) = make_word_list ((yyvsp[0].word), (WORD_LIST *)NULL); } +#line 1971 "y.tab.c" /* yacc.c:1646 */ + break; + + case 7: +#line 430 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.word_list) = make_word_list ((yyvsp[0].word), (yyvsp[-1].word_list)); } +#line 1977 "y.tab.c" /* yacc.c:1646 */ + break; + + case 8: +#line 434 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 1; + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_output_direction, redir, 0); + } +#line 1987 "y.tab.c" /* yacc.c:1646 */ + break; + + case 9: +#line 440 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 0; + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_input_direction, redir, 0); + } +#line 1997 "y.tab.c" /* yacc.c:1646 */ + break; + + case 10: +#line 446 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_output_direction, redir, 0); + } +#line 2007 "y.tab.c" /* yacc.c:1646 */ + break; + + case 11: +#line 452 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_input_direction, redir, 0); + } +#line 2017 "y.tab.c" /* yacc.c:1646 */ + break; + + case 12: +#line 458 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_output_direction, redir, REDIR_VARASSIGN); + } +#line 2027 "y.tab.c" /* yacc.c:1646 */ + break; + + case 13: +#line 464 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_input_direction, redir, REDIR_VARASSIGN); + } +#line 2037 "y.tab.c" /* yacc.c:1646 */ + break; + + case 14: +#line 470 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 1; + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_appending_to, redir, 0); + } +#line 2047 "y.tab.c" /* yacc.c:1646 */ + break; + + case 15: +#line 476 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_appending_to, redir, 0); + } +#line 2057 "y.tab.c" /* yacc.c:1646 */ + break; + + case 16: +#line 482 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_appending_to, redir, REDIR_VARASSIGN); + } +#line 2067 "y.tab.c" /* yacc.c:1646 */ + break; + + case 17: +#line 488 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 1; + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_output_force, redir, 0); + } +#line 2077 "y.tab.c" /* yacc.c:1646 */ + break; + + case 18: +#line 494 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_output_force, redir, 0); + } +#line 2087 "y.tab.c" /* yacc.c:1646 */ + break; + + case 19: +#line 500 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_output_force, redir, REDIR_VARASSIGN); + } +#line 2097 "y.tab.c" /* yacc.c:1646 */ + break; + + case 20: +#line 506 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 0; + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_input_output, redir, 0); + } +#line 2107 "y.tab.c" /* yacc.c:1646 */ + break; + + case 21: +#line 512 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_input_output, redir, 0); + } +#line 2117 "y.tab.c" /* yacc.c:1646 */ + break; + + case 22: +#line 518 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_input_output, redir, REDIR_VARASSIGN); + } +#line 2127 "y.tab.c" /* yacc.c:1646 */ + break; + + case 23: +#line 524 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 0; + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_reading_until, redir, 0); + push_heredoc ((yyval.redirect)); + } +#line 2138 "y.tab.c" /* yacc.c:1646 */ + break; + + case 24: +#line 531 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_reading_until, redir, 0); + push_heredoc ((yyval.redirect)); + } +#line 2149 "y.tab.c" /* yacc.c:1646 */ + break; + + case 25: +#line 538 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_reading_until, redir, REDIR_VARASSIGN); + push_heredoc ((yyval.redirect)); + } +#line 2160 "y.tab.c" /* yacc.c:1646 */ + break; + + case 26: +#line 545 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 0; + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_deblank_reading_until, redir, 0); + push_heredoc ((yyval.redirect)); + } +#line 2171 "y.tab.c" /* yacc.c:1646 */ + break; + + case 27: +#line 552 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_deblank_reading_until, redir, 0); + push_heredoc ((yyval.redirect)); + } +#line 2182 "y.tab.c" /* yacc.c:1646 */ + break; + + case 28: +#line 559 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_deblank_reading_until, redir, REDIR_VARASSIGN); + push_heredoc ((yyval.redirect)); + } +#line 2193 "y.tab.c" /* yacc.c:1646 */ + break; + + case 29: +#line 566 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 0; + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_reading_string, redir, 0); + } +#line 2203 "y.tab.c" /* yacc.c:1646 */ + break; + + case 30: +#line 572 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_reading_string, redir, 0); + } +#line 2213 "y.tab.c" /* yacc.c:1646 */ + break; + + case 31: +#line 578 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_reading_string, redir, REDIR_VARASSIGN); + } +#line 2223 "y.tab.c" /* yacc.c:1646 */ + break; + + case 32: +#line 584 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 0; + redir.dest = (yyvsp[0].number); + (yyval.redirect) = make_redirection (source, r_duplicating_input, redir, 0); + } +#line 2233 "y.tab.c" /* yacc.c:1646 */ + break; + + case 33: +#line 590 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.dest = (yyvsp[0].number); + (yyval.redirect) = make_redirection (source, r_duplicating_input, redir, 0); + } +#line 2243 "y.tab.c" /* yacc.c:1646 */ + break; + + case 34: +#line 596 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.dest = (yyvsp[0].number); + (yyval.redirect) = make_redirection (source, r_duplicating_input, redir, REDIR_VARASSIGN); + } +#line 2253 "y.tab.c" /* yacc.c:1646 */ + break; + + case 35: +#line 602 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 1; + redir.dest = (yyvsp[0].number); + (yyval.redirect) = make_redirection (source, r_duplicating_output, redir, 0); + } +#line 2263 "y.tab.c" /* yacc.c:1646 */ + break; + + case 36: +#line 608 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.dest = (yyvsp[0].number); + (yyval.redirect) = make_redirection (source, r_duplicating_output, redir, 0); + } +#line 2273 "y.tab.c" /* yacc.c:1646 */ + break; + + case 37: +#line 614 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.dest = (yyvsp[0].number); + (yyval.redirect) = make_redirection (source, r_duplicating_output, redir, REDIR_VARASSIGN); + } +#line 2283 "y.tab.c" /* yacc.c:1646 */ + break; + + case 38: +#line 620 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 0; + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_duplicating_input_word, redir, 0); + } +#line 2293 "y.tab.c" /* yacc.c:1646 */ + break; + + case 39: +#line 626 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_duplicating_input_word, redir, 0); + } +#line 2303 "y.tab.c" /* yacc.c:1646 */ + break; + + case 40: +#line 632 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_duplicating_input_word, redir, REDIR_VARASSIGN); + } +#line 2313 "y.tab.c" /* yacc.c:1646 */ + break; + + case 41: +#line 638 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 1; + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_duplicating_output_word, redir, 0); + } +#line 2323 "y.tab.c" /* yacc.c:1646 */ + break; + + case 42: +#line 644 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_duplicating_output_word, redir, 0); + } +#line 2333 "y.tab.c" /* yacc.c:1646 */ + break; + + case 43: +#line 650 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_duplicating_output_word, redir, REDIR_VARASSIGN); + } +#line 2343 "y.tab.c" /* yacc.c:1646 */ + break; + + case 44: +#line 656 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 1; + redir.dest = 0; + (yyval.redirect) = make_redirection (source, r_close_this, redir, 0); + } +#line 2353 "y.tab.c" /* yacc.c:1646 */ + break; + + case 45: +#line 662 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.dest = 0; + (yyval.redirect) = make_redirection (source, r_close_this, redir, 0); + } +#line 2363 "y.tab.c" /* yacc.c:1646 */ + break; + + case 46: +#line 668 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.dest = 0; + (yyval.redirect) = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN); + } +#line 2373 "y.tab.c" /* yacc.c:1646 */ + break; + + case 47: +#line 674 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 0; + redir.dest = 0; + (yyval.redirect) = make_redirection (source, r_close_this, redir, 0); + } +#line 2383 "y.tab.c" /* yacc.c:1646 */ + break; + + case 48: +#line 680 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = (yyvsp[-2].number); + redir.dest = 0; + (yyval.redirect) = make_redirection (source, r_close_this, redir, 0); + } +#line 2393 "y.tab.c" /* yacc.c:1646 */ + break; + + case 49: +#line 686 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.filename = (yyvsp[-2].word); + redir.dest = 0; + (yyval.redirect) = make_redirection (source, r_close_this, redir, REDIR_VARASSIGN); + } +#line 2403 "y.tab.c" /* yacc.c:1646 */ + break; + + case 50: +#line 692 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 1; + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_err_and_out, redir, 0); + } +#line 2413 "y.tab.c" /* yacc.c:1646 */ + break; + + case 51: +#line 698 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + source.dest = 1; + redir.filename = (yyvsp[0].word); + (yyval.redirect) = make_redirection (source, r_append_err_and_out, redir, 0); + } +#line 2423 "y.tab.c" /* yacc.c:1646 */ + break; + + case 52: +#line 706 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.element).word = (yyvsp[0].word); (yyval.element).redirect = 0; } +#line 2429 "y.tab.c" /* yacc.c:1646 */ + break; + + case 53: +#line 708 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.element).word = (yyvsp[0].word); (yyval.element).redirect = 0; } +#line 2435 "y.tab.c" /* yacc.c:1646 */ + break; + + case 54: +#line 710 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.element).redirect = (yyvsp[0].redirect); (yyval.element).word = 0; } +#line 2441 "y.tab.c" /* yacc.c:1646 */ + break; + + case 55: +#line 714 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.redirect) = (yyvsp[0].redirect); + } +#line 2449 "y.tab.c" /* yacc.c:1646 */ + break; + + case 56: +#line 718 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + register REDIRECT *t; + + for (t = (yyvsp[-1].redirect); t->next; t = t->next) + ; + t->next = (yyvsp[0].redirect); + (yyval.redirect) = (yyvsp[-1].redirect); + } +#line 2462 "y.tab.c" /* yacc.c:1646 */ + break; + + case 57: +#line 729 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_simple_command ((yyvsp[0].element), (COMMAND *)NULL); } +#line 2468 "y.tab.c" /* yacc.c:1646 */ + break; + + case 58: +#line 731 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_simple_command ((yyvsp[0].element), (yyvsp[-1].command)); } +#line 2474 "y.tab.c" /* yacc.c:1646 */ + break; + + case 59: +#line 735 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = clean_simple_command ((yyvsp[0].command)); } +#line 2480 "y.tab.c" /* yacc.c:1646 */ + break; + + case 60: +#line 737 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 2486 "y.tab.c" /* yacc.c:1646 */ + break; + + case 61: +#line 739 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + COMMAND *tc; + + tc = (yyvsp[-1].command); + if (tc->redirects) + { + register REDIRECT *t; + for (t = tc->redirects; t->next; t = t->next) + ; + t->next = (yyvsp[0].redirect); + } + else + tc->redirects = (yyvsp[0].redirect); + (yyval.command) = (yyvsp[-1].command); + } +#line 2506 "y.tab.c" /* yacc.c:1646 */ + break; + + case 62: +#line 755 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 2512 "y.tab.c" /* yacc.c:1646 */ + break; + + case 63: +#line 757 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 2518 "y.tab.c" /* yacc.c:1646 */ + break; + + case 64: +#line 761 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 2524 "y.tab.c" /* yacc.c:1646 */ + break; + + case 65: +#line 763 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 2530 "y.tab.c" /* yacc.c:1646 */ + break; + + case 66: +#line 765 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_while_command ((yyvsp[-3].command), (yyvsp[-1].command)); } +#line 2536 "y.tab.c" /* yacc.c:1646 */ + break; + + case 67: +#line 767 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_until_command ((yyvsp[-3].command), (yyvsp[-1].command)); } +#line 2542 "y.tab.c" /* yacc.c:1646 */ + break; + + case 68: +#line 769 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 2548 "y.tab.c" /* yacc.c:1646 */ + break; + + case 69: +#line 771 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 2554 "y.tab.c" /* yacc.c:1646 */ + break; + + case 70: +#line 773 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 2560 "y.tab.c" /* yacc.c:1646 */ + break; + + case 71: +#line 775 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 2566 "y.tab.c" /* yacc.c:1646 */ + break; + + case 72: +#line 777 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 2572 "y.tab.c" /* yacc.c:1646 */ + break; + + case 73: +#line 779 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 2578 "y.tab.c" /* yacc.c:1646 */ + break; + + case 74: +#line 781 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 2584 "y.tab.c" /* yacc.c:1646 */ + break; + + case 75: +#line 785 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_for_command ((yyvsp[-4].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2593 "y.tab.c" /* yacc.c:1646 */ + break; + + case 76: +#line 790 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_for_command ((yyvsp[-4].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2602 "y.tab.c" /* yacc.c:1646 */ + break; + + case 77: +#line 795 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_for_command ((yyvsp[-5].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2611 "y.tab.c" /* yacc.c:1646 */ + break; + + case 78: +#line 800 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_for_command ((yyvsp[-5].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2620 "y.tab.c" /* yacc.c:1646 */ + break; + + case 79: +#line 805 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_for_command ((yyvsp[-8].word), REVERSE_LIST ((yyvsp[-5].word_list), WORD_LIST *), (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2629 "y.tab.c" /* yacc.c:1646 */ + break; + + case 80: +#line 810 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_for_command ((yyvsp[-8].word), REVERSE_LIST ((yyvsp[-5].word_list), WORD_LIST *), (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2638 "y.tab.c" /* yacc.c:1646 */ + break; + + case 81: +#line 815 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_for_command ((yyvsp[-7].word), (WORD_LIST *)NULL, (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2647 "y.tab.c" /* yacc.c:1646 */ + break; + + case 82: +#line 820 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_for_command ((yyvsp[-7].word), (WORD_LIST *)NULL, (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2656 "y.tab.c" /* yacc.c:1646 */ + break; + + case 83: +#line 827 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_arith_for_command ((yyvsp[-5].word_list), (yyvsp[-1].command), arith_for_lineno); + if (word_top > 0) word_top--; + } +#line 2665 "y.tab.c" /* yacc.c:1646 */ + break; + + case 84: +#line 832 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_arith_for_command ((yyvsp[-5].word_list), (yyvsp[-1].command), arith_for_lineno); + if (word_top > 0) word_top--; + } +#line 2674 "y.tab.c" /* yacc.c:1646 */ + break; + + case 85: +#line 837 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_arith_for_command ((yyvsp[-3].word_list), (yyvsp[-1].command), arith_for_lineno); + if (word_top > 0) word_top--; + } +#line 2683 "y.tab.c" /* yacc.c:1646 */ + break; + + case 86: +#line 842 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_arith_for_command ((yyvsp[-3].word_list), (yyvsp[-1].command), arith_for_lineno); + if (word_top > 0) word_top--; + } +#line 2692 "y.tab.c" /* yacc.c:1646 */ + break; + + case 87: +#line 849 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_select_command ((yyvsp[-4].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2701 "y.tab.c" /* yacc.c:1646 */ + break; + + case 88: +#line 854 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_select_command ((yyvsp[-4].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2710 "y.tab.c" /* yacc.c:1646 */ + break; + + case 89: +#line 859 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_select_command ((yyvsp[-5].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2719 "y.tab.c" /* yacc.c:1646 */ + break; + + case 90: +#line 864 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_select_command ((yyvsp[-5].word), add_string_to_list ("\"$@\"", (WORD_LIST *)NULL), (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2728 "y.tab.c" /* yacc.c:1646 */ + break; + + case 91: +#line 869 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_select_command ((yyvsp[-8].word), REVERSE_LIST ((yyvsp[-5].word_list), WORD_LIST *), (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2737 "y.tab.c" /* yacc.c:1646 */ + break; + + case 92: +#line 874 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_select_command ((yyvsp[-8].word), REVERSE_LIST ((yyvsp[-5].word_list), WORD_LIST *), (yyvsp[-1].command), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2746 "y.tab.c" /* yacc.c:1646 */ + break; + + case 93: +#line 881 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_case_command ((yyvsp[-4].word), (PATTERN_LIST *)NULL, word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2755 "y.tab.c" /* yacc.c:1646 */ + break; + + case 94: +#line 886 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_case_command ((yyvsp[-5].word), (yyvsp[-2].pattern), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2764 "y.tab.c" /* yacc.c:1646 */ + break; + + case 95: +#line 891 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_case_command ((yyvsp[-4].word), (yyvsp[-1].pattern), word_lineno[word_top]); + if (word_top > 0) word_top--; + } +#line 2773 "y.tab.c" /* yacc.c:1646 */ + break; + + case 96: +#line 898 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_function_def ((yyvsp[-4].word), (yyvsp[0].command), function_dstart, function_bstart); } +#line 2779 "y.tab.c" /* yacc.c:1646 */ + break; + + case 97: +#line 901 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_function_def ((yyvsp[-4].word), (yyvsp[0].command), function_dstart, function_bstart); } +#line 2785 "y.tab.c" /* yacc.c:1646 */ + break; + + case 98: +#line 904 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_function_def ((yyvsp[-2].word), (yyvsp[0].command), function_dstart, function_bstart); } +#line 2791 "y.tab.c" /* yacc.c:1646 */ + break; + + case 99: +#line 908 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 2797 "y.tab.c" /* yacc.c:1646 */ + break; + + case 100: +#line 910 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + COMMAND *tc; + + tc = (yyvsp[-1].command); + /* According to Posix.2 3.9.5, redirections + specified after the body of a function should + be attached to the function and performed when + the function is executed, not as part of the + function definition command. */ + /* XXX - I don't think it matters, but we might + want to change this in the future to avoid + problems differentiating between a function + definition with a redirection and a function + definition containing a single command with a + redirection. The two are semantically equivalent, + though -- the only difference is in how the + command printing code displays the redirections. */ + if (tc->redirects) + { + register REDIRECT *t; + for (t = tc->redirects; t->next; t = t->next) + ; + t->next = (yyvsp[0].redirect); + } + else + tc->redirects = (yyvsp[0].redirect); + (yyval.command) = (yyvsp[-1].command); + } +#line 2830 "y.tab.c" /* yacc.c:1646 */ + break; + + case 101: +#line 941 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_subshell_command ((yyvsp[-1].command)); + (yyval.command)->flags |= CMD_WANT_SUBSHELL; + } +#line 2839 "y.tab.c" /* yacc.c:1646 */ + break; + + case 102: +#line 948 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_coproc_command ("COPROC", (yyvsp[0].command)); + (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL; + } +#line 2848 "y.tab.c" /* yacc.c:1646 */ + break; + + case 103: +#line 953 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + COMMAND *tc; + + tc = (yyvsp[-1].command); + if (tc->redirects) + { + register REDIRECT *t; + for (t = tc->redirects; t->next; t = t->next) + ; + t->next = (yyvsp[0].redirect); + } + else + tc->redirects = (yyvsp[0].redirect); + (yyval.command) = make_coproc_command ("COPROC", (yyvsp[-1].command)); + (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL; + } +#line 2869 "y.tab.c" /* yacc.c:1646 */ + break; + + case 104: +#line 970 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_coproc_command ((yyvsp[-1].word)->word, (yyvsp[0].command)); + (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL; + } +#line 2878 "y.tab.c" /* yacc.c:1646 */ + break; + + case 105: +#line 975 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + COMMAND *tc; + + tc = (yyvsp[-1].command); + if (tc->redirects) + { + register REDIRECT *t; + for (t = tc->redirects; t->next; t = t->next) + ; + t->next = (yyvsp[0].redirect); + } + else + tc->redirects = (yyvsp[0].redirect); + (yyval.command) = make_coproc_command ((yyvsp[-2].word)->word, (yyvsp[-1].command)); + (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL; + } +#line 2899 "y.tab.c" /* yacc.c:1646 */ + break; + + case 106: +#line 992 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = make_coproc_command ("COPROC", clean_simple_command ((yyvsp[0].command))); + (yyval.command)->flags |= CMD_WANT_SUBSHELL|CMD_COPROC_SUBSHELL; + } +#line 2908 "y.tab.c" /* yacc.c:1646 */ + break; + + case 107: +#line 999 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_if_command ((yyvsp[-3].command), (yyvsp[-1].command), (COMMAND *)NULL); } +#line 2914 "y.tab.c" /* yacc.c:1646 */ + break; + + case 108: +#line 1001 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_if_command ((yyvsp[-5].command), (yyvsp[-3].command), (yyvsp[-1].command)); } +#line 2920 "y.tab.c" /* yacc.c:1646 */ + break; + + case 109: +#line 1003 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_if_command ((yyvsp[-4].command), (yyvsp[-2].command), (yyvsp[-1].command)); } +#line 2926 "y.tab.c" /* yacc.c:1646 */ + break; + + case 110: +#line 1008 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_group_command ((yyvsp[-1].command)); } +#line 2932 "y.tab.c" /* yacc.c:1646 */ + break; + + case 111: +#line 1012 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_arith_command ((yyvsp[0].word_list)); } +#line 2938 "y.tab.c" /* yacc.c:1646 */ + break; + + case 112: +#line 1016 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[-1].command); } +#line 2944 "y.tab.c" /* yacc.c:1646 */ + break; + + case 113: +#line 1020 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_if_command ((yyvsp[-2].command), (yyvsp[0].command), (COMMAND *)NULL); } +#line 2950 "y.tab.c" /* yacc.c:1646 */ + break; + + case 114: +#line 1022 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_if_command ((yyvsp[-4].command), (yyvsp[-2].command), (yyvsp[0].command)); } +#line 2956 "y.tab.c" /* yacc.c:1646 */ + break; + + case 115: +#line 1024 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = make_if_command ((yyvsp[-3].command), (yyvsp[-1].command), (yyvsp[0].command)); } +#line 2962 "y.tab.c" /* yacc.c:1646 */ + break; + + case 117: +#line 1029 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyvsp[0].pattern)->next = (yyvsp[-1].pattern); (yyval.pattern) = (yyvsp[0].pattern); } +#line 2968 "y.tab.c" /* yacc.c:1646 */ + break; + + case 118: +#line 1033 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.pattern) = make_pattern_list ((yyvsp[-2].word_list), (yyvsp[0].command)); } +#line 2974 "y.tab.c" /* yacc.c:1646 */ + break; + + case 119: +#line 1035 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.pattern) = make_pattern_list ((yyvsp[-2].word_list), (COMMAND *)NULL); } +#line 2980 "y.tab.c" /* yacc.c:1646 */ + break; + + case 120: +#line 1037 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.pattern) = make_pattern_list ((yyvsp[-2].word_list), (yyvsp[0].command)); } +#line 2986 "y.tab.c" /* yacc.c:1646 */ + break; + + case 121: +#line 1039 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.pattern) = make_pattern_list ((yyvsp[-2].word_list), (COMMAND *)NULL); } +#line 2992 "y.tab.c" /* yacc.c:1646 */ + break; + + case 122: +#line 1043 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.pattern) = (yyvsp[-1].pattern); } +#line 2998 "y.tab.c" /* yacc.c:1646 */ + break; + + case 123: +#line 1045 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyvsp[-1].pattern)->next = (yyvsp[-2].pattern); (yyval.pattern) = (yyvsp[-1].pattern); } +#line 3004 "y.tab.c" /* yacc.c:1646 */ + break; + + case 124: +#line 1047 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyvsp[-1].pattern)->flags |= CASEPAT_FALLTHROUGH; (yyval.pattern) = (yyvsp[-1].pattern); } +#line 3010 "y.tab.c" /* yacc.c:1646 */ + break; + + case 125: +#line 1049 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyvsp[-1].pattern)->flags |= CASEPAT_FALLTHROUGH; (yyvsp[-1].pattern)->next = (yyvsp[-2].pattern); (yyval.pattern) = (yyvsp[-1].pattern); } +#line 3016 "y.tab.c" /* yacc.c:1646 */ + break; + + case 126: +#line 1051 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyvsp[-1].pattern)->flags |= CASEPAT_TESTNEXT; (yyval.pattern) = (yyvsp[-1].pattern); } +#line 3022 "y.tab.c" /* yacc.c:1646 */ + break; + + case 127: +#line 1053 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyvsp[-1].pattern)->flags |= CASEPAT_TESTNEXT; (yyvsp[-1].pattern)->next = (yyvsp[-2].pattern); (yyval.pattern) = (yyvsp[-1].pattern); } +#line 3028 "y.tab.c" /* yacc.c:1646 */ + break; + + case 128: +#line 1057 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.word_list) = make_word_list ((yyvsp[0].word), (WORD_LIST *)NULL); } +#line 3034 "y.tab.c" /* yacc.c:1646 */ + break; + + case 129: +#line 1059 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.word_list) = make_word_list ((yyvsp[0].word), (yyvsp[-2].word_list)); } +#line 3040 "y.tab.c" /* yacc.c:1646 */ + break; + + case 130: +#line 1068 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = (yyvsp[0].command); + if (need_here_doc) + gather_here_documents (); + } +#line 3050 "y.tab.c" /* yacc.c:1646 */ + break; + + case 132: +#line 1077 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = (yyvsp[0].command); + } +#line 3058 "y.tab.c" /* yacc.c:1646 */ + break; + + case 134: +#line 1084 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + if ((yyvsp[-2].command)->type == cm_connection) + (yyval.command) = connect_async_list ((yyvsp[-2].command), (COMMAND *)NULL, '&'); + else + (yyval.command) = command_connect ((yyvsp[-2].command), (COMMAND *)NULL, '&'); + } +#line 3069 "y.tab.c" /* yacc.c:1646 */ + break; + + case 136: +#line 1095 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), AND_AND); } +#line 3075 "y.tab.c" /* yacc.c:1646 */ + break; + + case 137: +#line 1097 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), OR_OR); } +#line 3081 "y.tab.c" /* yacc.c:1646 */ + break; + + case 138: +#line 1099 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + if ((yyvsp[-3].command)->type == cm_connection) + (yyval.command) = connect_async_list ((yyvsp[-3].command), (yyvsp[0].command), '&'); + else + (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), '&'); + } +#line 3092 "y.tab.c" /* yacc.c:1646 */ + break; + + case 139: +#line 1106 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), ';'); } +#line 3098 "y.tab.c" /* yacc.c:1646 */ + break; + + case 140: +#line 1108 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), ';'); } +#line 3104 "y.tab.c" /* yacc.c:1646 */ + break; + + case 141: +#line 1110 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 3110 "y.tab.c" /* yacc.c:1646 */ + break; + + case 144: +#line 1118 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.number) = '\n'; } +#line 3116 "y.tab.c" /* yacc.c:1646 */ + break; + + case 145: +#line 1120 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.number) = ';'; } +#line 3122 "y.tab.c" /* yacc.c:1646 */ + break; + + case 146: +#line 1122 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.number) = yacc_EOF; } +#line 3128 "y.tab.c" /* yacc.c:1646 */ + break; + + case 149: +#line 1136 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = (yyvsp[0].command); + if (need_here_doc) + gather_here_documents (); + if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token) + { + global_command = (yyvsp[0].command); + eof_encountered = 0; + rewind_input_string (); + YYACCEPT; + } + } +#line 3145 "y.tab.c" /* yacc.c:1646 */ + break; + + case 150: +#line 1149 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + if ((yyvsp[-1].command)->type == cm_connection) + (yyval.command) = connect_async_list ((yyvsp[-1].command), (COMMAND *)NULL, '&'); + else + (yyval.command) = command_connect ((yyvsp[-1].command), (COMMAND *)NULL, '&'); + if (need_here_doc) + gather_here_documents (); + if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token) + { + global_command = (yyvsp[-1].command); + eof_encountered = 0; + rewind_input_string (); + YYACCEPT; + } + } +#line 3165 "y.tab.c" /* yacc.c:1646 */ + break; + + case 151: +#line 1165 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + (yyval.command) = (yyvsp[-1].command); + if (need_here_doc) + gather_here_documents (); + if ((parser_state & PST_CMDSUBST) && current_token == shell_eof_token) + { + global_command = (yyvsp[-1].command); + eof_encountered = 0; + rewind_input_string (); + YYACCEPT; + } + } +#line 3182 "y.tab.c" /* yacc.c:1646 */ + break; + + case 152: +#line 1180 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), AND_AND); } +#line 3188 "y.tab.c" /* yacc.c:1646 */ + break; + + case 153: +#line 1182 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), OR_OR); } +#line 3194 "y.tab.c" /* yacc.c:1646 */ + break; + + case 154: +#line 1184 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + if ((yyvsp[-2].command)->type == cm_connection) + (yyval.command) = connect_async_list ((yyvsp[-2].command), (yyvsp[0].command), '&'); + else + (yyval.command) = command_connect ((yyvsp[-2].command), (yyvsp[0].command), '&'); + } +#line 3205 "y.tab.c" /* yacc.c:1646 */ + break; + + case 155: +#line 1191 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = command_connect ((yyvsp[-2].command), (yyvsp[0].command), ';'); } +#line 3211 "y.tab.c" /* yacc.c:1646 */ + break; + + case 156: +#line 1194 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 3217 "y.tab.c" /* yacc.c:1646 */ + break; + + case 157: +#line 1198 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 3223 "y.tab.c" /* yacc.c:1646 */ + break; + + case 158: +#line 1200 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].command)) + (yyvsp[0].command)->flags ^= CMD_INVERT_RETURN; /* toggle */ + (yyval.command) = (yyvsp[0].command); + } +#line 3233 "y.tab.c" /* yacc.c:1646 */ + break; + + case 159: +#line 1206 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].command)) + (yyvsp[0].command)->flags |= (yyvsp[-1].number); + (yyval.command) = (yyvsp[0].command); + } +#line 3243 "y.tab.c" /* yacc.c:1646 */ + break; + + case 160: +#line 1212 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + ELEMENT x; + + /* Boy, this is unclean. `time' by itself can + time a null command. We cheat and push a + newline back if the list_terminator was a newline + to avoid the double-newline problem (one to + terminate this, one to terminate the command) */ + x.word = 0; + x.redirect = 0; + (yyval.command) = make_simple_command (x, (COMMAND *)NULL); + (yyval.command)->flags |= (yyvsp[-1].number); + /* XXX - let's cheat and push a newline back */ + if ((yyvsp[0].number) == '\n') + token_to_read = '\n'; + else if ((yyvsp[0].number) == ';') + token_to_read = ';'; + } +#line 3266 "y.tab.c" /* yacc.c:1646 */ + break; + + case 161: +#line 1231 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + ELEMENT x; + + /* This is just as unclean. Posix says that `!' + by itself should be equivalent to `false'. + We cheat and push a + newline back if the list_terminator was a newline + to avoid the double-newline problem (one to + terminate this, one to terminate the command) */ + x.word = 0; + x.redirect = 0; + (yyval.command) = make_simple_command (x, (COMMAND *)NULL); + (yyval.command)->flags |= CMD_INVERT_RETURN; + /* XXX - let's cheat and push a newline back */ + if ((yyvsp[0].number) == '\n') + token_to_read = '\n'; + if ((yyvsp[0].number) == ';') + token_to_read = ';'; + } +#line 3290 "y.tab.c" /* yacc.c:1646 */ + break; + + case 162: +#line 1253 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), '|'); } +#line 3296 "y.tab.c" /* yacc.c:1646 */ + break; + + case 163: +#line 1255 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { + /* Make cmd1 |& cmd2 equivalent to cmd1 2>&1 | cmd2 */ + COMMAND *tc; + REDIRECTEE rd, sd; + REDIRECT *r; + + tc = (yyvsp[-3].command)->type == cm_simple ? (COMMAND *)(yyvsp[-3].command)->value.Simple : (yyvsp[-3].command); + sd.dest = 2; + rd.dest = 1; + r = make_redirection (sd, r_duplicating_output, rd, 0); + if (tc->redirects) + { + register REDIRECT *t; + for (t = tc->redirects; t->next; t = t->next) + ; + t->next = r; + } + else + tc->redirects = r; + + (yyval.command) = command_connect ((yyvsp[-3].command), (yyvsp[0].command), '|'); + } +#line 3323 "y.tab.c" /* yacc.c:1646 */ + break; + + case 164: +#line 1278 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.command) = (yyvsp[0].command); } +#line 3329 "y.tab.c" /* yacc.c:1646 */ + break; + + case 165: +#line 1282 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.number) = CMD_TIME_PIPELINE; } +#line 3335 "y.tab.c" /* yacc.c:1646 */ + break; + + case 166: +#line 1284 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.number) = CMD_TIME_PIPELINE|CMD_TIME_POSIX; } +#line 3341 "y.tab.c" /* yacc.c:1646 */ + break; + + case 167: +#line 1286 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1646 */ + { (yyval.number) = CMD_TIME_PIPELINE|CMD_TIME_POSIX; } +#line 3347 "y.tab.c" /* yacc.c:1646 */ + break; + + +#line 3351 "y.tab.c" /* yacc.c:1646 */ + default: break; + } + /* User semantic actions sometimes alter yychar, and that requires + that yytoken be updated with the new translation. We take the + approach of translating immediately before every use of yytoken. + One alternative is translating here after every semantic action, + but that translation would be missed if the semantic action invokes + YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or + if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an + incorrect destructor might then be invoked immediately. In the + case of YYERROR or YYBACKUP, subsequent parser actions might lead + to an incorrect destructor call or verbose syntax error message + before the lookahead is translated. */ + YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); + + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + + *++yyvsp = yyval; + + /* Now 'shift' the result of the reduction. Determine what state + that goes to, based on the state we popped back to and the rule + number reduced by. */ + + yyn = yyr1[yyn]; + + yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; + if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) + yystate = yytable[yystate]; + else + yystate = yydefgoto[yyn - YYNTOKENS]; + + goto yynewstate; + + +/*--------------------------------------. +| yyerrlab -- here on detecting error. | +`--------------------------------------*/ +yyerrlab: + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar); + + /* If not already recovering from an error, report this error. */ + if (!yyerrstatus) + { + ++yynerrs; +#if ! YYERROR_VERBOSE + yyerror (YY_("syntax error")); +#else +# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \ + yyssp, yytoken) + { + char const *yymsgp = YY_("syntax error"); + int yysyntax_error_status; + yysyntax_error_status = YYSYNTAX_ERROR; + if (yysyntax_error_status == 0) + yymsgp = yymsg; + else if (yysyntax_error_status == 1) + { + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); + yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc); + if (!yymsg) + { + yymsg = yymsgbuf; + yymsg_alloc = sizeof yymsgbuf; + yysyntax_error_status = 2; + } + else + { + yysyntax_error_status = YYSYNTAX_ERROR; + yymsgp = yymsg; + } + } + yyerror (yymsgp); + if (yysyntax_error_status == 2) + goto yyexhaustedlab; + } +# undef YYSYNTAX_ERROR +#endif + } + + + + if (yyerrstatus == 3) + { + /* If just tried and failed to reuse lookahead token after an + error, discard it. */ + + if (yychar <= YYEOF) + { + /* Return failure if at end of input. */ + if (yychar == YYEOF) + YYABORT; + } + else + { + yydestruct ("Error: discarding", + yytoken, &yylval); + yychar = YYEMPTY; + } + } + + /* Else will try to reuse lookahead token after shifting the error + token. */ + goto yyerrlab1; + + +/*---------------------------------------------------. +| yyerrorlab -- error raised explicitly by YYERROR. | +`---------------------------------------------------*/ +yyerrorlab: + + /* Pacify compilers like GCC when the user code never invokes + YYERROR and the label yyerrorlab therefore never appears in user + code. */ + if (/*CONSTCOND*/ 0) + goto yyerrorlab; + + /* Do not reclaim the symbols of the rule whose action triggered + this YYERROR. */ + YYPOPSTACK (yylen); + yylen = 0; + YY_STACK_PRINT (yyss, yyssp); + yystate = *yyssp; + goto yyerrlab1; + + +/*-------------------------------------------------------------. +| yyerrlab1 -- common code for both syntax error and YYERROR. | +`-------------------------------------------------------------*/ +yyerrlab1: + yyerrstatus = 3; /* Each real token shifted decrements this. */ + + for (;;) + { + yyn = yypact[yystate]; + if (!yypact_value_is_default (yyn)) + { + yyn += YYTERROR; + if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) + { + yyn = yytable[yyn]; + if (0 < yyn) + break; + } + } + + /* Pop the current state because it cannot handle the error token. */ + if (yyssp == yyss) + YYABORT; + + + yydestruct ("Error: popping", + yystos[yystate], yyvsp); + YYPOPSTACK (1); + yystate = *yyssp; + YY_STACK_PRINT (yyss, yyssp); + } + + YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN + *++yyvsp = yylval; + YY_IGNORE_MAYBE_UNINITIALIZED_END + + + /* Shift the error token. */ + YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); + + yystate = yyn; + goto yynewstate; + + +/*-------------------------------------. +| yyacceptlab -- YYACCEPT comes here. | +`-------------------------------------*/ +yyacceptlab: + yyresult = 0; + goto yyreturn; + +/*-----------------------------------. +| yyabortlab -- YYABORT comes here. | +`-----------------------------------*/ +yyabortlab: + yyresult = 1; + goto yyreturn; + +#if !defined yyoverflow || YYERROR_VERBOSE +/*-------------------------------------------------. +| yyexhaustedlab -- memory exhaustion comes here. | +`-------------------------------------------------*/ +yyexhaustedlab: + yyerror (YY_("memory exhausted")); + yyresult = 2; + /* Fall through. */ +#endif + +yyreturn: + if (yychar != YYEMPTY) + { + /* Make sure we have latest lookahead translation. See comments at + user semantic actions for why this is necessary. */ + yytoken = YYTRANSLATE (yychar); + yydestruct ("Cleanup: discarding lookahead", + yytoken, &yylval); + } + /* Do not reclaim the symbols of the rule whose action triggered + this YYABORT or YYACCEPT. */ + YYPOPSTACK (yylen); + YY_STACK_PRINT (yyss, yyssp); + while (yyssp != yyss) + { + yydestruct ("Cleanup: popping", + yystos[*yyssp], yyvsp); + YYPOPSTACK (1); + } +#ifndef yyoverflow + if (yyss != yyssa) + YYSTACK_FREE (yyss); +#endif +#if YYERROR_VERBOSE + if (yymsg != yymsgbuf) + YYSTACK_FREE (yymsg); +#endif + return yyresult; +} +#line 1288 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1906 */ + + +/* Initial size to allocate for tokens, and the + amount to grow them by. */ +#define TOKEN_DEFAULT_INITIAL_SIZE 496 +#define TOKEN_DEFAULT_GROW_SIZE 512 + +/* Should we call prompt_again? */ +#define SHOULD_PROMPT() \ + (interactive && (bash_input.type == st_stdin || bash_input.type == st_stream)) + +#if defined (ALIAS) +# define expanding_alias() (pushed_string_list && pushed_string_list->expander) +#else +# define expanding_alias() 0 +#endif + +/* Global var is non-zero when end of file has been reached. */ +int EOF_Reached = 0; + +#ifdef DEBUG +static void +debug_parser (i) + int i; +{ +#if YYDEBUG != 0 + yydebug = i; +#endif +} +#endif + +/* yy_getc () returns the next available character from input or EOF. + yy_ungetc (c) makes `c' the next character to read. + init_yy_io (get, unget, type, location) makes the function GET the + installed function for getting the next character, makes UNGET the + installed function for un-getting a character, sets the type of stream + (either string or file) from TYPE, and makes LOCATION point to where + the input is coming from. */ + +/* Unconditionally returns end-of-file. */ +int +return_EOF () +{ + return (EOF); +} + +/* Variable containing the current get and unget functions. + See ./input.h for a clearer description. */ +BASH_INPUT bash_input; + +/* Set all of the fields in BASH_INPUT to NULL. Free bash_input.name if it + is non-null, avoiding a memory leak. */ +void +initialize_bash_input () +{ + bash_input.type = st_none; + FREE (bash_input.name); + bash_input.name = (char *)NULL; + bash_input.location.file = (FILE *)NULL; + bash_input.location.string = (char *)NULL; + bash_input.getter = (sh_cget_func_t *)NULL; + bash_input.ungetter = (sh_cunget_func_t *)NULL; +} + +/* Set the contents of the current bash input stream from + GET, UNGET, TYPE, NAME, and LOCATION. */ +void +init_yy_io (get, unget, type, name, location) + sh_cget_func_t *get; + sh_cunget_func_t *unget; + enum stream_type type; + const char *name; + INPUT_STREAM location; +{ + bash_input.type = type; + FREE (bash_input.name); + bash_input.name = name ? savestring (name) : (char *)NULL; + + /* XXX */ +#if defined (CRAY) + memcpy((char *)&bash_input.location.string, (char *)&location.string, sizeof(location)); +#else + bash_input.location = location; +#endif + bash_input.getter = get; + bash_input.ungetter = unget; +} + +char * +yy_input_name () +{ + return (bash_input.name ? bash_input.name : "stdin"); +} + +/* Call this to get the next character of input. */ +static int +yy_getc () +{ + return (*(bash_input.getter)) (); +} + +/* Call this to unget C. That is, to make C the next character + to be read. */ +static int +yy_ungetc (c) + int c; +{ + return (*(bash_input.ungetter)) (c); +} + +#if defined (BUFFERED_INPUT) +#ifdef INCLUDE_UNUSED +int +input_file_descriptor () +{ + switch (bash_input.type) + { + case st_stream: + return (fileno (bash_input.location.file)); + case st_bstream: + return (bash_input.location.buffered_fd); + case st_stdin: + default: + return (fileno (stdin)); + } +} +#endif +#endif /* BUFFERED_INPUT */ + +/* **************************************************************** */ +/* */ +/* Let input be read from readline (). */ +/* */ +/* **************************************************************** */ + +#if defined (READLINE) +char *current_readline_prompt = (char *)NULL; +char *current_readline_line = (char *)NULL; +int current_readline_line_index = 0; + +static int +yy_readline_get () +{ + SigHandler *old_sigint; + int line_len; + unsigned char c; + + if (current_readline_line == 0) + { + if (bash_readline_initialized == 0) + initialize_readline (); + +#if defined (JOB_CONTROL) + if (job_control) + give_terminal_to (shell_pgrp, 0); +#endif /* JOB_CONTROL */ + + old_sigint = IMPOSSIBLE_TRAP_HANDLER; + if (signal_is_ignored (SIGINT) == 0) + { + /* interrupt_immediately++; */ + old_sigint = (SigHandler *)set_signal_handler (SIGINT, sigint_sighandler); + } + + current_readline_line = readline (current_readline_prompt ? + current_readline_prompt : ""); + + CHECK_TERMSIG; + if (signal_is_ignored (SIGINT) == 0) + { + /* interrupt_immediately--; */ + if (old_sigint != IMPOSSIBLE_TRAP_HANDLER) + set_signal_handler (SIGINT, old_sigint); + } + +#if 0 + /* Reset the prompt to the decoded value of prompt_string_pointer. */ + reset_readline_prompt (); +#endif + + if (current_readline_line == 0) + return (EOF); + + current_readline_line_index = 0; + line_len = strlen (current_readline_line); + + current_readline_line = (char *)xrealloc (current_readline_line, 2 + line_len); + current_readline_line[line_len++] = '\n'; + current_readline_line[line_len] = '\0'; + } + + if (current_readline_line[current_readline_line_index] == 0) + { + free (current_readline_line); + current_readline_line = (char *)NULL; + return (yy_readline_get ()); + } + else + { + c = current_readline_line[current_readline_line_index++]; + return (c); + } +} + +static int +yy_readline_unget (c) + int c; +{ + if (current_readline_line_index && current_readline_line) + current_readline_line[--current_readline_line_index] = c; + return (c); +} + +void +with_input_from_stdin () +{ + INPUT_STREAM location; + + if (bash_input.type != st_stdin && stream_on_stack (st_stdin) == 0) + { + location.string = current_readline_line; + init_yy_io (yy_readline_get, yy_readline_unget, + st_stdin, "readline stdin", location); + } +} + +#else /* !READLINE */ + +void +with_input_from_stdin () +{ + with_input_from_stream (stdin, "stdin"); +} +#endif /* !READLINE */ + +/* **************************************************************** */ +/* */ +/* Let input come from STRING. STRING is zero terminated. */ +/* */ +/* **************************************************************** */ + +static int +yy_string_get () +{ + register char *string; + register unsigned char c; + + string = bash_input.location.string; + + /* If the string doesn't exist, or is empty, EOF found. */ + if (string && *string) + { + c = *string++; + bash_input.location.string = string; + return (c); + } + else + return (EOF); +} + +static int +yy_string_unget (c) + int c; +{ + *(--bash_input.location.string) = c; + return (c); +} + +void +with_input_from_string (string, name) + char *string; + const char *name; +{ + INPUT_STREAM location; + + location.string = string; + init_yy_io (yy_string_get, yy_string_unget, st_string, name, location); +} + +/* Count the number of characters we've consumed from bash_input.location.string + and read into shell_input_line, but have not returned from shell_getc. + That is the true input location. Rewind bash_input.location.string by + that number of characters, so it points to the last character actually + consumed by the parser. */ +static void +rewind_input_string () +{ + int xchars; + + /* number of unconsumed characters in the input -- XXX need to take newlines + into account, e.g., $(...\n) */ + xchars = shell_input_line_len - shell_input_line_index; + if (bash_input.location.string[-1] == '\n') + xchars++; + + /* XXX - how to reflect bash_input.location.string back to string passed to + parse_and_execute or xparse_dolparen? xparse_dolparen needs to know how + far into the string we parsed. parse_and_execute knows where bash_input. + location.string is, and how far from orig_string that is -- that's the + number of characters the command consumed. */ + + /* bash_input.location.string - xchars should be where we parsed to */ + /* need to do more validation on xchars value for sanity -- test cases. */ + bash_input.location.string -= xchars; +} + +/* **************************************************************** */ +/* */ +/* Let input come from STREAM. */ +/* */ +/* **************************************************************** */ + +/* These two functions used to test the value of the HAVE_RESTARTABLE_SYSCALLS + define, and just use getc/ungetc if it was defined, but since bash + installs its signal handlers without the SA_RESTART flag, some signals + (like SIGCHLD, SIGWINCH, etc.) received during a read(2) will not cause + the read to be restarted. We need to restart it ourselves. */ + +static int +yy_stream_get () +{ + int result; + + result = EOF; + if (bash_input.location.file) + { +#if 0 + if (interactive) + interrupt_immediately++; +#endif + + /* XXX - don't need terminate_immediately; getc_with_restart checks + for terminating signals itself if read returns < 0 */ + result = getc_with_restart (bash_input.location.file); + +#if 0 + if (interactive) + interrupt_immediately--; +#endif + } + return (result); +} + +static int +yy_stream_unget (c) + int c; +{ + return (ungetc_with_restart (c, bash_input.location.file)); +} + +void +with_input_from_stream (stream, name) + FILE *stream; + const char *name; +{ + INPUT_STREAM location; + + location.file = stream; + init_yy_io (yy_stream_get, yy_stream_unget, st_stream, name, location); +} + +typedef struct stream_saver { + struct stream_saver *next; + BASH_INPUT bash_input; + int line; +#if defined (BUFFERED_INPUT) + BUFFERED_STREAM *bstream; +#endif /* BUFFERED_INPUT */ +} STREAM_SAVER; + +/* The globally known line number. */ +int line_number = 0; + +/* The line number offset set by assigning to LINENO. Not currently used. */ +int line_number_base = 0; + +#if defined (COND_COMMAND) +static int cond_lineno; +static int cond_token; +#endif + +STREAM_SAVER *stream_list = (STREAM_SAVER *)NULL; + +void +push_stream (reset_lineno) + int reset_lineno; +{ + STREAM_SAVER *saver = (STREAM_SAVER *)xmalloc (sizeof (STREAM_SAVER)); + + xbcopy ((char *)&bash_input, (char *)&(saver->bash_input), sizeof (BASH_INPUT)); + +#if defined (BUFFERED_INPUT) + saver->bstream = (BUFFERED_STREAM *)NULL; + /* If we have a buffered stream, clear out buffers[fd]. */ + if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0) + saver->bstream = set_buffered_stream (bash_input.location.buffered_fd, + (BUFFERED_STREAM *)NULL); +#endif /* BUFFERED_INPUT */ + + saver->line = line_number; + bash_input.name = (char *)NULL; + saver->next = stream_list; + stream_list = saver; + EOF_Reached = 0; + if (reset_lineno) + line_number = 0; +} + +void +pop_stream () +{ + if (!stream_list) + EOF_Reached = 1; + else + { + STREAM_SAVER *saver = stream_list; + + EOF_Reached = 0; + stream_list = stream_list->next; + + init_yy_io (saver->bash_input.getter, + saver->bash_input.ungetter, + saver->bash_input.type, + saver->bash_input.name, + saver->bash_input.location); + +#if defined (BUFFERED_INPUT) + /* If we have a buffered stream, restore buffers[fd]. */ + /* If the input file descriptor was changed while this was on the + save stack, update the buffered fd to the new file descriptor and + re-establish the buffer <-> bash_input fd correspondence. */ + if (bash_input.type == st_bstream && bash_input.location.buffered_fd >= 0) + { + if (bash_input_fd_changed) + { + bash_input_fd_changed = 0; + if (default_buffered_input >= 0) + { + bash_input.location.buffered_fd = default_buffered_input; + saver->bstream->b_fd = default_buffered_input; + SET_CLOSE_ON_EXEC (default_buffered_input); + } + } + /* XXX could free buffered stream returned as result here. */ + set_buffered_stream (bash_input.location.buffered_fd, saver->bstream); + } +#endif /* BUFFERED_INPUT */ + + line_number = saver->line; + + FREE (saver->bash_input.name); + free (saver); + } +} + +/* Return 1 if a stream of type TYPE is saved on the stack. */ +int +stream_on_stack (type) + enum stream_type type; +{ + register STREAM_SAVER *s; + + for (s = stream_list; s; s = s->next) + if (s->bash_input.type == type) + return 1; + return 0; +} + +/* Save the current token state and return it in a malloced array. */ +int * +save_token_state () +{ + int *ret; + + ret = (int *)xmalloc (4 * sizeof (int)); + ret[0] = last_read_token; + ret[1] = token_before_that; + ret[2] = two_tokens_ago; + ret[3] = current_token; + return ret; +} + +void +restore_token_state (ts) + int *ts; +{ + if (ts == 0) + return; + last_read_token = ts[0]; + token_before_that = ts[1]; + two_tokens_ago = ts[2]; + current_token = ts[3]; +} + +/* + * This is used to inhibit alias expansion and reserved word recognition + * inside case statement pattern lists. A `case statement pattern list' is: + * + * everything between the `in' in a `case word in' and the next ')' + * or `esac' + * everything between a `;;' and the next `)' or `esac' + */ + +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + +#define END_OF_ALIAS 0 + +/* + * Pseudo-global variables used in implementing token-wise alias expansion. + */ + +/* + * Pushing and popping strings. This works together with shell_getc to + * implement alias expansion on a per-token basis. + */ + +#define PSH_ALIAS 0x01 +#define PSH_DPAREN 0x02 +#define PSH_SOURCE 0x04 + +typedef struct string_saver { + struct string_saver *next; + int expand_alias; /* Value to set expand_alias to when string is popped. */ + char *saved_line; +#if defined (ALIAS) + alias_t *expander; /* alias that caused this line to be pushed. */ +#endif + size_t saved_line_size, saved_line_index; + int saved_line_terminator; + int flags; +} STRING_SAVER; + +STRING_SAVER *pushed_string_list = (STRING_SAVER *)NULL; + +/* + * Push the current shell_input_line onto a stack of such lines and make S + * the current input. Used when expanding aliases. EXPAND is used to set + * the value of expand_next_token when the string is popped, so that the + * word after the alias in the original line is handled correctly when the + * alias expands to multiple words. TOKEN is the token that was expanded + * into S; it is saved and used to prevent infinite recursive expansion. + */ +static void +push_string (s, expand, ap) + char *s; + int expand; + alias_t *ap; +{ + STRING_SAVER *temp = (STRING_SAVER *)xmalloc (sizeof (STRING_SAVER)); + + temp->expand_alias = expand; + temp->saved_line = shell_input_line; + temp->saved_line_size = shell_input_line_size; + temp->saved_line_index = shell_input_line_index; + temp->saved_line_terminator = shell_input_line_terminator; + temp->flags = 0; +#if defined (ALIAS) + temp->expander = ap; + if (ap) + temp->flags = PSH_ALIAS; +#endif + temp->next = pushed_string_list; + pushed_string_list = temp; + +#if defined (ALIAS) + if (ap) + ap->flags |= AL_BEINGEXPANDED; +#endif + + shell_input_line = s; + shell_input_line_size = STRLEN (s); + shell_input_line_index = 0; + shell_input_line_terminator = '\0'; +#if 0 + parser_state &= ~PST_ALEXPNEXT; /* XXX */ +#endif + + set_line_mbstate (); +} + +/* + * Make the top of the pushed_string stack be the current shell input. + * Only called when there is something on the stack. Called from shell_getc + * when it thinks it has consumed the string generated by an alias expansion + * and needs to return to the original input line. + */ +static void +pop_string () +{ + STRING_SAVER *t; + + FREE (shell_input_line); + shell_input_line = pushed_string_list->saved_line; + shell_input_line_index = pushed_string_list->saved_line_index; + shell_input_line_size = pushed_string_list->saved_line_size; + shell_input_line_terminator = pushed_string_list->saved_line_terminator; + + if (pushed_string_list->expand_alias) + parser_state |= PST_ALEXPNEXT; + else + parser_state &= ~PST_ALEXPNEXT; + + t = pushed_string_list; + pushed_string_list = pushed_string_list->next; + +#if defined (ALIAS) + if (t->expander) + t->expander->flags &= ~AL_BEINGEXPANDED; +#endif + + free ((char *)t); + + set_line_mbstate (); +} + +static void +free_string_list () +{ + register STRING_SAVER *t, *t1; + + for (t = pushed_string_list; t; ) + { + t1 = t->next; + FREE (t->saved_line); +#if defined (ALIAS) + if (t->expander) + t->expander->flags &= ~AL_BEINGEXPANDED; +#endif + free ((char *)t); + t = t1; + } + pushed_string_list = (STRING_SAVER *)NULL; +} + +#endif /* ALIAS || DPAREN_ARITHMETIC */ + +void +free_pushed_string_input () +{ +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + free_string_list (); +#endif +} + +int +parser_expanding_alias () +{ + return (expanding_alias ()); +} + +void +parser_save_alias () +{ +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + push_string ((char *)NULL, 0, (alias_t *)NULL); + pushed_string_list->flags = PSH_SOURCE; /* XXX - for now */ +#else + ; +#endif +} + +void +parser_restore_alias () +{ +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + if (pushed_string_list) + pop_string (); +#else + ; +#endif +} + +/* Return a line of text, taken from wherever yylex () reads input. + If there is no more input, then we return NULL. If REMOVE_QUOTED_NEWLINE + is non-zero, we remove unquoted \ pairs. This is used by + read_secondary_line to read here documents. */ +static char * +read_a_line (remove_quoted_newline) + int remove_quoted_newline; +{ + static char *line_buffer = (char *)NULL; + static int buffer_size = 0; + int indx, c, peekc, pass_next; + +#if defined (READLINE) + if (no_line_editing && SHOULD_PROMPT ()) +#else + if (SHOULD_PROMPT ()) +#endif + print_prompt (); + + pass_next = indx = 0; + while (1) + { + /* Allow immediate exit if interrupted during input. */ + QUIT; + + c = yy_getc (); + + /* Ignore null bytes in input. */ + if (c == 0) + { +#if 0 + internal_warning ("read_a_line: ignored null byte in input"); +#endif + continue; + } + + /* If there is no more input, then we return NULL. */ + if (c == EOF) + { + if (interactive && bash_input.type == st_stream) + clearerr (stdin); + if (indx == 0) + return ((char *)NULL); + c = '\n'; + } + + /* `+2' in case the final character in the buffer is a newline. */ + RESIZE_MALLOCED_BUFFER (line_buffer, indx, 2, buffer_size, 128); + + /* IF REMOVE_QUOTED_NEWLINES is non-zero, we are reading a + here document with an unquoted delimiter. In this case, + the line will be expanded as if it were in double quotes. + We allow a backslash to escape the next character, but we + need to treat the backslash specially only if a backslash + quoting a backslash-newline pair appears in the line. */ + if (pass_next) + { + line_buffer[indx++] = c; + pass_next = 0; + } + else if (c == '\\' && remove_quoted_newline) + { + QUIT; + peekc = yy_getc (); + if (peekc == '\n') + { + line_number++; + continue; /* Make the unquoted \ pair disappear. */ + } + else + { + yy_ungetc (peekc); + pass_next = 1; + line_buffer[indx++] = c; /* Preserve the backslash. */ + } + } + else + line_buffer[indx++] = c; + + if (c == '\n') + { + line_buffer[indx] = '\0'; + return (line_buffer); + } + } +} + +/* Return a line as in read_a_line (), but insure that the prompt is + the secondary prompt. This is used to read the lines of a here + document. REMOVE_QUOTED_NEWLINE is non-zero if we should remove + newlines quoted with backslashes while reading the line. It is + non-zero unless the delimiter of the here document was quoted. */ +char * +read_secondary_line (remove_quoted_newline) + int remove_quoted_newline; +{ + char *ret; + int n, c; + + prompt_string_pointer = &ps2_prompt; + if (SHOULD_PROMPT()) + prompt_again (); + ret = read_a_line (remove_quoted_newline); +#if defined (HISTORY) + if (ret && remember_on_history && (parser_state & PST_HEREDOC)) + { + /* To make adding the here-document body right, we need to rely on + history_delimiting_chars() returning \n for the first line of the + here-document body and the null string for the second and subsequent + lines, so we avoid double newlines. + current_command_line_count == 2 for the first line of the body. */ + + current_command_line_count++; + maybe_add_history (ret); + } +#endif /* HISTORY */ + return ret; +} + +/* **************************************************************** */ +/* */ +/* YYLEX () */ +/* */ +/* **************************************************************** */ + +/* Reserved words. These are only recognized as the first word of a + command. */ +STRING_INT_ALIST word_token_alist[] = { + { "if", IF }, + { "then", THEN }, + { "else", ELSE }, + { "elif", ELIF }, + { "fi", FI }, + { "case", CASE }, + { "esac", ESAC }, + { "for", FOR }, +#if defined (SELECT_COMMAND) + { "select", SELECT }, +#endif + { "while", WHILE }, + { "until", UNTIL }, + { "do", DO }, + { "done", DONE }, + { "in", IN }, + { "function", FUNCTION }, +#if defined (COMMAND_TIMING) + { "time", TIME }, +#endif + { "{", '{' }, + { "}", '}' }, + { "!", BANG }, +#if defined (COND_COMMAND) + { "[[", COND_START }, + { "]]", COND_END }, +#endif +#if defined (COPROCESS_SUPPORT) + { "coproc", COPROC }, +#endif + { (char *)NULL, 0} +}; + +/* other tokens that can be returned by read_token() */ +STRING_INT_ALIST other_token_alist[] = { + /* Multiple-character tokens with special values */ + { "--", TIMEIGN }, + { "-p", TIMEOPT }, + { "&&", AND_AND }, + { "||", OR_OR }, + { ">>", GREATER_GREATER }, + { "<<", LESS_LESS }, + { "<&", LESS_AND }, + { ">&", GREATER_AND }, + { ";;", SEMI_SEMI }, + { ";&", SEMI_AND }, + { ";;&", SEMI_SEMI_AND }, + { "<<-", LESS_LESS_MINUS }, + { "<<<", LESS_LESS_LESS }, + { "&>", AND_GREATER }, + { "&>>", AND_GREATER_GREATER }, + { "<>", LESS_GREATER }, + { ">|", GREATER_BAR }, + { "|&", BAR_AND }, + { "EOF", yacc_EOF }, + /* Tokens whose value is the character itself */ + { ">", '>' }, + { "<", '<' }, + { "-", '-' }, + { "{", '{' }, + { "}", '}' }, + { ";", ';' }, + { "(", '(' }, + { ")", ')' }, + { "|", '|' }, + { "&", '&' }, + { "newline", '\n' }, + { (char *)NULL, 0} +}; + +/* others not listed here: + WORD look at yylval.word + ASSIGNMENT_WORD look at yylval.word + NUMBER look at yylval.number + ARITH_CMD look at yylval.word_list + ARITH_FOR_EXPRS look at yylval.word_list + COND_CMD look at yylval.command +*/ + +/* These are used by read_token_word, but appear up here so that shell_getc + can use them to decide when to add otherwise blank lines to the history. */ + +/* The primary delimiter stack. */ +struct dstack dstack = { (char *)NULL, 0, 0 }; + +/* A temporary delimiter stack to be used when decoding prompt strings. + This is needed because command substitutions in prompt strings (e.g., PS2) + can screw up the parser's quoting state. */ +static struct dstack temp_dstack = { (char *)NULL, 0, 0 }; + +/* Macro for accessing the top delimiter on the stack. Returns the + delimiter or zero if none. */ +#define current_delimiter(ds) \ + (ds.delimiter_depth ? ds.delimiters[ds.delimiter_depth - 1] : 0) + +#define push_delimiter(ds, character) \ + do \ + { \ + if (ds.delimiter_depth + 2 > ds.delimiter_space) \ + ds.delimiters = (char *)xrealloc \ + (ds.delimiters, (ds.delimiter_space += 10) * sizeof (char)); \ + ds.delimiters[ds.delimiter_depth] = character; \ + ds.delimiter_depth++; \ + } \ + while (0) + +#define pop_delimiter(ds) ds.delimiter_depth-- + +/* Return the next shell input character. This always reads characters + from shell_input_line; when that line is exhausted, it is time to + read the next line. This is called by read_token when the shell is + processing normal command input. */ + +/* This implements one-character lookahead/lookbehind across physical input + lines, to avoid something being lost because it's pushed back with + shell_ungetc when we're at the start of a line. */ +static int eol_ungetc_lookahead = 0; + +static int +shell_getc (remove_quoted_newline) + int remove_quoted_newline; +{ + register int i; + int c, truncating, last_was_backslash; + unsigned char uc; + + QUIT; + + last_was_backslash = 0; + if (sigwinch_received) + { + sigwinch_received = 0; + get_new_window_size (0, (int *)0, (int *)0); + } + + if (eol_ungetc_lookahead) + { + c = eol_ungetc_lookahead; + eol_ungetc_lookahead = 0; + return (c); + } + +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + /* If shell_input_line[shell_input_line_index] == 0, but there is + something on the pushed list of strings, then we don't want to go + off and get another line. We let the code down below handle it. */ + + if (!shell_input_line || ((!shell_input_line[shell_input_line_index]) && + (pushed_string_list == (STRING_SAVER *)NULL))) +#else /* !ALIAS && !DPAREN_ARITHMETIC */ + if (!shell_input_line || !shell_input_line[shell_input_line_index]) +#endif /* !ALIAS && !DPAREN_ARITHMETIC */ + { + line_number++; + + /* Let's not let one really really long line blow up memory allocation */ + if (shell_input_line && shell_input_line_size >= 32768) + { + free (shell_input_line); + shell_input_line = 0; + shell_input_line_size = 0; + } + + restart_read: + + /* Allow immediate exit if interrupted during input. */ + QUIT; + + i = truncating = 0; + shell_input_line_terminator = 0; + + /* If the shell is interatctive, but not currently printing a prompt + (interactive_shell && interactive == 0), we don't want to print + notifies or cleanup the jobs -- we want to defer it until we do + print the next prompt. */ + if (interactive_shell == 0 || SHOULD_PROMPT()) + { +#if defined (JOB_CONTROL) + /* This can cause a problem when reading a command as the result + of a trap, when the trap is called from flush_child. This call + had better not cause jobs to disappear from the job table in + that case, or we will have big trouble. */ + notify_and_cleanup (); +#else /* !JOB_CONTROL */ + cleanup_dead_jobs (); +#endif /* !JOB_CONTROL */ + } + +#if defined (READLINE) + if (no_line_editing && SHOULD_PROMPT()) +#else + if (SHOULD_PROMPT()) +#endif + print_prompt (); + + if (bash_input.type == st_stream) + clearerr (stdin); + + while (1) + { + c = yy_getc (); + + /* Allow immediate exit if interrupted during input. */ + QUIT; + + if (c == '\0') + { +#if 0 + internal_warning ("shell_getc: ignored null byte in input"); +#endif + continue; + } + + /* Theoretical overflow */ + /* If we can't put 256 bytes more into the buffer, allocate + everything we can and fill it as full as we can. */ + /* XXX - we ignore rest of line using `truncating' flag */ + if (shell_input_line_size > (SIZE_MAX - 256)) + { + size_t n; + + n = SIZE_MAX - i; /* how much more can we put into the buffer? */ + if (n <= 2) /* we have to save 1 for the newline added below */ + { + if (truncating == 0) + internal_warning("shell_getc: shell_input_line_size (%zu) exceeds SIZE_MAX (%llu): line truncated", shell_input_line_size, SIZE_MAX); + shell_input_line[i] = '\0'; + truncating = 1; + } + if (shell_input_line_size < SIZE_MAX) + { + shell_input_line_size = SIZE_MAX; + shell_input_line = xrealloc (shell_input_line, shell_input_line_size); + } + } + else + RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256); + + if (c == EOF) + { + if (bash_input.type == st_stream) + clearerr (stdin); + + if (i == 0) + shell_input_line_terminator = EOF; + + shell_input_line[i] = '\0'; + break; + } + + if (truncating == 0 || c == '\n') + shell_input_line[i++] = c; + + if (c == '\n') + { + shell_input_line[--i] = '\0'; + current_command_line_count++; + break; + } + + last_was_backslash = last_was_backslash == 0 && c == '\\'; + } + + shell_input_line_index = 0; + shell_input_line_len = i; /* == strlen (shell_input_line) */ + + set_line_mbstate (); + +#if defined (HISTORY) + if (remember_on_history && shell_input_line && shell_input_line[0]) + { + char *expansions; +# if defined (BANG_HISTORY) + int old_hist; + + /* If the current delimiter is a single quote, we should not be + performing history expansion, even if we're on a different + line from the original single quote. */ + old_hist = history_expansion_inhibited; + if (current_delimiter (dstack) == '\'') + history_expansion_inhibited = 1; +# endif + expansions = pre_process_line (shell_input_line, 1, 1); +# if defined (BANG_HISTORY) + history_expansion_inhibited = old_hist; +# endif + if (expansions != shell_input_line) + { + free (shell_input_line); + shell_input_line = expansions; + shell_input_line_len = shell_input_line ? + strlen (shell_input_line) : 0; + if (shell_input_line_len == 0) + current_command_line_count--; + + /* We have to force the xrealloc below because we don't know + the true allocated size of shell_input_line anymore. */ + shell_input_line_size = shell_input_line_len; + + set_line_mbstate (); + } + } + /* Try to do something intelligent with blank lines encountered while + entering multi-line commands. XXX - this is grotesque */ + else if (remember_on_history && shell_input_line && + shell_input_line[0] == '\0' && + current_command_line_count > 1) + { + if (current_delimiter (dstack)) + /* We know shell_input_line[0] == 0 and we're reading some sort of + quoted string. This means we've got a line consisting of only + a newline in a quoted string. We want to make sure this line + gets added to the history. */ + maybe_add_history (shell_input_line); + else + { + char *hdcs; + hdcs = history_delimiting_chars (shell_input_line); + if (hdcs && hdcs[0] == ';') + maybe_add_history (shell_input_line); + } + } + +#endif /* HISTORY */ + + if (shell_input_line) + { + /* Lines that signify the end of the shell's input should not be + echoed. We should not echo lines while parsing command + substitutions with recursive calls into the parsing engine; those + should only be echoed once when we read the word. That is the + reason for the test against shell_eof_token, which is set to a + right paren when parsing the contents of command substitutions. */ + if (echo_input_at_read && (shell_input_line[0] || + shell_input_line_terminator != EOF) && + shell_eof_token == 0) + fprintf (stderr, "%s\n", shell_input_line); + } + else + { + shell_input_line_size = 0; + prompt_string_pointer = ¤t_prompt_string; + if (SHOULD_PROMPT ()) + prompt_again (); + goto restart_read; + } + + /* Add the newline to the end of this string, iff the string does + not already end in an EOF character. */ + if (shell_input_line_terminator != EOF) + { + if (shell_input_line_size < SIZE_MAX-3 && (shell_input_line_len+3 > shell_input_line_size)) + shell_input_line = (char *)xrealloc (shell_input_line, + 1 + (shell_input_line_size += 2)); + + /* Don't add a newline to a string that ends with a backslash if we're + going to be removing quoted newlines, since that will eat the + backslash. Add another backslash instead (will be removed by + word expansion). */ + if (bash_input.type == st_string && expanding_alias() == 0 && last_was_backslash && c == EOF && remove_quoted_newline) + shell_input_line[shell_input_line_len] = '\\'; + else + shell_input_line[shell_input_line_len] = '\n'; + shell_input_line[shell_input_line_len + 1] = '\0'; + + set_line_mbstate (); + } + } + +next_alias_char: + uc = shell_input_line[shell_input_line_index]; + + if (uc) + shell_input_line_index++; + +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + /* If UC is NULL, we have reached the end of the current input string. If + pushed_string_list is non-empty, it's time to pop to the previous string + because we have fully consumed the result of the last alias expansion. + Do it transparently; just return the next character of the string popped + to. */ + /* If pushed_string_list != 0 but pushed_string_list->expander == 0 (not + currently tested) and the flags value is not PSH_SOURCE, we are not + parsing an alias, we have just saved one (push_string, when called by + the parse_dparen code) In this case, just go on as well. The PSH_SOURCE + case is handled below. */ +pop_alias: + if (uc == 0 && pushed_string_list && pushed_string_list->flags != PSH_SOURCE) + { + pop_string (); + uc = shell_input_line[shell_input_line_index]; + if (uc) + shell_input_line_index++; + } +#endif /* ALIAS || DPAREN_ARITHMETIC */ + + if MBTEST(uc == '\\' && remove_quoted_newline && shell_input_line[shell_input_line_index] == '\n') + { + if (SHOULD_PROMPT ()) + prompt_again (); + line_number++; + /* What do we do here if we're expanding an alias whose definition + includes an escaped newline? If that's the last character in the + alias expansion, we just pop the pushed string list (recall that + we inhibit the appending of a space in mk_alexpansion() if newline + is the last character). If it's not the last character, we need + to consume the quoted newline and move to the next character in + the expansion. */ +#if defined (ALIAS) + if (expanding_alias () && shell_input_line[shell_input_line_index+1] == '\0') + { + uc = 0; + goto pop_alias; + } + else if (expanding_alias () && shell_input_line[shell_input_line_index+1] != '\0') + { + shell_input_line_index++; /* skip newline */ + goto next_alias_char; /* and get next character */ + } + else +#endif + goto restart_read; + } + + if (uc == 0 && shell_input_line_terminator == EOF) + return ((shell_input_line_index != 0) ? '\n' : EOF); + +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + /* We already know that we are not parsing an alias expansion because of the + check for expanding_alias() above. This knows how parse_and_execute + handles switching to st_string input while an alias is being expanded, + hence the check for pushed_string_list without pushed_string_list->expander + and the check for PSH_SOURCE as pushed_string_list->flags. + parse_and_execute and parse_string both change the input type to st_string + and place the string to be parsed and executed into location.string, so + we should not stop reading that until the pointer is '\0'. + The check for shell_input_line_terminator may be superfluous. + + This solves the problem of `.' inside a multi-line alias with embedded + newlines executing things out of order. */ + if (uc == 0 && bash_input.type == st_string && *bash_input.location.string && + pushed_string_list && pushed_string_list->flags == PSH_SOURCE && + shell_input_line_terminator == 0) + { + shell_input_line_index = 0; + goto restart_read; + } +#endif + + return (uc); +} + +/* Put C back into the input for the shell. This might need changes for + HANDLE_MULTIBYTE around EOLs. Since we (currently) never push back a + character different than we read, shell_input_line_property doesn't need + to change when manipulating shell_input_line. The define for + last_shell_getc_is_singlebyte should take care of it, though. */ +static void +shell_ungetc (c) + int c; +{ + if (shell_input_line && shell_input_line_index) + shell_input_line[--shell_input_line_index] = c; + else + eol_ungetc_lookahead = c; +} + +char * +parser_remaining_input () +{ + if (shell_input_line == 0) + return 0; + if (shell_input_line_index < 0 || shell_input_line_index >= shell_input_line_len) + return ""; /* XXX */ + return (shell_input_line + shell_input_line_index); +} + +#ifdef INCLUDE_UNUSED +/* Back the input pointer up by one, effectively `ungetting' a character. */ +static void +shell_ungetchar () +{ + if (shell_input_line && shell_input_line_index) + shell_input_line_index--; +} +#endif + +/* Discard input until CHARACTER is seen, then push that character back + onto the input stream. */ +static void +discard_until (character) + int character; +{ + int c; + + while ((c = shell_getc (0)) != EOF && c != character) + ; + + if (c != EOF) + shell_ungetc (c); +} + +void +execute_variable_command (command, vname) + char *command, *vname; +{ + char *last_lastarg; + sh_parser_state_t ps; + + save_parser_state (&ps); + last_lastarg = get_string_value ("_"); + if (last_lastarg) + last_lastarg = savestring (last_lastarg); + + parse_and_execute (savestring (command), vname, SEVAL_NONINT|SEVAL_NOHIST); + + restore_parser_state (&ps); + bind_variable ("_", last_lastarg, 0); + FREE (last_lastarg); + + if (token_to_read == '\n') /* reset_parser was called */ + token_to_read = 0; +} + +void +push_token (x) + int x; +{ + two_tokens_ago = token_before_that; + token_before_that = last_read_token; + last_read_token = current_token; + + current_token = x; +} + +/* Place to remember the token. We try to keep the buffer + at a reasonable size, but it can grow. */ +static char *token = (char *)NULL; + +/* Current size of the token buffer. */ +static int token_buffer_size; + +/* Command to read_token () explaining what we want it to do. */ +#define READ 0 +#define RESET 1 +#define prompt_is_ps1 \ + (!prompt_string_pointer || prompt_string_pointer == &ps1_prompt) + +/* Function for yyparse to call. yylex keeps track of + the last two tokens read, and calls read_token. */ +static int +yylex () +{ + if (interactive && (current_token == 0 || current_token == '\n')) + { + /* Before we print a prompt, we might have to check mailboxes. + We do this only if it is time to do so. Notice that only here + is the mail alarm reset; nothing takes place in check_mail () + except the checking of mail. Please don't change this. */ + if (prompt_is_ps1 && parse_and_execute_level == 0 && time_to_check_mail ()) + { + check_mail (); + reset_mail_timer (); + } + + /* Avoid printing a prompt if we're not going to read anything, e.g. + after resetting the parser with read_token (RESET). */ + if (token_to_read == 0 && SHOULD_PROMPT ()) + prompt_again (); + } + + two_tokens_ago = token_before_that; + token_before_that = last_read_token; + last_read_token = current_token; + current_token = read_token (READ); + + if ((parser_state & PST_EOFTOKEN) && current_token == shell_eof_token) + { + current_token = yacc_EOF; + if (bash_input.type == st_string) + rewind_input_string (); + } + parser_state &= ~PST_EOFTOKEN; + + return (current_token); +} + +/* When non-zero, we have read the required tokens + which allow ESAC to be the next one read. */ +static int esacs_needed_count; + +static void +push_heredoc (r) + REDIRECT *r; +{ + if (need_here_doc >= HEREDOC_MAX) + { + last_command_exit_value = EX_BADUSAGE; + need_here_doc = 0; + report_syntax_error (_("maximum here-document count exceeded")); + reset_parser (); + exit_shell (last_command_exit_value); + } + redir_stack[need_here_doc++] = r; +} + +void +gather_here_documents () +{ + int r; + + r = 0; + while (need_here_doc > 0) + { + parser_state |= PST_HEREDOC; + make_here_document (redir_stack[r++], line_number); + parser_state &= ~PST_HEREDOC; + need_here_doc--; + } +} + +/* When non-zero, an open-brace used to create a group is awaiting a close + brace partner. */ +static int open_brace_count; + +#define command_token_position(token) \ + (((token) == ASSIGNMENT_WORD) || (parser_state&PST_REDIRLIST) || \ + ((token) != SEMI_SEMI && (token) != SEMI_AND && (token) != SEMI_SEMI_AND && reserved_word_acceptable(token))) + +#define assignment_acceptable(token) \ + (command_token_position(token) && ((parser_state & PST_CASEPAT) == 0)) + +/* Check to see if TOKEN is a reserved word and return the token + value if it is. */ +#define CHECK_FOR_RESERVED_WORD(tok) \ + do { \ + if (!dollar_present && !quoted && \ + reserved_word_acceptable (last_read_token)) \ + { \ + int i; \ + for (i = 0; word_token_alist[i].word != (char *)NULL; i++) \ + if (STREQ (tok, word_token_alist[i].word)) \ + { \ + if ((parser_state & PST_CASEPAT) && (word_token_alist[i].token != ESAC)) \ + break; \ + if (word_token_alist[i].token == TIME && time_command_acceptable () == 0) \ + break; \ + if ((parser_state & PST_CASEPAT) && last_read_token == '|' && word_token_alist[i].token == ESAC) \ + break; /* Posix grammar rule 4 */ \ + if (word_token_alist[i].token == ESAC) \ + parser_state &= ~(PST_CASEPAT|PST_CASESTMT); \ + else if (word_token_alist[i].token == CASE) \ + parser_state |= PST_CASESTMT; \ + else if (word_token_alist[i].token == COND_END) \ + parser_state &= ~(PST_CONDCMD|PST_CONDEXPR); \ + else if (word_token_alist[i].token == COND_START) \ + parser_state |= PST_CONDCMD; \ + else if (word_token_alist[i].token == '{') \ + open_brace_count++; \ + else if (word_token_alist[i].token == '}' && open_brace_count) \ + open_brace_count--; \ + return (word_token_alist[i].token); \ + } \ + } \ + } while (0) + +#if defined (ALIAS) + + /* OK, we have a token. Let's try to alias expand it, if (and only if) + it's eligible. + + It is eligible for expansion if EXPAND_ALIASES is set, and + the token is unquoted and the last token read was a command + separator (or expand_next_token is set), and we are currently + processing an alias (pushed_string_list is non-empty) and this + token is not the same as the current or any previously + processed alias. + + Special cases that disqualify: + In a pattern list in a case statement (parser_state & PST_CASEPAT). */ + +static char * +mk_alexpansion (s) + char *s; +{ + int l; + char *r; + + l = strlen (s); + r = xmalloc (l + 2); + strcpy (r, s); + /* If the last character in the alias is a newline, don't add a trailing + space to the expansion. Works with shell_getc above. */ + if (r[l - 1] != ' ' && r[l - 1] != '\n' && shellmeta(r[l - 1]) == 0) + r[l++] = ' '; + r[l] = '\0'; + return r; +} + +static int +alias_expand_token (tokstr) + char *tokstr; +{ + char *expanded; + alias_t *ap; + + if (((parser_state & PST_ALEXPNEXT) || command_token_position (last_read_token)) && + (parser_state & PST_CASEPAT) == 0) + { + ap = find_alias (tokstr); + + /* Currently expanding this token. */ + if (ap && (ap->flags & AL_BEINGEXPANDED)) + return (NO_EXPANSION); + + /* mk_alexpansion puts an extra space on the end of the alias expansion, + so the lookahead by the parser works right. If this gets changed, + make sure the code in shell_getc that deals with reaching the end of + an expanded alias is changed with it. */ + expanded = ap ? mk_alexpansion (ap->value) : (char *)NULL; + + if (expanded) + { + push_string (expanded, ap->flags & AL_EXPANDNEXT, ap); + return (RE_READ_TOKEN); + } + else + /* This is an eligible token that does not have an expansion. */ + return (NO_EXPANSION); + } + return (NO_EXPANSION); +} +#endif /* ALIAS */ + +static int +time_command_acceptable () +{ +#if defined (COMMAND_TIMING) + int i; + + if (posixly_correct && shell_compatibility_level > 41) + { + /* Quick check of the rest of the line to find the next token. If it + begins with a `-', Posix says to not return `time' as the token. + This was interp 267. */ + i = shell_input_line_index; + while (i < shell_input_line_len && (shell_input_line[i] == ' ' || shell_input_line[i] == '\t')) + i++; + if (shell_input_line[i] == '-') + return 0; + } + + switch (last_read_token) + { + case 0: + case ';': + case '\n': + if (token_before_that == '|') + return (0); + /* FALLTHROUGH */ + case AND_AND: + case OR_OR: + case '&': + case WHILE: + case DO: + case UNTIL: + case IF: + case THEN: + case ELIF: + case ELSE: + case '{': /* } */ + case '(': /* )( */ + case ')': /* only valid in case statement */ + case BANG: /* ! time pipeline */ + case TIME: /* time time pipeline */ + case TIMEOPT: /* time -p time pipeline */ + case TIMEIGN: /* time -p -- ... */ + return 1; + default: + return 0; + } +#else + return 0; +#endif /* COMMAND_TIMING */ +} + +/* Handle special cases of token recognition: + IN is recognized if the last token was WORD and the token + before that was FOR or CASE or SELECT. + + DO is recognized if the last token was WORD and the token + before that was FOR or SELECT. + + ESAC is recognized if the last token caused `esacs_needed_count' + to be set + + `{' is recognized if the last token as WORD and the token + before that was FUNCTION, or if we just parsed an arithmetic + `for' command. + + `}' is recognized if there is an unclosed `{' present. + + `-p' is returned as TIMEOPT if the last read token was TIME. + `--' is returned as TIMEIGN if the last read token was TIMEOPT. + + ']]' is returned as COND_END if the parser is currently parsing + a conditional expression ((parser_state & PST_CONDEXPR) != 0) + + `time' is returned as TIME if and only if it is immediately + preceded by one of `;', `\n', `||', `&&', or `&'. +*/ + +static int +special_case_tokens (tokstr) + char *tokstr; +{ + if ((last_read_token == WORD) && +#if defined (SELECT_COMMAND) + ((token_before_that == FOR) || (token_before_that == CASE) || (token_before_that == SELECT)) && +#else + ((token_before_that == FOR) || (token_before_that == CASE)) && +#endif + (tokstr[0] == 'i' && tokstr[1] == 'n' && tokstr[2] == 0)) + { + if (token_before_that == CASE) + { + parser_state |= PST_CASEPAT; + esacs_needed_count++; + } + return (IN); + } + + if (last_read_token == WORD && +#if defined (SELECT_COMMAND) + (token_before_that == FOR || token_before_that == SELECT) && +#else + (token_before_that == FOR) && +#endif + (tokstr[0] == 'd' && tokstr[1] == 'o' && tokstr[2] == '\0')) + return (DO); + + /* Ditto for ESAC in the CASE case. + Specifically, this handles "case word in esac", which is a legal + construct, certainly because someone will pass an empty arg to the + case construct, and we don't want it to barf. Of course, we should + insist that the case construct has at least one pattern in it, but + the designers disagree. */ + if (esacs_needed_count) + { + esacs_needed_count--; + if (STREQ (tokstr, "esac")) + { + parser_state &= ~PST_CASEPAT; + return (ESAC); + } + } + + /* The start of a shell function definition. */ + if (parser_state & PST_ALLOWOPNBRC) + { + parser_state &= ~PST_ALLOWOPNBRC; + if (tokstr[0] == '{' && tokstr[1] == '\0') /* } */ + { + open_brace_count++; + function_bstart = line_number; + return ('{'); /* } */ + } + } + + /* We allow a `do' after a for ((...)) without an intervening + list_terminator */ + if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == 'd' && tokstr[1] == 'o' && !tokstr[2]) + return (DO); + if (last_read_token == ARITH_FOR_EXPRS && tokstr[0] == '{' && tokstr[1] == '\0') /* } */ + { + open_brace_count++; + return ('{'); /* } */ + } + + if (open_brace_count && reserved_word_acceptable (last_read_token) && tokstr[0] == '}' && !tokstr[1]) + { + open_brace_count--; /* { */ + return ('}'); + } + +#if defined (COMMAND_TIMING) + /* Handle -p after `time'. */ + if (last_read_token == TIME && tokstr[0] == '-' && tokstr[1] == 'p' && !tokstr[2]) + return (TIMEOPT); + /* Handle -- after `time -p'. */ + if (last_read_token == TIMEOPT && tokstr[0] == '-' && tokstr[1] == '-' && !tokstr[2]) + return (TIMEIGN); +#endif + +#if defined (COND_COMMAND) /* [[ */ + if ((parser_state & PST_CONDEXPR) && tokstr[0] == ']' && tokstr[1] == ']' && tokstr[2] == '\0') + return (COND_END); +#endif + + return (-1); +} + +/* Called from shell.c when Control-C is typed at top level. Or + by the error rule at top level. */ +void +reset_parser () +{ + dstack.delimiter_depth = 0; /* No delimiters found so far. */ + open_brace_count = 0; + +#if defined (EXTENDED_GLOB) + /* Reset to global value of extended glob */ + if (parser_state & PST_EXTPAT) + extended_glob = global_extglob; +#endif + + parser_state = 0; + +#if defined (ALIAS) || defined (DPAREN_ARITHMETIC) + if (pushed_string_list) + free_string_list (); +#endif /* ALIAS || DPAREN_ARITHMETIC */ + + if (shell_input_line) + { + free (shell_input_line); + shell_input_line = (char *)NULL; + shell_input_line_size = shell_input_line_index = 0; + } + + FREE (word_desc_to_read); + word_desc_to_read = (WORD_DESC *)NULL; + + eol_ungetc_lookahead = 0; + + current_token = '\n'; /* XXX */ + last_read_token = '\n'; + token_to_read = '\n'; +} + +/* Read the next token. Command can be READ (normal operation) or + RESET (to normalize state). */ +static int +read_token (command) + int command; +{ + int character; /* Current character. */ + int peek_char; /* Temporary look-ahead character. */ + int result; /* The thing to return. */ + + if (command == RESET) + { + reset_parser (); + return ('\n'); + } + + if (token_to_read) + { + result = token_to_read; + if (token_to_read == WORD || token_to_read == ASSIGNMENT_WORD) + { + yylval.word = word_desc_to_read; + word_desc_to_read = (WORD_DESC *)NULL; + } + token_to_read = 0; + return (result); + } + +#if defined (COND_COMMAND) + if ((parser_state & (PST_CONDCMD|PST_CONDEXPR)) == PST_CONDCMD) + { + cond_lineno = line_number; + parser_state |= PST_CONDEXPR; + yylval.command = parse_cond_command (); + if (cond_token != COND_END) + { + cond_error (); + return (-1); + } + token_to_read = COND_END; + parser_state &= ~(PST_CONDEXPR|PST_CONDCMD); + return (COND_CMD); + } +#endif + +#if defined (ALIAS) + /* This is a place to jump back to once we have successfully expanded a + token with an alias and pushed the string with push_string () */ + re_read_token: +#endif /* ALIAS */ + + /* Read a single word from input. Start by skipping blanks. */ + while ((character = shell_getc (1)) != EOF && shellblank (character)) + ; + + if (character == EOF) + { + EOF_Reached = 1; + return (yacc_EOF); + } + + if MBTEST(character == '#' && (!interactive || interactive_comments)) + { + /* A comment. Discard until EOL or EOF, and then return a newline. */ + discard_until ('\n'); + shell_getc (0); + character = '\n'; /* this will take the next if statement and return. */ + } + + if (character == '\n') + { + /* If we're about to return an unquoted newline, we can go and collect + the text of any pending here document. */ + if (need_here_doc) + gather_here_documents (); + +#if defined (ALIAS) + parser_state &= ~PST_ALEXPNEXT; +#endif /* ALIAS */ + + parser_state &= ~PST_ASSIGNOK; + + return (character); + } + + if (parser_state & PST_REGEXP) + goto tokword; + + /* Shell meta-characters. */ + if MBTEST(shellmeta (character) && ((parser_state & PST_DBLPAREN) == 0)) + { +#if defined (ALIAS) + /* Turn off alias tokenization iff this character sequence would + not leave us ready to read a command. */ + if (character == '<' || character == '>') + parser_state &= ~PST_ALEXPNEXT; +#endif /* ALIAS */ + + parser_state &= ~PST_ASSIGNOK; + + /* If we are parsing a command substitution and we have read a character + that marks the end of it, don't bother to skip over quoted newlines + when we read the next token. We're just interested in a character + that will turn this into a two-character token, so we let the higher + layers deal with quoted newlines following the command substitution. */ + if ((parser_state & PST_CMDSUBST) && character == shell_eof_token) + peek_char = shell_getc (0); + else + peek_char = shell_getc (1); + + if (character == peek_char) + { + switch (character) + { + case '<': + /* If '<' then we could be at "<<" or at "<<-". We have to + look ahead one more character. */ + peek_char = shell_getc (1); + if MBTEST(peek_char == '-') + return (LESS_LESS_MINUS); + else if MBTEST(peek_char == '<') + return (LESS_LESS_LESS); + else + { + shell_ungetc (peek_char); + return (LESS_LESS); + } + + case '>': + return (GREATER_GREATER); + + case ';': + parser_state |= PST_CASEPAT; +#if defined (ALIAS) + parser_state &= ~PST_ALEXPNEXT; +#endif /* ALIAS */ + + peek_char = shell_getc (1); + if MBTEST(peek_char == '&') + return (SEMI_SEMI_AND); + else + { + shell_ungetc (peek_char); + return (SEMI_SEMI); + } + + case '&': + return (AND_AND); + + case '|': + return (OR_OR); + +#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND) + case '(': /* ) */ + result = parse_dparen (character); + if (result == -2) + break; + else + return result; +#endif + } + } + else if MBTEST(character == '<' && peek_char == '&') + return (LESS_AND); + else if MBTEST(character == '>' && peek_char == '&') + return (GREATER_AND); + else if MBTEST(character == '<' && peek_char == '>') + return (LESS_GREATER); + else if MBTEST(character == '>' && peek_char == '|') + return (GREATER_BAR); + else if MBTEST(character == '&' && peek_char == '>') + { + peek_char = shell_getc (1); + if MBTEST(peek_char == '>') + return (AND_GREATER_GREATER); + else + { + shell_ungetc (peek_char); + return (AND_GREATER); + } + } + else if MBTEST(character == '|' && peek_char == '&') + return (BAR_AND); + else if MBTEST(character == ';' && peek_char == '&') + { + parser_state |= PST_CASEPAT; +#if defined (ALIAS) + parser_state &= ~PST_ALEXPNEXT; +#endif /* ALIAS */ + return (SEMI_AND); + } + + shell_ungetc (peek_char); + + /* If we look like we are reading the start of a function + definition, then let the reader know about it so that + we will do the right thing with `{'. */ + if MBTEST(character == ')' && last_read_token == '(' && token_before_that == WORD) + { + parser_state |= PST_ALLOWOPNBRC; +#if defined (ALIAS) + parser_state &= ~PST_ALEXPNEXT; +#endif /* ALIAS */ + function_dstart = line_number; + } + + /* case pattern lists may be preceded by an optional left paren. If + we're not trying to parse a case pattern list, the left paren + indicates a subshell. */ + if MBTEST(character == '(' && (parser_state & PST_CASEPAT) == 0) /* ) */ + parser_state |= PST_SUBSHELL; + /*(*/ + else if MBTEST((parser_state & PST_CASEPAT) && character == ')') + parser_state &= ~PST_CASEPAT; + /*(*/ + else if MBTEST((parser_state & PST_SUBSHELL) && character == ')') + parser_state &= ~PST_SUBSHELL; + +#if defined (PROCESS_SUBSTITUTION) + /* Check for the constructs which introduce process substitution. + Shells running in `posix mode' don't do process substitution. */ + if MBTEST(posixly_correct || ((character != '>' && character != '<') || peek_char != '(')) /*)*/ +#endif /* PROCESS_SUBSTITUTION */ + return (character); + } + + /* Hack <&- (close stdin) case. Also <&N- (dup and close). */ + if MBTEST(character == '-' && (last_read_token == LESS_AND || last_read_token == GREATER_AND)) + return (character); + +tokword: + /* Okay, if we got this far, we have to read a word. Read one, + and then check it against the known ones. */ + result = read_token_word (character); +#if defined (ALIAS) + if (result == RE_READ_TOKEN) + goto re_read_token; +#endif + return result; +} + +/* + * Match a $(...) or other grouping construct. This has to handle embedded + * quoted strings ('', ``, "") and nested constructs. It also must handle + * reprompting the user, if necessary, after reading a newline, and returning + * correct error values if it reads EOF. + */ +#define P_FIRSTCLOSE 0x0001 +#define P_ALLOWESC 0x0002 +#define P_DQUOTE 0x0004 +#define P_COMMAND 0x0008 /* parsing a command, so look for comments */ +#define P_BACKQUOTE 0x0010 /* parsing a backquoted command substitution */ +#define P_ARRAYSUB 0x0020 /* parsing a [...] array subscript for assignment */ +#define P_DOLBRACE 0x0040 /* parsing a ${...} construct */ + +/* Lexical state while parsing a grouping construct or $(...). */ +#define LEX_WASDOL 0x001 +#define LEX_CKCOMMENT 0x002 +#define LEX_INCOMMENT 0x004 +#define LEX_PASSNEXT 0x008 +#define LEX_RESWDOK 0x010 +#define LEX_CKCASE 0x020 +#define LEX_INCASE 0x040 +#define LEX_INHEREDOC 0x080 +#define LEX_HEREDELIM 0x100 /* reading here-doc delimiter */ +#define LEX_STRIPDOC 0x200 /* <<- strip tabs from here doc delim */ +#define LEX_INWORD 0x400 + +#define COMSUB_META(ch) ((ch) == ';' || (ch) == '&' || (ch) == '|') + +#define CHECK_NESTRET_ERROR() \ + do { \ + if (nestret == &matched_pair_error) \ + { \ + free (ret); \ + return &matched_pair_error; \ + } \ + } while (0) + +#define APPEND_NESTRET() \ + do { \ + if (nestlen) \ + { \ + RESIZE_MALLOCED_BUFFER (ret, retind, nestlen, retsize, 64); \ + strcpy (ret + retind, nestret); \ + retind += nestlen; \ + } \ + } while (0) + +static char matched_pair_error; + +static char * +parse_matched_pair (qc, open, close, lenp, flags) + int qc; /* `"' if this construct is within double quotes */ + int open, close; + int *lenp, flags; +{ + int count, ch, tflags; + int nestlen, ttranslen, start_lineno; + char *ret, *nestret, *ttrans; + int retind, retsize, rflags; + int dolbrace_state; + + dolbrace_state = (flags & P_DOLBRACE) ? DOLBRACE_PARAM : 0; + +/*itrace("parse_matched_pair[%d]: open = %c close = %c flags = %d", line_number, open, close, flags);*/ + count = 1; + tflags = 0; + + if ((flags & P_COMMAND) && qc != '`' && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0) + tflags |= LEX_CKCOMMENT; + + /* RFLAGS is the set of flags we want to pass to recursive calls. */ + rflags = (qc == '"') ? P_DQUOTE : (flags & P_DQUOTE); + + ret = (char *)xmalloc (retsize = 64); + retind = 0; + + start_lineno = line_number; + while (count) + { + ch = shell_getc (qc != '\'' && (tflags & (LEX_PASSNEXT)) == 0); + + if (ch == EOF) + { + free (ret); + parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close); + EOF_Reached = 1; /* XXX */ + return (&matched_pair_error); + } + + /* Possible reprompting. */ + if (ch == '\n' && SHOULD_PROMPT ()) + prompt_again (); + + /* Don't bother counting parens or doing anything else if in a comment + or part of a case statement */ + if (tflags & LEX_INCOMMENT) + { + /* Add this character. */ + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = ch; + + if (ch == '\n') + tflags &= ~LEX_INCOMMENT; + + continue; + } + + /* Not exactly right yet, should handle shell metacharacters, too. If + any changes are made to this test, make analogous changes to subst.c: + extract_delimited_string(). */ + else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (retind == 0 || ret[retind-1] == '\n' || shellblank (ret[retind - 1]))) + tflags |= LEX_INCOMMENT; + + if (tflags & LEX_PASSNEXT) /* last char was backslash */ + { + tflags &= ~LEX_PASSNEXT; + if (qc != '\'' && ch == '\n') /* double-quoted \ disappears. */ + { + if (retind > 0) + retind--; /* swallow previously-added backslash */ + continue; + } + + RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64); + if MBTEST(ch == CTLESC) + ret[retind++] = CTLESC; + ret[retind++] = ch; + continue; + } + /* If we're reparsing the input (e.g., from parse_string_to_word_list), + we've already prepended CTLESC to single-quoted results of $'...'. + We may want to do this for other CTLESC-quoted characters in + reparse, too. */ + else if MBTEST((parser_state & PST_REPARSE) && open == '\'' && (ch == CTLESC || ch == CTLNUL)) + { + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = ch; + continue; + } + else if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */ + { + RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64); + ret[retind++] = CTLESC; + ret[retind++] = ch; + continue; + } + else if MBTEST(ch == close) /* ending delimiter */ + count--; + /* handle nested ${...} specially. */ + else if MBTEST(open != close && (tflags & LEX_WASDOL) && open == '{' && ch == open) /* } */ + count++; + else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && ch == open) /* nested begin */ + count++; + + /* Add this character. */ + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = ch; + + /* If we just read the ending character, don't bother continuing. */ + if (count == 0) + break; + + if (open == '\'') /* '' inside grouping construct */ + { + if MBTEST((flags & P_ALLOWESC) && ch == '\\') + tflags |= LEX_PASSNEXT; + continue; + } + + if MBTEST(ch == '\\') /* backslashes */ + tflags |= LEX_PASSNEXT; + + /* Based on which dolstate is currently in (param, op, or word), + decide what the op is. We're really only concerned if it's % or + #, so we can turn on a flag that says whether or not we should + treat single quotes as special when inside a double-quoted + ${...}. This logic must agree with subst.c:extract_dollar_brace_string + since they share the same defines. */ + /* FLAG POSIX INTERP 221 */ + if (flags & P_DOLBRACE) + { + /* ${param%[%]word} */ + if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '%' && retind > 1) + dolbrace_state = DOLBRACE_QUOTE; + /* ${param#[#]word} */ + else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '#' && retind > 1) + dolbrace_state = DOLBRACE_QUOTE; + /* ${param/[/]pat/rep} */ + else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '/' && retind > 1) + dolbrace_state = DOLBRACE_QUOTE2; /* XXX */ + /* ${param^[^]pat} */ + else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == '^' && retind > 1) + dolbrace_state = DOLBRACE_QUOTE; + /* ${param,[,]pat} */ + else if MBTEST(dolbrace_state == DOLBRACE_PARAM && ch == ',' && retind > 1) + dolbrace_state = DOLBRACE_QUOTE; + else if MBTEST(dolbrace_state == DOLBRACE_PARAM && strchr ("#%^,~:-=?+/", ch) != 0) + dolbrace_state = DOLBRACE_OP; + else if MBTEST(dolbrace_state == DOLBRACE_OP && strchr ("#%^,~:-=?+/", ch) == 0) + dolbrace_state = DOLBRACE_WORD; + } + + /* The big hammer. Single quotes aren't special in double quotes. The + problem is that Posix used to say the single quotes are semi-special: + within a double-quoted ${...} construct "an even number of + unescaped double-quotes or single-quotes, if any, shall occur." */ + /* This was changed in Austin Group Interp 221 */ + if MBTEST(posixly_correct && shell_compatibility_level > 41 && dolbrace_state != DOLBRACE_QUOTE && dolbrace_state != DOLBRACE_QUOTE2 && (flags & P_DQUOTE) && (flags & P_DOLBRACE) && ch == '\'') + continue; + + /* Could also check open == '`' if we want to parse grouping constructs + inside old-style command substitution. */ + if (open != close) /* a grouping construct */ + { + if MBTEST(shellquote (ch)) + { + /* '', ``, or "" inside $(...) or other grouping construct. */ + push_delimiter (dstack, ch); + if MBTEST((tflags & LEX_WASDOL) && ch == '\'') /* $'...' inside group */ + nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags); + else + nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags); + pop_delimiter (dstack); + CHECK_NESTRET_ERROR (); + + if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0)) + { + /* Translate $'...' here. */ + ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen); + xfree (nestret); + + /* If we're parsing a double-quoted brace expansion and we are + not in a place where single quotes are treated specially, + make sure we single-quote the results of the ansi + expansion because quote removal should remove them later */ + /* FLAG POSIX INTERP 221 */ + if ((shell_compatibility_level > 42) && (rflags & P_DQUOTE) && (dolbrace_state == DOLBRACE_QUOTE2) && (flags & P_DOLBRACE)) + { + nestret = sh_single_quote (ttrans); + free (ttrans); + nestlen = strlen (nestret); + } + else if ((rflags & P_DQUOTE) == 0) + { + nestret = sh_single_quote (ttrans); + free (ttrans); + nestlen = strlen (nestret); + } + else + { + nestret = ttrans; + nestlen = ttranslen; + } + retind -= 2; /* back up before the $' */ + } + else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0)) + { + /* Locale expand $"..." here. */ + ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen); + xfree (nestret); + + nestret = sh_mkdoublequoted (ttrans, ttranslen, 0); + free (ttrans); + nestlen = ttranslen + 2; + retind -= 2; /* back up before the $" */ + } + + APPEND_NESTRET (); + FREE (nestret); + } + else if ((flags & (P_ARRAYSUB|P_DOLBRACE)) && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */ + goto parse_dollar_word; + } + /* Parse an old-style command substitution within double quotes as a + single word. */ + /* XXX - sh and ksh93 don't do this - XXX */ + else if MBTEST(open == '"' && ch == '`') + { + nestret = parse_matched_pair (0, '`', '`', &nestlen, rflags); + + CHECK_NESTRET_ERROR (); + APPEND_NESTRET (); + + FREE (nestret); + } + else if MBTEST(open != '`' && (tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */ + /* check for $(), $[], or ${} inside quoted string. */ + { +parse_dollar_word: + if (open == ch) /* undo previous increment */ + count--; + if (ch == '(') /* ) */ + nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE); + else if (ch == '{') /* } */ + nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags); + else if (ch == '[') /* ] */ + nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags); + + CHECK_NESTRET_ERROR (); + APPEND_NESTRET (); + + FREE (nestret); + } + if MBTEST(ch == '$') + tflags |= LEX_WASDOL; + else + tflags &= ~LEX_WASDOL; + } + + ret[retind] = '\0'; + if (lenp) + *lenp = retind; +/*itrace("parse_matched_pair[%d]: returning %s", line_number, ret);*/ + return ret; +} + +/* Parse a $(...) command substitution. This is messier than I'd like, and + reproduces a lot more of the token-reading code than I'd like. */ +static char * +parse_comsub (qc, open, close, lenp, flags) + int qc; /* `"' if this construct is within double quotes */ + int open, close; + int *lenp, flags; +{ + int count, ch, peekc, tflags, lex_rwlen, lex_wlen, lex_firstind; + int nestlen, ttranslen, start_lineno; + char *ret, *nestret, *ttrans, *heredelim; + int retind, retsize, rflags, hdlen; + + /* Posix interp 217 says arithmetic expressions have precedence, so + assume $(( introduces arithmetic expansion and parse accordingly. */ + peekc = shell_getc (0); + shell_ungetc (peekc); + if (peekc == '(') + return (parse_matched_pair (qc, open, close, lenp, 0)); + +/*itrace("parse_comsub: qc = `%c' open = %c close = %c", qc, open, close);*/ + count = 1; + tflags = LEX_RESWDOK; + + if ((flags & P_COMMAND) && qc != '\'' && qc != '"' && (flags & P_DQUOTE) == 0) + tflags |= LEX_CKCASE; + if ((tflags & LEX_CKCASE) && (interactive == 0 || interactive_comments)) + tflags |= LEX_CKCOMMENT; + + /* RFLAGS is the set of flags we want to pass to recursive calls. */ + rflags = (flags & P_DQUOTE); + + ret = (char *)xmalloc (retsize = 64); + retind = 0; + + start_lineno = line_number; + lex_rwlen = lex_wlen = 0; + + heredelim = 0; + lex_firstind = -1; + + while (count) + { +comsub_readchar: + ch = shell_getc (qc != '\'' && (tflags & (LEX_INCOMMENT|LEX_PASSNEXT)) == 0); + + if (ch == EOF) + { +eof_error: + free (ret); + FREE (heredelim); + parser_error (start_lineno, _("unexpected EOF while looking for matching `%c'"), close); + EOF_Reached = 1; /* XXX */ + return (&matched_pair_error); + } + + /* If we hit the end of a line and are reading the contents of a here + document, and it's not the same line that the document starts on, + check for this line being the here doc delimiter. Otherwise, if + we're in a here document, mark the next character as the beginning + of a line. */ + if (ch == '\n') + { + if ((tflags & LEX_HEREDELIM) && heredelim) + { + tflags &= ~LEX_HEREDELIM; + tflags |= LEX_INHEREDOC; + lex_firstind = retind + 1; + } + else if (tflags & LEX_INHEREDOC) + { + int tind; + tind = lex_firstind; + while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t') + tind++; + if (STREQN (ret + tind, heredelim, hdlen)) + { + tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC); +/*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/ + free (heredelim); + heredelim = 0; + lex_firstind = -1; + } + else + lex_firstind = retind + 1; + } + } + + /* Possible reprompting. */ + if (ch == '\n' && SHOULD_PROMPT ()) + prompt_again (); + + /* XXX -- possibly allow here doc to be delimited by ending right + paren. */ + if ((tflags & LEX_INHEREDOC) && ch == close && count == 1) + { + int tind; +/*itrace("parse_comsub: in here doc, ch == close, retind - firstind = %d hdlen = %d retind = %d", retind-lex_firstind, hdlen, retind);*/ + tind = lex_firstind; + while ((tflags & LEX_STRIPDOC) && ret[tind] == '\t') + tind++; + if (retind-tind == hdlen && STREQN (ret + tind, heredelim, hdlen)) + { + tflags &= ~(LEX_STRIPDOC|LEX_INHEREDOC); +/*itrace("parse_comsub:%d: found here doc end `%s'", line_number, ret + tind);*/ + free (heredelim); + heredelim = 0; + lex_firstind = -1; + } + } + + /* Don't bother counting parens or doing anything else if in a comment */ + if (tflags & (LEX_INCOMMENT|LEX_INHEREDOC)) + { + /* Add this character. */ + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = ch; + + if ((tflags & LEX_INCOMMENT) && ch == '\n') + { +/*itrace("parse_comsub:%d: lex_incomment -> 0 ch = `%c'", line_number, ch);*/ + tflags &= ~LEX_INCOMMENT; + } + + continue; + } + + if (tflags & LEX_PASSNEXT) /* last char was backslash */ + { +/*itrace("parse_comsub:%d: lex_passnext -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/ + tflags &= ~LEX_PASSNEXT; + if (qc != '\'' && ch == '\n') /* double-quoted \ disappears. */ + { + if (retind > 0) + retind--; /* swallow previously-added backslash */ + continue; + } + + RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64); + if MBTEST(ch == CTLESC) + ret[retind++] = CTLESC; + ret[retind++] = ch; + continue; + } + + /* If this is a shell break character, we are not in a word. If not, + we either start or continue a word. */ + if MBTEST(shellbreak (ch)) + { + tflags &= ~LEX_INWORD; +/*itrace("parse_comsub:%d: lex_inword -> 0 ch = `%c' (%d)", line_number, ch, __LINE__);*/ + } + else + { + if (tflags & LEX_INWORD) + { + lex_wlen++; +/*itrace("parse_comsub:%d: lex_inword == 1 ch = `%c' lex_wlen = %d (%d)", line_number, ch, lex_wlen, __LINE__);*/ + } + else + { +/*itrace("parse_comsub:%d: lex_inword -> 1 ch = `%c' (%d)", line_number, ch, __LINE__);*/ + tflags |= LEX_INWORD; + lex_wlen = 0; + if (tflags & LEX_RESWDOK) + lex_rwlen = 0; + } + } + + /* Skip whitespace */ + if MBTEST(shellblank (ch) && (tflags & LEX_HEREDELIM) == 0 && lex_rwlen == 0) + { + /* Add this character. */ + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = ch; + continue; + } + + /* Either we are looking for the start of the here-doc delimiter + (lex_firstind == -1) or we are reading one (lex_firstind >= 0). + If this character is a shell break character and we are reading + the delimiter, save it and note that we are now reading a here + document. If we've found the start of the delimiter, note it by + setting lex_firstind. Backslashes can quote shell metacharacters + in here-doc delimiters. */ + if (tflags & LEX_HEREDELIM) + { + if (lex_firstind == -1 && shellbreak (ch) == 0) + lex_firstind = retind; +#if 0 + else if (heredelim && (tflags & LEX_PASSNEXT) == 0 && ch == '\n') + { + tflags |= LEX_INHEREDOC; + tflags &= ~LEX_HEREDELIM; + lex_firstind = retind + 1; + } +#endif + else if (lex_firstind >= 0 && (tflags & LEX_PASSNEXT) == 0 && shellbreak (ch)) + { + if (heredelim == 0) + { + nestret = substring (ret, lex_firstind, retind); + heredelim = string_quote_removal (nestret, 0); + free (nestret); + hdlen = STRLEN(heredelim); +/*itrace("parse_comsub:%d: found here doc delimiter `%s' (%d)", line_number, heredelim, hdlen);*/ + } + if (ch == '\n') + { + tflags |= LEX_INHEREDOC; + tflags &= ~LEX_HEREDELIM; + lex_firstind = retind + 1; + } + else + lex_firstind = -1; + } + } + + /* Meta-characters that can introduce a reserved word. Not perfect yet. */ + if MBTEST((tflags & LEX_RESWDOK) == 0 && (tflags & LEX_CKCASE) && (tflags & LEX_INCOMMENT) == 0 && (shellmeta(ch) || ch == '\n')) + { + /* Add this character. */ + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = ch; + peekc = shell_getc (1); + if (ch == peekc && (ch == '&' || ch == '|' || ch == ';')) /* two-character tokens */ + { + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = peekc; +/*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/ + tflags |= LEX_RESWDOK; + lex_rwlen = 0; + continue; + } + else if (ch == '\n' || COMSUB_META(ch)) + { + shell_ungetc (peekc); +/*itrace("parse_comsub:%d: set lex_reswordok = 1, ch = `%c'", line_number, ch);*/ + tflags |= LEX_RESWDOK; + lex_rwlen = 0; + continue; + } + else if (ch == EOF) + goto eof_error; + else + { + /* `unget' the character we just added and fall through */ + retind--; + shell_ungetc (peekc); + } + } + + /* If we can read a reserved word, try to read one. */ + if (tflags & LEX_RESWDOK) + { + if MBTEST(islower ((unsigned char)ch)) + { + /* Add this character. */ + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = ch; + lex_rwlen++; + continue; + } + else if MBTEST(lex_rwlen == 4 && shellbreak (ch)) + { + if (STREQN (ret + retind - 4, "case", 4)) + { + tflags |= LEX_INCASE; +/*itrace("parse_comsub:%d: found `case', lex_incase -> 1 lex_reswdok -> 0", line_number);*/ + } + else if (STREQN (ret + retind - 4, "esac", 4)) + { + tflags &= ~LEX_INCASE; +/*itrace("parse_comsub:%d: found `esac', lex_incase -> 0 lex_reswdok -> 0", line_number);*/ + } + tflags &= ~LEX_RESWDOK; + } + else if MBTEST((tflags & LEX_CKCOMMENT) && ch == '#' && (lex_rwlen == 0 || ((tflags & LEX_INWORD) && lex_wlen == 0))) + ; /* don't modify LEX_RESWDOK if we're starting a comment */ + /* Allow `do' followed by space, tab, or newline to preserve the + RESWDOK flag, but reset the reserved word length counter so we + can read another one. */ + else if MBTEST(((tflags & LEX_INCASE) == 0) && + (isblank((unsigned char)ch) || ch == '\n') && + lex_rwlen == 2 && + STREQN (ret + retind - 2, "do", 2)) + { +/*itrace("parse_comsub:%d: lex_incase == 0 found `%c', found \"do\"", line_number, ch);*/ + lex_rwlen = 0; + } + else if MBTEST((tflags & LEX_INCASE) && ch != '\n') + /* If we can read a reserved word and we're in case, we're at the + point where we can read a new pattern list or an esac. We + handle the esac case above. If we read a newline, we want to + leave LEX_RESWDOK alone. If we read anything else, we want to + turn off LEX_RESWDOK, since we're going to read a pattern list. */ + { + tflags &= ~LEX_RESWDOK; +/*itrace("parse_comsub:%d: lex_incase == 1 found `%c', lex_reswordok -> 0", line_number, ch);*/ + } + else if MBTEST(shellbreak (ch) == 0) + { + tflags &= ~LEX_RESWDOK; +/*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/ + } +#if 0 + /* If we find a space or tab but have read something and it's not + `do', turn off the reserved-word-ok flag */ + else if MBTEST(isblank ((unsigned char)ch) && lex_rwlen > 0) + { + tflags &= ~LEX_RESWDOK; +/*itrace("parse_comsub:%d: found `%c', lex_reswordok -> 0", line_number, ch);*/ + } +#endif + } + + /* Might be the start of a here-doc delimiter */ + if MBTEST((tflags & LEX_INCOMMENT) == 0 && (tflags & LEX_CKCASE) && ch == '<') + { + /* Add this character. */ + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = ch; + peekc = shell_getc (1); + if (peekc == EOF) + goto eof_error; + if (peekc == ch) + { + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = peekc; + peekc = shell_getc (1); + if (peekc == EOF) + goto eof_error; + if (peekc == '-') + { + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = peekc; + tflags |= LEX_STRIPDOC; + } + else + shell_ungetc (peekc); + if (peekc != '<') + { + tflags |= LEX_HEREDELIM; + lex_firstind = -1; + } + continue; + } + else + ch = peekc; /* fall through and continue XXX */ + } + else if MBTEST((tflags & LEX_CKCOMMENT) && (tflags & LEX_INCOMMENT) == 0 && ch == '#' && (((tflags & LEX_RESWDOK) && lex_rwlen == 0) || ((tflags & LEX_INWORD) && lex_wlen == 0))) + { +/*itrace("parse_comsub:%d: lex_incomment -> 1 (%d)", line_number, __LINE__);*/ + tflags |= LEX_INCOMMENT; + } + + if MBTEST(ch == CTLESC || ch == CTLNUL) /* special shell escapes */ + { + RESIZE_MALLOCED_BUFFER (ret, retind, 2, retsize, 64); + ret[retind++] = CTLESC; + ret[retind++] = ch; + continue; + } +#if 0 + else if MBTEST((tflags & LEX_INCASE) && ch == close && close == ')') + tflags &= ~LEX_INCASE; /* XXX */ +#endif + else if MBTEST(ch == close && (tflags & LEX_INCASE) == 0) /* ending delimiter */ + { + count--; +/*itrace("parse_comsub:%d: found close: count = %d", line_number, count);*/ + } + else if MBTEST(((flags & P_FIRSTCLOSE) == 0) && (tflags & LEX_INCASE) == 0 && ch == open) /* nested begin */ + { + count++; +/*itrace("parse_comsub:%d: found open: count = %d", line_number, count);*/ + } + + /* Add this character. */ + RESIZE_MALLOCED_BUFFER (ret, retind, 1, retsize, 64); + ret[retind++] = ch; + + /* If we just read the ending character, don't bother continuing. */ + if (count == 0) + break; + + if MBTEST(ch == '\\') /* backslashes */ + tflags |= LEX_PASSNEXT; + + if MBTEST(shellquote (ch)) + { + /* '', ``, or "" inside $(...). */ + push_delimiter (dstack, ch); + if MBTEST((tflags & LEX_WASDOL) && ch == '\'') /* $'...' inside group */ + nestret = parse_matched_pair (ch, ch, ch, &nestlen, P_ALLOWESC|rflags); + else + nestret = parse_matched_pair (ch, ch, ch, &nestlen, rflags); + pop_delimiter (dstack); + CHECK_NESTRET_ERROR (); + + if MBTEST((tflags & LEX_WASDOL) && ch == '\'' && (extended_quote || (rflags & P_DQUOTE) == 0)) + { + /* Translate $'...' here. */ + ttrans = ansiexpand (nestret, 0, nestlen - 1, &ttranslen); + xfree (nestret); + + if ((rflags & P_DQUOTE) == 0) + { + nestret = sh_single_quote (ttrans); + free (ttrans); + nestlen = strlen (nestret); + } + else + { + nestret = ttrans; + nestlen = ttranslen; + } + retind -= 2; /* back up before the $' */ + } + else if MBTEST((tflags & LEX_WASDOL) && ch == '"' && (extended_quote || (rflags & P_DQUOTE) == 0)) + { + /* Locale expand $"..." here. */ + ttrans = localeexpand (nestret, 0, nestlen - 1, start_lineno, &ttranslen); + xfree (nestret); + + nestret = sh_mkdoublequoted (ttrans, ttranslen, 0); + free (ttrans); + nestlen = ttranslen + 2; + retind -= 2; /* back up before the $" */ + } + + APPEND_NESTRET (); + FREE (nestret); + } + else if MBTEST((tflags & LEX_WASDOL) && (ch == '(' || ch == '{' || ch == '[')) /* ) } ] */ + /* check for $(), $[], or ${} inside command substitution. */ + { + if ((tflags & LEX_INCASE) == 0 && open == ch) /* undo previous increment */ + count--; + if (ch == '(') /* ) */ + nestret = parse_comsub (0, '(', ')', &nestlen, (rflags|P_COMMAND) & ~P_DQUOTE); + else if (ch == '{') /* } */ + nestret = parse_matched_pair (0, '{', '}', &nestlen, P_FIRSTCLOSE|P_DOLBRACE|rflags); + else if (ch == '[') /* ] */ + nestret = parse_matched_pair (0, '[', ']', &nestlen, rflags); + + CHECK_NESTRET_ERROR (); + APPEND_NESTRET (); + + FREE (nestret); + } + if MBTEST(ch == '$') + tflags |= LEX_WASDOL; + else + tflags &= ~LEX_WASDOL; + } + + FREE (heredelim); + ret[retind] = '\0'; + if (lenp) + *lenp = retind; +/*itrace("parse_comsub:%d: returning `%s'", line_number, ret);*/ + return ret; +} + +/* Recursively call the parser to parse a $(...) command substitution. */ +char * +xparse_dolparen (base, string, indp, flags) + char *base; + char *string; + int *indp; + int flags; +{ + sh_parser_state_t ps; + sh_input_line_state_t ls; + int orig_ind, nc, sflags, orig_eof_token; + char *ret, *s, *ep, *ostring; + + /*yydebug = 1;*/ + orig_ind = *indp; + ostring = string; + +/*itrace("xparse_dolparen: size = %d shell_input_line = `%s'", shell_input_line_size, shell_input_line);*/ + sflags = SEVAL_NONINT|SEVAL_NOHIST|SEVAL_NOFREE; + if (flags & SX_NOLONGJMP) + sflags |= SEVAL_NOLONGJMP; + save_parser_state (&ps); + save_input_line_state (&ls); + orig_eof_token = shell_eof_token; + + /*(*/ + parser_state |= PST_CMDSUBST|PST_EOFTOKEN; /* allow instant ')' */ /*(*/ + shell_eof_token = ')'; + + parse_string (string, "command substitution", sflags, &ep); + + shell_eof_token = orig_eof_token; + restore_parser_state (&ps); + reset_parser (); + /* reset_parser clears shell_input_line and associated variables */ + restore_input_line_state (&ls); + + token_to_read = 0; + + /* Need to find how many characters parse_and_execute consumed, update + *indp, if flags != 0, copy the portion of the string parsed into RET + and return it. If flags & 1 (EX_NOALLOC) we can return NULL. */ + + /*(*/ + if (ep[-1] != ')') + { +#if DEBUG + if (ep[-1] != '\n') + itrace("xparse_dolparen:%d: ep[-1] != RPAREN (%d), ep = `%s'", line_number, ep[-1], ep); +#endif + while (ep > ostring && ep[-1] == '\n') ep--; + } + + nc = ep - ostring; + *indp = ep - base - 1; + + /*(*/ +#if DEBUG + if (base[*indp] != ')') + itrace("xparse_dolparen:%d: base[%d] != RPAREN (%d), base = `%s'", line_number, *indp, base[*indp], base); +#endif + + if (flags & SX_NOALLOC) + return (char *)NULL; + + if (nc == 0) + { + ret = xmalloc (1); + ret[0] = '\0'; + } + else + ret = substring (ostring, 0, nc - 1); + + return ret; +} + +#if defined (DPAREN_ARITHMETIC) || defined (ARITH_FOR_COMMAND) +/* Parse a double-paren construct. It can be either an arithmetic + command, an arithmetic `for' command, or a nested subshell. Returns + the parsed token, -1 on error, or -2 if we didn't do anything and + should just go on. */ +static int +parse_dparen (c) + int c; +{ + int cmdtyp, sline; + char *wval; + WORD_DESC *wd; + +#if defined (ARITH_FOR_COMMAND) + if (last_read_token == FOR) + { + arith_for_lineno = line_number; + cmdtyp = parse_arith_cmd (&wval, 0); + if (cmdtyp == 1) + { + wd = alloc_word_desc (); + wd->word = wval; + yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL); + return (ARITH_FOR_EXPRS); + } + else + return -1; /* ERROR */ + } +#endif + +#if defined (DPAREN_ARITHMETIC) + if (reserved_word_acceptable (last_read_token)) + { + sline = line_number; + + cmdtyp = parse_arith_cmd (&wval, 0); + if (cmdtyp == 1) /* arithmetic command */ + { + wd = alloc_word_desc (); + wd->word = wval; + wd->flags = W_QUOTED|W_NOSPLIT|W_NOGLOB|W_DQUOTE; + yylval.word_list = make_word_list (wd, (WORD_LIST *)NULL); + return (ARITH_CMD); + } + else if (cmdtyp == 0) /* nested subshell */ + { + push_string (wval, 0, (alias_t *)NULL); + pushed_string_list->flags = PSH_DPAREN; + if ((parser_state & PST_CASEPAT) == 0) + parser_state |= PST_SUBSHELL; + return (c); + } + else /* ERROR */ + return -1; + } +#endif + + return -2; /* XXX */ +} + +/* We've seen a `(('. Look for the matching `))'. If we get it, return 1. + If not, assume it's a nested subshell for backwards compatibility and + return 0. In any case, put the characters we've consumed into a locally- + allocated buffer and make *ep point to that buffer. Return -1 on an + error, for example EOF. */ +static int +parse_arith_cmd (ep, adddq) + char **ep; + int adddq; +{ + int exp_lineno, rval, c; + char *ttok, *tokstr; + int ttoklen; + + exp_lineno = line_number; + ttok = parse_matched_pair (0, '(', ')', &ttoklen, 0); + rval = 1; + if (ttok == &matched_pair_error) + return -1; + /* Check that the next character is the closing right paren. If + not, this is a syntax error. ( */ + c = shell_getc (0); + if MBTEST(c != ')') + rval = 0; + + tokstr = (char *)xmalloc (ttoklen + 4); + + /* if ADDDQ != 0 then (( ... )) -> "..." */ + if (rval == 1 && adddq) /* arith cmd, add double quotes */ + { + tokstr[0] = '"'; + strncpy (tokstr + 1, ttok, ttoklen - 1); + tokstr[ttoklen] = '"'; + tokstr[ttoklen+1] = '\0'; + } + else if (rval == 1) /* arith cmd, don't add double quotes */ + { + strncpy (tokstr, ttok, ttoklen - 1); + tokstr[ttoklen-1] = '\0'; + } + else /* nested subshell */ + { + tokstr[0] = '('; + strncpy (tokstr + 1, ttok, ttoklen - 1); + tokstr[ttoklen] = ')'; + tokstr[ttoklen+1] = c; + tokstr[ttoklen+2] = '\0'; + } + + *ep = tokstr; + FREE (ttok); + return rval; +} +#endif /* DPAREN_ARITHMETIC || ARITH_FOR_COMMAND */ + +#if defined (COND_COMMAND) +static void +cond_error () +{ + char *etext; + + if (EOF_Reached && cond_token != COND_ERROR) /* [[ */ + parser_error (cond_lineno, _("unexpected EOF while looking for `]]'")); + else if (cond_token != COND_ERROR) + { + if (etext = error_token_from_token (cond_token)) + { + parser_error (cond_lineno, _("syntax error in conditional expression: unexpected token `%s'"), etext); + free (etext); + } + else + parser_error (cond_lineno, _("syntax error in conditional expression")); + } +} + +static COND_COM * +cond_expr () +{ + return (cond_or ()); +} + +static COND_COM * +cond_or () +{ + COND_COM *l, *r; + + l = cond_and (); + if (cond_token == OR_OR) + { + r = cond_or (); + l = make_cond_node (COND_OR, (WORD_DESC *)NULL, l, r); + } + return l; +} + +static COND_COM * +cond_and () +{ + COND_COM *l, *r; + + l = cond_term (); + if (cond_token == AND_AND) + { + r = cond_and (); + l = make_cond_node (COND_AND, (WORD_DESC *)NULL, l, r); + } + return l; +} + +static int +cond_skip_newlines () +{ + while ((cond_token = read_token (READ)) == '\n') + { + if (SHOULD_PROMPT ()) + prompt_again (); + } + return (cond_token); +} + +#define COND_RETURN_ERROR() \ + do { cond_token = COND_ERROR; return ((COND_COM *)NULL); } while (0) + +static COND_COM * +cond_term () +{ + WORD_DESC *op; + COND_COM *term, *tleft, *tright; + int tok, lineno; + char *etext; + + /* Read a token. It can be a left paren, a `!', a unary operator, or a + word that should be the first argument of a binary operator. Start by + skipping newlines, since this is a compound command. */ + tok = cond_skip_newlines (); + lineno = line_number; + if (tok == COND_END) + { + COND_RETURN_ERROR (); + } + else if (tok == '(') + { + term = cond_expr (); + if (cond_token != ')') + { + if (term) + dispose_cond_node (term); /* ( */ + if (etext = error_token_from_token (cond_token)) + { + parser_error (lineno, _("unexpected token `%s', expected `)'"), etext); + free (etext); + } + else + parser_error (lineno, _("expected `)'")); + COND_RETURN_ERROR (); + } + term = make_cond_node (COND_EXPR, (WORD_DESC *)NULL, term, (COND_COM *)NULL); + (void)cond_skip_newlines (); + } + else if (tok == BANG || (tok == WORD && (yylval.word->word[0] == '!' && yylval.word->word[1] == '\0'))) + { + if (tok == WORD) + dispose_word (yylval.word); /* not needed */ + term = cond_term (); + if (term) + term->flags |= CMD_INVERT_RETURN; + } + else if (tok == WORD && yylval.word->word[0] == '-' && yylval.word->word[2] == 0 && test_unop (yylval.word->word)) + { + op = yylval.word; + tok = read_token (READ); + if (tok == WORD) + { + tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL); + term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL); + } + else + { + dispose_word (op); + if (etext = error_token_from_token (tok)) + { + parser_error (line_number, _("unexpected argument `%s' to conditional unary operator"), etext); + free (etext); + } + else + parser_error (line_number, _("unexpected argument to conditional unary operator")); + COND_RETURN_ERROR (); + } + + (void)cond_skip_newlines (); + } + else if (tok == WORD) /* left argument to binary operator */ + { + /* lhs */ + tleft = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL); + + /* binop */ + tok = read_token (READ); + if (tok == WORD && test_binop (yylval.word->word)) + { + op = yylval.word; + if (op->word[0] == '=' && (op->word[1] == '\0' || (op->word[1] == '=' && op->word[2] == '\0'))) + parser_state |= PST_EXTPAT; + else if (op->word[0] == '!' && op->word[1] == '=' && op->word[2] == '\0') + parser_state |= PST_EXTPAT; + } +#if defined (COND_REGEXP) + else if (tok == WORD && STREQ (yylval.word->word, "=~")) + { + op = yylval.word; + parser_state |= PST_REGEXP; + } +#endif + else if (tok == '<' || tok == '>') + op = make_word_from_token (tok); /* ( */ + /* There should be a check before blindly accepting the `)' that we have + seen the opening `('. */ + else if (tok == COND_END || tok == AND_AND || tok == OR_OR || tok == ')') + { + /* Special case. [[ x ]] is equivalent to [[ -n x ]], just like + the test command. Similarly for [[ x && expr ]] or + [[ x || expr ]] or [[ (x) ]]. */ + op = make_word ("-n"); + term = make_cond_node (COND_UNARY, op, tleft, (COND_COM *)NULL); + cond_token = tok; + return (term); + } + else + { + if (etext = error_token_from_token (tok)) + { + parser_error (line_number, _("unexpected token `%s', conditional binary operator expected"), etext); + free (etext); + } + else + parser_error (line_number, _("conditional binary operator expected")); + dispose_cond_node (tleft); + COND_RETURN_ERROR (); + } + + /* rhs */ + if (parser_state & PST_EXTPAT) + extended_glob = 1; + tok = read_token (READ); + if (parser_state & PST_EXTPAT) + extended_glob = global_extglob; + parser_state &= ~(PST_REGEXP|PST_EXTPAT); + + if (tok == WORD) + { + tright = make_cond_node (COND_TERM, yylval.word, (COND_COM *)NULL, (COND_COM *)NULL); + term = make_cond_node (COND_BINARY, op, tleft, tright); + } + else + { + if (etext = error_token_from_token (tok)) + { + parser_error (line_number, _("unexpected argument `%s' to conditional binary operator"), etext); + free (etext); + } + else + parser_error (line_number, _("unexpected argument to conditional binary operator")); + dispose_cond_node (tleft); + dispose_word (op); + COND_RETURN_ERROR (); + } + + (void)cond_skip_newlines (); + } + else + { + if (tok < 256) + parser_error (line_number, _("unexpected token `%c' in conditional command"), tok); + else if (etext = error_token_from_token (tok)) + { + parser_error (line_number, _("unexpected token `%s' in conditional command"), etext); + free (etext); + } + else + parser_error (line_number, _("unexpected token %d in conditional command"), tok); + COND_RETURN_ERROR (); + } + return (term); +} + +/* This is kind of bogus -- we slip a mini recursive-descent parser in + here to handle the conditional statement syntax. */ +static COMMAND * +parse_cond_command () +{ + COND_COM *cexp; + + global_extglob = extended_glob; + cexp = cond_expr (); + return (make_cond_command (cexp)); +} +#endif + +#if defined (ARRAY_VARS) +/* When this is called, it's guaranteed that we don't care about anything + in t beyond i. We do save and restore the chars, though. */ +static int +token_is_assignment (t, i) + char *t; + int i; +{ + unsigned char c, c1; + int r; + + c = t[i]; c1 = t[i+1]; + t[i] = '='; t[i+1] = '\0'; + r = assignment (t, (parser_state & PST_COMPASSIGN) != 0); + t[i] = c; t[i+1] = c1; + return r; +} + +/* XXX - possible changes here for `+=' */ +static int +token_is_ident (t, i) + char *t; + int i; +{ + unsigned char c; + int r; + + c = t[i]; + t[i] = '\0'; + r = legal_identifier (t); + t[i] = c; + return r; +} +#endif + +static int +read_token_word (character) + int character; +{ + /* The value for YYLVAL when a WORD is read. */ + WORD_DESC *the_word; + + /* Index into the token that we are building. */ + int token_index; + + /* ALL_DIGITS becomes zero when we see a non-digit. */ + int all_digit_token; + + /* DOLLAR_PRESENT becomes non-zero if we see a `$'. */ + int dollar_present; + + /* COMPOUND_ASSIGNMENT becomes non-zero if we are parsing a compound + assignment. */ + int compound_assignment; + + /* QUOTED becomes non-zero if we see one of ("), ('), (`), or (\). */ + int quoted; + + /* Non-zero means to ignore the value of the next character, and just + to add it no matter what. */ + int pass_next_character; + + /* The current delimiting character. */ + int cd; + int result, peek_char; + char *ttok, *ttrans; + int ttoklen, ttranslen; + intmax_t lvalue; + + if (token_buffer_size < TOKEN_DEFAULT_INITIAL_SIZE) + token = (char *)xrealloc (token, token_buffer_size = TOKEN_DEFAULT_INITIAL_SIZE); + + token_index = 0; + all_digit_token = DIGIT (character); + dollar_present = quoted = pass_next_character = compound_assignment = 0; + + for (;;) + { + if (character == EOF) + goto got_token; + + if (pass_next_character) + { + pass_next_character = 0; + goto got_escaped_character; + } + + cd = current_delimiter (dstack); + + /* Handle backslashes. Quote lots of things when not inside of + double-quotes, quote some things inside of double-quotes. */ + if MBTEST(character == '\\') + { + peek_char = shell_getc (0); + + /* Backslash-newline is ignored in all cases except + when quoted with single quotes. */ + if (peek_char == '\n') + { + character = '\n'; + goto next_character; + } + else + { + shell_ungetc (peek_char); + + /* If the next character is to be quoted, note it now. */ + if (cd == 0 || cd == '`' || + (cd == '"' && peek_char >= 0 && (sh_syntaxtab[peek_char] & CBSDQUOTE))) + pass_next_character++; + + quoted = 1; + goto got_character; + } + } + + /* Parse a matched pair of quote characters. */ + if MBTEST(shellquote (character)) + { + push_delimiter (dstack, character); + ttok = parse_matched_pair (character, character, character, &ttoklen, (character == '`') ? P_COMMAND : 0); + pop_delimiter (dstack); + if (ttok == &matched_pair_error) + return -1; /* Bail immediately. */ + RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2, + token_buffer_size, TOKEN_DEFAULT_GROW_SIZE); + token[token_index++] = character; + strcpy (token + token_index, ttok); + token_index += ttoklen; + all_digit_token = 0; + quoted = 1; + dollar_present |= (character == '"' && strchr (ttok, '$') != 0); + FREE (ttok); + goto next_character; + } + +#ifdef COND_REGEXP + /* When parsing a regexp as a single word inside a conditional command, + we need to special-case characters special to both the shell and + regular expressions. Right now, that is only '(' and '|'. */ /*)*/ + if MBTEST((parser_state & PST_REGEXP) && (character == '(' || character == '|')) /*)*/ + { + if (character == '|') + goto got_character; + + push_delimiter (dstack, character); + ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0); + pop_delimiter (dstack); + if (ttok == &matched_pair_error) + return -1; /* Bail immediately. */ + RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2, + token_buffer_size, TOKEN_DEFAULT_GROW_SIZE); + token[token_index++] = character; + strcpy (token + token_index, ttok); + token_index += ttoklen; + FREE (ttok); + dollar_present = all_digit_token = 0; + goto next_character; + } +#endif /* COND_REGEXP */ + +#ifdef EXTENDED_GLOB + /* Parse a ksh-style extended pattern matching specification. */ + if MBTEST(extended_glob && PATTERN_CHAR (character)) + { + peek_char = shell_getc (1); + if MBTEST(peek_char == '(') /* ) */ + { + push_delimiter (dstack, peek_char); + ttok = parse_matched_pair (cd, '(', ')', &ttoklen, 0); + pop_delimiter (dstack); + if (ttok == &matched_pair_error) + return -1; /* Bail immediately. */ + RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3, + token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + token[token_index++] = character; + token[token_index++] = peek_char; + strcpy (token + token_index, ttok); + token_index += ttoklen; + FREE (ttok); + dollar_present = all_digit_token = 0; + goto next_character; + } + else + shell_ungetc (peek_char); + } +#endif /* EXTENDED_GLOB */ + + /* If the delimiter character is not single quote, parse some of + the shell expansions that must be read as a single word. */ + if (shellexp (character)) + { + peek_char = shell_getc (1); + /* $(...), <(...), >(...), $((...)), ${...}, and $[...] constructs */ + if MBTEST(peek_char == '(' || + ((peek_char == '{' || peek_char == '[') && character == '$')) /* ) ] } */ + { + if (peek_char == '{') /* } */ + ttok = parse_matched_pair (cd, '{', '}', &ttoklen, P_FIRSTCLOSE|P_DOLBRACE); + else if (peek_char == '(') /* ) */ + { + /* XXX - push and pop the `(' as a delimiter for use by + the command-oriented-history code. This way newlines + appearing in the $(...) string get added to the + history literally rather than causing a possibly- + incorrect `;' to be added. ) */ + push_delimiter (dstack, peek_char); + ttok = parse_comsub (cd, '(', ')', &ttoklen, P_COMMAND); + pop_delimiter (dstack); + } + else + ttok = parse_matched_pair (cd, '[', ']', &ttoklen, 0); + if (ttok == &matched_pair_error) + return -1; /* Bail immediately. */ + RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 3, + token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + token[token_index++] = character; + token[token_index++] = peek_char; + strcpy (token + token_index, ttok); + token_index += ttoklen; + FREE (ttok); + dollar_present = 1; + all_digit_token = 0; + goto next_character; + } + /* This handles $'...' and $"..." new-style quoted strings. */ + else if MBTEST(character == '$' && (peek_char == '\'' || peek_char == '"')) + { + int first_line; + + first_line = line_number; + push_delimiter (dstack, peek_char); + ttok = parse_matched_pair (peek_char, peek_char, peek_char, + &ttoklen, + (peek_char == '\'') ? P_ALLOWESC : 0); + pop_delimiter (dstack); + if (ttok == &matched_pair_error) + return -1; + if (peek_char == '\'') + { + ttrans = ansiexpand (ttok, 0, ttoklen - 1, &ttranslen); + free (ttok); + + /* Insert the single quotes and correctly quote any + embedded single quotes (allowed because P_ALLOWESC was + passed to parse_matched_pair). */ + ttok = sh_single_quote (ttrans); + free (ttrans); + ttranslen = strlen (ttok); + ttrans = ttok; + } + else + { + /* Try to locale-expand the converted string. */ + ttrans = localeexpand (ttok, 0, ttoklen - 1, first_line, &ttranslen); + free (ttok); + + /* Add the double quotes back */ + ttok = sh_mkdoublequoted (ttrans, ttranslen, 0); + free (ttrans); + ttranslen += 2; + ttrans = ttok; + } + + RESIZE_MALLOCED_BUFFER (token, token_index, ttranslen + 1, + token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + strcpy (token + token_index, ttrans); + token_index += ttranslen; + FREE (ttrans); + quoted = 1; + all_digit_token = 0; + goto next_character; + } + /* This could eventually be extended to recognize all of the + shell's single-character parameter expansions, and set flags.*/ + else if MBTEST(character == '$' && peek_char == '$') + { + RESIZE_MALLOCED_BUFFER (token, token_index, 3, + token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + token[token_index++] = '$'; + token[token_index++] = peek_char; + dollar_present = 1; + all_digit_token = 0; + goto next_character; + } + else + shell_ungetc (peek_char); + } + +#if defined (ARRAY_VARS) + /* Identify possible array subscript assignment; match [...]. If + parser_state&PST_COMPASSIGN, we need to parse [sub]=words treating + `sub' as if it were enclosed in double quotes. */ + else if MBTEST(character == '[' && /* ] */ + ((token_index > 0 && assignment_acceptable (last_read_token) && token_is_ident (token, token_index)) || + (token_index == 0 && (parser_state&PST_COMPASSIGN)))) + { + ttok = parse_matched_pair (cd, '[', ']', &ttoklen, P_ARRAYSUB); + if (ttok == &matched_pair_error) + return -1; /* Bail immediately. */ + RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 2, + token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + token[token_index++] = character; + strcpy (token + token_index, ttok); + token_index += ttoklen; + FREE (ttok); + all_digit_token = 0; + goto next_character; + } + /* Identify possible compound array variable assignment. */ + else if MBTEST(character == '=' && token_index > 0 && (assignment_acceptable (last_read_token) || (parser_state & PST_ASSIGNOK)) && token_is_assignment (token, token_index)) + { + peek_char = shell_getc (1); + if MBTEST(peek_char == '(') /* ) */ + { + ttok = parse_compound_assignment (&ttoklen); + + RESIZE_MALLOCED_BUFFER (token, token_index, ttoklen + 4, + token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + + token[token_index++] = '='; + token[token_index++] = '('; + if (ttok) + { + strcpy (token + token_index, ttok); + token_index += ttoklen; + } + token[token_index++] = ')'; + FREE (ttok); + all_digit_token = 0; + compound_assignment = 1; +#if 1 + goto next_character; +#else + goto got_token; /* ksh93 seems to do this */ +#endif + } + else + shell_ungetc (peek_char); + } +#endif + + /* When not parsing a multi-character word construct, shell meta- + characters break words. */ + if MBTEST(shellbreak (character)) + { + shell_ungetc (character); + goto got_token; + } + +got_character: + + if (character == CTLESC || character == CTLNUL) + { + RESIZE_MALLOCED_BUFFER (token, token_index, 2, token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + token[token_index++] = CTLESC; + } + else +got_escaped_character: + RESIZE_MALLOCED_BUFFER (token, token_index, 1, token_buffer_size, + TOKEN_DEFAULT_GROW_SIZE); + + token[token_index++] = character; + + all_digit_token &= DIGIT (character); + dollar_present |= character == '$'; + + next_character: + if (character == '\n' && SHOULD_PROMPT ()) + prompt_again (); + + /* We want to remove quoted newlines (that is, a \ pair) + unless we are within single quotes or pass_next_character is + set (the shell equivalent of literal-next). */ + cd = current_delimiter (dstack); + character = shell_getc (cd != '\'' && pass_next_character == 0); + } /* end for (;;) */ + +got_token: + + /* Calls to RESIZE_MALLOCED_BUFFER ensure there is sufficient room. */ + token[token_index] = '\0'; + + /* Check to see what thing we should return. If the last_read_token + is a `<', or a `&', or the character which ended this token is + a '>' or '<', then, and ONLY then, is this input token a NUMBER. + Otherwise, it is just a word, and should be returned as such. */ + if MBTEST(all_digit_token && (character == '<' || character == '>' || + last_read_token == LESS_AND || + last_read_token == GREATER_AND)) + { + if (legal_number (token, &lvalue) && (int)lvalue == lvalue) + { + yylval.number = lvalue; + return (NUMBER); + } + } + + /* Check for special case tokens. */ + result = (last_shell_getc_is_singlebyte) ? special_case_tokens (token) : -1; + if (result >= 0) + return result; + +#if defined (ALIAS) + /* Posix.2 does not allow reserved words to be aliased, so check for all + of them, including special cases, before expanding the current token + as an alias. */ + if MBTEST(posixly_correct) + CHECK_FOR_RESERVED_WORD (token); + + /* Aliases are expanded iff EXPAND_ALIASES is non-zero, and quoting + inhibits alias expansion. */ + if (expand_aliases && quoted == 0) + { + result = alias_expand_token (token); + if (result == RE_READ_TOKEN) + return (RE_READ_TOKEN); + else if (result == NO_EXPANSION) + parser_state &= ~PST_ALEXPNEXT; + } + + /* If not in Posix.2 mode, check for reserved words after alias + expansion. */ + if MBTEST(posixly_correct == 0) +#endif + CHECK_FOR_RESERVED_WORD (token); + + the_word = alloc_word_desc (); + the_word->word = (char *)xmalloc (1 + token_index); + the_word->flags = 0; + strcpy (the_word->word, token); + if (dollar_present) + the_word->flags |= W_HASDOLLAR; + if (quoted) + the_word->flags |= W_QUOTED; /*(*/ + if (compound_assignment && token[token_index-1] == ')') + the_word->flags |= W_COMPASSIGN; + /* A word is an assignment if it appears at the beginning of a + simple command, or after another assignment word. This is + context-dependent, so it cannot be handled in the grammar. */ + if (assignment (token, (parser_state & PST_COMPASSIGN) != 0)) + { + the_word->flags |= W_ASSIGNMENT; + /* Don't perform word splitting on assignment statements. */ + if (assignment_acceptable (last_read_token) || (parser_state & PST_COMPASSIGN) != 0) + { + the_word->flags |= W_NOSPLIT; + if (parser_state & PST_COMPASSIGN) + the_word->flags |= W_NOGLOB; /* XXX - W_NOBRACE? */ + } + } + + if (command_token_position (last_read_token)) + { + struct builtin *b; + b = builtin_address_internal (token, 0); + if (b && (b->flags & ASSIGNMENT_BUILTIN)) + parser_state |= PST_ASSIGNOK; + else if (STREQ (token, "eval") || STREQ (token, "let")) + parser_state |= PST_ASSIGNOK; + } + + yylval.word = the_word; + + if (token[0] == '{' && token[token_index-1] == '}' && + (character == '<' || character == '>')) + { + /* can use token; already copied to the_word */ + token[token_index-1] = '\0'; +#if defined (ARRAY_VARS) + if (legal_identifier (token+1) || valid_array_reference (token+1, 0)) +#else + if (legal_identifier (token+1)) +#endif + { + strcpy (the_word->word, token+1); +/*itrace("read_token_word: returning REDIR_WORD for %s", the_word->word);*/ + return (REDIR_WORD); + } + } + + result = ((the_word->flags & (W_ASSIGNMENT|W_NOSPLIT)) == (W_ASSIGNMENT|W_NOSPLIT)) + ? ASSIGNMENT_WORD : WORD; + + switch (last_read_token) + { + case FUNCTION: + parser_state |= PST_ALLOWOPNBRC; + function_dstart = line_number; + break; + case CASE: + case SELECT: + case FOR: + if (word_top < MAX_CASE_NEST) + word_top++; + word_lineno[word_top] = line_number; + break; + } + + return (result); +} + +/* Return 1 if TOKSYM is a token that after being read would allow + a reserved word to be seen, else 0. */ +static int +reserved_word_acceptable (toksym) + int toksym; +{ + switch (toksym) + { + case '\n': + case ';': + case '(': + case ')': + case '|': + case '&': + case '{': + case '}': /* XXX */ + case AND_AND: + case BANG: + case BAR_AND: + case DO: + case DONE: + case ELIF: + case ELSE: + case ESAC: + case FI: + case IF: + case OR_OR: + case SEMI_SEMI: + case SEMI_AND: + case SEMI_SEMI_AND: + case THEN: + case TIME: + case TIMEOPT: + case TIMEIGN: + case COPROC: + case UNTIL: + case WHILE: + case 0: + return 1; + default: +#if defined (COPROCESS_SUPPORT) + if (last_read_token == WORD && token_before_that == COPROC) + return 1; +#endif + if (last_read_token == WORD && token_before_that == FUNCTION) + return 1; + return 0; + } +} + +/* Return the index of TOKEN in the alist of reserved words, or -1 if + TOKEN is not a shell reserved word. */ +int +find_reserved_word (tokstr) + char *tokstr; +{ + int i; + for (i = 0; word_token_alist[i].word; i++) + if (STREQ (tokstr, word_token_alist[i].word)) + return i; + return -1; +} + +/* An interface to let the rest of the shell (primarily the completion + system) know what the parser is expecting. */ +int +parser_in_command_position () +{ + return (command_token_position (last_read_token)); +} + +#if 0 +#if defined (READLINE) +/* Called after each time readline is called. This insures that whatever + the new prompt string is gets propagated to readline's local prompt + variable. */ +static void +reset_readline_prompt () +{ + char *temp_prompt; + + if (prompt_string_pointer) + { + temp_prompt = (*prompt_string_pointer) + ? decode_prompt_string (*prompt_string_pointer) + : (char *)NULL; + + if (temp_prompt == 0) + { + temp_prompt = (char *)xmalloc (1); + temp_prompt[0] = '\0'; + } + + FREE (current_readline_prompt); + current_readline_prompt = temp_prompt; + } +} +#endif /* READLINE */ +#endif /* 0 */ + +#if defined (HISTORY) +/* A list of tokens which can be followed by newlines, but not by + semi-colons. When concatenating multiple lines of history, the + newline separator for such tokens is replaced with a space. */ +static const int no_semi_successors[] = { + '\n', '{', '(', ')', ';', '&', '|', + CASE, DO, ELSE, IF, SEMI_SEMI, SEMI_AND, SEMI_SEMI_AND, THEN, UNTIL, + WHILE, AND_AND, OR_OR, IN, + 0 +}; + +/* If we are not within a delimited expression, try to be smart + about which separators can be semi-colons and which must be + newlines. Returns the string that should be added into the + history entry. LINE is the line we're about to add; it helps + make some more intelligent decisions in certain cases. */ +char * +history_delimiting_chars (line) + const char *line; +{ + static int last_was_heredoc = 0; /* was the last entry the start of a here document? */ + register int i; + + if ((parser_state & PST_HEREDOC) == 0) + last_was_heredoc = 0; + + if (dstack.delimiter_depth != 0) + return ("\n"); + + /* We look for current_command_line_count == 2 because we are looking to + add the first line of the body of the here document (the second line + of the command). We also keep LAST_WAS_HEREDOC as a private sentinel + variable to note when we think we added the first line of a here doc + (the one with a "<<" somewhere in it) */ + if (parser_state & PST_HEREDOC) + { + if (last_was_heredoc) + { + last_was_heredoc = 0; + return "\n"; + } + return (current_command_line_count == 2 ? "\n" : ""); + } + + if (parser_state & PST_COMPASSIGN) + return (" "); + + /* First, handle some special cases. */ + /*(*/ + /* If we just read `()', assume it's a function definition, and don't + add a semicolon. If the token before the `)' was not `(', and we're + not in the midst of parsing a case statement, assume it's a + parenthesized command and add the semicolon. */ + /*)(*/ + if (token_before_that == ')') + { + if (two_tokens_ago == '(') /*)*/ /* function def */ + return " "; + /* This does not work for subshells inside case statement + command lists. It's a suboptimal solution. */ + else if (parser_state & PST_CASESTMT) /* case statement pattern */ + return " "; + else + return "; "; /* (...) subshell */ + } + else if (token_before_that == WORD && two_tokens_ago == FUNCTION) + return " "; /* function def using `function name' without `()' */ + + /* If we're not in a here document, but we think we're about to parse one, + and we would otherwise return a `;', return a newline to delimit the + line with the here-doc delimiter */ + else if ((parser_state & PST_HEREDOC) == 0 && current_command_line_count > 1 && last_read_token == '\n' && strstr (line, "<<")) + { + last_was_heredoc = 1; + return "\n"; + } + + else if (token_before_that == WORD && two_tokens_ago == FOR) + { + /* Tricky. `for i\nin ...' should not have a semicolon, but + `for i\ndo ...' should. We do what we can. */ + for (i = shell_input_line_index; whitespace (shell_input_line[i]); i++) + ; + if (shell_input_line[i] && shell_input_line[i] == 'i' && shell_input_line[i+1] == 'n') + return " "; + return ";"; + } + else if (two_tokens_ago == CASE && token_before_that == WORD && (parser_state & PST_CASESTMT)) + return " "; + + for (i = 0; no_semi_successors[i]; i++) + { + if (token_before_that == no_semi_successors[i]) + return (" "); + } + + return ("; "); +} +#endif /* HISTORY */ + +/* Issue a prompt, or prepare to issue a prompt when the next character + is read. */ +static void +prompt_again () +{ + char *temp_prompt; + + if (interactive == 0 || expanding_alias ()) /* XXX */ + return; + + ps1_prompt = get_string_value ("PS1"); + ps2_prompt = get_string_value ("PS2"); + + if (!prompt_string_pointer) + prompt_string_pointer = &ps1_prompt; + + temp_prompt = *prompt_string_pointer + ? decode_prompt_string (*prompt_string_pointer) + : (char *)NULL; + + if (temp_prompt == 0) + { + temp_prompt = (char *)xmalloc (1); + temp_prompt[0] = '\0'; + } + + current_prompt_string = *prompt_string_pointer; + prompt_string_pointer = &ps2_prompt; + +#if defined (READLINE) + if (!no_line_editing) + { + FREE (current_readline_prompt); + current_readline_prompt = temp_prompt; + } + else +#endif /* READLINE */ + { + FREE (current_decoded_prompt); + current_decoded_prompt = temp_prompt; + } +} + +int +get_current_prompt_level () +{ + return ((current_prompt_string && current_prompt_string == ps2_prompt) ? 2 : 1); +} + +void +set_current_prompt_level (x) + int x; +{ + prompt_string_pointer = (x == 2) ? &ps2_prompt : &ps1_prompt; + current_prompt_string = *prompt_string_pointer; +} + +static void +print_prompt () +{ + fprintf (stderr, "%s", current_decoded_prompt); + fflush (stderr); +} + +/* Return a string which will be printed as a prompt. The string + may contain special characters which are decoded as follows: + + \a bell (ascii 07) + \d the date in Day Mon Date format + \e escape (ascii 033) + \h the hostname up to the first `.' + \H the hostname + \j the number of active jobs + \l the basename of the shell's tty device name + \n CRLF + \r CR + \s the name of the shell + \t the time in 24-hour hh:mm:ss format + \T the time in 12-hour hh:mm:ss format + \@ the time in 12-hour hh:mm am/pm format + \A the time in 24-hour hh:mm format + \D{fmt} the result of passing FMT to strftime(3) + \u your username + \v the version of bash (e.g., 2.00) + \V the release of bash, version + patchlevel (e.g., 2.00.0) + \w the current working directory + \W the last element of $PWD + \! the history number of this command + \# the command number of this command + \$ a $ or a # if you are root + \nnn character code nnn in octal + \\ a backslash + \[ begin a sequence of non-printing chars + \] end a sequence of non-printing chars +*/ +#define PROMPT_GROWTH 48 +char * +decode_prompt_string (string) + char *string; +{ + WORD_LIST *list; + char *result, *t; + struct dstack save_dstack; + int last_exit_value, last_comsub_pid; +#if defined (PROMPT_STRING_DECODE) + int result_size, result_index; + int c, n, i; + char *temp, octal_string[4]; + struct tm *tm; + time_t the_time; + char timebuf[128]; + char *timefmt; + + result = (char *)xmalloc (result_size = PROMPT_GROWTH); + result[result_index = 0] = 0; + temp = (char *)NULL; + + while (c = *string++) + { + if (posixly_correct && c == '!') + { + if (*string == '!') + { + temp = savestring ("!"); + goto add_string; + } + else + { +#if !defined (HISTORY) + temp = savestring ("1"); +#else /* HISTORY */ + temp = itos (history_number ()); +#endif /* HISTORY */ + string--; /* add_string increments string again. */ + goto add_string; + } + } + if (c == '\\') + { + c = *string; + + switch (c) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + strncpy (octal_string, string, 3); + octal_string[3] = '\0'; + + n = read_octal (octal_string); + temp = (char *)xmalloc (3); + + if (n == CTLESC || n == CTLNUL) + { + temp[0] = CTLESC; + temp[1] = n; + temp[2] = '\0'; + } + else if (n == -1) + { + temp[0] = '\\'; + temp[1] = '\0'; + } + else + { + temp[0] = n; + temp[1] = '\0'; + } + + for (c = 0; n != -1 && c < 3 && ISOCTAL (*string); c++) + string++; + + c = 0; /* tested at add_string: */ + goto add_string; + + case 'd': + case 't': + case 'T': + case '@': + case 'A': + /* Make the current time/date into a string. */ + (void) time (&the_time); +#if defined (HAVE_TZSET) + sv_tz ("TZ"); /* XXX -- just make sure */ +#endif + tm = localtime (&the_time); + + if (c == 'd') + n = strftime (timebuf, sizeof (timebuf), "%a %b %d", tm); + else if (c == 't') + n = strftime (timebuf, sizeof (timebuf), "%H:%M:%S", tm); + else if (c == 'T') + n = strftime (timebuf, sizeof (timebuf), "%I:%M:%S", tm); + else if (c == '@') + n = strftime (timebuf, sizeof (timebuf), "%I:%M %p", tm); + else if (c == 'A') + n = strftime (timebuf, sizeof (timebuf), "%H:%M", tm); + + if (n == 0) + timebuf[0] = '\0'; + else + timebuf[sizeof(timebuf) - 1] = '\0'; + + temp = savestring (timebuf); + goto add_string; + + case 'D': /* strftime format */ + if (string[1] != '{') /* } */ + goto not_escape; + + (void) time (&the_time); + tm = localtime (&the_time); + string += 2; /* skip { */ + timefmt = xmalloc (strlen (string) + 3); + for (t = timefmt; *string && *string != '}'; ) + *t++ = *string++; + *t = '\0'; + c = *string; /* tested at add_string */ + if (timefmt[0] == '\0') + { + timefmt[0] = '%'; + timefmt[1] = 'X'; /* locale-specific current time */ + timefmt[2] = '\0'; + } + n = strftime (timebuf, sizeof (timebuf), timefmt, tm); + free (timefmt); + + if (n == 0) + timebuf[0] = '\0'; + else + timebuf[sizeof(timebuf) - 1] = '\0'; + + if (promptvars || posixly_correct) + /* Make sure that expand_prompt_string is called with a + second argument of Q_DOUBLE_QUOTES if we use this + function here. */ + temp = sh_backslash_quote_for_double_quotes (timebuf); + else + temp = savestring (timebuf); + goto add_string; + + case 'n': + temp = (char *)xmalloc (3); + temp[0] = no_line_editing ? '\n' : '\r'; + temp[1] = no_line_editing ? '\0' : '\n'; + temp[2] = '\0'; + goto add_string; + + case 's': + temp = base_pathname (shell_name); + temp = savestring (temp); + goto add_string; + + case 'v': + case 'V': + temp = (char *)xmalloc (16); + if (c == 'v') + strcpy (temp, dist_version); + else + sprintf (temp, "%s.%d", dist_version, patch_level); + goto add_string; + + case 'w': + case 'W': + { + /* Use the value of PWD because it is much more efficient. */ + char t_string[PATH_MAX]; + int tlen; + + temp = get_string_value ("PWD"); + + if (temp == 0) + { + if (getcwd (t_string, sizeof(t_string)) == 0) + { + t_string[0] = '.'; + tlen = 1; + } + else + tlen = strlen (t_string); + } + else + { + tlen = sizeof (t_string) - 1; + strncpy (t_string, temp, tlen); + } + t_string[tlen] = '\0'; + +#if defined (MACOSX) + /* Convert from "fs" format to "input" format */ + temp = fnx_fromfs (t_string, strlen (t_string)); + if (temp != t_string) + strcpy (t_string, temp); +#endif + +#define ROOT_PATH(x) ((x)[0] == '/' && (x)[1] == 0) +#define DOUBLE_SLASH_ROOT(x) ((x)[0] == '/' && (x)[1] == '/' && (x)[2] == 0) + /* Abbreviate \W as ~ if $PWD == $HOME */ + if (c == 'W' && (((t = get_string_value ("HOME")) == 0) || STREQ (t, t_string) == 0)) + { + if (ROOT_PATH (t_string) == 0 && DOUBLE_SLASH_ROOT (t_string) == 0) + { + t = strrchr (t_string, '/'); + if (t) + memmove (t_string, t + 1, strlen (t)); /* strlen(t) to copy NULL */ + } + } +#undef ROOT_PATH +#undef DOUBLE_SLASH_ROOT + else + { + /* polite_directory_format is guaranteed to return a string + no longer than PATH_MAX - 1 characters. */ + temp = polite_directory_format (t_string); + if (temp != t_string) + strcpy (t_string, temp); + } + + temp = trim_pathname (t_string, PATH_MAX - 1); + /* If we're going to be expanding the prompt string later, + quote the directory name. */ + if (promptvars || posixly_correct) + /* Make sure that expand_prompt_string is called with a + second argument of Q_DOUBLE_QUOTES if we use this + function here. */ + temp = sh_backslash_quote_for_double_quotes (t_string); + else + temp = savestring (t_string); + + goto add_string; + } + + case 'u': + if (current_user.user_name == 0) + get_current_user_info (); + temp = savestring (current_user.user_name); + goto add_string; + + case 'h': + case 'H': + temp = savestring (current_host_name); + if (c == 'h' && (t = (char *)strchr (temp, '.'))) + *t = '\0'; + goto add_string; + + case '#': + temp = itos (current_command_number); + goto add_string; + + case '!': +#if !defined (HISTORY) + temp = savestring ("1"); +#else /* HISTORY */ + temp = itos (history_number ()); +#endif /* HISTORY */ + goto add_string; + + case '$': + t = temp = (char *)xmalloc (3); + if ((promptvars || posixly_correct) && (current_user.euid != 0)) + *t++ = '\\'; + *t++ = current_user.euid == 0 ? '#' : '$'; + *t = '\0'; + goto add_string; + + case 'j': + temp = itos (count_all_jobs ()); + goto add_string; + + case 'l': +#if defined (HAVE_TTYNAME) + temp = (char *)ttyname (fileno (stdin)); + t = temp ? base_pathname (temp) : "tty"; + temp = savestring (t); +#else + temp = savestring ("tty"); +#endif /* !HAVE_TTYNAME */ + goto add_string; + +#if defined (READLINE) + case '[': + case ']': + if (no_line_editing) + { + string++; + break; + } + temp = (char *)xmalloc (3); + n = (c == '[') ? RL_PROMPT_START_IGNORE : RL_PROMPT_END_IGNORE; + i = 0; + if (n == CTLESC || n == CTLNUL) + temp[i++] = CTLESC; + temp[i++] = n; + temp[i] = '\0'; + goto add_string; +#endif /* READLINE */ + + case '\\': + case 'a': + case 'e': + case 'r': + temp = (char *)xmalloc (2); + if (c == 'a') + temp[0] = '\07'; + else if (c == 'e') + temp[0] = '\033'; + else if (c == 'r') + temp[0] = '\r'; + else /* (c == '\\') */ + temp[0] = c; + temp[1] = '\0'; + goto add_string; + + default: +not_escape: + temp = (char *)xmalloc (3); + temp[0] = '\\'; + temp[1] = c; + temp[2] = '\0'; + + add_string: + if (c) + string++; + result = + sub_append_string (temp, result, &result_index, &result_size); + temp = (char *)NULL; /* Freed in sub_append_string (). */ + result[result_index] = '\0'; + break; + } + } + else + { + RESIZE_MALLOCED_BUFFER (result, result_index, 3, result_size, PROMPT_GROWTH); + result[result_index++] = c; + result[result_index] = '\0'; + } + } +#else /* !PROMPT_STRING_DECODE */ + result = savestring (string); +#endif /* !PROMPT_STRING_DECODE */ + + /* Save the delimiter stack and point `dstack' to temp space so any + command substitutions in the prompt string won't result in screwing + up the parser's quoting state. */ + save_dstack = dstack; + dstack = temp_dstack; + dstack.delimiter_depth = 0; + + /* Perform variable and parameter expansion and command substitution on + the prompt string. */ + if (promptvars || posixly_correct) + { + last_exit_value = last_command_exit_value; + last_comsub_pid = last_command_subst_pid; + list = expand_prompt_string (result, Q_DOUBLE_QUOTES, 0); + free (result); + result = string_list (list); + dispose_words (list); + last_command_exit_value = last_exit_value; + last_command_subst_pid = last_comsub_pid; + } + else + { + t = dequote_string (result); + free (result); + result = t; + } + + dstack = save_dstack; + + return (result); +} + +/************************************************ + * * + * ERROR HANDLING * + * * + ************************************************/ + +/* Report a syntax error, and restart the parser. Call here for fatal + errors. */ +int +yyerror (msg) + const char *msg; +{ + report_syntax_error ((char *)NULL); + reset_parser (); + return (0); +} + +static char * +error_token_from_token (tok) + int tok; +{ + char *t; + + if (t = find_token_in_alist (tok, word_token_alist, 0)) + return t; + + if (t = find_token_in_alist (tok, other_token_alist, 0)) + return t; + + t = (char *)NULL; + /* This stuff is dicy and needs closer inspection */ + switch (current_token) + { + case WORD: + case ASSIGNMENT_WORD: + if (yylval.word) + t = savestring (yylval.word->word); + break; + case NUMBER: + t = itos (yylval.number); + break; + case ARITH_CMD: + if (yylval.word_list) + t = string_list (yylval.word_list); + break; + case ARITH_FOR_EXPRS: + if (yylval.word_list) + t = string_list_internal (yylval.word_list, " ; "); + break; + case COND_CMD: + t = (char *)NULL; /* punt */ + break; + } + + return t; +} + +static char * +error_token_from_text () +{ + char *msg, *t; + int token_end, i; + + t = shell_input_line; + i = shell_input_line_index; + token_end = 0; + msg = (char *)NULL; + + if (i && t[i] == '\0') + i--; + + while (i && (whitespace (t[i]) || t[i] == '\n')) + i--; + + if (i) + token_end = i + 1; + + while (i && (member (t[i], " \n\t;|&") == 0)) + i--; + + while (i != token_end && (whitespace (t[i]) || t[i] == '\n')) + i++; + + /* Return our idea of the offending token. */ + if (token_end || (i == 0 && token_end == 0)) + { + if (token_end) + msg = substring (t, i, token_end); + else /* one-character token */ + { + msg = (char *)xmalloc (2); + msg[0] = t[i]; + msg[1] = '\0'; + } + } + + return (msg); +} + +static void +print_offending_line () +{ + char *msg; + int token_end; + + msg = savestring (shell_input_line); + token_end = strlen (msg); + while (token_end && msg[token_end - 1] == '\n') + msg[--token_end] = '\0'; + + parser_error (line_number, "`%s'", msg); + free (msg); +} + +/* Report a syntax error with line numbers, etc. + Call here for recoverable errors. If you have a message to print, + then place it in MESSAGE, otherwise pass NULL and this will figure + out an appropriate message for you. */ +static void +report_syntax_error (message) + char *message; +{ + char *msg, *p; + + if (message) + { + parser_error (line_number, "%s", message); + if (interactive && EOF_Reached) + EOF_Reached = 0; + last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE; + return; + } + + /* If the line of input we're reading is not null, try to find the + objectionable token. First, try to figure out what token the + parser's complaining about by looking at current_token. */ + if (current_token != 0 && EOF_Reached == 0 && (msg = error_token_from_token (current_token))) + { + if (ansic_shouldquote (msg)) + { + p = ansic_quote (msg, 0, NULL); + free (msg); + msg = p; + } + parser_error (line_number, _("syntax error near unexpected token `%s'"), msg); + free (msg); + + if (interactive == 0) + print_offending_line (); + + last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE; + return; + } + + /* If looking at the current token doesn't prove fruitful, try to find the + offending token by analyzing the text of the input line near the current + input line index and report what we find. */ + if (shell_input_line && *shell_input_line) + { + msg = error_token_from_text (); + if (msg) + { + parser_error (line_number, _("syntax error near `%s'"), msg); + free (msg); + } + + /* If not interactive, print the line containing the error. */ + if (interactive == 0) + print_offending_line (); + } + else + { + msg = EOF_Reached ? _("syntax error: unexpected end of file") : _("syntax error"); + parser_error (line_number, "%s", msg); + /* When the shell is interactive, this file uses EOF_Reached + only for error reporting. Other mechanisms are used to + decide whether or not to exit. */ + if (interactive && EOF_Reached) + EOF_Reached = 0; + } + + last_command_exit_value = parse_and_execute_level ? EX_BADSYNTAX : EX_BADUSAGE; +} + +/* ??? Needed function. ??? We have to be able to discard the constructs + created during parsing. In the case of error, we want to return + allocated objects to the memory pool. In the case of no error, we want + to throw away the information about where the allocated objects live. + (dispose_command () will actually free the command.) */ +static void +discard_parser_constructs (error_p) + int error_p; +{ +} + +/************************************************ + * * + * EOF HANDLING * + * * + ************************************************/ + +/* Do that silly `type "bye" to exit' stuff. You know, "ignoreeof". */ + +/* A flag denoting whether or not ignoreeof is set. */ +int ignoreeof = 0; + +/* The number of times that we have encountered an EOF character without + another character intervening. When this gets above the limit, the + shell terminates. */ +int eof_encountered = 0; + +/* The limit for eof_encountered. */ +int eof_encountered_limit = 10; + +/* If we have EOF as the only input unit, this user wants to leave + the shell. If the shell is not interactive, then just leave. + Otherwise, if ignoreeof is set, and we haven't done this the + required number of times in a row, print a message. */ +static void +handle_eof_input_unit () +{ + if (interactive) + { + /* shell.c may use this to decide whether or not to write out the + history, among other things. We use it only for error reporting + in this file. */ + if (EOF_Reached) + EOF_Reached = 0; + + /* If the user wants to "ignore" eof, then let her do so, kind of. */ + if (ignoreeof) + { + if (eof_encountered < eof_encountered_limit) + { + fprintf (stderr, _("Use \"%s\" to leave the shell.\n"), + login_shell ? "logout" : "exit"); + eof_encountered++; + /* Reset the parsing state. */ + last_read_token = current_token = '\n'; + /* Reset the prompt string to be $PS1. */ + prompt_string_pointer = (char **)NULL; + prompt_again (); + return; + } + } + + /* In this case EOF should exit the shell. Do it now. */ + reset_parser (); + exit_builtin ((WORD_LIST *)NULL); + } + else + { + /* We don't write history files, etc., for non-interactive shells. */ + EOF_Reached = 1; + } +} + +/************************************************ + * * + * STRING PARSING FUNCTIONS * + * * + ************************************************/ + +/* It's very important that these two functions treat the characters + between ( and ) identically. */ + +static WORD_LIST parse_string_error; + +/* Take a string and run it through the shell parser, returning the + resultant word list. Used by compound array assignment. */ +WORD_LIST * +parse_string_to_word_list (s, flags, whom) + char *s; + int flags; + const char *whom; +{ + WORD_LIST *wl; + int tok, orig_current_token, orig_line_number, orig_input_terminator; + int orig_line_count; + int old_echo_input, old_expand_aliases; +#if defined (HISTORY) + int old_remember_on_history, old_history_expansion_inhibited; +#endif + +#if defined (HISTORY) + old_remember_on_history = remember_on_history; +# if defined (BANG_HISTORY) + old_history_expansion_inhibited = history_expansion_inhibited; +# endif + bash_history_disable (); +#endif + + orig_line_number = line_number; + orig_line_count = current_command_line_count; + orig_input_terminator = shell_input_line_terminator; + old_echo_input = echo_input_at_read; + old_expand_aliases = expand_aliases; + + push_stream (1); + last_read_token = WORD; /* WORD to allow reserved words here */ + current_command_line_count = 0; + echo_input_at_read = expand_aliases = 0; + + with_input_from_string (s, whom); + wl = (WORD_LIST *)NULL; + + if (flags & 1) + parser_state |= PST_COMPASSIGN|PST_REPARSE; + + while ((tok = read_token (READ)) != yacc_EOF) + { + if (tok == '\n' && *bash_input.location.string == '\0') + break; + if (tok == '\n') /* Allow newlines in compound assignments */ + continue; + if (tok != WORD && tok != ASSIGNMENT_WORD) + { + line_number = orig_line_number + line_number - 1; + orig_current_token = current_token; + current_token = tok; + yyerror (NULL); /* does the right thing */ + current_token = orig_current_token; + if (wl) + dispose_words (wl); + wl = &parse_string_error; + break; + } + wl = make_word_list (yylval.word, wl); + } + + last_read_token = '\n'; + pop_stream (); + +#if defined (HISTORY) + remember_on_history = old_remember_on_history; +# if defined (BANG_HISTORY) + history_expansion_inhibited = old_history_expansion_inhibited; +# endif /* BANG_HISTORY */ +#endif /* HISTORY */ + + echo_input_at_read = old_echo_input; + expand_aliases = old_expand_aliases; + + current_command_line_count = orig_line_count; + shell_input_line_terminator = orig_input_terminator; + + if (flags & 1) + parser_state &= ~(PST_COMPASSIGN|PST_REPARSE); + + if (wl == &parse_string_error) + { + last_command_exit_value = EXECUTION_FAILURE; + if (interactive_shell == 0 && posixly_correct) + jump_to_top_level (FORCE_EOF); + else + jump_to_top_level (DISCARD); + } + + return (REVERSE_LIST (wl, WORD_LIST *)); +} + +static char * +parse_compound_assignment (retlenp) + int *retlenp; +{ + WORD_LIST *wl, *rl; + int tok, orig_line_number, orig_token_size, orig_last_token, assignok; + char *saved_token, *ret; + + saved_token = token; + orig_token_size = token_buffer_size; + orig_line_number = line_number; + orig_last_token = last_read_token; + + last_read_token = WORD; /* WORD to allow reserved words here */ + + token = (char *)NULL; + token_buffer_size = 0; + + assignok = parser_state&PST_ASSIGNOK; /* XXX */ + + wl = (WORD_LIST *)NULL; /* ( */ + parser_state |= PST_COMPASSIGN; + + while ((tok = read_token (READ)) != ')') + { + if (tok == '\n') /* Allow newlines in compound assignments */ + { + if (SHOULD_PROMPT ()) + prompt_again (); + continue; + } + if (tok != WORD && tok != ASSIGNMENT_WORD) + { + current_token = tok; /* for error reporting */ + if (tok == yacc_EOF) /* ( */ + parser_error (orig_line_number, _("unexpected EOF while looking for matching `)'")); + else + yyerror(NULL); /* does the right thing */ + if (wl) + dispose_words (wl); + wl = &parse_string_error; + break; + } + wl = make_word_list (yylval.word, wl); + } + + FREE (token); + token = saved_token; + token_buffer_size = orig_token_size; + + parser_state &= ~PST_COMPASSIGN; + + if (wl == &parse_string_error) + { + last_command_exit_value = EXECUTION_FAILURE; + last_read_token = '\n'; /* XXX */ + if (interactive_shell == 0 && posixly_correct) + jump_to_top_level (FORCE_EOF); + else + jump_to_top_level (DISCARD); + } + + last_read_token = orig_last_token; /* XXX - was WORD? */ + + if (wl) + { + rl = REVERSE_LIST (wl, WORD_LIST *); + ret = string_list (rl); + dispose_words (rl); + } + else + ret = (char *)NULL; + + if (retlenp) + *retlenp = (ret && *ret) ? strlen (ret) : 0; + + if (assignok) + parser_state |= PST_ASSIGNOK; + + return ret; +} + +/************************************************ + * * + * SAVING AND RESTORING PARTIAL PARSE STATE * + * * + ************************************************/ + +sh_parser_state_t * +save_parser_state (ps) + sh_parser_state_t *ps; +{ + if (ps == 0) + ps = (sh_parser_state_t *)xmalloc (sizeof (sh_parser_state_t)); + if (ps == 0) + return ((sh_parser_state_t *)NULL); + + ps->parser_state = parser_state; + ps->token_state = save_token_state (); + + ps->input_line_terminator = shell_input_line_terminator; + ps->eof_encountered = eof_encountered; + + ps->prompt_string_pointer = prompt_string_pointer; + + ps->current_command_line_count = current_command_line_count; + +#if defined (HISTORY) + ps->remember_on_history = remember_on_history; +# if defined (BANG_HISTORY) + ps->history_expansion_inhibited = history_expansion_inhibited; +# endif +#endif + + ps->last_command_exit_value = last_command_exit_value; +#if defined (ARRAY_VARS) + ps->pipestatus = save_pipestatus_array (); +#endif + + ps->last_shell_builtin = last_shell_builtin; + ps->this_shell_builtin = this_shell_builtin; + + ps->expand_aliases = expand_aliases; + ps->echo_input_at_read = echo_input_at_read; + ps->need_here_doc = need_here_doc; + + ps->token = token; + ps->token_buffer_size = token_buffer_size; + /* Force reallocation on next call to read_token_word */ + token = 0; + token_buffer_size = 0; + + return (ps); +} + +void +restore_parser_state (ps) + sh_parser_state_t *ps; +{ + if (ps == 0) + return; + + parser_state = ps->parser_state; + if (ps->token_state) + { + restore_token_state (ps->token_state); + free (ps->token_state); + } + + shell_input_line_terminator = ps->input_line_terminator; + eof_encountered = ps->eof_encountered; + + prompt_string_pointer = ps->prompt_string_pointer; + + current_command_line_count = ps->current_command_line_count; + +#if defined (HISTORY) + remember_on_history = ps->remember_on_history; +# if defined (BANG_HISTORY) + history_expansion_inhibited = ps->history_expansion_inhibited; +# endif +#endif + + last_command_exit_value = ps->last_command_exit_value; +#if defined (ARRAY_VARS) + restore_pipestatus_array (ps->pipestatus); +#endif + + last_shell_builtin = ps->last_shell_builtin; + this_shell_builtin = ps->this_shell_builtin; + + expand_aliases = ps->expand_aliases; + echo_input_at_read = ps->echo_input_at_read; + need_here_doc = ps->need_here_doc; + + FREE (token); + token = ps->token; + token_buffer_size = ps->token_buffer_size; +} + +sh_input_line_state_t * +save_input_line_state (ls) + sh_input_line_state_t *ls; +{ + if (ls == 0) + ls = (sh_input_line_state_t *)xmalloc (sizeof (sh_input_line_state_t)); + if (ls == 0) + return ((sh_input_line_state_t *)NULL); + + ls->input_line = shell_input_line; + ls->input_line_size = shell_input_line_size; + ls->input_line_len = shell_input_line_len; + ls->input_line_index = shell_input_line_index; + + /* force reallocation */ + shell_input_line = 0; + shell_input_line_size = shell_input_line_len = shell_input_line_index = 0; + + return ls; +} + +void +restore_input_line_state (ls) + sh_input_line_state_t *ls; +{ + FREE (shell_input_line); + shell_input_line = ls->input_line; + shell_input_line_size = ls->input_line_size; + shell_input_line_len = ls->input_line_len; + shell_input_line_index = ls->input_line_index; + + set_line_mbstate (); +} + +/************************************************ + * * + * MULTIBYTE CHARACTER HANDLING * + * * + ************************************************/ + +#if defined (HANDLE_MULTIBYTE) +static void +set_line_mbstate () +{ + int c; + size_t i, previ, len; + mbstate_t mbs, prevs; + size_t mbclen; + + if (shell_input_line == NULL) + return; + len = strlen (shell_input_line); /* XXX - shell_input_line_len ? */ + shell_input_line_property = (char *)xrealloc (shell_input_line_property, len + 1); + + memset (&prevs, '\0', sizeof (mbstate_t)); + for (i = previ = 0; i < len; i++) + { + mbs = prevs; + + c = shell_input_line[i]; + if (c == EOF) + { + size_t j; + for (j = i; j < len; j++) + shell_input_line_property[j] = 1; + break; + } + + mbclen = mbrlen (shell_input_line + previ, i - previ + 1, &mbs); + if (mbclen == 1 || mbclen == (size_t)-1) + { + mbclen = 1; + previ = i + 1; + } + else if (mbclen == (size_t)-2) + mbclen = 0; + else if (mbclen > 1) + { + mbclen = 0; + previ = i + 1; + prevs = mbs; + } + else + { + /* XXX - what to do if mbrlen returns 0? (null wide character) */ + size_t j; + for (j = i; j < len; j++) + shell_input_line_property[j] = 1; + break; + } + + shell_input_line_property[i] = mbclen; + } +} +#endif /* HANDLE_MULTIBYTE */ diff --git a/y.tab.h b/y.tab.h new file mode 100644 index 000000000..fce407ea4 --- /dev/null +++ b/y.tab.h @@ -0,0 +1,174 @@ +/* A Bison parser, made by GNU Bison 3.0.4. */ + +/* Bison interface for Yacc-like parsers in C + + Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* As a special exception, you may create a larger work that contains + part or all of the Bison parser skeleton and distribute that work + under terms of your choice, so long as that work isn't itself a + parser generator using the skeleton or a modified version thereof + as a parser skeleton. Alternatively, if you modify or redistribute + the parser skeleton itself, you may (at your option) remove this + special exception, which will cause the skeleton and the resulting + Bison output files to be licensed under the GNU General Public + License without this special exception. + + This special exception was added by the Free Software Foundation in + version 2.2 of Bison. */ + +#ifndef YY_YY_Y_TAB_H_INCLUDED +# define YY_YY_Y_TAB_H_INCLUDED +/* Debug traces. */ +#ifndef YYDEBUG +# define YYDEBUG 0 +#endif +#if YYDEBUG +extern int yydebug; +#endif + +/* Token type. */ +#ifndef YYTOKENTYPE +# define YYTOKENTYPE + enum yytokentype + { + IF = 258, + THEN = 259, + ELSE = 260, + ELIF = 261, + FI = 262, + CASE = 263, + ESAC = 264, + FOR = 265, + SELECT = 266, + WHILE = 267, + UNTIL = 268, + DO = 269, + DONE = 270, + FUNCTION = 271, + COPROC = 272, + COND_START = 273, + COND_END = 274, + COND_ERROR = 275, + IN = 276, + BANG = 277, + TIME = 278, + TIMEOPT = 279, + TIMEIGN = 280, + WORD = 281, + ASSIGNMENT_WORD = 282, + REDIR_WORD = 283, + NUMBER = 284, + ARITH_CMD = 285, + ARITH_FOR_EXPRS = 286, + COND_CMD = 287, + AND_AND = 288, + OR_OR = 289, + GREATER_GREATER = 290, + LESS_LESS = 291, + LESS_AND = 292, + LESS_LESS_LESS = 293, + GREATER_AND = 294, + SEMI_SEMI = 295, + SEMI_AND = 296, + SEMI_SEMI_AND = 297, + LESS_LESS_MINUS = 298, + AND_GREATER = 299, + AND_GREATER_GREATER = 300, + LESS_GREATER = 301, + GREATER_BAR = 302, + BAR_AND = 303, + yacc_EOF = 304 + }; +#endif +/* Tokens. */ +#define IF 258 +#define THEN 259 +#define ELSE 260 +#define ELIF 261 +#define FI 262 +#define CASE 263 +#define ESAC 264 +#define FOR 265 +#define SELECT 266 +#define WHILE 267 +#define UNTIL 268 +#define DO 269 +#define DONE 270 +#define FUNCTION 271 +#define COPROC 272 +#define COND_START 273 +#define COND_END 274 +#define COND_ERROR 275 +#define IN 276 +#define BANG 277 +#define TIME 278 +#define TIMEOPT 279 +#define TIMEIGN 280 +#define WORD 281 +#define ASSIGNMENT_WORD 282 +#define REDIR_WORD 283 +#define NUMBER 284 +#define ARITH_CMD 285 +#define ARITH_FOR_EXPRS 286 +#define COND_CMD 287 +#define AND_AND 288 +#define OR_OR 289 +#define GREATER_GREATER 290 +#define LESS_LESS 291 +#define LESS_AND 292 +#define LESS_LESS_LESS 293 +#define GREATER_AND 294 +#define SEMI_SEMI 295 +#define SEMI_AND 296 +#define SEMI_SEMI_AND 297 +#define LESS_LESS_MINUS 298 +#define AND_GREATER 299 +#define AND_GREATER_GREATER 300 +#define LESS_GREATER 301 +#define GREATER_BAR 302 +#define BAR_AND 303 +#define yacc_EOF 304 + +/* Value type. */ +#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED + +union YYSTYPE +{ +#line 329 "/usr/homes/chet/src/bash/src/parse.y" /* yacc.c:1909 */ + + WORD_DESC *word; /* the word that we read. */ + int number; /* the number that we read. */ + WORD_LIST *word_list; + COMMAND *command; + REDIRECT *redirect; + ELEMENT element; + PATTERN_LIST *pattern; + +#line 162 "y.tab.h" /* yacc.c:1909 */ +}; + +typedef union YYSTYPE YYSTYPE; +# define YYSTYPE_IS_TRIVIAL 1 +# define YYSTYPE_IS_DECLARED 1 +#endif + + +extern YYSTYPE yylval; + +int yyparse (void); + +#endif /* !YY_YY_Y_TAB_H_INCLUDED */ -- 2.47.2