1
/* A small List class HTList.c
4
** A list is represented as a sequence of linked nodes of type HTList.
5
** The first node is a header which contains no object.
6
** New nodes are inserted between the header and the rest of the list.
16
PUBLIC HTList * HTList_new NOARGS
20
if ((newList = typeMalloc(HTList)) == NULL)
21
outofmem(__FILE__, "HTList_new");
23
newList->object = NULL;
32
PUBLIC void HTList_delete ARGS1(
37
while ((current = me)) {
45
/* Reverse order of elements in list.
47
PUBLIC HTList * HTList_reverse ARGS1(
51
if (!(start && start->next && (cur = start->next->next)))
53
start->next->next = NULL;
56
cur->next = start->next;
63
/* Append a list to another.
65
* If successful, the second list will become empty but not freed.
67
PUBLIC HTList * HTList_appendList ARGS2(
71
HTList * temp = start;
74
CTRACE((tfp, "HTList: Trying to append list %p to a nonexisting list\n",
78
if (!(tail && tail->next))
84
temp->next = tail->next;
85
tail->next = NULL; /* tail is now an empty list */
90
/* Link object to START of list (so it is pointed to by the head).
92
* Unlike HTList_addObject(), it does not malloc memory for HTList entry,
93
* it use already allocated memory which should not be free'd by any
94
* list operations (optimization).
96
PUBLIC void HTList_linkObject ARGS3(
102
if (newNode->object == NULL && newNode->next == NULL) {
104
newNode->object = newObject;
105
newNode->next = me->next;
110
* This node is already linked to some list (probably this one),
111
* so refuse changing node pointers to keep the list valid!!!
113
CTRACE((tfp, "*** HTList: Refuse linking already linked obj "));
114
CTRACE((tfp, "%p, node %p, list %p\n",
115
newObject, newNode, me));
119
CTRACE((tfp, "HTList: Trying to link object %p to a nonexisting list\n",
127
/* Add object to START of list (so it is pointed to by the head).
129
PUBLIC void HTList_addObject ARGS2(
136
if ((newNode = typeMalloc(HTList)) == NULL)
137
outofmem(__FILE__, "HTList_addObject");
138
newNode->object = newObject;
139
newNode->next = me->next;
143
CTRACE((tfp, "HTList: Trying to add object %p to a nonexisting list\n",
151
/* Append object to END of list (furthest from the head).
153
PUBLIC void HTList_appendObject ARGS2(
159
if (temp && newObject) {
162
HTList_addObject(temp, newObject);
169
/* Insert an object into the list at a specified position.
170
** If position is 0, this places the object at the head of the list
171
** and is equivalent to HTList_addObject().
173
PUBLIC void HTList_insertObjectAt ARGS3(
184
CTRACE((tfp, "HTList: Trying to add object %p to a nonexisting list\n",
190
CTRACE((tfp, "HTList: Treating negative object position %d as %d.\n",
195
while ((temp = temp->next)) {
197
if ((newNode = typeMalloc(HTList)) == NULL)
198
outofmem(__FILE__, "HTList_addObjectAt");
199
newNode->object = newObject;
200
newNode->next = temp;
202
prevNode->next = newNode;
209
HTList_addObject(prevNode, newObject);
215
/* Unlink specified object from list.
216
* It does not free memory.
218
PUBLIC BOOL HTList_unlinkObject ARGS2(
225
if (temp && oldObject) {
229
if (temp->object == oldObject) {
230
prevNode->next = temp->next;
233
return YES; /* Success */
237
return NO; /* object not found or NULL list */
241
/* Remove specified object from list.
243
PUBLIC BOOL HTList_removeObject ARGS2(
250
if (temp && oldObject) {
254
if (temp->object == oldObject) {
255
prevNode->next = temp->next;
257
return YES; /* Success */
261
return NO; /* object not found or NULL list */
265
/* Remove object at a given position in the list, where 0 is the
266
** object pointed to by the head (returns a pointer to the element
267
** (->object) for the object, and NULL if the list is empty, or
268
** if it doesn't exist - Yuk!).
270
PUBLIC void * HTList_removeObjectAt ARGS2(
278
if (!temp || pos < 0)
282
while ((temp = temp->next)) {
284
prevNode->next = temp->next;
287
return prevNode->object;
293
return NULL; /* Reached the end of the list */
296
/* Unlink object from START of list (the Last one inserted
297
* via HTList_linkObject(), and pointed to by the head).
298
* It does not free memory.
300
PUBLIC void * HTList_unlinkLastObject ARGS1(
306
if (me && me->next) {
308
lastObject = lastNode->object;
309
me->next = lastNode->next;
310
lastNode->next = NULL;
311
lastNode->object = NULL;
314
} else { /* Empty list */
320
/* Remove object from START of list (the Last one inserted
321
** via HTList_addObject(), and pointed to by the head).
323
PUBLIC void * HTList_removeLastObject ARGS1(
329
if (me && me->next) {
331
lastObject = lastNode->object;
332
me->next = lastNode->next;
336
} else { /* Empty list */
342
/* Remove object from END of list (the First one inserted
343
** via HTList_addObject(), and furthest from the head).
345
PUBLIC void * HTList_removeFirstObject ARGS1(
361
firstObject = temp->object;
362
prevNode->next = NULL;
366
} else { /* Empty list */
372
/* Determine total number of objects in the list,
373
** not counting the head.
375
PUBLIC int HTList_count ARGS1(
382
while ((temp = temp->next))
389
/* Determine position of an object in the list (a value of 0
390
** means it is pointed to by the head; returns -1 if not found).
392
PUBLIC int HTList_indexOf ARGS2(
400
while ((temp = temp->next)) {
401
if (temp->object == object)
407
return -1; /* Object not in the list */
411
/* Return pointer to the object at a specified position in the list,
412
** where 0 is the object pointed to by the head (returns NULL if
413
** the list is empty, or if it doesn't exist - Yuk!).
415
PUBLIC void * HTList_objectAt ARGS2(
422
if (!temp || pos < 0)
425
while ((temp = temp->next)) {
431
return NULL; /* Reached the end of the list */