-
Notifications
You must be signed in to change notification settings - Fork 14
/
StringEscape.c
115 lines (112 loc) · 1.98 KB
/
StringEscape.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
#include <stddef.h>
#include <assert.h>
#include <stdlib.h>
//FIXME out gets silently truncated if outsize is too small
size_t escape(char* in, char* out, size_t outsize) {
size_t l = 0;
while(*in && l + 3 < outsize) {
switch(*in) {
case '\a': /* 0x07 */
case '\b': /* 0x08 */
case '\t': /* 0x09 */
case '\n': /* 0x0a */
case '\v': /* 0x0b */
case '\f': /* 0x0c */
case '\r': /* 0x0d */
case '\"': /* 0x22 */
case '\'': /* 0x27 */
case '\?': /* 0x3f */
case '\\': /* 0x5c */
*out++ = '\\';
l++;
switch(*in) {
case '\a': /* 0x07 */
*out = 'a'; break;
case '\b': /* 0x08 */
*out = 'b'; break;
case '\t': /* 0x09 */
*out = 't'; break;
case '\n': /* 0x0a */
*out = 'n'; break;
case '\v': /* 0x0b */
*out = 'v'; break;
case '\f': /* 0x0c */
*out = 'f'; break;
case '\r': /* 0x0d */
*out = 'r'; break;
case '\"': /* 0x22 */
*out = '\"'; break;
case '\'': /* 0x27 */
*out = '\''; break;
case '\?': /* 0x3f */
*out = '\?'; break;
case '\\': /* 0x5c */
*out = '\\'; break;
}
break;
default:
*out = *in;
}
in++;
out++;
l++;
}
*out = 0;
return l;
}
size_t unescape(char* in, char *out, size_t outsize) {
size_t l = 0;
while(*in && l + 1 < outsize) {
switch (*in) {
case '\\':
++in;
assert(*in);
switch(*in) {
case 'a':
*out = '\a';
break;
case 'b':
*out = '\b';
break;
case 't':
*out='\t';
break;
case 'n':
*out='\n';
break;
case 'v':
*out='\v';
break;
case 'f':
*out = '\f';
break;
case 'r':
*out='\r';
break;
case '"':
*out='"';
break;
case '\'':
*out = '\'';
break;
case '?':
*out = '\?';
break;
case '\\':
*out='\\';
break;
// FIXME add handling of hex and octal
default:
abort();
}
break;
default:
*out=*in;
}
in++;
out++;
l++;
}
*out = 0;
return l;
}