diff options
author | Kjell Wooding <kjell@cvs.openbsd.org> | 2005-11-22 04:38:58 +0000 |
---|---|---|
committer | Kjell Wooding <kjell@cvs.openbsd.org> | 2005-11-22 04:38:58 +0000 |
commit | 46e1924799731963a5a57b0777ff8febb5ae6958 (patch) | |
tree | 9efbec537575ada8a4a60ba4b8aaa43e984d7493 /usr.bin | |
parent | 506028da748115aa48171a9016671577b5d39956 (diff) |
Fix backwards insert into kill buffer (aaa \n bbb M-BS M-BS c-Y) by
batching string before prepending.
ok cloder, (grudgingly) beck
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/mg/line.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/usr.bin/mg/line.c b/usr.bin/mg/line.c index 6af891b1c76..66fea56b9c2 100644 --- a/usr.bin/mg/line.c +++ b/usr.bin/mg/line.c @@ -1,4 +1,4 @@ -/* $OpenBSD: line.c,v 1.31 2005/11/21 19:47:23 deraadt Exp $ */ +/* $OpenBSD: line.c,v 1.32 2005/11/22 04:38:57 kjell Exp $ */ /* This file is in the public domain. */ @@ -20,6 +20,9 @@ #include "def.h" +#include <stdlib.h> +#include <string.h> + /* * The number of bytes member from the start of the structure type should be * computed at compile time. @@ -411,11 +414,18 @@ ldelete(RSIZE n, int kflag) struct mgwin *wp; int doto; char *cp1, *cp2; + size_t len; + char *sv; + int end; if (curbp->b_flag & BFREADONLY) { ewprintf("Buffer is read only"); return (FALSE); } + len = n; + if ((sv = calloc(1, len + 1)) == NULL) + return (FALSE); + end = 0; undo_add_delete(curwp->w_dotp, curwp->w_doto, n); @@ -436,17 +446,18 @@ ldelete(RSIZE n, int kflag) /* End of buffer */ return (FALSE); lchange(WFHARD); - if (ldelnewline() == FALSE || - (kflag != KNONE && kinsert('\n', kflag) == FALSE)) + if (ldelnewline() == FALSE) return (FALSE); + end = strlcat(sv, "\n", len + 1); --n; continue; } lchange(WFEDIT); /* Scrunch text */ cp1 = &dotp->l_text[doto]; - if (kchunk(cp1, chunk, kflag) == FALSE) - return(FALSE); + memcpy(&sv[end], cp1, chunk); + end += chunk; + sv[end] = '\0'; for (cp2 = cp1 + chunk; cp2 < &dotp->l_text[dotp->l_used]; cp2++) *cp1++ = *cp2; @@ -467,6 +478,9 @@ ldelete(RSIZE n, int kflag) } n -= chunk; } + if (kchunk(sv, len, kflag) != TRUE) + return (FALSE); + free(sv); return (TRUE); } @@ -595,10 +609,13 @@ kdelete(void) * that if you put something in the kill buffer you are going to put more * stuff there too later. Return TRUE if all is well, and FALSE on errors. * Print a message on errors. Dir says whether to put it at back or front. + * This call is ignored if KNONE is set. */ int kinsert(int c, int dir) { + if (dir == KNONE) + return (TRUE); if (kused == ksize && dir == KFORW && kgrow(dir) == FALSE) return (FALSE); if (kstart == 0 && dir == KBACK && kgrow(dir) == FALSE) |