| 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[static 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 | static const char underscore[][2] = {"_"}; | |
| 79 | 2 | COLLECT_STRINGS(underscore, a, prefix); | |
| 80 | 2 | COLLECT_STRINGS(capture_names, a, prefix); | |
| 81 | 2 | } | |
| 82 | |||
| 83 | 3 | void dump_compiler(const Compiler *c, const char *name, String *s) | |
| 84 | { | ||
| 85 |
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++) { |
| 86 | 27 | const ErrorFormat *errfmt = c->error_formats.ptrs[i]; | |
| 87 | 27 | string_append_literal(s, "errorfmt "); | |
| 88 |
2/2✓ Branch 0 (4→5) taken 17 times.
✓ Branch 1 (4→6) taken 10 times.
|
27 | if (errfmt->ignore) { |
| 89 | 17 | string_append_literal(s, "-i "); | |
| 90 | } | ||
| 91 |
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] == '-' || errfmt->pattern[0] == '-')) { |
| 92 | ✗ | string_append_literal(s, "-- "); | |
| 93 | } | ||
| 94 | 27 | string_append_escaped_arg(s, name, true); | |
| 95 | 27 | string_append_byte(s, ' '); | |
| 96 | 27 | string_append_escaped_arg(s, errfmt->pattern, true); | |
| 97 | |||
| 98 | 27 | static_assert(ARRAYLEN(errfmt->capture_index) == 4); | |
| 99 | 27 | const int8_t *capidx = errfmt->capture_index; | |
| 100 | 27 | int max_idx = MAX4(capidx[0], capidx[1], capidx[2], capidx[3]); | |
| 101 | 27 | BUG_ON(max_idx > ERRORFMT_CAPTURE_MAX); | |
| 102 | |||
| 103 |
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++) { |
| 104 | 74 | const char *capname = "_"; | |
| 105 |
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++) { |
| 106 |
2/2✓ Branch 0 (14→15) taken 32 times.
✓ Branch 1 (14→16) taken 42 times.
|
74 | if (j == capidx[k]) { |
| 107 | 32 | capname = capture_names[k]; | |
| 108 | 32 | break; | |
| 109 | } | ||
| 110 | } | ||
| 111 | 32 | string_append_byte(s, ' '); | |
| 112 | 32 | string_append_cstring(s, capname); | |
| 113 | } | ||
| 114 | |||
| 115 | 27 | string_append_byte(s, '\n'); | |
| 116 | } | ||
| 117 | 3 | } | |
| 118 |