=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mg/line.c,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- src/usr.bin/mg/line.c 2001/05/24 03:05:23 1.8 +++ src/usr.bin/mg/line.c 2002/02/13 22:36:58 1.9 @@ -1,4 +1,4 @@ -/* $OpenBSD: line.c,v 1.8 2001/05/24 03:05:23 mickey Exp $ */ +/* $OpenBSD: line.c,v 1.9 2002/02/13 22:36:58 vincent Exp $ */ /* * Text line handling. @@ -43,50 +43,37 @@ static int kgrow __P((int)); /* - * This routine allocates a block of memory large enough to hold a LINE - * containing "used" characters. The block is rounded up to whatever - * needs to be allocated. (use lallocx for lines likely to grow.) - * Return a pointer to the new block, or NULL if there isn't any memory - * left. Print a message in the message line if no space. + * Allocate a new line of size `used'. lrealloc() can be called if the line + * ever needs to grow beyond that. */ LINE * -lalloc(used) - int used; +lalloc(int used) { - LINE *lp; - int size; + LINE *lp; - /* any padding at the end of the structure is used */ - if ((size = used + OFFSET(LINE, l_text[0])) < sizeof(LINE)) - size = sizeof(LINE); -#ifdef MALLOCROUND - MALLOCROUND(size); /* round up to a size optimal to malloc */ -#endif - if ((lp = malloc((unsigned)size)) == NULL) { - ewprintf("Can't get %d bytes", size); + if ((lp = malloc(sizeof *lp)) == NULL) + return FALSE; + lp->l_text = NULL; + lp->l_size = 0; + lp->l_used = used; /* XXX */ + if (lrealloc(lp, used) == FALSE) { + free(lp); return NULL; } - lp->l_size = size - OFFSET(LINE, l_text[0]); - lp->l_used = used; return lp; } -/* - * Like lalloc, only round amount desired up because this line will - * probably grow. We always make room for at least one more char. - * (thus making 0 not a special case anymore.) - */ -LINE * -lallocx(used) - int used; +int +lrealloc(LINE *lp, int newsize) { - int size; - LINE *lp; + char *tmp; - size = (NBLOCK + used) & ~(NBLOCK - 1); - if ((lp = lalloc(size)) != NULL) - lp->l_used = used; - return lp; + if ((tmp = realloc(lp->l_text, newsize)) == NULL) + return FALSE; + lp->l_text = tmp; + lp->l_size = newsize; + + return TRUE; } /* @@ -128,7 +115,9 @@ } lp->l_bp->l_fp = lp->l_fp; lp->l_fp->l_bp = lp->l_bp; - free((char *)lp); + if (lp->l_text != NULL) + free(lp->l_text); + free(lp); } /* @@ -171,27 +160,29 @@ linsert(n, c) int n, c; { - LINE *lp1, *lp2, *lp3; + LINE *lp1; MGWIN *wp; RSIZE i; int doto; - char *cp1, *cp2; lchange(WFEDIT); /* current line */ lp1 = curwp->w_dotp; - + /* special case for the end */ if (lp1 == curbp->b_linep) { + LINE *lp2, *lp3; + /* now should only happen in empty buffer */ if (curwp->w_doto != 0) { ewprintf("bug: linsert"); return FALSE; } /* allocate a new line */ - if ((lp2 = lallocx(n)) == NULL) + if ((lp2 = lalloc(n)) == NULL) return FALSE; + /* previous line */ lp3 = lp1->l_bp; /* link in */ @@ -209,62 +200,37 @@ if (wp->w_markp == lp1) wp->w_markp = lp2; } - /* NOSTRICT */ + curwp->w_doto = n; return TRUE; } /* save for later */ doto = curwp->w_doto; - /* NOSTRICT (2) */ - /* Hard case: reallocate */ - if (lp1->l_used + n > lp1->l_size) { - if ((lp2 = lallocx(lp1->l_used + n)) == NULL) + + + if ((lp1->l_used + n) > lp1->l_size) { + if (lrealloc(lp1, lp1->l_used + n) == FALSE) return FALSE; - cp1 = &lp1->l_text[0]; - cp2 = &lp2->l_text[0]; - while (cp1 != &lp1->l_text[doto]) - *cp2++ = *cp1++; - /* NOSTRICT */ - cp2 += n; - while (cp1 != &lp1->l_text[lp1->l_used]) - *cp2++ = *cp1++; - lp1->l_bp->l_fp = lp2; - lp2->l_fp = lp1->l_fp; - lp1->l_fp->l_bp = lp2; - lp2->l_bp = lp1->l_bp; - free((char *)lp1); - /* Easy case: in place */ - } else { - /* pretend there's a new line */ - lp2 = lp1; - /* NOSTRICT */ - lp2->l_used += n; - cp2 = &lp1->l_text[lp1->l_used]; + } + lp1->l_used += n; + if (lp1->l_used != n) + memmove(&lp1->l_text[doto + n], &lp1->l_text[doto], + lp1->l_used - n - doto); - cp1 = cp2 - n; - while (cp1 != &lp1->l_text[doto]) - *--cp2 = *--cp1; - } /* Add the characters */ for (i = 0; i < n; ++i) - lp2->l_text[doto + i] = c; - + lp1->l_text[doto + i] = c; for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { - if (wp->w_linep == lp1) - wp->w_linep = lp2; if (wp->w_dotp == lp1) { - wp->w_dotp = lp2; if (wp == curwp || wp->w_doto > doto) - /* NOSTRICT */ wp->w_doto += n; } if (wp->w_markp == lp1) { - wp->w_markp = lp2; if (wp->w_marko > doto) - /* NOSTRICT */ wp->w_marko += n; } } + return TRUE; } @@ -288,7 +254,7 @@ /* avoid unnecessary copying */ if (doto == 0) { /* new first part */ - if ((lp2 = lallocx(0)) == NULL) + if ((lp2 = lalloc(0)) == NULL) return FALSE; lp2->l_bp = lp1->l_bp; lp1->l_bp->l_fp = lp2; @@ -304,7 +270,7 @@ nlen = llength(lp1) - doto; /* new second half line */ - if ((lp2 = lallocx(nlen)) == NULL) + if ((lp2 = lalloc(nlen)) == NULL) return FALSE; if (nlen != 0) bcopy(&lp1->l_text[doto], &lp2->l_text[0], nlen); @@ -482,6 +448,7 @@ free((char *)lp2); return TRUE; } + /* * Replace plen characters before dot with argument string. Control-J