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.4 (Berkeley) 02/23/91"; 10 #endif /* LIBC_SCCS and not lint */ 11 12 #include <sys/types.h> 13 #include <ctype.h> 14 #include <vis.h> 15 16 #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') 17 18 /* 19 * vis - visually encode characters 20 */ 21 char * 22 #if __STDC__ 23 vis(register char *dst, register char c, register int flag, char nextc) 24 #else 25 vis(dst, c, flag, nextc) 26 register char *dst, c; 27 char nextc; 28 register int flag; 29 #endif 30 { 31 if (isascii(c) && isgraph(c) || 32 ((flag & VIS_SP) == 0 && c == ' ') || 33 ((flag & VIS_TAB) == 0 && c == '\t') || 34 ((flag & VIS_NL) == 0 && c == '\n') || 35 ((flag & VIS_SAFE) && (c == '\b' || c == '\007' || c == '\r'))) { 36 *dst++ = c; 37 if (c == '\\' && (flag & VIS_NOSLASH) == 0) 38 *dst++ = '\\'; 39 *dst = '\0'; 40 return (dst); 41 } 42 43 if (flag & VIS_CSTYLE) { 44 switch(c) { 45 case '\n': 46 *dst++ = '\\'; 47 *dst++ = 'n'; 48 goto done; 49 case '\r': 50 *dst++ = '\\'; 51 *dst++ = 'r'; 52 goto done; 53 case '\b': 54 *dst++ = '\\'; 55 *dst++ = 'b'; 56 goto done; 57 #if __STDC__ 58 case '\a': 59 #else 60 case '\007': 61 #endif 62 *dst++ = '\\'; 63 *dst++ = 'a'; 64 goto done; 65 case '\v': 66 *dst++ = '\\'; 67 *dst++ = 'v'; 68 goto done; 69 case '\t': 70 *dst++ = '\\'; 71 *dst++ = 't'; 72 goto done; 73 case '\f': 74 *dst++ = '\\'; 75 *dst++ = 'f'; 76 goto done; 77 case ' ': 78 *dst++ = '\\'; 79 *dst++ = 's'; 80 goto done; 81 case '\0': 82 *dst++ = '\\'; 83 *dst++ = '0'; 84 if (isoctal(nextc)) { 85 *dst++ = '0'; 86 *dst++ = '0'; 87 } 88 goto done; 89 } 90 } 91 if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) { 92 *dst++ = '\\'; 93 *dst++ = ((u_char)c >> 6 & 07) + '0'; 94 *dst++ = ((u_char)c >> 3 & 07) + '0'; 95 *dst++ = ((u_char)c & 07) + '0'; 96 goto done; 97 } 98 if ((flag & VIS_NOSLASH) == 0) 99 *dst++ = '\\'; 100 if (c & 0200) { 101 c &= 0177; 102 *dst++ = 'M'; 103 } 104 if (iscntrl(c)) { 105 *dst++ = '^'; 106 if (c == 0177) 107 *dst++ = '?'; 108 else 109 *dst++ = c + '@'; 110 } else { 111 *dst++ = '-'; 112 *dst++ = c; 113 } 114 done: 115 *dst = '\0'; 116 return (dst); 117 } 118 119 /* 120 * strvis, strvisx - visually encode characters from src into dst 121 * 122 * Dst must be 4 times the size of src to account for possible 123 * expansion. The length of dst, not including the trailing NULL, 124 * is returned. 125 * 126 * Strvisx encodes exactly len bytes from src into dst. 127 * This is useful for encoding a block of data. 128 */ 129 int 130 strvis(dst, src, flag) 131 register char *dst; 132 register const char *src; 133 int flag; 134 { 135 register char c; 136 char *start = dst; 137 138 for (;c = *src; src++) 139 dst = vis(dst, c, flag, *(src+1)); 140 141 return (dst - start); 142 } 143 144 int 145 strvisx(dst, src, len, flag) 146 register char *dst; 147 register const char *src; 148 register size_t len; 149 int flag; 150 { 151 char *start = dst; 152 153 while (len > 1) { 154 dst = vis(dst, *src, flag, *(src+1)); 155 len--; 156 } 157 if (len) 158 dst = vis(dst, *src, flag, '\0'); 159 160 return (dst - start); 161 } 162