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