home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / internet / netlite2 / NET / c / CMDPARSE < prev    next >
Encoding:
Text File  |  1993-03-27  |  4.4 KB  |  125 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.  * Improved error handling by Brian Boesch of Stanford University
  4.  */
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include "werr.h"
  8. #include "global.h"
  9. #include "cmdparse.h"
  10. #include "misc.h"
  11.  
  12. int cmdparse(struct cmds *cmds, register char *line)
  13. {
  14.         struct cmds *cmdp;
  15.         char *argv[NARG],*cp;
  16.         int argc,qflag;
  17.         int rslt;
  18.  
  19.         /* Remove cr/lf */
  20.         rip(line);
  21.  
  22.         for(argc = 0;argc < NARG;argc++)
  23.                 argv[argc] = NULLCHAR;
  24.  
  25.         for(argc = 0;argc < NARG;){
  26.                 qflag = 0;
  27.                 /* Skip leading white space */
  28.                 while(*line == ' ' || *line == '\t')
  29.                         line++;
  30.                 if(*line == '\0')
  31.                         break;
  32.                 /* Check for quoted token */
  33.                 if(*line == '"'){
  34.                         line++; /* Suppress quote */
  35.                         qflag = 1;
  36.                 }
  37.                 argv[argc++] = line;    /* Beginning of token */
  38.                 /* Find terminating delimiter */
  39.                 if(qflag){
  40.                         /* Find quote, it must be present */
  41.                         if((line = strchr(line,'"')) == NULLCHAR){
  42.                                 return -1;
  43.                         }
  44.                         *line++ = '\0';
  45.                 } else {
  46.                         /* Find space or tab. If not present,
  47.                          * then we've already found the last
  48.                          * token.
  49.                          */
  50.                         if((cp = strchr(line,' ')) == NULLCHAR
  51.                          && (cp = strchr(line,'\t')) == NULLCHAR){
  52.                                 break;
  53.                         }
  54.                         *cp++ = '\0';
  55.                         line = cp;
  56.                 }
  57.         }
  58.         if (argc < 1) {         /* empty command line */
  59.                 argc = 1;
  60.                 argv[0] = "";
  61.         }
  62.         /* Lines beginning with "#" are comments */
  63.         if(argv[0] == NULLCHAR || argv[0][0] == '#')
  64.                 return 0;
  65.  
  66.         /* Look up command in table; prefix matches are OK */
  67.         for(cmdp = cmds;cmdp->name != NULLCHAR;cmdp++){
  68.                 if(strncmp(argv[0],cmdp->name,strlen(argv[0])) == 0)
  69.                         break;
  70.         }
  71.         if(cmdp->name == NULLCHAR) {
  72.                 if(cmdp->argc_errmsg != NULLCHAR) 
  73.                         werr(0, cmdp->argc_errmsg);
  74.                 return -1;
  75.         } else {
  76.                 if(argc < cmdp->argcmin) {
  77.                         /* Insufficient arguments */
  78.                         werr(0,"Usage: %s",cmdp->argc_errmsg);
  79.                         return -1;
  80.                 } else {
  81.                         rslt = (*cmdp->func)(argc,argv);
  82.                         if ((rslt < 0) && (cmdp->exec_errmsg != NULLCHAR))
  83.                                 werr(0, cmdp->exec_errmsg);
  84.                         return(rslt);
  85.                 }
  86.         }
  87. }
  88.  
  89. /* Call a subcommand based on the first token in an already-parsed line */
  90. int subcmd(struct cmds *tab, int argc, char **argv)
  91. {
  92.         int rslt;
  93.         register struct cmds *cmdp;
  94.  
  95.         /* Strip off first token and pass rest of line to subcommand */
  96.         if (argc < 2) {
  97.                 if (argc < 1)
  98.                         werr(0, "SUBCMD - Don't know what to do?");
  99.                 else
  100.                         werr(0, "\"%s\" - takes at least one argument",argv[0]);
  101.                 return -1;
  102.         }
  103.         argc--;
  104.         argv++;
  105.         for(cmdp = tab;cmdp->name != NULLCHAR;cmdp++){
  106.                 if(strncmp(argv[0],cmdp->name,strlen(argv[0])) == 0){
  107.                         if(argc < cmdp->argcmin) {
  108.                                 if (cmdp->argc_errmsg != NULLCHAR)
  109.                                         werr(0,"Usage: %s",cmdp->argc_errmsg);
  110.                                 return -1;
  111.                         } else {
  112.                                 rslt = (*cmdp->func)(argc,argv);
  113.                                 if ((rslt < 0) && (cmdp->exec_errmsg != NULLCHAR))
  114.                                         werr(0, cmdp->exec_errmsg);
  115.                                 return(rslt);
  116.                         }
  117.                 }
  118.         }
  119.         if (cmdp->argc_errmsg != NULLCHAR) 
  120.                 werr(0 ,cmdp->argc_errmsg);
  121.  
  122.         return -1;
  123. }
  124.  
  125.