int list_verify (list_t * list) { lnode_t *node = list_first_priv (list), *nil = list_nil (list); listcount_t count = list_count (list); if (node->prev != nil) { return 0; } if (count > list->maxcount) { return 0; } while (node != nil && count--) { if (node->next->prev != node) { return 0; } node = node->next; } if (count != 0 || node != nil) { return 0; } return 1; }
lnode_t *list_next(list_t *list, lnode_t *lnode) { assert (list_contains(list, lnode)); if (lnode->next == list_nil(list)) return NULL; return lnode->next; }
lnode_t *list_prev(list_t *list, lnode_t *lnode) { assert (list_contains(list, lnode)); if (lnode->prev == list_nil(list)) return NULL; return lnode->prev; }
lnode_t *list_find(list_t *list, const void *key, int compare(const void *, const void *)) { lnode_t *node; for (node = list_first_priv(list); node != list_nil(list); node = node->next) { if (compare(lnode_get(node), key) == 0) return node; } return 0; }
int list_contains(list_t *list, lnode_t *node) { lnode_t *n, *nil = list_nil(list); for (n = list_first_priv(list); n != nil; n = lnode_next(n)) { if (node == n) return 1; } return 0; }
void list_process (list_t * list, void *context, void (*function) (list_t * list, lnode_t * lnode, void *context)) { lnode_t *node = list_first_priv (list), *next, *nil = list_nil (list); while (node != nil) { /* check for callback function deleting */ /* the next node from under us */ nassert (list_contains (list, node)); next = node->next; function (list, node, context); node = next; } }
void list_return_nodes(list_t *list, lnodepool_t *pool) { lnode_t *lnode = list_first_priv(list), *tmp, *nil = list_nil(list); while (lnode != nil) { tmp = lnode->next; lnode->next = NULL; lnode->prev = NULL; lnode_return(pool, lnode); lnode = tmp; } list_init(list, list->maxcount); }
void list_destroy_nodes(list_t *list) { lnode_t *lnode = list_first_priv(list), *nil = list_nil(list), *tmp; while (lnode != nil) { tmp = lnode->next; lnode->next = NULL; lnode->prev = NULL; lnode_destroy(lnode); lnode = tmp; } list_init(list, list->maxcount); }
void list_merge (list_t * dest, list_t * sour, int compare (const void *, const void *)) { lnode_t *dn, *sn, *tn; lnode_t *d_nil = list_nil (dest), *s_nil = list_nil (sour); /* Nothing to do if source and destination list are the same. */ if (dest == sour) return; /* overflow check */ nassert (list_count (sour) + list_count (dest) >= list_count (sour)); /* lists must be sorted */ nassert (list_is_sorted (sour, compare)); nassert (list_is_sorted (dest, compare)); dn = list_first_priv (dest); sn = list_first_priv (sour); while (dn != d_nil && sn != s_nil) { if (compare (lnode_get (dn), lnode_get (sn)) >= 0) { tn = lnode_next (sn); list_delete (sour, sn); list_ins_before (dest, sn, dn); sn = tn; } else { dn = lnode_next (dn); } } if (dn != d_nil) return; if (sn != s_nil) list_transfer (dest, sour, sn); }
int list_is_sorted(list_t *list, int compare(const void *, const void *)) { lnode_t *node, *next, *nil; next = nil = list_nil(list); node = list_first_priv(list); if (node != nil) next = lnode_next(node); for (; next != nil; node = next, next = lnode_next(next)) { if (compare(lnode_get(node), lnode_get(next)) > 0) return 0; } return 1; }
void list_ins_before(list_t *list, lnode_t *node, lnode_t *succ) { lnode_t *pred = succ->prev; assert (node != NULL); assert (!list_contains(list, node)); assert (!lnode_is_in_a_list(node)); assert (succ == list_nil(list) || list_contains(list, succ)); assert (list->nodecount + 1 > list->nodecount); node->next = succ; node->prev = pred; pred->next = node; succ->prev = node; list->nodecount++; assert (list->nodecount <= list->maxcount); }
void list_ins_after(list_t *list, lnode_t *node, lnode_t *pred) { lnode_t *succ = pred->next; assert (node != NULL); assert (!list_contains(list, node)); assert (!lnode_is_in_a_list(node)); assert (pred == list_nil(list) || list_contains(list, pred)); assert (list->nodecount + 1 > list->nodecount); node->prev = pred; node->next = succ; succ->prev = node; pred->next = node; list->nodecount++; assert (list->nodecount <= list->maxcount); }
void list_extract (list_t * dest, list_t * source, lnode_t * first, lnode_t * last) { listcount_t moved = 1; nassert (first == NULL || list_contains (source, first)); nassert (last == NULL || list_contains (source, last)); if (first == NULL || last == NULL) return; /* adjust the destination list so that the slice is spliced out */ first->prev->next = last->next; last->next->prev = first->prev; /* graft the splice at the end of the dest list */ last->next = &dest->nilnode; first->prev = dest->nilnode.prev; dest->nilnode.prev->next = first; dest->nilnode.prev = last; while (first != last) { first = first->next; nassert (first != list_nil (source)); /* oops, last before first! */ moved++; } /* nassert no overflows */ nassert (source->nodecount - moved <= source->nodecount); nassert (dest->nodecount + moved >= dest->nodecount); /* nassert no weirdness */ nassert (moved <= source->nodecount); source->nodecount -= moved; dest->nodecount += moved; /* nassert list sanity */ nassert (list_verify (source)); nassert (list_verify (dest)); }
void list_ins_before (list_t * list, lnode_t * newnode, lnode_t * thisnode) { lnode_t *that = thisnode->prev; nassert (newnode != NULL); nassert (!list_contains (list, newnode)); nassert (!lnode_is_in_a_list (newnode)); nassert (thisnode == list_nil (list) || list_contains (list, thisnode)); nassert (list->nodecount + 1 > list->nodecount); newnode->next = thisnode; newnode->prev = that; that->next = newnode; thisnode->prev = newnode; list->nodecount++; nassert (list->nodecount <= list->maxcount); }