mirror of
https://github.com/samba-team/samba.git
synced 2025-03-09 08:58:35 +03:00
CCAN includes a little utility called "namespacize" which prepends ccan_ to all public methods of a module, and fixes up any dependencies it finds. It's a little primitive, but it works here. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
266 lines
7.5 KiB
C
266 lines
7.5 KiB
C
/* Licensed under LGPL - see LICENSE file for details */
|
|
#ifndef CCAN_TLIST_H
|
|
#define CCAN_TLIST_H
|
|
#include <ccan/list/list.h>
|
|
#include <ccan/tcon/tcon.h>
|
|
|
|
/**
|
|
* TLIST_TYPE - declare a typed list type (struct tlist)
|
|
* @suffix: the name to use (struct tlist_@suffix)
|
|
* @type: the type the list will contain (void for any type)
|
|
*
|
|
* This declares a structure "struct tlist_@suffix" to use for
|
|
* lists containing this type. The actual list can be accessed using
|
|
* ".raw" or tlist_raw().
|
|
*
|
|
* Example:
|
|
* // Defines struct tlist_children
|
|
* TLIST_TYPE(children, struct child);
|
|
* struct parent {
|
|
* const char *name;
|
|
* struct tlist_children children;
|
|
* unsigned int num_children;
|
|
* };
|
|
*
|
|
* struct child {
|
|
* const char *name;
|
|
* struct ccan_list_node list;
|
|
* };
|
|
*/
|
|
#define TLIST_TYPE(suffix, type) \
|
|
struct tlist_##suffix { \
|
|
struct ccan_list_head raw; \
|
|
TCON(type *canary); \
|
|
}
|
|
|
|
/**
|
|
* TLIST_INIT - initalizer for an empty tlist
|
|
* @name: the name of the list.
|
|
*
|
|
* Explicit initializer for an empty list.
|
|
*
|
|
* See also:
|
|
* tlist_init()
|
|
*
|
|
* Example:
|
|
* static struct tlist_children my_list = TLIST_INIT(my_list);
|
|
*/
|
|
#define TLIST_INIT(name) { CCAN_LIST_HEAD_INIT(name.raw) }
|
|
|
|
/**
|
|
* tlist_check - check head of a list for consistency
|
|
* @h: the tlist_head
|
|
* @abortstr: the location to print on aborting, or NULL.
|
|
*
|
|
* Because list_nodes have redundant information, consistency checking between
|
|
* the back and forward links can be done. This is useful as a debugging check.
|
|
* If @abortstr is non-NULL, that will be printed in a diagnostic if the list
|
|
* is inconsistent, and the function will abort.
|
|
*
|
|
* Returns non-NULL if the list is consistent, NULL otherwise (it
|
|
* can never return NULL if @abortstr is set).
|
|
*
|
|
* See also: ccan_list_check()
|
|
*
|
|
* Example:
|
|
* static void dump_parent(struct parent *p)
|
|
* {
|
|
* struct child *c;
|
|
*
|
|
* printf("%s (%u children):\n", p->name, p->num_children);
|
|
* tlist_check(&p->children, "bad child list");
|
|
* tlist_for_each(&p->children, c, list)
|
|
* printf(" -> %s\n", c->name);
|
|
* }
|
|
*/
|
|
#define tlist_check(h, abortstr) \
|
|
ccan_list_check(&(h)->raw, (abortstr))
|
|
|
|
/**
|
|
* tlist_init - initialize a tlist
|
|
* @h: the tlist to set to the empty list
|
|
*
|
|
* Example:
|
|
* ...
|
|
* struct parent *parent = malloc(sizeof(*parent));
|
|
*
|
|
* tlist_init(&parent->children);
|
|
* parent->num_children = 0;
|
|
*/
|
|
#define tlist_init(h) ccan_list_head_init(&(h)->raw)
|
|
|
|
/**
|
|
* tlist_raw - unwrap the typed list and check the type
|
|
* @h: the tlist
|
|
* @expr: the expression to check the type against (not evaluated)
|
|
*
|
|
* This macro usually causes the compiler to emit a warning if the
|
|
* variable is of an unexpected type. It is used internally where we
|
|
* need to access the raw underlying list.
|
|
*/
|
|
#define tlist_raw(h, expr) (&tcon_check((h), canary, (expr))->raw)
|
|
|
|
/**
|
|
* tlist_add - add an entry at the start of a linked list.
|
|
* @h: the tlist to add the node to
|
|
* @n: the entry to add to the list.
|
|
* @member: the member of n to add to the list.
|
|
*
|
|
* The entry's ccan_list_node does not need to be initialized; it will be
|
|
* overwritten.
|
|
* Example:
|
|
* struct child *child = malloc(sizeof(*child));
|
|
*
|
|
* child->name = "marvin";
|
|
* tlist_add(&parent->children, child, list);
|
|
* parent->num_children++;
|
|
*/
|
|
#define tlist_add(h, n, member) ccan_list_add(tlist_raw((h), (n)), &(n)->member)
|
|
|
|
/**
|
|
* tlist_add_tail - add an entry at the end of a linked list.
|
|
* @h: the tlist to add the node to
|
|
* @n: the entry to add to the list.
|
|
* @member: the member of n to add to the list.
|
|
*
|
|
* The ccan_list_node does not need to be initialized; it will be overwritten.
|
|
* Example:
|
|
* tlist_add_tail(&parent->children, child, list);
|
|
* parent->num_children++;
|
|
*/
|
|
#define tlist_add_tail(h, n, member) \
|
|
ccan_list_add_tail(tlist_raw((h), (n)), &(n)->member)
|
|
|
|
/**
|
|
* tlist_del_from - delete an entry from a linked list.
|
|
* @h: the tlist @n is in
|
|
* @n: the entry to delete
|
|
* @member: the member of n to remove from the list.
|
|
*
|
|
* This explicitly indicates which list a node is expected to be in,
|
|
* which is better documentation and can catch more bugs.
|
|
*
|
|
* Note that this leaves @n->@member in an undefined state; it
|
|
* can be added to another list, but not deleted again.
|
|
*
|
|
* See also: tlist_del()
|
|
*
|
|
* Example:
|
|
* tlist_del_from(&parent->children, child, list);
|
|
* parent->num_children--;
|
|
*/
|
|
#define tlist_del_from(h, n, member) \
|
|
ccan_list_del_from(tlist_raw((h), (n)), &(n)->member)
|
|
|
|
/**
|
|
* tlist_del - delete an entry from an unknown linked list.
|
|
* @n: the entry to delete from the list.
|
|
* @member: the member of @n which is in the list.
|
|
*
|
|
* Example:
|
|
* tlist_del(child, list);
|
|
* parent->num_children--;
|
|
*/
|
|
#define tlist_del(n, member) \
|
|
ccan_list_del(&(n)->member)
|
|
|
|
/**
|
|
* tlist_empty - is a list empty?
|
|
* @h: the tlist
|
|
*
|
|
* If the list is empty, returns true.
|
|
*
|
|
* Example:
|
|
* assert(tlist_empty(&parent->children) == (parent->num_children == 0));
|
|
*/
|
|
#define tlist_empty(h) ccan_list_empty(&(h)->raw)
|
|
|
|
/**
|
|
* tlist_top - get the first entry in a list
|
|
* @h: the tlist
|
|
* @member: the ccan_list_node member of the type
|
|
*
|
|
* If the list is empty, returns NULL.
|
|
*
|
|
* Example:
|
|
* struct child *first;
|
|
* first = tlist_top(&parent->children, list);
|
|
*/
|
|
#define tlist_top(h, member) \
|
|
((tcon_type((h), canary)) \
|
|
ccan_list_top_(&(h)->raw, \
|
|
(char *)(&(h)->_tcon[0].canary->member) - \
|
|
(char *)((h)->_tcon[0].canary)))
|
|
|
|
/**
|
|
* tlist_tail - get the last entry in a list
|
|
* @h: the tlist
|
|
* @member: the ccan_list_node member of the type
|
|
*
|
|
* If the list is empty, returns NULL.
|
|
*
|
|
* Example:
|
|
* struct child *last;
|
|
* last = tlist_tail(&parent->children, list);
|
|
*/
|
|
#define tlist_tail(h, member) \
|
|
((tcon_type((h), canary)) \
|
|
ccan_list_tail_(&(h)->raw, \
|
|
(char *)(&(h)->_tcon[0].canary->member) - \
|
|
(char *)((h)->_tcon[0].canary)))
|
|
|
|
/**
|
|
* tlist_for_each - iterate through a list.
|
|
* @h: the tlist
|
|
* @i: an iterator of suitable type for this list.
|
|
* @member: the ccan_list_node member of @i
|
|
*
|
|
* This is a convenient wrapper to iterate @i over the entire list. It's
|
|
* a for loop, so you can break and continue as normal.
|
|
*
|
|
* Example:
|
|
* tlist_for_each(&parent->children, child, list)
|
|
* printf("Name: %s\n", child->name);
|
|
*/
|
|
#define tlist_for_each(h, i, member) \
|
|
ccan_list_for_each(tlist_raw((h), (i)), (i), member)
|
|
|
|
/**
|
|
* tlist_for_each - iterate through a list backwards.
|
|
* @h: the tlist
|
|
* @i: an iterator of suitable type for this list.
|
|
* @member: the ccan_list_node member of @i
|
|
*
|
|
* This is a convenient wrapper to iterate @i over the entire list. It's
|
|
* a for loop, so you can break and continue as normal.
|
|
*
|
|
* Example:
|
|
* tlist_for_each_rev(&parent->children, child, list)
|
|
* printf("Name: %s\n", child->name);
|
|
*/
|
|
#define tlist_for_each_rev(h, i, member) \
|
|
ccan_list_for_each_rev(tlist_raw((h), (i)), (i), member)
|
|
|
|
/**
|
|
* tlist_for_each_safe - iterate through a list, maybe during deletion
|
|
* @h: the tlist
|
|
* @i: an iterator of suitable type for this list.
|
|
* @nxt: another iterator to store the next entry.
|
|
* @member: the ccan_list_node member of the structure
|
|
*
|
|
* This is a convenient wrapper to iterate @i over the entire list. It's
|
|
* a for loop, so you can break and continue as normal. The extra variable
|
|
* @nxt is used to hold the next element, so you can delete @i from the list.
|
|
*
|
|
* Example:
|
|
* struct child *next;
|
|
* tlist_for_each_safe(&parent->children, child, next, list) {
|
|
* tlist_del(child, list);
|
|
* parent->num_children--;
|
|
* }
|
|
*/
|
|
#define tlist_for_each_safe(h, i, nxt, member) \
|
|
ccan_list_for_each_safe(tlist_raw((h), (i)), (i), (nxt), member)
|
|
|
|
#endif /* CCAN_TLIST_H */
|