diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2010-08-21 18:59:16 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2010-08-21 18:59:16 +0000 |
commit | 20b28aebdc9d72f6cff9b47e4a228afbd3d67834 (patch) | |
tree | 1f8d08fc90a6b3ce28d32ab07951169b175ea842 /lib | |
parent | dc723b55f0f06bf08b896ffd9eaec3d0472f9d46 (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')
-rw-r--r-- | lib/libc/gen/unvis.c | 53 | ||||
-rw-r--r-- | lib/libc/gen/vis.3 | 13 | ||||
-rw-r--r-- | lib/libc/gen/vis.c | 23 |
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) |