1/* $NetBSD: colcrt.c,v 1.7 2005/02/17 17:17:25 xtraeme 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.7 2005/02/17 17:17:25 xtraeme 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 default: 162 if (outcol >= 132) { 163 outcol++; 164 continue; 165 } 166 cp = &page[outline][outcol]; 167 outcol++; 168 if (c == '_') { 169 if (suppresul) 170 continue; 171 cp += 132; 172 c = '-'; 173 } 174 if (*cp == 0) { 175 *cp = c; 176 dp = cp - outcol; 177 for (cp--; cp >= dp && *cp == 0; cp--) 178 *cp = ' '; 179 } else 180 if (plus(c, *cp) || plus(*cp, c)) 181 *cp = '+'; 182 else if (*cp == ' ' || *cp == 0) 183 *cp = c; 184 continue; 185 } 186 } 187 } while (argc > 0); 188 fflush(stdout); 189 exit(0); 190} 191 192int 193plus(char c, char d) 194{ 195 196 return ((c == '|' && d == '-') || d == '_'); 197} 198 199int first; 200 201void 202pflush(int ol) 203{ 204 int i; 205 char *cp; 206 char lastomit; 207 int l; 208 209 l = ol; 210 lastomit = 0; 211 if (l > 266) 212 l = 266; 213 else 214 l |= 1; 215 for (i = first | 1; i < l; i++) { 216 move(i, i - 1); 217 move(i, i + 1); 218 } 219 for (i = first; i < l; i++) { 220 cp = page[i]; 221 if (printall == 0 && lastomit == 0 && *cp == 0) { 222 lastomit = 1; 223 continue; 224 } 225 lastomit = 0; 226 printf("%s\n", cp); 227 } 228 memmove(page, page[ol], (267 - ol) * 132); 229 memset(page[267- ol], 0, ol * 132); 230 outline -= ol; 231 outcol = 0; 232 first = 1; 233} 234 235void 236move(int l, int m) 237{ 238 char *cp, *dp; 239 240 for (cp = page[l], dp = page[m]; *cp; cp++, dp++) { 241 switch (*cp) { 242 case '|': 243 if (*dp != ' ' && *dp != '|' && *dp != 0) 244 return; 245 break; 246 case ' ': 247 break; 248 default: 249 return; 250 } 251 } 252 if (*cp == 0) { 253 for (cp = page[l], dp = page[m]; *cp; cp++, dp++) 254 if (*cp == '|') 255 *dp = '|'; 256 else if (*dp == 0) 257 *dp = ' '; 258 page[l][0] = 0; 259 } 260} 261