|
|
1.1 root 1: /*-
2: * Copyright (c) 1989 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms are permitted provided
6: * that: (1) source distributions retain this entire copyright notice and
7: * comment, and (2) distributions including binaries display the following
8: * acknowledgement: ``This product includes software developed by the
9: * University of California, Berkeley and its contributors'' in the
10: * documentation or other materials provided with the distribution and in
11: * all advertising materials mentioning features or use of this software.
12: * Neither the name of the University nor the names of its contributors may
13: * be used to endorse or promote products derived from this software without
14: * specific prior written permission.
15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18: */
19:
20: #if defined(LIBC_SCCS) && !defined(lint)
21: static char sccsid[] = "@(#)unvis.c 1.3 (Berkeley) 6/27/90";
22: #endif /* LIBC_SCCS and not lint */
23:
24: #include <sys/types.h>
25: #include <ctype.h>
26: #include <vis.h>
27:
28: /*
29: * decode driven by state machine
30: */
31: #define S_GROUND 0 /* haven't seen escape char */
32: #define S_START 1 /* start decoding special sequence */
33: #define S_META 2 /* metachar started (M) */
34: #define S_META1 3 /* metachar more, regular char (-) */
35: #define S_CTRL 4 /* control char started (^) */
36: #define S_OCTAL2 5 /* octal digit 2 */
37: #define S_OCTAL3 6 /* octal digit 3 */
38:
39: #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
40:
41: /*
42: * unvis - decode characters previously encoded by vis
43: */
44: unvis(cp, c, astate, flag)
45: u_char *cp, c;
46: int *astate, flag;
47: {
48:
49: if (flag & UNVIS_END) {
50: if (*astate == S_OCTAL2 || *astate == S_OCTAL3) {
51: *astate = S_GROUND;
52: return (UNVIS_VALID);
53: }
54: return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
55: }
56:
57: switch (*astate) {
58:
59: case S_GROUND:
60: *cp = 0;
61: if (c == '\\') {
62: *astate = S_START;
63: return (0);
64: }
65: *cp = c;
66: return (UNVIS_VALID);
67:
68: case S_START:
69: switch(c) {
70: case '\\':
71: *cp = c;
72: *astate = S_GROUND;
73: return (UNVIS_VALID);
74: case '0': case '1': case '2': case '3':
75: case '4': case '5': case '6': case '7':
76: *cp = (c - '0');
77: *astate = S_OCTAL2;
78: return (0);
79: case 'M':
80: *cp = 0200;
81: *astate = S_META;
82: return (0);
83: case '^':
84: *astate = S_CTRL;
85: return (0);
86: case 'n':
87: *cp = '\n';
88: *astate = S_GROUND;
89: return (UNVIS_VALID);
90: case 'r':
91: *cp = '\r';
92: *astate = S_GROUND;
93: return (UNVIS_VALID);
94: case 'b':
95: *cp = '\b';
96: *astate = S_GROUND;
97: return (UNVIS_VALID);
98: case 'a':
99: *cp = '\007';
100: *astate = S_GROUND;
101: return (UNVIS_VALID);
102: case 'v':
103: *cp = '\v';
104: *astate = S_GROUND;
105: return (UNVIS_VALID);
106: case 't':
107: *cp = '\t';
108: *astate = S_GROUND;
109: return (UNVIS_VALID);
110: case 'f':
111: *cp = '\f';
112: *astate = S_GROUND;
113: return (UNVIS_VALID);
114: case 's':
115: *cp = ' ';
116: *astate = S_GROUND;
117: return (UNVIS_VALID);
118: case 'E':
119: *cp = '\033';
120: *astate = S_GROUND;
121: return (UNVIS_VALID);
122: case '\n':
123: /*
124: * hidden newline
125: */
126: *astate = S_GROUND;
127: return (UNVIS_NOCHAR);
128: case '$':
129: /*
130: * hidden marker
131: */
132: *astate = S_GROUND;
133: return (UNVIS_NOCHAR);
134: }
135: *astate = S_GROUND;
136: return (UNVIS_SYNBAD);
137:
138: case S_META:
139: if (c == '-')
140: *astate = S_META1;
141: else if (c == '^')
142: *astate = S_CTRL;
143: else {
144: *astate = S_GROUND;
145: return (UNVIS_SYNBAD);
146: }
147: return (0);
148:
149: case S_META1:
150: *astate = S_GROUND;
151: *cp |= c;
152: return (UNVIS_VALID);
153:
154: case S_CTRL:
155: if (c == '?')
156: *cp |= 0177;
157: else
158: *cp |= c & 037;
159: *astate = S_GROUND;
160: return (UNVIS_VALID);
161:
162: case S_OCTAL2: /* second possible octal digit */
163: if (isoctal(c)) {
164: /*
165: * yes - and maybe a third
166: */
167: *cp = (*cp << 3) + (c - '0');
168: *astate = S_OCTAL3;
169: return (0);
170: }
171: /*
172: * no - done with current sequence, push back passed char
173: */
174: *astate = S_GROUND;
175: return (UNVIS_VALIDPUSH);
176:
177: case S_OCTAL3: /* third possible octal digit */
178: *astate = S_GROUND;
179: if (isoctal(c)) {
180: *cp = (*cp << 3) + (c - '0');
181: return (UNVIS_VALID);
182: }
183: /*
184: * we were done, push back passed char
185: */
186: return (UNVIS_VALIDPUSH);
187:
188: default:
189: /*
190: * decoder in unknown state - (probably uninitialized)
191: */
192: *astate = S_GROUND;
193: return (UNVIS_SYNBAD);
194: }
195: }
196:
197: /*
198: * strunvis - decode src into dst
199: *
200: * Number of chars decoded into dst is returned, -1 on error.
201: * Dst is null terminated.
202: */
203:
204: strunvis(dst, src)
205: register char *dst, *src;
206: {
207: register char c;
208: char *start = dst;
209: int state = 0;
210:
211: while (c = *src++) {
212: again:
213: switch (unvis(dst, c, &state, 0)) {
214: case UNVIS_VALID:
215: dst++;
216: break;
217: case UNVIS_VALIDPUSH:
218: dst++;
219: goto again;
220: case 0:
221: case UNVIS_NOCHAR:
222: break;
223: default:
224: return (-1);
225: }
226: }
227: if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID)
228: dst++;
229: *dst = '\0';
230: return (dst - start);
231: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.