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