~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

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

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*      $NetBSD: vis.c,v 1.38 2008/09/04 09:41:44 lukem 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. Neither the name of the University nor the names of its contributors
 
16
 *    may be used to endorse or promote products derived from this software
 
17
 *    without specific prior written permission.
 
18
 *
 
19
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 
20
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
21
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
22
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 
23
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
24
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
25
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
26
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
27
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
28
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
29
 * SUCH DAMAGE.
 
30
 */
 
31
 
 
32
/*-
 
33
 * Copyright (c) 1999, 2005 The NetBSD Foundation, Inc.
 
34
 * All rights reserved.
 
35
 *
 
36
 * Redistribution and use in source and binary forms, with or without
 
37
 * modification, are permitted provided that the following conditions
 
38
 * are met:
 
39
 * 1. Redistributions of source code must retain the above copyright
 
40
 *    notice, this list of conditions and the following disclaimer.
 
41
 * 2. Redistributions in binary form must reproduce the above copyright
 
42
 *    notice, this list of conditions and the following disclaimer in the
 
43
 *    documentation and/or other materials provided with the distribution.
 
44
 *
 
45
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 
46
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 
47
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 
48
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 
49
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 
50
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 
51
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 
52
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 
53
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
54
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 
55
 * POSSIBILITY OF SUCH DAMAGE.
 
56
 */
 
57
 
 
58
#include "config.h"
 
59
 
 
60
#if defined(LIBC_SCCS) && !defined(lint)
 
61
#endif /* LIBC_SCCS and not lint */
 
62
 
 
63
#include <sys/types.h>
 
64
 
 
65
#include <assert.h>
 
66
#ifdef HAVE_VIS_H
 
67
#include <vis.h>
 
68
#else
 
69
#include "np/vis.h"
 
70
#endif
 
71
#include <stdlib.h>
 
72
 
 
73
#ifdef __weak_alias
 
74
__weak_alias(strsvis,_strsvis)
 
75
__weak_alias(strsvisx,_strsvisx)
 
76
__weak_alias(strvis,_strvis)
 
77
__weak_alias(strvisx,_strvisx)
 
78
__weak_alias(svis,_svis)
 
79
__weak_alias(vis,_vis)
 
80
#endif
 
81
 
 
82
#if !HAVE_VIS || !HAVE_SVIS
 
83
#include <ctype.h>
 
84
#include <limits.h>
 
85
#include <stdio.h>
 
86
#include <string.h>
 
87
 
 
88
static char *do_svis(char *, int, int, int, const char *);
 
89
 
 
90
#undef BELL
 
91
#define BELL '\a'
 
92
 
 
93
#define isoctal(c)      (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
 
94
#define iswhite(c)      (c == ' ' || c == '\t' || c == '\n')
 
95
#define issafe(c)       (c == '\b' || c == BELL || c == '\r')
 
96
#define xtoa(c)         "0123456789abcdef"[c]
 
97
 
 
98
#define MAXEXTRAS       5
 
99
 
 
100
#define MAKEEXTRALIST(flag, extra, orig_str)                                  \
 
101
do {                                                                          \
 
102
        const char *orig = orig_str;                                          \
 
103
        const char *o = orig;                                                 \
 
104
        char *e;                                                              \
 
105
        while (*o++)                                                          \
 
106
                continue;                                                     \
 
107
        extra = malloc((size_t)((o - orig) + MAXEXTRAS));                     \
 
108
        if (!extra) break;                                                    \
 
109
        for (o = orig, e = extra; (*e++ = *o++) != '\0';)                     \
 
110
                continue;                                                     \
 
111
        e--;                                                                  \
 
112
        if (flag & VIS_SP) *e++ = ' ';                                        \
 
113
        if (flag & VIS_TAB) *e++ = '\t';                                      \
 
114
        if (flag & VIS_NL) *e++ = '\n';                                       \
 
115
        if ((flag & VIS_NOSLASH) == 0) *e++ = '\\';                           \
 
116
        *e = '\0';                                                            \
 
117
} while (/*CONSTCOND*/0)
 
118
 
 
119
/*
 
120
 * This is do_hvis, for HTTP style (RFC 1808)
 
121
 */
 
122
static char *
 
123
do_hvis(char *dst, int c, int flag, int nextc, const char *extra)
 
124
{
 
125
        if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) {
 
126
                *dst++ = '%';
 
127
                *dst++ = xtoa(((unsigned int)c >> 4) & 0xf);
 
128
                *dst++ = xtoa((unsigned int)c & 0xf);
 
129
        } else {
 
130
                dst = do_svis(dst, c, flag, nextc, extra);
 
131
        }
 
132
        return dst;
 
133
}
 
134
 
 
135
/*
 
136
 * This is do_vis, the central code of vis.
 
137
 * dst:       Pointer to the destination buffer
 
138
 * c:         Character to encode
 
139
 * flag:      Flag word
 
140
 * nextc:     The character following 'c'
 
141
 * extra:     Pointer to the list of extra characters to be
 
142
 *            backslash-protected.
 
143
 */
 
144
static char *
 
145
do_svis(char *dst, int c, int flag, int nextc, const char *extra)
 
146
{
 
147
        int isextra;
 
148
        isextra = strchr(extra, c) != NULL;
 
149
        if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) ||
 
150
            ((flag & VIS_SAFE) && issafe(c)))) {
 
151
                *dst++ = c;
 
152
                return dst;
 
153
        }
 
154
        if (flag & VIS_CSTYLE) {
 
155
                switch (c) {
 
156
                case '\n':
 
157
                        *dst++ = '\\'; *dst++ = 'n';
 
158
                        return dst;
 
159
                case '\r':
 
160
                        *dst++ = '\\'; *dst++ = 'r';
 
161
                        return dst;
 
162
                case '\b':
 
163
                        *dst++ = '\\'; *dst++ = 'b';
 
164
                        return dst;
 
165
                case BELL:
 
166
                        *dst++ = '\\'; *dst++ = 'a';
 
167
                        return dst;
 
168
                case '\v':
 
169
                        *dst++ = '\\'; *dst++ = 'v';
 
170
                        return dst;
 
171
                case '\t':
 
172
                        *dst++ = '\\'; *dst++ = 't';
 
173
                        return dst;
 
174
                case '\f':
 
175
                        *dst++ = '\\'; *dst++ = 'f';
 
176
                        return dst;
 
177
                case ' ':
 
178
                        *dst++ = '\\'; *dst++ = 's';
 
179
                        return dst;
 
180
                case '\0':
 
181
                        *dst++ = '\\'; *dst++ = '0';
 
182
                        if (isoctal(nextc)) {
 
183
                                *dst++ = '0';
 
184
                                *dst++ = '0';
 
185
                        }
 
186
                        return dst;
 
187
                default:
 
188
                        if (isgraph(c)) {
 
189
                                *dst++ = '\\'; *dst++ = c;
 
190
                                return dst;
 
191
                        }
 
192
                }
 
193
        }
 
194
        if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) {
 
195
                *dst++ = '\\';
 
196
                *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0';
 
197
                *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0';
 
198
                *dst++ =                             (c       & 07) + '0';
 
199
        } else {
 
200
                if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\';
 
201
                if (c & 0200) {
 
202
                        c &= 0177; *dst++ = 'M';
 
203
                }
 
204
                if (iscntrl(c)) {
 
205
                        *dst++ = '^';
 
206
                        if (c == 0177)
 
207
                                *dst++ = '?';
 
208
                        else
 
209
                                *dst++ = c + '@';
 
210
                } else {
 
211
                        *dst++ = '-'; *dst++ = c;
 
212
                }
 
213
        }
 
214
        return dst;
 
215
}
 
216
 
 
217
 
 
218
/*
 
219
 * svis - visually encode characters, also encoding the characters
 
220
 *        pointed to by `extra'
 
221
 */
 
222
char *
 
223
svis(char *dst, int c, int flag, int nextc, const char *extra)
 
224
{
 
225
        char *nextra = NULL;
 
226
 
 
227
        _DIAGASSERT(dst != NULL);
 
228
        _DIAGASSERT(extra != NULL);
 
229
        MAKEEXTRALIST(flag, nextra, extra);
 
230
        if (!nextra) {
 
231
                *dst = '\0';            /* can't create nextra, return "" */
 
232
                return dst;
 
233
        }
 
234
        if (flag & VIS_HTTPSTYLE)
 
235
                dst = do_hvis(dst, c, flag, nextc, nextra);
 
236
        else
 
237
                dst = do_svis(dst, c, flag, nextc, nextra);
 
238
        free(nextra);
 
239
        *dst = '\0';
 
240
        return dst;
 
241
}
 
242
 
 
243
 
 
244
/*
 
245
 * strsvis, strsvisx - visually encode characters from src into dst
 
246
 *
 
247
 *      Extra is a pointer to a \0-terminated list of characters to
 
248
 *      be encoded, too. These functions are useful e. g. to
 
249
 *      encode strings in such a way so that they are not interpreted
 
250
 *      by a shell.
 
251
 *
 
252
 *      Dst must be 4 times the size of src to account for possible
 
253
 *      expansion.  The length of dst, not including the trailing NULL,
 
254
 *      is returned.
 
255
 *
 
256
 *      Strsvisx encodes exactly len bytes from src into dst.
 
257
 *      This is useful for encoding a block of data.
 
258
 */
 
259
int
 
260
strsvis(char *dst, const char *csrc, int flag, const char *extra)
 
261
{
 
262
        int c;
 
263
        char *start;
 
264
        char *nextra = NULL;
 
265
        const unsigned char *src = (const unsigned char *)csrc;
 
266
 
 
267
        _DIAGASSERT(dst != NULL);
 
268
        _DIAGASSERT(src != NULL);
 
269
        _DIAGASSERT(extra != NULL);
 
270
        MAKEEXTRALIST(flag, nextra, extra);
 
271
        if (!nextra) {
 
272
                *dst = '\0';            /* can't create nextra, return "" */
 
273
                return 0;
 
274
        }
 
275
        if (flag & VIS_HTTPSTYLE) {
 
276
                for (start = dst; (c = *src++) != '\0'; /* empty */)
 
277
                        dst = do_hvis(dst, c, flag, *src, nextra);
 
278
        } else {
 
279
                for (start = dst; (c = *src++) != '\0'; /* empty */)
 
280
                        dst = do_svis(dst, c, flag, *src, nextra);
 
281
        }
 
282
        free(nextra);
 
283
        *dst = '\0';
 
284
        return (dst - start);
 
285
}
 
286
 
 
287
 
 
288
int
 
289
strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra)
 
290
{
 
291
        unsigned char c;
 
292
        char *start;
 
293
        char *nextra = NULL;
 
294
        const unsigned char *src = (const unsigned char *)csrc;
 
295
 
 
296
        _DIAGASSERT(dst != NULL);
 
297
        _DIAGASSERT(src != NULL);
 
298
        _DIAGASSERT(extra != NULL);
 
299
        MAKEEXTRALIST(flag, nextra, extra);
 
300
        if (! nextra) {
 
301
                *dst = '\0';            /* can't create nextra, return "" */
 
302
                return 0;
 
303
        }
 
304
 
 
305
        if (flag & VIS_HTTPSTYLE) {
 
306
                for (start = dst; len > 0; len--) {
 
307
                        c = *src++;
 
308
                        dst = do_hvis(dst, c, flag,
 
309
                            len > 1 ? *src : '\0', nextra);
 
310
                }
 
311
        } else {
 
312
                for (start = dst; len > 0; len--) {
 
313
                        c = *src++;
 
314
                        dst = do_svis(dst, c, flag,
 
315
                            len > 1 ? *src : '\0', nextra);
 
316
                }
 
317
        }
 
318
        free(nextra);
 
319
        *dst = '\0';
 
320
        return (dst - start);
 
321
}
 
322
#endif
 
323
 
 
324
#if !HAVE_VIS
 
325
/*
 
326
 * vis - visually encode characters
 
327
 */
 
328
char *
 
329
vis(char *dst, int c, int flag, int nextc)
 
330
{
 
331
        char *extra = NULL;
 
332
        unsigned char uc = (unsigned char)c;
 
333
 
 
334
        _DIAGASSERT(dst != NULL);
 
335
 
 
336
        MAKEEXTRALIST(flag, extra, "");
 
337
        if (! extra) {
 
338
                *dst = '\0';            /* can't create extra, return "" */
 
339
                return dst;
 
340
        }
 
341
        if (flag & VIS_HTTPSTYLE)
 
342
                dst = do_hvis(dst, uc, flag, nextc, extra);
 
343
        else
 
344
                dst = do_svis(dst, uc, flag, nextc, extra);
 
345
        free(extra);
 
346
        *dst = '\0';
 
347
        return dst;
 
348
}
 
349
 
 
350
 
 
351
/*
 
352
 * strvis, strvisx - visually encode characters from src into dst
 
353
 *
 
354
 *      Dst must be 4 times the size of src to account for possible
 
355
 *      expansion.  The length of dst, not including the trailing NULL,
 
356
 *      is returned.
 
357
 *
 
358
 *      Strvisx encodes exactly len bytes from src into dst.
 
359
 *      This is useful for encoding a block of data.
 
360
 */
 
361
int
 
362
strvis(char *dst, const char *src, int flag)
 
363
{
 
364
        char *extra = NULL;
 
365
        int rv;
 
366
 
 
367
        MAKEEXTRALIST(flag, extra, "");
 
368
        if (!extra) {
 
369
                *dst = '\0';            /* can't create extra, return "" */
 
370
                return 0;
 
371
        }
 
372
        rv = strsvis(dst, src, flag, extra);
 
373
        free(extra);
 
374
        return rv;
 
375
}
 
376
 
 
377
 
 
378
int
 
379
strvisx(char *dst, const char *src, size_t len, int flag)
 
380
{
 
381
        char *extra = NULL;
 
382
        int rv;
 
383
 
 
384
        MAKEEXTRALIST(flag, extra, "");
 
385
        if (!extra) {
 
386
                *dst = '\0';            /* can't create extra, return "" */
 
387
                return 0;
 
388
        }
 
389
        rv = strsvisx(dst, src, len, flag, extra);
 
390
        free(extra);
 
391
        return rv;
 
392
}
 
393
#endif