1 /* 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 char copyright[] = 20 "@(#) Copyright (c) 1989 The Regents of the University of California.\n\ 21 All rights reserved.\n"; 22 #endif /* not lint */ 23 24 #ifndef lint 25 static char sccsid[] = "@(#)vis.c 1.1 (Berkeley) 05/15/90"; 26 #endif /* not lint */ 27 28 #include <stdio.h> 29 #include <cencode.h> 30 31 int eflags, dflags, invert, strip, fold, foldwidth=80, none; 32 33 main(argc, argv) 34 char *argv[]; 35 { 36 extern char *optarg; 37 extern int optind; 38 extern int errno; 39 FILE *fp; 40 int ch; 41 42 while ((ch = getopt(argc, argv, "nwcgovishfF:")) != EOF) 43 switch((char)ch) { 44 case 'n': 45 none++; 46 break; 47 case 'w': 48 eflags |= CENC_WHITE; 49 break; 50 case 'c': 51 eflags |= CENC_CSTYLE; 52 break; 53 case 'g': 54 eflags |= CENC_GRAPH; 55 break; 56 case 'o': 57 eflags |= CENC_OCTAL; 58 break; 59 case 'v': /* vis -v considered harmful */ 60 eflags |= CENC_GRAPH | CENC_OCTAL; 61 break; 62 case 'i': 63 invert++; 64 break; 65 case 'F': 66 if ((foldwidth = atoi(optarg))<5) { 67 fprintf(stderr, 68 "vis: can't fold lines to less than 2 cols\n"); 69 exit(1); 70 } 71 /*FALLTHROUGH*/ 72 case 'f': 73 fold++; /* fold output lines to 80 cols */ 74 break; /* using hidden newline */ 75 case 's': 76 strip++; 77 break; 78 case 'h': 79 dflags |= CDEC_HAT; 80 break; 81 case '?': 82 default: 83 fprintf(stderr, 84 "usage: vis [-nwcgovifsh] [-F foldwidth]\n"); 85 exit(1); 86 } 87 argc -= optind; 88 argv += optind; 89 90 #define ALL (CENC_CSTYLE | CENC_GRAPH | CENC_OCTAL) 91 if (none) 92 eflags &= ~ALL; 93 else if (!(eflags&ALL)) 94 eflags |= ALL; 95 if (*argv) 96 while (*argv) { 97 if ((fp=fopen(*argv, "r")) != NULL) 98 process(fp, *argv); 99 else 100 fprintf(stderr, "vis: %s: %s\n", *argv, 101 (char *)strerror(errno)); 102 argv++; 103 } 104 else 105 process(stdin, "<stdin>"); 106 exit(0); 107 } 108 109 process(fp, filename) 110 FILE *fp; 111 char *filename; 112 { 113 static int col = 0; 114 register char *cp = "X"+1; /* so *(cp-1) starts out != '\n' */ 115 register int byte = 0; 116 register int c, rachar; 117 register char nc; 118 119 /* 120 * Encode 121 */ 122 if (!invert) { 123 c = getc(fp); 124 while (c != EOF) { 125 rachar = getc(fp); 126 if (strip) 127 c &= 0177; 128 cp = cencode((char)c, eflags|CENC_RACHAR, (char)rachar); 129 if (fold) { 130 /* 131 * Keep track of printables and 132 * space chars (like fold(1)). 133 */ 134 for (;;) { 135 switch(*cp) { 136 case '\n': 137 case '\r': 138 col = 0; 139 break; 140 case '\t': 141 col = col + 8 &~ 07; 142 break; 143 case '\b': 144 col = col ? col - 1 : 0; 145 break; 146 default: 147 col += strlen(cp); 148 } 149 if (col > (foldwidth-2)) { 150 printf("\\\n"); 151 col = 0; 152 } else 153 break; 154 } 155 } 156 do { 157 putchar(*cp++); 158 } while (*cp); 159 c = rachar; 160 } 161 if (fold && *(cp-1) != '\n') 162 printf("\\\n"); 163 /* 164 * Decode 165 */ 166 } else { 167 while ((c = getc(fp)) != EOF) { 168 byte++; 169 again: 170 switch(cdecode((char)c, &nc, dflags)) { 171 case CDEC_NEEDMORE: 172 case CDEC_NOCHAR: 173 break; 174 case CDEC_OK: 175 putchar(nc); 176 break; 177 case CDEC_OKPUSH: 178 putchar(nc); 179 goto again; 180 case CDEC_SYNBAD: 181 fprintf(stderr, 182 "vis: %s: offset: %d: can't decode\n", 183 filename, byte); 184 break; 185 default: 186 fprintf(stderr, 187 "vis: bad return value (can't happen)\n"); 188 exit(1); 189 } 190 } 191 if (cdecode((char)0, &nc, CDEC_END) == CDEC_OK) 192 putchar(nc); 193 } 194 exit(0); 195 } 196