7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#!/usr/bin/ksh93
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# CDDL HEADER START
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# The contents of this file are subject to the terms of the
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# Common Development and Distribution License (the "License").
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# You may not use this file except in compliance with the License.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# or http://www.opensolaris.org/os/licensing.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# See the License for the specific language governing permissions
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# and limitations under the License.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# When distributing Covered Code, include this CDDL HEADER in each
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# If applicable, add the following below this CDDL HEADER, with the
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# fields enclosed by brackets "[]" replaced with your own identifying
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# information: Portions Copyright [yyyy] [name of copyright owner]
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# CDDL HEADER END
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# shcalc - small shell-based calculator
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# Solaris needs /usr/xpg6/bin:/usr/xpg4/bin because the tools in /usr/bin are not POSIX-conformant
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinexport PATH=/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# Make sure all math stuff runs in the "C" locale to avoid problems
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# with alternative # radix point representations (e.g. ',' instead of
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# '.' in de_DE.*-locales). This needs to be set _before_ any
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# floating-point constants are defined in this script).
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinif [[ "${LC_ALL}" != "" ]] ; then
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin export \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin LC_MONETARY="${LC_ALL}" \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin LC_MESSAGES="${LC_ALL}" \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin LC_COLLATE="${LC_ALL}" \
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin LC_CTYPE="${LC_ALL}"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unset LC_ALL
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinfi
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinexport LC_NUMERIC=C
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinfunction fatal_error
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin print -u2 "${progname}: $*"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin exit 1
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinfunction do_calculate
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin typeset calcline="$1"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin float x=0.0
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin printf "(( x=( %s ) ))\n" "${calcline}" | source /dev/stdin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if (( $? != 0 )) ; then
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin print -f $"%s: Syntax error in %s\n" "${progname}" "${calcline}"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 1
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fi
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin printf "%s == %.40g\n" "${calcline}" x
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return 0
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinfunction usage
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin OPTIND=0
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin getopts -a "${progname}" "${shcalc_usage}" OPT '-?'
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin exit 2
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# program start
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# (be carefull with builtins here - they are unconditionally available
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# in the shell's "restricted" mode)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinbuiltin basename
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinbuiltin sum
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypeset progname="${ basename "${0}" ; }"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chintypeset -r shcalc_usage=$'+
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[-?\n@(#)\$Id: shcalc (Roland Mainz) 2008-11-03 \$\n]
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[-author?Roland Mainz <roland.mainz@nrubsig.org>]
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[+NAME?shcalc - simple shell calculator]
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[+DESCRIPTION?\bsshcalc\b is a small calculator application which
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin prints the results of ISO C99 math expressions read from either
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin arguments or stdin if no arguments are given.]
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin[+SEE ALSO?\bksh93\b(1),\bceil\b(3M), \bcopysign\b(3M), \bcos\b(3M),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin \bcosh\b(3M), \berf\b(3M), \berfc\b(3M), \bexp\b(3M),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin \bexp2\b(3M), \bexpm1\b(3M), \bfabs abs\b(3M), \bfdim\b(3M),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin \bfinite\b(3M), \bfloor int\b(3M), \bfma\b(3M), \bfmax\b(3M), \bfmin\b(3M),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin \bfmod\b(3M), \bfpclassify\b(3M), \bhypot\b(3M), \bilogb\b(3M),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin \bisfinite\b(3M), \bisgreater\b(3M), \bisgreaterequal\b(3M), \bisinf\b(3M),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin \bisless\b(3M), \bislessequal\b(3M), \bislessgreater\b(3M), \bisnan\b(3M),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin \bisnormal\b(3M), \bissubnormal\b(3M), \bisunordered\b(3M), \biszero\b(3M),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin \blgamma\b(3M), \blog\b(3M), \blog1p\b(3M), \blog2\b(3M),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin \blogb\b(3M), \bnearbyint\b(3M), \bnextafter\b(3M), \bnexttoward\b(3M),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin \bpow\b(3M), \bremainder\b(3M), \brint\b(3M), \bround\b(3M),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin \bscalb\b(3M), \bscalbn\b(3M), \bsignbit\b(3M), \bsin\b(3M),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin \bsinh\b(3M), \bsqrt\b(3M), \btan\b(3M), \btanh\b(3M),
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin \btgamma\b(3M), \btrunc\b(3M)]
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin'
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinwhile getopts -a "${progname}" "${shcalc_usage}" OPT ; do
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# printmsg "## OPT=|${OPT}|, OPTARG=|${OPTARG}|"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case ${OPT} in
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *) usage ;;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin esac
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chindone
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinshift $((OPTIND-1))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chininteger res
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinif (( $# == 0 )) ; then
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin # No arguments ? Switch to interactive mode...
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin # make sure "read" below uses "gmacs"-like editor keys and "multiline" mode
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin set -o gmacs
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin set -o multiline
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while read "calcline?calc> " ; do
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin # quit ?
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin [[ "${calcline}" == ~(Elri)(exit|quit|eof) ]] && break
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin # empty line ?
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin [[ "${calcline}" == ~(Elri)([[:space:]]*) ]] && continue
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do_calculate "$calcline"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (( res=$? ))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin done
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin exit ${res}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinelse
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin while (( $# > 0 )) ; do
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin do_calculate "$1"
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (( res=$? ))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shift
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin done
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin exit ${res}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinfi
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# not reached
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# EOF.