#include "list.h" #include "helpers.h" List *list_make() { List *list = malloc(sizeof(List)); if (list != NULL) { list->head = NULL; list->tail = NULL; list->count = 0; } else { FURI_LOG_W("LIST", "Failed to create list"); } return list; } void list_free(List *list) { if (list == NULL) return; ListItem *start = list->head; while (start) { ListItem *next = start->next; free(start->data); free(start); start = next; } free(list); } void list_free_data(List *list) { if (list == NULL) return; ListItem *start = list->head; while (start) { ListItem *next = start->next; free(start->data); free(start); start = next; } list->head = NULL; list->tail = NULL; list->count = 0; } void list_clear(List *list) { if (list == NULL) return; ListItem *start = list->head; while (start) { ListItem *next = start->next; free(start); start = next; } list->head = NULL; list->tail = NULL; list->count = 0; } void list_push_back(void *data, List *list) { if (list == NULL) { FURI_LOG_W("LIST", "List not initialized, cannot push data"); return; } ListItem *newItem = malloc(sizeof(ListItem)); if (newItem != NULL) { newItem->data = data; newItem->next = NULL; newItem->prev = list->tail; if (list->tail == NULL) { list->head = newItem; list->tail = newItem; } else { list->tail->next = newItem; list->tail = newItem; } list->count++; } } void list_push_front(void *data, List *list) { if (list == NULL) { FURI_LOG_W("LIST", "List not initialized, cannot push data"); return; } ListItem *newItem = malloc(sizeof(ListItem)); if (newItem != NULL) { newItem->data = data; newItem->next = list->head; if (list->head == NULL) { list->head = newItem; list->tail = newItem; } else { list->head->prev = newItem; list->head = newItem; } list->count++; } } void *list_pop_back(List *list) { if (!check_pointer(list)) { FURI_LOG_W("LIST", "List not initialized, cannot pop data"); return NULL; } if (!check_pointer(list->tail)) { FURI_LOG_W("LIST", "List empty, cannot pop"); return NULL; } void *data = list->tail->data; check_pointer(data); ListItem *prev = list->tail->prev; check_pointer(prev); if (prev) { prev->next = NULL; } else { list->head = NULL; } free(list->tail); list->tail = prev; list->count--; return data; } void *list_pop_front(List *list) { if (!check_pointer(list)) { FURI_LOG_W("LIST", "List not initialized, cannot pop data"); return NULL; } if (!check_pointer(list->head)) { FURI_LOG_W("LIST", "List empty, cannot pop"); return NULL; } void *data = list->head->data; check_pointer(data); ListItem *next = list->head->next; if (next) { next->prev = NULL; } else { list->tail = NULL; } free(list->head); list->head = next; list->count--; return data; } void *list_pop_at(size_t index, List *list) { if (!check_pointer(list)) { FURI_LOG_W("LIST", "List not initialized, cannot pop data"); return NULL; } if (index >= list->count) { FURI_LOG_W("LIST", "Out of range, cannot pop"); return NULL; } if (index == 0) { return list_pop_front(list); } if (index == list->count - 1) { return list_pop_back(list); } ListItem *current = list->head; check_pointer(current); for (size_t i = 0; i < index; i++) { current = current->next; } check_pointer(current); void *data = current->data; check_pointer(data); current->prev->next = current->next; current->next->prev = current->prev; free(current); list->count--; return data; } void list_remove_item(void *data, List *list) { if (list == NULL) { return; } ListItem *current = list->head; while (current != NULL) { if (current->data == data) { if (current->prev != NULL) { current->prev->next = current->next; } else { list->head = current->next; } if (current->next != NULL) { current->next->prev = current->prev; } else { list->tail = current->prev; } free(current); list->count--; break; } current = current->next; } } void list_remove_at(size_t index, List *list) { if (list == NULL) { return; } void *d = list_pop_at(index, list); free(d); } List *list_splice(size_t index, size_t count, List *list) { if (list == NULL) { FURI_LOG_W("LIST", "List not initialized, cannot splice"); return NULL; } List *newList = list_make(); if (index >= list->count || count == 0) { return newList; } if (index == 0 && count >= list->count) { newList->head = list->head; newList->tail = list->tail; newList->count = list->count; list->head = NULL; list->tail = NULL; list->count = 0; return newList; } ListItem *start = list->head; for (size_t i = 0; i < index; i++) { start = start->next; } size_t c = count; if (c > list->count) c = list->count - index; ListItem *end = start; for (size_t i = 1; i < c && end->next; i++) { end = end->next; if (end->next == NULL) c = i; } newList->head = start; newList->tail = end; newList->count = c; if (end->next != NULL) { end->next->prev = start->prev; } else { list->tail = start->prev; } if (start->prev != NULL) { start->prev->next = end->next; } else { list->head = end->next; } start->prev = NULL; end->next = NULL; list->count -= c; return newList; } void *list_peek_front(List *list) { if (list == NULL || list->head == NULL) { return NULL; } return list->head->data; } ListItem *list_get_index(List *list, size_t index){ check_pointer(list); ListItem *curr = list->head; check_pointer(curr); if(index > list->count || !curr) return NULL; for (size_t i = 0; i < index; i++) { if (!curr) return NULL; curr = curr->next; } return curr; } void *list_peek_index(List *list, size_t index) { ListItem *curr = list_get_index(list,index); check_pointer(curr); if(curr) { check_pointer(curr->data); return curr->data; } return NULL; } void *list_peek_back(List *list) { if (!list || !list->tail) { return NULL; } check_pointer(list->tail->data); return list->tail->data; }