dte test coverage


Directory: ./
File: src/util/str-array.h
Date: 2025-12-11 10:43:49
Coverage Exec Excl Total
Lines: 100.0% 37 0 37
Functions: 100.0% 7 0 7
Branches: 91.7% 22 0 24

Line Branch Exec Source
1 #ifndef UTIL_STR_ARRAY_H
2 #define UTIL_STR_ARRAY_H
3
4 // Utility functions for working with null-terminated arrays of null-terminated
5 // strings, like e.g. the "argv" argument passed to main()
6
7 #include <stdbool.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include "debug.h"
11 #include "macros.h"
12 #include "str-util.h"
13 #include "xmalloc.h"
14 #include "xstring.h"
15
16 11509 static inline size_t string_array_length(char **strings)
17 {
18 11509 size_t n = 0;
19
2/2
✓ Branch 4 → 3 taken 25063 times.
✓ Branch 4 → 5 taken 11509 times.
36572 while (strings[n]) {
20 25063 n++;
21 }
22 11509 return n;
23 }
24
25 48 static inline bool string_array_contains_prefix(char **strs, const char *prefix)
26 {
27 48 size_t prefix_len = strlen(prefix);
28
2/2
✓ Branch 5 → 3 taken 104 times.
✓ Branch 5 → 6 taken 48 times.
152 for (size_t i = 0; strs[i]; i++) {
29
1/2
✓ Branch 3 → 4 taken 104 times.
✗ Branch 3 → 6 not taken.
104 if (str_has_strn_prefix(strs[i], prefix, prefix_len)) {
30 return true;
31 }
32 }
33 return false;
34 }
35
36 2 static inline bool string_array_contains_str(char **strs, const char *str)
37 {
38
2/2
✓ Branch 5 → 3 taken 1 time.
✓ Branch 5 → 6 taken 1 time.
2 for (size_t i = 0; strs[i]; i++) {
39
1/2
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 6 taken 1 time.
1 if (streq(strs[i], str)) {
40 return true;
41 }
42 }
43 return false;
44 }
45
46 611 static inline char **copy_string_array(char **src, size_t count)
47 {
48 611 char **dst = xmallocarray(count + 1, sizeof(*dst));
49
2/2
✓ Branch 6 → 4 taken 1037 times.
✓ Branch 6 → 7 taken 611 times.
1648 for (size_t i = 0; i < count; i++) {
50 1037 dst[i] = xstrdup(src[i]);
51 }
52 611 dst[count] = NULL;
53 611 return dst;
54 }
55
56 // Concatenates an array of strings into a fixed-size buffer, as a single,
57 // delimiter-separated string. This is separate from string_array_concat()
58 // only as a convenience for testing.
59 WARN_UNUSED_RESULT NONNULL_ARGS
60 93 static inline bool string_array_concat_ (
61 char *buf, size_t bufsize,
62 const char *const *strs, size_t nstrs,
63 const char *delim, size_t delim_len
64 ) {
65 93 BUG_ON(bufsize == 0);
66 93 const char *end = buf + bufsize;
67 93 char *ptr = buf;
68 93 buf[0] = '\0'; // Always null-terminate `buf`, even if `nstrs == 0`
69
70
2/2
✓ Branch 12 → 5 taken 519 times.
✓ Branch 12 → 13 taken 64 times.
583 for (size_t i = 0; i < nstrs; i++) {
71 519 bool last_iter = (i + 1 == nstrs);
72 519 ptr = memccpy(ptr, strs[i], '\0', end - ptr);
73
6/6
✓ Branch 6 → 7 taken 510 times.
✓ Branch 6 → 13 taken 9 times.
✓ Branch 7 → 8 taken 449 times.
✓ Branch 7 → 9 taken 61 times.
✓ Branch 8 → 9 taken 429 times.
✓ Branch 8 → 13 taken 20 times.
519 if (unlikely(!ptr || (!last_iter && ptr + delim_len > end))) {
74 return false;
75 }
76 // Append `delim` (over the copied '\0'), if not on the last iteration
77
2/2
✓ Branch 9 → 10 taken 429 times.
✓ Branch 9 → 11 taken 61 times.
490 ptr = last_iter ? ptr : xmempcpy(ptr - 1, delim, delim_len);
78 }
79
80 return true;
81 }
82
83 // Like string_array_concat_(), but asserting that it should never return
84 // false (i.e. because the required `bufsize` is known at compile-time)
85 61 static inline void string_array_concat (
86 char *buf, size_t bufsize,
87 const char *const *strs, size_t nstrs,
88 const char *delim, size_t delim_len
89 ) {
90 61 bool r = string_array_concat_(buf, bufsize, strs, nstrs, delim, delim_len);
91 61 BUG_ON(!r);
92 61 }
93
94 NONNULL_ARGS
95 2558 static inline void free_string_array(char **strings)
96 {
97
2/2
✓ Branch 4 → 3 taken 1113 times.
✓ Branch 4 → 5 taken 2558 times.
3671 for (size_t i = 0; strings[i]; i++) {
98 1113 free(strings[i]);
99 }
100 2558 free(strings);
101 2558 }
102
103 #endif
104