Commit 78b06543 authored by David Gibson's avatar David Gibson

tlist: Use TCON_WRAP instead of TCON

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: default avatarDavid Gibson <david@gibson.dropbear.id.au>
parent 3ffb94e9
...@@ -15,11 +15,7 @@ ...@@ -15,11 +15,7 @@
* #include <stdlib.h> * #include <stdlib.h>
* #include <ccan/tlist/tlist.h> * #include <ccan/tlist/tlist.h>
* *
* // We could use TLIST_TYPE(children, struct child) to define this. * TLIST_TYPE(children, struct child);
* struct tlist_children {
* struct list_head raw;
* TCON(struct child *canary);
* };
* struct parent { * struct parent {
* const char *name; * const char *name;
* unsigned int num_children; * unsigned int num_children;
......
...@@ -37,10 +37,10 @@ int main(int argc, char *argv[]) ...@@ -37,10 +37,10 @@ int main(int argc, char *argv[])
tlist_add(&parent.children, &c2, list); tlist_add(&parent.children, &c2, list);
/* Test tlist_add and !tlist_empty. */ /* Test tlist_add and !tlist_empty. */
ok1(!tlist_empty(&parent.children)); 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 == &parent.children.raw.n); ok1(c2.list.prev == &tcon_unwrap(&parent.children)->n);
ok1(parent.children.raw.n.next == &c2.list); ok1(tcon_unwrap(&parent.children)->n.next == &c2.list);
ok1(parent.children.raw.n.prev == &c2.list); ok1(tcon_unwrap(&parent.children)->n.prev == &c2.list);
ok1(tlist_next(&parent.children, &c2, list) == NULL); ok1(tlist_next(&parent.children, &c2, list) == NULL);
ok1(tlist_prev(&parent.children, &c2, list) == NULL); ok1(tlist_prev(&parent.children, &c2, list) == NULL);
/* Test tlist_check */ /* Test tlist_check */
...@@ -50,12 +50,12 @@ int main(int argc, char *argv[]) ...@@ -50,12 +50,12 @@ int main(int argc, char *argv[])
tlist_add(&parent.children, &c1, list); tlist_add(&parent.children, &c1, list);
/* Test list_add and !list_empty. */ /* Test list_add and !list_empty. */
ok1(!tlist_empty(&parent.children)); 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(c2.list.prev == &c1.list);
ok1(parent.children.raw.n.next == &c1.list); ok1(tcon_unwrap(&parent.children)->n.next == &c1.list);
ok1(parent.children.raw.n.prev == &c2.list); ok1(tcon_unwrap(&parent.children)->n.prev == &c2.list);
ok1(c1.list.next == &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, &c1, list) == &c2);
ok1(tlist_next(&parent.children, &c2, list) == NULL); ok1(tlist_next(&parent.children, &c2, list) == NULL);
ok1(tlist_prev(&parent.children, &c2, list) == &c1); ok1(tlist_prev(&parent.children, &c2, list) == &c1);
...@@ -67,13 +67,13 @@ int main(int argc, char *argv[]) ...@@ -67,13 +67,13 @@ int main(int argc, char *argv[])
tlist_add_tail(&parent.children, &c3, list); tlist_add_tail(&parent.children, &c3, list);
/* Test list_add_tail and !list_empty. */ /* Test list_add_tail and !list_empty. */
ok1(!tlist_empty(&parent.children)); ok1(!tlist_empty(&parent.children));
ok1(parent.children.raw.n.next == &c1.list); ok1(tcon_unwrap(&parent.children)->n.next == &c1.list);
ok1(parent.children.raw.n.prev == &c3.list); ok1(tcon_unwrap(&parent.children)->n.prev == &c3.list);
ok1(c1.list.next == &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(c2.list.next == &c3.list); ok1(c2.list.next == &c3.list);
ok1(c2.list.prev == &c1.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(c3.list.prev == &c2.list);
ok1(tlist_next(&parent.children, &c1, list) == &c2); ok1(tlist_next(&parent.children, &c1, list) == &c2);
ok1(tlist_next(&parent.children, &c2, list) == &c3); ok1(tlist_next(&parent.children, &c2, list) == &c3);
......
...@@ -9,10 +9,10 @@ ...@@ -9,10 +9,10 @@
* @suffix: the name to use (struct tlist_@suffix) * @suffix: the name to use (struct tlist_@suffix)
* @type: the type the list will contain (void for any type) * @type: the type the list will contain (void for any type)
* *
* This declares a structure "struct tlist_@suffix" to use for * This declares a structure "struct tlist_@suffix" to use for lists
* lists containing this type. The actual list can be accessed using * containing this type. The actual list can be accessed using
* ".raw" or tlist_raw(). For maximum portability, place tlists * tlist_raw(). For maximum portability, place tlists embedded in
* embedded in structures as the last member. * structures as the last member.
* *
* Example: * Example:
* // Defines struct tlist_children * // Defines struct tlist_children
...@@ -30,8 +30,7 @@ ...@@ -30,8 +30,7 @@
*/ */
#define TLIST_TYPE(suffix, type) \ #define TLIST_TYPE(suffix, type) \
struct tlist_##suffix { \ struct tlist_##suffix { \
struct list_head raw; \ TCON_WRAP(struct list_head, type *canary); \
TCON(type *canary); \
} }
/** /**
...@@ -46,7 +45,7 @@ ...@@ -46,7 +45,7 @@
* Example: * Example:
* static struct tlist_children my_list = TLIST_INIT(my_list); * 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 * tlist_check - check head of a list for consistency
...@@ -75,7 +74,7 @@ ...@@ -75,7 +74,7 @@
* } * }
*/ */
#define tlist_check(h, abortstr) \ #define tlist_check(h, abortstr) \
list_check(&(h)->raw, (abortstr)) list_check(tcon_unwrap(h), (abortstr))
/** /**
* tlist_init - initialize a tlist * tlist_init - initialize a tlist
...@@ -88,7 +87,7 @@ ...@@ -88,7 +87,7 @@
* tlist_init(&parent->children); * tlist_init(&parent->children);
* parent->num_children = 0; * 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 * tlist_raw - unwrap the typed list and check the type
...@@ -99,7 +98,7 @@ ...@@ -99,7 +98,7 @@
* variable is of an unexpected type. It is used internally where we * variable is of an unexpected type. It is used internally where we
* need to access the raw underlying list. * 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. * tlist_add - add an entry at the start of a linked list.
...@@ -174,7 +173,7 @@ ...@@ -174,7 +173,7 @@
* Example: * Example:
* assert(tlist_empty(&parent->children) == (parent->num_children == 0)); * 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 * tlist_top - get the first entry in a list
...@@ -191,7 +190,7 @@ ...@@ -191,7 +190,7 @@
*/ */
#define tlist_top(h, member) \ #define tlist_top(h, member) \
((tcon_type((h), canary)) \ ((tcon_type((h), canary)) \
list_top_(&(h)->raw, \ list_top_(tcon_unwrap((h)), \
(char *)(&(h)->_tcon[0].canary->member) - \ (char *)(&(h)->_tcon[0].canary->member) - \
(char *)((h)->_tcon[0].canary))) (char *)((h)->_tcon[0].canary)))
...@@ -210,7 +209,7 @@ ...@@ -210,7 +209,7 @@
*/ */
#define tlist_tail(h, member) \ #define tlist_tail(h, member) \
((tcon_type((h), canary)) \ ((tcon_type((h), canary)) \
list_tail_(&(h)->raw, \ list_tail_(tcon_unwrap(h), \
(char *)(&(h)->_tcon[0].canary->member) - \ (char *)(&(h)->_tcon[0].canary->member) - \
(char *)((h)->_tcon[0].canary))) (char *)((h)->_tcon[0].canary)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment