/* vim: set ts=4 sw=4 ai: * sl.c -- singly linked list implementation derived from NetBSD's queue.h */ #include #include "sl.h" struct slh *sl_new(void) { struct slh *hd; hd = malloc(sizeof(*hd)); if (hd != NULL) sl_init(hd); return hd; } struct sle *sl_elem_new(void *data) { struct sle *e; e = malloc(sizeof(*e)); if (e != NULL) e->data = data; return e; } void sl_insert_after(struct sle *e, struct sle *n) { n->next = e->next; e->next = n; } void sl_insert_head(struct slh *hd, struct sle *e) { e->next = hd->first; hd->first = e; } void sl_remove_after(struct sle *e) { if (e->next != NULL) e->next = e->next->next; } void sl_remove_head(struct slh *hd) { if (hd->first != NULL) hd->first = hd->first->next; } void sl_remove(struct slh *hd, struct sle *e) { struct sle *cur; if (hd->first == e) { hd->first = hd->first->next; } else { cur = hd->first; while (cur->next != NULL && cur->next != e) cur = cur->next; if (cur->next == NULL) return; cur->next = cur->next->next; } } void sl_cleanup(struct slh *hd, void (*func)(void *)) { struct sle *e, *t; sl_foreach_safe(e, hd, t) { sl_remove(hd, e); if (func) func(e->data); free(e); } } struct sle *sl_find_from_data(struct slh *hd, const void *data, int (*cmp)(const void *, const void *)) { struct sle *e; if (hd && !sl_empty(hd)) sl_foreach(e, hd) if (e->data && cmp(e->data, data) == 0) return e; return NULL; }