DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T e

⟦d6bc4b29a⟧ TextFile

    Length: 16413 (0x401d)
    Types: TextFile
    Names: »exec.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec1/uEmacs/exec.c« 

TextFile

/*	This file is for functions dealing with execution of
	commands, command lines, buffers, files and startup files

	written 1986 by Daniel Lawrence				*/

#include	<stdio.h>
#include	"estruct.h"
#include	"edef.h"

#if	MEGAMAX & ST520
overlay	"exec"
#endif

#if	DEBUGM
char outline[NSTRING];		/* global string to hold debug line text */
#endif

/* 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 (*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} <command-name> {<argument string(s)>}

	Directives start with a "!" and include:

	!endm		End a macro
	!if (cond)	conditional execution
	!else
	!endif
	!return		Return (terminating current macro)
	!goto <label>	Jump to a label in the current macro

	Line Labels begin with a "*" in column 1, like:

	*LBL01
*/

docmd(cline)

char *cline;	/* command line to execute */

{
	register int f;		/* default argument flag */
	register int n;		/* numeric repeat value */
	register int i;
	int (*fnc)();		/* function to execute */
	int status;		/* return status of function */
	int oldcle;		/* old contents of clexec flag */
	int llen;		/* length of cline */
	int force;		/* force TRUE result? */
	char *tmp;		/* tmp pointer into cline */
	struct LINE *lp;	/* a line pointer */
	char *oldestr;		/* original exec string */
	char token[NSTRING];	/* next token off of command line */
	int (*fncmatch())();
#if	DEBUGM
	/* if $debug == TRUE, every line to execute
	   gets echoed and a key needs to be pressed to continue
	   ^G will abort the command */
	register char *sp;	/* pointer into buf to expand %s */

	if (macbug) {
		strcpy(outline, "<<<");
#if	1	/* debug if levels */
		strcat(outline, itoa(execlevel));
		strcat(outline, ":");
#endif
		strcat(outline, cline);
		strcat(outline, ">>>");

		/* change all '%' to ':' so mlwrite won't expect arguments */
		sp = outline;
		while (*sp) {
			if (*sp++ == '%')
				*(sp-1) = ':';
		}

		/* write out the debug line */
		mlwrite(outline);
		update(TRUE);

		/* and get the keystroke */
		if (tgetc() == 7) {
			mlwrite("[Macro aborted]");
			return(FALSE);
		}
	}
#endif
		
	/* dump comments and labels here */
	if (*cline == ';' || *cline == '*')
		return(TRUE);

	/* eat leading spaces */
	while (*cline == ' ' || *cline == '\t')
		++cline;

	/* check to see if this line turns macro storage off */
	if (cline[0] == '!' && strncmp(&cline[1], "endm", 4) == 0) {
		mstore = FALSE;
		bstore = NULL;
		return(TRUE);
	}

	/* if macro store is on, just salt this away */
	if (mstore) {
		/* allocate the space for the line */
		llen = strlen(cline);
		if ((lp=lalloc(llen)) == NULL) {
			mlwrite("Out of memory while storing macro");
			return (FALSE);
		}

		/* copy the text into the new line */
		for (i=0; i<llen; ++i)
			lputc(lp, i, cline[i]);

		/* attach the line to the end of the buffer */
       		bstore->b_linep->l_bp->l_fp = lp;
		lp->l_bp = bstore->b_linep->l_bp;
		bstore->b_linep->l_bp = lp;
		lp->l_fp = bstore->b_linep;
		return (TRUE);
	}
	
	force = FALSE;
	oldestr = execstr;	/* save last ptr to string to execute */
	execstr = cline;	/* and set this one as current */

	/* process directives */
	if (*cline == '!') {
		/* save directive location and skip it */
		tmp = cline;
		while (*execstr && *execstr != ' ' && *execstr != '\t')
			++execstr;

		if (tmp[1] == 'f' && tmp[2] == 'o') {
			force = TRUE;
			goto do001;

		} else if (tmp[1] == 'i' && tmp[2] == 'f') {

			/* IF directive */
			/* grab the value of the logical exp */
			if (execlevel == 0) {
				if ((status = macarg(token)) != TRUE) {
					execstr = oldestr;
					return(status);
				}
				status = stol(token);
			} else
				status = TRUE;

			if (status) {

				/* IF (TRUE) */
				if (execlevel != 0)
					++execlevel;
			} else {

				/* IF (FALSE) */
				++execlevel;
			}

		} else if (tmp[1] == 'e' && tmp[2] == 'l') {

			/* ELSE directive */
			if (execlevel == 1)
				--execlevel;
			else if (execlevel == 0 )
				++execlevel;

		} else if (tmp[1] == 'e' && tmp[2] == 'n') {

			/* ENDIF directive */
			if (execlevel)
				--execlevel;

		} else if (tmp[1] == 'r' && tmp[2] == 'e') {

			/* RETURN directive */
			execstr = oldestr;
			return(RET);

		} else if (tmp[1] == 'g' && tmp[2] == 'o') {

			/* GOTO directive */
			/* .....only if we are currently executing */
			if (execlevel) {
				execstr = oldestr;
				return(TRUE);
			}

			while (*execstr == ' ' || *execstr == '\t')
				++execstr;
			strncpy(golabel, execstr, NPAT - 1);
			return(GOLINE);

		} else {
			mlwrite("%%Unknown Directive");
			return(FALSE);
		}

		/* restore execstr and exit */
		execstr = oldestr;
		return(TRUE);
	}

do001:	/* if we are scanning and not executing..go back here */
	if (execlevel) {
		execstr = oldestr;
		return(TRUE);
	}

	/* first set up the default command values */
	f = FALSE;
	n = 1;
	lastflag = thisflag;
	thisflag = 0;

	if ((status = macarg(token)) != TRUE) {	/* and grab the first token */
		execstr = oldestr;
		return(status);
	}

	/* process leadin argument */
	if (gettyp(token) != TKCMD) {
		f = TRUE;
		n = atoi(getval(token));

		/* and now get the command to execute */
		if ((status = macarg(token)) != TRUE) {
			execstr = oldestr;
			return(status);	
		}	
	}

	/* and match the token to see if it exists */
	if ((fnc = fncmatch(token)) == 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 */
	if (force)			/* force the status */
		status = TRUE;
	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)

char *src, *tok;	/* source string, destination token string */

{
	register int quotef;	/* is the current string quoted? */

	/* 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':	*tok++ = 13; break;
				case 'n':	*tok++ = 10; break;
				case 't':	*tok++ = 9;  break;
				case 'b':	*tok++ = 8;  break;
				case 'f':	*tok++ = 12; break;
				default:	*tok++ = *(src-1);
			}
		} else {
			/* check for the end of the token */
			if (quotef) {
				if (*src == '"')
					break;
			} else {
				if (*src == ' ' || *src == '\t')
					break;
			}

			/* set quote mode if qoute found */
			if (*src == '"')
				quotef = TRUE;

			/* record the character */
			*tok++ = *src++;
		}
	}

	/* 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 */
char *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);

	/* 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);
}

/*	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[NBUFN];		/* 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				*/

dobuf(bp)

BUFFER *bp;	/* buffer to execute */

{
        register int status;		/* status return */
	register LINE *lp;		/* pointer to line to execute */
	register LINE *hlp;		/* pointer to line header */
	register LINE *glp;		/* line to goto */
	register int linlen;		/* length of line to execute */
	register WINDOW *wp;		/* ptr to windows to scan */
	char *eline;			/* text of line to execute */

	/* clear IF level flags */
	execlevel = 0;

	/* starting at the beginning of the buffer */
	hlp = bp->b_linep;
	lp = hlp->l_fp;
	while (lp != hlp) {
		/* allocate eline and copy macro line to it */
		linlen = lp->l_used;
		if ((eline = malloc(linlen+1)) == NULL) {
			mlwrite("%%Out of Memory during macro execution");
			return(FALSE);
		}
		strncpy(eline, lp->l_text, linlen);
		eline[linlen] = 0;	/* make sure it ends */

		/* trim leading whitespace */
		while (eline[0] == ' ' || eline[0] == '\t')
			strcpy(eline, &eline[1]);

		/* if it is not a comment, execute it */
		if (eline[0] != 0 && eline[0] != ';') {
			status = docmd(eline);

			/* if it is a !GOTO directive, deal with it */
			if (status == GOLINE) {
				linlen = strlen(golabel);
				glp = hlp->l_fp;
				while (glp != hlp) {
					if (*glp->l_text == '*' &&
					    (strncmp(&glp->l_text[1], golabel,
					            linlen) == 0)) {
						lp = glp;
						status = TRUE;
					}
				glp = glp->l_fp;
				}
			}

			if (status == GOLINE) {
				mlwrite("%%No such label");
				return(FALSE);
			}

			/* if it is a !RETURN directive...do so */
			if (status == RET) {
				free(eline);
				break;
			}

			/* check for a command error */
			if (status != TRUE) {
				/* look if buffer is showing */
				wp = wheadp;
				while (wp != NULL) {
					if (wp->w_bufp == bp) {
						/* and point it */
						wp->w_dotp = lp;
						wp->w_doto = 0;
						wp->w_flag |= WFHARD;
					}
					wp = wp->w_wndp;
				}
				/* in any case set the buffer . */
				bp->b_dotp = lp;
				bp->b_doto = 0;
				free(eline);
				execlevel = 0;
				return(status);
			}
		}

		/* on to the next line */
		free(eline);
		lp = lp->l_fp;
	}

	/* exit the current function */
	execlevel = 0;
        return(TRUE);
}

execfile(f, n)	/* execute a series of commands in a file
*/

int f, n;	/* default flag and numeric arg to pass on to file */

{
	register int status;	/* return status of name query */
	char *fname[NSTRING];	/* name of file to execute */

	if ((status = mlreply("File to execute: ", fname, NSTRING -1)) != TRUE)
		return(status);

	/* otherwise, execute it */
	while (n-- > 0)
		if ((status=dofile(fname)) != TRUE)
			return(status);

	return(TRUE);
}

/*	dofile:	yank a file into a buffer and execute it
		if there are no errors, delete the buffer on exit */

dofile(fname)

char *fname;	/* file name to execute */

{
	register BUFFER *bp;	/* buffer to place file to exeute */
	register BUFFER *cb;	/* temp to hold current buf while we read */
	register int status;	/* results of various calls */
	char bname[NBUFN];	/* name of buffer */

	makename(bname, fname);		/* derive the name of the buffer */
	if ((bp = bfind(bname, TRUE, 0)) == NULL) /* get the needed buffer */
		return(FALSE);

	bp->b_mode = MDVIEW;	/* mark the buffer as read only */
	cb = curbp;		/* save the old buffer */
	curbp = bp;		/* make this one current */
	/* and try to read in the file to execute */
	if ((status = readin(fname, FALSE)) != TRUE) {
		curbp = cb;	/* restore the current buffer */
		return(status);
	}

	/* go execute it! */
	curbp = cb;		/* restore the current buffer */
	if ((status = dobuf(bp)) != TRUE)
		return(status);

	/* if not displayed, remove the now unneeded buffer and exit */
	if (bp->b_nwnd == 0)
		zotbuf(bp);
	return(TRUE);
}

/*	cbuf:	Execute the contents of a numbered buffer	*/

cbuf(f, n, bufnum)

int f, n;	/* default flag and numeric arg */
int bufnum;	/* number of buffer to execute */

{
        register BUFFER *bp;		/* ptr to buffer to execute */
        register int status;		/* status return */
	static char bufname[] = "[Macro xx]";

	/* make the buffer name */
	bufname[7] = '0' + (bufnum / 10);
	bufname[8] = '0' + (bufnum % 10);

	/* find the pointer to that buffer */
        if ((bp=bfind(bufname, FALSE, 0)) == NULL) {
        	mlwrite("Macro not defined");
                return(FALSE);
        }

	/* and now execute it as asked */
	while (n-- > 0)
		if ((status = dobuf(bp)) != TRUE)
			return(status);
	return(TRUE);
}

cbuf1(f, n)

{
	cbuf(f, n, 1);
}

cbuf2(f, n)

{
	cbuf(f, n, 2);
}

cbuf3(f, n)

{
	cbuf(f, n, 3);
}

cbuf4(f, n)

{
	cbuf(f, n, 4);
}

cbuf5(f, n)

{
	cbuf(f, n, 5);
}

cbuf6(f, n)

{
	cbuf(f, n, 6);
}

cbuf7(f, n)

{
	cbuf(f, n, 7);
}

cbuf8(f, n)

{
	cbuf(f, n, 8);
}

cbuf9(f, n)

{
	cbuf(f, n, 9);
}

cbuf10(f, n)

{
	cbuf(f, n, 10);
}

cbuf11(f, n)

{
	cbuf(f, n, 11);
}

cbuf12(f, n)

{
	cbuf(f, n, 12);
}

cbuf13(f, n)

{
	cbuf(f, n, 13);
}

cbuf14(f, n)

{
	cbuf(f, n, 14);
}

cbuf15(f, n)

{
	cbuf(f, n, 15);
}

cbuf16(f, n)

{
	cbuf(f, n, 16);
}

cbuf17(f, n)

{
	cbuf(f, n, 17);
}

cbuf18(f, n)

{
	cbuf(f, n, 18);
}

cbuf19(f, n)

{
	cbuf(f, n, 19);
}

cbuf20(f, n)

{
	cbuf(f, n, 20);
}

cbuf21(f, n)

{
	cbuf(f, n, 21);
}

cbuf22(f, n)

{
	cbuf(f, n, 22);
}

cbuf23(f, n)

{
	cbuf(f, n, 23);
}

cbuf24(f, n)

{
	cbuf(f, n, 24);
}

cbuf25(f, n)

{
	cbuf(f, n, 25);
}

cbuf26(f, n)

{
	cbuf(f, n, 26);
}

cbuf27(f, n)

{
	cbuf(f, n, 27);
}

cbuf28(f, n)

{
	cbuf(f, n, 28);
}

cbuf29(f, n)

{
	cbuf(f, n, 29);
}

cbuf30(f, n)

{
	cbuf(f, n, 30);
}

cbuf31(f, n)

{
	cbuf(f, n, 31);
}

cbuf32(f, n)

{
	cbuf(f, n, 32);
}

cbuf33(f, n)

{
	cbuf(f, n, 33);
}

cbuf34(f, n)

{
	cbuf(f, n, 34);
}

cbuf35(f, n)

{
	cbuf(f, n, 35);
}

cbuf36(f, n)

{
	cbuf(f, n, 36);
}

cbuf37(f, n)

{
	cbuf(f, n, 37);
}

cbuf38(f, n)

{
	cbuf(f, n, 38);
}

cbuf39(f, n)

{
	cbuf(f, n, 39);
}

cbuf40(f, n)

{
	cbuf(f, n, 40);
}