diff options
author | Stef Walter <stefw@gnome.org> | 2013-03-06 19:12:28 +0100 |
---|---|---|
committer | Stef Walter <stefw@gnome.org> | 2013-03-15 17:21:49 +0100 |
commit | d2128c263ea77e4f99bccc6ac46964ad419ec2d1 (patch) | |
tree | 15cb1d23477b6e6df689e9c60c5ec8abcfd0a638 /common | |
parent | 86e60637394340ef2fa3b3db6b451dac1d73052b (diff) |
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
Diffstat (limited to 'common')
-rw-r--r-- | common/dict.h | 2 | ||||
-rw-r--r-- | common/tests/test-dict.c | 60 |
2 files changed, 62 insertions, 0 deletions
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); |