1 /* $NetBSD: colcrt.c,v 1.6 2003/08/07 11:13:24 agc 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. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 */ 31 32 #include <sys/cdefs.h> 33 #ifndef lint 34 __COPYRIGHT("@(#) Copyright (c) 1980, 1993\n\ 35 The Regents of the University of California. All rights reserved.\n"); 36 #endif /* not lint */ 37 38 #ifndef lint 39 #if 0 40 static char sccsid[] = "@(#)colcrt.c 8.1 (Berkeley) 6/6/93"; 41 #else 42 __RCSID("$NetBSD: colcrt.c,v 1.6 2003/08/07 11:13:24 agc Exp $"); 43 #endif 44 #endif /* not lint */ 45 46 #include <stdio.h> 47 #include <stdlib.h> 48 #include <string.h> 49 #include <unistd.h> 50 51 /* 52 * colcrt - replaces col for crts with new nroff esp. when using tbl. 53 * Bill Joy UCB July 14, 1977 54 * 55 * This filter uses a screen buffer, 267 half-lines by 132 columns. 56 * It interprets the up and down sequences generated by the new 57 * nroff when used with tbl and by \u \d and \r. 58 * General overstriking doesn't work correctly. 59 * Underlining is split onto multiple lines, etc. 60 * 61 * Option - suppresses all underlining. 62 * Option -2 forces printing of all half lines. 63 */ 64 65 char page[267][132]; 66 67 int outline = 1; 68 int outcol; 69 70 char suppresul; 71 char printall; 72 73 char *progname; 74 FILE *f; 75 76 int main __P((int, char **)); 77 void move __P((int, int)); 78 void pflush __P((int)); 79 int plus __P((char, char)); 80 81 int 82 main(argc, argv) 83 int argc; 84 char *argv[]; 85 { 86 int c; 87 char *cp, *dp; 88 89 argc--; 90 progname = *argv++; 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: 100 printf("usage: %s [ - ] [ -2 ] [ file ... ]\n", progname); 101 fflush(stdout); 102 exit(1); 103 } 104 argc--; 105 argv++; 106 } 107 do { 108 if (argc > 0) { 109 close(0); 110 if (!(f = fopen(argv[0], "r"))) { 111 fflush(stdout); 112 perror(argv[0]); 113 exit (1); 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 195 int 196 plus(c, d) 197 char c, d; 198 { 199 200 return ((c == '|' && d == '-') || d == '_'); 201 } 202 203 int first; 204 205 void 206 pflush(ol) 207 int ol; 208 { 209 int i; 210 char *cp; 211 char lastomit; 212 int l; 213 214 l = ol; 215 lastomit = 0; 216 if (l > 266) 217 l = 266; 218 else 219 l |= 1; 220 for (i = first | 1; i < l; i++) { 221 move(i, i - 1); 222 move(i, i + 1); 223 } 224 for (i = first; i < l; i++) { 225 cp = page[i]; 226 if (printall == 0 && lastomit == 0 && *cp == 0) { 227 lastomit = 1; 228 continue; 229 } 230 lastomit = 0; 231 printf("%s\n", cp); 232 } 233 memmove(page, page[ol], (267 - ol) * 132); 234 memset(page[267- ol], 0, ol * 132); 235 outline -= ol; 236 outcol = 0; 237 first = 1; 238 } 239 240 void 241 move(l, m) 242 int l, m; 243 { 244 char *cp, *dp; 245 246 for (cp = page[l], dp = page[m]; *cp; cp++, dp++) { 247 switch (*cp) { 248 case '|': 249 if (*dp != ' ' && *dp != '|' && *dp != 0) 250 return; 251 break; 252 case ' ': 253 break; 254 default: 255 return; 256 } 257 } 258 if (*cp == 0) { 259 for (cp = page[l], dp = page[m]; *cp; cp++, dp++) 260 if (*cp == '|') 261 *dp = '|'; 262 else if (*dp == 0) 263 *dp = ' '; 264 page[l][0] = 0; 265 } 266 } 267