summaryrefslogtreecommitdiff
path: root/lib/libc/gen/vis.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc/gen/vis.c')
-rw-r--r--lib/libc/gen/vis.c96
1 files changed, 71 insertions, 25 deletions
diff --git a/lib/libc/gen/vis.c b/lib/libc/gen/vis.c
index 17a6625f5f3..9021147c8a7 100644
--- a/lib/libc/gen/vis.c
+++ b/lib/libc/gen/vis.c
@@ -1,4 +1,4 @@
-/* $NetBSD: vis.c,v 1.21 2002/01/31 22:43:39 tv Exp $ */
+/* $NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $ */
/*-
* Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -36,7 +36,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: vis.c,v 1.21 2002/01/31 22:43:39 tv Exp $");
+__RCSID("$NetBSD: vis.c,v 1.22 2002/03/23 17:38:27 christos Exp $");
#endif /* LIBC_SCCS and not lint */
#include "namespace.h"
@@ -44,6 +44,7 @@ __RCSID("$NetBSD: vis.c,v 1.21 2002/01/31 22:43:39 tv Exp $");
#include <assert.h>
#include <vis.h>
+#include <stdlib.h>
#ifdef __weak_alias
__weak_alias(strsvis,_strsvis)
@@ -70,20 +71,43 @@ __weak_alias(vis,_vis)
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
#define iswhite(c) (c == ' ' || c == '\t' || c == '\n')
#define issafe(c) (c == '\b' || c == BELL || c == '\r')
+#define xtoa(c) "0123456789abcdef"[c]
#define MAXEXTRAS 5
-#define MAKEEXTRALIST(flag, extra) \
+#define MAKEEXTRALIST(flag, extra, orig) \
do { \
- char *pextra = extra; \
- if (flag & VIS_SP) *pextra++ = ' '; \
- if (flag & VIS_TAB) *pextra++ = '\t'; \
- if (flag & VIS_NL) *pextra++ = '\n'; \
- if ((flag & VIS_NOSLASH) == 0) *pextra++ = '\\'; \
- *pextra = '\0'; \
+ const char *o = orig; \
+ char *e; \
+ while (*o++) \
+ continue; \
+ extra = alloca((size_t)((o - orig) + MAXEXTRAS)); \
+ for (o = orig, e = extra; (*e++ = *o++) != '\0';) \
+ continue; \
+ e--; \
+ if (flag & VIS_SP) *e++ = ' '; \
+ if (flag & VIS_TAB) *e++ = '\t'; \
+ if (flag & VIS_NL) *e++ = '\n'; \
+ if ((flag & VIS_NOSLASH) == 0) *e++ = '\\'; \
+ *e = '\0'; \
} while (/*CONSTCOND*/0)
+
+/*
+ * This is HVIS, the macro of vis used to HTTP style (RFC 1808)
+ */
+#define HVIS(dst, c, flag, nextc, extra) \
+do \
+ if (!isascii(c) || !isalnum(c) || strchr("$-_.+!*'(),", c) != NULL) { \
+ *dst++ = '%'; \
+ *dst++ = xtoa(((unsigned int)c >> 4) & 0xf); \
+ *dst++ = xtoa((unsigned int)c & 0xf); \
+ } else { \
+ SVIS(dst, c, flag, nextc, extra); \
+ } \
+while (/*CONSTCOND*/0)
+
/*
* This is SVIS, the central macro of vis.
* dst: Pointer to the destination buffer
@@ -171,10 +195,14 @@ svis(dst, c, flag, nextc, extra)
int c, flag, nextc;
const char *extra;
{
+ char *nextra;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(extra != NULL);
-
- SVIS(dst, c, flag, nextc, extra);
+ MAKEEXTRALIST(flag, nextra, extra);
+ if (flag & VIS_HTTPSTYLE)
+ HVIS(dst, c, flag, nextc, nextra);
+ else
+ SVIS(dst, c, flag, nextc, nextra);
*dst = '\0';
return(dst);
}
@@ -204,13 +232,19 @@ strsvis(dst, src, flag, extra)
{
char c;
char *start;
+ char *nextra;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
_DIAGASSERT(extra != NULL);
-
- for (start = dst; (c = *src++) != '\0'; /* empty */)
- SVIS(dst, c, flag, *src, extra);
+ MAKEEXTRALIST(flag, nextra, extra);
+ if (flag & VIS_HTTPSTYLE) {
+ for (start = dst; (c = *src++) != '\0'; /* empty */)
+ HVIS(dst, c, flag, *src, nextra);
+ } else {
+ for (start = dst; (c = *src++) != '\0'; /* empty */)
+ SVIS(dst, c, flag, *src, nextra);
+ }
*dst = '\0';
return (dst - start);
}
@@ -226,14 +260,23 @@ strsvisx(dst, src, len, flag, extra)
{
char c;
char *start;
+ char *nextra;
_DIAGASSERT(dst != NULL);
_DIAGASSERT(src != NULL);
_DIAGASSERT(extra != NULL);
-
- for (start = dst; len > 0; len--) {
- c = *src++;
- SVIS(dst, c, flag, len ? *src : '\0', extra);
+ MAKEEXTRALIST(flag, nextra, extra);
+
+ if (flag & VIS_HTTPSTYLE) {
+ for (start = dst; len > 0; len--) {
+ c = *src++;
+ HVIS(dst, c, flag, len ? *src : '\0', nextra);
+ }
+ } else {
+ for (start = dst; len > 0; len--) {
+ c = *src++;
+ SVIS(dst, c, flag, len ? *src : '\0', nextra);
+ }
}
*dst = '\0';
return (dst - start);
@@ -249,12 +292,15 @@ vis(dst, c, flag, nextc)
int c, flag, nextc;
{
- char extra[MAXEXTRAS];
+ char *extra;
_DIAGASSERT(dst != NULL);
- MAKEEXTRALIST(flag, extra);
- SVIS(dst, c, flag, nextc, extra);
+ MAKEEXTRALIST(flag, extra, "");
+ if (flag & VIS_HTTPSTYLE)
+ HVIS(dst, c, flag, nextc, extra);
+ else
+ SVIS(dst, c, flag, nextc, extra);
*dst = '\0';
return (dst);
}
@@ -276,9 +322,9 @@ strvis(dst, src, flag)
const char *src;
int flag;
{
- char extra[MAXEXTRAS];
+ char *extra;
- MAKEEXTRALIST(flag, extra);
+ MAKEEXTRALIST(flag, extra, "");
return (strsvis(dst, src, flag, extra));
}
@@ -290,9 +336,9 @@ strvisx(dst, src, len, flag)
size_t len;
int flag;
{
- char extra[MAXEXTRAS];
+ char *extra;
- MAKEEXTRALIST(flag, extra);
+ MAKEEXTRALIST(flag, extra, "");
return (strsvisx(dst, src, len, flag, extra));
}
#endif