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