diff --git a/doc/libcfu.texi b/doc/libcfu.texi index ba0f0b4..d066b8f 100644 --- a/doc/libcfu.texi +++ b/doc/libcfu.texi @@ -514,6 +514,18 @@ cfulist_map(). The return value is used to build a new list. Pop a value from the end of the list (removing it from the list). @end deftypefun +@deftypefun {void} cfulist_delete_data (cfulist_t * @var{list}, void * @var{data}) + + Deletes the entry in the list associated with value. +@end deftypefun + +@deftypefun {void} cfulist_delete_data_with_free_fn (cfulist_t * @var{list}, void * @var{data}, cfulist_free_fn_t @var{ff}) + + Deletes the entry in the list associated with value. If ff is not NULL, it + is called for value of the entry passed as its only argument. + +@end deftypefun + @deftypefun {int} cfulist_unshift_data (cfulist_t * @var{list}, void * @var{data}, size_t @var{data_size}) Add a value at the beginning of the list. diff --git a/src/cfulist.c b/src/cfulist.c index b58846e..57736dd 100644 --- a/src/cfulist.c +++ b/src/cfulist.c @@ -418,6 +418,48 @@ cfulist_pop(cfulist_t *list) { return NULL; } +void +cfulist_delete_data(cfulist_t *list, void *data) { + cfulist_delete_data_with_free_fn(list, data, list->free_fn); + return; +} + +void +cfulist_delete_data_with_free_fn(cfulist_t *list, void *data, cfulist_free_fn_t free_fn) { + if (!list) { + return; + } + + lock_list(list); + + cfulist_entry *entry = list->entries; + while (entry) + { + if (entry->data == data) { + if (!entry->prev) { + if (entry->next) { + assert(list->num_entries > 1); + list->entries = entry->next; + list->entries->prev = NULL; + } else { + assert(list->num_entries == 1); + list->tail = NULL; + list->entries = NULL; + } + } else { + (entry->prev)->next = entry->next; + } + if (free_fn) free_fn(entry->data); + free (entry); + --list->num_entries; + break; + } + entry = entry->next; + } + + unlock_list(list); +} + int cfulist_unshift(cfulist_t *list, void *data) { return cfulist_unshift_data(list, data, 0); diff --git a/src/cfulist.h b/src/cfulist.h index e7cea4f..9531a07 100644 --- a/src/cfulist.h +++ b/src/cfulist.h @@ -79,6 +79,10 @@ int cfulist_push_data(cfulist_t *list, void *data, size_t data_size); /* Pop a value from the end of the list. */ int cfulist_pop_data(cfulist_t *list, void **data, size_t *data_size); +/* Deletes the entry in the list associated with value. */ +void cfulist_delete_data(cfulist_t *list, void *data); +void cfulist_delete_data_with_free_fn(cfulist_t *list, void *data, cfulist_free_fn_t free_fn); + /* Add a value at the beginning of the list. */ int cfulist_unshift_data(cfulist_t *list, void *data, size_t data_size);