xref: /original-bsd/lib/libc/gen/unvis.3 (revision 3705696b)
1.\" Copyright (c) 1989, 1991, 1993
2.\"	The Regents of the University of California.  All rights reserved.
3.\"
4.\" %sccs.include.redist.man%
5.\"
6.\"     @(#)unvis.3	8.1 (Berkeley) 06/09/93
7.\"
8.Dd
9.Dt UNVIS 3
10.Os
11.Sh NAME
12.Nm unvis ,
13.Nm strunvis
14.Nd decode a visual representation of characters
15.Sh SYNOPSIS
16.Fd #include <vis.h>
17.Ft int
18.Fn unvis "u_char *cp" "u_char c" "int *astate" "int flag"
19.Ft int
20.Fn strunvis "char *dst" "char *src"
21.Sh DESCRIPTION
22The
23.Fn unvis
24and
25.Fn strunvis
26functions
27are used to decode a visual representation of characters, as produced
28by the
29.Xr vis 3
30function, back into
31the original form.  Unvis is called with successive characters in
32.Ar c
33until a valid
34sequence is recognized, at which time the decoded character is
35available at the character pointed to by
36.Ar cp .
37Strunvis decodes the
38characters pointed to by
39.Ar src
40into the buffer pointed to by
41.Ar dst .
42.Pp
43The
44.Fn strunvis
45function
46simply copies
47.Ar src
48to
49.Ar dst ,
50decoding any escape sequences along the way,
51and returns the number of characters placed into
52.Ar dst ,
53or \-1 if an
54invalid escape sequence was detected.  The size of
55.Ar dst
56should be
57equal to the size of
58.Ar src
59(that is, no expansion takes place during
60decoding).
61.Pp
62The
63.Fn unvis
64function
65implements a state machine that can be used to decode an arbitrary
66stream of bytes.  All state associated with the bytes being decoded
67is stored outside the
68.Fn unvis
69function (that is, a pointer to the state is passed in), so
70calls decoding different streams can be freely intermixed.  To
71start decoding a stream of bytes, first initialize an integer
72to zero.  Call
73.Fn unvis
74with each successive byte, along with a pointer
75to this integer, and a pointer to an destination character.
76The
77.Xr unvis
78function
79has several return codes that must be handled properly.  They are:
80.Bl -tag -width UNVIS_VALIDPUSH
81.It Li \&0 (zero)
82Another character is necessary; nothing has been recognized yet.
83.It Dv  UNVIS_VALID
84A valid character has been recognized and is available at the location
85pointed to by cp.
86.It Dv  UNVIS_VALIDPUSH
87A valid character has been recognized and is available at the location
88pointed to by cp; however, the character currently passed in should
89be passed in again.
90.It Dv  UNVIS_NOCHAR
91A valid sequence was detected, but no character was produced.  This
92return code is necessary to indicate a logical break between characters.
93.It Dv  UNVIS_SYNBAD
94An invalid esacpe sequence was detected, or the decoder is in an
95unknown state.  The decoder is placed into the starting state.
96.El
97.Pp
98When all bytes in the stream have been processed, call
99.Fn unvis
100one more time with flag set to
101.Dv UNVIS_END
102to extract any remaining character (the character passed in is ignored).
103.Pp
104The following code fragment illustrates a proper use of
105.Fn unvis .
106.Bd -literal -offset indent
107int state = 0;
108char out;
109
110while ((ch = getchar()) != EOF) {
111again:
112	switch(unvis(&out, ch, &state, 0)) {
113	case 0:
114	case UNVIS_NOCHAR:
115		break;
116	case UNVIS_VALID:
117		(void) putchar(out);
118		break;
119	case UNVIS_VALIDPUSH:
120		(void) putchar(out);
121		goto again;
122	case UNVIS_SYNBAD:
123		(void)fprintf(stderr, "bad sequence!\n");
124	exit(1);
125	}
126}
127if (unvis(&out, (char)0, &state, UNVIS_END) == UNVIS_VALID)
128	(void) putchar(out);
129.Ed
130.Sh SEE ALSO
131.Xr vis 1
132.Sh HISTORY
133The
134.Nm unvis
135function
136first appeared in 4.4BSD.
137