1########################################################################
2#                                                                      #
3#               This software is part of the ast package               #
4#          Copyright (c) 1982-2011 AT&T Intellectual Property          #
5#                      and is licensed under the                       #
6#                 Eclipse Public License, Version 1.0                  #
7#                    by AT&T Intellectual Property                     #
8#                                                                      #
9#                A copy of the License is available at                 #
10#          http://www.eclipse.org/org/documents/epl-v10.html           #
11#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
12#                                                                      #
13#              Information and Software Systems Research               #
14#                            AT&T Research                             #
15#                           Florham Park NJ                            #
16#                                                                      #
17#                  David Korn <dgk@research.att.com>                   #
18#                                                                      #
19########################################################################
20#
21# variable tree test #001
22# Propose of this test is whether ksh93 handles global variable trees
23# and function-local variable trees the same way, including "nameref"
24# and "unset" handling.
25#
26
27function err_exit
28{
29	print -u2 -n "\t"
30	print -u2 -r ${Command}[$1]: "${@:2}"
31	(( Errors+=1 ))
32}
33
34alias err_exit='err_exit $LINENO'
35
36function build_tree
37{
38#set -o errexit -o xtrace
39	typeset index
40	typeset s
41	typeset i
42	typeset dummy
43	typeset a b c d e f
44
45	nameref dest_tree="$1" # destination tree
46	nameref srcdata="$2"   # source data
47	typeset tree_mode="$3" # mode to define the type of leads
48
49	typeset -A dest_tree.l1
50
51	for index in "${!srcdata.hashnodes[@]}" ; do
52		nameref node=srcdata.hashnodes["${index}"]
53
54		for i in "${node.xlfd[@]}" ; do
55			IFS='-' read dummy a b c d e f <<<"$i"
56
57			if [[ "$a" == "" ]] ; then
58				a="$dummy"
59			fi
60
61			[[ "$a" == "" ]] && a='-'
62			[[ "$b" == "" ]] && b='-'
63			[[ "$c" == "" ]] && c='-'
64
65			if [[ "${dest_tree.l1["$a"]}" == "" ]] ; then
66			#if ! (unset dest_tree.l1["$a"]) ; then
67				typeset -A dest_tree.l1["$a"].l2
68			fi
69
70			if [[ "${dest_tree.l1["$a"].l2["$b"]}" == "" ]] ; then
71			#if ! (unset dest_tree.l1["$a"].l2["$b"]) ; then
72				typeset -A dest_tree.l1["$a"].l2["$b"].l3
73			fi
74
75			if [[ "${!dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[*]}" == "" ]] ; then
76				typeset -A dest_tree.l1["$a"].l2["$b"].l3["$c"].entries
77			fi
78
79			#dest_tree.l1["$a"].l2["$b"].l3["$c"].entries+=( "$index" )
80			typeset new_index
81			if [[ "${tree_mode}" == "leaf_name" ]] ; then
82				new_index=$(( ${#dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[@]}+1 ))
83			else
84				new_index="${node.name}"
85
86				# skip if the leaf node already exists
87				if [[ "${dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[${new_index}]}" != "" ]] ; then
88					continue
89				fi
90			fi
91
92			add_tree_leaf dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[${new_index}] "${index}" "${tree_mode}"
93		done
94	done
95
96	return 0
97}
98
99function add_tree_leaf
100{
101	nameref tree_leafnode="$1"
102	nameref data_node=srcdata.hashnodes["$2"]
103	typeset add_mode="$3"
104
105	case "${add_mode}" in
106		"leaf_name")
107			tree_leafnode="${data_node.name}"
108			return 0
109			;;
110		"leaf_compound")
111			tree_leafnode=(
112				typeset name="${data_node.name}"
113				typeset -a filenames=( "${data_node.filenames[@]}" )
114				typeset -a comments=( "${data_node.comments[@]}" )
115				typeset -a xlfd=( "${data_node.xlfd[@]}" )
116			)
117			return 0
118			;;
119		*)
120			print -u2 -f "ERROR: Unknown mode %s in add_tree_leaf\n" "${add_mode}"
121			return 1
122			;;
123	esac
124
125	# not reached
126	return 1
127}
128
129# "mysrcdata_local" and "mysrcdata_global" must be identical
130typeset mysrcdata_global=(
131	typeset -A hashnodes=(
132		[abcd]=(
133			name='abcd'
134			typeset -a xlfd=(
135				'-urw-itc zapfchancery-medium-i-normal--0-0-0-0-p-0-iso8859-1'
136				'-urw-itc zapfdingbats-medium-r-normal--0-0-0-0-p-0-adobe-fontspecific'
137				'-urw-itc zapfdingbats-medium-r-normal--0-0-0-0-p-0-sun-fontspecific'
138			)
139			typeset -a comments=(
140				'comment 1'
141				'comment 2'
142				'comment 3'
143			)
144			typeset -a filenames=(
145				'/home/foo/abcd_1'
146				'/home/foo/abcd_2'
147				'/home/foo/abcd_3'
148			)
149		)
150	)
151)
152
153mytree_global=()
154
155function main
156{
157	# "mysrcdata_local" and "mysrcdata_global" must be identical
158	typeset mysrcdata_local=(
159		typeset -A hashnodes=(
160			[abcd]=(
161				name='abcd'
162				typeset -a xlfd=(
163					'-urw-itc zapfchancery-medium-i-normal--0-0-0-0-p-0-iso8859-1'
164					'-urw-itc zapfdingbats-medium-r-normal--0-0-0-0-p-0-adobe-fontspecific'
165					'-urw-itc zapfdingbats-medium-r-normal--0-0-0-0-p-0-sun-fontspecific'
166				)
167				typeset -a comments=(
168					'comment 1'
169					'comment 2'
170					'comment 3'
171				)
172				typeset -a filenames=(
173					'/home/foo/abcd_1'
174					'/home/foo/abcd_2'
175					'/home/foo/abcd_3'
176				)
177			)
178		)
179	)
180
181	# build tree using global tree variables
182	build_tree mytree_global mysrcdata_global leaf_compound || \
183		err_exit 'build_tree mytree_global mysrcdata_global leaf_compound returned an error'
184
185	(( $(print -r -- "${mytree_global}" | wc -l) > 10 )) || err_exit "compound tree 'mytree_global' too small"
186
187	# build tree using local tree variables
188	mytree_local=()
189	build_tree mytree_local mysrcdata_local leaf_compound || \
190		err_exit 'build_tree mytree_local mysrcdata_local leaf_compound returned an error'
191
192	(( $(print -r -- "${mytree_local}" | wc -l) > 10 )) || err_exit "compound tree 'mytree_local' too small"
193
194	# Compare trees
195	if [[ "${mytree_global}" != "${mytree_local}" ]] ; then
196		err_exit "compound trees 'mytree_local' and 'mytree_global' not identical"
197	fi
198
199	unset 'mytree_global.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' ||
200		err_exit "variable 'mytree_global.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' not found"
201
202	[[ "${mytree_global}" != "${mytree_local}" ]] || err_exit "mytree_global and mytree_local should differ"
203
204	unset 'mytree_local.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' ||
205		err_exit "variable 'mytree_local.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' not found"
206
207	# Compare trees (after "unset")
208	if [[ "${mytree_global}" != "${mytree_local}" ]] ; then
209		err_exit "compound trees 'mytree_local' and 'mytree_global' not identical after unset"
210	fi
211}
212
213main
214
215exit $((Errors<125?Errors:125))
216