}
DEFINE_HASH_OPS(string_hash_ops, char, string_hash_func, string_compare_func);
+DEFINE_HASH_OPS_FULL(string_hash_ops_free_free,
+ char, string_hash_func, string_compare_func, free,
+ char, free);
void path_hash_func(const char *q, struct siphash *state) {
size_t n;
void string_hash_func(const char *p, struct siphash *state);
#define string_compare_func strcmp
extern const struct hash_ops string_hash_ops;
+extern const struct hash_ops string_hash_ops_free_free;
void path_hash_func(const char *p, struct siphash *state);
int path_compare_func(const char *a, const char *b) _pure_;
return r;
}
+int hashmap_put_strdup(Hashmap **h, const char *k, const char *v) {
+ int r;
+
+ r = hashmap_ensure_allocated(h, &string_hash_ops_free_free);
+ if (r < 0)
+ return r;
+
+ _cleanup_free_ char *kdup = NULL, *vdup = NULL;
+ kdup = strdup(k);
+ vdup = strdup(v);
+ if (!kdup || !vdup)
+ return -ENOMEM;
+
+ r = hashmap_put(*h, kdup, vdup);
+ if (r < 0) {
+ if (r == -EEXIST && streq(v, hashmap_get(*h, kdup)))
+ return 0;
+ return r;
+ }
+
+ assert(r > 0); /* 0 would mean vdup is already in the hashmap, which cannot be */
+ kdup = vdup = NULL;
+
+ return 0;
+}
+
int set_put_strdup(Set *s, const char *p) {
char *c;
return hashmap_put(PLAIN_HASHMAP(h), key, value);
}
+int hashmap_put_strdup(Hashmap **h, const char *k, const char *v);
+
int hashmap_update(Hashmap *h, const void *key, void *value);
static inline int ordered_hashmap_update(OrderedHashmap *h, const void *key, void *value) {
return hashmap_update(PLAIN_HASHMAP(h), key, value);
assert_se(hashmap_reserve(m, UINT_MAX - 1) == -ENOMEM);
}
+static void test_string_strv_hashmap(void) {
+ _cleanup_hashmap_free_ Hashmap *m = NULL;
+ char **s;
+
+ log_info("/* %s */", __func__);
+
+ assert_se(string_strv_hashmap_put(&m, "foo", "bar") == 1);
+ assert_se(string_strv_hashmap_put(&m, "foo", "bar") == 0);
+ assert_se(string_strv_hashmap_put(&m, "foo", "BAR") == 1);
+ assert_se(string_strv_hashmap_put(&m, "foo", "BAR") == 0);
+ assert_se(string_strv_hashmap_put(&m, "foo", "bar") == 0);
+ assert_se(hashmap_contains(m, "foo"));
+
+ s = hashmap_get(m, "foo");
+ assert_se(strv_equal(s, STRV_MAKE("bar", "BAR")));
+
+ assert_se(string_strv_hashmap_put(&m, "xxx", "bar") == 1);
+ assert_se(string_strv_hashmap_put(&m, "xxx", "bar") == 0);
+ assert_se(string_strv_hashmap_put(&m, "xxx", "BAR") == 1);
+ assert_se(string_strv_hashmap_put(&m, "xxx", "BAR") == 0);
+ assert_se(string_strv_hashmap_put(&m, "xxx", "bar") == 0);
+ assert_se(hashmap_contains(m, "xxx"));
+
+ s = hashmap_get(m, "xxx");
+ assert_se(strv_equal(s, STRV_MAKE("bar", "BAR")));
+}
+
void test_hashmap_funcs(void) {
log_parse_environment();
log_open();
test_hashmap_clear_free_free();
test_hashmap_clear_free_with_destructor();
test_hashmap_reserve();
+ test_string_strv_hashmap();
}