xref: /titanic_51/usr/src/lib/libshell/common/tests/arrays.sh (revision f657cd55755084dade71fb0c1d9f51994c226a70)
1########################################################################
2#                                                                      #
3#               This software is part of the ast package               #
4#          Copyright (c) 1982-2008 AT&T Intellectual Property          #
5#                      and is licensed under the                       #
6#                  Common Public License, Version 1.0                  #
7#                    by AT&T Intellectual Property                     #
8#                                                                      #
9#                A copy of the License is available at                 #
10#            http://www.opensource.org/licenses/cpl1.0.txt             #
11#         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         #
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
28function fun
29{
30	integer i
31	unset xxx
32	for i in 0 1
33	do	xxx[$i]=$i
34	done
35}
36
37Command=${0##*/}
38integer Errors=0
39set -A x zero one two three four 'five six'
40if	[[ $x != zero ]]
41then	err_exit '$x is not element 0'
42fi
43if	[[ ${x[0]} != zero ]]
44then	err_exit '${x[0] is not element 0'
45fi
46if	(( ${#x[0]} != 4 ))
47then	err_exit "length of ${x[0]} is not 4"
48fi
49if	(( ${#x[@]} != 6  ))
50then	err_exit 'number of elements of x is not 6'
51fi
52if	[[ ${x[2]} != two  ]]
53then	err_exit ' element two is not 2'
54fi
55if	[[ ${x[@]:2:1} != two  ]]
56then	err_exit ' ${x[@]:2:1} is not two'
57fi
58set -A y -- ${x[*]}
59if	[[ $y != zero ]]
60then	err_exit '$x is not element 0'
61fi
62if	[[ ${y[0]} != zero ]]
63then	err_exit '${y[0] is not element 0'
64fi
65if	(( ${#y[@]} != 7  ))
66then	err_exit 'number of elements of y is not 7'
67fi
68if	[[ ${y[2]} != two  ]]
69then	err_exit ' element two is not 2'
70fi
71set +A y nine ten
72if	[[ ${y[2]} != two  ]]
73then	err_exit ' element two is not 2'
74fi
75if	[[ ${y[0]} != nine ]]
76then	err_exit '${y[0] is not nine'
77fi
78unset y[4]
79if	(( ${#y[@]} != 6  ))
80then	err_exit 'number of elements of y is not 6'
81fi
82if	(( ${#y[4]} != 0  ))
83then	err_exit 'string length of unset element is not 0'
84fi
85unset foo
86if	(( ${#foo[@]} != 0  ))
87then	err_exit 'number of elements of unset variable foo is not 0'
88fi
89foo=''
90if	(( ${#foo[0]} != 0  ))
91then	err_exit 'string length of null element is not 0'
92fi
93if	(( ${#foo[@]} != 1  ))
94then	err_exit 'number of elements of null variable foo is not 1'
95fi
96unset foo
97foo[0]=foo
98foo[3]=bar
99unset foo[0]
100unset foo[3]
101if	(( ${#foo[@]} != 0  ))
102then	err_exit 'number of elements of left in variable foo is not 0'
103fi
104unset foo
105foo[3]=bar
106foo[0]=foo
107unset foo[3]
108unset foo[0]
109if	(( ${#foo[@]} != 0  ))
110then	err_exit 'number of elements of left in variable foo again is not 0'
111fi
112fun
113if	(( ${#xxx[@]} != 2  ))
114then	err_exit 'number of elements of left in variable xxx is not 2'
115fi
116fun
117if	(( ${#xxx[@]} != 2  ))
118then	err_exit 'number of elements of left in variable xxx again is not 2'
119fi
120set -A foo -- "${x[@]}"
121if	(( ${#foo[@]} != 6  ))
122then	err_exit 'number of elements of foo is not 6'
123fi
124if	(( ${#PWD[@]} != 1  ))
125then	err_exit 'number of elements of PWD is not 1'
126fi
127unset x
128x[2]=foo x[4]=bar
129if	(( ${#x[@]} != 2  ))
130then	err_exit 'number of elements of x is not 2'
131fi
132s[1]=1 c[1]=foo
133if	[[ ${c[s[1]]} != foo ]]
134then	err_exit 'c[1]=foo s[1]=1; ${c[s[1]]} != foo'
135fi
136unset s
137typeset -Ai s
138y=* z=[
139s[$y]=1
140s[$z]=2
141if	(( ${#s[@]} != 2  ))
142then	err_exit 'number of elements of  is not 2'
143fi
144(( s[$z] = s[$z] + ${s[$y]} ))
145if	[[ ${s[$z]} != 3  ]]
146then	err_exit '[[ ${s[$z]} != 3  ]]'
147fi
148if	(( s[$z] != 3 ))
149then	err_exit '(( s[$z] != 3 ))'
150fi
151(( s[$y] = s[$y] + ${s[$z]} ))
152if	[[ ${s[$y]} != 4  ]]
153then	err_exit '[[ ${s[$y]} != 4  ]]'
154fi
155if	(( s[$y] != 4 ))
156then	err_exit '(( s[$y] != 4 ))'
157fi
158set -A y 2 4 6
159typeset -i y
160z=${y[@]}
161typeset -R12 y
162typeset -i y
163if      [[ ${y[@]} != "$z" ]]
164then    err_exit 'error in array conversion from int to R12'
165fi
166if      (( ${#y[@]} != 3  ))
167then    err_exit 'error in count of array conversion from int to R12'
168fi
169unset abcdefg
170:  ${abcdefg[1]}
171set | grep '^abcdefg$' >/dev/null && err_exit 'empty array variable in set list'
172unset x y
173x=1
174typeset -i y[$x]=4
175if	[[ ${y[1]} != 4 ]]
176then    err_exit 'arithmetic expressions in typeset not working'
177fi
178unset foo
179typeset foo=bar
180typeset -A foo
181if	[[ ${foo[0]} != bar ]]
182then	err_exit 'initial value not preserved when typecast to associative'
183fi
184unset foo
185foo=(one two)
186typeset -A foo
187foo[two]=3
188if	[[ ${#foo[*]} != 3 ]]
189then	err_exit 'conversion of indexed to associative array failed'
190fi
191set a b c d e f g h i j k l m
192if	[[ ${#} != 13 ]]
193then	err_exit '${#} not 13'
194fi
195unset xxx
196xxx=foo
197if	[[ ${!xxx[@]} != 0 ]]
198then	err_exit '${!xxx[@]} for scalar not 0'
199fi
200if	[[ ${11} != k ]]
201then	err_exit '${11} not working'
202fi
203if	[[ ${@:4:1} != d ]]
204then	err_exit '${@:4:1} not working'
205fi
206foovar1=abc
207foovar2=def
208if	[[ ${!foovar@} != +(foovar[[:alnum:]]?([ ])) ]]
209then	err_exit '${!foovar@} does not expand correctly'
210fi
211if	[[ ${!foovar1} != foovar1 ]]
212then	err_exit '${!foovar1} != foovar1'
213fi
214unset xxx
215: ${xxx[3]}
216if	[[ ${!xxx[@]} ]]
217then	err_exit '${!xxx[@]} should be null'
218fi
219integer i=0
220{
221	set -x
222	xxx[++i]=1
223	set +x
224} 2> /dev/null
225if	(( i != 1))
226then	err_exit 'execution trace side effects with array subscripts'
227fi
228unset list
229: $(set -A list foo bar)
230if	(( ${#list[@]} != 0))
231then	err_exit '$(set -A list ...) leaves side effects'
232fi
233unset list
234list= (foo bar bam)
235( set -A list one two three four)
236if	[[ ${list[1]} != bar ]]
237then	err_exit 'array not restored after subshell'
238fi
239XPATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:.:/sbin:/usr/sbin
240xpath=( $( IFS=: ; echo $XPATH ) )
241if	[[ $(print -r  "${xpath[@]##*/}") != 'bin bin ucb bin . sbin sbin' ]]
242then	err_exit '${xpath[@]##*/} not applied to each element'
243fi
244foo=( zero one '' three four '' six)
245integer n=-1
246if	[[ ${foo[@]:n} != six ]]
247then	err_exit 'array offset of -1 not working'
248fi
249if	[[ ${foo[@]: -3:1} != four ]]
250then	err_exit 'array offset of -3:1 not working'
251fi
252$SHELL -c 'x=(if then else fi)' 2> /dev/null  || err_exit 'reserved words in x=() assignment not working'
253unset foo
254foo=one
255foo=( $foo two)
256if	[[ ${#foo[@]} != 2 ]]
257then	err_exit 'array getting unset before right hand side evaluation'
258fi
259foo=(143 3643 38732)
260export foo
261typeset -i foo
262if	[[ $($SHELL -c 'print $foo') != 143 ]]
263then	err_exit 'exporting indexed array not exporting 0-th element'
264fi
265( $SHELL   -c '
266	unset foo
267	typeset -A foo=([0]=143 [1]=3643 [2]=38732)
268	export foo
269	typeset -i foo
270	[[ $($SHELL -c "print $foo") == 143 ]]'
271) 2> /dev/null ||
272		err_exit 'exporting associative array not exporting 0-th element'
273unset foo
274typeset -A foo
275foo[$((10))]=ok 2> /dev/null || err_exit 'arithmetic expression as subscript not working'
276unset foo
277typeset -A foo
278integer foo=0
279[[ $foo == 0 ]] || err_exit 'zero element of associative array not being set'
280unset foo
281typeset -A foo=( [two]=1)
282for i in one three four five
283do	: ${foo[$i]}
284done
285if	[[ ${!foo[@]} != two ]]
286then	err_exit 'Error in subscript names'
287fi
288unset x
289x=( 1 2 3)
290(x[1]=8)
291[[ ${x[1]} == 2 ]] || err_exit 'index array produce side effects in subshells'
292x=( 1 2 3)
293(
294	x+=(8)
295	[[ ${#x[@]} == 4 ]] || err_exit 'index array append in subshell error'
296)
297[[ ${#x[@]} == 3 ]] || err_exit 'index array append in subshell effects parent'
298x=( [one]=1 [two]=2 [three]=3)
299(x[two]=8)
300[[ ${x[two]} == 2 ]] || err_exit 'associative array produce side effects in subshells'
301unset x
302x=( [one]=1 [two]=2 [three]=3)
303(
304	x+=( [four]=4 )
305	[[ ${#x[@]} == 4 ]] || err_exit 'associative array append in subshell error'
306)
307[[ ${#x[@]} == 3 ]] || err_exit 'associative array append in subshell effects parent'
308unset x
309integer i
310for ((i=0; i < 40; i++))
311do	x[i]=$i
312done
313[[  ${#x[@]} == 40 ]] || err_exit 'index arrays loosing values'
314[[ $( ($SHELL -c 'typeset -A var; (IFS=: ; set -A var a:b:c ;print ${var[@]});:' )2>/dev/null) == 'a b c' ]] || err_exit 'change associative to index failed'
315unset foo
316[[ $(foo=good
317for ((i=0; i < 2; i++))
318do	[[ ${foo[i]} ]] && print ok
319done) == ok ]] || err_exit 'invalid optimization for subscripted variables'
320(
321x=([foo]=bar)
322set +A x bam
323) 2> /dev/null && err_exit 'set +A with associative array should be an error'
324unset bam foo
325foo=0
326typeset -A bam
327unset bam[foo]
328bam[foo]=value
329[[ $bam == value ]] && err_exit 'unset associative array element error'
330: only first element of an array can be exported
331unset bam
332trap 'rm -f /tmp/sharr$$' EXIT
333print 'print ${var[0]} ${var[1]}' > /tmp/sharr$$
334chmod +x /tmp/sharr$$
335[[ $($SHELL -c "var=(foo bar);export var;/tmp/sharr$$") == foo ]] || err_exit 'export array not exporting just first element'
336unset foo
337set -o allexport
338foo=one
339foo[1]=two
340foo[0]=three
341[[ $foo == three ]] || err_exit 'export all not working with arrays'
342cat > /tmp/sharr$$ <<- \!
343	typeset -A foo
344	print foo${foo[abc]}
345!
346# 04-05-24 bug fix
347unset foo
348[[ $($SHELL -c "typeset -A foo;/tmp/sharr$$")  == foo ]] 2> /dev/null || err_exit 'empty associative arrays not being cleared correctly before scripts'
349[[ $($SHELL -c "typeset -A foo;foo[abc]=abc;/tmp/sharr$$") == foo ]] 2> /dev/null || err_exit 'associative arrays not being cleared correctly before scripts'
350unset foo
351foo=(one two)
352[[ ${foo[@]:1} == two ]] || err_exit '${foo[@]:1} == two'
353[[ ! ${foo[@]:2} ]] || err_exit '${foo[@]:2} not null'
354unset foo
355foo=one
356[[ ! ${foo[@]:1} ]] || err_exit '${foo[@]:1} not null'
357function EMPTY
358{
359        typeset i
360        typeset -n ARRAY=$1
361        for i in ${!ARRAY[@]}
362        do      unset ARRAY[$i]
363        done
364}
365unset foo
366typeset -A foo
367foo[bar]=bam
368foo[x]=y
369EMPTY foo
370[[ $(typeset | grep foo$) == *associative* ]] || err_exit 'array lost associative attribute'
371[[ ! ${foo[@]}  ]] || err_exit 'array not empty'
372[[ ! ${!foo[@]}  ]] || err_exit 'array names not empty'
373unset foo
374foo=bar
375set -- "${foo[@]:1}"
376(( $# == 0 )) || err_exit '${foo[@]:1} should not have any values'
377unset bar
378: ${_foo[bar=4]}
379(( bar == 4 )) || err_exit 'subscript of unset variable not evaluated'
380unset foo bar
381foo[5]=4
382bar[4]=3
383bar[0]=foo
384foo[0]=bam
385foo[4]=5
386[[ ${!foo[2+2]} == 'foo[4]' ]] || err_exit '${!var[sub]} should be var[sub]'
387[[ ${bar[${foo[5]}]} == 3 ]] || err_exit  'array subscript cannot be an array instance'
388[[ $bar[4] == 3 ]] || err_exit '$bar[x] != ${bar[x]} inside [[ ]]'
389(( $bar[4] == 3  )) || err_exit '$bar[x] != ${bar[x]} inside (( ))'
390[[ $bar[$foo[5]] == 3 ]]  || err_exit '$bar[foo[x]] != ${bar[foo[x]]} inside [[ ]]'
391(( $bar[$foo[5]] == 3  )) || err_exit '$bar[foo[x]] != ${bar[foo[x]]} inside (( ))'
392x=$bar[4]
393[[ $x == 4 ]] && err_exit '$bar[4] should not be an array in an assignment'
394x=${bar[$foo[5]]}
395(( $x == 3 )) || err_exit '${bar[$foo[sub]]} not working'
396[[ $($SHELL  <<- \++EOF+++
397	typeset -i test_variable=0
398	typeset -A test_array
399	test_array[1]=100
400	read test_array[2] <<-!
401	2
402	!
403	read test_array[3] <<-!
404	3
405	!
406	test_array[3]=4
407	print "val=${test_array[3]}"
408++EOF+++
409) == val=4 ]] 2> /dev/null || err_exit 'after reading array[j] and assign array[j] fails'
410[[ $($SHELL <<- \+++EOF+++
411	pastebin=( typeset -a form)
412	pastebin.form+=( name="name"   data="clueless" )
413	print -r -- ${pastebin.form[0].name}
414+++EOF+++
415) == name ]] 2> /dev/null ||  err_exit 'indexed array in compound variable not working'
416unset foo bar
417: ${foo[bar=2]}
418[[ $bar == 2 ]] || err_exit 'subscript not evaluated for unset variable'
419unset foo bar
420bar=1
421typeset -a foo=([1]=ok [2]=no)
422[[ $foo[bar] == ok ]] || err_exit 'typeset -a not working for simple assignment'
423unset foo
424typeset -a foo=([1]=(x=ok) [2]=(x=no))
425[[ $(typeset | grep 'foo$') == *index* ]] || err_exit 'typeset -a not creating an indexed array'
426foo+=([5]=good)
427[[ $(typeset | grep 'foo$') == *index* ]] || err_exit 'append to indexed array not preserving array type'
428unset foo
429typeset -A foo=([1]=ok [2]=no)
430[[ $foo[bar] == ok ]] && err_exit 'typeset -A not working for simple assignment'
431unset foo
432typeset -A foo=([1]=(x=ok) [2]=(x=no))
433[[ ${foo[bar].x} == ok ]] && err_exit 'typeset -A not working for compound assignment'
434[[ $($SHELL -c 'typeset -a foo;typeset | grep "foo$"'  2> /dev/null) == *index* ]] || err_exit 'typeset fails for indexed array with no elements'
435xxxxx=(one)
436[[ $(typeset | grep xxxxx$) == *'indexed array'* ]] || err_exit 'array of one element not an indexed array'
437unset foo
438foo[1]=(x=3 y=4)
439{ [[ ${!foo[1].*} == 'foo[1].x foo[1].y' ]] ;} 2> /dev/null || err_exit '${!foo[sub].*} not expanding correctly'
440unset x
441x=( typeset -a foo=( [0]="a" [1]="b" [2]="c" ))
442[[  ${@x.foo} == 'typeset -a'* ]] || err_exit 'x.foo is not an indexed array'
443x=( typeset -A foo=( [0]="a" [1]="b" [2]="c" ))
444[[  ${@x.foo} == 'typeset -A'* ]] || err_exit 'x.foo is not an associative array'
445$SHELL -c $'x=(foo\n\tbar\nbam\n)' 2> /dev/null || err_exit 'compound array assignment with new-lines not working'
446$SHELL -c $'x=(foo\n\tbar:\nbam\n)' 2> /dev/null || err_exit 'compound array assignment with labels not working'
447$SHELL -c $'x=(foo\n\tdone\nbam\n)' 2> /dev/null || err_exit 'compound array assignment with reserved words not working'
448[[ $($SHELL -c 'typeset -A A; print $(( A[foo].bar ))' 2> /dev/null) == 0 ]] || err_exit 'unset variable not evaluating to 0'
449unset a
450typeset -A a
451a[a].z=1
452a[z].z=2
453unset a[a]
454[[ ${!a[@]} == z ]] || err_exit '"unset a[a]" unsets entire array'
455unset a
456a=([x]=1 [y]=2 [z]=(foo=3 bar=4))
457eval "b=$(printf "%B\n" a)"
458eval "c=$(printf "%#B\n" a)"
459[[ ${a[*]} == "${b[*]}" ]] || err_exit 'printf %B not preserving values for arrays'
460[[ ${a[*]} == "${c[*]}" ]] || err_exit 'printf %#B not preserving values for arrays'
461unset a
462a=(zero one two three four)
463a[6]=six
464[[ ${a[-1]} == six ]] || err_exit 'a[-1] should be six'
465[[ ${a[-3]} == four ]] || err_exit 'a[-3] should be four'
466[[ ${a[-3..-1]} == 'four six' ]] || err_exit "a[-3,-1] should be 'four six'"
467exit $((Errors))
468