From: Chet Ramey Date: Tue, 13 Dec 2011 03:02:22 +0000 (-0500) Subject: commit bash-20100708 snapshot X-Git-Tag: bash-4.3-alpha~166 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ee56a86545c78ce8876c0ad04d6d2507f2b235b9;p=thirdparty%2Fbash.git commit bash-20100708 snapshot --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 11095486e..99bc6e9df 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -10200,3 +10200,10 @@ jobs.[ch] execute_cmd.c - changes to lastpipe code to make `pipefail' option, $PIPESTATUS, and $? work correctly. Uses append_process and job_exit_status + + 7/10 + ---- +subst.c + - when performing pattern substitution word expansions, a `&' in the + replacement string is replaced by the text matched by the pattern. + The `&' can be quoted with a backslash to inhibit the expansion diff --git a/CWRU/CWRU.chlog~ b/CWRU/CWRU.chlog~ index ce9009c15..11095486e 100644 --- a/CWRU/CWRU.chlog~ +++ b/CWRU/CWRU.chlog~ @@ -10194,6 +10194,8 @@ jobs.[ch] takes info, creates a PROCESS from them, and adds it to the end of the passed job id's pipeline. lastpipe code uses it to add a dummy process for the last command in the pipeline + - freeze_jobs_list: new utility function so rest of shell can freeze + the jobs list. Used by the lastpipe code execute_cmd.c - changes to lastpipe code to make `pipefail' option, $PIPESTATUS, and diff --git a/bashline.c b/bashline.c index 575a0e257..7fee50d29 100644 --- a/bashline.c +++ b/bashline.c @@ -529,11 +529,8 @@ initialize_readline () enable_hostname_completion (perform_hostname_completion); /* characters that need to be quoted when appearing in filenames. */ -#if 0 - rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{"; /*}*/ -#else rl_filename_quote_characters = " \t\n\\\"'@<>=;|&()#$`?*[!:{~"; /*}*/ -#endif + rl_filename_quoting_function = bash_quote_filename; rl_filename_dequoting_function = bash_dequote_filename; rl_char_is_quoted_p = char_is_quoted; diff --git a/bashline.c~ b/bashline.c~ index eb86b3b71..575a0e257 100644 --- a/bashline.c~ +++ b/bashline.c~ @@ -1,6 +1,6 @@ /* bashline.c -- Bash's interface to the readline library. */ -/* Copyright (C) 1987-2009 Free Software Foundation, Inc. +/* Copyright (C) 1987-2010 Free Software Foundation, Inc. This file is part of GNU Bash, the Bourne Again SHell. diff --git a/doc/bash.1 b/doc/bash.1 index e65aec773..626aed701 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -10,7 +10,7 @@ .\" bash_builtins, strip all but Built-Ins section .if \n(zZ=1 .ig zZ .if \n(zY=1 .ig zY -.TH BASH 1 "2010 July 2" "GNU Bash-4.1" +.TH BASH 1 "2010 July 2" "GNU Bash-4.2" .\" .\" There's some problem with having a `@' .\" in a tagged paragraph with the BSD man macros. diff --git a/doc/bash.1~ b/doc/bash.1~ index 98faf6943..626aed701 100644 --- a/doc/bash.1~ +++ b/doc/bash.1~ @@ -10,7 +10,7 @@ .\" bash_builtins, strip all but Built-Ins section .if \n(zZ=1 .ig zZ .if \n(zY=1 .ig zY -.TH BASH 1 "2010 July 2" "GNU Bash-4.1" +.TH BASH 1 "2010 July 2" "GNU Bash-4.2" .\" .\" There's some problem with having a `@' .\" in a tagged paragraph with the BSD man macros. @@ -3868,8 +3868,10 @@ in multiple identically-named entries in the environment passed to the shell's children. Care should be taken in cases where this may cause a problem. .PP -Functions may be recursive. No limit is imposed on the number -of recursive calls. +Functions may be recursive. +The \fBFUNCNEST\fP variable may be used to limit the depth of the +function call stack and restrict the number of function invocations. +By default, no limit is imposed on the number of recursive calls. .SH "ARITHMETIC EVALUATION" The shell allows arithmetic expressions to be evaluated, under certain circumstances (see the \fBlet\fP and \fBdeclare\fP builtin diff --git a/doc/bashref.texi b/doc/bashref.texi index 1f3bacbee..f4faf8808 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -820,7 +820,7 @@ until it evaluates to zero. Each time @var{expr2} evaluates to a non-zero value, @var{commands} are executed and the arithmetic expression @var{expr3} is evaluated. If any expression is omitted, it behaves as if it evaluates to 1. -The return value is the exit status of the last command in @var{list} +The return value is the exit status of the last command in @var{commands} that is executed, or false if any of the expressions is invalid. @end table diff --git a/doc/bashref.texi~ b/doc/bashref.texi~ index d214d20ee..1f3bacbee 100644 --- a/doc/bashref.texi~ +++ b/doc/bashref.texi~ @@ -1328,8 +1328,10 @@ in multiple identically-named entries in the environment passed to the shell's children. Care should be taken in cases where this may cause a problem. -Functions may be recursive. No limit is placed on the number of -recursive calls. +Functions may be recursive. +The @code{FUNCNEST} variable may be used to limit the depth of the +function call stack and restrict the number of function invocations. +By default, no limit is placed on the number of recursive calls. @node Shell Parameters @section Shell Parameters diff --git a/execute_cmd.c b/execute_cmd.c index 8132566b0..af556fa91 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -2219,10 +2219,6 @@ execute_pipeline (command, asynchronous, pipe_in, pipe_out, fds_to_close) if (prev >= 0) add_unwind_protect (close, prev); - /* XXX - might need to temporarily put shell process in pgrp of the pipeline, - so after we give the terminal to that process group in stop_pipeline, the - shell can still access it. Would need to give it to - jobs[lastpipe_jid]->pgrp */ exec_result = execute_command_internal (cmd, asynchronous, prev, pipe_out, fds_to_close); if (lstdin > 0) diff --git a/lib/readline/keymaps.h b/lib/readline/keymaps.h index 6c4611d3e..af8d5d997 100644 --- a/lib/readline/keymaps.h +++ b/lib/readline/keymaps.h @@ -52,11 +52,6 @@ typedef struct _keymap_entry { #define KEYMAP_SIZE 257 #define ANYOTHERKEY KEYMAP_SIZE-1 -/* I wanted to make the above structure contain a union of: - union { rl_command_func_t *function; struct _keymap_entry *keymap; } value; - but this made it impossible for me to create a static array. - Maybe I need C lessons. */ - typedef KEYMAP_ENTRY KEYMAP_ENTRY_ARRAY[KEYMAP_SIZE]; typedef KEYMAP_ENTRY *Keymap; diff --git a/lib/sh/strftime.c b/lib/sh/strftime.c index 572baaee0..5335ead15 100644 --- a/lib/sh/strftime.c +++ b/lib/sh/strftime.c @@ -114,6 +114,11 @@ extern int timezone, altzone; #undef min /* just in case */ +/* format for %+ */ +#ifndef NATIONAL_FORMAT +#define NATIONAL_FORMAT "%a %b %e %H:%M:%S %Z %Y" +#endif + /* min --- return minimum of two numbers */ static inline int diff --git a/subst.c b/subst.c index e6cb89dd4..d20b055e6 100644 --- a/subst.c +++ b/subst.c @@ -288,6 +288,8 @@ static int get_var_and_type __P((char *, char *, int, SHELL_VAR **, char **)); static char *mb_substring __P((char *, int, int)); static char *parameter_brace_substring __P((char *, char *, char *, int)); +static int shouldexp_replacement __P((char *)); + static char *pos_params_pat_subst __P((char *, char *, char *, int)); static char *parameter_brace_patsub __P((char *, char *, char *, int)); @@ -6327,21 +6329,40 @@ parameter_brace_substring (varname, value, substr, quoted) /* */ /****************************************************************/ +static int +shouldexp_replacement (s) + char *s; +{ + register char *p; + + for (p = s; p && *p; p++) + { + if (*p == '\\') + p++; + else if (*p == '&') + return 1; + } + return 0; +} + char * pat_subst (string, pat, rep, mflags) char *string, *pat, *rep; int mflags; { - char *ret, *s, *e, *str; - int rsize, rptr, l, replen, mtype; + char *ret, *s, *e, *str, *rstr, *mstr; + int rsize, rptr, l, replen, mtype, rxpand, rslen, mlen; mtype = mflags & MATCH_TYPEMASK; + rxpand = (rep && *rep) ? shouldexp_replacement (rep) : 0; + /* Special cases: * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING * with REP and return the result. * 2. A null pattern with mtype == MATCH_END means to append REP to * STRING and return the result. + * These don't understand or process `&' in the replacement string. */ if ((pat == 0 || *pat == 0) && (mtype == MATCH_BEG || mtype == MATCH_END)) { @@ -6371,7 +6392,25 @@ pat_subst (string, pat, rep, mflags) if (match_pattern (str, pat, mtype, &s, &e) == 0) break; l = s - str; - RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64); + + if (rxpand) + { + int x; + mlen = e - s; + mstr = xmalloc (mlen + 1); + for (x = 0; x < mlen; x++) + mstr[x] = s[x]; + mstr[mlen] = '\0'; + rstr = strcreplace (rep, '&', mstr, 0); + rslen = strlen (rstr); + } + else + { + rstr = rep; + rslen = replen; + } + + RESIZE_MALLOCED_BUFFER (ret, rptr, (l + rslen), rsize, 64); /* OK, now copy the leading unmatched portion of the string (from str to s) to ret starting at rptr (the current offset). Then copy @@ -6384,11 +6423,14 @@ pat_subst (string, pat, rep, mflags) } if (replen) { - strncpy (ret + rptr, rep, replen); - rptr += replen; + strncpy (ret + rptr, rstr, rslen); + rptr += rslen; } str = e; /* e == end of match */ + if (rstr != rep) + free (rstr); + if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY) break; diff --git a/subst.c~ b/subst.c~ index 626ec80f8..b27c0310e 100644 --- a/subst.c~ +++ b/subst.c~ @@ -288,6 +288,8 @@ static int get_var_and_type __P((char *, char *, int, SHELL_VAR **, char **)); static char *mb_substring __P((char *, int, int)); static char *parameter_brace_substring __P((char *, char *, char *, int)); +static int shouldexp_replacement __P((char *)); + static char *pos_params_pat_subst __P((char *, char *, char *, int)); static char *parameter_brace_patsub __P((char *, char *, char *, int)); @@ -3942,6 +3944,8 @@ remove_pattern (param, pattern, op) return ((xret == param) ? savestring (param) : xret); } oret = ret = remove_wpattern (wparam, n, wpattern, op); + /* Don't bother to convert wparam back to multibyte string if nothing + matched; just return copy of original string */ if (ret == wparam) { free (wparam); @@ -6325,16 +6329,34 @@ parameter_brace_substring (varname, value, substr, quoted) /* */ /****************************************************************/ +static int +shouldexp_replacement (s) + char *s; +{ + register char *p; + + for (p = s; p && *p; p++) + { + if (*p == '\\') + p++; + else if (*p == '&') + return 1; + } + return 0; +} + char * pat_subst (string, pat, rep, mflags) char *string, *pat, *rep; int mflags; { - char *ret, *s, *e, *str; - int rsize, rptr, l, replen, mtype; + char *ret, *s, *e, *str, *rstr, *mstr; + int rsize, rptr, l, replen, mtype, rxpand, rslen, mlen; mtype = mflags & MATCH_TYPEMASK; + rxpand = (rep && *rep) ? shouldexp_replacement (rep) : 0; + /* Special cases: * 1. A null pattern with mtype == MATCH_BEG means to prefix STRING * with REP and return the result. @@ -6369,7 +6391,25 @@ pat_subst (string, pat, rep, mflags) if (match_pattern (str, pat, mtype, &s, &e) == 0) break; l = s - str; - RESIZE_MALLOCED_BUFFER (ret, rptr, (l + replen), rsize, 64); + + if (rxpand) + { + int x; + mlen = e - s; + mstr = xmalloc (mlen + 1); + for (x = 0; x < mlen; x++) + mstr[x] = s[x]; + mstr[mlen] = '\0'; + rstr = strcreplace (rep, '&', mstr, 0); + rslen = strlen (rstr); + } + else + { + rstr = rep; + rslen = replen; + } + + RESIZE_MALLOCED_BUFFER (ret, rptr, (l + rslen), rsize, 64); /* OK, now copy the leading unmatched portion of the string (from str to s) to ret starting at rptr (the current offset). Then copy @@ -6382,11 +6422,14 @@ pat_subst (string, pat, rep, mflags) } if (replen) { - strncpy (ret + rptr, rep, replen); - rptr += replen; + strncpy (ret + rptr, rstr, rslen); + rptr += rslen; } str = e; /* e == end of match */ + if (rstr != rep) + free (rstr); + if (((mflags & MATCH_GLOBREP) == 0) || mtype != MATCH_ANY) break; diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index 72ec06a2c..3efcf32d6 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -1,4 +1,4 @@ -BUILD_DIR=/usr/local/build/bash/bash-current +BUILD_DIR=/usr/local/build/chet/bash/bash-current THIS_SH=$BUILD_DIR/bash PATH=$PATH:$BUILD_DIR diff --git a/tests/lastpipe.tests b/tests/lastpipe.tests index 2b0990e31..c846316e5 100644 --- a/tests/lastpipe.tests +++ b/tests/lastpipe.tests @@ -1,3 +1,18 @@ +if [ -x /usr/bin/true ]; then + bintrue=/usr/bin/true +elif [ -x /bin/true ]; then + bintrue=/bin/true +else + bintrue=true +fi +if [ -x /usr/bin/false ]; then + binfalse=/usr/bin/false +elif [ -x /bin/false ]; then + binfalse=/bin/false +else + binfalse=true +fi + shopt -s lastpipe unset foo bar @@ -20,17 +35,17 @@ echo last = $last exit 142 | false echo $? -- ${PIPESTATUS[@]} -true | false | /usr/bin/true +true | false | $bintrue echo $? -- ${PIPESTATUS[@]} -true | /usr/bin/true | false +true | $bintrue | false echo $? -- ${PIPESTATUS[@]} set -o pipefail -true | /usr/bin/true | false +true | $bintrue | false echo $? -- ${PIPESTATUS[@]} -true | /usr/bin/false | true +true | $binfalse | true echo $? -- ${PIPESTATUS[@]} set +o pipefail diff --git a/tests/printf3.sub b/tests/printf3.sub index 0de273af1..85a2705c2 100644 --- a/tests/printf3.sub +++ b/tests/printf3.sub @@ -44,10 +44,10 @@ printf "current time: %(%F %r)T\n" $SECS printf "epoch time: %(%F %r %z)T\n" 0 printf "random time: %(%F %r %z)T\n" $SECS -printf "local time: %(%+)T\n" $SECS +printf "local time: %(%a %b %e %H:%M:%S %Z %Y)T\n" $SECS # test fieldwidth, justification, precision -printf "%-40.50(%+)T date-style time\n" $SECS +printf "%-40.50(%a %b %e %H:%M:%S %Z %Y)T date-style time\n" $SECS # test fieldwidth, justification, precision, embedded parens printf "%-40.50(%x (foo) %X)T date-style time\n" $SECS