kernel: Remove the FFS_ROOT option. It was a no-op since 4.9.
[dragonfly.git] / usr.bin / vis / vis.c
blobcb49f28ffaf0824f776d0b7bfddaefcc9b3b487d
1 /*-
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of the University nor the names of its contributors
14 * may be used to endorse or promote products derived from this software
15 * without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
29 * @(#) Copyright (c) 1989, 1993 The Regents of the University of California. All rights reserved.
30 * @(#)vis.c 8.1 (Berkeley) 6/6/93
31 * $NetBSD: vis.c,v 1.25 2015/05/24 19:42:39 christos Exp $
34 #include <stdio.h>
35 #include <string.h>
36 #include <stdlib.h>
37 #include <errno.h>
38 #include <wchar.h>
39 #include <limits.h>
40 #include <unistd.h>
41 #include <err.h>
42 #include <vis.h>
44 #include "extern.h"
46 static int eflags, fold, foldwidth = 80, none, markeol;
47 #ifdef DEBUG
48 int debug;
49 #endif
50 static const char *extra = "";
52 static void process(FILE *);
54 int
55 main(int argc, char *argv[])
57 FILE *fp;
58 int ch;
59 int rval;
61 while ((ch = getopt(argc, argv, "abcde:F:fhlMmNnoSstw")) != -1)
62 switch((char)ch) {
63 case 'a':
64 eflags |= VIS_ALL;
65 break;
66 case 'b':
67 eflags |= VIS_NOSLASH;
68 break;
69 case 'c':
70 eflags |= VIS_CSTYLE;
71 break;
72 #ifdef DEBUG
73 case 'd':
74 debug++;
75 break;
76 #endif
77 case 'e':
78 extra = optarg;
79 break;
80 case 'F':
81 if ((foldwidth = atoi(optarg)) < 5) {
82 errx(1, "can't fold lines to less than 5 cols");
84 markeol++;
85 break;
86 case 'f':
87 fold++; /* fold output lines to 80 cols */
88 break; /* using hidden newline */
89 case 'h':
90 eflags |= VIS_HTTPSTYLE;
91 break;
92 case 'l':
93 markeol++; /* mark end of line with \$ */
94 break;
95 case 'M':
96 eflags |= VIS_META;
97 break;
98 case 'm':
99 eflags |= VIS_MIMESTYLE;
100 if (foldwidth == 80)
101 foldwidth = 76;
102 break;
103 case 'N':
104 eflags |= VIS_NOLOCALE;
105 break;
106 case 'n':
107 none++;
108 break;
109 case 'o':
110 eflags |= VIS_OCTAL;
111 break;
112 case 'S':
113 eflags |= VIS_SHELL;
114 break;
115 case 's':
116 eflags |= VIS_SAFE;
117 break;
118 case 't':
119 eflags |= VIS_TAB;
120 break;
121 case 'w':
122 eflags |= VIS_WHITE;
123 break;
124 case '?':
125 default:
126 fprintf(stderr,
127 "usage: %s [-abcfhlMmNnoSstw] [-e extra]"
128 " [-F foldwidth] [file ...]\n", getprogname());
129 return 1;
132 if ((eflags & (VIS_HTTPSTYLE|VIS_MIMESTYLE)) ==
133 (VIS_HTTPSTYLE|VIS_MIMESTYLE))
134 errx(1, "Can't specify -m and -h at the same time");
136 argc -= optind;
137 argv += optind;
139 rval = 0;
141 if (*argv)
142 while (*argv) {
143 if ((fp = fopen(*argv, "r")) != NULL) {
144 process(fp);
145 fclose(fp);
146 } else {
147 warn("%s", *argv);
148 rval = 1;
150 argv++;
152 else
153 process(stdin);
154 return rval;
157 static void
158 process(FILE *fp)
160 static int col = 0;
161 static char nul[] = "\0";
162 char *cp = nul + 1; /* so *(cp-1) starts out != '\n' */
163 wint_t c, c1, rachar;
164 char mbibuff[2 * MB_LEN_MAX + 1]; /* max space for 2 wchars */
165 char buff[4 * MB_LEN_MAX + 1]; /* max encoding length for one char */
166 int mbilen, cerr = 0, raerr = 0;
169 * The input stream is considered to be multibyte characters.
170 * The input loop will read this data inputing one character,
171 * possibly multiple bytes, at a time and converting each to
172 * a wide character wchar_t.
174 * The vis(3) functions, however, require single either bytes
175 * or a multibyte string as their arguments. So we convert
176 * our input wchar_t and the following look-ahead wchar_t to
177 * a multibyte string for processing by vis(3).
180 /* Read one multibyte character, store as wchar_t */
181 c = getwc(fp);
182 if (c == WEOF && errno == EILSEQ) {
183 /* Error in multibyte data. Read one byte. */
184 c = (wint_t)getc(fp);
185 cerr = 1;
187 while (c != WEOF) {
188 /* Clear multibyte input buffer. */
189 memset(mbibuff, 0, sizeof(mbibuff));
190 /* Read-ahead next multibyte character. */
191 if (!cerr)
192 rachar = getwc(fp);
193 if (cerr || (rachar == WEOF && errno == EILSEQ)) {
194 /* Error in multibyte data. Read one byte. */
195 rachar = (wint_t)getc(fp);
196 raerr = 1;
198 if (none) {
199 /* Handle -n flag. */
200 cp = buff;
201 *cp++ = c;
202 if (c == '\\')
203 *cp++ = '\\';
204 *cp = '\0';
205 } else if (markeol && c == '\n') {
206 /* Handle -l flag. */
207 cp = buff;
208 if ((eflags & VIS_NOSLASH) == 0)
209 *cp++ = '\\';
210 *cp++ = '$';
211 *cp++ = '\n';
212 *cp = '\0';
213 } else {
215 * Convert character using vis(3) library.
216 * At this point we will process one character.
217 * But we must pass the vis(3) library this
218 * character plus the next one because the next
219 * one is used as a look-ahead to decide how to
220 * encode this one under certain circumstances.
222 * Since our characters may be multibyte, e.g.,
223 * in the UTF-8 locale, we cannot use vis() and
224 * svis() which require byte input, so we must
225 * create a multibyte string and use strvisx().
227 /* Treat EOF as a NUL char. */
228 c1 = rachar;
229 if (c1 == WEOF)
230 c1 = L'\0';
232 * If we hit a multibyte conversion error above,
233 * insert byte directly into string buff because
234 * wctomb() will fail. Else convert wchar_t to
235 * multibyte using wctomb().
237 if (cerr) {
238 *mbibuff = (char)c;
239 mbilen = 1;
240 } else
241 mbilen = wctomb(mbibuff, c);
242 /* Same for look-ahead character. */
243 if (raerr)
244 mbibuff[mbilen] = (char)c1;
245 else
246 wctomb(mbibuff + mbilen, c1);
247 /* Perform encoding on just first character. */
248 strsenvisx(buff, 4 * MB_LEN_MAX, mbibuff,
249 1, eflags, extra, &cerr);
252 cp = buff;
253 if (fold) {
254 #ifdef DEBUG
255 if (debug)
256 printf("<%02d,", col);
257 #endif
258 col = foldit(cp, col, foldwidth, eflags);
259 #ifdef DEBUG
260 if (debug)
261 printf("%02d>", col);
262 #endif
264 do {
265 putchar(*cp);
266 } while (*++cp);
267 c = rachar;
268 cerr = raerr;
271 * terminate partial line with a hidden newline
273 if (fold && *(cp - 1) != '\n')
274 printf(eflags & VIS_MIMESTYLE ? "=\n" : "\\\n");