vis.c revision 1.2 1 /*-
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
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. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #if defined(LIBC_SCCS) && !defined(lint)
35 /* from: static char sccsid[] = "@(#)vis.c 5.4 (Berkeley) 2/23/91"; */
36 static char rcsid[] = "$Id: vis.c,v 1.2 1993/07/15 17:54:43 cgd Exp $";
37 #endif /* LIBC_SCCS and not lint */
38
39 #include <sys/types.h>
40 #include <limits.h>
41 #include <ctype.h>
42 #include <vis.h>
43
44 #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
45
46 /*
47 * vis - visually encode characters
48 */
49 char *
50 #if __STDC__
51 vis(register char *dst, register char c, register int flag, char nextc)
52 #else
53 vis(dst, c, flag, nextc)
54 register char *dst, c;
55 char nextc;
56 register int flag;
57 #endif
58 {
59 if ((u_int)c <= UCHAR_MAX && isgraph(c) ||
60 ((flag & VIS_SP) == 0 && c == ' ') ||
61 ((flag & VIS_TAB) == 0 && c == '\t') ||
62 ((flag & VIS_NL) == 0 && c == '\n') ||
63 ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) {
64 *dst++ = c;
65 if (c == '\\' && (flag & VIS_NOSLASH) == 0)
66 *dst++ = '\\';
67 *dst = '\0';
68 return (dst);
69 }
70
71 if (flag & VIS_CSTYLE) {
72 switch(c) {
73 case '\n':
74 *dst++ = '\\';
75 *dst++ = 'n';
76 goto done;
77 case '\r':
78 *dst++ = '\\';
79 *dst++ = 'r';
80 goto done;
81 case '\b':
82 *dst++ = '\\';
83 *dst++ = 'b';
84 goto done;
85 #if __STDC__
86 case '\a':
87 #else
88 case '\007':
89 #endif
90 *dst++ = '\\';
91 *dst++ = 'a';
92 goto done;
93 case '\v':
94 *dst++ = '\\';
95 *dst++ = 'v';
96 goto done;
97 case '\t':
98 *dst++ = '\\';
99 *dst++ = 't';
100 goto done;
101 case '\f':
102 *dst++ = '\\';
103 *dst++ = 'f';
104 goto done;
105 case ' ':
106 *dst++ = '\\';
107 *dst++ = 's';
108 goto done;
109 case '\0':
110 *dst++ = '\\';
111 *dst++ = '0';
112 if (isoctal(nextc)) {
113 *dst++ = '0';
114 *dst++ = '0';
115 }
116 goto done;
117 }
118 }
119 if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
120 *dst++ = '\\';
121 *dst++ = ((u_char)c >> 6 & 07) + '0';
122 *dst++ = ((u_char)c >> 3 & 07) + '0';
123 *dst++ = ((u_char)c & 07) + '0';
124 goto done;
125 }
126 if ((flag & VIS_NOSLASH) == 0)
127 *dst++ = '\\';
128 if (c & 0200) {
129 c &= 0177;
130 *dst++ = 'M';
131 }
132 if (iscntrl(c)) {
133 *dst++ = '^';
134 if (c == 0177)
135 *dst++ = '?';
136 else
137 *dst++ = c + '@';
138 } else {
139 *dst++ = '-';
140 *dst++ = c;
141 }
142 done:
143 *dst = '\0';
144 return (dst);
145 }
146
147 /*
148 * strvis, strvisx - visually encode characters from src into dst
149 *
150 * Dst must be 4 times the size of src to account for possible
151 * expansion. The length of dst, not including the trailing NULL,
152 * is returned.
153 *
154 * Strvisx encodes exactly len bytes from src into dst.
155 * This is useful for encoding a block of data.
156 */
157 int
158 strvis(dst, src, flag)
159 register char *dst;
160 register const char *src;
161 int flag;
162 {
163 register char c;
164 char *start;
165
166 for (start = dst; c = *src;)
167 dst = vis(dst, c, flag, *++src);
168 *dst = '\0';
169 return (dst - start);
170 }
171
172 int
173 strvisx(dst, src, len, flag)
174 register char *dst;
175 register const char *src;
176 register size_t len;
177 int flag;
178 {
179 register char c;
180 char *start;
181
182 for (start = dst; len > 1; len--) {
183 c = *src;
184 dst = vis(dst, c, flag, *++src);
185 }
186 if (len)
187 dst = vis(dst, *src, flag, '\0');
188 *dst = '\0';
189
190 return (dst - start);
191 }
192