4 # The contents of this file are subject to the terms of the
5 # Common Development and Distribution License (the "License").
6 # You may not use this file except in compliance with the License.
8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 # or http://www.opensolaris.org/os/licensing.
10 # See the License for the specific language governing permissions
11 # and limitations under the License.
13 # When distributing Covered Code, include this CDDL HEADER in each
14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 # If applicable, add the following below this CDDL HEADER, with the
16 # fields enclosed by brackets "[]" replaced with your own identifying
17 # information: Portions Copyright [yyyy] [name of copyright owner]
23 # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
27 # variable tree test #002
28 # Propose of this test is whether ksh93 handles global variable trees
29 # and function-local variable trees the same way, including "nameref"
30 # and "unset" handling.
37 print
-u2 -r ${Command}[$1]: "${@:2}"
38 (( Errors
< 127 && Errors
++ ))
40 alias err_exit
='err_exit $LINENO'
42 # the test cannot use "nounset"
46 # "built_tree1" and "built_tree2" are identical except the way how they test
47 # whether a variable exists:
48 # - "built_tree1" uses "${varname}" != "", e.g. looking whether the variable
49 # as non-zero length content
50 # - "built_tree2" uses "! ([[ -v varname ]] ; res=$? ; unset varname ; exit $res)", e.g. "unset" in a subshell.
53 #set -o errexit -o xtrace
60 nameref dest_tree
="$1" # destination tree
61 nameref srcdata
="$2" # source data
62 typeset tree_mode
="$3" # mode to define the type of leads
64 typeset
-A dest_tree.l1
66 for index
in "${!srcdata.hashnodes[@]}" ; do
67 nameref node
=srcdata.hashnodes
["${index}"]
69 for i
in "${node.xlfd[@]}" ; do
70 IFS
='-' read dummy a b c d e f
<<<"$i"
72 if [[ "$a" == "" ]] ; then
76 [[ "$a" == "" ]] && a
='-'
77 [[ "$b" == "" ]] && b
='-'
78 [[ "$c" == "" ]] && c
='-'
80 if [[ "${dest_tree.l1["$a"]}" == "" ]] ; then
81 #if ! (unset dest_tree.l1["$a"]) ; then
82 typeset
-A dest_tree.l1
["$a"].l2
85 if [[ "${dest_tree.l1["$a"].l2["$b"]}" == "" ]] ; then
86 #if ! (unset dest_tree.l1["$a"].l2["$b"]) ; then
87 typeset
-A dest_tree.l1
["$a"].l2
["$b"].l3
90 if [[ "${!dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[*]}" == "" ]] ; then
91 typeset
-A dest_tree.l1
["$a"].l2
["$b"].l3
["$c"].entries
95 if [[ "${tree_mode}" == "leaf_name" ]] ; then
96 new_index
=$
(( ${#dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[@]}+1 ))
98 new_index
="${node.name}"
100 # skip if the leaf node already exists
101 if [[ "${dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[${new_index}]}" != "" ]] ; then
106 add_tree_leaf dest_tree.l1
["$a"].l2
["$b"].l3
["$c"].entries
[${new_index}] "${index}" "${tree_mode}"
113 # "built_tree1
" and "built_tree2
" are identical except the way how they test
114 # whether a variable exists:
115 # - "built_tree1
" uses "${varname}" != "", e.g. looking whether the variable
116 # as non-zero length content
117 # - "built_tree2
" uses "! ([[ -v varname
]] ; res
=$?
; unset varname
; exit $res)", e.g. "unset" in a subshell.
120 #set -o errexit -o xtrace
127 nameref dest_tree="$1" # destination tree
128 nameref srcdata="$2" # source data
129 typeset tree_mode="$3" # mode to define the type of leads
131 typeset -A dest_tree.l1
133 for index in "${!srcdata.hashnodes[@]}" ; do
134 nameref node=srcdata.hashnodes["${index}"]
136 for i in "${node.xlfd[@]}" ; do
137 IFS='-' read dummy a b c d e f <<<"$i"
139 if [[ "$a" == "" ]] ; then
143 [[ "$a" == "" ]] && a='-'
144 [[ "$b" == "" ]] && b='-'
145 [[ "$c" == "" ]] && c='-'
147 #if [[ "${dest_tree.l1["$a"]}" == "" ]] ; then
148 if ! ([[ -v dest_tree.l1["$a"] ]] ; res=$? ; unset dest_tree.l1["$a"] ; exit $res) ; then
149 typeset -A dest_tree.l1["$a"].l2
152 #if [[ "${dest_tree.l1["$a"].l2["$b"]}" == "" ]] ; then
153 if ! ([[ -v dest_tree.l1["$a"].l2["$b"] ]] ; res=$? ; unset dest_tree.l1["$a"].l2["$b"] ; exit $res) ; then
154 typeset -A dest_tree.l1["$a"].l2["$b"].l3
157 if [[ "${!dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[*]}" == "" ]] ; then
158 typeset -A dest_tree.l1["$a"].l2["$b"].l3["$c"].entries
162 if [[ "${tree_mode}" == "leaf_name
" ]] ; then
163 new_index=$(( ${#dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[@]}+1 ))
165 new_index="${node.name}"
167 # skip if the leaf node already exists
168 if [[ "${dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[${new_index}]}" != "" ]] ; then
173 add_tree_leaf dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[${new_index}] "${index}" "${tree_mode}"
181 function add_tree_leaf
183 nameref tree_leafnode
="$1"
184 nameref data_node
=srcdata.hashnodes
["$2"]
185 typeset add_mode
="$3"
187 case "${add_mode}" in
189 tree_leafnode
="${data_node.name}"
194 typeset name
="${data_node.name}"
195 typeset
-a filenames
=( "${data_node.filenames[@]}" )
196 typeset
-a comments
=( "${data_node.comments[@]}" )
197 typeset
-a xlfd
=( "${data_node.xlfd[@]}" )
202 print
-u2 -f "ERROR: Unknown mode %s in add_tree_leaf\n" "${add_mode}"
211 # "mysrcdata_local" and "mysrcdata_global" must be identical
212 typeset mysrcdata_global
=(
213 typeset
-A hashnodes
=(
217 '-urw-itc zapfchancery-medium-i-normal--0-0-0-0-p-0-iso8859-1'
218 '-urw-itc zapfdingbats-medium-r-normal--0-0-0-0-p-0-adobe-fontspecific'
219 '-urw-itc zapfdingbats-medium-r-normal--0-0-0-0-p-0-sun-fontspecific'
221 typeset
-a comments
=(
226 typeset
-a filenames
=(
240 # "mysrcdata_local" and "mysrcdata_global" must be identical
241 typeset mysrcdata_local
=(
242 typeset
-A hashnodes
=(
246 '-urw-itc zapfchancery-medium-i-normal--0-0-0-0-p-0-iso8859-1'
247 '-urw-itc zapfdingbats-medium-r-normal--0-0-0-0-p-0-adobe-fontspecific'
248 '-urw-itc zapfdingbats-medium-r-normal--0-0-0-0-p-0-sun-fontspecific'
250 typeset
-a comments
=(
255 typeset
-a filenames
=(
264 #### Build tree using global tree variables
265 build_tree1 mytree_global1 mysrcdata_global leaf_compound || \
266 err_exit
'build_tree1 mytree_global1 mysrcdata_global leaf_compound returned an error'
267 (( $
(print
-r -- "${mytree_global1}" |
wc -l) > 10 )) || err_exit
"Compound tree 'mytree_global1' too small."
269 build_tree2 mytree_global2 mysrcdata_global leaf_compound || \
270 err_exit
'build_tree2 mytree_global2 mysrcdata_global leaf_compound returned an error'
271 (( $
(print
-r -- "${mytree_global2}" |
wc -l) > 10 )) || err_exit
"Compound tree 'mytree_global2' too small."
274 #### build tree using local tree variables
278 build_tree1 mytree_local1 mysrcdata_local leaf_compound || \
279 err_exit
'build_tree1 mytree_local1 mysrcdata_local leaf_compound returned an error'
280 (( $
(print
-r -- "${mytree_local1}" |
wc -l) > 10 )) || err_exit
"Compound tree 'mytree_local1' too small."
282 build_tree2 mytree_local2 mysrcdata_local leaf_compound || \
283 err_exit
'build_tree2 mytree_local2 mysrcdata_local leaf_compound returned an error'
284 (( $
(print
-r -- "${mytree_local2}" |
wc -l) > 10 )) || err_exit
"Compound tree 'mytree_local2' too small."
288 if [[ "${mytree_global1}" != "${mytree_local1}" ]] ; then
289 err_exit
"Compound trees 'mytree_global1' and 'mytree_local1' not identical"
290 diff -u <( printf "%s\n" "${mytree_global1}" ) <( printf "%s\n" "${mytree_local1}" )
293 if [[ "${mytree_global1}" != "${mytree_global2}" ]] ; then
294 err_exit
"Compound trees 'mytree_global1' and 'mytree_global2' not identical"
295 diff -u <( printf "%s\n" "${mytree_global1}" ) <( printf "%s\n" "${mytree_global2}" )
298 if [[ "${mytree_local1}" != "${mytree_local2}" ]] ; then
299 err_exit
"Compound trees 'mytree_local1' and 'mytree_local2' not identical"
300 diff -u <( printf "%s\n" "${mytree_local1}" ) <( printf "%s\n" "${mytree_local2}" )
304 #### test "unset" in a subshell
305 ( [[ -v 'mytree_global1.l1[urw].l2[itc zapfdingbats]' ]] ; res
=$?
; unset 'mytree_global1.l1[urw].l2[itc zapfdingbats]' ; exit $res ) || \
306 err_exit
"Try 1: Variable 'mytree_global1.l1[urw].l2[itc zapfdingbats]' not found."
307 ( [[ -v 'mytree_global1.l1[urw].l2[itc zapfdingbats]' ]] ; res
=$?
; unset 'mytree_global1.l1[urw].l2[itc zapfdingbats]' ; exit $res ) || \
308 err_exit
"Try 2: Variable 'mytree_global1.l1[urw].l2[itc zapfdingbats]' not found."
310 # remove parent node (array element) and then check whether the child is gone, too:
313 unset 'mytree_global1.l1[urw].l2[itc zapfdingbats]'
314 ! [[ -v 'mytree_global1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' ]]
315 ) || err_exit
"Global: Parent node removed (array element), child still exists"
318 unset 'mytree_local1.l1[urw].l2[itc zapfdingbats]'
319 ! [[ -v 'mytree_local1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' ]]
320 ) || err_exit
"Local: Parent node removed (array element), child still exists"
322 # remove parent node (array variable) and then check whether the child is gone, too:
325 unset 'mytree_local1.l1[urw].l2'
326 ! [[ -v 'mytree_local1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' ]]
327 ) || err_exit
"Global: Parent node removed (array variable), child still exists"
330 unset 'mytree_local1.l1[urw].l2'
331 ! [[ -v 'mytree_local1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' ]]
332 ) || err_exit
"Local: Parent node removed (array variable), child still exists"
335 #### test "unset" and compare trees
336 [[ -v 'mytree_global1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' ]] ; res
=$?
337 unset 'mytree_global1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]'
339 err_exit
"Variable 'mytree_global1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' not found."
341 [[ "${mytree_global1}" != "${mytree_local1}" ]] || err_exit
"mytree_global1 and mytree_local1 should differ"
343 [[ -v 'mytree_local1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' ]] ; res
=$?
344 unset 'mytree_local1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]'
346 err_exit
"Variable 'mytree_local1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' not found."
348 # Compare trees (after "unset")
349 if [[ "${mytree_global1}" != "${mytree_local1}" ]] ; then
350 err_exit
"Compound trees 'mytree_local1' and 'mytree_global1' not identical after unset"
351 diff -u <( printf "%s\n" "${mytree_global1}" ) <( printf "%s\n" "${mytree_local1}" )