Added new 4.4 assert that Chris Torek posted to the net.
[unix-history] / lib / libc / gen / vis.c
CommitLineData
15637ed4
RG
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)
35static char sccsid[] = "@(#)vis.c 5.4 (Berkeley) 2/23/91";
36#endif /* LIBC_SCCS and not lint */
37
38#include <sys/types.h>
39#include <ctype.h>
40#include <vis.h>
41
42#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
43
44/*
45 * vis - visually encode characters
46 */
47char *
48#if __STDC__
49vis(register char *dst, register char c, register int flag, char nextc)
50#else
51vis(dst, c, flag, nextc)
52 register char *dst, c;
53 char nextc;
54 register int flag;
55#endif
56{
57 if (isascii(c) && isgraph(c) ||
58 ((flag & VIS_SP) == 0 && c == ' ') ||
59 ((flag & VIS_TAB) == 0 && c == '\t') ||
60 ((flag & VIS_NL) == 0 && c == '\n') ||
61 ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) {
62 *dst++ = c;
63 if (c == '\\' && (flag & VIS_NOSLASH) == 0)
64 *dst++ = '\\';
65 *dst = '\0';
66 return (dst);
67 }
68
69 if (flag & VIS_CSTYLE) {
70 switch(c) {
71 case '\n':
72 *dst++ = '\\';
73 *dst++ = 'n';
74 goto done;
75 case '\r':
76 *dst++ = '\\';
77 *dst++ = 'r';
78 goto done;
79 case '\b':
80 *dst++ = '\\';
81 *dst++ = 'b';
82 goto done;
83#if __STDC__
84 case '\a':
85#else
86 case '\007':
87#endif
88 *dst++ = '\\';
89 *dst++ = 'a';
90 goto done;
91 case '\v':
92 *dst++ = '\\';
93 *dst++ = 'v';
94 goto done;
95 case '\t':
96 *dst++ = '\\';
97 *dst++ = 't';
98 goto done;
99 case '\f':
100 *dst++ = '\\';
101 *dst++ = 'f';
102 goto done;
103 case ' ':
104 *dst++ = '\\';
105 *dst++ = 's';
106 goto done;
107 case '\0':
108 *dst++ = '\\';
109 *dst++ = '0';
110 if (isoctal(nextc)) {
111 *dst++ = '0';
112 *dst++ = '0';
113 }
114 goto done;
115 }
116 }
117 if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
118 *dst++ = '\\';
119 *dst++ = ((u_char)c >> 6 & 07) + '0';
120 *dst++ = ((u_char)c >> 3 & 07) + '0';
121 *dst++ = ((u_char)c & 07) + '0';
122 goto done;
123 }
124 if ((flag & VIS_NOSLASH) == 0)
125 *dst++ = '\\';
126 if (c & 0200) {
127 c &= 0177;
128 *dst++ = 'M';
129 }
130 if (iscntrl(c)) {
131 *dst++ = '^';
132 if (c == 0177)
133 *dst++ = '?';
134 else
135 *dst++ = c + '@';
136 } else {
137 *dst++ = '-';
138 *dst++ = c;
139 }
140done:
141 *dst = '\0';
142 return (dst);
143}
144
145/*
146 * strvis, strvisx - visually encode characters from src into dst
147 *
148 * Dst must be 4 times the size of src to account for possible
149 * expansion. The length of dst, not including the trailing NULL,
150 * is returned.
151 *
152 * Strvisx encodes exactly len bytes from src into dst.
153 * This is useful for encoding a block of data.
154 */
155int
156strvis(dst, src, flag)
157 register char *dst;
158 register const char *src;
159 int flag;
160{
161 register char c;
162 char *start = dst;
163
164 for (;c = *src; src++)
165 dst = vis(dst, c, flag, *(src+1));
166
167 return (dst - start);
168}
169
170int
171strvisx(dst, src, len, flag)
172 register char *dst;
173 register const char *src;
174 register size_t len;
175 int flag;
176{
177 char *start = dst;
178
179 while (len > 1) {
180 dst = vis(dst, *src, flag, *(src+1));
181 len--;
182 }
183 if (len)
184 dst = vis(dst, *src, flag, '\0');
185
186 return (dst - start);
187}