Blame src/cmd/ksh93/tests/vartree2.sh

Packit Service a8c26c
########################################################################
Packit Service a8c26c
#                                                                      #
Packit Service a8c26c
#               This software is part of the ast package               #
Packit Service a8c26c
#          Copyright (c) 1982-2011 AT&T Intellectual Property          #
Packit Service a8c26c
#                      and is licensed under the                       #
Packit Service a8c26c
#                 Eclipse Public License, Version 1.0                  #
Packit Service a8c26c
#                    by AT&T Intellectual Property                     #
Packit Service a8c26c
#                                                                      #
Packit Service a8c26c
#                A copy of the License is available at                 #
Packit Service a8c26c
#          http://www.eclipse.org/org/documents/epl-v10.html           #
Packit Service a8c26c
#         (with md5 checksum b35adb5213ca9657e911e9befb180842)         #
Packit Service a8c26c
#                                                                      #
Packit Service a8c26c
#              Information and Software Systems Research               #
Packit Service a8c26c
#                            AT&T Research                             #
Packit Service a8c26c
#                           Florham Park NJ                            #
Packit Service a8c26c
#                                                                      #
Packit Service a8c26c
#                  David Korn <dgk@research.att.com>                   #
Packit Service a8c26c
#                                                                      #
Packit Service a8c26c
########################################################################
Packit Service a8c26c
#
Packit Service a8c26c
# variable tree test #002
Packit Service a8c26c
# Propose of this test is whether ksh93 handles global variable trees
Packit Service a8c26c
# and function-local variable trees the same way, including "nameref"
Packit Service a8c26c
# and "unset" handling.
Packit Service a8c26c
#
Packit Service a8c26c
Packit Service a8c26c
function err_exit
Packit Service a8c26c
{
Packit Service a8c26c
	print -u2 -n "\t"
Packit Service a8c26c
	print -u2 -r ${Command}[$1]: "${@:2}"
Packit Service a8c26c
	(( Errors+=1 ))
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
alias err_exit='err_exit $LINENO'
Packit Service a8c26c
Packit Service a8c26c
# "built_tree1" and "built_tree2" are identical except the way how they test
Packit Service a8c26c
# whether a variable exists:
Packit Service a8c26c
# - "built_tree1" uses "${varname}" != "", e.g. looking whether the variable
Packit Service a8c26c
#    as non-zero length content
Packit Service a8c26c
# - "built_tree2" uses "! (unset varname)", e.g. "unset" in a subshell
Packit Service a8c26c
function build_tree1
Packit Service a8c26c
{
Packit Service a8c26c
#set -o errexit -o xtrace
Packit Service a8c26c
	typeset index
Packit Service a8c26c
	typeset s
Packit Service a8c26c
	typeset i
Packit Service a8c26c
	typeset dummy
Packit Service a8c26c
	typeset a b c d e f
Packit Service a8c26c
Packit Service a8c26c
	nameref dest_tree="$1" # destination tree
Packit Service a8c26c
	nameref srcdata="$2"   # source data
Packit Service a8c26c
	typeset tree_mode="$3" # mode to define the type of leads
Packit Service a8c26c
Packit Service a8c26c
	typeset -A dest_tree.l1
Packit Service a8c26c
Packit Service a8c26c
	for index in "${!srcdata.hashnodes[@]}" ; do
Packit Service a8c26c
		nameref node=srcdata.hashnodes["${index}"]
Packit Service a8c26c
Packit Service a8c26c
		for i in "${node.xlfd[@]}" ; do
Packit Service a8c26c
			IFS='-' read dummy a b c d e f <<<"$i"
Packit Service a8c26c
Packit Service a8c26c
			if [[ "$a" == "" ]] ; then
Packit Service a8c26c
				a="$dummy"
Packit Service a8c26c
			fi
Packit Service a8c26c
Packit Service a8c26c
			[[ "$a" == "" ]] && a='-'
Packit Service a8c26c
			[[ "$b" == "" ]] && b='-'
Packit Service a8c26c
			[[ "$c" == "" ]] && c='-'
Packit Service a8c26c
Packit Service a8c26c
			if [[ "${dest_tree.l1["$a"]}" == "" ]] ; then
Packit Service a8c26c
			#if ! (unset dest_tree.l1["$a"]) ; then
Packit Service a8c26c
				typeset -A dest_tree.l1["$a"].l2
Packit Service a8c26c
			fi
Packit Service a8c26c
Packit Service a8c26c
			if [[ "${dest_tree.l1["$a"].l2["$b"]}" == "" ]] ; then
Packit Service a8c26c
			#if ! (unset dest_tree.l1["$a"].l2["$b"]) ; then
Packit Service a8c26c
				typeset -A dest_tree.l1["$a"].l2["$b"].l3
Packit Service a8c26c
			fi
Packit Service a8c26c
Packit Service a8c26c
			if [[ "${!dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[*]}" == "" ]] ; then
Packit Service a8c26c
				typeset -A dest_tree.l1["$a"].l2["$b"].l3["$c"].entries
Packit Service a8c26c
			fi
Packit Service a8c26c
Packit Service a8c26c
			typeset new_index
Packit Service a8c26c
			if [[ "${tree_mode}" == "leaf_name" ]] ; then
Packit Service a8c26c
				new_index=$(( ${#dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[@]}+1 ))
Packit Service a8c26c
			else
Packit Service a8c26c
				new_index="${node.name}"
Packit Service a8c26c
Packit Service a8c26c
				# skip if the leaf node already exists
Packit Service a8c26c
				if [[ "${dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[${new_index}]}" != "" ]] ; then
Packit Service a8c26c
					continue
Packit Service a8c26c
				fi
Packit Service a8c26c
			fi
Packit Service a8c26c
Packit Service a8c26c
			add_tree_leaf dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[${new_index}] "${index}" "${tree_mode}"
Packit Service a8c26c
		done
Packit Service a8c26c
	done
Packit Service a8c26c
Packit Service a8c26c
	return 0
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
# "built_tree1" and "built_tree2" are identical except the way how they test
Packit Service a8c26c
# whether a variable exists:
Packit Service a8c26c
# - "built_tree1" uses "${varname}" != "", e.g. looking whether the variable
Packit Service a8c26c
#    as non-zero length content
Packit Service a8c26c
# - "built_tree2" uses "! (unset varname)", e.g. "unset" in a subshell
Packit Service a8c26c
function build_tree2
Packit Service a8c26c
{
Packit Service a8c26c
#set -o errexit -o xtrace
Packit Service a8c26c
	typeset index
Packit Service a8c26c
	typeset s
Packit Service a8c26c
	typeset i
Packit Service a8c26c
	typeset dummy
Packit Service a8c26c
	typeset a b c d e f
Packit Service a8c26c
Packit Service a8c26c
	nameref dest_tree="$1" # destination tree
Packit Service a8c26c
	nameref srcdata="$2"   # source data
Packit Service a8c26c
	typeset tree_mode="$3" # mode to define the type of leads
Packit Service a8c26c
Packit Service a8c26c
	typeset -A dest_tree.l1
Packit Service a8c26c
Packit Service a8c26c
	for index in "${!srcdata.hashnodes[@]}" ; do
Packit Service a8c26c
		nameref node=srcdata.hashnodes["${index}"]
Packit Service a8c26c
Packit Service a8c26c
		for i in "${node.xlfd[@]}" ; do
Packit Service a8c26c
			IFS='-' read dummy a b c d e f <<<"$i"
Packit Service a8c26c
Packit Service a8c26c
			if [[ "$a" == "" ]] ; then
Packit Service a8c26c
				a="$dummy"
Packit Service a8c26c
			fi
Packit Service a8c26c
Packit Service a8c26c
			[[ "$a" == "" ]] && a='-'
Packit Service a8c26c
			[[ "$b" == "" ]] && b='-'
Packit Service a8c26c
			[[ "$c" == "" ]] && c='-'
Packit Service a8c26c
Packit Service a8c26c
			#if [[ "${dest_tree.l1["$a"]}" == "" ]] ; then
Packit Service a8c26c
			if ! (unset dest_tree.l1["$a"]) ; then
Packit Service a8c26c
				typeset -A dest_tree.l1["$a"].l2
Packit Service a8c26c
			fi
Packit Service a8c26c
Packit Service a8c26c
			#if [[ "${dest_tree.l1["$a"].l2["$b"]}" == "" ]] ; then
Packit Service a8c26c
			if ! (unset dest_tree.l1["$a"].l2["$b"]) ; then
Packit Service a8c26c
				typeset -A dest_tree.l1["$a"].l2["$b"].l3
Packit Service a8c26c
			fi
Packit Service a8c26c
Packit Service a8c26c
			if [[ "${!dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[*]}" == "" ]] ; then
Packit Service a8c26c
				typeset -A dest_tree.l1["$a"].l2["$b"].l3["$c"].entries
Packit Service a8c26c
			fi
Packit Service a8c26c
Packit Service a8c26c
			typeset new_index
Packit Service a8c26c
			if [[ "${tree_mode}" == "leaf_name" ]] ; then
Packit Service a8c26c
				new_index=$(( ${#dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[@]}+1 ))
Packit Service a8c26c
			else
Packit Service a8c26c
				new_index="${node.name}"
Packit Service a8c26c
Packit Service a8c26c
				# skip if the leaf node already exists
Packit Service a8c26c
				if [[ "${dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[${new_index}]}" != "" ]] ; then
Packit Service a8c26c
					continue
Packit Service a8c26c
				fi
Packit Service a8c26c
			fi
Packit Service a8c26c
Packit Service a8c26c
			add_tree_leaf dest_tree.l1["$a"].l2["$b"].l3["$c"].entries[${new_index}] "${index}" "${tree_mode}"
Packit Service a8c26c
		done
Packit Service a8c26c
	done
Packit Service a8c26c
Packit Service a8c26c
	return 0
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
Packit Service a8c26c
function add_tree_leaf
Packit Service a8c26c
{
Packit Service a8c26c
	nameref tree_leafnode="$1"
Packit Service a8c26c
	nameref data_node=srcdata.hashnodes["$2"]
Packit Service a8c26c
	typeset add_mode="$3"
Packit Service a8c26c
Packit Service a8c26c
	case "${add_mode}" in
Packit Service a8c26c
		"leaf_name")
Packit Service a8c26c
			tree_leafnode="${data_node.name}"
Packit Service a8c26c
			return 0
Packit Service a8c26c
			;;
Packit Service a8c26c
		"leaf_compound")
Packit Service a8c26c
			tree_leafnode=(
Packit Service a8c26c
				typeset name="${data_node.name}"
Packit Service a8c26c
				typeset -a filenames=( "${data_node.filenames[@]}" )
Packit Service a8c26c
				typeset -a comments=( "${data_node.comments[@]}" )
Packit Service a8c26c
				typeset -a xlfd=( "${data_node.xlfd[@]}" )
Packit Service a8c26c
			)
Packit Service a8c26c
			return 0
Packit Service a8c26c
			;;
Packit Service a8c26c
		*)
Packit Service a8c26c
			print -u2 -f "ERROR: Unknown mode %s in add_tree_leaf\n" "${add_mode}"
Packit Service a8c26c
			return 1
Packit Service a8c26c
			;;
Packit Service a8c26c
	esac
Packit Service a8c26c
Packit Service a8c26c
	# not reached
Packit Service a8c26c
	return 1
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
# "mysrcdata_local" and "mysrcdata_global" must be identical
Packit Service a8c26c
typeset mysrcdata_global=(
Packit Service a8c26c
	typeset -A hashnodes=(
Packit Service a8c26c
		[abcd]=(
Packit Service a8c26c
			name='abcd'
Packit Service a8c26c
			typeset -a xlfd=(
Packit Service a8c26c
				'-urw-itc zapfchancery-medium-i-normal--0-0-0-0-p-0-iso8859-1'
Packit Service a8c26c
				'-urw-itc zapfdingbats-medium-r-normal--0-0-0-0-p-0-adobe-fontspecific'
Packit Service a8c26c
				'-urw-itc zapfdingbats-medium-r-normal--0-0-0-0-p-0-sun-fontspecific'
Packit Service a8c26c
			)
Packit Service a8c26c
			typeset -a comments=(
Packit Service a8c26c
				'comment 1'
Packit Service a8c26c
				'comment 2'
Packit Service a8c26c
				'comment 3'
Packit Service a8c26c
			)
Packit Service a8c26c
			typeset -a filenames=(
Packit Service a8c26c
				'/home/foo/abcd_1'
Packit Service a8c26c
				'/home/foo/abcd_2'
Packit Service a8c26c
				'/home/foo/abcd_3'
Packit Service a8c26c
			)
Packit Service a8c26c
		)
Packit Service a8c26c
	)
Packit Service a8c26c
)
Packit Service a8c26c
Packit Service a8c26c
mytree_global1=()
Packit Service a8c26c
mytree_global2=()
Packit Service a8c26c
Packit Service a8c26c
function main
Packit Service a8c26c
{
Packit Service a8c26c
	# "mysrcdata_local" and "mysrcdata_global" must be identical
Packit Service a8c26c
	typeset mysrcdata_local=(
Packit Service a8c26c
		typeset -A hashnodes=(
Packit Service a8c26c
			[abcd]=(
Packit Service a8c26c
				name='abcd'
Packit Service a8c26c
				typeset -a xlfd=(
Packit Service a8c26c
					'-urw-itc zapfchancery-medium-i-normal--0-0-0-0-p-0-iso8859-1'
Packit Service a8c26c
					'-urw-itc zapfdingbats-medium-r-normal--0-0-0-0-p-0-adobe-fontspecific'
Packit Service a8c26c
					'-urw-itc zapfdingbats-medium-r-normal--0-0-0-0-p-0-sun-fontspecific'
Packit Service a8c26c
				)
Packit Service a8c26c
				typeset -a comments=(
Packit Service a8c26c
					'comment 1'
Packit Service a8c26c
					'comment 2'
Packit Service a8c26c
					'comment 3'
Packit Service a8c26c
				)
Packit Service a8c26c
				typeset -a filenames=(
Packit Service a8c26c
					'/home/foo/abcd_1'
Packit Service a8c26c
					'/home/foo/abcd_2'
Packit Service a8c26c
					'/home/foo/abcd_3'
Packit Service a8c26c
				)
Packit Service a8c26c
			)
Packit Service a8c26c
		)
Packit Service a8c26c
	)
Packit Service a8c26c
Packit Service a8c26c
	#### Build tree using global tree variables
Packit Service a8c26c
	build_tree1 mytree_global1 mysrcdata_global leaf_compound || \
Packit Service a8c26c
		err_exit 'build_tree1 mytree_global1 mysrcdata_global leaf_compound returned an error'
Packit Service a8c26c
	(( $(print -r -- "${mytree_global1}" | wc -l) > 10 )) || err_exit "compound tree 'mytree_global1' too small"
Packit Service a8c26c
Packit Service a8c26c
	build_tree2 mytree_global2 mysrcdata_global leaf_compound || \
Packit Service a8c26c
		err_exit 'build_tree2 mytree_global2 mysrcdata_global leaf_compound returned an error'
Packit Service a8c26c
	(( $(print -r -- "${mytree_global2}" | wc -l) > 10 )) || err_exit "compound tree 'mytree_global2' too small"
Packit Service a8c26c
Packit Service a8c26c
Packit Service a8c26c
	#### build tree using local tree variables
Packit Service a8c26c
	mytree_local1=()
Packit Service a8c26c
	mytree_local2=()
Packit Service a8c26c
Packit Service a8c26c
	build_tree1 mytree_local1 mysrcdata_local leaf_compound || \
Packit Service a8c26c
		err_exit 'build_tree1 mytree_local1 mysrcdata_local leaf_compound returned an error'
Packit Service a8c26c
	(( $(print -r -- "${mytree_local1}" | wc -l) > 10 )) || err_exit "compound tree 'mytree_local1' too small"
Packit Service a8c26c
Packit Service a8c26c
	build_tree2 mytree_local2 mysrcdata_local leaf_compound || \
Packit Service a8c26c
		err_exit 'build_tree2 mytree_local2 mysrcdata_local leaf_compound returned an error'
Packit Service a8c26c
	(( $(print -r -- "${mytree_local2}" | wc -l) > 10 )) || err_exit "compound tree 'mytree_local2' too small"
Packit Service a8c26c
Packit Service a8c26c
Packit Service a8c26c
	#### Compare treess
Packit Service a8c26c
	if [[ "${mytree_global1}" != "${mytree_local1}" ]] ; then
Packit Service a8c26c
		err_exit "compound trees 'mytree_global1' and 'mytree_local1' not identical"
Packit Service a8c26c
	fi
Packit Service a8c26c
Packit Service a8c26c
	if [[ "${mytree_global1}" != "${mytree_global2}" ]] ; then
Packit Service a8c26c
		err_exit "compound trees 'mytree_global1' and 'mytree_global2' not identical"
Packit Service a8c26c
	fi
Packit Service a8c26c
Packit Service a8c26c
	if [[ "${mytree_local1}" != "${mytree_local2}" ]] ; then
Packit Service a8c26c
		err_exit "compound trees 'mytree_local1' and 'mytree_local2' not identical"
Packit Service a8c26c
	fi
Packit Service a8c26c
Packit Service a8c26c
Packit Service a8c26c
	#### test "unset" in a subshell
Packit Service a8c26c
	(  unset 'mytree_global1.l1[urw].l2[itc zapfdingbats]'  ) || \
Packit Service a8c26c
		err_exit "try 1: variable 'mytree_global1.l1[urw].l2[itc zapfdingbats]' not found"
Packit Service a8c26c
	(  unset 'mytree_global1.l1[urw].l2[itc zapfdingbats]'  ) || \
Packit Service a8c26c
		err_exit "try 2: variable 'mytree_global1.l1[urw].l2[itc zapfdingbats]' not found"
Packit Service a8c26c
Packit Service a8c26c
	# remove parent node (array element) and then check whether the child is gone, too:
Packit Service a8c26c
	(
Packit Service a8c26c
		unset 'mytree_global1.l1[urw].l2[itc zapfdingbats]'
Packit Service a8c26c
		[[ -v 'mytree_global1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]'} ]]
Packit Service a8c26c
	) && err_exit "global: parent node removed (array element), child still exists"
Packit Service a8c26c
	(
Packit Service a8c26c
		unset 'mytree_local1.l1[urw].l2[itc zapfdingbats]'
Packit Service a8c26c
		[[ -v 'mytree_local1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' ]]
Packit Service a8c26c
	) && err_exit "local: parent node removed (array element), child still exists"
Packit Service a8c26c
Packit Service a8c26c
	# remove parent node  (array variable) and then check whether the child is gone, too:
Packit Service a8c26c
	(
Packit Service a8c26c
		unset 'mytree_local1.l1[urw].l2'
Packit Service a8c26c
		[[ -v 'mytree_local1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' ]]
Packit Service a8c26c
	) && err_exit "global: parent node removed (array variable), child still exists"
Packit Service a8c26c
	(
Packit Service a8c26c
		unset 'mytree_local1.l1[urw].l2'
Packit Service a8c26c
		[[ -v 'mytree_local1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' ]]
Packit Service a8c26c
	) && err_exit "local: parent node removed (array variable), child still exists"
Packit Service a8c26c
Packit Service a8c26c
Packit Service a8c26c
	#### test "unset" and compare trees
Packit Service a8c26c
	unset 'mytree_global1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' ||
Packit Service a8c26c
		err_exit "variable 'mytree_global1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' not found"
Packit Service a8c26c
Packit Service a8c26c
	[[ "${mytree_global1}" != "${mytree_local1}" ]] || err_exit "mytree_global1 and mytree_local1 should differ"
Packit Service a8c26c
Packit Service a8c26c
	unset 'mytree_local1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' ||
Packit Service a8c26c
		err_exit "variable 'mytree_local1.l1[urw].l2[itc zapfdingbats].l3[medium].entries[abcd].filenames[0]' not found"
Packit Service a8c26c
Packit Service a8c26c
	# Compare trees (after "unset")
Packit Service a8c26c
	if [[ "${mytree_global1}" != "${mytree_local1}" ]] ; then
Packit Service a8c26c
		err_exit "compound trees 'mytree_local1' and 'mytree_global1' not identical after unset"
Packit Service a8c26c
	fi
Packit Service a8c26c
}
Packit Service a8c26c
Packit Service a8c26c
main
Packit Service a8c26c
Packit Service a8c26c
exit $((Errors<125?Errors:125))