home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rexxma.zip / REXXMATH.C < prev    next >
C/C++ Source or Header  |  1994-03-22  |  9KB  |  365 lines

  1. /**********************************************************************
  2. *   REXXMATH.c - (c) Zhitao Zeng Footprint Software 1994              *
  3. *   This program is released to the public domain, feel free to use   *
  4. *   it for any purposes.                                              *
  5. *   If you have any suggestions, please email to Zhitao Zeng at:      *
  6. *      CIS: 72000,2440                                                *
  7. *      Internet: zzeng@footprint.com                                  *
  8. **********************************************************************/
  9.  
  10. #define  INCL_ERRORS
  11. #define  INCL_REXXSAA
  12. #define  _DLL
  13. #define  _MT
  14. #include <os2.h>
  15. #include <rexxsaa.h>
  16. #include <float.h>
  17. #include <fcntl.h>
  18. #include <ctype.h>
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <math.h>
  23.  
  24. #define  ENABLE_CACHE
  25.  
  26. RexxFunctionHandler MathLoadFuncs;
  27. RexxFunctionHandler MathDropFuncs;
  28. RexxFunctionHandler MathFunc;
  29.  
  30. typedef enum _MathFuncID {
  31.     fn_acos,
  32.     fn_asin, 
  33.     fn_atan, 
  34.     fn_atan2,
  35.     fn_ceil, 
  36.     fn_cos,  
  37.     fn_cosh, 
  38.     fn_exp,  
  39.     fn_fabs, 
  40.     fn_floor,
  41.     fn_fmod, 
  42.     fn_frexp,
  43.     fn_ldexp,
  44.     fn_log,  
  45.     fn_log10,
  46.     fn_modf, 
  47.     fn_pow,  
  48.     fn_sin,  
  49.     fn_sinh, 
  50.     fn_sqrt, 
  51.     fn_tan, 
  52.     fn_tanh,
  53.     fn_erf,
  54.     fn_erfc,  
  55.     fn_gamma,
  56.     fn_hypot, 
  57.     fn_j0,    
  58.     fn_j1,    
  59.     fn_jn,    
  60.     fn_y0,    
  61.     fn_y1,    
  62.     fn_yn,
  63.     fn_pi
  64. } MathFuncID;
  65.  
  66. typedef struct _RxMathFunc
  67. {
  68.     PSZ        name;
  69.     MathFuncID id;
  70.     ULONG      numargs;
  71. } RxMathFunc, *PRxMathFunc;
  72.  
  73. static RxMathFunc RxMathFncTable[] =
  74. {
  75.     "acos",      fn_acos,    1,
  76.     "asin",       fn_asin,       1,
  77.     "atan",       fn_atan,       1,
  78.     "atan2",      fn_atan2,      2,
  79.     "ceil",       fn_ceil,       1,
  80.     "cos",        fn_cos,        1,
  81.     "cosh",       fn_cosh,       1,
  82.     "exp",        fn_exp,        1,
  83.     "fabs",       fn_fabs,       1,
  84.     "floor",      fn_floor,      1,
  85.     "fmod",       fn_fmod,       2,
  86.     "frexp",      fn_frexp,      1,
  87.     "ldexp",      fn_ldexp,      2,
  88.     "log",        fn_log,        1,
  89.     "log10",      fn_log10,      1,
  90.     "modf",       fn_modf,       1,
  91.     "pow",        fn_pow,        2,
  92.     "sin",        fn_sin,        1,
  93.     "sinh",       fn_sinh,       1,
  94.     "sqrt",       fn_sqrt,       1,
  95.     "tan",       fn_tan,       1,
  96.     "tanh",      fn_tanh,      1,
  97.    "erf",      fn_erf,      1,
  98.    "erfc",    fn_erfc,    1,
  99.    "gamma",   fn_gamma,   1,
  100.    "hypot",   fn_hypot,   2,
  101.    "j0",      fn_j0,      1,
  102.    "j1",      fn_j1,      1,
  103.    "jn",      fn_jn,      2,
  104.    "y0",      fn_y0,      1,
  105.    "y1",      fn_y1,      1,
  106.    "yn",      fn_yn,      2,
  107.    "pi",      fn_pi,      0,
  108. };
  109.  
  110. #ifdef ENABLE_CACHE
  111. static RxMathFunc RxMathFncCache =
  112. {
  113.     "",      -1,    0,
  114. };
  115. #endif                                  
  116.  
  117. #define  INVALID_ROUTINE 40            /* Error                      */
  118. #define  VALID_ROUTINE    0            /* Successful completion      */
  119.  
  120. /*************************************************************************
  121. * Function:  MathLoadFuncs                                               *
  122. * Syntax:    call MathLoadFuncs [option]                                 *
  123. * Return:    null string                                                 *
  124. *************************************************************************/
  125.  
  126. ULONG MathLoadFuncs(CHAR *name, ULONG numargs, RXSTRING args[],
  127.                            CHAR *queuename, RXSTRING *retstr)
  128. {
  129.   INT    entries;                      /* Num of entries             */
  130.   INT    j;                            /* Counter                    */
  131.  
  132.   retstr->strlength = 0;               /* set return value           */
  133.  
  134.   entries = sizeof(RxMathFncTable)/sizeof(RxMathFunc);
  135.  
  136.   RexxRegisterFunctionDll("MathLoadFuncs", "REXXMATH", "MathLoadFuncs");
  137.   RexxRegisterFunctionDll("MathDropFuncs", "REXXMATH", "MathDropFuncs");
  138.  
  139.   for (j = 0; j < entries; j++) {
  140.     RexxRegisterFunctionDll(RxMathFncTable[j].name,
  141.           "REXXMATH", "MathFunc");
  142.   }
  143.   return VALID_ROUTINE;
  144. }
  145.  
  146.  
  147. /*************************************************************************
  148. * Function:  MathDropFuncs                                               *
  149. * Syntax:    call MathDropFuncs                                          *
  150. * Return:    NO_UTIL_ERROR - Successful.                                 *
  151. *************************************************************************/
  152.  
  153. ULONG MathDropFuncs(CHAR *name, ULONG numargs, RXSTRING args[],
  154.                           CHAR *queuename, RXSTRING *retstr)
  155. {
  156.   INT     entries;                     /* Num of entries             */
  157.   INT     j;                           /* Counter                    */
  158.  
  159.   retstr->strlength = 0;               /* return a null string result*/
  160.  
  161.   RexxDeregisterFunction("MathLoadFuncs");
  162.   RexxDeregisterFunction("MathDropFuncs");
  163.  
  164.   entries = sizeof(RxMathFncTable)/sizeof(RxMathFunc);
  165.  
  166.   for (j = 0; j < entries; j++)
  167.     RexxDeregisterFunction(RxMathFncTable[j].name);
  168.  
  169.   return VALID_ROUTINE;                /* no error on call           */
  170. }
  171.  
  172. int resolve_func(CHAR *name, ULONG numargs)
  173. {
  174.     int entries = sizeof(RxMathFncTable)/sizeof(RxMathFunc);
  175.     register int i;
  176.     int fn_id = -1;
  177.  
  178.     for (i=0; i < entries; i++)
  179.         if (stricmp(name, RxMathFncTable[i].name) == 0)
  180.         {
  181.            if (numargs == RxMathFncTable[i].numargs)
  182.          {
  183.                 fn_id = RxMathFncTable[i].id;
  184. #ifdef ENABLE_CACHE
  185.                 RxMathFncCache.id = fn_id;
  186.                 RxMathFncCache.name = RxMathFncTable[i].name;
  187.                 RxMathFncCache.numargs = RxMathFncTable[i].numargs;
  188. #endif
  189.          }
  190.             break;
  191.         }
  192.  
  193.     return fn_id;
  194. }
  195.  
  196. #ifdef ENABLE_CACHE
  197. int cache_func(CHAR *name, ULONG numargs)
  198. {
  199.     int fn_id = -1;
  200.  
  201.     if (stricmp(name, RxMathFncCache.name) == 0)
  202.         if (numargs == RxMathFncCache.numargs)
  203.             fn_id = RxMathFncCache.id;
  204.  
  205.     return fn_id;
  206. }
  207. #endif
  208.  
  209. /*************************************************************************
  210. * Function:  MathFunc                                                    *
  211. *************************************************************************/
  212.  
  213. ULONG MathFunc(CHAR *name, ULONG numargs, RXSTRING args[],
  214.                         CHAR *queuename, RXSTRING *retstr)
  215. {
  216.     double x, y, result;
  217.     int i, fn_id = -1;
  218.  
  219. #ifdef ENABLE_CACHE
  220.    if (RxMathFncCache.id >= 0)
  221.       fn_id = cache_func(name, numargs);
  222.  
  223.    if (fn_id < 0)
  224.    {
  225.        fn_id = resolve_func(name, numargs);
  226.        if (fn_id < 0)           
  227.            return INVALID_ROUTINE;
  228.    }
  229. #else
  230.       fn_id = resolve_func(name, numargs);
  231.    if (fn_id < 0)           
  232.        return INVALID_ROUTINE;
  233. #endif
  234.  
  235.     x = atof(args[0].strptr);
  236.     if (numargs > 1L)
  237.     {
  238.         y = atof(args[1].strptr);
  239.         i = atoi(args[1].strptr);
  240.     }
  241.  
  242.     switch (fn_id)
  243.     {
  244.     case fn_acos:
  245.         result = acos(x);
  246.         break;
  247.     case fn_asin: 
  248.         result = asin(x);
  249.         break;
  250.     case fn_atan: 
  251.         result = atan(x);
  252.         break;
  253.     case fn_atan2:
  254.         result = atan2(x, y);
  255.         break;
  256.     case fn_ceil: 
  257.         result = ceil(x);
  258.         break;
  259.     case fn_cos:  
  260.         result = cos(x);
  261.         break;
  262.     case fn_cosh: 
  263.         result = cosh(x);
  264.         break;
  265.     case fn_exp:  
  266.         result = exp(x);
  267.         break;
  268.     case fn_fabs: 
  269.         result = fabs(x);
  270.         break;
  271.     case fn_floor:
  272.         result = floor(x);
  273.         break;
  274.     case fn_fmod: 
  275.         result = fmod(x, y);
  276.         break;
  277.     case fn_frexp:
  278.         result = frexp(x, &i);
  279.         break;
  280.     case fn_ldexp:
  281.         result = ldexp(x, i);
  282.         break;
  283.     case fn_log:  
  284.         result = log(x);
  285.         break;
  286.     case fn_log10:
  287.         result = log10(x);
  288.         break;
  289.     case fn_modf: 
  290.         result = modf(x, &y);
  291.         break;
  292.     case fn_pow:  
  293.         result = pow(x, y);
  294.         break;
  295.     case fn_sin:  
  296.         result = sin(x);
  297.         break;
  298.     case fn_sinh: 
  299.         result = sinh(x);
  300.         break;
  301.     case fn_sqrt: 
  302.         result = sqrt(x);
  303.         break;
  304.     case fn_tan: 
  305.         result = tan(x);
  306.         break;
  307.     case fn_tanh:
  308.         result = tanh(x);
  309.         break;
  310. #ifdef __IBMC__
  311.     case fn_erf:
  312.       result = erf( x );
  313.         break;
  314.     case fn_erfc:  
  315.       result = erfc( x );
  316.         break;
  317.     case fn_gamma: 
  318.       result = gamma( x );
  319.         break;
  320. #endif
  321.     case fn_hypot: 
  322.       result = hypot( x, y );
  323.         break;
  324.     case fn_j0:    
  325.       result = j0( x );
  326.         break;
  327.     case fn_j1:    
  328.       result = j1( x );
  329.         break;
  330.     case fn_jn:    
  331.       result = jn( i, x );
  332.         break;
  333.     case fn_y0:    
  334.       result = y0( x );
  335.         break;
  336.     case fn_y1:    
  337.       result = y1( x );
  338.         break;
  339.     case fn_yn:    
  340.       result = yn( i, x );
  341.         break;
  342.     case fn_pi:    
  343.       result = 3.1415926575;
  344.         break;
  345.    default:
  346.        return INVALID_ROUTINE;
  347.     }
  348.  
  349.     switch (fn_id)
  350.     {
  351.     case fn_frexp:
  352.         sprintf(retstr->strptr, "%lf %i", result, i);
  353.         break;
  354.     case fn_modf: 
  355.         sprintf(retstr->strptr, "%lf %lf", result, y);
  356.         break;
  357.     default:
  358.         sprintf(retstr->strptr, "%lf", result);
  359.         break;
  360.     }
  361.  
  362.     retstr->strlength = strlen(retstr->strptr);
  363.     return VALID_ROUTINE;
  364. }
  365.