Line | Branch | Exec | Source |
---|---|---|---|
1 | #include <stdlib.h> | ||
2 | #include <string.h> | ||
3 | #include "compiler.h" | ||
4 | #include "command/serialize.h" | ||
5 | #include "util/array.h" | ||
6 | #include "util/debug.h" | ||
7 | #include "util/intern.h" | ||
8 | #include "util/str-util.h" | ||
9 | #include "util/xmalloc.h" | ||
10 | |||
11 | static const char capture_names[NR_ERRFMT_INDICES][8] = { | ||
12 | [ERRFMT_FILE] = "file", | ||
13 | [ERRFMT_LINE] = "line", | ||
14 | [ERRFMT_COLUMN] = "column", | ||
15 | [ERRFMT_MESSAGE] = "message" | ||
16 | }; | ||
17 | |||
18 | 24 | UNITTEST { | |
19 | 24 | CHECK_STRING_ARRAY(capture_names); | |
20 | 24 | } | |
21 | |||
22 | 291 | ssize_t errorfmt_capture_name_to_index(const char *name) | |
23 | { | ||
24 |
2/2✓ Branch 0 (6→3) taken 673 times.
✓ Branch 1 (6→7) taken 1 times.
|
674 | for (size_t i = 0; i < ARRAYLEN(capture_names); i++) { |
25 |
2/2✓ Branch 0 (3→4) taken 290 times.
✓ Branch 1 (3→5) taken 383 times.
|
673 | if (streq(name, capture_names[i])) { |
26 | 290 | return i; | |
27 | } | ||
28 | } | ||
29 | return -1; | ||
30 | } | ||
31 | |||
32 | 243 | static Compiler *find_or_add_compiler(HashMap *compilers, const char *name) | |
33 | { | ||
34 | 243 | Compiler *c = find_compiler(compilers, name); | |
35 |
2/2✓ Branch 0 (3→4) taken 27 times.
✓ Branch 1 (3→7) taken 216 times.
|
243 | return c ? c : hashmap_insert(compilers, xstrdup(name), xcalloc1(sizeof(*c))); |
36 | } | ||
37 | |||
38 | 243 | void add_error_fmt ( | |
39 | HashMap *compilers, | ||
40 | const char *name, | ||
41 | const char *pattern, | ||
42 | regex_t *re, | ||
43 | int8_t idx[NR_ERRFMT_INDICES], | ||
44 | bool ignore | ||
45 | ) { | ||
46 | 243 | ErrorFormat *f = xmalloc(sizeof(*f)); | |
47 | 243 | f->ignore = ignore; | |
48 | 243 | f->re = *re; // Takes ownership (responsible for calling regfree(3)) | |
49 | 243 | memcpy(f->capture_index, idx, NR_ERRFMT_INDICES); | |
50 | |||
51 | 243 | Compiler *compiler = find_or_add_compiler(compilers, name); | |
52 | 243 | f->pattern = str_intern(pattern); | |
53 | 243 | ptr_array_append(&compiler->error_formats, f); | |
54 | 243 | } | |
55 | |||
56 | 243 | void free_error_format(ErrorFormat *f) | |
57 | { | ||
58 | 243 | regfree(&f->re); | |
59 | 243 | free(f); | |
60 | 243 | } | |
61 | |||
62 | 27 | void free_compiler(Compiler *c) | |
63 | { | ||
64 | 27 | ptr_array_free_cb(&c->error_formats, FREE_FUNC(free_error_format)); | |
65 | 27 | free(c); | |
66 | 27 | } | |
67 | |||
68 | 18 | void remove_compiler(HashMap *compilers, const char *name) | |
69 | { | ||
70 | 18 | Compiler *c = hashmap_remove(compilers, name); | |
71 |
1/2✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 18 times.
|
18 | if (c) { |
72 | ✗ | free_compiler(c); | |
73 | } | ||
74 | 18 | } | |
75 | |||
76 | 2 | void collect_errorfmt_capture_names(PointerArray *a, const char *prefix) | |
77 | { | ||
78 | 2 | COLLECT_STRINGS(capture_names, a, prefix); | |
79 |
2/2✓ Branch 0 (3→4) taken 1 times.
✓ Branch 1 (3→6) taken 1 times.
|
2 | if (str_has_prefix("_", prefix)) { |
80 | 1 | ptr_array_append(a, xstrdup("_")); | |
81 | } | ||
82 | 2 | } | |
83 | |||
84 | 3 | void dump_compiler(const Compiler *c, const char *name, String *s) | |
85 | { | ||
86 |
2/2✓ Branch 0 (24→3) taken 27 times.
✓ Branch 1 (24→25) taken 3 times.
|
30 | for (size_t i = 0, n = c->error_formats.count; i < n; i++) { |
87 | 27 | ErrorFormat *e = c->error_formats.ptrs[i]; | |
88 | 27 | string_append_literal(s, "errorfmt "); | |
89 |
2/2✓ Branch 0 (4→5) taken 17 times.
✓ Branch 1 (4→6) taken 10 times.
|
27 | if (e->ignore) { |
90 | 17 | string_append_literal(s, "-i "); | |
91 | } | ||
92 |
2/4✓ Branch 0 (6→7) taken 27 times.
✗ Branch 1 (6→8) not taken.
✗ Branch 2 (7→8) not taken.
✓ Branch 3 (7→9) taken 27 times.
|
27 | if (unlikely(name[0] == '-' || e->pattern[0] == '-')) { |
93 | ✗ | string_append_literal(s, "-- "); | |
94 | } | ||
95 | 27 | string_append_escaped_arg(s, name, true); | |
96 | 27 | string_append_byte(s, ' '); | |
97 | 27 | string_append_escaped_arg(s, e->pattern, true); | |
98 | |||
99 | 27 | static_assert(ARRAYLEN(e->capture_index) == 4); | |
100 | 27 | const int8_t *a = e->capture_index; | |
101 | 27 | int max_idx = MAX4(a[0], a[1], a[2], a[3]); | |
102 | 27 | BUG_ON(max_idx > ERRORFMT_CAPTURE_MAX); | |
103 | |||
104 |
2/2✓ Branch 0 (21→17) taken 32 times.
✓ Branch 1 (21→22) taken 27 times.
|
59 | for (int j = 1; j <= max_idx; j++) { |
105 | 74 | const char *capname = "_"; | |
106 |
1/2✓ Branch 0 (17→14) taken 74 times.
✗ Branch 1 (17→18) not taken.
|
74 | for (size_t k = 0; k < ARRAYLEN(capture_names); k++) { |
107 |
2/2✓ Branch 0 (14→15) taken 32 times.
✓ Branch 1 (14→16) taken 42 times.
|
74 | if (j == a[k]) { |
108 | 32 | capname = capture_names[k]; | |
109 | 32 | break; | |
110 | } | ||
111 | } | ||
112 | 32 | string_append_byte(s, ' '); | |
113 | 32 | string_append_cstring(s, capname); | |
114 | } | ||
115 | |||
116 | 27 | string_append_byte(s, '\n'); | |
117 | } | ||
118 | 3 | } | |
119 |