1 /* $NetBSD: ex_print.c,v 1.4 2014/01/26 21:43:45 christos Exp $ */
3 * Copyright (c) 1992, 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: ex_print.c,v 10.24 2001/07/29 19:07:29 skimo Exp (Berkeley) Date: 2001/07/29 19:07:29 ";
19 __RCSID("$NetBSD: ex_print.c,v 1.4 2014/01/26 21:43:45 christos Exp $");
22 #include <sys/types.h>
23 #include <sys/queue.h>
25 #include <bitstring.h>
37 #include "../common/common.h"
39 static int ex_prchars
__P((SCR
*, const CHAR_T
*, size_t *, size_t,
43 * ex_list -- :[line [,line]] l[ist] [count] [flags]
45 * Display the addressed lines such that the output is unambiguous.
47 * PUBLIC: int ex_list __P((SCR *, EXCMD *));
50 ex_list(SCR
*sp
, EXCMD
*cmdp
)
52 if (ex_print(sp
, cmdp
,
53 &cmdp
->addr1
, &cmdp
->addr2
, cmdp
->iflags
| E_C_LIST
))
55 sp
->lno
= cmdp
->addr2
.lno
;
56 sp
->cno
= cmdp
->addr2
.cno
;
61 * ex_number -- :[line [,line]] nu[mber] [count] [flags]
63 * Display the addressed lines with a leading line number.
65 * PUBLIC: int ex_number __P((SCR *, EXCMD *));
68 ex_number(SCR
*sp
, EXCMD
*cmdp
)
70 if (ex_print(sp
, cmdp
,
71 &cmdp
->addr1
, &cmdp
->addr2
, cmdp
->iflags
| E_C_HASH
))
73 sp
->lno
= cmdp
->addr2
.lno
;
74 sp
->cno
= cmdp
->addr2
.cno
;
79 * ex_pr -- :[line [,line]] p[rint] [count] [flags]
81 * Display the addressed lines.
83 * PUBLIC: int ex_pr __P((SCR *, EXCMD *));
86 ex_pr(SCR
*sp
, EXCMD
*cmdp
)
88 if (ex_print(sp
, cmdp
, &cmdp
->addr1
, &cmdp
->addr2
, cmdp
->iflags
))
90 sp
->lno
= cmdp
->addr2
.lno
;
91 sp
->cno
= cmdp
->addr2
.cno
;
97 * Print the selected lines.
99 * PUBLIC: int ex_print __P((SCR *, EXCMD *, MARK *, MARK *, u_int32_t));
102 ex_print(SCR
*sp
, EXCMD
*cmdp
, MARK
*fp
, MARK
*tp
, u_int32_t flags
)
112 for (from
= fp
->lno
, to
= tp
->lno
; from
<= to
; ++from
) {
116 * Display the line number. The %6 format is specified
117 * by POSIX 1003.2, and is almost certainly large enough.
118 * Check, though, just in case.
120 if (LF_ISSET(E_C_HASH
)) {
121 if (from
<= 999999) {
122 SPRINTF(buf
, SIZE(buf
), L("%6ld "), from
);
126 if (ex_prchars(sp
, p
, &col
, 8, 0, 0))
131 * Display the line. The format for E_C_PRINT isn't very good,
132 * especially in handling end-of-line tabs, but they're almost
133 * backward compatible.
135 if (db_get(sp
, from
, DBG_FATAL
, &q
, &len
))
139 if (len
== 0 && !LF_ISSET(E_C_LIST
))
140 (void)ex_puts(sp
, "\n");
141 else if (ex_ldisplay(sp
, p
, len
, col
, flags
))
152 * Display a line without any preceding number.
154 * PUBLIC: int ex_ldisplay __P((SCR *, const CHAR_T *, size_t, size_t, u_int));
157 ex_ldisplay(SCR
*sp
, const CHAR_T
*p
, size_t len
, size_t col
, u_int flags
)
159 if (len
> 0 && ex_prchars(sp
, p
, &col
, len
, LF_ISSET(E_C_LIST
), 0))
161 if (!INTERRUPTED(sp
) && LF_ISSET(E_C_LIST
)) {
163 if (ex_prchars(sp
, p
, &col
, 1, LF_ISSET(E_C_LIST
), 0))
166 if (!INTERRUPTED(sp
))
167 (void)ex_puts(sp
, "\n");
173 * Display a line for the substitute with confirmation routine.
175 * PUBLIC: int ex_scprint __P((SCR *, MARK *, MARK *));
178 ex_scprint(SCR
*sp
, MARK
*fp
, MARK
*tp
)
185 if (O_ISSET(sp
, O_NUMBER
)) {
187 if (ex_prchars(sp
, p
, &col
, 8, 0, 0))
191 if (db_get(sp
, fp
->lno
, DBG_FATAL
, &q
, &len
))
195 if (ex_prchars(sp
, p
, &col
, fp
->cno
, 0, ' '))
199 p
, &col
, tp
->cno
== fp
->cno
? 1 : tp
->cno
- fp
->cno
, 0, '^'))
203 p
= L("[ynq]"); /* XXX: should be msg_cat. */
204 if (ex_prchars(sp
, p
, &col
, 5, 0, 0))
212 * Local routine to dump characters to the screen.
215 ex_prchars(SCR
*sp
, const CHAR_T
*p
, size_t *colp
, size_t len
,
216 u_int flags
, int repeatc
)
220 size_t col
, tlen
, ts
;
222 if (O_ISSET(sp
, O_LIST
))
224 ts
= O_VAL(sp
, O_TABSTOP
);
225 for (col
= *colp
; len
--;)
226 if ((ch
= *p
++) == L('\t') && !LF_ISSET(E_C_LIST
))
227 for (tlen
= ts
- col
% ts
;
228 col
< sp
->cols
&& tlen
--; ++col
) {
230 "%c", repeatc
? repeatc
: ' ');
237 CHAR_T str
[2] = {0, 0};
239 INT2CHAR(sp
, str
, 2, kp
, tlen
);
241 kp
= (char *)KEY_NAME(sp
, ch
);
242 tlen
= KEY_LEN(sp
, ch
);
244 if (!repeatc
&& col
+ tlen
< sp
->cols
) {
245 (void)ex_puts(sp
, kp
);
248 for (; tlen
--; ++kp
, ++col
) {
249 if (col
== sp
->cols
) {
251 (void)ex_puts(sp
, "\n");
254 "%c", repeatc
? repeatc
: *kp
);
265 * Ex's version of printf.
267 * PUBLIC: int ex_printf __P((SCR *, const char *, ...));
271 ex_printf(SCR
*sp
, const char *fmt
, ...)
273 ex_printf(sp
, fmt
, va_alist
)
290 exp
->obp_len
+= n
= vsnprintf(exp
->obp
+ exp
->obp_len
,
291 sizeof(exp
->obp
) - exp
->obp_len
, fmt
, ap
);
294 /* Flush when reach a <newline> or half the buffer. */
295 if (exp
->obp
[exp
->obp_len
- 1] == '\n' ||
296 exp
->obp_len
> sizeof(exp
->obp
) / 2)
303 * Ex's version of puts.
305 * PUBLIC: int ex_puts __P((SCR *, const char *));
308 ex_puts(SCR
*sp
, const char *str
)
315 /* Flush when reach a <newline> or the end of the buffer. */
316 for (doflush
= n
= 0; *str
!= '\0'; ++n
) {
317 if (exp
->obp_len
> sizeof(exp
->obp
))
319 if ((exp
->obp
[exp
->obp_len
++] = *str
++) == '\n')
329 * Ex's version of fflush.
331 * PUBLIC: int ex_fflush __P((SCR *sp));
340 if (exp
&& exp
->obp_len
!= 0) {
341 sp
->wp
->scr_msg(sp
, M_NONE
, exp
->obp
, exp
->obp_len
);