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 |
|
|
} |