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