p The .Fn unvis function is called with successive characters in .Ar c until a valid sequence is recognized, at which time the decoded character is available at the character pointed to by .Ar cp .
p The .Fn strunvis function decodes the characters pointed to by .Ar src into the buffer pointed to by .Ar dst . The .Fn strunvis function simply copies .Ar src to .Ar dst , decoding any escape sequences along the way, and returns the number of characters placed into .Ar dst , or -1 if an invalid escape sequence was detected. The size of .Ar dst should be equal to the size of .Ar src (that is, no expansion takes place during decoding).
p The .Fn unvis function implements a state machine that can be used to decode an arbitrary stream of bytes. All state associated with the bytes being decoded is stored outside the .Fn unvis function (that is, a pointer to the state is passed in), so calls decoding different streams can be freely intermixed. To start decoding a stream of bytes, first initialize an integer to zero. Call .Fn unvis with each successive byte, along with a pointer to this integer, and a pointer to a destination character. The .Fn unvis function has several return codes that must be handled properly. They are: l -tag -width UNVIS_VALIDPUSH t Li 0 (zero) Another character is necessary; nothing has been recognized yet. t Dv UNVIS_VALID A valid character has been recognized and is available at the location pointed to by cp. t Dv UNVIS_VALIDPUSH A valid character has been recognized and is available at the location pointed to by cp; however, the character currently passed in should be passed in again. t Dv UNVIS_NOCHAR A valid sequence was detected, but no character was produced. This return code is necessary to indicate a logical break between characters. t Dv UNVIS_SYNBAD An invalid escape sequence was detected, or the decoder is in an unknown state. The decoder is placed into the starting state. .El
p When all bytes in the stream have been processed, call .Fn unvis one more time with flag set to .Dv UNVIS_END to extract any remaining character (the character passed in is ignored).
p The following code fragment illustrates a proper use of .Fn unvis . d -literal -offset indent int state = 0; char out; while ((ch = getchar()) != EOF) { again: switch(unvis(&out, ch, &state, 0)) { case 0: case UNVIS_NOCHAR: break; case UNVIS_VALID: (void) putchar(out); break; case UNVIS_VALIDPUSH: (void) putchar(out); goto again; case UNVIS_SYNBAD: (void)fprintf(stderr, "bad sequence!\n"); exit(1); } } if (unvis(&out, (char)0, &state, UNVIS_END) == UNVIS_VALID) (void) putchar(out); .Ed .Sh SEE ALSO .Xr vis 1 , .Xr unvis 1 , .Xr vis 3 .Sh HISTORY The .Fn unvis function first appeared in x 4.4 .