1.\"	$OpenBSD: unvis.3,v 1.18 2014/11/09 04:34:20 guenther Exp $
2.\"
3.\" Copyright (c) 1989, 1991, 1993
4.\"	The Regents of the University of California.  All rights reserved.
5.\"
6.\" Redistribution and use in source and binary forms, with or without
7.\" modification, are permitted provided that the following conditions
8.\" are met:
9.\" 1. Redistributions of source code must retain the above copyright
10.\"    notice, this list of conditions and the following disclaimer.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\"    notice, this list of conditions and the following disclaimer in the
13.\"    documentation and/or other materials provided with the distribution.
14.\" 3. Neither the name of the University nor the names of its contributors
15.\"    may be used to endorse or promote products derived from this software
16.\"    without specific prior written permission.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
19.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
22.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28.\" SUCH DAMAGE.
29.\"
30.Dd $Mdocdate: November 9 2014 $
31.Dt UNVIS 3
32.Os
33.Sh NAME
34.Nm unvis ,
35.Nm strunvis ,
36.Nm strnunvis
37.Nd decode a visual representation of characters
38.Sh SYNOPSIS
39.In vis.h
40.Ft int
41.Fn unvis "char *cp" "char c" "int *astate" "int flag"
42.Ft int
43.Fn strunvis "char *dst" "const char *src"
44.Ft ssize_t
45.Fn strnunvis "char *dst" "const char *src" "size_t size"
46.Sh DESCRIPTION
47The
48.Fn unvis ,
49.Fn strunvis
50and
51.Fn strnunvis
52functions are used to decode a visual representation of characters,
53as produced by the
54.Xr vis 3
55function, back into the original form.
56.Fn unvis
57is called with successive characters in
58.Fa c
59until a valid
60sequence is recognized, at which time the decoded character is
61available at the character pointed to by
62.Fa cp .
63.Pp
64.Fn strunvis
65decodes the characters pointed to by
66.Fa src
67into the buffer pointed to by
68.Fa dst .
69.Pp
70.Fn strnunvis
71decodes the characters pointed to by
72.Fa src
73into the buffer pointed to by
74.Fa dst ,
75writing a maximum of
76.Fa size
77bytes.
78The
79.Fn strunvis
80function simply copies
81.Fa src
82to
83.Fa dst ,
84decoding any escape sequences along the way,
85and returns the number of characters placed into
86.Fa dst ,
87or \-1 if an
88invalid escape sequence was detected.
89The size of
90.Fa dst
91should be
92equal to the size of
93.Fa src
94(that is, no expansion takes place during decoding).
95.Fn strunvis
96terminates the destination string with a trailing NUL byte;
97.Fn strnunvis
98does so if
99.Fa size
100is larger than 0.
101.Pp
102The
103.Fn unvis
104function implements a state machine that can be used to decode an arbitrary
105stream of bytes.
106All state associated with the bytes being decoded is stored outside the
107.Fn unvis
108function (that is, a pointer to the state is passed in), so
109calls decoding different streams can be freely intermixed.
110To start decoding a stream of bytes, first initialize an integer
111to zero.
112Call
113.Fn unvis
114with each successive byte, along with a pointer
115to this integer, and a pointer to a destination character.
116.Sh RETURN VALUES
117The
118.Fn unvis
119function has several return codes that must be handled properly.
120They are:
121.Bl -tag -width UNVIS_VALIDPUSH
122.It Li \&0 (zero)
123Another character is necessary; nothing has been recognized yet.
124.It Dv UNVIS_VALID
125A valid character has been recognized and is available at the location
126pointed to by
127.Fa cp .
128.It Dv UNVIS_VALIDPUSH
129A valid character has been recognized and is available at the location
130pointed to by
131.Fa cp ;
132however, the character currently passed in should be passed in again.
133.It Dv UNVIS_NOCHAR
134A valid sequence was detected, but no character was produced.
135This return code is necessary to indicate a logical break between characters.
136.It Dv UNVIS_SYNBAD
137An invalid escape sequence was detected, or the decoder is in an
138unknown state.
139The decoder is placed into the starting state.
140.El
141.Pp
142When all bytes in the stream have been processed, call
143.Fn unvis
144one more time with
145.Fa flag
146set to
147.Dv UNVIS_END
148to extract any remaining character (the character passed in is ignored).
149.Pp
150The
151.Fn strunvis
152function returns the number of bytes written (not counting
153the trailing NUL byte) or \-1 if an error occurred.
154.Pp
155The
156.Fn strnunvis
157function returns the number of bytes (not counting the trailing NUL byte)
158that would be needed to fully convert the input string, or \-1 if an
159error occurred.
160.Sh EXAMPLES
161The following code fragment illustrates a proper use of
162.Fn unvis .
163.Bd -literal -offset indent
164int state = 0;
165char out;
166
167while ((ch = getchar()) != EOF) {
168again:
169	switch(unvis(&out, ch, &state, 0)) {
170	case 0:
171	case UNVIS_NOCHAR:
172		break;
173	case UNVIS_VALID:
174		(void) putchar(out);
175		break;
176	case UNVIS_VALIDPUSH:
177		(void) putchar(out);
178		goto again;
179	case UNVIS_SYNBAD:
180		(void)fprintf(stderr, "bad sequence!\en");
181		exit(1);
182	}
183}
184if (unvis(&out, (char)0, &state, UNVIS_END) == UNVIS_VALID)
185	(void) putchar(out);
186.Ed
187.Sh SEE ALSO
188.Xr unvis 1 ,
189.Xr vis 1 ,
190.Xr vis 3
191.Sh HISTORY
192The
193.Fn unvis
194function first appeared in
195.Bx 4.4 .
196