Commit | Line | Data |
---|---|---|
8da38493 | 1 | /*- |
9c260c06 MT |
2 | * Copyright (c) 1989 The Regents of the University of California. |
3 | * All rights reserved. | |
4 | * | |
8da38493 | 5 | * %sccs.include.redist.c% |
9c260c06 MT |
6 | */ |
7 | ||
8 | #if defined(LIBC_SCCS) && !defined(lint) | |
8da38493 | 9 | static char sccsid[] = "@(#)vis.c 5.3 (Berkeley) %G%"; |
9c260c06 MT |
10 | #endif /* LIBC_SCCS and not lint */ |
11 | ||
12 | #include <sys/types.h> | |
13 | #include <ctype.h> | |
8da38493 | 14 | #include <vis.h> |
9c260c06 | 15 | |
9c260c06 MT |
16 | #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7') |
17 | ||
18 | /* | |
a11b735c | 19 | * vis - visually encode characters |
9c260c06 | 20 | */ |
9c260c06 | 21 | char * |
a11b735c MT |
22 | vis(dst, c, flag, nextc) |
23 | register char *dst, c; | |
24 | char nextc; | |
25 | register int flag; | |
9c260c06 | 26 | { |
a11b735c | 27 | if (isascii(c) && isgraph(c) || |
8da38493 MT |
28 | ((flag & VIS_SP) == 0 && c == ' ') || |
29 | ((flag & VIS_TAB) == 0 && c == '\t') || | |
30 | ((flag & VIS_NL) == 0 && c == '\n') || | |
a11b735c MT |
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); | |
9c260c06 | 37 | } |
a11b735c | 38 | |
a11b735c | 39 | if (flag & VIS_CSTYLE) { |
9c260c06 MT |
40 | switch(c) { |
41 | case '\n': | |
8da38493 | 42 | *dst++ = '\\'; |
a11b735c | 43 | *dst++ = 'n'; |
9c260c06 MT |
44 | goto done; |
45 | case '\r': | |
8da38493 | 46 | *dst++ = '\\'; |
a11b735c | 47 | *dst++ = 'r'; |
9c260c06 MT |
48 | goto done; |
49 | case '\b': | |
8da38493 | 50 | *dst++ = '\\'; |
a11b735c | 51 | *dst++ = 'b'; |
9c260c06 | 52 | goto done; |
a11b735c | 53 | case '\007': /* waiting for ansi compiler */ |
8da38493 | 54 | *dst++ = '\\'; |
a11b735c | 55 | *dst++ = 'a'; |
9c260c06 MT |
56 | goto done; |
57 | case '\v': | |
8da38493 | 58 | *dst++ = '\\'; |
a11b735c | 59 | *dst++ = 'v'; |
9c260c06 MT |
60 | goto done; |
61 | case '\t': | |
8da38493 | 62 | *dst++ = '\\'; |
a11b735c | 63 | *dst++ = 't'; |
9c260c06 MT |
64 | goto done; |
65 | case '\f': | |
8da38493 | 66 | *dst++ = '\\'; |
a11b735c | 67 | *dst++ = 'f'; |
9c260c06 MT |
68 | goto done; |
69 | case ' ': | |
8da38493 | 70 | *dst++ = '\\'; |
a11b735c | 71 | *dst++ = 's'; |
9c260c06 MT |
72 | goto done; |
73 | case '\0': | |
8da38493 | 74 | *dst++ = '\\'; |
a11b735c | 75 | *dst++ = '0'; |
8da38493 | 76 | if (isoctal(nextc)) { |
a11b735c MT |
77 | *dst++ = '0'; |
78 | *dst++ = '0'; | |
9c260c06 MT |
79 | } |
80 | goto done; | |
81 | } | |
82 | } | |
a11b735c | 83 | if (((c & 0177) == ' ') || (flag & VIS_OCTAL)) { |
8da38493 | 84 | *dst++ = '\\'; |
a11b735c MT |
85 | *dst++ = ((u_char)c >> 6 & 07) + '0'; |
86 | *dst++ = ((u_char)c >> 3 & 07) + '0'; | |
87 | *dst++ = ((u_char)c & 07) + '0'; | |
9c260c06 MT |
88 | goto done; |
89 | } | |
8da38493 MT |
90 | if ((flag & VIS_NOSLASH) == 0) |
91 | *dst++ = '\\'; | |
a11b735c MT |
92 | if (c & 0200) { |
93 | c &= 0177; | |
94 | *dst++ = 'M'; | |
95 | } | |
96 | if (iscntrl(c)) { | |
97 | *dst++ = '^'; | |
98 | if (c == 0177) | |
99 | *dst++ = '?'; | |
9c260c06 | 100 | else |
a11b735c MT |
101 | *dst++ = c + '@'; |
102 | } else { | |
103 | *dst++ = '-'; | |
104 | *dst++ = c; | |
9c260c06 | 105 | } |
9c260c06 | 106 | done: |
a11b735c MT |
107 | *dst = '\0'; |
108 | return (dst); | |
9c260c06 MT |
109 | } |
110 | ||
9c260c06 | 111 | /* |
8da38493 MT |
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. | |
9c260c06 | 117 | * |
8da38493 MT |
118 | * Strvisx encodes exactly len bytes from src into dst. |
119 | * This is useful for encoding a block of data. | |
9c260c06 | 120 | */ |
8da38493 MT |
121 | strvis(dst, src, flag) |
122 | register char *dst, *src; | |
9c260c06 | 123 | { |
8da38493 MT |
124 | register char c; |
125 | char *start = dst; | |
9c260c06 | 126 | |
8da38493 MT |
127 | for (;c = *src; src++) |
128 | dst = vis(dst, c, flag, *(src+1)); | |
9c260c06 | 129 | |
8da38493 | 130 | return (dst - start); |
9c260c06 | 131 | } |
a11b735c | 132 | |
8da38493 | 133 | strvisx(dst, src, len, flag) |
a11b735c MT |
134 | register char *dst, *src; |
135 | register int len; | |
136 | { | |
137 | char *start = dst; | |
138 | ||
8da38493 MT |
139 | while (len > 1) { |
140 | dst = vis(dst, *src, flag, *(src+1)); | |
141 | len--; | |
a11b735c | 142 | } |
8da38493 MT |
143 | if (len) |
144 | dst = vis(dst, *src, flag, '\0'); | |
a11b735c MT |
145 | |
146 | return (dst - start); | |
147 | } |