dte test coverage


Directory: ./
File: src/util/str-array.h
Date: 2025-06-04 06:50:24
Exec Total Coverage
Lines: 37 37 100.0%
Functions: 7 7 100.0%
Branches: 22 24 91.7%

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 10063 static inline size_t string_array_length(char **strings)
17 {
18 10063 size_t n = 0;
19
2/2
✓ Branch 0 (4→3) taken 22424 times.
✓ Branch 1 (4→5) taken 10063 times.
32487 while (strings[n]) {
20 22424 n++;
21 }
22 10063 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 0 (5→3) taken 104 times.
✓ Branch 1 (5→6) taken 48 times.
152 for (size_t i = 0; strs[i]; i++) {
29
1/2
✓ Branch 0 (3→4) taken 104 times.
✗ Branch 1 (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 0 (5→3) taken 1 times.
✓ Branch 1 (5→6) taken 1 times.
2 for (size_t i = 0; strs[i]; i++) {
39
1/2
✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→6) taken 1 times.
1 if (streq(strs[i], str)) {
40 return true;
41 }
42 }
43 return false;
44 }
45
46 519 static inline char **copy_string_array(char **src, size_t count)
47 {
48 519 char **dst = xmallocarray(count + 1, sizeof(*dst));
49
2/2
✓ Branch 0 (6→4) taken 851 times.
✓ Branch 1 (6→7) taken 519 times.
1370 for (size_t i = 0; i < count; i++) {
50 851 dst[i] = xstrdup(src[i]);
51 }
52 519 dst[count] = NULL;
53 519 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 89 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 89 BUG_ON(bufsize == 0);
66 89 const char *end = buf + bufsize;
67 89 char *ptr = buf;
68 89 buf[0] = '\0'; // Always null-terminate `buf`, even if `nstrs == 0`
69
70
2/2
✓ Branch 0 (12→5) taken 487 times.
✓ Branch 1 (12→13) taken 60 times.
547 for (size_t i = 0; i < nstrs; i++) {
71 487 bool last_iter = (i + 1 == nstrs);
72 487 ptr = memccpy(ptr, strs[i], '\0', end - ptr);
73
6/6
✓ Branch 0 (6→7) taken 478 times.
✓ Branch 1 (6→13) taken 9 times.
✓ Branch 2 (7→8) taken 421 times.
✓ Branch 3 (7→9) taken 57 times.
✓ Branch 4 (8→9) taken 401 times.
✓ Branch 5 (8→13) taken 20 times.
487 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 0 (9→10) taken 401 times.
✓ Branch 1 (9→11) taken 57 times.
458 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 57 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 57 bool r = string_array_concat_(buf, bufsize, strs, nstrs, delim, delim_len);
91 57 BUG_ON(!r);
92 57 }
93
94 NONNULL_ARGS
95 1978 static inline void free_string_array(char **strings)
96 {
97
2/2
✓ Branch 0 (4→3) taken 889 times.
✓ Branch 1 (4→5) taken 1978 times.
2867 for (size_t i = 0; strings[i]; i++) {
98 889 free(strings[i]);
99 }
100 1978 free(strings);
101 1978 }
102
103 #endif
104