1*b30d1939SAndy Fiddaman########################################################################
2*b30d1939SAndy Fiddaman#                                                                      #
3*b30d1939SAndy Fiddaman#               This software is part of the ast package               #
4*b30d1939SAndy Fiddaman#          Copyright (c) 1982-2012 AT&T Intellectual Property          #
5*b30d1939SAndy Fiddaman#                      and is licensed under the                       #
6*b30d1939SAndy Fiddaman#                 Eclipse Public License, Version 1.0                  #
7*b30d1939SAndy Fiddaman#                    by AT&T Intellectual Property                     #
8*b30d1939SAndy Fiddaman#                                                                      #
9*b30d1939SAndy Fiddaman#                A copy of the License is available at                 #
10*b30d1939SAndy Fiddaman#          http://www.eclipse.org/org/documents/epl-v10.html           #
11*b30d1939SAndy Fiddaman#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
12*b30d1939SAndy Fiddaman#                                                                      #
13*b30d1939SAndy Fiddaman#              Information and Software Systems Research               #
14*b30d1939SAndy Fiddaman#                            AT&T Research                             #
15*b30d1939SAndy Fiddaman#                           Florham Park NJ                            #
16*b30d1939SAndy Fiddaman#                                                                      #
17*b30d1939SAndy Fiddaman#                  David Korn <dgk@research.att.com>                   #
18*b30d1939SAndy Fiddaman#                                                                      #
19*b30d1939SAndy Fiddaman########################################################################
20*b30d1939SAndy Fiddaman########################################################################
21*b30d1939SAndy Fiddaman#                                                                      #
22*b30d1939SAndy Fiddaman#               This software is part of the ast package               #
23*b30d1939SAndy Fiddaman#          Copyright (c) 1982-2012 AT&T Intellectual Property          #
24*b30d1939SAndy Fiddaman#                      and is licensed under the                       #
25*b30d1939SAndy Fiddaman#                 Eclipse Public License, Version 1.0                  #
26*b30d1939SAndy Fiddaman#                    by AT&T Intellectual Property                     #
27*b30d1939SAndy Fiddaman#                                                                      #
28*b30d1939SAndy Fiddaman#                A copy of the License is available at                 #
29*b30d1939SAndy Fiddaman#          http://www.eclipse.org/org/documents/epl-v10.html           #
30*b30d1939SAndy Fiddaman#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
31*b30d1939SAndy Fiddaman#                                                                      #
32*b30d1939SAndy Fiddaman#              Information and Software Systems Research               #
33*b30d1939SAndy Fiddaman#                            AT&T Research                             #
34*b30d1939SAndy Fiddaman#                           Florham Park NJ                            #
35*b30d1939SAndy Fiddaman#                                                                      #
36*b30d1939SAndy Fiddaman#              Roland Mainz <roland.mainz@nrubsig.org>                 #
37*b30d1939SAndy Fiddaman#                                                                      #
38*b30d1939SAndy Fiddaman########################################################################
39*b30d1939SAndy Fiddaman
40*b30d1939SAndy Fiddaman# test setup
41*b30d1939SAndy Fiddamanfunction err_exit
42*b30d1939SAndy Fiddaman{
43*b30d1939SAndy Fiddaman	print -u2 -n '\t'
44*b30d1939SAndy Fiddaman	print -u2 -r ${Command}[$1]: "${@:2}"
45*b30d1939SAndy Fiddaman	(( Errors++ ))
46*b30d1939SAndy Fiddaman}
47*b30d1939SAndy Fiddamanalias err_exit='err_exit $LINENO'
48*b30d1939SAndy Fiddaman
49*b30d1939SAndy Fiddaman# "nounset" disabled for now
50*b30d1939SAndy Fiddaman#set -o nounset
51*b30d1939SAndy FiddamanCommand=${0##*/}
52*b30d1939SAndy Fiddamaninteger Errors=0 HAVE_signbit=0
53*b30d1939SAndy Fiddaman
54*b30d1939SAndy Fiddamanif	typeset -f .sh.math.signbit >/dev/null && (( signbit(-NaN) ))
55*b30d1939SAndy Fiddamanthen	HAVE_signbit=1
56*b30d1939SAndy Fiddamanelse	print -u2 "$0: warning: -lm does not support signbit(-NaN)"
57*b30d1939SAndy Fiddamanfi
58*b30d1939SAndy Fiddaman
59*b30d1939SAndy Fiddamancompound bracketstat=(
60*b30d1939SAndy Fiddaman	integer bopen=0
61*b30d1939SAndy Fiddaman	integer bclose=0
62*b30d1939SAndy Fiddaman)
63*b30d1939SAndy Fiddaman
64*b30d1939SAndy Fiddamanfunction count_brackets
65*b30d1939SAndy Fiddaman{
66*b30d1939SAndy Fiddaman	typeset x="$1"
67*b30d1939SAndy Fiddaman	typeset c
68*b30d1939SAndy Fiddaman
69*b30d1939SAndy Fiddaman	integer i
70*b30d1939SAndy Fiddaman	(( bracketstat.bopen=0 , bracketstat.bclose=0 ))
71*b30d1939SAndy Fiddaman
72*b30d1939SAndy Fiddaman	for (( i=0 ; i < ${#x} ; i++ )) ; do
73*b30d1939SAndy Fiddaman	        c="${x:i:1}"
74*b30d1939SAndy Fiddaman		[[ "$c" == '(' ]] && (( bracketstat.bopen++ ))
75*b30d1939SAndy Fiddaman		[[ "$c" == ')' ]] && (( bracketstat.bclose++ ))
76*b30d1939SAndy Fiddaman	done
77*b30d1939SAndy Fiddaman
78*b30d1939SAndy Fiddaman	(( bracketstat.bopen != bracketstat.bclose )) && return 1
79*b30d1939SAndy Fiddaman
80*b30d1939SAndy Fiddaman	return 0
81*b30d1939SAndy Fiddaman}
82*b30d1939SAndy Fiddaman
83*b30d1939SAndy Fiddaman# compound variable "cat" nr.1, using $ print "%B\n" ... #
84*b30d1939SAndy Fiddamanfunction cpvcat1
85*b30d1939SAndy Fiddaman{
86*b30d1939SAndy Fiddaman	set -o errexit
87*b30d1939SAndy Fiddaman	compound tmp
88*b30d1939SAndy Fiddaman
89*b30d1939SAndy Fiddaman	while read -C tmp ; do printf '%B\n' tmp ; done
90*b30d1939SAndy Fiddaman	return 0
91*b30d1939SAndy Fiddaman}
92*b30d1939SAndy Fiddaman
93*b30d1939SAndy Fiddaman# compound variable "cat" nr.2, using $ print "%#B\n" ... #
94*b30d1939SAndy Fiddamanfunction cpvcat2
95*b30d1939SAndy Fiddaman{
96*b30d1939SAndy Fiddaman	set -o errexit
97*b30d1939SAndy Fiddaman	compound tmp
98*b30d1939SAndy Fiddaman
99*b30d1939SAndy Fiddaman	while read -C tmp ; do printf '%#B\n' tmp ; done
100*b30d1939SAndy Fiddaman	return 0
101*b30d1939SAndy Fiddaman}
102*b30d1939SAndy Fiddaman
103*b30d1939SAndy Fiddaman# compound variable "cat" nr.3, using $ print -C ... #
104*b30d1939SAndy Fiddamanfunction cpvcat3
105*b30d1939SAndy Fiddaman{
106*b30d1939SAndy Fiddaman	set -o errexit
107*b30d1939SAndy Fiddaman	compound tmp
108*b30d1939SAndy Fiddaman
109*b30d1939SAndy Fiddaman	while read -C tmp ; do print -C tmp ; done
110*b30d1939SAndy Fiddaman	return 0
111*b30d1939SAndy Fiddaman}
112*b30d1939SAndy Fiddaman
113*b30d1939SAndy Fiddaman# compound variable "cat" nr.4, using $ print -v ... #
114*b30d1939SAndy Fiddamanfunction cpvcat4
115*b30d1939SAndy Fiddaman{
116*b30d1939SAndy Fiddaman	set -o errexit
117*b30d1939SAndy Fiddaman	compound tmp
118*b30d1939SAndy Fiddaman
119*b30d1939SAndy Fiddaman	while read -C tmp ; do print -v tmp ; done
120*b30d1939SAndy Fiddaman	return 0
121*b30d1939SAndy Fiddaman}
122*b30d1939SAndy Fiddaman
123*b30d1939SAndy Fiddamantypeset s
124*b30d1939SAndy Fiddaman
125*b30d1939SAndy Fiddaman# Test 1:
126*b30d1939SAndy Fiddaman# Check whether "read -C" leaves the file pointer at the next line
127*b30d1939SAndy Fiddaman# (and does not read beyond that point).
128*b30d1939SAndy Fiddaman# Data layout is:
129*b30d1939SAndy Fiddaman# -- snip --
130*b30d1939SAndy Fiddaman# <compound var>
131*b30d1939SAndy Fiddaman# hello
132*b30d1939SAndy Fiddaman# -- snip --
133*b30d1939SAndy Fiddaman# (additionally we test some extra stuff like bracket count)
134*b30d1939SAndy Fiddamans=${
135*b30d1939SAndy Fiddaman	compound x=(
136*b30d1939SAndy Fiddaman		a=1 b=2
137*b30d1939SAndy Fiddaman		typeset -a myarray=( 1 2 3 4 5 6 7 8 9 10 )
138*b30d1939SAndy Fiddaman		typeset -A myarray2=( [a]=1 [b]=2 ["c d"]=3 [e]=4 ["f"]=5 [g]=6 [h]=7 [i]=8 [j]=9 [k]=10 )
139*b30d1939SAndy Fiddaman		typeset -A myarray3=(
140*b30d1939SAndy Fiddaman			[a]=(
141*b30d1939SAndy Fiddaman				float m1=0.5
142*b30d1939SAndy Fiddaman				float m2=0.6
143*b30d1939SAndy Fiddaman				foo="hello"
144*b30d1939SAndy Fiddaman			)
145*b30d1939SAndy Fiddaman			[b]=(
146*b30d1939SAndy Fiddaman				foo="bar"
147*b30d1939SAndy Fiddaman			)
148*b30d1939SAndy Fiddaman			["c d"]=(
149*b30d1939SAndy Fiddaman				integer at=90
150*b30d1939SAndy Fiddaman			)
151*b30d1939SAndy Fiddaman			[e]=(
152*b30d1939SAndy Fiddaman				compound nested_cpv=(
153*b30d1939SAndy Fiddaman					typeset -a myarray=( 1 2 3 4 5 6 7 8 9 10 )
154*b30d1939SAndy Fiddaman					typeset str=$'a \'string'
155*b30d1939SAndy Fiddaman				)
156*b30d1939SAndy Fiddaman			)
157*b30d1939SAndy Fiddaman			[f]=(
158*b30d1939SAndy Fiddaman				typeset g="f"
159*b30d1939SAndy Fiddaman			)
160*b30d1939SAndy Fiddaman			[a_nan]=(
161*b30d1939SAndy Fiddaman				float my_nan=-nan
162*b30d1939SAndy Fiddaman			)
163*b30d1939SAndy Fiddaman			[a_hexfloat]=(
164*b30d1939SAndy Fiddaman			       typeset -X my_hexfloat=1.1
165*b30d1939SAndy Fiddaman			)
166*b30d1939SAndy Fiddaman		)
167*b30d1939SAndy Fiddaman	)
168*b30d1939SAndy Fiddaman
169*b30d1939SAndy Fiddaman	{
170*b30d1939SAndy Fiddaman		printf "%B\n" x
171*b30d1939SAndy Fiddaman		print "hello"
172*b30d1939SAndy Fiddaman	} | cpvcat1 | cpvcat2 | cpvcat3 | cpvcat4 | {
173*b30d1939SAndy Fiddaman		read -C y
174*b30d1939SAndy Fiddaman		read s
175*b30d1939SAndy Fiddaman	}
176*b30d1939SAndy Fiddaman	print "x${s}x"
177*b30d1939SAndy Fiddaman} || err_exit "test returned exit code $?"
178*b30d1939SAndy Fiddaman
179*b30d1939SAndy Fiddaman[[ "${s}" == "xhellox" ]] || err_exit "Expected 'xhellox', got ${s}"
180*b30d1939SAndy Fiddamancount_brackets "$y" || err_exit "y: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
181*b30d1939SAndy Fiddamancount_brackets "$(print -v y)" || err_exit "y: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
182*b30d1939SAndy Fiddamancount_brackets "$(print -C y)" || err_exit "y: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
183*b30d1939SAndy Fiddaman
184*b30d1939SAndy Fiddaman# cleanup
185*b30d1939SAndy Fiddamanunset x y || err_exit "unset failed"
186*b30d1939SAndy Fiddaman[[ "$x" == '' ]] || err_exit "cleanup failed for x"
187*b30d1939SAndy Fiddaman[[ "$y" == '' ]] || err_exit "cleanup failed for y"
188*b30d1939SAndy Fiddaman
189*b30d1939SAndy Fiddaman
190*b30d1939SAndy Fiddaman# Test 2:
191*b30d1939SAndy Fiddaman# Same as test 1 except one more compound var following the "hello"
192*b30d1939SAndy Fiddaman# line.
193*b30d1939SAndy Fiddaman# Data layout is:
194*b30d1939SAndy Fiddaman# -- snip --
195*b30d1939SAndy Fiddaman# <compound var>
196*b30d1939SAndy Fiddaman# hello
197*b30d1939SAndy Fiddaman# <compound var>
198*b30d1939SAndy Fiddaman# -- snip --
199*b30d1939SAndy Fiddamans=${
200*b30d1939SAndy Fiddaman	compound x=(
201*b30d1939SAndy Fiddaman		a=1 b=2
202*b30d1939SAndy Fiddaman		typeset -a myarray=( 1 2 3 4 5 6 7 8 9 10 )
203*b30d1939SAndy Fiddaman		typeset -A myarray2=( [a]=1 [b]=2 ["c d"]=3 [e]=4 ["f"]=5 [g]=6 [h]=7 [i]=8 [j]=9 [k]=10 )
204*b30d1939SAndy Fiddaman		compound -A myarray3=(
205*b30d1939SAndy Fiddaman			[a]=(
206*b30d1939SAndy Fiddaman				float m1=0.5
207*b30d1939SAndy Fiddaman				float m2=0.6
208*b30d1939SAndy Fiddaman				foo="hello"
209*b30d1939SAndy Fiddaman			)
210*b30d1939SAndy Fiddaman			[b]=(
211*b30d1939SAndy Fiddaman				foo="bar"
212*b30d1939SAndy Fiddaman			)
213*b30d1939SAndy Fiddaman			["c d"]=(
214*b30d1939SAndy Fiddaman				integer at=90
215*b30d1939SAndy Fiddaman			)
216*b30d1939SAndy Fiddaman			[e]=(
217*b30d1939SAndy Fiddaman				compound nested_cpv=(
218*b30d1939SAndy Fiddaman					typeset -a myarray=( 1 2 3 4 5 6 7 8 9 10 )
219*b30d1939SAndy Fiddaman					typeset str=$'a \'string'
220*b30d1939SAndy Fiddaman				)
221*b30d1939SAndy Fiddaman			)
222*b30d1939SAndy Fiddaman			[f]=(
223*b30d1939SAndy Fiddaman				typeset g="f"
224*b30d1939SAndy Fiddaman			)
225*b30d1939SAndy Fiddaman			[a_nan]=(
226*b30d1939SAndy Fiddaman				float my_nan=-nan
227*b30d1939SAndy Fiddaman			)
228*b30d1939SAndy Fiddaman			[a_hexfloat]=(
229*b30d1939SAndy Fiddaman			       typeset -X my_hexfloat=1.1
230*b30d1939SAndy Fiddaman			)
231*b30d1939SAndy Fiddaman		)
232*b30d1939SAndy Fiddaman	)
233*b30d1939SAndy Fiddaman
234*b30d1939SAndy Fiddaman	{
235*b30d1939SAndy Fiddaman		printf "%B\n" x
236*b30d1939SAndy Fiddaman		print "hello"
237*b30d1939SAndy Fiddaman		printf "%B\n" x
238*b30d1939SAndy Fiddaman	} | cpvcat1 | cpvcat2 | cpvcat3 | cpvcat4 | {
239*b30d1939SAndy Fiddaman		read -C y1
240*b30d1939SAndy Fiddaman		read s
241*b30d1939SAndy Fiddaman		read -C y2
242*b30d1939SAndy Fiddaman	}
243*b30d1939SAndy Fiddaman
244*b30d1939SAndy Fiddaman	print "x${s}x"
245*b30d1939SAndy Fiddaman} || err_exit "test returned exit code $?"
246*b30d1939SAndy Fiddaman
247*b30d1939SAndy Fiddaman[[ "${s}" == "xhellox" ]] || err_exit "Expected 'xhellox', got ${s}."
248*b30d1939SAndy Fiddaman[[ "${y1.myarray3[b].foo}" == "bar" ]] || err_exit "y1.myarray3[b].foo != bar"
249*b30d1939SAndy Fiddaman[[ "${y2.myarray3[b].foo}" == "bar" ]] || err_exit "y2.myarray3[b].foo != bar"
250*b30d1939SAndy Fiddaman[[ "$y1" != "" ]] || err_exit "y1 is empty"
251*b30d1939SAndy Fiddaman[[ "$y2" != "" ]] || err_exit "y2 is empty"
252*b30d1939SAndy Fiddaman(( ${#y1.myarray3[e].nested_cpv.myarray[@]} == 10 )) || err_exit "Expected 10 elements in y1.myarray3[e].nested_cpv, got ${#y1.myarray3[e].nested_cpv[@]}"
253*b30d1939SAndy Fiddaman(( ${#y2.myarray3[e].nested_cpv.myarray[@]} == 10 )) || err_exit "Expected 10 elements in y2.myarray3[e].nested_cpv, got ${#y2.myarray3[e].nested_cpv[@]}"
254*b30d1939SAndy Fiddaman(( isnan(y1.myarray3[a_nan].my_nan) ))   || err_exit "y1.myarray3[a_nan].my_nan not a NaN"
255*b30d1939SAndy Fiddaman(( isnan(y2.myarray3[a_nan].my_nan) ))   || err_exit "y2.myarray3[a_nan].my_nan not a NaN"
256*b30d1939SAndy Fiddamanif	(( HAVE_signbit ))
257*b30d1939SAndy Fiddamanthen	(( signbit(y1.myarray3[a_nan].my_nan) )) || err_exit "y1.myarray3[a_nan].my_nan not negative"
258*b30d1939SAndy Fiddaman	(( signbit(y2.myarray3[a_nan].my_nan) )) || err_exit "y2.myarray3[a_nan].my_nan not negative"
259*b30d1939SAndy Fiddamanfi
260*b30d1939SAndy Fiddamancount_brackets "$y1" || err_exit "y1: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
261*b30d1939SAndy Fiddamancount_brackets "$(print -v y1)" || err_exit "y1: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
262*b30d1939SAndy Fiddamancount_brackets "$(print -C y1)" || err_exit "y1: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
263*b30d1939SAndy Fiddamancount_brackets "$y2" || err_exit "y2: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
264*b30d1939SAndy Fiddamancount_brackets "$(print -v y2)" || err_exit "y2: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
265*b30d1939SAndy Fiddamancount_brackets "$(print -C y2)" || err_exit "y2: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
266*b30d1939SAndy Fiddaman[[ "$y1" == "$y2" ]] || err_exit "Expected $(printf "%q\n" "${y1}") == $(printf "%q\n" "${y2}")."
267*b30d1939SAndy Fiddaman[[ "$x"  == "$y1" ]] || err_exit "Expected $(printf "%q\n" "${x}") == $(printf "%q\n" "${y1}")."
268*b30d1939SAndy Fiddaman
269*b30d1939SAndy Fiddaman# cleanup
270*b30d1939SAndy Fiddamanunset x y1 y2 || err_exit "unset failed"
271*b30d1939SAndy Fiddaman[[ "$x" == '' ]]  || err_exit "cleanup failed for x"
272*b30d1939SAndy Fiddaman[[ "$y1" == '' ]] || err_exit "cleanup failed for y1"
273*b30d1939SAndy Fiddaman[[ "$y2" == '' ]] || err_exit "cleanup failed for y2"
274*b30d1939SAndy Fiddaman
275*b30d1939SAndy Fiddaman
276*b30d1939SAndy Fiddaman# Test 3: Test compound variable copy operator vs. "read -C"
277*b30d1939SAndy Fiddamancompound x=(
278*b30d1939SAndy Fiddaman	a=1 b=2
279*b30d1939SAndy Fiddaman	typeset -a myarray=( 1 2 3 4 5 6 7 8 9 10 )
280*b30d1939SAndy Fiddaman	typeset -A myarray2=( [a]=1 [b]=2 ["c d"]=3 [e]=4 ["f"]=5 [g]=6 [h]=7 [i]=8 [j]=9 [k]=10 )
281*b30d1939SAndy Fiddaman	compound -A myarray3=(
282*b30d1939SAndy Fiddaman		[a]=(
283*b30d1939SAndy Fiddaman			float m1=0.5
284*b30d1939SAndy Fiddaman			float m2=0.6
285*b30d1939SAndy Fiddaman			foo="hello"
286*b30d1939SAndy Fiddaman		)
287*b30d1939SAndy Fiddaman		[b]=(
288*b30d1939SAndy Fiddaman			foo="bar"
289*b30d1939SAndy Fiddaman		)
290*b30d1939SAndy Fiddaman		["c d"]=(
291*b30d1939SAndy Fiddaman			integer at=90
292*b30d1939SAndy Fiddaman		)
293*b30d1939SAndy Fiddaman		[e]=(
294*b30d1939SAndy Fiddaman			compound nested_cpv=(
295*b30d1939SAndy Fiddaman				typeset -a myarray=( 1 2 3 4 5 6 7 8 9 10 )
296*b30d1939SAndy Fiddaman				typeset str=$'a \'string'
297*b30d1939SAndy Fiddaman			)
298*b30d1939SAndy Fiddaman		)
299*b30d1939SAndy Fiddaman		[f]=(
300*b30d1939SAndy Fiddaman			typeset g="f"
301*b30d1939SAndy Fiddaman		)
302*b30d1939SAndy Fiddaman		[a_nan]=(
303*b30d1939SAndy Fiddaman			float my_nan=-nan
304*b30d1939SAndy Fiddaman		)
305*b30d1939SAndy Fiddaman		[a_hexfloat]=(
306*b30d1939SAndy Fiddaman		       typeset -X my_hexfloat=1.1
307*b30d1939SAndy Fiddaman		)
308*b30d1939SAndy Fiddaman	)
309*b30d1939SAndy Fiddaman)
310*b30d1939SAndy Fiddaman
311*b30d1939SAndy Fiddamancompound x_copy=x || err_exit "x_copy copy failed"
312*b30d1939SAndy Fiddaman[[ "${x_copy}" != "" ]] || err_exit "x_copy should not be empty"
313*b30d1939SAndy Fiddamancount_brackets "${x_copy}" || err_exit "x_copy: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
314*b30d1939SAndy Fiddamancount_brackets "$(print -v x_copy)" || err_exit "x_copy: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
315*b30d1939SAndy Fiddamancount_brackets "$(print -C x_copy)" || err_exit "x_copy: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
316*b30d1939SAndy Fiddaman
317*b30d1939SAndy Fiddamancompound nested_cpv_copy
318*b30d1939SAndy Fiddaman
319*b30d1939SAndy Fiddamannested_cpv_copy=x.myarray3[e].nested_cpv || err_exit "x.myarray3[e].nested_cpv copy failed"
320*b30d1939SAndy Fiddaman(( ${#nested_cpv_copy.myarray[@]} == 10 )) || err_exit "Expected 10 elements in nested_cpv_copy.myarray, got ${#nested_cpv_copy.myarray[@]}"
321*b30d1939SAndy Fiddaman
322*b30d1939SAndy Fiddaman# unset branch "x.myarray3[e].nested_cpv" of the variable tree "x" ...
323*b30d1939SAndy Fiddamanunset x.myarray3[e].nested_cpv || err_exit "unset x.myarray3[e].nested_cpv failed"
324*b30d1939SAndy Fiddaman[[ "${x.myarray3[e].nested_cpv}" == "" ]] || err_exit "x.myarray3[e].nested_cpv still has a value"
325*b30d1939SAndy Fiddaman
326*b30d1939SAndy Fiddaman# ... and restore it from the saved copy
327*b30d1939SAndy Fiddamanprintf "%B\n" nested_cpv_copy | cpvcat1 | cpvcat2 | cpvcat3 | cpvcat4 | read -C x.myarray3[e].nested_cpv || err_exit "read failed"
328*b30d1939SAndy Fiddaman
329*b30d1939SAndy Fiddaman# compare copy of the original tree and the modified one
330*b30d1939SAndy Fiddaman[[ "${x}" == "${x_copy}" ]] || err_exit "x != x_copy"
331*b30d1939SAndy Fiddamancount_brackets "${x}" || err_exit "x: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
332*b30d1939SAndy Fiddamancount_brackets "$(print -v x)" || err_exit "x: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
333*b30d1939SAndy Fiddamancount_brackets "$(print -C x)" || err_exit "x: bracket open ${bracketstat.bopen} != bracket close ${bracketstat.bclose}"
334*b30d1939SAndy Fiddaman(( ${#x.myarray3[e].nested_cpv.myarray[@]} == 10 )) || err_exit "Expected 10 elements in x.myarray3[e].nested_cpv, got ${#x.myarray3[e].nested_cpv[@]}"
335*b30d1939SAndy Fiddaman(( isnan(x.myarray3[a_nan].my_nan) ))   || err_exit "x.myarray3[a_nan].my_nan not a NaN"
336*b30d1939SAndy Fiddamanif	(( HAVE_signbit ))
337*b30d1939SAndy Fiddamanthen	(( signbit(x.myarray3[a_nan].my_nan) )) || err_exit "x.myarray3[a_nan].my_nan not negative"
338*b30d1939SAndy Fiddamanfi
339*b30d1939SAndy Fiddaman
340*b30d1939SAndy Fiddaman# cleanup
341*b30d1939SAndy Fiddamanunset x x_copy nested_cpv_copy || err_exit "unset failed"
342*b30d1939SAndy Fiddaman
343*b30d1939SAndy Fiddaman
344*b30d1939SAndy Fiddaman# Test 4: Test "read -C" failure for missing bracket at the end
345*b30d1939SAndy Fiddamantypeset s
346*b30d1939SAndy Fiddamans=$($SHELL -c 'compound myvar ; print "( unfinished=1" | read -C myvar 2>'/dev/null' || print "error $?"') || err_exit 'shell failed'
347*b30d1939SAndy Fiddaman[[ "$s" == 'error 3' ]] || err_exit "compound_read: expected error 3, got ${s}"
348*b30d1939SAndy Fiddaman
349*b30d1939SAndy Fiddaman
350*b30d1939SAndy Fiddaman# Test 5: Test "read -C" failure for missing bracket at the beginning
351*b30d1939SAndy Fiddamantypeset s
352*b30d1939SAndy Fiddamans=$($SHELL -c 'compound myvar ; print "  unfinished=1 )" | read -C myvar 2>'/dev/null' || print "error $?"') || err_exit 'shell failed'
353*b30d1939SAndy Fiddaman[[ "$s" == 'error 3' ]] || err_exit "compound_read: expected error 3, got ${s}"
354*b30d1939SAndy Fiddaman
355*b30d1939SAndy Fiddaman
356*b30d1939SAndy Fiddaman# test6: Derived from the test2 for CR #6944386
357*b30d1939SAndy Fiddaman# ("compound v=( integer -A ar=( [aa]=4 [bb]=9 ) ; ) ; print -C v prints trash")
358*b30d1939SAndy Fiddaman# which caused compound variables to be corrupted like this:
359*b30d1939SAndy Fiddaman# -- snip --
360*b30d1939SAndy Fiddaman# ksh93 -c 'compound v=( integer -A ar=( [aa]=4 [bb]=9 ) ; ) ; print -v v'
361*b30d1939SAndy Fiddaman# (
362*b30d1939SAndy Fiddaman#        typeset -A -l -i ar=(
363*b30d1939SAndy Fiddaman#                [aa]=$'\004'
364*b30d1939SAndy Fiddaman#                [bb]=$'\t'
365*b30d1939SAndy Fiddaman#        )
366*b30d1939SAndy Fiddaman# )
367*b30d1939SAndy Fiddaman# -- snip --
368*b30d1939SAndy Fiddaman
369*b30d1939SAndy Fiddamanfunction test6
370*b30d1939SAndy Fiddaman{
371*b30d1939SAndy Fiddaman        compound out=( typeset stdout stderr ; integer res )
372*b30d1939SAndy Fiddaman	compound val
373*b30d1939SAndy Fiddaman	integer testid
374*b30d1939SAndy Fiddaman
375*b30d1939SAndy Fiddaman	compound -r -a tests=(
376*b30d1939SAndy Fiddaman		# subtests1:
377*b30d1939SAndy Fiddaman		( cmd='compound v=( integer -A ar=( [aa]=4 [bb]=9 ) ; ) ; print -C v' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'			arrefname='ar' )
378*b30d1939SAndy Fiddaman		( cmd='compound v=( float   -A ar=( [aa]=4 [bb]=9 ) ; ) ; print -C v' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)' 			arrefname='ar' )
379*b30d1939SAndy Fiddaman		( cmd='compound v=( typeset -A ar=( [aa]=4 [bb]=9 ) ; ) ; print -C v' stdoutpattern=$'~(Alr)(.*\\[bb\\]=["\']*9.*)&(.*\\[aa\\]=["\']*4.*)'	arrefname='ar' )
380*b30d1939SAndy Fiddaman		( cmd='compound v=( integer -A ar=( [aa]=4 [bb]=9 ) ; ) ; print -v v' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)' 			arrefname='ar' )
381*b30d1939SAndy Fiddaman		( cmd='compound v=( float   -A ar=( [aa]=4 [bb]=9 ) ; ) ; print -v v' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)' 			arrefname='ar' )
382*b30d1939SAndy Fiddaman		( cmd='compound v=( typeset -A ar=( [aa]=4 [bb]=9 ) ; ) ; print -v v' stdoutpattern=$'~(Alr)(.*\\[bb\\]=["\']*9.*)&(.*\\[aa\\]=["\']*4.*)' 	arrefname='ar' )
383*b30d1939SAndy Fiddaman
384*b30d1939SAndy Fiddaman		# subtests2: Same as subtests1 but variable "v" is inside "vx"
385*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound v=( integer -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; print -C vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'		arrefname='v.ar' )
386*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound v=( float   -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; print -C vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'		arrefname='v.ar' )
387*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound v=( typeset -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; print -C vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=["\']*9.*)&(.*\\[aa\\]=["\']*4.*)'	arrefname='v.ar' )
388*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound v=( integer -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; print -v vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'		arrefname='v.ar' )
389*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound v=( float   -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; print -v vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'		arrefname='v.ar' )
390*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound v=( typeset -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; print -v vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=["\']*9.*)&(.*\\[aa\\]=["\']*4.*)'	arrefname='v.ar' )
391*b30d1939SAndy Fiddaman
392*b30d1939SAndy Fiddaman		# subtests3: Same as subtests1 but variable "va" is an indexed array
393*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound -a va=( [3]=( integer -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -C vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'			arrefname='va[3].ar' )
394*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound -a va=( [3]=( float   -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -C vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)' 		arrefname='va[3].ar' )
395*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound -a va=( [3]=( typeset -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -C vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=["\']*9.*)&(.*\\[aa\\]=["\']*4.*)'	arrefname='va[3].ar' )
396*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound -a va=( [3]=( integer -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -v vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'			arrefname='va[3].ar' )
397*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound -a va=( [3]=( float   -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -v vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'			arrefname='va[3].ar' )
398*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound -a va=( [3]=( typeset -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -v vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=["\']*9.*)&(.*\\[aa\\]=["\']*4.*)'	arrefname='va[3].ar' )
399*b30d1939SAndy Fiddaman
400*b30d1939SAndy Fiddaman		# subtests4: Same as subtests1 but variable "va" is an 2d indexed array
401*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound -a va=( [3][17]=( integer -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -C vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'		arrefname='va[3][17].ar' )
402*b30d1939SAndy Fiddaman 		( cmd='compound vx=( compound -a va=( [3][17]=( float	-A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -C vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'		arrefname='va[3][17].ar' )
403*b30d1939SAndy Fiddaman 		( cmd='compound vx=( compound -a va=( [3][17]=( typeset -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -C vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=["\']*9.*)&(.*\\[aa\\]=["\']*4.*)' arrefname='va[3][17].ar' )
404*b30d1939SAndy Fiddaman 		( cmd='compound vx=( compound -a va=( [3][17]=( integer -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -v vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'		arrefname='va[3][17].ar' )
405*b30d1939SAndy Fiddaman 		( cmd='compound vx=( compound -a va=( [3][17]=( float	-A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -v vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'		arrefname='va[3][17].ar' )
406*b30d1939SAndy Fiddaman 		( cmd='compound vx=( compound -a va=( [3][17]=( typeset -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -v vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=["\']*9.*)&(.*\\[aa\\]=["\']*4.*)' arrefname='va[3][17].ar' )
407*b30d1939SAndy Fiddaman
408*b30d1939SAndy Fiddaman		# subtests5: Same as subtests1 but variable "va" is an associative array
409*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound -A va=( [l]=( integer -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -C vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'			arrefname='va[l].ar' )
410*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound -A va=( [l]=( float   -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -C vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'			arrefname='va[l].ar' )
411*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound -A va=( [l]=( typeset -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -C vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=["\']*9.*)&(.*\\[aa\\]=["\']*4.*)'	arrefname='va[l].ar' )
412*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound -A va=( [l]=( integer -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -v vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'			arrefname='va[l].ar' )
413*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound -A va=( [l]=( float   -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -v vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=9.*)&(.*\\[aa\\]=4.*)'			arrefname='va[l].ar' )
414*b30d1939SAndy Fiddaman		( cmd='compound vx=( compound -A va=( [l]=( typeset -A ar=( [aa]=4 [bb]=9 ) ; ) ; ) ; ) ; print -v vx' stdoutpattern=$'~(Alr)(.*\\[bb\\]=["\']*9.*)&(.*\\[aa\\]=["\']*4.*)'	arrefname='va[l].ar' )
415*b30d1939SAndy Fiddaman	)
416*b30d1939SAndy Fiddaman
417*b30d1939SAndy Fiddaman	for testid in "${!tests[@]}" ; do
418*b30d1939SAndy Fiddaman		nameref test=tests[testid]
419*b30d1939SAndy Fiddaman		typeset testname="test2/${testid}"
420*b30d1939SAndy Fiddaman
421*b30d1939SAndy Fiddaman	        out.stderr="${ { out.stdout="${ ${SHELL} -c "${test.cmd}" ; (( out.res=$? )) ; }" ; } 2>&1 ; }"
422*b30d1939SAndy Fiddaman
423*b30d1939SAndy Fiddaman        	(( out.res == 0 )) || err_exit "${testname}: Test shell returned with exit code ${out.res}"
424*b30d1939SAndy Fiddaman        	[[ "${out.stdout}" == ${test.stdoutpattern} ]] || err_exit "${testname}: Expected match for ${test.stdoutpattern}, got $(printf "%q\n" "${out.stdout}")"
425*b30d1939SAndy Fiddaman        	[[ "${out.stderr}" == ""                    ]] || err_exit "${testname}: Expected empty stderr, got $(printf "%q\n" "${out.stderr}")"
426*b30d1939SAndy Fiddaman
427*b30d1939SAndy Fiddaman		read -C val <<<"${out.stdout}" || err_exit "${testname}: read -C val failed with exit code $?"
428*b30d1939SAndy Fiddaman		nameref ar="val.${test.arrefname}"
429*b30d1939SAndy Fiddaman		(( ar[aa] == 4 )) || err_exit "${testname}: Expected ar[aa] == 4, got ${ar[aa]}"
430*b30d1939SAndy Fiddaman		(( ar[bb] == 9 )) || err_exit "${testname}: Expected ar[bb] == 9, got ${ar[bb]}"
431*b30d1939SAndy Fiddaman	done
432*b30d1939SAndy Fiddaman
433*b30d1939SAndy Fiddaman	return 0
434*b30d1939SAndy Fiddaman}
435*b30d1939SAndy Fiddaman
436*b30d1939SAndy Fiddamantest6
437*b30d1939SAndy Fiddaman
438*b30d1939SAndy Fiddamanfunction test_3D_array_read_C
439*b30d1939SAndy Fiddaman{
440*b30d1939SAndy Fiddaman        compound out=( typeset stdout stderr ; integer res )
441*b30d1939SAndy Fiddaman	integer i
442*b30d1939SAndy Fiddaman	typeset -r -a tests=(
443*b30d1939SAndy Fiddaman		# ast-ksh.2010-03-09 will print "ksh93[1]: read: line 4: 0[0]: invalid variable name" for 3D arrays passed to read -C
444*b30d1939SAndy Fiddaman		'compound c=( typeset -a x ) ; for (( i=0 ; i < 3 ; i++ )) ; do for (( j=0 ; j < 3 ; j++ )) ; do for (( k=0 ; k < 3 ; k++ )) ; do c.x[i][j][k]="$i$j$k" ; done; done; done ; unset c.x[2][0][1] ; print -v c | read -C dummy'
445*b30d1939SAndy Fiddaman
446*b30d1939SAndy Fiddaman		# same test, 4D, fails with 'ksh[1]: read: line 4: 0: invalid variable name'
447*b30d1939SAndy Fiddaman		'compound c=( typeset -a x ) ; for (( i=0 ; i < 3 ; i++ )) ; do for (( j=0 ; j < 3 ; j++ )) ; do for (( k=0 ; k < 3 ; k++ )) ; do for (( l=0 ; l < 3 ; l++ )) ; do c.x[i][j][k][l]="$i$j$k$l" ; done; done; done ; done ; unset c.x[2][0][1][2] ; print -v c | read -C dummy'
448*b30d1939SAndy Fiddaman	)
449*b30d1939SAndy Fiddaman
450*b30d1939SAndy Fiddaman	for (( i=0 ; i < ${#tests[@]} ; i++ )) ; do
451*b30d1939SAndy Fiddaman		out.stderr="${ { out.stdout="${ ${SHELL} -o nounset -c "${tests[i]}" ; (( out.res=$? )) ; }" ; } 2>&1 ; }"
452*b30d1939SAndy Fiddaman
453*b30d1939SAndy Fiddaman	        [[ "${out.stdout}" == '' ]] || err_exit "$0/${i}: Expected empty stdout, got $(printf '%q\n' "${out.stdout}")"
454*b30d1939SAndy Fiddaman        	[[ "${out.stderr}" == '' ]] || err_exit "$0/${i}: Expected empty stderr, got $(printf '%q\n' "${out.stderr}")"
455*b30d1939SAndy Fiddaman	done
456*b30d1939SAndy Fiddaman
457*b30d1939SAndy Fiddaman	return 0
458*b30d1939SAndy Fiddaman}
459*b30d1939SAndy Fiddaman
460*b30d1939SAndy Fiddaman
461*b30d1939SAndy Fiddamanfunction test_access_2Darray_in_type_in_compound
462*b30d1939SAndy Fiddaman{
463*b30d1939SAndy Fiddaman        compound out=( typeset stdout stderr ; integer res )
464*b30d1939SAndy Fiddaman	integer i
465*b30d1939SAndy Fiddaman	typeset -r -a tests=(
466*b30d1939SAndy Fiddaman		# ast-ksh.2010-03-09 will print 'ksh: line 1: l.c.x[i][j]=: no parent'
467*b30d1939SAndy Fiddaman		'typeset -T c_t=(typeset -a x) ; compound l=( c_t c ) ; for ((i=0;i<3;i++));do for ((j=0;j<3;j++));do l.c.x[i][j]="" ; done; done; print -v l | read -C dummy'
468*b30d1939SAndy Fiddaman	)
469*b30d1939SAndy Fiddaman
470*b30d1939SAndy Fiddaman	for (( i=0 ; i < ${#tests[@]} ; i++ )) ; do
471*b30d1939SAndy Fiddaman		out.stderr="${ { out.stdout="${ ${SHELL} -o nounset -c "${tests[i]}" ; (( out.res=$? )) ; }" ; } 2>&1 ; }"
472*b30d1939SAndy Fiddaman
473*b30d1939SAndy Fiddaman	        [[ "${out.stdout}" == '' ]] || err_exit "$0/${i}: Expected empty stdout, got $(printf '%q\n' "${out.stdout}")"
474*b30d1939SAndy Fiddaman        	[[ "${out.stderr}" == '' ]] || err_exit "$0/${i}: Expected empty stderr, got $(printf '%q\n' "${out.stderr}")"
475*b30d1939SAndy Fiddaman	done
476*b30d1939SAndy Fiddaman
477*b30d1939SAndy Fiddaman	return 0
478*b30d1939SAndy Fiddaman}
479*b30d1939SAndy Fiddaman
480*b30d1939SAndy Fiddamanfunction test_read_type_crash
481*b30d1939SAndy Fiddaman{
482*b30d1939SAndy Fiddaman        compound out=( typeset stdout stderr ; integer res )
483*b30d1939SAndy Fiddaman	typeset -r test='
484*b30d1939SAndy Fiddamantypeset -T field_t=(
485*b30d1939SAndy Fiddaman	typeset -a f
486*b30d1939SAndy Fiddaman
487*b30d1939SAndy Fiddaman	function reset
488*b30d1939SAndy Fiddaman	{
489*b30d1939SAndy Fiddaman		integer i j
490*b30d1939SAndy Fiddaman
491*b30d1939SAndy Fiddaman		for (( i=0 ; i < 3 ; i++ )) ; do
492*b30d1939SAndy Fiddaman			for (( j=0 ; j < 3 ; j++ )) ; do
493*b30d1939SAndy Fiddaman				_.f[i][j]=""
494*b30d1939SAndy Fiddaman			done
495*b30d1939SAndy Fiddaman		done
496*b30d1939SAndy Fiddaman		return 0
497*b30d1939SAndy Fiddaman	}
498*b30d1939SAndy Fiddaman
499*b30d1939SAndy Fiddaman	function enumerate_empty_fields
500*b30d1939SAndy Fiddaman	{
501*b30d1939SAndy Fiddaman		integer i j
502*b30d1939SAndy Fiddaman
503*b30d1939SAndy Fiddaman		for (( i=0 ; i < 3 ; i++ )) ; do
504*b30d1939SAndy Fiddaman			for (( j=0 ; j < 3 ; j++ )) ; do
505*b30d1939SAndy Fiddaman				[[ "${_.f[i][j]}" == "" ]] && printf "[%d][%d]\n" i j
506*b30d1939SAndy Fiddaman			done
507*b30d1939SAndy Fiddaman		done
508*b30d1939SAndy Fiddaman		return 0
509*b30d1939SAndy Fiddaman	}
510*b30d1939SAndy Fiddaman
511*b30d1939SAndy Fiddaman	function setf
512*b30d1939SAndy Fiddaman	{
513*b30d1939SAndy Fiddaman		_.f[$1][$2]="$3"
514*b30d1939SAndy Fiddaman	}
515*b30d1939SAndy Fiddaman)
516*b30d1939SAndy Fiddaman
517*b30d1939SAndy Fiddamanset -o nounset
518*b30d1939SAndy Fiddaman
519*b30d1939SAndy Fiddamancompound c1=( field_t x )
520*b30d1939SAndy Fiddaman
521*b30d1939SAndy Fiddamanc1.x.reset
522*b30d1939SAndy Fiddaman
523*b30d1939SAndy Fiddamanprint -v c1 | read -C c2
524*b30d1939SAndy Fiddamanprint -v c2
525*b30d1939SAndy Fiddaman'
526*b30d1939SAndy Fiddaman
527*b30d1939SAndy Fiddaman	out.stderr="${ { out.stdout="${ ${SHELL} -o nounset -c "${test}" ; (( out.res=$? )) ; }" ; } 2>&1 ; }"
528*b30d1939SAndy Fiddaman
529*b30d1939SAndy Fiddaman        [[ "${out.stdout}" != '' ]] || err_exit "$0: Expected nonempty stdout."
530*b30d1939SAndy Fiddaman       	[[ "${out.stderr}" == '' ]] || err_exit "$0: Expected empty stderr, got $(printf '%q\n' "${out.stderr}")"
531*b30d1939SAndy Fiddaman
532*b30d1939SAndy Fiddaman	if [[ -f 'core' && -x '/usr/bin/pstack' ]] ; then
533*b30d1939SAndy Fiddaman		pstack 'core'
534*b30d1939SAndy Fiddaman		rm 'core'
535*b30d1939SAndy Fiddaman	fi
536*b30d1939SAndy Fiddaman
537*b30d1939SAndy Fiddaman	return 0
538*b30d1939SAndy Fiddaman}
539*b30d1939SAndy Fiddaman
540*b30d1939SAndy Fiddaman
541*b30d1939SAndy Fiddamanfunction test_read_C_into_array
542*b30d1939SAndy Fiddaman{
543*b30d1939SAndy Fiddaman        compound out=( typeset stdout stderr ; integer res )
544*b30d1939SAndy Fiddaman	# fixme:
545*b30d1939SAndy Fiddaman	# - The tests should cover 3D and 5D indexed arrays and namerefs to sub-dimensions of a 5D indexed array
546*b30d1939SAndy Fiddaman	compound -r -a tests=(
547*b30d1939SAndy Fiddaman		( cmd='             typeset -a -C l   ;                        printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l[4] ;      print -v l' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)' ) )
548*b30d1939SAndy Fiddaman		( cmd='             typeset -a -C l   ; nameref l4=l[4] ;      printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l4 ;        print -v l' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)' ) )
549*b30d1939SAndy Fiddaman
550*b30d1939SAndy Fiddaman		( cmd='             typeset -a -C l   ;                        printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l[4][6] ;   print -v l' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)&(.+\[6\].+)' ) )
551*b30d1939SAndy Fiddaman		( cmd='             typeset -a -C l   ; nameref l4=l[4][6] ;   printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l4 ;        print -v l' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)&(.+\[6\].+)' ) )
552*b30d1939SAndy Fiddaman
553*b30d1939SAndy Fiddaman		( cmd='             typeset -a -C l   ;                        printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l[4][6][9][11][15] ;   print -v l' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)&(.+\[6\].+)' '~(X)(.+\[9\].+)&(.+\[11\].+)&(.+\[15\].+)' ) )
554*b30d1939SAndy Fiddaman		( cmd='             typeset -a -C l   ; nameref l4=l[4][6][9][11][15] ;   printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l4 ;        print -v l' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)&(.+\[6\].+)' '~(X)(.+\[9\].+)&(.+\[11\].+)&(.+\[15\].+)' ) )
555*b30d1939SAndy Fiddaman
556*b30d1939SAndy Fiddaman		( cmd='             typeset -A -C l   ;                        printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l[4] ;      print -v l' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)' ) )
557*b30d1939SAndy Fiddaman		( cmd='             typeset -A -C l   ; nameref l4=l[4] ;      printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l4 ;        print -v l' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)' ) )
558*b30d1939SAndy Fiddaman		( cmd='compound c ; typeset -a -C c.l ;                        printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C c.l[4] ;    print -v c' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)' ) )
559*b30d1939SAndy Fiddaman		( cmd='compound c ; typeset -a -C c.l ; nameref l4=c.l[4] ;    printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l4 ;        print -v c' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)' ) )
560*b30d1939SAndy Fiddaman
561*b30d1939SAndy Fiddaman		( cmd='compound c ; typeset -a -C c.l ;                        printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C c.l[4][6] ; print -v c' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)&(.+\[6\].+)' ) )
562*b30d1939SAndy Fiddaman		( cmd='compound c ; typeset -a -C c.l ; nameref l4=c.l[4][6] ; printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l4 ;        print -v c' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)&(.+\[6\].+)' ) )
563*b30d1939SAndy Fiddaman
564*b30d1939SAndy Fiddaman		( cmd='compound c ; typeset -a -C c.l ;                        printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C c.l[4][6][9][11][15] ; print -v c' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)&(.+\[6\].+)' '~(X)(.+\[9\].+)&(.+\[11\].+)&(.+\[15\].+)'  ) )
565*b30d1939SAndy Fiddaman		( cmd='compound c ; typeset -a -C c.l ; nameref l4=c.[4][6][9][11][15] ; printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l4 ;         print -v c' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)&(.+\[6\].+)' '~(X)(.+\[9\].+)&(.+\[11\].+)&(.+\[15\].+)'  ) )
566*b30d1939SAndy Fiddaman
567*b30d1939SAndy Fiddaman		( cmd='compound c ; typeset -A -C c.l ;                        printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C c.l[4] ;    print -v c' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)' ) )
568*b30d1939SAndy Fiddaman		( cmd='compound c ; typeset -A -C c.l ; nameref l4=c.l[4] ;    printf "( typeset -a ar=( 1\n2\n3\n) b=1 )\n" | read -C l4 ;        print -v c' typeset -a stdoutpattern=( '~(X)(.+b=1.+)&(.+\[4\].+)' ) )
569*b30d1939SAndy Fiddaman	)
570*b30d1939SAndy Fiddaman	typeset cmd
571*b30d1939SAndy Fiddaman	typeset pat
572*b30d1939SAndy Fiddaman	integer i
573*b30d1939SAndy Fiddaman
574*b30d1939SAndy Fiddaman	compound -a test_variants
575*b30d1939SAndy Fiddaman
576*b30d1939SAndy Fiddaman	# build list of variations of the tests above
577*b30d1939SAndy Fiddaman	for (( i=0 ; i < ${#tests[@]} ; i++ )) ; do
578*b30d1939SAndy Fiddaman		nameref tst=tests[i]
579*b30d1939SAndy Fiddaman
580*b30d1939SAndy Fiddaman		# plain test
581*b30d1939SAndy Fiddaman		cmd="${tst.cmd}"
582*b30d1939SAndy Fiddaman		test_variants+=( testname="${0}/${i}/plain" cmd="$cmd" typeset -a stdoutpattern=( "${tst.stdoutpattern[@]}" ) )
583*b30d1939SAndy Fiddaman
584*b30d1939SAndy Fiddaman		# test with "read -C" in a function
585*b30d1939SAndy Fiddaman		cmd="${tst.cmd/~(E)read[[:space:]]+-C[[:space:]]+([[:alnum:]]+)[[:space:]]+\;/{ function rf { nameref val=\$1 \; read -C val \; } \; rf \1 \; } \; }"
586*b30d1939SAndy Fiddaman		test_variants+=( testname="${0}/${i}/read_in_function" cmd="$cmd" typeset -a stdoutpattern=( "${tst.stdoutpattern[@]}" ) )
587*b30d1939SAndy Fiddaman
588*b30d1939SAndy Fiddaman		# test with "read -C" in a nested function
589*b30d1939SAndy Fiddaman		cmd="${tst.cmd/~(E)read[[:space:]]+-C[[:space:]]+([[:alnum:]]+)[[:space:]]+\;/{ function rf2 { nameref val=\$1 \; read -C val \; } \; function rf { nameref val=\$1 \; rf2 val \; } \; rf \1 \; } \; }"
590*b30d1939SAndy Fiddaman		test_variants+=( testname="${0}/${i}/read_in_nested_function" cmd="$cmd" typeset -a stdoutpattern=( "${tst.stdoutpattern[@]}" ) )
591*b30d1939SAndy Fiddaman
592*b30d1939SAndy Fiddaman		# test with "read -C" in a nested function with target variable
593*b30d1939SAndy Fiddaman		# being a function-local variable of function "main"
594*b30d1939SAndy Fiddaman		cmd='function rf2 { nameref val=$1 ; read -C val ; } ; function rf { nameref val=$1 ; rf2 val ; } ; function main { '
595*b30d1939SAndy Fiddaman		cmd+="${tst.cmd/~(E)read[[:space:]]+-C[[:space:]]+([[:alnum:]]+)[[:space:]]+\;/rf \1 \; }"
596*b30d1939SAndy Fiddaman		cmd+=' ; } ; main'
597*b30d1939SAndy Fiddaman		test_variants+=( testname="${0}/${i}/read_into_localvar_in_nested_function" cmd="$cmd" typeset -a stdoutpattern=( "${tst.stdoutpattern[@]}" ) )
598*b30d1939SAndy Fiddaman	done
599*b30d1939SAndy Fiddaman
600*b30d1939SAndy Fiddaman	# run test variants
601*b30d1939SAndy Fiddaman	for (( i=0 ; i < ${#test_variants[@]} ; i++ )) ; do
602*b30d1939SAndy Fiddaman		nameref tv=test_variants[i]
603*b30d1939SAndy Fiddaman
604*b30d1939SAndy Fiddaman		out.stderr="${ { out.stdout="${ ${SHELL} -o nounset -o errexit -c "${tv.cmd}" ; (( out.res=$? )) ; }" ; } 2>&1 ; }"
605*b30d1939SAndy Fiddaman
606*b30d1939SAndy Fiddaman		for pat in "${tv.stdoutpattern[@]}" ; do
607*b30d1939SAndy Fiddaman			[[ "${out.stdout}" == ${pat} ]] || err_exit "${tv.testname}: Expected stdout of $(printf '%q\n' "${tv.cmd}") to match $(printf '%q\n' "${pat}"), got $(printf '%q\n' "${out.stdout}")"
608*b30d1939SAndy Fiddaman		done
609*b30d1939SAndy Fiddaman		[[ "${out.stderr}" == '' ]] || err_exit "${tv.testname}: Expected empty stderr for $(printf '%q\n' "${tv.cmd}"), got $(printf '%q\n' "${out.stderr}")"
610*b30d1939SAndy Fiddaman		(( out.res == 0 )) || err_exit "${tv.testname}: Unexpected exit code ${out.res} for $(printf '%q\n' "${tv.cmd}")"
611*b30d1939SAndy Fiddaman	done
612*b30d1939SAndy Fiddaman
613*b30d1939SAndy Fiddaman	return 0
614*b30d1939SAndy Fiddaman}
615*b30d1939SAndy Fiddaman
616*b30d1939SAndy Fiddaman
617*b30d1939SAndy Fiddaman# This test checks whether reading a compound variable value with
618*b30d1939SAndy Fiddaman# "read -C var" which contains special shell keywords or aliases
619*b30d1939SAndy Fiddaman# like "functions", "alias", "!" etc. in a string array causes the
620*b30d1939SAndy Fiddaman# shell to produce errors like this:
621*b30d1939SAndy Fiddaman# -- snip --
622*b30d1939SAndy Fiddaman# $ ksh93 -c 'print "( compound -A a1=( [4]=( typeset -a x=( alias ) ) ) ;
623*b30d1939SAndy Fiddaman# compound -A a2=( [4]=( typeset -a x=( ! ! ! alias ) ) ) )" | read -C c ; print -v c' 1>/dev/null
624*b30d1939SAndy Fiddaman# ksh93[1]: alias: c.a1[4].x: compound assignment requires sub-variable name
625*b30d1939SAndy Fiddaman# -- snip --
626*b30d1939SAndy Fiddaman# A 2nd issue indirectly tested here was that simple indexed string array
627*b30d1939SAndy Fiddaman# declarations in a function with the same special keywords did not work
628*b30d1939SAndy Fiddaman# either.
629*b30d1939SAndy Fiddaman# This happened in ast-ksh.2010-11-12 or older.
630*b30d1939SAndy Fiddamanfunction test_read_C_special_shell_keywords
631*b30d1939SAndy Fiddaman{
632*b30d1939SAndy Fiddaman	typeset -r -a testcmdpatterns=(
633*b30d1939SAndy Fiddaman		# this was the original testcase
634*b30d1939SAndy Fiddaman		'print "( compound -A a1=( [4]=( typeset -a x=( %keyword% ) ) ) ; compound -A a2=( [4]=( typeset -a x=( ! ! ! alias ) ) ) )" | read -C c ; print "X${c.a1[4].x[0]}X"'
635*b30d1939SAndy Fiddaman		# same as above but uses indexed arrays instead of associative arrays
636*b30d1939SAndy Fiddaman		'print "( compound -a a1=( [4]=( typeset -a x=( %keyword% ) ) ) ; compound -a a2=( [4]=( typeset -a x=( ! ! ! alias ) ) ) )" | read -C c ; print "X${c.a1[4].x[0]}X"'
637*b30d1939SAndy Fiddaman		# same as first testcase but uses a blank in the array index value
638*b30d1939SAndy Fiddaman		$'print "( compound -A a1=( [\'hello world\']=( typeset -a x=( %keyword% ) ) ) ; compound -A a2=( [\'hello world\']=( typeset -a x=( ! ! ! alias ) ) ) )" | read -C c ; print "X${c.a1[\'hello world\'].x[0]}X"'
639*b30d1939SAndy Fiddaman	)
640*b30d1939SAndy Fiddaman	typeset -r -a shell_special_words=(
641*b30d1939SAndy Fiddaman		'alias'
642*b30d1939SAndy Fiddaman		'compound'
643*b30d1939SAndy Fiddaman		'function'
644*b30d1939SAndy Fiddaman		'functions'
645*b30d1939SAndy Fiddaman		'integer'
646*b30d1939SAndy Fiddaman		'local'
647*b30d1939SAndy Fiddaman		'namespace'
648*b30d1939SAndy Fiddaman		'typeset'
649*b30d1939SAndy Fiddaman		'SECONDS'
650*b30d1939SAndy Fiddaman		'.sh.version'
651*b30d1939SAndy Fiddaman		'!'
652*b30d1939SAndy Fiddaman	)
653*b30d1939SAndy Fiddaman	integer spwi # shell_special_words index
654*b30d1939SAndy Fiddaman	integer tcpi # testcmdpatterns index
655*b30d1939SAndy Fiddaman	typeset testcmd
656*b30d1939SAndy Fiddaman	typeset testname
657*b30d1939SAndy Fiddaman	typeset shkeyword
658*b30d1939SAndy Fiddaman        compound out=( typeset stdout stderr ; integer res )
659*b30d1939SAndy Fiddaman
660*b30d1939SAndy Fiddaman	for (( tcpi=0 ; tcpi < ${#testcmdpatterns[@]} ; tcpi++ )) ; do
661*b30d1939SAndy Fiddaman		for (( spwi=0 ; spwi < ${#shell_special_words[@]} ; spwi++ )) ; do
662*b30d1939SAndy Fiddaman			shkeyword=${shell_special_words[spwi]}
663*b30d1939SAndy Fiddaman			testcmd="${testcmdpatterns[tcpi]//%keyword%/${shkeyword}}"
664*b30d1939SAndy Fiddaman			testname="${0}/${tcpi}/${spwi}/"
665*b30d1939SAndy Fiddaman
666*b30d1939SAndy Fiddaman			out.stderr="${ { out.stdout="${ ${SHELL} -o nounset -o errexit -c "${testcmd}" ; (( out.res=$? )) ; }" ; } 2>&1 ; }"
667*b30d1939SAndy Fiddaman
668*b30d1939SAndy Fiddaman        		[[ "${out.stdout}" == "X${shkeyword}X" ]] || err_exit "${testname}: Expected stdout to match $(printf '%q\n' "X${shkeyword}X"), got $(printf '%q\n' "${out.stdout}")"
669*b30d1939SAndy Fiddaman			[[ "${out.stderr}" == '' ]] || err_exit "${testname}: Expected empty stderr, got $(printf '%q\n' "${out.stderr}")"
670*b30d1939SAndy Fiddaman			(( out.res == 0 )) || err_exit "${testname}: Unexpected exit code ${out.res}"
671*b30d1939SAndy Fiddaman		done
672*b30d1939SAndy Fiddaman	done
673*b30d1939SAndy Fiddaman
674*b30d1939SAndy Fiddaman	return 0
675*b30d1939SAndy Fiddaman}
676*b30d1939SAndy Fiddaman
677*b30d1939SAndy Fiddaman
678*b30d1939SAndy Fiddamantest_3D_array_read_C
679*b30d1939SAndy Fiddamantest_access_2Darray_in_type_in_compound
680*b30d1939SAndy Fiddamantest_read_type_crash
681*b30d1939SAndy Fiddamantest_read_C_into_array
682*b30d1939SAndy Fiddamantest_read_C_special_shell_keywords
683*b30d1939SAndy Fiddaman
684*b30d1939SAndy Fiddaman
685*b30d1939SAndy Fiddaman# tests done
686*b30d1939SAndy Fiddamanexit $((Errors<125?Errors:125))
687