[ovs-dev] [tests+nxm-ofctl 29/42] util: Introduce ASSIGN_CONTAINER to make iteration macros easier to read.
Justin Pettit
jpettit at nicira.com
Sat Dec 4 23:24:28 UTC 2010
Looks good.
--Justin
On Nov 23, 2010, at 2:44 PM, Ben Pfaff wrote:
> ---
> 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 5629fc0..76a3a5c 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 674c6c7..f6d2827 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 0481477..013f048 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 29e212d..4979049 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
> --
> 1.7.1
>
>
> _______________________________________________
> dev mailing list
> dev at openvswitch.org
> http://openvswitch.org/mailman/listinfo/dev_openvswitch.org
More information about the dev
mailing list