Merge pull request #34511 from YHNdnzj/strv-extend-strv-consume

basic/strv: introduce strv_extend_strv_consume()
This commit is contained in:
Yu Watanabe
2024-09-21 13:57:02 +09:00
committed by GitHub
29 changed files with 238 additions and 189 deletions
+78 -9
View File
@@ -264,20 +264,18 @@ char** strv_new_internal(const char *x, ...) {
int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates) {
size_t p, q, i = 0;
char **t;
assert(a);
if (strv_isempty(b))
q = strv_length(b);
if (q == 0)
return 0;
p = strv_length(*a);
q = strv_length(b);
if (p >= SIZE_MAX - q)
return -ENOMEM;
t = reallocarray(*a, GREEDY_ALLOC_ROUND_UP(p + q + 1), sizeof(char *));
char **t = reallocarray(*a, GREEDY_ALLOC_ROUND_UP(p + q + 1), sizeof(char *));
if (!t)
return -ENOMEM;
@@ -306,9 +304,67 @@ rollback:
return -ENOMEM;
}
int strv_extend_strv_consume(char ***a, char **b, bool filter_duplicates) {
_cleanup_strv_free_ char **b_consume = b;
size_t p, q, i;
assert(a);
q = strv_length(b);
if (q == 0)
return 0;
p = strv_length(*a);
if (p == 0) {
strv_free_and_replace(*a, b_consume);
if (filter_duplicates)
strv_uniq(*a);
return strv_length(*a);
}
if (p >= SIZE_MAX - q)
return -ENOMEM;
char **t = reallocarray(*a, GREEDY_ALLOC_ROUND_UP(p + q + 1), sizeof(char *));
if (!t)
return -ENOMEM;
t[p] = NULL;
*a = t;
if (!filter_duplicates) {
*mempcpy_typesafe(t + p, b, q) = NULL;
i = q;
} else {
i = 0;
STRV_FOREACH(s, b) {
if (strv_contains(t, *s)) {
free(*s);
continue;
}
t[p+i] = *s;
i++;
t[p+i] = NULL;
}
}
assert(i <= q);
b_consume = mfree(b_consume);
return (int) i;
}
int strv_extend_strv_biconcat(char ***a, const char *prefix, const char* const *b, const char *suffix) {
int r;
assert(a);
STRV_FOREACH(s, b) {
char *v;
@@ -384,7 +440,7 @@ int strv_split_full(char ***t, const char *s, const char *separators, ExtractFla
}
int strv_split_and_extend_full(char ***t, const char *s, const char *separators, bool filter_duplicates, ExtractFlags flags) {
_cleanup_strv_free_ char **l = NULL;
char **l;
int r;
assert(t);
@@ -394,7 +450,7 @@ int strv_split_and_extend_full(char ***t, const char *s, const char *separators,
if (r < 0)
return r;
r = strv_extend_strv(t, l, filter_duplicates);
r = strv_extend_strv_consume(t, l, filter_duplicates);
if (r < 0)
return r;
@@ -987,10 +1043,16 @@ int fputstrv(FILE *f, char * const *l, const char *separator, bool *space) {
return 0;
}
DEFINE_PRIVATE_HASH_OPS_FULL(string_strv_hash_ops, char, string_hash_func, string_compare_func, free, char*, strv_free);
static int string_strv_hashmap_put_internal(Hashmap *h, const char *key, const char *value) {
char **l;
int r;
assert(h);
assert(key);
assert(value);
l = hashmap_get(h, key);
if (l) {
/* A list for this key already exists, let's append to it if it is not listed yet */
@@ -1018,6 +1080,7 @@ static int string_strv_hashmap_put_internal(Hashmap *h, const char *key, const c
r = hashmap_put(h, t, l2);
if (r < 0)
return r;
TAKE_PTR(t);
TAKE_PTR(l2);
}
@@ -1028,6 +1091,10 @@ static int string_strv_hashmap_put_internal(Hashmap *h, const char *key, const c
int _string_strv_hashmap_put(Hashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS) {
int r;
assert(h);
assert(key);
assert(value);
r = _hashmap_ensure_allocated(h, &string_strv_hash_ops HASHMAP_DEBUG_PASS_ARGS);
if (r < 0)
return r;
@@ -1038,6 +1105,10 @@ int _string_strv_hashmap_put(Hashmap **h, const char *key, const char *value HA
int _string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS) {
int r;
assert(h);
assert(key);
assert(value);
r = _ordered_hashmap_ensure_allocated(h, &string_strv_hash_ops HASHMAP_DEBUG_PASS_ARGS);
if (r < 0)
return r;
@@ -1045,8 +1116,6 @@ int _string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const
return string_strv_hashmap_put_internal(PLAIN_HASHMAP(*h), key, value);
}
DEFINE_HASH_OPS_FULL(string_strv_hash_ops, char, string_hash_func, string_compare_func, free, char*, strv_free);
int strv_rebreak_lines(char **l, size_t width, char ***ret) {
_cleanup_strv_free_ char **broken = NULL;
int r;