home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-11-17 | 42.5 KB | 1,798 lines |
- Article 81 of comp.sources.misc:
- Path: tut!osu-cis!cbosgd!mandrill!hal!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: 14 Nov 87 21:08:42 GMT
- 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 <stdio.h>
- 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} <command-name> {<argument string(s)>}
- 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 <label> Jump to a label in the current macro
- X !force Force macro to continue...even if command fails
- X !while (cond) Execute a loop if the condition is true
- X !endwhile
- X
- X Line Labels begin with a "*" as the first nonblank char, like:
- X
- X *LBL01
- X*/
- X
- Xdobuf(bp)
- X
- XBUFFER *bp; /* buffer to execute */
- X
- X{
- X register int status; /* status return */
- X register LINE *lp; /* pointer to line to execute */
- X register LINE *hlp; /* pointer to line header */
- X register LINE *glp; /* line to goto */
- X LINE *mp; /* Macro line storage temp */
- X int dirnum; /* directive index */
- X int linlen; /* length of line to execute */
- X int i; /* index */
- X int c; /* temp character */
- X int force; /* force TRUE result? */
- X WINDOW *wp; /* ptr to windows to scan */
- X WHBLOCK *whlist; /* ptr to !WHILE list */
- X WHBLOCK *scanner; /* ptr during scan */
- X WHBLOCK *whtemp; /* temporary ptr to a WHBLOCK */
- X char *einit; /* initial value of eline */
- X char *eline; /* text of line to execute */
- X char tkn[NSTRING]; /* buffer to evaluate an expresion in */
- X
- X#if DEBUGM
- X char *sp; /* temp for building debug string */
- X register char *ep; /* ptr to end of outline */
- X#endif
- X
- X /* clear IF level flags/while ptr */
- X execlevel = 0;
- X whlist = NULL;
- X scanner = NULL;
- X
- X /* scan the buffer to execute, building WHILE header blocks */
- X hlp = bp->b_linep;
- X lp = hlp->l_fp;
- X while (lp != hlp) {
- X /* scan the current line */
- X eline = lp->l_text;
- X i = lp->l_used;
- X
- X /* trim leading whitespace */
- X while (i-- > 0 && (*eline == ' ' || *eline == '\t'))
- X ++eline;
- X
- X /* if theres nothing here, don't bother */
- X if (i <= 0)
- X goto nxtscan;
- X
- X /* if is a while directive, make a block... */
- X if (eline[0] == '!' && eline[1] == 'w' && eline[2] == 'h') {
- X whtemp = (WHBLOCK *)malloc(sizeof(WHBLOCK));
- X if (whtemp == NULL) {
- Xnoram: mlwrite("%%Out of memory during while scan");
- Xfailexit: freewhile(scanner);
- X freewhile(whlist);
- X return(FALSE);
- X }
- X whtemp->w_begin = lp;
- X whtemp->w_type = BTWHILE;
- X whtemp->w_next = scanner;
- X scanner = whtemp;
- X }
- X
- X /* if is a BREAK directive, make a block... */
- X if (eline[0] == '!' && eline[1] == 'b' && eline[2] == 'r') {
- X if (scanner == NULL) {
- X mlwrite("%%!BREAK outside of any !WHILE loop");
- X goto failexit;
- X }
- X whtemp = (WHBLOCK *)malloc(sizeof(WHBLOCK));
- X if (whtemp == NULL)
- X goto noram;
- X whtemp->w_begin = lp;
- X whtemp->w_type = BTBREAK;
- X whtemp->w_next = scanner;
- X scanner = whtemp;
- X }
- X
- X /* if it is an endwhile directive, record the spot... */
- X if (eline[0] == '!' && strncmp(&eline[1], "endw", 4) == 0) {
- X if (scanner == NULL) {
- X mlwrite("%%!ENDWHILE with no preceding !WHILE in '%s'",
- X bp->b_bname);
- X goto failexit;
- X }
- X /* move top records from the scanner list to the
- X whlist until we have moved all BREAK records
- X and one WHILE record */
- X do {
- X scanner->w_end = lp;
- X whtemp = whlist;
- X whlist = scanner;
- X scanner = scanner->w_next;
- X whlist->w_next = whtemp;
- X } while (whlist->w_type == BTBREAK);
- X }
- X
- Xnxtscan: /* on to the next line */
- X lp = lp->l_fp;
- X }
- X
- X /* while and endwhile should match! */
- X if (scanner != NULL) {
- X mlwrite("%%!WHILE with no matching !ENDWHILE in '%s'",
- X bp->b_bname);
- X goto failexit;
- X }
- X
- X /* let the first command inherit the flags from the last one..*/
- X thisflag = lastflag;
- X
- X /* starting at the beginning of the buffer */
- X hlp = bp->b_linep;
- X lp = hlp->l_fp;
- X while (lp != hlp) {
- X /* allocate eline and copy macro line to it */
- X linlen = lp->l_used;
- X if ((einit = eline = malloc(linlen+1)) == NULL) {
- X mlwrite("%%Out of Memory during macro execution");
- X freewhile(whlist);
- X return(FALSE);
- X }
- X strncpy(eline, lp->l_text, linlen);
- X eline[linlen] = 0; /* make sure it ends */
- X
- X /* trim leading whitespace */
- X while (*eline == ' ' || *eline == '\t')
- X ++eline;
- X
- X /* dump comments and blank lines */
- X if (*eline == ';' || *eline == 0)
- X goto onward;
- X
- X#if DEBUGM
- X /* if $debug == TRUE, every line to execute
- X gets echoed and a key needs to be pressed to continue
- X ^G will abort the command */
- X
- X if (macbug) {
- X strcpy(outline, "<<<");
- X
- X /* debug macro name */
- X strcat(outline, bp->b_bname);
- X strcat(outline, ":");
- X
- X /* debug if levels */
- X strcat(outline, itoa(execlevel));
- X strcat(outline, ":");
- X
- X /* and lastly the line */
- X strcat(outline, eline);
- X strcat(outline, ">>>");
- X
- X /* change all '%' to ':' so mlwrite won't expect arguments */
- X sp = outline;
- X while (*sp)
- X if (*sp++ == '%') {
- X /* advance to the end */
- X ep = --sp;
- X while (*ep++)
- X ;
- X /* null terminate the string one out */
- X *(ep + 1) = 0;
- X /* copy backwards */
- X while(ep-- > sp)
- X *(ep + 1) = *ep;
- X
- X /* and advance sp past the new % */
- X sp += 2;
- X }
- X
- X /* write out the debug line */
- X mlforce(outline);
- X update(TRUE);
- X
- X /* and get the keystroke */
- X if ((c = get1key()) == abortc) {
- X mlforce("[Macro aborted]");
- X freewhile(whlist);
- X return(FALSE);
- X }
- X
- X if (c == metac)
- X macbug = FALSE;
- X }
- X#endif
- X
- X /* Parse directives here.... */
- X dirnum = -1;
- X if (*eline == '!') {
- X /* Find out which directive this is */
- X ++eline;
- X for (dirnum = 0; dirnum < NUMDIRS; dirnum++)
- X if (strncmp(eline, dname[dirnum],
- X strlen(dname[dirnum])) == 0)
- X break;
- X
- X /* and bitch if it's illegal */
- X if (dirnum == NUMDIRS) {
- X mlwrite("%%Unknown Directive");
- X freewhile(whlist);
- X return(FALSE);
- X }
- X
- X /* service only the !ENDM macro here */
- X if (dirnum == DENDM) {
- X mstore = FALSE;
- X bstore = NULL;
- X goto onward;
- X }
- X
- X /* restore the original eline....*/
- X --eline;
- X }
- X
- X /* if macro store is on, just salt this away */
- X if (mstore) {
- X /* allocate the space for the line */
- X linlen = strlen(eline);
- X if ((mp=lalloc(linlen)) == NULL) {
- X mlwrite("Out of memory while storing macro");
- X return (FALSE);
- X }
- X
- X /* copy the text into the new line */
- X for (i=0; i<linlen; ++i)
- X lputc(mp, i, eline[i]);
- X
- X /* attach the line to the end of the buffer */
- X bstore->b_linep->l_bp->l_fp = mp;
- X mp->l_bp = bstore->b_linep->l_bp;
- X bstore->b_linep->l_bp = mp;
- X mp->l_fp = bstore->b_linep;
- X goto onward;
- X }
- X
- X
- X force = FALSE;
- X
- X /* dump comments */
- X if (*eline == '*')
- X goto onward;
- X
- X /* now, execute directives */
- X if (dirnum != -1) {
- X /* skip past the directive */
- X while (*eline && *eline != ' ' && *eline != '\t')
- X ++eline;
- X execstr = eline;
- X
- X switch (dirnum) {
- X case DIF: /* IF directive */
- X /* grab the value of the logical exp */
- X if (execlevel == 0) {
- X if (macarg(tkn) != TRUE)
- X goto eexec;
- X if (stol(tkn) == FALSE)
- X ++execlevel;
- X } else
- X ++execlevel;
- X goto onward;
- X
- X case DWHILE: /* WHILE directive */
- X /* grab the value of the logical exp */
- X if (execlevel == 0) {
- X if (macarg(tkn) != TRUE)
- X goto eexec;
- X if (stol(tkn) == TRUE)
- X goto onward;
- X }
- X /* drop down and act just like !BREAK */
- X
- X case DBREAK: /* BREAK directive */
- X if (dirnum == DBREAK && execlevel)
- X goto onward;
- X
- X /* jump down to the endwhile */
- X /* find the right while loop */
- X whtemp = whlist;
- X while (whtemp) {
- X if (whtemp->w_begin == lp)
- X break;
- X whtemp = whtemp->w_next;
- X }
- X
- X if (whtemp == NULL) {
- X mlwrite("%%Internal While loop error");
- X freewhile(whlist);
- X return(FALSE);
- X }
- X
- X /* reset the line pointer back.. */
- X lp = whtemp->w_end;
- X goto onward;
- X
- X case DELSE: /* ELSE directive */
- X if (execlevel == 1)
- X --execlevel;
- X else if (execlevel == 0 )
- X ++execlevel;
- X goto onward;
- X
- X case DENDIF: /* ENDIF directive */
- X if (execlevel)
- X --execlevel;
- X goto onward;
- X
- X case DGOTO: /* GOTO directive */
- X /* .....only if we are currently executing */
- X if (execlevel == 0) {
- X
- X /* grab label to jump to */
- X eline = token(eline, golabel, NPAT);
- X linlen = strlen(golabel);
- X glp = hlp->l_fp;
- X while (glp != hlp) {
- X if (*glp->l_text == '*' &&
- X (strncmp(&glp->l_text[1], golabel,
- X linlen) == 0)) {
- X lp = glp;
- X goto onward;
- X }
- X glp = glp->l_fp;
- X }
- X mlwrite("%%No such label");
- X freewhile(whlist);
- X return(FALSE);
- X }
- X goto onward;
- X
- X case DRETURN: /* RETURN directive */
- X if (execlevel == 0)
- X goto eexec;
- X goto onward;
- X
- X case DENDWHILE: /* ENDWHILE directive */
- X if (execlevel) {
- X --execlevel;
- X goto onward;
- X } else {
- X /* find the right while loop */
- X whtemp = whlist;
- X while (whtemp) {
- X if (whtemp->w_type == BTWHILE &&
- X whtemp->w_end == lp)
- X break;
- X whtemp = whtemp->w_next;
- X }
- X
- X if (whtemp == NULL) {
- X mlwrite("%%Internal While loop error");
- X freewhile(whlist);
- X return(FALSE);
- X }
- X
- X /* reset the line pointer back.. */
- X lp = whtemp->w_begin->l_bp;
- X goto onward;
- X }
- X
- X case DFORCE: /* FORCE directive */
- X force = TRUE;
- X
- X }
- X }
- X
- X /* execute the statement */
- X status = docmd(eline);
- X if (force) /* force the status */
- X status = TRUE;
- X
- X /* check for a command error */
- X if (status != TRUE) {
- X /* look if buffer is showing */
- X wp = wheadp;
- X while (wp != NULL) {
- X if (wp->w_bufp == bp) {
- X /* and point it */
- X wp->w_dotp = lp;
- X wp->w_doto = 0;
- X wp->w_flag |= WFHARD;
- X }
- X wp = wp->w_wndp;
- X }
- X /* in any case set the buffer . */
- X bp->b_dotp = lp;
- X bp->b_doto = 0;
- X free(einit);
- X execlevel = 0;
- X freewhile(whlist);
- X return(status);
- X }
- X
- Xonward: /* on to the next line */
- X free(einit);
- X lp = lp->l_fp;
- X }
- X
- Xeexec: /* exit the current function */
- X execlevel = 0;
- X freewhile(whlist);
- X return(TRUE);
- X}
- X
- Xfreewhile(wp) /* free a list of while block pointers */
- X
- XWHBLOCK *wp; /* head of structure to free */
- X
- X{
- X if (wp == NULL)
- X return;
- X if (wp->w_next)
- X freewhile(wp->w_next);
- X free(wp);
- X}
- X
- Xexecfile(f, n) /* execute a series of commands in a file */
- X
- Xint f, n; /* default flag and numeric arg to pass on to file */
- X
- X{
- X register int status; /* return status of name query */
- X char fname[NSTRING]; /* name of file to execute */
- X char *fspec; /* full file spec */
- X
- X if ((status = mlreply("File to execute: ", fname, NSTRING -1)) != TRUE)
- X return(status);
- X
- X#if 1
- X /* look up the path for the file */
- X fspec = flook(fname, TRUE);
- X
- X /* if it isn't around */
- X if (fspec == NULL)
- X return(FALSE);
- X
- X#endif
- X /* otherwise, execute it */
- X while (n-- > 0)
- X if ((status=dofile(fspec)) != TRUE)
- X return(status);
- X
- X return(TRUE);
- X}
- X
- X/* dofile: yank a file into a buffer and execute it
- X if there are no errors, delete the buffer on exit */
- X
- Xdofile(fname)
- X
- Xchar *fname; /* file name to execute */
- X
- X{
- X register BUFFER *bp; /* buffer to place file to exeute */
- X register BUFFER *cb; /* temp to hold current buf while we read */
- X register int status; /* results of various calls */
- X char bname[NBUFN]; /* name of buffer */
- X
- X makename(bname, fname); /* derive the name of the buffer */
- X unqname(bname); /* make sure we don't stomp things */
- X if ((bp = bfind(bname, TRUE, 0)) == NULL) /* get the needed buffer */
- X return(FALSE);
- X
- X bp->b_mode = MDVIEW; /* mark the buffer as read only */
- X cb = curbp; /* save the old buffer */
- X curbp = bp; /* make this one current */
- X /* and try to read in the file to execute */
- X if ((status = readin(fname, FALSE)) != TRUE) {
- X curbp = cb; /* restore the current buffer */
- X return(status);
- X }
- X
- X /* go execute it! */
- X curbp = cb; /* restore the current buffer */
- X if ((status = dobuf(bp)) != TRUE)
- X return(status);
- X
- X /* if not displayed, remove the now unneeded buffer and exit */
- X if (bp->b_nwnd == 0)
- X zotbuf(bp);
- X return(TRUE);
- X}
- X
- X/* cbuf: Execute the contents of a numbered buffer */
- X
- Xcbuf(f, n, bufnum)
- X
- Xint f, n; /* default flag and numeric arg */
- Xint bufnum; /* number of buffer to execute */
- X
- X{
- X register BUFFER *bp; /* ptr to buffer to execute */
- X register int status; /* status return */
- X static char bufname[] = "[Macro xx]";
- X
- X /* make the buffer name */
- X bufname[7] = '0' + (bufnum / 10);
- X bufname[8] = '0' + (bufnum % 10);
- X
- X /* find the pointer to that buffer */
- X if ((bp=bfind(bufname, FALSE, 0)) == NULL) {
- X mlwrite("Macro not defined");
- 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
- Xcbuf1(f, n)
- X
- X{
- X cbuf(f, n, 1);
- X}
- X
- Xcbuf2(f, n)
- X
- X{
- X cbuf(f, n, 2);
- X}
- X
- Xcbuf3(f, n)
- X
- X{
- X cbuf(f, n, 3);
- X}
- X
- Xcbuf4(f, n)
- X
- X{
- X cbuf(f, n, 4);
- X}
- X
- Xcbuf5(f, n)
- X
- X{
- X cbuf(f, n, 5);
- X}
- X
- Xcbuf6(f, n)
- X
- X{
- X cbuf(f, n, 6);
- X}
- X
- Xcbuf7(f, n)
- X
- X{
- X cbuf(f, n, 7);
- X}
- X
- Xcbuf8(f, n)
- X
- X{
- X cbuf(f, n, 8);
- X}
- X
- Xcbuf9(f, n)
- X
- X{
- X cbuf(f, n, 9);
- X}
- X
- Xcbuf10(f, n)
- X
- X{
- X cbuf(f, n, 10);
- X}
- X
- Xcbuf11(f, n)
- X
- X{
- X cbuf(f, n, 11);
- X}
- X
- Xcbuf12(f, n)
- X
- X{
- X cbuf(f, n, 12);
- X}
- X
- Xcbuf13(f, n)
- X
- X{
- X cbuf(f, n, 13);
- X}
- X
- Xcbuf14(f, n)
- X
- X{
- X cbuf(f, n, 14);
- X}
- X
- Xcbuf15(f, n)
- X
- X{
- X cbuf(f, n, 15);
- X}
- X
- Xcbuf16(f, n)
- X
- X{
- X cbuf(f, n, 16);
- X}
- X
- Xcbuf17(f, n)
- X
- X{
- X cbuf(f, n, 17);
- X}
- X
- Xcbuf18(f, n)
- X
- X{
- X cbuf(f, n, 18);
- X}
- X
- Xcbuf19(f, n)
- X
- X{
- X cbuf(f, n, 19);
- X}
- X
- Xcbuf20(f, n)
- X
- X{
- X cbuf(f, n, 20);
- X}
- X
- Xcbuf21(f, n)
- X
- X{
- X cbuf(f, n, 21);
- X}
- X
- Xcbuf22(f, n)
- X
- X{
- X cbuf(f, n, 22);
- X}
- X
- Xcbuf23(f, n)
- X
- X{
- X cbuf(f, n, 23);
- X}
- X
- Xcbuf24(f, n)
- X
- X{
- X cbuf(f, n, 24);
- X}
- X
- Xcbuf25(f, n)
- X
- X{
- X cbuf(f, n, 25);
- X}
- X
- Xcbuf26(f, n)
- X
- X{
- X cbuf(f, n, 26);
- X}
- X
- Xcbuf27(f, n)
- X
- X{
- X cbuf(f, n, 27);
- X}
- X
- Xcbuf28(f, n)
- X
- X{
- X cbuf(f, n, 28);
- X}
- X
- Xcbuf29(f, n)
- X
- X{
- X cbuf(f, n, 29);
- X}
- X
- Xcbuf30(f, n)
- X
- X{
- X cbuf(f, n, 30);
- X}
- X
- Xcbuf31(f, n)
- X
- X{
- X cbuf(f, n, 31);
- X}
- X
- Xcbuf32(f, n)
- X
- X{
- X cbuf(f, n, 32);
- X}
- X
- Xcbuf33(f, n)
- X
- X{
- X cbuf(f, n, 33);
- X}
- X
- Xcbuf34(f, n)
- X
- X{
- X cbuf(f, n, 34);
- X}
- X
- Xcbuf35(f, n)
- X
- X{
- X cbuf(f, n, 35);
- X}
- X
- Xcbuf36(f, n)
- X
- X{
- X cbuf(f, n, 36);
- X}
- X
- Xcbuf37(f, n)
- X
- X{
- X cbuf(f, n, 37);
- X}
- X
- Xcbuf38(f, n)
- X
- X{
- X cbuf(f, n, 38);
- X}
- X
- Xcbuf39(f, n)
- X
- X{
- X cbuf(f, n, 39);
- X}
- X
- Xcbuf40(f, n)
- X
- X{
- X cbuf(f, n, 40);
- X}
- X
- X
- FRIDAY_NIGHT
- echo extracting - file.c
- sed 's/^X//' > file.c << 'FRIDAY_NIGHT'
- X/* FILE.C: for MicroEMACS
- X
- X The routines in this file handle the reading, writing
- X and lookup of disk files. All of details about the
- X reading and writing of the disk are in "fileio.c".
- X
- X*/
- X
- X#include <stdio.h>
- X#include "estruct.h"
- X#include "edef.h"
- X
- X/*
- X * Read a file into the current
- X * buffer. This is really easy; all you do it
- X * find the name of the file, and call the standard
- X * "read a file into the current buffer" code.
- X * Bound to "C-X C-R".
- X */
- Xfileread(f, n)
- X{
- X register int s;
- X char fname[NFILEN];
- X
- X if (restflag) /* don't allow this command if restricted */
- X return(resterr());
- X if ((s=mlreply("Read file: ", fname, NFILEN)) != TRUE)
- X return(s);
- X return(readin(fname, TRUE));
- X}
- X
- X/*
- X * Insert a file into the current
- X * buffer. This is really easy; all you do it
- X * find the name of the file, and call the standard
- X * "insert a file into the current buffer" code.
- X * Bound to "C-X C-I".
- X */
- Xinsfile(f, n)
- X{
- X register int s;
- X char fname[NFILEN];
- X
- X if (restflag) /* don't allow this command if restricted */
- X return(resterr());
- X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
- X return(rdonly()); /* we are in read only mode */
- X if ((s=mlreply("Insert file: ", fname, NFILEN)) != TRUE)
- X return(s);
- X return(ifile(fname));
- X}
- X
- X/*
- X * Select a file for editing.
- X * Look around to see if you can find the
- X * fine in another buffer; if you can find it
- X * just switch to the buffer. If you cannot find
- X * the file, create a new buffer, read in the
- X * text, and switch to the new buffer.
- X * Bound to C-X C-F.
- X */
- Xfilefind(f, n)
- X{
- X char fname[NFILEN]; /* file user wishes to find */
- X register int s; /* status return */
- X
- X if (restflag) /* don't allow this command if restricted */
- X return(resterr());
- X if ((s=mlreply("Find file: ", fname, NFILEN)) != TRUE)
- X return(s);
- X return(getfile(fname, TRUE));
- X}
- X
- Xviewfile(f, n) /* visit a file in VIEW mode */
- X{
- X char fname[NFILEN]; /* file user wishes to find */
- X register int s; /* status return */
- X register WINDOW *wp; /* scan for windows that need updating */
- X
- X if (restflag) /* don't allow this command if restricted */
- X return(resterr());
- X if ((s=mlreply("View file: ", fname, NFILEN)) != TRUE)
- X return (s);
- X s = getfile(fname, FALSE);
- X if (s) { /* if we succeed, put it in view mode */
- X curwp->w_bufp->b_mode |= MDVIEW;
- X
- X /* scan through and update mode lines of all windows */
- X wp = wheadp;
- X while (wp != NULL) {
- X wp->w_flag |= WFMODE;
- X wp = wp->w_wndp;
- X }
- X }
- X return(s);
- X}
- X
- X#if CRYPT
- Xresetkey() /* reset the encryption key if needed */
- X
- X{
- X register int s; /* return status */
- X
- X /* turn off the encryption flag */
- X cryptflag = FALSE;
- X
- X /* if we are in crypt mode */
- X if (curbp->b_mode & MDCRYPT) {
- X if (curbp->b_key[0] == 0) {
- X s = setkey(FALSE, 0);
- X if (s != TRUE)
- X return(s);
- X }
- X
- X /* let others know... */
- X cryptflag = TRUE;
- X
- X /* and set up the key to be used! */
- X /* de-encrypt it */
- X crypt((char *)NULL, 0);
- X crypt(curbp->b_key, strlen(curbp->b_key));
- X
- X /* re-encrypt it...seeding it to start */
- X crypt((char *)NULL, 0);
- X crypt(curbp->b_key, strlen(curbp->b_key));
- X }
- X
- X return(TRUE);
- X}
- X#endif
- X
- Xgetfile(fname, lockfl)
- X
- Xchar fname[]; /* file name to find */
- Xint lockfl; /* check the file for locks? */
- X
- X{
- X register BUFFER *bp;
- X register LINE *lp;
- X register int i;
- X register int s;
- X char bname[NBUFN]; /* buffer name to put file */
- X
- X#if MSDOS
- X mklower(fname); /* msdos isn't case sensitive */
- X#endif
- X for (bp=bheadp; bp!=NULL; bp=bp->b_bufp) {
- X if ((bp->b_flag&BFINVS)==0 && strcmp(bp->b_fname, fname)==0) {
- X swbuffer(bp);
- X lp = curwp->w_dotp;
- X i = curwp->w_ntrows/2;
- X while (i-- && lback(lp)!=curbp->b_linep)
- X lp = lback(lp);
- X curwp->w_linep = lp;
- X curwp->w_flag |= WFMODE|WFHARD;
- X mlwrite("[Old buffer]");
- X return (TRUE);
- X }
- X }
- X makename(bname, fname); /* New buffer name. */
- X while ((bp=bfind(bname, FALSE, 0)) != NULL) {
- X /* old buffer name conflict code */
- X s = mlreply("Buffer name: ", bname, NBUFN);
- X if (s == ABORT) /* ^G to just quit */
- X return (s);
- X if (s == FALSE) { /* CR to clobber it */
- X makename(bname, fname);
- X break;
- X }
- X }
- X if (bp==NULL && (bp=bfind(bname, TRUE, 0))==NULL) {
- X mlwrite("Cannot create buffer");
- X return (FALSE);
- X }
- X if (--curbp->b_nwnd == 0) { /* Undisplay. */
- X curbp->b_dotp = curwp->w_dotp;
- X curbp->b_doto = curwp->w_doto;
- X curbp->b_markp = curwp->w_markp;
- X curbp->b_marko = curwp->w_marko;
- X }
- X curbp = bp; /* Switch to it. */
- X curwp->w_bufp = bp;
- X curbp->b_nwnd++;
- X return(readin(fname, lockfl)); /* Read it in. */
- X}
- X
- X/*
- X Read file "fname" into the current buffer, blowing away any text
- X found there. Called by both the read and find commands. Return
- X the final status of the read. Also called by the mainline, to
- X read in a file specified on the command line as an argument.
- X The command bound to M-FNR is called after the buffer is set up
- X and before it is read.
- X*/
- X
- Xreadin(fname, lockfl)
- X
- Xchar fname[]; /* name of file to read */
- Xint lockfl; /* check for file locks? */
- X
- X{
- X register LINE *lp1;
- X register LINE *lp2;
- X register int i;
- X register WINDOW *wp;
- X register BUFFER *bp;
- X register int s;
- X register int nbytes;
- X register int nline;
- X int lflag; /* any lines longer than allowed? */
- X char mesg[NSTRING];
- X
- X#if FILOCK
- X if (lockfl && lockchk(fname) == ABORT)
- X return(ABORT);
- X#endif
- X#if CRYPT
- X s = resetkey();
- X if (s != TRUE)
- X return(s);
- X#endif
- X bp = curbp; /* Cheap. */
- X if ((s=bclear(bp)) != TRUE) /* Might be old. */
- X return (s);
- X bp->b_flag &= ~(BFINVS|BFCHG);
- X strcpy(bp->b_fname, fname);
- X
- X /* let a user macro get hold of things...if he wants */
- X execute(META|SPEC|'R', FALSE, 1);
- X
- X /* turn off ALL keyboard translation in case we get a dos error */
- X TTkclose();
- X
- X if ((s=ffropen(fname)) == FIOERR) /* Hard file open. */
- X goto out;
- X
- X if (s == FIOFNF) { /* File not found. */
- X mlwrite("[New file]");
- X goto out;
- X }
- X
- X /* read the file in */
- X mlwrite("[Reading file]");
- X nline = 0;
- X lflag = FALSE;
- X while ((s=ffgetline()) == FIOSUC) {
- X nbytes = strlen(fline);
- X if ((lp1=lalloc(nbytes)) == NULL) {
- X s = FIOMEM; /* Keep message on the */
- X break; /* display. */
- X }
- X lp2 = lback(curbp->b_linep);
- X lp2->l_fp = lp1;
- X lp1->l_fp = curbp->b_linep;
- X lp1->l_bp = lp2;
- X curbp->b_linep->l_bp = lp1;
- X for (i=0; i<nbytes; ++i)
- X lputc(lp1, i, fline[i]);
- X ++nline;
- X }
- X ffclose(); /* Ignore errors. */
- X strcpy(mesg, "[");
- X if (s==FIOERR) {
- X strcat(mesg, "I/O ERROR, ");
- X curbp->b_flag |= BFTRUNC;
- X }
- X if (s == FIOMEM) {
- X strcat(mesg, "OUT OF MEMORY, ");
- X curbp->b_flag |= BFTRUNC;
- X }
- X sprintf(&mesg[strlen(mesg)], "Read %d line", nline);
- X if (nline > 1)
- X strcat(mesg, "s");
- X strcat(mesg, "]");
- X mlwrite(mesg);
- X
- Xout:
- X TTkopen(); /* open the keyboard again */
- X for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
- X if (wp->w_bufp == curbp) {
- X wp->w_linep = lforw(curbp->b_linep);
- X wp->w_dotp = lforw(curbp->b_linep);
- X wp->w_doto = 0;
- X wp->w_markp = NULL;
- X wp->w_marko = 0;
- X wp->w_flag |= WFMODE|WFHARD;
- X }
- X }
- X if (s == FIOERR || s == FIOFNF) /* False if error. */
- X return(FALSE);
- X return (TRUE);
- X}
- X
- X/*
- X * Take a file name, and from it
- X * fabricate a buffer name. This routine knows
- X * about the syntax of file names on the target system.
- X * I suppose that this information could be put in
- X * a better place than a line of code.
- X */
- Xmakename(bname, fname)
- Xchar bname[];
- Xchar fname[];
- X{
- X register char *cp1;
- X register char *cp2;
- X
- X cp1 = &fname[0];
- X while (*cp1 != 0)
- X ++cp1;
- X
- X#if AMIGA
- X while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='/')
- X --cp1;
- X#endif
- X#if VMS
- X while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!=']')
- X --cp1;
- X#endif
- X#if CPM
- X while (cp1!=&fname[0] && cp1[-1]!=':')
- X --cp1;
- X#endif
- X#if MSDOS
- X while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\'&&cp1[-1]!='/')
- X --cp1;
- X#endif
- X#if ST520
- X while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\')
- X --cp1;
- X#endif
- X#if FINDER
- X while (cp1!=&fname[0] && cp1[-1]!=':' && cp1[-1]!='\\'&&cp1[-1]!='/')
- X --cp1;
- X#endif
- X#if V7 | USG | BSD
- X while (cp1!=&fname[0] && cp1[-1]!='/')
- X --cp1;
- X#endif
- X cp2 = &bname[0];
- X while (cp2!=&bname[NBUFN-1] && *cp1!=0 && *cp1!=';')
- X *cp2++ = *cp1++;
- X *cp2 = 0;
- X}
- X
- Xunqname(name) /* make sure a buffer name is unique */
- X
- Xchar *name; /* name to check on */
- X
- X{
- X register char *sp;
- X
- X /* check to see if it is in the buffer list */
- X while (bfind(name, 0, FALSE) != NULL) {
- X
- X /* go to the end of the name */
- X sp = name;
- X while (*sp)
- X ++sp;
- X if (sp == name || (*(sp-1) <'0' || *(sp-1) > '8')) {
- X *sp++ = '0';
- X *sp = 0;
- X } else
- X *(--sp) += 1;
- X }
- X}
- X
- X/*
- X * Ask for a file name, and write the
- X * contents of the current buffer to that file.
- X * Update the remembered file name and clear the
- X * buffer changed flag. This handling of file names
- X * is different from the earlier versions, and
- X * is more compatable with Gosling EMACS than
- X * with ITS EMACS. Bound to "C-X C-W".
- X */
- Xfilewrite(f, n)
- X{
- X register WINDOW *wp;
- X register int s;
- X char fname[NFILEN];
- X
- X if (restflag) /* don't allow this command if restricted */
- X return(resterr());
- X if ((s=mlreply("Write file: ", fname, NFILEN)) != TRUE)
- X return (s);
- X if ((s=writeout(fname)) == TRUE) {
- X strcpy(curbp->b_fname, fname);
- X curbp->b_flag &= ~BFCHG;
- X wp = wheadp; /* Update mode lines. */
- X while (wp != NULL) {
- X if (wp->w_bufp == curbp)
- X wp->w_flag |= WFMODE;
- X wp = wp->w_wndp;
- X }
- X }
- X return (s);
- X}
- X
- X/*
- X * Save the contents of the current
- X * buffer in its associatd file. No nothing
- X * if nothing has changed (this may be a bug, not a
- X * feature). Error if there is no remembered file
- X * name for the buffer. Bound to "C-X C-S". May
- X * get called by "C-Z".
- X */
- Xfilesave(f, n)
- X{
- X register WINDOW *wp;
- X register int s;
- X
- X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
- X return(rdonly()); /* we are in read only mode */
- X if ((curbp->b_flag&BFCHG) == 0) /* Return, no changes. */
- X return (TRUE);
- X if (curbp->b_fname[0] == 0) { /* Must have a name. */
- X mlwrite("No file name");
- X return (FALSE);
- X }
- X
- X /* complain about truncated files */
- X if ((curbp->b_flag&BFTRUNC) != 0) {
- X if (mlyesno("Truncated file..write it out") == FALSE) {
- X mlwrite("[Aborted]");
- X return(FALSE);
- X }
- X }
- X
- X if ((s=writeout(curbp->b_fname)) == TRUE) {
- X curbp->b_flag &= ~BFCHG;
- X wp = wheadp; /* Update mode lines. */
- X while (wp != NULL) {
- X if (wp->w_bufp == curbp)
- X wp->w_flag |= WFMODE;
- X wp = wp->w_wndp;
- X }
- X }
- X return (s);
- X}
- X
- X/*
- X * This function performs the details of file
- X * writing. Uses the file management routines in the
- X * "fileio.c" package. The number of lines written is
- X * displayed. Sadly, it looks inside a LINE; provide
- X * a macro for this. Most of the grief is error
- X * checking of some sort.
- X */
- Xwriteout(fn)
- Xchar *fn;
- X{
- X register int s;
- X register LINE *lp;
- X register int nline;
- X
- X#if CRYPT
- X s = resetkey();
- X if (s != TRUE)
- X return(s);
- X#endif
- X /* turn off ALL keyboard translation in case we get a dos error */
- X TTkclose();
- X
- X if ((s=ffwopen(fn)) != FIOSUC) { /* Open writes message. */
- X TTkopen();
- X return (FALSE);
- X }
- X mlwrite("[Writing...]"); /* tell us were writing */
- X lp = lforw(curbp->b_linep); /* First line. */
- X nline = 0; /* Number of lines. */
- X while (lp != curbp->b_linep) {
- X if ((s=ffputline(&lp->l_text[0], llength(lp))) != FIOSUC)
- X break;
- X ++nline;
- X lp = lforw(lp);
- X }
- X if (s == FIOSUC) { /* No write error. */
- X s = ffclose();
- X if (s == FIOSUC) { /* No close error. */
- X if (nline == 1)
- X mlwrite("[Wrote 1 line]");
- X else
- X mlwrite("[Wrote %d lines]", nline);
- X }
- X } else /* Ignore close error */
- X ffclose(); /* if a write error. */
- X TTkopen();
- X if (s != FIOSUC) /* Some sort of error. */
- X return (FALSE);
- X return (TRUE);
- X}
- X
- X/*
- X * The command allows the user
- X * to modify the file name associated with
- X * the current buffer. It is like the "f" command
- X * in UNIX "ed". The operation is simple; just zap
- X * the name in the BUFFER structure, and mark the windows
- X * as needing an update. You can type a blank line at the
- X * prompt if you wish.
- X */
- Xfilename(f, n)
- X{
- X register WINDOW *wp;
- X register int s;
- X char fname[NFILEN];
- X
- X if (restflag) /* don't allow this command if restricted */
- X return(resterr());
- X if ((s=mlreply("Name: ", fname, NFILEN)) == ABORT)
- X return (s);
- X if (s == FALSE)
- X strcpy(curbp->b_fname, "");
- X else
- X strcpy(curbp->b_fname, fname);
- X wp = wheadp; /* Update mode lines. */
- X while (wp != NULL) {
- X if (wp->w_bufp == curbp)
- X wp->w_flag |= WFMODE;
- X wp = wp->w_wndp;
- X }
- X curbp->b_mode &= ~MDVIEW; /* no longer read only mode */
- X return (TRUE);
- X}
- X
- X/*
- X * Insert file "fname" into the current
- X * buffer, Called by insert file command. Return the final
- X * status of the read.
- X */
- Xifile(fname)
- Xchar fname[];
- X{
- X register LINE *lp0;
- X register LINE *lp1;
- X register LINE *lp2;
- X register int i;
- X register BUFFER *bp;
- X register int s;
- X register int nbytes;
- X register int nline;
- X int lflag; /* any lines longer than allowed? */
- X char mesg[NSTRING];
- X
- X bp = curbp; /* Cheap. */
- X bp->b_flag |= BFCHG; /* we have changed */
- X bp->b_flag &= ~BFINVS; /* and are not temporary*/
- X if ((s=ffropen(fname)) == FIOERR) /* Hard file open. */
- X goto out;
- X if (s == FIOFNF) { /* File not found. */
- X mlwrite("[No such file]");
- X return(FALSE);
- X }
- X mlwrite("[Inserting file]");
- X
- X#if CRYPT
- X s = resetkey();
- X if (s != TRUE)
- X return(s);
- X#endif
- X /* back up a line and save the mark here */
- X curwp->w_dotp = lback(curwp->w_dotp);
- X curwp->w_doto = 0;
- X curwp->w_markp = curwp->w_dotp;
- X curwp->w_marko = 0;
- X
- X nline = 0;
- X lflag = FALSE;
- X while ((s=ffgetline()) == FIOSUC) {
- X nbytes = strlen(fline);
- X if ((lp1=lalloc(nbytes)) == NULL) {
- X s = FIOMEM; /* Keep message on the */
- X break; /* display. */
- X }
- X lp0 = curwp->w_dotp; /* line previous to insert */
- X lp2 = lp0->l_fp; /* line after insert */
- X
- X /* re-link new line between lp0 and lp2 */
- X lp2->l_bp = lp1;
- X lp0->l_fp = lp1;
- X lp1->l_bp = lp0;
- X lp1->l_fp = lp2;
- X
- X /* and advance and write out the current line */
- X curwp->w_dotp = lp1;
- X for (i=0; i<nbytes; ++i)
- X lputc(lp1, i, fline[i]);
- X ++nline;
- X }
- X ffclose(); /* Ignore errors. */
- X curwp->w_markp = lforw(curwp->w_markp);
- X strcpy(mesg, "[");
- X if (s==FIOERR) {
- X strcat(mesg, "I/O ERROR, ");
- X curbp->b_flag |= BFTRUNC;
- X }
- X if (s == FIOMEM) {
- X strcat(mesg, "OUT OF MEMORY, ");
- X curbp->b_flag |= BFTRUNC;
- X }
- X sprintf(&mesg[strlen(mesg)], "Inserted %d line", nline);
- X if (nline > 1)
- X strcat(mesg, "s");
- X strcat(mesg, "]");
- X mlwrite(mesg);
- X
- Xout:
- X /* advance to the next line and mark the window for changes */
- X curwp->w_dotp = lforw(curwp->w_dotp);
- X curwp->w_flag |= WFHARD | WFMODE;
- X
- X /* copy window parameters back to the buffer structure */
- X curbp->b_dotp = curwp->w_dotp;
- X curbp->b_doto = curwp->w_doto;
- X curbp->b_markp = curwp->w_markp;
- X curbp->b_marko = curwp->w_marko;
- X
- X if (s == FIOERR) /* False if error. */
- X return (FALSE);
- X return (TRUE);
- X}
- FRIDAY_NIGHT
- echo mes.5 completed!
- # That's all folks!
-
-
-