/* Parse command line, set up command arguments Unix-style, and call function. * Note: argument is modified (delimiters are overwritten with nulls) * Improved error handling by Brian Boesch of Stanford University */ #ifdef TRACE #include #include "machdep.h" #include "trace.h" #endif #include "cmdparse.h" int cmdparse(cmds,line) struct cmds cmds[]; register char *line; { struct cmds *cmdp; char *argv[NARG],*cp,*index(); int argc,qflag; int i, rslt; /* Remove cr/lf */ if((cp = index(line,'\r')) != NULLCHAR) *cp = '\0'; if((cp = index(line,'\n')) != NULLCHAR) *cp = '\0'; /* shouldn't be necessary */ for(argc = 0;argc < NARG;argc++) argv[argc] = NULLCHAR; for(argc = 0;argc < NARG;){ qflag = 0; /* Skip leading white space */ while(*line == ' ' || *line == '\t') line++; if(*line == '\0') break; /* Check for quoted token */ if(*line == '"'){ line++; /* Suppress quote */ qflag = 1; } argv[argc++] = line; /* Beginning of token */ /* Find terminating delimiter */ if(qflag){ /* Find quote, it must be present */ if((line = index(line,'"')) == NULLCHAR){ return -1; } } else { /* Find space or tab. If not present, * then we've already found the last * token. */ if((cp = index(line,' ')) == NULLCHAR && (cp = index(line,'\t')) == NULLCHAR){ break; } *cp++ = '\0'; line = cp; } } #ifdef TRACE if(trace & TRACE_CMDPARSE) { printf("Number of tokens = %d\r\n",argc); for (i=0; i< argc; i++) { printf("Argument=%d '%s'\r\n",i,argv[i]); } } #endif if (argc < 1) { /* empty command line */ argc = 1; argv[0] = ""; } /* Lines beginning with "#" are comments */ if(argv[0][0] == '#') return 0; /* Look up command in table; prefix matches are OK */ for(cmdp = cmds;cmdp->name != NULLCHAR;cmdp++){ if(strncmp(argv[0],cmdp->name,strlen(argv[0])) == 0) break; } if(cmdp->name == NULLCHAR) { if(cmdp->argc_errmsg != NULLCHAR) printf("%s\r\n",cmdp->argc_errmsg); return -1; } else { if(argc < cmdp->argcmin) { /* Insufficient arguments */ printf("Usage: %s\r\n",cmdp->argc_errmsg); return -1; } else { rslt = (*cmdp->func)(argc,argv); if ((rslt < 0) && (cmdp->exec_errmsg != NULLCHAR)) printf("%s\r\n",cmdp->exec_errmsg); return(rslt); } } } /* Call a subcommand based on the first token in an already-parsed line */ int subcmd(tab,argc,argv) struct cmds tab[]; int argc; char *argv[]; { int rslt; register struct cmds *cmdp; /* Strip off first token and pass rest of line to subcommand */ if (argc < 2) { if (argc < 1) printf("SUBCMD - Don't know what to do?\r\n"); else printf("\"%s\" - takes at least one argument\r\n",argv[0]); return -1; } argc--; argv++; for(cmdp = tab;cmdp->name != NULLCHAR;cmdp++){ if(strncmp(argv[0],cmdp->name,strlen(argv[0])) == 0){ if(argc < cmdp->argcmin) { if (cmdp->argc_errmsg != NULLCHAR) printf("Usage: %s\r\n",cmdp->argc_errmsg); return -1; } else { rslt = (*cmdp->func)(argc,argv); if ((rslt < 0) && (cmdp->exec_errmsg != NULLCHAR)) printf("%s\r\n",cmdp->exec_errmsg); return(rslt); } } } if (cmdp->argc_errmsg != NULLCHAR) printf("%s\r\n",cmdp->argc_errmsg); return -1; }