update to 1.01
[nvi.git] / vi / v_itxt.c
blob3083c6a5b3c508920d2b7057961d457d7848f52b
1 /*-
2 * Copyright (c) 1992, 1993
3 * The Regents of the University of California. All rights reserved.
5 * %sccs.include.redist.c%
6 */
8 #ifndef lint
9 static char sccsid[] = "$Id: v_itxt.c,v 8.23 1994/01/09 23:24:44 bostic Exp $ (Berkeley) $Date: 1994/01/09 23:24:44 $";
10 #endif /* not lint */
12 #include <sys/types.h>
14 #include <ctype.h>
15 #include <errno.h>
16 #include <stdlib.h>
17 #include <string.h>
19 #include "vi.h"
20 #include "vcmd.h"
23 * !!!
24 * Repeated input in the historic vi is mostly wrong and this isn't very
25 * backward compatible. For example, if the user entered "3Aab\ncd" in
26 * the historic vi, the "ab" was repeated 3 times, and the "\ncd" was then
27 * appended to the result. There was also a hack which I don't remember
28 * right now, where "3o" would open 3 lines and then let the user fill them
29 * in, to make screen movements on 300 baud modems more tolerable. I don't
30 * think it's going to be missed.
33 #define SET_TXT_STD(sp, f) { \
34 LF_INIT((f) | TXT_BEAUTIFY | TXT_CNTRLT | TXT_ESCAPE | \
35 TXT_MAPINPUT | TXT_RECORD | TXT_RESOLVE); \
36 if (O_ISSET(sp, O_ALTWERASE)) \
37 LF_SET(TXT_ALTWERASE); \
38 if (O_ISSET(sp, O_AUTOINDENT)) \
39 LF_SET(TXT_AUTOINDENT); \
40 if (O_ISSET(sp, O_SHOWMATCH)) \
41 LF_SET(TXT_SHOWMATCH); \
42 if (O_ISSET(sp, O_WRAPMARGIN)) \
43 LF_SET(TXT_WRAPMARGIN); \
44 if (F_ISSET(sp, S_SCRIPT)) \
45 LF_SET(TXT_CR); \
46 if (O_ISSET(sp, O_TTYWERASE)) \
47 LF_SET(TXT_TTYWERASE); \
50 /*
51 * !!!
52 * There's a problem with the way that we do logging for change commands with
53 * implied motions (e.g. A, I, O, cc, etc.). Since the main vi loop logs the
54 * starting cursor position before the change command "moves" the cursor, the
55 * cursor position to which we return on undo will be where the user entered
56 * the change command, not the start of the change. Several of the following
57 * routines re-log the cursor to make this work correctly. Historic vi tried
58 * to do the same thing, and mostly got it right. (The only spectacular way
59 * it fails is if the user entered 'o' from anywhere but the last character of
60 * the line, the undo returned the cursor to the start of the line. If the
61 * user was on the last character of the line, the cursor returned to that
62 * position.)
65 static int v_CS __P((SCR *, EXF *, VICMDARG *, MARK *, MARK *, MARK *, u_int));
68 * v_iA -- [count]A
69 * Append text to the end of the line.
71 int
72 v_iA(sp, ep, vp, fm, tm, rp)
73 SCR *sp;
74 EXF *ep;
75 VICMDARG *vp;
76 MARK *fm, *tm, *rp;
78 recno_t lno;
79 u_long cnt;
80 size_t len;
81 u_int flags;
82 int first;
83 char *p;
85 SET_TXT_STD(sp, TXT_APPENDEOL);
86 if (F_ISSET(vp, VC_ISDOT))
87 LF_SET(TXT_REPLAY);
88 for (first = 1, lno = fm->lno,
89 cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
90 /* Move the cursor to the end of the line + 1. */
91 if ((p = file_gline(sp, ep, lno, &len)) == NULL) {
92 if (file_lline(sp, ep, &lno))
93 return (1);
94 if (lno != 0) {
95 GETLINE_ERR(sp, lno);
96 return (1);
98 lno = 1;
99 len = 0;
100 } else {
101 /* Correct logging for implied cursor motion. */
102 sp->cno = len == 0 ? 0 : len - 1;
103 if (first == 1) {
104 log_cursor(sp, ep);
105 first = 0;
107 /* Start the change after the line. */
108 sp->cno = len;
111 if (v_ntext(sp, ep,
112 &sp->tiq, NULL, p, len, rp, 0, OOBLNO, flags))
113 return (1);
115 SET_TXT_STD(sp, TXT_APPENDEOL | TXT_REPLAY);
116 sp->lno = lno = rp->lno;
117 sp->cno = rp->cno;
119 return (0);
123 * v_ia -- [count]a
124 * Append text to the cursor position.
127 v_ia(sp, ep, vp, fm, tm, rp)
128 SCR *sp;
129 EXF *ep;
130 VICMDARG *vp;
131 MARK *fm, *tm, *rp;
133 recno_t lno;
134 u_long cnt;
135 u_int flags;
136 size_t len;
137 char *p;
139 SET_TXT_STD(sp, 0);
140 if (F_ISSET(vp, VC_ISDOT))
141 LF_SET(TXT_REPLAY);
142 for (lno = fm->lno,
143 cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
145 * Move the cursor one column to the right and
146 * repaint the screen.
148 if ((p = file_gline(sp, ep, lno, &len)) == NULL) {
149 if (file_lline(sp, ep, &lno))
150 return (1);
151 if (lno != 0) {
152 GETLINE_ERR(sp, lno);
153 return (1);
155 lno = 1;
156 len = 0;
157 LF_SET(TXT_APPENDEOL);
158 } else if (len) {
159 if (len == sp->cno + 1) {
160 sp->cno = len;
161 LF_SET(TXT_APPENDEOL);
162 } else
163 ++sp->cno;
164 } else
165 LF_SET(TXT_APPENDEOL);
167 if (v_ntext(sp, ep,
168 &sp->tiq, NULL, p, len, rp, 0, OOBLNO, flags))
169 return (1);
171 SET_TXT_STD(sp, TXT_REPLAY);
172 sp->lno = lno = rp->lno;
173 sp->cno = rp->cno;
175 return (0);
179 * v_iI -- [count]I
180 * Insert text at the first non-blank character in the line.
183 v_iI(sp, ep, vp, fm, tm, rp)
184 SCR *sp;
185 EXF *ep;
186 VICMDARG *vp;
187 MARK *fm, *tm, *rp;
189 recno_t lno;
190 u_long cnt;
191 size_t len;
192 u_int flags;
193 int first;
194 char *p;
196 SET_TXT_STD(sp, 0);
197 if (F_ISSET(vp, VC_ISDOT))
198 LF_SET(TXT_REPLAY);
199 for (first = 1, lno = fm->lno,
200 cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
202 * Move the cursor to the start of the line and repaint
203 * the screen.
205 if ((p = file_gline(sp, ep, lno, &len)) == NULL) {
206 if (file_lline(sp, ep, &lno))
207 return (1);
208 if (lno != 0) {
209 GETLINE_ERR(sp, lno);
210 return (1);
212 lno = 1;
213 len = 0;
214 } else {
215 sp->cno = 0;
216 if (nonblank(sp, ep, lno, &sp->cno))
217 return (1);
218 /* Correct logging for implied cursor motion. */
219 if (first == 1) {
220 log_cursor(sp, ep);
221 first = 0;
224 if (len == 0)
225 LF_SET(TXT_APPENDEOL);
227 if (v_ntext(sp, ep,
228 &sp->tiq, NULL, p, len, rp, 0, OOBLNO, flags))
229 return (1);
231 SET_TXT_STD(sp, TXT_REPLAY);
232 sp->lno = lno = rp->lno;
233 sp->cno = rp->cno;
235 return (0);
239 * v_ii -- [count]i
240 * Insert text at the cursor position.
243 v_ii(sp, ep, vp, fm, tm, rp)
244 SCR *sp;
245 EXF *ep;
246 VICMDARG *vp;
247 MARK *fm, *tm, *rp;
249 recno_t lno;
250 u_long cnt;
251 size_t len;
252 u_int flags;
253 char *p;
255 SET_TXT_STD(sp, 0);
256 if (F_ISSET(vp, VC_ISDOT))
257 LF_SET(TXT_REPLAY);
258 for (lno = fm->lno,
259 cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
260 if ((p = file_gline(sp, ep, lno, &len)) == NULL) {
261 if (file_lline(sp, ep, &lno))
262 return (1);
263 if (lno != 0) {
264 GETLINE_ERR(sp, fm->lno);
265 return (1);
267 lno = 1;
268 len = 0;
270 /* If len == sp->cno, it's a replay caused by a count. */
271 if (len == 0 || len == sp->cno)
272 LF_SET(TXT_APPENDEOL);
274 if (v_ntext(sp, ep,
275 &sp->tiq, NULL, p, len, rp, 0, OOBLNO, flags))
276 return (1);
279 * On replay, if the line isn't empty, advance the insert
280 * by one (make it an append).
282 SET_TXT_STD(sp, TXT_REPLAY);
283 sp->lno = lno = rp->lno;
284 if ((sp->cno = rp->cno) != 0)
285 ++sp->cno;
287 return (0);
291 * v_iO -- [count]O
292 * Insert text above this line.
295 v_iO(sp, ep, vp, fm, tm, rp)
296 SCR *sp;
297 EXF *ep;
298 VICMDARG *vp;
299 MARK *fm, *tm, *rp;
301 recno_t ai_line, lno;
302 size_t len;
303 u_long cnt;
304 u_int flags;
305 int first;
306 char *p;
308 SET_TXT_STD(sp, TXT_APPENDEOL);
309 if (F_ISSET(vp, VC_ISDOT))
310 LF_SET(TXT_REPLAY);
311 for (first = 1, cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
312 if (sp->lno == 1) {
313 if (file_lline(sp, ep, &lno))
314 return (1);
315 if (lno != 0)
316 goto insert;
317 p = NULL;
318 len = 0;
319 ai_line = OOBLNO;
320 } else {
321 insert: p = "";
322 sp->cno = 0;
323 /* Correct logging for implied cursor motion. */
324 if (first == 1) {
325 log_cursor(sp, ep);
326 first = 0;
328 if (file_iline(sp, ep, sp->lno, p, 0))
329 return (1);
330 if ((p = file_gline(sp, ep, sp->lno, &len)) == NULL) {
331 GETLINE_ERR(sp, sp->lno);
332 return (1);
334 ai_line = sp->lno + 1;
337 if (v_ntext(sp, ep,
338 &sp->tiq, NULL, p, len, rp, 0, ai_line, flags))
339 return (1);
341 SET_TXT_STD(sp, TXT_APPENDEOL | TXT_REPLAY);
342 sp->lno = lno = rp->lno;
343 sp->cno = rp->cno;
345 return (0);
349 * v_io -- [count]o
350 * Insert text after this line.
353 v_io(sp, ep, vp, fm, tm, rp)
354 SCR *sp;
355 EXF *ep;
356 VICMDARG *vp;
357 MARK *fm, *tm, *rp;
359 recno_t ai_line, lno;
360 size_t len;
361 u_long cnt;
362 u_int flags;
363 int first;
364 char *p;
366 SET_TXT_STD(sp, TXT_APPENDEOL);
367 if (F_ISSET(vp, VC_ISDOT))
368 LF_SET(TXT_REPLAY);
369 for (first = 1,
370 cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1; cnt--;) {
371 if (sp->lno == 1) {
372 if (file_lline(sp, ep, &lno))
373 return (1);
374 if (lno != 0)
375 goto insert;
376 p = NULL;
377 len = 0;
378 ai_line = OOBLNO;
379 } else {
380 insert: p = "";
381 sp->cno = 0;
382 /* Correct logging for implied cursor motion. */
383 if (first == 1) {
384 log_cursor(sp, ep);
385 first = 0;
387 len = 0;
388 if (file_aline(sp, ep, 1, sp->lno, p, len))
389 return (1);
390 if ((p = file_gline(sp, ep, ++sp->lno, &len)) == NULL) {
391 GETLINE_ERR(sp, sp->lno);
392 return (1);
394 ai_line = sp->lno - 1;
397 if (v_ntext(sp, ep,
398 &sp->tiq, NULL, p, len, rp, 0, ai_line, flags))
399 return (1);
401 SET_TXT_STD(sp, TXT_APPENDEOL | TXT_REPLAY);
402 sp->lno = lno = rp->lno;
403 sp->cno = rp->cno;
405 return (0);
409 * v_Change -- [buffer][count]C
410 * Change line command.
413 v_Change(sp, ep, vp, fm, tm, rp)
414 SCR *sp;
415 EXF *ep;
416 VICMDARG *vp;
417 MARK *fm, *tm, *rp;
419 return (v_CS(sp, ep, vp, fm, tm, rp, 0));
423 * v_Subst -- [buffer][count]S
424 * Line substitute command.
427 v_Subst(sp, ep, vp, fm, tm, rp)
428 SCR *sp;
429 EXF *ep;
430 VICMDARG *vp;
431 MARK *fm, *tm, *rp;
433 u_int flags;
436 * The S command is the same as a 'C' command from the beginning
437 * of the line. This is hard to do in the parser, so do it here.
439 * If autoindent is on, the change is from the first *non-blank*
440 * character of the line, not the first character. And, to make
441 * it just a bit more exciting, the initial space is handled as
442 * auto-indent characters.
444 LF_INIT(0);
445 if (O_ISSET(sp, O_AUTOINDENT)) {
446 fm->cno = 0;
447 if (nonblank(sp, ep, fm->lno, &fm->cno))
448 return (1);
449 LF_SET(TXT_AICHARS);
450 } else
451 fm->cno = 0;
452 sp->cno = fm->cno;
453 return (v_CS(sp, ep, vp, fm, tm, rp, flags));
457 * v_CS --
458 * C and S commands.
460 static int
461 v_CS(sp, ep, vp, fm, tm, rp, iflags)
462 SCR *sp;
463 EXF *ep;
464 VICMDARG *vp;
465 MARK *fm, *tm, *rp;
466 u_int iflags;
468 recno_t lno;
469 size_t len;
470 char *p;
471 u_int flags;
473 SET_TXT_STD(sp, iflags);
474 if (F_ISSET(vp, VC_ISDOT))
475 LF_SET(TXT_REPLAY);
478 * There are two cases -- if a count is supplied, we do a line
479 * mode change where we delete the lines and then insert text
480 * into a new line. Otherwise, we replace the current line.
482 tm->lno = fm->lno + (F_ISSET(vp, VC_C1SET) ? vp->count - 1 : 0);
483 if (fm->lno != tm->lno) {
484 /* Make sure that the to line is real. */
485 if (file_gline(sp, ep, tm->lno, NULL) == NULL) {
486 v_eof(sp, ep, fm);
487 return (1);
490 /* Cut the lines. */
491 if (cut(sp, ep,
492 NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
493 fm, tm, CUT_LINEMODE))
494 return (1);
496 /* Insert a line while we still can... */
497 if (file_iline(sp, ep, fm->lno, "", 0))
498 return (1);
499 ++fm->lno;
500 ++tm->lno;
502 /* Delete the lines. */
503 if (delete(sp, ep, fm, tm, 1))
504 return (1);
506 /* Get the inserted line. */
507 if ((p = file_gline(sp, ep, --fm->lno, &len)) == NULL) {
508 GETLINE_ERR(sp, fm->lno);
509 return (1);
511 tm = NULL;
512 sp->lno = fm->lno;
513 sp->cno = 0;
514 LF_SET(TXT_APPENDEOL);
515 } else {
516 /* The line may be empty, but that's okay. */
517 if ((p = file_gline(sp, ep, fm->lno, &len)) == NULL) {
518 if (file_lline(sp, ep, &lno))
519 return (1);
520 if (lno != 0) {
521 GETLINE_ERR(sp, tm->lno);
522 return (1);
524 len = 0;
525 LF_SET(TXT_APPENDEOL);
526 } else {
527 if (cut(sp, ep,
528 NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
529 fm, tm, CUT_LINEMODE))
530 return (1);
531 tm->cno = len;
532 if (len == 0)
533 LF_SET(TXT_APPENDEOL);
534 LF_SET(TXT_EMARK | TXT_OVERWRITE);
537 /* Correct logging for implied cursor motion. */
538 log_cursor(sp, ep);
539 return (v_ntext(sp, ep,
540 &sp->tiq, tm, p, len, rp, 0, OOBLNO, flags));
544 * v_change -- [buffer][count]c[count]motion
545 * Change command.
548 v_change(sp, ep, vp, fm, tm, rp)
549 SCR *sp;
550 EXF *ep;
551 VICMDARG *vp;
552 MARK *fm, *tm, *rp;
554 recno_t lno;
555 size_t blen, len;
556 u_int flags;
557 int lmode, rval;
558 char *bp, *p;
560 SET_TXT_STD(sp, 0);
561 if (F_ISSET(vp, VC_ISDOT))
562 LF_SET(TXT_REPLAY);
565 * Move the cursor to the start of the change. Note, if autoindent
566 * is turned on, the cc command in line mode changes from the first
567 * *non-blank* character of the line, not the first character. And,
568 * to make it just a bit more exciting, the initial space is handled
569 * as auto-indent characters.
571 lmode = F_ISSET(vp, VC_LMODE) ? CUT_LINEMODE : 0;
572 if (lmode) {
573 fm->cno = 0;
574 if (O_ISSET(sp, O_AUTOINDENT)) {
575 if (nonblank(sp, ep, fm->lno, &fm->cno))
576 return (1);
577 LF_SET(TXT_AICHARS);
580 sp->lno = fm->lno;
581 sp->cno = fm->cno;
583 /* Correct logging for implied cursor motion. */
584 log_cursor(sp, ep);
587 * If changing within a single line, the line either currently has
588 * text or it doesn't. If it doesn't, just insert text. Otherwise,
589 * copy it and overwrite it.
591 if (fm->lno == tm->lno) {
592 if ((p = file_gline(sp, ep, fm->lno, &len)) == NULL) {
593 if (p == NULL) {
594 if (file_lline(sp, ep, &lno))
595 return (1);
596 if (lno != 0) {
597 GETLINE_ERR(sp, fm->lno);
598 return (1);
601 len = 0;
602 LF_SET(TXT_APPENDEOL);
603 } else {
604 if (cut(sp, ep,
605 NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL,
606 fm, tm, lmode))
607 return (1);
608 if (len == 0)
609 LF_SET(TXT_APPENDEOL);
610 LF_SET(TXT_EMARK | TXT_OVERWRITE);
612 return (v_ntext(sp, ep,
613 &sp->tiq, tm, p, len, rp, 0, OOBLNO, flags));
617 * It's trickier if changing over multiple lines. If we're in
618 * line mode we delete all of the lines and insert a replacement
619 * line which the user edits. If there was leading whitespace
620 * in the first line being changed, we copy it and use it as the
621 * replacement. If we're not in line mode, we just delete the
622 * text and start inserting.
624 * Copy the text.
626 if (cut(sp, ep,
627 NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL, fm, tm, lmode))
628 return (1);
630 /* If replacing entire lines and there's leading text. */
631 if (lmode && fm->cno) {
632 /* Get a copy of the first line changed. */
633 if ((p = file_gline(sp, ep, fm->lno, &len)) == NULL) {
634 GETLINE_ERR(sp, fm->lno);
635 return (1);
637 /* Copy the leading text elsewhere. */
638 GET_SPACE_RET(sp, bp, blen, fm->cno);
639 memmove(bp, p, fm->cno);
640 } else
641 bp = NULL;
643 /* Delete the text. */
644 if (delete(sp, ep, fm, tm, lmode))
645 return (1);
647 /* If replacing entire lines, insert a replacement line. */
648 if (lmode) {
649 if (file_iline(sp, ep, fm->lno, bp, fm->cno))
650 return (1);
651 sp->lno = fm->lno;
652 len = sp->cno = fm->cno;
655 /* Get the line we're editing. */
656 if ((p = file_gline(sp, ep, fm->lno, &len)) == NULL) {
657 if (file_lline(sp, ep, &lno))
658 return (1);
659 if (lno != 0) {
660 GETLINE_ERR(sp, fm->lno);
661 return (1);
663 len = 0;
666 /* Check to see if we're appending to the line. */
667 if (fm->cno >= len)
668 LF_SET(TXT_APPENDEOL);
670 /* No to mark. */
671 tm = NULL;
673 rval = v_ntext(sp, ep, &sp->tiq, tm, p, len, rp, 0, OOBLNO, flags);
675 if (bp != NULL)
676 FREE_SPACE(sp, bp, blen);
677 return (rval);
681 * v_Replace -- [count]R
682 * Overwrite multiple characters.
685 v_Replace(sp, ep, vp, fm, tm, rp)
686 SCR *sp;
687 EXF *ep;
688 VICMDARG *vp;
689 MARK *fm, *tm, *rp;
691 recno_t lno;
692 u_long cnt;
693 size_t len;
694 u_int flags;
695 char *p;
697 SET_TXT_STD(sp, 0);
698 if (F_ISSET(vp, VC_ISDOT))
699 LF_SET(TXT_REPLAY);
701 cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1;
702 if ((p = file_gline(sp, ep, rp->lno, &len)) == NULL) {
703 if (file_lline(sp, ep, &lno))
704 return (1);
705 if (lno != 0) {
706 GETLINE_ERR(sp, rp->lno);
707 return (1);
709 len = 0;
710 LF_SET(TXT_APPENDEOL);
711 } else {
712 if (len == 0)
713 LF_SET(TXT_APPENDEOL);
714 LF_SET(TXT_OVERWRITE | TXT_REPLACE);
716 tm->lno = rp->lno;
717 tm->cno = len ? len : 0;
718 if (v_ntext(sp, ep, &sp->tiq, tm, p, len, rp, 0, OOBLNO, flags))
719 return (1);
722 * Special case. The historic vi handled [count]R badly, in that R
723 * would replace some number of characters, and then the count would
724 * append count-1 copies of the replacing chars to the replaced space.
725 * This seems wrong, so this version counts R commands. There is some
726 * trickiness in moving back to where the user stopped replacing after
727 * each R command. Basically, if the user ended with a newline, we
728 * want to use rp->cno (which will be 0). Otherwise, use the column
729 * after the returned cursor, unless it would be past the end of the
730 * line, in which case we append to the line.
732 while (--cnt) {
733 if ((p = file_gline(sp, ep, rp->lno, &len)) == NULL)
734 GETLINE_ERR(sp, rp->lno);
735 SET_TXT_STD(sp, TXT_REPLAY);
737 sp->lno = rp->lno;
739 if (len == 0 || rp->cno == len - 1) {
740 sp->cno = len;
741 LF_SET(TXT_APPENDEOL);
742 } else {
743 sp->cno = rp->cno;
744 if (rp->cno != 0)
745 ++sp->cno;
746 LF_SET(TXT_OVERWRITE | TXT_REPLACE);
749 if (v_ntext(sp, ep,
750 &sp->tiq, tm, p, len, rp, 0, OOBLNO, flags))
751 return (1);
753 return (0);
757 * v_subst -- [buffer][count]s
758 * Substitute characters.
761 v_subst(sp, ep, vp, fm, tm, rp)
762 SCR *sp;
763 EXF *ep;
764 VICMDARG *vp;
765 MARK *fm, *tm, *rp;
767 recno_t lno;
768 size_t len;
769 u_int flags;
770 char *p;
772 SET_TXT_STD(sp, 0);
773 if (F_ISSET(vp, VC_ISDOT))
774 LF_SET(TXT_REPLAY);
775 if ((p = file_gline(sp, ep, fm->lno, &len)) == NULL) {
776 if (file_lline(sp, ep, &lno))
777 return (1);
778 if (lno != 0) {
779 GETLINE_ERR(sp, fm->lno);
780 return (1);
782 len = 0;
783 LF_SET(TXT_APPENDEOL);
784 } else {
785 if (len == 0)
786 LF_SET(TXT_APPENDEOL);
787 LF_SET(TXT_EMARK | TXT_OVERWRITE);
790 tm->lno = fm->lno;
791 tm->cno = fm->cno + (F_ISSET(vp, VC_C1SET) ? vp->count : 1);
792 if (tm->cno > len)
793 tm->cno = len;
795 if (p != NULL && cut(sp, ep,
796 NULL, F_ISSET(vp, VC_BUFFER) ? &vp->buffer : NULL, fm, tm, 0))
797 return (1);
799 return (v_ntext(sp, ep,
800 &sp->tiq, tm, p, len, rp, 0, OOBLNO, flags));