Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!uunet!husc6!cmcl2!rutgers!sri-spam!ames!necntc!ncoast!allbery From: nwd@j.cc.purdue.edu (Daniel Lawrence) Newsgroups: comp.sources.misc Subject: MicroEmacs 3.9 (Part 5 of 16) Message-ID: <5652@ncoast.UUCP> Date: Sat, 14-Nov-87 16:08:42 EST Article-I.D.: ncoast.5652 Posted: Sat Nov 14 16:08:42 1987 Date-Received: Tue, 17-Nov-87 03:03:02 EST Sender: allbery@ncoast.UUCP Lines: 1783 Approved: allbery@ncoast.UUCP X-Archive: comp.sources.misc/microemacs-3.9/4 # This is a shar archive. # Remove everything above this line. # Run the file through sh, not csh. # (type `sh mes.5') # If you do not see the message # `mes.5 completed!' # then the file was incomplete. echo extracting - exec.c sed 's/^X//' > exec.c << 'FRIDAY_NIGHT' X/* This file is for functions dealing with execution of X commands, command lines, buffers, files and startup files X X written 1986 by Daniel Lawrence */ X X#include X#include "estruct.h" X#include "edef.h" X X/* namedcmd: execute a named command even if it is not bound */ X Xnamedcmd(f, n) X Xint f, n; /* command arguments [passed through to command executed] */ X X{ X register int (*kfunc)(); /* ptr to the requexted function to bind to */ X int (*getname())(); X X /* prompt the user to type a named command */ X mlwrite(": "); X X /* and now get the function name to execute */ X kfunc = getname(); X if (kfunc == NULL) { X mlwrite("[No such function]"); X return(FALSE); X } X X /* and then execute the command */ X return((*kfunc)(f, n)); X} X X/* execcmd: Execute a command line command to be typed in X by the user */ X Xexeccmd(f, n) X Xint f, n; /* default Flag and Numeric argument */ X X{ X register int status; /* status return */ X char cmdstr[NSTRING]; /* string holding command to execute */ X X /* get the line wanted */ X if ((status = mlreply(": ", cmdstr, NSTRING)) != TRUE) X return(status); X X execlevel = 0; X return(docmd(cmdstr)); X} X X/* docmd: take a passed string as a command line and translate X it to be executed as a command. This function will be X used by execute-command-line and by all source and X startup files. Lastflag/thisflag is also updated. X X format of the command line is: X X {# arg} {} X X*/ X Xdocmd(cline) X Xchar *cline; /* command line to execute */ X X{ X register int f; /* default argument flag */ X register int n; /* numeric repeat value */ X int (*fnc)(); /* function to execute */ X int status; /* return status of function */ X int oldcle; /* old contents of clexec flag */ X char *oldestr; /* original exec string */ X char tkn[NSTRING]; /* next token off of command line */ X int (*fncmatch())(); X X /* if we are scanning and not executing..go back here */ X if (execlevel) X return(TRUE); X X oldestr = execstr; /* save last ptr to string to execute */ X execstr = cline; /* and set this one as current */ X X /* first set up the default command values */ X f = FALSE; X n = 1; X lastflag = thisflag; X thisflag = 0; X X if ((status = macarg(tkn)) != TRUE) { /* and grab the first token */ X execstr = oldestr; X return(status); X } X X /* process leadin argument */ X if (gettyp(tkn) != TKCMD) { X f = TRUE; X strcpy(tkn, getval(tkn)); X n = atoi(tkn); X X /* and now get the command to execute */ X if ((status = macarg(tkn)) != TRUE) { X execstr = oldestr; X return(status); X } X } X X /* and match the token to see if it exists */ X if ((fnc = fncmatch(tkn)) == NULL) { X mlwrite("[No such Function]"); X execstr = oldestr; X return(FALSE); X } X X /* save the arguments and go execute the command */ X oldcle = clexec; /* save old clexec flag */ X clexec = TRUE; /* in cline execution */ X status = (*fnc)(f, n); /* call the function */ X cmdstatus = status; /* save the status */ X clexec = oldcle; /* restore clexec flag */ X execstr = oldestr; X return(status); X} X X/* token: chop a token off a string X return a pointer past the token X*/ X Xchar *token(src, tok, size) X Xchar *src, *tok; /* source string, destination token string */ Xint size; /* maximum size of token */ X X{ X register int quotef; /* is the current string quoted? */ X register char c; /* temporary character */ X X /* first scan past any whitespace in the source string */ X while (*src == ' ' || *src == '\t') X ++src; X X /* scan through the source string */ X quotef = FALSE; X while (*src) { X /* process special characters */ X if (*src == '~') { X ++src; X if (*src == 0) X break; X switch (*src++) { X case 'r': c = 13; break; X case 'n': c = 10; break; X case 't': c = 9; break; X case 'b': c = 8; break; X case 'f': c = 12; break; X default: c = *(src-1); X } X if (--size > 0) { X *tok++ = c; X } X } else { X /* check for the end of the token */ X if (quotef) { X if (*src == '"') X break; X } else { X if (*src == ' ' || *src == '\t') X break; X } X X /* set quote mode if quote found */ X if (*src == '"') X quotef = TRUE; X X /* record the character */ X c = *src++; X if (--size > 0) X *tok++ = c; X } X } X X /* terminate the token and exit */ X if (*src) X ++src; X *tok = 0; X return(src); X} X Xmacarg(tok) /* get a macro line argument */ X Xchar *tok; /* buffer to place argument */ X X{ X int savcle; /* buffer to store original clexec */ X int status; X X savcle = clexec; /* save execution mode */ X clexec = TRUE; /* get the argument */ X status = nextarg("", tok, NSTRING, ctoec('\n')); X clexec = savcle; /* restore execution mode */ X return(status); X} X X/* nextarg: get the next argument */ X Xnextarg(prompt, buffer, size, terminator) X Xchar *prompt; /* prompt to use if we must be interactive */ Xchar *buffer; /* buffer to put token into */ Xint size; /* size of the buffer */ Xint terminator; /* terminating char to be used on interactive fetch */ X X{ X /* if we are interactive, go get it! */ X if (clexec == FALSE) X return(getstring(prompt, buffer, size, terminator)); X X /* grab token and advance past */ X execstr = token(execstr, buffer, size); X X /* evaluate it */ X strcpy(buffer, getval(buffer)); X return(TRUE); X} X X/* storemac: Set up a macro buffer and flag to store all X executed command lines there */ X Xstoremac(f, n) X Xint f; /* default flag */ Xint n; /* macro number to use */ X X{ X register struct BUFFER *bp; /* pointer to macro buffer */ X char bname[NBUFN]; /* name of buffer to use */ X X /* must have a numeric argument to this function */ X if (f == FALSE) { X mlwrite("No macro specified"); X return(FALSE); X } X X /* range check the macro number */ X if (n < 1 || n > 40) { X mlwrite("Macro number out of range"); X return(FALSE); X } X X /* construct the macro buffer name */ X strcpy(bname, "[Macro xx]"); X bname[7] = '0' + (n / 10); X bname[8] = '0' + (n % 10); X X /* set up the new macro buffer */ X if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) { X mlwrite("Can not create macro"); X return(FALSE); X } X X /* and make sure it is empty */ X bclear(bp); X X /* and set the macro store pointers to it */ X mstore = TRUE; X bstore = bp; X return(TRUE); X} X X#if PROC X/* storeproc: Set up a procedure buffer and flag to store all X executed command lines there */ X Xstoreproc(f, n) X Xint f; /* default flag */ Xint n; /* macro number to use */ X X{ X register struct BUFFER *bp; /* pointer to macro buffer */ X register int status; /* return status */ X char bname[NBUFN]; /* name of buffer to use */ X X /* a numeric argument means its a numbered macro */ X if (f == TRUE) X return(storemac(f, n)); X X /* get the name of the procedure */ X if ((status = mlreply("Procedure name: ", &bname[1], NBUFN-2)) != TRUE) X return(status); X X /* construct the macro buffer name */ X bname[0] = '['; X strcat(bname, "]"); X X /* set up the new macro buffer */ X if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) { X mlwrite("Can not create macro"); X return(FALSE); X } X X /* and make sure it is empty */ X bclear(bp); X X /* and set the macro store pointers to it */ X mstore = TRUE; X bstore = bp; X return(TRUE); X} X X/* execproc: Execute a procedure */ X Xexecproc(f, n) X Xint f, n; /* default flag and numeric arg */ X X{ X register BUFFER *bp; /* ptr to buffer to execute */ X register int status; /* status return */ X char bufn[NBUFN+2]; /* name of buffer to execute */ X X /* find out what buffer the user wants to execute */ X if ((status = mlreply("Execute procedure: ", &bufn[1], NBUFN)) != TRUE) X return(status); X X /* construct the buffer name */ X bufn[0] = '['; X strcat(bufn, "]"); X X /* find the pointer to that buffer */ X if ((bp=bfind(bufn, FALSE, 0)) == NULL) { X mlwrite("No such procedure"); X return(FALSE); X } X X /* and now execute it as asked */ X while (n-- > 0) X if ((status = dobuf(bp)) != TRUE) X return(status); X return(TRUE); X} X#endif X X/* execbuf: Execute the contents of a buffer of commands */ X Xexecbuf(f, n) X Xint f, n; /* default flag and numeric arg */ X X{ X register BUFFER *bp; /* ptr to buffer to execute */ X register int status; /* status return */ X char bufn[NSTRING]; /* name of buffer to execute */ X X /* find out what buffer the user wants to execute */ X if ((status = mlreply("Execute buffer: ", bufn, NBUFN)) != TRUE) X return(status); X X /* find the pointer to that buffer */ X if ((bp=bfind(bufn, FALSE, 0)) == NULL) { X mlwrite("No such buffer"); X return(FALSE); X } X X /* and now execute it as asked */ X while (n-- > 0) X if ((status = dobuf(bp)) != TRUE) X return(status); X return(TRUE); X} X X/* dobuf: execute the contents of the buffer pointed to X by the passed BP X X Directives start with a "!" and include: X X !endm End a macro X !if (cond) conditional execution X !else X !endif X !return Return (terminating current macro) X !goto