--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/openenvutils/commandshell/shell/src/modules/mathfunc.c Tue Feb 02 10:12:00 2010 +0200
@@ -0,0 +1,591 @@
+// mathfunc.c - basic mathematical functions for use in math evaluations
+//
+// © Portions Copyright (c) Symbian Software Ltd 2007. All rights reserved.
+//
+/*
+ * This file is part of zsh, the Z shell.
+ *
+ * Copyright (c) 1999 Peter Stephenson
+ * All rights reserved.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and to distribute modified versions of this software for any
+ * purpose, provided that the above copyright notice and the following
+ * two paragraphs appear in all copies of this software.
+ *
+ * In no event shall Peter Stephenson or the Zsh Development Group be liable
+ * to any party for direct, indirect, special, incidental, or consequential
+ * damages arising out of the use of this software and its documentation,
+ * even if Peter Stephenson and the Zsh Development Group have been advised of
+ * the possibility of such damage.
+ *
+ * Peter Stephenson and the Zsh Development Group specifically disclaim any
+ * warranties, including, but not limited to, the implied warranties of
+ * merchantability and fitness for a particular purpose. The software
+ * provided hereunder is on an "as is" basis, and Peter Stephenson and the
+ * Zsh Development Group have no obligation to provide maintenance,
+ * support, updates, enhancements, or modifications.
+ *
+ */
+#include "mathfunc.mdh"
+#include "mathfunc.pro"
+
+#include <math.h>
+
+#ifdef __SYMBIAN32__
+#ifdef __WINSCW__
+#pragma warn_unusedarg off
+#endif//__WINSCW__
+#endif//__SYMBIAN32__
+
+enum {
+MF_ABS,
+MF_ACOS,
+MF_ACOSH,
+MF_ASIN,
+MF_ASINH,
+MF_ATAN,
+MF_ATANH,
+MF_CBRT,
+MF_CEIL,
+MF_COPYSIGN,
+MF_COS,
+MF_COSH,
+MF_ERF,
+MF_ERFC,
+MF_EXP,
+MF_EXPM1,
+MF_FABS,
+MF_FLOAT,
+MF_FLOOR,
+MF_FMOD,
+MF_GAMMA,
+MF_HYPOT,
+MF_ILOGB,
+MF_INT,
+MF_J0,
+MF_J1,
+MF_JN,
+MF_LDEXP,
+MF_LGAMMA,
+MF_LOG,
+MF_LOG10,
+MF_LOG1P,
+MF_LOGB,
+MF_NEXTAFTER,
+MF_RINT,
+MF_SCALB,
+#ifdef HAVE_SIGNGAM
+MF_SIGNGAM,
+#endif
+MF_SIN,
+MF_SINH,
+MF_SQRT,
+MF_TAN,
+MF_TANH,
+MF_Y0,
+MF_Y1,
+MF_YN
+};
+
+/* also functions taking a string argument */
+
+enum {
+MS_RAND48
+};
+
+/*
+ * also to do, but differently argument or returned: abs (no type
+ * conversion), atan2.
+ */
+
+/* Flags for bounds. Note these must start at 1, not 0. */
+
+enum {
+ BF_POS = 1, /* must be positive */
+ BF_NONNEG = 2, /* must be non-negative */
+ BF_FRAC = 3, /* must be -1 <= x <= 1 */
+ BF_GE1 = 4, /* must be >= 1 */
+ BF_FRACO = 5, /* must be in open range -1 < x < 1 */
+ BF_INTPOS = 6, /* must be non-integer or positive */
+ BF_GTRM1 = 7, /* must be > -1 */
+ BF_NONZ = 8, /* must be nonzero */
+ BF_POS2 = 9 /* second argument must be positive */
+};
+
+#define BFLAG(x) ((x) << 8)
+
+/*
+ * Flags for type of function: unlike the above, these must
+ * be individually bit-testable.
+ */
+
+enum {
+ TF_NOCONV = 1, /* don't convert to float */
+ TF_INT1 = 2, /* first argument is integer */
+ TF_INT2 = 4, /* second argument is integer */
+ TF_NOASS = 8 /* don't assign result as double */
+};
+
+#define TFLAG(x) ((x) << 16)
+
+
+static struct mathfunc mftab[] = {
+ /* Functions taking string arguments */
+#ifdef HAVE_ERAND48
+ /* here to avoid comma hassle */
+ STRMATHFUNC("rand48", math_string, MS_RAND48),
+#endif
+
+ NUMMATHFUNC("abs", math_func, 1, 1, MF_ABS | BFLAG(BF_FRAC) |
+ TFLAG(TF_NOCONV|TF_NOASS)),
+ NUMMATHFUNC("acos", math_func, 1, 1, MF_ACOS | BFLAG(BF_FRAC)),
+ NUMMATHFUNC("acosh", math_func, 1, 1, MF_ACOSH | BFLAG(BF_GE1)),
+ NUMMATHFUNC("asin", math_func, 1, 1, MF_ASIN | BFLAG(BF_FRAC)),
+ NUMMATHFUNC("asinh", math_func, 1, 1, MF_ASINH),
+ NUMMATHFUNC("atan", math_func, 1, 2, MF_ATAN),
+ NUMMATHFUNC("atanh", math_func, 1, 1, MF_ATANH | BFLAG(BF_FRACO)),
+ NUMMATHFUNC("cbrt", math_func, 1, 1, MF_CBRT),
+ NUMMATHFUNC("ceil", math_func, 1, 1, MF_CEIL),
+ NUMMATHFUNC("copysign", math_func, 2, 2, MF_COPYSIGN),
+ NUMMATHFUNC("cos", math_func, 1, 1, MF_COS),
+ NUMMATHFUNC("cosh", math_func, 1, 1, MF_COSH),
+ NUMMATHFUNC("erf", math_func, 1, 1, MF_ERF),
+ NUMMATHFUNC("erfc", math_func, 1, 1, MF_ERFC),
+ NUMMATHFUNC("exp", math_func, 1, 1, MF_EXP),
+ NUMMATHFUNC("expm1", math_func, 1, 1, MF_EXPM1),
+ NUMMATHFUNC("fabs", math_func, 1, 1, MF_FABS),
+ NUMMATHFUNC("float", math_func, 1, 1, MF_FLOAT),
+ NUMMATHFUNC("floor", math_func, 1, 1, MF_FLOOR),
+ NUMMATHFUNC("fmod", math_func, 2, 2, MF_FMOD),
+ NUMMATHFUNC("gamma", math_func, 1, 1, MF_GAMMA | BFLAG(BF_INTPOS)),
+ NUMMATHFUNC("hypot", math_func, 2, 2, MF_HYPOT),
+ NUMMATHFUNC("ilogb", math_func, 1, 1, MF_ILOGB | BFLAG(BF_NONZ) |
+ TFLAG(TF_NOASS)),
+ NUMMATHFUNC("int", math_func, 1, 1, MF_INT | TFLAG(TF_NOASS)),
+ NUMMATHFUNC("j0", math_func, 1, 1, MF_J0),
+ NUMMATHFUNC("j1", math_func, 1, 1, MF_J1),
+ NUMMATHFUNC("jn", math_func, 2, 2, MF_JN | TFLAG(TF_INT1)),
+ NUMMATHFUNC("ldexp", math_func, 2, 2, MF_LDEXP | TFLAG(TF_INT2)),
+ NUMMATHFUNC("lgamma", math_func, 1, 1, MF_LGAMMA | BFLAG(BF_INTPOS)),
+ NUMMATHFUNC("log", math_func, 1, 1, MF_LOG | BFLAG(BF_POS)),
+ NUMMATHFUNC("log10", math_func, 1, 1, MF_LOG10 | BFLAG(BF_POS)),
+ NUMMATHFUNC("log1p", math_func, 1, 1, MF_LOG1P | BFLAG(BF_GTRM1)),
+ NUMMATHFUNC("logb", math_func, 1, 1, MF_LOGB | BFLAG(BF_NONZ)),
+ NUMMATHFUNC("nextafter", math_func, 2, 2, MF_NEXTAFTER),
+ NUMMATHFUNC("rint", math_func, 1, 1, MF_RINT),
+ NUMMATHFUNC("scalb", math_func, 2, 2, MF_SCALB | TFLAG(TF_INT2)),
+#ifdef HAVE_SIGNGAM
+ NUMMATHFUNC("signgam", math_func, 0, 0, MF_SIGNGAM | TFLAG(TF_NOASS)),
+#endif
+ NUMMATHFUNC("sin", math_func, 1, 1, MF_SIN),
+ NUMMATHFUNC("sinh", math_func, 1, 1, MF_SINH),
+ NUMMATHFUNC("sqrt", math_func, 1, 1, MF_SQRT | BFLAG(BF_NONNEG)),
+ NUMMATHFUNC("tan", math_func, 1, 1, MF_TAN),
+ NUMMATHFUNC("tanh", math_func, 1, 1, MF_TANH),
+ NUMMATHFUNC("y0", math_func, 1, 1, MF_Y0 | BFLAG(BF_POS)),
+ NUMMATHFUNC("y1", math_func, 1, 1, MF_Y1 | BFLAG(BF_POS)),
+ NUMMATHFUNC("yn", math_func, 2, 2, MF_YN | BFLAG(BF_POS2) | TFLAG(TF_INT1))
+};
+
+/**/
+static mnumber
+math_func(char *name, int argc, mnumber *argv, int id)
+{
+ mnumber ret;
+
+ double argd = 0, argd2 = 0, retd = 0;
+ int argi = 0;
+
+ if (argc && !(id & TFLAG(TF_NOCONV))) {
+ if (id & TFLAG(TF_INT1))
+ argi = (argv->type == MN_FLOAT) ? (zlong)argv->u.d : argv->u.l;
+ else
+ argd = (argv->type == MN_INTEGER) ? (double)argv->u.l : argv->u.d;
+ if (argc > 1) {
+ if (id & TFLAG(TF_INT2))
+ argi = (argv[1].type == MN_FLOAT) ? (zlong)argv[1].u.d :
+ argv[1].u.l;
+ else
+ argd2 = (argv[1].type == MN_INTEGER) ? (double)argv[1].u.l :
+ argv[1].u.d;
+ }
+ }
+
+ ret.type = MN_FLOAT;
+ ret.u.d = 0;
+
+ if (errflag)
+ return ret;
+
+ if (id & 0xff00) {
+ int rtst = 0;
+
+ switch ((id >> 8) & 0xff) {
+ case BF_POS:
+ rtst = (argd <= 0.0);
+ break;
+
+ case BF_NONNEG:
+ rtst = (argd < 0.0);
+ break;
+
+ case BF_FRAC:
+ rtst = (fabs(argd) > 1.0);
+ break;
+
+ case BF_GE1:
+ rtst = (argd < 1.0);
+ break;
+
+ case BF_FRACO:
+ rtst = (fabs(argd) >= 1.0);
+ break;
+
+ case BF_INTPOS:
+ rtst = (argd <= 0 && (double)(zlong)argd == argd);
+ break;
+
+ case BF_GTRM1:
+ rtst = (argd <= -1);
+ break;
+
+ case BF_POS2:
+ rtst = (argd2 <= 0.0);
+ break;
+ }
+
+ if (rtst) {
+ zerr("math: argument to %s out of range", name, 0);
+ return ret;
+ }
+ }
+
+ switch (id & 0xff) {
+ case MF_ABS:
+ ret.type = argv->type;
+ if (argv->type == MN_INTEGER)
+ ret.u.l = (argv->u.l < 0) ? - argv->u.l : argv->u.l;
+ else
+ ret.u.d = fabs(argv->u.d);
+ break;
+
+ case MF_ACOS:
+ retd = acos(argd);
+ break;
+
+ case MF_ACOSH:
+ retd = acosh(argd);
+ break;
+
+ case MF_ASIN:
+ retd = asin(argd);
+ break;
+
+ case MF_ASINH:
+ retd = asinh(argd);
+ break;
+
+ case MF_ATAN:
+ if (argc == 2)
+ retd = atan2(argd, argd2);
+ else
+ retd = atan(argd);
+ break;
+
+ case MF_ATANH:
+ retd = atanh(argd);
+ break;
+
+ case MF_CBRT:
+ retd = cbrt(argd);
+ break;
+
+ case MF_CEIL:
+ retd = ceil(argd);
+ break;
+
+ case MF_COPYSIGN:
+ retd = copysign(argd, argd2);
+ break;
+
+ case MF_COS:
+ retd = cos(argd);
+ break;
+
+ case MF_COSH:
+ retd = cosh(argd);
+ break;
+
+ case MF_ERF:
+ retd = erf(argd);
+ break;
+
+ case MF_ERFC:
+ retd = erfc(argd);
+ break;
+
+ case MF_EXP:
+ retd = exp(argd);
+ break;
+
+ case MF_EXPM1:
+ retd = expm1(argd);
+ break;
+
+ case MF_FABS:
+ retd = fabs(argd);
+ break;
+
+ case MF_FLOAT:
+ retd = argd;
+ break;
+
+ case MF_FLOOR:
+ retd = floor(argd);
+ break;
+
+ case MF_FMOD:
+ retd = fmod(argd, argd2);
+ break;
+
+ case MF_GAMMA:
+ retd = gamma(argd);
+ break;
+
+ case MF_HYPOT:
+ retd = hypot(argd, argd2);
+ break;
+
+ case MF_ILOGB:
+ ret.type = MN_INTEGER;
+ ret.u.l = ilogb(argd);
+ break;
+
+ case MF_INT:
+ ret.type = MN_INTEGER;
+ ret.u.l = (zlong)argd;
+ break;
+
+ case MF_J0:
+ retd = j0(argd);
+ break;
+
+ case MF_J1:
+ retd = j1(argd);
+ break;
+
+ case MF_JN:
+ retd = jn(argi, argd2);
+ break;
+
+ case MF_LDEXP:
+ retd = ldexp(argd, argi);
+ break;
+
+ case MF_LGAMMA:
+ retd = lgamma(argd);
+ break;
+
+ case MF_LOG:
+ retd = log(argd);
+ break;
+
+ case MF_LOG10:
+ retd = log10(argd);
+ break;
+
+ case MF_LOG1P:
+ retd = log1p(argd);
+ break;
+
+ case MF_LOGB:
+ retd = logb(argd);
+ break;
+
+ case MF_NEXTAFTER:
+ retd = nextafter(argd, argd2);
+ break;
+
+ case MF_RINT:
+ retd = rint(argd);
+ break;
+
+ case MF_SCALB:
+ retd = scalb(argd, argi);
+ break;
+
+#ifdef HAVE_SIGNGAM
+ case MF_SIGNGAM:
+ ret.type = MN_INTEGER;
+ ret.u.l = signgam;
+ break;
+#endif
+
+ case MF_SIN:
+ retd = sin(argd);
+ break;
+
+ case MF_SINH:
+ retd = sinh(argd);
+ break;
+
+ case MF_SQRT:
+ retd = sqrt(argd);
+ break;
+
+ case MF_TAN:
+ retd = tan(argd);
+ break;
+
+ case MF_TANH:
+ retd = tanh(argd);
+ break;
+
+ case MF_Y0:
+ retd = y0(argd);
+ break;
+
+ case MF_Y1:
+ retd = y1(argd);
+ break;
+
+ case MF_YN:
+ retd = yn(argi, argd2);
+ break;
+
+#ifdef DEBUG
+ default:
+ fprintf(stderr, "BUG: mathfunc type not handled: %d", id);
+ break;
+#endif
+ }
+
+ if (!(id & TFLAG(TF_NOASS)))
+ ret.u.d = retd;
+ return ret;
+}
+
+/**/
+static mnumber
+math_string(UNUSED(char *name), char *arg, int id)
+{
+ mnumber ret = zero_mnumber;
+ char *send;
+ /*
+ * Post-process the string argument, which is just passed verbatim.
+ * Not clear if any other functions that use math_string() will
+ * want this, but assume so for now.
+ */
+ while (iblank(*arg))
+ arg++;
+ send = arg + strlen(arg);
+ while (send > arg && iblank(send[-1]))
+ send--;
+ *send = '\0';
+
+ switch (id)
+ {
+#ifdef HAVE_ERAND48
+ case MS_RAND48:
+ {
+ static unsigned short seedbuf[3];
+ static int seedbuf_init;
+ unsigned short tmp_seedbuf[3], *seedbufptr;
+ int do_init = 1;
+
+ if (*arg) {
+ /* Seed is contained in parameter named by arg */
+ char *seedstr;
+ seedbufptr = tmp_seedbuf;
+ if ((seedstr = getsparam(arg)) && strlen(seedstr) >= 12) {
+ int i, j;
+ do_init = 0;
+ /*
+ * Decode three sets of four hex digits corresponding
+ * to each unsigned short.
+ */
+ for (i = 0; i < 3 && !do_init; i++) {
+ unsigned short *seedptr = seedbufptr + i;
+ *seedptr = 0;
+ for (j = 0; j < 4; j++) {
+ if (*seedstr >= '0' && *seedstr <= '9')
+ *seedptr += *seedstr - '0';
+ else if (tolower(*seedstr) >= 'a' &&
+ tolower(*seedstr) <= 'f')
+ *seedptr += tolower(*seedstr) - 'a' + 10;
+ else {
+ do_init = 1;
+ break;
+ }
+ seedstr++;
+ if (j < 3)
+ *seedptr *= 16;
+ }
+ }
+ }
+ else if (errflag)
+ break;
+ }
+ else
+ {
+ /* Use default seed: must be initialised. */
+ seedbufptr = seedbuf;
+ if (!seedbuf_init)
+ seedbuf_init = 1;
+ else
+ do_init = 1;
+ }
+ if (do_init) {
+ seedbufptr[0] = (unsigned short)rand();
+ seedbufptr[1] = (unsigned short)rand();
+ seedbufptr[2] = (unsigned short)rand();
+ }
+ ret.type = MN_FLOAT;
+ ret.u.d = 0;//erand48(seedbufptr); //KARTHIK
+
+ if (*arg)
+ {
+ char outbuf[13];
+ sprintf(outbuf, "%04x%04x%04x", (int)seedbufptr[0],
+ (int)seedbufptr[1], (int)seedbufptr[2]);
+ setsparam(arg, ztrdup(outbuf));
+ }
+ }
+ break;
+#endif
+ }
+
+ return ret;
+}
+
+
+/**/
+int
+setup_(UNUSED(Module m))
+{
+ return 0;
+}
+
+/**/
+int
+boot_(Module m)
+{
+ return !addmathfuncs(m->nam, mftab, sizeof(mftab)/sizeof(*mftab));
+}
+
+/**/
+int
+cleanup_(Module m)
+{
+ deletemathfuncs(m->nam, mftab, sizeof(mftab)/sizeof(*mftab));
+ return 0;
+}
+
+/**/
+int
+finish_(UNUSED(Module m))
+{
+ return 0;
+}