1 /*-
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * %sccs.include.redist.c%
6 */
7
8 #if defined(LIBC_SCCS) && !defined(lint)
9 static char sccsid[] = "@(#)vis.c 8.1 (Berkeley) 07/19/93";
10 #endif /* LIBC_SCCS and not lint */
11
12 #include <sys/types.h>
13 #include <limits.h>
14 #include <ctype.h>
15 #include <vis.h>
16
17 #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
18
19 /*
20 * vis - visually encode characters
21 */
22 char *
vis(dst,c,flag,nextc)23 vis(dst, c, flag, nextc)
24 register char *dst;
25 int c, nextc;
26 register int flag;
27 {
28 if ((u_int)c <= UCHAR_MAX && isgraph(c) ||
29 ((flag & VIS_SP) == 0 && c == ' ') ||
30 ((flag & VIS_TAB) == 0 && c == '\t') ||
31 ((flag & VIS_NL) == 0 && c == '\n') ||
32 ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) {
33 *dst++ = c;
34 if (c == '\\' && (flag & VIS_NOSLASH) == 0)
35 *dst++ = '\\';
36 *dst = '\0';
37 return (dst);
38 }
39
40 if (flag & VIS_CSTYLE) {
41 switch(c) {
42 case '\n':
43 *dst++ = '\\';
44 *dst++ = 'n';
45 goto done;
46 case '\r':
47 *dst++ = '\\';
48 *dst++ = 'r';
49 goto done;
50 case '\b':
51 *dst++ = '\\';
52 *dst++ = 'b';
53 goto done;
54 #if __STDC__
55 case '\a':
56 #else
57 case '\007':
58 #endif
59 *dst++ = '\\';
60 *dst++ = 'a';
61 goto done;
62 case '\v':
63 *dst++ = '\\';
64 *dst++ = 'v';
65 goto done;
66 case '\t':
67 *dst++ = '\\';
68 *dst++ = 't';
69 goto done;
70 case '\f':
71 *dst++ = '\\';
72 *dst++ = 'f';
73 goto done;
74 case ' ':
75 *dst++ = '\\';
76 *dst++ = 's';
77 goto done;
78 case '\0':
79 *dst++ = '\\';
80 *dst++ = '0';
81 if (isoctal(nextc)) {
82 *dst++ = '0';
83 *dst++ = '0';
84 }
85 goto done;
86 }
87 }
88 if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
89 *dst++ = '\\';
90 *dst++ = ((u_char)c >> 6 & 07) + '0';
91 *dst++ = ((u_char)c >> 3 & 07) + '0';
92 *dst++ = ((u_char)c & 07) + '0';
93 goto done;
94 }
95 if ((flag & VIS_NOSLASH) == 0)
96 *dst++ = '\\';
97 if (c & 0200) {
98 c &= 0177;
99 *dst++ = 'M';
100 }
101 if (iscntrl(c)) {
102 *dst++ = '^';
103 if (c == 0177)
104 *dst++ = '?';
105 else
106 *dst++ = c + '@';
107 } else {
108 *dst++ = '-';
109 *dst++ = c;
110 }
111 done:
112 *dst = '\0';
113 return (dst);
114 }
115
116 /*
117 * strvis, strvisx - visually encode characters from src into dst
118 *
119 * Dst must be 4 times the size of src to account for possible
120 * expansion. The length of dst, not including the trailing NULL,
121 * is returned.
122 *
123 * Strvisx encodes exactly len bytes from src into dst.
124 * This is useful for encoding a block of data.
125 */
126 int
strvis(dst,src,flag)127 strvis(dst, src, flag)
128 register char *dst;
129 register const char *src;
130 int flag;
131 {
132 register char c;
133 char *start;
134
135 for (start = dst; c = *src;)
136 dst = vis(dst, c, flag, *++src);
137 *dst = '\0';
138 return (dst - start);
139 }
140
141 int
strvisx(dst,src,len,flag)142 strvisx(dst, src, len, flag)
143 register char *dst;
144 register const char *src;
145 register size_t len;
146 int flag;
147 {
148 int c;
149 char *start;
150
151 for (start = dst; len > 1; len--) {
152 c = *src;
153 dst = vis(dst, c, flag, *++src);
154 }
155 if (len)
156 dst = vis(dst, *src, flag, '\0');
157 *dst = '\0';
158
159 return (dst - start);
160 }
161