summaryrefslogtreecommitdiff
path: root/lib/libc
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2010-08-21 18:59:16 +0000
committerDamien Miller <djm@cvs.openbsd.org>2010-08-21 18:59:16 +0000
commit20b28aebdc9d72f6cff9b47e4a228afbd3d67834 (patch)
tree1f8d08fc90a6b3ce28d32ab07951169b175ea842 /lib/libc
parentdc723b55f0f06bf08b896ffd9eaec3d0472f9d46 (diff)
Two new flags: VIS_ALL - encode all characters, not just invisible ones
and VIS_HEX - use C89 \xff style hexadecimal encoding. Teach unvis(3) how to deal with the hex encoding. feedback and ok millert@ chl@
Diffstat (limited to 'lib/libc')
-rw-r--r--lib/libc/gen/unvis.c53
-rw-r--r--lib/libc/gen/vis.313
-rw-r--r--lib/libc/gen/vis.c23
3 files changed, 77 insertions, 12 deletions
diff --git a/lib/libc/gen/unvis.c b/lib/libc/gen/unvis.c
index 258c2d51996..29c3d0a7913 100644
--- a/lib/libc/gen/unvis.c
+++ b/lib/libc/gen/unvis.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: unvis.c,v 1.12 2005/08/08 08:05:34 espie Exp $ */
+/* $OpenBSD: unvis.c,v 1.13 2010/08/21 18:59:15 djm Exp $ */
/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -42,8 +42,25 @@
#define S_CTRL 4 /* control char started (^) */
#define S_OCTAL2 5 /* octal digit 2 */
#define S_OCTAL3 6 /* octal digit 3 */
+#define S_HEX1 7 /* hex digit 1 */
+#define S_HEX2 8 /* hex digit 2 */
#define isoctal(c) (((u_char)(c)) >= '0' && ((u_char)(c)) <= '7')
+#define ishex(c) ((((u_char)(c)) >= '0' && ((u_char)(c)) <= '9') || \
+ (((u_char)(c)) >= 'a' && ((u_char)(c)) <= 'f') || \
+ (((u_char)(c)) >= 'A' && ((u_char)(c)) <= 'F'))
+
+static u_int
+dehex(u_int c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'a' && c <= 'f')
+ return 10 + c - 'a';
+ if (c >= 'A' && c <= 'F')
+ return 10 + c - 'A';
+ return 0;
+}
/*
* unvis - decode characters previously encoded by vis
@@ -53,7 +70,8 @@ unvis(char *cp, char c, int *astate, int flag)
{
if (flag & UNVIS_END) {
- if (*astate == S_OCTAL2 || *astate == S_OCTAL3) {
+ if (*astate == S_OCTAL2 || *astate == S_OCTAL3 ||
+ *astate == S_HEX1 || *astate == S_HEX2) {
*astate = S_GROUND;
return (UNVIS_VALID);
}
@@ -77,6 +95,9 @@ unvis(char *cp, char c, int *astate, int flag)
*cp = c;
*astate = S_GROUND;
return (UNVIS_VALID);
+ case 'x':
+ *astate = S_HEX1;
+ return (0);
case '0': case '1': case '2': case '3':
case '4': case '5': case '6': case '7':
*cp = (c - '0');
@@ -190,7 +211,33 @@ unvis(char *cp, char c, int *astate, int flag)
* we were done, push back passed char
*/
return (UNVIS_VALIDPUSH);
-
+
+ case S_HEX1: /* first possible hex digit */
+ if (ishex(c)) {
+ /*
+ * yes - and maybe a second
+ */
+ *cp = dehex(c);
+ *astate = S_HEX2;
+ return (0);
+ }
+ /*
+ * no - done with current sequence, push back passed char
+ */
+ *astate = S_GROUND;
+ return (UNVIS_VALIDPUSH);
+
+ case S_HEX2: /* second possible hex digit */
+ *astate = S_GROUND;
+ if (ishex(c)) {
+ *cp = ((u_int)*cp << 4) + dehex(c);
+ return (UNVIS_VALID);
+ }
+ /*
+ * we were done, push back passed char
+ */
+ return (UNVIS_VALIDPUSH);
+
default:
/*
* decoder in unknown state - (probably uninitialized)
diff --git a/lib/libc/gen/vis.3 b/lib/libc/gen/vis.3
index 1fae60697db..ce63c2c49f7 100644
--- a/lib/libc/gen/vis.3
+++ b/lib/libc/gen/vis.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: vis.3,v 1.24 2007/05/31 19:19:29 jmc Exp $
+.\" $OpenBSD: vis.3,v 1.25 2010/08/21 18:59:15 djm Exp $
.\"
.\" Copyright (c) 1989, 1991, 1993
.\" The Regents of the University of California. All rights reserved.
@@ -27,7 +27,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd $Mdocdate: May 31 2007 $
+.Dd $Mdocdate: August 21 2010 $
.Dt VIS 3
.Os
.Sh NAME
@@ -163,6 +163,8 @@ except space, tab, and newline are encoded
The following flags
alter this:
.Bl -tag -width VIS_WHITEX
+.It Dv VIS_ALL
+Encode all characters, whether visible or not.
.It Dv VIS_GLOB
Also encode magic characters recognized by
.Xr glob 3
@@ -278,6 +280,13 @@ If
.Fa nextc
is an octal digit, the latter representation is used to
avoid ambiguity.
+.It Dv VIS_HEX
+Use a two digit hexadecimal sequence.
+The form is
+.Ql \exdd
+where
+.Ar d
+represents a hexadecimal digit.
.It Dv VIS_OCTAL
Use a three digit octal sequence.
The form is
diff --git a/lib/libc/gen/vis.c b/lib/libc/gen/vis.c
index 8e44ad733c7..51407e6a7da 100644
--- a/lib/libc/gen/vis.c
+++ b/lib/libc/gen/vis.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vis.c,v 1.19 2005/09/01 17:15:49 millert Exp $ */
+/* $OpenBSD: vis.c,v 1.20 2010/08/21 18:59:15 djm Exp $ */
/*-
* Copyright (c) 1989, 1993
* The Regents of the University of California. All rights reserved.
@@ -46,13 +46,15 @@
(c) == '\007' || (c) == '\r' || \
isgraph((u_char)(c)))))
+static const char hexdigits[] = "0123456789abcdef";
+
/*
* vis - visually encode characters
*/
char *
vis(char *dst, int c, int flag, int nextc)
{
- if (isvisible(c)) {
+ if (isvisible(c) && (flag & VIS_ALL) == 0) {
*dst++ = c;
if (c == '\\' && (flag & VIS_NOSLASH) == 0)
*dst++ = '\\';
@@ -104,12 +106,19 @@ vis(char *dst, int c, int flag, int nextc)
goto done;
}
}
- if (((c & 0177) == ' ') || (flag & VIS_OCTAL) ||
+ if (((c & 0177) == ' ') || (flag & (VIS_OCTAL|VIS_HEX)) ||
((flag & VIS_GLOB) && (c == '*' || c == '?' || c == '[' || c == '#'))) {
- *dst++ = '\\';
- *dst++ = ((u_char)c >> 6 & 07) + '0';
- *dst++ = ((u_char)c >> 3 & 07) + '0';
- *dst++ = ((u_char)c & 07) + '0';
+ if ((flag & VIS_HEX) != 0) {
+ *dst++ = '\\';
+ *dst++ = 'x';
+ *dst++ = hexdigits[((u_char)c >> 4 & 0xf)];
+ *dst++ = hexdigits[((u_char)c & 0xf)];
+ } else {
+ *dst++ = '\\';
+ *dst++ = ((u_char)c >> 6 & 07) + '0';
+ *dst++ = ((u_char)c >> 3 & 07) + '0';
+ *dst++ = ((u_char)c & 07) + '0';
+ }
goto done;
}
if ((flag & VIS_NOSLASH) == 0)