P8000/WEGA/contrib/K5JB/cmdparse.c

245 lines
5.7 KiB
C

/* 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
* Separated lineparse() so other routines could use it. Also ifdefed
* out parts we don't use - K5JB 3/16/92
*/
#include <stdio.h>
#include <ctype.h>
#include "global.h"
#include "cmdparse.h"
int
lineparse(xargc,xargv,line)
int *xargc;
char *xargv[];
register char *line;
{
char *argv[NARG],*cp;
int argc;
#ifdef NOTUSED
static char pool[POOLSIZE];
int quote,rslt;
char *pp;*vp,*ep,*rp,*getenv();
#endif
void rip();
int doexit(); /* in main.c */
extern int exitval;
/* Remove cr/lf */
rip(line);
for(argc = 0;argc < NARG;argc++)
argv[argc] = NULLCHAR;
#ifdef NOTUSED
pp = pool;
#endif
for(argc = 0;argc < NARG && *line != '\0';){
#ifdef NOTUSED
quote = 0;
#endif
/* Skip leading white space */
while(*line == ' ' || *line == '\t')
line++;
if(*line == '\0')
break;
#ifdef NOTUSED
/* Check for quoted token */
if(*line == '"' || *line == '\'')
quote = *line++; /* Suppress quote, remember it */
#endif
argv[argc++] = line; /* Beginning of token */
/* Find terminating delimiter */
#ifdef NOTUSED
if(quote){
/* Find quote, it must be present */
if((line = index(line,quote)) == NULLCHAR)
return -1;
*line++ = '\0';
} else
#endif
{
/* Find space or tab. If not present,
* then we've already found the last
* token.
*/
for (cp = line; *cp; cp++)
if (*cp == ' ' || *cp == '\t')
break;
if (*cp != '\0')
*cp++ = '\0';
line = cp;
}
#ifdef NOTUSED
/* Check for variablename */
if(quote != '\'' && index(cp = argv[argc - 1],'$') != NULLCHAR){
argv[argc - 1] = pp;
while(*cp != '\0') {
if(*cp != '$')
*pp++ = *cp++;
else{
if(*++cp == '{'){
if((ep = index(++cp,'}')) == NULLCHAR)
return -1;
*ep++ = '\0';
}else{
ep = NULLCHAR;
}
/* Scan to end of varname and mark it */
for (vp = cp; isalnum(*vp) || *vp == '_'; vp++)
*vp = toupper(*vp);
/* If a name found, get value */
if (vp != cp){
rslt = *vp; /* save next and make \0 */
*vp = '\0';
rp = getenv(cp);
*vp = rslt; /* restore next character */
if (ep == NULLCHAR){ /* no braces */
if(rp == NULLCHAR) /* undef'd var */
rp = ""; /* then just empty */
}else{
if(rp == NULLCHAR) /* undef'd var */
switch(rslt){ /* else look at next */
/* case '=': */
/* dosetenv(2,(&cp)-1);/* assign and subst */
case '-':
rp = vp + 1; /* subst next word */
break;
case '?':
if(*++vp == '\0')
vp = "undefined variable";
printf("%s\n",vp);
return -1;
default:
rp = ""; /* default is empty */
}
else
if(rslt == '+') /* defined and subst */
rp = vp + 1;
} /* else */
/* Copy the result to the pool */
while ((*pp++ = *rp++) != 0) /* K5JB */
;
pp--;
cp = vp;
} /* if (/
if(ep != NULLCHAR)
cp = ep;
} /* else */
} /* while */
*pp++ = '\0';
if(pp > pool + POOLSIZE){ /* check pool overflow */
printf("panic: pool overflow\n");
fflush(stdout);
exitval = 1;
doexit(); /* dangerous to continue (was for(;;); */
}
} /* if(quote... */
#endif
} /* for() */
*xargc = argc;
while(argc--)
xargv[argc] = argv[argc];
return(0);
}
int
cmdparse(cmds,line)
struct cmds cmds[];
char *line;
{
struct cmds *cmdp;
char *argv[NARG];
int argc;
int rslt;
if (lineparse(&argc,argv,line) || 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\n",cmdp->argc_errmsg);
return -1;
} else {
if(argc < cmdp->argcmin) {
/* Insufficient arguments */
printf("Usage: %s\n",cmdp->argc_errmsg);
return -1;
} else {
argv[0] = cmdp->name;
rslt = (*cmdp->func)(argc,argv);
if ((rslt < 0) && (cmdp->exec_errmsg != NULLCHAR))
printf("%s\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,len;
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?\n");
else
printf("\"%s\" - takes at least one argument\n",argv[0]);
return -1;
}
for(cmdp = tab;cmdp->name != NULLCHAR;cmdp++){
if(strncmp(argv[1],cmdp->name,strlen(argv[1])) == 0){
if(--argc < cmdp->argcmin) {
if (cmdp->argc_errmsg != NULLCHAR)
printf("Usage: %s\n",cmdp->argc_errmsg);
return -1;
} else {
(++argv)[0] = cmdp->name;
rslt = (*cmdp->func)(argc,argv);
if ((rslt < 0) && (cmdp->exec_errmsg != NULLCHAR))
printf("%s\n",cmdp->exec_errmsg);
return(rslt);
}
}
}
if (cmdp->argc_errmsg != NULLCHAR){
if (cmdp->argc_errmsg[0] != '?'){
printf("%s\n",cmdp->argc_errmsg);
} else {
printf("%s %s:",argv[0],cmdp->argc_errmsg + 1);
len = strlen(argv[0]) + strlen(cmdp->argc_errmsg) + 1;
for(cmdp = tab;cmdp->name != NULLCHAR;cmdp++){
if ((len += strlen(cmdp->name) + 1) > 79){
len = strlen(cmdp->name) + 9;
printf("\n ");
}
printf(" %s",cmdp->name);
}
printf("\n");
}
}
return -1;
}