AmendHub

Download

ftech

/

SList

/

slist.c

 

(View History)

Francois Techene   Changed license to MIT + refactored to feature camel case syntax. Latest amendment: 4 on 2026-04-01

1 /* slist.c
2 *
3 * Copyright 2026 Francois Techene
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining
6 * a copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sublicense, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be
14 * included in all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 * NONINFRINGEMENT. IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY
20 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Except as contained in this notice, the name(s) of the above copyright
25 * holders shall not be used in advertising or otherwise to promote the sale,
26 * use or other dealings in this Software without prior written
27 * authorization.
28 */
29
30 #include "slist.h"
31
32 #include <stdlib.h>
33
34
35 SListItem*
36 NewSListItem(void* data)
37 {
38 SListItem* self = (SListItem*)NewPtr(sizeof(SListItem));
39 self->data = data;
40 self->next = NULL;
41
42 return self;
43 }
44
45 void
46 DeleteSListItem(SListItem* item)
47 {
48 if (item) {
49 DisposePtr((Ptr)(item));
50 }
51 }
52
53 SList*
54 NewSList()
55 {
56 SList* self = (SList*)NewPtr(sizeof(SList));
57
58 self->first = SListFirst;
59 self->last = SListLast;
60 self->next = SListNext;
61
62 self->head = NULL;
63 self->count = 0;
64
65 return self;
66 }
67
68 void
69 DeleteSList(SList* list)
70 {
71 SListEmpty(list);
72
73 if (list) {
74 DisposePtr((Ptr)list);
75 }
76 }
77
78 void*
79 SListFirst(SList* self)
80 {
81 return self->head;
82 }
83
84 void*
85 SListLast(SList* self)
86 {
87 return NULL;
88 }
89
90 void*
91 SListNext(SList* self, SListItem* item)
92 {
93 return item->next;
94 }
95
96 void
97 SListAppend(SList* self, void* data)
98 {
99 SListItem* elem = self->head;
100 SListItem* newElem = NewSListItem(data);
101
102 if (!elem) {
103 self->head = newElem;
104 self->count++;
105 return;
106 }
107
108 while (elem->next) {
109 elem = elem->next;
110 }
111 elem->next = newElem;
112
113 self->count++;
114 }
115
116 void
117 SListInsertAt(SList* self, void* data, int index)
118 {
119 int count = 0;
120 SListItem* prevElem = NULL;
121 SListItem* elem = self->head;
122 SListItem* newElem = NewSListItem(data);
123
124 while (elem && count < index) {
125 prevElem = elem;
126 elem = elem->next;
127 count++;
128 }
129
130 newElem->next = elem;
131
132 if (!prevElem) {
133 self->head = newElem;
134 }
135 else {
136 prevElem->next = newElem;
137 }
138
139 self->count++;
140 }
141
142 void
143 SListInsertAfter(SList* self, void* data, void* value)
144 {
145 SListItem* elem = self->head;
146 SListItem* newElem = NewSListItem(data);
147
148 if (!self->head) {
149 self->head = newElem;
150 self->count++;
151 return;
152 }
153
154 while (elem->next && elem->data != value) {
155 elem = elem->next;
156 }
157
158 newElem->next = elem->next;
159 elem->next = newElem;
160
161 self->count++;
162 }
163
164
165 void SListEmpty(SList* self)
166 {
167 while (self->head) {
168 SListRemoveAt(self, 0);
169 }
170 self->head = NULL;
171 self->count = 0;
172 }
173
174 void
175 SListRemoveAt(SList* self, int index)
176 {
177 int count = 0;
178 SListItem* prevElem = NULL;
179 SListItem* elem = self->head;
180
181 if (!elem) {
182 return; // List is empty;
183 }
184
185 while (elem && count < index) {
186 prevElem = elem;
187 elem = elem->next;
188 count++;
189 }
190
191 if (!elem) {
192 return; // No element at that index position.
193 }
194
195 if (!prevElem) {
196 self->head = elem->next;
197 }
198 else {
199 prevElem->next = elem->next;
200 }
201
202 DeleteSListItem(elem);
203 elem = NULL;
204
205 self->count--;
206 }
207
208 void
209 SListRemoveLast(SList* self)
210 {
211 SListItem* prevElem = NULL;
212 SListItem* elem = self->head;
213
214 if (!elem) {
215 return; // List is empty
216 }
217
218 while (elem->next) {
219 prevElem = elem;
220 elem = elem->next;
221 }
222
223 // prevElem->next is freed and set to NULL by the
224 // delete method.
225 //
226 DeleteSListItem(prevElem->next);
227 prevElem->next = NULL;
228
229 self->count--;
230 }
231
232 // Remove the first occurence of the item having the same value
233 // as 'value'.
234 //
235 void
236 SListRemoveValue(SList* self, void* value)
237 {
238 SListItem* prevElem = NULL;
239 SListItem* elem = self->head;
240
241
242 while (elem != NULL) {
243 if (elem->data == value) {
244
245 if (!prevElem) {
246 self->head = elem->next;
247 }
248 else {
249 prevElem->next = elem->next;
250 }
251
252 // elem is freed and set to NULL by the
253 // delete method.
254 //
255 DeleteSListItem(elem);
256 elem = NULL;
257
258 self->count--;
259 }
260 else {
261 prevElem = elem;
262 elem = elem->next;
263 }
264 }
265 }