[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