[ccan] [PATCH 1/4] tlist: Use TCON_WRAP instead of TCON

David Gibson david at gibson.dropbear.id.au
Sun Jul 23 22:29:04 AEST 2017


TCON() uses flexible-array members which aren't allowed in the middle
of structures, except as a gcc extension.  TCON_WRAP() avoids this and so
is more portable.

This doesn't change the tlist interface, only its internals.

Signed-off-by: David Gibson <david at gibson.dropbear.id.au>
---
 ccan/tlist/_info      |  6 +-----
 ccan/tlist/test/run.c | 24 ++++++++++++------------
 ccan/tlist/tlist.h    | 25 ++++++++++++-------------
 3 files changed, 25 insertions(+), 30 deletions(-)

diff --git a/ccan/tlist/_info b/ccan/tlist/_info
index 4c3394c9..c3c116d2 100644
--- a/ccan/tlist/_info
+++ b/ccan/tlist/_info
@@ -15,11 +15,7 @@
  *	#include <stdlib.h>
  *	#include <ccan/tlist/tlist.h>
  *
- *	// We could use TLIST_TYPE(children, struct child) to define this.
- *	struct tlist_children {
- *		struct list_head raw;
- *		TCON(struct child *canary);
- *	};
+ *	TLIST_TYPE(children, struct child);
  *	struct parent {
  *		const char *name;
  *		unsigned int num_children;
diff --git a/ccan/tlist/test/run.c b/ccan/tlist/test/run.c
index d36cd8bc..739c85f0 100644
--- a/ccan/tlist/test/run.c
+++ b/ccan/tlist/test/run.c
@@ -37,10 +37,10 @@ int main(int argc, char *argv[])
 	tlist_add(&parent.children, &c2, list);
 	/* Test tlist_add and !tlist_empty. */
 	ok1(!tlist_empty(&parent.children));
-	ok1(c2.list.next == &parent.children.raw.n);
-	ok1(c2.list.prev == &parent.children.raw.n);
-	ok1(parent.children.raw.n.next == &c2.list);
-	ok1(parent.children.raw.n.prev == &c2.list);
+	ok1(c2.list.next == &tcon_unwrap(&parent.children)->n);
+	ok1(c2.list.prev == &tcon_unwrap(&parent.children)->n);
+	ok1(tcon_unwrap(&parent.children)->n.next == &c2.list);
+	ok1(tcon_unwrap(&parent.children)->n.prev == &c2.list);
 	ok1(tlist_next(&parent.children, &c2, list) == NULL);
 	ok1(tlist_prev(&parent.children, &c2, list) == NULL);
 	/* Test tlist_check */
@@ -50,12 +50,12 @@ int main(int argc, char *argv[])
 	tlist_add(&parent.children, &c1, list);
 	/* Test list_add and !list_empty. */
 	ok1(!tlist_empty(&parent.children));
-	ok1(c2.list.next == &parent.children.raw.n);
+	ok1(c2.list.next == &tcon_unwrap(&parent.children)->n);
 	ok1(c2.list.prev == &c1.list);
-	ok1(parent.children.raw.n.next == &c1.list);
-	ok1(parent.children.raw.n.prev == &c2.list);
+	ok1(tcon_unwrap(&parent.children)->n.next == &c1.list);
+	ok1(tcon_unwrap(&parent.children)->n.prev == &c2.list);
 	ok1(c1.list.next == &c2.list);
-	ok1(c1.list.prev == &parent.children.raw.n);
+	ok1(c1.list.prev == &tcon_unwrap(&parent.children)->n);
 	ok1(tlist_next(&parent.children, &c1, list) == &c2);
 	ok1(tlist_next(&parent.children, &c2, list) == NULL);
 	ok1(tlist_prev(&parent.children, &c2, list) == &c1);
@@ -67,13 +67,13 @@ int main(int argc, char *argv[])
 	tlist_add_tail(&parent.children, &c3, list);
 	/* Test list_add_tail and !list_empty. */
 	ok1(!tlist_empty(&parent.children));
-	ok1(parent.children.raw.n.next == &c1.list);
-	ok1(parent.children.raw.n.prev == &c3.list);
+	ok1(tcon_unwrap(&parent.children)->n.next == &c1.list);
+	ok1(tcon_unwrap(&parent.children)->n.prev == &c3.list);
 	ok1(c1.list.next == &c2.list);
-	ok1(c1.list.prev == &parent.children.raw.n);
+	ok1(c1.list.prev == &tcon_unwrap(&parent.children)->n);
 	ok1(c2.list.next == &c3.list);
 	ok1(c2.list.prev == &c1.list);
-	ok1(c3.list.next == &parent.children.raw.n);
+	ok1(c3.list.next == &tcon_unwrap(&parent.children)->n);
 	ok1(c3.list.prev == &c2.list);
 	ok1(tlist_next(&parent.children, &c1, list) == &c2);
 	ok1(tlist_next(&parent.children, &c2, list) == &c3);
diff --git a/ccan/tlist/tlist.h b/ccan/tlist/tlist.h
index a99191a2..37882ee7 100644
--- a/ccan/tlist/tlist.h
+++ b/ccan/tlist/tlist.h
@@ -9,10 +9,10 @@
  * @suffix: the name to use (struct tlist_ at suffix)
  * @type: the type the list will contain (void for any type)
  *
- * This declares a structure "struct tlist_ at suffix" to use for
- * lists containing this type.  The actual list can be accessed using
- * ".raw" or tlist_raw().  For maximum portability, place tlists
- * embedded in structures as the last member.
+ * This declares a structure "struct tlist_ at suffix" to use for lists
+ * containing this type.  The actual list can be accessed using
+ * tlist_raw().  For maximum portability, place tlists embedded in
+ * structures as the last member.
  *
  * Example:
  *	// Defines struct tlist_children
@@ -30,8 +30,7 @@
  */
 #define TLIST_TYPE(suffix, type)			\
 	struct tlist_##suffix {				\
-		struct list_head raw;			\
-		TCON(type *canary);			\
+		TCON_WRAP(struct list_head, type *canary);	\
 	}
 
 /**
@@ -46,7 +45,7 @@
  * Example:
  *	static struct tlist_children my_list = TLIST_INIT(my_list);
  */
-#define TLIST_INIT(name) { LIST_HEAD_INIT(name.raw) }
+#define TLIST_INIT(name) TCON_WRAP_INIT(LIST_HEAD_INIT(*tcon_unwrap(&name)))
 
 /**
  * tlist_check - check head of a list for consistency
@@ -75,7 +74,7 @@
  *	}
  */
 #define tlist_check(h, abortstr) \
-	list_check(&(h)->raw, (abortstr))
+	list_check(tcon_unwrap(h), (abortstr))
 
 /**
  * tlist_init - initialize a tlist
@@ -88,7 +87,7 @@
  *	tlist_init(&parent->children);
  *	parent->num_children = 0;
  */
-#define tlist_init(h) list_head_init(&(h)->raw)
+#define tlist_init(h) list_head_init(tcon_unwrap(h))
 
 /**
  * tlist_raw - unwrap the typed list and check the type
@@ -99,7 +98,7 @@
  * variable is of an unexpected type.  It is used internally where we
  * need to access the raw underlying list.
  */
-#define tlist_raw(h, expr) (&tcon_check((h), canary, (expr))->raw)
+#define tlist_raw(h, expr) tcon_unwrap(tcon_check((h), canary, (expr)))
 
 /**
  * tlist_add - add an entry at the start of a linked list.
@@ -174,7 +173,7 @@
  * Example:
  *	assert(tlist_empty(&parent->children) == (parent->num_children == 0));
  */
-#define tlist_empty(h) list_empty(&(h)->raw)
+#define tlist_empty(h) list_empty(tcon_unwrap(h))
 
 /**
  * tlist_top - get the first entry in a list
@@ -191,7 +190,7 @@
  */
 #define tlist_top(h, member)						\
 	((tcon_type((h), canary))					\
-	 list_top_(&(h)->raw,						\
+	 list_top_(tcon_unwrap((h)),					\
 		   (char *)(&(h)->_tcon[0].canary->member) -		\
 		   (char *)((h)->_tcon[0].canary)))
 
@@ -210,7 +209,7 @@
  */
 #define tlist_tail(h, member)						\
 	((tcon_type((h), canary))					\
-	 list_tail_(&(h)->raw,						\
+	 list_tail_(tcon_unwrap(h),					\
 		    (char *)(&(h)->_tcon[0].canary->member) -		\
 		    (char *)((h)->_tcon[0].canary)))
 
-- 
2.13.3



More information about the ccan mailing list