00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "copyright.h"
00010 #include "autoconf.h"
00011 #include "config.h"
00012 #include "externs.h"
00013
00014 #include <float.h>
00015 #include <limits.h>
00016 #include <math.h>
00017
00018 #include "functions.h"
00019 #include "funmath.h"
00020 #include "sha1.h"
00021
00022 #ifdef HAVE_IEEE_FP_FORMAT
00023
00024 static const char *mux_FPStrings[] = { "+Inf", "-Inf", "Ind", "NaN", "0", "0", "0", "0" };
00025
00026 #define MUX_FPGROUP_PASS 0x00 // Pass-through to printf
00027 #define MUX_FPGROUP_ZERO 0x10 // Force to be zero.
00028 #define MUX_FPGROUP_PINF 0x20 // "+Inf"
00029 #define MUX_FPGROUP_NINF 0x30 // "-Inf"
00030 #define MUX_FPGROUP_IND 0x40 // "Ind"
00031 #define MUX_FPGROUP_NAN 0x50 // "NaN"
00032 #define MUX_FPGROUP(x) ((x) & 0xF0)
00033
00034
00035
00036 #define MUX_FPCLASS_PINF (MUX_FPGROUP_PINF|0) // Positive infinity (+INF)
00037 #define MUX_FPCLASS_NINF (MUX_FPGROUP_NINF|1) // Negative infinity (-INF)
00038 #define MUX_FPCLASS_QNAN (MUX_FPGROUP_IND |2) // Quiet NAN (Indefinite)
00039 #define MUX_FPCLASS_SNAN (MUX_FPGROUP_NAN |3) // Signaling NAN
00040 #define MUX_FPCLASS_ND (MUX_FPGROUP_ZERO|4) // Negative denormalized
00041 #define MUX_FPCLASS_NZ (MUX_FPGROUP_ZERO|5) // Negative zero (-0)
00042 #define MUX_FPCLASS_PZ (MUX_FPGROUP_ZERO|6) // Positive zero (+0)
00043 #define MUX_FPCLASS_PD (MUX_FPGROUP_ZERO|7) // Positive denormalized
00044 #define MUX_FPCLASS_PN (MUX_FPGROUP_PASS|8) // Positive normalized non-zero
00045 #define MUX_FPCLASS_NN (MUX_FPGROUP_PASS|9) // Negative normalized non-zero
00046 #define MUX_FPCLASS(x) ((x) & 0x0F)
00047
00048 #ifdef WIN32
00049 #define IEEE_MASK_SIGN 0x8000000000000000ui64
00050 #define IEEE_MASK_EXPONENT 0x7FF0000000000000ui64
00051 #define IEEE_MASK_MANTISSA 0x000FFFFFFFFFFFFFui64
00052 #define IEEE_MASK_QNAN 0x0008000000000000ui64
00053 #else
00054 #define IEEE_MASK_SIGN 0x8000000000000000ull
00055 #define IEEE_MASK_EXPONENT 0x7FF0000000000000ull
00056 #define IEEE_MASK_MANTISSA 0x000FFFFFFFFFFFFFull
00057 #define IEEE_MASK_QNAN 0x0008000000000000ull
00058 #endif
00059
00060 #define ARBITRARY_NUMBER 1
00061 #define IEEE_MAKE_TABLESIZE 5
00062 typedef union
00063 {
00064 INT64 i64;
00065 double d;
00066 } SpecialFloatUnion;
00067
00068
00069
00070
00071
00072
00073 static SpecialFloatUnion SpecialFloatTable[IEEE_MAKE_TABLESIZE] =
00074 {
00075 { 0 },
00076 { IEEE_MASK_EXPONENT | IEEE_MASK_QNAN | ARBITRARY_NUMBER },
00077 { IEEE_MASK_EXPONENT | IEEE_MASK_QNAN | ARBITRARY_NUMBER },
00078 { IEEE_MASK_EXPONENT },
00079 { IEEE_MASK_EXPONENT | IEEE_MASK_SIGN }
00080 };
00081
00082 double MakeSpecialFloat(int iWhich)
00083 {
00084 return SpecialFloatTable[iWhich].d;
00085 }
00086
00087 static int mux_fpclass(double result)
00088 {
00089 union
00090 {
00091 UINT64 i64;
00092 double d;
00093 } u;
00094
00095 u.d = result;
00096
00097 if ((u.i64 & IEEE_MASK_EXPONENT) == 0)
00098 {
00099 if (u.i64 & IEEE_MASK_MANTISSA)
00100 {
00101 if (u.i64 & IEEE_MASK_SIGN) return MUX_FPCLASS_ND;
00102 else return MUX_FPCLASS_PD;
00103 }
00104 else
00105 {
00106 if (u.i64 & IEEE_MASK_SIGN) return MUX_FPCLASS_NZ;
00107 else return MUX_FPCLASS_PZ;
00108 }
00109 }
00110 else if ((u.i64 & IEEE_MASK_EXPONENT) == IEEE_MASK_EXPONENT)
00111 {
00112 if (u.i64 & IEEE_MASK_MANTISSA)
00113 {
00114 if (u.i64 & IEEE_MASK_QNAN) return MUX_FPCLASS_QNAN;
00115 else return MUX_FPCLASS_SNAN;
00116 }
00117 else
00118 {
00119 if (u.i64 & IEEE_MASK_SIGN) return MUX_FPCLASS_NINF;
00120 else return MUX_FPCLASS_PINF;
00121 }
00122 }
00123 else
00124 {
00125 if (u.i64 & IEEE_MASK_SIGN) return MUX_FPCLASS_NN;
00126 else return MUX_FPCLASS_PN;
00127 }
00128 }
00129 #endif // HAVE_IEEE_FP_FORMAT
00130
00131 static double AddWithError(double& err, double a, double b)
00132 {
00133 double sum = a+b;
00134 err = b-(sum-a);
00135 return sum;
00136 }
00137
00138
00139
00140
00141 static double NearestPretty(double R)
00142 {
00143 char *rve = NULL;
00144 int decpt;
00145 int bNegative;
00146 const int mode = 0;
00147
00148 double ulpR = ulp(R);
00149 double R0 = R-ulpR;
00150 double R1 = R+ulpR;
00151
00152
00153
00154 char *p = mux_dtoa(R, mode, 50, &decpt, &bNegative, &rve);
00155 int nDigits = rve - p;
00156
00157
00158
00159 p = mux_dtoa(R0, mode, 50, &decpt, &bNegative, &rve);
00160 if (rve - p < nDigits)
00161 {
00162 nDigits = rve - p;
00163 R = R0;
00164 }
00165
00166
00167
00168 p = mux_dtoa(R1, mode, 50, &decpt, &bNegative, &rve);
00169 if (rve - p < nDigits)
00170 {
00171 nDigits = rve - p;
00172 R = R1;
00173 }
00174 return R;
00175 }
00176
00177
00178
00179 static int DCL_CDECL f_comp_abs(const void *s1, const void *s2)
00180 {
00181 double a = fabs(*(double *)s1);
00182 double b = fabs(*(double *)s2);
00183
00184 if (a > b)
00185 {
00186 return -1;
00187 }
00188 else if (a < b)
00189 {
00190 return 1;
00191 }
00192 return 0;
00193 }
00194
00195
00196
00197
00198
00199
00200 static double AddDoubles(int n, double pd[])
00201 {
00202 qsort(pd, n, sizeof(double), f_comp_abs);
00203 double sum = 0.0;
00204 if (0 < n)
00205 {
00206 sum = pd[0];
00207 double sum_err = 0.0;
00208 int i;
00209 for (i = 1; i < n; i++)
00210 {
00211 double addend_err;
00212 double addend = AddWithError(addend_err, sum_err, pd[i]);
00213 double sum1_err;
00214 double sum1 = AddWithError(sum1_err, sum, addend);
00215 sum = AddWithError(sum_err, sum1, addend_err + sum1_err);
00216 }
00217 }
00218 return NearestPretty(sum);
00219 }
00220
00221
00222
00223
00224 static void fval(char *buff, char **bufc, double result)
00225 {
00226
00227
00228 #ifdef HAVE_IEEE_FP_FORMAT
00229 int fpc = mux_fpclass(result);
00230 if (MUX_FPGROUP(fpc) == MUX_FPGROUP_PASS)
00231 {
00232 #endif // HAVE_IEEE_FP_FORMAT
00233 double rIntegerPart;
00234 double rFractionalPart = modf(result, &rIntegerPart);
00235 if ( 0.0 == rFractionalPart
00236 && LONG_MIN <= rIntegerPart
00237 && rIntegerPart <= LONG_MAX)
00238 {
00239 long i = (long)rIntegerPart;
00240 safe_ltoa(i, buff, bufc);
00241 }
00242 else
00243 {
00244 safe_str(mux_ftoa(result, false, 0), buff, bufc);
00245 }
00246 #ifdef HAVE_IEEE_FP_FORMAT
00247 }
00248 else
00249 {
00250 safe_str(mux_FPStrings[MUX_FPCLASS(fpc)], buff, bufc);
00251 }
00252 #endif // HAVE_IEEE_FP_FORMAT
00253 }
00254
00255 static const long nMaximums[10] =
00256 {
00257 0, 9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999
00258 };
00259
00260 static double g_aDoubles[LBUF_SIZE];
00261 int const g_nDoubles = sizeof(g_aDoubles)/sizeof(double);
00262
00263 FUNCTION(fun_add)
00264 {
00265 UNUSED_PARAMETER(executor);
00266 UNUSED_PARAMETER(caller);
00267 UNUSED_PARAMETER(enactor);
00268 UNUSED_PARAMETER(cargs);
00269 UNUSED_PARAMETER(ncargs);
00270
00271 int nArgs = nfargs;
00272 if (g_nDoubles < nArgs)
00273 {
00274 nArgs = g_nDoubles;
00275 }
00276
00277 int i;
00278 for (i = 0; i < nArgs; i++)
00279 {
00280 int nDigits;
00281 long nMaxValue = 0;
00282 if ( !is_integer(fargs[i], &nDigits)
00283 || nDigits > 9
00284 || (nMaxValue += nMaximums[nDigits]) > 999999999L)
00285 {
00286
00287
00288 for (int j = 0; j < nArgs; j++)
00289 {
00290 g_aDoubles[j] = mux_atof(fargs[j]);
00291 }
00292
00293 fval(buff, bufc, AddDoubles(nArgs, g_aDoubles));
00294 return;
00295 }
00296 }
00297
00298
00299
00300 long sum = 0;
00301 for (i = 0; i < nArgs; i++)
00302 {
00303 sum += mux_atol(fargs[i]);
00304 }
00305 safe_ltoa(sum, buff, bufc);
00306 }
00307
00308 FUNCTION(fun_ladd)
00309 {
00310 UNUSED_PARAMETER(executor);
00311 UNUSED_PARAMETER(caller);
00312 UNUSED_PARAMETER(enactor);
00313 UNUSED_PARAMETER(cargs);
00314 UNUSED_PARAMETER(ncargs);
00315
00316 int n = 0;
00317 if (0 < nfargs)
00318 {
00319 SEP sep;
00320 if (!OPTIONAL_DELIM(2, sep, DELIM_DFLT|DELIM_STRING))
00321 {
00322 return;
00323 }
00324
00325 char *cp = trim_space_sep(fargs[0], &sep);
00326 while ( cp
00327 && n < g_nDoubles)
00328 {
00329 char *curr = split_token(&cp, &sep);
00330 g_aDoubles[n++] = mux_atof(curr);
00331 }
00332 }
00333 fval(buff, bufc, AddDoubles(n, g_aDoubles));
00334 }
00335
00337
00338
00339
00341
00342 FUNCTION(fun_iadd)
00343 {
00344 UNUSED_PARAMETER(executor);
00345 UNUSED_PARAMETER(caller);
00346 UNUSED_PARAMETER(enactor);
00347 UNUSED_PARAMETER(cargs);
00348 UNUSED_PARAMETER(ncargs);
00349
00350 INT64 sum = 0;
00351 for (int i = 0; i < nfargs; i++)
00352 {
00353 sum += mux_atoi64(fargs[i]);
00354 }
00355 safe_i64toa(sum, buff, bufc);
00356 }
00357
00358 FUNCTION(fun_sub)
00359 {
00360 UNUSED_PARAMETER(executor);
00361 UNUSED_PARAMETER(caller);
00362 UNUSED_PARAMETER(enactor);
00363 UNUSED_PARAMETER(nfargs);
00364 UNUSED_PARAMETER(cargs);
00365 UNUSED_PARAMETER(ncargs);
00366
00367 int nDigits;
00368 if ( is_integer(fargs[0], &nDigits)
00369 && nDigits <= 9
00370 && is_integer(fargs[1], &nDigits)
00371 && nDigits <= 9)
00372 {
00373 int iResult;
00374 iResult = mux_atol(fargs[0]) - mux_atol(fargs[1]);
00375 safe_ltoa(iResult, buff, bufc);
00376 }
00377 else
00378 {
00379 g_aDoubles[0] = mux_atof(fargs[0]);
00380 g_aDoubles[1] = -mux_atof(fargs[1]);
00381 fval(buff, bufc, AddDoubles(2, g_aDoubles));
00382 }
00383 }
00384
00386
00387
00388
00390
00391 FUNCTION(fun_isub)
00392 {
00393 UNUSED_PARAMETER(executor);
00394 UNUSED_PARAMETER(caller);
00395 UNUSED_PARAMETER(enactor);
00396 UNUSED_PARAMETER(nfargs);
00397 UNUSED_PARAMETER(cargs);
00398 UNUSED_PARAMETER(ncargs);
00399
00400 INT64 diff = mux_atoi64(fargs[0]) - mux_atoi64(fargs[1]);
00401 safe_i64toa(diff, buff, bufc);
00402 }
00403
00404 FUNCTION(fun_mul)
00405 {
00406 UNUSED_PARAMETER(executor);
00407 UNUSED_PARAMETER(caller);
00408 UNUSED_PARAMETER(enactor);
00409 UNUSED_PARAMETER(cargs);
00410 UNUSED_PARAMETER(ncargs);
00411
00412 double prod = 1.0;
00413 for (int i = 0; i < nfargs; i++)
00414 {
00415 prod *= mux_atof(fargs[i]);
00416 }
00417 fval(buff, bufc, NearestPretty(prod));
00418 }
00419
00421
00422
00423
00425
00426 FUNCTION(fun_imul)
00427 {
00428 UNUSED_PARAMETER(executor);
00429 UNUSED_PARAMETER(caller);
00430 UNUSED_PARAMETER(enactor);
00431 UNUSED_PARAMETER(cargs);
00432 UNUSED_PARAMETER(ncargs);
00433
00434 INT64 prod = 1;
00435 for (int i = 0; i < nfargs; i++)
00436 {
00437 prod *= mux_atoi64(fargs[i]);
00438 }
00439 safe_i64toa(prod, buff, bufc);
00440 }
00441
00442 FUNCTION(fun_gt)
00443 {
00444 UNUSED_PARAMETER(executor);
00445 UNUSED_PARAMETER(caller);
00446 UNUSED_PARAMETER(enactor);
00447 UNUSED_PARAMETER(nfargs);
00448 UNUSED_PARAMETER(cargs);
00449 UNUSED_PARAMETER(ncargs);
00450
00451 bool bResult = false;
00452 int nDigits;
00453 if ( is_integer(fargs[0], &nDigits)
00454 && nDigits <= 9
00455 && is_integer(fargs[1], &nDigits)
00456 && nDigits <= 9)
00457 {
00458 bResult = (mux_atol(fargs[0]) > mux_atol(fargs[1]));
00459 }
00460 else
00461 {
00462 bResult = (mux_atof(fargs[0]) > mux_atof(fargs[1]));
00463 }
00464 safe_bool(bResult, buff, bufc);
00465 }
00466
00467 FUNCTION(fun_gte)
00468 {
00469 UNUSED_PARAMETER(executor);
00470 UNUSED_PARAMETER(caller);
00471 UNUSED_PARAMETER(enactor);
00472 UNUSED_PARAMETER(nfargs);
00473 UNUSED_PARAMETER(cargs);
00474 UNUSED_PARAMETER(ncargs);
00475
00476 bool bResult = false;
00477 int nDigits;
00478 if ( is_integer(fargs[0], &nDigits)
00479 && nDigits <= 9
00480 && is_integer(fargs[1], &nDigits)
00481 && nDigits <= 9)
00482 {
00483 bResult = (mux_atol(fargs[0]) >= mux_atol(fargs[1]));
00484 }
00485 else
00486 {
00487 bResult = (mux_atof(fargs[0]) >= mux_atof(fargs[1]));
00488 }
00489 safe_bool(bResult, buff, bufc);
00490 }
00491
00492 FUNCTION(fun_lt)
00493 {
00494 UNUSED_PARAMETER(executor);
00495 UNUSED_PARAMETER(caller);
00496 UNUSED_PARAMETER(enactor);
00497 UNUSED_PARAMETER(nfargs);
00498 UNUSED_PARAMETER(cargs);
00499 UNUSED_PARAMETER(ncargs);
00500
00501 bool bResult = false;
00502 int nDigits;
00503 if ( is_integer(fargs[0], &nDigits)
00504 && nDigits <= 9
00505 && is_integer(fargs[1], &nDigits)
00506 && nDigits <= 9)
00507 {
00508 bResult = (mux_atol(fargs[0]) < mux_atol(fargs[1]));
00509 }
00510 else
00511 {
00512 bResult = (mux_atof(fargs[0]) < mux_atof(fargs[1]));
00513 }
00514 safe_bool(bResult, buff, bufc);
00515 }
00516
00517 FUNCTION(fun_lte)
00518 {
00519 UNUSED_PARAMETER(executor);
00520 UNUSED_PARAMETER(caller);
00521 UNUSED_PARAMETER(enactor);
00522 UNUSED_PARAMETER(nfargs);
00523 UNUSED_PARAMETER(cargs);
00524 UNUSED_PARAMETER(ncargs);
00525
00526 bool bResult = false;
00527 int nDigits;
00528 if ( is_integer(fargs[0], &nDigits)
00529 && nDigits <= 9
00530 && is_integer(fargs[1], &nDigits)
00531 && nDigits <= 9)
00532 {
00533 bResult = (mux_atol(fargs[0]) <= mux_atol(fargs[1]));
00534 }
00535 else
00536 {
00537 bResult = (mux_atof(fargs[0]) <= mux_atof(fargs[1]));
00538 }
00539 safe_bool(bResult, buff, bufc);
00540 }
00541
00542 FUNCTION(fun_eq)
00543 {
00544 UNUSED_PARAMETER(executor);
00545 UNUSED_PARAMETER(caller);
00546 UNUSED_PARAMETER(enactor);
00547 UNUSED_PARAMETER(nfargs);
00548 UNUSED_PARAMETER(cargs);
00549 UNUSED_PARAMETER(ncargs);
00550
00551 bool bResult = false;
00552 int nDigits;
00553 if ( is_integer(fargs[0], &nDigits)
00554 && nDigits <= 9
00555 && is_integer(fargs[1], &nDigits)
00556 && nDigits <= 9)
00557 {
00558 bResult = (mux_atol(fargs[0]) == mux_atol(fargs[1]));
00559 }
00560 else
00561 {
00562 bResult = ( strcmp(fargs[0], fargs[1]) == 0
00563 || mux_atof(fargs[0]) == mux_atof(fargs[1]));
00564 }
00565 safe_bool(bResult, buff, bufc);
00566 }
00567
00568 FUNCTION(fun_neq)
00569 {
00570 UNUSED_PARAMETER(executor);
00571 UNUSED_PARAMETER(caller);
00572 UNUSED_PARAMETER(enactor);
00573 UNUSED_PARAMETER(nfargs);
00574 UNUSED_PARAMETER(cargs);
00575 UNUSED_PARAMETER(ncargs);
00576
00577 bool bResult = false;
00578 int nDigits;
00579 if ( is_integer(fargs[0], &nDigits)
00580 && nDigits <= 9
00581 && is_integer(fargs[1], &nDigits)
00582 && nDigits <= 9)
00583 {
00584 bResult = (mux_atol(fargs[0]) != mux_atol(fargs[1]));
00585 }
00586 else
00587 {
00588 bResult = ( strcmp(fargs[0], fargs[1]) != 0
00589 && mux_atof(fargs[0]) != mux_atof(fargs[1]));
00590 }
00591 safe_bool(bResult, buff, bufc);
00592 }
00593
00594
00595
00596
00597
00598
00599 FUNCTION(fun_max)
00600 {
00601 UNUSED_PARAMETER(executor);
00602 UNUSED_PARAMETER(caller);
00603 UNUSED_PARAMETER(enactor);
00604 UNUSED_PARAMETER(cargs);
00605 UNUSED_PARAMETER(ncargs);
00606
00607 double maximum = 0.0;
00608 for (int i = 0; i < nfargs; i++)
00609 {
00610 double tval = mux_atof(fargs[i]);
00611 if ( i == 0
00612 || tval > maximum)
00613 {
00614 maximum = tval;
00615 }
00616 }
00617 fval(buff, bufc, maximum);
00618 }
00619
00620 FUNCTION(fun_min)
00621 {
00622 UNUSED_PARAMETER(executor);
00623 UNUSED_PARAMETER(caller);
00624 UNUSED_PARAMETER(enactor);
00625 UNUSED_PARAMETER(cargs);
00626 UNUSED_PARAMETER(ncargs);
00627
00628 double minimum = 0.0;
00629 for (int i = 0; i < nfargs; i++)
00630 {
00631 double tval = mux_atof(fargs[i]);
00632 if ( i == 0
00633 || tval < minimum)
00634 {
00635 minimum = tval;
00636 }
00637 }
00638 fval(buff, bufc, minimum);
00639 }
00640
00641
00642
00643
00644
00645 FUNCTION(fun_sign)
00646 {
00647 UNUSED_PARAMETER(executor);
00648 UNUSED_PARAMETER(caller);
00649 UNUSED_PARAMETER(enactor);
00650 UNUSED_PARAMETER(nfargs);
00651 UNUSED_PARAMETER(cargs);
00652 UNUSED_PARAMETER(ncargs);
00653
00654 double num = mux_atof(fargs[0]);
00655 if (num < 0)
00656 {
00657 safe_str("-1", buff, bufc);
00658 }
00659 else
00660 {
00661 safe_bool(num > 0, buff, bufc);
00662 }
00663 }
00664
00665
00666
00667 FUNCTION(fun_isign)
00668 {
00669 UNUSED_PARAMETER(executor);
00670 UNUSED_PARAMETER(caller);
00671 UNUSED_PARAMETER(enactor);
00672 UNUSED_PARAMETER(nfargs);
00673 UNUSED_PARAMETER(cargs);
00674 UNUSED_PARAMETER(ncargs);
00675
00676 INT64 num = mux_atoi64(fargs[0]);
00677
00678 if (num < 0)
00679 {
00680 safe_str("-1", buff, bufc);
00681 }
00682 else
00683 {
00684 safe_bool(num > 0, buff, bufc);
00685 }
00686 }
00687
00688
00689
00690 FUNCTION(fun_shl)
00691 {
00692 UNUSED_PARAMETER(executor);
00693 UNUSED_PARAMETER(caller);
00694 UNUSED_PARAMETER(enactor);
00695 UNUSED_PARAMETER(nfargs);
00696 UNUSED_PARAMETER(cargs);
00697 UNUSED_PARAMETER(ncargs);
00698
00699 if ( is_integer(fargs[0], NULL)
00700 && is_integer(fargs[1], NULL))
00701 {
00702 INT64 a = mux_atoi64(fargs[0]);
00703 long b = mux_atol(fargs[1]);
00704 safe_i64toa(a << b, buff, bufc);
00705 }
00706 else
00707 {
00708 safe_str("#-1 ARGUMENTS MUST BE INTEGERS", buff, bufc);
00709 }
00710 }
00711
00712 FUNCTION(fun_shr)
00713 {
00714 UNUSED_PARAMETER(executor);
00715 UNUSED_PARAMETER(caller);
00716 UNUSED_PARAMETER(enactor);
00717 UNUSED_PARAMETER(nfargs);
00718 UNUSED_PARAMETER(cargs);
00719 UNUSED_PARAMETER(ncargs);
00720
00721 if ( is_integer(fargs[0], NULL)
00722 && is_integer(fargs[1], NULL))
00723 {
00724 INT64 a = mux_atoi64(fargs[0]);
00725 long b = mux_atol(fargs[1]);
00726 safe_i64toa(a >> b, buff, bufc);
00727 }
00728 else
00729 {
00730 safe_str("#-1 ARGUMENTS MUST BE INTEGERS", buff, bufc);
00731 }
00732 }
00733
00734 FUNCTION(fun_inc)
00735 {
00736 UNUSED_PARAMETER(executor);
00737 UNUSED_PARAMETER(caller);
00738 UNUSED_PARAMETER(enactor);
00739 UNUSED_PARAMETER(cargs);
00740 UNUSED_PARAMETER(ncargs);
00741
00742 if (nfargs == 1)
00743 {
00744 safe_i64toa(mux_atoi64(fargs[0]) + 1, buff, bufc);
00745 }
00746 else
00747 {
00748 safe_chr('1', buff, bufc);
00749 }
00750 }
00751
00752 FUNCTION(fun_dec)
00753 {
00754 UNUSED_PARAMETER(executor);
00755 UNUSED_PARAMETER(caller);
00756 UNUSED_PARAMETER(enactor);
00757 UNUSED_PARAMETER(cargs);
00758 UNUSED_PARAMETER(ncargs);
00759
00760 if (nfargs == 1)
00761 {
00762 safe_i64toa(mux_atoi64(fargs[0]) - 1, buff, bufc);
00763 }
00764 else
00765 {
00766 safe_str("-1", buff, bufc);
00767 }
00768 }
00769
00770 FUNCTION(fun_trunc)
00771 {
00772 UNUSED_PARAMETER(executor);
00773 UNUSED_PARAMETER(caller);
00774 UNUSED_PARAMETER(enactor);
00775 UNUSED_PARAMETER(nfargs);
00776 UNUSED_PARAMETER(cargs);
00777 UNUSED_PARAMETER(ncargs);
00778
00779 double rArg = mux_atof(fargs[0]);
00780 double rIntegerPart;
00781
00782 mux_FPRestore();
00783 (void)modf(rArg, &rIntegerPart);
00784 mux_FPSet();
00785
00786 #ifdef HAVE_IEEE_FP_FORMAT
00787 int fpc = mux_fpclass(rIntegerPart);
00788 if (MUX_FPGROUP(fpc) == MUX_FPGROUP_PASS)
00789 {
00790 #endif // HAVE_IEEE_FP_FORMAT
00791 safe_tprintf_str(buff, bufc, "%.0f", rIntegerPart);
00792 #ifdef HAVE_IEEE_FP_FORMAT
00793 }
00794 else
00795 {
00796 safe_str(mux_FPStrings[MUX_FPCLASS(fpc)], buff, bufc);
00797 }
00798 #endif // HAVE_IEEE_FP_FORMAT
00799 }
00800
00801 FUNCTION(fun_fdiv)
00802 {
00803 UNUSED_PARAMETER(executor);
00804 UNUSED_PARAMETER(caller);
00805 UNUSED_PARAMETER(enactor);
00806 UNUSED_PARAMETER(nfargs);
00807 UNUSED_PARAMETER(cargs);
00808 UNUSED_PARAMETER(ncargs);
00809
00810 double bot = mux_atof(fargs[1]);
00811 double top = mux_atof(fargs[0]);
00812 #ifndef HAVE_IEEE_FP_SNAN
00813 if (bot == 0.0)
00814 {
00815 if (top > 0.0)
00816 {
00817 safe_str("+Inf", buff, bufc);
00818 }
00819 else if (top < 0.0)
00820 {
00821 safe_str("-Inf", buff, bufc);
00822 }
00823 else
00824 {
00825 safe_str("Ind", buff, bufc);
00826 }
00827 }
00828 else
00829 {
00830 fval(buff, bufc, top/bot);
00831 }
00832 #else
00833 fval(buff, bufc, top/bot);
00834 #endif
00835 }
00836
00837 FUNCTION(fun_idiv)
00838 {
00839 UNUSED_PARAMETER(executor);
00840 UNUSED_PARAMETER(caller);
00841 UNUSED_PARAMETER(enactor);
00842 UNUSED_PARAMETER(nfargs);
00843 UNUSED_PARAMETER(cargs);
00844 UNUSED_PARAMETER(ncargs);
00845
00846 INT64 bot, top;
00847
00848 bot = mux_atoi64(fargs[1]);
00849 if (bot == 0)
00850 {
00851 safe_str("#-1 DIVIDE BY ZERO", buff, bufc);
00852 }
00853 else
00854 {
00855 top = mux_atoi64(fargs[0]);
00856 top = i64Division(top, bot);
00857 safe_i64toa(top, buff, bufc);
00858 }
00859 }
00860
00861 FUNCTION(fun_floordiv)
00862 {
00863 UNUSED_PARAMETER(executor);
00864 UNUSED_PARAMETER(caller);
00865 UNUSED_PARAMETER(enactor);
00866 UNUSED_PARAMETER(nfargs);
00867 UNUSED_PARAMETER(cargs);
00868 UNUSED_PARAMETER(ncargs);
00869
00870 INT64 bot, top;
00871
00872 bot = mux_atoi64(fargs[1]);
00873 if (bot == 0)
00874 {
00875 safe_str("#-1 DIVIDE BY ZERO", buff, bufc);
00876 }
00877 else
00878 {
00879 top = mux_atoi64(fargs[0]);
00880 top = i64FloorDivision(top, bot);
00881 safe_i64toa(top, buff, bufc);
00882 }
00883 }
00884
00885 FUNCTION(fun_mod)
00886 {
00887 UNUSED_PARAMETER(executor);
00888 UNUSED_PARAMETER(caller);
00889 UNUSED_PARAMETER(enactor);
00890 UNUSED_PARAMETER(nfargs);
00891 UNUSED_PARAMETER(cargs);
00892 UNUSED_PARAMETER(ncargs);
00893
00894 INT64 bot, top;
00895
00896 bot = mux_atoi64(fargs[1]);
00897 if (bot == 0)
00898 {
00899 bot = 1;
00900 }
00901 top = mux_atoi64(fargs[0]);
00902 top = i64Mod(top, bot);
00903 safe_i64toa(top, buff, bufc);
00904 }
00905
00906 FUNCTION(fun_remainder)
00907 {
00908 UNUSED_PARAMETER(executor);
00909 UNUSED_PARAMETER(caller);
00910 UNUSED_PARAMETER(enactor);
00911 UNUSED_PARAMETER(nfargs);
00912 UNUSED_PARAMETER(cargs);
00913 UNUSED_PARAMETER(ncargs);
00914
00915 INT64 bot, top;
00916
00917 bot = mux_atoi64(fargs[1]);
00918 if (bot == 0)
00919 {
00920 bot = 1;
00921 }
00922 top = mux_atoi64(fargs[0]);
00923 top = i64Remainder(top, bot);
00924 safe_i64toa(top, buff, bufc);
00925 }
00926
00927
00928
00929
00930
00931 FUNCTION(fun_abs)
00932 {
00933 UNUSED_PARAMETER(executor);
00934 UNUSED_PARAMETER(caller);
00935 UNUSED_PARAMETER(enactor);
00936 UNUSED_PARAMETER(nfargs);
00937 UNUSED_PARAMETER(cargs);
00938 UNUSED_PARAMETER(ncargs);
00939
00940 double num = mux_atof(fargs[0]);
00941 if (num == 0.0)
00942 {
00943 safe_chr('0', buff, bufc);
00944 }
00945 else if (num < 0.0)
00946 {
00947 fval(buff, bufc, -num);
00948 }
00949 else
00950 {
00951 fval(buff, bufc, num);
00952 }
00953 }
00954
00955
00956
00957 FUNCTION(fun_iabs)
00958 {
00959 UNUSED_PARAMETER(executor);
00960 UNUSED_PARAMETER(caller);
00961 UNUSED_PARAMETER(enactor);
00962 UNUSED_PARAMETER(nfargs);
00963 UNUSED_PARAMETER(cargs);
00964 UNUSED_PARAMETER(ncargs);
00965
00966 INT64 num = mux_atoi64(fargs[0]);
00967
00968 if (num == 0)
00969 {
00970 safe_chr('0', buff, bufc);
00971 }
00972 else if (num < 0)
00973 {
00974 safe_i64toa(-num, buff, bufc);
00975 }
00976 else
00977 {
00978 safe_i64toa(num, buff, bufc);
00979 }
00980 }
00981
00982 FUNCTION(fun_dist2d)
00983 {
00984 UNUSED_PARAMETER(executor);
00985 UNUSED_PARAMETER(caller);
00986 UNUSED_PARAMETER(enactor);
00987 UNUSED_PARAMETER(nfargs);
00988 UNUSED_PARAMETER(cargs);
00989 UNUSED_PARAMETER(ncargs);
00990
00991 double d;
00992 double sum;
00993
00994 d = mux_atof(fargs[0]) - mux_atof(fargs[2]);
00995 sum = d * d;
00996 d = mux_atof(fargs[1]) - mux_atof(fargs[3]);
00997 sum += d * d;
00998
00999 mux_FPRestore();
01000 double result = sqrt(sum);
01001 mux_FPSet();
01002
01003 fval(buff, bufc, result);
01004 }
01005
01006 FUNCTION(fun_dist3d)
01007 {
01008 UNUSED_PARAMETER(executor);
01009 UNUSED_PARAMETER(caller);
01010 UNUSED_PARAMETER(enactor);
01011 UNUSED_PARAMETER(nfargs);
01012 UNUSED_PARAMETER(cargs);
01013 UNUSED_PARAMETER(ncargs);
01014
01015 double d;
01016 double sum;
01017
01018 d = mux_atof(fargs[0]) - mux_atof(fargs[3]);
01019 sum = d * d;
01020 d = mux_atof(fargs[1]) - mux_atof(fargs[4]);
01021 sum += d * d;
01022 d = mux_atof(fargs[2]) - mux_atof(fargs[5]);
01023 sum += d * d;
01024
01025 mux_FPRestore();
01026 double result = sqrt(sum);
01027 mux_FPSet();
01028
01029 fval(buff, bufc, result);
01030 }
01031
01032
01033
01034
01035
01036 #define VADD_F 0
01037 #define VSUB_F 1
01038 #define VMUL_F 2
01039 #define VDOT_F 3
01040 #define VCROSS_F 4
01041
01042 static void handle_vectors
01043 (
01044 char *vecarg1, char *vecarg2, char *buff, char **bufc, SEP *psep,
01045 SEP *posep, int flag
01046 )
01047 {
01048 char *v1[(LBUF_SIZE+1)/2], *v2[(LBUF_SIZE+1)/2];
01049 double scalar;
01050 int n, m, i;
01051
01052
01053
01054 if (!vecarg1 || !*vecarg1 || !vecarg2 || !*vecarg2)
01055 {
01056 return;
01057 }
01058 n = list2arr(v1, (LBUF_SIZE+1)/2, vecarg1, psep);
01059 m = list2arr(v2, (LBUF_SIZE+1)/2, vecarg2, psep);
01060
01061
01062
01063
01064 if ( n != m
01065 && !( ( flag == VMUL_F
01066 || flag == VADD_F
01067 || flag == VSUB_F)
01068 && ( n == 1
01069 || m == 1)))
01070 {
01071 safe_str("#-1 VECTORS MUST BE SAME DIMENSIONS", buff, bufc);
01072 return;
01073 }
01074
01075 switch (flag)
01076 {
01077 case VADD_F:
01078
01079
01080
01081
01082 if (n == 1)
01083 {
01084 scalar = mux_atof(v1[0]);
01085 for (i = 0; i < m; i++)
01086 {
01087 if (i != 0)
01088 {
01089 print_sep(posep, buff, bufc);
01090 }
01091 fval(buff, bufc, mux_atof(v2[i]) + scalar);
01092 }
01093 n = m;
01094 }
01095 else if (m == 1)
01096 {
01097 scalar = mux_atof(v2[0]);
01098 for (i = 0; i < n; i++)
01099 {
01100 if (i != 0)
01101 {
01102 print_sep(posep, buff, bufc);
01103 }
01104 fval(buff, bufc, mux_atof(v1[i]) + scalar);
01105 }
01106 }
01107 else
01108 {
01109 for (i = 0; i < n; i++)
01110 {
01111 if (i != 0)
01112 {
01113 print_sep(posep, buff, bufc);
01114 }
01115 double a = mux_atof(v1[i]);
01116 double b = mux_atof(v2[i]);
01117 fval(buff, bufc, a + b);
01118 }
01119 }
01120 break;
01121
01122 case VSUB_F:
01123
01124 if (n == 1)
01125 {
01126
01127
01128 scalar = mux_atof(v1[0]);
01129 for (i = 0; i < m; i++)
01130 {
01131 if (i != 0)
01132 {
01133 print_sep(posep, buff, bufc);
01134 }
01135 fval(buff, bufc, scalar - mux_atof(v2[i]));
01136 }
01137 }
01138 else if (m == 1)
01139 {
01140
01141
01142 scalar = mux_atof(v2[0]);
01143 for (i = 0; i < n; i++)
01144 {
01145 if (i != 0)
01146 {
01147 print_sep(posep, buff, bufc);
01148 }
01149 fval(buff, bufc, mux_atof(v1[i]) - scalar);
01150 }
01151 }
01152 else
01153 {
01154
01155
01156 for (i = 0; i < n; i++)
01157 {
01158 if (i != 0)
01159 {
01160 print_sep(posep, buff, bufc);
01161 }
01162 double a = mux_atof(v1[i]);
01163 double b = mux_atof(v2[i]);
01164 fval(buff, bufc, a - b);
01165 }
01166 }
01167 break;
01168
01169 case VMUL_F:
01170
01171
01172
01173
01174 if (n == 1)
01175 {
01176 scalar = mux_atof(v1[0]);
01177 for (i = 0; i < m; i++)
01178 {
01179 if (i != 0)
01180 {
01181 print_sep(posep, buff, bufc);
01182 }
01183 fval(buff, bufc, mux_atof(v2[i]) * scalar);
01184 }
01185 }
01186 else if (m == 1)
01187 {
01188 scalar = mux_atof(v2[0]);
01189 for (i = 0; i < n; i++)
01190 {
01191 if (i != 0)
01192 {
01193 print_sep(posep, buff, bufc);
01194 }
01195 fval(buff, bufc, mux_atof(v1[i]) * scalar);
01196 }
01197 }
01198 else
01199 {
01200
01201
01202 for (i = 0; i < n; i++)
01203 {
01204 if (i != 0)
01205 {
01206 print_sep(posep, buff, bufc);
01207 }
01208 double a = mux_atof(v1[i]);
01209 double b = mux_atof(v2[i]);
01210 fval(buff, bufc, a * b);
01211 }
01212 }
01213 break;
01214
01215 case VDOT_F:
01216
01217 scalar = 0.0;
01218 for (i = 0; i < n; i++)
01219 {
01220 double a = mux_atof(v1[i]);
01221 double b = mux_atof(v2[i]);
01222 scalar += a * b;
01223 }
01224 fval(buff, bufc, scalar);
01225 break;
01226
01227 case VCROSS_F:
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241 if (n != 3)
01242 {
01243 safe_str("#-1 VECTORS MUST BE DIMENSION OF 3", buff, bufc);
01244 }
01245 else
01246 {
01247 double a[2][3];
01248 for (i = 0; i < 3; i++)
01249 {
01250 a[0][i] = mux_atof(v1[i]);
01251 a[1][i] = mux_atof(v2[i]);
01252 }
01253 fval(buff, bufc, (a[0][1] * a[1][2]) - (a[0][2] * a[1][1]));
01254 print_sep(posep, buff, bufc);
01255 fval(buff, bufc, (a[0][2] * a[1][0]) - (a[0][0] * a[1][2]));
01256 print_sep(posep, buff, bufc);
01257 fval(buff, bufc, (a[0][0] * a[1][1]) - (a[0][1] * a[1][0]));
01258 }
01259 break;
01260
01261 default:
01262
01263
01264
01265 safe_str("#-1 UNIMPLEMENTED", buff, bufc);
01266 }
01267 }
01268
01269 FUNCTION(fun_vadd)
01270 {
01271 SEP sep;
01272 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
01273 {
01274 return;
01275 }
01276
01277 SEP osep = sep;
01278 if (!OPTIONAL_DELIM(4, osep, DELIM_NULL|DELIM_CRLF|DELIM_STRING|DELIM_INIT))
01279 {
01280 return;
01281 }
01282 handle_vectors(fargs[0], fargs[1], buff, bufc, &sep, &osep, VADD_F);
01283 }
01284
01285 FUNCTION(fun_vsub)
01286 {
01287 SEP sep;
01288 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
01289 {
01290 return;
01291 }
01292
01293 SEP osep = sep;
01294 if (!OPTIONAL_DELIM(4, osep, DELIM_NULL|DELIM_CRLF|DELIM_STRING|DELIM_INIT))
01295 {
01296 return;
01297 }
01298 handle_vectors(fargs[0], fargs[1], buff, bufc, &sep, &osep, VSUB_F);
01299 }
01300
01301 FUNCTION(fun_vmul)
01302 {
01303 SEP sep;
01304 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
01305 {
01306 return;
01307 }
01308
01309 SEP osep = sep;
01310 if (!OPTIONAL_DELIM(4, osep, DELIM_NULL|DELIM_CRLF|DELIM_STRING|DELIM_INIT))
01311 {
01312 return;
01313 }
01314 handle_vectors(fargs[0], fargs[1], buff, bufc, &sep, &osep, VMUL_F);
01315 }
01316
01317 FUNCTION(fun_vdot)
01318 {
01319
01320
01321 SEP sep;
01322 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
01323 {
01324 return;
01325 }
01326
01327 SEP osep = sep;
01328 if (!OPTIONAL_DELIM(4, osep, DELIM_NULL|DELIM_CRLF|DELIM_STRING|DELIM_INIT))
01329 {
01330 return;
01331 }
01332 handle_vectors(fargs[0], fargs[1], buff, bufc, &sep, &osep, VDOT_F);
01333 }
01334
01335 FUNCTION(fun_vcross)
01336 {
01337
01338
01339 SEP sep;
01340 if (!OPTIONAL_DELIM(3, sep, DELIM_DFLT|DELIM_STRING))
01341 {
01342 return;
01343 }
01344
01345 SEP osep = sep;
01346 if (!OPTIONAL_DELIM(4, osep, DELIM_NULL|DELIM_CRLF|DELIM_STRING|DELIM_INIT))
01347 {
01348 return;
01349 }
01350 handle_vectors(fargs[0], fargs[1], buff, bufc, &sep, &osep, VCROSS_F);
01351 }
01352
01353 FUNCTION(fun_vmag)
01354 {
01355 SEP sep;
01356 if (!OPTIONAL_DELIM(2, sep, DELIM_DFLT|DELIM_STRING))
01357 {
01358 return;
01359 }
01360
01361 char *v1[LBUF_SIZE];
01362 int n, i;
01363 double tmp, res = 0.0;
01364
01365
01366
01367 if (!fargs[0] || !*fargs[0])
01368 {
01369 return;
01370 }
01371 n = list2arr(v1, LBUF_SIZE, fargs[0], &sep);
01372
01373
01374
01375 for (i = 0; i < n; i++)
01376 {
01377 tmp = mux_atof(v1[i]);
01378 res += tmp * tmp;
01379 }
01380
01381 if (res > 0)
01382 {
01383 mux_FPRestore();
01384 double result = sqrt(res);
01385 mux_FPSet();
01386
01387 fval(buff, bufc, result);
01388 }
01389 else
01390 {
01391 safe_chr('0', buff, bufc);
01392 }
01393 }
01394
01395 FUNCTION(fun_vunit)
01396 {
01397 SEP sep;
01398 if (!OPTIONAL_DELIM(2, sep, DELIM_DFLT|DELIM_STRING))
01399 {
01400 return;
01401 }
01402
01403 char *v1[LBUF_SIZE];
01404 int n, i;
01405 double tmp, res = 0.0;
01406
01407
01408
01409 if (!fargs[0] || !*fargs[0])
01410 {
01411 return;
01412 }
01413 n = list2arr(v1, LBUF_SIZE, fargs[0], &sep);
01414
01415
01416
01417 for (i = 0; i < n; i++)
01418 {
01419 tmp = mux_atof(v1[i]);
01420 res += tmp * tmp;
01421 }
01422
01423 if (res <= 0)
01424 {
01425 safe_str("#-1 CAN'T MAKE UNIT VECTOR FROM ZERO-LENGTH VECTOR",
01426 buff, bufc);
01427 return;
01428 }
01429 for (i = 0; i < n; i++)
01430 {
01431 if (i != 0)
01432 {
01433 print_sep(&sep, buff, bufc);
01434 }
01435
01436 mux_FPRestore();
01437 double result = sqrt(res);
01438 mux_FPSet();
01439
01440 fval(buff, bufc, mux_atof(v1[i]) / result);
01441 }
01442 }
01443
01444 FUNCTION(fun_floor)
01445 {
01446 UNUSED_PARAMETER(executor);
01447 UNUSED_PARAMETER(caller);
01448 UNUSED_PARAMETER(enactor);
01449 UNUSED_PARAMETER(nfargs);
01450 UNUSED_PARAMETER(cargs);
01451 UNUSED_PARAMETER(ncargs);
01452
01453 mux_FPRestore();
01454 double r = floor(mux_atof(fargs[0]));
01455 mux_FPSet();
01456
01457 #ifdef HAVE_IEEE_FP_FORMAT
01458 int fpc = mux_fpclass(r);
01459 if (MUX_FPGROUP(fpc) == MUX_FPGROUP_PASS)
01460 {
01461 #endif // HAVE_IEEE_FP_FORMAT
01462 safe_tprintf_str(buff, bufc, "%.0f", r);
01463 #ifdef HAVE_IEEE_FP_FORMAT
01464 }
01465 else
01466 {
01467 safe_str(mux_FPStrings[MUX_FPCLASS(fpc)], buff, bufc);
01468 }
01469 #endif // HAVE_IEEE_FP_FORMAT
01470 }
01471
01472 FUNCTION(fun_ceil)
01473 {
01474 UNUSED_PARAMETER(executor);
01475 UNUSED_PARAMETER(caller);
01476 UNUSED_PARAMETER(enactor);
01477 UNUSED_PARAMETER(nfargs);
01478 UNUSED_PARAMETER(cargs);
01479 UNUSED_PARAMETER(ncargs);
01480
01481 mux_FPRestore();
01482 double r = ceil(mux_atof(fargs[0]));
01483 mux_FPSet();
01484
01485 #ifdef HAVE_IEEE_FP_FORMAT
01486 int fpc = mux_fpclass(r);
01487 if (MUX_FPGROUP(fpc) == MUX_FPGROUP_PASS)
01488 {
01489 #endif // HAVE_IEEE_FP_FORMAT
01490 safe_tprintf_str(buff, bufc, "%.0f", r);
01491 #ifdef HAVE_IEEE_FP_FORMAT
01492 }
01493 else
01494 {
01495 safe_str(mux_FPStrings[MUX_FPCLASS(fpc)], buff, bufc);
01496 }
01497 #endif // HAVE_IEEE_FP_FORMAT
01498 }
01499
01500 FUNCTION(fun_round)
01501 {
01502 UNUSED_PARAMETER(executor);
01503 UNUSED_PARAMETER(caller);
01504 UNUSED_PARAMETER(enactor);
01505 UNUSED_PARAMETER(nfargs);
01506 UNUSED_PARAMETER(cargs);
01507 UNUSED_PARAMETER(ncargs);
01508
01509 double r = mux_atof(fargs[0]);
01510 #ifdef HAVE_IEEE_FP_FORMAT
01511 int fpc = mux_fpclass(r);
01512 if ( MUX_FPGROUP(fpc) == MUX_FPGROUP_PASS
01513 || MUX_FPGROUP(fpc) == MUX_FPGROUP_ZERO)
01514 {
01515 if (MUX_FPGROUP(fpc) == MUX_FPGROUP_ZERO)
01516 {
01517 r = 0.0;
01518 }
01519 #endif // HAVE_IEEE_FP_FORMAT
01520 int frac = mux_atol(fargs[1]);
01521 safe_str(mux_ftoa(r, true, frac), buff, bufc);
01522 #ifdef HAVE_IEEE_FP_FORMAT
01523 }
01524 else
01525 {
01526 safe_str(mux_FPStrings[MUX_FPCLASS(fpc)], buff, bufc);
01527 }
01528 #endif // HAVE_IEEE_FP_FORMAT
01529 }
01530
01531 FUNCTION(fun_pi)
01532 {
01533 UNUSED_PARAMETER(executor);
01534 UNUSED_PARAMETER(caller);
01535 UNUSED_PARAMETER(enactor);
01536 UNUSED_PARAMETER(fargs);
01537 UNUSED_PARAMETER(nfargs);
01538 UNUSED_PARAMETER(cargs);
01539 UNUSED_PARAMETER(ncargs);
01540
01541 safe_str("3.141592653589793", buff, bufc);
01542 }
01543
01544 FUNCTION(fun_e)
01545 {
01546 UNUSED_PARAMETER(executor);
01547 UNUSED_PARAMETER(caller);
01548 UNUSED_PARAMETER(enactor);
01549 UNUSED_PARAMETER(fargs);
01550 UNUSED_PARAMETER(nfargs);
01551 UNUSED_PARAMETER(cargs);
01552 UNUSED_PARAMETER(ncargs);
01553
01554 safe_str("2.718281828459045", buff, bufc);
01555 }
01556
01557 static double ConvertRDG2R(double d, const char *szUnits)
01558 {
01559 switch (mux_tolower(szUnits[0]))
01560 {
01561 case 'd':
01562
01563
01564 d *= 0.017453292519943295;
01565 break;
01566
01567 case 'g':
01568
01569
01570 d *= 0.015707963267948967;
01571 break;
01572 }
01573 return d;
01574 }
01575
01576 static double ConvertR2RDG(double d, const char *szUnits)
01577 {
01578 switch (mux_tolower(szUnits[0]))
01579 {
01580 case 'd':
01581
01582
01583 d *= 57.29577951308232;
01584 break;
01585
01586 case 'g':
01587
01588
01589 d *= 63.66197723675813;
01590 break;
01591 }
01592 return d;
01593 }
01594
01595 FUNCTION(fun_ctu)
01596 {
01597 UNUSED_PARAMETER(executor);
01598 UNUSED_PARAMETER(caller);
01599 UNUSED_PARAMETER(enactor);
01600 UNUSED_PARAMETER(nfargs);
01601 UNUSED_PARAMETER(cargs);
01602 UNUSED_PARAMETER(ncargs);
01603
01604 double val = mux_atof(fargs[0]);
01605 val = ConvertRDG2R(val, fargs[1]);
01606 val = ConvertR2RDG(val, fargs[2]);
01607 fval(buff, bufc, val);
01608 }
01609
01610 FUNCTION(fun_sin)
01611 {
01612 UNUSED_PARAMETER(executor);
01613 UNUSED_PARAMETER(caller);
01614 UNUSED_PARAMETER(enactor);
01615 UNUSED_PARAMETER(cargs);
01616 UNUSED_PARAMETER(ncargs);
01617
01618 double d = mux_atof(fargs[0]);
01619 if (nfargs == 2)
01620 {
01621 d = ConvertRDG2R(d, fargs[1]);
01622 }
01623
01624 mux_FPRestore();
01625 d = sin(d);
01626 mux_FPSet();
01627
01628 fval(buff, bufc, d);
01629 }
01630
01631 FUNCTION(fun_cos)
01632 {
01633 UNUSED_PARAMETER(executor);
01634 UNUSED_PARAMETER(caller);
01635 UNUSED_PARAMETER(enactor);
01636 UNUSED_PARAMETER(cargs);
01637 UNUSED_PARAMETER(ncargs);
01638
01639 double d = mux_atof(fargs[0]);
01640 if (nfargs == 2)
01641 {
01642 d = ConvertRDG2R(d, fargs[1]);
01643 }
01644
01645 mux_FPRestore();
01646 d = cos(d);
01647 mux_FPSet();
01648
01649 fval(buff, bufc, d);
01650 }
01651
01652 FUNCTION(fun_tan)
01653 {
01654 UNUSED_PARAMETER(executor);
01655 UNUSED_PARAMETER(caller);
01656 UNUSED_PARAMETER(enactor);
01657 UNUSED_PARAMETER(cargs);
01658 UNUSED_PARAMETER(ncargs);
01659
01660 double d = mux_atof(fargs[0]);
01661 if (nfargs == 2)
01662 {
01663 d = ConvertRDG2R(d, fargs[1]);
01664 }
01665
01666 mux_FPRestore();
01667 d = tan(d);
01668 mux_FPSet();
01669
01670 fval(buff, bufc, d);
01671 }
01672
01673 FUNCTION(fun_asin)
01674 {
01675 UNUSED_PARAMETER(executor);
01676 UNUSED_PARAMETER(caller);
01677 UNUSED_PARAMETER(enactor);
01678 UNUSED_PARAMETER(cargs);
01679 UNUSED_PARAMETER(ncargs);
01680
01681 double val = mux_atof(fargs[0]);
01682 #ifndef HAVE_IEEE_FP_SNAN
01683 if ((val < -1.0) || (val > 1.0))
01684 {
01685 safe_str("Ind", buff, bufc);
01686 return;
01687 }
01688 #endif
01689 mux_FPRestore();
01690 val = asin(val);
01691 mux_FPSet();
01692
01693 if (nfargs == 2)
01694 {
01695 val = ConvertR2RDG(val, fargs[1]);
01696 }
01697 fval(buff, bufc, val);
01698 }
01699
01700 FUNCTION(fun_acos)
01701 {
01702 UNUSED_PARAMETER(executor);
01703 UNUSED_PARAMETER(caller);
01704 UNUSED_PARAMETER(enactor);
01705 UNUSED_PARAMETER(cargs);
01706 UNUSED_PARAMETER(ncargs);
01707
01708 double val = mux_atof(fargs[0]);
01709 #ifndef HAVE_IEEE_FP_SNAN
01710 if ((val < -1.0) || (val > 1.0))
01711 {
01712 safe_str("Ind", buff, bufc);
01713 return;
01714 }
01715 #endif
01716 mux_FPRestore();
01717 val = acos(val);
01718 mux_FPSet();
01719
01720 if (nfargs == 2)
01721 {
01722 val = ConvertR2RDG(val, fargs[1]);
01723 }
01724 fval(buff, bufc, val);
01725 }
01726
01727 FUNCTION(fun_atan)
01728 {
01729 UNUSED_PARAMETER(executor);
01730 UNUSED_PARAMETER(caller);
01731 UNUSED_PARAMETER(enactor);
01732 UNUSED_PARAMETER(cargs);
01733 UNUSED_PARAMETER(ncargs);
01734
01735 double val = mux_atof(fargs[0]);
01736
01737 mux_FPRestore();
01738 val = atan(val);
01739 mux_FPSet();
01740
01741 if (nfargs == 2)
01742 {
01743 val = ConvertR2RDG(val, fargs[1]);
01744 }
01745 fval(buff, bufc, val);
01746 }
01747
01748 FUNCTION(fun_exp)
01749 {
01750 UNUSED_PARAMETER(executor);
01751 UNUSED_PARAMETER(caller);
01752 UNUSED_PARAMETER(enactor);
01753 UNUSED_PARAMETER(nfargs);
01754 UNUSED_PARAMETER(cargs);
01755 UNUSED_PARAMETER(ncargs);
01756
01757 double val = mux_atof(fargs[0]);
01758
01759 mux_FPRestore();
01760 val = exp(val);
01761 mux_FPSet();
01762
01763 fval(buff, bufc, val);
01764 }
01765
01766 FUNCTION(fun_power)
01767 {
01768 UNUSED_PARAMETER(executor);
01769 UNUSED_PARAMETER(caller);
01770 UNUSED_PARAMETER(enactor);
01771 UNUSED_PARAMETER(nfargs);
01772 UNUSED_PARAMETER(cargs);
01773 UNUSED_PARAMETER(ncargs);
01774
01775 double val, val1, val2;
01776
01777 val1 = mux_atof(fargs[0]);
01778 val2 = mux_atof(fargs[1]);
01779 #ifndef HAVE_IEEE_FP_SNAN
01780 if (val1 < 0.0)
01781 {
01782 safe_str("Ind", buff, bufc);
01783 }
01784 else
01785 {
01786 mux_FPRestore();
01787 val = pow(val1, val2);
01788 mux_FPSet();
01789 fval(buff, bufc, val);
01790 }
01791 #else
01792 mux_FPRestore();
01793 val = pow(val1, val2);
01794 mux_FPSet();
01795 fval(buff, bufc, val);
01796 #endif
01797 }
01798
01799 FUNCTION(fun_fmod)
01800 {
01801 UNUSED_PARAMETER(executor);
01802 UNUSED_PARAMETER(caller);
01803 UNUSED_PARAMETER(enactor);
01804 UNUSED_PARAMETER(nfargs);
01805 UNUSED_PARAMETER(cargs);
01806 UNUSED_PARAMETER(ncargs);
01807
01808 double val, val1, val2;
01809
01810 val1 = mux_atof(fargs[0]);
01811 val2 = mux_atof(fargs[1]);
01812 #ifndef HAVE_IEEE_FP_SNAN
01813 if (val1 == 0.0)
01814 {
01815 safe_str("Ind", buff, bufc);
01816 }
01817 else
01818 {
01819 mux_FPRestore();
01820 val = fmod(val1, val2);
01821 mux_FPSet();
01822 fval(buff, bufc, val);
01823 }
01824 #else
01825 mux_FPRestore();
01826 val = fmod(val1, val2);
01827 mux_FPSet();
01828 fval(buff, bufc, val);
01829 #endif
01830 }
01831
01832 FUNCTION(fun_ln)
01833 {
01834 UNUSED_PARAMETER(executor);
01835 UNUSED_PARAMETER(caller);
01836 UNUSED_PARAMETER(enactor);
01837 UNUSED_PARAMETER(nfargs);
01838 UNUSED_PARAMETER(cargs);
01839 UNUSED_PARAMETER(ncargs);
01840
01841 double val;
01842
01843 val = mux_atof(fargs[0]);
01844 #ifndef HAVE_IEEE_FP_SNAN
01845 if (val < 0.0)
01846 {
01847 safe_str("Ind", buff, bufc);
01848 }
01849 else if (val == 0.0)
01850 {
01851 safe_str("-Inf", buff, bufc);
01852 }
01853 else
01854 {
01855 mux_FPRestore();
01856 val = log(val);
01857 mux_FPSet();
01858 }
01859 #else
01860 mux_FPRestore();
01861 val = log(val);
01862 mux_FPSet();
01863 #endif
01864 fval(buff, bufc, val);
01865 }
01866
01867 FUNCTION(fun_log)
01868 {
01869 UNUSED_PARAMETER(executor);
01870 UNUSED_PARAMETER(caller);
01871 UNUSED_PARAMETER(enactor);
01872 UNUSED_PARAMETER(nfargs);
01873 UNUSED_PARAMETER(cargs);
01874 UNUSED_PARAMETER(ncargs);
01875
01876 double val;
01877
01878 val = mux_atof(fargs[0]);
01879 #ifndef HAVE_IEEE_FP_SNAN
01880 if (val < 0.0)
01881 {
01882 safe_str("Ind", buff, bufc);
01883 }
01884 else if (val == 0.0)
01885 {
01886 safe_str("-Inf", buff, bufc);
01887 }
01888 else
01889 {
01890 mux_FPRestore();
01891 val = log10(val);
01892 mux_FPSet();
01893 }
01894 #else
01895 mux_FPRestore();
01896 val = log10(val);
01897 mux_FPSet();
01898 #endif
01899 fval(buff, bufc, val);
01900 }
01901
01902 FUNCTION(fun_sqrt)
01903 {
01904 UNUSED_PARAMETER(executor);
01905 UNUSED_PARAMETER(caller);
01906 UNUSED_PARAMETER(enactor);
01907 UNUSED_PARAMETER(nfargs);
01908 UNUSED_PARAMETER(cargs);
01909 UNUSED_PARAMETER(ncargs);
01910
01911 double val;
01912
01913 val = mux_atof(fargs[0]);
01914 #ifndef HAVE_IEEE_FP_SNAN
01915 if (val < 0.0)
01916 {
01917 safe_str("Ind", buff, bufc);
01918 }
01919 else if (val == 0.0)
01920 {
01921 safe_chr('0', buff, bufc);
01922 }
01923 else
01924 {
01925 mux_FPRestore();
01926 val = sqrt(val);
01927 mux_FPSet();
01928 }
01929 #else
01930 mux_FPRestore();
01931 val = sqrt(val);
01932 mux_FPSet();
01933 #endif
01934 fval(buff, bufc, val);
01935 }
01936
01937
01938
01939
01940
01941 FUNCTION(fun_isnum)
01942 {
01943 UNUSED_PARAMETER(executor);
01944 UNUSED_PARAMETER(caller);
01945 UNUSED_PARAMETER(enactor);
01946 UNUSED_PARAMETER(nfargs);
01947 UNUSED_PARAMETER(cargs);
01948 UNUSED_PARAMETER(ncargs);
01949
01950 safe_bool(is_real(fargs[0]), buff, bufc);
01951 }
01952
01953
01954
01955
01956
01957 FUNCTION(fun_israt)
01958 {
01959 UNUSED_PARAMETER(executor);
01960 UNUSED_PARAMETER(caller);
01961 UNUSED_PARAMETER(enactor);
01962 UNUSED_PARAMETER(nfargs);
01963 UNUSED_PARAMETER(cargs);
01964 UNUSED_PARAMETER(ncargs);
01965
01966 safe_bool(is_rational(fargs[0]), buff, bufc);
01967 }
01968
01969
01970
01971
01972
01973 FUNCTION(fun_isint)
01974 {
01975 UNUSED_PARAMETER(executor);
01976 UNUSED_PARAMETER(caller);
01977 UNUSED_PARAMETER(enactor);
01978 UNUSED_PARAMETER(nfargs);
01979 UNUSED_PARAMETER(cargs);
01980 UNUSED_PARAMETER(ncargs);
01981
01982 safe_bool(is_integer(fargs[0], NULL), buff, bufc);
01983 }
01984
01985 FUNCTION(fun_and)
01986 {
01987 UNUSED_PARAMETER(executor);
01988 UNUSED_PARAMETER(caller);
01989 UNUSED_PARAMETER(enactor);
01990 UNUSED_PARAMETER(cargs);
01991 UNUSED_PARAMETER(ncargs);
01992
01993 bool val = true;
01994 for (int i = 0; i < nfargs && val; i++)
01995 {
01996 val = isTRUE(mux_atol(fargs[i]));
01997 }
01998 safe_bool(val, buff, bufc);
01999 }
02000
02001 FUNCTION(fun_or)
02002 {
02003 UNUSED_PARAMETER(executor);
02004 UNUSED_PARAMETER(caller);
02005 UNUSED_PARAMETER(enactor);
02006 UNUSED_PARAMETER(cargs);
02007 UNUSED_PARAMETER(ncargs);
02008
02009 bool val = false;
02010 for (int i = 0; i < nfargs && !val; i++)
02011 {
02012 val = isTRUE(mux_atol(fargs[i]));
02013 }
02014 safe_bool(val, buff, bufc);
02015 }
02016
02017 FUNCTION(fun_andbool)
02018 {
02019 UNUSED_PARAMETER(executor);
02020 UNUSED_PARAMETER(caller);
02021 UNUSED_PARAMETER(enactor);
02022 UNUSED_PARAMETER(cargs);
02023 UNUSED_PARAMETER(ncargs);
02024
02025 bool val = true;
02026 for (int i = 0; i < nfargs && val; i++)
02027 {
02028 val = xlate(fargs[i]);
02029 }
02030 safe_bool(val, buff, bufc);
02031 }
02032
02033 FUNCTION(fun_orbool)
02034 {
02035 UNUSED_PARAMETER(executor);
02036 UNUSED_PARAMETER(caller);
02037 UNUSED_PARAMETER(enactor);
02038 UNUSED_PARAMETER(cargs);
02039 UNUSED_PARAMETER(ncargs);
02040
02041 bool val = false;
02042 for (int i = 0; i < nfargs && !val; i++)
02043 {
02044 val = xlate(fargs[i]);
02045 }
02046 safe_bool(val, buff, bufc);
02047 }
02048
02049 FUNCTION(fun_cand)
02050 {
02051 bool val = true;
02052 char *temp = alloc_lbuf("fun_cand");
02053 for (int i = 0; i < nfargs && val && !MuxAlarm.bAlarmed; i++)
02054 {
02055 char *bp = temp;
02056 char *str = fargs[i];
02057 mux_exec(temp, &bp, executor, caller, enactor,
02058 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, cargs, ncargs);
02059 *bp = '\0';
02060 val = isTRUE(mux_atol(temp));
02061 }
02062 free_lbuf(temp);
02063 safe_bool(val, buff, bufc);
02064 }
02065
02066 FUNCTION(fun_cor)
02067 {
02068 bool val = false;
02069 char *temp = alloc_lbuf("fun_cor");
02070 for (int i = 0; i < nfargs && !val && !MuxAlarm.bAlarmed; i++)
02071 {
02072 char *bp = temp;
02073 char *str = fargs[i];
02074 mux_exec(temp, &bp, executor, caller, enactor,
02075 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, cargs, ncargs);
02076 *bp = '\0';
02077 val = isTRUE(mux_atol(temp));
02078 }
02079 free_lbuf(temp);
02080 safe_bool(val, buff, bufc);
02081 }
02082
02083 FUNCTION(fun_candbool)
02084 {
02085 bool val = true;
02086 char *temp = alloc_lbuf("fun_candbool");
02087 for (int i = 0; i < nfargs && val && !MuxAlarm.bAlarmed; i++)
02088 {
02089 char *bp = temp;
02090 char *str = fargs[i];
02091 mux_exec(temp, &bp, executor, caller, enactor,
02092 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, cargs, ncargs);
02093 *bp = '\0';
02094 val = xlate(temp);
02095 }
02096 free_lbuf(temp);
02097 safe_bool(val, buff, bufc);
02098 }
02099
02100 FUNCTION(fun_corbool)
02101 {
02102 bool val = false;
02103 char *temp = alloc_lbuf("fun_corbool");
02104 for (int i = 0; i < nfargs && !val && !MuxAlarm.bAlarmed; i++)
02105 {
02106 char *bp = temp;
02107 char *str = fargs[i];
02108 mux_exec(temp, &bp, executor, caller, enactor,
02109 EV_STRIP_CURLY | EV_FCHECK | EV_EVAL, &str, cargs, ncargs);
02110 *bp = '\0';
02111 val = xlate(temp);
02112 }
02113 free_lbuf(temp);
02114 safe_bool(val, buff, bufc);
02115 }
02116
02117 FUNCTION(fun_xor)
02118 {
02119 UNUSED_PARAMETER(executor);
02120 UNUSED_PARAMETER(caller);
02121 UNUSED_PARAMETER(enactor);
02122 UNUSED_PARAMETER(cargs);
02123 UNUSED_PARAMETER(ncargs);
02124
02125 bool val = false;
02126 for (int i = 0; i < nfargs; i++)
02127 {
02128 int tval = mux_atol(fargs[i]);
02129 val = (val && !tval) || (!val && tval);
02130 }
02131 safe_bool(val, buff, bufc);
02132 }
02133
02134 FUNCTION(fun_not)
02135 {
02136 UNUSED_PARAMETER(executor);
02137 UNUSED_PARAMETER(caller);
02138 UNUSED_PARAMETER(enactor);
02139 UNUSED_PARAMETER(nfargs);
02140 UNUSED_PARAMETER(cargs);
02141 UNUSED_PARAMETER(ncargs);
02142
02143 safe_bool(!xlate(fargs[0]), buff, bufc);
02144 }
02145
02146 FUNCTION(fun_t)
02147 {
02148 UNUSED_PARAMETER(executor);
02149 UNUSED_PARAMETER(caller);
02150 UNUSED_PARAMETER(enactor);
02151 UNUSED_PARAMETER(cargs);
02152 UNUSED_PARAMETER(ncargs);
02153
02154 if ( nfargs <= 0
02155 || fargs[0][0] == '\0')
02156 {
02157 safe_chr('0', buff, bufc);
02158 }
02159 else
02160 {
02161 safe_bool(xlate(fargs[0]), buff, bufc);
02162 }
02163 }
02164 static const char *bigones[] =
02165 {
02166 "",
02167 "thousand",
02168 "million",
02169 "billion",
02170 "trillion"
02171 };
02172
02173 static const char *singles[] =
02174 {
02175 "",
02176 "one",
02177 "two",
02178 "three",
02179 "four",
02180 "five",
02181 "six",
02182 "seven",
02183 "eight",
02184 "nine"
02185 };
02186
02187 static const char *teens[] =
02188 {
02189 "ten",
02190 "eleven",
02191 "twelve",
02192 "thirteen",
02193 "fourteen",
02194 "fifteen",
02195 "sixteen",
02196 "seventeen",
02197 "eighteen",
02198 "nineteen"
02199 };
02200
02201 static const char *tens[] =
02202 {
02203 "",
02204 "",
02205 "twenty",
02206 "thirty",
02207 "forty",
02208 "fifty",
02209 "sixty",
02210 "seventy",
02211 "eighty",
02212 "ninety"
02213 };
02214
02215 static const char *th_prefix[] =
02216 {
02217 "",
02218 "ten",
02219 "hundred"
02220 };
02221
02222 class CSpellNum
02223 {
02224 public:
02225 void SpellNum(const char *p, char *buff_arg, char **bufc_arg);
02226
02227 private:
02228 void TwoDigits(const char *p);
02229 void ThreeDigits(const char *p, int iBigOne);
02230 void ManyDigits(int n, const char *p, bool bHundreds);
02231 void FractionalDigits(int n, const char *p);
02232
02233 void StartWord(void);
02234 void AddWord(const char *p);
02235
02236 char *buff;
02237 char **bufc;
02238 bool bNeedSpace;
02239 };
02240
02241 void CSpellNum::StartWord(void)
02242 {
02243 if (bNeedSpace)
02244 {
02245 safe_chr(' ', buff, bufc);
02246 }
02247 bNeedSpace = true;
02248 }
02249
02250 void CSpellNum::AddWord(const char *p)
02251 {
02252 safe_str(p, buff, bufc);
02253 }
02254
02255
02256
02257 void CSpellNum::TwoDigits(const char *p)
02258 {
02259 int n0 = p[0] - '0';
02260 int n1 = p[1] - '0';
02261
02262 if (n0 == 0)
02263 {
02264 if (n1 != 0)
02265 {
02266 StartWord();
02267 AddWord(singles[n1]);
02268 }
02269 return;
02270 }
02271 else if (n0 == 1)
02272 {
02273 StartWord();
02274 AddWord(teens[n1]);
02275 return;
02276 }
02277 if (n1 == 0)
02278 {
02279 StartWord();
02280 AddWord(tens[n0]);
02281 }
02282 else
02283 {
02284 StartWord();
02285 AddWord(tens[n0]);
02286 AddWord("-");
02287 AddWord(singles[n1]);
02288 }
02289 }
02290
02291
02292
02293 void CSpellNum::ThreeDigits(const char *p, int iBigOne)
02294 {
02295 if ( p[0] == '0'
02296 && p[1] == '0'
02297 && p[2] == '0')
02298 {
02299 return;
02300 }
02301
02302
02303
02304 if (p[0] != '0')
02305 {
02306 StartWord();
02307 AddWord(singles[p[0]-'0']);
02308 StartWord();
02309 AddWord("hundred");
02310 }
02311 TwoDigits(p+1);
02312 if (iBigOne > 0)
02313 {
02314 StartWord();
02315 AddWord(bigones[iBigOne]);
02316 }
02317 }
02318
02319
02320
02321 void CSpellNum::ManyDigits(int n, const char *p, bool bHundreds)
02322 {
02323
02324
02325 if ( bHundreds
02326 && n == 4
02327 && p[1] != '0')
02328 {
02329 TwoDigits(p);
02330 StartWord();
02331 AddWord("hundred");
02332 TwoDigits(p+2);
02333 return;
02334 }
02335
02336
02337
02338 int ndiv = ((n + 2) / 3) - 1;
02339 int nrem = n % 3;
02340 char buf[3];
02341 if (nrem == 0)
02342 {
02343 nrem = 3;
02344 }
02345
02346 int j = nrem;
02347 for (int i = 2; 0 <= i; i--)
02348 {
02349 if (j)
02350 {
02351 j--;
02352 buf[i] = p[j];
02353 }
02354 else
02355 {
02356 buf[i] = '0';
02357 }
02358 }
02359 ThreeDigits(buf, ndiv);
02360 p += nrem;
02361 while (ndiv-- > 0)
02362 {
02363 ThreeDigits(p, ndiv);
02364 p += 3;
02365 }
02366 }
02367
02368
02369
02370 void CSpellNum::FractionalDigits(int n, const char *p)
02371 {
02372 ManyDigits(n, p, false);
02373 if ( 0 < n
02374 && n < 15)
02375 {
02376 int d = n / 3;
02377 int r = n % 3;
02378 StartWord();
02379 if (r != 0)
02380 {
02381 AddWord(th_prefix[r]);
02382 if (d != 0)
02383 {
02384 AddWord("-");
02385 }
02386 }
02387 AddWord(bigones[d]);
02388 AddWord("th");
02389 INT64 i64 = mux_atoi64(p);
02390 if (i64 != 1)
02391 {
02392 AddWord("s");
02393 }
02394 }
02395 }
02396
02397 void CSpellNum::SpellNum(const char *number, char *buff_arg, char **bufc_arg)
02398 {
02399 buff = buff_arg;
02400 bufc = bufc_arg;
02401 bNeedSpace = false;
02402
02403
02404
02405 while (mux_isspace(*number))
02406 {
02407 number++;
02408 }
02409
02410 if (*number == '-')
02411 {
02412 StartWord();
02413 AddWord("negative");
02414 number++;
02415 }
02416
02417
02418
02419 while (*number == '0')
02420 {
02421 number++;
02422 }
02423
02424 const char *pA = number;
02425 while (mux_isdigit(*number))
02426 {
02427 number++;
02428 }
02429 size_t nA = number - pA;
02430
02431 const char *pB = NULL;
02432 size_t nB = 0;
02433 if (*number == '.')
02434 {
02435 number++;
02436 pB = number;
02437 while (mux_isdigit(*number))
02438 {
02439 number++;
02440 }
02441 nB = number - pB;
02442 }
02443
02444
02445
02446 while (mux_isspace(*number))
02447 {
02448 number++;
02449 }
02450
02451 if ( *number
02452 || nA >= 16
02453 || nB >= 15)
02454 {
02455 safe_str("#-1 ARGUMENT MUST BE A NUMBER", buff, bufc);
02456 return;
02457 }
02458
02459 if (nA == 0)
02460 {
02461 if (nB == 0)
02462 {
02463 StartWord();
02464 AddWord("zero");
02465 }
02466 }
02467 else
02468 {
02469 ManyDigits(nA, pA, true);
02470 if (nB)
02471 {
02472 StartWord();
02473 AddWord("and");
02474 }
02475 }
02476 if (nB)
02477 {
02478 FractionalDigits(nB, pB);
02479 }
02480 }
02481
02482 FUNCTION(fun_spellnum)
02483 {
02484 UNUSED_PARAMETER(executor);
02485 UNUSED_PARAMETER(caller);
02486 UNUSED_PARAMETER(enactor);
02487 UNUSED_PARAMETER(nfargs);
02488 UNUSED_PARAMETER(cargs);
02489 UNUSED_PARAMETER(ncargs);
02490
02491 CSpellNum sn;
02492 sn.SpellNum(fargs[0], buff, bufc);
02493 }
02494
02495 FUNCTION(fun_roman)
02496 {
02497 UNUSED_PARAMETER(executor);
02498 UNUSED_PARAMETER(caller);
02499 UNUSED_PARAMETER(enactor);
02500 UNUSED_PARAMETER(nfargs);
02501 UNUSED_PARAMETER(cargs);
02502 UNUSED_PARAMETER(ncargs);
02503
02504 const char *number = fargs[0];
02505
02506
02507
02508 while (mux_isspace(*number))
02509 {
02510 number++;
02511 }
02512
02513
02514
02515 while (*number == '0')
02516 {
02517 number++;
02518 }
02519
02520 const char *pA = number;
02521 while (mux_isdigit(*number))
02522 {
02523 number++;
02524 }
02525 size_t nA = number - pA;
02526
02527
02528
02529 while (mux_isspace(*number))
02530 {
02531 number++;
02532 }
02533
02534
02535
02536 if (*number || nA < 1)
02537 {
02538 safe_str("#-1 ARGUMENT MUST BE A POSITIVE NUMBER", buff, bufc);
02539 return;
02540 }
02541 else if ( nA > 4
02542 || ( nA == 1
02543 && pA[0] == '0')
02544 || ( nA == 4
02545 && '3' < pA[0]))
02546 {
02547 safe_range(buff, bufc);
02548 return;
02549 }
02550
02551
02552
02553
02554
02555
02556
02557
02558 static const char aLetters[4][3] =
02559 {
02560 { 'I', 'V', 'X' },
02561 { 'X', 'L', 'C' },
02562 { 'C', 'D', 'M' },
02563 { 'M', ' ', ' ' }
02564 };
02565
02566 static const char *aCode[10] =
02567 {
02568 "",
02569 "1",
02570 "11",
02571 "111",
02572 "12",
02573 "2",
02574 "21",
02575 "211",
02576 "2111",
02577 "13"
02578 };
02579
02580 while (nA--)
02581 {
02582 const char *pCode = aCode[*pA - '0'];
02583 const char *pLetters = aLetters[nA];
02584
02585 while (*pCode)
02586 {
02587 safe_chr(pLetters[*pCode - '1'], buff, bufc);
02588 pCode++;
02589 }
02590 pA++;
02591 }
02592 }
02593
02594
02595
02596
02597
02598 FUNCTION(fun_land)
02599 {
02600 UNUSED_PARAMETER(executor);
02601 UNUSED_PARAMETER(caller);
02602 UNUSED_PARAMETER(enactor);
02603 UNUSED_PARAMETER(cargs);
02604 UNUSED_PARAMETER(ncargs);
02605
02606 bool bValue = true;
02607 if (0 < nfargs)
02608 {
02609 SEP sep;
02610 if (!OPTIONAL_DELIM(2, sep, DELIM_DFLT|DELIM_STRING))
02611 {
02612 return;
02613 }
02614
02615 char *cp = trim_space_sep(fargs[0], &sep);
02616 while (cp && bValue)
02617 {
02618 char *curr = split_token(&cp, &sep);
02619 bValue = isTRUE(mux_atol(curr));
02620 }
02621 }
02622 safe_bool(bValue, buff, bufc);
02623 }
02624
02625 FUNCTION(fun_lor)
02626 {
02627 UNUSED_PARAMETER(executor);
02628 UNUSED_PARAMETER(caller);
02629 UNUSED_PARAMETER(enactor);
02630 UNUSED_PARAMETER(cargs);
02631 UNUSED_PARAMETER(ncargs);
02632
02633 bool bValue = false;
02634 if (0 < nfargs)
02635 {
02636 SEP sep;
02637 if (!OPTIONAL_DELIM(2, sep, DELIM_DFLT|DELIM_STRING))
02638 {
02639 return;
02640 }
02641
02642 char *cp = trim_space_sep(fargs[0], &sep);
02643 while (cp && !bValue)
02644 {
02645 char *curr = split_token(&cp, &sep);
02646 bValue = isTRUE(mux_atol(curr));
02647 }
02648 }
02649 safe_bool(bValue, buff, bufc);
02650 }
02651
02652 FUNCTION(fun_band)
02653 {
02654 UNUSED_PARAMETER(executor);
02655 UNUSED_PARAMETER(caller);
02656 UNUSED_PARAMETER(enactor);
02657 UNUSED_PARAMETER(cargs);
02658 UNUSED_PARAMETER(ncargs);
02659
02660 UINT64 val = UINT64_MAX_VALUE;
02661 for (int i = 0; i < nfargs; i++)
02662 {
02663 if (is_integer(fargs[i], NULL))
02664 {
02665 val &= mux_atoi64(fargs[i]);
02666 }
02667 else
02668 {
02669 safe_str("#-1 ARGUMENTS MUST BE INTEGERS", buff, bufc);
02670 return;
02671 }
02672 }
02673 safe_i64toa(val, buff, bufc);
02674 }
02675
02676 FUNCTION(fun_bor)
02677 {
02678 UNUSED_PARAMETER(executor);
02679 UNUSED_PARAMETER(caller);
02680 UNUSED_PARAMETER(enactor);
02681 UNUSED_PARAMETER(cargs);
02682 UNUSED_PARAMETER(ncargs);
02683
02684 UINT64 val = 0;
02685 for (int i = 0; i < nfargs; i++)
02686 {
02687 if (is_integer(fargs[i], NULL))
02688 {
02689 val |= mux_atoi64(fargs[i]);
02690 }
02691 else
02692 {
02693 safe_str("#-1 ARGUMENTS MUST BE INTEGERS", buff, bufc);
02694 return;
02695 }
02696 }
02697 safe_i64toa(val, buff, bufc);
02698 }
02699
02700 FUNCTION(fun_bnand)
02701 {
02702 UNUSED_PARAMETER(executor);
02703 UNUSED_PARAMETER(caller);
02704 UNUSED_PARAMETER(enactor);
02705 UNUSED_PARAMETER(nfargs);
02706 UNUSED_PARAMETER(cargs);
02707 UNUSED_PARAMETER(ncargs);
02708
02709 if ( is_integer(fargs[0], NULL)
02710 && is_integer(fargs[1], NULL))
02711 {
02712 INT64 a = mux_atoi64(fargs[0]);
02713 INT64 b = mux_atoi64(fargs[1]);
02714 safe_i64toa(a & ~(b), buff, bufc);
02715 }
02716 else
02717 {
02718 safe_str("#-1 ARGUMENTS MUST BE INTEGERS", buff, bufc);
02719 }
02720 }
02721
02722 FUNCTION(fun_bxor)
02723 {
02724 UNUSED_PARAMETER(executor);
02725 UNUSED_PARAMETER(caller);
02726 UNUSED_PARAMETER(enactor);
02727 UNUSED_PARAMETER(cargs);
02728 UNUSED_PARAMETER(ncargs);
02729
02730 UINT64 val = 0;
02731 for (int i = 0; i < nfargs; i++)
02732 {
02733 if (is_integer(fargs[i], NULL))
02734 {
02735 val ^= mux_atoi64(fargs[i]);
02736 }
02737 else
02738 {
02739 safe_str("#-1 ARGUMENTS MUST BE INTEGERS", buff, bufc);
02740 return;
02741 }
02742 }
02743 safe_i64toa(val, buff, bufc);
02744 }
02745
02746 FUNCTION(fun_crc32)
02747 {
02748 UNUSED_PARAMETER(executor);
02749 UNUSED_PARAMETER(caller);
02750 UNUSED_PARAMETER(enactor);
02751 UNUSED_PARAMETER(cargs);
02752 UNUSED_PARAMETER(ncargs);
02753
02754 UINT32 ulCRC32 = 0;
02755 for (int i = 0; i < nfargs; i++)
02756 {
02757 int n = strlen(fargs[i]);
02758 ulCRC32 = CRC32_ProcessBuffer(ulCRC32, fargs[i], n);
02759 }
02760 safe_i64toa(ulCRC32, buff, bufc);
02761 }
02762
02763 FUNCTION(fun_sha1)
02764 {
02765 UNUSED_PARAMETER(executor);
02766 UNUSED_PARAMETER(caller);
02767 UNUSED_PARAMETER(enactor);
02768 UNUSED_PARAMETER(cargs);
02769 UNUSED_PARAMETER(ncargs);
02770
02771 int i;
02772 SHA1_CONTEXT shac;
02773 SHA1_Init(&shac);
02774 for (i = 0; i < nfargs; i++)
02775 {
02776 SHA1_Compute(&shac, strlen(fargs[i]), fargs[i]);
02777 }
02778 SHA1_Final(&shac);
02779 for (i = 0; i <= 4; i++)
02780 {
02781 char buf[9];
02782 sprintf(buf, "%08X", shac.H[i]);
02783 safe_str(buf, buff, bufc);
02784 }
02785 }