[ccan] [PATCH] tlist: Add tlist_next() and tlist_prev() functions

David Gibson david at gibson.dropbear.id.au
Sat Jun 4 20:21:33 AEST 2016


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 <david at gibson.dropbear.id.au>
---
 ccan/tlist/test/compile_fail-tlist_next.c  | 33 ++++++++++++++++++++++++++++++
 ccan/tlist/test/compile_fail-tlist_next2.c | 32 +++++++++++++++++++++++++++++
 ccan/tlist/test/compile_fail-tlist_prev.c  | 33 ++++++++++++++++++++++++++++++
 ccan/tlist/test/compile_fail-tlist_prev2.c | 32 +++++++++++++++++++++++++++++
 ccan/tlist/test/run.c                      | 14 ++++++++++++-
 ccan/tlist/tlist.h                         | 24 ++++++++++++++++++++++
 6 files changed, 167 insertions(+), 1 deletion(-)
 create mode 100644 ccan/tlist/test/compile_fail-tlist_next.c
 create mode 100644 ccan/tlist/test/compile_fail-tlist_next2.c
 create mode 100644 ccan/tlist/test/compile_fail-tlist_prev.c
 create mode 100644 ccan/tlist/test/compile_fail-tlist_prev2.c

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 0000000..02ae16a
--- /dev/null
+++ b/ccan/tlist/test/compile_fail-tlist_next.c
@@ -0,0 +1,33 @@
+#include <ccan/tlist/tlist.h>
+
+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 0000000..c67fb8e
--- /dev/null
+++ b/ccan/tlist/test/compile_fail-tlist_next2.c
@@ -0,0 +1,32 @@
+#include <ccan/tlist/tlist.h>
+
+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 0000000..5357eaa
--- /dev/null
+++ b/ccan/tlist/test/compile_fail-tlist_prev.c
@@ -0,0 +1,33 @@
+#include <ccan/tlist/tlist.h>
+
+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 0000000..c1a536d
--- /dev/null
+++ b/ccan/tlist/test/compile_fail-tlist_prev2.c
@@ -0,0 +1,32 @@
+#include <ccan/tlist/tlist.h>
+
+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 f94438e..06732cc 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 937a834..2897851 100644
--- a/ccan/tlist/tlist.h
+++ b/ccan/tlist/tlist.h
@@ -214,6 +214,30 @@
 		    (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
  * @i: an iterator of suitable type for this list.
-- 
2.5.5



More information about the ccan mailing list