1*10898Sroland.mainz@nrubsig.org#!/usr/bin/ksh93
2*10898Sroland.mainz@nrubsig.org
3*10898Sroland.mainz@nrubsig.org#
4*10898Sroland.mainz@nrubsig.org# CDDL HEADER START
5*10898Sroland.mainz@nrubsig.org#
6*10898Sroland.mainz@nrubsig.org# The contents of this file are subject to the terms of the
7*10898Sroland.mainz@nrubsig.org# Common Development and Distribution License (the "License").
8*10898Sroland.mainz@nrubsig.org# You may not use this file except in compliance with the License.
9*10898Sroland.mainz@nrubsig.org#
10*10898Sroland.mainz@nrubsig.org# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11*10898Sroland.mainz@nrubsig.org# or http://www.opensolaris.org/os/licensing.
12*10898Sroland.mainz@nrubsig.org# See the License for the specific language governing permissions
13*10898Sroland.mainz@nrubsig.org# and limitations under the License.
14*10898Sroland.mainz@nrubsig.org#
15*10898Sroland.mainz@nrubsig.org# When distributing Covered Code, include this CDDL HEADER in each
16*10898Sroland.mainz@nrubsig.org# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17*10898Sroland.mainz@nrubsig.org# If applicable, add the following below this CDDL HEADER, with the
18*10898Sroland.mainz@nrubsig.org# fields enclosed by brackets "[]" replaced with your own identifying
19*10898Sroland.mainz@nrubsig.org# information: Portions Copyright [yyyy] [name of copyright owner]
20*10898Sroland.mainz@nrubsig.org#
21*10898Sroland.mainz@nrubsig.org# CDDL HEADER END
22*10898Sroland.mainz@nrubsig.org#
23*10898Sroland.mainz@nrubsig.org
24*10898Sroland.mainz@nrubsig.org#
25*10898Sroland.mainz@nrubsig.org# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
26*10898Sroland.mainz@nrubsig.org# Use is subject to license terms.
27*10898Sroland.mainz@nrubsig.org#
28*10898Sroland.mainz@nrubsig.org
29*10898Sroland.mainz@nrubsig.org#
30*10898Sroland.mainz@nrubsig.org# numtree1 - basic compound variable tree demo+benchmark
31*10898Sroland.mainz@nrubsig.org#
32*10898Sroland.mainz@nrubsig.org
33*10898Sroland.mainz@nrubsig.org# Solaris needs /usr/xpg6/bin:/usr/xpg4/bin because the tools in /usr/bin are not POSIX-conformant
34*10898Sroland.mainz@nrubsig.orgexport PATH=/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin
35*10898Sroland.mainz@nrubsig.org
36*10898Sroland.mainz@nrubsig.org# Make sure all math stuff runs in the "C" locale to avoid problems
37*10898Sroland.mainz@nrubsig.org# with alternative # radix point representations (e.g. ',' instead of
38*10898Sroland.mainz@nrubsig.org# '.' in de_DE.*-locales). This needs to be set _before_ any
39*10898Sroland.mainz@nrubsig.org# floating-point constants are defined in this script).
40*10898Sroland.mainz@nrubsig.orgif [[ "${LC_ALL}" != "" ]] ; then
41*10898Sroland.mainz@nrubsig.org    export \
42*10898Sroland.mainz@nrubsig.org        LC_MONETARY="${LC_ALL}" \
43*10898Sroland.mainz@nrubsig.org        LC_MESSAGES="${LC_ALL}" \
44*10898Sroland.mainz@nrubsig.org        LC_COLLATE="${LC_ALL}" \
45*10898Sroland.mainz@nrubsig.org        LC_CTYPE="${LC_ALL}"
46*10898Sroland.mainz@nrubsig.org        unset LC_ALL
47*10898Sroland.mainz@nrubsig.orgfi
48*10898Sroland.mainz@nrubsig.orgexport LC_NUMERIC=C
49*10898Sroland.mainz@nrubsig.org
50*10898Sroland.mainz@nrubsig.orgfunction fatal_error
51*10898Sroland.mainz@nrubsig.org{
52*10898Sroland.mainz@nrubsig.org	print -u2 "${progname}: $*"
53*10898Sroland.mainz@nrubsig.org	exit 1
54*10898Sroland.mainz@nrubsig.org}
55*10898Sroland.mainz@nrubsig.org
56*10898Sroland.mainz@nrubsig.orgfunction add_number_to_tree
57*10898Sroland.mainz@nrubsig.org{
58*10898Sroland.mainz@nrubsig.org	typeset treename=$1
59*10898Sroland.mainz@nrubsig.org	integer num=$2
60*10898Sroland.mainz@nrubsig.org	integer i
61*10898Sroland.mainz@nrubsig.org	typeset nodepath # full name of compound variable
62*10898Sroland.mainz@nrubsig.org	integer -a pe # path elements
63*10898Sroland.mainz@nrubsig.org
64*10898Sroland.mainz@nrubsig.org	# first built an array containing the names of each path element
65*10898Sroland.mainz@nrubsig.org	# (e.g. "135" results in an array containing "( 1 3 5 )")
66*10898Sroland.mainz@nrubsig.org	for (( i=$(rev <<<$num) ; i > 0 ; i=i/10 )) ; do
67*10898Sroland.mainz@nrubsig.org		pe+=( $((i % 10)) )
68*10898Sroland.mainz@nrubsig.org	done
69*10898Sroland.mainz@nrubsig.org
70*10898Sroland.mainz@nrubsig.org	# walk path described via the "pe" array and build nodes if
71*10898Sroland.mainz@nrubsig.org	# there aren't any nodes yet
72*10898Sroland.mainz@nrubsig.org	nodepath="${treename}"
73*10898Sroland.mainz@nrubsig.org	for (( i=0 ; i < ${#pe[@]} ; i++ )) ; do
74*10898Sroland.mainz@nrubsig.org		nameref x="${nodepath}"
75*10898Sroland.mainz@nrubsig.org		[[ ! -v x.node ]] && compound -C -a x.nodes
76*10898Sroland.mainz@nrubsig.org
77*10898Sroland.mainz@nrubsig.org		nodepath+=".nodes[${pe[i]}]"
78*10898Sroland.mainz@nrubsig.org	done
79*10898Sroland.mainz@nrubsig.org
80*10898Sroland.mainz@nrubsig.org	# insert element
81*10898Sroland.mainz@nrubsig.org	nameref node="${nodepath}"
82*10898Sroland.mainz@nrubsig.org	[[ ! -v node.elements ]] && integer -a node.elements
83*10898Sroland.mainz@nrubsig.org	node.elements+=( ${num} )
84*10898Sroland.mainz@nrubsig.org
85*10898Sroland.mainz@nrubsig.org	return 0
86*10898Sroland.mainz@nrubsig.org}
87*10898Sroland.mainz@nrubsig.org
88*10898Sroland.mainz@nrubsig.org
89*10898Sroland.mainz@nrubsig.org# floating-point version of "seq"
90*10898Sroland.mainz@nrubsig.orgfunction floatseq
91*10898Sroland.mainz@nrubsig.org{
92*10898Sroland.mainz@nrubsig.org	float i
93*10898Sroland.mainz@nrubsig.org	float arg1=$1
94*10898Sroland.mainz@nrubsig.org	float arg2=$2
95*10898Sroland.mainz@nrubsig.org	float arg3=$3
96*10898Sroland.mainz@nrubsig.org
97*10898Sroland.mainz@nrubsig.org	case $# in
98*10898Sroland.mainz@nrubsig.org		1)
99*10898Sroland.mainz@nrubsig.org			for (( i=1. ; i <= arg1 ; i=i+1. )) ; do
100*10898Sroland.mainz@nrubsig.org				printf "%a\n" i
101*10898Sroland.mainz@nrubsig.org			done
102*10898Sroland.mainz@nrubsig.org			;;
103*10898Sroland.mainz@nrubsig.org		2)
104*10898Sroland.mainz@nrubsig.org			for (( i=arg1 ; i <= arg2 ; i=i+1. )) ; do
105*10898Sroland.mainz@nrubsig.org				printf "%a\n" i
106*10898Sroland.mainz@nrubsig.org			done
107*10898Sroland.mainz@nrubsig.org			;;
108*10898Sroland.mainz@nrubsig.org		3)
109*10898Sroland.mainz@nrubsig.org			for (( i=arg1 ; i <= arg3 ; i+=arg2 )) ; do
110*10898Sroland.mainz@nrubsig.org				printf "%a\n" i
111*10898Sroland.mainz@nrubsig.org			done
112*10898Sroland.mainz@nrubsig.org			;;
113*10898Sroland.mainz@nrubsig.org		*)
114*10898Sroland.mainz@nrubsig.org			print -u2 -f "%s: Illegal number of arguments %d\n" "$0" $#
115*10898Sroland.mainz@nrubsig.org			return 1
116*10898Sroland.mainz@nrubsig.org			;;
117*10898Sroland.mainz@nrubsig.org	esac
118*10898Sroland.mainz@nrubsig.org
119*10898Sroland.mainz@nrubsig.org	return 0
120*10898Sroland.mainz@nrubsig.org}
121*10898Sroland.mainz@nrubsig.org
122*10898Sroland.mainz@nrubsig.org
123*10898Sroland.mainz@nrubsig.orgfunction usage
124*10898Sroland.mainz@nrubsig.org{
125*10898Sroland.mainz@nrubsig.org	OPTIND=0
126*10898Sroland.mainz@nrubsig.org	getopts -a "${progname}" "${numtree1_usage}" OPT '-?'
127*10898Sroland.mainz@nrubsig.org	exit 2
128*10898Sroland.mainz@nrubsig.org}
129*10898Sroland.mainz@nrubsig.org
130*10898Sroland.mainz@nrubsig.org# main
131*10898Sroland.mainz@nrubsig.orgbuiltin basename
132*10898Sroland.mainz@nrubsig.orgbuiltin rev
133*10898Sroland.mainz@nrubsig.org
134*10898Sroland.mainz@nrubsig.orgset -o noglob
135*10898Sroland.mainz@nrubsig.orgset -o errexit
136*10898Sroland.mainz@nrubsig.orgset -o nounset
137*10898Sroland.mainz@nrubsig.org
138*10898Sroland.mainz@nrubsig.orgcompound base
139*10898Sroland.mainz@nrubsig.org
140*10898Sroland.mainz@nrubsig.orgcompound bench=(
141*10898Sroland.mainz@nrubsig.org	float start
142*10898Sroland.mainz@nrubsig.org	float stop
143*10898Sroland.mainz@nrubsig.org)
144*10898Sroland.mainz@nrubsig.org
145*10898Sroland.mainz@nrubsig.orginteger i
146*10898Sroland.mainz@nrubsig.org
147*10898Sroland.mainz@nrubsig.orgtypeset progname="${ basename "${0}" ; }"
148*10898Sroland.mainz@nrubsig.org
149*10898Sroland.mainz@nrubsig.orgtypeset -r numtree1_usage=$'+
150*10898Sroland.mainz@nrubsig.org[-?\n@(#)\$Id: numtree1 (Roland Mainz) 2009-08-17 \$\n]
151*10898Sroland.mainz@nrubsig.org[-author?Roland Mainz <roland.mainz@nrubsig.org>]
152*10898Sroland.mainz@nrubsig.org[+NAME?numtree1 - generate sorted variable tree containing numbers]
153*10898Sroland.mainz@nrubsig.org[+DESCRIPTION?\bnumtree1\b is a simple variable tree generator
154*10898Sroland.mainz@nrubsig.org	sorts a given set of numbers into a ksh compound variable tree).
155*10898Sroland.mainz@nrubsig.org	the application supports two different modes: \'seq\' takes
156*10898Sroland.mainz@nrubsig.org	1-3 arguments to specify the set of numbers via seq(1) and
157*10898Sroland.mainz@nrubsig.org	\'stdin\' reads the numbers from stdin (one per line)]
158*10898Sroland.mainz@nrubsig.org
159*10898Sroland.mainz@nrubsig.orgmethod [ arguments ]
160*10898Sroland.mainz@nrubsig.org
161*10898Sroland.mainz@nrubsig.org[+SEE ALSO?\bksh93\b(1), \bseq\b(1)]
162*10898Sroland.mainz@nrubsig.org'
163*10898Sroland.mainz@nrubsig.org
164*10898Sroland.mainz@nrubsig.orgwhile getopts -a "${progname}" "${numtree1_usage}" OPT ; do
165*10898Sroland.mainz@nrubsig.org#	printmsg "## OPT=|${OPT}|, OPTARG=|${OPTARG}|"
166*10898Sroland.mainz@nrubsig.org	case ${OPT} in
167*10898Sroland.mainz@nrubsig.org		*) usage ;;
168*10898Sroland.mainz@nrubsig.org	esac
169*10898Sroland.mainz@nrubsig.orgdone
170*10898Sroland.mainz@nrubsig.orgshift $((OPTIND-1))
171*10898Sroland.mainz@nrubsig.org
172*10898Sroland.mainz@nrubsig.org# prechecks
173*10898Sroland.mainz@nrubsig.org(( $# > 0 )) || usage
174*10898Sroland.mainz@nrubsig.org
175*10898Sroland.mainz@nrubsig.orgcmd=$1
176*10898Sroland.mainz@nrubsig.orgshift
177*10898Sroland.mainz@nrubsig.org
178*10898Sroland.mainz@nrubsig.org# Read numbers from stdin outside benchmark loop
179*10898Sroland.mainz@nrubsig.orgif [[ ${cmd} == 'stdin' ]] ; then
180*10898Sroland.mainz@nrubsig.org	stdin_numbers="$( cat /dev/stdin )" || fatal_error "stdin read error"
181*10898Sroland.mainz@nrubsig.orgfi
182*10898Sroland.mainz@nrubsig.org
183*10898Sroland.mainz@nrubsig.org(( bench.start=SECONDS ))
184*10898Sroland.mainz@nrubsig.org
185*10898Sroland.mainz@nrubsig.orgcase ${cmd} in
186*10898Sroland.mainz@nrubsig.org	"seq")
187*10898Sroland.mainz@nrubsig.org		for i in ${ floatseq "$@" ; } ; do
188*10898Sroland.mainz@nrubsig.org			add_number_to_tree base "${i}"
189*10898Sroland.mainz@nrubsig.org		done
190*10898Sroland.mainz@nrubsig.org		;;
191*10898Sroland.mainz@nrubsig.org	"stdin")
192*10898Sroland.mainz@nrubsig.org		for i in ${stdin_numbers} ; do
193*10898Sroland.mainz@nrubsig.org			add_number_to_tree base "${i}"
194*10898Sroland.mainz@nrubsig.org		done
195*10898Sroland.mainz@nrubsig.org		;;
196*10898Sroland.mainz@nrubsig.org	"demo1")
197*10898Sroland.mainz@nrubsig.org		for i in 1 32 33 34 34 38 90 ; do
198*10898Sroland.mainz@nrubsig.org			add_number_to_tree base "${i}"
199*10898Sroland.mainz@nrubsig.org		done
200*10898Sroland.mainz@nrubsig.org		;;
201*10898Sroland.mainz@nrubsig.org	"demo2")
202*10898Sroland.mainz@nrubsig.org		for (( i=1000000000 ; i < 1000000000+10 ; i++ )) ; do
203*10898Sroland.mainz@nrubsig.org			add_number_to_tree base "$i"
204*10898Sroland.mainz@nrubsig.org		done
205*10898Sroland.mainz@nrubsig.org		;;
206*10898Sroland.mainz@nrubsig.org	*)
207*10898Sroland.mainz@nrubsig.org		fatal_error "Invalid command ${cmd}."
208*10898Sroland.mainz@nrubsig.org		;;
209*10898Sroland.mainz@nrubsig.orgesac
210*10898Sroland.mainz@nrubsig.org
211*10898Sroland.mainz@nrubsig.org(( bench.stop=SECONDS ))
212*10898Sroland.mainz@nrubsig.org
213*10898Sroland.mainz@nrubsig.orgprint -u2 -f "# time used: %f\n" $((bench.stop - bench.start))
214*10898Sroland.mainz@nrubsig.org
215*10898Sroland.mainz@nrubsig.org# print tree
216*10898Sroland.mainz@nrubsig.orgprint -v base
217*10898Sroland.mainz@nrubsig.org
218*10898Sroland.mainz@nrubsig.orgexit 0
219*10898Sroland.mainz@nrubsig.org# EOF.
220