From: David Gibson Date: Sat, 4 Jun 2016 10:21:33 +0000 (+1000) Subject: tlist: Add tlist_next() and tlist_prev() functions X-Git-Url: http://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=d81e79b8dfdfb0da8766c022e767a5b040e5d07b tlist: Add tlist_next() and tlist_prev() functions An odd omission from the tlist module is basic tlist_next() and tlist_prev() macros matching list_next() and list_prev() in the basic list module. This adds them. Signed-off-by: David Gibson Signed-off-by: Rusty Russell --- diff --git a/ccan/tlist/test/compile_fail-tlist_next.c b/ccan/tlist/test/compile_fail-tlist_next.c new file mode 100644 index 00000000..02ae16a8 --- /dev/null +++ b/ccan/tlist/test/compile_fail-tlist_next.c @@ -0,0 +1,33 @@ +#include + +TLIST_TYPE(children, struct child); + +struct child { + const char *name; + struct list_node list; +}; + +struct cousin { + const char *name; + struct list_node list; +}; + +int main(int argc, char *argv[]) +{ + struct tlist_children children; + struct child child = { "child" }; +#ifdef FAIL +#if !HAVE_FLEXIBLE_ARRAY_MEMBER +#error Need flexible array members to check type +#endif + struct cousin *p; +#else + struct child *p; +#endif + + tlist_init(&children); + tlist_add(&children, &child, list); + p = tlist_next(&children, &child, list); + (void) p; + return 0; +} diff --git a/ccan/tlist/test/compile_fail-tlist_next2.c b/ccan/tlist/test/compile_fail-tlist_next2.c new file mode 100644 index 00000000..c67fb8e1 --- /dev/null +++ b/ccan/tlist/test/compile_fail-tlist_next2.c @@ -0,0 +1,32 @@ +#include + +TLIST_TYPE(children, struct child); + +struct child { + const char *name; + struct list_node list; +}; + +struct cousin { + const char *name; + struct list_node list; +}; + +int main(int argc, char *argv[]) +{ + struct tlist_children children; + struct child child = { "child" }; +#ifdef FAIL +#if !HAVE_FLEXIBLE_ARRAY_MEMBER +#error Need flexible array members to check type +#endif + struct cousin *p = NULL; +#else + struct child *p = NULL; +#endif + + tlist_init(&children); + tlist_add(&children, &child, list); + (void)tlist_next(&children, p, list); + return 0; +} diff --git a/ccan/tlist/test/compile_fail-tlist_prev.c b/ccan/tlist/test/compile_fail-tlist_prev.c new file mode 100644 index 00000000..5357eaa7 --- /dev/null +++ b/ccan/tlist/test/compile_fail-tlist_prev.c @@ -0,0 +1,33 @@ +#include + +TLIST_TYPE(children, struct child); + +struct child { + const char *name; + struct list_node list; +}; + +struct cousin { + const char *name; + struct list_node list; +}; + +int main(int argc, char *argv[]) +{ + struct tlist_children children; + struct child child = { "child" }; +#ifdef FAIL +#if !HAVE_FLEXIBLE_ARRAY_MEMBER +#error Need flexible array members to check type +#endif + struct cousin *p; +#else + struct child *p; +#endif + + tlist_init(&children); + tlist_add(&children, &child, list); + p = tlist_prev(&children, &child, list); + (void) p; + return 0; +} diff --git a/ccan/tlist/test/compile_fail-tlist_prev2.c b/ccan/tlist/test/compile_fail-tlist_prev2.c new file mode 100644 index 00000000..c1a536d5 --- /dev/null +++ b/ccan/tlist/test/compile_fail-tlist_prev2.c @@ -0,0 +1,32 @@ +#include + +TLIST_TYPE(children, struct child); + +struct child { + const char *name; + struct list_node list; +}; + +struct cousin { + const char *name; + struct list_node list; +}; + +int main(int argc, char *argv[]) +{ + struct tlist_children children; + struct child child = { "child" }; +#ifdef FAIL +#if !HAVE_FLEXIBLE_ARRAY_MEMBER +#error Need flexible array members to check type +#endif + struct cousin *p = NULL; +#else + struct child *p = NULL; +#endif + + tlist_init(&children); + tlist_add(&children, &child, list); + (void)tlist_prev(&children, p, list); + return 0; +} diff --git a/ccan/tlist/test/run.c b/ccan/tlist/test/run.c index f94438ea..06732cc3 100644 --- a/ccan/tlist/test/run.c +++ b/ccan/tlist/test/run.c @@ -22,7 +22,7 @@ int main(int argc, char *argv[]) unsigned int i; struct tlist_children tlist = TLIST_INIT(tlist); - plan_tests(48); + plan_tests(60); /* Test TLIST_INIT, and tlist_empty */ ok1(tlist_empty(&tlist)); ok1(tlist_check(&tlist, NULL)); @@ -41,6 +41,8 @@ int main(int argc, char *argv[]) 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(tlist_next(&parent.children, &c2, list) == NULL); + ok1(tlist_prev(&parent.children, &c2, list) == NULL); /* Test tlist_check */ ok1(tlist_check(&parent.children, NULL)); @@ -54,6 +56,10 @@ int main(int argc, char *argv[]) ok1(parent.children.raw.n.prev == &c2.list); ok1(c1.list.next == &c2.list); ok1(c1.list.prev == &parent.children.raw.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); + ok1(tlist_prev(&parent.children, &c1, list) == NULL); /* Test tlist_check */ ok1(tlist_check(&parent.children, NULL)); @@ -69,6 +75,12 @@ int main(int argc, char *argv[]) ok1(c2.list.prev == &c1.list); ok1(c3.list.next == &parent.children.raw.n); ok1(c3.list.prev == &c2.list); + ok1(tlist_next(&parent.children, &c1, list) == &c2); + ok1(tlist_next(&parent.children, &c2, list) == &c3); + ok1(tlist_next(&parent.children, &c3, list) == NULL); + ok1(tlist_prev(&parent.children, &c3, list) == &c2); + ok1(tlist_prev(&parent.children, &c2, list) == &c1); + ok1(tlist_prev(&parent.children, &c1, list) == NULL); /* Test tlist_check */ ok1(tlist_check(&parent.children, NULL)); diff --git a/ccan/tlist/tlist.h b/ccan/tlist/tlist.h index 937a834c..28978514 100644 --- a/ccan/tlist/tlist.h +++ b/ccan/tlist/tlist.h @@ -213,6 +213,30 @@ (char *)(&(h)->_tcon[0].canary->member) - \ (char *)((h)->_tcon[0].canary))) +/** + * tlist_next - get the next entry in a list + * @h: the tlist + * @n: the list element + * @member: the list_node member of the type + * + * Returns the element of list @h immediately after @n, or NULL, if @n + * is the last element in the list. + */ +#define tlist_next(h, n, member) \ + list_next(tlist_raw((h), (n)), (n), member) + +/** + * tlist_prev - get the previous entry in a list + * @h: the tlist + * @n: the list element + * @member: the list_node member of the type + * + * Returns the element of list @h immediately before @n, or NULL, if + * @n is the first element in the list. + */ +#define tlist_prev(h, n, member) \ + list_prev(tlist_raw((h), (n)), (n), member) + /** * tlist_for_each - iterate through a list. * @h: the tlist