GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/parse/did_you_mean.c Lines: 42 42 100.0 %
Date: 2020-09-12 17:36:58 Branches: 33 38 86.8 %

Line Branch Exec Source
1
#include "gwion_util.h"
2
#include "gwion_ast.h"
3
#include "gwion_env.h"
4
5
#ifdef min
6
#undef min
7
#endif
8
9
#define MAX_DISTANCE 2
10
#define min2(a, b) ((a) < (b) ? (a) : (b))
11
#define min(a, b, c) (min2(min2((a), (b)), (c)))
12
13
770
static m_bool wagner_fisher(const char *s, const char* t) {
14
770
  const size_t m = strlen(s);
15
770
  const size_t n = strlen(t);
16
770
  unsigned int d[m][n];
17
  uint i, j;
18
3481
  for(i = 0; i < m; ++i)
19
2711
    d[i][0] = i;
20
6233
  for(i = 0; i < n; ++i)
21
5463
    d[0][i] = i;
22
3281
  for(j = 1; j < n; ++j) {
23
7552
    for(i = 1; i < m; ++i) {
24
5041
      if(s[i] == t[j])
25
361
        d[i][j] = d[i-1][j-1];
26
      else
27
4680
        d[i][j] = min(d[i-1][j] + 1, d[i][j-1] + 1, d[i-1][j-1] + 1);
28
5041
      if(d[i][j] > MAX_DISTANCE + 1)
29
418
        return 0;
30
    }
31
  }
32

352
  return (i && j && d[m-1][n-1] < MAX_DISTANCE);
33
}
34
35
58
ANN static void ressembles(const Vector v, const Nspc nspc, const char* name) {
36
58
  struct scope_iter iter = { nspc->info->value, 0, 0 };
37
  Value value;
38
890
  while(scope_iter(&iter, &value) > 0) {
39
774
    if(!strcmp(name, value->name))
40
4
      continue;
41
770
    if(wagner_fisher(name, value->name))
42
21
      vector_add(v, (vtype)value->name);
43
  }
44
58
}
45
46
#define MAX_NAME_LEN 16
47
#define CHECK_LEN(name) if(strlen(name) > MAX_NAME_LEN) return;
48
49
#undef did_you_mean_nspc
50
11
ANN void did_you_mean_nspc(Nspc nspc, const char* name) {
51
11
  CHECK_LEN(name)
52
  struct Vector_ v;
53
11
  vector_init(&v);
54
44
  do ressembles(&v, nspc, name);
55
44
  while((nspc = nspc->parent));
56
29
  for(m_uint i = 0; i < vector_size(&v); ++i)
57
18
    gw_err(_("  (did you mean '%s'?)\n"), (m_str)vector_at(&v, i));
58
11
  vector_release(&v);
59
}
60
61
#undef did_you_mean_type
62
10
ANN void did_you_mean_type(Type type, const char* name) {
63
10
  CHECK_LEN(name)
64
10
  Type t = type;
65
  struct Vector_ v;
66
10
  vector_init(&v);
67
14
  do ressembles(&v, t->nspc, name);
68

14
  while((t = t->e->parent) && t->nspc);
69
13
  for(m_uint i = 0; i < vector_size(&v); ++i)
70
3
    gw_err(_("  (did you mean '%s'?)\n"), (m_str)vector_at(&v, i));
71
10
  did_you_mean_nspc(type->nspc, name);
72
10
  vector_release(&v);
73
}