1 |
|
|
#include "gwion_util.h" |
2 |
|
|
#include "gwion_ast.h" |
3 |
|
|
#include "gwion_env.h" |
4 |
|
|
#include "vm.h" |
5 |
|
|
#include "instr.h" |
6 |
|
|
#include "emit.h" |
7 |
|
|
#include "escape.h" |
8 |
|
|
|
9 |
|
716 |
char* escape_table(MemPool p) { |
10 |
|
716 |
char *escape = (char*)mp_calloc2(p, 256); |
11 |
|
716 |
escape['0'] = '0'; |
12 |
|
716 |
escape['\''] = '\''; |
13 |
|
716 |
escape['"'] = '"'; |
14 |
|
716 |
escape['\\'] = '\\'; |
15 |
|
716 |
escape['a'] = (char)7; // audible bell |
16 |
|
716 |
escape['b'] = (char)8; // back space |
17 |
|
716 |
escape['f'] = (char)12; // form feed |
18 |
|
716 |
escape['n'] = (char)10; // new line |
19 |
|
716 |
escape['r'] = (char)13; // carriage return |
20 |
|
716 |
escape['t'] = (char)9; // horizontal tab |
21 |
|
716 |
escape['v'] = (char)11; // vertical tab |
22 |
|
716 |
return escape; |
23 |
|
|
} |
24 |
|
|
|
25 |
|
21 |
static int get_escape(const Emitter emit, const char c, const loc_t pos) { |
26 |
✓✓ |
21 |
if(emit->info->escape[(int)c]) |
27 |
|
20 |
return emit->info->escape[(int)c]; |
28 |
|
1 |
env_err(emit->env, pos, _("unrecognized escape sequence '\\%c'"), c); |
29 |
|
1 |
return GW_ERROR; |
30 |
|
|
} |
31 |
|
|
|
32 |
|
299 |
m_bool escape_str(const Emitter emit, const m_str base, const loc_t pos) { |
33 |
|
299 |
unsigned char* str_lit = (unsigned char*)base; |
34 |
|
299 |
m_str str = base; |
35 |
✓✓ |
3793 |
while(*str_lit) { |
36 |
✓✓ |
3197 |
if(*str_lit == '\\') { |
37 |
|
17 |
++str_lit; |
38 |
|
17 |
const unsigned char c = *(str_lit); |
39 |
|
17 |
const unsigned char c2 = *(str_lit+1); |
40 |
✓✓✓✓
|
17 |
if(c >= '0' && c <= '7') { |
41 |
✓✗✓✗ ✓✓ |
9 |
if(c == '0' && (c2 < '0' || c2 > '7')) |
42 |
|
2 |
*str++ = '\0'; |
43 |
|
|
else { |
44 |
|
3 |
const unsigned char c3 = *(str_lit+2); |
45 |
✓✗✓✗ ✓✗✓✓
|
3 |
if(c2 >= '0' && c2 <= '7' && c3 >= '0' && c3 <= '7') { |
46 |
|
2 |
*str++ = (char)((c-'0') * 64 + (c2-'0') * 8 + (c3-'0')); |
47 |
|
2 |
str_lit += 2; |
48 |
|
|
} else { |
49 |
|
1 |
env_err(emit->env, pos, _("malformed octal escape sequence '\\%c%c%c'"), c, c2, c3); |
50 |
|
1 |
return GW_ERROR; |
51 |
|
|
} |
52 |
|
|
} |
53 |
✓✓ |
12 |
} else if(c == 'x') { |
54 |
|
2 |
++str_lit; |
55 |
|
2 |
const unsigned char c1 = *(str_lit); |
56 |
|
2 |
const unsigned char c3 = *(str_lit+1); |
57 |
✓✗✓✓ ✓✗✓✗
|
2 |
if(c1 >= '0' && c1 <= 'F' && c3 >= '0' && c3 <= 'F') { |
58 |
|
1 |
*str++ = (char)((c1-'0') * 16 + (c3-'0')); |
59 |
|
1 |
++str_lit; |
60 |
|
|
} else { |
61 |
|
1 |
env_err(emit->env, pos, _("malformed hex escape sequence '\\%c%c'"), c1, c3); |
62 |
|
1 |
return GW_ERROR; |
63 |
|
|
} |
64 |
|
|
} else |
65 |
✗✓ |
10 |
CHECK_BB((*str++ = (char)get_escape(emit, (char)c, pos))) |
66 |
|
|
} |
67 |
|
|
else |
68 |
|
3180 |
*str++ = (char)*str_lit; |
69 |
|
3195 |
++str_lit; |
70 |
|
|
} |
71 |
|
297 |
*str = '\0'; |
72 |
|
297 |
return GW_OK; |
73 |
|
|
} |
74 |
|
|
|
75 |
|
15 |
ANN char str2char(const Emitter emit, const m_str c, const loc_t pos) { |
76 |
✓✓ |
15 |
return c[0] != '\\' ? c[0] : get_escape(emit, c[1], pos); |
77 |
|
|
} |