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