diff options
author | Otto Moerbeek <otto@cvs.openbsd.org> | 2004-10-17 20:25:32 +0000 |
---|---|---|
committer | Otto Moerbeek <otto@cvs.openbsd.org> | 2004-10-17 20:25:32 +0000 |
commit | 8566f00d2c81878ad985906994fedb6fbb16df24 (patch) | |
tree | c040b009eee232769227b6f430ef75ceb07ee082 /lib/libc | |
parent | 6119135c871cdb14d2c537be99ec398e13edf027 (diff) |
implement strnunvis(3), a bounded version of strunvis(3). ok millert@
Diffstat (limited to 'lib/libc')
-rw-r--r-- | lib/libc/gen/unvis.3 | 38 | ||||
-rw-r--r-- | lib/libc/gen/unvis.c | 45 |
2 files changed, 78 insertions, 5 deletions
diff --git a/lib/libc/gen/unvis.3 b/lib/libc/gen/unvis.3 index e7fe0c7cac6..de4fcff41d2 100644 --- a/lib/libc/gen/unvis.3 +++ b/lib/libc/gen/unvis.3 @@ -1,4 +1,4 @@ -.\" $OpenBSD: unvis.3,v 1.13 2003/06/02 20:18:35 millert Exp $ +.\" $OpenBSD: unvis.3,v 1.14 2004/10/17 20:25:31 otto Exp $ .\" .\" Copyright (c) 1989, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -32,7 +32,8 @@ .Os .Sh NAME .Nm unvis , -.Nm strunvis +.Nm strunvis , +.Nm strnunvis .Nd decode a visual representation of characters .Sh SYNOPSIS .Fd #include <vis.h> @@ -40,11 +41,14 @@ .Fn unvis "char *cp" "char c" "int *astate" "int flag" .Ft int .Fn strunvis "char *dst" "char *src" +.Ft ssize_t +.Fn strnunvis "char *dst" "char *src" "size_t size" .Sh DESCRIPTION The -.Fn unvis -and +.Fn unvis , .Fn strunvis +and +.Fn strnunvis functions are used to decode a visual representation of characters, as produced by the .Xr vis 3 @@ -63,6 +67,14 @@ decodes the characters pointed to by into the buffer pointed to by .Fa dst . .Pp +.Fn strnunvis +decodes the characters pointed to by +.Fa src +into the buffer pointed to by +.Fa dst , +writing a maximum of +.Fa size +bytes. The .Fn strunvis function simply copies @@ -80,6 +92,12 @@ should be equal to the size of .Fa src (that is, no expansion takes place during decoding). +.Fn strunvis +terminates the destination string with a trailing NUL byte; +.Fn strnunvis +does so if +.Fa size +is larger than 0. .Pp The .Fn unvis @@ -95,6 +113,7 @@ Call .Fn unvis with each successive byte, along with a pointer to this integer, and a pointer to a destination character. +.Sh RETURN VALUES The .Fn unvis function has several return codes that must be handled properly. @@ -125,6 +144,17 @@ When all bytes in the stream have been processed, call one more time with flag set to .Dv UNVIS_END to extract any remaining character (the character passed in is ignored). +.Pp +The +.Fn strunvis +function returns the number of bytes written (not counting +the trailing NUL byte) or \-1 if an error occurred. +.Pp +The +.Fn strnunvis +function returns the number of bytes (not counting the trailing NUL byte), +that would be needed to fully convert the input string, or \-1 if an +error occurred. .Sh EXAMPLES The following code fragment illustrates a proper use of .Fn unvis . diff --git a/lib/libc/gen/unvis.c b/lib/libc/gen/unvis.c index 52e204c4641..d0bc70d5af3 100644 --- a/lib/libc/gen/unvis.c +++ b/lib/libc/gen/unvis.c @@ -28,7 +28,7 @@ */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$OpenBSD: unvis.c,v 1.9 2004/05/18 02:05:52 jfb Exp $"; +static char rcsid[] = "$OpenBSD: unvis.c,v 1.10 2004/10/17 20:25:31 otto Exp $"; #endif /* LIBC_SCCS and not lint */ #include <sys/types.h> @@ -230,6 +230,7 @@ strunvis(char *dst, const char *src) case UNVIS_NOCHAR: break; default: + *dst = '\0'; return (-1); } } @@ -238,3 +239,45 @@ strunvis(char *dst, const char *src) *dst = '\0'; return (dst - start); } + +ssize_t +strnunvis(char *dst, const char *src, size_t sz) +{ + char c, p; + char *start = dst, *end = dst + sz - 1; + int state = 0; + + if (sz > 0) + *end = '\0'; + while ((c = *src++)) { + again: + switch (unvis(&p, c, &state, 0)) { + case UNVIS_VALID: + if (dst < end) + *dst = p; + dst++; + break; + case UNVIS_VALIDPUSH: + if (dst < end) + *dst = p; + dst++; + goto again; + case 0: + case UNVIS_NOCHAR: + break; + default: + if (dst <= end) + *dst = '\0'; + return (-1); + } + } + if (unvis(&p, c, &state, UNVIS_END) == UNVIS_VALID) { + if (dst < end) + *dst = p; + dst++; + } + if (dst <= end) + *dst = '\0'; + return (dst - start); +} + |