7 /* translate C-like escape sequences
9 /* #include <stringops.h>
11 /* VSTRING *unescape(result, input)
15 /* VSTRING *escape(result, input, len)
20 /* unescape() translates C-like escape sequences in the null-terminated
21 /* string \fIinput\fR and places the result in \fIresult\fR. The result
22 /* is null-terminated, and is the function result value.
24 /* escape() does the reverse transformation.
26 /* Escape sequences and their translations:
30 /* Backspace character.
32 /* formfeed character.
36 /* Carriage-return character.
38 /* Horizontal tab character.
40 /* Vertical tab character.
42 /* Backslash character.
44 /* 8-bit character whose ASCII value is the 1..3 digit
45 /* octal number \fInum\fR.
47 /* The backslash character is discarded.
51 /* The Secure Mailer license must be distributed with this software.
54 /* IBM T.J. Watson Research
56 /* Yorktown Heights, NY 10598, USA
64 /* Utility library. */
67 #include <stringops.h>
69 /* unescape - process escape sequences */
71 VSTRING
*unescape(VSTRING
*result
, const char *data
)
77 #define UCHAR(cp) ((unsigned char *) (cp))
78 #define ISOCTAL(ch) (ISDIGIT(ch) && (ch) != '8' && (ch) != '9')
80 VSTRING_RESET(result
);
82 while ((ch
= *UCHAR(data
++)) != 0) {
84 if ((ch
= *UCHAR(data
++)) == 0)
87 case 'a': /* \a -> audible bell */
90 case 'b': /* \b -> backspace */
93 case 'f': /* \f -> formfeed */
96 case 'n': /* \n -> newline */
99 case 'r': /* \r -> carriagereturn */
102 case 't': /* \t -> horizontal tab */
105 case 'v': /* \v -> vertical tab */
108 case '0': /* \nnn -> ASCII value */
116 for (oval
= ch
- '0', i
= 0;
117 i
< 2 && (ch
= *UCHAR(data
)) != 0 && ISOCTAL(ch
);
119 oval
= (oval
<< 3) | (ch
- '0');
123 default: /* \any -> any */
127 VSTRING_ADDCH(result
, ch
);
129 VSTRING_TERMINATE(result
);
133 /* escape - reverse transformation */
135 VSTRING
*escape(VSTRING
*result
, const char *data
, ssize_t len
)
139 VSTRING_RESET(result
);
145 VSTRING_ADDCH(result
, ch
);
146 VSTRING_ADDCH(result
, ch
);
148 } else if (ch
== '\a') { /* \a -> audible bell */
149 vstring_strcat(result
, "\\a");
151 } else if (ch
== '\b') { /* \b -> backspace */
152 vstring_strcat(result
, "\\b");
154 } else if (ch
== '\f') { /* \f -> formfeed */
155 vstring_strcat(result
, "\\f");
157 } else if (ch
== '\n') { /* \n -> newline */
158 vstring_strcat(result
, "\\n");
160 } else if (ch
== '\r') { /* \r -> carriagereturn */
161 vstring_strcat(result
, "\\r");
163 } else if (ch
== '\t') { /* \t -> horizontal tab */
164 vstring_strcat(result
, "\\t");
166 } else if (ch
== '\v') { /* \v -> vertical tab */
167 vstring_strcat(result
, "\\v");
171 if (ISDIGIT(*UCHAR(data
)))
172 vstring_sprintf_append(result
, "\\%03d", ch
);
174 vstring_sprintf_append(result
, "\\%d", ch
);
176 VSTRING_TERMINATE(result
);
185 #include <vstring_vstream.h>
187 int main(int argc
, char **argv
)
189 VSTRING
*in
= vstring_alloc(10);
190 VSTRING
*out
= vstring_alloc(10);
193 if (argc
> 2 || (argc
> 1 && (un_escape
= strcmp(argv
[1], "-e"))) != 0)
194 msg_fatal("usage: %s [-e (escape)]", argv
[0]);
197 while (vstring_fgets_nonl(in
, VSTREAM_IN
)) {
198 unescape(out
, vstring_str(in
));
199 vstream_fwrite(VSTREAM_OUT
, vstring_str(out
), VSTRING_LEN(out
));
202 while (vstring_fgets(in
, VSTREAM_IN
)) {
203 escape(out
, vstring_str(in
), VSTRING_LEN(in
));
204 vstream_fwrite(VSTREAM_OUT
, vstring_str(out
), VSTRING_LEN(out
));
207 vstream_fflush(VSTREAM_OUT
);