* BIRD Library -- Linked Lists
*
* (c) 1998 Martin Mares <mj@ucw.cz>
- * (c) 2015, 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+ * (c) 2015, 2020-2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
* similar to that used in the &fib structure.
*/
+#include <assert.h>
#include <stdlib.h>
#include <string.h>
+
#include "contrib/ucw/lists.h"
#include "contrib/mempattern.h"
void
add_tail(list_t *l, node_t *n)
{
- node_t *z = l->tail;
+ node_t *z = &l->tail;
- n->next = (node_t *) &l->null;
- n->prev = z;
- z->next = n;
- l->tail = n;
+ n->next = z;
+ n->prev = z->prev;
+ z->prev->next = n;
+ z->prev = n;
+ assert(z->next == NULL);
}
/**
void
add_head(list_t *l, node_t *n)
{
- node_t *z = l->head;
+ node_t *z = &l->head;
- n->next = z;
- n->prev = (node_t *) &l->head;
- z->prev = n;
- l->head = n;
+ n->next = z->next;
+ n->prev = z;
+ z->next->prev = n;
+ z->next = n;
+ assert(z->prev == NULL);
}
/**
void
init_list(list_t *l)
{
- l->head = (node_t *) &l->null;
- l->null = NULL;
- l->tail = (node_t *) &l->head;
+ l->head.next = &l->tail;
+ l->head.prev = NULL;
+ l->tail.next = NULL;
+ l->tail.prev = &l->head;
}
/**
void
add_tail_list(list_t *to, list_t *l)
{
- node_t *p = to->tail;
- node_t *q = l->head;
+ node_t *p = to->tail.prev;
+ node_t *q = l->head.next;
p->next = q;
q->prev = p;
- q = l->tail;
- q->next = (node_t *) &to->null;
- to->tail = q;
+ to->tail.prev = l->tail.prev;
}
/**
* BIRD Library -- Linked Lists
*
* (c) 1998 Martin Mares <mj@ucw.cz>
- * (c) 2015, 2020 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
+ * (c) 2015, 2020-2021 CZ.NIC, z.s.p.o. <knot-dns@labs.nic.cz>
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#pragma once
-/*
- * I admit the list structure is very tricky and also somewhat awkward,
- * but it's both efficient and easy to manipulate once one understands the
- * basic trick: The list head always contains two synthetic nodes which are
- * always present in the list: the head and the tail. But as the `next'
- * entry of the tail and the `prev' entry of the head are both NULL, the
- * nodes can overlap each other:
- *
- * head head_node.next
- * null head_node.prev tail_node.next
- * tail tail_node.prev
- */
-
#include <string.h>
#include "libknot/mm_ctx.h"
struct node *next, *prev;
} node_t;
-typedef struct list { /* In fact two overlayed nodes */
- struct node *head, *null, *tail;
+typedef struct list {
+ node_t head, tail;
} list_t;
#define NODE (node_t *)
-#define HEAD(list) ((void *)((list).head))
-#define TAIL(list) ((void *)((list).tail))
+#define HEAD(list) ((void *)((list).head.next))
+#define TAIL(list) ((void *)((list).tail.prev))
#define WALK_LIST(n,list) for(n=HEAD(list);(NODE (n))->next; \
n=(void *)((NODE (n))->next))
#define WALK_LIST_DELSAFE(n,nxt,list) \
#define WALK_LIST_BACKWARDS_DELSAFE(n,prv,list) \
for(n=TAIL(list); prv=(void *)((NODE (n))->prev); n=(void *) prv)
-#define EMPTY_LIST(list) (!(list).head->next)
+#define EMPTY_LIST(list) (!(NODE HEAD(list))->next)
/*! \brief Free every node in the list. */
#define WALK_LIST_FREE(list) \