BSD 3 development
[unix-history] / usr / src / cmd / colcrt.c
CommitLineData
64afdfd4
BJ
1#include <stdio.h>
2/*
3 * colcrt - replaces col for crts with new nroff esp. when using tbl.
4 * Bill Joy UCB July 14, 1977
5 *
6 * This filter uses a screen buffer, 267 half-lines by 132 columns.
7 * It interprets the up and down sequences generated by the new
8 * nroff when used with tbl and by \u \d and \r.
9 * General overstriking doesn't work correctly.
10 * Underlining is split onto multiple lines, etc.
11 *
12 * Option - suppresses all underlining.
13 * Option -2 forces printing of all half lines.
14 */
15
16char page[267][132];
17
18int outline = 1;
19int outcol;
20
21char buf[256];
22char suppresul;
23char printall;
24
25char *progname;
26FILE *f;
27
28main(argc, argv)
29 int argc;
30 char *argv[];
31{
32 register c;
33 register char *cp, *dp;
34
35 argc--;
36 progname = *argv++;
37 while (argc > 0 && argv[0][0] == '-') {
38 switch (argv[0][1]) {
39 case 0:
40 suppresul = 1;
41 break;
42 case '2':
43 printall = 1;
44 break;
45 default:
46 printf("usage: %s [ - ] [ -2 ] [ file ... ]\n", progname);
47 fflush(stdout);
48 exit(1);
49 }
50 argc--;
51 argv++;
52 }
53 setbuf(stdout, buf);
54 do {
55 if (argc > 0) {
56 close(0);
57 if ((f=fopen(argv[0], "r")
58) < 0) {
59 fflush(stdout);
60 perror(argv[0]);
61 fflush(stdout);
62 exit (1);
63 }
64 argc--;
65 argv++;
66 }
67 for (;;) {
68 c = getc(stdin);
69 if (c == -1) {
70 pflush(outline);
71 fflush(stdout);
72 break;
73 }
74 switch (c) {
75 case '\n':
76 if (outline >= 265)
77 pflush(62);
78 outline += 2;
79 outcol = 0;
80 continue;
81 case '\016':
82 case '\017':
83 continue;
84 case 033:
85 c = getc(stdin);
86 switch (c) {
87 case '9':
88 if (outline >= 266)
89 pflush(62);
90 outline++;
91 continue;
92 case '8':
93 if (outline >= 1)
94 outline--;
95 continue;
96 case '7':
97 outline -= 2;
98 if (outline < 0)
99 outline = 0;
100 continue;
101 default:
102 continue;
103 }
104 case '\b':
105 if (outcol)
106 outcol--;
107 continue;
108 case '\t':
109 outcol += 8;
110 outcol &= ~7;
111 outcol--;
112 c = ' ';
113 default:
114 if (outcol >= 132) {
115 outcol++;
116 continue;
117 }
118 cp = &page[outline][outcol];
119 outcol++;
120 if (c == '_') {
121 if (suppresul)
122 continue;
123 cp += 132;
124 c = '-';
125 }
126 if (*cp == 0) {
127 *cp = c;
128 dp = cp - outcol;
129 for (cp--; cp >= dp && *cp == 0; cp--)
130 *cp = ' ';
131 } else
132 if (plus(c, *cp) || plus(*cp, c))
133 *cp = '+';
134 else if (*cp == ' ' || *cp == 0)
135 *cp = c;
136 continue;
137 }
138 }
139 } while (argc > 0);
140 fflush(stdout);
141 exit(0);
142}
143
144plus(c, d)
145 char c, d;
146{
147
148 return (c == '|' && d == '-' || d == '_');
149}
150
151int first;
152
153pflush(ol)
154 int ol;
155{
156 register int i, j;
157 register char *cp;
158 char lastomit;
159 int l;
160
161 l = ol;
162 lastomit = 0;
163 if (l > 266)
164 l = 266;
165 else
166 l |= 1;
167 for (i = first | 1; i < l; i++) {
168 move(i, i - 1);
169 move(i, i + 1);
170 }
171 for (i = first; i < l; i++) {
172 cp = page[i];
173 if (printall == 0 && lastomit == 0 && *cp == 0) {
174 lastomit = 1;
175 continue;
176 }
177 lastomit = 0;
178 printf("%s\n", cp);
179 }
180 copy(page, page[ol], (267 - ol) * 132);
181 clear(page[267- ol], ol * 132);
182 outline -= ol;
183 outcol = 0;
184 first = 1;
185}
186move(l, m)
187 int l, m;
188{
189 register char *cp, *dp;
190
191 for (cp = page[l], dp = page[m]; *cp; cp++, dp++) {
192 switch (*cp) {
193 case '|':
194 if (*dp != ' ' && *dp != '|' && *dp != 0)
195 return;
196 break;
197 case ' ':
198 break;
199 default:
200 return;
201 }
202 }
203 if (*cp == 0) {
204 for (cp = page[l], dp = page[m]; *cp; cp++, dp++)
205 if (*cp == '|')
206 *dp = '|';
207 else if (*dp == 0)
208 *dp = ' ';
209 page[l][0] = 0;
210 }
211}
212
213copy(to, from, i)
214 register char *to, *from;
215 register int i;
216{
217
218 if (i > 0)
219 do
220 *to++ = *from++;
221 while (--i);
222}
223
224clear(at, cnt)
225 register char *at;
226 register int cnt;
227{
228
229 if (cnt > 0)
230 do
231 *at++ = 0;
232 while (--cnt);
233}