]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
hashmap,set: make hashmap_clear_with_destructor() or friends safer
authorYu Watanabe <watanabe.yu+github@gmail.com>
Sat, 8 May 2021 06:32:52 +0000 (15:32 +0900)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Wed, 12 May 2021 01:30:45 +0000 (10:30 +0900)
src/basic/hashmap.h
src/basic/set.h

index c20ee8eb4bc425829f062dbcc1105a524c70b14e..c855f39b1d37389cdbca0c7d025f0a1268d6f401 100644 (file)
@@ -371,28 +371,26 @@ static inline void *ordered_hashmap_first_key(OrderedHashmap *h) {
         return _hashmap_first_key(HASHMAP_BASE(h), false);
 }
 
-#define hashmap_clear_with_destructor(_s, _f)                   \
+#define hashmap_clear_with_destructor(h, f)                     \
         ({                                                      \
+                Hashmap *_h = (h);                              \
                 void *_item;                                    \
-                while ((_item = hashmap_steal_first(_s)))       \
-                        _f(_item);                              \
+                while ((_item = hashmap_steal_first(_h)))       \
+                        f(_item);                               \
+                _h;                                             \
         })
-#define hashmap_free_with_destructor(_s, _f)                    \
-        ({                                                      \
-                hashmap_clear_with_destructor(_s, _f);          \
-                hashmap_free(_s);                               \
-        })
-#define ordered_hashmap_clear_with_destructor(_s, _f)                   \
+#define hashmap_free_with_destructor(h, f)                      \
+        hashmap_free(hashmap_clear_with_destructor(h, f))
+#define ordered_hashmap_clear_with_destructor(h, f)                     \
         ({                                                              \
+                OrderedHashmap *_h = (h);                               \
                 void *_item;                                            \
-                while ((_item = ordered_hashmap_steal_first(_s)))       \
-                        _f(_item);                                      \
-        })
-#define ordered_hashmap_free_with_destructor(_s, _f)                    \
-        ({                                                              \
-                ordered_hashmap_clear_with_destructor(_s, _f);          \
-                ordered_hashmap_free(_s);                               \
+                while ((_item = ordered_hashmap_steal_first(_h)))       \
+                        f(_item);                                       \
+                _h;                                                     \
         })
+#define ordered_hashmap_free_with_destructor(h, f)                      \
+        ordered_hashmap_free(ordered_hashmap_clear_with_destructor(h, f))
 
 /* no hashmap_next */
 void* ordered_hashmap_next(OrderedHashmap *h, const void *key);
index 52b6f4984c00787bce20790f8c117e85e4809d3e..0f8673934f118d72a45de0c028be154be42a48f0 100644 (file)
@@ -95,17 +95,16 @@ static inline void *set_steal_first(Set *s) {
         return _hashmap_first_key_and_value(HASHMAP_BASE(s), true, NULL);
 }
 
-#define set_clear_with_destructor(_s, _f)               \
+#define set_clear_with_destructor(s, f)                 \
         ({                                              \
+                Set *_s = (s);                          \
                 void *_item;                            \
                 while ((_item = set_steal_first(_s)))   \
-                        _f(_item);                      \
-        })
-#define set_free_with_destructor(_s, _f)                \
-        ({                                              \
-                set_clear_with_destructor(_s, _f);      \
-                set_free(_s);                           \
+                        f(_item);                       \
+                _s;                                     \
         })
+#define set_free_with_destructor(s, f)                  \
+        set_free(set_clear_with_destructor(s, f))
 
 /* no set_steal_first_key */
 /* no set_first_key */