~vlad-lesin/percona-server/mysql-5.0.33-original

« back to all changes in this revision

Viewing changes to cmd-line-utils/libedit/np/unvis.c

  • Committer: Vlad Lesin
  • Date: 2012-07-31 09:21:34 UTC
  • Revision ID: vladislav.lesin@percona.com-20120731092134-zfodx022b7992wsi
VirginĀ 5.0.33

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*      $NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $      */
 
2
 
 
3
/*-
 
4
 * Copyright (c) 1989, 1993
 
5
 *      The Regents of the University of California.  All rights reserved.
 
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
 
 
36
#include "config.h"
 
37
#if defined(LIBC_SCCS) && !defined(lint)
 
38
#if 0
 
39
static char sccsid[] = "@(#)unvis.c     8.1 (Berkeley) 6/4/93";
 
40
#else
 
41
__RCSID("$NetBSD: unvis.c,v 1.22 2002/03/23 17:38:27 christos Exp $");
 
42
#endif
 
43
#endif /* LIBC_SCCS and not lint */
 
44
 
 
45
#define __LIBC12_SOURCE__
 
46
 
 
47
#include <sys/types.h>
 
48
 
 
49
#include <assert.h>
 
50
#include <ctype.h>
 
51
#include <stdio.h>
 
52
#include "np/vis.h"
 
53
 
 
54
#ifdef __weak_alias
 
55
__weak_alias(strunvis,_strunvis)
 
56
__weak_alias(unvis,_unvis)
 
57
#endif
 
58
 
 
59
#ifdef __warn_references
 
60
__warn_references(unvis,
 
61
    "warning: reference to compatibility unvis(); include <vis.h> for correct reference")
 
62
#endif
 
63
 
 
64
#if !HAVE_VIS_H
 
65
/*
 
66
 * decode driven by state machine
 
67
 */
 
68
#define S_GROUND        0       /* haven't seen escape char */
 
69
#define S_START         1       /* start decoding special sequence */
 
70
#define S_META          2       /* metachar started (M) */
 
71
#define S_META1         3       /* metachar more, regular char (-) */
 
72
#define S_CTRL          4       /* control char started (^) */
 
73
#define S_OCTAL2        5       /* octal digit 2 */
 
74
#define S_OCTAL3        6       /* octal digit 3 */
 
75
#define S_HEX1          7       /* hex digit */
 
76
#define S_HEX2          8       /* hex digit 2 */
 
77
 
 
78
#define isoctal(c)      (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
 
79
#define xtod(c)         (isdigit(c) ? (c - '0') : ((tolower(c) - 'a') + 10))
 
80
 
 
81
int
 
82
unvis(cp, c, astate, flag)
 
83
        char *cp;
 
84
        int c;
 
85
        int *astate, flag;
 
86
{
 
87
        return __unvis13(cp, (int)c, astate, flag);
 
88
}
 
89
 
 
90
/*
 
91
 * unvis - decode characters previously encoded by vis
 
92
 */
 
93
int
 
94
__unvis13(cp, c, astate, flag)
 
95
        char *cp;
 
96
        int c;
 
97
        int *astate, flag;
 
98
{
 
99
 
 
100
        _DIAGASSERT(cp != NULL);
 
101
        _DIAGASSERT(astate != NULL);
 
102
 
 
103
        if (flag & UNVIS_END) {
 
104
                if (*astate == S_OCTAL2 || *astate == S_OCTAL3
 
105
                    || *astate == S_HEX2) {
 
106
                        *astate = S_GROUND;
 
107
                        return (UNVIS_VALID);
 
108
                } 
 
109
                return (*astate == S_GROUND ? UNVIS_NOCHAR : UNVIS_SYNBAD);
 
110
        }
 
111
 
 
112
        switch (*astate) {
 
113
 
 
114
        case S_GROUND:
 
115
                *cp = 0;
 
116
                if (c == '\\') {
 
117
                        *astate = S_START;
 
118
                        return (0);
 
119
                } 
 
120
                if ((flag & VIS_HTTPSTYLE) && c == '%') {
 
121
                        *astate = S_HEX1;
 
122
                        return (0);
 
123
                }
 
124
                *cp = c;
 
125
                return (UNVIS_VALID);
 
126
 
 
127
        case S_START:
 
128
                switch(c) {
 
129
                case '\\':
 
130
                        *cp = c;
 
131
                        *astate = S_GROUND;
 
132
                        return (UNVIS_VALID);
 
133
                case '0': case '1': case '2': case '3':
 
134
                case '4': case '5': case '6': case '7':
 
135
                        *cp = (c - '0');
 
136
                        *astate = S_OCTAL2;
 
137
                        return (0);
 
138
                case 'M':
 
139
                        *cp = (char)0200;
 
140
                        *astate = S_META;
 
141
                        return (0);
 
142
                case '^':
 
143
                        *astate = S_CTRL;
 
144
                        return (0);
 
145
                case 'n':
 
146
                        *cp = '\n';
 
147
                        *astate = S_GROUND;
 
148
                        return (UNVIS_VALID);
 
149
                case 'r':
 
150
                        *cp = '\r';
 
151
                        *astate = S_GROUND;
 
152
                        return (UNVIS_VALID);
 
153
                case 'b':
 
154
                        *cp = '\b';
 
155
                        *astate = S_GROUND;
 
156
                        return (UNVIS_VALID);
 
157
                case 'a':
 
158
                        *cp = '\007';
 
159
                        *astate = S_GROUND;
 
160
                        return (UNVIS_VALID);
 
161
                case 'v':
 
162
                        *cp = '\v';
 
163
                        *astate = S_GROUND;
 
164
                        return (UNVIS_VALID);
 
165
                case 't':
 
166
                        *cp = '\t';
 
167
                        *astate = S_GROUND;
 
168
                        return (UNVIS_VALID);
 
169
                case 'f':
 
170
                        *cp = '\f';
 
171
                        *astate = S_GROUND;
 
172
                        return (UNVIS_VALID);
 
173
                case 's':
 
174
                        *cp = ' ';
 
175
                        *astate = S_GROUND;
 
176
                        return (UNVIS_VALID);
 
177
                case 'E':
 
178
                        *cp = '\033';
 
179
                        *astate = S_GROUND;
 
180
                        return (UNVIS_VALID);
 
181
                case '\n':
 
182
                        /*
 
183
                         * hidden newline
 
184
                         */
 
185
                        *astate = S_GROUND;
 
186
                        return (UNVIS_NOCHAR);
 
187
                case '$':
 
188
                        /*
 
189
                         * hidden marker
 
190
                         */
 
191
                        *astate = S_GROUND;
 
192
                        return (UNVIS_NOCHAR);
 
193
                }
 
194
                *astate = S_GROUND;
 
195
                return (UNVIS_SYNBAD);
 
196
                 
 
197
        case S_META:
 
198
                if (c == '-')
 
199
                        *astate = S_META1;
 
200
                else if (c == '^')
 
201
                        *astate = S_CTRL;
 
202
                else {
 
203
                        *astate = S_GROUND;
 
204
                        return (UNVIS_SYNBAD);
 
205
                }
 
206
                return (0);
 
207
                 
 
208
        case S_META1:
 
209
                *astate = S_GROUND;
 
210
                *cp |= c;
 
211
                return (UNVIS_VALID);
 
212
                 
 
213
        case S_CTRL:
 
214
                if (c == '?')
 
215
                        *cp |= 0177;
 
216
                else
 
217
                        *cp |= c & 037;
 
218
                *astate = S_GROUND;
 
219
                return (UNVIS_VALID);
 
220
 
 
221
        case S_OCTAL2:  /* second possible octal digit */
 
222
                if (isoctal(c)) {
 
223
                        /* 
 
224
                         * yes - and maybe a third 
 
225
                         */
 
226
                        *cp = (*cp << 3) + (c - '0');
 
227
                        *astate = S_OCTAL3;     
 
228
                        return (0);
 
229
                } 
 
230
                /* 
 
231
                 * no - done with current sequence, push back passed char 
 
232
                 */
 
233
                *astate = S_GROUND;
 
234
                return (UNVIS_VALIDPUSH);
 
235
 
 
236
        case S_OCTAL3:  /* third possible octal digit */
 
237
                *astate = S_GROUND;
 
238
                if (isoctal(c)) {
 
239
                        *cp = (*cp << 3) + (c - '0');
 
240
                        return (UNVIS_VALID);
 
241
                }
 
242
                /*
 
243
                 * we were done, push back passed char
 
244
                 */
 
245
                return (UNVIS_VALIDPUSH);
 
246
        case S_HEX1:
 
247
                if (isxdigit(c)) {
 
248
                        *cp = xtod(c);
 
249
                        *astate = S_HEX2;
 
250
                        return (0);
 
251
                }
 
252
                /* 
 
253
                 * no - done with current sequence, push back passed char 
 
254
                 */
 
255
                *astate = S_GROUND;
 
256
                return (UNVIS_VALIDPUSH);
 
257
        case S_HEX2:
 
258
                *astate = S_GROUND;
 
259
                if (isxdigit(c)) {
 
260
                        *cp = xtod(c) | (*cp << 4);
 
261
                        return (UNVIS_VALID);
 
262
                }
 
263
                return (UNVIS_VALIDPUSH);
 
264
        default:        
 
265
                /* 
 
266
                 * decoder in unknown state - (probably uninitialized) 
 
267
                 */
 
268
                *astate = S_GROUND;
 
269
                return (UNVIS_SYNBAD);
 
270
        }
 
271
}
 
272
 
 
273
/*
 
274
 * strunvis - decode src into dst 
 
275
 *
 
276
 *      Number of chars decoded into dst is returned, -1 on error.
 
277
 *      Dst is null terminated.
 
278
 */
 
279
 
 
280
int
 
281
strunvisx(dst, src, flag)
 
282
        char *dst;
 
283
        const char *src;
 
284
        int flag;
 
285
{
 
286
        char c;
 
287
        char *start = dst;
 
288
        int state = 0;
 
289
 
 
290
        _DIAGASSERT(src != NULL);
 
291
        _DIAGASSERT(dst != NULL);
 
292
 
 
293
        while ((c = *src++) != '\0') {
 
294
        again:
 
295
                switch (__unvis13(dst, c, &state, flag)) {
 
296
                case UNVIS_VALID:
 
297
                        dst++;
 
298
                        break;
 
299
                case UNVIS_VALIDPUSH:
 
300
                        dst++;
 
301
                        goto again;
 
302
                case 0:
 
303
                case UNVIS_NOCHAR:
 
304
                        break;
 
305
                default:
 
306
                        return (-1);
 
307
                }
 
308
        }
 
309
        if (__unvis13(dst, c, &state, UNVIS_END) == UNVIS_VALID)
 
310
                dst++;
 
311
        *dst = '\0';
 
312
        return (dst - start);
 
313
}
 
314
 
 
315
int
 
316
strunvis(dst, src)
 
317
        char *dst;
 
318
        const char *src;
 
319
{
 
320
        return strunvisx(dst, src, 0);
 
321
}
 
322
#endif