1######################################################################## 2# # 3# This software is part of the ast package # 4# Copyright (c) 1982-2012 AT&T Intellectual Property # 5# and is licensed under the # 6# Eclipse Public License, Version 1.0 # 7# by AT&T Intellectual Property # 8# # 9# A copy of the License is available at # 10# http://www.eclipse.org/org/documents/epl-v10.html # 11# (with md5 checksum b35adb5213ca9657e911e9befb180842) # 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 (( Errors+=1 )) 25} 26alias err_exit='err_exit $LINENO' 27 28Command=${0##*/} 29integer Errors=0 30 31tmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; } 32trap "cd /; rm -rf $tmp" EXIT 33 34integer n=2 35 36typeset -T Type_t=( 37 typeset name=foobar 38 typeset x=(hi=ok bar=yes) 39 typeset y=(xa=xx xq=89) 40 typeset -A aa=([one]=abc [two]=def) 41 typeset -a ia=(abc def) 42 typeset -i z=5 43) 44for ((i=0; i < 10; i++)) 45do 46 Type_t r s 47 [[ $r == "$s" ]] || err_exit 'r is not equal to s' 48 typeset -C x=r.x 49 y=(xa=bb xq=cc) 50 y2=xyz 51 z2=xyz 52 typeset -C z=y 53 [[ $y == "$z" ]] || err_exit 'y is not equal to z' 54 typeset -C s.y=z 55 [[ $y == "${s.y}" ]] || err_exit 'y is not equal to s.y' 56 .sh.q=$y 57 typeset -C www=.sh.q 58 [[ $www == "$z" ]] || err_exit 'www is not equal to z' 59 typeset -C s.x=r.x 60 [[ ${s.x} == "${r.x}" ]] || err_exit 's.x is not equal to r.x' 61 62 function foo 63 { 64 nameref x=$1 y=$2 65 typeset z=$x 66 y=$x 67 [[ $x == "$y" ]] || err_exit "x is not equal to y with ${!x}" 68 } 69 foo r.y y 70 [[ $y == "${r.y}" ]] || err_exit 'y is not equal to r.y' 71 typeset -C y=z 72 foo y r.y 73 [[ $y == "${r.y}" ]] || err_exit 'y is not equal to r.y again' 74 typeset -C y=z 75 ( 76 q=${z} 77 [[ $q == "$z" ]] || err_exit 'q is not equal to z' 78 z=abc 79 ) 80 [[ $z == "$y" ]] || err_exit 'value of z not preserved after subshell' 81 unset z y r s x z2 y2 www .sh.q 82done 83typeset -T Frame_t=( typeset file lineno ) 84Frame_t frame 85[[ $(typeset -p frame) == 'Frame_t frame=(typeset file;typeset lineno)' ]] || err_exit 'empty fields in type not displayed' 86x=( typeset -a arr=([2]=abc [4]=(x=1 y=def));zz=abc) 87typeset -C y=x 88[[ "$x" == "$y" ]] || print -u2 'y is not equal to x' 89Type_t z=(y=(xa=bb xq=cc)) 90typeset -A arr=([foo]=one [bar]=2) 91typeset -A brr=([foo]=one [bar]=2) 92[[ "${arr[@]}" == "${brr[@]}" ]] || err_exit 'arr is not brr' 93for ((i=0; i < 1; i++)) 94do typeset -m zzz=x 95 [[ $zzz == "$y" ]] || err_exit 'zzz is not equal to y' 96 typeset -m x=zzz 97 [[ $x == "$y" ]] || err_exit 'x is not equal to y' 98 Type_t t=(y=(xa=bb xq=cc)) 99 typeset -m r=t 100 [[ $r == "$z" ]] || err_exit 'r is not equal to z' 101 typeset -m t=r 102 [[ $t == "$z" ]] || err_exit 't is not equal to z' 103 typeset -m crr=arr 104 [[ "${crr[@]}" == "${brr[@]}" ]] || err_exit 'crr is not brr' 105 typeset -m arr=crr 106 [[ "${arr[@]}" == "${brr[@]}" ]] || err_exit 'brr is not arr' 107done 108typeset -m brr[foo]=brr[bar] 109[[ ${brr[foo]} == 2 ]] || err_exit 'move an associative array element fails' 110[[ ${brr[bar]} ]] && err_exit 'brr[bar] should be unset after move' 111unset x y zzz 112x=(a b c) 113typeset -m x[1]=x[2] 114[[ ${x[1]} == c ]] || err_exit 'move an indexed array element fails' 115[[ ${x[2]} ]] && err_exit 'x[2] should be unset after move' 116cat > $tmp/types <<- \+++ 117 typeset -T Pt_t=(float x=1. y=0.) 118 Pt_t p=(y=2) 119 print -r -- ${p.y} 120+++ 121expected=2 122got=$(. $tmp/types) 2>/dev/null 123[[ "$got" == "$expected" ]] || err_exit "typedefs in dot script failed -- expected '$expected', got '$got'" 124typeset -T X_t=( 125 typeset x=foo y=bar 126 typeset s=${_.x} 127 create() 128 { 129 _.y=bam 130 } 131) 132X_t x 133[[ ${x.x} == foo ]] || err_exit 'x.x should be foo' 134[[ ${x.y} == bam ]] || err_exit 'x.y should be bam' 135[[ ${x.s} == ${x.x} ]] || err_exit 'x.s should be x.x' 136typeset -T Y_t=( X_t r ) 137Y_t z 138[[ ${z.r.x} == foo ]] || err_exit 'z.r.x should be foo' 139[[ ${z.r.y} == bam ]] || err_exit 'z.r.y should be bam' 140[[ ${z.r.s} == ${z.r.x} ]] || err_exit 'z.r.s should be z.r.x' 141 142unset xx yy 143typeset -T xx=(typeset yy=zz) 144xx=yy 145{ typeset -T xx=(typeset yy=zz) ;} 2>/dev/null && err_exit 'type redefinition should fail' 146$SHELL 2> /dev/null <<- +++ || err_exit 'typedef with only f(){} fails' 147 typeset -T X_t=( 148 f() 149 { 150 print ok 151 } 152 ) 153+++ 154$SHELL 2> /dev/null <<- +++ || err_exit 'unable to redefine f discipline function' 155 typeset -T X_t=( 156 x=1 157 f() 158 { 159 print ok 160 } 161 ) 162 X_t z=( 163 function f 164 { 165 print override f 166 } 167 ) 168+++ 169$SHELL 2> /dev/null <<- +++ && err_exit 'invalid discipline name should be an error' 170 typeset -T X_t=( 171 x=1 172 f() 173 { 174 print ok 175 } 176 ) 177 X_t z=( 178 function g 179 { 180 print override f 181 } 182 ) 183+++ 184# compound variables containing type variables 185Type_t r 186var=( 187 typeset x=foobar 188 Type_t r 189 integer z=5 190) 191[[ ${var.r} == "$r" ]] || err_exit 'var.r != r' 192(( var.z == 5)) || err_exit 'var.z !=5' 193[[ "$var" == *x=foobar* ]] || err_exit '$var does not contain x=foobar' 194 195typeset -T A_t=( 196 typeset x=aha 197 typeset b=${_.x} 198) 199unset x 200A_t x 201expected=aha 202got=${x.b} 203[[ "$got" == "$expected" ]] || err_exit "type '_' reference failed -- expected '$expected', got '$got'" 204 205typeset -T Tst_t=( 206 function f 207 { 208 A_t a 209 print ${ _.g ${a.x}; } 210 } 211 function g 212 { 213 print foo 214 } 215) 216Tst_t tst 217expected=foo 218got=${ tst.f;} 219[[ "$got" == "$expected" ]] || err_exit "_.g where g is a function in type discipline method failed -- expected '$expected', got '$got'" 220 221typeset -T B_t=( 222 integer -a arr 223 function f 224 { 225 (( _.arr[0] = 0 )) 226 (( _.arr[1] = 1 )) 227 print ${_.arr[*]} 228 } 229) 230unset x 231B_t x 232expected='0 1' 233got=${ x.f;} 234[[ "$got" == "$expected" ]] || err_exit "array assignment of subscripts in type discipline arithmetic failed -- expected '$expected', got '$got'" 235 236typeset -T Fileinfo_t=( 237 size=-1 238 typeset -a text=() 239 integer mtime=-1 240) 241Fileinfo_t -A _Dbg_filenames 242Fileinfo_t finfo 243function bar 244{ 245 finfo.text=(line1 line2 line3) 246 finfo.size=${#finfo.text[@]} 247 _Dbg_filenames[foo]=finfo 248} 249bar 250 251expected='Fileinfo_t -A _Dbg_filenames=([foo]=(size=3;typeset -a text=(line1 line2 line3);typeset -l -i mtime=-1))' 252got=$(typeset -p _Dbg_filenames) 253[[ "$got" == "$expected" ]] || { 254 got=$(printf %q "$got") 255 err_exit "copy to associative array of types in function failed -- expected '$expected', got $got" 256} 257 258$SHELL > /dev/null <<- '+++++' || err_exit 'passing _ as nameref arg not working' 259 function f1 260 { 261 typeset -n v=$1 262 print -r -- "$v" 263 } 264 typeset -T A_t=( 265 typeset blah=xxx 266 function f { f1 _ ;} 267 ) 268 A_t a 269 [[ ${ a.f ./t1;} == "$a" ]] 270+++++ 271expected='A_t b.a=(name=one)' 272[[ $( $SHELL << \+++ 273 typeset -T A_t=( 274 typeset name=aha 275 ) 276 typeset -T B_t=( 277 typeset arr 278 A_t a 279 f() 280 { 281 _.a=(name=one) 282 typeset -p _.a 283 } 284 ) 285 B_t b 286 b.f 287+++ 288) == "$expected" ]] 2> /dev/null || err_exit '_.a=(name=one) not expanding correctly' 289expected='A_t x=(name=xxx)' 290[[ $( $SHELL << \+++ 291 typeset -T A_t=( 292 typeset name 293 ) 294 A_t x=(name="xxx") 295 typeset -p x 296+++ 297) == "$expected" ]] || err_exit 'empty field in definition does not expand correctly' 298 299typeset -T Foo_t=( 300 integer x=3 301 integer y=4 302 len() { print -r -- $(( sqrt(_.x**2 + _.y**2))) ;} 303) 304Foo_t foo 305[[ ${foo.len} == 5 ]] || err_exit "discipline function len not working" 306 307typeset -T benchmark_t=( 308 integer num_iterations 309) 310function do_benchmarks 311{ 312 nameref tst=b 313 integer num_iterations 314 (( num_iterations= int(tst.num_iterations * 1.0) )) 315 printf "%d\n" num_iterations 316} 317benchmark_t b=(num_iterations=5) 318[[ $(do_benchmarks) == 5 ]] || err_exit 'scoping of nameref of type variables in arithmetic expressions not working' 319 320function cat_content 321{ 322 cat <<- EOF 323 ( 324 foo_t -a foolist=( 325 ( val=3 ) 326 ( val=4 ) 327 ( val=5 ) 328 ) 329 ) 330 EOF 331 return 0 332} 333typeset -T foo_t=( 334 integer val=-1 335 function print 336 { 337 print -- ${_.val} 338 } 339) 340function do_something 341{ 342 nameref li=$1 # "li" may be an index or associative array 343 li[2].print 344} 345cat_content | read -C x 346[[ $(do_something x.foolist) == 5 ]] || err_exit 'subscripts not honored for arrays of type with disciplines' 347 348typeset -T benchcmd_t=( 349 float x=1 350 float y=2 351) 352unset x 353compound x=( 354 float o 355 benchcmd_t -a m 356 integer h 357) 358expected=$'(\n\ttypeset -l -i h=0\n\tbenchcmd_t -a m\n\ttypeset -l -E o=0\n)' 359[[ $x == "$expected" ]] || err_exit 'compound variable with array of types with no elements not working' 360 361expected=$'Std_file_t db.file[/etc/profile]=(action=preserve;typeset -A sum=([8242e663d6f7bb4c5427a0e58e2925f3]=1);)' 362{ 363 got=$($SHELL <<- \EOF 364 MAGIC='stdinstall (at&t research) 2009-08-25' 365 typeset -T Std_file_t=( 366 typeset action 367 typeset -A sum 368 ) 369 typeset -T Std_t=( 370 typeset magic=$MAGIC 371 Std_file_t -A file 372 ) 373 Std_t db=(magic='stdinstall (at&t research) 2009-08-25';Std_file_t -A file=( [/./home/gsf/.env.sh]=(action=preserve;typeset -A sum=([9b67ab407d01a52b3e73e3945b9a3ee0]=1);)[/etc/profile]=(action=preserve;typeset -A sum=([8242e663d6f7bb4c5427a0e58e2925f3]=1);)[/home/gsf/.profile]=(action=preserve;typeset -A sum=([3ce23137335219672bf2865d003a098e]=1);));) 374 typeset -p db.file[/etc/profile] 375 EOF) 376} 2> /dev/null 377[[ $got == "$expected" ]] || err_exit 'types with arrays of types as members fails' 378 379typeset -T x_t=( 380 integer dummy 381 function set 382 { 383 [[ ${.sh.name} == v ]] || err_exit "name=${.sh.name} should be v" 384 [[ ${.sh.subscript} == 4 ]] || err_exit "subscript=${.sh.subscript} should be 4" 385 [[ ${.sh.value} == hello ]] || err_exit "value=${.sh.value} should be hello" 386 } 387) 388x_t -a v 389v[4]="hello" 390 391typeset -T oset=( 392 typeset -A s 393) 394oset foo bar 395: ${foo.s[a]:=foobar} 396: ${bar.s[d]:=foobar} 397[[ ${bar.s[a]} == foobar ]] && err_exit '${var:=val} for types assigns to type instead of type instance' 398 399typeset -T olist=( 400 typeset -a l 401) 402olist foo 403foo.l[1]=x 404[[ ${!foo.l[*]} == *0* ]] && '0-th elment of foo.l should not be set' 405 406typeset -T oset2=( typeset -A foo ) 407oset2 bar 408: ${bar.foo[a]} 409bar.foo[a]=b 410[[ ${#bar.foo[*]} == 1 ]] || err_exit "bar.foo should have 1 element not ${#bar.foo[*]}" 411[[ ${bar.foo[*]} == b ]] || err_exit "bar.foo[*] should be 'b' not ${bar.foo[*]}" 412[[ ${bar.foo[a]} == b ]] || err_exit "bar.foo[a] should be 'b' not ${bar.foo[*]}" 413 414{ x=$( $SHELL 2> /dev/null << \++EOF++ 415 typeset -T ab_t=( 416 integer a=1 b=2 417 function increment 418 { 419 (( _.a++, _.b++ )) 420 } 421 ) 422 function ar_n 423 { 424 nameref sn=$2 425 sn.increment 426 $1 && printf "a=%d, b=%d\n" sn.a sn.b 427 } 428 function ar 429 { 430 ab_t -S -a s 431 [[ -v s[5] ]] || s[5]=( ) 432 ar_n $1 s[5] 433 } 434 x=$(ar false ; ar false ; ar true ; printf ";") 435 y=$(ar false ; ar false ; ar true ; printf ";") 436 print -r -- "\"$x\"" == "\"$y\"" 437++EOF++ 438) ;} 2> /dev/null 439[[ $x == *a=4*b=5* ]] || err_exit 'static types in a function not working' 440{ eval "[[ $x ]]";} 2> /dev/null || err_exit 'arrays of types leaving side effects in subshells' 441 442typeset -T y_t=( 443 typeset dummy 444 function print_b 445 { 446 print "B" 447 } 448) 449y_t a b=( 450 function print_b 451 { 452 print "1" 453 } 454) 455[[ $(a.print_b) == B ]] || err_exit 'default discipline not working' 456[[ $(b.print_b) == 1 ]] || err_exit 'discipline override not working' 457 458$SHELL 2> /dev/null -c 'true || { typeset -T Type_t=(typeset name=foo); 459 Type_t z=(name=bar) ;}' || err_exit 'unable to parse type command until typeset -T executes' 460 461cd "$tmp" 462FPATH=$PWD 463PATH=$PWD:$PATH 464cat > A_t <<- \EOF 465 typeset -T A_t=( 466 B_t b 467 ) 468EOF 469cat > B_t <<- \EOF 470 typeset -T B_t=( 471 integer n=5 472 ) 473EOF 474 475unset n 476if n=$(FPATH=$PWD PATH=$PWD:$PATH $SHELL 2> /dev/null -c 'A_t a; print ${a.b.n}') 477then (( n==5 )) || err_exit 'dynamic loading of types gives wrong result' 478else err_exit 'unable to load types dynamically' 479fi 480 481# check that typeset -T reproduces a type. 482if $SHELL > /dev/null 2>&1 -c 'typeset -T' 483then $SHELL > junk1 <<- \+++EOF 484 typeset -T foo_t=( 485 integer x=3 y=4 486 float z=1.2 487 len() 488 { 489 ((.sh.value=sqrt(_.x**2 + _.y**2) )) 490 } 491 function count 492 { 493 print z=$z 494 } 495 ) 496 typeset -T 497 print 'typeset -T' 498 +++EOF 499 $SHELL -c '. ./junk1;print "typeset -T"' > junk2 500 diff junk[12] > /dev/null || err_exit 'typeset -T not idempotent' 501 $SHELL -c '. ./junk1;print "typeset +f"' > junk2 502 [[ -s junk2 ]] || err_exit 'non-discipline-method functions found' 503else 504 err_exit 'typeset -T not supported' 505fi 506 507[[ $($SHELL -c 'typeset -T x=( typeset -a h ) ; x j; print -v j.h') ]] && err_exit 'type with indexed array without elements inserts element 0' 508 509[[ $($SHELL -c 'typeset -T x=( integer -a s ) ; compound c ; x c.i ; c.i.s[4]=666 ; print -v c') == *'[0]'* ]] && err_exit 'type with indexed array with non-zero element inserts element 0' 510 511 512{ $SHELL -c '(sleep 3;kill $$)& typeset -T x=( typeset -a s );compound c;x c.i;c.i.s[7][5][3]=hello;x c.j=c.i;[[ ${c.i} == "${c.j}" ]]';} 2> /dev/null 513exitval=$? 514if [[ $(kill -l $exitval) == TERM ]] 515then err_exit 'clone of multi-dimensional array timed out' 516elif ((exitval)) 517then err_exit "c.i and c.j are not the same multi-dimensional array" 518fi 519 520typeset -T foobar_t=( 521 float x=1 y=0 522 slen() 523 { 524 print -r -- $((sqrt(_.x**2 + _.y**2))) 525 } 526 typeset -fS slen 527 len() 528 { 529 print -r -- $((sqrt(_.x**2 + _.y**2))) 530 } 531) 532unset z 533foobar_t z=(x=3 y=4) 534(( z.len == 5 )) || err_exit 'z.len should be 5' 535(( z.slen == 1 )) || err_exit 'z.slen should be 1' 536(( .sh.type.foobar_t.slen == 1 )) || err_exit '.sh.type.foobar_t.slen should be 1' 537(( .sh.type.foobar_t.len == 1 )) || err_exit '.sh.type.foobar_t.len should be 1' 538 539typeset -T z_t=( typeset -a ce ) 540z_t x1 541x1.ce[3][4]=45 542compound c 543z_t -a c.x2 544c.x2[9]=x1 545got=$(typeset +p "c.x2[9].ce") 546exp='typeset -a c.x2[9].ce' 547[[ $got == "$exp" ]] || err_exit "typeset +p 'c.x2[9].ce' failed -- expected '$exp', got '$got'" 548 549unset b 550typeset -T a_t=( 551 typeset a="hello" 552) 553typeset -T b_t=( 554 a_t b 555) 556compound b 557compound -a b.ca 558b_t b.ca[4].b 559exp='typeset -C b=(typeset -C -a ca=( [4]=(b_t b=(a_t b=(a=hello))));)' 560got=$(typeset -p b) 561[[ $got == "$exp" ]] || err_exit 'typeset -p of nested type not correct' 562 563typeset -T u_t=( 564 integer dummy 565 unset() 566 { 567 print unset 568 } 569) 570unset z 571u_t -a x | read z 572[[ $z == unset ]] && err_exit 'unset discipline called on type creation' 573 574{ z=$($SHELL 2> /dev/null 'typeset -T foo; typeset -T') ;} 2> /dev/null 575[[ $z == 'typeset -T foo' ]] || err_exit '"typeset -T foo; typeset -T" failed' 576 577{ z=$($SHELL 2> /dev/null 'typeset -T foo=bar; typeset -T') ;} 2> /dev/null 578[[ $z ]] && err_exit '"typeset -T foo=bar" should not creates type foo' 579 580{ 581$SHELL << \EOF 582 typeset -T board_t=( 583 compound -a board_y 584 function binsert 585 { 586 nameref figure=$1 587 integer y=$2 x=$3 588 typeset -m "_.board_y[y].board_x[x].field=figure" 589 } 590 ) 591 function main 592 { 593 compound c=( 594 board_t b 595 ) 596 for ((i=0 ; i < 2 ; i++ )) ; do 597 compound p=( hello=world ) 598 c.b.binsert p 1 $i 599 done 600 exp='typeset -C c=(board_t b=(typeset -a board_y=( [1]=(typeset -a board_x=( [0]=(field=(hello=world;))[1]=(field=(hello=world)));));))' 601 [[ $(typeset -p c) == "$exp" ]] || exit 1 602 } 603 main 604EOF 605} 2> /dev/null 606if (( exitval=$?)) 607then if [[ $(kill -l $exitval) == SEGV ]] 608 then err_exit 'typeset -m in type discipline causes exception' 609 else err_exit 'typeset -m in type discipline gives wrong value' 610 fi 611fi 612 613typeset -T pawn_t=( 614 print_debug() 615 { 616 print 'PAWN' 617 } 618) 619function main 620{ 621 compound c=( 622 compound -a board 623 ) 624 625 for ((i=2 ; i < 8 ; i++ )) ; do 626 pawn_t c.board[1][$i] 627 done 628 629} 630main 2> /dev/null && err_exit 'type assignment to compound array instance should generate an error' 631 632{ $SHELL -c 'typeset -T Foo_t=(integer -a data=([0]=0) );Foo_t x=(data[0]=2);((x.data[0]==2))' 633} 2> /dev/null || err_exit 'type definition with integer array variable not working' 634 635typeset -T Bar_t=( 636 typeset -a foo 637) 638Bar_t bar 639bar.foo+=(bam) 640[[ ${bar.foo[0]} == bam ]] || err_exit 'appending to empty array variable in type does not create element 0' 641 642exit $((Errors<125?Errors:125)) 643