1 /*
2  *	BIRD Library -- Linked Lists
3  *
4  *	(c) 1998 Martin Mares <mj@ucw.cz>
5  *	(c) 2015, 2020-2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
6  *
7  *	Can be freely distributed and used under the terms of the GNU GPL.
8  */
9 
10 #pragma once
11 
12 #include <string.h>
13 #include "libknot/mm_ctx.h"
14 
15 typedef struct node {
16   struct node *next, *prev;
17 } node_t;
18 
19 typedef struct list {
20   node_t head, tail;
21 } list_t;
22 
23 #define NODE (node_t *)
24 #define HEAD(list) ((void *)((list).head.next))
25 #define TAIL(list) ((void *)((list).tail.prev))
26 #define WALK_LIST(n,list) for(n=HEAD(list);(NODE (n))->next; \
27 				n=(void *)((NODE (n))->next))
28 #define WALK_LIST_DELSAFE(n,nxt,list) \
29      for(n=HEAD(list); (nxt=(void *)((NODE (n))->next)); n=(void *) nxt)
30 /* WALK_LIST_FIRST supposes that called code removes each processed node */
31 #define WALK_LIST_FIRST(n,list) \
32      while(n=HEAD(list), (NODE (n))->next)
33 #define WALK_LIST_BACKWARDS(n,list) for(n=TAIL(list);(NODE (n))->prev; \
34 				n=(void *)((NODE (n))->prev))
35 #define WALK_LIST_BACKWARDS_DELSAFE(n,prv,list) \
36      for(n=TAIL(list); prv=(void *)((NODE (n))->prev); n=(void *) prv)
37 
38 #define EMPTY_LIST(list) (!(NODE HEAD(list))->next)
39 
40 /*! \brief Free every node in the list. */
41 #define WALK_LIST_FREE(list) \
42 	do { \
43 	node_t *n=0,*nxt=0;  \
44 	WALK_LIST_DELSAFE(n,nxt,list) { \
45 	    free(n); \
46 	} \
47 	init_list(&list); \
48 	} while(0)
49 
50 void add_tail(list_t *, node_t *);
51 void add_head(list_t *, node_t *);
52 void rem_node(node_t *);
53 void add_tail_list(list_t *, list_t *);
54 void init_list(list_t *);
55 void insert_node(node_t *, node_t *);
56 void list_dup(list_t *dst, list_t *src, size_t itemsz);
57 size_t list_size(const list_t *);
58 
59 /*!
60  * \brief Generic pointer list implementation.
61  */
62 typedef struct ptrnode {
63 	node_t n;
64 	void *d;
65 } ptrnode_t;
66 
67 ptrnode_t *ptrlist_add(list_t *, void *, knot_mm_t *);
68 void ptrlist_free(list_t *, knot_mm_t *);
69 void ptrlist_rem(ptrnode_t *node, knot_mm_t *mm);
70 void ptrlist_deep_free(list_t *, knot_mm_t *);
71 
72 typedef void (*ptrlist_free_cb)(void *);
73 void ptrlist_free_custom(list_t *l, knot_mm_t *mm, ptrlist_free_cb free_cb);
74