1 /* $NetBSD: vs_msg.c,v 1.6 2014/01/26 21:43:45 christos Exp $ */
3 * Copyright (c) 1993, 1994
4 * The Regents of the University of California. All rights reserved.
5 * Copyright (c) 1992, 1993, 1994, 1995, 1996
6 * Keith Bostic. All rights reserved.
8 * See the LICENSE file for redistribution information.
13 #include <sys/cdefs.h>
16 static const char sccsid
[] = "Id: vs_msg.c,v 10.85 2001/07/29 19:07:31 skimo Exp (Berkeley) Date: 2001/07/29 19:07:31 ";
19 __RCSID("$NetBSD: vs_msg.c,v 1.6 2014/01/26 21:43:45 christos Exp $");
22 #include <sys/types.h>
23 #include <sys/queue.h>
26 #include <bitstring.h>
33 #include "../common/common.h"
37 SCROLL_W
, /* User wait. */
38 SCROLL_W_EX
, /* User wait, or enter : to continue. */
39 SCROLL_W_QUIT
/* User wait, or enter q to quit. */
41 * SCROLL_W_QUIT has another semantic
42 * -- only wait if the screen is full
46 static void vs_divider
__P((SCR
*));
47 static void vs_msgsave
__P((SCR
*, mtype_t
, char *, size_t));
48 static void vs_output
__P((SCR
*, mtype_t
, const char *, int));
49 static void vs_scroll
__P((SCR
*, int *, sw_t
));
50 static void vs_wait
__P((SCR
*, int *, sw_t
));
54 * Display, update or clear a busy message.
56 * This routine is the default editor interface for vi busy messages. It
57 * implements a standard strategy of stealing lines from the bottom of the
58 * vi text screen. Screens using an alternate method of displaying busy
59 * messages, e.g. X11 clock icons, should set their scr_busy function to the
60 * correct function before calling the main editor routine.
62 * PUBLIC: void vs_busy __P((SCR *, const char *, busy_t));
65 vs_busy(SCR
*sp
, const char *msg
, busy_t btype
)
69 static const char flagc
[] = "|/-\\";
74 /* Ex doesn't display busy messages. */
75 if (F_ISSET(sp
, SC_EX
| SC_SCR_EXWROTE
))
82 * Most of this routine is to deal with the screen sharing real estate
83 * between the normal edit messages and the busy messages. Logically,
84 * all that's needed is something that puts up a message, periodically
85 * updates it, and then goes away.
90 if (vip
->totalcount
!= 0 || vip
->busy_ref
!= 1)
93 /* Initialize state for updates. */
95 (void)gettimeofday(&vip
->busy_tv
, NULL
);
97 /* Save the current cursor. */
98 (void)gp
->scr_cursor(sp
, &vip
->busy_oldy
, &vip
->busy_oldx
);
100 /* Display the busy message. */
101 p
= msg_cat(sp
, msg
, &len
);
102 (void)gp
->scr_move(sp
, LASTLINE(sp
), 0);
103 (void)gp
->scr_addstr(sp
, p
, len
);
104 (void)gp
->scr_cursor(sp
, ¬used
, &vip
->busy_fx
);
105 (void)gp
->scr_clrtoeol(sp
);
106 (void)gp
->scr_move(sp
, LASTLINE(sp
), vip
->busy_fx
);
109 if (vip
->busy_ref
== 0)
114 * If the line isn't in use for another purpose, clear it.
115 * Always return to the original position.
117 if (vip
->totalcount
== 0 && vip
->busy_ref
== 0) {
118 (void)gp
->scr_move(sp
, LASTLINE(sp
), 0);
119 (void)gp
->scr_clrtoeol(sp
);
121 (void)gp
->scr_move(sp
, vip
->busy_oldy
, vip
->busy_oldx
);
124 if (vip
->totalcount
!= 0 || vip
->busy_ref
== 0)
127 /* Update no more than every 1/8 of a second. */
128 (void)gettimeofday(&tv
, NULL
);
129 if (((tv
.tv_sec
- vip
->busy_tv
.tv_sec
) * 1000000 +
130 (tv
.tv_usec
- vip
->busy_tv
.tv_usec
)) < 125000)
134 /* Display the update. */
135 if (vip
->busy_ch
== sizeof(flagc
) - 1)
137 (void)gp
->scr_move(sp
, LASTLINE(sp
), vip
->busy_fx
);
138 (void)gp
->scr_addstr(sp
, flagc
+ vip
->busy_ch
++, 1);
139 (void)gp
->scr_move(sp
, LASTLINE(sp
), vip
->busy_fx
);
142 (void)gp
->scr_refresh(sp
, 0);
147 * Home the cursor to the bottom row, left-most column.
149 * PUBLIC: void vs_home __P((SCR *));
154 (void)sp
->gp
->scr_move(sp
, LASTLINE(sp
), 0);
155 (void)sp
->gp
->scr_refresh(sp
, 0);
162 * PUBLIC: void vs_update __P((SCR *, const char *, const CHAR_T *));
165 vs_update(SCR
*sp
, const char *m1
, const CHAR_T
*m2
)
168 size_t len
, mlen
, oldx
, oldy
;
175 * This routine displays a message on the bottom line of the screen,
176 * without updating any of the command structures that would keep it
177 * there for any period of time, i.e. it is overwritten immediately.
179 * It's used by the ex read and ! commands when the user's command is
180 * expanded, and by the ex substitution confirmation prompt.
182 if (F_ISSET(sp
, SC_SCR_EXWROTE
)) {
184 INT2CHAR(sp
, m2
, STRLEN(m2
) + 1, np
, nlen
);
186 "%s%s\n", m1
== NULL
? "" : m1
, m2
== NULL
? "" : np
);
191 * Save the cursor position, the substitute-with-confirmation code
192 * will have already set it correctly.
194 (void)gp
->scr_cursor(sp
, &oldy
, &oldx
);
196 /* Clear the bottom line. */
197 (void)gp
->scr_move(sp
, LASTLINE(sp
), 0);
198 (void)gp
->scr_clrtoeol(sp
);
202 * Don't let long file names screw up the screen.
205 mlen
= len
= strlen(m1
);
206 if (len
> sp
->cols
- 2)
207 mlen
= len
= sp
->cols
- 2;
208 (void)gp
->scr_addstr(sp
, m1
, mlen
);
213 if (len
+ mlen
> sp
->cols
- 2)
214 mlen
= (sp
->cols
- 2) - len
;
215 (void)gp
->scr_waddstr(sp
, m2
, mlen
);
218 (void)gp
->scr_move(sp
, oldy
, oldx
);
219 (void)gp
->scr_refresh(sp
, 0);
224 * Display ex output or error messages for the screen.
226 * This routine is the default editor interface for all ex output, and all ex
227 * and vi error/informational messages. It implements the standard strategy
228 * of stealing lines from the bottom of the vi text screen. Screens using an
229 * alternate method of displaying messages, e.g. dialog boxes, should set their
230 * scr_msg function to the correct function before calling the editor.
232 * PUBLIC: void vs_msg __P((SCR *, mtype_t, char *, size_t));
235 vs_msg(SCR
*sp
, mtype_t mtype
, char *line
, size_t len
)
239 size_t maxcols
, oldx
, oldy
, padding
;
240 const char *e
, *s
, *t
;
246 * Ring the bell if it's scheduled.
249 * Shouldn't we save this, too?
251 if (F_ISSET(sp
, SC_TINPUT_INFO
) || F_ISSET(gp
, G_BELLSCHED
)) {
252 if (F_ISSET(sp
, SC_SCR_VI
)) {
253 F_CLR(gp
, G_BELLSCHED
);
254 (void)gp
->scr_bell(sp
);
256 F_SET(gp
, G_BELLSCHED
);
260 * If vi is using the error line for text input, there's no screen
261 * real-estate for the error message. Nothing to do without some
262 * information as to how important the error message is.
264 if (F_ISSET(sp
, SC_TINPUT_INFO
))
268 * Ex or ex controlled screen output.
270 * If output happens during startup, e.g., a .exrc file, we may be
271 * in ex mode but haven't initialized the screen. Initialize here,
272 * and in this case, stay in ex mode.
274 * If the SC_SCR_EXWROTE bit is set, then we're switching back and
275 * forth between ex and vi, but the screen is trashed and we have
276 * to respect that. Switch to ex mode long enough to put out the
279 * If the SC_EX_WAIT_NO bit is set, turn it off -- we're writing to
280 * the screen, so previous opinions are ignored.
282 if (F_ISSET(sp
, SC_EX
| SC_SCR_EXWROTE
)) {
283 if (!F_ISSET(sp
, SC_SCR_EX
)) {
284 if (F_ISSET(sp
, SC_SCR_EXWROTE
)) {
285 if (sp
->gp
->scr_screen(sp
, SC_EX
))
293 (void)gp
->scr_attr(sp
, SA_INVERSE
, 1);
294 (void)printf("%.*s", (int)len
, line
);
296 (void)gp
->scr_attr(sp
, SA_INVERSE
, 0);
297 (void)fflush(stdout
);
299 F_CLR(sp
, SC_EX_WAIT_NO
);
301 if (!F_ISSET(sp
, SC_SCR_EX
))
302 (void)sp
->gp
->scr_screen(sp
, SC_VI
);
306 /* If the vi screen isn't ready, save the message. */
307 if (!F_ISSET(sp
, SC_SCR_VI
)) {
308 (void)vs_msgsave(sp
, mtype
, line
, len
);
312 /* Save the cursor position. */
313 (void)gp
->scr_cursor(sp
, &oldy
, &oldx
);
315 /* If it's an ex output message, just write it out. */
316 if (mtype
== M_NONE
) {
317 vs_output(sp
, mtype
, line
, len
);
322 * If it's a vi message, strip the trailing <newline> so we can
323 * try and paste messages together.
325 if (line
[len
- 1] == '\n')
329 * If a message won't fit on a single line, try to split on a <blank>.
330 * If a subsequent message fits on the same line, write a separator
331 * and output it. Otherwise, put out a newline.
333 * Need up to two padding characters normally; a semi-colon and a
334 * separating space. If only a single line on the screen, add some
335 * more for the trailing continuation message.
338 * Assume that periods and semi-colons take up a single column on the
342 * There are almost certainly pathological cases that will break this
346 (void)msg_cmsg(sp
, CMSG_CONT_S
, &padding
);
351 maxcols
= sp
->cols
- 1;
352 if (vip
->lcontinue
!= 0) {
353 if (len
+ vip
->lcontinue
+ padding
> maxcols
)
354 vs_output(sp
, vip
->mtype
, ".\n", 2);
356 vs_output(sp
, vip
->mtype
, ";", 1);
357 vs_output(sp
, M_NONE
, " ", 1);
361 for (s
= line
;; s
= t
) {
362 for (; len
> 0 && isblank((unsigned char)*s
); --len
, ++s
);
365 if (len
+ vip
->lcontinue
> maxcols
) {
366 for (e
= s
+ (maxcols
- vip
->lcontinue
);
367 e
> s
&& !isblank((unsigned char)*e
); --e
);
369 e
= t
= s
+ (maxcols
- vip
->lcontinue
);
371 for (t
= e
; isblank((unsigned char)e
[-1]); --e
);
376 * If the message ends in a period, discard it, we want to
377 * gang messages where possible.
380 if (len
== 0 && (e
- s
) > 1 && s
[(e
- s
) - 1] == '.')
382 vs_output(sp
, mtype
, s
, e
- s
);
385 vs_output(sp
, M_NONE
, "\n", 1);
391 ret
: (void)gp
->scr_move(sp
, oldy
, oldx
);
392 (void)gp
->scr_refresh(sp
, 0);
397 * Output the text to the screen.
400 vs_output(SCR
*sp
, mtype_t mtype
, const char *line
, int llen
)
405 size_t chlen
, notused
;
408 char *cbp
, *ecbp
, cbuf
[128];
412 for (p
= line
; llen
> 0;) {
413 /* Get the next physical line. */
414 if ((p
= memchr(line
, '\n', llen
)) == NULL
)
420 * The max is sp->cols characters, and we may have already
421 * written part of the line.
423 if (len
+ vip
->lcontinue
> sp
->cols
)
424 len
= sp
->cols
- vip
->lcontinue
;
427 * If the first line output, do nothing. If the second line
428 * output, draw the divider line. If drew a full screen, we
429 * remove the divider line. If it's a continuation line, move
430 * to the continuation point, else, move the screen up.
432 if (vip
->lcontinue
== 0) {
433 if (!IS_ONELINE(sp
)) {
434 if (vip
->totalcount
== 1) {
435 (void)gp
->scr_move(sp
,
436 LASTLINE(sp
) - 1, 0);
437 (void)gp
->scr_clrtoeol(sp
);
438 (void)vs_divider(sp
);
439 F_SET(vip
, VIP_DIVIDER
);
443 if (vip
->totalcount
== sp
->t_maxrows
&&
444 F_ISSET(vip
, VIP_DIVIDER
)) {
447 F_CLR(vip
, VIP_DIVIDER
);
450 if (vip
->totalcount
!= 0)
451 vs_scroll(sp
, NULL
, SCROLL_W_QUIT
);
453 (void)gp
->scr_move(sp
, LASTLINE(sp
), 0);
460 (void)gp
->scr_move(sp
, LASTLINE(sp
), vip
->lcontinue
);
462 /* Error messages are in inverse video. */
464 (void)gp
->scr_attr(sp
, SA_INVERSE
, 1);
466 /* Display the line, doing character translation. */
469 (void)gp->scr_addstr(sp, cbuf, cbp - cbuf); \
472 ecbp
= (cbp
= cbuf
) + sizeof(cbuf
) - 1;
473 for (t
= line
, tlen
= len
; tlen
--; ++t
) {
476 * Replace tabs with spaces, there are places in
477 * ex that do column calculations without looking
478 * at <tabs> -- and all routines that care about
479 * <tabs> do their own expansions. This catches
480 * <tabs> in things like tag search strings.
484 chlen
= KEY_LEN(sp
, ch
);
485 if (cbp
+ chlen
>= ecbp
)
487 for (kp
= KEY_NAME(sp
, ch
); chlen
--;)
493 (void)gp
->scr_attr(sp
, SA_INVERSE
, 0);
495 /* Clear the rest of the line. */
496 (void)gp
->scr_clrtoeol(sp
);
498 /* If we loop, it's a new line. */
501 /* Reset for the next line. */
510 /* Set up next continuation line. */
512 gp
->scr_cursor(sp
, ¬used
, &vip
->lcontinue
);
517 * Deal with ex message output.
519 * This routine is called when exiting a colon command to resolve any ex
520 * output that may have occurred.
522 * PUBLIC: int vs_ex_resolve __P((SCR *, int *));
525 vs_ex_resolve(SCR
*sp
, int *continuep
)
536 /* If we ran any ex command, we can't trust the cursor position. */
537 F_SET(vip
, VIP_CUR_INVALID
);
539 /* Terminate any partially written message. */
540 if (vip
->lcontinue
!= 0) {
541 vs_output(sp
, vip
->mtype
, ".", 1);
548 * If we switched out of the vi screen into ex, switch back while we
549 * figure out what to do with the screen and potentially get another
550 * command to execute.
552 * If we didn't switch into ex, we're not required to wait, and less
553 * than 2 lines of output, we can continue without waiting for the
556 * Note, all other code paths require waiting, so we leave the report
557 * of modified lines until later, so that we won't wait for no other
558 * reason than a threshold number of lines were modified. This means
559 * we display cumulative line modification reports for groups of ex
560 * commands. That seems right to me (well, at least not wrong).
562 if (F_ISSET(sp
, SC_SCR_EXWROTE
)) {
563 if (sp
->gp
->scr_screen(sp
, SC_VI
))
566 if (!F_ISSET(sp
, SC_EX_WAIT_YES
) && vip
->totalcount
< 2) {
567 F_CLR(sp
, SC_EX_WAIT_NO
);
571 /* Clear the required wait flag, it's no longer needed. */
572 F_CLR(sp
, SC_EX_WAIT_YES
);
575 * Wait, unless explicitly told not to wait or the user interrupted
576 * the command. If the user is leaving the screen, for any reason,
577 * they can't continue with further ex commands.
579 if (!F_ISSET(sp
, SC_EX_WAIT_NO
) && !INTERRUPTED(sp
)) {
580 wtype
= F_ISSET(sp
, SC_EXIT
| SC_EXIT_FORCE
|
581 SC_FSWITCH
| SC_SSWITCH
) ? SCROLL_W
: SCROLL_W_EX
;
582 if (F_ISSET(sp
, SC_SCR_EXWROTE
))
583 vs_wait(sp
, continuep
, wtype
);
585 vs_scroll(sp
, continuep
, wtype
);
590 /* If ex wrote on the screen, refresh the screen image. */
591 if (F_ISSET(sp
, SC_SCR_EXWROTE
))
592 F_SET(vip
, VIP_N_EX_PAINT
);
595 * If we're not the bottom of the split screen stack, the screen
596 * image itself is wrong, so redraw everything.
598 if (TAILQ_NEXT(sp
, q
) != NULL
)
599 F_SET(sp
, SC_SCR_REDRAW
);
601 /* If ex changed the underlying file, the map itself is wrong. */
602 if (F_ISSET(vip
, VIP_N_EX_REDRAW
))
603 F_SET(sp
, SC_SCR_REFORMAT
);
605 /* Ex may have switched out of the alternate screen, return. */
606 (void)gp
->scr_attr(sp
, SA_ALTERNATE
, 1);
609 * Whew. We're finally back home, after what feels like years.
612 F_CLR(sp
, SC_SCR_EXWROTE
| SC_EX_WAIT_NO
);
615 * We may need to repaint some of the screen, e.g.:
620 * gives us a combination of some lines that are "wrong", and a need
621 * for a full refresh.
623 if (vip
->totalcount
> 1) {
624 /* Set up the redraw of the overwritten lines. */
625 ev
.e_event
= E_REPAINT
;
626 ev
.e_flno
= vip
->totalcount
>=
627 sp
->rows
? 1 : sp
->rows
- vip
->totalcount
;
628 ev
.e_tlno
= sp
->rows
;
630 /* Reset the count of overwriting lines. */
631 vip
->linecount
= vip
->lcontinue
= vip
->totalcount
= 0;
634 (void)v_erepaint(sp
, &ev
);
636 /* Reset the count of overwriting lines. */
637 vip
->linecount
= vip
->lcontinue
= vip
->totalcount
= 0;
644 * Deal with message output.
646 * PUBLIC: int vs_resolve __P((SCR *, SCR *, int));
649 vs_resolve(SCR
*sp
, SCR
*csp
, int forcewait
)
660 * Vs_resolve is called from the main vi loop and the refresh function
661 * to periodically ensure that the user has seen any messages that have
662 * been displayed and that any status lines are correct. The sp screen
663 * is the screen we're checking, usually the current screen. When it's
664 * not, csp is the current screen, used for final cursor positioning.
672 /* Save the cursor position. */
673 (void)gp
->scr_cursor(csp
, &oldy
, &oldx
);
675 /* Ring the bell if it's scheduled. */
676 if (F_ISSET(gp
, G_BELLSCHED
)) {
677 F_CLR(gp
, G_BELLSCHED
);
678 (void)gp
->scr_bell(sp
);
681 /* Display new file status line. */
682 if (F_ISSET(sp
, SC_STATUS
)) {
683 F_CLR(sp
, SC_STATUS
);
684 msgq_status(sp
, sp
->lno
, MSTAT_TRUNCATE
);
687 /* Report on line modifications. */
691 * Flush any saved messages. If the screen isn't ready, refresh
692 * it. (A side-effect of screen refresh is that we can display
693 * messages.) Once this is done, don't trust the cursor. That
694 * extra refresh screwed the pooch.
696 if (!LIST_EMPTY(&gp
->msgq
)) {
697 if (!F_ISSET(sp
, SC_SCR_VI
) && vs_refresh(sp
, 1))
699 while ((mp
= LIST_FIRST(&gp
->msgq
)) != NULL
) {
700 wp
->scr_msg(sp
, mp
->mtype
, mp
->buf
, mp
->len
);
705 F_SET(vip
, VIP_CUR_INVALID
);
708 switch (vip
->totalcount
) {
714 * If we're switching screens, we have to wait for messages,
715 * regardless. If we don't wait, skip updating the modeline.
718 vs_scroll(sp
, NULL
, SCROLL_W
);
720 F_SET(vip
, VIP_S_MODELINE
);
726 * If >1 message line in use, prompt the user to continue and
727 * repaint overwritten lines.
729 vs_scroll(sp
, NULL
, SCROLL_W
);
731 ev
.e_event
= E_REPAINT
;
732 ev
.e_flno
= vip
->totalcount
>=
733 sp
->rows
? 1 : sp
->rows
- vip
->totalcount
;
734 ev
.e_tlno
= sp
->rows
;
740 /* Reset the count of overwriting lines. */
741 vip
->linecount
= vip
->lcontinue
= vip
->totalcount
= 0;
745 (void)v_erepaint(sp
, &ev
);
747 /* Restore the cursor position. */
748 (void)gp
->scr_move(csp
, oldy
, oldx
);
755 * Scroll the screen for output.
758 vs_scroll(SCR
*sp
, int *continuep
, sw_t wtype
)
765 if (!IS_ONELINE(sp
)) {
767 * Scroll the screen. Instead of scrolling the entire screen,
768 * delete the line above the first line output so preserve the
769 * maximum amount of the screen.
771 (void)gp
->scr_move(sp
, vip
->totalcount
<
772 sp
->rows
? LASTLINE(sp
) - vip
->totalcount
: 0, 0);
773 (void)gp
->scr_deleteln(sp
);
775 /* If there are screens below us, push them back into place. */
776 if (TAILQ_NEXT(sp
, q
) != NULL
) {
777 (void)gp
->scr_move(sp
, LASTLINE(sp
), 0);
778 (void)gp
->scr_insertln(sp
);
781 if (wtype
== SCROLL_W_QUIT
&& vip
->linecount
< sp
->t_maxrows
)
783 vs_wait(sp
, continuep
, wtype
);
788 * Prompt the user to continue.
791 vs_wait(SCR
*sp
, int *continuep
, sw_t wtype
)
802 (void)gp
->scr_move(sp
, LASTLINE(sp
), 0);
804 p
= msg_cmsg(sp
, CMSG_CONT_S
, &len
);
808 p
= msg_cmsg(sp
, CMSG_CONT_Q
, &len
);
811 p
= msg_cmsg(sp
, CMSG_CONT_EX
, &len
);
814 p
= msg_cmsg(sp
, CMSG_CONT
, &len
);
820 (void)gp
->scr_addstr(sp
, p
, len
);
825 (void)gp
->scr_clrtoeol(sp
);
826 (void)gp
->scr_refresh(sp
, 0);
828 /* Get a single character from the terminal. */
829 if (continuep
!= NULL
)
832 if (v_event_get(sp
, &ev
, 0, 0))
834 if (ev
.e_event
== E_CHARACTER
)
836 if (ev
.e_event
== E_INTERRUPT
) {
838 F_SET(gp
, G_INTERRUPTED
);
841 (void)gp
->scr_bell(sp
);
845 if (ev
.e_c
== CH_QUIT
)
846 F_SET(gp
, G_INTERRUPTED
);
849 if (ev
.e_c
== ':' && continuep
!= NULL
)
859 * Draw a dividing line between the screen and the output.
867 #define DIVIDESTR "+=+=+=+=+=+=+=+"
869 sizeof(DIVIDESTR
) - 1 > sp
->cols
? sp
->cols
: sizeof(DIVIDESTR
) - 1;
871 (void)gp
->scr_attr(sp
, SA_INVERSE
, 1);
872 (void)gp
->scr_addstr(sp
, DIVIDESTR
, len
);
873 (void)gp
->scr_attr(sp
, SA_INVERSE
, 0);
878 * Save a message for later display.
881 vs_msgsave(SCR
*sp
, mtype_t mt
, char *p
, size_t len
)
887 * We have to handle messages before we have any place to put them.
888 * If there's no screen support yet, allocate a msg structure, copy
889 * in the message, and queue it on the global structure. If we can't
890 * allocate memory here, we're genuinely screwed, dump the message
891 * to stderr in the (probably) vain hope that someone will see it.
893 CALLOC_GOTO(sp
, mp_n
, MSGS
*, 1, sizeof(MSGS
));
894 MALLOC_GOTO(sp
, mp_n
->buf
, char *, len
);
896 memmove(mp_n
->buf
, p
, len
);
901 if ((mp_c
= LIST_FIRST(&gp
->msgq
)) == NULL
) {
902 LIST_INSERT_HEAD(&gp
->msgq
, mp_n
, q
);
904 while (LIST_NEXT(mp_c
, q
) != NULL
)
905 mp_c
= LIST_NEXT(mp_c
, q
);
906 LIST_INSERT_AFTER(mp_c
, mp_n
, q
);
913 (void)fprintf(stderr
, "%.*s\n", (int)len
, p
);