diff options
Diffstat (limited to 'libqueue/queue/stq.c')
| -rw-r--r-- | libqueue/queue/stq.c | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/libqueue/queue/stq.c b/libqueue/queue/stq.c new file mode 100644 index 0000000..a39a608 --- /dev/null +++ b/libqueue/queue/stq.c @@ -0,0 +1,105 @@ +/* vim: set ts=4 sw=4 ai: + * stq.c -- singly linked tail queue implementation derived from NetBSD's queue.h + */ + +#include <stdlib.h> +#include "stq.h" + +struct stqh *stq_new(void) +{ + struct stqh *hd; + + hd = malloc(sizeof(*hd)); + if (hd != NULL) + stq_init(hd); + + return hd; +} + +struct stqe *stq_elem_new(void *data) +{ + struct stqe *e; + + e = malloc(sizeof(*e)); + if (e != NULL) + e->data = data; + + return e; +} + +void stq_insert_head(struct stqh *hd, struct stqe *e) +{ + if ((e->next = hd->first) == NULL) + hd->last = &e->next; + hd->first = e; +} + +void stq_insert_tail(struct stqh *hd, struct stqe *e) +{ + e->next = NULL; + *hd->last = e; + hd->last = &e->next; +} + +void stq_insert_after(struct stqh *hd, struct stqe *e, struct stqe *n) +{ + if ((n->next = e->next) == NULL) + hd->last = &n->next; + e->next = n; +} + +void stq_remove_head(struct stqh *hd) +{ + if ((hd->first = hd->first->next) == NULL) + hd->last = &hd->first; +} + +void stq_remove(struct stqh *hd, struct stqe *e) +{ + if (hd->first == (e)) { + if ((hd->first = hd->first->next) == NULL) + hd->last = &hd->first; + } + else { + struct stqe *cur = hd->first; + while (cur->next != (e)) + cur = cur->next; + if ((cur->next = cur->next->next) == NULL) + hd->last = &cur->next; + } +} + +void stq_concat(struct stqh *hd1, struct stqh *hd2) +{ + if (!(hd2->first == NULL)) { + *hd1->last = hd2->first; + hd1->last = hd2->last; + hd2->first = NULL; + hd2->last = &hd2->first; + } +} + +void stq_cleanup(struct stqh *hd, void (*func)(void *)) +{ + struct stqe *e, *t; + + stq_foreach_safe(e, hd, t) { + stq_remove(hd, e); + if (func) + func(e->data); + free(e); + } +} + +struct stqe *stq_find_from_data(struct stqh *hd, const void *data, int (*cmp)(const void *, const void *)) +{ + struct stqe *e; + + if (hd && stq_empty(hd)) + stq_foreach(e, hd) + if (e->data && cmp(e->data, data) == 0) + return e; + + return NULL; +} + |
