Annotation of src/usr.bin/colcrt/colcrt.c, Revision 1.3
1.3 ! deraadt 1: /* $OpenBSD: colcrt.c,v 1.2 1996/06/26 05:32:12 deraadt Exp $ */
1.1 deraadt 2: /* $NetBSD: colcrt.c,v 1.3 1995/03/26 05:31:00 glass Exp $ */
3:
4: /*
5: * Copyright (c) 1980, 1993
6: * The Regents of the University of California. All rights reserved.
7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: */
36:
37: #ifndef lint
38: static char copyright[] =
39: "@(#) Copyright (c) 1980, 1993\n\
40: The Regents of the University of California. All rights reserved.\n";
41: #endif /* not lint */
42:
43: #ifndef lint
44: #if 0
45: static char sccsid[] = "@(#)colcrt.c 8.1 (Berkeley) 6/6/93";
46: #else
1.3 ! deraadt 47: static char rcsid[] = "$OpenBSD: colcrt.c,v 1.2 1996/06/26 05:32:12 deraadt Exp $";
1.1 deraadt 48: #endif
49: #endif /* not lint */
50:
1.3 ! deraadt 51: #include <sys/types.h>
! 52: #include <unistd.h>
! 53: #include <stdlib.h>
! 54: #include <string.h>
1.1 deraadt 55: #include <stdio.h>
1.3 ! deraadt 56:
1.1 deraadt 57: /*
58: * colcrt - replaces col for crts with new nroff esp. when using tbl.
59: * Bill Joy UCB July 14, 1977
60: *
61: * This filter uses a screen buffer, 267 half-lines by 132 columns.
62: * It interprets the up and down sequences generated by the new
63: * nroff when used with tbl and by \u \d and \r.
64: * General overstriking doesn't work correctly.
65: * Underlining is split onto multiple lines, etc.
66: *
67: * Option - suppresses all underlining.
68: * Option -2 forces printing of all half lines.
69: */
70:
71: char page[267][132];
72:
73: int outline = 1;
74: int outcol;
75:
76: char suppresul;
77: char printall;
78:
79: char *progname;
80: FILE *f;
81:
1.3 ! deraadt 82: void pflush(int);
! 83: int plus(char, char);
! 84: void move(int, int);
! 85:
! 86: int
1.1 deraadt 87: main(argc, argv)
88: int argc;
89: char *argv[];
90: {
1.3 ! deraadt 91: register int c;
1.1 deraadt 92: register char *cp, *dp;
93:
94: argc--;
95: progname = *argv++;
96: while (argc > 0 && argv[0][0] == '-') {
97: switch (argv[0][1]) {
98: case 0:
99: suppresul = 1;
100: break;
101: case '2':
102: printall = 1;
103: break;
104: default:
105: printf("usage: %s [ - ] [ -2 ] [ file ... ]\n", progname);
106: fflush(stdout);
107: exit(1);
108: }
109: argc--;
110: argv++;
111: }
112: do {
113: if (argc > 0) {
114: close(0);
115: if (!(f = fopen(argv[0], "r"))) {
116: fflush(stdout);
117: perror(argv[0]);
118: exit (1);
119: }
120: argc--;
121: argv++;
122: }
123: for (;;) {
124: c = getc(stdin);
125: if (c == -1) {
126: pflush(outline);
127: fflush(stdout);
128: break;
129: }
130: switch (c) {
131: case '\n':
132: if (outline >= 265)
133: pflush(62);
134: outline += 2;
135: outcol = 0;
136: continue;
137: case '\016':
138: case '\017':
139: continue;
140: case 033:
141: c = getc(stdin);
142: switch (c) {
143: case '9':
144: if (outline >= 266)
145: pflush(62);
146: outline++;
147: continue;
148: case '8':
149: if (outline >= 1)
150: outline--;
151: continue;
152: case '7':
153: outline -= 2;
154: if (outline < 0)
155: outline = 0;
156: continue;
157: default:
158: continue;
159: }
160: case '\b':
161: if (outcol)
162: outcol--;
163: continue;
164: case '\t':
165: outcol += 8;
166: outcol &= ~7;
167: outcol--;
168: c = ' ';
169: default:
170: if (outcol >= 132) {
171: outcol++;
172: continue;
173: }
174: cp = &page[outline][outcol];
175: outcol++;
176: if (c == '_') {
177: if (suppresul)
178: continue;
179: cp += 132;
180: c = '-';
181: }
182: if (*cp == 0) {
183: *cp = c;
184: dp = cp - outcol;
185: for (cp--; cp >= dp && *cp == 0; cp--)
186: *cp = ' ';
187: } else
188: if (plus(c, *cp) || plus(*cp, c))
189: *cp = '+';
190: else if (*cp == ' ' || *cp == 0)
191: *cp = c;
192: continue;
193: }
194: }
195: } while (argc > 0);
196: fflush(stdout);
197: exit(0);
198: }
199:
1.3 ! deraadt 200: int
1.1 deraadt 201: plus(c, d)
202: char c, d;
203: {
204:
1.3 ! deraadt 205: return ((c == '|' && d == '-') || d == '_');
1.1 deraadt 206: }
207:
208: int first;
209:
1.3 ! deraadt 210: void
1.1 deraadt 211: pflush(ol)
212: int ol;
213: {
1.3 ! deraadt 214: register int i;
1.1 deraadt 215: register char *cp;
216: char lastomit;
217: int l;
218:
219: l = ol;
220: lastomit = 0;
221: if (l > 266)
222: l = 266;
223: else
224: l |= 1;
225: for (i = first | 1; i < l; i++) {
226: move(i, i - 1);
227: move(i, i + 1);
228: }
229: for (i = first; i < l; i++) {
230: cp = page[i];
231: if (printall == 0 && lastomit == 0 && *cp == 0) {
232: lastomit = 1;
233: continue;
234: }
235: lastomit = 0;
236: printf("%s\n", cp);
237: }
238: bcopy(page[ol], page, (267 - ol) * 132);
239: bzero(page[267- ol], ol * 132);
240: outline -= ol;
241: outcol = 0;
242: first = 1;
243: }
244:
1.3 ! deraadt 245: void
1.1 deraadt 246: move(l, m)
247: int l, m;
248: {
249: register char *cp, *dp;
250:
251: for (cp = page[l], dp = page[m]; *cp; cp++, dp++) {
252: switch (*cp) {
253: case '|':
254: if (*dp != ' ' && *dp != '|' && *dp != 0)
255: return;
256: break;
257: case ' ':
258: break;
259: default:
260: return;
261: }
262: }
263: if (*cp == 0) {
264: for (cp = page[l], dp = page[m]; *cp; cp++, dp++)
265: if (*cp == '|')
266: *dp = '|';
267: else if (*dp == 0)
268: *dp = ' ';
269: page[l][0] = 0;
270: }
271: }