134f9b3eRoland Mainz#!/usr/bin/ksh93
234f9b3eRoland Mainz
334f9b3eRoland Mainz#
434f9b3eRoland Mainz# CDDL HEADER START
534f9b3eRoland Mainz#
634f9b3eRoland Mainz# The contents of this file are subject to the terms of the
734f9b3eRoland Mainz# Common Development and Distribution License (the "License").
834f9b3eRoland Mainz# You may not use this file except in compliance with the License.
934f9b3eRoland Mainz#
1034f9b3eRoland Mainz# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
1134f9b3eRoland Mainz# or http://www.opensolaris.org/os/licensing.
1234f9b3eRoland Mainz# See the License for the specific language governing permissions
1334f9b3eRoland Mainz# and limitations under the License.
1434f9b3eRoland Mainz#
1534f9b3eRoland Mainz# When distributing Covered Code, include this CDDL HEADER in each
1634f9b3eRoland Mainz# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1734f9b3eRoland Mainz# If applicable, add the following below this CDDL HEADER, with the
1834f9b3eRoland Mainz# fields enclosed by brackets "[]" replaced with your own identifying
1934f9b3eRoland Mainz# information: Portions Copyright [yyyy] [name of copyright owner]
2034f9b3eRoland Mainz#
2134f9b3eRoland Mainz# CDDL HEADER END
2234f9b3eRoland Mainz#
2334f9b3eRoland Mainz
2434f9b3eRoland Mainz#
253e14f97Roger A. Faulkner# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
2634f9b3eRoland Mainz#
2734f9b3eRoland Mainz
2834f9b3eRoland Mainz#
2934f9b3eRoland Mainz# numtree1 - basic compound variable tree demo+benchmark
3034f9b3eRoland Mainz#
3134f9b3eRoland Mainz
3234f9b3eRoland Mainz# Solaris needs /usr/xpg6/bin:/usr/xpg4/bin because the tools in /usr/bin are not POSIX-conformant
3334f9b3eRoland Mainzexport PATH=/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin
3434f9b3eRoland Mainz
3534f9b3eRoland Mainz# Make sure all math stuff runs in the "C" locale to avoid problems
3634f9b3eRoland Mainz# with alternative # radix point representations (e.g. ',' instead of
3734f9b3eRoland Mainz# '.' in de_DE.*-locales). This needs to be set _before_ any
3834f9b3eRoland Mainz# floating-point constants are defined in this script).
3934f9b3eRoland Mainzif [[ "${LC_ALL}" != "" ]] ; then
4034f9b3eRoland Mainz    export \
4134f9b3eRoland Mainz        LC_MONETARY="${LC_ALL}" \
4234f9b3eRoland Mainz        LC_MESSAGES="${LC_ALL}" \
4334f9b3eRoland Mainz        LC_COLLATE="${LC_ALL}" \
4434f9b3eRoland Mainz        LC_CTYPE="${LC_ALL}"
4534f9b3eRoland Mainz        unset LC_ALL
4634f9b3eRoland Mainzfi
4734f9b3eRoland Mainzexport LC_NUMERIC=C
4834f9b3eRoland Mainz
4934f9b3eRoland Mainzfunction fatal_error
5034f9b3eRoland Mainz{
5134f9b3eRoland Mainz	print -u2 "${progname}: $*"
5234f9b3eRoland Mainz	exit 1
5334f9b3eRoland Mainz}
5434f9b3eRoland Mainz
5534f9b3eRoland Mainzfunction add_number_to_tree
5634f9b3eRoland Mainz{
5734f9b3eRoland Mainz	typeset treename=$1
5834f9b3eRoland Mainz	integer num=$2
5934f9b3eRoland Mainz	integer i
6034f9b3eRoland Mainz	typeset nodepath # full name of compound variable
6134f9b3eRoland Mainz	integer -a pe # path elements
623e14f97Roger A. Faulkner	integer len
633e14f97Roger A. Faulkner	typeset revnums="$(rev <<<"${num}")"
6434f9b3eRoland Mainz
6534f9b3eRoland Mainz	# first built an array containing the names of each path element
6634f9b3eRoland Mainz	# (e.g. "135" results in an array containing "( 1 3 5 )")
673e14f97Roger A. Faulkner	# 10#<number> is used to prevent leading zeros being interpreted
683e14f97Roger A. Faulkner	# as octals
693e14f97Roger A. Faulkner	for (( len=${#revnums} , i=$( printf "10#%s\n" "${revnums}" ) ; len > 0 ; len--, i=i/10 )) ; do
7034f9b3eRoland Mainz		pe+=( $((i % 10)) )
7134f9b3eRoland Mainz	done
7234f9b3eRoland Mainz
7334f9b3eRoland Mainz	# walk path described via the "pe" array and build nodes if
7434f9b3eRoland Mainz	# there aren't any nodes yet
7534f9b3eRoland Mainz	nodepath="${treename}"
7634f9b3eRoland Mainz	for (( i=0 ; i < ${#pe[@]} ; i++ )) ; do
7734f9b3eRoland Mainz		nameref x="${nodepath}"
783e14f97Roger A. Faulkner		
793e14f97Roger A. Faulkner		# [[ -v ]] does not work for arrays because [[ -v ar ]]
803e14f97Roger A. Faulkner		# is equal to [[ -v ar[0] ]]. In this case we can
813e14f97Roger A. Faulkner		# use the output of typeset +p x.nodes
823e14f97Roger A. Faulkner		[[ "${ typeset +p x.nodes ;}" == "" ]] && compound -a x.nodes
833e14f97Roger A. Faulkner		
8434f9b3eRoland Mainz		nodepath+=".nodes[${pe[i]}]"
8534f9b3eRoland Mainz	done
8634f9b3eRoland Mainz	
873e14f97Roger A. Faulkner	# insert element (leaf)
8834f9b3eRoland Mainz	nameref node="${nodepath}"
893e14f97Roger A. Faulkner	[[ "${ typeset +p node.elements ;}" == "" ]] && integer -a node.elements
9034f9b3eRoland Mainz	node.elements+=( ${num} )
913e14f97Roger A. Faulkner
923e14f97Roger A. Faulkner	# DEBUG only
933e14f97Roger A. Faulkner	[[ "${!node.elements[*]}" != ""                ]] || fatal_error "assertion $LINENO FAILED"
943e14f97Roger A. Faulkner	[[ "${ typeset +p node.elements ;}" == *-a*    ]] || fatal_error "assertion $LINENO FAILED"
953e14f97Roger A. Faulkner	[[ "${ typeset +p node.elements ;}" == *-i*    ]] || fatal_error "assertion $LINENO FAILED"
963e14f97Roger A. Faulkner	[[ -v node                                     ]] || fatal_error "assertion $LINENO FAILED"
973e14f97Roger A. Faulkner	[[ -R node                                     ]] || fatal_error "assertion $LINENO FAILED"
983e14f97Roger A. Faulkner	[[ "${ typeset +p ${!node} ;}" == *-C*         ]] || fatal_error "assertion $LINENO FAILED"
993e14f97Roger A. Faulkner	[[ "${!x.nodes[*]}" != ""                      ]] || fatal_error "assertion $LINENO FAILED"
1003e14f97Roger A. Faulkner	[[ "${ typeset +p x.nodes ;}" == *-a*          ]] || fatal_error "assertion $LINENO FAILED"
1013e14f97Roger A. Faulkner	[[ "${ typeset +p x.nodes ;}" == *-C*          ]] || fatal_error "assertion $LINENO FAILED"
10234f9b3eRoland Mainz	
10334f9b3eRoland Mainz	return 0
10434f9b3eRoland Mainz}
10534f9b3eRoland Mainz
10634f9b3eRoland Mainz
10734f9b3eRoland Mainz# floating-point version of "seq"
10834f9b3eRoland Mainzfunction floatseq
10934f9b3eRoland Mainz{
11034f9b3eRoland Mainz	float i
11134f9b3eRoland Mainz	float arg1=$1
11234f9b3eRoland Mainz	float arg2=$2
11334f9b3eRoland Mainz	float arg3=$3
11434f9b3eRoland Mainz
11534f9b3eRoland Mainz	case $# in
11634f9b3eRoland Mainz		1)
11734f9b3eRoland Mainz			for (( i=1. ; i <= arg1 ; i=i+1. )) ; do
11834f9b3eRoland Mainz				printf "%a\n" i
11934f9b3eRoland Mainz			done
12034f9b3eRoland Mainz			;;
12134f9b3eRoland Mainz		2)
12234f9b3eRoland Mainz			for (( i=arg1 ; i <= arg2 ; i=i+1. )) ; do
12334f9b3eRoland Mainz				printf "%a\n" i
12434f9b3eRoland Mainz			done
12534f9b3eRoland Mainz			;;
12634f9b3eRoland Mainz		3)
12734f9b3eRoland Mainz			for (( i=arg1 ; i <= arg3 ; i+=arg2 )) ; do
12834f9b3eRoland Mainz				printf "%a\n" i
12934f9b3eRoland Mainz			done
13034f9b3eRoland Mainz			;;
13134f9b3eRoland Mainz		*)
13234f9b3eRoland Mainz			print -u2 -f "%s: Illegal number of arguments %d\n" "$0" $#
13334f9b3eRoland Mainz			return 1
13434f9b3eRoland Mainz			;;
13534f9b3eRoland Mainz	esac
13634f9b3eRoland Mainz	
13734f9b3eRoland Mainz	return 0
13834f9b3eRoland Mainz}
13934f9b3eRoland Mainz
14034f9b3eRoland Mainz
14134f9b3eRoland Mainzfunction usage
14234f9b3eRoland Mainz{
14334f9b3eRoland Mainz	OPTIND=0
14434f9b3eRoland Mainz	getopts -a "${progname}" "${numtree1_usage}" OPT '-?'
14534f9b3eRoland Mainz	exit 2
14634f9b3eRoland Mainz}
14734f9b3eRoland Mainz
14834f9b3eRoland Mainz# main
14934f9b3eRoland Mainzbuiltin basename
15034f9b3eRoland Mainzbuiltin rev
15134f9b3eRoland Mainz
15234f9b3eRoland Mainzset -o noglob
15334f9b3eRoland Mainzset -o errexit
15434f9b3eRoland Mainzset -o nounset
15534f9b3eRoland Mainz