ls_new, ls_free, ls_append, ls_push, ls_sort, ls_iter - manipulate linked lists
ls_list *ls_new(size_t size, void (*init)(void *));
void ls_free(void *list, void (*deinit)(void *));
ls_list *ls_append(void *dest, void *src);
ls_list *ls_push(void *dest, void *src);
ls_list *ls_sort(void *list, int nelem, int (*cmp)(const void *, const void *));
ls_list *ls_iter(void *list, int (*fn)(void *));
ls_new() - make new list
ls_free() - free list
ls_append() - append onto a list
ls_push() - push in front of a list
ls_sort() - sort a list
ls_iter() - iterate through a list
ls_new( ) allocates at least size bytes of memory for a list member, and calls init( ) on the memory. It returns NULL on failure.
ls_free( ) calls deinit( ) on the memory provided, and frees it. It is intended to be symmetrical with ls_new( ). ls_append( ) causes the list src to be appended to the list dest, and returns a pointer to dest. ls_push( ) causes the list src to be prepended to the list dest, and returns a pointer to the new head (which is src). ls_sort( ) causes the list list to be sorted, according to the comparison function cmp( ), and returns a pointer to the new head element. It assumes that list has nelem elements. (If nelem is -1, it counts items.) ls_iter( ) iterates through the list, calling fn( ) on each member, and stops when fn( ) returns non-zero. It returns a pointer to the item it stopped on, or NULL if it reached the end of the list.
None known. The code attempts to be robust in the handling of lists.
Arguably, the use of casts in here is shaky; it depends on the assumption that "pointer to struct foo" and "pointer to struct bar" are always compatible.