Annotation of src/lib/libc/gen/vis.c, Revision 1.13.4.1
1.13.4.1! wrstuden 1: /* $NetBSD: vis.c,v 1.17 1999/12/07 18:20:28 wennmach Exp $ */
1.6 cgd 2:
1.1 cgd 3: /*-
1.13.4.1! wrstuden 4: * Copyright (c) 1999 The NetBSD Foundation, Inc.
1.6 cgd 5: * Copyright (c) 1989, 1993
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:
18: * This product includes software developed by the University of
19: * California, Berkeley and its contributors.
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.13.4.1! wrstuden 37:
1.7 christos 38: #include <sys/cdefs.h>
1.13.4.1! wrstuden 39: #if !defined(lint)
! 40: __RCSID("$NetBSD: vis.c,v 1.17 1999/12/07 18:20:28 wennmach Exp $");
! 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.13.4.1! wrstuden 50: #include <string.h>
1.1 cgd 51: #include <vis.h>
1.8 jtc 52:
53: #ifdef __weak_alias
1.13.4.1! wrstuden 54: __weak_alias(strsvis,_strsvis);
! 55: __weak_alias(strsvisx,_strsvisx);
1.8 jtc 56: __weak_alias(strvis,_strvis);
57: __weak_alias(strvisx,_strvisx);
1.13.4.1! wrstuden 58: __weak_alias(svis,_svis);
1.8 jtc 59: __weak_alias(vis,_vis);
60: #endif
1.1 cgd 61:
1.13.4.1! wrstuden 62: #undef BELL
! 63: #if defined(__STDC__)
! 64: #define BELL '\a'
! 65: #else
! 66: #define BELL '\007'
! 67: #endif
! 68:
! 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
! 74:
! 75:
! 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'; \
! 84: } while (0)
1.1 cgd 85:
86: /*
1.13.4.1! wrstuden 87: * This is SVIS, the central macro of vis.
! 88: * dst: Pointer to the destination buffer
! 89: * c: Character to encode
! 90: * flag: Flag word
! 91: * nextc: The character following 'c'
! 92: * extra: Pointer to the list of extra characters to be
! 93: * backslash-protected.
! 94: */
! 95: #define SVIS(dst, c, flag, nextc, extra) \
! 96: do { \
! 97: int isextra, isc; \
! 98: isextra = strchr(extra, c) != NULL; \
! 99: if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \
! 100: ((flag & VIS_SAFE) && issafe(c)))) { \
! 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; \
! 140: if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \
! 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: } \
! 160: } while(0)
! 161:
! 162:
! 163: /*
! 164: * svis - visually encode characters, also encoding the characters
! 165: * pointed to by `extra'
1.1 cgd 166: */
167: char *
1.13.4.1! wrstuden 168: svis(dst, c, flag, nextc, extra)
1.9 perry 169: char *dst;
1.13.4.1! wrstuden 170: int c, flag, nextc;
! 171: const char *extra;
1.1 cgd 172: {
1.12 lukem 173: _DIAGASSERT(dst != NULL);
1.13.4.1! wrstuden 174: _DIAGASSERT(extra != NULL);
1.12 lukem 175:
1.13.4.1! wrstuden 176: SVIS(dst, c, flag, nextc, extra);
1.1 cgd 177: *dst = '\0';
1.13.4.1! wrstuden 178: return(dst);
1.1 cgd 179: }
180:
1.13.4.1! wrstuden 181:
1.1 cgd 182: /*
1.13.4.1! wrstuden 183: * strsvis, strsvisx - visually encode characters from src into dst
! 184: *
! 185: * Extra is a pointer to a \0-terminated list of characters to
! 186: * be encoded, too. These functions are useful e. g. to
! 187: * encode strings in such a way so that they are not interpreted
! 188: * by a shell.
1.1 cgd 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.
193: *
1.13.4.1! wrstuden 194: * Strsvisx encodes exactly len bytes from src into dst.
1.1 cgd 195: * This is useful for encoding a block of data.
196: */
197: int
1.13.4.1! wrstuden 198: strsvis(dst, src, flag, extra)
1.9 perry 199: char *dst;
200: const char *src;
1.1 cgd 201: int flag;
1.13.4.1! wrstuden 202: const char *extra;
1.1 cgd 203: {
1.9 perry 204: char c;
1.2 cgd 205: char *start;
1.1 cgd 206:
1.12 lukem 207: _DIAGASSERT(dst != NULL);
208: _DIAGASSERT(src != NULL);
1.13.4.1! wrstuden 209: _DIAGASSERT(extra != NULL);
1.12 lukem 210:
1.13.4.1! wrstuden 211: for (start = dst; (c = *src++) != '\0'; /* empty */)
! 212: SVIS(dst, c, flag, *src, extra);
1.2 cgd 213: *dst = '\0';
1.1 cgd 214: return (dst - start);
215: }
216:
1.13.4.1! wrstuden 217:
1.1 cgd 218: int
1.13.4.1! wrstuden 219: strsvisx(dst, src, len, flag, extra)
1.9 perry 220: char *dst;
221: const char *src;
222: size_t len;
1.1 cgd 223: int flag;
1.13.4.1! wrstuden 224: const char *extra;
1.1 cgd 225: {
1.9 perry 226: char c;
1.4 mycroft 227: char *start;
1.12 lukem 228:
229: _DIAGASSERT(dst != NULL);
230: _DIAGASSERT(src != NULL);
1.13.4.1! wrstuden 231: _DIAGASSERT(extra != NULL);
1.1 cgd 232:
1.13.4.1! wrstuden 233: for (start = dst; len > 0; len--) {
! 234: c = *src++;
! 235: SVIS(dst, c, flag, len ? *src : '\0', extra);
1.1 cgd 236: }
1.4 mycroft 237: *dst = '\0';
1.1 cgd 238: return (dst - start);
1.13.4.1! wrstuden 239: }
! 240:
! 241:
! 242: /*
! 243: * vis - visually encode characters
! 244: */
! 245: char *
! 246: vis(dst, c, flag, nextc)
! 247: char *dst;
! 248: int c, flag, nextc;
! 249:
! 250: {
! 251: char extra[MAXEXTRAS];
! 252:
! 253: _DIAGASSERT(dst != NULL);
! 254:
! 255: MAKEEXTRALIST(flag, extra);
! 256: SVIS(dst, c, flag, nextc, extra);
! 257: *dst = '\0';
! 258: return (dst);
! 259: }
! 260:
! 261:
! 262: /*
! 263: * strvis, strvisx - visually encode characters from src into dst
! 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.
! 268: *
! 269: * Strvisx encodes exactly len bytes from src into dst.
! 270: * This is useful for encoding a block of data.
! 271: */
! 272: int
! 273: strvis(dst, src, flag)
! 274: char *dst;
! 275: const char *src;
! 276: int flag;
! 277: {
! 278: char extra[MAXEXTRAS];
! 279:
! 280: MAKEEXTRALIST(flag, extra);
! 281: return (strsvis(dst, src, flag, extra));
! 282: }
! 283:
! 284:
! 285: int
! 286: strvisx(dst, src, len, flag)
! 287: char *dst;
! 288: const char *src;
! 289: size_t len;
! 290: int flag;
! 291: {
! 292: char extra[MAXEXTRAS];
! 293:
! 294: MAKEEXTRALIST(flag, extra);
! 295: return (strsvisx(dst, src, len, flag, extra));
1.1 cgd 296: }
CVSweb <webmaster@jp.NetBSD.org>