diff --git a/include/list.h b/include/list.h index 9b62270b..e3d0d890 100644 --- a/include/list.h +++ b/include/list.h @@ -18,11 +18,16 @@ typedef struct list { size_t len; } list_t; +typedef void (*list_elem_free_fn)(void *); + /// Alloc elems if needed and ensure the list has room for at least min_size elements. void list_ensure_size(list_t *list, size_t min_size); /// Add to the end of elems, allocs or grows the list if needed and ensures the list has a terminating NULL. void list_push(list_t *list, void *p); -/// Free each element and elems, does not free list itself. -void list_free(list_t *list); +/// Clear the list, frees each element with fn, does not free backing or list itself. +void list_clear(list_t *list, list_elem_free_fn elem_free); + +/// Clear the list, free backing, does not free list itself. +void list_free_elems(list_t *list, list_elem_free_fn elem_free); diff --git a/src/list.c b/src/list.c index ecef7928..acd89f56 100644 --- a/src/list.c +++ b/src/list.c @@ -32,15 +32,23 @@ void list_push(list_t *list, void *p) list->elems[list->len] = NULL; // ensure a terminating NULL } -void list_free(list_t *list) +void list_clear(list_t *list, list_elem_free_fn elem_free) { - if (list->len) { - for (void **iter = list->elems; iter && *iter; ++iter) - free(*iter); - list->len = 0; - - free(list->elems); - list->elems = NULL; - list->size = 0; + if (elem_free) { + for (size_t i = 0; i < list->len; ++i) { // list might contain NULLs + elem_free(list->elems[i]); + } + } + list->len = 0; + if (list->elems) { + list->elems[0] = NULL; // ensure a terminating NULL } } + +void list_free_elems(list_t *list, list_elem_free_fn elem_free) +{ + list_clear(list, elem_free); + free(list->elems); + list->elems = NULL; + list->size = 0; +} diff --git a/src/rtl_433.c b/src/rtl_433.c index 7f90d949..2078215b 100644 --- a/src/rtl_433.c +++ b/src/rtl_433.c @@ -1717,11 +1717,11 @@ int main(int argc, char **argv) { if (dumper->file && (dumper->file != stdout)) fclose(dumper->file); } - list_free(&demod->dumper); + list_free_elems(&demod->dumper, free); r = sdr_deactivate(cfg.dev); - list_free(&demod->r_devs); + list_free_elems(&demod->r_devs, free); if (demod->am_analyze) am_analyze_free(demod->am_analyze); @@ -1731,10 +1731,9 @@ int main(int argc, char **argv) { sdr_close(cfg.dev); out: - for (size_t i = 0; i < cfg.output_handler.len; ++i) { // list might contain NULLs - data_output_free(cfg.output_handler.elems[i]); - } - free(cfg.output_handler.elems); + list_free_elems(&cfg.output_handler, (list_elem_free_fn)data_output_free); + + list_free_elems(&cfg.in_files, NULL); return r >= 0 ? r : -r; }