Annotation of src/lib/libc/gen/vis.c, Revision 1.17
1.17 ! wennmach 1: /* $NetBSD: vis.c,v 1.16 1999/11/28 22:51:37 wennmach Exp $ */
1.6 cgd 2:
1.1 cgd 3: /*-
1.15 wennmach 4: * Copyright (c) 1999 The NetBSD Foundation, Inc.
1.6 cgd 5: * Copyright (c) 1989, 1993
1.16 wennmach 6: * The Regents of the University of California. All rights reserved.
1.1 cgd 7: *
8: * Redistribution and use in source and binary forms, with or without
9: * modification, are permitted provided that the following conditions
10: * are met:
11: * 1. Redistributions of source code must retain the above copyright
12: * notice, this list of conditions and the following disclaimer.
13: * 2. Redistributions in binary form must reproduce the above copyright
14: * notice, this list of conditions and the following disclaimer in the
15: * documentation and/or other materials provided with the distribution.
16: * 3. All advertising materials mentioning features or use of this software
17: * must display the following acknowledgement:
1.16 wennmach 18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
1.1 cgd 20: * 4. Neither the name of the University nor the names of its contributors
21: * may be used to endorse or promote products derived from this software
22: * without specific prior written permission.
23: *
24: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34: * SUCH DAMAGE.
35: */
36:
1.15 wennmach 37:
1.7 christos 38: #include <sys/cdefs.h>
1.15 wennmach 39: #if !defined(lint)
1.17 ! wennmach 40: __RCSID("$NetBSD: vis.c,v 1.16 1999/11/28 22:51:37 wennmach Exp $");
1.15 wennmach 41: #endif /* not lint */
1.1 cgd 42:
1.8 jtc 43: #include "namespace.h"
1.1 cgd 44: #include <sys/types.h>
1.12 lukem 45:
46: #include <assert.h>
47: #include <ctype.h>
1.2 cgd 48: #include <limits.h>
1.12 lukem 49: #include <stdio.h>
1.15 wennmach 50: #include <string.h>
1.1 cgd 51: #include <vis.h>
1.8 jtc 52:
53: #ifdef __weak_alias
1.15 wennmach 54: __weak_alias(strsvis,_strsvis);
55: __weak_alias(strsvisx,_strsvisx);
1.8 jtc 56: __weak_alias(strvis,_strvis);
57: __weak_alias(strvisx,_strvisx);
1.15 wennmach 58: __weak_alias(svis,_svis);
1.8 jtc 59: __weak_alias(vis,_vis);
60: #endif
1.1 cgd 61:
1.15 wennmach 62: #undef BELL
63: #if defined(__STDC__)
64: #define BELL '\a'
65: #else
66: #define BELL '\007'
67: #endif
68:
1.16 wennmach 69: #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
70: #define iswhite(c) (c == ' ' || c == '\t' || c == '\n')
71: #define issafe(c) (c == '\b' || c == BELL || c == '\r')
72:
73: #define MAXEXTRAS 5
1.15 wennmach 74:
75:
1.16 wennmach 76: #define MAKEEXTRALIST(flag, extra) \
77: do { \
78: char *pextra = extra; \
79: if (flag & VIS_SP) *pextra++ = ' '; \
80: if (flag & VIS_TAB) *pextra++ = '\t'; \
81: if (flag & VIS_NL) *pextra++ = '\n'; \
82: if ((flag & VIS_NOSLASH) == 0) *pextra++ = '\\'; \
83: *pextra = '\0'; \
1.15 wennmach 84: } while (0)
85:
86: /*
87: * This is SVIS, the central macro of vis.
1.16 wennmach 88: * dst: Pointer to the destination buffer
89: * c: Character to encode
1.15 wennmach 90: * flag: Flag word
91: * nextc: The character following 'c'
92: * extra: Pointer to the list of extra characters to be
1.16 wennmach 93: * backslash-protected.
1.15 wennmach 94: */
1.16 wennmach 95: #define SVIS(dst, c, flag, nextc, extra) \
96: do { \
97: int isextra, isc; \
98: isextra = strchr(extra, c) != NULL; \
1.17 ! wennmach 99: if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \
! 100: ((flag & VIS_SAFE) && issafe(c)))) { \
1.16 wennmach 101: *dst++ = c; \
102: break; \
103: } \
104: isc = 0; \
105: if (flag & VIS_CSTYLE) { \
106: switch (c) { \
107: case '\n': \
108: isc = 1; *dst++ = '\\'; *dst++ = 'n'; \
109: break; \
110: case '\r': \
111: isc = 1; *dst++ = '\\'; *dst++ = 'r'; \
112: break; \
113: case '\b': \
114: isc = 1; *dst++ = '\\'; *dst++ = 'b'; \
115: break; \
116: case BELL: \
117: isc = 1; *dst++ = '\\'; *dst++ = 'a'; \
118: break; \
119: case '\v': \
120: isc = 1; *dst++ = '\\'; *dst++ = 'v'; \
121: break; \
122: case '\t': \
123: isc = 1; *dst++ = '\\'; *dst++ = 't'; \
124: break; \
125: case '\f': \
126: isc = 1; *dst++ = '\\'; *dst++ = 'f'; \
127: break; \
128: case ' ': \
129: isc = 1; *dst++ = '\\'; *dst++ = 's'; \
130: break; \
131: case '\0': \
132: isc = 1; *dst++ = '\\'; *dst++ = '0'; \
133: if (isoctal(nextc)) { \
134: *dst++ = '0'; \
135: *dst++ = '0'; \
136: } \
137: } \
138: } \
139: if (isc) break; \
1.17 ! wennmach 140: if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \
1.16 wennmach 141: *dst++ = '\\'; \
142: *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; \
143: *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; \
144: *dst++ = (c & 07) + '0'; \
145: } else { \
146: if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \
147: if (c & 0200) { \
148: c &= 0177; *dst++ = 'M'; \
149: } \
150: if (iscntrl(c)) { \
151: *dst++ = '^'; \
152: if (c == 0177) \
153: *dst++ = '?'; \
154: else \
155: *dst++ = c + '@'; \
156: } else { \
157: *dst++ = '-'; *dst++ = c; \
158: } \
159: } \
1.15 wennmach 160: } while(0)
161:
162:
163: /*
1.17 ! wennmach 164: * svis - visually encode characters, also encoding the characters
! 165: * pointed to by `extra'
1.15 wennmach 166: */
167: char *
168: svis(dst, c, flag, nextc, extra)
1.16 wennmach 169: char *dst;
170: int c, flag, nextc;
171: const char *extra;
1.15 wennmach 172: {
1.16 wennmach 173: _DIAGASSERT(dst != NULL);
174: _DIAGASSERT(extra != NULL);
1.15 wennmach 175:
1.16 wennmach 176: SVIS(dst, c, flag, nextc, extra);
177: *dst = '\0';
178: return(dst);
1.15 wennmach 179: }
180:
181:
182: /*
183: * strsvis, strsvisx - visually encode characters from src into dst
184: *
1.16 wennmach 185: * Extra is a pointer to a \0-terminated list of characters to
1.17 ! wennmach 186: * be encoded, too. These functions are useful e. g. to
! 187: * encode strings in such a way so that they are not interpreted
1.16 wennmach 188: * by a shell.
189: *
190: * Dst must be 4 times the size of src to account for possible
191: * expansion. The length of dst, not including the trailing NULL,
192: * is returned.
1.15 wennmach 193: *
1.16 wennmach 194: * Strsvisx encodes exactly len bytes from src into dst.
195: * This is useful for encoding a block of data.
1.15 wennmach 196: */
197: int
198: strsvis(dst, src, flag, extra)
1.16 wennmach 199: char *dst;
200: const char *src;
201: int flag;
202: const char *extra;
1.15 wennmach 203: {
1.16 wennmach 204: char c;
205: char *start;
1.15 wennmach 206:
1.16 wennmach 207: _DIAGASSERT(dst != NULL);
208: _DIAGASSERT(src != NULL);
209: _DIAGASSERT(extra != NULL);
210:
211: for (start = dst; (c = *src++) != '\0'; /* empty */)
212: SVIS(dst, c, flag, *src, extra);
213: *dst = '\0';
214: return (dst - start);
1.15 wennmach 215: }
216:
217:
218: int
219: strsvisx(dst, src, len, flag, extra)
1.16 wennmach 220: char *dst;
221: const char *src;
222: size_t len;
223: int flag;
224: const char *extra;
1.15 wennmach 225: {
1.16 wennmach 226: char c;
227: char *start;
1.15 wennmach 228:
1.16 wennmach 229: _DIAGASSERT(dst != NULL);
230: _DIAGASSERT(src != NULL);
231: _DIAGASSERT(extra != NULL);
232:
233: for (start = dst; len > 0; len--) {
234: c = *src++;
235: SVIS(dst, c, flag, len ? *src : '\0', extra);
236: }
237: *dst = '\0';
238: return (dst - start);
1.15 wennmach 239: }
240:
1.1 cgd 241:
242: /*
243: * vis - visually encode characters
244: */
245: char *
246: vis(dst, c, flag, nextc)
1.16 wennmach 247: char *dst;
248: int c, flag, nextc;
249:
1.15 wennmach 250: {
1.16 wennmach 251: char extra[MAXEXTRAS];
1.15 wennmach 252:
1.16 wennmach 253: _DIAGASSERT(dst != NULL);
1.15 wennmach 254:
1.16 wennmach 255: MAKEEXTRALIST(flag, extra);
256: SVIS(dst, c, flag, nextc, extra);
257: *dst = '\0';
258: return (dst);
1.1 cgd 259: }
260:
1.15 wennmach 261:
1.1 cgd 262: /*
263: * strvis, strvisx - visually encode characters from src into dst
1.16 wennmach 264: *
265: * Dst must be 4 times the size of src to account for possible
266: * expansion. The length of dst, not including the trailing NULL,
267: * is returned.
1.1 cgd 268: *
1.16 wennmach 269: * Strvisx encodes exactly len bytes from src into dst.
270: * This is useful for encoding a block of data.
1.1 cgd 271: */
272: int
273: strvis(dst, src, flag)
1.16 wennmach 274: char *dst;
275: const char *src;
276: int flag;
1.15 wennmach 277: {
1.16 wennmach 278: char extra[MAXEXTRAS];
1.15 wennmach 279:
1.16 wennmach 280: MAKEEXTRALIST(flag, extra);
281: return (strsvis(dst, src, flag, extra));
1.1 cgd 282: }
283:
1.15 wennmach 284:
1.1 cgd 285: int
286: strvisx(dst, src, len, flag)
1.16 wennmach 287: char *dst;
288: const char *src;
289: size_t len;
290: int flag;
1.15 wennmach 291: {
1.16 wennmach 292: char extra[MAXEXTRAS];
1.1 cgd 293:
1.16 wennmach 294: MAKEEXTRALIST(flag, extra);
295: return (strsvisx(dst, src, len, flag, extra));
1.1 cgd 296: }
CVSweb <webmaster@jp.NetBSD.org>