X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=lib%2Fllist.c;h=dbb5352a66f02b29951803b8daa374102c9fd130;hb=86fb74fe51d96e63fd9576813064b23fb2476706;hp=9b6c29504f8618749d839e1729a1bc054da45f40;hpb=7aa651a6a4496d848f86de9b1e6b3a003256a01f;p=android-x86%2Fexternal-toybox.git diff --git a/lib/llist.c b/lib/llist.c index 9b6c2950..dbb5352a 100644 --- a/lib/llist.c +++ b/lib/llist.c @@ -5,15 +5,35 @@ #include "toys.h" +// Callback function to free data pointer of double_list or arg_list + +void llist_free_arg(void *node) +{ + struct arg_list *d = node; + + free(d->arg); + free(d); +} + +void llist_free_double(void *node) +{ + struct double_list *d = node; + + free(d->data); + free(d); +} + // Call a function (such as free()) on each element of a linked list. -void llist_traverse(void *list, void (*using)(void *data)) +void llist_traverse(void *list, void (*using)(void *node)) { + void *old = list; + while (list) { void *pop = llist_pop(&list); using(pop); // End doubly linked list too. - if (list==pop) break; + if (old == list) break; } } @@ -31,6 +51,19 @@ void *llist_pop(void *list) return (void *)next; } +void *dlist_pop(void *list) +{ + struct double_list **pdlist = (struct double_list **)list, *dlist = *pdlist; + + if (dlist->next == dlist) *pdlist = 0; + else { + dlist->next->prev = dlist->prev; + dlist->prev->next = *pdlist = dlist->next; + } + + return dlist; +} + void dlist_add_nomalloc(struct double_list **list, struct double_list *new) { if (*list) { @@ -52,3 +85,46 @@ struct double_list *dlist_add(struct double_list **list, char *data) return new; } + +// Terminate circular list for traversal in either direction. Returns end *. +void *dlist_terminate(void *list) +{ + struct double_list *end = list; + + if (!list) return 0; + + end = end->prev; + end->next->prev = 0; + end->next = 0; + + return end; +} + +// Find num in cache +struct num_cache *get_num_cache(struct num_cache *cache, long long num) +{ + while (cache) { + if (num==cache->num) return cache; + cache = cache->next; + } + + return 0; +} + +// Uniquely add num+data to cache. Updates *cache, returns pointer to existing +// entry if it was already there. +struct num_cache *add_num_cache(struct num_cache **cache, long long num, + void *data, int len) +{ + struct num_cache *old = get_num_cache(*cache, num); + + if (old) return old; + + old = xzalloc(sizeof(struct num_cache)+len); + old->next = *cache; + old->num = num; + memcpy(old->data, data, len); + *cache = old; + + return 0; +}