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