Postfix3.3.1
unescape.c
[詳解]
1 /*++
2 /* NAME
3 /* unescape 3
4 /* SUMMARY
5 /* translate C-like escape sequences
6 /* SYNOPSIS
7 /* #include <stringops.h>
8 /*
9 /* VSTRING *unescape(result, input)
10 /* VSTRING *result;
11 /* const char *input;
12 /*
13 /* VSTRING *escape(result, input, len)
14 /* VSTRING *result;
15 /* const char *input;
16 /* ssize_t len;
17 /* DESCRIPTION
18 /* unescape() translates C-like escape sequences in the null-terminated
19 /* string \fIinput\fR and places the result in \fIresult\fR. The result
20 /* is null-terminated, and is the function result value.
21 /*
22 /* escape() does the reverse transformation.
23 /*
24 /* Escape sequences and their translations:
25 /* .IP \ea
26 /* Bell character.
27 /* .IP \eb
28 /* Backspace character.
29 /* .IP \ef
30 /* formfeed character.
31 /* .IP \en
32 /* newline character
33 /* .IP \er
34 /* Carriage-return character.
35 /* .IP \et
36 /* Horizontal tab character.
37 /* .IP \ev
38 /* Vertical tab character.
39 /* .IP \e\e
40 /* Backslash character.
41 /* .IP \e\fInum\fR
42 /* 8-bit character whose ASCII value is the 1..3 digit
43 /* octal number \fInum\fR.
44 /* .IP \e\fIother\fR
45 /* The backslash character is discarded.
46 /* LICENSE
47 /* .ad
48 /* .fi
49 /* The Secure Mailer license must be distributed with this software.
50 /* AUTHOR(S)
51 /* Wietse Venema
52 /* IBM T.J. Watson Research
53 /* P.O. Box 704
54 /* Yorktown Heights, NY 10598, USA
55 /*--*/
56 
57 /* System library. */
58 
59 #include <sys_defs.h>
60 #include <ctype.h>
61 
62 /* Utility library. */
63 
64 #include <vstring.h>
65 #include <stringops.h>
66 
67 /* unescape - process escape sequences */
68 
69 VSTRING *unescape(VSTRING *result, const char *data)
70 {
71  int ch;
72  int oval;
73  int i;
74 
75 #define UCHAR(cp) ((unsigned char *) (cp))
76 #define ISOCTAL(ch) (ISDIGIT(ch) && (ch) != '8' && (ch) != '9')
77 
78  VSTRING_RESET(result);
79 
80  while ((ch = *UCHAR(data++)) != 0) {
81  if (ch == '\\') {
82  if ((ch = *UCHAR(data++)) == 0)
83  break;
84  switch (ch) {
85  case 'a': /* \a -> audible bell */
86  ch = '\a';
87  break;
88  case 'b': /* \b -> backspace */
89  ch = '\b';
90  break;
91  case 'f': /* \f -> formfeed */
92  ch = '\f';
93  break;
94  case 'n': /* \n -> newline */
95  ch = '\n';
96  break;
97  case 'r': /* \r -> carriagereturn */
98  ch = '\r';
99  break;
100  case 't': /* \t -> horizontal tab */
101  ch = '\t';
102  break;
103  case 'v': /* \v -> vertical tab */
104  ch = '\v';
105  break;
106  case '0': /* \nnn -> ASCII value */
107  case '1':
108  case '2':
109  case '3':
110  case '4':
111  case '5':
112  case '6':
113  case '7':
114  for (oval = ch - '0', i = 0;
115  i < 2 && (ch = *UCHAR(data)) != 0 && ISOCTAL(ch);
116  i++, data++) {
117  oval = (oval << 3) | (ch - '0');
118  }
119  ch = oval;
120  break;
121  default: /* \any -> any */
122  break;
123  }
124  }
125  VSTRING_ADDCH(result, ch);
126  }
127  VSTRING_TERMINATE(result);
128  return (result);
129 }
130 
131 /* escape - reverse transformation */
132 
133 VSTRING *escape(VSTRING *result, const char *data, ssize_t len)
134 {
135  int ch;
136 
137  VSTRING_RESET(result);
138  while (len-- > 0) {
139  ch = *UCHAR(data++);
140  if (ISASCII(ch)) {
141  if (ISPRINT(ch)) {
142  if (ch == '\\')
143  VSTRING_ADDCH(result, ch);
144  VSTRING_ADDCH(result, ch);
145  continue;
146  } else if (ch == '\a') { /* \a -> audible bell */
147  vstring_strcat(result, "\\a");
148  continue;
149  } else if (ch == '\b') { /* \b -> backspace */
150  vstring_strcat(result, "\\b");
151  continue;
152  } else if (ch == '\f') { /* \f -> formfeed */
153  vstring_strcat(result, "\\f");
154  continue;
155  } else if (ch == '\n') { /* \n -> newline */
156  vstring_strcat(result, "\\n");
157  continue;
158  } else if (ch == '\r') { /* \r -> carriagereturn */
159  vstring_strcat(result, "\\r");
160  continue;
161  } else if (ch == '\t') { /* \t -> horizontal tab */
162  vstring_strcat(result, "\\t");
163  continue;
164  } else if (ch == '\v') { /* \v -> vertical tab */
165  vstring_strcat(result, "\\v");
166  continue;
167  }
168  }
169  vstring_sprintf_append(result, "\\%03o", ch);
170  }
171  VSTRING_TERMINATE(result);
172  return (result);
173 }
174 
175 #ifdef TEST
176 
177 #include <stdlib.h>
178 #include <string.h>
179 #include <msg.h>
180 #include <vstring_vstream.h>
181 
182 int main(int argc, char **argv)
183 {
184  VSTRING *in = vstring_alloc(10);
185  VSTRING *out = vstring_alloc(10);
186  int un_escape = 1;
187 
188  if (argc > 2 || (argc > 1 && (un_escape = strcmp(argv[1], "-e"))) != 0)
189  msg_fatal("usage: %s [-e (escape)]", argv[0]);
190 
191  if (un_escape) {
192  while (vstring_fgets_nonl(in, VSTREAM_IN)) {
193  unescape(out, vstring_str(in));
195  VSTREAM_PUTC('\n', VSTREAM_OUT);
196  }
197  } else {
198  while (vstring_fgets_nonl(in, VSTREAM_IN)) {
199  escape(out, vstring_str(in), VSTRING_LEN(in));
201  VSTREAM_PUTC('\n', VSTREAM_OUT);
202  }
203  }
205  exit(0);
206 }
207 
208 #endif
#define vstring_fgets_nonl(s, p)
#define vstring_str(vp)
Definition: vstring.h:71
#define VSTREAM_OUT
Definition: vstream.h:67
int main(int argc, char **argv)
Definition: anvil.c:1010
#define ISASCII(c)
Definition: sys_defs.h:1743
#define VSTREAM_IN
Definition: vstream.h:66
VSTRING * unescape(VSTRING *result, const char *data)
Definition: unescape.c:69
#define VSTRING_LEN(vp)
Definition: vstring.h:72
#define VSTRING_TERMINATE(vp)
Definition: vstring.h:74
#define VSTRING_ADDCH(vp, ch)
Definition: vstring.h:81
VSTRING * vstring_sprintf_append(VSTRING *vp, const char *format,...)
Definition: vstring.c:624
#define ISOCTAL(ch)
#define VSTRING_RESET(vp)
Definition: vstring.h:77
VSTRING * vstring_alloc(ssize_t len)
Definition: vstring.c:353
NORETURN msg_fatal(const char *fmt,...)
Definition: msg.c:249
int vstream_fflush(VSTREAM *stream)
Definition: vstream.c:1257
VSTRING * escape(VSTRING *result, const char *data, ssize_t len)
Definition: unescape.c:133
#define vstream_fwrite(v, b, n)
Definition: vstream.h:105
#define ISPRINT(c)
Definition: sys_defs.h:1751
#define UCHAR(cp)
#define VSTREAM_PUTC(ch, vp)
Definition: vstream.h:107
VSTRING * vstring_strcat(VSTRING *vp, const char *src)
Definition: vstring.c:459