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