Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/ksh93/tests/functions.sh
1810 views
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 <[email protected]> #
18
# #
19
########################################################################
20
function err_exit
21
{
22
print -u2 -n "\t"
23
print -u2 -r ${Command}[$1]: "${@:2}"
24
let Errors+=1
25
}
26
alias err_exit='err_exit $LINENO'
27
28
integer Errors=0
29
Command=${0##*/}
30
compiled=''
31
read -n4 c < $0 2> /dev/null
32
[[ $c == *$'\ck'* ]] && compiled=1
33
34
ulimit -c 0
35
36
tmp=$(mktemp -dt) || { err_exit mktemp -dt failed; exit 1; }
37
trap "cd /; rm -rf $tmp" EXIT
38
39
integer foo=33
40
bar=bye
41
# check for global variables and $0
42
function 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
}
54
function print
55
{
56
command print hi
57
}
58
if [[ $(print) != hi ]]
59
then err_exit "command print not working inside print function"
60
fi
61
unset -f print
62
63
if [[ $(foobar 1) != '33 bye' ]]
64
then err_exit 'global variables not correct'
65
fi
66
67
if [[ $(foobar 2) != 'foobar' ]]
68
then err_exit '$0 not correct'
69
fi
70
71
if [[ $(bar=foo foobar 1) != '33 foo' ]]
72
then err_exit 'environment override not correct'
73
fi
74
if [[ $bar == foo ]]
75
then err_exit 'scoping error'
76
fi
77
78
if [[ $(foobar 3) != 'foo 10' ]]
79
then err_exit non-local variables
80
fi
81
82
foobar 4
83
if [[ $foo != 36 ]]
84
then err_exit EXIT trap in wrong scope
85
fi
86
unset -f foobar || err_exit "cannot unset function foobar"
87
typeset -f foobar>/dev/null && err_exit "typeset -f has incorrect exit status"
88
89
function foobar
90
{
91
(return 0)
92
}
93
> $tmp/test1
94
{
95
foobar
96
if [ -r $tmp/test1 ]
97
then rm -r $tmp/test1
98
else err_exit 'return within subshell inside function error'
99
fi
100
}
101
abc() print hi
102
if [[ $(abc) != hi ]]
103
then err_exit 'abc() print hi not working'
104
fi
105
( unset -f abc )
106
if [[ $(abc 2>/dev/null) != hi ]]
107
then err_exit 'abc() print hi not working after subshell unset'
108
fi
109
(
110
function f
111
{
112
exit 1
113
}
114
f
115
err_exit 'exit from function not working'
116
)
117
unset -f foo
118
function 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
}
130
x=1
131
dir=$PWD
132
if [[ $(foo) != bar ]]
133
then err_exit 'cd inside nested subshell not working'
134
fi
135
if [[ $PWD != "$dir" ]]
136
then err_exit 'cd inside nested subshell changes $PWD'
137
fi
138
fun() /bin/echo hello
139
if [[ $(fun) != hello ]]
140
then err_exit one line functions not working
141
fi
142
cat > $tmp/script <<-\!
143
print -r -- "$1"
144
!
145
chmod +x $tmp/script
146
function passargs
147
{
148
$tmp/script "$@"
149
}
150
if [[ $(passargs one) != one ]]
151
then err_exit 'passing args from functions to scripts not working'
152
fi
153
cat > $tmp/script <<-\!
154
trap 'exit 0' EXIT
155
function foo
156
{
157
/tmp > /dev/null 2>&1
158
}
159
foo
160
!
161
if ! $tmp/script
162
then err_exit 'exit trap incorrectly triggered'
163
fi
164
if ! $SHELL -c $tmp/script
165
then err_exit 'exit trap incorrectly triggered when invoked with -c'
166
fi
167
$SHELL -c "trap 'rm $tmp/script' EXIT"
168
if [[ -f $tmp/script ]]
169
then err_exit 'exit trap not triggered when invoked with -c'
170
fi
171
cat > $tmp/script <<- \EOF
172
foobar()
173
{
174
return
175
}
176
shift
177
foobar
178
print -r -- "$1"
179
EOF
180
chmod +x $tmp/script
181
if [[ $( $SHELL $tmp/script arg1 arg2) != arg2 ]]
182
then err_exit 'arguments not restored by posix functions'
183
fi
184
function 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
)
197
if [[ $(foo) != hello ]]
198
then err_exit 'function definitions inside subshells not restored'
199
fi
200
unset -f foo bar
201
function bar
202
{
203
print "$y"
204
}
205
206
function foo
207
{
208
typeset x=3
209
y=$x bar
210
}
211
x=1
212
if [[ $(foo) != 3 ]]
213
then err_exit 'variable assignment list not using parent scope'
214
fi
215
unset -f foobar
216
cat > $tmp/foobar <<!
217
function foobar
218
{
219
print foo
220
}
221
!
222
chmod +x $tmp/foobar
223
FPATH=$tmp
224
autoload foobar
225
if [[ $(foobar 2>/dev/null) != foo ]]
226
then err_exit 'autoload not working'
227
fi
228
unset -f foobar
229
function foobar
230
{
231
typeset -r x=3
232
return 0
233
}
234
( foobar ) 2> /dev/null || err_exit "cannot unset readonly variable in function"
235
if $SHELL -n 2> /dev/null <<-!
236
abc()
237
!
238
then err_exit 'abc() without a function body is not a syntax error'
239
fi
240
function 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
}
251
if [[ $( (winpath --man 2>/dev/null); print ok) != ok ]]
252
then err_exit 'getopts --man in functions not working'
253
fi
254
if [[ $( (winpath -z 2>/dev/null); print ok) != ok ]]
255
then err_exit 'getopts with bad option in functions not working'
256
fi
257
unset -f x
258
function x
259
{
260
print "$@"
261
}
262
typeset -ft x
263
if [[ $(x x=y 2>/dev/null) != x=y ]]
264
then err_exit 'name=value pair args not passed to traced functions'
265
fi
266
function bad
267
{
268
false
269
}
270
trap 'val=false' ERR
271
val=true
272
bad
273
if [[ $val != false ]]
274
then err_exit 'set -e not working for functions'
275
fi
276
function bad
277
{
278
false
279
return 0
280
}
281
val=true
282
bad
283
if [[ $val != true ]]
284
then err_exit 'set -e not disabled for functions'
285
fi
286
bad()
287
{
288
false
289
return 0
290
}
291
val=true
292
bad
293
if [[ $val != false ]]
294
then err_exit 'set -e not inherited for posix functions'
295
fi
296
trap - ERR
297
298
function 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
}
312
export dgk=base
313
val=$(myexport dgk fun)
314
if [[ $val != fun ]]
315
then err_exit "export inside function not working -- expected 'fun', got '$val'"
316
fi
317
val=$(export | sed -e '/^dgk=/!d' -e 's/^dgk=//')
318
if [[ $val != base ]]
319
then err_exit "export not restored after function call -- expected 'base', got '$val'"
320
fi
321
val=$(myexport dgk fun fun2)
322
if [[ $val != fun2 ]]
323
then err_exit "export inside function not working with recursive function -- expected 'fun2', got '$val'"
324
fi
325
val=$(export | sed -e '/^dgk=/!d' -e 's/^dgk=//')
326
if [[ $val != base ]]
327
then err_exit "export not restored after recursive function call -- expected 'base', got '$val'"
328
fi
329
val=$(dgk=try3 myexport dgk)
330
if [[ $val != try3 ]]
331
then err_exit "name=value not added to export list with function call -- expected 'try3', got '$val'"
332
fi
333
val=$(export | sed -e '/^dgk=/!d' -e 's/^dgk=//')
334
if [[ $val != base ]]
335
then err_exit "export not restored name=value function call -- expected 'base', got '$val'"
336
fi
337
unset zzz
338
val=$(myexport zzz fun)
339
if [[ $val != fun ]]
340
then err_exit "export inside function not working -- expected 'fun', got '$val'"
341
fi
342
val=$(export | sed -e '/^zzz=/!d' -e 's/^zzz=//')
343
if [[ $val ]]
344
then err_exit "unset varaible exported after function call -- expected '', got '$val'"
345
fi
346
347
unset zzz
348
typeset -u zzz
349
function foo
350
{
351
zzz=abc
352
print $zzz
353
}
354
if [[ $(foo)$(foo) != ABCABC ]]
355
then err_exit 'attributes on unset variables not saved/restored'
356
fi
357
function xpd {
358
typeset i j=$1
359
for i
360
do print i=$i j=$j
361
[[ $i == a ]] && xpd b
362
done
363
}
364
if [[ $(xpd a c) != $'i=a j=a\ni=b j=b\ni=c j=a' ]]
365
then err_exit 'for loop function optimization error'
366
fi
367
368
typeset -A visited
369
integer level=0
370
function 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
}
384
closure 0 || err_exit -u2 'for loop function optimization bug2'
385
dir=$tmp/dir
386
mkdir $dir
387
cd $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'
403
rm -f file
404
405
print 'false' > try
406
chmod +x try
407
cat > tst <<- EOF
408
function ignore
409
{
410
./try
411
return 0
412
}
413
trap "print error; exit 1" ERR
414
ignore
415
EOF
416
if [[ $($SHELL < tst) == error ]]
417
then err_exit 'ERR trap not cleared'
418
fi
419
FPATH=$dir
420
print ': This does nothing' > foobar
421
chmod +x foobar
422
unset -f foobar
423
{ foobar; } 2>/dev/null
424
got=$?
425
exp=126
426
if [[ $got != $exp ]]
427
then err_exit "function file without function definition processes wrong error -- expected '$exp', got '$got'"
428
fi
429
print 'set a b c' > dotscript
430
[[ $(PATH=$PATH: $SHELL -c '. dotscript;print $#') == 3 ]] || err_exit 'positional parameters not preserved with . script without arguments'
431
cd ~- || err_exit "cd back failed"
432
function errcheck
433
{
434
trap 'print ERR; return 1' ERR
435
false
436
print ok
437
}
438
err=$(errcheck)
439
[[ $err == ERR ]] || err_exit 'trap on ERR not working in a function'
440
x="$(
441
function foobar
442
{
443
print ok
444
}
445
typeset -f foobar
446
)"
447
eval "$x" || err_exit 'typeset -f generates syntax error'
448
[[ $(foobar) != ok ]] && err_exit 'typeset -f not generating function'
449
unset -f a b c
450
a()
451
{
452
b
453
b
454
print ${.sh.fun}
455
}
456
b() { : ;}
457
[[ $(a) == a ]] || err_exit '.sh.fun not set correctly in a function'
458
print $'a(){\ndate\n}' | $SHELL 2> /dev/null || err_exit 'parser error in a(){;date;}'
459
cat > $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
481
cat > $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
743
f()
744
{
745
cat <<\M
746
++EOF
747
cat $tmp/data1 >> $tmp/script
748
printf 'M\n}\n\nf\n\n' >> $tmp/script
749
$SHELL -c $tmp/script > $tmp/data2
750
cmp -s $tmp/data[12] || err_exit 'error with long functions'
751
v=1
752
function 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
}
761
f || err_exit "typeset optimization bug"
762
function f
763
{
764
print -r -- "$foo$bar"
765
}
766
function g
767
{
768
print -r -- $(bar=bam f)
769
}
770
unset 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'
773
unset -f foo
774
function 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'
790
unset x
791
x=$(
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'
805
export environment
806
typeset global
807
function 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
}
836
f 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++
849
function main
850
{
851
typeset key
852
typeset -A entry
853
entry[a]=( value=aaa )
854
}
855
main
856
++EOF++
857
) 2> /dev/null || err_exit 'function main fails'
858
optind=$OPTIND
859
sub()
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
872
function bar
873
{
874
[[ -o nounset ]] && err_exit 'nounset option should not be inherited'
875
}
876
function foo
877
{
878
set -o nounset
879
bar
880
}
881
set +o nounset
882
foo
883
function 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'
892
xyz=$0
893
function 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
904
function foo
905
{
906
typeset xyz=foo
907
set -- $((LINENO+1))
908
bar $LINENO "$1"
909
}
910
911
function bar
912
{
913
typeset xyz=bar
914
set -- $((LINENO+2))
915
trap 'traceback $LINENO' DEBUG
916
: $LINENO "$1"
917
}
918
919
set -- $((LINENO+1))
920
foo $LINENO
921
function .sh.fun.set
922
{
923
print -r -- "${.sh.value}"
924
}
925
function abc
926
{
927
:
928
}
929
def()
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()'
935
unset -f .sh.fun.set
936
937
# tests for debug functions
938
basefile=${.sh.file}
939
integer baseline
940
cat > $tmp/debug << \+++
941
: line 1
942
943
: line 3
944
+++
945
# Print one line in a call stack
946
function _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
966
function _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))
978
trap '_Dbg_debug_trap_handler' DEBUG
979
. $tmp/debug foo bar
980
trap '' DEBUG
981
982
caller() {
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
}
990
bar() { caller;}
991
set -- $(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
{
996
got=$(
997
s=$(ulimit -s)
998
if [[ $s == +([[:digit:]]) ]] && (( s < 16384 ))
999
then ulimit -s 16384 2>/dev/null
1000
fi
1001
$SHELL << \+++
1002
f()
1003
{
1004
if (($1>1))
1005
then x=$(f $(($1-1))) || exit 1
1006
fi
1007
return 0
1008
}
1009
f 257 && print ok
1010
+++
1011
)
1012
} 2>/dev/null
1013
[[ $got == ok ]] || err_exit 'cannot handle comsub depth > 256 in function'
1014
1015
tmp1=$tmp/job.1
1016
tmp2=$tmp/job.2
1017
cat > $tmp1 << +++
1018
#! $SHELL
1019
print \$\$
1020
+++
1021
chmod +x $tmp1
1022
function foo
1023
{
1024
typeset pid
1025
$tmp1 > $tmp2 & pid=$!
1026
wait $!
1027
[[ $(< $tmp2) == $pid ]] || err_exit 'wrong pid for & job in function'
1028
}
1029
foo
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
1052
print $'print hello\nprint world' > $tmp/foo
1053
${SHCOMP:-${SHELL%/*}/shcomp} $tmp/foo > $tmp/foo.sh
1054
val=$(. $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.
1057
unset -f foo foobar bar
1058
cd "$tmp"
1059
FPATH=$PWD
1060
PATH=$FPATH:$PATH
1061
cat > foo <<- \EOF
1062
function bar
1063
{
1064
print foobar
1065
}
1066
function foo
1067
{
1068
bar
1069
}
1070
EOF
1071
chmod +x foo
1072
: $(foo)
1073
[[ $(typeset +f) == *foo* ]] && err_exit 'function in subshell leaving side effect of function foo'
1074
unset -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
1079
unset -f foo
1080
typeset -A bar
1081
function foo
1082
{
1083
typeset -i bar[$1].x
1084
bar[$1].x=5
1085
}
1086
foo sub
1087
[[ ${!bar[@]} == sub ]] || err_exit 'scoping problem with compound array variables'
1088
1089
function A
1090
{
1091
trap "> /dev/null;print TRAP A" EXIT
1092
# (( stderr )) && print >&2
1093
}
1094
1095
function B
1096
{
1097
trap "> /dev/null;print TRAP B" EXIT
1098
A
1099
}
1100
1101
x=$(B)
1102
[[ $x == $'TRAP A\nTRAP B' ]] || err_exit "trap from functions in subshells fails got" $x
1103
1104
function 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
}
1111
bar=bam
1112
foo
1113
1114
sleep=$(whence -p sleep)
1115
function gosleep
1116
{
1117
$sleep 4
1118
}
1119
x=$(
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()
1127
func1()
1128
{
1129
[[ $0 == "$dol0" ]] || err_exit "\$0 changed in func1() to $0"
1130
}
1131
function func2
1132
{
1133
[[ $0 == func2 ]] || err_exit "\$0 changed in func2() to $0"
1134
dol0=func2
1135
func1
1136
}
1137
func2
1138
1139
{ $SHELL <<- \EOF
1140
function foo
1141
{
1142
typeset rc=0
1143
unset -f foo
1144
return $rc;
1145
}
1146
foo
1147
EOF
1148
} 2> /dev/null || err_exit 'problem with unset -f foo within function foo'
1149
1150
val=$($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
1157
EOF)
1158
[[ $val == f1xtrace*on*off*f2xtrace*on* ]] || err_exit "'.sh.fun.set() { set -x; }' not tracing all functions"
1159
1160
function 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
}
1173
OPTIND=6 OPTARG=xxx
1174
foo -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
1178
if [[ ! $compiled ]]
1179
then function foo { getopts --man; }
1180
[[ $(typeset -f foo) == 'function foo { getopts --man; }' ]] || err_exit 'typeset -f not work for function with getopts'
1181
fi
1182
1183
function foo
1184
{
1185
let 1
1186
return $1
1187
}
1188
invals=(135 255 256 267 -1)
1189
outvals=(135 255 0 267 255)
1190
for ((i=0; i < ${#invals[@]}; i++))
1191
do foo ${invals[i]}
1192
[[ $? == "${outvals[i]}" ]] || err_exit "function exit ${invals[i]} should set \$? to ${outvals[i]}"
1193
done
1194
1195
function 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
}
1205
foo 2> /dev/null
1206
rc=$?
1207
exp=$((256+$(kill -l TERM) ))
1208
[[ $rc == "$exp" ]] || err_exit "expected exitval $exp got $rc"
1209
1210
exit $((Errors<125?Errors:125))
1211
1212