home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD2.mdf / c / newemacs / buffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-02-04  |  8.6 KB  |  346 lines

  1. /*
  2.  * Buffer management.
  3.  * Some of the functions are internal,
  4.  * and some are actually attached to user
  5.  * keys. Like everyone else, they set hints
  6.  * for the display system.
  7.  */
  8. #include    <stdio.h>
  9. #include    "ed.h"
  10.  
  11. /*
  12.  * Attach a buffer to a window. The
  13.  * values of dot and mark come from the buffer
  14.  * if the use count is 0. Otherwise, they come
  15.  * from some other window.
  16.  */
  17. usebuffer(f, n)
  18. {
  19.     register BUFFER    *bp;
  20.     register WINDOW    *wp;
  21.     register int    s;
  22.     char        bufn[NBUFN];
  23.  
  24.     if ((s=mlreply("Use buffer: ", bufn, NBUFN)) != TRUE)
  25.         return (s);
  26.     if (!(bp=bfind(bufn, TRUE, 0)))
  27.         return (FALSE);
  28.     if (!--curbp->b_nwnd) {        /* Last use.        */
  29.         curbp->b_dotp  = curwp->w_dotp;
  30.         curbp->b_doto  = curwp->w_doto;
  31.         curbp->b_markp = curwp->w_markp;
  32.         curbp->b_marko = curwp->w_marko;
  33.     }
  34.     curbp = bp;                /* Switch.        */
  35.     curwp->w_bufp  = bp;
  36.     curwp->w_linep = bp->b_linep;        /* For macros, ignored.    */
  37.     curwp->w_flag |= WFMODE|WFFORCE|WFHARD;    /* Quite nasty.        */
  38.     if (!bp->b_nwnd++) {        /* First use.        */
  39.         curwp->w_dotp  = bp->b_dotp;
  40.         curwp->w_doto  = bp->b_doto;
  41.         curwp->w_markp = bp->b_markp;
  42.         curwp->w_marko = bp->b_marko;
  43.         return (TRUE);
  44.     }
  45.  
  46.     /* Look for old */
  47.  
  48.     for (wp = wheadp; wp; wp = wp->w_wndp) {
  49.         if (wp!=curwp && wp->w_bufp==bp) {
  50.             curwp->w_dotp  = wp->w_dotp;
  51.             curwp->w_doto  = wp->w_doto;
  52.             curwp->w_markp = wp->w_markp;
  53.             curwp->w_marko = wp->w_marko;
  54.             break;
  55.         }
  56.     }
  57.     return (TRUE);
  58. }
  59.  
  60. /*
  61.  * Dispose of a buffer, by name.
  62.  * Ask for the name. Look it up (don't get too
  63.  * upset if it isn't there at all!). Get quite upset
  64.  * if the buffer is being displayed. Clear the buffer (ask
  65.  * if the buffer has been changed). Then free the header
  66.  * line and the buffer header. Bound to "C-X K".
  67.  */
  68. killbuffer(f, n)
  69. {
  70.     register BUFFER    *bp;
  71.     register BUFFER    *bp1;
  72.     register BUFFER    *bp2;
  73.     register int    s;
  74.     char        bufn[NBUFN];
  75.  
  76.     if ((s=mlreply("Kill buffer: ", bufn, NBUFN)) != TRUE)
  77.         return (s);
  78.     if (!(bp=bfind(bufn, FALSE, 0)))    /* Easy if unknown.    */
  79.         return (TRUE);
  80.     if (bp->b_nwnd) {            /* Error if on screen.    */
  81.         mlwrite("Buffer is being displayed");
  82.         return (FALSE);
  83.     }
  84.     if ((s=bclear(bp)) != TRUE)        /* Blow text away.    */
  85.         return (s);
  86.     free((char *) bp->b_linep);        /* Release header line.    */
  87.     bp1 = NULL;                /* Find the header.    */
  88.     for (bp2 = bheadp; bp2 != bp; bp2 = bp2->b_bufp) bp1 = bp2;
  89.     bp2 = bp2->b_bufp;            /* Next one in chain.    */
  90.     if (!bp1)            /* Unlink it.        */
  91.         bheadp = bp2;
  92.     else
  93.         bp1->b_bufp = bp2;
  94.     free((char *) bp);            /* Release buffer block    */
  95.     return (TRUE);
  96. }
  97.  
  98. /*
  99.  * List all of the active
  100.  * buffers. First update the special
  101.  * buffer that holds the list. Next make
  102.  * sure at least 1 window is displaying the
  103.  * buffer list, splitting the screen if this
  104.  * is what it takes. Lastly, repaint all of
  105.  * the windows that are displaying the
  106.  * list. Bound to "C-X C-B".
  107.  */
  108. listbuffers(f, n)
  109. {
  110.     register WINDOW    *wp;
  111.     register BUFFER    *bp;
  112.     register int    s;
  113.  
  114.     if ((s=makelist()) != TRUE)
  115.         return (s);
  116.     if (!blistp->b_nwnd) {        /* Not on screen yet.    */
  117.         if (!(wp=wpopup()))
  118.             return (FALSE);
  119.         bp = wp->w_bufp;
  120.         if (!--bp->b_nwnd) {
  121.             bp->b_dotp  = wp->w_dotp;
  122.             bp->b_doto  = wp->w_doto;
  123.             bp->b_markp = wp->w_markp;
  124.             bp->b_marko = wp->w_marko;
  125.         }
  126.         wp->w_bufp  = blistp;
  127.         ++blistp->b_nwnd;
  128.     }
  129.     for (wp = wheadp; wp; wp = wp->w_wndp) {
  130.         if (wp->w_bufp == blistp) {
  131.             wp->w_linep = lforw(blistp->b_linep);
  132.             wp->w_dotp  = lforw(blistp->b_linep);
  133.             wp->w_doto  = wp->w_markp = wp->w_marko = 0;
  134.             wp->w_flag |= WFMODE|WFHARD;
  135.         }
  136.     }
  137.     return (TRUE);
  138. }
  139.  
  140. /*
  141.  * This routine rebuilds the
  142.  * text in the special secret buffer
  143.  * that holds the buffer list. It is called
  144.  * by the list buffers command. Return TRUE
  145.  * if everything works. Return FALSE if there
  146.  * is an error (if there is no memory).
  147.  */
  148. makelist()
  149. {
  150.     register char    *cp1;
  151.     register char    *cp2;
  152.     register int    c;
  153.     register BUFFER    *bp;
  154.     register LINE    *lp;
  155.     register int    nbytes;
  156.     register int    s;
  157.     register int    type;
  158.     char        b[6+1];
  159.     char        line[128];
  160.  
  161.     blistp->b_flag &= ~BFCHG;        /* Don't complain!    */
  162.     if ((s=bclear(blistp)) != TRUE)        /* Blow old text away    */
  163.         return (s);
  164.     strcpy(blistp->b_fname, "");
  165.     if (addline("C   Size Buffer           File") == FALSE
  166.     ||  addline("-   ---- ------           ----") == FALSE)
  167.         return (FALSE);
  168.  
  169.     /* For all buffers    */
  170.  
  171.     for (bp = bheadp; bp; bp = bp->b_bufp) {
  172.         if (bp->b_flag&BFTEMP) {    /* Skip magic ones.    */
  173.             bp = bp->b_bufp;
  174.             continue;
  175.         }
  176.         cp1 = line;            /* Start at left edge    */
  177.         if (bp->b_flag&BFCHG)    /* "*" if changed    */
  178.             *cp1++ = '*';
  179.         else
  180.             *cp1++ = ' ';
  181.         *cp1++ = ' ';            /* Gap.            */
  182.         nbytes = 0;            /* Count bytes in buf.    */
  183.         for (lp=lforw(bp->b_linep); lp!=bp->b_linep; lp=lforw(lp)) {
  184.             nbytes += llength(lp)+1;
  185.         }
  186.         itoa(b, 6, nbytes);        /* 6 digit buffer size.    */
  187.         cp2 = b;
  188.         while (c = *cp2++)
  189.             *cp1++ = c;
  190.         *cp1++ = ' ';            /* Gap.            */
  191.         cp2 = bp->b_bname;        /* Buffer name        */
  192.         while (c = *cp2++)
  193.             *cp1++ = c;
  194.         cp2 = bp->b_fname;        /* File name        */
  195.         if (*cp2) {
  196.             while (cp1 < line+10+NBUFN)
  197.                 *cp1++ = ' ';        
  198.             while (c = *cp2++) {
  199.                 if (cp1 < line+127)
  200.                     *cp1++ = c;
  201.             }
  202.         }
  203.         *cp1 = 0;            /* Add to the buffer.    */
  204.         if (addline(line) == FALSE)
  205.             return (FALSE);
  206.     }
  207.     return (TRUE);                /* All done        */
  208. }
  209.  
  210. itoa(buf, width, num)
  211. register char    buf[];
  212. register int    width;
  213. register int    num;
  214. {
  215.     buf[width] = 0;                /* End of string.    */
  216.     while (num >= 10) {            /* Conditional digits.    */
  217.         buf[--width] = (num%10) + '0';
  218.         num /= 10;
  219.     }
  220.     buf[--width] = num + '0';        /* Always 1 digit.    */
  221.     while (width)            /* Pad with blanks.    */
  222.         buf[--width] = ' ';
  223. }
  224.  
  225. /*
  226.  * The argument "text" points to
  227.  * a string. Append this line to the
  228.  * buffer list buffer. Handcraft the EOL
  229.  * on the end. Return TRUE if it worked and
  230.  * FALSE if you ran out of room.
  231.  */
  232. addline(text)
  233. char    *text;
  234. {
  235.     register LINE    *lp;
  236.     register int    i;
  237.     register int    ntext;
  238.  
  239.     ntext = strlen(text);
  240.     if (!(lp=lalloc(ntext)))
  241.         return (FALSE);
  242.     for (i=0; i<ntext; ++i)
  243.         lputc(lp, i, text[i]);
  244.     blistp->b_linep->l_bp->l_fp = lp;    /* Hook onto the end    */
  245.     lp->l_bp = blistp->b_linep->l_bp;
  246.     blistp->b_linep->l_bp = lp;
  247.     lp->l_fp = blistp->b_linep;
  248.     if (blistp->b_dotp == blistp->b_linep)    /* If "." is at the end    */
  249.         blistp->b_dotp = lp;        /* move it to new line    */
  250.     return (TRUE);
  251. }
  252.  
  253. /*
  254.  * Look through the list of
  255.  * buffers. Return TRUE if there
  256.  * are any changed buffers. Buffers
  257.  * that hold magic internal stuff are
  258.  * not considered; who cares if the
  259.  * list of buffer names is hacked.
  260.  * Return FALSE if no buffers
  261.  * have been changed.
  262.  */
  263. anycb()
  264. {
  265.     register BUFFER    *bp;
  266.  
  267.     for (bp = bheadp; bp; bp = bp->b_bufp) {
  268.         if (!(bp->b_flag&BFTEMP) && (bp->b_flag&BFCHG))
  269.             return (TRUE);
  270.     }
  271.     return (FALSE);
  272. }
  273.  
  274. /*
  275.  * Find a buffer, by name. Return a pointer
  276.  * to the BUFFER structure associated with it. If
  277.  * the named buffer is found, but is a TEMP buffer (like
  278.  * the buffer list) conplain. If the buffer is not found
  279.  * and the "cflag" is TRUE, create it. The "bflag" is
  280.  * the settings for the flags in in buffer.
  281.  */
  282. BUFFER    *
  283. bfind(bname, cflag, bflag)
  284. register char    *bname;
  285. {
  286.     register BUFFER    *bp;
  287.     register LINE    *lp;
  288.  
  289.     for (bp = bheadp; bp; bp = bp->b_bufp) {
  290.         if (!strcmp(bname, bp->b_bname)) {
  291.             if (bp->b_flag&BFTEMP) {
  292.                 mlwrite("Cannot select builtin buffer");
  293.                 return (NULL);
  294.             }
  295.             return (bp);
  296.         }
  297.     }
  298.     if (cflag) {
  299.         if (!(bp=(BUFFER *)malloc(sizeof(BUFFER))))
  300.             return (NULL);
  301.         if (!(lp=lalloc(0))) {
  302.             free((char *) bp);
  303.             return (NULL);
  304.         }
  305.         bp->b_bufp  = bheadp;
  306.         bheadp = bp;
  307.         bp->b_dotp  = lp;
  308.         bp->b_doto  = bp->b_markp = bp->b_marko = bp->b_nwnd  = 0;
  309.         bp->b_flag  = bflag;
  310.         bp->b_linep = lp;
  311.         strcpy(bp->b_fname, "");
  312.         strcpy(bp->b_bname, bname);
  313.         lp->l_fp = lp;
  314.         lp->l_bp = lp;
  315.     }
  316.     return (bp);
  317. }
  318.  
  319. /*
  320.  * This routine blows away all of the text
  321.  * in a buffer. If the buffer is marked as changed
  322.  * then we ask if it is ok to blow it away; this is
  323.  * to save the user the grief of losing text. The
  324.  * window chain is nearly always wrong if this gets
  325.  * called; the caller must arrange for the updates
  326.  * that are required. Return TRUE if everything
  327.  * looks good.
  328.  */
  329. bclear(bp)
  330. register BUFFER    *bp;
  331. {
  332.     register LINE    *lp;
  333.     register int    s;
  334.     
  335.     if (!(bp->b_flag&BFTEMP)        /* Not scratch buffer.    */
  336.     && (bp->b_flag&BFCHG)            /* Something changed    */
  337.     && (s=mlyesno("Discard changes")) != TRUE)
  338.         return (s);
  339.     bp->b_flag  &= ~BFCHG;            /* Not changed        */
  340.     while ((lp=lforw(bp->b_linep)) != bp->b_linep)
  341.         lfree(lp);
  342.     bp->b_dotp  = bp->b_linep;        /* Fix "."        */
  343.     bp->b_doto  = bp->b_markp = bp->b_marko = 0;
  344.     return (TRUE);
  345. }
  346.