File indexing completed on 2025-05-11 08:24:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065 #ifdef HAVE_CONFIG_H
0066 #include "config.h"
0067 #endif
0068
0069 #define _DIAGASSERT(a)
0070
0071 #if 0
0072 #include <sys/cdefs.h>
0073 #if defined(LIBC_SCCS) && !defined(lint)
0074 __RCSID("$NetBSD: vis.c,v 1.33 2005/05/28 13:11:14 lukem Exp $");
0075 #endif
0076 #endif
0077
0078 #include <sys/types.h>
0079
0080 #include "vis.h"
0081 #include <stdlib.h>
0082
0083 #if !HAVE_VIS || !HAVE_SVIS
0084 #include <ctype.h>
0085 #include <limits.h>
0086 #include <stdio.h>
0087 #include <string.h>
0088
0089 #undef BELL
0090 #define BELL '\a'
0091
0092 #define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
0093 #define iswhite(c) (c == ' ' || c == '\t' || c == '\n')
0094 #define issafe(c) (c == '\b' || c == BELL || c == '\r')
0095 #define xtoa(c) "0123456789abcdef"[c]
0096
0097 #define MAXEXTRAS 5
0098
0099
0100 #define MAKEEXTRALIST(flag, extra, orig) \
0101 do { \
0102 const char *o = orig; \
0103 char *e; \
0104 while (*o++) \
0105 continue; \
0106 extra = malloc((size_t)((o - orig) + MAXEXTRAS)); \
0107 if (!extra) break; \
0108 for (o = orig, e = extra; (*e++ = *o++) != '\0';) \
0109 continue; \
0110 e--; \
0111 if (flag & VIS_SP) *e++ = ' '; \
0112 if (flag & VIS_TAB) *e++ = '\t'; \
0113 if (flag & VIS_NL) *e++ = '\n'; \
0114 if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \
0115 *e = '\0'; \
0116 } while (0)
0117
0118
0119
0120
0121
0122 #define HVIS(dst, c, flag, nextc, extra) \
0123 do \
0124 if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \
0125 *dst++ = '%'; \
0126 *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); \
0127 *dst++ = xtoa((unsigned int)c & 0xf); \
0128 } else { \
0129 SVIS(dst, c, flag, nextc, extra); \
0130 } \
0131 while (0)
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142 #define SVIS(dst, c, flag, nextc, extra) \
0143 do { \
0144 int isextra; \
0145 isextra = strchr(extra, c) != NULL; \
0146 if (!isextra && isascii(c) && (isgraph(c) || iswhite(c) || \
0147 ((flag & VIS_SAFE) && issafe(c)))) { \
0148 *dst++ = c; \
0149 break; \
0150 } \
0151 if (flag & VIS_CSTYLE) { \
0152 switch (c) { \
0153 case '\n': \
0154 *dst++ = '\\'; *dst++ = 'n'; \
0155 continue; \
0156 case '\r': \
0157 *dst++ = '\\'; *dst++ = 'r'; \
0158 continue; \
0159 case '\b': \
0160 *dst++ = '\\'; *dst++ = 'b'; \
0161 continue; \
0162 case BELL: \
0163 *dst++ = '\\'; *dst++ = 'a'; \
0164 continue; \
0165 case '\v': \
0166 *dst++ = '\\'; *dst++ = 'v'; \
0167 continue; \
0168 case '\t': \
0169 *dst++ = '\\'; *dst++ = 't'; \
0170 continue; \
0171 case '\f': \
0172 *dst++ = '\\'; *dst++ = 'f'; \
0173 continue; \
0174 case ' ': \
0175 *dst++ = '\\'; *dst++ = 's'; \
0176 continue; \
0177 case '\0': \
0178 *dst++ = '\\'; *dst++ = '0'; \
0179 if (isoctal(nextc)) { \
0180 *dst++ = '0'; \
0181 *dst++ = '0'; \
0182 } \
0183 continue; \
0184 default: \
0185 if (isgraph(c)) { \
0186 *dst++ = '\\'; *dst++ = c; \
0187 continue; \
0188 } \
0189 } \
0190 } \
0191 if (isextra || ((c & 0177) == ' ') || (flag & VIS_OCTAL)) { \
0192 *dst++ = '\\'; \
0193 *dst++ = (u_char)(((u_int32_t)(u_char)c >> 6) & 03) + '0'; \
0194 *dst++ = (u_char)(((u_int32_t)(u_char)c >> 3) & 07) + '0'; \
0195 *dst++ = (c & 07) + '0'; \
0196 } else { \
0197 if ((flag & VIS_NOSLASH) == 0) *dst++ = '\\'; \
0198 if (c & 0200) { \
0199 c &= 0177; *dst++ = 'M'; \
0200 } \
0201 if (iscntrl(c)) { \
0202 *dst++ = '^'; \
0203 if (c == 0177) \
0204 *dst++ = '?'; \
0205 else \
0206 *dst++ = c + '@'; \
0207 } else { \
0208 *dst++ = '-'; *dst++ = c; \
0209 } \
0210 } \
0211 } while (0)
0212
0213
0214
0215
0216
0217
0218 char *
0219 svis(char *dst, int c, int flag, int nextc, const char *extra)
0220 {
0221 char *nextra = NULL;
0222
0223 _DIAGASSERT(dst != NULL);
0224 _DIAGASSERT(extra != NULL);
0225 MAKEEXTRALIST(flag, nextra, extra);
0226 if (!nextra) {
0227 *dst = '\0';
0228 return dst;
0229 }
0230 if (flag & VIS_HTTPSTYLE)
0231 HVIS(dst, c, flag, nextc, nextra);
0232 else
0233 SVIS(dst, c, flag, nextc, nextra);
0234 free(nextra);
0235 *dst = '\0';
0236 return dst;
0237 }
0238
0239
0240
0241
0242
0243
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255 int
0256 strsvis(char *dst, const char *csrc, int flag, const char *extra)
0257 {
0258 int c;
0259 char *start;
0260 char *nextra = NULL;
0261 const unsigned char *src = (const unsigned char *)csrc;
0262
0263 _DIAGASSERT(dst != NULL);
0264 _DIAGASSERT(src != NULL);
0265 _DIAGASSERT(extra != NULL);
0266 MAKEEXTRALIST(flag, nextra, extra);
0267 if (!nextra) {
0268 *dst = '\0';
0269 return 0;
0270 }
0271 if (flag & VIS_HTTPSTYLE) {
0272 for (start = dst; (c = *src++) != '\0'; )
0273 HVIS(dst, c, flag, *src, nextra);
0274 } else {
0275 for (start = dst; (c = *src++) != '\0'; )
0276 SVIS(dst, c, flag, *src, nextra);
0277 }
0278 free(nextra);
0279 *dst = '\0';
0280 return (dst - start);
0281 }
0282
0283
0284 int
0285 strsvisx(char *dst, const char *csrc, size_t len, int flag, const char *extra)
0286 {
0287 unsigned char c;
0288 char *start;
0289 char *nextra = NULL;
0290 const unsigned char *src = (const unsigned char *)csrc;
0291
0292 _DIAGASSERT(dst != NULL);
0293 _DIAGASSERT(src != NULL);
0294 _DIAGASSERT(extra != NULL);
0295 MAKEEXTRALIST(flag, nextra, extra);
0296 if (! nextra) {
0297 *dst = '\0';
0298 return 0;
0299 }
0300
0301 if (flag & VIS_HTTPSTYLE) {
0302 for (start = dst; len > 0; len--) {
0303 c = *src++;
0304 HVIS(dst, c, flag, len ? *src : '\0', nextra);
0305 }
0306 } else {
0307 for (start = dst; len > 0; len--) {
0308 c = *src++;
0309 SVIS(dst, c, flag, len ? *src : '\0', nextra);
0310 }
0311 }
0312 free(nextra);
0313 *dst = '\0';
0314 return (dst - start);
0315 }
0316 #endif
0317
0318 #if !HAVE_VIS
0319
0320
0321
0322 char *
0323 vis(char *dst, int c, int flag, int nextc)
0324 {
0325 char *extra = NULL;
0326 unsigned char uc = (unsigned char)c;
0327
0328 _DIAGASSERT(dst != NULL);
0329
0330 MAKEEXTRALIST(flag, extra, "");
0331 if (! extra) {
0332 *dst = '\0';
0333 return dst;
0334 }
0335 if (flag & VIS_HTTPSTYLE)
0336 HVIS(dst, uc, flag, nextc, extra);
0337 else
0338 SVIS(dst, uc, flag, nextc, extra);
0339 free(extra);
0340 *dst = '\0';
0341 return dst;
0342 }
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355 int
0356 strvis(char *dst, const char *src, int flag)
0357 {
0358 char *extra = NULL;
0359 int rv;
0360
0361 MAKEEXTRALIST(flag, extra, "");
0362 if (!extra) {
0363 *dst = '\0';
0364 return 0;
0365 }
0366 rv = strsvis(dst, src, flag, extra);
0367 free(extra);
0368 return rv;
0369 }
0370
0371
0372 int
0373 strvisx(char *dst, const char *src, size_t len, int flag)
0374 {
0375 char *extra = NULL;
0376 int rv;
0377
0378 MAKEEXTRALIST(flag, extra, "");
0379 if (!extra) {
0380 *dst = '\0';
0381 return 0;
0382 }
0383 rv = strsvisx(dst, src, len, flag, extra);
0384 free(extra);
0385 return rv;
0386 }
0387 #endif