1######################################################################## 2# # 3# This software is part of the ast package # 4# Copyright (c) 1982-2007 AT&T Knowledge Ventures # 5# and is licensed under the # 6# Common Public License, Version 1.0 # 7# by AT&T Knowledge Ventures # 8# # 9# A copy of the License is available at # 10# http://www.opensource.org/licenses/cpl1.0.txt # 11# (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) # 12# # 13# Information and Software Systems Research # 14# AT&T Research # 15# Florham Park NJ # 16# # 17# David Korn <dgk@research.att.com> # 18# # 19######################################################################## 20function err_exit 21{ 22 print -u2 -n "\t" 23 print -u2 -r ${Command}[$1]: "${@:2}" 24 let Errors+=1 25} 26alias err_exit='err_exit $LINENO' 27 28Command=${0##*/} 29trap '' FPE # NOTE: osf.alpha requires this (no ieee math) 30integer Errors=0 31integer x=1 y=2 z=3 32if (( 2+2 != 4 )) 33then err_exit 2+2!=4 34fi 35if ((x+y!=z)) 36then err_exit x+y!=z 37fi 38if (($x+$y!=$z)) 39then err_exit $x+$y!=$z 40fi 41if (((x|y)!=z)) 42then err_exit "(x|y)!=z" 43fi 44if ((y >= z)) 45then err_exit "y>=z" 46fi 47if ((y+3 != z+2)) 48then err_exit "y+3!=z+2" 49fi 50if ((y<<2 != 1<<3)) 51then err_exit "y<<2!=1<<3" 52fi 53if ((133%10 != 3)) 54then err_exit "133%10!=3" 55 if (( 2.5 != 2.5 )) 56 then err_exit 2.5!=2.5 57 fi 58fi 59d=0 60((d || 1)) || err_exit 'd=0; ((d||1))' 61if (( d++!=0)) 62then err_exit "d++!=0" 63fi 64if (( --d!=0)) 65then err_exit "--d!=0" 66fi 67if (( (d++,6)!=6 && d!=1)) 68then err_exit '(d++,6)!=6 && d!=1' 69fi 70d=0 71if (( (1?2+1:3*4+d++)!=3 || d!=0)) 72then err_exit '(1?2+1:3*4+d++) !=3' 73fi 74for ((i=0; i < 20; i++)) 75do : 76done 77if (( i != 20)) 78then err_exit 'for (( expr)) failed' 79fi 80for ((i=0; i < 20; i++)); do : ; done 81if (( i != 20)) 82then err_exit 'for (( expr));... failed' 83fi 84for ((i=0; i < 20; i++)) do : ; done 85if (( i != 20)) 86then err_exit 'for (( expr))... failed' 87fi 88if (( (i?0:1) )) 89then err_exit '(( (i?0:1) )) failed' 90fi 91if (( (1 || 1 && 0) != 1 )) 92then err_exit '( (1 || 1 && 0) != 1) failed' 93fi 94if (( (_=1)+(_x=0)-_ )) 95then err_exit '(_=1)+(_x=0)-_ failed' 96fi 97if (( (3^6) != 5)) 98then err_exit '((3^6) != 5) failed' 99fi 100integer x=1 101if (( (x=-x) != -1 )) 102then err_exit '(x=-x) != -1 failed' 103fi 104i=2 105if (( 1$(($i))3 != 123 )) 106then err_exit ' 1$(($i))3 failed' 107fi 108((pi=4*atan(1.))) 109point=( 110 float x 111 float y 112) 113(( point.x = cos(pi/6), point.y = sin(pi/6) )) 114if (( point.x*point.x + point.y*point.y > 1.01 )) 115then err_exit 'cos*cos +sin*sin > 1.01' 116fi 117if (( point.x*point.x + point.y*point.y < .99 )) 118then err_exit 'cos*cos +sin*sin < .99' 119fi 120if [[ $((y=x=1.5)) != 1 ]] 121then err_exit 'typecast not working in arithmetic evaluation' 122fi 123typeset -E x=1.5 124( ((x++)) ) 2>/dev/null 125if [[ $? == 0 ]] 126then err_exit 'postincrement of floating point allowed' 127fi 128( ((++x)) ) 2>/dev/null 129if [[ $? == 0 ]] 130then err_exit 'preincrement of floating point allowed' 131fi 132x=1.5 133( ((x%1.1)) ) 2>/dev/null 134if [[ $? == 0 ]] 135then err_exit 'floating point allowed with % operator' 136fi 137x=.125 138if [[ $(( 4 * x/2 )) != 0.25 ]] 139then err_exit '(( 4 * x/2 )) is not 0.25, with x=.125' 140fi 141if [[ $(( pow(2,3) )) != 8 ]] 142then err_exit '$(( pow(2,3) )) != 8' 143fi 144( [[ $(( pow(2,(3)) )) == 8 ]] ) 2> /dev/null 145if (( $? )) 146then err_exit '$(( pow(2,(3)) )) != 8' 147fi 148unset x 149integer x=1; integer x=1 150if [[ $x != 1 ]] 151then err_exit 'two consecutive integer x=1 not working' 152fi 153unset z 154{ z=$(typeset -RZ2 z2; (( z2 = 8 )); print $z2) ;} 2>/dev/null 155if [[ $z != "08" ]] 156then err_exit "typeset -RZ2 leading 0 decimal not working [z=$z]" 157fi 158{ z=$(typeset -RZ3 z3; (( z3 = 8 )); print $z3) ;} 2>/dev/null 159if [[ $z != "008" ]] 160then err_exit "typeset -RZ3 leading 0 decimal not working [z=$z]" 161fi 162unset z 163typeset -Z3 z=010 164(( z=z+1)) 165if [[ $z != 011 ]] 166then err_exit "leading 0's in -Z not treated as decimal" 167fi 168unset x 169integer x=0 170if [[ $((x+=1)) != 1 ]] || ((x!=1)) 171then err_exit "+= not working" 172 x=1 173fi 174x=1 175if [[ $((x*=5)) != 5 ]] || ((x!=5)) 176then err_exit "*= not working" 177 x=5 178fi 179if [[ $((x%=4)) != 1 ]] || ((x!=1)) 180then err_exit "%= not working" 181 x=1 182fi 183if [[ $((x|=6)) != 7 ]] || ((x!=7)) 184then err_exit "|= not working" 185 x=7 186fi 187if [[ $((x&=5)) != 5 ]] || ((x!=5)) 188then err_exit "&= not working" 189 x=5 190fi 191function newscope 192{ 193 float x=1.5 194 (( x += 1 )) 195 print -r -- $x 196} 197if [[ $(newscope) != 2.5 ]] 198then err_exit "arithmetic using wrong scope" 199fi 200unset x 201integer y[3]=9 y[4]=2 i=3 202(( x = y[3] + y[4] )) 203if [[ $x != 11 ]] 204then err_exit "constant index array arithmetic failure" 205fi 206(( x = $empty y[3] + y[4] )) 207if [[ $x != 11 ]] 208then err_exit "empty constant index array arithmetic failure" 209fi 210(( x = y[i] + y[i+1] )) 211if [[ $x != 11 ]] 212then err_exit "variable subscript index array arithmetic failure" 213fi 214integer a[5]=3 a[2]=4 215(( x = y[a[5]] + y[a[2]] )) 216if [[ $x != 11 ]] 217then err_exit "nested subscript index array arithmetic failure" 218fi 219unset y 220typeset -Ai y 221y[three]=9 y[four]=2 222three=four 223four=three 224(( x = y[three] + y[four] )) 225if [[ $x != 11 ]] 226then err_exit "constant associative array arithmetic failure" 227fi 228(( x = y[$three] + y[$four] )) 229if [[ $x != 11 ]] 230then err_exit "variable subscript associative array arithmetic failure" 231fi 232$SHELL -nc '((a = 1))' 2> /dev/null || err_exit "sh -n fails with arithmetic" 233$SHELL -nc '((a.b++))' 2> /dev/null || err_exit "sh -n fails with arithmetic2" 234unset z 235float z=7.5 236if { (( z%2 != 1));} 2> /dev/null 237then err_exit '% not working on floating point' 238fi 239chr=(a ' ' '=' '\r' '\n' '\\' '\"' '$' "\\'" '[' ']' '(' ')' '<' '\xab' '\040' '`' '{' '}' '*' '\E') 240if (('a' == 97)) 241then val=(97 32 61 13 10 92 34 36 39 91 93 40 41 60 171 32 96 123 125 42 27) 242else val=(129 64 126 13 21 224 127 91 125 173 189 77 93 76 171 32 121 192 208 92 39 21) 243fi 244q=0 245for ((i=0; i < ${#chr[@]}; i++)) 246do if (( '${chr[i]}' != ${val[i]} )) 247 then err_exit "(( '${chr[i]}' != ${val[i]} ))" 248 fi 249 if [[ $(( '${chr[i]}' )) != ${val[i]} ]] 250 then err_exit "(( '${chr[i]}' )) != ${val[i]}" 251 fi 252 if [[ $(( L'${chr[i]}' )) != ${val[i]} ]] 253 then err_exit "(( '${chr[i]}' )) != ${val[i]}" 254 fi 255 if eval '((' "'${chr[i]}'" != ${val[i]} '))' 256 then err_exit "eval (( '${chr[i]}' != ${val[i]} ))" 257 fi 258 if eval '((' "'${chr[i]}'" != ${val[i]} ' + $q ))' 259 then err_exit "eval (( '${chr[i]}' != ${val[i]} ))" 260 fi 261done 262unset x 263typeset -ui x=4294967293 264[[ $x != 4294967293 ]] && err_exit "unsigned integers not working" 265x=32767 266x=x+1 267[[ $x != 32768 ]] && err_exit "unsigned integer addition not working" 268unset x 269float x=99999999999999999999999999 270if (( x < 1e20 )) 271then err_exit 'large integer constants not working' 272fi 273unset x y 274function foobar 275{ 276 nameref x=$1 277 (( x +=1 )) 278 print $x 279} 280x=0 y=4 281if [[ $(foobar y) != 5 ]] 282then err_exit 'name references in arithmetic statements in functions broken' 283fi 284if (( 2**3 != pow(2,3) )) 285then err_exit '2**3 not working' 286fi 287if (( 2**3*2 != pow(2,3)*2 )) 288then err_exit '2**3*2 not working' 289fi 290if (( 4**3**2 != pow(4,pow(3,2)) )) 291then err_exit '4**3**2 not working' 292fi 293if (( (4**3)**2 != pow(pow(4,3),2) )) 294then err_exit '(4**3)**2 not working' 295fi 296typeset -Z3 x=11 297typeset -i x 298if (( x != 11 )) 299then err_exit '-Z3 not treated as decimal' 300fi 301unset x 302typeset -ui x=-1 303(( x >= 0 )) || err_exit 'unsigned integer not working' 304(( $x >= 0 )) || err_exit 'unsigned integer not working as $x' 305unset x 306typeset -ui42 x=50 307if [[ $x != 42#18 ]] 308then err_exit 'display of unsigned integers in non-decimal bases wrong' 309fi 310$SHELL -c 'i=0;(( ofiles[i] != -1 && (ofiles[i] < mins || mins == -1) ));exit 0' 2> /dev/null || err_exit 'lexical error with arithemtic expression' 311rm -f core 312$SHELL -c '(( +1 == 1))' 2> /dev/null || err_exit 'unary + not working' 313typeset -E20 val=123.01234567890 314[[ $val == 123.0123456789 ]] || err_exit "rounding error val=$val" 315if [[ $(print x$((10))=foo) != x10=foo ]] 316then err_exit 'parsing error with x$((10))=foo' 317fi 318$SHELL -c 'typeset x$((10))=foo' 2> /dev/null || err_exit 'typeset x$((10)) parse error' 319unset x 320x=$(( exp(log(2.0)) )) 321(( x > 1.999 && x < 2.001 )) || err_exit 'composite functions not working' 322unset x y n 323typeset -Z8 x=0 y=0 324integer n 325for (( n=0; n < 20; n++ )) 326do let "x = $x+1" 327 (( y = $y+1 )) 328done 329(( x == n )) || err_exit 'let with zero filled fields not working' 330(( y == n )) || err_exit '((...)) with zero filled fields not working' 331typeset -LZ3 x=10 332[[ $(($x)) == 10 && $((1$x)) == 1010 ]] || err_exit 'zero filled fields not preserving leading zeros' 333unset y 334[[ $(let y=$x;print $y) == 10 && $(let y=1$x;print $y) == 1010 ]] || err_exit 'zero filled fields not preserving leading zeros with let' 335unset i ip ipx 336typeset -i hex=( 172 30 18 1) 337typeset -iu ip=0 ipx=0 338integer i 339for ((i=0; i < 4; i++)) 340do (( ip = (ip<<8) | hex[i])) 341done 342for ((i=0; i < 4; i++)) 343do (( ipx = ip % 256 )) 344 (( ip /= 256 )) 345 (( ipx != hex[3-i] )) && err_exit "hex digit $((3-i)) not correct" 346done 347unset x 348x=010 349(( x == 8 )) || err_exit 'leading zeros not treated as octal arithmetic' 350(( $x == 8 )) || err_exit 'leading zeros not treated as octal arithmetic with $x' 351unset x 352typeset -Z x=010 353(( x == 10 )) || err_exit 'leading zeros not ignored for arithmetic' 354(( $x == 10 )) || err_exit 'leading zeros not ignored for arithmetic with $x' 355typeset -i i=x 356(( i == 10 )) || err_exit 'leading zeros not ignored for arithmetic assignment' 357(( ${x:0:1} == 0 )) || err_exit 'leading zero should not be stripped for x:a:b' 358c010=3 359(( c$x == 3 )) || err_exit 'leading zero with variable should not be stripped' 360[[ $( ($SHELL -c '((++1))' 2>&1)2>/dev/null ) == *lvalue* ]] || err_exit "((--1)) not generating error message" 361i=2 362(( "22" == 22 )) || err_exit "double quoted constants fail" 363(( "2$i" == 22 )) || err_exit "double quoted variables fail" 364(( "18+$i+2" == 22 )) || err_exit "double quoted expressions fail" 365# 04-04-28 bug fix 366unset i; typeset -i i=01-2 367(( i == -1 )) || err_exit "01-2 is not -1" 368 369trap 'rm -f /tmp/script$$ /tmp/data$$.[12]' EXIT 370cat > /tmp/script$$ <<-\! 371tests=$* 372typeset -A blop 373function blop.get 374{ 375 .sh.value=777 376} 377function mkobj 378{ 379 nameref obj=$1 380 obj=() 381 [[ $tests == *1* ]] && { 382 (( obj.foo = 1 )) 383 (( obj.bar = 2 )) 384 (( obj.baz = obj.foo + obj.bar )) # ok 385 echo $obj 386 } 387 [[ $tests == *2* ]] && { 388 (( obj.faz = faz = obj.foo + obj.bar )) # ok 389 echo $obj 390 } 391 [[ $tests == *3* ]] && { 392 # case 3, 'active' variable involved, w/ intermediate variable 393 (( obj.foz = foz = ${blop[1]} )) # coredump 394 echo $obj 395 } 396 [[ $tests == *4* ]] && { 397 # case 4, 'active' variable, in two steps 398 (( foz = ${blop[1]} )) # ok 399 (( obj.foz = foz )) # ok 400 echo $obj 401 } 402 [[ $tests == *5* ]] && { 403 # case 5, 'active' variable involved, w/o intermediate variable 404 (( obj.fuz = ${blop[1]} )) # coredump 405 echo $obj 406 } 407 [[ $tests == *6* ]] && { 408 echo $(( obj.baz = obj.foo + obj.bar )) # coredump 409 } 410 [[ $tests == *7* ]] && { 411 echo $(( obj.foo + obj.bar )) # coredump 412 } 413} 414mkobj bla 415! 416chmod +x /tmp/script$$ 417[[ $(/tmp/script$$ 1) != '( bar=2 baz=3 foo=1 )' ]] 2>/dev/null && err_exit 'compound var arithmetic failed' 418[[ $(/tmp/script$$ 2) != '( faz=0 )' ]] 2>/dev/null && err_exit 'compound var arithmetic failed' 419[[ $(/tmp/script$$ 3) != '( foz=777 )' ]] 2>/dev/null && err_exit 'compound var arithmetic failed' 420[[ $(/tmp/script$$ 4) != '( foz=777 )' ]] 2>/dev/null && err_exit 'compound var arithmetic failed' 421[[ $(/tmp/script$$ 5) != '( fuz=777 )' ]] 2>/dev/null && err_exit 'compound var arithmetic failed' 422[[ $(/tmp/script$$ 6) != '0' ]] 2>/dev/null && err_exit 'compound var arithmetic failed' 423[[ $(/tmp/script$$ 7) != '0' ]] 2>/dev/null && err_exit 'compound var arithmetic failed' 424unset foo 425typeset -F1 foo=123456789.19 426[[ $foo == 123456789.2 ]] || err_exit 'typeset -F1 not working correctly' 427 428# divide by zero 429 430for expr in '1/(1/2)' '8%(1/2)' '8%(1.0/2)' 431do [[ $( ( $SHELL -c "( (($expr)) ) || print ok" ) 2>/dev/null ) == ok ]] || err_exit "divide by zero not trapped: $expr" 432done 433 434for expr in '1/(1.0/2)' '1/(1/2.0)' 435do [[ $( ( $SHELL -c "( print -r -- \$(($expr)) )" ) 2>/dev/null ) == 2 ]] || err_exit "invalid value for: $expr" 436done 437[[ $((5||0)) == 1 ]] || err_exit '$((5||0))'" == $((5||0)) should be 1" 438$SHELL -c 'integer x=3 y=2; (( (y += x += 2) == 7 && x==5))' 2> /dev/null || err_exit '((y += x += 2)) not working' 439$SHELL -c 'b=0; [[ $((b?a=1:b=9)) == 9 ]]' 2> /dev/null || err_exit 'b?a=1:b=9 not working' 440unset x 441(( x = 4*atan(1.0) )) 442[[ $x == "$((x))" ]] || err_exit '$x !- $((x)) when x is pi' 443$SHELL -c "[[ ${x//./} == {14,100}(\d) ]]" 2> /dev/null || err_exit 'pi has less than 14 significant places' 444if (( Inf+1 == Inf )) 445then [[ $(printf "%g\n" $((Inf))) == inf ]] || err_exit 'printf "%g\n" $((Inf)) fails' 446# [[ $(printf "%g\n" $((Nan))) == inf ]] || err_exit 'printf "%g\n" $((Nan)) fails' 447 [[ $(printf "%g\n" Inf) == inf ]] || err_exit 'printf "%g\n" Inf fails' 448 [[ $(printf "%g\n" NaN) == nan ]] || err_exit 'printf "%g\n" NaN fails' 449 [[ $(print -- $((Inf))) == inf ]] || err_exit 'print -- $((Inf)) fails' 450 (( 1.0/0.0 == Inf )) || err_exit '1.0/0.0 != Inf' 451 [[ $(print -- $((0.0/0.0))) == nan ]] || err_exit '0.0/0.0 != NaN' 452 (( Inf*Inf == Inf )) || err_exit 'Inf*Inf != Inf' 453 (( NaN != NaN )) || err_exit 'NaN == NaN' 454 (( -5*Inf == -Inf )) || err_exit '-5*Inf != -Inf' 455 [[ $(print -- $((sqrt(-1.0)))) == nan ]]|| err_exit 'sqrt(-1.0) != NaN' 456 (( pow(1.0,Inf) == 1.0 )) || err_exit 'pow(1.0,Inf) != 1.0' 457 (( pow(Inf,0.0) == 1.0 )) || err_exit 'pow(Inf,0.0) != 1.0' 458 [[ $(print -- $((NaN/Inf))) == nan ]] || err_exit 'NaN/Inf != NaN' 459 (( 4.0/Inf == 0.0 )) || err_exit '4.0/Inf != 0.0' 460else err_exit 'Inf and NaN not working' 461fi 462unset x y 463float x=14.555 y 464y=$(printf "%a" x) 465(( x == y )) || err_exit "output of printf %a not self preserving -- expected $x, got $y" 466exit $((Errors)) 467