[BACK]Return to line.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

Diff for /src/usr.bin/mg/line.c between version 1.3 and 1.4

version 1.3, 2000/04/13 06:12:15 version 1.4, 2000/09/01 14:59:09
Line 1 
Line 1 
 /*  /*
  *              Text line handling.   *              Text line handling.
  * The functions in this file   *
  * are a general set of line management   * The functions in this file are a general set of line management
  * utilities. They are the only routines that   * utilities. They are the only routines that touch the text. They
  * touch the text. They also touch the buffer   * also touch the buffer and window structures to make sure that the
  * and window structures, to make sure that the   * necessary updating gets done.  There are routines in this file that
  * necessary updating gets done. There are routines   * handle the kill buffer too.  It isn't here for any good reason.
  * in this file that handle the kill buffer too.  
  * It isn't here for any good reason.  
  *   *
  * Note that this code only updates the dot and   * Note that this code only updates the dot and mark values in the window
  * mark values in the window list. Since all the code   * list.  Since all the code acts on the current window, the buffer that
  * acts on the current window, the buffer that we   * we are editing must be displayed, which means that "b_nwnd" is non-zero,
  * are editing must be being displayed, which means   * which means that the dot and mark values in the buffer headers are
  * that "b_nwnd" is non zero, which means that the  
  * dot and mark values in the buffer headers are  
  * nonsense.   * nonsense.
  */   */
 #include        "def.h"  
   
 /* number of bytes member is from start of structure type        */  #include "def.h"
 /* should be computed at compile time                            */  
   
   /*
    * The number of bytes member from the start of the structure type should be
    * computed at compile time.
    */
   
 #ifndef OFFSET  #ifndef OFFSET
 #define OFFSET(type,member) ((char *)&(((type *)0)->member)-(char *)((type *)0))  #define OFFSET(type,member) ((char *)&(((type *)0)->member)-(char *)((type *)0))
 #endif  #endif
Line 34 
Line 33 
 #define KBLOCK  256             /* Kill buffer block size.       */  #define KBLOCK  256             /* Kill buffer block size.       */
 #endif  #endif
   
 static char    *kbufp = NULL;   /* Kill buffer data.             */  static char     *kbufp = NULL;  /* Kill buffer data.             */
 static RSIZE    kused = 0;      /* # of bytes used in KB.        */  static RSIZE     kused = 0;     /* # of bytes used in KB.        */
 static RSIZE    ksize = 0;      /* # of bytes allocated in KB.   */  static RSIZE     ksize = 0;     /* # of bytes allocated in KB.   */
 static RSIZE    kstart = 0;     /* # of first used byte in KB.   */  static RSIZE     kstart = 0;    /* # of first used byte in KB.   */
   
   static int       kgrow          __P((int));
   
 /*  /*
  * This routine allocates a block of memory large enough to hold a LINE   * This routine allocates a block of memory large enough to hold a LINE
  * containing "used" characters. The block is rounded up to whatever   * containing "used" characters. The block is rounded up to whatever
  * needs to be allocated. (use lallocx for lines likely to grow.)   * needs to be allocated. (use lallocx for lines likely to grow.)
  * Return a pointer to the new block, or NULL if there isn't   * Return a pointer to the new block, or NULL if there isn't any memory
  * any memory left. Print a message in the message line if no space.   * left. Print a message in the message line if no space.
  */   */
 LINE *  LINE *
 lalloc(used)  lalloc(used)
         int    used;          int used;
 {  {
         LINE  *lp;          LINE    *lp;
         int    size;          int      size;
   
         /* any padding at the end of the structure is used */          /* any padding at the end of the structure is used */
         if ((size = used + OFFSET(LINE, l_text[0])) < sizeof(LINE))          if ((size = used + OFFSET(LINE, l_text[0])) < sizeof(LINE))
                 size = sizeof(LINE);              size = sizeof(LINE);
 #ifdef MALLOCROUND  #ifdef MALLOCROUND
         MALLOCROUND(size);      /* round up to a size optimal to malloc */          MALLOCROUND(size);      /* round up to a size optimal to malloc */
 #endif  #endif
         if ((lp = (LINE *) malloc((unsigned) size)) == NULL) {          if ((lp = (LINE *)malloc((unsigned)size)) == NULL) {
                 ewprintf("Can't get %d bytes", size);                  ewprintf("Can't get %d bytes", size);
                 return (LINE *) NULL;                  return (LINE *)NULL;
         }          }
         lp->l_size = size - OFFSET(LINE, l_text[0]);          lp->l_size = size - OFFSET(LINE, l_text[0]);
         lp->l_used = used;          lp->l_used = used;
Line 75 
Line 76 
  */   */
 LINE *  LINE *
 lallocx(used)  lallocx(used)
         int    used;          int used;
 {  {
         int    size;          int      size;
         LINE  *lp;          LINE    *lp;
   
         size = (NBLOCK + used) & ~(NBLOCK - 1);          size = (NBLOCK + used) & ~(NBLOCK - 1);
         if ((lp = lalloc(size)) != NULL)          if ((lp = lalloc(size)) != NULL)
Line 87 
Line 88 
 }  }
   
 /*  /*
  * Delete line "lp". Fix all of the   * Delete line "lp".  Fix all of the links that might point to it (they are
  * links that might point at it (they are   * moved to offset 0 of the next line.  Unlink the line from whatever buffer
  * moved to offset 0 of the next line.   * it might be in, and release the memory.  The buffers are updated too; the
  * Unlink the line from whatever buffer it   * magic conditions described in the above comments don't hold here.
  * might be in. Release the memory. The  
  * buffers are updated too; the magic conditions  
  * described in the above comments don't hold  
  * here.  
  */   */
 VOID  VOID
 lfree(lp)  lfree(lp)
         register LINE  *lp;          LINE *lp;
 {  {
         register BUFFER *bp;          BUFFER  *bp;
         register MGWIN *wp;          MGWIN   *wp;
   
         for (wp = wheadp; wp != NULL; wp = wp->w_wndp) {          for (wp = wheadp; wp != NULL; wp = wp->w_wndp) {
                 if (wp->w_linep == lp)                  if (wp->w_linep == lp)
Line 129 
Line 126 
         }          }
         lp->l_bp->l_fp = lp->l_fp;          lp->l_bp->l_fp = lp->l_fp;
         lp->l_fp->l_bp = lp->l_bp;          lp->l_fp->l_bp = lp->l_bp;
         free((char *) lp);          free((char *)lp);
 }  }
   
 /*  /*
  * This routine gets called when   * This routine is called when a character changes in place in the current
  * a character is changed in place in the   * buffer. It updates all of the required flags in the buffer and window
  * current buffer. It updates all of the required   * system. The flag used is passed as an argument; if the buffer is being
  * flags in the buffer and window system. The flag   * displayed in more than 1 window we change EDIT to HARD. Set MODE if the
  * used is passed as an argument; if the buffer is being   * mode line needs to be updated (the "*" has to be set).
  * displayed in more than 1 window we change EDIT to  
  * HARD. Set MODE if the mode line needs to be  
  * updated (the "*" has to be set).  
  */   */
 VOID  VOID
 lchange(flag)  lchange(flag)
         register int    flag;          int flag;
 {  {
         register MGWIN *wp;          MGWIN   *wp;
   
         if ((curbp->b_flag & BFCHG) == 0) {     /* First change, so      */          /* update mode lines if this is the first change. */
                 flag |= WFMODE; /* update mode lines.    */          if ((curbp->b_flag & BFCHG) == 0) {
                   flag |= WFMODE;
                 curbp->b_flag |= BFCHG;                  curbp->b_flag |= BFCHG;
         }          }
         for (wp = wheadp; wp != NULL; wp = wp->w_wndp) {          for (wp = wheadp; wp != NULL; wp = wp->w_wndp) {
Line 162 
Line 157 
 }  }
   
 /*  /*
  * Insert "n" copies of the character "c"   * Insert "n" copies of the character "c" at the current location of dot.
  * at the current location of dot. In the easy case   * In the easy case all that happens is the text is stored in the line.
  * all that happens is the text is stored in the line.   * In the hard case, the line has to be reallocated.  When the window list
  * In the hard case, the line has to be reallocated.   * is updated, take special care; I screwed it up once.  You always update
  * When the window list is updated, take special   * dot in the current window.  You update mark and a dot in another window
  * care; I screwed it up once. You always update dot   * if it is greater than the place where you did the insert. Return TRUE
  * in the current window. You update mark, and a  
  * dot in another window, if it is greater than  
  * the place where you did the insert. Return TRUE  
  * if all is well, and FALSE on errors.   * if all is well, and FALSE on errors.
  */   */
   int
 linsert(n, c)  linsert(n, c)
         int             n;          int n, c;
 {  {
         register char  *cp1;          LINE    *lp1, *lp2, *lp3;
         register char  *cp2;          MGWIN   *wp;
         register LINE  *lp1;          RSIZE    i;
         LINE           *lp2;          int      doto;
         LINE           *lp3;          char    *cp1, *cp2;
         register int    doto;  
         register RSIZE  i;  
         MGWIN          *wp;  
   
         lchange(WFEDIT);          lchange(WFEDIT);
         lp1 = curwp->w_dotp;    /* Current line          */  
         if (lp1 == curbp->b_linep) {    /* At the end: special   */          /* current line */
                 /* (now should only happen in empty buffer       */          lp1 = curwp->w_dotp;
   
           /* special case for the end */
           if (lp1 == curbp->b_linep) {
                   /* now should only happen in empty buffer */
                 if (curwp->w_doto != 0) {                  if (curwp->w_doto != 0) {
                         ewprintf("bug: linsert");                          ewprintf("bug: linsert");
                         return FALSE;                          return FALSE;
                 }                  }
                 if ((lp2 = lallocx(n)) == NULL) /* Allocate new line */                  /* allocate a new line */
                   if ((lp2 = lallocx(n)) == NULL)
                         return FALSE;                          return FALSE;
                 lp3 = lp1->l_bp;/* Previous line         */                  /* previous line */
                 lp3->l_fp = lp2;/* Link in               */                  lp3 = lp1->l_bp;
                   /* link in */
                   lp3->l_fp = lp2;
                 lp2->l_fp = lp1;                  lp2->l_fp = lp1;
                 lp1->l_bp = lp2;                  lp1->l_bp = lp2;
                 lp2->l_bp = lp3;                  lp2->l_bp = lp3;
Line 214 
Line 211 
                 curwp->w_doto = n;                  curwp->w_doto = n;
                 return TRUE;                  return TRUE;
         }          }
         doto = curwp->w_doto;   /* Save for later.       */          /* save for later */
           doto = curwp->w_doto;
         /* NOSTRICT (2) */          /* NOSTRICT (2) */
         if (lp1->l_used + n > lp1->l_size) {    /* Hard: reallocate      */          /* Hard case: reallocate */
           if (lp1->l_used + n > lp1->l_size) {
                 if ((lp2 = lallocx(lp1->l_used + n)) == NULL)                  if ((lp2 = lallocx(lp1->l_used + n)) == NULL)
                         return FALSE;                          return FALSE;
                 cp1 = &lp1->l_text[0];                  cp1 = &lp1->l_text[0];
Line 231 
Line 230 
                 lp2->l_fp = lp1->l_fp;                  lp2->l_fp = lp1->l_fp;
                 lp1->l_fp->l_bp = lp2;                  lp1->l_fp->l_bp = lp2;
                 lp2->l_bp = lp1->l_bp;                  lp2->l_bp = lp1->l_bp;
                 free((char *) lp1);                  free((char *)lp1);
         } else {                /* Easy: in place        */          /* Easy case: in place */
                 lp2 = lp1;      /* Pretend new line      */          } else {
                   /* pretend there's a new line */
                   lp2 = lp1;
                 /* NOSTRICT */                  /* NOSTRICT */
                 lp2->l_used += n;                  lp2->l_used += n;
                 cp2 = &lp1->l_text[lp1->l_used];                  cp2 = &lp1->l_text[lp1->l_used];
Line 242 
Line 243 
                 while (cp1 != &lp1->l_text[doto])                  while (cp1 != &lp1->l_text[doto])
                         *--cp2 = *--cp1;                          *--cp2 = *--cp1;
         }          }
         for (i = 0; i < n; ++i) /* Add the characters    */          /* Add the characters */
           for (i = 0; i < n; ++i)
                 lp2->l_text[doto + i] = c;                  lp2->l_text[doto + i] = c;
   
         for (wp = wheadp; wp != NULL; wp = wp->w_wndp) {          for (wp = wheadp; wp != NULL; wp = wp->w_wndp) {
Line 265 
Line 267 
 }  }
   
 /*  /*
  * Insert a newline into the buffer   * Insert a newline into the buffer at the current location of dot in the
  * at the current location of dot in the current   * current window.  The funny ass-backwards way is no longer used.
  * window.  The funny ass-backwards way is no longer used.  
  */   */
   int
 lnewline()  lnewline()
 {  {
         register LINE  *lp1;          LINE    *lp1, *lp2;
         register LINE  *lp2;          int      doto, nlen;
         register int    doto;          MGWIN   *wp;
         register int    nlen;  
         MGWIN          *wp;  
   
         lchange(WFHARD);          lchange(WFHARD);
         lp1 = curwp->w_dotp;    /* Get the address and   */  
         doto = curwp->w_doto;   /* offset of "."         */          /* Get the address and offset of "." */
         if (doto == 0) {        /* avoid unnessisary copying */          lp1 = curwp->w_dotp;
                 if ((lp2 = lallocx(0)) == NULL) /* new first part        */          doto = curwp->w_doto;
   
           /* avoid unnecessary copying */
           if (doto == 0) {
                   /* new first part */
                   if ((lp2 = lallocx(0)) == NULL)
                         return FALSE;                          return FALSE;
                 lp2->l_bp = lp1->l_bp;                  lp2->l_bp = lp1->l_bp;
                 lp1->l_bp->l_fp = lp2;                  lp1->l_bp->l_fp = lp2;
Line 292 
Line 297 
                                 wp->w_linep = lp2;                                  wp->w_linep = lp2;
                 return TRUE;                  return TRUE;
         }          }
         nlen = llength(lp1) - doto;     /* length of new part    */  
         if ((lp2 = lallocx(nlen)) == NULL)      /* New second half line */          /* length of new part */
           nlen = llength(lp1) - doto;
   
           /* new second half line */
           if ((lp2 = lallocx(nlen)) == NULL)
                 return FALSE;                  return FALSE;
         if (nlen != 0)          if (nlen != 0)
                 bcopy(&lp1->l_text[doto], &lp2->l_text[0], nlen);                  bcopy(&lp1->l_text[doto], &lp2->l_text[0], nlen);
Line 302 
Line 311 
         lp2->l_fp = lp1->l_fp;          lp2->l_fp = lp1->l_fp;
         lp1->l_fp = lp2;          lp1->l_fp = lp2;
         lp2->l_fp->l_bp = lp2;          lp2->l_fp->l_bp = lp2;
         for (wp = wheadp; wp != NULL; wp = wp->w_wndp) {        /* Windows       */          /* Windows */
           for (wp = wheadp; wp != NULL; wp = wp->w_wndp) {
                 if (wp->w_dotp == lp1 && wp->w_doto >= doto) {                  if (wp->w_dotp == lp1 && wp->w_doto >= doto) {
                         wp->w_dotp = lp2;                          wp->w_dotp = lp2;
                         wp->w_doto -= doto;                          wp->w_doto -= doto;
Line 316 
Line 326 
 }  }
   
 /*  /*
  * This function deletes "n" bytes,   * This function deletes "n" bytes, starting at dot. It understands how to
  * starting at dot. It understands how do deal   * deal with end of lines, etc.  It returns TRUE if all of the characters
  * with end of lines, etc. It returns TRUE if all   * were deleted, and FALSE if they were not (because dot ran into the end
  * of the characters were deleted, and FALSE if   * of the buffer.  The "kflag" indicates either no insertion, or direction
  * they were not (because dot ran into the end of   * of insertion into the kill buffer.
  * the buffer. The "kflag" indicates either no insertion,  
  * or direction of insertion into the kill buffer.  
  */   */
   int
 ldelete(n, kflag)  ldelete(n, kflag)
         RSIZE           n;          RSIZE n;
           int   kflag;
 {  {
         register char  *cp1;          LINE    *dotp;
         register char  *cp2;          RSIZE    chunk;
         register LINE  *dotp;          MGWIN   *wp;
         register int    doto;          int      doto;
         register RSIZE  chunk;          char    *cp1, *cp2;
         MGWIN          *wp;  
   
         /*          /*
          * HACK - doesn't matter, and fixes back-over-nl bug for empty           * HACK - doesn't matter, and fixes back-over-nl bug for empty
Line 344 
Line 353 
         while (n != 0) {          while (n != 0) {
                 dotp = curwp->w_dotp;                  dotp = curwp->w_dotp;
                 doto = curwp->w_doto;                  doto = curwp->w_doto;
                 if (dotp == curbp->b_linep)     /* Hit end of buffer.    */                  /* Hit the end of the buffer */
                   if (dotp == curbp->b_linep)
                         return FALSE;                          return FALSE;
                 chunk = dotp->l_used - doto;    /* Size of chunk.        */                  /* Size of the chunk */
                   chunk = dotp->l_used - doto;
                 if (chunk > n)                  if (chunk > n)
                         chunk = n;                          chunk = n;
                 if (chunk == 0) {       /* End of line, merge.   */                  /* End of line, merge */
                   if (chunk == 0) {
                         if (dotp == lback(curbp->b_linep))                          if (dotp == lback(curbp->b_linep))
                                 return FALSE;   /* End of buffer.        */                                  /* End of buffer */
                                   return FALSE;
                         lchange(WFHARD);                          lchange(WFHARD);
                         if (ldelnewline() == FALSE                          if (ldelnewline() == FALSE ||
                         || (kflag != KNONE && kinsert('\n', kflag) == FALSE))                              (kflag != KNONE && kinsert('\n', kflag) == FALSE))
                                 return FALSE;                                  return FALSE;
                         --n;                          --n;
                         continue;                          continue;
                 }                  }
                 lchange(WFEDIT);                  lchange(WFEDIT);
                 cp1 = &dotp->l_text[doto];      /* Scrunch text.         */                  /* Scrunch text */
                   cp1 = &dotp->l_text[doto];
                 cp2 = cp1 + chunk;                  cp2 = cp1 + chunk;
                 if (kflag == KFORW) {                  if (kflag == KFORW) {
                         while (ksize - kused < chunk)                          while (ksize - kused < chunk)
                                 if (kgrow(FALSE) == FALSE)                                  if (kgrow(FALSE) == FALSE)
                                         return FALSE;                                          return FALSE;
                         bcopy(cp1, &(kbufp[kused]), (int) chunk);                          bcopy(cp1, &(kbufp[kused]), (int)chunk);
                         kused += chunk;                          kused += chunk;
                 } else if (kflag == KBACK) {                  } else if (kflag == KBACK) {
                         while (kstart < chunk)                          while (kstart < chunk)
                                 if (kgrow(TRUE) == FALSE)                                  if (kgrow(TRUE) == FALSE)
                                         return FALSE;                                          return FALSE;
                         bcopy(cp1, &(kbufp[kstart - chunk]), (int) chunk);                          bcopy(cp1, &(kbufp[kstart - chunk]), (int)chunk);
                         kstart -= chunk;                          kstart -= chunk;
                 } else if (kflag != KNONE)                  } else if (kflag != KNONE)
                         panic("broken ldelete call");                          panic("broken ldelete call");
                 while (cp2 != &dotp->l_text[dotp->l_used])                  while (cp2 != &dotp->l_text[dotp->l_used])
                         *cp1++ = *cp2++;                          *cp1++ = *cp2++;
                 dotp->l_used -= (int) chunk;                  dotp->l_used -= (int)chunk;
                 for (wp = wheadp; wp != NULL; wp = wp->w_wndp) {                  for (wp = wheadp; wp != NULL; wp = wp->w_wndp) {
                         if (wp->w_dotp == dotp && wp->w_doto >= doto) {                          if (wp->w_dotp == dotp && wp->w_doto >= doto) {
                                 /* NOSTRICT */                                  /* NOSTRICT */
Line 399 
Line 413 
 }  }
   
 /*  /*
  * Delete a newline. Join the current line   * Delete a newline and join the current line with the next line. If the next
  * with the next line. If the next line is the magic   * line is the magic header line always return TRUE; merging the last line
  * header line always return TRUE; merging the last line   * with the header line can be thought of as always being a successful
  * with the header line can be thought of as always being a   * operation.  Even if nothing is done, this makes the kill buffer work
  * successful operation, even if nothing is done, and this makes   * "right".  Easy cases can be done by shuffling data around.  Hard cases
  * the kill buffer work "right". Easy cases can be done by   * require that lines be moved about in memory.  Return FALSE on error and
  * shuffling data around. Hard cases require that lines be moved   * TRUE if all looks ok.
  * about in memory. Return FALSE on error and TRUE if all  
  * looks ok.  
  */   */
   int
 ldelnewline()  ldelnewline()
 {  {
         register LINE  *lp1;          LINE    *lp1, *lp2, *lp3;
         register LINE  *lp2;          MGWIN   *wp;
         register MGWIN *wp;  
         LINE           *lp3;  
   
         lp1 = curwp->w_dotp;          lp1 = curwp->w_dotp;
         lp2 = lp1->l_fp;          lp2 = lp1->l_fp;
         if (lp2 == curbp->b_linep)      /* At the buffer end.    */          /* at the end of the buffer */
           if (lp2 == curbp->b_linep)
                 return TRUE;                  return TRUE;
         if (lp2->l_used <= lp1->l_size - lp1->l_used) {          if (lp2->l_used <= lp1->l_size - lp1->l_used) {
                 bcopy(&lp2->l_text[0], &lp1->l_text[lp1->l_used], lp2->l_used);                  bcopy(&lp2->l_text[0], &lp1->l_text[lp1->l_used], lp2->l_used);
Line 437 
Line 449 
                 lp1->l_used += lp2->l_used;                  lp1->l_used += lp2->l_used;
                 lp1->l_fp = lp2->l_fp;                  lp1->l_fp = lp2->l_fp;
                 lp2->l_fp->l_bp = lp1;                  lp2->l_fp->l_bp = lp1;
                 free((char *) lp2);                  free((char *)lp2);
                 return TRUE;                  return TRUE;
         }          }
         if ((lp3 = lalloc(lp1->l_used + lp2->l_used)) == NULL)          if ((lp3 = lalloc(lp1->l_used + lp2->l_used)) == NULL)
Line 464 
Line 476 
                         wp->w_marko += lp1->l_used;                          wp->w_marko += lp1->l_used;
                 }                  }
         }          }
         free((char *) lp1);          free((char *)lp1);
         free((char *) lp2);          free((char *)lp2);
         return TRUE;          return TRUE;
 }  }
   
 /*  /*
  * Replace plen characters before dot with argument string.   * Replace plen characters before dot with argument string.  Control-J
  * Control-J characters in st are interpreted as newlines.   * characters in st are interpreted as newlines.  There is a casehack
  * There is a casehack disable flag (normally it likes to match   * disable flag (normally it likes to match case of replacement to what
  * case of replacement to what was there).   * was there).
  */   */
   int
 lreplace(plen, st, f)  lreplace(plen, st, f)
         register RSIZE  plen;   /* length to remove              */          RSIZE  plen;    /* length to remove              */
         char           *st;     /* replacement string            */          char  *st;      /* replacement string            */
         int             f;      /* case hack disable             */          int    f;       /* case hack disable             */
 {  {
         register RSIZE  rlen;   /* replacement length            */          RSIZE   rlen;   /* replacement length            */
         register int    rtype;  /* capitalization                */          int     rtype;  /* capitalization                */
         register int    c;      /* used for random characters    */          int     c;      /* used for random characters    */
         register int    doto;   /* offset into line              */          int     doto;   /* offset into line              */
   
         /*          /*
          * Find the capitalization of the word that was found.           * Find the capitalization of the word that was found.  f says use
          * f says use exact case of replacement string (same thing that           * exact case of replacement string (same thing that happens with
          * happens with lowercase found), so bypass check.           * lowercase found), so bypass check.
          */           */
         /* NOSTRICT */          /* NOSTRICT */
         (VOID) backchar(FFARG | FFRAND, (int) plen);          (VOID)backchar(FFARG | FFRAND, (int)plen);
         rtype = _L;          rtype = _L;
         c = lgetc(curwp->w_dotp, curwp->w_doto);          c = lgetc(curwp->w_dotp, curwp->w_doto);
         if (ISUPPER(c) != FALSE && f == FALSE) {          if (ISUPPER(c) != FALSE && f == FALSE) {
Line 511 
Line 524 
         rlen = strlen(st);          rlen = strlen(st);
         doto = curwp->w_doto;          doto = curwp->w_doto;
         if (plen > rlen)          if (plen > rlen)
                 (VOID) ldelete((RSIZE) (plen - rlen), KNONE);                  (VOID)ldelete((RSIZE) (plen - rlen), KNONE);
         else if (plen < rlen) {          else if (plen < rlen) {
                 if (linsert((int) (rlen - plen), ' ') == FALSE)                  if (linsert((int)(rlen - plen), ' ') == FALSE)
                         return FALSE;                          return FALSE;
         }          }
         curwp->w_doto = doto;          curwp->w_doto = doto;
Line 530 
Line 543 
                         rtype = _L;                          rtype = _L;
                 if (c == CCHR('J')) {                  if (c == CCHR('J')) {
                         if (curwp->w_doto == llength(curwp->w_dotp))                          if (curwp->w_doto == llength(curwp->w_dotp))
                                 (VOID) forwchar(FFRAND, 1);                                  (VOID)forwchar(FFRAND, 1);
                         else {                          else {
                                 if (ldelete((RSIZE) 1, KNONE) != FALSE)                                  if (ldelete((RSIZE) 1, KNONE) != FALSE)
                                         (VOID) lnewline();                                          (VOID)lnewline();
                         }                          }
                 } else if (curwp->w_dotp == curbp->b_linep) {                  } else if (curwp->w_dotp == curbp->b_linep) {
                         (VOID) linsert(1, c);                          (VOID)linsert(1, c);
                 } else if (curwp->w_doto == llength(curwp->w_dotp)) {                  } else if (curwp->w_doto == llength(curwp->w_dotp)) {
                         if (ldelete((RSIZE) 1, KNONE) != FALSE)                          if (ldelete((RSIZE) 1, KNONE) != FALSE)
                                 (VOID) linsert(1, c);                                  (VOID)linsert(1, c);
                 } else                  } else
                         lputc(curwp->w_dotp, curwp->w_doto++, c);                          lputc(curwp->w_dotp, curwp->w_doto++, c);
         }          }
Line 548 
Line 561 
 }  }
   
 /*  /*
  * Delete all of the text   * Delete all of the text saved in the kill buffer.  Called by commands when
  * saved in the kill buffer. Called by commands   * a new kill context is created. The kill buffer array is released, just in
  * when a new kill context is being created. The kill   * case the buffer has grown to an immense size.  No errors.
  * buffer array is released, just in case the buffer has  
  * grown to immense size. No errors.  
  */   */
 VOID  VOID
 kdelete()  kdelete()
 {  {
   
         if (kbufp != NULL) {          if (kbufp != NULL) {
                 free((char *) kbufp);                  free((char *)kbufp);
                 kbufp = NULL;                  kbufp = NULL;
                 kstart = kused = ksize = 0;                  kstart = kused = ksize = 0;
         }          }
 }  }
   
 /*  /*
  * Insert a character to the kill buffer,   * Insert a character to the kill buffer, enlarging the buffer if there
  * enlarging the buffer if there isn't any room. Always   * isn't any room. Always grow the buffer in chunks, on the assumption
  * grow the buffer in chunks, on the assumption that if you   * that if you put something in the kill buffer you are going to put more
  * put something in the kill buffer you are going to put   * stuff there too later. Return TRUE if all is well, and FALSE on errors.
  * more stuff there too later. Return TRUE if all is   * Print a message on errors.  Dir says whether to put it at back or front.
  * well, and FALSE on errors. Print a message on  
  * errors. Dir says whether to put it at back or front.  
  */   */
   int
 kinsert(c, dir)  kinsert(c, dir)
           int c, dir;
 {  {
   
         if (kused == ksize && dir == KFORW && kgrow(FALSE) == FALSE)          if (kused == ksize && dir == KFORW && kgrow(FALSE) == FALSE)
                 return FALSE;                  return FALSE;
         if (kstart == 0 && dir == KBACK && kgrow(TRUE) == FALSE)          if (kstart == 0 && dir == KBACK && kgrow(TRUE) == FALSE)
Line 594 
Line 603 
  * kgrow - just get more kill buffer for the callee. back is true if   * kgrow - just get more kill buffer for the callee. back is true if
  * we are trying to get space at the beginning of the kill buffer.   * we are trying to get space at the beginning of the kill buffer.
  */   */
   static int
 kgrow(back)  kgrow(back)
           int back;
 {  {
         register int    nstart;          int      nstart;
         register char  *nbufp;          char    *nbufp;
   
         if ((unsigned) (ksize + KBLOCK) <= (unsigned) ksize) {          if ((unsigned)(ksize + KBLOCK) <= (unsigned)ksize) {
                 /* probably 16 bit unsigned */                  /* probably 16 bit unsigned */
                 ewprintf("Kill buffer size at maximum");                  ewprintf("Kill buffer size at maximum");
                 return FALSE;                  return FALSE;
         }          }
         if ((nbufp = malloc((unsigned) (ksize + KBLOCK))) == NULL) {          if ((nbufp = malloc((unsigned)(ksize + KBLOCK))) == NULL) {
                 ewprintf("Can't get %ld bytes", (long) (ksize + KBLOCK));                  ewprintf("Can't get %ld bytes", (long)(ksize + KBLOCK));
                 return FALSE;                  return FALSE;
         }          }
         nstart = (back == TRUE) ? (kstart + KBLOCK) : (KBLOCK / 4);          nstart = (back == TRUE) ? (kstart + KBLOCK) : (KBLOCK / 4);
         bcopy(&(kbufp[kstart]), &(nbufp[nstart]), (int) (kused - kstart));          bcopy(&(kbufp[kstart]), &(nbufp[nstart]), (int)(kused - kstart));
         if (kbufp != NULL)          if (kbufp != NULL)
                 free((char *) kbufp);                  free((char *)kbufp);
         kbufp = nbufp;          kbufp = nbufp;
         ksize += KBLOCK;          ksize += KBLOCK;
         kused = kused - kstart + nstart;          kused = kused - kstart + nstart;
Line 620 
Line 631 
 }  }
   
 /*  /*
  * This function gets characters from   * This function gets characters from the kill buffer. If the character
  * the kill buffer. If the character index "n" is   * index "n" is off the end, it returns "-1". This lets the caller just
  * off the end, it returns "-1". This lets the caller   * scan along until it gets a "-1" back.
  * just scan along until it gets a "-1" back.  
  */   */
   int
 kremove(n)  kremove(n)
           int n;
 {  {
         if (n < 0 || n + kstart >= kused)          if (n < 0 || n + kstart >= kused)
                 return -1;                  return -1;

Legend:
Removed from v.1.3  
changed lines
  Added in v.1.4