SilverMUD/source/server/lists.c

231 lines
4.7 KiB
C
Raw Normal View History

// =========================================
// | SilverMUD Server - lists.c |
// | Copyright (C) 2023, Barra Ó Catháin |
// | See end of file for copyright notice. |
// =========================================
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#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 <https://www.gnu.org/licenses/>.