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