blob: be5ec55c35c31d7a1db61e0718317d9b80615265 (
plain)
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
|
#include <stddef.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 '\n':
*out++ = '\\';
l++;
*out = 'n';
break;
case '\r':
*out++ = '\\';
l++;
*out = 'r';
break;
case '\t':
*out++ = '\\';
l++;
*out = 't';
break;
case '\\':
*out++ = '\\';
l++;
*out = '\\';
break;
case '"':
*out++ = '\\';
l++;
*out = '"';
break;
case '\v':
*out++ = '\\';
l++;
*out = '\v';
break;
case '\?':
*out++ = '\\';
l++;
*out = '\?';
break;
case '\f':
*out++ = '\\';
l++;
*out = '\f';
break;
default:
*out = *in;
}
in++;
out++;
l++;
}
*out = 0;
return l;
}
#include <assert.h>
#include <stdlib.h>
size_t unescape(char* in, char *out, size_t outsize) {
size_t l = 0;
while(*in && l + 2 < outsize) {
switch (*in) {
case '\\':
++in;
assert(*in);
switch(*in) {
case 'n':
*out='\n';
break;
case 'r':
*out='\r';
break;
case 't':
*out='\t';
break;
case '\\':
*out='\\';
break;
case '"':
*out='"';
break;
case 'v':
*out='\v';
break;
case '\?':
*out = '\?';
break;
case 'f':
*out = '\f';
break;
case '\'':
*out = '\'';
break;
case 'b':
*out = '\b';
break;
// FIXME add handling of hex and octal
default:
abort();
}
break;
default:
*out=*in;
}
in++;
out++;
l++;
}
*out = 0;
return l;
}
|