GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/emit/escape.c Lines: 52 52 100.0 %
Date: 2020-09-22 13:02:15 Branches: 29 38 76.3 %

Line Branch Exec Source
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
715
char* escape_table(MemPool p) {
10
715
  char *escape = (char*)mp_calloc2(p, 256);
11
715
  escape['0'] = '0';
12
715
  escape['\''] = '\'';
13
715
  escape['"'] = '"';
14
715
  escape['\\'] = '\\';
15
715
  escape['a'] = (char)7; // audible bell
16
715
  escape['b'] = (char)8; // back space
17
715
  escape['f'] = (char)12; // form feed
18
715
  escape['n'] = (char)10; // new line
19
715
  escape['r'] = (char)13; // carriage return
20
715
  escape['t'] = (char)9; // horizontal tab
21
715
  escape['v'] = (char)11; // vertical tab
22
715
  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
}