Chapter Contents

Previous

Next
rxresult

An Example of a REXX Function Package

This example shows a REXX function package containing three trigonometric functions: csqrt , csin , and ccos . The routines in the package can be called either as functions or as subroutines from REXX.

A copy of this example program is provided with the compiler and library. See your SAS Software Representative for C compiler products for more information.

#include <cmsexec.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <options.h>

   /* Because this program cannot be invoked directly from the        */
   /* command line, run-time options should be specified via the      */
   /* '_options' variable. For example, int _options = _DEBUG;        */
static int csin(), ccos(), csqrt();
static double todouble();
static void result();

   /* Define the values of 'fncv' and 'fncc'.                         */
REXX_FNC funlist[] = {csin,ccos,csqrt};
#define NFUNCS sizeof(funlist)/sizeof(REXX_FNC)

void main(int argc, char *argv[]);
{
   int rc;
   rc = cmsrxfn(argc,argv,NFUNCS,funlist);
      /* A positive return code from cmsrxfn() indicates that either  */
      /* a NUCXDROP RXLOCFN was entered or an ABEND occurred under    */
      /* CMS.  A negative return code indicates that initialization   */
      /* did not complete.                                            */
   if (rc < 0)
      puts("RXLOCFN did not initialize.");
}

   /* Compute trigonometric sine.  Example:  x = csin(y)              */
static csin(struct REXX_PLIST args[]);
{
   register double r;
      /* Ensure that there is exactly one argument and that it is     */
      /* 15 or fewer characters long.  (Other validation is probably  */
      /* useful, but it has been omitted here.)                       */
   if (args->ad == REXX_LAST_AD || args->len > 15 ||
       args[1].ad != REXX_LAST_AD)
      return 1;
      /* Perform other parameter validation as necessary.             */
   r = todouble(args->ad,args->len);   /* Convert to double.          */
   r = sin(r);                         /* Get the sine.               */
   result(r);                          /* Set REXX 'result' variable. */
   return 0;                           /* Tell REXX it worked.        */
}

   /* Compute trigonometric cosine.  Example:  x= ccos(y)             */
static ccos(struct REXX_PLIST args[]);
{
   register double r;
   if (args->ad == REXX_LAST_AD || args->len > 15 ||
       args[1].ad != REXX_LAST_AD)
      return 1;
   r = todouble(args->ad,args->len);
   r = cos(r);
   result(r);
   return 0;
}

   /* Compute square root.  Example:  x = csqrt(y)                    */
static csqrt(struct REXX_PLIST args[]);
{
   register double r;
   if (args->ad == REXX_LAST_AD || args->len > 15 ||
       args[1].ad != REXX_LAST_AD)
      return 1;
   r = todouble(args->ad,args->len);
   if (r < 0.0)
      return 1;
   r = sqrt(r);
   result(r);
   return 0;
}

   /* Convert REXX parameter from Adlen to double.                    */
static double todouble(char *str, int len);
{
   char buff[16];                        /* Convert string to double. */
   double d;

      /* Copy to a temporary buffer and add a null terminator.        */
   memcpy(buff,str,len);
   buff[len] = '\0';
   d = strtod(buff,0);
   return d;             /* Return converted argument.                */
}

   /* Convert function result to char and set REXX result variable.   */
static void result(double r);
{
      /* Need enough room to handle leading 0, sign, decimal point,   */
      /* and exponent.                                                */
   char buff[15];
      /* This is similar to REXX's NUMERIC DIGITS 9 format.           */
   sprintf(buff,"%.9G",r);
   rxresult(buff);
}


Chapter Contents

Previous

Next

Top of Page

Copyright © 2001 by SAS Institute Inc., Cary, NC, USA. All rights reserved.