update to 1.01
[nvi.git] / ex / ex_print.c
blob15a245fb786692db47d9f5802a1c385a0261831c
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: ex_print.c,v 8.6 1993/11/02 18:46:49 bostic Exp $ (Berkeley) $Date: 1993/11/02 18:46:49 $";
10 #endif /* not lint */
12 #include <sys/types.h>
14 #include <ctype.h>
15 #include <string.h>
17 #include "vi.h"
18 #include "excmd.h"
21 * ex_list -- :[line [,line]] l[ist] [count] [flags]
23 * Display the addressed lines such that the output is unambiguous.
25 int
26 ex_list(sp, ep, cmdp)
27 SCR *sp;
28 EXF *ep;
29 EXCMDARG *cmdp;
31 if (ex_print(sp, ep,
32 &cmdp->addr1, &cmdp->addr2, cmdp->flags | E_F_LIST))
33 return (1);
34 sp->lno = cmdp->addr2.lno;
35 sp->cno = cmdp->addr2.cno;
36 return (0);
40 * ex_number -- :[line [,line]] nu[mber] [count] [flags]
42 * Display the addressed lines with a leading line number.
44 int
45 ex_number(sp, ep, cmdp)
46 SCR *sp;
47 EXF *ep;
48 EXCMDARG *cmdp;
50 if (ex_print(sp, ep,
51 &cmdp->addr1, &cmdp->addr2, cmdp->flags | E_F_HASH))
52 return (1);
53 sp->lno = cmdp->addr2.lno;
54 sp->cno = cmdp->addr2.cno;
55 return (0);
59 * ex_pr -- :[line [,line]] p[rint] [count] [flags]
61 * Display the addressed lines.
63 int
64 ex_pr(sp, ep, cmdp)
65 SCR *sp;
66 EXF *ep;
67 EXCMDARG *cmdp;
69 if (ex_print(sp, ep, &cmdp->addr1, &cmdp->addr2, cmdp->flags))
70 return (1);
71 sp->lno = cmdp->addr2.lno;
72 sp->cno = cmdp->addr2.cno;
73 return (0);
77 * ex_print --
78 * Print the selected lines.
80 int
81 ex_print(sp, ep, fp, tp, flags)
82 SCR *sp;
83 EXF *ep;
84 MARK *fp, *tp;
85 register int flags;
87 register int ch, col, rlen;
88 recno_t from, to;
89 size_t len;
90 int cnt;
91 char *p, buf[10];
93 F_SET(sp, S_INTERRUPTIBLE);
94 for (from = fp->lno, to = tp->lno; from <= to; ++from) {
95 /* Display the line number. */
96 if (LF_ISSET(E_F_HASH))
97 col = ex_printf(EXCOOKIE, "%7ld ", from);
98 else
99 col = 0;
102 * Display the line. The format for E_F_PRINT isn't very good,
103 * especially in handling end-of-line tabs, but they're almost
104 * backward compatible.
106 if ((p = file_gline(sp, ep, from, &len)) == NULL) {
107 GETLINE_ERR(sp, from);
108 return (1);
111 #define WCHECK(ch) { \
112 if (col == sp->cols) { \
113 (void)ex_printf(EXCOOKIE, "\n"); \
114 col = 0; \
116 (void)ex_printf(EXCOOKIE, "%c", ch); \
117 ++col; \
119 for (rlen = len; rlen--;) {
120 ch = *p++;
121 if (LF_ISSET(E_F_LIST))
122 if (ch != '\t' && isprint(ch)) {
123 WCHECK(ch);
124 } else if (ch & 0x80) {
125 (void)snprintf(buf,
126 sizeof(buf), "\\%03o", ch);
127 len = strlen(buf);
128 for (cnt = 0; cnt < len; ++cnt)
129 WCHECK(buf[cnt]);
130 } else {
131 WCHECK('^');
132 WCHECK(ch + 0x40);
134 else {
135 ch &= 0x7f;
136 if (ch == '\t') {
137 while (col < sp->cols &&
138 ++col % O_VAL(sp, O_TABSTOP))
139 (void)ex_printf(EXCOOKIE, " ");
140 if (col == sp->cols) {
141 col = 0;
142 (void)ex_printf(EXCOOKIE, "\n");
144 } else if (isprint(ch)) {
145 WCHECK(ch);
146 } else if (ch == '\n') {
147 col = 0;
148 (void)ex_printf(EXCOOKIE, "\n");
149 } else {
150 WCHECK('^');
151 WCHECK(ch + 0x40);
155 if (LF_ISSET(E_F_LIST)) {
156 WCHECK('$');
157 } else if (len == 0) {
159 * If the line is empty, output a space
160 * to overwrite the colon prompt.
162 WCHECK(' ');
164 (void)ex_printf(EXCOOKIE, "\n");
166 if (F_ISSET(sp, S_INTERRUPTED))
167 break;
169 return (0);