per-process limits are resources, not sysctl(3) variables
[unix-history] / usr / src / lib / libc / gen / unvis.c
CommitLineData
d6a13ceb 1/*-
1af61e06
MT
2 * Copyright (c) 1989 The Regents of the University of California.
3 * All rights reserved.
4 *
d6a13ceb 5 * %sccs.include.redist.c%
1af61e06
MT
6 */
7
8#if defined(LIBC_SCCS) && !defined(lint)
edb52c06 9static char sccsid[] = "@(#)unvis.c 5.1 (Berkeley) %G%";
1af61e06
MT
10#endif /* LIBC_SCCS and not lint */
11
12#include <sys/types.h>
13#include <ctype.h>
14#include <vis.h>
15
16/*
17 * decode driven by state machine
18 */
19#define S_GROUND 0 /* haven't seen escape char */
20#define S_START 1 /* start decoding special sequence */
21#define S_META 2 /* metachar started (M) */
22#define S_META1 3 /* metachar more, regular char (-) */
23#define S_CTRL 4 /* control char started (^) */
24#define S_OCTAL2 5 /* octal digit 2 */
25#define S_OCTAL3 6 /* octal digit 3 */
26
d6a13ceb
MT
27#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
28
1af61e06
MT
29/*
30 * unvis - decode characters previously encoded by vis
31 */
c5980113 32int
1af61e06 33unvis(cp, c, astate, flag)
edb52c06
KB
34 char *cp;
35 int c, *astate, flag;
1af61e06
MT
36{
37
38 if (flag & UNVIS_END) {
39 if (*astate == S_OCTAL2 || *astate == S_OCTAL3) {
40 *astate = S_GROUND;
41 return (UNVIS_VALID);
42 }
43 return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
44 }
45
46 switch (*astate) {
47
48 case S_GROUND:
49 *cp = 0;
50 if (c == '\\') {
51 *astate = S_START;
52 return (0);
53 }
54 *cp = c;
55 return (UNVIS_VALID);
56
57 case S_START:
58 switch(c) {
59 case '\\':
60 *cp = c;
61 *astate = S_GROUND;
62 return (UNVIS_VALID);
63 case '0': case '1': case '2': case '3':
64 case '4': case '5': case '6': case '7':
65 *cp = (c - '0');
66 *astate = S_OCTAL2;
67 return (0);
68 case 'M':
69 *cp = 0200;
70 *astate = S_META;
71 return (0);
72 case '^':
73 *astate = S_CTRL;
74 return (0);
75 case 'n':
76 *cp = '\n';
77 *astate = S_GROUND;
78 return (UNVIS_VALID);
79 case 'r':
80 *cp = '\r';
81 *astate = S_GROUND;
82 return (UNVIS_VALID);
83 case 'b':
84 *cp = '\b';
85 *astate = S_GROUND;
86 return (UNVIS_VALID);
87 case 'a':
88 *cp = '\007';
89 *astate = S_GROUND;
90 return (UNVIS_VALID);
91 case 'v':
92 *cp = '\v';
93 *astate = S_GROUND;
94 return (UNVIS_VALID);
95 case 't':
96 *cp = '\t';
97 *astate = S_GROUND;
98 return (UNVIS_VALID);
99 case 'f':
100 *cp = '\f';
101 *astate = S_GROUND;
102 return (UNVIS_VALID);
103 case 's':
104 *cp = ' ';
105 *astate = S_GROUND;
106 return (UNVIS_VALID);
107 case 'E':
108 *cp = '\033';
109 *astate = S_GROUND;
110 return (UNVIS_VALID);
111 case '\n':
112 /*
113 * hidden newline
114 */
115 *astate = S_GROUND;
116 return (UNVIS_NOCHAR);
d6a13ceb
MT
117 case '$':
118 /*
119 * hidden marker
120 */
121 *astate = S_GROUND;
122 return (UNVIS_NOCHAR);
1af61e06
MT
123 }
124 *astate = S_GROUND;
125 return (UNVIS_SYNBAD);
126
127 case S_META:
128 if (c == '-')
129 *astate = S_META1;
130 else if (c == '^')
131 *astate = S_CTRL;
132 else {
133 *astate = S_GROUND;
134 return (UNVIS_SYNBAD);
135 }
136 return (0);
137
138 case S_META1:
139 *astate = S_GROUND;
140 *cp |= c;
141 return (UNVIS_VALID);
142
143 case S_CTRL:
144 if (c == '?')
145 *cp |= 0177;
146 else
147 *cp |= c & 037;
148 *astate = S_GROUND;
149 return (UNVIS_VALID);
150
151 case S_OCTAL2: /* second possible octal digit */
152 if (isoctal(c)) {
153 /*
154 * yes - and maybe a third
155 */
156 *cp = (*cp << 3) + (c - '0');
157 *astate = S_OCTAL3;
158 return (0);
159 }
160 /*
161 * no - done with current sequence, push back passed char
162 */
163 *astate = S_GROUND;
164 return (UNVIS_VALIDPUSH);
165
166 case S_OCTAL3: /* third possible octal digit */
167 *astate = S_GROUND;
168 if (isoctal(c)) {
169 *cp = (*cp << 3) + (c - '0');
170 return (UNVIS_VALID);
171 }
172 /*
173 * we were done, push back passed char
174 */
175 return (UNVIS_VALIDPUSH);
176
177 default:
178 /*
179 * decoder in unknown state - (probably uninitialized)
180 */
2e93102d
MT
181 *astate = S_GROUND;
182 return (UNVIS_SYNBAD);
1af61e06
MT
183 }
184}
185
186/*
d6a13ceb 187 * strunvis - decode src into dst
1af61e06 188 *
d6a13ceb
MT
189 * Number of chars decoded into dst is returned, -1 on error.
190 * Dst is null terminated.
1af61e06 191 */
d6a13ceb 192
c5980113 193int
d6a13ceb 194strunvis(dst, src)
c5980113
DS
195 register char *dst;
196 register const char *src;
1af61e06 197{
d6a13ceb 198 register char c;
1af61e06 199 char *start = dst;
2e93102d 200 int state = 0;
1af61e06 201
d6a13ceb
MT
202 while (c = *src++) {
203 again:
204 switch (unvis(dst, c, &state, 0)) {
205 case UNVIS_VALID:
206 dst++;
1af61e06 207 break;
d6a13ceb
MT
208 case UNVIS_VALIDPUSH:
209 dst++;
210 goto again;
211 case 0:
212 case UNVIS_NOCHAR:
213 break;
214 default:
215 return (-1);
216 }
1af61e06 217 }
2e93102d
MT
218 if (unvis(dst, c, &state, UNVIS_END) == UNVIS_VALID)
219 dst++;
d6a13ceb 220 *dst = '\0';
1af61e06
MT
221 return (dst - start);
222}