Merge branch 'master' of ctdb into 'master' of samba
[samba.git] / lib / ccan / list / list.c
1 /* Licensed under LGPLv2.1+ - see LICENSE file for details */
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "list.h"
5
6 static void *corrupt(const char *abortstr,
7                      const struct ccan_list_node *head,
8                      const struct ccan_list_node *node,
9                      unsigned int count)
10 {
11         if (abortstr) {
12                 fprintf(stderr,
13                         "%s: prev corrupt in node %p (%u) of %p\n",
14                         abortstr, node, count, head);
15                 abort();
16         }
17         return NULL;
18 }
19
20 struct ccan_list_node *ccan_list_check_node(const struct ccan_list_node *node,
21                                   const char *abortstr)
22 {
23         const struct ccan_list_node *p, *n;
24         int count = 0;
25
26         for (p = node, n = node->next; n != node; p = n, n = n->next) {
27                 count++;
28                 if (n->prev != p)
29                         return corrupt(abortstr, node, n, count);
30         }
31         /* Check prev on head node. */
32         if (node->prev != p)
33                 return corrupt(abortstr, node, node, 0);
34
35         return (struct ccan_list_node *)node;
36 }
37
38 struct ccan_list_head *ccan_list_check(const struct ccan_list_head *h, const char *abortstr)
39 {
40         if (!ccan_list_check_node(&h->n, abortstr))
41                 return NULL;
42         return (struct ccan_list_head *)h;
43 }