GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/parse/did_you_mean.c Lines: 39 41 95.1 %
Date: 2020-10-03 10:30:04 Branches: 30 40 75.0 %

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
79
static m_bool wagner_fisher(const char *s, const char* t) {
14
79
  const size_t m = strlen(s);
15
79
  const size_t n = strlen(t);
16
79
  unsigned int d[m][n];
17
  uint i, j;
18
742
  for(i = 0; i < m; ++i)
19
663
    d[i][0] = i;
20
695
  for(i = 0; i < n; ++i)
21
616
    d[0][i] = i;
22
150
  for(j = 1; j < n; ++j) {
23
558
    for(i = 1; i < m; ++i) {
24
487
      if(s[i] == t[j])
25
51
        d[i][j] = d[i-1][j-1];
26
      else
27
436
        d[i][j] = min(d[i-1][j] + 1, d[i][j-1] + 1, d[i-1][j-1] + 1);
28
487
      if(d[i][j] > MAX_DISTANCE + 1)
29
78
        return 0;
30
    }
31
  }
32

1
  return (i && j && d[m-1][n-1] < MAX_DISTANCE);
33
}
34
35
7
ANN static void ressembles(const Vector v, const Nspc nspc, const char* name) {
36
7
  struct scope_iter iter = { nspc->info->value, 0, 0 };
37
  Value value;
38
93
  while(scope_iter(&iter, &value) > 0) {
39

79
    if(vector_find(v, (vtype)value->name) > 0 &&!strcmp(name, value->name))
40
      continue;
41
79
    if(wagner_fisher(name, value->name))
42
1
      vector_add(v, (vtype)value->name);
43
  }
44
7
}
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
1
ANN void did_you_mean_nspc(Nspc nspc, const char* name) {
51
1
  CHECK_LEN(name)
52
  struct Vector_ v;
53
1
  vector_init(&v);
54
3
  do ressembles(&v, nspc, name);
55
3
  while((nspc = nspc->parent));
56
1
  for(m_uint i = 0; i < vector_size(&v); ++i)
57
    gw_err(_("  (did you mean '%s'?)\n"), (m_str)vector_at(&v, i));
58
1
  vector_release(&v);
59
}
60
61
#undef did_you_mean_type
62
3
ANN void did_you_mean_type(Type type, const char* name) {
63
3
  CHECK_LEN(name)
64
3
  Type t = type;
65
  struct Vector_ v;
66
3
  vector_init(&v);
67
4
  do ressembles(&v, t->nspc, name);
68

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