Annotation of src/usr.bin/colcrt/colcrt.c, Revision 1.7
1.7 ! mickey 1: /* $OpenBSD: colcrt.c,v 1.6 2003/06/10 22:20:45 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.7 ! mickey 43: static char rcsid[] = "$OpenBSD: colcrt.c,v 1.6 2003/06/10 22:20:45 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.3 deraadt 52:
1.1 deraadt 53: /*
54: * colcrt - replaces col for crts with new nroff esp. when using tbl.
55: * Bill Joy UCB July 14, 1977
56: *
57: * This filter uses a screen buffer, 267 half-lines by 132 columns.
58: * It interprets the up and down sequences generated by the new
59: * nroff when used with tbl and by \u \d and \r.
60: * General overstriking doesn't work correctly.
61: * Underlining is split onto multiple lines, etc.
62: *
63: * Option - suppresses all underlining.
64: * Option -2 forces printing of all half lines.
65: */
66:
67: char page[267][132];
68:
69: int outline = 1;
70: int outcol;
71:
72: char suppresul;
73: char printall;
74:
75: FILE *f;
76:
1.3 deraadt 77: void pflush(int);
78: int plus(char, char);
79: void move(int, int);
80:
81: int
1.6 deraadt 82: main(int argc, char *argv[])
1.1 deraadt 83: {
1.7 ! mickey 84: extern char *__progname;
! 85: char *cp, *dp;
1.4 mpech 86: int c;
1.1 deraadt 87:
88: argc--;
1.7 ! mickey 89: *argv++;
1.1 deraadt 90: while (argc > 0 && argv[0][0] == '-') {
91: switch (argv[0][1]) {
92: case 0:
93: suppresul = 1;
94: break;
95: case '2':
96: printall = 1;
97: break;
98: default:
1.7 ! mickey 99: fprintf(stderr,
! 100: "usage: %s [ - ] [ -2 ] [ file ... ]\n",
! 101: __progname);
1.1 deraadt 102: fflush(stdout);
103: exit(1);
104: }
105: argc--;
106: argv++;
107: }
108: do {
109: if (argc > 0) {
110: close(0);
111: if (!(f = fopen(argv[0], "r"))) {
112: fflush(stdout);
1.7 ! mickey 113: err(1, "fopen: %s", argv[0]);
1.1 deraadt 114: }
115: argc--;
116: argv++;
117: }
118: for (;;) {
119: c = getc(stdin);
120: if (c == -1) {
121: pflush(outline);
122: fflush(stdout);
123: break;
124: }
125: switch (c) {
126: case '\n':
127: if (outline >= 265)
128: pflush(62);
129: outline += 2;
130: outcol = 0;
131: continue;
132: case '\016':
133: case '\017':
134: continue;
135: case 033:
136: c = getc(stdin);
137: switch (c) {
138: case '9':
139: if (outline >= 266)
140: pflush(62);
141: outline++;
142: continue;
143: case '8':
144: if (outline >= 1)
145: outline--;
146: continue;
147: case '7':
148: outline -= 2;
149: if (outline < 0)
150: outline = 0;
151: continue;
152: default:
153: continue;
154: }
155: case '\b':
156: if (outcol)
157: outcol--;
158: continue;
159: case '\t':
160: outcol += 8;
161: outcol &= ~7;
162: outcol--;
163: c = ' ';
164: default:
165: if (outcol >= 132) {
166: outcol++;
167: continue;
168: }
169: cp = &page[outline][outcol];
170: outcol++;
171: if (c == '_') {
172: if (suppresul)
173: continue;
174: cp += 132;
175: c = '-';
176: }
177: if (*cp == 0) {
178: *cp = c;
179: dp = cp - outcol;
180: for (cp--; cp >= dp && *cp == 0; cp--)
181: *cp = ' ';
182: } else
183: if (plus(c, *cp) || plus(*cp, c))
184: *cp = '+';
185: else if (*cp == ' ' || *cp == 0)
186: *cp = c;
187: continue;
188: }
189: }
190: } while (argc > 0);
191: fflush(stdout);
192: exit(0);
193: }
194:
1.3 deraadt 195: int
1.6 deraadt 196: plus(char c, char d)
1.1 deraadt 197: {
198:
1.3 deraadt 199: return ((c == '|' && d == '-') || d == '_');
1.1 deraadt 200: }
201:
202: int first;
203:
1.3 deraadt 204: void
1.6 deraadt 205: pflush(int ol)
1.1 deraadt 206: {
1.4 mpech 207: int i;
208: char *cp;
1.1 deraadt 209: char lastomit;
210: int l;
211:
212: l = ol;
213: lastomit = 0;
214: if (l > 266)
215: l = 266;
216: else
217: l |= 1;
218: for (i = first | 1; i < l; i++) {
219: move(i, i - 1);
220: move(i, i + 1);
221: }
222: for (i = first; i < l; i++) {
223: cp = page[i];
224: if (printall == 0 && lastomit == 0 && *cp == 0) {
225: lastomit = 1;
226: continue;
227: }
228: lastomit = 0;
229: printf("%s\n", cp);
230: }
231: bcopy(page[ol], page, (267 - ol) * 132);
232: bzero(page[267- ol], ol * 132);
233: outline -= ol;
234: outcol = 0;
235: first = 1;
236: }
237:
1.3 deraadt 238: void
1.6 deraadt 239: move(int l, int m)
1.1 deraadt 240: {
1.4 mpech 241: char *cp, *dp;
1.1 deraadt 242:
243: for (cp = page[l], dp = page[m]; *cp; cp++, dp++) {
244: switch (*cp) {
245: case '|':
246: if (*dp != ' ' && *dp != '|' && *dp != 0)
247: return;
248: break;
249: case ' ':
250: break;
251: default:
252: return;
253: }
254: }
255: if (*cp == 0) {
256: for (cp = page[l], dp = page[m]; *cp; cp++, dp++)
257: if (*cp == '|')
258: *dp = '|';
259: else if (*dp == 0)
260: *dp = ' ';
261: page[l][0] = 0;
262: }
263: }