Line | Branch | Exec | Source |
---|---|---|---|
1 | #include <stdlib.h> | ||
2 | #include <string.h> | ||
3 | #include "compiler.h" | ||
4 | #include "command/serialize.h" | ||
5 | #include "error.h" | ||
6 | #include "regexp.h" | ||
7 | #include "util/array.h" | ||
8 | #include "util/debug.h" | ||
9 | #include "util/intern.h" | ||
10 | #include "util/str-util.h" | ||
11 | #include "util/xmalloc.h" | ||
12 | |||
13 | static const char capture_names[][8] = { | ||
14 | [ERRFMT_FILE] = "file", | ||
15 | [ERRFMT_LINE] = "line", | ||
16 | [ERRFMT_COLUMN] = "column", | ||
17 | [ERRFMT_MESSAGE] = "message" | ||
18 | }; | ||
19 | |||
20 | 18 | UNITTEST { | |
21 | 18 | CHECK_STRING_ARRAY(capture_names); | |
22 | 18 | } | |
23 | |||
24 | 162 | static Compiler *find_or_add_compiler(HashMap *compilers, const char *name) | |
25 | { | ||
26 | 162 | Compiler *c = find_compiler(compilers, name); | |
27 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 144 times.
|
162 | return c ? c : hashmap_insert(compilers, xstrdup(name), xnew0(Compiler, 1)); |
28 | } | ||
29 | |||
30 | 163 | Compiler *find_compiler(const HashMap *compilers, const char *name) | |
31 | { | ||
32 | 163 | return hashmap_get(compilers, name); | |
33 | } | ||
34 | |||
35 | 164 | bool add_error_fmt ( | |
36 | HashMap *compilers, | ||
37 | const char *name, | ||
38 | bool ignore, | ||
39 | const char *format, | ||
40 | char **desc | ||
41 | ) { | ||
42 | 164 | int8_t idx[] = { | |
43 | [ERRFMT_FILE] = -1, | ||
44 | [ERRFMT_LINE] = -1, | ||
45 | [ERRFMT_COLUMN] = -1, | ||
46 | [ERRFMT_MESSAGE] = 0, | ||
47 | }; | ||
48 | |||
49 | 164 | size_t max_idx = 0; | |
50 |
2/2✓ Branch 0 taken 195 times.
✓ Branch 1 taken 163 times.
|
358 | for (size_t i = 0, j = 0, n = ARRAYLEN(capture_names); desc[i]; i++) { |
51 | 195 | BUG_ON(i >= ERRORFMT_CAPTURE_MAX); | |
52 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 195 times.
|
195 | if (streq(desc[i], "_")) { |
53 | ✗ | continue; | |
54 | } | ||
55 |
2/2✓ Branch 0 taken 451 times.
✓ Branch 1 taken 1 times.
|
452 | for (j = 0; j < n; j++) { |
56 |
2/2✓ Branch 0 taken 194 times.
✓ Branch 1 taken 257 times.
|
451 | if (streq(desc[i], capture_names[j])) { |
57 | 194 | max_idx = i + 1; | |
58 | 194 | idx[j] = max_idx; | |
59 | 194 | break; | |
60 | } | ||
61 | } | ||
62 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 194 times.
|
195 | if (unlikely(j == n)) { |
63 | 1 | return error_msg("unknown substring name %s", desc[i]); | |
64 | } | ||
65 | } | ||
66 | |||
67 | 163 | ErrorFormat *f = xnew(ErrorFormat, 1); | |
68 | 163 | f->ignore = ignore; | |
69 | 163 | static_assert_compatible_types(f->capture_index, idx); | |
70 | 163 | memcpy(f->capture_index, idx, sizeof(idx)); | |
71 | |||
72 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 163 times.
|
163 | if (unlikely(!regexp_compile(&f->re, format, 0))) { |
73 | ✗ | free(f); | |
74 | ✗ | return false; | |
75 | } | ||
76 | |||
77 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 162 times.
|
163 | if (unlikely(max_idx > f->re.re_nsub)) { |
78 | 1 | regfree(&f->re); | |
79 | 1 | free(f); | |
80 | 1 | return error_msg("invalid substring count"); | |
81 | } | ||
82 | |||
83 | 162 | Compiler *compiler = find_or_add_compiler(compilers, name); | |
84 | 162 | f->pattern = str_intern(format); | |
85 | 162 | ptr_array_append(&compiler->error_formats, f); | |
86 | 162 | return true; | |
87 | } | ||
88 | |||
89 | 162 | static void free_error_format(ErrorFormat *f) | |
90 | { | ||
91 | 162 | regfree(&f->re); | |
92 | 162 | free(f); | |
93 | 162 | } | |
94 | |||
95 | 18 | void free_compiler(Compiler *c) | |
96 | { | ||
97 | 18 | ptr_array_free_cb(&c->error_formats, FREE_FUNC(free_error_format)); | |
98 | 18 | free(c); | |
99 | 18 | } | |
100 | |||
101 | 18 | void remove_compiler(HashMap *compilers, const char *name) | |
102 | { | ||
103 | 18 | Compiler *c = hashmap_remove(compilers, name); | |
104 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 18 times.
|
18 | if (c) { |
105 | ✗ | free_compiler(c); | |
106 | } | ||
107 | 18 | } | |
108 | |||
109 | 2 | void collect_errorfmt_capture_names(PointerArray *a, const char *prefix) | |
110 | { | ||
111 | 2 | COLLECT_STRINGS(capture_names, a, prefix); | |
112 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | if (str_has_prefix("_", prefix)) { |
113 | 1 | ptr_array_append(a, xstrdup("_")); | |
114 | } | ||
115 | 2 | } | |
116 | |||
117 | 3 | void dump_compiler(const Compiler *c, const char *name, String *s) | |
118 | { | ||
119 |
2/2✓ Branch 0 taken 27 times.
✓ Branch 1 taken 3 times.
|
30 | for (size_t i = 0, n = c->error_formats.count; i < n; i++) { |
120 | 27 | ErrorFormat *e = c->error_formats.ptrs[i]; | |
121 | 27 | string_append_literal(s, "errorfmt "); | |
122 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 10 times.
|
27 | if (e->ignore) { |
123 | 17 | string_append_literal(s, "-i "); | |
124 | } | ||
125 |
2/4✓ Branch 0 taken 27 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 27 times.
|
27 | if (unlikely(name[0] == '-' || e->pattern[0] == '-')) { |
126 | ✗ | string_append_literal(s, "-- "); | |
127 | } | ||
128 | 27 | string_append_escaped_arg(s, name, true); | |
129 | 27 | string_append_byte(s, ' '); | |
130 | 27 | string_append_escaped_arg(s, e->pattern, true); | |
131 | |||
132 | 27 | static_assert(ARRAYLEN(e->capture_index) == 4); | |
133 | 27 | const int8_t *a = e->capture_index; | |
134 | 27 | int max_idx = MAX4(a[0], a[1], a[2], a[3]); | |
135 | 27 | BUG_ON(max_idx > ERRORFMT_CAPTURE_MAX); | |
136 | |||
137 |
2/2✓ Branch 0 taken 32 times.
✓ Branch 1 taken 27 times.
|
59 | for (int j = 1; j <= max_idx; j++) { |
138 | 74 | const char *capname = "_"; | |
139 |
1/2✓ Branch 0 taken 74 times.
✗ Branch 1 not taken.
|
74 | for (size_t k = 0; k < ARRAYLEN(capture_names); k++) { |
140 |
2/2✓ Branch 0 taken 32 times.
✓ Branch 1 taken 42 times.
|
74 | if (j == a[k]) { |
141 | 32 | capname = capture_names[k]; | |
142 | 32 | break; | |
143 | } | ||
144 | } | ||
145 | 32 | string_append_byte(s, ' '); | |
146 | 32 | string_append_cstring(s, capname); | |
147 | } | ||
148 | |||
149 | 27 | string_append_byte(s, '\n'); | |
150 | } | ||
151 | 3 | } | |
152 |