| Line | Branch | Exec | Source | 
|---|---|---|---|
| 1 | #include "array.h" | ||
| 2 | #include "log.h" | ||
| 3 | #include "str-util.h" | ||
| 4 | #include "xmalloc.h" | ||
| 5 | |||
| 6 | // This can be used to collect all prefix-matched strings from a "flat" array | ||
| 7 | // (i.e. an array of fixed-length char arrays; *not* pointers to char) | ||
| 8 | 20 | void collect_strings_from_flat_array ( | |
| 9 | const char *base, | ||
| 10 | size_t nr_elements, | ||
| 11 | size_t element_len, | ||
| 12 | PointerArray *a, | ||
| 13 | const char *prefix | ||
| 14 | ) { | ||
| 15 | 20 | const char *end = base + (nr_elements * element_len); | |
| 16 | 20 | size_t prefix_len = strlen(prefix); | |
| 17 | 2/2✓ Branch 0 (7→3) taken 550 times. ✓ Branch 1 (7→8) taken 20 times. | 570 | for (const char *str = base; str < end; str += element_len) { | 
| 18 | 2/2✓ Branch 0 (3→4) taken 311 times. ✓ Branch 1 (3→6) taken 239 times. | 550 | if (str_has_strn_prefix(str, prefix, prefix_len)) { | 
| 19 | 311 | ptr_array_append(a, xstrdup(str)); | |
| 20 | } | ||
| 21 | } | ||
| 22 | 20 | } | |
| 23 | |||
| 24 | // Return bitflags corresponding to a set of comma-delimited substrings | ||
| 25 | // found in an array. For example, if the string is "str3,str7" and | ||
| 26 | // those 2 substrings are found at array[3] and array[7] respectively, | ||
| 27 | // the returned value will be `1 << 3 | 1 << 7`. | ||
| 28 | 9 | unsigned int str_to_bitflags ( | |
| 29 | const char *str, | ||
| 30 | const char *base, // Pointer to start of char[nstrs][size] array | ||
| 31 | size_t nstrs, | ||
| 32 | size_t size, | ||
| 33 | bool tolerate_errors // Whether to ignore invalid substrings | ||
| 34 | ) { | ||
| 35 | // Copy `str` into a mutable buffer, so that get_delim_str() can be | ||
| 36 | // used to split (and null-terminate) the comma-delimited substrings | ||
| 37 | 9 | char buf[512]; | |
| 38 | 9 | const char *end = memccpy(buf, str, '\0', sizeof(buf)); | |
| 39 | 1/2✗ Branch 0 (3→4) not taken. ✓ Branch 1 (3→6) taken 9 times. | 9 | if (unlikely(!end)) { | 
| 40 | ✗ | LOG_ERROR("flags string too long: %.*s...", 80, str); | |
| 41 | ✗ | return 0; | |
| 42 | } | ||
| 43 | |||
| 44 | 9 | unsigned int flags = 0; | |
| 45 | 2/2✓ Branch 0 (16→7) taken 20 times. ✓ Branch 1 (16→17) taken 8 times. | 28 | for (size_t pos = 0, len = end - buf - 1; pos < len; ) { | 
| 46 | 20 | const char *substr = get_delim_str(buf, &pos, len, ','); | |
| 47 | 20 | ssize_t idx = find_str_idx(substr, base, nstrs, size, streq); | |
| 48 | 2/2✓ Branch 0 (9→10) taken 10 times. ✓ Branch 1 (9→14) taken 10 times. | 20 | if (unlikely(idx < 0)) { | 
| 49 | 2/2✓ Branch 0 (10→11) taken 1 times. ✓ Branch 1 (10→12) taken 9 times. | 10 | if (!tolerate_errors) { | 
| 50 | 1 | return 0; | |
| 51 | } | ||
| 52 | 9 | LOG_WARNING("unrecognized flag string: '%s'", substr); | |
| 53 | 9 | continue; | |
| 54 | } | ||
| 55 | 10 | flags |= 1u << idx; | |
| 56 | } | ||
| 57 | |||
| 58 | 8 | return flags; | |
| 59 | } | ||
| 60 |