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