home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 277.lha / TestRH / src / command.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-08-08  |  4.3 KB  |  222 lines

  1.  
  2. /*
  3.  * COMMAND.C
  4.  *
  5.  *    (C)Copyright 1987 by Matthew Dillon, All Rights Reserved
  6.  *
  7.  *    Modified for use with testrh by Vidhyanath Rao 
  8.  *
  9.  * \c             single character (escape)
  10.  * `string'          string of characters w/ embedded `' allowed!
  11.  * (string)             same thing w/ embedded () allowed!
  12.  *
  13.  * name arg arg      command name. The arguments are interpreted as strings
  14.  *             for the command.
  15.  *
  16.  * $             insert saved string.
  17.  *             [mostly returns from REXX macros].
  18.  *
  19.  * Any string arguments not part of a command are considered to be typed
  20.  * text.
  21.  */
  22.  
  23.  
  24. #include <stdio.h>
  25. #include "defs.h"
  26.  
  27. #define CF_NRX  8   /*  NOT OK to do from inside REXX            */
  28. #define NESTMAX 4
  29.  
  30. extern char *breakout();
  31.  
  32. typedef struct {
  33.    char *name;        /* command name      */
  34.    ubyte args;
  35.    ubyte flags;
  36.    int (*func)();   /* function           */
  37. } COMM;
  38.  
  39. extern int
  40.     do_execute(),    do_null(),    do_quit(),    do_show(),
  41.     do_rxc(),    do_rxo(),    do_rhlocks(),    do_rximpld(),
  42.     do_set();
  43.  
  44. ubyte hindex[26];   /*    alpha hash into table    */
  45.  
  46.     /*      args flags    */
  47.  
  48. COMM Comm[] = {
  49.     "clrrhlocks",    0, CF_NRX, do_rhlocks,
  50.     "execute",       1, CF_NRX, do_execute,
  51.     "lockrh",         0, CF_NRX, do_rhlocks,
  52.     "null",          0,      0, do_null,
  53.     "quit",          0, CF_NRX, do_quit,
  54.     "rxc",           1,      0, do_rxc,      /* explicit ARexx macro
  55.                         invocation      */
  56.     "rxo",           2,      0, do_rxo,     /* explicit, ARexx macro
  57.                         invocation, with options */
  58.     "set",         1,         0, do_set,
  59.     "show",         0,         0, do_show,
  60.     "unlockrh",         0, CF_NRX, do_rhlocks,
  61.     NULL, 0, 0, NULL
  62. };
  63.  
  64. init_command()
  65. {
  66.     register short hi;
  67.     register COMM *comm;
  68.  
  69.     hi = sizeof(Comm)/sizeof(Comm[0]) - 2;
  70.     comm = Comm + hi;
  71.  
  72.     while (hi >= 0) {
  73.     hindex[comm->name[0] - 'a'] = hi;
  74.     --hi;
  75.     --comm;
  76.     }
  77. }
  78.  
  79.  
  80. do_command(str)
  81. char *str;
  82.  
  83. {
  84.     register char *arg;
  85.     register short i, j;
  86.     static int level;
  87.     char *tbf[8], quoted;
  88.  
  89.     if (level == 0)
  90.     CmdErr = 0; /*Clear command error at start. */
  91.  
  92.     if (++level > NESTMAX) {
  93.     puts("Recursion Too Deep!");
  94.     --level;
  95.     CmdErr |= RDE_BADCMD;
  96.     return(0);
  97.     }
  98.     while ( (tbf[0] = arg = breakout(&str, "ed)) != NULL) {
  99.     switch (quoted) {
  100.       case '\3':
  101.         CmdErr |= RDE_NOMEM; /* malloc() failed */
  102.       case '\2': /* Nesting error for `' or () /*
  103.         goto fail;
  104.       case '\1': /*quoted string. enter into file */
  105.         puts(arg);
  106.         free(arg);
  107.         continue; /*the while loop. [no continue for switch()] */
  108.       default:
  109.         ;
  110.     }
  111.  
  112.     for (i = 0; arg[i]; ++i) {
  113.         if (arg[i] >= 'A' && arg[i] <= 'Z')
  114.         arg[i] += 'a' - 'A';
  115.     }
  116.  
  117.     j = 1;
  118.  
  119.     if (arg[0] >= 'a' && arg[0] <= 'z') {
  120.         register COMM *comm = &Comm[hindex[arg[0]-'a']];
  121.         for (; comm->name && comm->name[0] == arg[0]; ++comm) {
  122.         if (strcmp(arg, comm->name) == 0) {
  123.             av[0] = (ubyte *)comm->name;
  124.             if ( ((comm->flags & CF_NRX) != 0) &&
  125.               (RHFlags & RHF_ACTIVE) ) {
  126.             puts ("No can do from inside the Rexx server");
  127.             CmdErr |= RDE_NESTRX;
  128.             goto fail;
  129.             }
  130.             for (; (j <= comm->args) && (j < 8); ++j) {
  131.             av[j] = (ubyte *)
  132.                   (tbf[j] = breakout(&str, "ed));
  133.             switch (quoted) {
  134.               case '\3':
  135.                 CmdErr |= RDE_NOMEM; /* malloc() failed */
  136.               case '\2': /* Nesting error for `' or () */
  137.                 goto fail;
  138.               default:
  139.                 ;
  140.             }
  141.             if (av[j] == NULL) {
  142.                 puts("Bad argument");
  143.                 CmdErr |= RDE_BADARG;
  144.                 goto fail;
  145.             }
  146.             }
  147.             av[j] = NULL;   /* end of arglist */
  148.  
  149.         
  150.             if ( ((*comm->func)(-1) != 0) && (CmdErr == 0) ) {
  151.             goto loop;
  152.             } else {
  153.             goto fail;
  154.             }
  155.         }
  156.         }
  157.     }
  158.  
  159.  
  160.     /* Command not found, check for macro    */
  161.  
  162.     /* Command still not found, and if no errors, try ARexx macro  */
  163.     if (CmdErr == 0)
  164.         do_rximpld(arg, str);
  165.  
  166.     if (CmdErr != 0) {
  167. fail:
  168.         --level;
  169.         CmdErr |= RDE_CMDERR;
  170.         for (--j; j >= 0; --j)
  171.         free(tbf[j]);
  172.         return(0);
  173.     }
  174. loop:
  175.         for (--j; j >= 0; --j)
  176.         free(tbf[j]);
  177.     }
  178.     --level;
  179.     return(1);
  180. }
  181.  
  182. do_execute()
  183.  
  184. {
  185.     Execute(av[1], 0L, 0L);
  186. }
  187.  
  188. do_quit()
  189.  
  190. {
  191.     Quitflag = 1;
  192.     RHFlags |= RHF_HALTED;
  193. }
  194.  
  195. do_show()
  196.  
  197. {
  198.     printf("Rexx Result: %s \n", String);
  199. }
  200.  
  201. do_null()
  202.  
  203. {
  204.     return(1);
  205. }
  206.  
  207. do_set()
  208.  
  209. {
  210.     if (String != NULL) {
  211.     free(String);
  212.     }
  213.     if ( (String = malloc(strlen(av[1]) + 1)) != NULL) {
  214.     strcpy(String, av[1]);
  215.     return(1);
  216.     } else {
  217.     CmdErr |= RDE_NOMEM;
  218.     return(0);
  219.     }
  220. }
  221.  
  222.