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