/* vim: set ts=4 sw=4 ai: * sq.c -- simple queue implementation derived from NetBSD's queue.h */ #include #include "sq.h" struct sqh *sq_new(void) { struct sqh *hd; hd = malloc(sizeof(*hd)); if (hd != NULL) sq_init(hd); return hd; } struct sqe *sq_elem_new(void *data) { struct sqe *e; e = malloc(sizeof(*e)); if (e != NULL) e->data = data; return e; } void sq_insert_head(struct sqh *hd, struct sqe *e) { if ((e->next = hd->first) == NULL) hd->last = &e->next; hd->first = e; } void sq_insert_tail(struct sqh *hd, struct sqe *e) { e->next = NULL; *hd->last = e; hd->last = &e->next; } void sq_insert_after(struct sqh *hd, struct sqe *e, struct sqe *n) { if ((n->next = e->next) == NULL) hd->last = &n->next; e->next = n; } void sq_remove_head(struct sqh *hd) { if ((hd->first = hd->first->next) == NULL) hd->last = &hd->first; } void sq_remove_after(struct sqh *hd, struct sqe *e) { if ((e->next = e->next->next) == NULL) hd->last = &e->next; } void sq_remove(struct sqh *hd, struct sqe *e) { if (hd->first == e) { if ((hd->first = hd->first->next) == NULL) hd->last = &hd->first; } else { struct sqe *cur = hd->first; while (cur->next != e) cur = cur->next; if ((cur->next = cur->next->next) == NULL) hd->last = &cur->next; } } void sq_concat(struct sqh *hd1, struct sqh *hd2) { if (!(hd2->first == NULL)) { *hd1->last = hd2->first; hd1->last = hd2->last; hd2->first = NULL; hd2->last = &hd2->first; } } void sq_cleanup(struct sqh *hd, void (*func)(void *)) { struct sqe *e, *t; sq_foreach_safe(e, hd, t) { sq_remove(hd, e); if (func) func(e->data); free(e); } } struct sqe *sq_find_from_data(struct sqh *hd, const void *data, int (*cmp)(const void *, const void *)) { struct sqe *e; if (hd && !sq_empty(hd)) sq_foreach(e, hd) if (e->data && cmp(e->data, data) == 0) return e; return NULL; }