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