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 let Errors+=1 25} 26alias err_exit='err_exit $LINENO' 27 28integer Errors=0 29Command=${0##*/} 30compiled='' 31read -n4 c < $0 2> /dev/null 32[[ $c == *$'\ck'* ]] && compiled=1 33 34ulimit -c 0 35 36tmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; } 37trap "cd /; rm -rf $tmp" EXIT 38 39integer foo=33 40bar=bye 41# check for global variables and $0 42function foobar 43{ 44 case $1 in 45 1) print -r - "$foo" "$bar";; 46 2) print -r - "$0";; 47 3) typeset foo=foo 48 integer bar=10 49 print -r - "$foo" "$bar";; 50 4) trap 'foo=36' EXIT 51 typeset foo=20;; 52 esac 53} 54function print 55{ 56 command print hi 57} 58if [[ $(print) != hi ]] 59then err_exit "command print not working inside print function" 60fi 61unset -f print 62 63if [[ $(foobar 1) != '33 bye' ]] 64then err_exit 'global variables not correct' 65fi 66 67if [[ $(foobar 2) != 'foobar' ]] 68then err_exit '$0 not correct' 69fi 70 71if [[ $(bar=foo foobar 1) != '33 foo' ]] 72then err_exit 'environment override not correct' 73fi 74if [[ $bar == foo ]] 75then err_exit 'scoping error' 76fi 77 78if [[ $(foobar 3) != 'foo 10' ]] 79then err_exit non-local variables 80fi 81 82foobar 4 83if [[ $foo != 36 ]] 84then err_exit EXIT trap in wrong scope 85fi 86unset -f foobar || err_exit "cannot unset function foobar" 87typeset -f foobar>/dev/null && err_exit "typeset -f has incorrect exit status" 88 89function foobar 90{ 91 (return 0) 92} 93> $tmp/test1 94{ 95foobar 96if [ -r $tmp/test1 ] 97then rm -r $tmp/test1 98else err_exit 'return within subshell inside function error' 99fi 100} 101abc() print hi 102if [[ $(abc) != hi ]] 103then err_exit 'abc() print hi not working' 104fi 105( unset -f abc ) 106if [[ $(abc 2>/dev/null) != hi ]] 107then err_exit 'abc() print hi not working after subshell unset' 108fi 109( 110 function f 111 { 112 exit 1 113 } 114 f 115 err_exit 'exit from function not working' 116) 117unset -f foo 118function foo 119{ 120 x=2 121 ( 122 x=3 123 cd $tmp 124 print bar 125 ) 126 if [[ $x != 2 ]] 127 then err_exit 'value of x not restored after subshell inside function' 128 fi 129} 130x=1 131dir=$PWD 132if [[ $(foo) != bar ]] 133then err_exit 'cd inside nested subshell not working' 134fi 135if [[ $PWD != "$dir" ]] 136then err_exit 'cd inside nested subshell changes $PWD' 137fi 138fun() /bin/echo hello 139if [[ $(fun) != hello ]] 140then err_exit one line functions not working 141fi 142cat > $tmp/script <<-\! 143 print -r -- "$1" 144! 145chmod +x $tmp/script 146function passargs 147{ 148 $tmp/script "$@" 149} 150if [[ $(passargs one) != one ]] 151then err_exit 'passing args from functions to scripts not working' 152fi 153cat > $tmp/script <<-\! 154 trap 'exit 0' EXIT 155 function foo 156 { 157 /tmp > /dev/null 2>&1 158 } 159 foo 160! 161if ! $tmp/script 162then err_exit 'exit trap incorrectly triggered' 163fi 164if ! $SHELL -c $tmp/script 165then err_exit 'exit trap incorrectly triggered when invoked with -c' 166fi 167$SHELL -c "trap 'rm $tmp/script' EXIT" 168if [[ -f $tmp/script ]] 169then err_exit 'exit trap not triggered when invoked with -c' 170fi 171cat > $tmp/script <<- \EOF 172 foobar() 173 { 174 return 175 } 176 shift 177 foobar 178 print -r -- "$1" 179EOF 180chmod +x $tmp/script 181if [[ $( $SHELL $tmp/script arg1 arg2) != arg2 ]] 182then err_exit 'arguments not restored by posix functions' 183fi 184function foo 185{ 186 print hello 187} 188( 189 function foo 190 { 191 print bar 192 } 193 if [[ $(foo) != bar ]] 194 then err_exit 'function definitions inside subshells not working' 195 fi 196) 197if [[ $(foo) != hello ]] 198then err_exit 'function definitions inside subshells not restored' 199fi 200unset -f foo bar 201function bar 202{ 203 print "$y" 204} 205 206function foo 207{ 208 typeset x=3 209 y=$x bar 210} 211x=1 212if [[ $(foo) != 3 ]] 213then err_exit 'variable assignment list not using parent scope' 214fi 215unset -f foobar 216cat > $tmp/foobar <<! 217function foobar 218{ 219 print foo 220} 221! 222chmod +x $tmp/foobar 223FPATH=$tmp 224autoload foobar 225if [[ $(foobar 2>/dev/null) != foo ]] 226then err_exit 'autoload not working' 227fi 228unset -f foobar 229function foobar 230{ 231 typeset -r x=3 232 return 0 233} 234( foobar ) 2> /dev/null || err_exit "cannot unset readonly variable in function" 235if $SHELL -n 2> /dev/null <<-! 236 abc() 237 ! 238then err_exit 'abc() without a function body is not a syntax error' 239fi 240function winpath 241{ 242 usage='q pathname ...' 243 typeset var format=s 244 while getopts "$usage" var 245 do case $var in 246 q) format=q;; 247 esac 248 done 249 print done 250} 251if [[ $( (winpath --man 2>/dev/null); print ok) != ok ]] 252then err_exit 'getopts --man in functions not working' 253fi 254if [[ $( (winpath -z 2>/dev/null); print ok) != ok ]] 255then err_exit 'getopts with bad option in functions not working' 256fi 257unset -f x 258function x 259{ 260 print "$@" 261} 262typeset -ft x 263if [[ $(x x=y 2>/dev/null) != x=y ]] 264then err_exit 'name=value pair args not passed to traced functions' 265fi 266function bad 267{ 268 false 269} 270trap 'val=false' ERR 271val=true 272bad 273if [[ $val != false ]] 274then err_exit 'set -e not working for functions' 275fi 276function bad 277{ 278 false 279 return 0 280} 281val=true 282bad 283if [[ $val != true ]] 284then err_exit 'set -e not disabled for functions' 285fi 286bad() 287{ 288 false 289 return 0 290} 291val=true 292bad 293if [[ $val != false ]] 294then err_exit 'set -e not inherited for posix functions' 295fi 296trap - ERR 297 298function myexport 299{ 300 nameref var=$1 301 if (( $# > 1 )) 302 then export $1=$2 303 fi 304 if (( $# > 2 )) 305 then print $(myexport "$1" "$3" ) 306 return 307 fi 308 typeset val 309 val=$(export | grep "^$1=") 310 print ${val#"$1="} 311} 312export dgk=base 313val=$(myexport dgk fun) 314if [[ $val != fun ]] 315then err_exit "export inside function not working -- expected 'fun', got '$val'" 316fi 317val=$(export | sed -e '/^dgk=/!d' -e 's/^dgk=//') 318if [[ $val != base ]] 319then err_exit "export not restored after function call -- expected 'base', got '$val'" 320fi 321val=$(myexport dgk fun fun2) 322if [[ $val != fun2 ]] 323then err_exit "export inside function not working with recursive function -- expected 'fun2', got '$val'" 324fi 325val=$(export | sed -e '/^dgk=/!d' -e 's/^dgk=//') 326if [[ $val != base ]] 327then err_exit "export not restored after recursive function call -- expected 'base', got '$val'" 328fi 329val=$(dgk=try3 myexport dgk) 330if [[ $val != try3 ]] 331then err_exit "name=value not added to export list with function call -- expected 'try3', got '$val'" 332fi 333val=$(export | sed -e '/^dgk=/!d' -e 's/^dgk=//') 334if [[ $val != base ]] 335then err_exit "export not restored name=value function call -- expected 'base', got '$val'" 336fi 337unset zzz 338val=$(myexport zzz fun) 339if [[ $val != fun ]] 340then err_exit "export inside function not working -- expected 'fun', got '$val'" 341fi 342val=$(export | sed -e '/^zzz=/!d' -e 's/^zzz=//') 343if [[ $val ]] 344then err_exit "unset varaible exported after function call -- expected '', got '$val'" 345fi 346 347unset zzz 348typeset -u zzz 349function foo 350{ 351 zzz=abc 352 print $zzz 353} 354if [[ $(foo)$(foo) != ABCABC ]] 355then err_exit 'attributes on unset variables not saved/restored' 356fi 357function xpd { 358 typeset i j=$1 359 for i 360 do print i=$i j=$j 361 [[ $i == a ]] && xpd b 362 done 363 } 364if [[ $(xpd a c) != $'i=a j=a\ni=b j=b\ni=c j=a' ]] 365then err_exit 'for loop function optimization error' 366fi 367 368typeset -A visited 369integer level=0 370function closure 371{ 372 (( $# > 5 )) && return 1 373 ((level < 2)) && ((level++)) 374 typeset tmp r=0 375 visited[$1]=1 376 377 for tmp in $level _$level 378 do 379 [[ ${visited[$tmp]} == 1 ]] && continue 380 closure $tmp $* || r=1 381 done 382 return $r 383} 384closure 0 || err_exit -u2 'for loop function optimization bug2' 385dir=$tmp/dir 386mkdir $dir 387cd $dir || { err_exit "cd $dir failed"; exit 1; } 388 389( 390 function a { 391 print a 392 } 393 function b { 394 print 1 395 a 396 print 2 397 } > /dev/null 398 typeset -ft a b 399 PS4=X 400 b 401) > file 2>&1 402[[ $(<file) == *'Xprint 2'* ]] || err_exit 'function trace disabled by function call' 403rm -f file 404 405print 'false' > try 406chmod +x try 407cat > tst <<- EOF 408 function ignore 409 { 410 ./try 411 return 0 412 } 413 trap "print error; exit 1" ERR 414 ignore 415EOF 416if [[ $($SHELL < tst) == error ]] 417then err_exit 'ERR trap not cleared' 418fi 419FPATH=$dir 420print ': This does nothing' > foobar 421chmod +x foobar 422unset -f foobar 423{ foobar; } 2>/dev/null 424got=$? 425exp=126 426if [[ $got != $exp ]] 427then err_exit "function file without function definition processes wrong error -- expected '$exp', got '$got'" 428fi 429print 'set a b c' > dotscript 430[[ $(PATH=$PATH: $SHELL -c '. dotscript;print $#') == 3 ]] || err_exit 'positional parameters not preserved with . script without arguments' 431cd ~- || err_exit "cd back failed" 432function errcheck 433{ 434 trap 'print ERR; return 1' ERR 435 false 436 print ok 437} 438err=$(errcheck) 439[[ $err == ERR ]] || err_exit 'trap on ERR not working in a function' 440x="$( 441 function foobar 442 { 443 print ok 444 } 445 typeset -f foobar 446)" 447eval "$x" || err_exit 'typeset -f generates syntax error' 448[[ $(foobar) != ok ]] && err_exit 'typeset -f not generating function' 449unset -f a b c 450a() 451{ 452 b 453 b 454 print ${.sh.fun} 455} 456b() { : ;} 457[[ $(a) == a ]] || err_exit '.sh.fun not set correctly in a function' 458print $'a(){\ndate\n}' | $SHELL 2> /dev/null || err_exit 'parser error in a(){;date;}' 459cat > $tmp/data1 << '++EOF' 460 1 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 461 2 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 462 3 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 463 4 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 464 5 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 465 6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 466 7 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 467 8 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 468 9 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 469 10 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 470 11 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 471 12 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 472 13 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 473 14 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 474 15 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 475 16 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 476 17 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 477 18 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 478 19 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 479 20 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 480++EOF 481cat > $tmp/script << '++EOF' 482# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 483# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 484# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 485# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 486# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 487# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 488# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 489# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 490# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 491# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 492# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 493# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 494# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 495# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 496# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 497# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 498# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 499# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 500# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 501# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 502# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 503# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 504# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 505# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 506# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 507# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 508# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 509# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 510# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 511# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 512# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 513# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 514# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 515# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 516# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 517# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 518# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 519# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 520# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 521# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 522# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 523# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 524# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 525# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 526# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 527# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 528# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 529# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 530# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 531# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 532# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 533# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 534# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 535# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 536# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 537# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 538# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 539# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 540# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 541# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 542# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 543# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 544# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 545# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 546# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 547# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 548# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 549# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 550# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 551# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 552# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 553# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 554# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 555# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 556# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 557# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 558# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 559# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 560# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 561# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 562# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 563# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 564# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 565# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 566# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 567# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 568# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 569# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 570# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 571# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 572# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 573# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 574# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 575# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 576# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 577# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 578# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 579# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 580# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 581# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 582# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 583# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 584# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 585# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 586# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 587# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 588# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 589# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 590# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 591# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 592# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 593# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 594# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 595# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 596# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 597# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 598# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 599# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 600# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 601# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 602# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 603# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 604# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 605# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 606# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 607# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 608# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 609# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 610# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 611# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 612# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 613# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 614# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 615# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 616# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 617# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 618# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 619# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 620# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 621# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 622# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 623# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 624# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 625# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 626# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 627# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 628# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 629# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 630# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 631# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 632# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 633# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 634# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 635# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 636# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 637# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 638# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 639# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 640# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 641# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 642# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 643# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 644# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 645# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 646# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 647# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 648# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 649# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 650# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 651# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 652# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 653# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 654# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 655# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 656# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 657# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 658# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 659# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 660# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 661# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 662# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 663# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 664# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 665# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 666# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 667# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 668# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 669# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 670# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 671# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 672# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 673# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 674# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 675# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 676# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 677# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 678# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 679# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 680# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 681# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 682# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 683# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 684# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 685# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 686# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 687# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 688# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 689# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 690# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 691# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 692# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 693# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 694# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 695# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 696# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 697# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 698# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 699# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 700# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 701# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 702# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 703# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 704# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 705# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 706# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 707# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 708# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 709# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 710# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 711# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 712# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 713# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 714# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 715# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 716# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 717# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 718# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 719# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 720# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 721# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 722# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 723# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 724# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 725# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 726# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 727# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 728# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 729# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 730# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 731# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 732# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 733# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 734# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 735# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 736# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 737# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 738# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 739# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 740# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 741# XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX 742 743f() 744{ 745cat <<\M 746++EOF 747cat $tmp/data1 >> $tmp/script 748printf 'M\n}\n\nf\n\n' >> $tmp/script 749$SHELL -c $tmp/script > $tmp/data2 750cmp -s $tmp/data[12] || err_exit 'error with long functions' 751v=1 752function f 753{ 754 typeset i 755 for i in 0 1 756 do typeset v 757 v=$i 758 [[ $v == $i ]] || return 1 759 done 760} 761f || err_exit "typeset optimization bug" 762function f 763{ 764 print -r -- "$foo$bar" 765} 766function g 767{ 768 print -r -- $(bar=bam f) 769} 770unset foo bar 771[[ $(foo=hello g) == hellobam ]] || err_exit 'function exports not passed on' 772[[ $(bar=hello g) == bam ]] || err_exit 'function exports not overridden' 773unset -f foo 774function foo 775{ 776 typeset line=$1 777 set +n 778 while [[ $line ]] 779 do if [[ ! $varname ]] 780 then varname=${line%% *} 781 line=${line##"$varname"?( )} 782 [[ $line ]] && continue 783 else print ok 784 return 785 fi 786 varname= 787 done 788} 789[[ $(foo 'NUMBERED RECORDSIZE') == ok ]] || err_exit 'optimization error with undefined variable' 790unset x 791x=$( 792 set -e 793 integer count=0 794 function err_f 795 { 796 if ((count++==3)) 797 then print failed 798 else false 799 fi 800 } 801 trap 'err_f' ERR 802 false 803) 804[[ $x == failed ]] && err_exit 'ERR trap executed multiple times' 805export environment 806typeset global 807function f 808{ 809 typeset i t local 810 811 for i 812 do case $i in 813 [-+]*) set "$@" 814 continue 815 ;; 816 local) local=f 817 t=$(typeset +f $local) 818 ;; 819 global) global=f 820 t=$(typeset +f $global) 821 ;; 822 environment) 823 environment=f 824 t=$(typeset +f $environment) 825 ;; 826 literal)t=$(typeset +f f) 827 ;; 828 positional) 829 set -- f 830 t=$(typeset +f $1) 831 ;; 832 esac 833 [[ $t ]] || err_exit "typeset +f \$$i failed" 834 done 835} 836f local global environment literal positional 837$SHELL -c ' 838 print exit 0 > '$tmp'/script 839 chmod +x '$tmp'/script 840 unset var 841 var=( ident=1 ) 842 function fun 843 { 844 PATH='$tmp' script 845 } 846 fun 847' || err_exit "compound variable cleanup before script exec failed" 848( $SHELL << \++EOF++ 849function main 850{ 851 typeset key 852 typeset -A entry 853 entry[a]=( value=aaa ) 854} 855main 856++EOF++ 857) 2> /dev/null || err_exit 'function main fails' 858optind=$OPTIND 859sub() 860{ 861 ( 862 OPTIND=1 863 while getopts :abc OPTION "$@" 864 do print OPTIND=$OPTIND 865 done 866 ) 867} 868[[ $(sub -a) == OPTIND=2 ]] || err_exit 'OPTIND should be 2' 869[[ $(sub -a) == OPTIND=2 ]] || err_exit 'OPTIND should be 2 again' 870[[ $OPTIND == "$optind" ]] || err_exit 'OPTIND should be 1' 871 872function bar 873{ 874 [[ -o nounset ]] && err_exit 'nounset option should not be inherited' 875} 876function foo 877{ 878 set -o nounset 879 bar 880} 881set +o nounset 882foo 883function red 884{ 885 integer -S d=0 886 printf 'red_one %d\n' d 887 (( d++ )) 888 return 0 889} 890[[ ${ red } != 'red_one 0' ]] && err_exit 'expected red_one 0' 891[[ ${ red } != 'red_one 1' ]] && err_exit 'expected red_one 1' 892xyz=$0 893function traceback 894{ 895 integer .level=.sh.level 896 while((--.level>=0)) 897 do 898 ((.sh.level = .level)) 899 [[ $xyz == "$0" ]] || err_exit "\$xyz=$xyz does not match $0 on level ${.level}" 900 [[ ${.sh.lineno} == "$1" ]] || err_exit "\${.sh.lineno}=${.sh.lineno} does not match $1 on level ${.level}" 901 done 902} 903 904function foo 905{ 906 typeset xyz=foo 907 set -- $((LINENO+1)) 908 bar $LINENO "$1" 909} 910 911function bar 912{ 913 typeset xyz=bar 914 set -- $((LINENO+2)) 915 trap 'traceback $LINENO' DEBUG 916 : $LINENO "$1" 917} 918 919set -- $((LINENO+1)) 920foo $LINENO 921function .sh.fun.set 922{ 923 print -r -- "${.sh.value}" 924} 925function abc 926{ 927 : 928} 929def() 930{ 931 : 932} 933[[ $(abc) == abc ]] || err_exit '.sh.fun.set not capturing function name' 934[[ $(def) == def ]] || err_exit '.sh.fun.set not capturing name()' 935unset -f .sh.fun.set 936 937# tests for debug functions 938basefile=${.sh.file} 939integer baseline 940cat > $tmp/debug << \+++ 941 : line 1 942 943 : line 3 944+++ 945# Print one line in a call stack 946function _Dbg_print_frame 947{ 948 typeset -i pos=$1 949 typeset fn=$2 950 typeset filename="$3" 951 typeset -i line=$4 952 typeset arg=$5 953 shift 5 954 if ((pos==0)) 955 then [[ $filename == "$basefile" ]] || err_exit "filename for level 0 is $filename not $basename" 956 [[ $arg == DEBUG ]] && ((baseline++)) 957 [[ $line == "$baseline" ]] || err_exit "line number for level 0 is $line not $baseline" 958 elif ((pos==1)) 959 then [[ $filename == "$tmp/debug" ]] || err_exit "filename for level 1 is $filename not $tmp/debug" 960 [[ $* == 'foo bar' ]] || err_exit "args are '$*', not 'foo bar'" 961 [[ $line == $arg ]] || err_exit "line number for level 1 is $line not $arg" 962 else err_exit "level should be 0 or 1 but is $pos" 963 fi 964} 965 966function _Dbg_debug_trap_handler 967{ 968 969 integer .level=.sh.level .max=.sh.level-1 970 while((--.level>=0)) 971 do 972 ((.sh.level = .level)) 973 _Dbg_print_frame "${.level}" "$0" "${.sh.file}" "${.sh.lineno}" "${.sh.command##* }" "$@" 974 done 975} 976 977((baseline=LINENO+2)) 978trap '_Dbg_debug_trap_handler' DEBUG 979. $tmp/debug foo bar 980trap '' DEBUG 981 982caller() { 983 integer .level=.sh.level .max=.sh.level-1 984 while((--.level>=0)) 985 do 986 ((.sh.level = .level)) 987 print -r -- "${.sh.lineno}" 988 done 989} 990bar() { caller;} 991set -- $(bar) 992[[ $1 == $2 ]] && err_exit ".sh.inline optimization bug" 993( $SHELL -c ' function foo { typeset x=$1;print $1;};z=();z=($(foo bar)) ') 2> /dev/null || err_exit 'using a function to set an array in a command sub fails' 994 995{ 996got=$( 997s=$(ulimit -s) 998if [[ $s == +([[:digit:]]) ]] && (( s < 16384 )) 999then ulimit -s 16384 2>/dev/null 1000fi 1001$SHELL << \+++ 1002f() 1003{ 1004 if (($1>1)) 1005 then x=$(f $(($1-1))) || exit 1 1006 fi 1007 return 0 1008} 1009f 257 && print ok 1010+++ 1011) 1012} 2>/dev/null 1013[[ $got == ok ]] || err_exit 'cannot handle comsub depth > 256 in function' 1014 1015tmp1=$tmp/job.1 1016tmp2=$tmp/job.2 1017cat > $tmp1 << +++ 1018#! $SHELL 1019print \$\$ 1020+++ 1021chmod +x $tmp1 1022function foo 1023{ 1024 typeset pid 1025 $tmp1 > $tmp2 & pid=$! 1026 wait $! 1027 [[ $(< $tmp2) == $pid ]] || err_exit 'wrong pid for & job in function' 1028} 1029foo 1030# make sure compiled functions work 1031[[ $(tmp=$tmp $SHELL <<- \++++ 1032 cat > $tmp/functions <<- \EOF 1033 function bar 1034 { 1035 print foo 1036 } 1037 function foobar 1038 { 1039 bar 1040 } 1041 EOF 1042 ${SHCOMP:-${SHELL%/*}/shcomp} $tmp/functions > $tmp/foobar 1043 rm -f "$tmp/functions" 1044 chmod +x $tmp/foobar 1045 rm $tmp/!(dir|foobar) 1046 FPATH=$tmp 1047 PATH=$FPATH:$PATH 1048 foobar 1049++++ 1050) == foo ]] > /dev/null || err_exit 'functions compiled with shcomp not working' 1051# tests for compiled . scripts 1052print $'print hello\nprint world' > $tmp/foo 1053${SHCOMP:-${SHELL%/*}/shcomp} $tmp/foo > $tmp/foo.sh 1054val=$(. $tmp/foo.sh) 1055[[ $val == $'hello\nworld' ]] || err_exit "processing compiled dot files not working correctly val=$val" 1056# test for functions in shell having side effects. 1057unset -f foo foobar bar 1058cd "$tmp" 1059FPATH=$PWD 1060PATH=$FPATH:$PATH 1061cat > foo <<- \EOF 1062 function bar 1063 { 1064 print foobar 1065 } 1066 function foo 1067 { 1068 bar 1069 } 1070EOF 1071chmod +x foo 1072: $(foo) 1073[[ $(typeset +f) == *foo* ]] && err_exit 'function in subshell leaving side effect of function foo' 1074unset -f foo bar 1075: $(foo) 1076[[ $(typeset +f) == *foo* ]] && err_exit 'function in subshell leaving side effects of function foo after reload' 1077[[ $(typeset +f) == *bar* ]] && err_exit 'function in subshell leaving side effects of function bar after reload' 1078 1079unset -f foo 1080typeset -A bar 1081function foo 1082{ 1083 typeset -i bar[$1].x 1084 bar[$1].x=5 1085} 1086foo sub 1087[[ ${!bar[@]} == sub ]] || err_exit 'scoping problem with compound array variables' 1088 1089function A 1090{ 1091 trap "> /dev/null;print TRAP A" EXIT 1092 # (( stderr )) && print >&2 1093} 1094 1095function B 1096{ 1097 trap "> /dev/null;print TRAP B" EXIT 1098 A 1099} 1100 1101x=$(B) 1102[[ $x == $'TRAP A\nTRAP B' ]] || err_exit "trap from functions in subshells fails got" $x 1103 1104function foo 1105{ 1106 typeset bar=abc 1107 unset bar 1108# [[ $bar == bam ]] || err_exit 'unsetting local variable does not expose global variable' 1109 [[ $bar ]] && err_exit 'unsetting local variable exposes global variable' 1110} 1111bar=bam 1112foo 1113 1114sleep=$(whence -p sleep) 1115function gosleep 1116{ 1117 $sleep 4 1118} 1119x=$( 1120 (sleep 2; pid=; ps | grep sleep | read pid extra; [[ $pid ]] && kill -- $pid) & 1121 gosleep 2> /dev/null 1122 print ok 1123) 1124[[ $x == ok ]] || err_exit 'TERM signal sent to last process of function kills the script' 1125 1126# verify that $0 does not change with functions defined as fun() 1127func1() 1128{ 1129 [[ $0 == "$dol0" ]] || err_exit "\$0 changed in func1() to $0" 1130} 1131function func2 1132{ 1133 [[ $0 == func2 ]] || err_exit "\$0 changed in func2() to $0" 1134 dol0=func2 1135 func1 1136} 1137func2 1138 1139{ $SHELL <<- \EOF 1140 function foo 1141 { 1142 typeset rc=0 1143 unset -f foo 1144 return $rc; 1145 } 1146 foo 1147EOF 1148} 2> /dev/null || err_exit 'problem with unset -f foo within function foo' 1149 1150val=$($SHELL 2> /dev/null <<- \EOF 1151 .sh.fun.set() { set -x; } 1152 function f1 { print -n ${.sh.fun}; set -o | grep xtrace;} 1153 function f2 { print -n ${.sh.fun}; set -o | grep xtrace;} 1154 f1 1155 set -o | grep xtrace 1156 f2 1157EOF) 1158[[ $val == f1xtrace*on*off*f2xtrace*on* ]] || err_exit "'.sh.fun.set() { set -x; }' not tracing all functions" 1159 1160function foo 1161{ 1162 typeset opt OPTIND=1 OPTARG hflag= 1163 while getopts hi: opt 1164 do case $opt in 1165 h) hflag=1;; 1166 i) [[ $OPTARG == foobar ]] || err_exit 'OPTARG should be set to foobar in function foo';; 1167 esac 1168 done 1169 shift $((OPTIND - 1)) 1170 (( OPTIND == 4 )) || err_exit "OPTIND is $OPTIND at end of function foo; it should be 4" 1171 [[ $1 == foo2 ]] || err_exit "\$1 is $1, not foo after getopts in function" 1172} 1173OPTIND=6 OPTARG=xxx 1174foo -h -i foobar foo2 1175[[ $OPTARG == xxx ]] || err_exit 'getopts in function changes global OPTARG' 1176(( OPTIND == 6 )) || err_exit 'getopts in function changes global OPTIND' 1177 1178if [[ ! $compiled ]] 1179then function foo { getopts --man; } 1180 [[ $(typeset -f foo) == 'function foo { getopts --man; }' ]] || err_exit 'typeset -f not work for function with getopts' 1181fi 1182 1183function foo 1184{ 1185 let 1 1186 return $1 1187} 1188invals=(135 255 256 267 -1) 1189outvals=(135 255 0 267 255) 1190for ((i=0; i < ${#invals[@]}; i++)) 1191do foo ${invals[i]} 1192 [[ $? == "${outvals[i]}" ]] || err_exit "function exit ${invals[i]} should set \$? to ${outvals[i]}" 1193done 1194 1195function foo 1196{ 1197 typeset pid 1198 sleep 2 & pid=$! 1199 sleep 1 1200 kill -TERM $pid 1201 wait $pid 1202 rc=$? 1203 return $rc 1204} 1205foo 2> /dev/null 1206rc=$? 1207exp=$((256+$(kill -l TERM) )) 1208[[ $rc == "$exp" ]] || err_exit "expected exitval $exp got $rc" 1209 1210exit $((Errors<125?Errors:125)) 1211