home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 1 / HamRadio.cdr / misc / tcpipsrc / cmdparse.c < prev    next >
C/C++ Source or Header  |  1991-01-26  |  6KB  |  272 lines

  1. /* Parse command line, set up command arguments Unix-style, and call function.
  2.  * Note: argument is modified (delimiters are overwritten with nulls)
  3.  *
  4.  * Copyright 1991 Phil Karn, KA9Q
  5.  *
  6.  * Improved error handling by Brian Boesch of Stanford University
  7.  */
  8. #include <stdio.h>
  9. #include "global.h"
  10. #include "cmdparse.h"
  11. #include "proc.h"
  12.  
  13. struct boolcmd {
  14.     char *str;    /* Token */
  15.     int val;    /* Value */
  16. };
  17.  
  18. static struct boolcmd Boolcmds[] = {
  19.     "y",        1,    /* Synonyms for "true" */
  20.     "yes",        1,
  21.     "true",        1,
  22.     "on",        1,
  23.     "1",        1,
  24.     "set",        1,
  25.     "enable",    1,
  26.  
  27.     "n",        0,    /* Synonyms for "false" */
  28.     "no",        0,
  29.     "false",    0,
  30.     "off",        0,
  31.     "0",        0,
  32.     "clear",    0,
  33.     "disable",    0,
  34.     NULLCHAR
  35. };
  36.  
  37. int
  38. cmdparse(cmds,line,p)
  39. struct cmds cmds[];
  40. register char *line;
  41. void *p;
  42. {
  43.     struct cmds *cmdp;
  44.     char *argv[NARG],*cp;
  45.     char **pargv;
  46.     int argc,qflag,i;
  47.  
  48.     /* Remove cr/lf */
  49.     rip(line);
  50.  
  51.     for(argc = 0;argc < NARG;argc++)
  52.         argv[argc] = NULLCHAR;
  53.  
  54.     for(argc = 0;argc < NARG;){
  55.         qflag = 0;
  56.         /* Skip leading white space */
  57.         while(*line == ' ' || *line == '\t')
  58.             line++;
  59.         if(*line == '\0')
  60.             break;
  61.         /* Check for quoted token */
  62.         if(*line == '"'){
  63.             line++;    /* Suppress quote */
  64.             qflag = 1;
  65.         }
  66.         argv[argc++] = line;    /* Beginning of token */
  67.         /* Find terminating delimiter */
  68.         if(qflag){
  69.             /* Find quote, it must be present */
  70.             if((line = strchr(line,'"')) == NULLCHAR){
  71.                 return -1;
  72.             }
  73.             *line++ = '\0';
  74.         } else {
  75.             /* Find space or tab. If not present,
  76.              * then we've already found the last
  77.              * token.
  78.              */
  79.             if((cp = strchr(line,' ')) == NULLCHAR
  80.              && (cp = strchr(line,'\t')) == NULLCHAR){
  81.                 break;
  82.             }
  83.             *cp++ = '\0';
  84.             line = cp;
  85.         }
  86.     }
  87.     if (argc < 1) {        /* empty command line */
  88.         argc = 1;
  89.         argv[0] = "";
  90.     }
  91.     /* Lines beginning with "#" are comments */
  92.     if(argv[0] == NULLCHAR || argv[0][0] == '#')
  93.         return 0;
  94.  
  95.     /* Look up command in table; prefix matches are OK */
  96.     for(cmdp = cmds;cmdp->name != NULLCHAR;cmdp++){
  97.         if(strncmp(argv[0],cmdp->name,strlen(argv[0])) == 0)
  98.             break;
  99.     }
  100.     if(cmdp->name == NULLCHAR) {
  101.         if(cmdp->argc_errmsg != NULLCHAR) 
  102.             tprintf("%s\n",cmdp->argc_errmsg);
  103.         return -1;
  104.     } else {
  105.         if(argc < cmdp->argcmin) {
  106.             /* Insufficient arguments */
  107.             tprintf("Usage: %s\n",cmdp->argc_errmsg);
  108.             return -1;
  109.         } else {
  110.             if(cmdp->stksize == 0){
  111.                 return (*cmdp->func)(argc,argv,p);
  112.             } else {
  113.                 /* Make private copy of argv and args,
  114.                  * spawn off subprocess and return.
  115.                  */
  116.                 pargv = (char **)callocw(argc,sizeof(char *));
  117.                 for(i=0;i<argc;i++)
  118.                     pargv[i] = strdup(argv[i]);
  119.                 newproc(cmdp->name,cmdp->stksize,
  120.                 (void (*)())cmdp->func,argc,pargv,p,1);
  121.                 return(0);
  122.             }
  123.         }
  124.     }
  125. }
  126.  
  127. /* Call a subcommand based on the first token in an already-parsed line */
  128. int
  129. subcmd(tab,argc,argv,p)
  130. struct cmds tab[];
  131. int argc;
  132. char *argv[];
  133. void *p;
  134. {
  135.     register struct cmds *cmdp;
  136.     char **pargv;
  137.     int found = 0;
  138.     int i;
  139.  
  140.     /* Strip off first token and pass rest of line to subcommand */
  141.     if (argc < 2) {
  142.         if (argc < 1)
  143.             tprintf("SUBCMD - Don't know what to do?\n");
  144.         else
  145.             tprintf("\"%s\" - takes at least one argument\n",argv[0]);
  146.         return -1;
  147.     }
  148.     argc--;
  149.     argv++;
  150.     for(cmdp = tab;cmdp->name != NULLCHAR;cmdp++){
  151.         if(strncmp(argv[0],cmdp->name,strlen(argv[0])) == 0){
  152.             found = 1;
  153.             break;
  154.         }
  155.     }
  156.     if(!found){
  157.         tprintf("valid subcommands:");
  158.         for(cmdp = tab;cmdp->name != NULLCHAR;cmdp++)
  159.             if(tprintf(" %s",cmdp->name) == EOF)
  160.                 return -1;
  161.         tprintf("\n");
  162.         return -1;
  163.     }
  164.     if(argc < cmdp->argcmin){
  165.         if(cmdp->argc_errmsg != NULLCHAR)
  166.             tprintf("Usage: %s\n",cmdp->argc_errmsg);
  167.         return -1;
  168.     }
  169.     if(cmdp->stksize == 0){
  170.         return (*cmdp->func)(argc,argv,p);
  171.     } else {
  172.         /* Make private copy of argv and args */
  173.         pargv = (char **)callocw(argc,sizeof(char *));
  174.         for(i=0;i<argc;i++)
  175.             pargv[i] = strdup(argv[i]);
  176.         newproc(cmdp->name,cmdp->stksize,
  177.          (void (*)())cmdp->func,argc,pargv,p,1);
  178.         return(0);
  179.     }
  180. }
  181.  
  182. /* Subroutine for setting and displaying boolean flags */
  183. int
  184. setbool(var,label,argc,argv)
  185. int *var;
  186. char *label;
  187. int argc;
  188. char *argv[];
  189. {
  190.     struct boolcmd *bc;
  191.  
  192.     if(argc < 2){
  193.         tprintf("%s: %s\n",label,*var ? "on":"off");
  194.         return 0;
  195.     }
  196.     for(bc = Boolcmds;bc->str != NULLCHAR;bc++){
  197.         if(strcmpi(argv[1],bc->str) == 0){
  198.             *var = bc->val;
  199.             return 0;
  200.         }
  201.     }
  202.     tprintf("Valid options:");
  203.     for(bc = Boolcmds;bc->str != NULLCHAR;bc++)
  204.         if(tprintf(" %s",bc->str) == EOF)
  205.             return 1;
  206.     tprintf("\n");
  207.     return 1;
  208. }
  209. /* Subroutine for setting and displaying long variables */
  210. int
  211. setlong(var,label,argc,argv)
  212. long *var;
  213. char *label;
  214. int argc;
  215. char *argv[];
  216. {
  217.     if(argc < 2)
  218.         tprintf("%s: %ld\n",label,*var);
  219.     else
  220.         *var = atol(argv[1]);
  221.  
  222.     return 0;
  223. }
  224. /* Subroutine for setting and displaying short variables */
  225. int
  226. setshort(var,label,argc,argv)
  227. unsigned short *var;
  228. char *label;
  229. int argc;
  230. char *argv[];
  231. {
  232.     if(argc < 2)
  233.         tprintf("%s: %u\n",label,*var);
  234.     else
  235.         *var = atoi(argv[1]);
  236.  
  237.     return 0;
  238. }
  239. /* Subroutine for setting and displaying integer variables */
  240. int
  241. setint(var,label,argc,argv)
  242. int *var;
  243. char *label;
  244. int argc;
  245. char *argv[];
  246. {
  247.     if(argc < 2)
  248.         tprintf("%s: %i\n",label,*var);
  249.     else
  250.         *var = atoi(argv[1]);
  251.  
  252.     return 0;
  253. }
  254.  
  255. /* Subroutine for setting and displaying unsigned integer variables */
  256. int
  257. setuns(var,label,argc,argv)
  258. unsigned *var;
  259. char *label;
  260. int argc;
  261. char *argv[];
  262. {
  263.     if(argc < 2)
  264.         tprintf("%s: %u\n",label,*var);
  265.     else
  266.         *var = atoi(argv[1]);
  267.  
  268.     return 0;
  269. }
  270.  
  271.  
  272.