home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / RXCALC.ZIP / REXXCAL3.C < prev    next >
Text File  |  1992-02-17  |  32KB  |  615 lines

  1. /*********************************************************************/
  2. /*                                                                   */
  3. /* REXXCAL3 - A simple PM based pocket calculator                    */
  4. /*                                                                   */
  5. /*********************************************************************/
  6.  
  7. /* Standard C libraries */
  8.  
  9. #include <stdlib.h>
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <math.h>
  13.  
  14.  /* Include specific parts of the OS/2 and presentation manager      */
  15.  /* definitions                                                      */
  16.  
  17. #define INCL_WIN
  18. #include <os2.h>
  19. #define INCL_RXFUNC
  20. #include <rexxsaa.h>
  21.  
  22. /* Include the constants file created by the Dialog Box Editor.      */
  23. /* This include file defines symbols for all elements of the         */
  24. /* calculator dialog.                                                */
  25.  
  26. #include <rexxcal3.h>
  27.  
  28. /* Declare prototypes for all subroutines.                           */
  29.  
  30. INT main(VOID);                        /* Main PM calculator program */
  31.  
  32.                                        /* Calculator dialog          */
  33. MRESULT EXPENTRY Calculator(HWND, ULONG, MPARAM, MPARAM);
  34.                                        /* CalcForm external function */
  35. LONG    APIENTRY CalcForm(PSZ, LONG, PRXSTRING, PSZ, PRXSTRING);
  36.                                        /* CalcPrecision ext function */
  37. LONG    APIENTRY CalcPrecision(PSZ, LONG, PRXSTRING, PSZ, PRXSTRING);
  38. VOID    ProcessArithmetic(LONG);       /* Arithmetic processor       */
  39. VOID    AddDigit(INT);                 /* add digit to display       */
  40. VOID    SetDisplay(PRXSTRING);         /* set new display            */
  41. INT     ProcessProgram(PSZ);           /* process a programmed key   */
  42. INT     CheckWhole(PRXSTRING);         /* validate a whole number    */
  43.  
  44. /* Define some constants for the calculator dialog                   */
  45.  
  46. #define DISPLAY_WIDTH    20            /* width of display area      */
  47. #define MAX_DIGITS       18            /* maximum digits in display  */
  48. #define SCIENTIFIC        0            /* Scientific floating point  */
  49. #define ENGINEERING       1            /* Engineering floating point */
  50. #define YES               1            /* YES and NO constants (I    */
  51. #define NO                0            /* prefer these over TRUE and */
  52.                                        /* FALSE                      */
  53.  
  54. /* Global data used for the dialog                                   */
  55.  
  56.  HAB    hab;                           /* Anchor block handle        */
  57.  HWND   hwndCalc;                      /* Handle for calculator      */
  58.                                        /*   dialog (created using    */
  59.                                        /*   the dialog editor)       */
  60.  
  61. /* Global data used for the calculator                               */
  62.  
  63.  UCHAR    accbuff[DISPLAY_WIDTH + 1];  /* accumulator buffer         */
  64.  UCHAR    dispbuff[DISPLAY_WIDTH + 1]; /* display buffer             */
  65.  UCHAR    precision[MAX_DIGITS + 1];   /* current precision          */
  66.  INT      form;                        /* engineering/scientific flag*/
  67.  RXSTRING accumulator;                 /* current register value     */
  68.  RXSTRING display;                     /* current display            */
  69.  INT      oldaction;                   /* pending key action         */
  70.  INT      digits;                      /* digits in display          */
  71.  INT      hadperiod;                   /* period in number           */
  72.  INT      hadexponent;                 /* exponent in number         */
  73.  
  74.                                        /* table of external function */
  75.                                        /* macro names                */
  76. PUCHAR     operator_names[] = {
  77.     "MULTIPLY.CAL",                    /* * key                      */
  78.     "MINUS.CAL",                       /* - key                      */
  79.     "PLUS.CAL",                        /* + key                      */
  80.     "DIVIDE.CAL",                      /* / key                      */
  81.     "INTEGER.CAL",                     /* % key                      */
  82.     "REMAIND.CAL",                     /* // key                     */
  83.     "POWER.CAL",                       /* ** key                     */
  84.     "PROGRAM1.CAL",                    /* first program key          */
  85.     "PROGRAM2.CAL" };                  /* second program key         */
  86.  
  87. /*********************************************************************/
  88. /* main() - the main calculator program entry point                  */
  89. /*********************************************************************/
  90.  
  91. INT main()
  92. {
  93.   HMQ   hmq;                           /* Message queue handle       */
  94.   QMSG  qmsg;                          /* Receive PM queue message   */
  95.  
  96.                                        /* startup PM usage           */
  97.   hab = WinInitialize(0);              /* Get the anchor block handle*/
  98.   hmq = WinCreateMsgQueue(hab, 0);     /* Create the message queue   */
  99.                                        /* register our window class  */
  100.   WinRegisterClass(hab, "RexxCalc", Calculator, 0l, 0);
  101.  
  102.   /* Load the calculator dialog.  The dialog definitions are in      */
  103.   /* rexxcalc.rc                                                     */
  104.  
  105.   hwndCalc = WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP,
  106.                         NULL,
  107.                         0,
  108.                         REXXCALC,      /* Dialog ID                  */
  109.                         NULL);
  110.  
  111.   WinSendMsg(hwndCalc, WM_SETICON,     /* Set program icon           */
  112.       (MPARAM)WinLoadPointer(HWND_DESKTOP, 0, REXXCALC), NULL);
  113.  
  114.                                        /* set the window focus       */
  115.   WinSetFocus(HWND_DESKTOP,
  116.       WinWindowFromID(hwndCalc, FID_CLIENT));
  117.  
  118.   /* Process the standard Presentation Manager message loop until    */
  119.   /* we are told to terminate                                        */
  120.  
  121.                                        /* While more messages        */
  122.   while (WinGetMsg(hab, &qmsg, 0, 0, 0))
  123.      WinDispatchMsg(hab, &qmsg);       /* dispatch application       */
  124.                                        /*   message handler          */
  125.  
  126.  
  127.   /* The close option has been selected so we need to clean up       */
  128.   /* our context.                                                    */
  129.  
  130.   WinDestroyWindow(hwndCalc);          /* Destroy the dialog window  */
  131.   WinDestroyMsgQueue(hmq);             /* Destroy the message queue  */
  132.   WinTerminate(hab);                   /* Terminate PM usage         */
  133.   return (0);                          /* Indicate successful        */
  134.                                        /*   completion               */
  135. }
  136.  
  137. /*********************************************************************/
  138. /*                                                                   */
  139. /* Calculator() - the PM WinProc for handling the calculator dialog. */
  140. /* The dialog itself has been created using the dialog box editor.   */
  141. /* This seperates the actual form of the calculator from the program */
  142. /* source.                                                           */
  143. /*                                                                   */
  144. /*********************************************************************/
  145.  
  146. MRESULT EXPENTRY Calculator(
  147.   HWND    hwnd,                        /* window handle              */
  148.   ULONG   msg,                         /* dispatched message id      */
  149.   MPARAM  mp1,                         /* first message parameter    */
  150.   MPARAM  mp2 )                        /* second message parameter   */
  151. {
  152.   ULONG   action;                      /* Action to process          */
  153.  
  154.    switch (msg) {                      /* switch based on the message*/
  155.                                        /* received                   */
  156.  
  157.       /* The initialization message has been received.  We do some   */
  158.       /* additional fixup of the dialog to make it look a little     */
  159.       /* nicer.                                                      */
  160.  
  161.       case WM_INITDLG:
  162.  
  163.                                        /* initialize accumulator     */
  164.          MAKERXSTRING(accumulator, accbuff, 1);
  165.          strcpy(accbuff, "0");         /* fill in a zero             */
  166.          digits = 0;                   /* no digits in number        */
  167.          hadperiod = NO;               /* no period yet              */
  168.          hadexponent = NO;             /* no exponential yet         */
  169.          oldaction = 0;                /* no pending operations      */
  170.          strcpy(precision, "9");       /* set default precision      */
  171.          form = SCIENTIFIC;            /* set default form           */
  172.          SetDisplay(&accumulator);     /* set initial display value  */
  173.                                        /* update the calculator      */
  174.                                        /* display                    */
  175.          WinSetWindowText(WinWindowFromID(hwnd, DISPLAY),
  176.              display.strptr);
  177.                                        /* register our external      */
  178.                                        /* functions                  */
  179.          RexxRegisterFunctionExe("CalcPrecision", (PFN)CalcPrecision);
  180.          RexxRegisterFunctionExe("CalcForm", (PFN)CalcForm);
  181.  
  182.          return FALSE;                 /* initialization complete    */
  183.  
  184.       /* We are going away, time to post a quit message to the       */
  185.       /* message loop.                                               */
  186.  
  187.       case WM_CLOSE:
  188.  
  189.                                        /* Deregister our defined     */
  190.                                        /* functions                  */
  191.          RexxDeregisterFunction("CalcPrecision");
  192.          RexxDeregisterFunction("CalcForm");
  193.                                        /* Standard Close processing  */
  194.          WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
  195.          return FALSE;                 /* Exit now                   */
  196.  
  197.       /* We've received a WM_CONTROL message.  This was              */
  198.       /* generated by the "Form" check blox.                         */
  199.  
  200.       case WM_CONTROL:                 /* change current form        */
  201.  
  202.          action = SHORT1FROMMP(mp1);   /* Extract message sub-type   */
  203.  
  204.          switch (action) {             /* process the control        */
  205.  
  206.            case BUTTON_FORM:           /* form switch button         */
  207.  
  208.              if (form == SCIENTIFIC) { /* current scientific?        */
  209.                form = ENGINEERING;     /* make it engineering        */
  210.                                        /* update label               */
  211.                WinSetWindowText(WinWindowFromID(hwnd, BUTTON_FORM),
  212.                    "Engineering");
  213.              }
  214.              else {
  215.                form = SCIENTIFIC;      /* otherwise scientfic        */
  216.                WinSetWindowText(WinWindowFromID(hwnd, BUTTON_FORM),
  217.                   "Scientific");
  218.              }
  219.              return FALSE;             /* all done                   */
  220.            default:                    /* Unknown, can't handle this */
  221.              return FALSE;
  222.          }
  223.  
  224.       /* We've received a WM_COMMAND message.  WM_COMMAND messages   */
  225.       /* are generated by "pressing" buttons on the calculator.  The */
  226.       /* additional parameters in the received message identify the  */
  227.       /* button that was pressed                                     */
  228.  
  229.       case WM_COMMAND:
  230.  
  231.          action = SHORT1FROMMP(mp1);   /* Extract message sub-type   */
  232.  
  233.          switch (action) {
  234.  
  235.             /* The following buttons will be processed by the actual */
  236.             /* calculator routine                                    */
  237.  
  238.             case BUTTON_CLEAR:         /* Clear key                  */
  239.  
  240.                                        /* initialize accumulator     */
  241.               MAKERXSTRING(accumulator, accbuff, 1);
  242.               strcpy(accbuff, "0");    /* fill in a zero             */
  243.                                        /* initialize the display     */
  244.               MAKERXSTRING(display, dispbuff, 1);
  245.               strcpy(dispbuff, "0");   /* fill in a zero display     */
  246.               digits = 0;              /* no digits yet              */
  247.               hadperiod = NO;          /* turn off number processing */
  248.               hadexponent = NO;        /* flags.                     */
  249.               oldaction = 0;           /* and any pending operations */
  250.                                        /* update the calculator      */
  251.                                        /* display                    */
  252.               WinSetWindowText(WinWindowFromID(hwnd, DISPLAY),
  253.                   display.strptr);
  254.               return FALSE;            /* All done                   */
  255.  
  256.             case BUTTON_DIGITS:        /* set new digits             */
  257.                                        /* not a whole number?        */
  258.               if (!CheckWhole(&display))
  259.                                        /* give an error beep         */
  260.                 WinAlarm(HWND_DESKTOP, WA_ERROR);
  261.               else {                   /* process the number         */
  262.                                        /* copy the number            */
  263.                 strcpy(precision, display.strptr);
  264.                                        /* redisplay the accumlator   */
  265.                 SetDisplay(&accumulator);
  266.                                        /* display                    */
  267.                 WinSetWindowText(WinWindowFromID(hwnd, DISPLAY),
  268.                     display.strptr);
  269.               }
  270.               return FALSE;            /* All done                   */
  271.  
  272.             case BUTTON_0:             /* Numeric keys               */
  273.             case BUTTON_1:
  274.             case BUTTON_2:
  275.             case BUTTON_3:
  276.             case BUTTON_4:
  277.             case BUTTON_5:
  278.             case BUTTON_6:
  279.             case BUTTON_7:
  280.             case BUTTON_8:
  281.             case BUTTON_9:
  282.             case BUTTON_PERIOD:        /* decimal point              */
  283.             case BUTTON_EXPONENT:      /* exponent value             */
  284.             case BUTTON_SIGN:          /* sign change                */
  285.  
  286.                                        /* Add a digit to display     */
  287.               AddDigit(action);
  288.                                        /* update the accumulator     */
  289.                                        /* display                    */
  290.               WinSetWindowText(WinWindowFromID(hwnd, DISPLAY),
  291.                     display.strptr);
  292.               return FALSE;            /* All done                   */
  293.  
  294.             /* The arithmetic operation keys all have a deferred     */
  295.             /* execution.  When one of these is pressed, the previous*/
  296.             /* arithmetic operation is processed using the           */
  297.             /* accumulator and the current display.  The new operator*/
  298.             /* is saved for later execution.  If no operator exists, */
  299.             /* then the current display is moved to the accumulator  */
  300.             /* and no arithmetic is done                             */
  301.  
  302.             case BUTTON_MULTIPLY:      /* Multiply key               */
  303.             case BUTTON_DIVIDE:        /* Division key               */
  304.             case BUTTON_PLUS:          /* Addition key               */
  305.             case BUTTON_MINUS:         /* Subtraction key            */
  306.             case BUTTON_IDIV:          /* integer division           */
  307.             case BUTTON_REMAINDER:     /* remainder division         */
  308.             case BUTTON_POWER:         /* raise a number to power    */
  309.             case BUTTON_ENTER:         /* "Total" key                */
  310.             case BUTTON_PROGRAM1:      /* programmed Rexx function   */
  311.             case BUTTON_PROGRAM2:      /* programmed Rexx function   */
  312.  
  313.                                        /* Process pending operations */
  314.               ProcessArithmetic(action);
  315.               SetDisplay(&accumulator);/* reset display buffer       */
  316.                                        /* update the calculator      */
  317.                                        /* display                    */
  318.               WinSetWindowText(WinWindowFromID(hwnd, DISPLAY),
  319.                     accumulator.strptr);
  320.               return FALSE;            /* All done                   */
  321.  
  322.             default:                   /* Unknown, can't handle this */
  323.                return FALSE;
  324.          }
  325.  
  326.       case WM_ERASEBACKGROUND:         /* disable background erase   */
  327.         return MRFROMLONG(TRUE);       /* don't allow this           */
  328.  
  329.       /* Message not handled by us.  PM gives us first chance at all */
  330.       /* messages.  Those we don't want to process we pass on to the */
  331.       /* default dialog procedure.                                   */
  332.  
  333.       default:
  334.          return WinDefWindowProc(hwnd, msg, mp1, mp2);
  335.  
  336.    }
  337.  
  338.    return FALSE;                       /* Should never reach here    */
  339.  }
  340.  
  341. /*********************************************************************/
  342. /*                                                                   */
  343. /* AddDigit(digit) - add a digit to the calculator display           */
  344. /*                                                                   */
  345. /*********************************************************************/
  346.  
  347. VOID AddDigit(
  348. INT    digit )                         /* new digit to add           */
  349. {
  350.  
  351.   if (digit == BUTTON_SIGN) {          /* negate number              */
  352.     if (!digits ||                     /* first press?               */
  353.                                        /* sign after exponent?       */
  354.         display.strptr[digits-1] == 'E') {
  355.       display.strptr[digits++] = '-';  /* add the minus sign         */
  356.       display.strptr[digits] = '\0';   /* add new string terminator  */
  357.       display.strlength = digits;      /* keep length in check       */
  358.     }
  359.     else                               /* invalid sign press         */
  360.       WinAlarm(HWND_DESKTOP, WA_ERROR);/* beep at the user           */
  361.   }
  362.  
  363.   else if (digit == BUTTON_PERIOD) {   /* decimal point              */
  364.     if (hadperiod ||                   /* have one already?          */
  365.         hadexponent ||                 /* or an exponent?            */
  366.         digits >= MAX_DIGITS)          /* or too big                 */
  367.       WinAlarm(HWND_DESKTOP, WA_ERROR);/* beep at the user           */
  368.     else {                             /* add a decimal point        */
  369.       if (!digits)                     /* have digits already?       */
  370.         display.strptr[digits++] = '0';/* no, add leading zero       */
  371.       display.strptr[digits++] = '.';  /* add the decimal point      */
  372.       display.strptr[digits] = '\0';   /* add new string terminator  */
  373.       display.strlength = digits;      /* keep length in check       */
  374.       hadperiod = YES;                 /* remember this              */
  375.     }
  376.   }
  377.  
  378.   else if (digit == BUTTON_EXPONENT) { /* use scientific             */
  379.     if (hadexponent ||                 /* have one already?          */
  380.         digits >= MAX_DIGITS)          /* or too big                 */
  381.       WinAlarm(HWND_DESKTOP, WA_ERROR);/* beep at the user           */
  382.     else {
  383.       if (!digits)                     /* have digits already?       */
  384.         display.strptr[digits++] = '0';/* no, add leading zero       */
  385.       display.strptr[digits++] = 'E';  /* add the exponent           */
  386.       display.strptr[digits] = '\0';   /* add new string terminator  */
  387.       display.strlength = digits;      /* keep length in check       */
  388.       hadexponent = YES;               /* remember this              */
  389.     }
  390.   }
  391.  
  392.   else {                               /* real digit                 */
  393.     digit -= BUTTON_0;                 /* make base zero             */
  394.     digit += (INT)'0';                 /* convert to character value */
  395.     if (digits >= MAX_DIGITS)          /* or too big                 */
  396.       WinAlarm(HWND_DESKTOP, WA_ERROR);/* beep at the user           */
  397.  
  398.     else {                             /* if small enough            */
  399.                                        /* add new digit to display   */
  400.       display.strptr[digits++] = (UCHAR)digit;
  401.       display.strptr[digits] = '\0';   /* add new string terminator  */
  402.       display.strlength = digits;      /* keep length in check       */
  403.     }
  404.   }
  405. }
  406.  
  407. /*********************************************************************/
  408. /*                                                                   */
  409. /* SetDisplay(newdisplay) - Set the current display string to a new  */
  410. /*                display value.                                     */
  411. /*                                                                   */
  412. /*********************************************************************/
  413.  
  414. VOID SetDisplay(
  415.   PRXSTRING  newdisplay )              /* new number to display      */
  416. {
  417.                                        /* copy the new value         */
  418.    memcpy(dispbuff, newdisplay->strptr, newdisplay->strlength);
  419.    display.strptr = dispbuff;          /* point at current buffer    */
  420.                                        /* update the length          */
  421.    display.strlength = newdisplay->strlength;
  422.    dispbuff[display.strlength] = '\0'; /* make into ASCII-Z          */
  423.    digits = 0;                         /* no digits in number        */
  424.    hadperiod = NO;                     /* no period yet              */
  425.    hadexponent = NO;                   /* no exponential yet         */
  426. }
  427.  
  428. /*********************************************************************/
  429. /*                                                                   */
  430. /* ProcessArithmetic(newaction)  -  Process any pending arithmetic   */
  431. /*                operation updating the accumulator and the pending */
  432. /*                operation.                                         */
  433. /*                                                                   */
  434. /*********************************************************************/
  435.  
  436. VOID ProcessArithmetic(
  437.   LONG  newaction )                    /* new operator key pressed   */
  438. {
  439.  
  440.    switch(oldaction) {                 /* process prior action key   */
  441.  
  442.      case BUTTON_MULTIPLY:             /* multiplication             */
  443.      case BUTTON_DIVIDE:               /* division                   */
  444.      case BUTTON_PLUS:                 /* addition                   */
  445.      case BUTTON_MINUS:                /* subtraction                */
  446.      case BUTTON_IDIV:                 /* integer division           */
  447.      case BUTTON_REMAINDER:            /* remainder division         */
  448.      case BUTTON_POWER:                /* raise a number to power    */
  449.  
  450.                                        /* call the appropriate       */
  451.                                        /* Rexx operand processor     */
  452.        if (ProcessProgram(operator_names[oldaction-BUTTON_MULTIPLY]))
  453.          oldaction = 0;                /* cancel next on error       */
  454.        else
  455.          oldaction = newaction;        /* remember the new action    */
  456.        break;
  457.  
  458.      default:
  459.  
  460.                                        /* copy display into accum    */
  461.        strcpy(accumulator.strptr, display.strptr);
  462.                                        /* copy the length also       */
  463.        accumulator.strlength = display.strlength;
  464.        display.strlength = 0;          /* clear out digits           */
  465.        break;                          /* no more needed             */
  466.  
  467.    }
  468.    switch (newaction) {                /* now process then new key   */
  469.  
  470.                                        /* process function keys      */
  471.                                        /* immediately                */
  472.      case BUTTON_PROGRAM1:             /* program key one            */
  473.      case BUTTON_PROGRAM2:             /* program key two            */
  474.  
  475.                                        /* call the appropriate       */
  476.                                        /* Rexx operand processor     */
  477.        SetDisplay(&accumulator);       /* update display             */
  478.        ProcessProgram(operator_names[newaction-BUTTON_MULTIPLY]);
  479.        oldaction = 0;                  /* cancel next action         */
  480.        break;
  481.  
  482.      default:                          /* all other operations       */
  483.       oldaction = newaction;           /* remember the new action    */
  484.    }
  485.  
  486. }
  487.  
  488. /*********************************************************************/
  489. /*                                                                   */
  490. /* ProcessProgram()  - Process a call to a programed Rexx function.  */
  491. /*                     The program is passed both the accumulator    */
  492. /*                     and the current display as strings.           */
  493. /*                                                                   */
  494. /*********************************************************************/
  495.  
  496. INT  ProcessProgram(
  497.   PSZ        macro_name )              /* macro to invoke            */
  498. {
  499.   RXSTRING   args[2];                  /* passed argument strings    */
  500.   RXSTRING   result;                   /* returned result string     */
  501.   INT        rc;                       /* Rexx return code           */
  502.   SHORT      return_code;              /* function return code       */
  503.  
  504.  
  505.   args[0] = accumulator;               /* set first argument         */
  506.   args[1] = display;                   /* set second argument        */
  507.                                        /* ask for result in accum    */
  508.   result = accumulator;                /* copy accumulator data      */
  509.   result.strlength = DISPLAY_WIDTH;    /* set maximum size           */
  510.  
  511.   rc = RexxStart(2,                    /* two arguments              */
  512.                  args,                 /* array of arguments         */
  513.                  macro_name,           /* name of the macro          */
  514.                  NULL, NULL,
  515.                  RXFUNCTION,           /* calling this a function    */
  516.                  NULL,
  517.                  &return_code,         /* numeric value of return str*/
  518.                  &result);             /* returned string result     */
  519.                                        /* update accumulator length  */
  520.    accumulator.strlength = result.strlength;
  521.                                        /* make into an ASCII-Z string*/
  522.    accumulator.strptr[accumulator.strlength] = '\0';
  523.    if (accumulator.strptr[0] == 'E')   /* function return an error?  */
  524.      return YES;                       /* yes, indicate so           */
  525.    else
  526.      return NO;                        /* no errors                  */
  527. }
  528.  
  529. /*********************************************************************/
  530. /*                                                                   */
  531. /* CheckWhole()      - Call Rexx to check if the digits setting is   */
  532. /*                     a whole number.                               */
  533. /*                                                                   */
  534. /*********************************************************************/
  535.  
  536. INT CheckWhole(
  537.   PRXSTRING  number )                  /* number to check            */
  538. {
  539.   RXSTRING   argv;                     /* passed argument string     */
  540.   RXSTRING   result;                   /* returned result string     */
  541.   UCHAR      resbuf[10];               /* result buffer              */
  542.   INT        rc;                       /* Rexx return code           */
  543.   SHORT      return_code;              /* function return code       */
  544.  
  545.  
  546.   argv = *number;                      /* set the operand            */
  547.   result.strptr = resbuf;              /* point to return point      */
  548.   result.strlength = sizeof(resbuf);   /* set maximum size           */
  549.  
  550.   rc = RexxStart(1,                    /* two arguments              */
  551.                  &argv,                /* array of arguments         */
  552.                  "WHOLE.CAL",          /* Whole number checker       */
  553.                  NULL, NULL,
  554.                  RXFUNCTION,           /* calling this a function    */
  555.                  NULL,
  556.                  &return_code,         /* numeric value of return str*/
  557.                  &result);             /* returned string result     */
  558.  
  559.    if (resbuf[0] == '1')               /* whole number?              */
  560.      return YES;                       /* yes, this is good          */
  561.    else
  562.      return NO;                        /* nope, bad number           */
  563. }
  564.  
  565. /*********************************************************************/
  566. /*                                                                   */
  567. /* CalcPrecision - External Rexx function for obtaining current      */
  568. /*                 calculator numeric precision                      */
  569. /*                                                                   */
  570. /*********************************************************************/
  571.  
  572.  
  573. LONG   APIENTRY CalcPrecision(
  574.   PSZ        name,                     /* function name              */
  575.   LONG       argc,                     /* count of arguments         */
  576.   PRXSTRING  argv,                     /* argument RXSTRINGs         */
  577.   PSZ        queue,                    /* current Rexx queue         */
  578.   PRXSTRING  retstr )                  /* returned string value      */
  579. {
  580.   strcpy(RXSTRPTR(*retstr), precision);/* copy over current precision*/
  581.                                        /* set new length             */
  582.   retstr->strlength = strlen(precision);
  583.   return 0;                            /* completed successfully     */
  584. }
  585.  
  586.  
  587. /*********************************************************************/
  588. /*                                                                   */
  589. /* CalcForm      - External Rexx function for obtaining current      */
  590. /*                 caculator numeric form                            */
  591. /*                                                                   */
  592. /*********************************************************************/
  593.  
  594. LONG   APIENTRY CalcForm(
  595.   PSZ        name,                     /* function name              */
  596.   LONG       argc,                     /* count of arguments         */
  597.   PRXSTRING  argv,                     /* argument RXSTRINGs         */
  598.   PSZ        queue,                    /* current Rexx queue         */
  599.   PRXSTRING  retstr )                  /* returned string value      */
  600. {
  601.   if (form == SCIENTIFIC) {            /* scientific precision?      */
  602.                                        /* return that word           */
  603.     strcpy(RXSTRPTR(*retstr), "SCIENTIFIC");
  604.                                        /* set new length             */
  605.     retstr->strlength = strlen("SCIENTIFIC");
  606.   }
  607.   else {                               /* engineering precision      */
  608.                                        /* return that word           */
  609.     strcpy(RXSTRPTR(*retstr), "ENGINEERING");
  610.                                        /* set new length             */
  611.     retstr->strlength = strlen("ENGINERRING");
  612.   }
  613.   return 0;                            /* completed successfully     */
  614. }
  615.