discard the old line before updating the screen so that the line
[nvi.git] / vi / v_itxt.c
blob2e34c4e16c52a89f62218cc5e78ab99dfb0c0598
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.21 1993/12/29 12:30:28 bostic Exp $ (Berkeley) $Date: 1993/12/29 12:30:28 $";
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, *t;
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 F_ISSET(vp, VC_BUFFER) ? vp->buffer : DEFCB, fm, tm, 1))
493 return (1);
495 /* Insert a line while we still can... */
496 if (file_iline(sp, ep, fm->lno, "", 0))
497 return (1);
498 ++fm->lno;
499 ++tm->lno;
501 /* Delete the lines. */
502 if (delete(sp, ep, fm, tm, 1))
503 return (1);
505 /* Get the inserted line. */
506 if ((p = file_gline(sp, ep, --fm->lno, &len)) == NULL) {
507 GETLINE_ERR(sp, fm->lno);
508 return (1);
510 tm = NULL;
511 sp->lno = fm->lno;
512 sp->cno = 0;
513 LF_SET(TXT_APPENDEOL);
514 } else {
515 /* The line may be empty, but that's okay. */
516 if ((p = file_gline(sp, ep, fm->lno, &len)) == NULL) {
517 if (file_lline(sp, ep, &lno))
518 return (1);
519 if (lno != 0) {
520 GETLINE_ERR(sp, tm->lno);
521 return (1);
523 len = 0;
524 LF_SET(TXT_APPENDEOL);
525 } else {
526 if (cut(sp, ep,
527 F_ISSET(vp, VC_BUFFER) ? vp->buffer : DEFCB,
528 fm, tm, 1))
529 return (1);
530 tm->cno = len;
531 if (len == 0)
532 LF_SET(TXT_APPENDEOL);
533 LF_SET(TXT_EMARK | TXT_OVERWRITE);
536 /* Correct logging for implied cursor motion. */
537 log_cursor(sp, ep);
538 return (v_ntext(sp, ep,
539 &sp->tiq, tm, p, len, rp, 0, OOBLNO, flags));
543 * v_change -- [buffer][count]c[count]motion
544 * Change command.
547 v_change(sp, ep, vp, fm, tm, rp)
548 SCR *sp;
549 EXF *ep;
550 VICMDARG *vp;
551 MARK *fm, *tm, *rp;
553 recno_t lno;
554 size_t blen, len;
555 u_int flags;
556 int lmode, rval;
557 char *bp, *p;
559 SET_TXT_STD(sp, 0);
560 if (F_ISSET(vp, VC_ISDOT))
561 LF_SET(TXT_REPLAY);
564 * Move the cursor to the start of the change. Note, if autoindent
565 * is turned on, the cc command in line mode changes from the first
566 * *non-blank* character of the line, not the first character. And,
567 * to make it just a bit more exciting, the initial space is handled
568 * as auto-indent characters.
570 if (lmode = F_ISSET(vp, VC_LMODE)) {
571 fm->cno = 0;
572 if (O_ISSET(sp, O_AUTOINDENT)) {
573 if (nonblank(sp, ep, fm->lno, &fm->cno))
574 return (1);
575 LF_SET(TXT_AICHARS);
578 sp->lno = fm->lno;
579 sp->cno = fm->cno;
581 /* Correct logging for implied cursor motion. */
582 log_cursor(sp, ep);
585 * If changing within a single line, the line either currently has
586 * text or it doesn't. If it doesn't, just insert text. Otherwise,
587 * copy it and overwrite it.
589 if (fm->lno == tm->lno) {
590 if ((p = file_gline(sp, ep, fm->lno, &len)) == NULL) {
591 if (p == NULL) {
592 if (file_lline(sp, ep, &lno))
593 return (1);
594 if (lno != 0) {
595 GETLINE_ERR(sp, fm->lno);
596 return (1);
599 len = 0;
600 LF_SET(TXT_APPENDEOL);
601 } else {
602 if (cut(sp, ep,
603 F_ISSET(vp, VC_BUFFER) ? vp->buffer : DEFCB,
604 fm, tm, lmode))
605 return (1);
606 if (len == 0)
607 LF_SET(TXT_APPENDEOL);
608 LF_SET(TXT_EMARK | TXT_OVERWRITE);
610 return (v_ntext(sp, ep,
611 &sp->tiq, tm, p, len, rp, 0, OOBLNO, flags));
615 * It's trickier if changing over multiple lines. If we're in
616 * line mode we delete all of the lines and insert a replacement
617 * line which the user edits. If there was leading whitespace
618 * in the first line being changed, we copy it and use it as the
619 * replacement. If we're not in line mode, we just delete the
620 * text and start inserting.
622 * Copy the text.
624 if (cut(sp, ep,
625 F_ISSET(vp, VC_BUFFER) ? vp->buffer : DEFCB, fm, tm, lmode))
626 return (1);
628 /* If replacing entire lines and there's leading text. */
629 if (lmode && fm->cno) {
630 /* Get a copy of the first line changed. */
631 if ((p = file_gline(sp, ep, fm->lno, &len)) == NULL) {
632 GETLINE_ERR(sp, fm->lno);
633 return (1);
635 /* Copy the leading text elsewhere. */
636 GET_SPACE_RET(sp, bp, blen, fm->cno);
637 memmove(bp, p, fm->cno);
638 } else
639 bp = NULL;
641 /* Delete the text. */
642 if (delete(sp, ep, fm, tm, lmode))
643 return (1);
645 /* If replacing entire lines, insert a replacement line. */
646 if (lmode) {
647 if (file_iline(sp, ep, fm->lno, bp, fm->cno))
648 return (1);
649 sp->lno = fm->lno;
650 len = sp->cno = fm->cno;
653 /* Get the line we're editing. */
654 if ((p = file_gline(sp, ep, fm->lno, &len)) == NULL) {
655 if (file_lline(sp, ep, &lno))
656 return (1);
657 if (lno != 0) {
658 GETLINE_ERR(sp, fm->lno);
659 return (1);
661 len = 0;
664 /* Check to see if we're appending to the line. */
665 if (fm->cno >= len)
666 LF_SET(TXT_APPENDEOL);
668 /* No to mark. */
669 tm = NULL;
671 rval = v_ntext(sp, ep, &sp->tiq, tm, p, len, rp, 0, OOBLNO, flags);
673 if (bp != NULL)
674 FREE_SPACE(sp, bp, blen);
675 return (rval);
679 * v_Replace -- [count]R
680 * Overwrite multiple characters.
683 v_Replace(sp, ep, vp, fm, tm, rp)
684 SCR *sp;
685 EXF *ep;
686 VICMDARG *vp;
687 MARK *fm, *tm, *rp;
689 recno_t lno;
690 u_long cnt;
691 size_t len;
692 u_int flags;
693 char *p;
695 SET_TXT_STD(sp, 0);
696 if (F_ISSET(vp, VC_ISDOT))
697 LF_SET(TXT_REPLAY);
699 cnt = F_ISSET(vp, VC_C1SET) ? vp->count : 1;
700 if ((p = file_gline(sp, ep, rp->lno, &len)) == NULL) {
701 if (file_lline(sp, ep, &lno))
702 return (1);
703 if (lno != 0) {
704 GETLINE_ERR(sp, rp->lno);
705 return (1);
707 len = 0;
708 LF_SET(TXT_APPENDEOL);
709 } else {
710 if (len == 0)
711 LF_SET(TXT_APPENDEOL);
712 LF_SET(TXT_OVERWRITE | TXT_REPLACE);
714 tm->lno = rp->lno;
715 tm->cno = len ? len : 0;
716 if (v_ntext(sp, ep, &sp->tiq, tm, p, len, rp, 0, OOBLNO, flags))
717 return (1);
720 * Special case. The historic vi handled [count]R badly, in that R
721 * would replace some number of characters, and then the count would
722 * append count-1 copies of the replacing chars to the replaced space.
723 * This seems wrong, so this version counts R commands. There is some
724 * trickiness in moving back to where the user stopped replacing after
725 * each R command. Basically, if the user ended with a newline, we
726 * want to use rp->cno (which will be 0). Otherwise, use the column
727 * after the returned cursor, unless it would be past the end of the
728 * line, in which case we append to the line.
730 while (--cnt) {
731 if ((p = file_gline(sp, ep, rp->lno, &len)) == NULL)
732 GETLINE_ERR(sp, rp->lno);
733 SET_TXT_STD(sp, TXT_REPLAY);
735 sp->lno = rp->lno;
737 if (len == 0 || rp->cno == len - 1) {
738 sp->cno = len;
739 LF_SET(TXT_APPENDEOL);
740 } else {
741 sp->cno = rp->cno;
742 if (rp->cno != 0)
743 ++sp->cno;
744 LF_SET(TXT_OVERWRITE | TXT_REPLACE);
747 if (v_ntext(sp, ep,
748 &sp->tiq, tm, p, len, rp, 0, OOBLNO, flags))
749 return (1);
751 return (0);
755 * v_subst -- [buffer][count]s
756 * Substitute characters.
759 v_subst(sp, ep, vp, fm, tm, rp)
760 SCR *sp;
761 EXF *ep;
762 VICMDARG *vp;
763 MARK *fm, *tm, *rp;
765 recno_t lno;
766 size_t len;
767 u_int flags;
768 char *p;
770 SET_TXT_STD(sp, 0);
771 if (F_ISSET(vp, VC_ISDOT))
772 LF_SET(TXT_REPLAY);
773 if ((p = file_gline(sp, ep, fm->lno, &len)) == NULL) {
774 if (file_lline(sp, ep, &lno))
775 return (1);
776 if (lno != 0) {
777 GETLINE_ERR(sp, fm->lno);
778 return (1);
780 len = 0;
781 LF_SET(TXT_APPENDEOL);
782 } else {
783 if (len == 0)
784 LF_SET(TXT_APPENDEOL);
785 LF_SET(TXT_EMARK | TXT_OVERWRITE);
788 tm->lno = fm->lno;
789 tm->cno = fm->cno + (F_ISSET(vp, VC_C1SET) ? vp->count : 1);
790 if (tm->cno > len)
791 tm->cno = len;
793 if (p != NULL && cut(sp, ep,
794 F_ISSET(vp, VC_BUFFER) ? vp->buffer : DEFCB, fm, tm, 0))
795 return (1);
797 return (v_ntext(sp, ep,
798 &sp->tiq, tm, p, len, rp, 0, OOBLNO, flags));