diff --git a/common/list.c b/common/list.c index 16956632f..98005d9e0 100644 --- a/common/list.c +++ b/common/list.c @@ -54,26 +54,6 @@ static bool resize(list_t *list) { return true; } -void list_add(list_t *list, const void *data) { - if (!sway_assert(list && data, "Invalid argument") || !resize(list)) { - return; - } - - size_t size = list->memb_size; - uint8_t (*array)[size] = list->items; - - memcpy(&array[list->length], data, size); - ++list->length; -} - -void *list_alloc(list_t *list) { - if (!sway_assert(list, "Invalid argument") || !resize(list)) { - return NULL; - } - - return (uint8_t *)list->items + list->memb_size * list->length++; -} - void list_insert(list_t *list, size_t index, const void *data) { if (!sway_assert(list && data && index <= list->length, "Invalid argument") || !resize(list)) { @@ -88,6 +68,14 @@ void list_insert(list_t *list, size_t index, const void *data) { ++list->length; } +void list_add(list_t *list, const void *data) { + if (!sway_assert(list && data, "Invalid argument")) { + return; + } + + list_insert(list, list->length, data); +} + static void shrink(list_t *list) { /* We shrink very sparse lists, but only down to a certain size. * The choice of >= 8 is somewhat arbitrary, but leaves a minimum @@ -105,15 +93,6 @@ static void shrink(list_t *list) { } } -void list_remove(list_t *list) { - if (!sway_assert(list, "Invalid argument") || list->length == 0) { - return; - } - - --list->length; - shrink(list); -} - void list_delete(list_t *list, size_t index) { if (!sway_assert(list && index < list->length, "Invalid argument")) { return; @@ -127,6 +106,14 @@ void list_delete(list_t *list, size_t index) { shrink(list); } +void list_remove(list_t *list) { + if (!sway_assert(list, "Invalid argument") || list->length == 0) { + return; + } + + list_delete(list, list->length - 1); +} + void list_swap(list_t *list, size_t i1, size_t i2) { if (!sway_assert(list && i1 < list->length && i2 < list->length, "Invalid argument")) { return; @@ -240,7 +227,20 @@ void list_foreach(list_t *list, void callback(void *item)) { } } -void list_free_with(list_t *list, void callback(void *item)) { +void list_foreachp(list_t *list, void callback(void *item)) { + if (!sway_assert(list && callback, "Invalid argument")) { + return; + } + + size_t size = list->memb_size; + uint8_t (*array)[size] = list->items; + + for (size_t i = 0; i < list->length; ++i) { + callback(*(void **)&array[i]); + } +} + +void list_free_with(list_t *list, freefn_t callback) { if (!sway_assert(callback, "Invalid argument") || !list) { return; } @@ -249,6 +249,15 @@ void list_free_with(list_t *list, void callback(void *item)) { list_free(list); } +void list_free_withp(list_t *list, freefn_t callback) { + if (!sway_assert(callback, "Invalid argument") || !list) { + return; + } + + list_foreachp(list, callback); + list_free(list); +} + void *list_end(list_t *list) { if (!sway_assert(list, "Invalid argument")) { return NULL; @@ -256,7 +265,3 @@ void *list_end(list_t *list) { return (uint8_t *)list->items + list->memb_size * list->length; } - -void list_elem_free(void *item) { - free(*(void **)item); -} diff --git a/common/stringop.c b/common/stringop.c index 7a7696516..14dd4c3fc 100644 --- a/common/stringop.c +++ b/common/stringop.c @@ -84,7 +84,7 @@ list_t *split_string(const char *str, const char *delims) { } void free_flat_list(list_t *list) { - list_free_with(list, list_elem_free); + list_free_withp(list, free); } char **split_args(const char *start, int *argc) { diff --git a/include/list.h b/include/list.h index 5ab15c227..757a71f6c 100644 --- a/include/list.h +++ b/include/list.h @@ -27,36 +27,30 @@ list_t *list_new(size_t memb_size, size_t capacity); */ void list_free(list_t *list); +typedef void (*freefn_t)(void *arg); + /* * Frees a list, calling a function on each element before doing so. * If list is null, no action is taken. - * DO NOT pass free as the callback. Use list_elem_free if - * you want to do that. + * DO NOT pass free as the callback. Use list_free_withp for that. */ -void list_free_with(list_t *list, void callback(void *item)); +void list_free_with(list_t *list, freefn_t callback); /* - * This is a convinience function designed to be used with - * list_free_with or list_foreach. - * It calls the stdlib free function on each element. - * We can't pass in free directly, as each pointer needs to be - * dereferenced first. - * This should only be used on lists of pointers that were - * allocated using malloc (or similar). + * Frees a list, calling a function on each element after it's + * dereferenced before doing do. + * For example, if you have a list of char * allocated with malloc, + * it would be safe to use free with this function. + * If list is null, no action is taken. + * list must be a list of pointers. */ -void list_elem_free(void *item); +void list_free_withp(list_t *list, freefn_t callback); /* * Adds an element at the end of the list. */ void list_add(list_t *list, const void *data); -/* - * Adds an uninitialized element at the end of the list, - * and returns a pointer to it. - */ -void *list_alloc(list_t *list); - /* * Deletes the last element of the list. * If the list is empty, no action is taken. @@ -132,6 +126,15 @@ ssize_t list_lsearch(const list_t *list, int compare(const void *key, const void */ void list_foreach(list_t *list, void callback(void *item)); +/* + * Calls a function on every item in the list, after dereferencing + * the element. + * For example, if you have a list of char *, you will receive a char * + * in callback, instead of a char **, unlike list_foreach. + * list must be a list of pointers. + */ +void list_foreachp(list_t *list, void callback(void *item)); + /* * Returns a pointer to just past the end of the list. * This can be used to write for loops more easily. diff --git a/sway/commands/mark.c b/sway/commands/mark.c index 66452a62c..a93239a20 100644 --- a/sway/commands/mark.c +++ b/sway/commands/mark.c @@ -68,13 +68,11 @@ struct cmd_results *cmd_mark(int argc, char **argv) { } else { if (toggle && list_lsearch(view->marks, strcmp_ptr, &mark, NULL) != -1) { // Delete the list - list_foreach(view->marks, list_elem_free); - list_free(view->marks); + list_free_withp(view->marks, free); view->marks = NULL; } else { // Delete and replace with a new list - list_foreach(view->marks, list_elem_free); - list_free(view->marks); + list_free_withp(view->marks, free); view->marks = list_new(sizeof(char *), 0); list_add(view->marks, &mark); diff --git a/sway/commands/unmark.c b/sway/commands/unmark.c index 30c001173..938c0a84d 100644 --- a/sway/commands/unmark.c +++ b/sway/commands/unmark.c @@ -23,8 +23,7 @@ struct cmd_results *cmd_unmark(int argc, char **argv) { } free(mark); } else { - list_foreach(view->marks, list_elem_free); - list_free(view->marks); + list_free_with(view->marks, free); view->marks = NULL; } }