Annotation of src/usr.bin/colcrt/colcrt.c, Revision 1.6
1.6 ! deraadt 1: /* $OpenBSD: colcrt.c,v 1.5 2003/06/03 02:56:07 millert 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.6 ! deraadt 43: static char rcsid[] = "$OpenBSD: colcrt.c,v 1.5 2003/06/03 02:56:07 millert 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: char *progname;
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.4 mpech 85: int c;
86: char *cp, *dp;
1.1 deraadt 87:
88: argc--;
89: progname = *argv++;
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:
99: printf("usage: %s [ - ] [ -2 ] [ file ... ]\n", progname);
100: fflush(stdout);
101: exit(1);
102: }
103: argc--;
104: argv++;
105: }
106: do {
107: if (argc > 0) {
108: close(0);
109: if (!(f = fopen(argv[0], "r"))) {
110: fflush(stdout);
111: perror(argv[0]);
112: exit (1);
113: }
114: argc--;
115: argv++;
116: }
117: for (;;) {
118: c = getc(stdin);
119: if (c == -1) {
120: pflush(outline);
121: fflush(stdout);
122: break;
123: }
124: switch (c) {
125: case '\n':
126: if (outline >= 265)
127: pflush(62);
128: outline += 2;
129: outcol = 0;
130: continue;
131: case '\016':
132: case '\017':
133: continue;
134: case 033:
135: c = getc(stdin);
136: switch (c) {
137: case '9':
138: if (outline >= 266)
139: pflush(62);
140: outline++;
141: continue;
142: case '8':
143: if (outline >= 1)
144: outline--;
145: continue;
146: case '7':
147: outline -= 2;
148: if (outline < 0)
149: outline = 0;
150: continue;
151: default:
152: continue;
153: }
154: case '\b':
155: if (outcol)
156: outcol--;
157: continue;
158: case '\t':
159: outcol += 8;
160: outcol &= ~7;
161: outcol--;
162: c = ' ';
163: default:
164: if (outcol >= 132) {
165: outcol++;
166: continue;
167: }
168: cp = &page[outline][outcol];
169: outcol++;
170: if (c == '_') {
171: if (suppresul)
172: continue;
173: cp += 132;
174: c = '-';
175: }
176: if (*cp == 0) {
177: *cp = c;
178: dp = cp - outcol;
179: for (cp--; cp >= dp && *cp == 0; cp--)
180: *cp = ' ';
181: } else
182: if (plus(c, *cp) || plus(*cp, c))
183: *cp = '+';
184: else if (*cp == ' ' || *cp == 0)
185: *cp = c;
186: continue;
187: }
188: }
189: } while (argc > 0);
190: fflush(stdout);
191: exit(0);
192: }
193:
1.3 deraadt 194: int
1.6 ! deraadt 195: plus(char c, char d)
1.1 deraadt 196: {
197:
1.3 deraadt 198: return ((c == '|' && d == '-') || d == '_');
1.1 deraadt 199: }
200:
201: int first;
202:
1.3 deraadt 203: void
1.6 ! deraadt 204: pflush(int ol)
1.1 deraadt 205: {
1.4 mpech 206: int i;
207: char *cp;
1.1 deraadt 208: char lastomit;
209: int l;
210:
211: l = ol;
212: lastomit = 0;
213: if (l > 266)
214: l = 266;
215: else
216: l |= 1;
217: for (i = first | 1; i < l; i++) {
218: move(i, i - 1);
219: move(i, i + 1);
220: }
221: for (i = first; i < l; i++) {
222: cp = page[i];
223: if (printall == 0 && lastomit == 0 && *cp == 0) {
224: lastomit = 1;
225: continue;
226: }
227: lastomit = 0;
228: printf("%s\n", cp);
229: }
230: bcopy(page[ol], page, (267 - ol) * 132);
231: bzero(page[267- ol], ol * 132);
232: outline -= ol;
233: outcol = 0;
234: first = 1;
235: }
236:
1.3 deraadt 237: void
1.6 ! deraadt 238: move(int l, int m)
1.1 deraadt 239: {
1.4 mpech 240: char *cp, *dp;
1.1 deraadt 241:
242: for (cp = page[l], dp = page[m]; *cp; cp++, dp++) {
243: switch (*cp) {
244: case '|':
245: if (*dp != ' ' && *dp != '|' && *dp != 0)
246: return;
247: break;
248: case ' ':
249: break;
250: default:
251: return;
252: }
253: }
254: if (*cp == 0) {
255: for (cp = page[l], dp = page[m]; *cp; cp++, dp++)
256: if (*cp == '|')
257: *dp = '|';
258: else if (*dp == 0)
259: *dp = ' ';
260: page[l][0] = 0;
261: }
262: }