From 772ec52b896380f23b587bea4a5bf18edd22449d Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Wed, 17 Nov 2010 14:25:33 -0800 Subject: [PATCH] util: Introduce ASSIGN_CONTAINER to make iteration macros easier to read. --- lib/classifier.h | 16 ++++++---------- lib/hmap.h | 29 +++++++++++------------------ lib/list.h | 19 ++++++++++--------- lib/util.h | 8 ++++++++ 4 files changed, 35 insertions(+), 37 deletions(-) diff --git a/lib/classifier.h b/lib/classifier.h index 5629fc02..76a3a5c0 100644 --- a/lib/classifier.h +++ b/lib/classifier.h @@ -135,20 +135,16 @@ struct cls_rule *cls_cursor_first(struct cls_cursor *); struct cls_rule *cls_cursor_next(struct cls_cursor *, struct cls_rule *); #define CLS_CURSOR_FOR_EACH(RULE, MEMBER, CURSOR) \ - for ((RULE) = OBJECT_CONTAINING(cls_cursor_first(CURSOR), \ - RULE, MEMBER); \ + for (ASSIGN_CONTAINER(RULE, cls_cursor_first(CURSOR), MEMBER); \ &(RULE)->MEMBER != NULL; \ - (RULE) = OBJECT_CONTAINING(cls_cursor_next(CURSOR, \ - &(RULE)->MEMBER), \ - RULE, MEMBER)) + ASSIGN_CONTAINER(RULE, cls_cursor_next(CURSOR, &(RULE)->MEMBER), \ + MEMBER)) #define CLS_CURSOR_FOR_EACH_SAFE(RULE, NEXT, MEMBER, CURSOR) \ - for ((RULE) = OBJECT_CONTAINING(cls_cursor_first(CURSOR), \ - RULE, MEMBER); \ + for (ASSIGN_CONTAINER(RULE, cls_cursor_first(CURSOR), MEMBER); \ (&(RULE)->MEMBER != NULL \ - ? ((NEXT) = OBJECT_CONTAINING(cls_cursor_next(CURSOR, \ - &(RULE)->MEMBER), \ - RULE, MEMBER), 1) \ + ? ASSIGN_CONTAINER(NEXT, cls_cursor_next(CURSOR, &(RULE)->MEMBER), \ + MEMBER) \ : 0); \ (RULE) = (NEXT)) diff --git a/lib/hmap.h b/lib/hmap.h index 674c6c77..f6d28274 100644 --- a/lib/hmap.h +++ b/lib/hmap.h @@ -114,17 +114,14 @@ struct hmap_node *hmap_random_node(const struct hmap *); * HASH is only evaluated once. */ #define HMAP_FOR_EACH_WITH_HASH(NODE, MEMBER, HASH, HMAP) \ - for ((NODE) = OBJECT_CONTAINING(hmap_first_with_hash(HMAP, HASH), \ - NODE, MEMBER); \ + for (ASSIGN_CONTAINER(NODE, hmap_first_with_hash(HMAP, HASH), MEMBER); \ &(NODE)->MEMBER != NULL; \ - (NODE) = OBJECT_CONTAINING(hmap_next_with_hash(&(NODE)->MEMBER), \ - NODE, MEMBER)) + ASSIGN_CONTAINER(NODE, hmap_next_with_hash(&(NODE)->MEMBER), \ + MEMBER)) #define HMAP_FOR_EACH_IN_BUCKET(NODE, MEMBER, HASH, HMAP) \ - for ((NODE) = OBJECT_CONTAINING(hmap_first_in_bucket(HMAP, HASH), \ - NODE, MEMBER); \ + for (ASSIGN_CONTAINER(NODE, hmap_first_in_bucket(HMAP, HASH), MEMBER); \ &(NODE)->MEMBER != NULL; \ - (NODE) = OBJECT_CONTAINING(hmap_next_in_bucket(&(NODE)->MEMBER), \ - NODE, MEMBER)) + ASSIGN_CONTAINER(NODE, hmap_next_in_bucket(&(NODE)->MEMBER), MEMBER)) static inline struct hmap_node *hmap_first_with_hash(const struct hmap *, size_t hash); @@ -137,28 +134,24 @@ static inline struct hmap_node *hmap_next_in_bucket(const struct hmap_node *); /* Iterates through every node in HMAP. */ #define HMAP_FOR_EACH(NODE, MEMBER, HMAP) \ - for ((NODE) = OBJECT_CONTAINING(hmap_first(HMAP), NODE, MEMBER); \ + for (ASSIGN_CONTAINER(NODE, hmap_first(HMAP), MEMBER); \ &(NODE)->MEMBER != NULL; \ - (NODE) = OBJECT_CONTAINING(hmap_next(HMAP, &(NODE)->MEMBER), \ - NODE, MEMBER)) + ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER)) /* Safe when NODE may be freed (not needed when NODE may be removed from the * hash map but its members remain accessible and intact). */ #define HMAP_FOR_EACH_SAFE(NODE, NEXT, MEMBER, HMAP) \ - for ((NODE) = OBJECT_CONTAINING(hmap_first(HMAP), NODE, MEMBER); \ + for (ASSIGN_CONTAINER(NODE, hmap_first(HMAP), MEMBER); \ (&(NODE)->MEMBER != NULL \ - ? (NEXT) = OBJECT_CONTAINING(hmap_next(HMAP, &(NODE)->MEMBER), \ - NODE, MEMBER), 1 \ + ? ASSIGN_CONTAINER(NEXT, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER) \ : 0); \ (NODE) = (NEXT)) /* Continues an iteration from just after NODE. */ #define HMAP_FOR_EACH_CONTINUE(NODE, MEMBER, HMAP) \ - for ((NODE) = OBJECT_CONTAINING(hmap_next(HMAP, &(NODE)->MEMBER), \ - NODE, MEMBER); \ + for (ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER); \ &(NODE)->MEMBER != NULL; \ - (NODE) = OBJECT_CONTAINING(hmap_next(HMAP, &(NODE)->MEMBER), \ - NODE, MEMBER)) + ASSIGN_CONTAINER(NODE, hmap_next(HMAP, &(NODE)->MEMBER), MEMBER)) static inline struct hmap_node *hmap_first(const struct hmap *); static inline struct hmap_node *hmap_next(const struct hmap *, diff --git a/lib/list.h b/lib/list.h index 0481477a..013f0488 100644 --- a/lib/list.h +++ b/lib/list.h @@ -54,17 +54,18 @@ size_t list_size(const struct list *); bool list_is_empty(const struct list *); #define LIST_FOR_EACH(ITER, MEMBER, LIST) \ - for (ITER = OBJECT_CONTAINING((LIST)->next, ITER, MEMBER); \ + for (ASSIGN_CONTAINER(ITER, (LIST)->next, MEMBER); \ &(ITER)->MEMBER != (LIST); \ - ITER = OBJECT_CONTAINING((ITER)->MEMBER.next, ITER, MEMBER)) + ASSIGN_CONTAINER(ITER, (ITER)->MEMBER.next, MEMBER)) #define LIST_FOR_EACH_REVERSE(ITER, MEMBER, LIST) \ - for (ITER = OBJECT_CONTAINING((LIST)->prev, ITER, MEMBER); \ + for (ASSIGN_CONTAINER(ITER, (LIST)->prev, MEMBER); \ &(ITER)->MEMBER != (LIST); \ - ITER = OBJECT_CONTAINING((ITER)->MEMBER.prev, ITER, MEMBER)) -#define LIST_FOR_EACH_SAFE(ITER, NEXT, MEMBER, LIST) \ - for (ITER = OBJECT_CONTAINING((LIST)->next, ITER, MEMBER); \ - (NEXT = OBJECT_CONTAINING((ITER)->MEMBER.next, ITER, MEMBER), \ - &(ITER)->MEMBER != (LIST)); \ - ITER = NEXT) + ASSIGN_CONTAINER(ITER, (ITER)->MEMBER.prev, MEMBER)) +#define LIST_FOR_EACH_SAFE(ITER, NEXT, MEMBER, LIST) \ + for (ASSIGN_CONTAINER(ITER, (LIST)->next, MEMBER); \ + (&(ITER)->MEMBER != (LIST) \ + ? ASSIGN_CONTAINER(NEXT, (ITER)->MEMBER.next, MEMBER) \ + : 0); \ + (ITER) = (NEXT)) #endif /* list.h */ diff --git a/lib/util.h b/lib/util.h index 29e212dc..49790490 100644 --- a/lib/util.h +++ b/lib/util.h @@ -101,6 +101,14 @@ extern const char *program_name; ((OVS_TYPEOF(OBJECT)) (void *) \ ((char *) (POINTER) - ((char *) &(OBJECT)->MEMBER - (char *) (OBJECT)))) +/* Given POINTER, the address of the given MEMBER within an object of the type + * that that OBJECT points to, assigns the address of the outer object to + * OBJECT, which must be an lvalue. + * + * Evaluates to 1. */ +#define ASSIGN_CONTAINER(OBJECT, POINTER, MEMBER) \ + ((OBJECT) = OBJECT_CONTAINING(POINTER, OBJECT, MEMBER), 1) + #ifdef __cplusplus extern "C" { #endif -- 2.30.2