[BACK]Return to vis.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / lib / libc / gen

Annotation of src/lib/libc/gen/vis.c, Revision 1.24

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

CVSweb <webmaster@jp.NetBSD.org>