Commit d81e79b8 authored by David Gibson's avatar David Gibson Committed by Rusty Russell

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: default avatarDavid Gibson <david@gibson.dropbear.id.au>
Signed-off-by: default avatarRusty Russell <rusty@rustcorp.com.au>
parent c23a40c7
#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;
}
#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;
}
#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;
}
#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;
}
......@@ -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));
......
......@@ -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
......
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