diff options
Diffstat (limited to 'usr/src/lib/libshell/common/scripts/numtree1.sh')
-rw-r--r-- | usr/src/lib/libshell/common/scripts/numtree1.sh | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/usr/src/lib/libshell/common/scripts/numtree1.sh b/usr/src/lib/libshell/common/scripts/numtree1.sh new file mode 100644 index 0000000000..beca4aae76 --- /dev/null +++ b/usr/src/lib/libshell/common/scripts/numtree1.sh @@ -0,0 +1,219 @@ +#!/usr/bin/ksh93 + +# +# CDDL HEADER START +# +# The contents of this file are subject to the terms of the +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. +# +# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE +# or http://www.opensolaris.org/os/licensing. +# See the License for the specific language governing permissions +# and limitations under the License. +# +# When distributing Covered Code, include this CDDL HEADER in each +# file and include the License file at usr/src/OPENSOLARIS.LICENSE. +# If applicable, add the following below this CDDL HEADER, with the +# fields enclosed by brackets "[]" replaced with your own identifying +# information: Portions Copyright [yyyy] [name of copyright owner] +# +# CDDL HEADER END +# + +# +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. +# + +# +# numtree1 - basic compound variable tree demo+benchmark +# + +# Solaris needs /usr/xpg6/bin:/usr/xpg4/bin because the tools in /usr/bin are not POSIX-conformant +export PATH=/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin + +# Make sure all math stuff runs in the "C" locale to avoid problems +# with alternative # radix point representations (e.g. ',' instead of +# '.' in de_DE.*-locales). This needs to be set _before_ any +# floating-point constants are defined in this script). +if [[ "${LC_ALL}" != "" ]] ; then + export \ + LC_MONETARY="${LC_ALL}" \ + LC_MESSAGES="${LC_ALL}" \ + LC_COLLATE="${LC_ALL}" \ + LC_CTYPE="${LC_ALL}" + unset LC_ALL +fi +export LC_NUMERIC=C + +function fatal_error +{ + print -u2 "${progname}: $*" + exit 1 +} + +function add_number_to_tree +{ + typeset treename=$1 + integer num=$2 + integer i + typeset nodepath # full name of compound variable + integer -a pe # path elements + + # first built an array containing the names of each path element + # (e.g. "135" results in an array containing "( 1 3 5 )") + for (( i=$(rev <<<$num) ; i > 0 ; i=i/10 )) ; do + pe+=( $((i % 10)) ) + done + + # walk path described via the "pe" array and build nodes if + # there aren't any nodes yet + nodepath="${treename}" + for (( i=0 ; i < ${#pe[@]} ; i++ )) ; do + nameref x="${nodepath}" + [[ ! -v x.node ]] && compound -C -a x.nodes + + nodepath+=".nodes[${pe[i]}]" + done + + # insert element + nameref node="${nodepath}" + [[ ! -v node.elements ]] && integer -a node.elements + node.elements+=( ${num} ) + + return 0 +} + + +# floating-point version of "seq" +function floatseq +{ + float i + float arg1=$1 + float arg2=$2 + float arg3=$3 + + case $# in + 1) + for (( i=1. ; i <= arg1 ; i=i+1. )) ; do + printf "%a\n" i + done + ;; + 2) + for (( i=arg1 ; i <= arg2 ; i=i+1. )) ; do + printf "%a\n" i + done + ;; + 3) + for (( i=arg1 ; i <= arg3 ; i+=arg2 )) ; do + printf "%a\n" i + done + ;; + *) + print -u2 -f "%s: Illegal number of arguments %d\n" "$0" $# + return 1 + ;; + esac + + return 0 +} + + +function usage +{ + OPTIND=0 + getopts -a "${progname}" "${numtree1_usage}" OPT '-?' + exit 2 +} + +# main +builtin basename +builtin rev + +set -o noglob +set -o errexit +set -o nounset + +compound base + +compound bench=( + float start + float stop +) + +integer i + +typeset progname="${ basename "${0}" ; }" + +typeset -r numtree1_usage=$'+ +[-?\n@(#)\$Id: numtree1 (Roland Mainz) 2009-08-17 \$\n] +[-author?Roland Mainz <roland.mainz@nrubsig.org>] +[+NAME?numtree1 - generate sorted variable tree containing numbers] +[+DESCRIPTION?\bnumtree1\b is a simple variable tree generator + sorts a given set of numbers into a ksh compound variable tree). + the application supports two different modes: \'seq\' takes + 1-3 arguments to specify the set of numbers via seq(1) and + \'stdin\' reads the numbers from stdin (one per line)] + +method [ arguments ] + +[+SEE ALSO?\bksh93\b(1), \bseq\b(1)] +' + +while getopts -a "${progname}" "${numtree1_usage}" OPT ; do +# printmsg "## OPT=|${OPT}|, OPTARG=|${OPTARG}|" + case ${OPT} in + *) usage ;; + esac +done +shift $((OPTIND-1)) + +# prechecks +(( $# > 0 )) || usage + +cmd=$1 +shift + +# Read numbers from stdin outside benchmark loop +if [[ ${cmd} == 'stdin' ]] ; then + stdin_numbers="$( cat /dev/stdin )" || fatal_error "stdin read error" +fi + +(( bench.start=SECONDS )) + +case ${cmd} in + "seq") + for i in ${ floatseq "$@" ; } ; do + add_number_to_tree base "${i}" + done + ;; + "stdin") + for i in ${stdin_numbers} ; do + add_number_to_tree base "${i}" + done + ;; + "demo1") + for i in 1 32 33 34 34 38 90 ; do + add_number_to_tree base "${i}" + done + ;; + "demo2") + for (( i=1000000000 ; i < 1000000000+10 ; i++ )) ; do + add_number_to_tree base "$i" + done + ;; + *) + fatal_error "Invalid command ${cmd}." + ;; +esac + +(( bench.stop=SECONDS )) + +print -u2 -f "# time used: %f\n" $((bench.stop - bench.start)) + +# print tree +print -v base + +exit 0 +# EOF. |