1 /*- 2 * Copyright (c) 1989 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #if defined(LIBC_SCCS) && !defined(lint) 9 static char sccsid[] = "@(#)vis.c 5.6 (Berkeley) 02/05/92"; 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 * 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 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 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 char *start = dst; 149 150 while (len > 1) { 151 dst = vis(dst, *src, flag, *(src+1)); 152 len--; 153 } 154 if (len) 155 dst = vis(dst, *src, flag, '\0'); 156 157 return (dst - start); 158 } 159