home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD 2.1 / Amiga Developer CD v2.1.iso / NDK / NDK_3.5 / Tutorials / ARexx / FunctionLibrary / Source / dispatch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-10-04  |  5.3 KB  |  286 lines

  1. /*
  2.  * $Id: dispatch.c 1.1 1997/06/25 18:46:44 olsen Exp $
  3.  *
  4.  * ARexx sample library
  5.  *
  6.  * :ts=4
  7.  */
  8.  
  9. #include "rexxsamplebase.h"
  10.  
  11. /****************************************************************************/
  12.  
  13.     /* StringToNumber(STRPTR String,struct RexxSampleBase *RexxSampleBase):
  14.      *
  15.      *    Convert a string into a number.
  16.      */
  17.  
  18. LONG
  19. StringToNumber(
  20.     STRPTR                    String,
  21.     struct RexxSampleBase *    RexxSampleBase)
  22. {
  23.     LONG Result;
  24.  
  25.         /* Uses the dos.library code. */
  26.  
  27.     StrToLong(String,&Result);
  28.  
  29.     return(Result);
  30. }
  31.  
  32.     /* NumberToString(LONG Value,STRPTR String,struct RexxSampleBase *RexxSampleBase):
  33.      *
  34.      *    Convert a number into a string. This is done using the
  35.      *    utility.library integer math routines and thus looks a
  36.      *    bit bizarre...
  37.      */
  38.  
  39. VOID
  40. NumberToString(
  41.     LONG                    Value,
  42.     STRPTR                    String,
  43.     struct RexxSampleBase *    RexxSampleBase)
  44. {
  45.     LONG Sign;
  46.     LONG Next;
  47.     LONG Len;
  48.     LONG i;
  49.     UBYTE c;
  50.  
  51.     if(Value < 0)
  52.     {
  53.         Sign = -1;
  54.         Value = (-Value);
  55.     }
  56.     else
  57.     {
  58.         Sign = 1;
  59.     }
  60.  
  61.     Len = 0;
  62.  
  63.     while(Value > 0 && Len < 15)
  64.     {
  65.         Next = SDivMod32(Value,10);
  66.  
  67.         String[Len++] = (Value - SMult32(Next,10)) + '0';
  68.  
  69.         Value = Next;
  70.     }
  71.  
  72.     if(Sign < 0)
  73.         String[Len++] = '-';
  74.  
  75.     String[Len] = 0;
  76.  
  77.     if(Len > 1)
  78.     {
  79.         for(i = 0 ; i < Len / 2 ; i++)
  80.         {
  81.             c                        = String[i];
  82.             String[i]                = String[Len - (i + 1)];
  83.             String[Len - (i + 1)]    = c;
  84.         }
  85.     }
  86. }
  87.  
  88. /****************************************************************************/
  89.  
  90. LONG
  91. Cmd_Add(
  92.     STRPTR *                Args,
  93.     LONG *                    Error,
  94.     struct RexxSampleBase *    RexxSampleBase)
  95. {
  96.     LONG a;
  97.     LONG b;
  98.     LONG result;
  99.  
  100.     a = StringToNumber(Args[0],RexxSampleBase);
  101.     b = StringToNumber(Args[1],RexxSampleBase);
  102.  
  103.     result = a + b;
  104.  
  105.     return(result);
  106. }
  107.  
  108. LONG
  109. Cmd_Sub(
  110.     STRPTR *                Args,
  111.     LONG *                    Error,
  112.     struct RexxSampleBase *    RexxSampleBase)
  113. {
  114.     LONG a;
  115.     LONG b;
  116.     LONG result;
  117.  
  118.     a = StringToNumber(Args[0],RexxSampleBase);
  119.     b = StringToNumber(Args[1],RexxSampleBase);
  120.  
  121.     result = a - b;
  122.  
  123.     return(result);
  124. }
  125.  
  126. LONG
  127. Cmd_Mul(
  128.     STRPTR *                Args,
  129.     LONG *                    Error,
  130.     struct RexxSampleBase *    RexxSampleBase)
  131. {
  132.     LONG a;
  133.     LONG b;
  134.     LONG result;
  135.  
  136.     a = StringToNumber(Args[0],RexxSampleBase);
  137.     b = StringToNumber(Args[1],RexxSampleBase);
  138.  
  139.     result = SMult32(a,b);
  140.  
  141.     return(result);
  142. }
  143.  
  144. LONG
  145. Cmd_Div(
  146.     STRPTR *                Args,
  147.     LONG *                    Error,
  148.     struct RexxSampleBase *    RexxSampleBase)
  149. {
  150.     LONG a;
  151.     LONG b;
  152.     LONG result;
  153.  
  154.     a = StringToNumber(Args[0],RexxSampleBase);
  155.     b = StringToNumber(Args[1],RexxSampleBase);
  156.  
  157.     if(b == 0)
  158.     {
  159.         result = 0;
  160.  
  161.         (*Error) = ERR10_018;    /* Invalid argument to function. */
  162.     }
  163.     else
  164.     {
  165.         result = SDivMod32(a,b);
  166.     }
  167.  
  168.     return(result);
  169. }
  170.  
  171. /****************************************************************************/
  172.  
  173. STATIC struct RexxCmd CommandTable[] =
  174. {
  175.     "ADD",    2,        Cmd_Add,
  176.     "SUB",    2,        Cmd_Sub,
  177.     "MUL",    2,        Cmd_Mul,
  178.     "DIV",    2,        Cmd_Div,
  179.  
  180.     NULL,    NULL,    NULL
  181. };
  182.  
  183. /****************************************************************************/
  184.  
  185. #define SAME    (0)
  186. #define OK        (0)
  187. #define NOT        !
  188.  
  189. /****************************************************************************/
  190.  
  191.     /* RexxDispatch():
  192.      *
  193.      *    This is the function dispatcher. For every ARexx script that has
  194.      *    added this library to its list of hosts to be searched the ARexx
  195.      *    resident process will pass each single command through here.
  196.      *    If we can handle one of the commands, we tell the resident process
  197.      *    by returning 0, indicating "no error, command was handled". If
  198.      *    the command is unknown to us, we *must* return error ERR10_001,
  199.      *    indicating "we do not know this command". In the latter case,
  200.      *    the resident process will pass the command on to the next host
  201.      *    in the list of hosts.
  202.      */
  203.  
  204. LONG ASM
  205. RexxDispatch(
  206.     REG(a0) struct RexxMsg *        RexxMsg,
  207.     REG(a1) STRPTR *                Result,
  208.     REG(a6) struct RexxSampleBase *    RexxSampleBase)
  209. {
  210.     LONG Error = ERR10_001;    /* Program not found. */
  211.     BOOL Found = FALSE;
  212.     LONG i;
  213.  
  214.         /* Search the table for the command. */
  215.  
  216.     for(i = 0 ; NOT Found && CommandTable[i].Name != NULL ; i++)
  217.     {
  218.             /* Does this one match? */
  219.  
  220.         if(Stricmp(RexxMsg->rm_Args[0],CommandTable[i].Name) == SAME)
  221.         {
  222.             Found = TRUE;
  223.  
  224.                 /* Do the number of arguments match? The
  225.                  * number is passed in the lower eight bits
  226.                  * of the action field. Up to 15 arguments
  227.                  * can be passed to your library. Each
  228.                  * argument represents a pointer to a
  229.                  * null-terminated string.
  230.                  */
  231.  
  232.             if((RexxMsg->rm_Action & 0xFF) != CommandTable[i].NumArgs)
  233.             {
  234.                 Error = ERR10_017;    /* Wrong number of arguments. */
  235.             }
  236.             else
  237.             {
  238.                 UBYTE String[20];
  239.                 LONG Number;
  240.  
  241.                     /* Clear the error value. */
  242.  
  243.                 Error = OK;
  244.  
  245.                     /* Invoke the command. */
  246.  
  247.                 Number = (*CommandTable[i].Cmd)(&RexxMsg->rm_Args[1],
  248.                                                 &Error,
  249.                                                 RexxSampleBase);
  250.  
  251.                     /* Did the command return without
  252.                      * error?
  253.                      */
  254.  
  255.                 if(Error == OK)
  256.                 {
  257.                         /* Convert the number to a string.
  258.                          * The library result has to be
  259.                          * a standard ARexx string.
  260.                          */
  261.  
  262.                     NumberToString(Number,String,RexxSampleBase);
  263.  
  264.                         /* Make a copy of the string. This
  265.                          * is what we will return as the
  266.                          * result to to the caller.
  267.                          */
  268.  
  269.                     (*Result) = CreateArgstring(String,strlen(String));
  270.  
  271.                         /* If the result string could not
  272.                          * be created, flag this as an error.
  273.                          */
  274.  
  275.                     if((*Result) == NULL)
  276.                         Error = ERR10_003;    /* No memory available. */
  277.                 }
  278.             }
  279.         }
  280.     }
  281.  
  282.         /* Return the error if any. */
  283.  
  284.     return(Error);
  285. }
  286.