vis.c revision 1.17 1 /* $NetBSD: vis.c,v 1.17 2013/02/13 13:58:44 christos Exp $ */
2
3 /*-
4 * Copyright (c) 1989, 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) 1989, 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[] = "@(#)vis.c 8.1 (Berkeley) 6/6/93";
41 #endif
42 __RCSID("$NetBSD: vis.c,v 1.17 2013/02/13 13:58:44 christos Exp $");
43 #endif /* not lint */
44
45 #include <stdio.h>
46 #include <string.h>
47 #include <stdlib.h>
48 #include <errno.h>
49 #include <wchar.h>
50 #include <unistd.h>
51 #include <err.h>
52 #include <vis.h>
53
54 #include "extern.h"
55
56 static int eflags, fold, foldwidth = 80, none, markeol;
57 #ifdef DEBUG
58 int debug;
59 #endif
60 static char *extra;
61
62 static void process(FILE *);
63
64 int
65 main(int argc, char *argv[])
66 {
67 FILE *fp;
68 int ch;
69 int rval;
70
71 while ((ch = getopt(argc, argv, "bcde:F:fhlmnostw")) != -1)
72 switch((char)ch) {
73 case 'b':
74 eflags |= VIS_NOSLASH;
75 break;
76 case 'c':
77 eflags |= VIS_CSTYLE;
78 break;
79 #ifdef DEBUG
80 case 'd':
81 debug++;
82 break;
83 #endif
84 case 'e':
85 extra = optarg;
86 break;
87 case 'F':
88 if ((foldwidth = atoi(optarg)) < 5) {
89 errx(1, "can't fold lines to less than 5 cols");
90 /* NOTREACHED */
91 }
92 markeol++;
93 break;
94 case 'f':
95 fold++; /* fold output lines to 80 cols */
96 break; /* using hidden newline */
97 case 'h':
98 eflags |= VIS_HTTPSTYLE;
99 break;
100 case 'l':
101 markeol++; /* mark end of line with \$ */
102 break;
103 case 'm':
104 eflags |= VIS_MIMESTYLE;
105 if (foldwidth == 80)
106 foldwidth = 76;
107 break;
108 case 'n':
109 none++;
110 break;
111 case 'o':
112 eflags |= VIS_OCTAL;
113 break;
114 case 's':
115 eflags |= VIS_SAFE;
116 break;
117 case 't':
118 eflags |= VIS_TAB;
119 break;
120 case 'w':
121 eflags |= VIS_WHITE;
122 break;
123 case '?':
124 default:
125 (void)fprintf(stderr,
126 "Usage: %s [-bcfhlmnostw] [-e extra]"
127 " [-F foldwidth] [file ...]\n", getprogname());
128 return 1;
129 }
130
131 if ((eflags & (VIS_HTTPSTYLE|VIS_MIMESTYLE)) ==
132 (VIS_HTTPSTYLE|VIS_MIMESTYLE))
133 errx(1, "Can't specify -m and -h at the same time");
134
135 argc -= optind;
136 argv += optind;
137
138 rval = 0;
139
140 if (*argv)
141 while (*argv) {
142 if ((fp = fopen(*argv, "r")) != NULL) {
143 process(fp);
144 (void)fclose(fp);
145 } else {
146 warn("%s", *argv);
147 rval = 1;
148 }
149 argv++;
150 }
151 else
152 process(stdin);
153 return rval;
154 }
155
156 static void
157 process(FILE *fp)
158 {
159 static int col = 0;
160 static char nul[] = "\0";
161 char *cp = nul + 1; /* so *(cp-1) starts out != '\n' */
162 wint_t c, rachar;
163 char buff[5];
164
165 c = getwc(fp);
166 if (c == WEOF && errno == EILSEQ)
167 c = (wint_t)getc(fp);
168 while (c != WEOF) {
169 rachar = getwc(fp);
170 if (rachar == WEOF && errno == EILSEQ)
171 rachar = (wint_t)getc(fp);
172 if (none) {
173 cp = buff;
174 *cp++ = c;
175 if (c == '\\')
176 *cp++ = '\\';
177 *cp = '\0';
178 } else if (markeol && c == '\n') {
179 cp = buff;
180 if ((eflags & VIS_NOSLASH) == 0)
181 *cp++ = '\\';
182 *cp++ = '$';
183 *cp++ = '\n';
184 *cp = '\0';
185 } else if (extra)
186 (void)svis(buff, c, eflags, rachar, extra);
187 else
188 (void)vis(buff, c, eflags, rachar);
189
190 cp = buff;
191 if (fold) {
192 #ifdef DEBUG
193 if (debug)
194 (void)printf("<%02d,", col);
195 #endif
196 col = foldit(cp, col, foldwidth, eflags);
197 #ifdef DEBUG
198 if (debug)
199 (void)printf("%02d>", col);
200 #endif
201 }
202 do {
203 (void)putchar(*cp);
204 } while (*++cp);
205 c = rachar;
206 }
207 /*
208 * terminate partial line with a hidden newline
209 */
210 if (fold && *(cp - 1) != '\n')
211 (void)printf(eflags & VIS_MIMESTYLE ? "=\n" : "\\\n");
212 }
213