From cc1a0728cda6c20ac2dc7c45caa31e19c51e78dc Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Wed, 6 Mar 2013 19:12:28 +0100 Subject: [PATCH] dict: Allow removal of current item in a p11_dict iteration * This was already possible to do safely before * Document and test this behavior https://bugs.freedesktop.org/show_bug.cgi?id=61499 --- common/dict.h | 2 ++ common/tests/test-dict.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+) diff --git a/common/dict.h b/common/dict.h index e13c5d6..080f6b8 100644 --- a/common/dict.h +++ b/common/dict.h @@ -141,6 +141,8 @@ void p11_dict_iterate (p11_dict *dict, * p11_dict_next: Enumerate through hash table * - sets key and value to key and/or value * - returns whether there was another entry + * - p11_dict_remove or p11_dict_steal is safe to use on + * the current key. */ bool p11_dict_next (p11_dictiter *iter, void **key, diff --git a/common/tests/test-dict.c b/common/tests/test-dict.c index 00b64c5..316d9f5 100644 --- a/common/tests/test-dict.c +++ b/common/tests/test-dict.c @@ -143,6 +143,65 @@ test_iterate (CuTest *tc) p11_dict_free (map); } +static int +compar_pointers (const void *one, + const void *two) +{ + char **p1 = (char **)one; + char **p2 = (char **)two; + return *p1 - *p2; +} + +static void +test_iterate_remove (CuTest *tc) +{ + p11_dict *map; + p11_dictiter iter; + char *keys[] = { "one", "two", "three" }; + char *values[] = { "four", "eight", "twelve" }; + void *okeys[3]; + void *ovalues[3]; + bool ret; + int i; + + map = p11_dict_new (p11_dict_direct_hash, p11_dict_direct_equal, NULL, NULL); + CuAssertPtrNotNull (tc, map); + + for (i = 0; i < 3; i++) { + if (!p11_dict_set (map, keys[i], values[i])) + CuFail (tc, "should not be reached"); + } + + p11_dict_iterate (map, &iter); + + ret = p11_dict_next (&iter, &okeys[0], &ovalues[0]); + CuAssertIntEquals (tc, true, ret); + + ret = p11_dict_next (&iter, &okeys[1], &ovalues[1]); + CuAssertIntEquals (tc, true, ret); + if (!p11_dict_remove (map, okeys[1])) + CuFail (tc, "should not be reached"); + + ret = p11_dict_next (&iter, &okeys[2], &ovalues[2]); + CuAssertIntEquals (tc, true, ret); + + ret = p11_dict_next (&iter, NULL, NULL); + CuAssertIntEquals (tc, false, ret); + + CuAssertIntEquals (tc, 2, p11_dict_size (map)); + p11_dict_free (map); + + qsort (okeys, 3, sizeof (void *), compar_pointers); + qsort (ovalues, 3, sizeof (void *), compar_pointers); + + for (i = 0; i < 3; i++) { + CuAssertStrEquals (tc, keys[i], okeys[i]); + CuAssertPtrEquals (tc, keys[i], okeys[i]); + CuAssertStrEquals (tc, values[i], ovalues[i]); + CuAssertPtrEquals (tc, values[i], ovalues[i]); + } +} + static void test_set_get (CuTest *tc) { @@ -455,6 +514,7 @@ main (void) SUITE_ADD_TEST (suite, test_free_null); SUITE_ADD_TEST (suite, test_free_destroys); SUITE_ADD_TEST (suite, test_iterate); + SUITE_ADD_TEST (suite, test_iterate_remove); SUITE_ADD_TEST (suite, test_hash_add_check_lots_and_collisions); SUITE_ADD_TEST (suite, test_hash_count); SUITE_ADD_TEST (suite, test_hash_ulongptr); -- 1.8.1.4