diff options
Diffstat (limited to 'src/list.c')
-rw-r--r-- | src/list.c | 84 |
1 files changed, 59 insertions, 25 deletions
@@ -86,6 +86,46 @@ grecs_list_remove_entry(struct grecs_list *lp, struct grecs_list_entry *ent) lp->count--; } +void * +grecs_list_remove_tail(struct grecs_list *lp) +{ + void *data; + struct grecs_list_entry *ep; + + if (!lp || !lp->tail) + return NULL; + ep = lp->tail; + data = lp->tail->data; + grecs_list_remove_entry(lp, ep); + return data; +} + +static int +_ptrcmp(const void *a, const void *b) +{ + return a != b; +} + +int +grecs_list_remove(struct grecs_list *lp, void *data) +{ + struct grecs_list_entry *ep; + int (*cmp)(const void *, const void *); + + + if (!lp) + return 1; + + cmp = lp->cmp ? lp->cmp : _ptrcmp; + for (ep = lp->head; ep; ep = ep->next) { + if (cmp(ep->data, data) == 0) { + grecs_list_remove_entry(lp, ep); + return 0; + } + } + return 1; +} + void grecs_list_append(struct grecs_list *lp, void *val) { @@ -123,7 +163,11 @@ void * grecs_list_pop(struct grecs_list *lp) { void *data; - struct grecs_list_entry *ep = lp->head; + struct grecs_list_entry *ep; + + if (!lp) + return NULL; + ep = lp->head; if (ep) { data = ep->data; grecs_list_remove_entry(lp, ep); @@ -132,25 +176,14 @@ grecs_list_pop(struct grecs_list *lp) return data; } -void * -grecs_list_remove_tail(struct grecs_list *lp) -{ - void *data; - struct grecs_list_entry *ep; - - if (!lp->tail) - return NULL; - ep = lp->tail; - data = lp->tail->data; - grecs_list_remove_entry(lp, ep); - return data; -} - void grecs_list_clear(struct grecs_list *lp) { - struct grecs_list_entry *ep = lp->head; + struct grecs_list_entry *ep; + if (!lp) + return; + ep = lp->head; while (ep) { struct grecs_list_entry *next = ep->next; if (lp->free_entry) @@ -171,17 +204,16 @@ grecs_list_free(struct grecs_list *lp) } } -static int -_ptrcmp(const void *a, const void *b) -{ - return a != b; -} - void * grecs_list_locate(struct grecs_list *lp, void *data) { struct grecs_list_entry *ep; - int (*cmp)(const void *, const void *) = lp->cmp ? lp->cmp : _ptrcmp; + int (*cmp)(const void *, const void *); + + if (!lp) + return NULL; + + cmp = lp->cmp ? lp->cmp : _ptrcmp; for (ep = lp->head; ep; ep = ep->next) { if (cmp(ep->data, data) == 0) @@ -194,7 +226,9 @@ void * grecs_list_index(struct grecs_list *lp, size_t idx) { struct grecs_list_entry *ep; - + + if (!lp) + return NULL; for (ep = lp->head; ep && idx; ep = ep->next, idx--) ; return ep ? ep->data : NULL; @@ -219,7 +253,7 @@ grecs_list_compare(struct grecs_list *a, struct grecs_list *b) cmp = a->cmp ? a->cmp : _ptrcmp; for (ap = a->head, bp = b->head; ap; ap = ap->next, bp = bp->next) - if (cmp (ap->data, bp->data)) + if (cmp(ap->data, bp->data)) return 1; return 0; |