dte test coverage


Directory: ./
File: src/util/bsearch.h
Date: 2025-02-14 16:55: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 (10→6) taken 15642 times.
✓ Branch 1 (10→11) taken 288 times.
15930 for (size_t i = 1; i < array_len; i++) {
49 15642 const char *curr_name = first_name + (i * elem_size);
50 15642 const char *prev_name = curr_name - elem_size;
51
1/2
✗ Branch 0 (7→8) not taken.
✓ Branch 1 (7→9) taken 15642 times.
15642 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 9312 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 9312 const char *found = bsearch(key, base, nmemb, size, compare);
71
2/2
✓ Branch 0 (3→4) taken 230 times.
✓ Branch 1 (3→5) taken 9082 times.
9312 if (!found) {
72 return -1;
73 }
74 230 const char *char_base = base;
75 230 return (size_t)(found - char_base) / size;
76 }
77
78 // This is a wrapper around strcmp(3) with void* parameters, suitable
79 // for use in bsearch(3) without the need for casting
80 38272 static inline int vstrcmp(const void *a, const void *b)
81 {
82 38272 return strcmp(a, b);
83 }
84
85 #endif
86