return r;
_cleanup_free_ char *kdup = NULL, *vdup = NULL;
+
kdup = strdup(k);
- vdup = strdup(v);
- if (!kdup || !vdup)
+ if (!kdup)
return -ENOMEM;
+ if (v) {
+ vdup = strdup(v);
+ if (!vdup)
+ return -ENOMEM;
+ }
+
r = hashmap_put(*h, kdup, vdup);
if (r < 0) {
- if (r == -EEXIST && streq(v, hashmap_get(*h, kdup)))
+ if (r == -EEXIST && streq_ptr(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;
+ /* 0 with non-null vdup would mean vdup is already in the hashmap, which cannot be */
+ assert(vdup == NULL || r > 0);
+ if (r > 0)
+ kdup = vdup = NULL;
- return 0;
+ return r;
}
int set_put_strdup(Set **s, const char *p) {
/* SPDX-License-Identifier: LGPL-2.1+ */
#include "hashmap.h"
+#include "string-util.h"
#include "util.h"
unsigned custom_counter = 0;
assert_se(iterated_cache_free(c) == NULL);
}
+static void test_hashmap_put_strdup(void) {
+ _cleanup_hashmap_free_ Hashmap *m = NULL;
+ char *s;
+
+ /* We don't have ordered_hashmap_put_strdup() yet. If it is added,
+ * these tests should be moved to test-hashmap-plain.c. */
+
+ log_info("/* %s */", __func__);
+
+ assert_se(hashmap_put_strdup(&m, "foo", "bar") == 1);
+ assert_se(hashmap_put_strdup(&m, "foo", "bar") == 0);
+ assert_se(hashmap_put_strdup(&m, "foo", "BAR") == -EEXIST);
+ assert_se(hashmap_put_strdup(&m, "foo", "bar") == 0);
+ assert_se(hashmap_contains(m, "foo"));
+
+ s = hashmap_get(m, "foo");
+ assert_se(streq(s, "bar"));
+
+ assert_se(hashmap_put_strdup(&m, "xxx", "bar") == 1);
+ assert_se(hashmap_put_strdup(&m, "xxx", "bar") == 0);
+ assert_se(hashmap_put_strdup(&m, "xxx", "BAR") == -EEXIST);
+ assert_se(hashmap_put_strdup(&m, "xxx", "bar") == 0);
+ assert_se(hashmap_contains(m, "xxx"));
+
+ s = hashmap_get(m, "xxx");
+ assert_se(streq(s, "bar"));
+}
+
+static void test_hashmap_put_strdup_null(void) {
+ _cleanup_hashmap_free_ Hashmap *m = NULL;
+ char *s;
+
+ log_info("/* %s */", __func__);
+
+ assert_se(hashmap_put_strdup(&m, "foo", "bar") == 1);
+ assert_se(hashmap_put_strdup(&m, "foo", "bar") == 0);
+ assert_se(hashmap_put_strdup(&m, "foo", NULL) == -EEXIST);
+ assert_se(hashmap_put_strdup(&m, "foo", "bar") == 0);
+ assert_se(hashmap_contains(m, "foo"));
+
+ s = hashmap_get(m, "foo");
+ assert_se(streq(s, "bar"));
+
+ assert_se(hashmap_put_strdup(&m, "xxx", NULL) == 1);
+ assert_se(hashmap_put_strdup(&m, "xxx", "bar") == -EEXIST);
+ assert_se(hashmap_put_strdup(&m, "xxx", NULL) == 0);
+ assert_se(hashmap_contains(m, "xxx"));
+
+ s = hashmap_get(m, "xxx");
+ assert_se(s == NULL);
+}
+
int main(int argc, const char *argv[]) {
/* This file tests in test-hashmap-plain.c, and tests in test-hashmap-ordered.c, which is generated
* from test-hashmap-plain.c. Hashmap tests should be added to test-hashmap-plain.c, and here only if
test_trivial_compare_func();
test_string_compare_func();
test_iterated_cache();
+ test_hashmap_put_strdup();
+ test_hashmap_put_strdup_null();
return 0;
}