home *** CD-ROM | disk | FTP | other *** search
/ vsiftp.vmssoftware.com / VSIPUBLIC@vsiftp.vmssoftware.com.tar / FREEWARE / FREEWARE40.ZIP / pine / pico / buffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-06  |  16.0 KB  |  422 lines

  1. #if    !defined(lint) && !defined(DOS)
  2. static char rcsid[] = "$Id: buffer.c,v 4.5 1993/08/02 20:27:19 mikes Exp $";
  3. #endif
  4. /*
  5.  * Program:    Buffer management routines
  6.  *
  7.  *
  8.  * Michael Seibel
  9.  * Networks and Distributed Computing
  10.  * Computing and Communications
  11.  * University of Washington
  12.  * Administration Builiding, AG-44
  13.  * Seattle, Washington, 98195, USA
  14.  * Internet: mikes@cac.washington.edu
  15.  *
  16.  * Please address all bugs and comments to "pine-bugs@cac.washington.edu"
  17.  *
  18.  * Copyright 1991-1993  University of Washington
  19.  *
  20.  *  Permission to use, copy, modify, and distribute this software and its
  21.  * documentation for any purpose and without fee to the University of
  22.  * Washington is hereby granted, provided that the above copyright notice
  23.  * appears in all copies and that both the above copyright notice and this
  24.  * permission notice appear in supporting documentation, and that the name
  25.  * of the University of Washington not be used in advertising or publicity
  26.  * pertaining to distribution of the software without specific, written
  27.  * prior permission.  This software is made available "as is", and
  28.  * THE UNIVERSITY OF WASHINGTON DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED,
  29.  * WITH REGARD TO THIS SOFTWARE, INCLUDING WITHOUT LIMITATION ALL IMPLIED
  30.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, AND IN
  31.  * NO EVENT SHALL THE UNIVERSITY OF WASHINGTON BE LIABLE FOR ANY SPECIAL,
  32.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  33.  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, TORT
  34.  * (INCLUDING NEGLIGENCE) OR STRICT LIABILITY, ARISING OUT OF OR IN CONNECTION
  35.  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  36.  *
  37.  * Pine and Pico are trademarks of the University of Washington.
  38.  * No commercial use of these trademarks may be made without prior
  39.  * written permission of the University of Washington.
  40.  *
  41.  */
  42. /*
  43.  * Buffer management.
  44.  * Some of the functions are internal,
  45.  * and some are actually attached to user
  46.  * keys. Like everyone else, they set hints
  47.  * for the display system.
  48.  */
  49. #include        <stdio.h>
  50. #include    "osdep.h"
  51. #include    "estruct.h"
  52. #include        "pico.h"
  53. #include        "edef.h"
  54. #ifdef HEBREW
  55. #include "hebrew.h"
  56. #endif
  57.  
  58. #ifdef    ANSI
  59. int zotbuf(struct BUFFER *);
  60. int sgetline(char **, int *, char *, int);
  61. #else
  62. int zotbuf();
  63. int sgetline();
  64. #endif
  65.  
  66.  
  67. zotbuf(bp)    /* kill the buffer pointed to by bp */
  68.   register BUFFER *bp;
  69. {
  70.     register BUFFER *bp1;
  71.     register BUFFER *bp2;
  72.     register int    s;
  73.  
  74.         if (bp->b_nwnd != 0) {                  /* Error if on screen.  */
  75.                 mlwrite("Buffer is being displayed");
  76.                 return (FALSE);
  77.         }
  78.         if ((s=bclear(bp)) != TRUE)             /* Blow text away.      */
  79.                 return (s);
  80.         free((char *) bp->b_linep);             /* Release header line. */
  81.         bp1 = NULL;                             /* Find the header.     */
  82.         bp2 = bheadp;
  83.         while (bp2 != bp) {
  84.                 bp1 = bp2;
  85.                 bp2 = bp2->b_bufp;
  86.         }
  87.         bp2 = bp2->b_bufp;                      /* Next one in chain.   */
  88.         if (bp1 == NULL)                        /* Unlink it.           */
  89.                 bheadp = bp2;
  90.         else
  91.                 bp1->b_bufp = bp2;
  92.         free((char *) bp);                      /* Release buffer block */
  93.         return (TRUE);
  94. }
  95.  
  96.  
  97.  
  98. /*
  99.  * Look through the list of
  100.  * buffers. Return TRUE if there
  101.  * are any changed buffers. Buffers
  102.  * that hold magic internal stuff are
  103.  * not considered; who cares if the
  104.  * list of buffer names is hacked.
  105.  * Return FALSE if no buffers
  106.  * have been changed.
  107.  */
  108. anycb()
  109. {
  110.         register BUFFER *bp;
  111.  
  112.         bp = bheadp;
  113.         while (bp != NULL) {
  114.                 if ((bp->b_flag&BFTEMP)==0 && (bp->b_flag&BFCHG)!=0)
  115.                         return (TRUE);
  116.                 bp = bp->b_bufp;
  117.         }
  118.         return (FALSE);
  119. }
  120.  
  121. /*
  122.  * Find a buffer, by name. Return a pointer
  123.  * to the BUFFER structure associated with it. If
  124.  * the named buffer is found, but is a TEMP buffer (like
  125.  * the buffer list) conplain. If the buffer is not found
  126.  * and the "cflag" is TRUE, create it. The "bflag" is
  127.  * the settings for the flags in in buffer.
  128.  */
  129. BUFFER  *
  130. bfind(bname, cflag, bflag)
  131. register char   *bname;
  132. {
  133.         register BUFFER *bp;
  134.     register BUFFER *sb;    /* buffer to insert after */
  135.         register LINE   *lp;
  136.  
  137.         bp = bheadp;
  138.         while (bp != NULL) {
  139.                 if (strcmp(bname, bp->b_bname) == 0) {
  140.                         if ((bp->b_flag&BFTEMP) != 0) {
  141.                                 mlwrite("Cannot select builtin buffer");
  142.                                 return (NULL);
  143.                         }
  144.                         return (bp);
  145.                 }
  146.                 bp = bp->b_bufp;
  147.         }
  148.         if (cflag != FALSE) {
  149.                 if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL)
  150.                         return (NULL);
  151.                 if ((lp=lalloc(0)) == NULL) {
  152.                         free((char *) bp);
  153.                         return (NULL);
  154.                 }
  155.         /* find the place in the list to insert this buffer */
  156.         if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0) {
  157.             /* insert at the begining */
  158.                     bp->b_bufp = bheadp;
  159.                     bheadp = bp;
  160.             } else {
  161.             sb = bheadp;
  162.             while (sb->b_bufp != NULL) {
  163.                 if (strcmp(sb->b_bufp->b_bname, bname) > 0)
  164.                     break;
  165.                 sb = sb->b_bufp;
  166.             }
  167.  
  168.             /* and insert it */
  169.                    bp->b_bufp = sb->b_bufp;
  170.                 sb->b_bufp = bp;
  171.                }
  172.  
  173.         /* and set up the other buffer fields */
  174.         bp->b_active = TRUE;
  175.                 bp->b_dotp  = lp;
  176.                 bp->b_doto  = 0;
  177.                 bp->b_markp = NULL;
  178.                 bp->b_marko = 0;
  179.                 bp->b_flag  = bflag;
  180.         bp->b_mode  = gmode;
  181.                 bp->b_nwnd  = 0;
  182.                 bp->b_linep = lp;
  183.                 strcpy(bp->b_fname, "");
  184.                 strcpy(bp->b_bname, bname);
  185.                 lp->l_fp = lp;
  186.                 lp->l_bp = lp;
  187.         }
  188.         return (bp);
  189. }
  190.  
  191. /*
  192.  * This routine blows away all of the text
  193.  * in a buffer. If the buffer is marked as changed
  194.  * then we ask if it is ok to blow it away; this is
  195.  * to save the user the grief of losing text. The
  196.  * window chain is nearly always wrong if this gets
  197.  * called; the caller must arrange for the updates
  198.  * that are required. Return TRUE if everything
  199.  * looks good.
  200.  */
  201. bclear(bp)
  202. register BUFFER *bp;
  203. {
  204.         register LINE   *lp;
  205.         register int    s = FALSE;
  206.  
  207.     if(Pmaster){
  208.         if ((bp->b_flag&BFTEMP) == 0     /* Not scratch buffer.  */
  209.         && (bp->b_flag&BFCHG) != 0){    /* Something changed    */
  210.         emlwrite("buffer lines not freed.");
  211.         return (s);
  212.         }
  213.     }
  214.     else{
  215.         if ((bp->b_flag&BFTEMP) == 0    /* Not scratch buffer.  */
  216.         && (bp->b_flag&BFCHG) != 0    /* Something changed    */
  217.         && (s=mlyesno("Discard changes", -1)) != TRUE){
  218.         return (s);
  219.         }
  220.     }
  221.  
  222.         bp->b_flag  &= ~BFCHG;                  /* Not changed          */
  223.         while ((lp=lforw(bp->b_linep)) != bp->b_linep)
  224.                 lfree(lp);
  225.         bp->b_dotp  = bp->b_linep;              /* Fix "."              */
  226.         bp->b_doto  = 0;
  227.         bp->b_markp = NULL;                     /* Invalidate "mark"    */
  228.         bp->b_marko = 0;
  229.         return (TRUE);
  230. }
  231.  
  232.  
  233. /*
  234.  * packbuf - will pack up the main buffer in the buffer provided 
  235.  *           to be returned to the program that called pico.
  236.  *         if need be, allocate memory for the new message. 
  237.  *           will also free the memory associated with the editor
  238.  *           buffer, by calling zotedit.
  239.  */
  240. packbuf(buf, blen, lcrlf)
  241. char    **buf;
  242. int    *blen;
  243. int    lcrlf;                /* EOLs are local or CRLF */
  244. {
  245.     register int    s;
  246.     register int    i = 0;
  247.     register LINE   *lp;
  248.     register int    retval = 0;
  249.     register char   *bufp;
  250.     register char   *eobuf;
  251.  
  252.     if(anycb() != FALSE){
  253.  
  254.         lp = lforw(curbp->b_linep);
  255.         do{                    /* how many chars? */
  256.             i += llength(lp);
  257.         /*
  258.          * add extra for new lines to be inserted later
  259.          */
  260.         i += 2;
  261.         lp = lforw(lp);
  262.         }
  263.         while(lp != curbp->b_linep);
  264.  
  265.         if(i > *blen){                /* new buffer ? */
  266.             /*
  267.              * don't forget to add one for the null terminator!!!
  268.              */
  269.         if((bufp = (char *)malloc((i+1)*sizeof(char))) == NULL){
  270.                     zotedit();            /* bag it! */
  271.             return(COMP_FAILED);
  272.         }
  273.             free(*buf);
  274.         *buf = bufp;
  275.         *blen = i;
  276.         }
  277.         else{
  278.             bufp = *buf;
  279.         }
  280.     
  281.         eobuf = bufp + *blen;
  282.         lp = lforw(curbp->b_linep);             /* First line.          */
  283.         do {
  284.         for (i = 0; i < llength(lp); i++){    /* copy into buffer */
  285.             if((bufp+1) < eobuf){
  286.             *bufp++ = (lp->l_text[i].c & 0xFF);
  287.             }
  288.             else{
  289.             /*
  290.              * the idea is to malloc enough space for the new
  291.              * buffer...
  292.              */
  293.             *bufp = '\0';
  294.                     zotedit();
  295.             return(BUF_CHANGED|COMP_FAILED);
  296.             }
  297.         }
  298.         if(lcrlf){
  299.         *bufp++ = '\n';            /* EOLs use local convention */
  300.         }
  301.         else{
  302.         *bufp++ = 0x0D;            /* EOLs use net standard */
  303.         *bufp++ = 0x0A;
  304.         }
  305.             lp = lforw(lp);
  306.         }
  307.         while (lp != curbp->b_linep);
  308.     if(lcrlf)
  309.       *--bufp = '\0';
  310.     else
  311.       *bufp = '\0';
  312.         retval = BUF_CHANGED;
  313.     }
  314.  
  315.     zotedit();
  316.     return(retval);
  317. }
  318.  
  319.  
  320. /*
  321.  * readbuf - reads in a buffer.
  322.  */
  323. readbuf(buf)
  324. char    **buf;
  325. {
  326.         register LINE   *lp1;
  327.         register LINE   *lp2;
  328.         register BUFFER *bp;
  329.         register WINDOW *wp;
  330.         register int    i;
  331.         register int    s;
  332.         char   *sptr;          /* pointer into buffer string */
  333.         int        nbytes;
  334.         char            line[NLINE];
  335.     CELL            ac;
  336.  
  337.     bp = curbp;
  338.         bp->b_flag &= ~(BFTEMP|BFCHG);
  339.     sptr = *buf;
  340.     ac.a  = 0;
  341.  
  342.         while((s=sgetline(&sptr,&nbytes,line,NLINE)) == FIOSUC || s == FIOLNG){
  343.  
  344.                 if ((lp1=lalloc(nbytes)) == NULL) {
  345.                         s = FIOERR;             /* Keep message on the  */
  346.                         break;                  /* display.             */
  347.                 }
  348.                 lp2 = lback(curbp->b_linep);
  349.                 lp2->l_fp = lp1;
  350.                 lp1->l_fp = curbp->b_linep;
  351.                 lp1->l_bp = lp2;
  352.                 curbp->b_linep->l_bp = lp1;
  353. #ifdef HEBREW
  354.         lp1->l_type=L_ENG;
  355. #endif
  356.                 for (i=0; i<nbytes; ++i){
  357.             ac.c = line[i];
  358.             lputc(lp1, i, ac);
  359.         }
  360.         }
  361.  
  362.         for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
  363.                 if (wp->w_bufp == curbp) {
  364.                         wheadp->w_linep = lforw(curbp->b_linep);
  365.                         wheadp->w_dotp  = lback(curbp->b_linep);
  366.                         wheadp->w_doto  = 0;
  367.                         wheadp->w_markp = NULL;
  368.                         wheadp->w_marko = 0;
  369.                         wheadp->w_flag |= WFHARD;
  370.                 }
  371.         }
  372.  
  373.     strcpy(bp->b_bname, "main");
  374.     strcpy(bp->b_fname, "");
  375.  
  376.     bp->b_dotp = bp->b_linep;
  377.     bp->b_doto = 0;
  378. }
  379.  
  380.  
  381. /*
  382.  * sgetline - copy characters from ibuf to obuf, ending at the first 
  383.  *            newline.  return with ibuf pointing to first char after
  384.  *            newline.
  385.  */
  386. sgetline(ibuf, nchars, obuf, blen)
  387. char    **ibuf;
  388. int    *nchars;
  389. char    *obuf;
  390. int    blen;
  391. {
  392.     register char     *len;
  393.     register char     *cbuf = *ibuf;
  394.     register char     *bufp = obuf;
  395.     register int     retval = FIOSUC;
  396. #define CR '\015'
  397. #define LF '\012'
  398.  
  399.     *nchars = 0;
  400.     if(*cbuf == '\0'){
  401.     retval = FIOEOF;
  402.     }
  403.     else{
  404.     len = obuf + blen;
  405.     while (*cbuf != CR && *cbuf != LF && *cbuf != '\0'){
  406.         if(bufp < len){
  407.         *bufp++ = *cbuf++;
  408.         (*nchars)++;
  409.         }
  410.         else{
  411.         *bufp = '\0';
  412.         retval = FIOLNG;
  413.         break;
  414.         }
  415.     }
  416.     }
  417.     *bufp = '\0';            /* end retured line */
  418.     *ibuf = (*cbuf == CR) ? ++cbuf : cbuf;
  419.     *ibuf = (*cbuf == LF) ? ++cbuf : cbuf;
  420.     return(retval);
  421. }