dte test coverage


Directory: ./
File: src/util/bsearch.h
Date: 2024-12-21 16:03:22
Exec Total Coverage
Lines: 16 16 100.0%
Functions: 3 3 100.0%
Branches: 5 6 83.3%

Line Branch Exec Source
1 #ifndef UTIL_BSEARCH_H
2 #define UTIL_BSEARCH_H
3
4 #include <stddef.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <sys/types.h>
8 #include "array.h"
9 #include "debug.h"
10 #include "macros.h"
11
12 typedef int (*CompareFunction)(const void *key, const void *elem);
13 typedef int (*StringCompareFunction)(const char *key, const char *elem);
14
15 #define BSEARCH(key, a, cmp) bsearch(key, a, ARRAYLEN(a), sizeof(a[0]), cmp)
16 #define BSEARCH_IDX(key, a, cmp) bisearch_idx(key, a, ARRAYLEN(a), sizeof(a[0]), cmp)
17
18 #define CHECK_BSEARCH_ARRAY(a, field, cmp) do { \
19 static_assert_flat_struct_array(a, field); \
20 check_bsearch_array ( \
21 a, #a, "." #field, ARRAYLEN(a), sizeof(a[0]), sizeof(a[0].field), cmp \
22 ); \
23 } while (0)
24
25 #define CHECK_BSEARCH_STR_ARRAY(a, cmp) do { \
26 static_assert_flat_string_array(a); \
27 check_bsearch_array(a, #a, "", ARRAYLEN(a), sizeof(a[0]), sizeof(a[0]), cmp); \
28 } while (0)
29
30 // NOLINTNEXTLINE(readability-function-size): 7 param debug function is fine
31 288 static inline void check_bsearch_array (
32 const void *base,
33 const char *array_name,
34 const char *name_field_name,
35 size_t array_len,
36 size_t elem_size,
37 size_t name_size,
38 StringCompareFunction cmp
39 ) {
40 288 if (DEBUG < 1) {
41 return;
42 }
43
44 288 BUG_ON(!cmp);
45 288 check_array(base, array_name, name_field_name, array_len, elem_size, name_size);
46
47 288 const char *first_name = base;
48
2/2
✓ Branch 0 taken 15570 times.
✓ Branch 1 taken 288 times.
15858 for (size_t i = 1; i < array_len; i++) {
49 15570 const char *curr_name = first_name + (i * elem_size);
50 15570 const char *prev_name = curr_name - elem_size;
51
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15570 times.
15570 if (cmp(curr_name, prev_name) <= 0) {
52 BUG (
53 "String at %s[%zu]%s not in sorted order: \"%s\" (prev: \"%s\")",
54 array_name, i, name_field_name,
55 curr_name, prev_name
56 );
57 }
58 }
59 }
60
61 // Like bsearch(3), but returning the index of the element instead of
62 // a pointer to it (or -1 if not found)
63 9262 static inline ssize_t bisearch_idx (
64 const void *key,
65 const void *base,
66 size_t nmemb,
67 size_t size,
68 CompareFunction compare
69 ) {
70 9262 const char *found = bsearch(key, base, nmemb, size, compare);
71
2/2
✓ Branch 0 taken 223 times.
✓ Branch 1 taken 9039 times.
9262 if (!found) {
72 return -1;
73 }
74 223 const char *char_base = base;
75 223 return (size_t)(found - char_base) / size;
76 }
77
78 // This is a wrapper around strcmp(3) with void* parameters, suitable
79 // for use with bsearch(3) without the need for casting
80 38076 static inline int vstrcmp(const void *a, const void *b)
81 {
82 38076 return strcmp(a, b);
83 }
84
85 #endif
86