diff --git a/doc/libcfu.texi b/doc/libcfu.texi index 997290f..aacca70 100644 --- a/doc/libcfu.texi +++ b/doc/libcfu.texi @@ -514,6 +514,14 @@ cfulist_map(). The return value is used to build a new list. 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. If ff is not NULL, + it overrides any function set previously with cfulist_set_free_function(). + +@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 661b257..4bb1524 100644 --- a/src/cfulist.c +++ b/src/cfulist.c @@ -414,18 +414,25 @@ cfulist_pop(cfulist_t *list) { 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); - if (list->entries) { - cfulist_entry *entry = list->entries; - while (entry && entry->data != data) + cfulist_entry *entry = list->entries; + while (entry) + { + if (entry->data != data) { entry = entry->next; - - if (entry && entry->data == data) { + continue; + } else { if (!entry->prev) { if (entry->next) { assert(list->num_entries > 1); @@ -439,8 +446,10 @@ cfulist_delete_data(cfulist_t *list, void *data) { } else { (entry->prev)->next = entry->next; } + if (free_fn) free_fn(entry->data); free (entry); --list->num_entries; + break; } } diff --git a/src/cfulist.h b/src/cfulist.h index f0d5c33..40da0fb 100644 --- a/src/cfulist.h +++ b/src/cfulist.h @@ -83,6 +83,7 @@ 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);