dte test coverage


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 50.0% high: ≥ 85.0%
Coverage Exec / Excl / Total
Lines: 100.0% 21 / 2 / 23
Functions: 100.0% 3 / 0 / 3
Branches: 83.3% 10 / 14 / 26

src/util/array.h
Line Branch Exec Source
1 #ifndef UTIL_ARRAY_H
2 #define UTIL_ARRAY_H
3
4 #include <stdbool.h>
5 #include <sys/types.h>
6 #include "debug.h"
7 #include "macros.h"
8 #include "ptr-array.h"
9 #include "string-view.h"
10 #include "xstring.h"
11
12 #define static_assert_flat_string_array(a) \
13 static_assert_incompatible_types(a[0], const char*); \
14 static_assert_incompatible_types(a[0], char*); \
15 static_assert_compatible_types(a[0][0], char)
16
17 #define static_assert_flat_struct_array(a, field) \
18 static_assert_offsetof(a[0], field, 0); \
19 static_assert_incompatible_types(a[0].field, const char*); \
20 static_assert_incompatible_types(a[0].field, char*); \
21 static_assert_compatible_types(a[0].field[0], char)
22
23 #define CHECK_STRING_ARRAY(a) \
24 static_assert_flat_string_array(a); \
25 check_array(a, #a, "", ARRAYLEN(a), sizeof(a[0]), sizeof(a[0]))
26
27 #define CHECK_STRUCT_ARRAY(a, field) \
28 static_assert_flat_struct_array(a, field); \
29 check_array(a, #a, "." #field, ARRAYLEN(a), sizeof(a[0]), sizeof(a[0].field))
30
31 #define COLLECT_STRINGS(a, ptrs, prefix) \
32 static_assert_flat_string_array(a); \
33 collect_strings_from_flat_array(a[0], ARRAYLEN(a), sizeof(a[0]), ptrs, prefix)
34
35 #define COLLECT_STRING_FIELDS(a, field, ptrs, prefix) \
36 static_assert_flat_struct_array(a, field); \
37 collect_strings_from_flat_array(a[0].field, ARRAYLEN(a), sizeof(a[0]), ptrs, prefix)
38
39 #define STR_TO_ENUM_WITH_OFFSET(str, a, nfval, off) \
40 str_to_enum(str, a[0], ARRAYLEN(a), sizeof(a[0]), off, nfval)
41
42 #define SSTR_TO_ENUM_WITH_OFFSET(str, a, field, nfval, off) \
43 str_to_enum(str, a[0].field, ARRAYLEN(a), sizeof(a[0]), off, nfval)
44
45 #define STR_TO_ENUM(str, a, nfval) \
46 STR_TO_ENUM_WITH_OFFSET(str, a, nfval, 0)
47
48 #define STR_TO_BITFLAGS(str, a, tolerate_errors) \
49 str_to_bitflags(str, a[0], ARRAYLEN(a), sizeof(a[0]), tolerate_errors)
50
51 #define FIND_STR_IDX(str, a) \
52 find_str_idx(str, (char*)a, ARRAYLEN(a), sizeof(a[0]), streq)
53
54 // This is somewhat similar to lfind(3), but returning an index
55 // instead of a pointer and specifically for arrays of type
56 // `const char[nmemb][size]`
57 1259 static inline ssize_t find_str_idx (
58 const char *str,
59 const char *base,
60 size_t nmemb,
61 size_t size,
62 bool (*equal)(const char *s1, const char *s2)
63 ) {
64 1259 const char *entry = base;
65
2/2
✓ Branch 7 → 3 taken 12653 times.
✓ Branch 7 → 8 taken 455 times.
13108 for (size_t i = 0; i < nmemb; i++, entry += size) {
66
2/2
✓ Branch 4 → 5 taken 804 times.
✓ Branch 4 → 6 taken 11849 times.
12653 if (equal(str, entry)) {
67 804 return i;
68 }
69 }
70 return -1;
71 }
72
73 // Attempt to find `str` in a flat array of strings starting at `base`.
74 // If found, return the index plus `return_offset`, otherwise return
75 // `not_found_val`.
76 1239 static inline int str_to_enum (
77 const char *str,
78 const char *base,
79 size_t nmemb,
80 size_t size,
81 int return_offset,
82 int not_found_val
83 ) {
84 1239 ssize_t idx = find_str_idx(str, base, nmemb, size, streq);
85
2/2
✓ Branch 3 → 4 taken 794 times.
✓ Branch 3 → 5 taken 445 times.
1239 return (idx >= 0) ? idx + return_offset : not_found_val;
86 }
87
88 void collect_strings_from_flat_array (
89 const char *base,
90 size_t nr_elements,
91 size_t element_len,
92 PointerArray *a,
93 StringView prefix
94 );
95
96 696 static inline void check_array (
97 const void *base,
98 const char *array_name,
99 const char *name_field_name,
100 size_t array_len,
101 size_t elem_size,
102 size_t name_size
103 ) {
104 696 if (!DEBUG_ASSERTIONS_ENABLED) {
105 return;
106 }
107
108 696 BUG_ON(!base);
109 696 BUG_ON(!array_name);
110 696 BUG_ON(!name_field_name);
111 696 BUG_ON(name_field_name[0] != '\0' && name_field_name[0] != '.');
112 696 BUG_ON(array_len == 0);
113 696 BUG_ON(elem_size == 0);
114 696 BUG_ON(name_size == 0);
115
116 const char *first_name = base;
117
2/2
✓ Branch 21 → 16 taken 25824 times.
✓ Branch 21 → 22 taken 696 times.
26520 for (size_t i = 0; i < array_len; i++) {
118 25824 const char *curr_name = first_name + (i * elem_size);
119 // NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult)
120
1/2
✗ Branch 16 → 17 not taken.
✓ Branch 16 → 18 taken 25824 times.
25824 if (curr_name[0] == '\0') {
121 BUG("Empty string at %s[%zu]%s", array_name, i, name_field_name);
122 }
123 // NOLINTNEXTLINE(clang-analyzer-core.UndefinedBinaryOperatorResult)
124
1/2
✗ Branch 18 → 19 not taken.
✓ Branch 18 → 20 taken 25824 times.
25824 if (curr_name[name_size - 1] != '\0') {
125 BUG("String sentinel missing from %s[%zu]%s", array_name, i, name_field_name);
126 }
127 }
128 }
129
130 unsigned int str_to_bitflags(const char *str, const char *base, size_t nstrs, size_t size, bool tolerate_errors);
131
132 #endif
133