Annotation of src/lib/libc/gen/unvis.c, Revision 1.19.6.1
1.19.6.1! nathanw 1: /* $NetBSD: unvis.c,v 1.19 2000/01/22 22:19:13 mycroft 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.19.6.1! nathanw 41: __RCSID("$NetBSD: unvis.c,v 1.19 2000/01/22 22:19:13 mycroft 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>
1.15 lukem 49:
50: #include <assert.h>
1.1 cgd 51: #include <ctype.h>
1.15 lukem 52: #include <stdio.h>
1.1 cgd 53: #include <vis.h>
1.7 jtc 54:
55: #ifdef __weak_alias
1.19 mycroft 56: __weak_alias(strunvis,_strunvis)
57: __weak_alias(unvis,_unvis)
1.7 jtc 58: #endif
1.14 thorpej 59:
1.19.6.1! nathanw 60: #ifdef __warn_references
1.14 thorpej 61: __warn_references(unvis,
62: "warning: reference to compatibility unvis(); include <vis.h> for correct reference")
1.19.6.1! nathanw 63: #endif
1.1 cgd 64:
1.19.6.1! nathanw 65: #if !HAVE_VIS_H
1.1 cgd 66: /*
67: * decode driven by state machine
68: */
69: #define S_GROUND 0 /* haven't seen escape char */
70: #define S_START 1 /* start decoding special sequence */
71: #define S_META 2 /* metachar started (M) */
72: #define S_META1 3 /* metachar more, regular char (-) */
73: #define S_CTRL 4 /* control char started (^) */
74: #define S_OCTAL2 5 /* octal digit 2 */
75: #define S_OCTAL3 6 /* octal digit 3 */
76:
77: #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
1.9 thorpej 78:
79: int
80: unvis(cp, c, astate, flag)
81: char *cp;
1.13 christos 82: int c;
1.9 thorpej 83: int *astate, flag;
84: {
85: return __unvis13(cp, (int)c, astate, flag);
86: }
87:
1.1 cgd 88: /*
89: * unvis - decode characters previously encoded by vis
90: */
91: int
1.9 thorpej 92: __unvis13(cp, c, astate, flag)
1.4 cgd 93: char *cp;
1.8 christos 94: int c;
1.5 cgd 95: int *astate, flag;
1.1 cgd 96: {
97:
1.15 lukem 98: _DIAGASSERT(cp != NULL);
99: _DIAGASSERT(astate != NULL);
100:
1.1 cgd 101: if (flag & UNVIS_END) {
102: if (*astate == S_OCTAL2 || *astate == S_OCTAL3) {
103: *astate = S_GROUND;
104: return (UNVIS_VALID);
105: }
106: return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
107: }
108:
109: switch (*astate) {
110:
111: case S_GROUND:
112: *cp = 0;
113: if (c == '\\') {
114: *astate = S_START;
115: return (0);
116: }
117: *cp = c;
118: return (UNVIS_VALID);
119:
120: case S_START:
121: switch(c) {
122: case '\\':
123: *cp = c;
124: *astate = S_GROUND;
125: return (UNVIS_VALID);
126: case '0': case '1': case '2': case '3':
127: case '4': case '5': case '6': case '7':
128: *cp = (c - '0');
129: *astate = S_OCTAL2;
130: return (0);
131: case 'M':
1.13 christos 132: *cp = (char)0200;
1.1 cgd 133: *astate = S_META;
134: return (0);
135: case '^':
136: *astate = S_CTRL;
137: return (0);
138: case 'n':
139: *cp = '\n';
140: *astate = S_GROUND;
141: return (UNVIS_VALID);
142: case 'r':
143: *cp = '\r';
144: *astate = S_GROUND;
145: return (UNVIS_VALID);
146: case 'b':
147: *cp = '\b';
148: *astate = S_GROUND;
149: return (UNVIS_VALID);
150: case 'a':
151: *cp = '\007';
152: *astate = S_GROUND;
153: return (UNVIS_VALID);
154: case 'v':
155: *cp = '\v';
156: *astate = S_GROUND;
157: return (UNVIS_VALID);
158: case 't':
159: *cp = '\t';
160: *astate = S_GROUND;
161: return (UNVIS_VALID);
162: case 'f':
163: *cp = '\f';
164: *astate = S_GROUND;
165: return (UNVIS_VALID);
166: case 's':
167: *cp = ' ';
168: *astate = S_GROUND;
169: return (UNVIS_VALID);
170: case 'E':
171: *cp = '\033';
172: *astate = S_GROUND;
173: return (UNVIS_VALID);
174: case '\n':
175: /*
176: * hidden newline
177: */
178: *astate = S_GROUND;
179: return (UNVIS_NOCHAR);
180: case '$':
181: /*
182: * hidden marker
183: */
184: *astate = S_GROUND;
185: return (UNVIS_NOCHAR);
186: }
1.18 wennmach 187: *astate = S_GROUND;
188: return (UNVIS_SYNBAD);
1.1 cgd 189:
190: case S_META:
191: if (c == '-')
192: *astate = S_META1;
193: else if (c == '^')
194: *astate = S_CTRL;
195: else {
196: *astate = S_GROUND;
197: return (UNVIS_SYNBAD);
198: }
199: return (0);
200:
201: case S_META1:
202: *astate = S_GROUND;
203: *cp |= c;
204: return (UNVIS_VALID);
205:
206: case S_CTRL:
207: if (c == '?')
208: *cp |= 0177;
209: else
210: *cp |= c & 037;
211: *astate = S_GROUND;
212: return (UNVIS_VALID);
213:
214: case S_OCTAL2: /* second possible octal digit */
215: if (isoctal(c)) {
216: /*
217: * yes - and maybe a third
218: */
219: *cp = (*cp << 3) + (c - '0');
220: *astate = S_OCTAL3;
221: return (0);
222: }
223: /*
224: * no - done with current sequence, push back passed char
225: */
226: *astate = S_GROUND;
227: return (UNVIS_VALIDPUSH);
228:
229: case S_OCTAL3: /* third possible octal digit */
230: *astate = S_GROUND;
231: if (isoctal(c)) {
232: *cp = (*cp << 3) + (c - '0');
233: return (UNVIS_VALID);
234: }
235: /*
236: * we were done, push back passed char
237: */
238: return (UNVIS_VALIDPUSH);
239:
240: default:
241: /*
242: * decoder in unknown state - (probably uninitialized)
243: */
244: *astate = S_GROUND;
245: return (UNVIS_SYNBAD);
246: }
247: }
248:
249: /*
250: * strunvis - decode src into dst
251: *
252: * Number of chars decoded into dst is returned, -1 on error.
253: * Dst is null terminated.
254: */
255:
256: int
257: strunvis(dst, src)
1.12 perry 258: char *dst;
259: const char *src;
1.1 cgd 260: {
1.12 perry 261: char c;
1.1 cgd 262: char *start = dst;
263: int state = 0;
1.15 lukem 264:
265: _DIAGASSERT(src != NULL);
266: _DIAGASSERT(dst != NULL);
1.1 cgd 267:
1.6 christos 268: while ((c = *src++) != '\0') {
1.1 cgd 269: again:
1.9 thorpej 270: switch (__unvis13(dst, c, &state, 0)) {
1.1 cgd 271: case UNVIS_VALID:
272: dst++;
273: break;
274: case UNVIS_VALIDPUSH:
275: dst++;
276: goto again;
277: case 0:
278: case UNVIS_NOCHAR:
279: break;
280: default:
281: return (-1);
282: }
283: }
1.9 thorpej 284: if (__unvis13(dst, c, &state, UNVIS_END) == UNVIS_VALID)
1.1 cgd 285: dst++;
286: *dst = '\0';
287: return (dst - start);
288: }
1.19.6.1! nathanw 289: #endif
CVSweb <webmaster@jp.NetBSD.org>