AmendHub

Download

ftech

/

SList

/

slist.c

 

(View History)

Francois Techene   First commit Latest amendment: 1 on 2025-03-31

1 /* slist.c
2 *
3 * Copyright 2025 Francois Techene
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 * SPDX-License-Identifier: GPL-3.0-or-later
19 */
20
21 #include "slist.h"
22
23 #include <stdlib.h>
24
25
26 SListItem*
27 SListItem_new(void* data)
28 {
29 SListItem* self = (SListItem*)NewPtr(sizeof(SListItem));
30 self->data = data;
31 self->next = NULL;
32
33 return self;
34 }
35
36 void
37 SListItem_delete(SListItem** item)
38 {
39 if (*item) {
40 DisposPtr(*item);
41 *item = NULL;
42 }
43 }
44
45 SList*
46 SList_new()
47 {
48 SList* self = (SList*)NewPtr(sizeof(SList));
49
50 self->first = slist_first;
51 self->last = slist_last;
52 self->next = slist_next;
53
54 self->head = NULL;
55 self->count = 0;
56
57 return self;
58 }
59
60 void
61 SList_delete(SList** list)
62 {
63 slist_empty(*list);
64
65 if (*list) {
66 DisposPtr(*list);
67 *list = NULL;
68 }
69 }
70
71 void*
72 slist_first(SList* self)
73 {
74 return self->head;
75 }
76
77 void*
78 slist_last(SList* self)
79 {
80 return NULL;
81 }
82
83 void*
84 slist_next(SList* self, SListItem* item)
85 {
86 return item->next;
87 }
88
89 void
90 slist_append(SList* self, void* data)
91 {
92 SListItem* elem = self->head;
93 SListItem* new_elem = SListItem_new(data);
94
95 if (!elem) {
96 self->head = new_elem;
97 self->count++;
98 return;
99 }
100
101 while (elem->next) {
102 elem = elem->next;
103 }
104 elem->next = new_elem;
105
106 self->count++;
107 }
108
109 void
110 slist_insert_at(SList* self, void* data, int index)
111 {
112 int count = 0;
113 SListItem* prev_elem = NULL;
114 SListItem* elem = self->head;
115 SListItem* new_elem = SListItem_new(data);
116
117 while (elem && count < index) {
118 prev_elem = elem;
119 elem = elem->next;
120 count++;
121 }
122
123 new_elem->next = elem;
124
125 if (!prev_elem) {
126 self->head = new_elem;
127 }
128 else {
129 prev_elem->next = new_elem;
130 }
131
132 self->count++;
133 }
134
135 void
136 slist_insert_after(SList* self, void* data, void* value)
137 {
138 SListItem* elem = self->head;
139 SListItem* new_elem = SListItem_new(data);
140
141 if (!self->head) {
142 self->head = new_elem;
143 self->count++;
144 return;
145 }
146
147 while (elem->next && elem->data != value) {
148 elem = elem->next;
149 }
150
151 new_elem->next = elem->next;
152 elem->next = new_elem;
153
154 self->count++;
155 }
156
157
158 void slist_empty(SList* self)
159 {
160 while (self->head) {
161 slist_remove_at(self, 0);
162 }
163 self->head = NULL;
164 self->count = 0;
165 }
166
167 void
168 slist_remove_at(SList* self, int index)
169 {
170 int count = 0;
171 SListItem* prev_elem = NULL;
172 SListItem* elem = self->head;
173
174 if (!elem) {
175 return; // List is empty;
176 }
177
178 while (elem && count < index) {
179 prev_elem = elem;
180 elem = elem->next;
181 count++;
182 }
183
184 if (!elem) {
185 return; // No element at that index position.
186 }
187
188 if (!prev_elem) {
189 self->head = elem->next;
190 }
191 else {
192 prev_elem->next = elem->next;
193 }
194
195 SListItem_delete(&elem);
196 elem = NULL;
197
198 self->count--;
199 }
200
201 void
202 slist_remove_last(SList* self)
203 {
204 SListItem* prev_elem = NULL;
205 SListItem* elem = self->head;
206
207 if (!elem) {
208 return; // List is empty
209 }
210
211 while (elem->next) {
212 prev_elem = elem;
213 elem = elem->next;
214 }
215
216 // prev_elem->next is freed and set to NULL by the
217 // delete method.
218 //
219 SListItem_delete(&(prev_elem->next));
220 prev_elem->next = NULL;
221
222 self->count--;
223 }
224
225 // Remove the first occurence of the item having the same value
226 // as 'value'.
227 //
228 void
229 slist_remove_value(SList* self, void* value)
230 {
231 SListItem* prev_elem = NULL;
232 SListItem* elem = self->head;
233
234
235 while (elem != NULL) {
236 if (elem->data == value) {
237
238 if (!prev_elem) {
239 self->head = elem->next;
240 }
241 else {
242 prev_elem->next = elem->next;
243 }
244
245 // elem is freed and set to NULL by the
246 // delete method.
247 //
248 SListItem_delete(&elem);
249 elem = NULL;
250
251 self->count--;
252 }
253 else {
254 prev_elem = elem;
255 elem = elem->next;
256 }
257 }
258 }