// ========================================= // | SilverMUD Server - lists.c | // | Copyright (C) 2023, Barra Ó Catháin | // | See end of file for copyright notice. | // ========================================= #include #include #include #include #include "lists.h" // Functions: // ========== struct List * createList(enum DataType type) { struct List * newList = calloc(1, sizeof(struct List)); newList->itemCount = 0; newList->head = NULL; newList->tail = NULL; newList->type = type; return newList; } size_t appendToList(enum DataType type, struct List * list, void * data) { // First check that you're adding the correct type: assert(type == list->type); struct ListNode * newListNode = calloc(1, sizeof(struct ListNode)); newListNode->next = NULL; newListNode->previous = list->tail; newListNode->data = data; if (list->itemCount == 0) { list->head = newListNode; } else { list->tail->next = newListNode; } list->tail = newListNode; list->itemCount++; return list->itemCount; } void * deleteListNodeFromList(size_t index, struct List * list) { void * toReturn; if ((list->itemCount - 1) < index) { return NULL; } struct ListNode * currentListNode = NULL; if (index < (list->itemCount / 2)) { currentListNode = list->head; // Get to the correct point in the linked list: for (int currentIndex = 0; currentIndex < index; currentIndex++) { currentListNode = currentListNode->next; } } else { currentListNode = list->tail; // Get to the correct point in the linked list: for (int currentIndex = list->itemCount - 1; currentIndex > index; currentIndex--) { currentListNode = currentListNode->previous; } } if (currentListNode == list->head) { list->head = list->head->next; if (list->head) { list->head->previous = NULL; } } if (currentListNode == list->tail) { list->tail = list->tail->previous; if (list->tail) { list->tail->next = NULL; } } if (currentListNode->next != NULL) { currentListNode->next->previous = currentListNode->previous; } if (currentListNode->previous != NULL) { currentListNode->previous->next = currentListNode->next; } toReturn = currentListNode->data; free(currentListNode); list->itemCount--; return toReturn; } ssize_t indexOfFromList(bool (*comparisonFunction)(void *, void *), void * data, struct List * list) { size_t index = 0; if (list->head == NULL) { return -1; } else { struct ListNode * currentListNode = list->head; do { if (comparisonFunction(currentListNode->data, data) == true) { return index; } index++; currentListNode = currentListNode->next; } while (currentListNode != NULL); return -1; } } void * getFirstFromList(bool (*comparisonFunction)(void *, void *), void * data, struct List * list) { size_t index = 0; if (list->head == NULL) { return NULL; } else { struct ListNode * currentListNode = list->head; do { if (comparisonFunction(currentListNode->data, data) == true) { return currentListNode; } index++; currentListNode = currentListNode->next; } while (currentListNode != NULL); return NULL; } } bool isInList(bool (*comparisonFunction)(void *, void *), void * data, struct List * list) { if (list->head == NULL) { return false; } else { struct ListNode * currentListNode = list->head; do { if (comparisonFunction(currentListNode->data, data) == 0) { return true; } currentListNode = currentListNode->next; } while (currentListNode != NULL); return false; } } bool isPointerInList(void * data, struct List * list) { if (list->head == NULL) { return false; } else { struct ListNode * currentListNode = list->head; do { if (currentListNode->data == data) { return true; } currentListNode = currentListNode->next; } while (currentListNode != NULL); return false; } } // ============================================= // | End of lists.h, copyright notice follows. | // ============================================= // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU Affero General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Affero General Public License for more details. // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see .