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 | 1158 | static m_bool wagner_fisher(const char *s, const char *t) { | |
14 | 1158 | const size_t m = strlen(s); | |
15 | 1158 | const size_t n = strlen(t); | |
16 | 1158 | unsigned int d[m][n]; | |
17 | uint i, j; | ||
18 |
2/2✓ Branch 0 taken 3917 times.
✓ Branch 1 taken 1158 times.
|
5075 | for (i = 0; i < m; ++i) d[i][0] = i; |
19 |
2/2✓ Branch 0 taken 9927 times.
✓ Branch 1 taken 1158 times.
|
11085 | for (i = 0; i < n; ++i) d[0][i] = i; |
20 |
2/2✓ Branch 0 taken 5384 times.
✓ Branch 1 taken 646 times.
|
6030 | for (j = 1; j < n; ++j) { |
21 |
2/2✓ Branch 0 taken 4605 times.
✓ Branch 1 taken 4872 times.
|
9477 | for (i = 1; i < m; ++i) { |
22 |
2/2✓ Branch 0 taken 271 times.
✓ Branch 1 taken 4334 times.
|
4605 | if (s[i] == t[j]) |
23 | 271 | d[i][j] = d[i - 1][j - 1]; | |
24 | else | ||
25 | 4334 | d[i][j] = min(d[i - 1][j] + 1, d[i][j - 1] + 1, d[i - 1][j - 1] + 1); | |
26 |
2/2✓ Branch 0 taken 512 times.
✓ Branch 1 taken 4093 times.
|
4605 | if (d[i][j] > MAX_DISTANCE + 1) return 0; |
27 | } | ||
28 | } | ||
29 |
4/6✓ Branch 0 taken 646 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 646 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 35 times.
✓ Branch 5 taken 611 times.
|
646 | return (i && j && d[m - 1][n - 1] < MAX_DISTANCE); |
30 | } | ||
31 | |||
32 | 73 | ANN static void ressembles(const Scope scope, const char *name, | |
33 | bool *const done) { | ||
34 | 73 | struct scope_iter iter = { scope, 0, 0 }; | |
35 | Value value; | ||
36 |
2/2✓ Branch 1 taken 1158 times.
✓ Branch 2 taken 73 times.
|
1231 | while (scope_iter(&iter, &value) > 0) { |
37 |
2/2✓ Branch 1 taken 35 times.
✓ Branch 2 taken 1123 times.
|
1158 | if (wagner_fisher(name, value->name)) { |
38 |
2/2✓ Branch 0 taken 9 times.
✓ Branch 1 taken 26 times.
|
35 | if (!*done) { |
39 | 9 | *done = true; | |
40 | 9 | gw_err("{-/}did you mean{0}:\n"); | |
41 | } | ||
42 |
2/2✓ Branch 1 taken 20 times.
✓ Branch 2 taken 15 times.
|
35 | if (!vflag(value, vflag_builtin)) defined_here(value); |
43 | } | ||
44 | } | ||
45 | 73 | } | |
46 | |||
47 | ✗ | ANN static void trait_ressembles(const Scope scope, const char *name, | |
48 | bool *const done) { | ||
49 | ✗ | struct scope_iter iter = { scope, 0, 0 }; | |
50 | Trait trait; | ||
51 | ✗ | while (scope_iter(&iter, &trait) > 0) { | |
52 | ✗ | if (wagner_fisher(name, trait->name)) { | |
53 | ✗ | if (!*done) { | |
54 | ✗ | *done = true; | |
55 | ✗ | gw_err("{-/}did you mean{0}:\n"); | |
56 | } | ||
57 | ✗ | if (trait->filename) // TODO: check why is that from check | |
58 | ✗ | gwerr_secondary(_("defined here"), trait->filename, trait->loc); | |
59 | } | ||
60 | } | ||
61 | } | ||
62 | |||
63 | #define MAX_NAME_LEN 16 | ||
64 | #define CHECK_LEN(name) \ | ||
65 | if (strlen(name) > MAX_NAME_LEN) return; | ||
66 | |||
67 | #undef did_you_mean_nspc | ||
68 | 13 | ANN void did_you_mean_nspc(Nspc nspc, const char *name) { | |
69 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
|
13 | CHECK_LEN(name) |
70 | 13 | bool done = false; | |
71 | 56 | do ressembles(nspc->info->value, name, &done); | |
72 |
2/2✓ Branch 0 taken 43 times.
✓ Branch 1 taken 13 times.
|
56 | while ((nspc = nspc->parent)); |
73 | } | ||
74 | |||
75 | #undef did_you_mean_type | ||
76 | 7 | ANN void did_you_mean_type(Type type, const char *name) { | |
77 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 7 times.
|
7 | CHECK_LEN(name) |
78 | 7 | bool done = false; | |
79 | 17 | do ressembles(type->nspc->info->value, name, &done); | |
80 |
3/4✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 10 times.
✓ Branch 3 taken 7 times.
|
17 | while ((type = type->info->parent) && type->nspc); |
81 | } | ||
82 | |||
83 | ✗ | ANN void did_you_mean_trait(Nspc nspc, const char *name) { | |
84 | ✗ | CHECK_LEN(name) | |
85 | ✗ | bool done = false; | |
86 | ✗ | do trait_ressembles(nspc->info->trait, name, &done); | |
87 | ✗ | while ((nspc = nspc->parent)); | |
88 | } | ||
89 |