1#
2# CDDL HEADER START
3#
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.
7#
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.
12#
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]
18#
19# CDDL HEADER END
20#
21
22#
23# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
24#
25
26#
27# This test checks whether "typeset -m" correctly moves local variables
28# into a global variable tree.
29#
30# This was reported as CR #6805792 ("XXXX"):
31# -------- snip --------
32# The following attempt to move a local node into an associative array
33# fails like this:
34# -- snip --
35# typeset -C tree
36# function f1
37# {
38#        nameref tr=$1
39#
40#        typeset -A tr.subtree
41#
42#        typeset -C node
43#
44#        node.one="hello"
45#        node.two="world"
46#
47#        # move local note into the array
48#        typeset -m tr.subtree["a_node"]=node
49#
50#        return 0
51# }
52# f1 tree
53# printf "%B\n" tree
54# print "ok"
55# exit 0
56# -- snip --
57# The output looks like this:
58# -- snip --
59# $ ksh93
60# varmovetest1.sh
61# (
62# (
63# )
64# ok
65# -- snip --
66# ... but AFAIK it should print:
67# -- snip --
68# (
69#        typeset -A subtree=(
70#                [a_node]=(
71#                        one=hello
72#                        two=world
73#                )
74#        )
75# )
76# ok
77# -- snip --
78# -------- snip --------
79#
80
81# test setup
82function err_exit
83{
84	print -u2 -n "\t"
85	print -u2 -r ${Command}[$1]: "${@:2}"
86	(( Errors < 127 && Errors++ ))
87}
88alias err_exit='err_exit $LINENO'
89
90set -o nounset
91Command=${0##*/}
92integer Errors=0
93
94
95## test start
96compound tree1 tree2
97
98# add node to tree which uses "typeset -m" to move a local variable
99# into tree1.subtree["a_node"]
100function f1
101{
102	nameref tr=$1
103
104	typeset -A tr.subtree
105
106	compound node
107
108	node.one="dummy1"
109	node.two="dummy2"
110
111	# We use the nameref's here since ast-ksh,2008-12-12 crashes
112	# when this function returns because "nodeone" and "nodetwo"
113	# still reference "node" which was renamed.
114	# (note that "f1" must be first function and the first being
115	# called, otherwise the crash will not occur)
116	nameref nodeone=node.one
117	nameref nodetwo=node.two
118	nodeone="hello"
119	nodetwo="world"
120
121	# move local note into the array
122	typeset -m tr.subtree["a_node"]=node
123
124	return 0
125}
126
127# Alternative version which uses "nameref" instead of "typeset -m"
128function f2
129{
130	nameref tr=$1
131
132	typeset -A tr.subtree
133
134	nameref node=tr.subtree["a_node"]
135
136	node.one="hello"
137	node.two="world"
138
139	return 0
140}
141
142f1 tree1
143f2 tree2
144
145[[ "${tree1.subtree["a_node"].one}" == "hello" ]] || err_exit "Expected tree1.subtree[\"a_node\"].one == 'hello', got ${tree1.subtree["a_node"].one}"
146[[ "${tree1.subtree["a_node"].two}" == "world" ]] || err_exit "Expected tree1.subtree[\"a_node\"].two == 'world', got ${tree1.subtree["a_node"].two}"
147[[ "${tree1}" == "${tree2}" ]] || err_exit "tree1 and tree2 differ:"$'\n'"$(diff -u <( printf '%B\n' tree1 ) <( printf '%B\n' tree2 ) )"
148
149
150# tests done
151exit $((Errors))
152