mirror of
https://github.com/swaywm/sway.git
synced 2026-04-29 06:46:22 -04:00
Updated list operations
This commit is contained in:
parent
508200e83d
commit
6b05f44339
5 changed files with 63 additions and 58 deletions
|
|
@ -54,26 +54,6 @@ static bool resize(list_t *list) {
|
||||||
return true;
|
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) {
|
void list_insert(list_t *list, size_t index, const void *data) {
|
||||||
if (!sway_assert(list && data && index <= list->length, "Invalid argument") ||
|
if (!sway_assert(list && data && index <= list->length, "Invalid argument") ||
|
||||||
!resize(list)) {
|
!resize(list)) {
|
||||||
|
|
@ -88,6 +68,14 @@ void list_insert(list_t *list, size_t index, const void *data) {
|
||||||
++list->length;
|
++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) {
|
static void shrink(list_t *list) {
|
||||||
/* We shrink very sparse lists, but only down to a certain size.
|
/* We shrink very sparse lists, but only down to a certain size.
|
||||||
* The choice of >= 8 is somewhat arbitrary, but leaves a minimum
|
* 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) {
|
void list_delete(list_t *list, size_t index) {
|
||||||
if (!sway_assert(list && index < list->length, "Invalid argument")) {
|
if (!sway_assert(list && index < list->length, "Invalid argument")) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -127,6 +106,14 @@ void list_delete(list_t *list, size_t index) {
|
||||||
shrink(list);
|
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) {
|
void list_swap(list_t *list, size_t i1, size_t i2) {
|
||||||
if (!sway_assert(list && i1 < list->length && i2 < list->length, "Invalid argument")) {
|
if (!sway_assert(list && i1 < list->length && i2 < list->length, "Invalid argument")) {
|
||||||
return;
|
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) {
|
if (!sway_assert(callback, "Invalid argument") || !list) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -249,6 +249,15 @@ void list_free_with(list_t *list, void callback(void *item)) {
|
||||||
list_free(list);
|
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) {
|
void *list_end(list_t *list) {
|
||||||
if (!sway_assert(list, "Invalid argument")) {
|
if (!sway_assert(list, "Invalid argument")) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
@ -256,7 +265,3 @@ void *list_end(list_t *list) {
|
||||||
|
|
||||||
return (uint8_t *)list->items + list->memb_size * list->length;
|
return (uint8_t *)list->items + list->memb_size * list->length;
|
||||||
}
|
}
|
||||||
|
|
||||||
void list_elem_free(void *item) {
|
|
||||||
free(*(void **)item);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,7 @@ list_t *split_string(const char *str, const char *delims) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_flat_list(list_t *list) {
|
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) {
|
char **split_args(const char *start, int *argc) {
|
||||||
|
|
|
||||||
|
|
@ -27,36 +27,30 @@ list_t *list_new(size_t memb_size, size_t capacity);
|
||||||
*/
|
*/
|
||||||
void list_free(list_t *list);
|
void list_free(list_t *list);
|
||||||
|
|
||||||
|
typedef void (*freefn_t)(void *arg);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Frees a list, calling a function on each element before doing so.
|
* Frees a list, calling a function on each element before doing so.
|
||||||
* If list is null, no action is taken.
|
* If list is null, no action is taken.
|
||||||
* DO NOT pass free as the callback. Use list_elem_free if
|
* DO NOT pass free as the callback. Use list_free_withp for that.
|
||||||
* you want to do 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
|
* Frees a list, calling a function on each element after it's
|
||||||
* list_free_with or list_foreach.
|
* dereferenced before doing do.
|
||||||
* It calls the stdlib free function on each element.
|
* For example, if you have a list of char * allocated with malloc,
|
||||||
* We can't pass in free directly, as each pointer needs to be
|
* it would be safe to use free with this function.
|
||||||
* dereferenced first.
|
* If list is null, no action is taken.
|
||||||
* This should only be used on lists of pointers that were
|
* list must be a list of pointers.
|
||||||
* allocated using malloc (or similar).
|
|
||||||
*/
|
*/
|
||||||
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.
|
* Adds an element at the end of the list.
|
||||||
*/
|
*/
|
||||||
void list_add(list_t *list, const void *data);
|
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.
|
* Deletes the last element of the list.
|
||||||
* If the list is empty, no action is taken.
|
* 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));
|
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.
|
* Returns a pointer to just past the end of the list.
|
||||||
* This can be used to write for loops more easily.
|
* This can be used to write for loops more easily.
|
||||||
|
|
|
||||||
|
|
@ -68,13 +68,11 @@ struct cmd_results *cmd_mark(int argc, char **argv) {
|
||||||
} else {
|
} else {
|
||||||
if (toggle && list_lsearch(view->marks, strcmp_ptr, &mark, NULL) != -1) {
|
if (toggle && list_lsearch(view->marks, strcmp_ptr, &mark, NULL) != -1) {
|
||||||
// Delete the list
|
// Delete the list
|
||||||
list_foreach(view->marks, list_elem_free);
|
list_free_withp(view->marks, free);
|
||||||
list_free(view->marks);
|
|
||||||
view->marks = NULL;
|
view->marks = NULL;
|
||||||
} else {
|
} else {
|
||||||
// Delete and replace with a new list
|
// Delete and replace with a new list
|
||||||
list_foreach(view->marks, list_elem_free);
|
list_free_withp(view->marks, free);
|
||||||
list_free(view->marks);
|
|
||||||
|
|
||||||
view->marks = list_new(sizeof(char *), 0);
|
view->marks = list_new(sizeof(char *), 0);
|
||||||
list_add(view->marks, &mark);
|
list_add(view->marks, &mark);
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,7 @@ struct cmd_results *cmd_unmark(int argc, char **argv) {
|
||||||
}
|
}
|
||||||
free(mark);
|
free(mark);
|
||||||
} else {
|
} else {
|
||||||
list_foreach(view->marks, list_elem_free);
|
list_free_with(view->marks, free);
|
||||||
list_free(view->marks);
|
|
||||||
view->marks = NULL;
|
view->marks = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue