From: Chet Ramey Date: Wed, 7 Dec 2011 14:22:12 +0000 (-0500) Subject: commit bash-20080417 snapshot X-Git-Tag: bash-4.0-alpha~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=adfe6c99d0b1e39afa93074497ec2038231223d2;p=thirdparty%2Fbash.git commit bash-20080417 snapshot --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index d2d928211..bb7e37212 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -15585,3 +15585,10 @@ MANIFEST,Makefile.in,builtins/Makefile.in arrayfunc.[ch] - new function, bind_array_element, to support mapfile builtin + + 4/20 + ---- +expr.c + - fix operator precendence in expcond(): term after the `:' is + a conditional-expression, not a logical-OR-expression (using C + terminology). Bug reported by diff --git a/CWRU/CWRU.chlog~ b/CWRU/CWRU.chlog~ index 3ddb2a8b3..d2d928211 100644 --- a/CWRU/CWRU.chlog~ +++ b/CWRU/CWRU.chlog~ @@ -14313,6 +14313,11 @@ subst.c - change cond_expand_word to translate SPECIAL==2 into passing QGLOB_REGEXP to quote_string_for_globbing +locale.c + - by default, if all else fails, set shell's idea of locale to "" + instead of its idea of `default_locale' -- the library functions + behave better with that value + 2/2 --- builtins/printf.def diff --git a/builtins/evalstring.c b/builtins/evalstring.c index 56461b3c8..beffa3667 100644 --- a/builtins/evalstring.c +++ b/builtins/evalstring.c @@ -79,11 +79,13 @@ parse_and_execute_cleanup () run_unwind_frame ("parse_and_execute_top"); } +#if defined (HISTORY) static void set_history_remembering () { remember_on_history = enable_history_list; } +#endif /* Parse and execute the commands in STRING. Returns whatever execute_command () returns. This frees STRING. FLAGS is a diff --git a/expr.c b/expr.c index b325a82f8..99bd106cf 100644 --- a/expr.c +++ b/expr.c @@ -520,7 +520,8 @@ expcond () set_noeval = 1; noeval++; } - val2 = explor (); + + val2 = expcond (); if (set_noeval) noeval--; rval = cval ? val1 : val2; diff --git a/expr.c~ b/expr.c~ index 3ec64c010..e5f5034e4 100644 --- a/expr.c~ +++ b/expr.c~ @@ -286,6 +286,8 @@ expr_unwind () free (expr_stack[expr_depth]); } free (expr_stack[expr_depth]); /* free the allocated EXPR_CONTEXT */ + + noeval = 0; /* XXX */ } static void @@ -319,6 +321,7 @@ evalexp (expr, validp) procenv_t oevalbuf; val = 0; + noeval = 0; FASTCOPY (evalbuf, oevalbuf, sizeof (evalbuf)); @@ -517,7 +520,11 @@ expcond () set_noeval = 1; noeval++; } +#if 0 val2 = explor (); +#else + val2 = expcond (); +#endif if (set_noeval) noeval--; rval = cval ? val1 : val2; @@ -929,6 +936,7 @@ expr_streval (tok, e) if (interactive_shell) { expr_unwind (); + top_level_cleanup (); jump_to_top_level (DISCARD); } else @@ -1028,8 +1036,6 @@ readtok () if (c) cp++; - lasttp = tp = cp - 1; - if (c == '\0') { lasttok = curtok; @@ -1037,6 +1043,7 @@ readtok () tp = cp; return; } + lasttp = tp = cp - 1; if (legal_variable_starter (c)) { diff --git a/redir.c b/redir.c index 47a6097c8..2baf5041b 100644 --- a/redir.c +++ b/redir.c @@ -156,7 +156,7 @@ redirection_error (temp, error) #endif /* RESTRICTED_SHELL */ case HEREDOC_REDIRECT: - internal_error (_("cannot create temp file for here document: %s"), strerror (heredoc_errno)); + internal_error (_("cannot create temp file for here-document: %s"), strerror (heredoc_errno)); break; default: diff --git a/redir.c~ b/redir.c~ index 1da53c0bf..47a6097c8 100644 --- a/redir.c~ +++ b/redir.c~ @@ -778,6 +778,11 @@ do_redirection_internal (redirect, flags) fflush (stdout); fpurge (stdout); } + else if (redirector == 2 && fileno (stderr) == redirector) + { + fflush (stderr); + fpurge (stderr); + } if ((fd != redirector) && (dup2 (fd, redirector) < 0)) return (errno); diff --git a/tests/arith.right b/tests/arith.right index 52c619d39..51d740e49 100644 --- a/tests/arith.right +++ b/tests/arith.right @@ -51,6 +51,7 @@ 1 1 32 +4 20 1,i+=2 30 @@ -59,7 +60,7 @@ 1,i+=2 30 1,j+=2 -./arith.tests: line 108: 1 ? 20 : x+=2: attempted assignment to non-variable (error token is "+=2") +./arith.tests: line 114: 1 ? 20 : x+=2: attempted assignment to non-variable (error token is "+=2") 20 6 6,5,3 @@ -79,16 +80,16 @@ 36 62 63 -./arith.tests: line 143: 3425#56: invalid arithmetic base (error token is "3425#56") +./arith.tests: line 149: 3425#56: invalid arithmetic base (error token is "3425#56") 0 -./arith.tests: line 149: 7 = 43 : attempted assignment to non-variable (error token is "= 43 ") -./arith.tests: line 150: 2#44: value too great for base (error token is "2#44") -./arith.tests: line 151: 44 / 0 : division by 0 (error token is "0 ") -./arith.tests: line 152: let: jv += $iv: syntax error: operand expected (error token is "$iv") -./arith.tests: line 153: jv += $iv : syntax error: operand expected (error token is "$iv ") -./arith.tests: line 154: let: rv = 7 + (43 * 6: missing `)' (error token is "6") -./arith.tests: line 158: 0#4: invalid number (error token is "0#4") -./arith.tests: line 159: 2#110#11: invalid number (error token is "2#110#11") +./arith.tests: line 155: 7 = 43 : attempted assignment to non-variable (error token is "= 43 ") +./arith.tests: line 156: 2#44: value too great for base (error token is "2#44") +./arith.tests: line 157: 44 / 0 : division by 0 (error token is "0 ") +./arith.tests: line 158: let: jv += $iv: syntax error: operand expected (error token is "$iv") +./arith.tests: line 159: jv += $iv : syntax error: operand expected (error token is "$iv ") +./arith.tests: line 160: let: rv = 7 + (43 * 6: missing `)' (error token is "6") +./arith.tests: line 164: 0#4: invalid number (error token is "0#4") +./arith.tests: line 165: 2#110#11: invalid number (error token is "2#110#11") abc def ghi @@ -96,15 +97,15 @@ ok 6 1 0 -./arith.tests: line 177: 4 + : syntax error: operand expected (error token is "+ ") +./arith.tests: line 183: 4 + : syntax error: operand expected (error token is "+ ") 16 -./arith.tests: line 182: 4 ? : 3 + 5 : expression expected (error token is ": 3 + 5 ") -./arith.tests: line 183: 1 ? 20 : `:' expected for conditional expression (error token is "20 ") -./arith.tests: line 184: 4 ? 20 : : expression expected (error token is ": ") +./arith.tests: line 188: 4 ? : 3 + 5 : expression expected (error token is ": 3 + 5 ") +./arith.tests: line 189: 1 ? 20 : `:' expected for conditional expression (error token is "20 ") +./arith.tests: line 190: 4 ? 20 : : expression expected (error token is ": ") 9 -./arith.tests: line 190: 0 && B=42 : attempted assignment to non-variable (error token is "=42 ") +./arith.tests: line 196: 0 && B=42 : attempted assignment to non-variable (error token is "=42 ") 9 -./arith.tests: line 193: 1 || B=88 : attempted assignment to non-variable (error token is "=88 ") +./arith.tests: line 199: 1 || B=88 : attempted assignment to non-variable (error token is "=88 ") 9 0 9 @@ -130,11 +131,11 @@ ok 4 4 7 -./arith.tests: line 241: 7-- : syntax error: operand expected (error token is "- ") -./arith.tests: line 243: --x=7 : attempted assignment to non-variable (error token is "=7 ") -./arith.tests: line 244: ++x=7 : attempted assignment to non-variable (error token is "=7 ") -./arith.tests: line 246: x++=7 : attempted assignment to non-variable (error token is "=7 ") -./arith.tests: line 247: x--=7 : attempted assignment to non-variable (error token is "=7 ") +./arith.tests: line 247: 7-- : syntax error: operand expected (error token is "- ") +./arith.tests: line 249: --x=7 : attempted assignment to non-variable (error token is "=7 ") +./arith.tests: line 250: ++x=7 : attempted assignment to non-variable (error token is "=7 ") +./arith.tests: line 252: x++=7 : attempted assignment to non-variable (error token is "=7 ") +./arith.tests: line 253: x--=7 : attempted assignment to non-variable (error token is "=7 ") 4 7 -7 @@ -191,13 +192,13 @@ ok 7 7 8 12 -./arith.tests: line 268: ((: x=9 y=41 : syntax error in expression (error token is "y=41 ") -./arith.tests: line 272: a b: syntax error in expression (error token is "b") -./arith.tests: line 273: ((: a b: syntax error in expression (error token is "b") +./arith.tests: line 274: ((: x=9 y=41 : syntax error in expression (error token is "y=41 ") +./arith.tests: line 278: a b: syntax error in expression (error token is "b") +./arith.tests: line 279: ((: a b: syntax error in expression (error token is "b") 42 42 42 42 42 42 -./arith.tests: line 284: b[c]d: syntax error in expression (error token is "d") +./arith.tests: line 290: b[c]d: syntax error in expression (error token is "d") diff --git a/tests/arith.tests b/tests/arith.tests index 33622e76b..9e82bb1db 100644 --- a/tests/arith.tests +++ b/tests/arith.tests @@ -84,6 +84,12 @@ echo $(( 4<(2+3) ? 1 : 32)) echo $(( (2+2)<(2+3) ? 1 : 32)) echo $(( (2+2)>(2+3) ? 1 : 32)) +# bug in bash versions through bash-3.2 +S=105 +W=$((S>99?4:S>9?3:S>0?2:0)) +echo $W +unset W S + # check that the unevaluated part of the ternary operator does not do # evaluation or assignment x=i+=2 diff --git a/tests/arith.tests~ b/tests/arith.tests~ new file mode 100644 index 000000000..33622e76b --- /dev/null +++ b/tests/arith.tests~ @@ -0,0 +1,284 @@ +set +o posix +declare -i iv jv + +iv=$(( 3 + 5 * 32 )) +echo $iv +iv=iv+3 +echo $iv +iv=2 +jv=iv + +let "jv *= 2" +echo $jv +jv=$(( $jv << 2 )) +echo $jv + +let jv="$jv / 2" +echo $jv +jv="jv >> 2" +echo $jv + +iv=$((iv+ $jv)) +echo $iv +echo $((iv -= jv)) +echo $iv +echo $(( iv == jv )) +echo $(( iv != $jv )) +echo $(( iv < jv )) +echo $(( $iv > $jv )) +echo $(( iv <= $jv )) +echo $(( $iv >= jv )) + +echo $jv +echo $(( ~$jv )) +echo $(( ~1 )) +echo $(( ! 0 )) + +echo $(( jv % 2 )) +echo $(( $iv % 4 )) + +echo $(( iv <<= 16 )) +echo $(( iv %= 33 )) + +echo $(( 33 & 55 )) +echo $(( 33 | 17 )) + +echo $(( iv && $jv )) +echo $(( $iv || jv )) + +echo $(( iv && 0 )) +echo $(( iv & 0 )) +echo $(( iv && 1 )) +echo $(( iv & 1 )) + +echo $(( $jv || 0 )) +echo $(( jv | 0 )) +echo $(( jv | 1 )) +echo $(( $jv || 1 )) + +let 'iv *= jv' +echo $iv +echo $jv +let "jv += $iv" +echo $jv + +echo $(( jv /= iv )) +echo $(( jv <<= 8 )) +echo $(( jv >>= 4 )) + +echo $(( iv |= 4 )) +echo $(( iv &= 4 )) + +echo $(( iv += (jv + 9))) +echo $(( (iv + 4) % 7 )) + +# unary plus, minus +echo $(( +4 - 8 )) +echo $(( -4 + 8 )) + +# conditional expressions +echo $(( 4<5 ? 1 : 32)) +echo $(( 4>5 ? 1 : 32)) +echo $(( 4>(2+3) ? 1 : 32)) +echo $(( 4<(2+3) ? 1 : 32)) +echo $(( (2+2)<(2+3) ? 1 : 32)) +echo $(( (2+2)>(2+3) ? 1 : 32)) + +# check that the unevaluated part of the ternary operator does not do +# evaluation or assignment +x=i+=2 +y=j+=2 +declare -i i=1 j=1 +echo $((1 ? 20 : (x+=2))) +echo $i,$x +echo $((0 ? (y+=2) : 30)) +echo $j,$y + +x=i+=2 +y=j+=2 +declare -i i=1 j=1 +echo $((1 ? 20 : (x+=2))) +echo $i,$x +echo $((0 ? (y+=2) : 30)) +echo $i,$y + +# check precedence of assignment vs. conditional operator +# should be an error +declare -i x=2 +y=$((1 ? 20 : x+=2)) + +# check precedence of assignment vs. conditional operator +declare -i x=2 +echo $((0 ? x+=2 : 20)) + +# associativity of assignment-operator operator +declare -i i=1 j=2 k=3 +echo $((i += j += k)) +echo $i,$j,$k + +# octal, hex +echo $(( 0x100 | 007 )) +echo $(( 0xff )) +echo $(( 16#ff )) +echo $(( 16#FF/2 )) +echo $(( 8#44 )) + +echo $(( 8 ^ 32 )) + +# other bases +echo $(( 16#a )) +echo $(( 32#a )) +echo $(( 56#a )) +echo $(( 64#a )) + +echo $(( 16#A )) +echo $(( 32#A )) +echo $(( 56#A )) +echo $(( 64#A )) + +echo $(( 64#@ )) +echo $(( 64#_ )) + +# weird bases +echo $(( 3425#56 )) + +# missing number after base +echo $(( 2# )) + +# these should generate errors +echo $(( 7 = 43 )) +echo $(( 2#44 )) +echo $(( 44 / 0 )) +let 'jv += $iv' +echo $(( jv += \$iv )) +let 'rv = 7 + (43 * 6' + +# more errors +declare -i i +i=0#4 +i=2#110#11 + +((echo abc; echo def;); echo ghi) + +if (((4+4) + (4 + 7))); then + echo ok +fi + +(()) # make sure the null expression works OK + +a=(0 2 4 6) +echo $(( a[1] + a[2] )) +echo $(( (a[1] + a[2]) == a[3] )) +(( (a[1] + a[2]) == a[3] )) ; echo $? + +# test pushing and popping the expression stack +unset A +A="4 + " +echo $(( ( 4 + A ) + 4 )) +A="3 + 5" +echo $(( ( 4 + A ) + 4 )) + +# badly-formed conditional expressions +echo $(( 4 ? : $A )) +echo $(( 1 ? 20 )) +echo $(( 4 ? 20 : )) + +# precedence and short-circuit evaluation +B=9 +echo $B + +echo $(( 0 && B=42 )) +echo $B + +echo $(( 1 || B=88 )) +echo $B + +echo $(( 0 && (B=42) )) +echo $B + +echo $(( (${$} - $$) && (B=42) )) +echo $B + +echo $(( 1 || (B=88) )) +echo $B + +# until command with (( )) command +x=7 + +echo $x +until (( x == 4 )) +do + echo $x + x=4 +done + +echo $x + +# exponentiation +echo $(( 2**15 - 1)) +echo $(( 2**(16-1))) +echo $(( 2**16*2 )) +echo $(( 2**31-1)) +echo $(( 2**0 )) + +# {pre,post}-{inc,dec}rement and associated errors + +x=4 + +echo $x +echo $(( x++ )) +echo $x +echo $(( x-- )) +echo $x + +echo $(( --x )) +echo $x + +echo $(( ++x )) +echo $x + +echo $(( ++7 )) +echo $(( 7-- )) + +echo $(( --x=7 )) +echo $(( ++x=7 )) + +echo $(( x++=7 )) +echo $(( x--=7 )) + +echo $x + +echo $(( +7 )) +echo $(( -7 )) + +echo $(( ++7 )) +echo $(( --7 )) + +${THIS_SH} ./arith1.sub +${THIS_SH} ./arith2.sub + +x=4 +y=7 + +(( x=8 , y=12 )) + +echo $x $y + +# should be an error +(( x=9 y=41 )) + +# These are errors +unset b +echo $((a b)) +((a b)) + +n=42 +printf "%d\n" $n +printf "%i\n" $n +echo $(( 8#$(printf "%o\n" $n) )) +printf "%u\n" $n +echo $(( 16#$(printf "%x\n" $n) )) +echo $(( 16#$(printf "%X\n" $n) )) + +# causes longjmp botches through bash-2.05b +a[b[c]d]=e