1#!/usr/bin/ksh93 2 3# 4# CDDL HEADER START 5# 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. 9# 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. 14# 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] 20# 21# CDDL HEADER END 22# 23 24# 25# Copyright 2008 Sun Microsystems, Inc. All rights reserved. 26# Use is subject to license terms. 27# 28 29# 30# shcalc - small shell-based calculator 31# 32 33# Solaris needs /usr/xpg6/bin:/usr/xpg4/bin because the tools in /usr/bin are not POSIX-conformant 34export PATH=/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin 35 36# Make sure all math stuff runs in the "C" locale to avoid problems 37# with alternative # radix point representations (e.g. ',' instead of 38# '.' in de_DE.*-locales). This needs to be set _before_ any 39# floating-point constants are defined in this script). 40if [[ "${LC_ALL}" != "" ]] ; then 41 export \ 42 LC_MONETARY="${LC_ALL}" \ 43 LC_MESSAGES="${LC_ALL}" \ 44 LC_COLLATE="${LC_ALL}" \ 45 LC_CTYPE="${LC_ALL}" 46 unset LC_ALL 47fi 48export LC_NUMERIC=C 49 50function fatal_error 51{ 52 print -u2 "${progname}: $*" 53 exit 1 54} 55 56function do_calculate 57{ 58 typeset calcline="$1" 59 float x=0.0 60 61 printf "(( x=( %s ) ))\n" "${calcline}" | source /dev/stdin 62 if (( $? != 0 )) ; then 63 print -f $"%s: Syntax error in %s\n" "${progname}" "${calcline}" 64 return 1 65 fi 66 67 printf "%s == %.40g\n" "${calcline}" x 68 69 return 0 70} 71 72function usage 73{ 74 OPTIND=0 75 getopts -a "${progname}" "${shcalc_usage}" OPT '-?' 76 exit 2 77} 78 79# program start 80# (be carefull with builtins here - they are unconditionally available 81# in the shell's "restricted" mode) 82builtin basename 83builtin sum 84 85typeset progname="${ basename "${0}" ; }" 86 87typeset -r shcalc_usage=$'+ 88[-?\n@(#)\$Id: shcalc (Roland Mainz) 2008-11-03 \$\n] 89[-author?Roland Mainz <roland.mainz@nrubsig.org>] 90[+NAME?shcalc - simple shell calculator] 91[+DESCRIPTION?\bsshcalc\b is a small calculator application which 92 prints the results of ISO C99 math expressions read from either 93 arguments or stdin if no arguments are given.] 94[+SEE ALSO?\bksh93\b(1),\bceil\b(3M), \bcopysign\b(3M), \bcos\b(3M), 95 \bcosh\b(3M), \berf\b(3M), \berfc\b(3M), \bexp\b(3M), 96 \bexp2\b(3M), \bexpm1\b(3M), \bfabs abs\b(3M), \bfdim\b(3M), 97 \bfinite\b(3M), \bfloor int\b(3M), \bfma\b(3M), \bfmax\b(3M), \bfmin\b(3M), 98 \bfmod\b(3M), \bfpclassify\b(3M), \bhypot\b(3M), \bilogb\b(3M), 99 \bisfinite\b(3M), \bisgreater\b(3M), \bisgreaterequal\b(3M), \bisinf\b(3M), 100 \bisless\b(3M), \bislessequal\b(3M), \bislessgreater\b(3M), \bisnan\b(3M), 101 \bisnormal\b(3M), \bissubnormal\b(3M), \bisunordered\b(3M), \biszero\b(3M), 102 \blgamma\b(3M), \blog\b(3M), \blog1p\b(3M), \blog2\b(3M), 103 \blogb\b(3M), \bnearbyint\b(3M), \bnextafter\b(3M), \bnexttoward\b(3M), 104 \bpow\b(3M), \bremainder\b(3M), \brint\b(3M), \bround\b(3M), 105 \bscalb\b(3M), \bscalbn\b(3M), \bsignbit\b(3M), \bsin\b(3M), 106 \bsinh\b(3M), \bsqrt\b(3M), \btan\b(3M), \btanh\b(3M), 107 \btgamma\b(3M), \btrunc\b(3M)] 108' 109while getopts -a "${progname}" "${shcalc_usage}" OPT ; do 110# printmsg "## OPT=|${OPT}|, OPTARG=|${OPTARG}|" 111 case ${OPT} in 112 *) usage ;; 113 esac 114done 115shift $((OPTIND-1)) 116 117integer res 118 119if (( $# == 0 )) ; then 120 # No arguments ? Switch to interactive mode... 121 122 # make sure "read" below uses "gmacs"-like editor keys and "multiline" mode 123 124 set -o gmacs 125 set -o multiline 126 127 while read "calcline?calc> " ; do 128 # quit ? 129 [[ "${calcline}" == ~(Elri)(exit|quit|eof) ]] && break 130 131 # empty line ? 132 [[ "${calcline}" == ~(Elri)([[:space:]]*) ]] && continue 133 134 do_calculate "$calcline" 135 (( res=$? )) 136 done 137 138 exit ${res} 139else 140 while (( $# > 0 )) ; do 141 do_calculate "$1" 142 (( res=$? )) 143 shift 144 done 145 146 exit ${res} 147fi 148 149# not reached 150 151# EOF. 152