X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Flist%2Ftest%2Frun.c;h=306744598e2461a5bd6eb28de70593c7b009088e;hp=ac318e1a7fe484c75b072feeb7c5ac96bfca297c;hb=3d74240c155b68ae0d59a5942048aa1db3e29b01;hpb=0c492447b997ad50c289314a7ba41cca6bcc1c3c diff --git a/ccan/list/test/run.c b/ccan/list/test/run.c index ac318e1a..30674459 100644 --- a/ccan/list/test/run.c +++ b/ccan/list/test/run.c @@ -1,6 +1,7 @@ -#include "list/list.h" -#include "tap/tap.h" -#include "list/list.c" +#include +#include +#include +#include "helper.h" struct parent { const char *name; @@ -18,13 +19,18 @@ static LIST_HEAD(static_list); int main(int argc, char *argv[]) { struct parent parent; - struct child c1, c2, c3, *c, *n; + struct child c1, c2, c3, x1, *c, *n; unsigned int i; + struct list_head list = LIST_HEAD_INIT(list); + opaque_t *q, *nq; + struct list_head opaque_list = LIST_HEAD_INIT(opaque_list); - plan_tests(44); - /* Test LIST_HEAD, list_empty and check_list */ + plan_tests(84); + /* Test LIST_HEAD, LIST_HEAD_INIT, list_empty and check_list */ ok1(list_empty(&static_list)); ok1(list_check(&static_list, NULL)); + ok1(list_empty(&list)); + ok1(list_check(&list, NULL)); parent.num_children = 0; list_head_init(&parent.children); @@ -71,9 +77,19 @@ int main(int argc, char *argv[]) /* Test list_check */ ok1(list_check(&parent.children, NULL)); + /* Test list_check_node */ + ok1(list_check_node(&c1.list, NULL)); + ok1(list_check_node(&c2.list, NULL)); + ok1(list_check_node(&c3.list, NULL)); + /* Test list_top */ ok1(list_top(&parent.children, struct child, list) == &c1); + /* Test list_pop */ + ok1(list_pop(&parent.children, struct child, list) == &c1); + ok1(list_top(&parent.children, struct child, list) == &c2); + list_add(&parent.children, &c1.list); + /* Test list_tail */ ok1(list_tail(&parent.children, struct child, list) == &c3); @@ -96,21 +112,42 @@ int main(int argc, char *argv[]) } ok1(i == 3); - /* Test list_for_each_safe and list_del. */ + /* Test list_for_each_rev. */ i = 0; - list_for_each_safe(&parent.children, c, n, list) { + list_for_each_rev(&parent.children, c, list) { switch (i++) { case 0: + ok1(c == &c3); + break; + case 1: + ok1(c == &c2); + break; + case 2: ok1(c == &c1); break; + } + if (i > 2) + break; + } + ok1(i == 3); + + /* Test list_for_each_safe, list_del and list_del_from. */ + i = 0; + list_for_each_safe(&parent.children, c, n, list) { + switch (i++) { + case 0: + ok1(c == &c1); + list_del(&c->list); + break; case 1: ok1(c == &c2); + list_del_from(&parent.children, &c->list); break; case 2: ok1(c == &c3); + list_del_from(&parent.children, &c->list); break; } - list_del(&c->list); ok1(list_check(&parent.children, NULL)); if (i > 2) break; @@ -118,8 +155,122 @@ int main(int argc, char *argv[]) ok1(i == 3); ok1(list_empty(&parent.children)); - /* Test list_top/list_tail on empty list. */ + /* Test list_node_init: safe to list_del after this. */ + list_node_init(&c->list); + list_del(&c->list); + + /* Test list_del_init */ + list_add(&parent.children, &c->list); + ok1(!list_empty(&parent.children)); + list_del_init(&c->list); + ok1(list_empty(&parent.children)); + /* We can call this as many times as we like. */ + list_del_init(&c->list); + list_del_init(&c->list); + + /* Test list_for_each_off. */ + list_add_tail(&opaque_list, + (struct list_node *)create_opaque_blob()); + list_add_tail(&opaque_list, + (struct list_node *)create_opaque_blob()); + list_add_tail(&opaque_list, + (struct list_node *)create_opaque_blob()); + + i = 0; + + list_for_each_off(&opaque_list, q, 0) { + i++; + ok1(if_blobs_know_the_secret(q)); + } + ok1(i == 3); + + /* Test list_for_each_safe_off, list_del_off and list_del_from_off. */ + i = 0; + list_for_each_safe_off(&opaque_list, q, nq, 0) { + switch (i++) { + case 0: + ok1(if_blobs_know_the_secret(q)); + list_del_off(q, 0); + destroy_opaque_blob(q); + break; + case 1: + ok1(if_blobs_know_the_secret(q)); + list_del_from_off(&opaque_list, q, 0); + destroy_opaque_blob(q); + break; + case 2: + ok1(c == &c3); + list_del_from_off(&opaque_list, q, 0); + destroy_opaque_blob(q); + break; + } + ok1(list_check(&opaque_list, NULL)); + if (i > 2) + break; + } + ok1(i == 3); + ok1(list_empty(&opaque_list)); + + /* Test list_top/list_tail/list_pop on empty list. */ ok1(list_top(&parent.children, struct child, list) == NULL); ok1(list_tail(&parent.children, struct child, list) == NULL); + ok1(list_pop(&parent.children, struct child, list) == NULL); + + /* Test list_add_before and list_add_after */ + list_add(&parent.children, &c1.list); + list_add_after(&parent.children, &c1.list, &c2.list); + ok1(list_check(&parent.children, "list_add_after")); + + i = 0; + list_for_each(&parent.children, c, list) { + switch (i++) { + case 0: + ok1(c == &c1); + break; + case 1: + ok1(c == &c2); + break; + } + } + ok1(i == 2); + + list_add_before(&parent.children, &c2.list, &c3.list); + ok1(list_check(&parent.children, "list_add_before")); + + i = 0; + list_for_each(&parent.children, c, list) { + switch (i++) { + case 0: + ok1(c == &c1); + break; + case 1: + ok1(c == &c3); + break; + case 2: + ok1(c == &c2); + break; + } + } + ok1(i == 3); + + /* test list_swap */ + list_swap(&c3.list, &x1.list); + ok1(list_check(&parent.children, "list_swap")); + i = 0; + list_for_each(&parent.children, c, list) { + switch (i++) { + case 0: + ok1(c == &c1); + break; + case 1: + ok1(c == &x1); + break; + case 2: + ok1(c == &c2); + break; + } + } + ok1(i == 3); + return exit_status(); }