/* EXEC.C * * This file is for functions dealing with execution of * commands, command lines, buffers, files and startup files * * written 1986 by Daniel Lawrence * modified by Petri Kutvonen */ #include #include "estruct.h" #include "edef.h" /* namedcmd: execute a named command even if it is not bound */ namedcmd(f, n) int f, n; /* command arguments [passed through to command executed] */ { register int (*kfunc)(); /* ptr to the requexted function to bind to */ int (*getname())(); /* prompt the user to type a named command */ mlwrite(": "); /* and now get the function name to execute */ kfunc = getname(); if (kfunc == NULL) { mlwrite("(No such function)"); return(FALSE); } /* and then execute the command */ return((*kfunc)(f, n)); } /* execcmd: Execute a command line command to be typed in by the user */ execcmd(f, n) int f, n; /* default Flag and Numeric argument */ { register int status; /* status return */ char cmdstr[NSTRING]; /* string holding command to execute */ /* get the line wanted */ if ((status = mlreply(": ", cmdstr, NSTRING)) != TRUE) return(status); execlevel = 0; return(docmd(cmdstr)); } /* docmd: take a passed string as a command line and translate it to be executed as a command. This function will be used by execute-command-line and by all source and startup files. Lastflag/thisflag is also updated. format of the command line is: {# arg} {} */ docmd(cline) char *cline; /* command line to execute */ { register int f; /* default argument flag */ register int n; /* numeric repeat value */ int (*fnc)(); /* function to execute */ int status; /* return status of function */ int oldcle; /* old contents of clexec flag */ char *oldestr; /* original exec string */ char tkn[NSTRING]; /* next token off of command line */ int (*fncmatch())(); /* if we are scanning and not executing..go back here */ if (execlevel) return(TRUE); oldestr = execstr; /* save last ptr to string to execute */ execstr = cline; /* and set this one as current */ /* first set up the default command values */ f = FALSE; n = 1; lastflag = thisflag; thisflag = 0; if ((status = macarg(tkn)) != TRUE) { /* and grab the first token */ execstr = oldestr; return(status); } /* process leadin argument */ if (gettyp(tkn) != TKCMD) { f = TRUE; strcpy(tkn, getval(tkn)); n = atoi(tkn); /* and now get the command to execute */ if ((status = macarg(tkn)) != TRUE) { execstr = oldestr; return(status); } } /* and match the token to see if it exists */ if ((fnc = fncmatch(tkn)) == NULL) { mlwrite("(No such Function)"); execstr = oldestr; return(FALSE); } /* save the arguments and go execute the command */ oldcle = clexec; /* save old clexec flag */ clexec = TRUE; /* in cline execution */ status = (*fnc)(f, n); /* call the function */ cmdstatus = status; /* save the status */ clexec = oldcle; /* restore clexec flag */ execstr = oldestr; return(status); } /* token: chop a token off a string return a pointer past the token */ char *token(src, tok, size) char *src, *tok; /* source string, destination token string */ int size; /* maximum size of token */ { register int quotef; /* is the current string quoted? */ register char c; /* temporary character */ /* first scan past any whitespace in the source string */ while (*src == ' ' || *src == '\t') ++src; /* scan through the source string */ quotef = FALSE; while (*src) { /* process special characters */ if (*src == '~') { ++src; if (*src == 0) break; switch (*src++) { case 'r': c = 13; break; case 'n': c = 10; break; case 't': c = 9; break; case 'b': c = 8; break; case 'f': c = 12; break; default: c = *(src-1); } if (--size > 0) { *tok++ = c; } } else { /* check for the end of the token */ if (quotef) { if (*src == '"') break; } else { if (*src == ' ' || *src == '\t') break; } /* set quote mode if quote found */ if (*src == '"') quotef = TRUE; /* record the character */ c = *src++; if (--size > 0) *tok++ = c; } } /* terminate the token and exit */ if (*src) ++src; *tok = 0; return(src); } macarg(tok) /* get a macro line argument */ char *tok; /* buffer to place argument */ { int savcle; /* buffer to store original clexec */ int status; savcle = clexec; /* save execution mode */ clexec = TRUE; /* get the argument */ status = nextarg("", tok, NSTRING, ctoec('\n')); clexec = savcle; /* restore execution mode */ return(status); } /* nextarg: get the next argument */ nextarg(prompt, buffer, size, terminator) char *prompt; /* prompt to use if we must be interactive */ char *buffer; /* buffer to put token into */ int size; /* size of the buffer */ int terminator; /* terminating char to be used on interactive fetch */ { /* if we are interactive, go get it! */ if (clexec == FALSE) return(getstring(prompt, buffer, size, terminator)); /* grab token and advance past */ execstr = token(execstr, buffer, size); /* evaluate it */ strcpy(buffer, getval(buffer)); return(TRUE); } /* storemac: Set up a macro buffer and flag to store all executed command lines there */ storemac(f, n) int f; /* default flag */ int n; /* macro number to use */ { register struct BUFFER *bp; /* pointer to macro buffer */ char bname[NBUFN]; /* name of buffer to use */ /* must have a numeric argument to this function */ if (f == FALSE) { mlwrite("No macro specified"); return(FALSE); } /* range check the macro number */ if (n < 1 || n > 40) { mlwrite("Macro number out of range"); return(FALSE); } /* construct the macro buffer name */ strcpy(bname, "*Macro xx*"); bname[7] = '0' + (n / 10); bname[8] = '0' + (n % 10); /* set up the new macro buffer */ if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) { mlwrite("Can not create macro"); return(FALSE); } /* and make sure it is empty */ bclear(bp); /* and set the macro store pointers to it */ mstore = TRUE; bstore = bp; return(TRUE); } #if PROC /* storeproc: Set up a procedure buffer and flag to store all executed command lines there */ storeproc(f, n) int f; /* default flag */ int n; /* macro number to use */ { register struct BUFFER *bp; /* pointer to macro buffer */ register int status; /* return status */ char bname[NBUFN]; /* name of buffer to use */ /* a numeric argument means its a numbered macro */ if (f == TRUE) return(storemac(f, n)); /* get the name of the procedure */ if ((status = mlreply("Procedure name: ", &bname[1], NBUFN-2)) != TRUE) return(status); /* construct the macro buffer name */ bname[0] = '*'; strcat(bname, "*"); /* set up the new macro buffer */ if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) { mlwrite("Can not create macro"); return(FALSE); } /* and make sure it is empty */ bclear(bp); /* and set the macro store pointers to it */ mstore = TRUE; bstore = bp; return(TRUE); } /* execproc: Execute a procedure */ execproc(f, n) int f, n; /* default flag and numeric arg */ { register BUFFER *bp; /* ptr to buffer to execute */ register int status; /* status return */ char bufn[NBUFN+2]; /* name of buffer to execute */ /* find out what buffer the user wants to execute */ if ((status = mlreply("Execute procedure: ", &bufn[1], NBUFN)) != TRUE) return(status); /* construct the buffer name */ bufn[0] = '*'; strcat(bufn, "*"); /* find the pointer to that buffer */ if ((bp=bfind(bufn, FALSE, 0)) == NULL) { mlwrite("No such procedure"); return(FALSE); } /* and now execute it as asked */ while (n-- > 0) if ((status = dobuf(bp)) != TRUE) return(status); return(TRUE); } #endif /* execbuf: Execute the contents of a buffer of commands */ execbuf(f, n) int f, n; /* default flag and numeric arg */ { register BUFFER *bp; /* ptr to buffer to execute */ register int status; /* status return */ char bufn[NSTRING]; /* name of buffer to execute */ /* find out what buffer the user wants to execute */ if ((status = mlreply("Execute buffer: ", bufn, NBUFN)) != TRUE) return(status); /* find the pointer to that buffer */ if ((bp=bfind(bufn, FALSE, 0)) == NULL) { mlwrite("No such buffer"); return(FALSE); } /* and now execute it as asked */ while (n-- > 0) if ((status = dobuf(bp)) != TRUE) return(status); return(TRUE); } /* dobuf: execute the contents of the buffer pointed to by the passed BP Directives start with a "!" and include: !endm End a macro !if (cond) conditional execution !else !endif !return Return (terminating current macro) !goto