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