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 40static 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 65char page[267][132]; 66 67int outline = 1; 68int outcol; 69 70char suppresul; 71char printall; 72 73char *progname; 74FILE *f; 75 76void move(int, int); 77void pflush(int); 78int plus(char, char); 79 80int 81main(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 193int 194plus(char c, char d) 195{ 196 197 return ((c == '|' && d == '-') || d == '_'); 198} 199 200int first; 201 202void 203pflush(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 236void 237move(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