Download raw body.
vi(1) count paste bug. New diff.
My last patch introduced a regression. Below the fixed version with
some simplification of the code.
Index: common/put.c
===================================================================
RCS file: /cvs/src/usr.bin/vi/common/put.c,v
diff -u -p -r1.16 put.c
--- common/put.c 27 May 2016 09:18:11 -0000 1.16
+++ common/put.c 13 Aug 2025 13:08:37 -0000
@@ -27,16 +27,16 @@
* put --
* Put text buffer contents into the file.
*
- * PUBLIC: int put(SCR *, CB *, CHAR_T *, MARK *, MARK *, int);
+ * PUBLIC: int put(SCR *, CB *, CHAR_T *, MARK *, MARK *, int, int);
*/
int
-put(SCR *sp, CB *cbp, CHAR_T *namep, MARK *cp, MARK *rp, int append)
+put(SCR *sp, CB *cbp, CHAR_T *namep, MARK *cp, MARK *rp, int append, int cnt)
{
CHAR_T name;
TEXT *ltp, *tp;
recno_t lno;
size_t blen, clen, len;
- int rval;
+ int rval, i, isempty;
char *bp, *p, *t;
if (cbp == NULL) {
@@ -74,28 +74,23 @@ put(SCR *sp, CB *cbp, CHAR_T *namep, MAR
* Historical practice is that the cursor ends at the first character
* in the file.
*/
- if (cp->lno == 1) {
- if (db_last(sp, &lno))
- return (1);
- if (lno == 0) {
- for (; tp; ++lno, ++sp->rptlines[L_ADDED],
+ if (cp->lno == 1 && db_last(sp, &lno))
+ return (1);
+
+ /* If a line mode buffer, append each new line into the file. */
+ if (F_ISSET(cbp, CB_LMODE)) {
+ if (lno != 0) {
+ lno = append ? cp->lno : cp->lno - 1;
+ rp->lno = lno + 1;
+ }
+ for (i = cnt; i > 0; i--) {
+ for (; tp;
+ ++lno, ++sp->rptlines[L_ADDED],
tp = TAILQ_NEXT(tp, q))
if (db_append(sp, 1, lno, tp->lb, tp->len))
return (1);
- rp->lno = 1;
- rp->cno = 0;
- return (0);
+ tp = TAILQ_FIRST(&cbp->textq);
}
- }
-
- /* If a line mode buffer, append each new line into the file. */
- if (F_ISSET(cbp, CB_LMODE)) {
- lno = append ? cp->lno : cp->lno - 1;
- rp->lno = lno + 1;
- for (; tp;
- ++lno, ++sp->rptlines[L_ADDED], tp = TAILQ_NEXT(tp, q))
- if (db_append(sp, 1, lno, tp->lb, tp->len))
- return (1);
rp->cno = 0;
(void)nonblank(sp, rp->lno, &rp->cno);
return (0);
@@ -111,8 +106,11 @@ put(SCR *sp, CB *cbp, CHAR_T *namep, MAR
* Get the first line.
*/
lno = cp->lno;
- if (db_get(sp, lno, DBG_FATAL, &p, &len))
- return (1);
+ if (db_eget(sp, lno, &p, &len, &isempty)) {
+ if (!isempty)
+ return (1);
+ len = 0;
+ }
GET_SPACE_RET(sp, bp, blen, tp->len + len + 1);
t = bp;
@@ -126,8 +124,10 @@ put(SCR *sp, CB *cbp, CHAR_T *namep, MAR
/* First line from the CB. */
if (tp->len != 0) {
- memcpy(t, tp->lb, tp->len);
- t += tp->len;
+ for (i = cnt; i > 0; i--) {
+ memcpy(t, tp->lb, tp->len);
+ t += tp->len;
+ }
}
/* Calculate length left in the original line. */
Index: ex/ex_move.c
===================================================================
RCS file: /cvs/src/usr.bin/vi/ex/ex_move.c,v
diff -u -p -r1.11 ex_move.c
--- ex/ex_move.c 6 Jan 2016 22:28:52 -0000 1.11
+++ ex/ex_move.c 13 Aug 2025 13:08:37 -0000
@@ -59,7 +59,7 @@ ex_copy(SCR *sp, EXCMD *cmdp)
/* Put the text into place. */
tm.lno = cmdp->lineno;
tm.cno = 0;
- if (put(sp, &cb, NULL, &tm, &m, 1))
+ if (put(sp, &cb, NULL, &tm, &m, 1,1))
rval = 1;
else {
/*
Index: ex/ex_put.c
===================================================================
RCS file: /cvs/src/usr.bin/vi/ex/ex_put.c,v
diff -u -p -r1.6 ex_put.c
--- ex/ex_put.c 12 Nov 2014 04:28:41 -0000 1.6
+++ ex/ex_put.c 13 Aug 2025 13:08:37 -0000
@@ -39,7 +39,7 @@ ex_put(SCR *sp, EXCMD *cmdp)
m.cno = sp->cno;
if (put(sp, NULL,
FL_ISSET(cmdp->iflags, E_C_BUFFER) ? &cmdp->buffer : NULL,
- &cmdp->addr1, &m, 1))
+ &cmdp->addr1, &m, 1, 1))
return (1);
sp->lno = m.lno;
sp->cno = m.cno;
Index: include/com_extern.h
===================================================================
RCS file: /cvs/src/usr.bin/vi/include/com_extern.h,v
diff -u -p -r1.16 com_extern.h
--- include/com_extern.h 21 May 2019 09:24:58 -0000 1.16
+++ include/com_extern.h 13 Aug 2025 13:08:37 -0000
@@ -81,7 +81,7 @@ int f_w300(SCR *, OPTION *, char *, u_lo
int f_w1200(SCR *, OPTION *, char *, u_long *);
int f_w9600(SCR *, OPTION *, char *, u_long *);
int f_window(SCR *, OPTION *, char *, u_long *);
-int put(SCR *, CB *, CHAR_T *, MARK *, MARK *, int);
+int put(SCR *, CB *, CHAR_T *, MARK *, MARK *, int, int);
int rcv_tmp(SCR *, EXF *, char *);
int rcv_init(SCR *);
int rcv_sync(SCR *, u_int);
Index: vi/v_put.c
===================================================================
RCS file: /cvs/src/usr.bin/vi/vi/v_put.c,v
diff -u -p -r1.8 v_put.c
--- vi/v_put.c 27 May 2016 09:18:12 -0000 1.8
+++ vi/v_put.c 13 Aug 2025 13:08:37 -0000
@@ -43,15 +43,11 @@ v_Put(SCR *sp, VICMD *vp)
* Historic vi did not support a count with the 'p' and 'P'
* commands. It's useful, so we do.
*/
- for (cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
- if (put(sp, NULL,
- F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
- &vp->m_start, &vp->m_final, 0))
- return (1);
- vp->m_start = vp->m_final;
- if (INTERRUPTED(sp))
- return (1);
- }
+ cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1;
+ if (put(sp, NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
+ &vp->m_start, &vp->m_final, 0, cnt))
+ return (1);
+
return (0);
}
@@ -74,15 +70,11 @@ v_put(SCR *sp, VICMD *vp)
* Historic vi did not support a count with the 'p' and 'P'
* commands. It's useful, so we do.
*/
- for (cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
- if (put(sp, NULL,
- F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
- &vp->m_start, &vp->m_final, 1))
- return (1);
- vp->m_start = vp->m_final;
- if (INTERRUPTED(sp))
- return (1);
- }
+ cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1;
+ if (put(sp, NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
+ &vp->m_start, &vp->m_final, 1, cnt))
+ return (1);
+
return (0);
}
--
Walter
vi(1) count paste bug. New diff.