[sheepdog] [PATCH] generate dynamic variable names for iteration macros

MORITA Kazutaka morita.kazutaka at gmail.com
Tue Sep 24 11:52:55 CEST 2013


From: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>

This patch generates a variable name based on the current line number.
This allows calling *_for_each() macros inside *_for_each() and
removes a magic variable name.

Signed-off-by: MORITA Kazutaka <morita.kazutaka at lab.ntt.co.jp>
---
 include/compiler.h |  4 ++++
 include/list.h     | 39 +++++++++++++++++++++------------------
 include/rbtree.h   | 51 +++++++++++++++++++++++++--------------------------
 3 files changed, 50 insertions(+), 44 deletions(-)

diff --git a/include/compiler.h b/include/compiler.h
index 93b1a72..324dacf 100644
--- a/include/compiler.h
+++ b/include/compiler.h
@@ -21,6 +21,10 @@
 
 #include "config.h"
 
+#define __LOCAL(var, line) __ ## var ## line
+#define _LOCAL(var, line) __LOCAL(var, line)
+#define LOCAL(var) _LOCAL(var, __LINE__)
+
 #define container_of(ptr, type, member) ({			\
 	const typeof(((type *)0)->member) *__mptr = (ptr);	\
 	(type *)((char *)__mptr - offsetof(type, member)); })
diff --git a/include/list.h b/include/list.h
index 97a88c3..c1bd583 100644
--- a/include/list.h
+++ b/include/list.h
@@ -52,18 +52,22 @@ static inline bool list_linked(const struct list_node *node)
 #define list_entry(ptr, type, member) \
 	container_of(ptr, type, member)
 
-#define list_for_each(pos, head) \
-	pos = (head)->n.next;					\
-	for (typeof(pos) __n = pos->next; pos != &(head)->n;	\
-	     pos = __n, __n = pos->next)
+#define list_for_each(pos, head)					\
+	for (typeof(pos) LOCAL(n) = (pos = (head)->n.next, pos->next);	\
+	     pos != &(head)->n;						\
+	     pos = LOCAL(n), LOCAL(n) = pos->next)
 
 #define list_for_each_entry(pos, head, member)				\
-	pos = list_entry((head)->n.next, typeof(*pos), member);		\
-	for (typeof(pos) __n = list_entry(pos->member.next, typeof(*pos), \
-					  member);			\
+	for (typeof(pos) LOCAL(n) = (pos = list_entry((head)->n.next,	\
+						      typeof(*pos),	\
+						      member),		\
+				     list_entry(pos->member.next,	\
+						typeof(*pos),		\
+						member));		\
 	     &pos->member != &(head)->n;				\
-	     pos = __n, __n = list_entry(__n->member.next, typeof(*__n), \
-					 member))
+	     pos = LOCAL(n), LOCAL(n) = list_entry(LOCAL(n)->member.next, \
+						   typeof(*LOCAL(n)),	\
+						   member))
 
 static inline void __list_add(struct list_node *new,
 			      struct list_node *prev,
@@ -228,10 +232,10 @@ static inline void hlist_add_after(struct hlist_node *n,
 
 #define hlist_entry(ptr, type, member) container_of(ptr, type, member)
 
-#define hlist_for_each(pos, head)				\
-	pos = (head)->first;					\
-	for (typeof(pos) __n; pos && ({ __n = pos->next; 1; });	\
-	     pos = __n)						\
+#define hlist_for_each(pos, head)					\
+	for (typeof(pos) LOCAL(n) = (pos = (head)->first, NULL);	\
+	     pos && (LOCAL(n) = pos->next, 1);				\
+	     pos = LOCAL(n))						\
 
 /*
  * hlist_for_each_entry - iterate over list of given type
@@ -241,11 +245,10 @@ static inline void hlist_add_after(struct hlist_node *n,
  * @member:     the name of the hlist_node within the struct.
  */
 #define hlist_for_each_entry(tpos, pos, head, member)			\
-	pos = (head)->first;						\
-	for (typeof(pos) __n;						\
-	     pos && ({ __n = pos->next; 1; }) &&			\
-		     ({ tpos = hlist_entry(pos, typeof(*tpos), member); 1; }); \
-	     pos = __n)
+	for (typeof(pos) LOCAL(n) = (pos = (head)->first, NULL);	\
+	     pos && (LOCAL(n) = pos->next, 1) &&			\
+		     (tpos = hlist_entry(pos, typeof(*tpos), member), 1); \
+	     pos = LOCAL(n))
 
 void list_sort(void *priv, struct list_head *head,
 	       int (*cmp)(void *priv, struct list_node *a,
diff --git a/include/rbtree.h b/include/rbtree.h
index 928eda6..6aba6ad 100644
--- a/include/rbtree.h
+++ b/include/rbtree.h
@@ -165,38 +165,37 @@ static inline void rb_link_node(struct rb_node *node, struct rb_node *parent,
 })
 
 /* Iterate over a rbtree safe against removal of rbnode */
-#define rb_for_each(pos, root)					\
-	pos = rb_first(root);					\
-	for (struct rb_node *__n1 = rb_next(pos);		\
-	     pos && ({ __n1 = rb_next(pos); 1; });		\
-	     pos = __n1)
+#define rb_for_each(pos, root)						\
+	for (struct rb_node *LOCAL(n) = (pos = rb_first(root), NULL);	\
+	     pos && (LOCAL(n) = rb_next(pos), 1);			\
+	     pos = LOCAL(n))
 
 /* Iterate over a rbtree of given type safe against removal of rbnode */
 #define rb_for_each_entry(pos, root, member)				\
-	for (struct rb_node *__pos = rb_first(root), *__n2;		\
-	     __pos && ({ __n2 = rb_next(__pos); 1; }) &&		\
-		     ({ pos =  rb_entry(__pos, typeof(*pos), member); 1; }); \
-	     __pos = __n2)
+	for (struct rb_node *LOCAL(p) = rb_first(root), *LOCAL(n);	\
+	     LOCAL(p) && (LOCAL(n) = rb_next(LOCAL(p)), 1) &&		\
+		     (pos = rb_entry(LOCAL(p), typeof(*pos), member), 1); \
+	     LOCAL(p) = LOCAL(n))
 
 /* Destroy the tree and free the memory */
-#define rb_destroy(root, type, member)                                  \
-{                                                                       \
-        type *__dummy;                                                  \
-        rb_for_each_entry(__dummy, root, member) {                      \
-                rb_erase(&__dummy->member, root);                       \
-                free(__dummy);                                          \
-        }                                                               \
-}
+#define rb_destroy(root, type, member)					\
+({									\
+	type *__dummy;							\
+	rb_for_each_entry(__dummy, root, member) {			\
+		rb_erase(&__dummy->member, root);			\
+		free(__dummy);						\
+	}								\
+})
 
 /* Copy the tree 'root' as 'outroot' */
-#define rb_copy(root, type, member, outroot, compar)                    \
-{                                                                       \
-        type *__p, *__n3;                                               \
-        rb_for_each_entry(__p, root, member) {                          \
-                __n3 = xmalloc(sizeof(*__n3));                          \
-                *__n3 = *__p;                                           \
-                rb_insert(outroot, __n3, member, compar);               \
-        }                                                               \
-}
+#define rb_copy(root, type, member, outroot, compar)			\
+({									\
+	type *__src, *__dst;						\
+	rb_for_each_entry(__src, root, member) {			\
+		__dst = xmalloc(sizeof(*__dst));			\
+		*__dst = *__src;					\
+		rb_insert(outroot, __dst, member, compar);		\
+	}								\
+})
 
 #endif /* __RBTREE_H_ */
-- 
1.8.1.2




More information about the sheepdog mailing list