home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2877 / buffer.c next >
Encoding:
C/C++ Source or Header  |  1991-02-28  |  20.5 KB  |  828 lines

  1. /*
  2. *       Buffer handling.
  3. */
  4.  
  5. #include    "def.h"
  6.  
  7. bool    onebuf ();
  8. bool    killablebufs ();
  9. bool    _yankbuffer ();
  10. char    next_buf ();
  11. bool    bclear ();
  12. bool    addline ();
  13. void    i_to_a ();
  14. char    makelist ();
  15. bool    popblist ();
  16. char    listbuffers ();
  17. char    _killbuffer ();
  18. bool    _usebuffer ();
  19.  
  20. extern  ROW_FMT text_fmt;
  21. extern    char    MSG_use_b[];
  22. extern    char    MSG_kill_b[];
  23. extern    char    MSG_not_fnd[];
  24. extern    char    MSG_no_del_m[];
  25. extern    char    MSG_buf_disp[];
  26. extern    char    MSG_main[];
  27. extern    char    MSG_l_buf_h[];
  28. extern    char    MSG_l_buf_h1[];
  29. extern    char    MSG_no_chg[];
  30. extern    char    MSG_yank_b[];
  31. extern    char    MSG_no_buf[];
  32. extern    char    MSG_no_s_yank[];
  33. extern    char    MSG_buf_nam[];
  34. extern    char    MSG_bad_l[];
  35. extern    char    MSG_pick[];
  36. extern    char    MSG_siz_chg[];
  37. extern    char    MSG_no_siz_chg[];
  38. extern    char    MSG_up_arrow[];
  39. extern    char    MSG_null[];
  40.  
  41. #include    "lintfunc.dec"
  42. /*
  43. * Attach a buffer to a window. The
  44. * values of dot and mark come from the buffer
  45. * if the use count is 0. Otherwise, they come
  46. * from some other window.
  47. *
  48. * plus hacks for prev/next buffer and use-buffer-split  (jam)
  49. * functions (like in file.c)
  50. */
  51. char    usebuffer ()
  52. {
  53.  
  54.     char    bufn[NBUFN];
  55.     register char   s;
  56.  
  57.     if ((s = ereply (MSG_use_b, bufn, NBUFN, 0)) != TRUE)
  58.         return (s);
  59.     return (_usebuffer (bufn));
  60. }
  61.  
  62. /* use buffer, split window first
  63. */
  64. char    use_buffer ()
  65. {
  66.     char    bufn[NBUFN];
  67.     register char   s;
  68.  
  69.     if ((s = ereply (MSG_use_b, bufn, NBUFN, 0)) != TRUE)
  70.         return (s);
  71.     splitwind ();
  72.     return (_usebuffer (bufn));
  73. }
  74.  
  75. /* does all the work for changing to a new buffer for use-buffer,
  76. * use-buffer-split and prev-buff & next-buff
  77. */
  78. bool _usebuffer (bufn)
  79. char   *bufn;
  80. {
  81.     register    BUFFER * bp;
  82.     register    WINDOW * wp;
  83.  
  84.     if (strcmp (MSG_kill_b, bufn) == 0)/* hack! */
  85.         bp = blistp;
  86.     else
  87.         if ((bp = bfind (bufn, TRUE)) == NULL)
  88.             return (FALSE);
  89.  
  90.     /* if current buffer is special and new buffer is normal */
  91.     /* set to hex byte mode */
  92.     if ((curbp == blistp) && (bp != blistp))
  93.         {
  94.         dispsize1 ();
  95.         hexmode (); 
  96.         }
  97.         
  98.     if (--curbp -> b_nwnd == 0)
  99.         {
  100.         /* Last use.         */
  101.         curbp -> b_dotp = curwp -> w_dotp;
  102.         curbp -> b_doto = curwp -> w_doto;
  103.         curbp -> b_unit_offset = curwp -> w_unit_offset;/* pvr */
  104.         curbp -> b_markp = curwp -> w_markp;
  105.         curbp -> b_marko = curwp -> w_marko;
  106.         }
  107.     curbp = bp;                 /* Switch.       */
  108.     curwp -> w_bufp = bp;
  109.     curwp -> w_linep = bp -> b_linep;/* For macros, ignored.     */
  110.     curwp -> w_loff = 0; /* pvr */
  111.     curwp -> w_flag |= WFMODE | WFFORCE | WFHARD;
  112.     /* Quite nasty.      */
  113.     if (bp -> b_nwnd++ == 0)
  114.         {
  115.         /* First use.        */
  116.         curwp -> w_dotp = bp -> b_dotp;
  117.         curwp -> w_doto = bp -> b_doto;
  118.         curwp -> w_unit_offset = 0;     /* pvr */
  119.         curwp -> w_markp = bp -> b_markp;
  120.         curwp -> w_marko = bp -> b_marko;
  121.         wind_on_dot (curwp);
  122.         /* if we are in the funny TEXT mode then goto standard HEX mode */
  123.         if (R_TYPE(curwp) == TEXT)
  124.             hexmode ();
  125.         return (TRUE);
  126.         }
  127.     wp = wheadp;                /* Look for old.     */
  128.     while (wp != NULL)
  129.         {
  130.         if (wp != curwp && wp -> w_bufp == bp)
  131.             {
  132.             curwp -> w_dotp = wp -> w_dotp;
  133.             curwp -> w_doto = wp -> w_doto;
  134.             curwp -> w_unit_offset = wp -> w_unit_offset;/* pvr */
  135.             curwp -> w_markp = wp -> w_markp;
  136.             curwp -> w_marko = wp -> w_marko;
  137.             break;
  138.             }
  139.         wp = wp -> w_wndp;
  140.         }
  141.     wind_on_dot (curwp);
  142.     /* if we are in the funny TEXT mode then goto standard HEX mode */
  143.     if (R_TYPE(curwp) == TEXT)
  144.         hexmode ();
  145.     return (TRUE);
  146. }
  147.  
  148.  
  149. /*
  150. * Dispose of a buffer, by name.
  151. * Ask for the name. Look it up (don't get too
  152. * upset if it isn't there at all!). Get quite upset
  153. * if the buffer is being displayed. Clear the buffer (ask
  154. * if the buffer has been changed). Then free the header
  155. * line and the buffer header. Bound to "C-X K".
  156. */
  157. char    killbuffer ()
  158. {
  159.     register char   s;
  160.     char    bufn[NBUFN];
  161.  
  162.     if ((s = ereply (MSG_kill_b, bufn, NBUFN, 0)) != TRUE)
  163.         return (s);
  164.     if (s = _killbuffer (bufn))
  165.         writ_echo (okmsg);             /* verbose-ness (jam) */
  166.     return (s);
  167. }
  168.  
  169.  
  170. char    _killbuffer (bufn)
  171. char   *bufn;
  172. {
  173.     register    BUFFER * bp,
  174.                *bp1,
  175.                *bp2;
  176.     register char   s,
  177.                     x = 0;
  178.  
  179.     if ((bp = bfind (bufn, FALSE)) == NULL)
  180.         {
  181.         writ_echo (MSG_not_fnd);
  182.         return (FALSE);
  183.         }
  184.  
  185.  
  186.     if (killablebufs (bp))      /* can't kill '?' if no other buffers */
  187.         {
  188.         writ_echo (MSG_no_del_m);
  189.         return (FALSE);
  190.         }
  191.  
  192.  /* see if the buffer to be killed is in a window */
  193.     bp1 = bp;
  194.     if (curbp == blistp && onebuf (bp))/* Hack ! */
  195.         {
  196.         next_buf ();
  197.         onlywind ();
  198.         update ();
  199.         }
  200.  
  201.     if (bp -> b_nwnd > 0)
  202.         {
  203.         if ((s = eyesno (MSG_buf_disp)) != TRUE)
  204.             return (s);
  205.  
  206.     /* make the current window the only window if it is to die */
  207.         onlywind ();
  208.         if (curbp == bp)
  209.             {
  210.             next_buf ();
  211.             if (curbp == bp)
  212.                 x++;
  213.             }
  214.         }
  215.     if ((s = bclear (bp)) != TRUE)/* Blow text away.      */
  216.         {
  217.         if (bp1 == blistp)      /* special buffer */
  218.             curbp = bp1;
  219.         else
  220.             if (!x)
  221.                 _usebuffer (bp1 -> b_bname);
  222.     /* back to original buffer (jam) */
  223.         return (s);
  224.         }
  225.     if (x)
  226.         {
  227.         _usebuffer (MSG_main);
  228.         x++;
  229.         }
  230.  
  231.     free ((char *) bp -> b_linep);/* Release header line.         */
  232.     bp1 = NULL;                 /* Find the header.     */
  233.     bp2 = bheadp;
  234.     while (bp2 != bp)
  235.         {
  236.         bp1 = bp2;
  237.         bp2 = bp2 -> b_bufp;
  238.         }
  239.     bp2 = bp2 -> b_bufp;        /* Next one in chain.   */
  240.     if (bp1 == NULL)            /* Unlink it.           */
  241.         bheadp = bp2;
  242.     else
  243.         bp1 -> b_bufp = bp2;
  244.     free ((char *) bp);         /* Release buffer block         */
  245.     if (x)
  246.         update ();
  247.     if (blistp -> b_nwnd != 0)  /* update buffer display */
  248.         listbuffers ();
  249.     return (TRUE);
  250. }
  251.  
  252.  
  253. /*
  254. * Display the buffer list. This is done
  255. * in two parts. The "makelist" routine figures out
  256. * the text, and puts it in the buffer whoses header is
  257. * pointed to by the external "blistp". The "popblist"
  258. * then pops the data onto the screen. Bound to
  259. * "C-X C-B".
  260. */
  261. char    listbuffers ()
  262. {
  263.     register char   s;
  264.  
  265.     if ((s = makelist ()) != TRUE)
  266.         return (s);
  267.     return (popblist ());
  268. }
  269.  
  270. /*
  271. * Pop the special buffer whose
  272. * buffer header is pointed to by the external
  273. * variable "blistp" onto the screen. This is used
  274. * by the "listbuffers" routine (above) and by
  275. * some other packages. Returns a status.
  276. */
  277. bool popblist ()
  278. {
  279.     register    WINDOW * wp;
  280.     register    BUFFER * bp;
  281.  
  282.     if (blistp -> b_nwnd == 0)  /* Not on screen yet.    */
  283.         {
  284.         if ((wp = wpopup ()) == NULL)
  285.             return (FALSE);
  286.         bp = wp -> w_bufp;
  287.         if (--bp -> b_nwnd == 0)
  288.             {
  289.             bp -> b_dotp = wp -> w_dotp;
  290.             bp -> b_doto = wp -> w_doto;
  291.             bp -> b_unit_offset = wp -> w_unit_offset;/* pvr */
  292.             bp -> b_markp = wp -> w_markp;
  293.             bp -> b_marko = wp -> w_marko;
  294.             }
  295.         wp -> w_bufp = blistp;
  296.         ++blistp -> b_nwnd;
  297.         }
  298.     wp = wheadp;
  299.     while (wp != NULL)
  300.         {
  301.         if (wp -> w_bufp == blistp)
  302.             {
  303.             wp -> w_linep = lforw (blistp -> b_linep);
  304.             wp -> w_loff = 0;
  305.             wp -> w_dotp = lforw (blistp -> b_linep);
  306.             wp -> w_doto = 0;
  307.             wp -> w_unit_offset = 0;
  308.             wp -> w_markp = NULL;
  309.             wp -> w_marko = 0;
  310.             wp -> w_disp_shift = 0;
  311.             wp -> w_intel_mode = FALSE;
  312.             wp -> w_fmt_ptr = &text_fmt;
  313.             wp -> w_flag |= WFMODE | WFHARD;
  314.             }
  315.         wp = wp -> w_wndp;
  316.         }
  317.     return (TRUE);
  318. }
  319.  
  320. /*
  321. * This routine rebuilds the
  322. * text in the special secret buffer
  323. * that holds the buffer list. It is called
  324. * by the list buffers command. Return TRUE
  325. * if everything works. Return FALSE if there
  326. * is an error (if there is no memory).
  327. */
  328. char    makelist ()
  329. {
  330.     register    char  *cp1;
  331.     register    char  *cp2;
  332.     register    int    c;
  333.     register    BUFFER * bp;
  334.     register    LINE * lp;
  335.     register    long   nbytes;
  336.     register    char   s;
  337.     char    b[6 + 1];
  338.     char    line[128];
  339.  
  340.     blistp -> b_flag &= ~BFCHG; /* Blow away old.    */
  341.     if ((s = bclear (blistp)) != TRUE)
  342.         return (s);
  343.     blistp -> b_flag |= BFVIEW;
  344.     strcpy (blistp -> b_fname, MSG_up_arrow);
  345.     if (addline (MSG_l_buf_h) == FALSE
  346.             || addline (MSG_l_buf_h1) == FALSE)
  347.         return (FALSE);
  348.     bp = bheadp;                /* For all buffers   */
  349.     while (bp != NULL)
  350.         {
  351.         cp1 = &line[0];         /* Start at left edge    */
  352.         if ((bp -> b_flag & BFCHG) != 0)/* "*" if changed    */
  353.             *cp1++ = '*';
  354.         else
  355.             if (bp -> b_flag & BFVIEW)/* jam */
  356.                 *cp1++ = 'R';   /* readonly */
  357.             else
  358.                 *cp1++ = ' ';
  359.         *cp1++ = ' ';           /* Gap. */
  360.         if ((bp -> b_flag & BFBAD) != 0)/* "?" if maybe trashed  */
  361.             *cp1++ = '?';
  362.         else
  363.             *cp1++ = ' ';
  364.         *cp1++ = ' ';           /* Gap. */
  365.         nbytes = bp -> b_linep -> l_bp -> l_file_offset +
  366.                     bp -> b_linep -> l_bp -> l_used;
  367.         i_to_a (b, 6, (long) nbytes);/* 6 digit buffer size.   */
  368.         cp2 = &b[0];
  369.         while ((c = *cp2++) != 0)
  370.             *cp1++ = c;
  371.         *cp1++ = ' ';           /* Gap.          */
  372.         cp2 = &bp -> b_bname[0];/* Buffer name       */
  373.         while ((c = *cp2++) != 0)
  374.             *cp1++ = c;
  375.         *cp1++ = ' ';           /* Gap.          */
  376.         *cp1++ = ' ';           /* Gap.          */
  377.         cp2 = &bp -> b_fname[0];/* File name         */
  378.         if (*cp2 != 0)
  379.             {
  380.             while (cp1 < &line[1 + 1 + 1 + 1 + 6 + 1 + NBUFN + 1])
  381.                 *cp1++ = ' ';
  382.             while ((c = *cp2++) != 0)
  383.                 {
  384.                 if (cp1 < &line[128 - 1])
  385.                     *cp1++ = c;
  386.                 }
  387.             }
  388.         while (cp1 < &line[80])   /* Fill out line to col 80 */
  389.             *cp1++ = ' ';
  390.  
  391.         *cp1 = 0;               /* Add to the buffer.    */
  392.         if (addline (line) == FALSE)
  393.             return (FALSE);
  394.         bp = bp -> b_bufp;
  395.         }
  396.     return (TRUE);              /* All done      */
  397. }
  398.  
  399.  
  400. /*
  401. * Used above.
  402. */
  403. void i_to_a (buf, width, num)
  404. register char   buf[];
  405. register int    width;
  406. register long   num;
  407. {
  408.     buf[width] = 0;             /* End of string.    */
  409.     while (num >= 10)
  410.         {
  411.     /* Conditional digits.   */
  412.         buf[--width] = (num % 10) + '0';
  413.         num /= 10;
  414.         }
  415.     buf[--width] = num + '0';   /* Always 1 digit.   */
  416.     while (width != 0)          /* Pad with blanks.  */
  417.         buf[--width] = ' ';
  418. }
  419.  
  420.  
  421. /*
  422. * The argument "text" points to
  423. * a string. Append this line to the
  424. * buffer list buffer. 
  425. * Return TRUE if it worked and
  426. * FALSE if you ran out of room.
  427. */
  428. bool addline (text)
  429. char   *text;
  430. {
  431.     register    LINE    * lp;
  432.     register    int     i, allocsize;
  433.     register    int     ntext;
  434.  
  435.     ntext = strlen (text);
  436.     allocsize = 128;
  437.  
  438.     if ((lp = lalloc (allocsize)) == NULL)
  439.         return (FALSE);
  440.  
  441.     for (i = 0; i < ntext; ++i)
  442.         lputc (lp, i, text[i]);
  443.  
  444.     for (; i < allocsize; ++i)     /* fill out line with spaces */
  445.         lputc (lp, i, ' ');
  446.  
  447.     blistp -> b_linep -> l_bp -> l_fp = lp;/* Hook onto the end  */
  448.     lp -> l_bp = blistp -> b_linep -> l_bp;
  449.     blistp -> b_linep -> l_bp = lp;
  450.     lp -> l_fp = blistp -> b_linep;
  451.     lp -> l_size = allocsize;  /* line size is limited to 80 chars */
  452.     lp -> l_used = allocsize;
  453.     lp -> l_file_offset = lp -> l_bp -> l_file_offset + lp -> l_bp -> l_used;
  454.     if (blistp -> b_dotp == blistp -> b_linep)/* If "." is at the end    */
  455.         blistp -> b_dotp = lp;  /* move it to new line   */
  456.     return (TRUE);
  457. }
  458.  
  459.  
  460. /*
  461. * Look through the list of
  462. * buffers. Return TRUE if there
  463. * are any changed buffers. Special buffers
  464. * like the buffer list buffer don't count, as
  465. * they are not in the list. Return FALSE if
  466. * there are no changed buffers.
  467. */
  468. bool anycb ()
  469. {
  470.     register    BUFFER * bp;
  471.  
  472.     bp = bheadp;
  473.     while (bp != NULL)
  474.         {
  475.  
  476.         if ((bp -> b_flag & BFCHG) != 0)
  477.             return (TRUE);
  478.         bp = bp -> b_bufp;
  479.         }
  480.     return (FALSE);
  481. }
  482.  
  483.  
  484. /*
  485. * Search for a buffer, by name.
  486. * If not found, and the "cflag" is TRUE,
  487. * create a buffer and put it in the list of
  488. * all buffers. Return pointer to the BUFFER
  489. * block for the buffer.
  490. */
  491. BUFFER * bfind (bname, cflag)
  492. register char  *bname;
  493. {
  494.     register    BUFFER * bp;
  495.  
  496.     bp = bheadp;
  497.     while (bp != NULL)
  498.         {
  499.         if (strcmp (bname, bp -> b_bname) == 0)
  500.             return (bp);
  501.         bp = bp -> b_bufp;
  502.         }
  503.     if (cflag != FALSE && (bp = bcreate (bname)) != NULL)
  504.         {
  505.         bp -> b_bufp = bheadp;
  506.         bheadp = bp;
  507.         }
  508.     return (bp);
  509. }
  510.  
  511.  
  512. /*
  513. * Create a buffer, by name.
  514. * Return a pointer to the BUFFER header
  515. * block, or NULL if the buffer cannot
  516. * be created. The BUFFER is not put in the
  517. * list of all buffers; this is called by
  518. * "edinit" to create the buffer list
  519. * buffer.
  520. */
  521. BUFFER * bcreate (bname)
  522. register char  *bname;
  523. {
  524.  
  525.     register    BUFFER * bp;
  526.     register    LINE * lp;
  527.  
  528.     if ((bp = (BUFFER *) malloc (sizeof (BUFFER))) == NULL)
  529.         return (NULL);
  530.     if ((lp = lalloc (0)) == NULL)
  531.         {
  532.         free ((char *) bp);
  533.         return (NULL);
  534.         }
  535.     bp -> b_bufp = NULL;
  536.     bp -> b_dotp = lp;
  537.     bp -> b_doto = 0;
  538.     bp -> b_unit_offset = 0;    /* unit offset   pvr */
  539.     bp -> b_markp = NULL;
  540.     bp -> b_marko = 0;
  541.     bp -> b_flag = 0;
  542.     bp -> b_nwnd = 0;
  543.     bp -> b_linep = lp;
  544.     strcpy (bp -> b_fname, MSG_null);
  545.     strcpy (bp -> b_bname, bname);
  546.     lp -> l_fp = lp;
  547.     lp -> l_bp = lp;
  548.     lp -> l_file_offset = 0;    /* pvr */
  549.     lp -> l_used = 0;           /* pvr */
  550.     lp -> l_size = 0;           /* size of zero indicates the header line  pvr 
  551.                                 */
  552.     return (bp);
  553. }
  554.  
  555.  
  556. /*
  557. * This routine blows away all of the text
  558. * in a buffer. If the buffer is marked as changed
  559. * then we ask if it is ok to blow it away; this is
  560. * to save the user the grief of losing text. The
  561. * window chain is nearly always wrong if this gets
  562. * called; the caller must arrange for the updates
  563. * that are required. Return TRUE if everything
  564. * looks good.
  565. */
  566. bool bclear (bp)
  567. register    BUFFER * bp;
  568. {
  569.     register    LINE * lp;
  570.     register char   s;
  571.  
  572.     if ((bp -> b_flag & BFCHG) != 0/* Changed.       */
  573.             && (s = eyesno (MSG_no_chg)) != TRUE)
  574.         return (s);
  575.     bp -> b_flag &= ~BFCHG;     /* Not changed       */
  576.     while ((lp = lforw (bp -> b_linep)) != bp -> b_linep)
  577.         lfree (lp);
  578.     bp -> b_dotp = bp -> b_linep;/* Fix "."      */
  579.     bp -> b_doto = 0;
  580.     bp -> b_unit_offset = 0;    /* pvr */
  581.     bp -> b_markp = NULL;       /* Invalidate mark  */
  582.     bp -> b_marko = 0;
  583.     return (TRUE);
  584. }
  585.  
  586.  
  587. /* flip to next buffer in the list, wrap
  588. * to beginning if required (wrap around)
  589. * (skips buffers saved  by save-region)  
  590. */
  591. char    next_buf ()
  592. {
  593.     register    BUFFER * bp;
  594.  
  595.     bp = curbp;
  596.     while (TRUE)
  597.         {
  598.         if (!(bp = bp -> b_bufp))
  599.             bp = bheadp;
  600.         if (!(bp -> b_flag & BFSAV))/* skip save-region buffers */
  601.             break;
  602.         }
  603.     _usebuffer (bp -> b_bname);
  604. }
  605.  
  606.  
  607. /* flip to prev buffer in the list, wrap
  608. * to end if required (wrap around)
  609. * (does NOT skip buffers saved by save-region)  
  610. */
  611. char    prev_buf ()
  612. {
  613.     register    BUFFER * sp;
  614.  
  615.     if ((sp = curbp) == bheadp) /* front of list */
  616.         for (; sp -> b_bufp; sp = sp -> b_bufp)
  617.             ;
  618.     else                        /* cycle around */
  619.         for (sp = bheadp; sp -> b_bufp; sp = sp -> b_bufp)
  620.             if (sp -> b_bufp == curbp)
  621.                 break;
  622.     return (_usebuffer (sp -> b_bname));
  623. }
  624.  
  625.  
  626. /* yank a buffer into current buffer
  627. */
  628. char    yank_buffer ()
  629. {
  630.     register    LINE * lp;
  631.     register    BUFFER * bp = curbp;
  632.     register char   s;
  633.     char    bufn[NBUFN];
  634.  
  635.     if ((s = ereply (MSG_yank_b, bufn, NBUFN, 0)) != TRUE)
  636.         return (FALSE);
  637.     return (_yankbuffer (bufn));
  638. }
  639.  
  640.  
  641. bool _yankbuffer (bufn)
  642. char   *bufn;
  643. {
  644.     register    LINE * lp;
  645.     register    BUFFER * bp = curbp;
  646.     register int    s;
  647.  
  648.     if ((bp = bfind (bufn, FALSE)) == NULL)
  649.         {
  650.         writ_echo (MSG_no_buf);
  651.         return (FALSE);
  652.         }
  653.     if (strcmp (bp -> b_bname, curbp -> b_bname) == 0)
  654.         {
  655.         writ_echo (MSG_no_s_yank);
  656.         return (FALSE);
  657.         }
  658.     lp = lforw (bp -> b_linep);
  659.     while (TRUE)
  660.         {
  661.         for (s = 0; s < lp -> l_used; s++)
  662.             linsert (1, lp -> l_text[s]);
  663.  
  664.         if ((lp = lforw (lp)) == bp -> b_linep)
  665.             {
  666.             break;
  667.             }
  668.         lp = lp -> l_fp;    /* step to next line */
  669.         }
  670.     writ_echo (okmsg);
  671.     return (TRUE);
  672. }
  673.  
  674.  
  675. bool buffername ()
  676. {
  677.  
  678.     register    WINDOW * wp;
  679.     register char  *p;
  680.     register char   s;
  681.     char    bname[NBUFN + 1];
  682.  
  683.     if ((s = ereply (MSG_buf_nam, bname, NBUFN, 0)) == ABORT)
  684.         return (s);
  685.     for (p = bname; *p && *p != ' '; p++)
  686.         ;
  687.     *p = 0;                     /* no blanks */
  688.     strcpy (curbp -> b_bname, bname);
  689.     wp = wheadp;                /* Update mode lines.   */
  690.     while (wp != NULL)
  691.         {
  692.         if (wp -> w_bufp == curbp)
  693.             wp -> w_flag |= WFMODE;
  694.         wp = wp -> w_wndp;
  695.         }
  696.     if (blistp -> b_nwnd != 0)  /* update buffer display */
  697.         listbuffers ();
  698.     return (TRUE);
  699. }
  700.  
  701.  
  702. /* any killable buffers around ? (jam)
  703. */
  704. bool killablebufs (bp)
  705. register    BUFFER * bp;
  706. {
  707.     if (strcmp (bp -> b_bname, MSG_main) == 0)/* doomed buffer is 'empty' */
  708.         if (bheadp == bp)       /* and is only buffer in list */
  709.             if (bheadp -> b_bufp == 0)/* then there are no killable buffers */
  710.                 return (TRUE);
  711.     return (FALSE);
  712. }
  713.  
  714.  
  715. /* only 1 buffer around ?
  716. */
  717. bool onebuf (bp)
  718. register    BUFFER * bp;
  719. {
  720.     if (strcmp (bp -> b_bname, bheadp -> b_bname) == 0)
  721.         if (bheadp -> b_bufp == 0)
  722.             return (TRUE);
  723.     return (FALSE);
  724. }
  725.  
  726.  
  727. /* funky new name; real yukky!!!! (jam) 
  728. */
  729. void funky_name (bname, n)
  730. register char  *bname;
  731. int     n;
  732. {
  733.     char    num[10];
  734.     register int    i;
  735.     register char  *p;
  736.  
  737.     for (i = 0; i < 10; i++)
  738.         num[i] = ' ';
  739.     for (p = bname; *p; p++)
  740.         *p = 0;
  741.     *bname++ = '#';
  742.     i_to_a (num, 6, (long) n + 1);
  743.     for (p = num; *p; p++)
  744.         if (*p != ' ')
  745.             *bname++ = *p;
  746.     *bname = 0;
  747. }
  748.  
  749.  
  750. /* pick a buffer to goto/kill
  751. */
  752. #define BUFFEROFFSET (11)       /* depends on makelist !! */
  753.  
  754. bool pickone ()
  755. {
  756.     register int    s,
  757.                     i,
  758.                     c;
  759.     register char  *p;
  760.     register    LINE * lp;
  761.     char    name[NBUFN + 1];
  762.     char    buf[3];
  763.  
  764.     lp = curwp -> w_dotp;       /* get the buffer name from the line */
  765.  
  766.     i = 0;
  767.     if (!llength (lp))
  768.         {
  769.         writ_echo (MSG_bad_l);
  770.         return (FALSE);
  771.         }
  772.     for (s = BUFFEROFFSET; (c = lgetc (lp, s)) != ' '; s++)
  773.         {
  774.         name[i++] = c;
  775.         if (s >= llength (lp))
  776.             break;
  777.         }
  778.     name[i] = 0;
  779.     if (!bfind (name, FALSE))
  780.         {
  781.         writ_echo (MSG_bad_l);
  782.         return (FALSE);
  783.         }
  784. loop: 
  785.     if ((s = ereply (MSG_pick, buf, 2, name)) != TRUE)
  786.         return (FALSE);
  787.     if (ISLOWER (buf[0]) != FALSE)
  788.         buf[0] = TOUPPER (buf[0]);
  789.     if (buf[0] == 'K')
  790.         _killbuffer (name);
  791.     else
  792.         if (buf[0] == 'G')
  793.             _usebuffer (name);
  794.         else
  795.             if (buf[0] == 'S')
  796.                 {
  797.                 _usebuffer (name);
  798.             /* goto this buffer, but don't show the user */
  799.                 filesave ();
  800.                 _usebuffer (MSG_kill_b);
  801.             /* jump back to this window - HACK ! */
  802.                 listbuffers (); /* update the list */
  803.                 }
  804.             else
  805.                 goto loop;
  806.     writ_echo (MSG_null);
  807.     return (TRUE);
  808. }
  809. /*
  810. *   Toggle the buffer size lock bit.
  811. */
  812. char bufsizlock ()
  813. {
  814.     if (curbp -> b_flag & BFSLOCK)
  815.     {
  816.         curbp -> b_flag &= ~BFSLOCK;
  817.         writ_echo (MSG_siz_chg);
  818.     }
  819.     else
  820.     {
  821.         if (insert_mode)
  822.             insert_toggle ();
  823.         curbp -> b_flag |= BFSLOCK;
  824.         writ_echo (MSG_no_siz_chg);
  825.     }
  826.     return (TRUE);
  827. }
  828.