Annotation of src/lib/libc/gen/unvis.c, Revision 1.14
1.14 ! thorpej 1: /* $NetBSD: unvis.c,v 1.13 1998/11/13 12:31:53 christos Exp $ */
1.4 cgd 2:
1.1 cgd 3: /*-
1.4 cgd 4: * Copyright (c) 1989, 1993
5: * The Regents of the University of California. All rights reserved.
1.1 cgd 6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: * 3. All advertising materials mentioning features or use of this software
16: * must display the following acknowledgement:
17: * This product includes software developed by the University of
18: * California, Berkeley and its contributors.
19: * 4. Neither the name of the University nor the names of its contributors
20: * may be used to endorse or promote products derived from this software
21: * without specific prior written permission.
22: *
23: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33: * SUCH DAMAGE.
34: */
35:
1.6 christos 36: #include <sys/cdefs.h>
1.1 cgd 37: #if defined(LIBC_SCCS) && !defined(lint)
1.4 cgd 38: #if 0
39: static char sccsid[] = "@(#)unvis.c 8.1 (Berkeley) 6/4/93";
40: #else
1.14 ! thorpej 41: __RCSID("$NetBSD: unvis.c,v 1.13 1998/11/13 12:31:53 christos Exp $");
1.4 cgd 42: #endif
1.1 cgd 43: #endif /* LIBC_SCCS and not lint */
44:
1.10 fvdl 45: #define __LIBC12_SOURCE__
46:
1.7 jtc 47: #include "namespace.h"
1.1 cgd 48: #include <sys/types.h>
49: #include <ctype.h>
50: #include <vis.h>
1.7 jtc 51:
52: #ifdef __weak_alias
53: __weak_alias(strunvis,_strunvis);
54: __weak_alias(unvis,_unvis);
55: #endif
1.14 ! thorpej 56:
! 57: __warn_references(unvis,
! 58: "warning: reference to compatibility unvis(); include <vis.h> for correct reference")
1.1 cgd 59:
60: /*
61: * decode driven by state machine
62: */
63: #define S_GROUND 0 /* haven't seen escape char */
64: #define S_START 1 /* start decoding special sequence */
65: #define S_META 2 /* metachar started (M) */
66: #define S_META1 3 /* metachar more, regular char (-) */
67: #define S_CTRL 4 /* control char started (^) */
68: #define S_OCTAL2 5 /* octal digit 2 */
69: #define S_OCTAL3 6 /* octal digit 3 */
70:
71: #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
1.9 thorpej 72:
73: int
74: unvis(cp, c, astate, flag)
75: char *cp;
1.13 christos 76: int c;
1.9 thorpej 77: int *astate, flag;
78: {
79: return __unvis13(cp, (int)c, astate, flag);
80: }
81:
1.1 cgd 82: /*
83: * unvis - decode characters previously encoded by vis
84: */
85: int
1.9 thorpej 86: __unvis13(cp, c, astate, flag)
1.4 cgd 87: char *cp;
1.8 christos 88: int c;
1.5 cgd 89: int *astate, flag;
1.1 cgd 90: {
91:
92: if (flag & UNVIS_END) {
93: if (*astate == S_OCTAL2 || *astate == S_OCTAL3) {
94: *astate = S_GROUND;
95: return (UNVIS_VALID);
96: }
97: return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
98: }
99:
100: switch (*astate) {
101:
102: case S_GROUND:
103: *cp = 0;
104: if (c == '\\') {
105: *astate = S_START;
106: return (0);
107: }
108: *cp = c;
109: return (UNVIS_VALID);
110:
111: case S_START:
112: switch(c) {
113: case '\\':
114: *cp = c;
115: *astate = S_GROUND;
116: return (UNVIS_VALID);
117: case '0': case '1': case '2': case '3':
118: case '4': case '5': case '6': case '7':
119: *cp = (c - '0');
120: *astate = S_OCTAL2;
121: return (0);
122: case 'M':
1.13 christos 123: *cp = (char)0200;
1.1 cgd 124: *astate = S_META;
125: return (0);
126: case '^':
127: *astate = S_CTRL;
128: return (0);
129: case 'n':
130: *cp = '\n';
131: *astate = S_GROUND;
132: return (UNVIS_VALID);
133: case 'r':
134: *cp = '\r';
135: *astate = S_GROUND;
136: return (UNVIS_VALID);
137: case 'b':
138: *cp = '\b';
139: *astate = S_GROUND;
140: return (UNVIS_VALID);
141: case 'a':
142: *cp = '\007';
143: *astate = S_GROUND;
144: return (UNVIS_VALID);
145: case 'v':
146: *cp = '\v';
147: *astate = S_GROUND;
148: return (UNVIS_VALID);
149: case 't':
150: *cp = '\t';
151: *astate = S_GROUND;
152: return (UNVIS_VALID);
153: case 'f':
154: *cp = '\f';
155: *astate = S_GROUND;
156: return (UNVIS_VALID);
157: case 's':
158: *cp = ' ';
159: *astate = S_GROUND;
160: return (UNVIS_VALID);
161: case 'E':
162: *cp = '\033';
163: *astate = S_GROUND;
164: return (UNVIS_VALID);
165: case '\n':
166: /*
167: * hidden newline
168: */
169: *astate = S_GROUND;
170: return (UNVIS_NOCHAR);
171: case '$':
172: /*
173: * hidden marker
174: */
175: *astate = S_GROUND;
176: return (UNVIS_NOCHAR);
177: }
178: *astate = S_GROUND;
179: return (UNVIS_SYNBAD);
180:
181: case S_META:
182: if (c == '-')
183: *astate = S_META1;
184: else if (c == '^')
185: *astate = S_CTRL;
186: else {
187: *astate = S_GROUND;
188: return (UNVIS_SYNBAD);
189: }
190: return (0);
191:
192: case S_META1:
193: *astate = S_GROUND;
194: *cp |= c;
195: return (UNVIS_VALID);
196:
197: case S_CTRL:
198: if (c == '?')
199: *cp |= 0177;
200: else
201: *cp |= c & 037;
202: *astate = S_GROUND;
203: return (UNVIS_VALID);
204:
205: case S_OCTAL2: /* second possible octal digit */
206: if (isoctal(c)) {
207: /*
208: * yes - and maybe a third
209: */
210: *cp = (*cp << 3) + (c - '0');
211: *astate = S_OCTAL3;
212: return (0);
213: }
214: /*
215: * no - done with current sequence, push back passed char
216: */
217: *astate = S_GROUND;
218: return (UNVIS_VALIDPUSH);
219:
220: case S_OCTAL3: /* third possible octal digit */
221: *astate = S_GROUND;
222: if (isoctal(c)) {
223: *cp = (*cp << 3) + (c - '0');
224: return (UNVIS_VALID);
225: }
226: /*
227: * we were done, push back passed char
228: */
229: return (UNVIS_VALIDPUSH);
230:
231: default:
232: /*
233: * decoder in unknown state - (probably uninitialized)
234: */
235: *astate = S_GROUND;
236: return (UNVIS_SYNBAD);
237: }
238: }
239:
240: /*
241: * strunvis - decode src into dst
242: *
243: * Number of chars decoded into dst is returned, -1 on error.
244: * Dst is null terminated.
245: */
246:
247: int
248: strunvis(dst, src)
1.12 perry 249: char *dst;
250: const char *src;
1.1 cgd 251: {
1.12 perry 252: char c;
1.1 cgd 253: char *start = dst;
254: int state = 0;
255:
1.6 christos 256: while ((c = *src++) != '\0') {
1.1 cgd 257: again:
1.9 thorpej 258: switch (__unvis13(dst, c, &state, 0)) {
1.1 cgd 259: case UNVIS_VALID:
260: dst++;
261: break;
262: case UNVIS_VALIDPUSH:
263: dst++;
264: goto again;
265: case 0:
266: case UNVIS_NOCHAR:
267: break;
268: default:
269: return (-1);
270: }
271: }
1.9 thorpej 272: if (__unvis13(dst, c, &state, UNVIS_END) == UNVIS_VALID)
1.1 cgd 273: dst++;
274: *dst = '\0';
275: return (dst - start);
276: }
CVSweb <webmaster@jp.NetBSD.org>