version 1.8, 2001/05/24 03:05:23 |
version 1.9, 2002/02/13 22:36:58 |
|
|
static int kgrow __P((int)); |
static int kgrow __P((int)); |
|
|
/* |
/* |
* This routine allocates a block of memory large enough to hold a LINE |
* Allocate a new line of size `used'. lrealloc() can be called if the line |
* containing "used" characters. The block is rounded up to whatever |
* ever needs to grow beyond that. |
* 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. |
|
*/ |
*/ |
LINE * |
LINE * |
lalloc(used) |
lalloc(int used) |
int used; |
|
{ |
{ |
LINE *lp; |
LINE *lp; |
int size; |
|
|
|
/* any padding at the end of the structure is used */ |
if ((lp = malloc(sizeof *lp)) == NULL) |
if ((size = used + OFFSET(LINE, l_text[0])) < sizeof(LINE)) |
return FALSE; |
size = sizeof(LINE); |
lp->l_text = NULL; |
#ifdef MALLOCROUND |
lp->l_size = 0; |
MALLOCROUND(size); /* round up to a size optimal to malloc */ |
lp->l_used = used; /* XXX */ |
#endif |
if (lrealloc(lp, used) == FALSE) { |
if ((lp = malloc((unsigned)size)) == NULL) { |
free(lp); |
ewprintf("Can't get %d bytes", size); |
|
return NULL; |
return NULL; |
} |
} |
lp->l_size = size - OFFSET(LINE, l_text[0]); |
|
lp->l_used = used; |
|
return lp; |
return lp; |
} |
} |
|
|
/* |
int |
* Like lalloc, only round amount desired up because this line will |
lrealloc(LINE *lp, int newsize) |
* 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 size; |
char *tmp; |
LINE *lp; |
|
|
|
size = (NBLOCK + used) & ~(NBLOCK - 1); |
if ((tmp = realloc(lp->l_text, newsize)) == NULL) |
if ((lp = lalloc(size)) != NULL) |
return FALSE; |
lp->l_used = used; |
lp->l_text = tmp; |
return lp; |
lp->l_size = newsize; |
|
|
|
return TRUE; |
} |
} |
|
|
/* |
/* |
|
|
} |
} |
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); |
if (lp->l_text != NULL) |
|
free(lp->l_text); |
|
free(lp); |
} |
} |
|
|
/* |
/* |
|
|
linsert(n, c) |
linsert(n, c) |
int n, c; |
int n, c; |
{ |
{ |
LINE *lp1, *lp2, *lp3; |
LINE *lp1; |
MGWIN *wp; |
MGWIN *wp; |
RSIZE i; |
RSIZE i; |
int doto; |
int doto; |
char *cp1, *cp2; |
|
|
|
lchange(WFEDIT); |
lchange(WFEDIT); |
|
|
/* current line */ |
/* current line */ |
lp1 = curwp->w_dotp; |
lp1 = curwp->w_dotp; |
|
|
/* special case for the end */ |
/* special case for the end */ |
if (lp1 == curbp->b_linep) { |
if (lp1 == curbp->b_linep) { |
|
LINE *lp2, *lp3; |
|
|
/* now should only happen in empty buffer */ |
/* 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; |
} |
} |
/* allocate a new line */ |
/* allocate a new line */ |
if ((lp2 = lallocx(n)) == NULL) |
if ((lp2 = lalloc(n)) == NULL) |
return FALSE; |
return FALSE; |
|
|
/* previous line */ |
/* previous line */ |
lp3 = lp1->l_bp; |
lp3 = lp1->l_bp; |
/* link in */ |
/* link in */ |
|
|
if (wp->w_markp == lp1) |
if (wp->w_markp == lp1) |
wp->w_markp = lp2; |
wp->w_markp = lp2; |
} |
} |
/* NOSTRICT */ |
|
curwp->w_doto = n; |
curwp->w_doto = n; |
return TRUE; |
return TRUE; |
} |
} |
/* save for later */ |
/* save for later */ |
doto = curwp->w_doto; |
doto = curwp->w_doto; |
/* NOSTRICT (2) */ |
|
/* Hard case: reallocate */ |
|
if (lp1->l_used + n > lp1->l_size) { |
if ((lp1->l_used + n) > lp1->l_size) { |
if ((lp2 = lallocx(lp1->l_used + n)) == NULL) |
if (lrealloc(lp1, lp1->l_used + n) == FALSE) |
return FALSE; |
return FALSE; |
cp1 = &lp1->l_text[0]; |
} |
cp2 = &lp2->l_text[0]; |
lp1->l_used += n; |
while (cp1 != &lp1->l_text[doto]) |
if (lp1->l_used != n) |
*cp2++ = *cp1++; |
memmove(&lp1->l_text[doto + n], &lp1->l_text[doto], |
/* NOSTRICT */ |
lp1->l_used - n - doto); |
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]; |
|
|
|
cp1 = cp2 - n; |
|
while (cp1 != &lp1->l_text[doto]) |
|
*--cp2 = *--cp1; |
|
} |
|
/* Add the characters */ |
/* Add the characters */ |
for (i = 0; i < n; ++i) |
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) { |
for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { |
if (wp->w_linep == lp1) |
|
wp->w_linep = lp2; |
|
if (wp->w_dotp == lp1) { |
if (wp->w_dotp == lp1) { |
wp->w_dotp = lp2; |
|
if (wp == curwp || wp->w_doto > doto) |
if (wp == curwp || wp->w_doto > doto) |
/* NOSTRICT */ |
|
wp->w_doto += n; |
wp->w_doto += n; |
} |
} |
if (wp->w_markp == lp1) { |
if (wp->w_markp == lp1) { |
wp->w_markp = lp2; |
|
if (wp->w_marko > doto) |
if (wp->w_marko > doto) |
/* NOSTRICT */ |
|
wp->w_marko += n; |
wp->w_marko += n; |
} |
} |
} |
} |
|
|
return TRUE; |
return TRUE; |
} |
} |
|
|
|
|
/* avoid unnecessary copying */ |
/* avoid unnecessary copying */ |
if (doto == 0) { |
if (doto == 0) { |
/* new first part */ |
/* new first part */ |
if ((lp2 = lallocx(0)) == NULL) |
if ((lp2 = lalloc(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; |
|
|
nlen = llength(lp1) - doto; |
nlen = llength(lp1) - doto; |
|
|
/* new second half line */ |
/* new second half line */ |
if ((lp2 = lallocx(nlen)) == NULL) |
if ((lp2 = lalloc(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); |
|
|
free((char *)lp2); |
free((char *)lp2); |
return TRUE; |
return TRUE; |
} |
} |
|
|
|
|
/* |
/* |
* Replace plen characters before dot with argument string. Control-J |
* Replace plen characters before dot with argument string. Control-J |