diff options
Diffstat (limited to 'libqueue/queue/dl.c')
| -rw-r--r-- | libqueue/queue/dl.c | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/libqueue/queue/dl.c b/libqueue/queue/dl.c new file mode 100644 index 0000000..65e024d --- /dev/null +++ b/libqueue/queue/dl.c @@ -0,0 +1,103 @@ +/* vim: set ts=4 sw=4 ai: + * dl.c -- doubly linked list implementation derived from NetBSD's queue.h + */ + +#include <stdlib.h> +#include "dl.h" + +struct dlh *dl_new(void) +{ + struct dlh *hd; + + hd = malloc(sizeof(*hd)); + if (hd != NULL) + dl_init(hd); + + return hd; +} + +struct dle *dl_elem_new(void *data) +{ + struct dle *e; + + e = malloc(sizeof(*e)); + if (e != NULL) + e->data = data; + + return e; +} + +void dl_insert_after(struct dle *e, struct dle *n) +{ + if ((n->next = e->next) != NULL) + e->next->pprev = &n->next; + e->next = n; + n->pprev = &e->next; +} + +void dl_insert_before(struct dle *e, struct dle *n) +{ + n->pprev = e->pprev; + n->next = e; + *e->pprev = n; + e->pprev = &n->next; +} + +void dl_insert_head(struct dlh *hd, struct dle *e) +{ + if ((e->next = hd->first) != NULL) + hd->first->pprev = &e->next; + hd->first = e; + e->pprev = &hd->first; +} + +void dl_remove(struct dlh *hd, struct dle *e) +{ + if (e->next != NULL) + e->next->pprev = e->pprev; + *e->pprev = e->next; +} + +void dl_replace(struct dle *e1, struct dle *e2) +{ + if ((e2->next = e1->next) != NULL) + e2->next->pprev = &e2->next; + e2->pprev = e1->pprev; + + *e2->pprev = e2; +} + +void dlist_move(struct dlh *hd1, struct dlh *hd2) +{ + hd2->first = NULL; + if (!(hd1->first == NULL)) + { + hd2->first = hd1->first; + hd2->first->pprev = &hd2->first; + hd1->first = NULL; + } +} + +void dl_cleanup(struct dlh *hd, void (*func)(void *)) +{ + struct dle *e, *t; + + dl_foreach_safe(e, hd, t) { + dl_remove(hd, e); + if (func) + func(e->data); + free(e); + } +} + +struct dle *dl_find_from_data(struct dlh *hd, const void *data, int (*cmp)(const void *, const void *)) +{ + struct dle *e; + + if (hd && !dl_empty(hd)) + dl_foreach(e, hd) + if (e->data && cmp(e->data, data) == 0) + return e; + + return NULL; +} |
