Merge pull request #34511 from YHNdnzj/strv-extend-strv-consume
basic/strv: introduce strv_extend_strv_consume()
This commit is contained in:
+78
-9
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user