home *** CD-ROM | disk | FTP | other *** search
- /*
- * Buffer management.
- * Some of the functions are internal,
- * and some are actually attached to user
- * keys. Like everyone else, they set hints
- * for the display system.
- */
- #include <stdio.h>
- #include "ed.h"
-
- /* USEBUFFER eXtended command. Prompt for buffer name. Store it in
- * external pattern lastbuf. Call selbuf() to make the change. Bound
- * to CTLX-B.
- */
- usebuffer(f, n)
- register int f, n;
- {
- register int s;
-
- if ((s=readpattern("Use buffer [DEFAULT] ", &lastbuf)) != TRUE)
- return (s);
- return(selbuf(lastbuf));
- }
-
- /*
- * Attach a buffer to a window. The
- * values of dot and mark come from the buffer
- * if the use count is 0. Otherwise, they come
- * from some other window.
- */
- selbuf(bufname)
- register char *bufname;
- {
- register BUFFER *bp;
- register WINDOW *wp;
-
- /* Find a buffer. If the buffer does not exist, then ask the user
- * whether a new buffer should be created.
- */
-
- if ((bp=bfind(bufname, MAYBE, 0)) == NULL)
- return (FALSE);
- strcpy(lastbuf, curbp->b_bname); /* set up for return */
- if (--curbp->b_nwnd == 0) { /* Last use. */
- curbp->b_dotp = curwp->w_dotp;
- curbp->b_doto = curwp->w_doto;
- curbp->b_markp = curwp->w_markp;
- curbp->b_marko = curwp->w_marko;
- }
- curbp = bp; /* Switch. */
- curwp->w_bufp = bp;
- curwp->w_linep = bp->b_linep; /* For macros, ignored. */
- curwp->w_flag |= WFMODE|WFFORCE|WFHARD; /* Quite nasty. */
- if (bp->b_nwnd++ == 0) { /* First use. */
- curwp->w_dotp = bp->b_dotp;
- curwp->w_doto = bp->b_doto;
- curwp->w_markp = bp->b_markp;
- curwp->w_marko = bp->b_marko;
- return (TRUE);
- }
- wp = wheadp; /* Look for old. */
- while (wp != NULL) {
- if (wp!=curwp && wp->w_bufp==bp) {
- curwp->w_dotp = wp->w_dotp;
- curwp->w_doto = wp->w_doto;
- curwp->w_markp = wp->w_markp;
- curwp->w_marko = wp->w_marko;
- break;
- }
- wp = wp->w_wndp;
- }
- return (TRUE);
- }
-
- /* KILLBUFFER eXtended command. Prompt for buffer name. Call delbuf()
- * to do the actual kill. Bound to CTLX-K.
- */
- killbuffer(f, n)
- register int f, n;
- {
- register int s;
-
- if ((s=readpattern("Kill buffer [DEFAULT] ", &lastbuf)) != TRUE)
- return (s);
- return(delbuf(lastbuf));
- }
-
- /*
- * Dispose of a buffer, by name.
- * Look up bufname (don't get too
- * upset if it isn't there at all!). Get quite upset
- * if the buffer is being displayed. Clear the buffer (ask
- * if the buffer has been changed). Then free the header
- * line and the buffer header.
- */
- delbuf(bufname)
- register char *bufname;
- {
- register BUFFER *bp;
- register BUFFER *bp1;
- register BUFFER *bp2;
- register int s;
-
- if ((bp=bfind(bufname, FALSE, 0)) == NULL) /* Easy if unknown.*/
- return (TRUE);
- strcpy(lastbuf, curbp->b_bname);
- if (bp->b_nwnd != 0) { /* Error if on screen. */
- mlwrite("Buffer is being displayed");
- return (FALSE);
- }
- if ((s=bclear(bp)) != TRUE) /* Blow text away. */
- return (s);
- free((char *) bp->b_linep); /* Release header line. */
- bp1 = NULL; /* Find the header. */
- bp2 = bheadp;
- while (bp2 != bp) {
- bp1 = bp2;
- bp2 = bp2->b_bufp;
- }
- bp2 = bp2->b_bufp; /* Next one in chain. */
- if (bp1 == NULL) /* Unlink it. */
- bheadp = bp2;
- else
- bp1->b_bufp = bp2;
- free((char *) bp); /* Release buffer block */
- return (TRUE);
- }
-
- /*
- * List all of the active
- * buffers. First update the special
- * buffer that holds the list. Next make
- * sure at least 1 window is displaying the
- * buffer list, splitting the screen if this
- * is what it takes. Lastly, repaint all of
- * the windows that are displaying the
- * list. Bound to "C-X C-B".
- */
- listbuffers(f, n)
- register int f, n;
- {
- register WINDOW *wp;
- register BUFFER *bp;
- register int s;
-
- if (blistp == NULL)
- {
- blistp = bfind("[List]", TRUE, BFTEMP); /* Buffer list buffer*/
- if (blistp == NULL)
- return(ABORT);
- }
- if ((s=makelist()) != TRUE)
- return (s);
- if (blistp->b_nwnd == 0) { /* Not on screen yet. */
- if ((wp=wpopup()) == NULL)
- return (FALSE);
- bp = wp->w_bufp;
- if (--bp->b_nwnd == 0) {
- bp->b_dotp = wp->w_dotp;
- bp->b_doto = wp->w_doto;
- bp->b_markp = wp->w_markp;
- bp->b_marko = wp->w_marko;
- }
- wp->w_bufp = blistp;
- ++blistp->b_nwnd;
- }
- wp = wheadp;
- while (wp != NULL) {
- if (wp->w_bufp == blistp) {
- wp->w_linep = lforw(blistp->b_linep);
- wp->w_dotp = lforw(blistp->b_linep);
- wp->w_doto = 0;
- wp->w_markp = NULL;
- wp->w_marko = 0;
- wp->w_flag |= WFMODE|WFHARD;
- }
- wp = wp->w_wndp;
- }
- return (TRUE);
- }
-
- /*
- * This routine rebuilds the
- * text in the special secret buffer
- * that holds the buffer list. It is called
- * by the list buffers command. Return TRUE
- * if everything works. Return FALSE if there
- * is an error (if there is no memory).
- */
- makelist()
- {
- register char *cp1;
- register char *cp2;
- register int c;
- register BUFFER *bp;
- register LINE *lp;
- register long nbytes;
- register int s;
- register int type;
- char b[6+1];
- char line[128];
-
- blistp->b_flag &= ~BFCHG; /* Don't complain! */
- blistp->b_bmode |= BMNWRAP;
- if ((s=bclear(blistp)) != TRUE) /* Blow old text away */
- return (s);
- strcpy(blistp->b_fname, "");
- if (addline(blistp,"C Size Buffer File") == FALSE
- || addline(blistp,"- ---- ------ ----") == FALSE)
- return (FALSE);
- bp = bheadp; /* For all buffers */
- while (bp != NULL) {
- if ((bp->b_flag&BFTEMP) != 0) { /* Skip magic ones. */
- bp = bp->b_bufp;
- continue;
- }
- cp1 = &line[0]; /* Start at left edge */
- if ((bp->b_flag&BFCHG) != 0) /* "*" if changed */
- *cp1++ = '*';
- else
- *cp1++ = ' ';
- *cp1++ = ' '; /* Gap. */
- nbytes = 0L; /* Count bytes in buf. */
- lp = lforw(bp->b_linep);
- while (lp != bp->b_linep) {
- nbytes += llength(lp)+1;
- lp = lforw(lp);
- }
- ltoa(b, 6, nbytes); /* 6 digit buffer size. */
- cp2 = &b[0];
- while ((c = *cp2++) != 0)
- *cp1++ = c;
- *cp1++ = ' '; /* Gap. */
- cp2 = &bp->b_bname[0]; /* Buffer name */
- while ((c = *cp2++) != 0)
- *cp1++ = c;
- cp2 = &bp->b_fname[0]; /* File name */
- if (*cp2 != 0) {
- while (cp1 < &line[1+1+6+1+NBUFN+1])
- *cp1++ = ' ';
- while ((c = *cp2++) != 0) {
- if (cp1 < &line[128-1])
- *cp1++ = c;
- }
- }
- *cp1 = 0; /* Add to the buffer. */
- if (addline(blistp, line) == FALSE)
- return (FALSE);
- bp = bp->b_bufp;
- }
- return (TRUE); /* All done */
- }
-
- ltoa(buf, width, num)
- register char buf[];
- register int width;
- register long num;
- {
- buf[width] = 0; /* End of string. */
- while (num >= 10L) { /* Conditional digits. */
- buf[--width] = (int)(num%10L) + '0';
- num /= 10L;
- }
- buf[--width] = num + '0'; /* Always 1 digit. */
- while (width != 0) /* Pad with blanks. */
- buf[--width] = ' ';
- }
-
- /*
- * The argument "text" points to
- * a string. Append this line to the
- * buffer "bp" (one with BFTEMP set). Handcraft the EOL
- * on the end. Return TRUE if it worked and
- * FALSE if you ran out of room.
- */
- addline(bp, text)
- register BUFFER *bp;
- register char *text;
- {
- register LINE *lp;
- register int i;
- register int ntext;
-
- ntext = strlen(text);
- if ((lp=lalloc(ntext)) == NULL)
- return (FALSE);
- for (i=0; i<ntext; ++i)
- lputc(lp, i, text[i]);
- bp->b_linep->l_bp->l_fp = lp; /* Hook onto the end */
- lp->l_bp = bp->b_linep->l_bp;
- bp->b_linep->l_bp = lp;
- lp->l_fp = bp->b_linep;
- if (bp->b_dotp == bp->b_linep) /* If "." is at the end */
- bp->b_dotp = lp; /* move it to new line */
- return (TRUE);
- }
-
- /*
- * Look through the list of
- * buffers. Return TRUE if there
- * are any changed buffers. Buffers
- * that hold magic internal stuff are
- * not considered; who cares if the
- * list of buffer names is hacked.
- * Return FALSE if no buffers
- * have been changed.
- */
- anycb()
- {
- register BUFFER *bp;
-
- bp = bheadp;
- while (bp != NULL) {
- if ((bp->b_flag&BFTEMP)==0 && (bp->b_flag&BFCHG)!=0)
- return (TRUE);
- bp = bp->b_bufp;
- }
- return (FALSE);
- }
-
- /*
- * Find a buffer, by name. Return a pointer
- * to the BUFFER structure associated with it. If
- * the named buffer is found, but is a TEMP buffer (like
- * the buffer list) conplain. If the buffer is not found
- * and the "cflag" is TRUE, create it. The "bflag" is
- * the settings for the flags in in buffer.
- */
- BUFFER *
- bfind(bname, cflag, bflag)
- register char *bname;
- register int cflag, bflag;
- {
- register BUFFER *bp;
- register LINE *lp;
- char *index(),*ptr;
-
- bp = bheadp;
- while (bp != NULL)
- {
- if (strcmp(bname, bp->b_bname) == 0)
- {
- if ((bp->b_flag&BFTEMP) != 0)
- if (cflag == FALSE)
- {
- mlwrite("Cannot select builtin buffer");
- return (FALSE);
- }
- return (bp);
- }
- bp = bp->b_bufp;
- }
- /* Buffer does not exist. Prompt the user to see if a new
- * buffer should be created.
- */
- if (cflag == MAYBE) {
- if (mlyesno("Create new buffer") != TRUE)
- return(FALSE);
- cflag = TRUE; /* yes, create it */
- }
- if (cflag == TRUE) {
- if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL)
- return (NULL);
- if ((lp=lalloc(0)) == NULL) {
- free((char *) bp);
- return (NULL);
- }
- /* clear all mode flags */
- bp->b_bmode &=~BMWRAP;
- bp->b_bmode &=~BMNWRAP;
- bp->b_bmode &=~BMCMODE;
- if (ptr=index(bname,'.'))
- {
- if (strncmp(ptr, ".mss",4)==0)
- bp->b_bmode |= BMWRAP;
- else if (strcmp(ptr,".c")==0)
- bp->b_bmode |= BMCMODE;
- else if (strcmp(ptr,".h")==0)
- bp->b_bmode |= BMCMODE;
- else
- bp->b_bmode |= glmode;
- }
- else
- bp->b_bmode |= glmode;
- bp->b_bufp = bheadp;
- bheadp = bp;
- bp->b_dotp = lp;
- bp->b_doto = 0;
- bp->b_markp = lp; /* All new buffers begin with mark */
- bp->b_marko = 0;
- bp->b_flag = bflag;
- bp->b_nwnd = 0;
- bp->b_linep = lp;
- strcpy(bp->b_fname, "");
- strcpy(bp->b_bname, bname);
- lp->l_fp = lp;
- lp->l_bp = lp;
- }
- return (bp);
- }
-
- /*
- * This routine blows away all of the text
- * in a buffer. If the buffer is marked as changed
- * then we ask if it is ok to blow it away; this is
- * to save the user the grief of losing text. The
- * window chain is nearly always wrong if this gets
- * called; the caller must arrange for the updates
- * that are required. Return TRUE if everything
- * looks good.
- */
- bclear(bp)
- register BUFFER *bp;
- {
- register LINE *lp;
- register int s;
-
- if ((bp->b_flag&BFTEMP) == 0 /* Not scratch buffer. */
- && (bp->b_flag&BFCHG) != 0 /* Something changed */
- && (s=mlyesno("Discard changes")) != TRUE)
- return (s);
- bp->b_flag &= ~BFCHG; /* Not changed */
- while ((lp=lforw(bp->b_linep)) != bp->b_linep)
- lfree(lp);
- bp->b_dotp = bp->b_linep; /* Fix "." */
- bp->b_doto = 0;
- bp->b_markp = NULL; /* Invalidate "mark" */
- bp->b_marko = 0;
- return (TRUE);
- }
-