| 1 | .\" Copyright (c) 1989, 1991 The Regents of the University of California. |
| 2 | .\" All rights reserved. |
| 3 | .\" |
| 4 | .\" %sccs.include.redist.man% |
| 5 | .\" |
| 6 | .\" @(#)unvis.3 1.3 (Berkeley) %G% |
| 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 |
| 22 | The |
| 23 | .Fn unvis |
| 24 | and |
| 25 | .Fn strunvis |
| 26 | functions |
| 27 | are used to decode a visual representation of characters, as produced |
| 28 | by the |
| 29 | .Xr vis 3 |
| 30 | function, back into |
| 31 | the original form. Unvis is called with successive characters in |
| 32 | .Ar c |
| 33 | until a valid |
| 34 | sequence is recognized, at which time the decoded character is |
| 35 | available at the character pointed to by |
| 36 | .Ar cp . |
| 37 | Strunvis decodes the |
| 38 | characters pointed to by |
| 39 | .Ar src |
| 40 | into the buffer pointed to by |
| 41 | .Ar dst . |
| 42 | .Pp |
| 43 | The |
| 44 | .Fn strunvis |
| 45 | function |
| 46 | simply copies |
| 47 | .Ar src |
| 48 | to |
| 49 | .Ar dst , |
| 50 | decoding any escape sequences along the way, |
| 51 | and returns the number of characters placed into |
| 52 | .Ar dst , |
| 53 | or \-1 if an |
| 54 | invalid escape sequence was detected. The size of |
| 55 | .Ar dst |
| 56 | should be |
| 57 | equal to the size of |
| 58 | .Ar src |
| 59 | (that is, no expansion takes place during |
| 60 | decoding). |
| 61 | .Pp |
| 62 | The |
| 63 | .Fn unvis |
| 64 | function |
| 65 | implements a state machine that can be used to decode an arbitrary |
| 66 | stream of bytes. All state associated with the bytes being decoded |
| 67 | is stored outside the |
| 68 | .Fn unvis |
| 69 | function (that is, a pointer to the state is passed in), so |
| 70 | calls decoding different streams can be freely intermixed. To |
| 71 | start decoding a stream of bytes, first initialize an integer |
| 72 | to zero. Call |
| 73 | .Fn unvis |
| 74 | with each successive byte, along with a pointer |
| 75 | to this integer, and a pointer to an destination character. |
| 76 | The |
| 77 | .Xr unvis |
| 78 | function |
| 79 | has several return codes that must be handled properly. They are: |
| 80 | .Bl -tag -width UNVIS_VALIDPUSH |
| 81 | .It Li \&0 (zero) |
| 82 | Another character is necessary; nothing has been recognized yet. |
| 83 | .It Dv UNVIS_VALID |
| 84 | A valid character has been recognized and is available at the location |
| 85 | pointed to by cp. |
| 86 | .It Dv UNVIS_VALIDPUSH |
| 87 | A valid character has been recognized and is available at the location |
| 88 | pointed to by cp; however, the character currently passed in should |
| 89 | be passed in again. |
| 90 | .It Dv UNVIS_NOCHAR |
| 91 | A valid sequence was detected, but no character was produced. This |
| 92 | return code is necessary to indicate a logical break between characters. |
| 93 | .It Dv UNVIS_SYNBAD |
| 94 | An invalid esacpe sequence was detected, or the decoder is in an |
| 95 | unknown state. The decoder is placed into the starting state. |
| 96 | .El |
| 97 | .Pp |
| 98 | When all bytes in the stream have been processed, call |
| 99 | .Fn unvis |
| 100 | one more time with flag set to |
| 101 | .Dv UNVIS_END |
| 102 | to extract any remaining character (the character passed in is ignored). |
| 103 | .Pp |
| 104 | The following code fragment illustrates a proper use of |
| 105 | .Fn unvis . |
| 106 | .Bd -literal -offset indent |
| 107 | int state = 0; |
| 108 | char out; |
| 109 | |
| 110 | while ((ch = getchar()) != EOF) { |
| 111 | again: |
| 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 | } |
| 127 | if (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 |
| 133 | The |
| 134 | .Fn unvis |
| 135 | function is |
| 136 | .Ud . |