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.2 (Berkeley) 12/11/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 a 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 escape 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