2 * vis functions - visually encode characters
3 * Originally from OpenBSD
7 * Copyright (c) 1989, 1993
8 * The Regents of the University of California. All rights reserved.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
42 * vis - visually encode characters
45 vis(dst, c, flag, nextc)
52 if (c == '\\' && (flag & VIS_NOSLASH) == 0)
58 if (flag & VIS_CSTYLE) {
106 if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
108 *dst++ = ((u_char)c >> 6 & 07) + '0';
109 *dst++ = ((u_char)c >> 3 & 07) + '0';
110 *dst++ = ((u_char)c & 07) + '0';
113 if ((flag & VIS_NOSLASH) == 0)
135 * strvis, strnvis, strvisx - visually encode characters from src into dst
137 * Dst must be 4 times the size of src to account for possible
138 * expansion. The length of dst, not including the trailing NULL,
141 * Strnvis will write no more than siz-1 bytes (and will NULL terminate).
142 * The number of bytes needed to fully encode the string is returned.
144 * Strvisx encodes exactly len bytes from src into dst.
145 * This is useful for encoding a block of data.
148 strvis(dst, src, flag)
150 register const char *src;
156 for (start = dst; (c = *src);)
157 dst = vis(dst, c, flag, *++src);
159 return (dst - start);
163 strnvis(dst, src, siz, flag)
165 register const char *src;
172 for (start = dst, end = start + siz - 1; (c = *src) && dst < end; ) {
175 if (c == '\\' && (flag & VIS_NOSLASH) == 0) {
176 /* need space for the extra '\\' */
186 /* vis(3) requires up to 4 chars */
188 dst = vis(dst, c, flag, *++src);
197 /* adjust return value for truncation */
199 dst += vis(tbuf, c, flag, *++src) - tbuf;
201 return (dst - start);
205 strvisx(dst, src, len, flag)
207 register const char *src;
214 for (start = dst; len > 1; len--) {
216 dst = vis(dst, c, flag, *++src);
219 dst = vis(dst, *src, flag, '\0');
221 return (dst - start);
225 * unvis - decode characters previously encoded by vis
229 unvis(char *cp, char c, int *astate, int flag)
231 unvis(cp, c, astate, flag)
238 if (flag & UNVIS_END) {
239 if (*astate == S_OCTAL2 || *astate == S_OCTAL3) {
241 return (UNVIS_VALID);
243 return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
255 return (UNVIS_VALID);
262 return (UNVIS_VALID);
263 case '0': case '1': case '2': case '3':
264 case '4': case '5': case '6': case '7':
278 return (UNVIS_VALID);
282 return (UNVIS_VALID);
286 return (UNVIS_VALID);
290 return (UNVIS_VALID);
294 return (UNVIS_VALID);
298 return (UNVIS_VALID);
302 return (UNVIS_VALID);
306 return (UNVIS_VALID);
310 return (UNVIS_VALID);
316 return (UNVIS_NOCHAR);
322 return (UNVIS_NOCHAR);
325 return (UNVIS_SYNBAD);
334 return (UNVIS_SYNBAD);
341 return (UNVIS_VALID);
349 return (UNVIS_VALID);
351 case S_OCTAL2: /* second possible octal digit */
354 * yes - and maybe a third
356 *cp = (*cp << 3) + (c - '0');
361 * no - done with current sequence, push back passed char
364 return (UNVIS_VALIDPUSH);
366 case S_OCTAL3: /* third possible octal digit */
369 *cp = (*cp << 3) + (c - '0');
370 return (UNVIS_VALID);
373 * we were done, push back passed char
375 return (UNVIS_VALIDPUSH);
379 * decoder in unknown state - (probably uninitialized)
382 return (UNVIS_SYNBAD);
387 * strunvis - decode src into dst
389 * Number of chars decoded into dst is returned, -1 on error.
390 * Dst is null terminated.
396 register const char *src;
402 while ((c = *src++)) {
404 switch (unvis(dst, c, &state, 0)) {
408 case UNVIS_VALIDPUSH:
418 if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID)
421 return (dst - start);
424 #endif /* HAVE_STRVIS */