Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

PATCH: 3.1.6-pws-5: mathfunc module



This is a collection of functions for math evaluations as a module,
mathfunc.  Broadly they are taken out of the standard math library, though
I added int and float, which just perform casts as functions, and abs,
which takes the absolute value of its argument but doesn't change the
type.  I can add simple ad hoc functions on request (e.g. isint and isfloat
aren't included but might be useful).

The only hard part was choosing what to include.

- This is a separate module for the express purpose of providing math
  functions, so there didn't seem to be any point in arbitrarily leaving
  things out.  I have doubts over whether many people will use Bessel
  functions of the second kind at arbitrary order, but you never know.
  We don't have a namespace pollution problem here --- functions
  and parameters are distinct.
- Hard cases, such as functions with pointers --- i.e. effectively
  those with two return values --- are omitted.
- Also, IEEE floating point test thingummybobs like finite() and so on
  aren't included.
- I compared between AIX 3.2 and HPUX 10.20 and threw out anything which
  wasn't on the second.  If other things not in people's math libraries
  turn up, then (a) if they're obscure, they can go (up to the next
  release) (b) if they seem marginally useful they can have a configure
  test.
- I have not rewritten the manual pages for the standard mathematical
  functions, just referred to them.

As with division by zero, domain errors are supposed to be caught by the
shell, so that in principle you should never get NaNs and infinities,
except possibly for floating point arithmetic overflow.

One other change was parsing of function arguments, which should now be
completely compatible with the rest of math evaluation (assuming valid
syntax).

It's not linked in by default, but there is an argument for that.
Autoloading isn't going to be a lot of use unless we define a zmodload
option to mean `load this if you find any unknown math functions'.

--- Doc/Makefile.in.mf	Wed Sep  8 09:48:59 1999
+++ Doc/Makefile.in	Wed Sep 22 14:19:00 1999
@@ -59,7 +59,7 @@
 Zsh/modules.yo Zsh/mod_cap.yo \
 Zsh/mod_clone.yo Zsh/mod_comp1.yo Zsh/mod_compctl.yo Zsh/mod_complist.yo \
 Zsh/mod_deltochar.yo Zsh/mod_example.yo Zsh/mod_files.yo \
-Zsh/mod_mapfile.yo Zsh/mod_parameter.yo Zsh/mod_sched.yo \
+Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo Zsh/mod_parameter.yo Zsh/mod_sched.yo \
 Zsh/mod_stat.yo Zsh/mod_zftp.yo Zsh/mod_zle.yo Zsh/options.yo \
 Zsh/params.yo Zsh/prompt.yo Zsh/redirect.yo Zsh/restricted.yo \
 Zsh/seealso.yo Zsh/zftpsys.yo Zsh/zle.yo
@@ -135,8 +135,8 @@
 zshmodules.1: Zsh/modules.yo Zsh/mod_cap.yo Zsh/mod_clone.yo \
               Zsh/mod_comp1.yo Zsh/mod_complist.yo Zsh/mod_compctl.yo \
               Zsh/mod_deltochar.yo Zsh/mod_example.yo Zsh/mod_files.yo \
-              Zsh/mod_mapfile.yo Zsh/mod_sched.yo Zsh/mod_stat.yo \
-              Zsh/mod_zftp.yo Zsh/mod_zle.yo
+              Zsh/mod_mapfile.yo Zsh/mod_mathfunc.yo Zsh/mod_sched.yo \
+              Zsh/mod_stat.yo Zsh/mod_zftp.yo Zsh/mod_zle.yo
 
 zshoptions.1: Zsh/options.yo
 
--- Doc/Zsh/guide.yo.mf	Wed Jun 16 17:27:00 1999
+++ Doc/Zsh/guide.yo	Wed Sep 22 14:24:40 1999
@@ -119,9 +119,13 @@
 menu(The clone Module)
 menu(The comp1 Module)
 menu(The compctl Module)
+menu(The complist Module)
 menu(The deltochar Module)
 menu(The example Module)
 menu(The files Module)
+menu(The mapfile Module)
+menu(The mathfunc Module)
+menu(The parameter Module)
 menu(The sched Module)
 menu(The stat Module)
 menu(The zftp Module)
--- Doc/Zsh/mod_mapfile.yo.mf	Mon Jun 14 09:12:39 1999
+++ Doc/Zsh/mod_mapfile.yo	Wed Sep 22 10:51:52 1999
@@ -1,4 +1,4 @@
-texinode(The mapfile Module)(The parameter Module)(The files Module)(Zsh Modules)
+texinode(The mapfile Module)(The mathfunc Module)(The files Module)(Zsh Modules)
 sect(The mapfile Module)
 cindex(parameter, file access via)
 The tt(mapfile) module provides one special associative array parameter of
--- Doc/Zsh/mod_mathfunc.yo.mf	Wed Sep 22 10:49:28 1999
+++ Doc/Zsh/mod_mathfunc.yo	Wed Sep 22 14:27:44 1999
@@ -0,0 +1,52 @@
+texinode(The mathfunc Module)(The parameter Module)(The mapfile Module)(Zsh Modules)
+sect(The mathfunc Module)
+cindex(functions, mathematical)
+cindex(mathematical functions)
+The tt(mathfunc) module provides standard mathematical functions for use when
+evaluating mathematical formulae.  The syntax agrees with normal C and
+FORTRAN conventions, for example,
+
+example((( f = sin(0.3) )))
+
+assigns the sine of 0.3 to the parameter f.
+
+Most functions take floating point arguments and return a floating point
+value.  However, any necessary conversions from or to integer type will be
+performed automatically by the shell.  Apart from tt(atan) with a second
+argument and the tt(abs), tt(int) and tt(float) functions, all functions
+behave as noted in the manual page for the corresponding C function,
+except that any arguments out of range for the function in question will be
+detected by the shell and an error reported.
+
+The following functions take a single floating point argument: tt(acos),
+tt(acosh), tt(asin), tt(asinh), tt(atan), tt(atanh), tt(cbrt), tt(ceil),
+tt(cos), tt(cosh), tt(erf), tt(erfc), tt(exp), tt(expm1), tt(fabs),
+tt(floor), tt(gamma), tt(j0), tt(j1), tt(lgamma), tt(log), tt(log10),
+tt(log1p), tt(logb), tt(sin), tt(sinh), tt(sqrt), tt(tan), tt(tanh),
+tt(y0), tt(y1).  The tt(atan) function can optionally take a second
+argument, in which case it behaves like the C function tt(atan2).
+The tt(ilogb) function takes a single floating point argument, but
+returns an integer.
+
+The function tt(signgam) takes no arguments, and returns an integer, which
+is the C variable of the same name, as described in manref(gamma)(3).  Note
+that it is therefore only useful immediately after a call to tt(gamma) or
+tt(lgamma).  Note also that `tt(signgam())' and `tt(signgam)' are distinct
+expresssions.
+
+The following functions take two floating point arguments: tt(copysign),
+tt(drem), tt(fmod), tt(hypot), tt(nextafter).
+
+The following take an integer first argument and a floating point second
+argument: tt(jn), tt(yn).
+
+The following take a floating point first argument and an integer second
+argument: tt(ldexp), tt(scalb).
+
+The function tt(abs) does not convert the type of its single argument; it
+returns the absolute value of either a floating point number or an
+integer.  The functions tt(float) and tt(int) convert their arguments into
+a floating point or integer value (by truncation) respectively.
+
+Note that the C tt(pow) function is available in ordinary math evaluation
+as the `tt(**)' operator and is not provided here.
--- Doc/Zsh/modules.yo.mf	Tue Jun 22 10:02:49 1999
+++ Doc/Zsh/modules.yo	Wed Sep 22 10:50:49 1999
@@ -37,6 +37,9 @@
 item(tt(mapfile))(
 Access to external files via a special associative array.
 )
+item(tt(mathfunc))(
+Standard scientific functions for use in mathematical evaluations.
+)
 item(tt(parameter))(
 Access to internal hash tables via special associative arrays.
 )
@@ -63,6 +66,7 @@
 menu(The example Module)
 menu(The files Module)
 menu(The mapfile Module)
+menu(The mathfunc Module)
 menu(The parameter Module)
 menu(The sched Module)
 menu(The stat Module)
@@ -78,6 +82,7 @@
 includefile(Zsh/mod_example.yo)
 includefile(Zsh/mod_files.yo)
 includefile(Zsh/mod_mapfile.yo)
+includefile(Zsh/mod_mathfunc.yo)
 includefile(Zsh/mod_parameter.yo)
 includefile(Zsh/mod_sched.yo)
 includefile(Zsh/mod_stat.yo)
--- Src/Modules/mathfunc.c.mf	Wed Sep 22 10:49:11 1999
+++ Src/Modules/mathfunc.c	Wed Sep 22 13:43:38 1999
@@ -0,0 +1,482 @@
+/*
+ * mathfunc.c - basic mathematical functions for use in math evaluations
+ *
+ * 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>
+
+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_DREM,
+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,
+MF_SIGNGAM,
+MF_SIN,
+MF_SINH,
+MF_SQRT,
+MF_TAN,
+MF_TANH,
+MF_Y0,
+MF_Y1,
+MF_YN,
+};
+
+/*
+ * 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[] = {
+  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("drem", math_func, 2, 2, MF_DREM),
+  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)),
+  NUMMATHFUNC("signgam", math_func, 0, 0, MF_SIGNGAM | TFLAG(TF_NOASS)),
+  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_DREM:
+      retd = drem(argd, argd2);
+      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;
+
+  case MF_SIGNGAM:
+      ret.type = MN_INTEGER;
+      ret.u.l = signgam;
+      break;
+
+  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;
+}
+
+/**/
+int
+setup_mathfunc(Module m)
+{
+    return 0;
+}
+
+/**/
+int
+boot_mathfunc(Module m)
+{
+    return !addmathfuncs(m->nam, mftab, sizeof(mftab)/sizeof(*mftab));
+}
+
+#ifdef MODULE
+
+/**/
+int
+cleanup_mathfunc(Module m)
+{
+    deletemathfuncs(m->nam, mftab, sizeof(mftab)/sizeof(*mftab));
+    return 0;
+}
+
+/**/
+int
+finish_mathfunc(Module m)
+{
+    return 0;
+}
+
+#endif
--- Src/Modules/mathfunc.mdd.mf	Wed Sep 22 10:49:15 1999
+++ Src/Modules/mathfunc.mdd	Tue Sep 21 17:23:26 1999
@@ -0,0 +1,3 @@
+autobins="mathfunc"
+
+objects="mathfunc.o"
--- Src/math.c.mf	Tue Sep 21 14:23:59 1999
+++ Src/math.c	Wed Sep 22 14:10:17 1999
@@ -161,7 +161,7 @@
      0,  16, 0
 };
 
-#define TOPPREC 16
+#define TOPPREC 17
 #define ARGPREC (TOPPREC-1)
 
 static int type[TOKCOUNT] =
@@ -498,31 +498,35 @@
 	    mnumber *argv = NULL, *q;
 	    LinkList l = newlinklist();
 	    LinkNode node;
-	    char *p;
 
-	    if (*a) {
-		for (p = a; *a; a++) {
-		    if (*a == '\\' && a[1])
-			a++;
-		    else if (*a == ',') {
-			*a = '\0';
-			addlinknode(l, p);
-			argc++;
-			p = a + 1;
+	    while (iblank(*a))
+		a++;
+	    while (*a) {
+		if (*a) {
+		    argc++;
+ 		    q = (mnumber *)zhalloc(sizeof(mnumber));
+		    *q = mathevall(a, ARGPREC, &a);
+		    addlinknode(l, q);
+		    if (errflag || mtok != COMMA)
+			break;
+		    a++;
+		}
+	    }
+	    if (*a && !errflag)
+		zerr("bad math expression: illegal character: %c",
+		     NULL, *a);
+	    if (!errflag) {
+		if (argc >= f->minargs && (f->maxargs < 0 ||
+					   argc <= f->maxargs)) {
+		    if (argc) {
+			q = argv = (mnumber *)zhalloc(argc * sizeof(mnumber));
+			for (node = firstnode(l); node; incnode(node))
+			    *q++ = *(mnumber *)getdata(node);
 		    }
-		}
-		addlinknode(l, p);
-		argc++;
+		    return f->nfunc(n, argc, argv, f->funcid);
+		} else
+		    zerr("wrong number of arguments: %s", o, 0);
 	    }
-	    if (argc >= f->minargs && (f->maxargs < 0 || argc <= f->maxargs)) {
-		if (argc) {
-		    q = argv = (mnumber *) zhalloc(argc * sizeof(mnumber));
-		    for (node = firstnode(l); node; incnode(node))
-			*q++ = matheval((char *) getdata(node));
-		}
-		return f->nfunc(n, argc, argv, f->funcid);
-	    } else
-		zerr("wrong number of argument: %s", o, 0);
 	}
     } else
 	zerr("unknown function: %s", n, 0);

-- 
Peter Stephenson <pws@xxxxxxxxxxxxxxxxx>       Tel: +39 050 844536
WWW:  http://www.ifh.de/~pws/
Dipartimento di Fisica, Via Buonarroti 2, 56127 Pisa, Italy



Messages sorted by: Reverse Date, Date, Thread, Author