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