basic/set: add set_ensure_consume()
This combines set_ensure_allocated() with set_consume(). The cool thing is that because we know the hash ops, we can correctly free the item if appropriate. Similarly to set_consume(), the goal is to simplify handling of the case where the item needs to be freed on error and if already present in the set.
This commit is contained in:
@@ -1257,6 +1257,20 @@ int _set_ensure_put(Set **s, const struct hash_ops *hash_ops, const void *key H
|
||||
return set_put(*s, key);
|
||||
}
|
||||
|
||||
int _set_ensure_consume(Set **s, const struct hash_ops *hash_ops, void *key HASHMAP_DEBUG_PARAMS) {
|
||||
int r;
|
||||
|
||||
r = _set_ensure_put(s, hash_ops, key HASHMAP_DEBUG_PASS_ARGS);
|
||||
if (r <= 0) {
|
||||
if (hash_ops && hash_ops->free_key)
|
||||
hash_ops->free_key(key);
|
||||
else
|
||||
free(key);
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int hashmap_replace(Hashmap *h, const void *key, void *value) {
|
||||
struct swap_entries swap;
|
||||
struct plain_hashmap_entry *e;
|
||||
|
||||
@@ -123,6 +123,9 @@ static inline char **set_get_strv(Set *s) {
|
||||
int _set_ensure_put(Set **s, const struct hash_ops *hash_ops, const void *key HASHMAP_DEBUG_PARAMS);
|
||||
#define set_ensure_put(s, hash_ops, key) _set_ensure_put(s, hash_ops, key HASHMAP_DEBUG_SRC_ARGS)
|
||||
|
||||
int _set_ensure_consume(Set **s, const struct hash_ops *hash_ops, void *key HASHMAP_DEBUG_PARAMS);
|
||||
#define set_ensure_consume(s, hash_ops, key) _set_ensure_consume(s, hash_ops, key HASHMAP_DEBUG_SRC_ARGS)
|
||||
|
||||
int set_consume(Set *s, void *value);
|
||||
int set_put_strdup(Set **s, const char *p);
|
||||
int set_put_strdupv(Set **s, char **l);
|
||||
|
||||
@@ -128,6 +128,28 @@ static void test_set_ensure_put(void) {
|
||||
assert_se(set_size(m) == 2);
|
||||
}
|
||||
|
||||
static void test_set_ensure_consume(void) {
|
||||
_cleanup_set_free_ Set *m = NULL;
|
||||
char *s, *t;
|
||||
|
||||
assert_se(s = strdup("a"));
|
||||
assert_se(set_ensure_consume(&m, &string_hash_ops_free, s) == 1);
|
||||
|
||||
assert_se(t = strdup("a"));
|
||||
assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 0);
|
||||
|
||||
assert_se(t = strdup("a"));
|
||||
assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 0);
|
||||
|
||||
assert_se(t = strdup("b"));
|
||||
assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 1);
|
||||
|
||||
assert_se(t = strdup("b"));
|
||||
assert_se(set_ensure_consume(&m, &string_hash_ops_free, t) == 0);
|
||||
|
||||
assert_se(set_size(m) == 2);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
test_set_steal_first();
|
||||
test_set_free_with_destructor();
|
||||
@@ -137,6 +159,7 @@ int main(int argc, const char *argv[]) {
|
||||
test_set_put_strdupv();
|
||||
test_set_ensure_allocated();
|
||||
test_set_ensure_put();
|
||||
test_set_ensure_consume();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
[Network]
|
||||
DNSSECNegativeTrustAnchors=i i
|
||||
Reference in New Issue
Block a user