Commit 22ffb884 authored by Rusty Russell's avatar Rusty Russell

list: implement list_check_node to check list from node rather than head

parent 1f4312c3
......@@ -2,32 +2,40 @@
#include <stdlib.h>
#include "list.h"
struct list_head *list_check(const struct list_head *h, const char *abortstr)
struct list_node *list_check_node(const struct list_node *node,
const char *abortstr)
{
const struct list_node *n, *p;
const struct list_node *p, *n;
int count = 0;
if (h->n.next == &h->n) {
if (h->n.prev != &h->n) {
for (p = node, n = node->next; n != node; p = n, n = n->next) {
count++;
if (n->prev != p) {
if (!abortstr)
return NULL;
fprintf(stderr, "%s: prev corrupt in empty %p\n",
abortstr, h);
fprintf(stderr,
"%s: prev corrupt in node %p (%u) of %p\n",
abortstr, n, count, node);
abort();
}
return (struct list_head *)h;
}
return (struct list_node *)node;
}
for (p = &h->n, n = h->n.next; n != &h->n; p = n, n = n->next) {
count++;
if (n->prev != p) {
struct list_head *list_check(const struct list_head *h, const char *abortstr)
{
if (h->n.next == &h->n) {
if (h->n.prev != &h->n) {
if (!abortstr)
return NULL;
fprintf(stderr,
"%s: prev corrupt in node %p (%u) of %p\n",
abortstr, n, count, h);
fprintf(stderr, "%s: prev corrupt in empty %p\n",
abortstr, h);
abort();
}
return (struct list_head *)h;
}
if (!list_check_node(&h->n, abortstr))
return NULL;
return (struct list_head *)h;
}
......@@ -39,7 +39,7 @@ struct list_head
};
/**
* list_check - check a list for consistency
* list_check - check head of a list for consistency
* @h: the list_head
* @abortstr: the location to print on aborting, or NULL.
*
......@@ -51,6 +51,8 @@ struct list_head
* Returns the list head if the list is consistent, NULL if not (it
* can never return NULL if @abortstr is set).
*
* See also: list_check_node()
*
* Example:
* static void dump_parent(struct parent *p)
* {
......@@ -64,6 +66,25 @@ struct list_head
*/
struct list_head *list_check(const struct list_head *h, const char *abortstr);
/**
* list_check_node - check node of a list for consistency
* @n: the list_node
* @abortstr: the location to print on aborting, or NULL.
*
* Check consistency of the list node is in (it must be in one).
*
* See also: list_check()
*
* Example:
* static void dump_child(const struct child *c)
* {
* list_check_node(&c->list, "bad child list");
* printf("%s\n", c->name);
* }
*/
struct list_node *list_check_node(const struct list_node *n,
const char *abortstr);
#ifdef CCAN_LIST_DEBUG
#define debug_list(h) list_check((h), __func__)
#else
......
......@@ -21,7 +21,7 @@ int main(int argc, char *argv[])
struct child c1, c2, c3, *c, *n;
unsigned int i;
plan_tests(44);
plan_tests(47);
/* Test LIST_HEAD, list_empty and check_list */
ok1(list_empty(&static_list));
ok1(list_check(&static_list, NULL));
......@@ -71,6 +71,11 @@ 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);
......
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