8354 sync regcomp(3C) with upstream (fix make catalog)
[unleashed/tickless.git] / usr / src / lib / libshell / common / scripts / numtree1.sh
blobba7783e91e9be601ed27145c8e13ae8e18038b10
1 #!/usr/bin/ksh93
4 # CDDL HEADER START
6 # The contents of this file are subject to the terms of the
7 # Common Development and Distribution License (the "License").
8 # You may not use this file except in compliance with the License.
10 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
11 # or http://www.opensolaris.org/os/licensing.
12 # See the License for the specific language governing permissions
13 # and limitations under the License.
15 # When distributing Covered Code, include this CDDL HEADER in each
16 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
17 # If applicable, add the following below this CDDL HEADER, with the
18 # fields enclosed by brackets "[]" replaced with your own identifying
19 # information: Portions Copyright [yyyy] [name of copyright owner]
21 # CDDL HEADER END
25 # Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
29 # numtree1 - basic compound variable tree demo+benchmark
32 # Solaris needs /usr/xpg6/bin:/usr/xpg4/bin because the tools in /usr/bin are not POSIX-conformant
33 export PATH=/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin
35 # Make sure all math stuff runs in the "C" locale to avoid problems
36 # with alternative # radix point representations (e.g. ',' instead of
37 # '.' in de_DE.*-locales). This needs to be set _before_ any
38 # floating-point constants are defined in this script).
39 if [[ "${LC_ALL}" != "" ]] ; then
40 export \
41 LC_MONETARY="${LC_ALL}" \
42 LC_MESSAGES="${LC_ALL}" \
43 LC_COLLATE="${LC_ALL}" \
44 LC_CTYPE="${LC_ALL}"
45 unset LC_ALL
47 export LC_NUMERIC=C
49 function fatal_error
51 print -u2 "${progname}: $*"
52 exit 1
55 function add_number_to_tree
57 typeset treename=$1
58 integer num=$2
59 integer i
60 typeset nodepath # full name of compound variable
61 integer -a pe # path elements
62 integer len
63 typeset revnums="$(rev <<<"${num}")"
65 # first built an array containing the names of each path element
66 # (e.g. "135" results in an array containing "( 1 3 5 )")
67 # 10#<number> is used to prevent leading zeros being interpreted
68 # as octals
69 for (( len=${#revnums} , i=$( printf "10#%s\n" "${revnums}" ) ; len > 0 ; len--, i=i/10 )) ; do
70 pe+=( $((i % 10)) )
71 done
73 # walk path described via the "pe" array and build nodes if
74 # there aren't any nodes yet
75 nodepath="${treename}"
76 for (( i=0 ; i < ${#pe[@]} ; i++ )) ; do
77 nameref x="${nodepath}"
79 # [[ -v ]] does not work for arrays because [[ -v ar ]]
80 # is equal to [[ -v ar[0] ]]. In this case we can
81 # use the output of typeset +p x.nodes
82 [[ "${ typeset +p x.nodes ;}" == "" ]] && compound -a x.nodes
84 nodepath+=".nodes[${pe[i]}]"
85 done
87 # insert element (leaf)
88 nameref node="${nodepath}"
89 [[ "${ typeset +p node.elements ;}" == "" ]] && integer -a node.elements
90 node.elements+=( ${num} )
92 # DEBUG only
93 [[ "${!node.elements[*]}" != "" ]] || fatal_error "assertion $LINENO FAILED"
94 [[ "${ typeset +p node.elements ;}" == *-a* ]] || fatal_error "assertion $LINENO FAILED"
95 [[ "${ typeset +p node.elements ;}" == *-i* ]] || fatal_error "assertion $LINENO FAILED"
96 [[ -v node ]] || fatal_error "assertion $LINENO FAILED"
97 [[ -R node ]] || fatal_error "assertion $LINENO FAILED"
98 [[ "${ typeset +p ${!node} ;}" == *-C* ]] || fatal_error "assertion $LINENO FAILED"
99 [[ "${!x.nodes[*]}" != "" ]] || fatal_error "assertion $LINENO FAILED"
100 [[ "${ typeset +p x.nodes ;}" == *-a* ]] || fatal_error "assertion $LINENO FAILED"
101 [[ "${ typeset +p x.nodes ;}" == *-C* ]] || fatal_error "assertion $LINENO FAILED"
103 return 0
107 # floating-point version of "seq"
108 function floatseq
110 float i
111 float arg1=$1
112 float arg2=$2
113 float arg3=$3
115 case $# in
117 for (( i=1. ; i <= arg1 ; i=i+1. )) ; do
118 printf "%a\n" i
119 done
122 for (( i=arg1 ; i <= arg2 ; i=i+1. )) ; do
123 printf "%a\n" i
124 done
127 for (( i=arg1 ; i <= arg3 ; i+=arg2 )) ; do
128 printf "%a\n" i
129 done
132 print -u2 -f "%s: Illegal number of arguments %d\n" "$0" $#
133 return 1
135 esac
137 return 0
141 function usage
143 OPTIND=0
144 getopts -a "${progname}" "${numtree1_usage}" OPT '-?'
145 exit 2
148 # main
149 builtin basename
150 builtin rev
152 set -o noglob
153 set -o errexit
154 set -o nounset
156 compound base
158 compound bench=(
159 float start
160 float stop
163 integer i
165 typeset progname="${ basename "${0}" ; }"
167 typeset -r numtree1_usage=$'+
168 [-?\n@(#)\$Id: numtree1 (Roland Mainz) 2010-03-27 \$\n]
169 [-author?Roland Mainz <roland.mainz@nrubsig.org>]
170 [+NAME?numtree1 - generate sorted variable tree containing numbers]
171 [+DESCRIPTION?\bnumtree1\b is a simple variable tree generator
172 sorts a given set of numbers into a ksh compound variable tree).
173 the application supports two different modes: \'seq\' takes
174 1-3 arguments to specify the set of numbers via seq(1) and
175 \'stdin\' reads the numbers from stdin (one per line)]
177 method [ arguments ]
179 [+SEE ALSO?\bksh93\b(1), \bseq\b(1)]
182 while getopts -a "${progname}" "${numtree1_usage}" OPT ; do
183 # printmsg "## OPT=|${OPT}|, OPTARG=|${OPTARG}|"
184 case ${OPT} in
185 *) usage ;;
186 esac
187 done
188 shift $((OPTIND-1))
190 # prechecks
191 (( $# > 0 )) || usage
193 cmd=$1
194 shift
196 # Read numbers from stdin outside benchmark loop
197 if [[ ${cmd} == 'stdin' ]] ; then
198 stdin_numbers="$( cat /dev/stdin )" || fatal_error "stdin read error"
201 (( bench.start=SECONDS ))
203 case ${cmd} in
204 "seq")
205 for i in ${ floatseq "$@" ; } ; do
206 add_number_to_tree base "${i}"
207 done
209 "stdin")
210 for i in ${stdin_numbers} ; do
211 add_number_to_tree base "${i}"
212 done
214 "demo1")
215 for i in 1 32 33 34 34 38 90 ; do
216 add_number_to_tree base "${i}"
217 done
219 "demo2")
220 for (( i=1000000000 ; i < 1000000000+10 ; i++ )) ; do
221 add_number_to_tree base "$i"
222 done
225 fatal_error "Invalid command ${cmd}."
227 esac
229 (( bench.stop=SECONDS ))
231 print -u2 -f "# time used: %f\n" $((bench.stop - bench.start))
233 # print tree
234 print -v base
236 exit 0
237 # EOF.