/* slist.c * * Copyright 2025 Francois Techene * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * * SPDX-License-Identifier: GPL-3.0-or-later */ #include "slist.h" #include SListItem* SListItem_new(void* data) { SListItem* self = (SListItem*)NewPtr(sizeof(SListItem)); self->data = data; self->next = NULL; return self; } void SListItem_delete(SListItem** item) { if (*item) { DisposPtr(*item); *item = NULL; } } SList* SList_new() { SList* self = (SList*)NewPtr(sizeof(SList)); self->first = slist_first; self->last = slist_last; self->next = slist_next; self->head = NULL; self->count = 0; return self; } void SList_delete(SList** list) { slist_empty(*list); if (*list) { DisposPtr(*list); *list = NULL; } } void* slist_first(SList* self) { return self->head; } void* slist_last(SList* self) { return NULL; } void* slist_next(SList* self, SListItem* item) { return item->next; } void slist_append(SList* self, void* data) { SListItem* elem = self->head; SListItem* new_elem = SListItem_new(data); if (!elem) { self->head = new_elem; self->count++; return; } while (elem->next) { elem = elem->next; } elem->next = new_elem; self->count++; } void slist_insert_at(SList* self, void* data, int index) { int count = 0; SListItem* prev_elem = NULL; SListItem* elem = self->head; SListItem* new_elem = SListItem_new(data); while (elem && count < index) { prev_elem = elem; elem = elem->next; count++; } new_elem->next = elem; if (!prev_elem) { self->head = new_elem; } else { prev_elem->next = new_elem; } self->count++; } void slist_insert_after(SList* self, void* data, void* value) { SListItem* elem = self->head; SListItem* new_elem = SListItem_new(data); if (!self->head) { self->head = new_elem; self->count++; return; } while (elem->next && elem->data != value) { elem = elem->next; } new_elem->next = elem->next; elem->next = new_elem; self->count++; } void slist_empty(SList* self) { while (self->head) { slist_remove_at(self, 0); } self->head = NULL; self->count = 0; } void slist_remove_at(SList* self, int index) { int count = 0; SListItem* prev_elem = NULL; SListItem* elem = self->head; if (!elem) { return; // List is empty; } while (elem && count < index) { prev_elem = elem; elem = elem->next; count++; } if (!elem) { return; // No element at that index position. } if (!prev_elem) { self->head = elem->next; } else { prev_elem->next = elem->next; } SListItem_delete(&elem); elem = NULL; self->count--; } void slist_remove_last(SList* self) { SListItem* prev_elem = NULL; SListItem* elem = self->head; if (!elem) { return; // List is empty } while (elem->next) { prev_elem = elem; elem = elem->next; } // prev_elem->next is freed and set to NULL by the // delete method. // SListItem_delete(&(prev_elem->next)); prev_elem->next = NULL; self->count--; } // Remove the first occurence of the item having the same value // as 'value'. // void slist_remove_value(SList* self, void* value) { SListItem* prev_elem = NULL; SListItem* elem = self->head; while (elem != NULL) { if (elem->data == value) { if (!prev_elem) { self->head = elem->next; } else { prev_elem->next = elem->next; } // elem is freed and set to NULL by the // delete method. // SListItem_delete(&elem); elem = NULL; self->count--; } else { prev_elem = elem; elem = elem->next; } } }