xref: /titanic_51/usr/src/lib/libshell/common/scripts/shcalc.sh (revision 3e14f97f673e8a630f076077de35afdd43dc1587)
17c2fbfb3SApril Chin#!/usr/bin/ksh93
27c2fbfb3SApril Chin
37c2fbfb3SApril Chin#
47c2fbfb3SApril Chin# CDDL HEADER START
57c2fbfb3SApril Chin#
67c2fbfb3SApril Chin# The contents of this file are subject to the terms of the
77c2fbfb3SApril Chin# Common Development and Distribution License (the "License").
87c2fbfb3SApril Chin# You may not use this file except in compliance with the License.
97c2fbfb3SApril Chin#
107c2fbfb3SApril Chin# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
117c2fbfb3SApril Chin# or http://www.opensolaris.org/os/licensing.
127c2fbfb3SApril Chin# See the License for the specific language governing permissions
137c2fbfb3SApril Chin# and limitations under the License.
147c2fbfb3SApril Chin#
157c2fbfb3SApril Chin# When distributing Covered Code, include this CDDL HEADER in each
167c2fbfb3SApril Chin# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
177c2fbfb3SApril Chin# If applicable, add the following below this CDDL HEADER, with the
187c2fbfb3SApril Chin# fields enclosed by brackets "[]" replaced with your own identifying
197c2fbfb3SApril Chin# information: Portions Copyright [yyyy] [name of copyright owner]
207c2fbfb3SApril Chin#
217c2fbfb3SApril Chin# CDDL HEADER END
227c2fbfb3SApril Chin#
237c2fbfb3SApril Chin
247c2fbfb3SApril Chin#
25*3e14f97fSRoger A. Faulkner# Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
267c2fbfb3SApril Chin#
277c2fbfb3SApril Chin
287c2fbfb3SApril Chin#
297c2fbfb3SApril Chin# shcalc - small shell-based calculator
307c2fbfb3SApril Chin#
317c2fbfb3SApril Chin
327c2fbfb3SApril Chin# Solaris needs /usr/xpg6/bin:/usr/xpg4/bin because the tools in /usr/bin are not POSIX-conformant
337c2fbfb3SApril Chinexport PATH=/usr/xpg6/bin:/usr/xpg4/bin:/bin:/usr/bin
347c2fbfb3SApril Chin
357c2fbfb3SApril Chin# Make sure all math stuff runs in the "C" locale to avoid problems
367c2fbfb3SApril Chin# with alternative # radix point representations (e.g. ',' instead of
377c2fbfb3SApril Chin# '.' in de_DE.*-locales). This needs to be set _before_ any
387c2fbfb3SApril Chin# floating-point constants are defined in this script).
397c2fbfb3SApril Chinif [[ "${LC_ALL}" != "" ]] ; then
407c2fbfb3SApril Chin    export \
417c2fbfb3SApril Chin        LC_MONETARY="${LC_ALL}" \
427c2fbfb3SApril Chin        LC_MESSAGES="${LC_ALL}" \
437c2fbfb3SApril Chin        LC_COLLATE="${LC_ALL}" \
447c2fbfb3SApril Chin        LC_CTYPE="${LC_ALL}"
457c2fbfb3SApril Chin        unset LC_ALL
467c2fbfb3SApril Chinfi
477c2fbfb3SApril Chinexport LC_NUMERIC=C
487c2fbfb3SApril Chin
497c2fbfb3SApril Chinfunction fatal_error
507c2fbfb3SApril Chin{
517c2fbfb3SApril Chin	print -u2 "${progname}: $*"
527c2fbfb3SApril Chin	exit 1
537c2fbfb3SApril Chin}
547c2fbfb3SApril Chin
557c2fbfb3SApril Chinfunction do_calculate
567c2fbfb3SApril Chin{
577c2fbfb3SApril Chin	typeset calcline="$1"
587c2fbfb3SApril Chin	float x=0.0
597c2fbfb3SApril Chin
607c2fbfb3SApril Chin	printf "(( x=( %s ) ))\n" "${calcline}" | source /dev/stdin
617c2fbfb3SApril Chin	if (( $? != 0 )) ; then
627c2fbfb3SApril Chin		print -f $"%s: Syntax error in %s\n" "${progname}" "${calcline}"
637c2fbfb3SApril Chin		return 1
647c2fbfb3SApril Chin	fi
657c2fbfb3SApril Chin
667c2fbfb3SApril Chin	printf "%s == %.40g\n" "${calcline}" x
677c2fbfb3SApril Chin
687c2fbfb3SApril Chin	return 0
697c2fbfb3SApril Chin}
707c2fbfb3SApril Chin
717c2fbfb3SApril Chinfunction usage
727c2fbfb3SApril Chin{
737c2fbfb3SApril Chin	OPTIND=0
747c2fbfb3SApril Chin	getopts -a "${progname}" "${shcalc_usage}" OPT '-?'
757c2fbfb3SApril Chin	exit 2
767c2fbfb3SApril Chin}
777c2fbfb3SApril Chin
787c2fbfb3SApril Chin# program start
797c2fbfb3SApril Chin# (be carefull with builtins here - they are unconditionally available
807c2fbfb3SApril Chin# in the shell's "restricted" mode)
817c2fbfb3SApril Chinbuiltin basename
827c2fbfb3SApril Chinbuiltin sum
837c2fbfb3SApril Chin
847c2fbfb3SApril Chintypeset progname="${ basename "${0}" ; }"
857c2fbfb3SApril Chin
867c2fbfb3SApril Chintypeset -r shcalc_usage=$'+
877c2fbfb3SApril Chin[-?\n@(#)\$Id: shcalc (Roland Mainz) 2008-11-03 \$\n]
887c2fbfb3SApril Chin[-author?Roland Mainz <roland.mainz@nrubsig.org>]
897c2fbfb3SApril Chin[+NAME?shcalc - simple shell calculator]
907c2fbfb3SApril Chin[+DESCRIPTION?\bsshcalc\b is a small calculator application which
917c2fbfb3SApril Chin	prints the results of ISO C99 math expressions read from either
927c2fbfb3SApril Chin	arguments or stdin if no arguments are given.]
937c2fbfb3SApril Chin[+SEE ALSO?\bksh93\b(1),\bceil\b(3M), \bcopysign\b(3M), \bcos\b(3M),
947c2fbfb3SApril Chin	\bcosh\b(3M), \berf\b(3M), \berfc\b(3M), \bexp\b(3M),
957c2fbfb3SApril Chin	\bexp2\b(3M), \bexpm1\b(3M), \bfabs abs\b(3M), \bfdim\b(3M),
967c2fbfb3SApril Chin	\bfinite\b(3M), \bfloor int\b(3M), \bfma\b(3M), \bfmax\b(3M), \bfmin\b(3M),
977c2fbfb3SApril Chin	\bfmod\b(3M), \bfpclassify\b(3M), \bhypot\b(3M), \bilogb\b(3M),
987c2fbfb3SApril Chin	\bisfinite\b(3M), \bisgreater\b(3M), \bisgreaterequal\b(3M), \bisinf\b(3M),
997c2fbfb3SApril Chin	\bisless\b(3M), \bislessequal\b(3M), \bislessgreater\b(3M), \bisnan\b(3M),
1007c2fbfb3SApril Chin	\bisnormal\b(3M), \bissubnormal\b(3M), \bisunordered\b(3M), \biszero\b(3M),
1017c2fbfb3SApril Chin	\blgamma\b(3M), \blog\b(3M), \blog1p\b(3M), \blog2\b(3M),
1027c2fbfb3SApril Chin	\blogb\b(3M), \bnearbyint\b(3M), \bnextafter\b(3M), \bnexttoward\b(3M),
1037c2fbfb3SApril Chin	\bpow\b(3M), \bremainder\b(3M), \brint\b(3M), \bround\b(3M),
1047c2fbfb3SApril Chin	\bscalb\b(3M), \bscalbn\b(3M), \bsignbit\b(3M), \bsin\b(3M),
1057c2fbfb3SApril Chin	\bsinh\b(3M), \bsqrt\b(3M), \btan\b(3M), \btanh\b(3M),
1067c2fbfb3SApril Chin	\btgamma\b(3M), \btrunc\b(3M)]
1077c2fbfb3SApril Chin'
1087c2fbfb3SApril Chinwhile getopts -a "${progname}" "${shcalc_usage}" OPT ; do
1097c2fbfb3SApril Chin#	printmsg "## OPT=|${OPT}|, OPTARG=|${OPTARG}|"
1107c2fbfb3SApril Chin	case ${OPT} in
1117c2fbfb3SApril Chin		*)	usage ;;
1127c2fbfb3SApril Chin	esac
1137c2fbfb3SApril Chindone
1147c2fbfb3SApril Chinshift $((OPTIND-1))
1157c2fbfb3SApril Chin
1167c2fbfb3SApril Chininteger res
1177c2fbfb3SApril Chin
1187c2fbfb3SApril Chinif (( $# == 0 )) ; then
1197c2fbfb3SApril Chin	# No arguments ? Switch to interactive mode...
1207c2fbfb3SApril Chin
1217c2fbfb3SApril Chin	# make sure "read" below uses "gmacs"-like editor keys and "multiline" mode
1227c2fbfb3SApril Chin
1237c2fbfb3SApril Chin	set -o gmacs
1247c2fbfb3SApril Chin	set -o multiline
1257c2fbfb3SApril Chin
1267c2fbfb3SApril Chin	while read "calcline?calc> " ; do
1277c2fbfb3SApril Chin		# quit ?
1287c2fbfb3SApril Chin		[[ "${calcline}" == ~(Elri)(exit|quit|eof) ]] && break
1297c2fbfb3SApril Chin
1307c2fbfb3SApril Chin		# empty line ?
1317c2fbfb3SApril Chin		[[ "${calcline}" == ~(Elri)([[:space:]]*) ]] && continue
1327c2fbfb3SApril Chin
1337c2fbfb3SApril Chin		do_calculate "$calcline"
1347c2fbfb3SApril Chin		(( res=$? ))
1357c2fbfb3SApril Chin	done
1367c2fbfb3SApril Chin
1377c2fbfb3SApril Chin	exit ${res}
1387c2fbfb3SApril Chinelse
1397c2fbfb3SApril Chin	while (( $# > 0 )) ; do
1407c2fbfb3SApril Chin		do_calculate "$1"
1417c2fbfb3SApril Chin		(( res=$? ))
1427c2fbfb3SApril Chin		shift
1437c2fbfb3SApril Chin	done
1447c2fbfb3SApril Chin
1457c2fbfb3SApril Chin	exit ${res}
1467c2fbfb3SApril Chinfi
1477c2fbfb3SApril Chin
1487c2fbfb3SApril Chin# not reached
1497c2fbfb3SApril Chin
1507c2fbfb3SApril Chin# EOF.
151