home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume4 / fmtr / command.c next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  4.4 KB  |  217 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: command.c,v 1.4 86/05/05 14:08:32 root Exp $";
  3. #endif
  4.  
  5. /* command.c decodes command.  Uses binary search in array
  6.  * of struct cmd.
  7.  */
  8.  
  9. #include "fmtr.h"
  10.  
  11. #define HUGE 1000
  12. #define PLUS '+'
  13. #define MINUS '-'
  14.  
  15. #define MAX(x,y) ((x) > (y) ? (x) : (y))
  16. #define MIN(x,y) ((x) < (y) ? (x) : (y))
  17.  
  18. /*  cmdtype is upper case version of command.  All commands of
  19.  *  interest to us are either ce, ul, or else equivalent to
  20.  *  fi or nf
  21.  */
  22.  
  23. enum cmdtype
  24.     {
  25.     CE, UL, FI, NF, OTHER
  26.     } cmd, getcmd();
  27.  
  28. int len;
  29.  
  30. struct cmd {
  31.     char *name;
  32.     enum cmdtype type;
  33. } cmd_table[50] = { "ce", CE,    /* basic nroff requests */
  34.             "ul", UL,
  35.             "nf", NF,
  36.             "fi", FI,
  37.             "TS", NF,    /* universal macros */
  38.             "TE", FI,
  39.             "EQ", NF,
  40.             "EN", FI,
  41.             "PS", NF,
  42.             "PE", FI,
  43.             "IS", NF,
  44.             "IE", FI,
  45.             "DS", NF,    /* ms macros */
  46.             "ID", NF,
  47.             "CD", NF,
  48.             "LD", NF,
  49.             "DE", FI,
  50.             "(b", NF,    /* me macros */
  51.             ")b", FI,
  52.             "(c", NF,
  53.             ")c", FI,
  54.             "(l", NF,
  55.             ")l", FI,
  56.             "(z", NF,
  57.             ")z", FI,
  58.             (char *) NULL, OTHER
  59.         };
  60.  
  61. int val;    /* both are set in getval() */
  62. char argtype;    /* and used in setparam() */
  63.  
  64. /*  command() takes a line starting with some form of the command start
  65.  *  sequence (period or apostrophe, optionally preceded by \&), and
  66.  *  calls getcmd() to return an integer representing the command name,
  67.  *  and then takes appropriate action.
  68.  *
  69.  *  In all cases it produces a break and prints out the command line as is.
  70.  */
  71.  
  72. command(line)
  73. char line[];
  74. {
  75.     cmd = getcmd(line);
  76.  
  77.     if (cmd != OTHER)
  78.     switch (cmd) {
  79.     case CE:
  80.         getval(line);        /* only need getval() with CE and UL */
  81.         ce_val = setparam(ce_val, 1, 0, HUGE);
  82.         break;
  83.     case UL:
  84.         getval(line);
  85.         ul_val = setparam(ul_val, 1, 0, HUGE);
  86.         break;
  87.     case NF:
  88.         nf_val = 1;
  89.         break;
  90.     case FI:
  91.         nf_val = 0;
  92.         break;
  93.     }
  94.  
  95.     n_brk();
  96.     puts(line);
  97. }
  98.  
  99. enum cmdtype getcmd(line)    /* gets command type by binary search */
  100. char *line;        /* stolen from K & R p. 125 with minor changes */
  101. {
  102.     int high, low, mid, cond;
  103.     char *cp;
  104.  
  105.     low = 0;
  106.     high = len - 1;
  107.  
  108.     cp = (*line == '\\') ? line + 3 : line + 1;
  109.  
  110.     while (low <= high) {
  111.     mid = (low + high)/2;
  112.     if ((cond = strncmp(cp, cmd_table[mid].name, 2)) < 0)
  113.         high = mid - 1;
  114.     else if (cond > 0)
  115.         low = mid + 1;
  116.     else
  117.         return(cmd_table[mid].type);
  118.     }
  119.     return(OTHER);
  120. }
  121.  
  122. mk_table(sarray, earray)
  123. char *sarray, *earray;
  124. {
  125.     int mycmp();
  126.     char *cp, *malloc(), *strncpy();
  127.     struct cmd *cmdptr;
  128.  
  129.     if (len == 0) {        /* find end */
  130.     cmdptr = cmd_table;
  131.     while (cmdptr->name)
  132.         cmdptr++;        /* now pointing to NULL ending defined */
  133.     len = cmdptr - cmd_table;
  134.     }
  135.     else
  136.     cmdptr = cmd_table + len;
  137.  
  138.     if (sarray)
  139.     for (cp = sarray; *cp; cp += 3) {
  140.         cmdptr->name = malloc(3);
  141.         (void) strncpy(cmdptr->name, cp + 1, 2);
  142.         cmdptr->type = NF;
  143.         cmdptr++;
  144.     }
  145.  
  146.     if (earray)
  147.     for (cp = earray; *cp; cp += 3) {
  148.         cmdptr->name = malloc(3);
  149.         (void) strncpy(cmdptr->name, cp + 1, 2);
  150.         cmdptr->type = FI;
  151.         cmdptr++;
  152.     }
  153.  
  154.     len = cmdptr - cmd_table;
  155.  
  156.     qsort((char *) cmd_table, len, sizeof cmd_table[0], mycmp);
  157. }
  158.  
  159. mycmp(s1, s2)
  160. struct cmd *s1, *s2;
  161. {
  162.     return(strcmp(s1->name, s2->name));
  163. }
  164.  
  165. /*  getval() gets value of argument preceded by optional sign.  Here
  166.     we are following the nroff rules: commands are exactly two
  167.     letters long followed by optional spaces before arguments.  */
  168.  
  169. getval(line)
  170. char *line;
  171. {
  172.     char *cp;
  173.  
  174.     if (*line == '\\')        /* don't test for z_flag, since otherwise */
  175.     cp = line + 5;        /* we would not be here */
  176.     else
  177.     cp = line + 3;
  178.     for ( ; isspace(*cp); *cp++)
  179.     ;
  180.     argtype = *cp;
  181.     if (argtype == PLUS  ||  argtype == MINUS)
  182.     cp++;
  183.     val = atoi(cp);
  184. }
  185.  
  186. /* setparam() sets parameter.  May be set to param if present and legal,
  187.  * otherwise to def_val, if absent, less than min_val or greater than
  188.  * max_val.
  189.  */
  190.  
  191. setparam(param, def_val, min_val, max_val)
  192. int param, def_val, min_val, max_val;
  193. {
  194.     if (argtype == '\0')
  195.     return(def_val);
  196.     else if (argtype == PLUS)
  197.     param += val;
  198.     else if (argtype == MINUS)
  199.     param -= val;
  200.     else
  201.     param = val;
  202.     param = MAX(param, min_val);
  203.     param = MIN(param, max_val);
  204.  
  205.     return(param);
  206. }
  207.  
  208. #ifdef DEBUG
  209. print_tab()    /* prints table, useful while debugging */
  210. {
  211.     struct cmd *cmdptr;
  212.  
  213.     for (cmdptr = cmd_table; cmdptr < cmd_table + len; cmdptr++)
  214.     printf("%s\n", cmdptr->name);
  215. }
  216. #endif
  217.