1######################################################################## 2# # 3# This software is part of the ast package # 4# Copyright (c) 1982-2011 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######################################################################## 20# 21# Written by Roland Mainz <roland.mainz@nrubsig.org> 22# 23 24function err_exit 25{ 26 print -u2 -n "\t" 27 print -u2 -r ${Command}[$1]: "${@:2}" 28 (( Errors < 127 && Errors++ )) 29} 30 31alias err_exit='err_exit $LINENO' 32 33set -o nounset 34Command=${0##*/} 35integer Errors=0 36 37 38 39typeset -T test_t=( 40 typeset name 41 typeset cmd 42 typeset expected_output 43) 44 45function testfunc 46{ 47 integer line_number=$1 48 typeset cmd="$2" 49 typeset expected_output="$3" 50 typeset output 51 52 output="$($SHELL -c "${cmd}" 2>&1 )" 53 54 [[ "${output}" == "${expected_output}" ]] || err_exit ${line_number} "${output} != ${expected_output}" 55} 56 57# test1: basic tests 58function test1 59{ 60 # string 61 testfunc ${LINENO} '(function l { typeset -S x ; x+="#" ; $1 && print "$x" ; } ; l false ; l false ; l true)' "###" 62 testfunc ${LINENO} 'function l { typeset -S x=">" ; x+="#" ; $1 && print "$x" ; } ; l false ; l false ; l true' ">###" 63 testfunc ${LINENO} 'function l { typeset -S x=">" ; x+="#" ; $1 && print "$x" ; } ; l false ; (l false) ; l true' ">##" 64 testfunc ${LINENO} 'function l { typeset -S x=">" ; x+="#" ; $1 && print "$x" ; } ; l false; ( ulimit -c 0 ; l false) ; l true' ">##" 65 66 # integer 67 # (normal) 68 testfunc ${LINENO} '(function l { integer -S x ; x+=1 ; $1 && print "$x" ; } ; l false ; l false ; l true )' "3" 69 testfunc ${LINENO} '(function l { integer -S x ; x+=1 ; $1 && print "$x" ; } ; l false ; (l false) ; l true )' "2" 70 # (int) 71 testfunc ${LINENO} '(function l { typeset -S -i x ; x+=1 ; $1 && print "$x" ; } ; l false ; l false ; l true )' "3" 72 testfunc ${LINENO} '(function l { typeset -S -i x ; x+=1 ; $1 && print "$x" ; } ; l false ; (l false) ; l true )' "2" 73 # (short) 74 testfunc ${LINENO} '(function l { typeset -S -s -i x ; x+=1 ; $1 && print "$x" ; } ; l false ; l false ; l true )' "3" 75 testfunc ${LINENO} '(function l { typeset -S -s -i x ; x+=1 ; $1 && print "$x" ; } ; l false ; (l false) ; l true )' "2" 76 77 # float 78 testfunc ${LINENO} '(function l { float -S x=0.5 ; (( x+=.5 )) ; $1 && print "$x" ; } ; l false ; l false ; l true )' "2" 79 testfunc ${LINENO} '(function l { float -S x=0.5 ; (( x+=.5 )) ; $1 && print "$x" ; } ; l false ; (l false) ; l true )' "1.5" 80 81 return 0 82} 83 84# test2: test the more complex datatypes 85function test2 86{ 87 compound out=( typeset stdout stderr ; integer res ) 88 integer i 89 90 test_t -r -a tests=( 91 ( 92 name='compound' 93 cmd=$' 94 function l 95 { 96 compound -S s=( 97 integer a=1 98 integer b=2 99 ) 100 101 (( s.a++, s.b++ )) 102 103 $1 && printf "a=%d, b=%d\n" s.a s.b 104 } 105 (l false ; l false ; l true ; printf ";") 106 (l false ; l false ; l true ; printf ";") 107 ' 108 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 109 ) 110 ( 111 name='compound_nameref' 112 cmd=$' 113 function l_n 114 { 115 nameref sn=$2 116 (( sn.a++, sn.b++ )) 117 118 $1 && printf "a=%d, b=%d\n" sn.a sn.b 119 } 120 function l 121 { 122 compound -S s=( a=1 b=2 ) 123 l_n $1 s 124 } 125 (l false ; l false ; l true ; printf ";") 126 (l false ; l false ; l true ; printf ";") 127 ' 128 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 129 ) 130 131 ( 132 name='type' 133 cmd=$' 134 typeset -T ab_t=( 135 integer a=1 136 integer b=2 137 138 function increment 139 { 140 (( _.a++, _.b++ )) 141 } 142 ) 143 function l 144 { 145 ab_t -S s 146 147 s.increment 148 149 $1 && printf "a=%d, b=%d\n" s.a s.b 150 } 151 (l false ; l false ; l true ; printf ";") 152 (l false ; l false ; l true ; printf ";") 153 ' 154 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 155 ) 156 157 ( 158 name='type_nameref' 159 cmd=$' 160 typeset -T ab_t=( 161 integer a=1 162 integer b=2 163 164 function increment 165 { 166 (( _.a++, _.b++ )) 167 } 168 ) 169 function l_n 170 { 171 nameref sn=$2 172 173 sn.increment 174 175 $1 && printf "a=%d, b=%d\n" sn.a sn.b 176 } 177 function l 178 { 179 ab_t -S s 180 l_n $1 s 181 } 182 (l false ; l false ; l true ; printf ";") 183 (l false ; l false ; l true ; printf ";") 184 ' 185 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 186 ) 187 188 ( 189 name='indexed_string_array_appendelement' 190 cmd=$' 191 function ar 192 { 193 typeset -a -S s=( "hello" ) 194 195 s+=( "an element" ) 196 197 $1 && { printf "%s" "${s[@]}" ; printf "\n" ; } 198 } 199 (ar false ; ar false ; ar true ; printf ";") 200 (ar false ; ar false ; ar true ; printf ";") 201 ' 202 expected_output=$'helloan elementan elementan element\n;helloan elementan elementan element\n;' 203 ) 204 205 ( 206 name='indexed_string_array_nameref_appendelement' 207 cmd=$' 208 function ar_n 209 { 210 nameref sn=$2 211 sn+=( "an element" ) 212 213 $1 && { printf "%s" "${sn[@]}" ; printf "\n" ; } 214 } 215 function ar 216 { 217 typeset -a -S s=( "hello" ) 218 ar_n $1 s 219 } 220 (ar false ; ar false ; ar true ; printf ";") 221 (ar false ; ar false ; ar true ; printf ";") 222 ' 223 expected_output=$'helloan elementan elementan element\n;helloan elementan elementan element\n;' 224 ) 225 226 ( 227 name='associative_string_array_appendelement' 228 cmd=$' 229 function ar 230 { 231 typeset -A -S s=( [0]="hello" ) 232 233 s[$(( ${#s[@]} + 1))]="an element" 234 235 $1 && { printf "%s" "${s[@]}" ; printf "\n" ; } 236 } 237 (ar false ; ar false ; ar true ; printf ";") 238 (ar false ; ar false ; ar true ; printf ";") 239 ' 240 expected_output=$'helloan elementan elementan element\n;helloan elementan elementan element\n;' 241 ) 242 243 ( 244 name='associative_string_array_nameref_appendelement' 245 cmd=$' 246 function ar_n 247 { 248 nameref sn=$2 249 250 sn[$(( ${#sn[@]} + 1))]="an element" 251 252 $1 && { printf "%s" "${sn[@]}" ; printf "\n" ; } 253 } 254 function ar 255 { 256 typeset -A -S s=( [0]="hello" ) 257 ar_n $1 s 258 } 259 (ar false ; ar false ; ar true ; printf ";") 260 (ar false ; ar false ; ar true ; printf ";") 261 ' 262 expected_output=$'helloan elementan elementan element\n;helloan elementan elementan element\n;' 263 ) 264 265 ( 266 name='indexed_compound_array_editelement' 267 cmd=$' 268 function ar 269 { 270 compound -S -a s=( 271 [5]=( 272 integer a=1 273 integer b=2 274 ) 275 ) 276 277 (( s[5].a++, s[5].b++ )) 278 $1 && printf "a=%d, b=%d\n" s[5].a s[5].b 279 } 280 (ar false ; ar false ; ar true ; printf ";") 281 (ar false ; ar false ; ar true ; printf ";") 282 ' 283 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 284 ) 285 286 ( 287 name='indexed_compound_array_nameref_editelement' 288 cmd=$' 289 function ar_n 290 { 291 nameref sn=$2 292 293 (( sn.a++, sn.b++ )) 294 $1 && printf "a=%d, b=%d\n" sn.a sn.b 295 } 296 function ar 297 { 298 compound -S -a s=( 299 [5]=( 300 integer a=1 301 integer b=2 302 ) 303 ) 304 305 ar_n $1 s[5] 306 } 307 (ar false ; ar false ; ar true ; printf ";") 308 (ar false ; ar false ; ar true ; printf ";") 309 ' 310 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 311 ) 312 313 ( 314 name='2d_indexed_compound_array_editelement' 315 cmd=$' 316 function ar 317 { 318 compound -S -a s=( 319 [8][5]=( 320 integer a=1 321 integer b=2 322 ) 323 ) 324 325 (( s[8][5].a++, s[8][5].b++ )) 326 $1 && printf "a=%d, b=%d\n" s[8][5].a s[8][5].b 327 } 328 (ar false ; ar false ; ar true ; printf ";") 329 (ar false ; ar false ; ar true ; printf ";") 330 ' 331 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 332 ) 333 334 ( 335 name='2d_indexed_compound_array_nameref_editelement' 336 cmd=$' 337 function ar_n 338 { 339 nameref sn=$2 340 341 (( sn.a++, sn.b++ )) 342 $1 && printf "a=%d, b=%d\n" sn.a sn.b 343 } 344 function ar 345 { 346 compound -S -a s=( 347 [8][5]=( 348 integer a=1 349 integer b=2 350 ) 351 ) 352 353 ar_n $1 s[8][5] 354 } 355 (ar false ; ar false ; ar true ; printf ";") 356 (ar false ; ar false ; ar true ; printf ";") 357 ' 358 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 359 ) 360 ( 361 name='4d_indexed_compound_array_editelement' 362 cmd=$' 363 function ar 364 { 365 compound -S -a s=( 366 [8][5][0][9]=( 367 integer a=1 368 integer b=2 369 ) 370 ) 371 372 (( s[8][5][0][9].a++, s[8][5][0][9].b++ )) 373 $1 && printf "a=%d, b=%d\n" s[8][5][0][9].a s[8][5][0][9].b 374 } 375 (ar false ; ar false ; ar true ; printf ";") 376 (ar false ; ar false ; ar true ; printf ";") 377 ' 378 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 379 ) 380 381 ( 382 name='4d_indexed_compound_array_nameref_editelement' 383 cmd=$' 384 function ar_n 385 { 386 nameref sn=$2 387 388 (( sn.a++, sn.b++ )) 389 $1 && printf "a=%d, b=%d\n" sn.a sn.b 390 } 391 function ar 392 { 393 compound -S -a s=( 394 [8][5][0][9]=( 395 integer a=1 396 integer b=2 397 ) 398 ) 399 400 ar_n $1 s[8][5][0][9] 401 } 402 (ar false ; ar false ; ar true ; printf ";") 403 (ar false ; ar false ; ar true ; printf ";") 404 ' 405 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 406 ) 407 408 ( 409 name='associative_compound_array_editelement' 410 cmd=$' 411 function ar 412 { 413 compound -S -A s=( 414 [5]=( 415 integer a=1 416 integer b=2 417 ) 418 ) 419 420 (( s[5].a++, s[5].b++ )) 421 $1 && printf "a=%d, b=%d\n" s[5].a s[5].b 422 } 423 (ar false ; ar false ; ar true ; printf ";") 424 (ar false ; ar false ; ar true ; printf ";") 425 ' 426 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 427 ) 428 429 ( 430 name='associative_compound_array_nameref_editelement' 431 cmd=$' 432 function ar_n 433 { 434 nameref sn=$2 435 436 (( sn.a++, sn.b++ )) 437 $1 && printf "a=%d, b=%d\n" sn.a sn.b 438 } 439 function ar 440 { 441 compound -S -A s=( 442 [5]=( 443 integer a=1 444 integer b=2 445 ) 446 ) 447 448 ar_n $1 s[5] 449 } 450 (ar false ; ar false ; ar true ; printf ";") 451 (ar false ; ar false ; ar true ; printf ";") 452 ' 453 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 454 ) 455 456 ( 457 name='indexed_type_array_editelement' 458 cmd=$' 459 typeset -T ab_t=( 460 integer a=1 461 integer b=2 462 463 function increment 464 { 465 (( _.a++, _.b++ )) 466 } 467 ) 468 469 function ar 470 { 471 ab_t -S -a s 472 [[ -v s[5] ]] || s[5]=( ) # how do I init an array of types ? 473 474 s[5].increment 475 $1 && printf "a=%d, b=%d\n" s[5].a s[5].b 476 } 477 (ar false ; ar false ; ar true ; printf ";") 478 (ar false ; ar false ; ar true ; printf ";") 479 ' 480 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 481 ) 482 483 ( 484 name='indexed_type_array_nameref_editelement' 485 cmd=$' 486 typeset -T ab_t=( 487 integer a=1 488 integer b=2 489 490 function increment 491 { 492 (( _.a++, _.b++ )) 493 } 494 ) 495 496 function ar_n 497 { 498 nameref sn=$2 499 500 sn.increment 501 $1 && printf "a=%d, b=%d\n" sn.a sn.b 502 } 503 function ar 504 { 505 ab_t -S -a s 506 [[ -v s[5] ]] || s[5]=( ) # how do I init an array of types ? 507 508 ar_n $1 s[5] 509 } 510 (ar false ; ar false ; ar true ; printf ";") 511 (ar false ; ar false ; ar true ; printf ";") 512 ' 513 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 514 ) 515 516 ( 517 name='2d_indexed_type_array_editelement' 518 cmd=$' 519 typeset -T ab_t=( 520 integer a=1 521 integer b=2 522 523 function increment 524 { 525 (( _.a++, _.b++ )) 526 } 527 ) 528 529 function ar 530 { 531 ab_t -S -a s 532 [[ -v s[9][5] ]] || s[9][5]=( ) # how do I init an array of types ? 533 534 s[9][5].increment 535 $1 && printf "a=%d, b=%d\n" s[9][5].a s[9][5].b 536 } 537 (ar false ; ar false ; ar true ; printf ";") 538 (ar false ; ar false ; ar true ; printf ";") 539 ' 540 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 541 ) 542 543 ( 544 name='2d_indexed_type_array_nameref_editelement' 545 cmd=$' 546 typeset -T ab_t=( 547 integer a=1 548 integer b=2 549 550 function increment 551 { 552 (( _.a++, _.b++ )) 553 } 554 ) 555 556 function ar_n 557 { 558 nameref sn=$2 559 560 sn.increment 561 $1 && printf "a=%d, b=%d\n" sn.a sn.b 562 } 563 function ar 564 { 565 ab_t -S -a s 566 [[ -v s[9][5] ]] || s[9][5]=( ) # how do I init an array of types ? 567 568 ar_n $1 s[9][5] 569 } 570 (ar false ; ar false ; ar true ; printf ";") 571 (ar false ; ar false ; ar true ; printf ";") 572 ' 573 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 574 ) 575 576 ( 577 name='associative_type_array_editelement' 578 cmd=$' 579 typeset -T ab_t=( 580 integer a=1 581 integer b=2 582 583 function increment 584 { 585 (( _.a++, _.b++ )) 586 } 587 ) 588 589 function ar 590 { 591 ab_t -S -A s 592 [[ -v s[5] ]] || s[5]=( ) # how do I init an array of types ? 593 594 s[5].increment 595 $1 && printf "a=%d, b=%d\n" s[5].a s[5].b 596 } 597 (ar false ; ar false ; ar true ; printf ";") 598 (ar false ; ar false ; ar true ; printf ";") 599 ' 600 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 601 ) 602 603 ( 604 name='associative_type_array_nameref_editelement' 605 cmd=$' 606 typeset -T ab_t=( 607 integer a=1 608 integer b=2 609 610 function increment 611 { 612 (( _.a++, _.b++ )) 613 } 614 ) 615 616 function ar_n 617 { 618 nameref sn=$2 619 620 sn.increment 621 $1 && printf "a=%d, b=%d\n" sn.a sn.b 622 } 623 function ar 624 { 625 ab_t -S -A s 626 [[ -v s[5] ]] || s[5]=( ) # how do I init an array of types ? 627 628 ar_n $1 s[5] 629 } 630 (ar false ; ar false ; ar true ; printf ";") 631 (ar false ; ar false ; ar true ; printf ";") 632 ' 633 expected_output=$'a=4, b=5\n;a=4, b=5\n;' 634 ) 635 636 ) 637 638 for (( i=0 ; i < ${#tests[@]} ; i++ )) ; do 639 nameref currtest=tests[i] 640 641#print -u2 -- "${currtest.cmd}" 642 out.stderr="${ { out.stdout="${ ${SHELL} -o nounset -c "${currtest.cmd}" ; (( out.res=$? )) ; }" ; } 2>&1 ; }" 643 644 (( out.res == 0 )) || err_exit "${currtest.name}: Test shell returned with exit code ${out.res}" 645 [[ "${out.stdout}" == "${currtest.expected_output}" ]] || err_exit "${currtest.name}: Expected stdout == $(printf "%q\n" "${currtest.expected_output}"), got $(printf "%q\n" "${out.stdout}")" 646 [[ "${out.stderr}" == '' ]] || err_exit "${currtest.name}: Expected empty stderr, got $(printf "%q\n" "${out.stderr}")" 647 done 648 649 return 0 650} 651 652# run tests 653test1 654test2 655 656 657# Test visibilty of "global" vs. "static" variables. if we have a "static" variable in a 658# function and "unset" it we should see a global variable with the same 659# name, right ? 660integer hx=5 661function test_hx_scope 662{ 663 integer -S hx=9 664 $2 && unset hx 665 $1 && printf 'hx=%d\n' hx 666} 667test_hx_scope false false 668test_hx_scope false false 669# first test the "unset" call in a $(...) subshell... 670[[ "$( test_hx_scope true true )" == 'hx=5' ]] || err_exit "can't see global variable hx after unsetting static variable hx" 671# ... end then test whether the value has changed. 672[[ "${ test_hx_scope true false ;}" == 'hx=9' ]] || err_exit "hx variable somehow changed" 673 674out=$(function fun2 675{ 676 nameref sn=$1 677 (( sn.a++, sn.b++ )) 678 $2 && printf "a=%d, b=%d\n" sn.a sn.b 679} 680function fun1 681{ 682 compound -S s=( a=0 b=0 ) 683 fun2 s $1 684} 685(fun1 false ; fun1 false ; fun1 true) 686(fun1 false ; fun1 false ; fun1 true) 687) 688[[ $out == $'a=3, b=3\na=3, b=3' ]] || err_exit 'static variables in functions with initializers not working' 689 690exit $((Errors<125?Errors:125)) 691