home *** CD-ROM | disk | FTP | other *** search
Text File | 1987-11-17 | 78.1 KB | 2,465 lines |
- Article 84 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 8 of 16)
- Message-ID: <5655@ncoast.UUCP>
- Date: 14 Nov 87 21:11:14 GMT
- Sender: allbery@ncoast.UUCP
- Lines: 2450
- Approved: allbery@ncoast.UUCP
- X-Archive: comp.sources.misc/microemacs-3.9/7
-
- # This is a shar archive.
- # Remove everything above this line.
- # Run the file through sh, not csh.
- # (type `sh mes.8')
- # If you do not see the message
- # `mes.8 completed!'
- # then the file was incomplete.
- echo extracting - line.c
- sed 's/^X//' > line.c << 'FRIDAY_NIGHT'
- X/*
- X * The functions in this file are a general set of line management utilities.
- X * They are the only routines that touch the text. They also touch the buffer
- X * and window structures, to make sure that the necessary updating gets done.
- X * There are routines in this file that handle the kill buffer too. It isn't
- X * here for any good reason.
- X *
- X * Note that this code only updates the dot and mark values in the window list.
- X * Since all the code acts on the current window, the buffer that we are
- X * editing must be being displayed, which means that "b_nwnd" is non zero,
- X * which means that the dot and mark values in the buffer headers are nonsense.
- X */
- X
- X#include <stdio.h>
- X#include "estruct.h"
- X#include "edef.h"
- X
- XKILL *ykbuf; /* ptr to current kill buffer chunk being yanked */
- Xint ykboff; /* offset into that chunk */
- X
- X/*
- X * This routine allocates a block of memory large enough to hold a LINE
- X * containing "used" characters. The block is always rounded up a bit. Return
- X * a pointer to the new block, or NULL if there isn't any memory left. Print a
- X * message in the message line if no space.
- X */
- XLINE *lalloc(used)
- X
- Xregister int used;
- X
- X{
- X register LINE *lp;
- X register int size;
- X char *malloc();
- X
- X size = (used+NBLOCK-1) & ~(NBLOCK-1);
- X if (size == 0) /* Assume that an empty */
- X size = NBLOCK; /* line is for type-in. */
- X if ((lp = (LINE *) malloc(sizeof(LINE)+size)) == NULL) {
- X mlwrite("[OUT OF MEMORY]");
- X return (NULL);
- X }
- X lp->l_size = size;
- X lp->l_used = used;
- X return (lp);
- X}
- X
- X/*
- X * Delete line "lp". Fix all of the links that might point at it (they are
- X * moved to offset 0 of the next line. Unlink the line from whatever buffer it
- X * might be in. Release the memory. The buffers are updated too; the magic
- X * conditions described in the above comments don't hold here.
- X */
- Xlfree(lp)
- Xregister LINE *lp;
- X{
- X register BUFFER *bp;
- X register WINDOW *wp;
- X
- X wp = wheadp;
- X while (wp != NULL) {
- X if (wp->w_linep == lp)
- X wp->w_linep = lp->l_fp;
- X if (wp->w_dotp == lp) {
- X wp->w_dotp = lp->l_fp;
- X wp->w_doto = 0;
- X }
- X if (wp->w_markp == lp) {
- X wp->w_markp = lp->l_fp;
- X wp->w_marko = 0;
- X }
- X wp = wp->w_wndp;
- X }
- X bp = bheadp;
- X while (bp != NULL) {
- X if (bp->b_nwnd == 0) {
- X if (bp->b_dotp == lp) {
- X bp->b_dotp = lp->l_fp;
- X bp->b_doto = 0;
- X }
- X if (bp->b_markp == lp) {
- X bp->b_markp = lp->l_fp;
- X bp->b_marko = 0;
- X }
- X }
- X bp = bp->b_bufp;
- X }
- X lp->l_bp->l_fp = lp->l_fp;
- X lp->l_fp->l_bp = lp->l_bp;
- X free((char *) lp);
- X}
- X
- X/*
- X * This routine gets called when a character is changed in place in the current
- X * buffer. It updates all of the required flags in the buffer and window
- X * system. The flag used is passed as an argument; if the buffer is being
- X * displayed in more than 1 window we change EDIT t HARD. Set MODE if the
- X * mode line needs to be updated (the "*" has to be set).
- X */
- Xlchange(flag)
- Xregister int flag;
- X{
- X register WINDOW *wp;
- X
- X if (curbp->b_nwnd != 1) /* Ensure hard. */
- X flag = WFHARD;
- X if ((curbp->b_flag&BFCHG) == 0) { /* First change, so */
- X flag |= WFMODE; /* update mode lines. */
- X curbp->b_flag |= BFCHG;
- X }
- X wp = wheadp;
- X while (wp != NULL) {
- X if (wp->w_bufp == curbp)
- X wp->w_flag |= flag;
- X wp = wp->w_wndp;
- X }
- X}
- X
- Xinsspace(f, n) /* insert spaces forward into text */
- X
- Xint f, n; /* default flag and numeric argument */
- X
- X{
- X linsert(n, ' ');
- X backchar(f, n);
- X}
- X
- X/*
- X * linstr -- Insert a string at the current point
- X */
- X
- Xlinstr(instr)
- Xchar *instr;
- X{
- X register int status = TRUE;
- X char tmpc;
- X
- X if (instr != NULL)
- X while ((tmpc = *instr) && status == TRUE) {
- X status = (tmpc == '\n'? lnewline(): linsert(1, tmpc));
- X
- X /* Insertion error? */
- X if (status != TRUE) {
- X mlwrite("%%Out of memory while inserting");
- X break;
- X }
- X instr++;
- X }
- X return(status);
- X}
- X
- X/*
- X * Insert "n" copies of the character "c" at the current location of dot. In
- X * the easy case all that happens is the text is stored in the line. In the
- X * hard case, the line has to be reallocated. When the window list is updated,
- X * take special care; I screwed it up once. You always update dot in the
- X * current window. You update mark, and a dot in another window, if it is
- X * greater than the place where you did the insert. Return TRUE if all is
- X * well, and FALSE on errors.
- X */
- X
- Xlinsert(n, c)
- X{
- X register char *cp1;
- X register char *cp2;
- X register LINE *lp1;
- X register LINE *lp2;
- X register LINE *lp3;
- X register int doto;
- X register int i;
- X register WINDOW *wp;
- X
- X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
- X return(rdonly()); /* we are in read only mode */
- X lchange(WFEDIT);
- X lp1 = curwp->w_dotp; /* Current line */
- X if (lp1 == curbp->b_linep) { /* At the end: special */
- X if (curwp->w_doto != 0) {
- X mlwrite("bug: linsert");
- X return (FALSE);
- X }
- X if ((lp2=lalloc(n)) == NULL) /* Allocate new line */
- X return (FALSE);
- X lp3 = lp1->l_bp; /* Previous line */
- X lp3->l_fp = lp2; /* Link in */
- X lp2->l_fp = lp1;
- X lp1->l_bp = lp2;
- X lp2->l_bp = lp3;
- X for (i=0; i<n; ++i)
- X lp2->l_text[i] = c;
- X curwp->w_dotp = lp2;
- X curwp->w_doto = n;
- X return (TRUE);
- X }
- X doto = curwp->w_doto; /* Save for later. */
- X if (lp1->l_used+n > lp1->l_size) { /* Hard: reallocate */
- X if ((lp2=lalloc(lp1->l_used+n)) == NULL)
- X return (FALSE);
- X cp1 = &lp1->l_text[0];
- X cp2 = &lp2->l_text[0];
- X while (cp1 != &lp1->l_text[doto])
- X *cp2++ = *cp1++;
- X cp2 += n;
- X while (cp1 != &lp1->l_text[lp1->l_used])
- X *cp2++ = *cp1++;
- X lp1->l_bp->l_fp = lp2;
- X lp2->l_fp = lp1->l_fp;
- X lp1->l_fp->l_bp = lp2;
- X lp2->l_bp = lp1->l_bp;
- X free((char *) lp1);
- X } else { /* Easy: in place */
- X lp2 = lp1; /* Pretend new line */
- X lp2->l_used += n;
- X cp2 = &lp1->l_text[lp1->l_used];
- X cp1 = cp2-n;
- X while (cp1 != &lp1->l_text[doto])
- X *--cp2 = *--cp1;
- X }
- X for (i=0; i<n; ++i) /* Add the characters */
- X lp2->l_text[doto+i] = c;
- X wp = wheadp; /* Update windows */
- X while (wp != NULL) {
- X if (wp->w_linep == lp1)
- X wp->w_linep = lp2;
- X if (wp->w_dotp == lp1) {
- X wp->w_dotp = lp2;
- X if (wp==curwp || wp->w_doto>doto)
- X wp->w_doto += n;
- X }
- X if (wp->w_markp == lp1) {
- X wp->w_markp = lp2;
- X if (wp->w_marko > doto)
- X wp->w_marko += n;
- X }
- X wp = wp->w_wndp;
- X }
- X return (TRUE);
- X}
- X
- X/*
- X * Overwrite a character into the current line at the current position
- X *
- X */
- X
- Xlowrite(c)
- X
- Xchar c; /* character to overwrite on current position */
- X
- X{
- X if (curwp->w_doto < curwp->w_dotp->l_used &&
- X (lgetc(curwp->w_dotp, curwp->w_doto) != '\t' ||
- X (curwp->w_doto) % 8 == 7))
- X ldelete(1L, FALSE);
- X return(linsert(1, c));
- X}
- X
- X/*
- X * lover -- Overwrite a string at the current point
- X */
- X
- Xlover(ostr)
- X
- Xchar *ostr;
- X
- X{
- X register int status = TRUE;
- X char tmpc;
- X
- X if (ostr != NULL)
- X while ((tmpc = *ostr) && status == TRUE) {
- X status = (tmpc == '\n'? lnewline(): lowrite(tmpc));
- X
- X /* Insertion error? */
- X if (status != TRUE) {
- X mlwrite("%%Out of memory while overwriting");
- X break;
- X }
- X ostr++;
- X }
- X return(status);
- X}
- X
- X/*
- X * Insert a newline into the buffer at the current location of dot in the
- X * current window. The funny ass-backwards way it does things is not a botch;
- X * it just makes the last line in the file not a special case. Return TRUE if
- X * everything works out and FALSE on error (memory allocation failure). The
- X * update of dot and mark is a bit easier then in the above case, because the
- X * split forces more updating.
- X */
- Xlnewline()
- X{
- X register char *cp1;
- X register char *cp2;
- X register LINE *lp1;
- X register LINE *lp2;
- X register int doto;
- X register WINDOW *wp;
- X
- X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
- X return(rdonly()); /* we are in read only mode */
- X lchange(WFHARD);
- X lp1 = curwp->w_dotp; /* Get the address and */
- X doto = curwp->w_doto; /* offset of "." */
- X if ((lp2=lalloc(doto)) == NULL) /* New first half line */
- X return (FALSE);
- X cp1 = &lp1->l_text[0]; /* Shuffle text around */
- X cp2 = &lp2->l_text[0];
- X while (cp1 != &lp1->l_text[doto])
- X *cp2++ = *cp1++;
- X cp2 = &lp1->l_text[0];
- X while (cp1 != &lp1->l_text[lp1->l_used])
- X *cp2++ = *cp1++;
- X lp1->l_used -= doto;
- X lp2->l_bp = lp1->l_bp;
- X lp1->l_bp = lp2;
- X lp2->l_bp->l_fp = lp2;
- X lp2->l_fp = lp1;
- X wp = wheadp; /* Windows */
- X while (wp != NULL) {
- X if (wp->w_linep == lp1)
- X wp->w_linep = lp2;
- X if (wp->w_dotp == lp1) {
- X if (wp->w_doto < doto)
- X wp->w_dotp = lp2;
- X else
- X wp->w_doto -= doto;
- X }
- X if (wp->w_markp == lp1) {
- X if (wp->w_marko < doto)
- X wp->w_markp = lp2;
- X else
- X wp->w_marko -= doto;
- X }
- X wp = wp->w_wndp;
- X }
- X return (TRUE);
- X}
- X
- X/*
- X * This function deletes "n" bytes, starting at dot. It understands how do deal
- X * with end of lines, etc. It returns TRUE if all of the characters were
- X * deleted, and FALSE if they were not (because dot ran into the end of the
- X * buffer. The "kflag" is TRUE if the text should be put in the kill buffer.
- X */
- Xldelete(n, kflag)
- X
- Xlong n; /* # of chars to delete */
- Xint kflag; /* put killed text in kill buffer flag */
- X
- X{
- X register char *cp1;
- X register char *cp2;
- X register LINE *dotp;
- X register int doto;
- X register int chunk;
- X register WINDOW *wp;
- X
- X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
- X return(rdonly()); /* we are in read only mode */
- X while (n != 0) {
- X dotp = curwp->w_dotp;
- X doto = curwp->w_doto;
- X if (dotp == curbp->b_linep) /* Hit end of buffer. */
- X return (FALSE);
- X chunk = dotp->l_used-doto; /* Size of chunk. */
- X if (chunk > n)
- X chunk = n;
- X if (chunk == 0) { /* End of line, merge. */
- X lchange(WFHARD);
- X if (ldelnewline() == FALSE
- X || (kflag!=FALSE && kinsert('\n')==FALSE))
- X return (FALSE);
- X --n;
- X continue;
- X }
- X lchange(WFEDIT);
- X cp1 = &dotp->l_text[doto]; /* Scrunch text. */
- X cp2 = cp1 + chunk;
- X if (kflag != FALSE) { /* Kill? */
- X while (cp1 != cp2) {
- X if (kinsert(*cp1) == FALSE)
- X return (FALSE);
- X ++cp1;
- X }
- X cp1 = &dotp->l_text[doto];
- X }
- X while (cp2 != &dotp->l_text[dotp->l_used])
- X *cp1++ = *cp2++;
- X dotp->l_used -= chunk;
- X wp = wheadp; /* Fix windows */
- X while (wp != NULL) {
- X if (wp->w_dotp==dotp && wp->w_doto>=doto) {
- X wp->w_doto -= chunk;
- X if (wp->w_doto < doto)
- X wp->w_doto = doto;
- X }
- X if (wp->w_markp==dotp && wp->w_marko>=doto) {
- X wp->w_marko -= chunk;
- X if (wp->w_marko < doto)
- X wp->w_marko = doto;
- X }
- X wp = wp->w_wndp;
- X }
- X n -= chunk;
- X }
- X return (TRUE);
- X}
- X
- X/* getctext: grab and return a string with the text of
- X the current line
- X*/
- X
- Xchar *getctext()
- X
- X{
- X register LINE *lp; /* line to copy */
- X register int size; /* length of line to return */
- X register char *sp; /* string pointer into line */
- X register char *dp; /* string pointer into returned line */
- X char rline[NSTRING]; /* line to return */
- X
- X /* find the contents of the current line and its length */
- X lp = curwp->w_dotp;
- X sp = lp->l_text;
- X size = lp->l_used;
- X if (size >= NSTRING)
- X size = NSTRING - 1;
- X
- X /* copy it across */
- X dp = rline;
- X while (size--)
- X *dp++ = *sp++;
- X *dp = 0;
- X return(rline);
- X}
- X
- X/* putctext: replace the current line with the passed in text */
- X
- Xputctext(iline)
- X
- Xchar *iline; /* contents of new line */
- X
- X{
- X register int status;
- X
- X /* delete the current line */
- X curwp->w_doto = 0; /* starting at the beginning of the line */
- X if ((status = killtext(TRUE, 1)) != TRUE)
- X return(status);
- X
- X /* insert the new line */
- X if ((status = linstr(iline)) != TRUE)
- X return(status);
- X status = lnewline();
- X backline(TRUE, 1);
- X return(status);
- X}
- X
- X/*
- X * Delete a newline. Join the current line with the next line. If the next line
- X * is the magic header line always return TRUE; merging the last line with the
- X * header line can be thought of as always being a successful operation, even
- X * if nothing is done, and this makes the kill buffer work "right". Easy cases
- X * can be done by shuffling data around. Hard cases require that lines be moved
- X * about in memory. Return FALSE on error and TRUE if all looks ok. Called by
- X * "ldelete" only.
- X */
- Xldelnewline()
- X{
- X register char *cp1;
- X register char *cp2;
- X register LINE *lp1;
- X register LINE *lp2;
- X register LINE *lp3;
- X register WINDOW *wp;
- X
- X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
- X return(rdonly()); /* we are in read only mode */
- X lp1 = curwp->w_dotp;
- X lp2 = lp1->l_fp;
- X if (lp2 == curbp->b_linep) { /* At the buffer end. */
- X if (lp1->l_used == 0) /* Blank line. */
- X lfree(lp1);
- X return (TRUE);
- X }
- X if (lp2->l_used <= lp1->l_size-lp1->l_used) {
- X cp1 = &lp1->l_text[lp1->l_used];
- X cp2 = &lp2->l_text[0];
- X while (cp2 != &lp2->l_text[lp2->l_used])
- X *cp1++ = *cp2++;
- X wp = wheadp;
- X while (wp != NULL) {
- X if (wp->w_linep == lp2)
- X wp->w_linep = lp1;
- X if (wp->w_dotp == lp2) {
- X wp->w_dotp = lp1;
- X wp->w_doto += lp1->l_used;
- X }
- X if (wp->w_markp == lp2) {
- X wp->w_markp = lp1;
- X wp->w_marko += lp1->l_used;
- X }
- X wp = wp->w_wndp;
- X }
- X lp1->l_used += lp2->l_used;
- X lp1->l_fp = lp2->l_fp;
- X lp2->l_fp->l_bp = lp1;
- X free((char *) lp2);
- X return (TRUE);
- X }
- X if ((lp3=lalloc(lp1->l_used+lp2->l_used)) == NULL)
- X return (FALSE);
- X cp1 = &lp1->l_text[0];
- X cp2 = &lp3->l_text[0];
- X while (cp1 != &lp1->l_text[lp1->l_used])
- X *cp2++ = *cp1++;
- X cp1 = &lp2->l_text[0];
- X while (cp1 != &lp2->l_text[lp2->l_used])
- X *cp2++ = *cp1++;
- X lp1->l_bp->l_fp = lp3;
- X lp3->l_fp = lp2->l_fp;
- X lp2->l_fp->l_bp = lp3;
- X lp3->l_bp = lp1->l_bp;
- X wp = wheadp;
- X while (wp != NULL) {
- X if (wp->w_linep==lp1 || wp->w_linep==lp2)
- X wp->w_linep = lp3;
- X if (wp->w_dotp == lp1)
- X wp->w_dotp = lp3;
- X else if (wp->w_dotp == lp2) {
- X wp->w_dotp = lp3;
- X wp->w_doto += lp1->l_used;
- X }
- X if (wp->w_markp == lp1)
- X wp->w_markp = lp3;
- X else if (wp->w_markp == lp2) {
- X wp->w_markp = lp3;
- X wp->w_marko += lp1->l_used;
- X }
- X wp = wp->w_wndp;
- X }
- X free((char *) lp1);
- X free((char *) lp2);
- X return (TRUE);
- X}
- X
- X/*
- X * Delete all of the text saved in the kill buffer. Called by commands when a
- X * new kill context is being created. The kill buffer array is released, just
- X * in case the buffer has grown to immense size. No errors.
- X */
- Xkdelete()
- X{
- X KILL *kp; /* ptr to scan kill buffer chunk list */
- X
- X if (kbufh != NULL) {
- X
- X /* first, delete all the chunks */
- X kbufp = kbufh;
- X while (kbufp != NULL) {
- X kp = kbufp->d_next;
- X free(kbufp);
- X kbufp = kp;
- X }
- X
- X /* and reset all the kill buffer pointers */
- X kbufh = kbufp = NULL;
- X kused = KBLOCK;
- X }
- X}
- X
- X/*
- X * Insert a character to the kill buffer, allocating new chunks as needed.
- X * Return TRUE if all is well, and FALSE on errors.
- X */
- X
- Xkinsert(c)
- X
- Xint c; /* character to insert in the kill buffer */
- X
- X{
- X KILL *nchunk; /* ptr to newly malloced chunk */
- X
- X /* check to see if we need a new chunk */
- X if (kused >= KBLOCK) {
- X if ((nchunk = (KILL *)malloc(sizeof(KILL))) == NULL)
- X return(FALSE);
- X if (kbufh == NULL) /* set head ptr if first time */
- X kbufh = nchunk;
- X if (kbufp != NULL) /* point the current to this new one */
- X kbufp->d_next = nchunk;
- X kbufp = nchunk;
- X kbufp->d_next = NULL;
- X kused = 0;
- X }
- X
- X /* and now insert the character */
- X kbufp->d_chunk[kused++] = c;
- X return(TRUE);
- X}
- X
- X/*
- X * Yank text back from the kill buffer. This is really easy. All of the work
- X * is done by the standard insert routines. All you do is run the loop, and
- X * check for errors. Bound to "C-Y".
- X */
- Xyank(f, n)
- X{
- X register int c;
- X register int i;
- X register char *sp; /* pointer into string to insert */
- X KILL *kp; /* pointer into kill buffer */
- X
- X if (curbp->b_mode&MDVIEW) /* don't allow this command if */
- X return(rdonly()); /* we are in read only mode */
- X if (n < 0)
- X return (FALSE);
- X /* make sure there is something to yank */
- X if (kbufh == NULL)
- X return(TRUE); /* not an error, just nothing */
- X
- X /* for each time.... */
- X while (n--) {
- X kp = kbufh;
- X while (kp != NULL) {
- X if (kp->d_next == NULL)
- X i = kused;
- X else
- X i = KBLOCK;
- X sp = kp->d_chunk;
- X while (i--) {
- X if ((c = *sp++) == '\n') {
- X if (lnewline() == FALSE)
- X return (FALSE);
- X } else {
- X if (linsert(1, c) == FALSE)
- X return (FALSE);
- X }
- X }
- X kp = kp->d_next;
- X }
- X }
- X return (TRUE);
- X}
- FRIDAY_NIGHT
- echo extracting - lock.c
- sed 's/^X//' > lock.c << 'FRIDAY_NIGHT'
- X/* LOCK: File locking command routines for MicroEMACS
- X written by Daniel Lawrence
- X */
- X
- X#include <stdio.h>
- X#include "estruct.h"
- X#include "edef.h"
- X
- X#if FILOCK
- X#if BSD
- X#include <sys/errno.h>
- X
- Xextern int sys_nerr; /* number of system error messages defined */
- Xextern char *sys_errlist[]; /* list of message texts */
- Xextern int errno; /* current error */
- X
- Xchar *lname[NLOCKS]; /* names of all locked files */
- Xint numlocks; /* # of current locks active */
- X
- X/* lockchk: check a file for locking and add it to the list */
- X
- Xlockchk(fname)
- X
- Xchar *fname; /* file to check for a lock */
- X
- X{
- X register int i; /* loop indexes */
- X register int status; /* return status */
- X char *undolock();
- X
- X /* check to see if that file is already locked here */
- X if (numlocks > 0)
- X for (i=0; i < numlocks; ++i)
- X if (strcmp(fname, lname[i]) == 0)
- X return(TRUE);
- X
- X /* if we have a full locking table, bitch and leave */
- X if (numlocks == NLOCKS) {
- X mlwrite("LOCK ERROR: Lock table full");
- X return(ABORT);
- X }
- X
- X /* next, try to lock it */
- X status = lock(fname);
- X if (status == ABORT) /* file is locked, no override */
- X return(ABORT);
- X if (status == FALSE) /* locked, overriden, dont add to table */
- X return(TRUE);
- X
- X /* we have now locked it, add it to our table */
- X lname[++numlocks - 1] = (char *)malloc(strlen(fname) + 1);
- X if (lname[numlocks - 1] == NULL) { /* malloc failure */
- X undolock(fname); /* free the lock */
- X mlwrite("Cannot lock, out of memory");
- X --numlocks;
- X return(ABORT);
- X }
- X
- X /* everthing is cool, add it to the table */
- X strcpy(lname[numlocks-1], fname);
- X return(TRUE);
- X}
- X
- X/* lockrel: release all the file locks so others may edit */
- X
- Xlockrel()
- X
- X{
- X register int i; /* loop index */
- X register int status; /* status of locks */
- X register int s; /* status of one unlock */
- X
- X status = TRUE;
- X if (numlocks > 0)
- X for (i=0; i < numlocks; ++i) {
- X if ((s = unlock(lname[i])) != TRUE)
- X status = s;
- X free(lname[i]);
- X }
- X numlocks = 0;
- X return(status);
- X}
- X
- X/* lock: Check and lock a file from access by others
- X returns TRUE = files was not locked and now is
- X FALSE = file was locked and overridden
- X ABORT = file was locked, abort command
- X*/
- X
- Xlock(fname)
- X
- Xchar *fname; /* file name to lock */
- X
- X{
- X register char *locker; /* lock error message */
- X register int status; /* return status */
- X char msg[NSTRING]; /* message string */
- X char *dolock();
- X
- X /* attempt to lock the file */
- X locker = dolock(fname);
- X if (locker == NULL) /* we win */
- X return(TRUE);
- X
- X /* file failed...abort */
- X if (strncmp(locker, "LOCK", 4) == 0) {
- X lckerror(locker);
- X return(ABORT);
- X }
- X
- X /* someone else has it....override? */
- X strcpy(msg, "File in use by ");
- X strcat(msg, locker);
- X strcat(msg, ", overide?");
- X status = mlyesno(msg); /* ask them */
- X if (status == TRUE)
- X return(FALSE);
- X else
- X return(ABORT);
- X}
- X
- X/* unlock: Unlock a file
- X this only warns the user if it fails
- X */
- X
- Xunlock(fname)
- X
- Xchar *fname; /* file to unlock */
- X
- X{
- X register char *locker; /* undolock return string */
- X char *undolock();
- X
- X /* unclock and return */
- X locker = undolock(fname);
- X if (locker == NULL)
- X return(TRUE);
- X
- X /* report the error and come back */
- X lckerror(locker);
- X return(FALSE);
- X}
- X
- Xlckerror(errstr) /* report a lock error */
- X
- Xchar *errstr; /* lock error string to print out */
- X
- X{
- X char obuf[NSTRING]; /* output buffer for error message */
- X
- X strcpy(obuf, errstr);
- X strcat(obuf, " - ");
- X if (errno < sys_nerr)
- X strcat(obuf, sys_errlist[errno]);
- X else
- X strcat(obuf, "[can not get system error message]");
- X mlwrite(obuf);
- X}
- X#endif
- X#else
- Xlckhello() /* dummy function */
- X{
- X}
- X#endif
- FRIDAY_NIGHT
- echo extracting - main.c
- sed 's/^X//' > main.c << 'FRIDAY_NIGHT'
- X/*
- X * MicroEMACS 3.9
- X * written by Dave G. Conroy.
- X * substatially modified by Daniel M. Lawrence
- X *
- X * (C)opyright 1987 by Daniel M. Lawrence
- X * MicroEMACS 3.9 can be copied and distributed freely for any
- X * non-commercial purposes. MicroEMACS 3.9 can only be incorporated
- X * into commercial software with the permission of the current author.
- X *
- X * This file contains the main driving routine, and some keyboard processing
- X * code, for the MicroEMACS screen editor.
- X *
- X * REVISION HISTORY:
- X *
- X * 1.0 Steve Wilhite, 30-Nov-85
- X * - Removed the old LK201 and VT100 logic. Added code to support the
- X * DEC Rainbow keyboard (which is a LK201 layout) using the the Level
- X * 1 Console In ROM INT. See "rainbow.h" for the function key defs
- X * Steve Wilhite, 1-Dec-85
- X * - massive cleanup on code in display.c and search.c
- X *
- X * 2.0 George Jones, 12-Dec-85
- X * - Ported to Amiga.
- X *
- X * 3.0 Daniel Lawrence, 29-Dec-85
- X * - rebound keys/added new fast buffered I/O for AMIGA
- X * - added META- repeat commands
- X * - added reposition default to center screen (yeah!)
- X * - changed exit with modified buffers message
- X * - made filesave tell us what it is doing
- X * - changed search string entry to terminate with <ESC>
- X * so we can use <NL> in search/replace strings
- X * - updated version number in mode line to 3.0
- X * 12-Jan-86
- X * - Added code to reconize the search/replace functions
- X * - Added code to perform search/replace & query functions
- X * 14-Jan-86
- X * - moved search logic to separate function in search.c
- X * - added replace and query replace functions
- X * - separated out control key expansions to be used by others in search.c
- X * 15-Jan-86
- X * - changed "visiting" to finding
- X * - changed yes/no responses to not need return
- X * - cleaned up various messages
- X * 16-jan-86
- X * - fixed spurious spawn message in MSDOS
- X * - added ^X-S synonym to save command
- X * - moved escape to shell to ^X-C
- X * 21-jan-86
- X * - added code to suspend shell under BSD
- X * 22-jan-86
- X * - added function key support (SPEC) under MSDOS
- X * - Abort now prints [Aborted] on message line
- X * 23-jan-86
- X * - Added modes and commands to set/unset them
- X * 24-jan-86
- X * - Added Goto Line command
- X * - added Rename Buffer command
- X * 28-jan-86
- X * - added goto beginning and end of paragraph commands (META-P/META-N)
- X * - re-wrote kdelete to use realloc. Gained MUCH speed here when
- X * doing large wipes on both UNIX and MSDOS. Changed kill buffer
- X * allocation block size from 256 bytes to 1 k
- X * 29-jan-86
- X * - moved extern function declarations to efunc.h
- X * - made name[] name binding table
- X * 30-jan-86
- X * - fixed Previous/Next paragraph command not to wrap around EOF
- X * - added Fill Paragraph command (META-Q)
- X * 4-feb-86
- X * - added code to properly display long lines, scrolling them right
- X * to left
- X * 5-feb-85
- X * - rewrote code to right/left scroll...much better
- X * - added shifted arrow keys on IBMPC
- X * 6-feb-85
- X * - add option to allow forward-word to jump to beginning of
- X * next word instead of end of current one. This is different from
- X * other emacs' but can be configured off in estruct.h
- X * - added VIEW mode to allow a buffer to be read only
- X * (-v switch on command line will activate this)
- X * - changed quick exit to write out ALL changed buffers!!!
- X * MAKE SURE YOU KNOW THIS WHEN META-Zing
- X * 10-feb-86
- X * - added handling of lines longer than allowed on file read in
- X * (they wrap on additional lines)
- X * - made having space clear the message line and NOT insert itself
- X * a configuration option in ed.h
- X * 11-feb-86
- X * - added Describe-command and Help commands.
- X * 13-feb-86
- X * - added View file command (^X ^V) and finished HELP command
- X * 14-feb-86
- X * - added option to let main loop skip update if type ahead commands
- X * are queued up
- X * 16-feb-86
- X * - added Insert File command
- X * 17-feb-86
- X * - added scroll next window up/down commands
- X * 18-feb-86
- X * - added CMODE indentation
- X * - re-arranged header files to standardize extern and global
- X * definitions
- X * - changed version number to 3.2
- X * - added numeric arguments to search, reverse search and
- X * search and replace
- X * 24-feb-86
- X * - added Bind To Key function (^C for now) to allow the user
- X * to change his command keys
- X * - added Unbind key function (M-^C for now)
- X * - added execute named command to execute unbound commands (M-X)
- X * - added describe bindings command (not bound)
- X * - changed version number to 3.3
- X * 25-feb-86
- X * - scrapped CERROR mode (too many compilers)
- X * - added EXACT mode for case sensitive searchers
- X * 26-feb-86
- X * - added command completion on execute named command and
- X * all routined grabbing a command name
- X * - adding execute-command-line command and its support functions
- X * (in preparation for sourcing files)
- X * - added Execute Buffer command
- X * 27-feb-86
- X * - added execute(source) file command and added code to automatically
- X * execute emacs.rc (or .emacsrc on UNIX) before initial read in
- X * - changed version number to 3.4
- X * 4-mar-86
- X * - changed word delete to be consistant with word move (it gets
- X * rid of the inter word space now) This is configurable with the
- X * NFWORD symbol in estruct.h
- X * - added B_ACTIVE entry to the buffer table. Let emacs read multiple
- X * file names from the command line and only read them in as needed
- X * 5-mar-85
- X * - rewrote command line parser to get rid of my patchy code
- X * - changed version number to 3.5
- X * 1-apr-86
- X * - added support for Aztec C 3.20e under MSDOS
- X * - fixed bug in mlwrite on ADM3's and their ilk under V7
- X * - added insertion of pounds in column one under CMODE
- X * - changed version number to 3.6
- X * 3-apr-86
- X * - added next-buffer command (^X-X)
- X * 5-apr-86
- X * - added kill paragraph command (M-^W)
- X * - changed fill-paragraph to leave 2 spaces after a period at the
- X * end of a word.
- X * - added OVERWRITE mode
- X * 7-apr-86
- X * - fixed overwrite mode to handle tabs
- X * 8-apr-86
- X * - added add/delete global mode (<ESC>M & <ESC> ^M) commands
- X * 9-apr-86
- X * - added insert space command
- X * - moved bindings around ^C insert space
- X * M-K bind-to-key
- X * INSERT insert space
- X * DELETE forwdel
- X * - added hunt forward and hunt reverse commands
- X * 10-apr-86
- X * - fixed bug in DOBUF with non-terminated command string
- X * 15-apr-86
- X * - fixed tab expansion bug in DISPLAY which hung the AMIGA
- X * (sent in by Dawn Banks)
- X * - fixed curcol problen if forwline/backline during keyboard
- X * macro execution (sent in by Ernst Christen)
- X * - added AMIGA function/cursor key support
- X * - fixed nonterminating <NL> replacement bug
- X * - fixed word wrapping problems
- X * 16-apr-86
- X * - updated documentation and froze development for 3.6 net release
- X * 23-apr-86 version 3.6a
- X * - added foreground and background colors. Setable with the
- X * add mode commands for the moment
- X * 24-apr-86
- X * - added command to pipe CLI output to a buffer
- X * 25-apr-86
- X * - added Dana Hoggatt's code to replace Lattice's sick system()
- X * function. Now we no longer care what the switchar is.
- X * - cleaned up the positioning on several of the spawing commands
- X * 26-apr-86
- X * - added an output flush in vttidy(). Unix really appreciates this.
- X * - added filter-buffer (^X#) command to send a buffer through
- X * a DOS filter
- X * - made automatic CMODE on .c and .h file compilation dependant
- X * in estruct.h
- X * 1-may-86
- X * - optimized some code in update(). It certainly need a lot more.
- X * - added Aztec profiling capabilities. These are conditional on
- X * the APROF symbol in estruct.h
- X * 2-may-86
- X * - added (u)ndo command in query-replace. undoes last repalce.
- X * 6-may-86
- X * - re-organized and wrote the update() function in display.c
- X * Now my color hacks are in the right places and the code can be
- X * understood.
- X * [Released version 3.6f for BETA test sites]
- X * 8-may-86
- X * - fixed bug in new display routine to wrap cursor on extended
- X * lines at the right time
- X * - modified the buffer-position command to give reasonable info
- X * 9-may-86
- X * - improved the word wrap algorithm as not to discard non-space
- X * delimiters. The backscan now looks for white space rather than
- X * !inword().
- X * [Released version 3.6g to Krannert]
- X * 10-may-86
- X * - Added IBMPC.C an IBM-PC specific display driver. This makes paging
- X * 4-6 times faster. Also made some conditional changes to DISPLAY.C
- X * to eliminate the pscreen[] if using the PC driver.
- X * [changed version number to 3.6i]
- X * 12-may-86
- X * - added delete-window (^X 0) command to dispose of a single window
- X * - fixed problem with multiple prefixes from a command line which
- X * was reported by John Gamble
- X * 14-may-86
- X * - Added Aztec support for the IBMPC display driver. Had to
- X * readjust some includes and defines for this.
- X * - fixed bug in delete-window.
- X * - fixed some bizarre behavior with the cursor after coming back
- X * from spawn calls.
- X * [changed version number to 3.7 freezing development for net release]
- X * 15-may-86
- X * - (that didn't last long...) Added execute-macro-(1 thru 20) commands
- X * to execute macro buffers (named "[Macro nn]")
- X * - changed BFTEMP to BFINVS and cleaned up treatment of invisible
- X * buffers.
- X * 16-may-86
- X * - added store-macro (unbound) to store any executed command lines to
- X * macro buffer.
- X * - added clear-message-line (unbound) command to do just that
- X * - added resize-window command to change a window's size to the
- X * specified argument
- X * - improved help's logic not to re-read the file if it was already
- X * in a buffer
- X * - added MAGIC mode to all structures and command tables, but the
- X * regular expression code that John Gamble is writing is not ready.
- X * 18-may-86
- X * - added interactive prompt requests in command line execution (i.e.
- X * while executing a macro, a parameter starting with an at sign (@)
- X * causes emacs to prompt with the rest of the parameter and return
- X * the resulting input as the value of the parameter).
- X * - added arguments to split-current-window to force the cursor into
- X * the upper or lower window.
- X * 20-may-86
- X * - added support for the Microsoft C compiler as per the changes
- X * sent in by Oliver Sharp
- X * - made some upgrades and fixes for VMS sent in by Guy Streeter
- X * 21-may-86
- X * - fixed an Aztec bug in ttgetc by clearing the upper byte
- X * - fixed buf in CMODE with #preprocesser input (bug fix submitted by
- X * Willis of unknown path)
- X * - added support of alternative startup file ( @<filename> ) in
- X * the command line
- X * - added ^Q quoting in interactive input (mlreplyt()).
- X * - added re-binding of meta-prefix and ctlx-prefix
- X * 22-may-86
- X * - reorganized getkey routines to make more sense and let prefix
- X * binding work properly.
- X * 23-may-86
- X * - checked new code on BSD4.2 and made a few fixes
- X * - added optional fence matching while in CMODE
- X * - added goto and search command line arguments by Mike Spitzer
- X * 26-may-86
- X * - added parameter fetching from buffers
- X * 27-may-86
- X * - fixed some HP150 bugs......
- X * 31-may-86
- X * - Added Wang PC keyboard support from modifications by
- X * Sid Shapiro @ Wang Institute
- X * - Fixed some reverse video bugs with code submitted by Peter Chubb
- X * - Fixed bug in nextbuffer reported by Dave Forslund
- X * - added system V support (USG) from Linwood Varney
- X * 2-jun-86
- X * - changed defines to just define one Unix define (for example,
- X * just define BSD for Unix BSD 4.2)
- X * - Added Incremental search functions written by D. R. Banks
- X * in file ISEARCH.C
- X * - added insert-string (unbound) command to help the macro
- X * language out.
- X * - added unmark-buffer (M-~) command to turn off the current buffers
- X * change flag
- X * - fixed nxtarg to truncate strings longer than asked for max length
- X * 4-jun-86
- X * - added special characters in command line tokens. Tilde (~) is
- X * the special lead-in character for "nrtb".
- X * - Fixed bad ifdef in Aztec code so it could look at HOME dir
- X * for startup, help, and emacs.rc files
- X * 6-jun-86
- X * - make delete word commands clear the kill buffer if not after another
- X * kill command
- X * 11-jun-86
- X * - made ~@ in string arguments pass as char(192) to nxtarg() so one can
- X * quote @ at the beginning of string arguments
- X * - changed buffer size vars in listbuffers() to long (for big files)
- X * - re-wrote buffer-position command to be much faster
- X * 12-jun-86
- X * - added count-words (M-^C) command to count the words/chars and
- X * lines in a region
- X * - changed regions so they could be larger than 65535 (short ->
- X * long in the REGION structure)
- X * - changed ldelete() and all callers to use a long size. The kill
- X * buffer will still have a problem >65535 that can not be solved
- X * until I restructure it.
- X * - grouped paragraph commands and word count together under symbol
- X * WORDPRO to allow them to be conditionally made (or not)
- X * 13-jun-86
- X * - re-wrote kill buffer routines again. Now they support an unlimited
- X * size kill buffer, and are (in theory) faster.
- X * - changed delete-next-word (M-D) to not eat the newline after a word,
- X * instead it checks and eats a newline at the cursor.
- X * 17-jun-86
- X * - added numeric argument to next/previous-window to access the nth
- X * window from the top/bottom
- X * - added support for the Data General 10 MSDOS machine
- X * - added save-window (unbound) and restore-window (unbound) commands
- X * for the use of the menu script. Save-window remembers which window
- X * is current, and restore-window returns the cursor to that window.
- X * 20-jun-86
- X * - fixed a bug with the fence matching locking up near the beginning
- X * of a buffer
- X * - added argument to update to selectively force a complete update
- X * - added update-screen (unbound) command so macros can force a
- X * screen update
- X * 21-jun-86
- X * - rearranged token() and nxtarg() calls so that command names and
- X * repeat counts could also be prompted and fetched from buffers
- X * [this broke later with the exec re-write....]
- X * - added write-message (unbound) command to write out a message
- X * on the message line (for macros)
- X * - changed ifdef's so that color modes are recognized as legal in
- X * b/w version, and simply do nothing (allowing us to use the same
- X * script files)
- X * [Released version 3.7 on July 1 to the net and elswhere]
- X * 2-jul-86
- X * - Changed search string terminator to always be the meta character
- X * even if it is rebound.
- X * 3-jul-86
- X * - removed extra calls to set color in startup code. This caused the
- X * original current window to always be the global colors.
- X * 7-jul-86
- X * - Fixed bugs in mlreplyt() to work properly with all terminators
- X * including control and spec characters
- X * 22-jul-86
- X * - fixed replaces() so that it will return FALSE properly on the
- X * input of the replacement string.
- X * - added a definition for FAILED as a return type.....
- X * - changed version number to 3.7b
- X * 23-jul-86
- X * - fixed o -> 0 problem in TERMIO.C
- X * - made ^U universal-argument re-bindable
- X * - wrote atoi() for systems (like Aztec) where it acts strangely
- X * - changed version number to 3.7c
- X * 25-jul-86
- X * - make ^G abort-command rebindable
- X * 29-jul-86
- X * - added HP110 Portable Computer support
- X * - changed version number to 3.7d
- X * 30-jul-86
- X * - Fixed a couple of errors in the new VMS code as pointer
- X * out by Ken Shacklford
- X * - split terminal open/close routines into screen and keyboard
- X * open/close routines
- X * - closed the keyboard during all disk I/O so that OS errors
- X * can be respoded to correctly (especially on the HP150)
- X * - changed version number to 3.7e
- X * 31-jul-86
- X * - added label-function-key (unbound) command under symbol FLABEL
- X * (primarily for the HP150)
- X * 4-aug-86
- X * - added fixes for Microsoft C as suggested by ihnp4!ihuxm!gmd1
- X * <<remember to fix [list] deletion bug as reported
- X * by craig@hp-pcd>>
- X * 8-aug-86
- X * - fixed beginning misspelling error everywhere
- X * - fixed some more MSC errors
- X * - changed version number to 3.7g
- X * 20-aug-86
- X * - fixed CMODE .h scanning bug
- X * - changed version number to 3.7h
- X * 30-aug-86
- X * - fixed killing renamed [list] buffer (it can't) as submitted
- X * by James Aldridge
- X * - Added code to allow multiple lines to display during
- X * vertical retrace
- X * [total disaster....yanked it back out]
- X * 9-sep-86
- X * - added M-A (apropos) command to list commands containing a substring.
- X * - fixed an inefficiency in the display update code submitted
- X * by William W. Carlson (wwc@pur-ee)
- X * 10-sep-86
- X * - added Dana Hoggatt's code for encryption and spliced it into the
- X * proper commands. CRYPT mode now triggers encryption.
- X * - added -k flag to allow encryption key (no spaces) in command line
- X * 14-sep-86
- X * - added missing lastflag/thisflag processing to docmd()
- X * - changed version to 3.7i and froze for partial release via mail
- X * and BBS
- X * 05-oct-86
- X * - changed some strcpys in MAIN.C to strncpys as suggested by John
- X * Gamble
- X * - replaces SEARCH.C and ISEARCH.C with versions modified by
- X * John Gamble
- X * 10-oct-86
- X * - removed references to lflick....it just won't work that way.
- X * - removed defines LAT2 and LAT3...the code no longer is Lattice
- X * version dependant.
- X * 14-oct-86
- X * - changed spawn so that it will not not pause if executed from
- X * a command line
- X * 15-oct-86
- X * - added argument concatination (+) to the macro parsing
- X * - added [] as fence pairs
- X * 16-oct-86
- X * - rewrote all macro line parsing routines and rearranged the
- X * mlreply code. Saved 6K!!! Have blazed the path for expanding
- X * the command language.
- X * 17-oct-86
- X * - added new keyboard macro routines (plus a new level to the
- X * input character function)
- X * 22-oct-86
- X * - improved EGA cursor problems
- X * - added -r (restricted) switch to command line for BBS use
- X * 06-nov-86
- X * - fixed terminator declarations from char to int in getarg() and
- X * nxtarg() in EXEC.C as pointed out by John Gamble
- X * 07-nov-86
- X * - made wordrap() user callable as wrap-word (M-FNW) and changed
- X * the getckey() routine so that illegal keystrokes (too many
- X * prefixes set) could be used for internal bindings. When word
- X * wrap conditions are met, the keystroke M-FNW is executed. Added
- X * word wrap check/call to newline().
- X * 11-nov-86
- X * - added and checked support for Mark Williams C 86
- X * 12-nov-86
- X * - added goto-matching-fence (M-^F) command to jump to a matching
- X * fence "({[]})" or beep if there is none. This can reframe the
- X * screen.
- X * - added code and structure elements to support change-screen-size
- X * command (M-^S) to change the number of lines being used by
- X * MicroEMACS.
- X * 15-nov-86
- X * - finished debugging change-screen-size
- X * 17-nov-86
- X * - Incorporated in James Turner's modifications for the Atari ST
- X * 23-sep-86
- X * - added support for the Atari ST line of computers (jmt)
- X * - added a '\r' to the end of each line on output and strip
- X * it on input for the SHOW function from the desktop
- X * - added 3 new mode functions (HIREZ, MEDREZ, and LOREZ);
- X * chgrez routine in TERM structure; and MULTREZ define in
- X * ESTRUCT.H to handle multiple screen resolutions
- X * [note....ST still not running under Lattice yet...]
- X * 25-nov-86
- X * - Made the filter-buffer (^X-#) command not work on VIEW mode
- X * buffers
- X * - Made the quick-exit (M-Z) command throw out a newline after
- X * each message so they could be seen.
- X * 26-nov-86
- X * - fixed a couple of bugs in change-screen-size (M-^S) command
- X * - changed file read behavior on long lines and last lines
- X * with no newline (it no longer throws the partial line out)
- X * - [as suggested by Dave Tweten] Made adding a ^Z to the end
- X * of an output file under MSDOS configurable under the
- X * CTRL-Z symbol in ESTRUCT.H
- X * - [Dave Tweten] Spawn will look up the "TMP" environment variable
- X * for use during various pipeing commands.
- X * - [Dave Tweten] changed pipe command under MSDOS to use '>>'
- X * instead of '>'
- X * 04-dec-86
- X * - moved processing of '@' and '#' so that they can be outside
- X * the quotes in an argument, and added hooks to process '%' for
- X * environment and user variables.
- X * - modified IBMPC.C to sense the graphics adapter (CGA and MONO)
- X * at runtime to cut down on the number of versions.
- X * 05-dec-86
- X * - changed macro directive character to "!" instead of "$" (see
- X * below) and fixed the standard .rc file to comply.
- X * - added code to interpret environment variables ($vars). Added
- X * hooks for built in functions (&func). So, to recap:
- X *
- X * @<string> prompt and return a string from the user
- X * #<buffer name> get the next line from a buffer and advance
- X * %<var> get user variable <var>
- X * $<evar> get environment variable <evar>
- X * &<func> evaluate function <func>
- X *
- X * - allowed repeat counts to be any of the above
- X * - added code to allow insert-string (unbound) to use its
- X * repeat count properly
- X * - added set (^X-A) command to set variables. Only works on
- X * environmental vars yet.
- X * 9-dec-86
- X * - added some code for user defined variables...more to come
- X * - added options for malloc() memory pool tracking
- X * - preliminary user variables (%) working
- X * - changed terminal calls to macro's (to prepare for the new
- X * terminal drivers)
- X * 15-dec-86
- X * - changed previous-line (^P) and next-line (^N) to return a
- X * FALSE at the end or beginning of the file so repeated
- X * macros involving them terminate properly!
- X * - added code for $CURCOL and $CURLINE
- X * 20-dec-86
- X * - set (^X-A) now works with all vars
- X * - added some new functions
- X * &ADD &SUB &TIMES &DIV &MOD &NEG &CAT
- X * - once again rearranged functions to control macro execution. Did
- X * away with getarg()
- X * 23-dec-86
- X * - added string functions
- X * &LEFt &RIGht &MID
- X * 31-dec-86
- X * - added many logical functions
- X * &NOT &EQUal &LESs &GREater
- X * - added string functions
- X * &SEQual &SLEss &SGReater
- X * - added variable indirection with &INDirect
- X * - made fixes to allow recursive macro executions
- X * (improved speed during macro execution as well)
- X * 3-jan-87
- X * - added $FLICKER to control flicker supression
- X * - made spawn commands restricted
- X * - cleaned up lots of unintentional int<->char problems
- X * 4-jan-87
- X * - Fixed broken pipe-command (^X-@) command under MSDOS
- X * - added !IF !ELSE !ENDIF directives and changed the
- X * name of !END to !ENDM....real slick stuff
- X * 5-jan-87
- X * - quick-exit (M-Z) aborts on any filewrite errors
- X * 8-jan-87
- X * - debugged a lot of the new directive and evaluation code.
- X * BEWARE of stack space overflows! (increasing stack to
- X * 16K under MSDOS)
- X * - removed non-standard DEC Rainbow keyboard support...let someone
- X * PLEASE implement this in the standard manner using key bindings
- X * and send the results to me.
- X * - added change-screen-width () command and $CURWIDTH variable
- X * 11-jan-87
- X * - fixed an incredibly deeply buried bug in vtputc and combined
- X * it with vtpute (saving about 200 bytes!)
- X * 16-jan-87
- X * - added code to handle controlling multiple screen resolutions...
- X * allowed the IBM-PC driver to force Mono or CGA modes.
- X * - added current buffer name and filename variables
- X * $cbufname and $cfname
- X * 18-jan-87
- X * - added $sres variable to control screen resolution
- X * - added $debug variable to control macro debugging code (no longer
- X * is this activated by GLOBAL spell mode)
- X * - fixed bug in -g command line option
- X * - Released Version 3.8 to BBSNET
- X * 21-jan-87
- X * - added $status variable to record return status of last command
- X * 2-feb-87
- X * - added ATARI 1040 support...runs in all three modes right now
- X * - added $palette var with palette value in it
- X * - undefined "register" in BIND.C and INPUT.C for ST520 & LATTICE
- X * to get around a nasty Lattice bug
- X * 4-feb-87
- X * - added, debugged code for switching all 1040ST color modes, added
- X * code for HIGH monochrome mode as well, DENSE still pending
- X * 5-feb-87
- X * - with John Gamble, found and corrected the infamous bad matching
- X * fence problems.
- X * - added error return check in various add/delete mode commands
- X * 10-feb-87
- X * - re-arrange code in docmd() so that labels are stored in
- X * macro buffers
- X * - fixed !RETURN to only return if (execlevel == 0) [If we are
- X * currently executing]
- X * 14-feb-87
- X * - added to outp() calls in the EGA driver to fix a bug in the BIOS
- X * - adding code for 1040ST 40 line DENSE mode (not complete)
- X * 25-feb-87
- X * - added auto-save "ASAVE" mode....variables $asave and $acount
- X * control the frequency of saving and count until next save
- X * - added &and and &or as functions for logical anding and oring
- X * - added string length &LEN, upper and lower case string funtions
- X * &LOWER and &UPPER
- X * 27-feb-87
- X * - added $lastkey last keystroke struck and
- X * $curchar character under cursor
- X * 28-feb-87
- X * - added code for trim-line (^X^T) command and table entries
- X * for the entab-line (^X^E) and detab-line (^X^D) commands.
- X * These are conditional on AEDIT (Advanced editing) in estruct.h
- X * 18-mar-87
- X * - finished above three commands
- X * - added $version environment variable to return the current
- X * MicroEMACS version number
- X * - added $discmd emvironment variable. This is a logical flag that
- X * indicates if emacs should be echoing commands on the command line.
- X * real useful in order to stop flashing macros and .rc files
- X * - added $progname environment variable. this always returns the
- X * string "MicroEMACS". OEM's should change this so that macros can
- X * tell if they are running on an unmodified emacs or not.
- X * - fixed a minor bug in the CGA/MONO detection routine in IBMPC.C
- X * 20-mar-87
- X * - integrated EGAPC.C into IBMPC.C and eliminated the file. Now an
- X * EGA user can switch from EGA to CGA modes at will
- X * - A LOT of little fixes and corrections sent in by John Ruply
- X * 25-mar-87
- X * - Fixed buffer variables so they will work when referencing the
- X * current buffer
- X * 26-mar-87
- X * - Fixed atoi() to be more reasonable. trailing whitespace ignored,
- X * only one leading sign, no non-digits allowed after the sign.
- X * - fixed buffer variables to go from the point to the end of
- X * line.
- X * 28-mar-87
- X * - fixed bugs with 8 bit chars as submited by Jari Salminen
- X * - replace AZTEC/MSDOS agetc() with a1getc() which won't strip
- X * the high order bit
- X * 30-mar-87
- X * - changed list-buffers (^X^B) so that with any argument, it will
- X * also list the normally invisable buffers
- X * - added store-procedure and execute-procedure/run (M-^E)
- X * commands to store and execute named procedures.
- X * 31-mar-87
- X * - Fixed infinite loop in ^X-X command (when [LIST] is the
- X * only buffer left) as pointed out by John Maline
- X * - made filenames in getfile() always lower case as pointed
- X * out by John Maline
- X * 2-apr-87
- X * - Fixed buffer variables so they would work on non-current displayed
- X * buffers. They should now work with ALL buffers....
- X * 3-apr-87
- X * - Yanked AZTEC profiling code....not very useful
- X * - Modified IBMPC driver so it will not start in EGA mode
- X * - allow the next-buffer (^X-X) command to have a preceding
- X * non-negative argument.
- X * 14-apr-87
- X * - added John Gamble's modified search.c. The code has cut apx
- X * 200-300 bytes off the executable.
- X * - added the &RND function to generate a random integer between
- X * 1 and its arguments value. Also $SEED is availible as the
- X * random number seed.
- X * - changed the -k command line switch so if there is no argument,
- X * it will prompt for one when the file is read
- X * 15-apr-87
- X * - added 20 bytes of buffer in getval()'s local argument alloc so
- X * when it returns a value, it has enough stack space to do at least
- X * one strcpy() before stomping on the returned value. ALWAYS call
- X * getval() ONLY from within a strcpy() call.
- X * - made $curcol return a 1 based value instead of a zero based one.
- X * [changed this back later for 3.8o it was simply wrong.....]
- X * 16-apr-87
- X * - re-wrote strncpy() for AZTEC & MSDOS so it null terminates the
- X * string.
- X * - changed pipe() to pipecmd() to avoid conflicts with various
- X * UNIX systems
- X * 24-apr-87
- X * - changed open parameters on AMIGA window open to 0/0/640/200
- X * [Froze and released v3.8i via BBS net]
- X * 14-may-87
- X * - added nop (M-FNC) that gets called on every command loop
- X * - added $wline, returns and sets # lines in current window
- X * - added $cwline, returns and set current line within window
- X * - added $target, returns/sets target for line moves
- X * - added $search, returns/sets default search string
- X * - added $replace, returns/sets default replace string
- X * - added $match, returns last matched string in magic search
- X * 29-may-87
- X * - rewrote word deletes to not kill trailing non-whitespace after
- X * the last word. Also a zero argument will cause it to just delete
- X * the word and nothing else.
- X * - more fixes for the search pattern environment variables
- X * 30-may-87
- X * - forced all windows to redraw on a width change
- X * 2-jun-87
- X * - forced clear-message-line to overide $discmd
- X * - added mlforce() routine and call it in clear-message-line,
- X * write-message and when $debug is TRUE
- X * - recoded the startup sequence in main()....Much Better...
- X * 4-jun-87
- X * - forced interactive arguments ( @"question" ) to ALWAYS be echoed
- X * regardless of the setting of $discmd.
- X * 7-jun-87
- X * - started adding support for Turbo C under MSDOS
- X * 11-jun-87
- X * - words now include ONLY upper/lower case alphas and digits
- X * - fixed some more bugs with the startup..(ORed in the global modes)
- X * - took more limits off the self-insert list....
- X * 16-jun-87
- X * - macro debugging now displays the name of the current macro.
- X * - fixed a problem in expandp() in search.c that kept high-byte
- X * characters from working in search strings
- X * 18-jun-87
- X * - added &sindex <str1> <str2> function which searches for string 2
- X * within string 1
- X * [released verion 3.8o internally]
- X * 19-jun-87
- X * - added $cmode and $gmode to return and set the mode of the
- X * current buffer and the global mode
- X * - separated findvar() out from setvar() so it could be used in
- X * the !LOOP directive (which got canned....read on)
- X * - %No such variable message now types the name of the offending
- X * variable
- X * 22-jun-87
- X * - fixed startup bug when editing the startup file
- X * - added the !LOOP <var> <label> directive
- X * 26-jun-87
- X * - dumped !LOOP......added !WHILE. This needed and caused a vaste
- X * reorginization in exec.c which mainly involved moving all the
- X * directive handling from docmd() to dobuf(), in the process
- X * getting rid of a lot of junk and making the result smaller
- X * than it started.....(yea!)
- X * - added $tpause to control the fence flashing time in CMODE.
- X * The value is machine dependant, but you can multiply the
- X * original in macros to stay machine independant. (as
- X * suggested by Baron O.A. Grey)
- X * - added hook to execute M-FNR (null) during a file read, after
- X * the name is set and right before the file is read. Took out
- X * any auto-CMODE code, as this is now handled with a macro.
- X * (also suggested by Baron O.A. Grey)
- X * - Added Baron O.A. Grey's SYSTEM V typeahead() code...I hope
- X * this works....if you check this out, drop me a line.
- X * - Added new variable $pending, returns a logical telling if
- X * a typed ahead character is pending.
- X * 29-jun-87
- X * - Made adjustmode() use curbp-> instead of curwp->w_bufp-> which
- X * fixed some bugs in the startup routines.
- X * - added $lwidth to return the length of the current line
- X * 2-jul-87
- X * - Added &env <str> which returns the value of the environment
- X * variable <str> where possible
- X * - Fixed a NASTY bug in execbuf()..the buffer for the name
- X * of the buffer to execute was NBUFN long, and got overflowed
- X * with a long interactive argument.
- X * 3-jul-87
- X * - Moved the loop to match a key against its binding out of execute()
- X * to getbind() so it could be used later elsewhere.
- X * - Added &bind <keyname> which returns the function bound to the
- X * named key
- X * - changed execute-file to look in the executable path first...
- X * 6-jul-87
- X * - changed $curchar to return a newline at the end of a line and
- X * it no longer advances the cursor
- X * - a lot of minor changes sent by various people....
- X * 7-jul-87
- X * - some amiga specific fixes as suggested by Kenn Barry
- X * - added $line [read/write] that contains the current line in the
- X * current buffer
- X * - changed $curcol so setting it beyond the end of the line will
- X * move the cursor to the end of the line and then fail.
- X * 10-jul-87
- X * - added a number of fixes and optimizations along with the rest
- X * of the TURBO-C support as submited by John Maline
- X * 13-jun-87
- X * - caused dobuf() to copy lastflag to thisflag so the first
- X * command executed will inherit the lastflag from the command
- X * before the execute-buffer command. (needed this for smooth
- X * scrolling to work)
- X * - made flook() look first in the $HOME directory, then in the
- X * current directory, then down the $PATH, and then in the
- X * list in epath.h
- X * 14-jul-87
- X * - added some fixes for VMS along with support for the SMG
- X * screen package as submited by Curtis Smith
- X * 15-jul-87
- X * - fixed M-^H (delete-previous-word) so it can delete the first
- X * word in a file....I think there may be more of this kind of thing
- X * to fix.
- X * 16-jul-87
- X * - added code to allow arbitrary sized lines to be read from files..
- X * speed up file reading in the process.
- X * - made out of memory conditions safer.. especial on file reads
- X * - fixed a bug in bind having to do with uppercasing function
- X * key names (submitted by Jari Salminen)
- X * - made ST520 exit in the same resolution that EMACS was started in
- X * (for the 1040ST)
- X * [FROZE development and released version 3.9 to USENET]
- X * {It never made it.....got killed by comp.unix.sources}
- X * 15-sep-87
- X * - added support for Mark Williams C on the Atari ST
- X * - made the MALLOC debugging package only conditional on RAMSIZE
- X * - added code for flagging truncated buffers
- X * 23-sep-87
- X * - fixed &RIGHT to return the <arg2> rightmost characters
- X * - fixed a buffer in getval() to be static....things are stabler
- X * now.
- X * - moved all the stack size declarations to after include "estruct.h"
- X * they work a lot better now....... (rather than not at all)
- X * - made Atari ST spawns all work with MWshell
- X * - fixed spawning on the 1040ST under MWC
- X * 27-sep-87
- X * - added &exist function to check to see if a named file exist
- X * - added &find function to find a file along the PATH
- X * - added -A switch to run "error.cmd" from command line
- X * - added $gflags to control startup behavior....
- X * 03-oct-87
- X * - changed ":c\" to "c:" in epath.h for the AMIGA as suggested
- X * by Tom Edds
- X * - added binary and, or, and xor functions as submited by John Maline
- X * (&band &bor and &bxor)
- X * - added binary not (&bnot) function
- X * - added fixes for gotoline() and nextarg() as submited by David
- X * Dermott
- X * - fixed return value of $curwidth as submitted by David Dermott
- X * - fixed several calls to ldelete() to have a long first argument
- X * (pointed out by David Dermott)
- X * - Fixed a bug in stock() which prevented uppercase FN bindings as
- X * pointed out by many people
- X * - changed dofile() to make sure all executed files don't conflict
- X * with existing buffer names. Took out cludged code in main.c to
- X * handle this problem... this solution is better (suggested by
- X * Don Nash)
- X * 05-oct-87
- X * - added in John Gamble's code to allow for a replacement regular
- X * expresion character in MAGIC mode
- X * [note: under MSDOS we are still TOO BIG!!!!]
- X * - added overwrite-string as a new user callable function, and
- X * lowrite(c) as an internal function for overwriting characters
- X * - added &xlate function to translate strings according to a
- X * translation table
- X * 10-oct-87
- X * - added code to allow emacs to clean its own buffers on exit.
- X * useful if emacs is used as a subprogram. Conditional on
- X * the CLEAN definition in estruct.h
- X * 14-oct-87
- X * - swallowed very hard and switched to LARGE code/LARGE data model
- X * - packaged and released version 3.9c internally
- X * (MSDOS executables compiled with TURBO C Large model)
- X * 16-oct-87
- X * - temporary fix for FUNCTION keys now includes the Meta-O sequence
- X * if VT100 is definined (submited by Jeff Lomicka)
- X * - an VT100 also triggers input.c to force ESC to always
- X * be interpeted as META as well as the currently bound key
- X * - fixed a bug in the VMSVT driver as pointed out by Dave Dermott
- X * - added a size parameter to token() to eliminate problems with
- X * long variable names. (as sugested by Ray Wallace)
- X * 18-oct-87
- X * - fixed a bug in the free ram code that did not clear the buffer
- X * flag causing emacs to ask for more confirnmations on the way out.
- X * 19-oct-87
- X * - added ^X-$ execute-program call to directly execute a program
- X * without going through a shell... not all environments have this
- X * code completed yet (uses shell-command where not)
- X * [Froze for 3.9d release internally]
- X * 28-oct-87
- X * - added code for Atari ST DENSE mode and new bell as submited
- X * by J. C. Benoist
- X * - made extra CR for ST files conditional on ADDCR. This is only
- X * needed to make the desktop happy...and is painful for porting
- X * files (with 2 CR's) elsewhere (Also from J. C. Benoist)
- X * - added optional more intellegent (and larger) close brace
- X * insertion code (also from J. C. Benoist)
- X * 4-nov-87
- X * - fixed AZTEC spawning... all MSDOS spawns should work now
- X * - a META key while debugging will turn $debug to false
- X * and continue execution.
- X * [Froze for version 3.9e USENET release]
- X */
- X
- X#include <stdio.h>
- X
- X/* make global definitions not external */
- X#define maindef
- X
- X#include "estruct.h" /* global structures and defines */
- X#include "efunc.h" /* function declarations and name table */
- X#include "edef.h" /* global definitions */
- X#include "ebind.h" /* default key bindings */
- X
- X/* for MSDOS, increase the default stack space */
- X
- X#if MSDOS & LATTICE
- Xunsigned _stack = 32766;
- X#endif
- X
- X#if ATARI & MWC
- Xlong _stksize = 32766L; /* reset stack size (must be even) */
- X#endif
- X
- X#if MSDOS & AZTEC
- Xint _STKSIZ = 32766/16; /* stack size in paragraphs */
- Xint _STKRED = 1024; /* stack checking limit */
- Xint _HEAPSIZ = 4096/16; /* (in paragraphs) */
- Xint _STKLOW = 0; /* default is stack above heap (small only) */
- X#endif
- X
- X#if MSDOS & TURBO
- Xextern unsigned _stklen = 32766;
- X#endif
- X
- X#if VMS
- X#include <ssdef.h>
- X#define GOOD (SS$_NORMAL)
- X#endif
- X
- X#ifndef GOOD
- X#define GOOD 0
- X#endif
- X
- X#if CALLED
- Xemacs(argc, argv)
- X#else
- Xmain(argc, argv)
- X#endif
- Xint argc; /* # of arguments */
- Xchar *argv[]; /* argument strings */
- X
- X{
- X register int c; /* command character */
- X register int f; /* default flag */
- X register int n; /* numeric repeat count */
- X register int mflag; /* negative flag on repeat */
- X register BUFFER *bp; /* temp buffer pointer */
- X register int firstfile; /* first file flag */
- X register int carg; /* current arg to scan */
- X register int startflag; /* startup executed flag */
- X BUFFER *firstbp = NULL; /* ptr to first buffer in cmd line */
- X int basec; /* c stripped of meta character */
- X int viewflag; /* are we starting in view mode? */
- X int gotoflag; /* do we need to goto a line at start? */
- X int gline; /* if so, what line? */
- X int searchflag; /* Do we need to search at start? */
- X int saveflag; /* temp store for lastflag */
- X int errflag; /* C error processing? */
- X char bname[NBUFN]; /* buffer name of file to read */
- X#if CRYPT
- X int cryptflag; /* encrypting on the way in? */
- X char ekey[NPAT]; /* startup encryption key */
- X#endif
- X char *strncpy();
- X extern *pathname[]; /* startup file path/name array */
- X
- X /* initialize the editor */
- X vtinit(); /* Display */
- X edinit("main"); /* Buffers, windows */
- X varinit(); /* user variables */
- X
- X viewflag = FALSE; /* view mode defaults off in command line */
- X gotoflag = FALSE; /* set to off to begin with */
- X searchflag = FALSE; /* set to off to begin with */
- X firstfile = TRUE; /* no file to edit yet */
- X startflag = FALSE; /* startup file not executed yet */
- X errflag = FALSE; /* not doing C error parsing */
- X#if CRYPT
- X cryptflag = FALSE; /* no encryption by default */
- X#endif
- X#if CALLED
- X eexitflag = FALSE; /* not time to exit yet */
- X#endif
- X
- X /* Parse the command line */
- X for (carg = 1; carg < argc; ++carg) {
- X
- X /* Process Switches */
- X if (argv[carg][0] == '-') {
- X switch (argv[carg][1]) {
- X /* Process Startup macroes */
- X case 'a': /* process error file */
- X case 'A':
- X errflag = TRUE;
- X break;
- X case 'e': /* -e for Edit file */
- X case 'E':
- X viewflag = FALSE;
- X break;
- X case 'g': /* -g for initial goto */
- X case 'G':
- X gotoflag = TRUE;
- X gline = atoi(&argv[carg][2]);
- X break;
- X#if CRYPT
- X case 'k': /* -k<key> for code key */
- X case 'K':
- X cryptflag = TRUE;
- X strcpy(ekey, &argv[carg][2]);
- X break;
- X#endif
- X case 'r': /* -r restrictive use */
- X case 'R':
- X restflag = TRUE;
- X break;
- X case 's': /* -s for initial search string */
- X case 'S':
- X searchflag = TRUE;
- X strncpy(pat,&argv[carg][2],NPAT);
- X break;
- X case 'v': /* -v for View File */
- X case 'V':
- X viewflag = TRUE;
- X break;
- X default: /* unknown switch */
- X /* ignore this for now */
- X break;
- X }
- X
- X } else if (argv[carg][0]== '@') {
- X
- X /* Process Startup macroes */
- X if (startup(&argv[carg][1]) == TRUE)
- X /* don't execute emacs.rc */
- X startflag = TRUE;
- X
- X } else {
- X
- X /* Process an input file */
- X
- X /* set up a buffer for this file */
- X makename(bname, argv[carg]);
- X unqname(bname);
- X
- X /* set this to inactive */
- X bp = bfind(bname, TRUE, 0);
- X strcpy(bp->b_fname, argv[carg]);
- X bp->b_active = FALSE;
- X if (firstfile) {
- X firstbp = bp;
- X firstfile = FALSE;
- X }
- X
- X /* set the modes appropriatly */
- X if (viewflag)
- X bp->b_mode |= MDVIEW;
- X#if CRYPT
- X if (cryptflag) {
- X bp->b_mode |= MDCRYPT;
- X crypt((char *)NULL, 0);
- X crypt(ekey, strlen(ekey));
- X strncpy(bp->b_key, ekey, NPAT);
- X }
- X#endif
- X }
- X }
- X
- X /* if we are C error parsing... run it! */
- X if (errflag) {
- X if (startup("error.cmd") == TRUE)
- X startflag = TRUE;
- X }
- X
- X /* if invoked with no other startup files,
- X run the system startup file here */
- X if (startflag == FALSE) {
- X startup("");
- X startflag = TRUE;
- X }
- X
- X /* if there are any files to read, read the first one! */
- X bp = bfind("main", FALSE, 0);
- X if (firstfile == FALSE && (gflags & GFREAD)) {
- X swbuffer(firstbp);
- X curbp->b_mode |= gmode;
- X zotbuf(bp);
- X } else
- X bp->b_mode |= gmode;
- X
- X /* Deal with startup gotos and searches */
- X if (gotoflag && searchflag) {
- X update(FALSE);
- X mlwrite("[Can not search and goto at the same time!]");
- X }
- X else if (gotoflag) {
- X if (gotoline(TRUE,gline) == FALSE) {
- X update(FALSE);
- X mlwrite("[Bogus goto argument]");
- X }
- X } else if (searchflag) {
- X if (forwhunt(FALSE, 0) == FALSE)
- X update(FALSE);
- X }
- X
- X /* setup to process commands */
- X lastflag = 0; /* Fake last flags. */
- X
- Xloop:
- X
- X#if CALLED
- X /* if we were called as a subroutine and want to leave, do so */
- X if (eexitflag)
- X return(eexitval);
- X#endif
- X
- X /* execute the "command" macro...normally null */
- X saveflag = lastflag; /* preserve lastflag through this */
- X execute(META|SPEC|'C', FALSE, 1);
- X lastflag = saveflag;
- X
- X /* Fix up the screen */
- X update(FALSE);
- X
- X /* get the next command from the keyboard */
- X c = getcmd();
- X
- X /* if there is something on the command line, clear it */
- X if (mpresf != FALSE) {
- X mlerase();
- X update(FALSE);
- X#if CLRMSG
- X if (c == ' ') /* ITS EMACS does this */
- X goto loop;
- X#endif
- X }
- X f = FALSE;
- X n = 1;
- X
- X /* do META-# processing if needed */
- X
- X basec = c & ~META; /* strip meta char off if there */
- X if ((c & META) && ((basec >= '0' && basec <= '9') || basec == '-')) {
- X f = TRUE; /* there is a # arg */
- X n = 0; /* start with a zero default */
- X mflag = 1; /* current minus flag */
- X c = basec; /* strip the META */
- X while ((c >= '0' && c <= '9') || (c == '-')) {
- X if (c == '-') {
- X /* already hit a minus or digit? */
- X if ((mflag == -1) || (n != 0))
- X break;
- X mflag = -1;
- X } else {
- X n = n * 10 + (c - '0');
- X }
- X if ((n == 0) && (mflag == -1)) /* lonely - */
- X mlwrite("Arg:");
- X else
- X mlwrite("Arg: %d",n * mflag);
- X
- X c = getcmd(); /* get the next key */
- X }
- X n = n * mflag; /* figure in the sign */
- X }
- X
- X /* do ^U repeat argument processing */
- X
- X if (c == reptc) { /* ^U, start argument */
- X f = TRUE;
- X n = 4; /* with argument of 4 */
- X mflag = 0; /* that can be discarded. */
- X mlwrite("Arg: 4");
- X while ((c=getcmd()) >='0' && c<='9' || c==reptc || c=='-'){
- X if (c == reptc)
- X if ((n > 0) == ((n*4) > 0))
- X n = n*4;
- X else
- X n = 1;
- X /*
- X * If dash, and start of argument string, set arg.
- X * to -1. Otherwise, insert it.
- X */
- X else if (c == '-') {
- X if (mflag)
- X break;
- X n = 0;
- X mflag = -1;
- X }
- X /*
- X * If first digit entered, replace previous argument
- X * with digit and set sign. Otherwise, append to arg.
- X */
- X else {
- X if (!mflag) {
- X n = 0;
- X mflag = 1;
- X }
- X n = 10*n + c - '0';
- X }
- X mlwrite("Arg: %d", (mflag >=0) ? n : (n ? -n : -1));
- X }
- X /*
- X * Make arguments preceded by a minus sign negative and change
- X * the special argument "^U -" to an effective "^U -1".
- X */
- X if (mflag == -1) {
- X if (n == 0)
- X n++;
- X n = -n;
- X }
- X }
- X
- X /* and execute the command */
- X execute(c, f, n);
- X goto loop;
- X}
- X
- X/*
- X * Initialize all of the buffers and windows. The buffer name is passed down
- X * as an argument, because the main routine may have been told to read in a
- X * file by default, and we want the buffer name to be right.
- X */
- Xedinit(bname)
- Xchar bname[];
- X{
- X register BUFFER *bp;
- X register WINDOW *wp;
- X char *malloc();
- X
- X bp = bfind(bname, TRUE, 0); /* First buffer */
- X blistp = bfind("[List]", TRUE, BFINVS); /* Buffer list buffer */
- X wp = (WINDOW *) malloc(sizeof(WINDOW)); /* First window */
- X if (bp==NULL || wp==NULL || blistp==NULL)
- X exit(1);
- X curbp = bp; /* Make this current */
- X wheadp = wp;
- X curwp = wp;
- X wp->w_wndp = NULL; /* Initialize window */
- X wp->w_bufp = bp;
- X bp->b_nwnd = 1; /* Displayed. */
- X wp->w_linep = bp->b_linep;
- X wp->w_dotp = bp->b_linep;
- X wp->w_doto = 0;
- X wp->w_markp = NULL;
- X wp->w_marko = 0;
- X wp->w_toprow = 0;
- X#if COLOR
- X /* initalize colors to global defaults */
- X wp->w_fcolor = gfcolor;
- X wp->w_bcolor = gbcolor;
- X#endif
- X wp->w_ntrows = term.t_nrow-1; /* "-1" for mode line. */
- X wp->w_force = 0;
- X wp->w_flag = WFMODE|WFHARD; /* Full. */
- X}
- X
- X/*
- X * This is the general command execution routine. It handles the fake binding
- X * of all the keys to "self-insert". It also clears out the "thisflag" word,
- X * and arranges to move it to the "lastflag", so that the next command can
- X * look at it. Return the status of command.
- X */
- Xexecute(c, f, n)
- X{
- X register int status;
- X int (*execfunc)(); /* ptr to function to execute */
- X int (*getbind())();
- X
- X /* if the keystroke is a bound function...do it */
- X execfunc = getbind(c);
- X if (execfunc != NULL) {
- X thisflag = 0;
- X status = (*execfunc)(f, n);
- X lastflag = thisflag;
- X return (status);
- X }
- X
- X /*
- X * If a space was typed, fill column is defined, the argument is non-
- X * negative, wrap mode is enabled, and we are now past fill column,
- X * and we are not read-only, perform word wrap.
- X */
- X if (c == ' ' && (curwp->w_bufp->b_mode & MDWRAP) && fillcol > 0 &&
- X n >= 0 && getccol(FALSE) > fillcol &&
- X (curwp->w_bufp->b_mode & MDVIEW) == FALSE)
- X execute(META|SPEC|'W', FALSE, 1);
- X
- X if ((c>=0x20 && c<=0xFF)) { /* Self inserting. */
- X if (n <= 0) { /* Fenceposts. */
- X lastflag = 0;
- X return (n<0 ? FALSE : TRUE);
- X }
- X thisflag = 0; /* For the future. */
- X
- X /* if we are in overwrite mode, not at eol,
- X and next char is not a tab or we are at a tab stop,
- X delete a char forword */
- X if (curwp->w_bufp->b_mode & MDOVER &&
- X curwp->w_doto < curwp->w_dotp->l_used &&
- X (lgetc(curwp->w_dotp, curwp->w_doto) != '\t' ||
- X (curwp->w_doto) % 8 == 7))
- X ldelete(1L, FALSE);
- X
- X /* do the appropriate insertion */
- X if (c == '}' && (curbp->b_mode & MDCMOD) != 0)
- X status = insbrace(n, c);
- X else if (c == '#' && (curbp->b_mode & MDCMOD) != 0)
- X status = inspound();
- X else
- X status = linsert(n, c);
- X
- X#if CFENCE
- X /* check for CMODE fence matching */
- X if ((c == '}' || c == ')' || c == ']') &&
- X (curbp->b_mode & MDCMOD) != 0)
- X fmatch(c);
- X#endif
- X
- X /* check auto-save mode */
- X if (curbp->b_mode & MDASAVE)
- X if (--gacount == 0) {
- X /* and save the file if needed */
- X upscreen(FALSE, 0);
- X filesave(FALSE, 0);
- X gacount = gasave;
- X }
- X
- X lastflag = thisflag;
- X return (status);
- X }
- X TTbeep();
- X mlwrite("[Key not bound]"); /* complain */
- X lastflag = 0; /* Fake last flags. */
- X return (FALSE);
- X}
- X
- X/*
- X * Fancy quit command, as implemented by Norm. If the any buffer has
- X * changed do a write on that buffer and exit emacs, otherwise simply exit.
- X */
- Xquickexit(f, n)
- X{
- X register BUFFER *bp; /* scanning pointer to buffers */
- X register BUFFER *oldcb; /* original current buffer */
- X register int status;
- X
- X oldcb = curbp; /* save in case we fail */
- X
- X bp = bheadp;
- X while (bp != NULL) {
- X if ((bp->b_flag&BFCHG) != 0 /* Changed. */
- X && (bp->b_flag&BFINVS) == 0) { /* Real. */
- X curbp = bp; /* make that buffer cur */
- X mlwrite("[Saving %s]",bp->b_fname);
- X mlwrite("\n");
- X if ((status = filesave(f, n)) != TRUE) {
- X curbp = oldcb; /* restore curbp */
- X return(status);
- X }
- X }
- X bp = bp->b_bufp; /* on to the next buffer */
- X }
- X quit(f, n); /* conditionally quit */
- X return(TRUE);
- X}
- X
- X/*
- X * Quit command. If an argument, always quit. Otherwise confirm if a buffer
- X * has been changed and not written out. Normally bound to "C-X C-C".
- X */
- Xquit(f, n)
- X{
- X register int s;
- X
- X if (f != FALSE /* Argument forces it. */
- X || anycb() == FALSE /* All buffers clean. */
- X /* User says it's OK. */
- X || (s=mlyesno("Modified buffers exist. Leave anyway")) == TRUE) {
- X#if FILOCK
- X if (lockrel() != TRUE) {
- X TTputc('\n');
- X TTputc('\r');
- X TTclose();
- X TTkclose();
- X exit(1);
- X }
- X#endif
- X vttidy();
- X if (f)
- X exit(n);
- X else
- X exit(GOOD);
- X }
- X mlwrite("");
- X return(s);
- X}
- X
- X/*
- X * Begin a keyboard macro.
- X * Error if not at the top level in keyboard processing. Set up variables and
- X * return.
- X */
- Xctlxlp(f, n)
- X{
- X if (kbdmode != STOP) {
- X mlwrite("%%Macro already active");
- X return(FALSE);
- X }
- X mlwrite("[Start macro]");
- X kbdptr = &kbdm[0];
- X kbdend = kbdptr;
- X kbdmode = RECORD;
- X return (TRUE);
- X}
- X
- X/*
- X * End keyboard macro. Check for the same limit conditions as the above
- X * routine. Set up the variables and return to the caller.
- X */
- Xctlxrp(f, n)
- X{
- X if (kbdmode == STOP) {
- X mlwrite("%%Macro not active");
- X return(FALSE);
- X }
- X if (kbdmode == RECORD) {
- X mlwrite("[End macro]");
- X kbdmode = STOP;
- X }
- X return(TRUE);
- X}
- X
- X/*
- X * Execute a macro.
- X * The command argument is the number of times to loop. Quit as soon as a
- X * command gets an error. Return TRUE if all ok, else FALSE.
- X */
- Xctlxe(f, n)
- X{
- X if (kbdmode != STOP) {
- X mlwrite("%%Macro already active");
- X return(FALSE);
- X }
- X if (n <= 0)
- X return (TRUE);
- X kbdrep = n; /* remember how many times to execute */
- X kbdmode = PLAY; /* start us in play mode */
- X kbdptr = &kbdm[0]; /* at the beginning */
- X return(TRUE);
- X}
- X
- X/*
- X * Abort.
- X * Beep the beeper. Kill off any keyboard macro, etc., that is in progress.
- X * Sometimes called as a routine, to do general aborting of stuff.
- X */
- Xctrlg(f, n)
- X{
- X TTbeep();
- X kbdmode = STOP;
- X mlwrite("[Aborted]");
- X return(ABORT);
- X}
- X
- X/* tell the user that this command is illegal while we are in
- X VIEW (read-only) mode */
- X
- Xrdonly()
- X
- X{
- X TTbeep();
- X mlwrite("[Key illegal in VIEW mode]");
- X return(FALSE);
- X}
- X
- Xresterr()
- X
- X{
- X TTbeep();
- X mlwrite("[That command is RESTRICTED]");
- X return(FALSE);
- X}
- X
- Xnullproc() /* user function that does NOTHING */
- X
- X{
- X}
- X
- Xmeta() /* dummy function for binding to meta prefix */
- X{
- X}
- X
- Xcex() /* dummy function for binding to control-x prefix */
- X{
- X}
- X
- Xunarg() /* dummy function for binding to universal-argument */
- X{
- X}
- X
- X/***** Compiler specific Library functions ****/
- X
- X#if MWC86 & MSDOS
- Xmovmem(source, dest, size)
- X
- Xchar *source; /* mem location to move memory from */
- Xchar *dest; /* memory location to move text to */
- Xint size; /* number of bytes to move */
- X
- X{
- X register int i;
- X
- X for (i=0; i < size; i++)
- X *dest++ = *source++;
- X}
- X#endif
- X
- X#if MSDOS | AMIGA | ST520
- X/* strncpy: copy a string...with length restrictions
- X ALWAYS null terminate
- X*/
- X
- Xchar *strncpy(dst, src, maxlen)
- X
- Xchar *dst; /* destination of copied string */
- Xchar *src; /* source */
- Xint maxlen; /* maximum length */
- X
- X{
- X char *dptr; /* ptr into dst */
- X
- X dptr = dst;
- X while (*src && (maxlen-- > 0))
- X *dptr++ = *src++;
- X *dptr = 0;
- X return(dst);
- X}
- X#endif
- X
- X#if RAMSIZE
- X/* These routines will allow me to track memory usage by placing
- X a layer on top of the standard system malloc() and free() calls.
- X with this code defined, the environment variable, $RAM, will
- X report on the number of bytes allocated via malloc.
- X
- X with SHOWRAM defined, the number is also posted on the
- X end of the bottom mode line and is updated whenever it is changed.
- X*/
- X
- X#undef malloc
- X#undef free
- X
- Xchar *allocate(nbytes) /* allocate nbytes and track */
- X
- Xunsigned nbytes; /* # of bytes to allocate */
- X
- X{
- X char *mp; /* ptr returned from malloc */
- X char *malloc();
- X
- X mp = malloc(nbytes);
- X if (mp) {
- X envram += nbytes;
- X#if RAMSHOW
- X dspram();
- X#endif
- X }
- X
- X return(mp);
- X}
- X
- Xrelease(mp) /* release malloced memory and track */
- X
- Xchar *mp; /* chunk of RAM to release */
- X
- X{
- X unsigned *lp; /* ptr to the long containing the block size */
- X
- X if (mp) {
- X /* update amount of ram currently malloced */
- X lp = ((unsigned *)mp) - 1;
- X envram -= (long)*lp - 2;
- X free(mp);
- X#if RAMSHOW
- X dspram();
- X#endif
- X }
- X}
- X
- X#if RAMSHOW
- Xdspram() /* display the amount of RAM currently malloced */
- X
- X{
- X char mbuf[20];
- X char *sp;
- X
- X TTmove(term.t_nrow - 1, 70);
- X#if COLOR
- X TTforg(7);
- X TTbacg(0);
- X#endif
- X sprintf(mbuf, "[%lu]", envram);
- X sp = &mbuf[0];
- X while (*sp)
- X TTputc(*sp++);
- X TTmove(term.t_nrow, 0);
- X movecursor(term.t_nrow, 0);
- X}
- X#endif
- X#endif
- X
- X/* On some primitave operation systems, and when emacs is used as
- X a subprogram to a larger project, emacs needs to de-alloc its
- X own used memory
- X*/
- X
- X#if CLEAN
- Xcexit(status)
- X
- Xint status; /* return status of emacs */
- X
- X{
- X register BUFFER *bp; /* buffer list pointer */
- X register WINDOW *wp; /* window list pointer */
- X register WINDOW *tp; /* temporary window pointer */
- X
- X /* first clean up the windows */
- X wp = wheadp;
- X while (wp) {
- X tp = wp->w_wndp;
- X free(wp);
- X wp = tp;
- X }
- X wheadp = NULL;
- X
- X /* then the buffers */
- X bp = bheadp;
- X while (bp) {
- X bp->b_nwnd = 0;
- X bp->b_flag = 0; /* don't say anything about a changed buffer! */
- X zotbuf(bp);
- X bp = bheadp;
- X }
- X
- X /* and the kill buffer */
- X kdelete();
- X
- X /* and the video buffers */
- X vtfree();
- X
- X /* and now.. we leave [pick the return if we are a subprogram] */
- X#if CALLED
- X eexitflag = TRUE; /* flag a program exit */
- X eexitval = status;
- X return(status);
- X#else
- X#undef exit
- X exit(status);
- X#endif
- X}
- X#endif
- FRIDAY_NIGHT
- echo mes.8 completed!
- # That's all folks!
-
-
-