add two new functions: LL_GoTo(), LL_ForALL()

This commit is contained in:
marschap
2008-11-30 22:01:19 +00:00
parent 34cdf356e5
commit db5e45b534
2 changed files with 98 additions and 5 deletions
+91 -3
View File
@@ -61,7 +61,7 @@ LL_new(void)
int
LL_Destroy(LinkedList *list)
{
LL_node *next, *prev;
LL_node *prev, *next;
LL_node *node;
if (!list)
@@ -91,6 +91,42 @@ LL_Destroy(LinkedList *list)
}
/* Move to another entry in the list.
* Set list's \c current pointer to the node denoted to by \c whereto.
* \param list List object.
* \param whereto Direction where to set the list's \c current pointer
* \return New value of list's \c current pointer;
* \c NULL on error or when moving beyond ends.
*/
LL_node *
LL_GoTo(LinkedList *list, Direction whereto)
{
if (!list)
return NULL;
switch (whereto) {
case HEAD: list->current = (list->head.next != &list->tail)
? list->head.next
: NULL;
break;
case PREV: if (list->current->prev == &list->head)
return NULL;
list->current = list->current->prev;
case CURRENT: break;
case NEXT: if (list->current->next == &list->tail)
return NULL;
list->current = list->current->next;
break;
case TAIL: list->current = (list->tail.prev != &list->head)
? list->tail.prev
: NULL;
break;
}
return list->current;
}
/* Return to the beginning of the list.
* Set list's \c current pointer to the first node in the list.
* \param list List object.
@@ -445,9 +481,9 @@ LL_DeleteNode(LinkedList *list, Direction whereto)
free(list->current);
switch (whereto) {
case FIRST: list->current = list->head.next;
case HEAD: list->current = list->head.next;
break;
case LAST: list->current = list->tail.prev;
case TAIL: list->current = list->tail.prev;
break;
case PREV: list->current = prev;
break;
@@ -727,6 +763,57 @@ LL_Find(LinkedList *list, int (*compare)(void *, void *), void *value)
}
/** Perform an action for the all list elements.
* Execute a function on the data of each node in the list.
* Depending on the result of the function, new nodes may get added,
* nodes may get deleted or simply changed by the function itself.
*
* The \c action() function is in turn called with each node's data
* pointer as the first argument and \c value as its second argument.
* If it returns \c NULL, the node will be deleted from the list,
* otherwise, if the pointer returned from the function differs from
* data, a new node gets added after the current node.
* If the result equals the payload data, no addition or deletio happens.
*
* \note
* Removing the client payload in case of deletion, or creation of
* the payload for the new node in case of addition is up to the
* \c action() function.
*
* \note
* \c value can be used to report errors, pass additional information, ...
*
* \param list List object.
* \param action Pointer to the action function that takes two void pointers
* as arguments and returns a void pointer.
* \param value Pointer to data that is used as second argument to
* \c action().
*/
void
LL_ForAll(LinkedList *list, void *(*action)(void *, void *), void *value)
{
if (!list)
return;
if (!action)
return;
LL_Rewind(list);
if (list->current != NULL) {
do {
void *data = LL_Get(list);
void *result = action(data, value);
if (result != data) {
if (result != NULL)
LL_AddNode(list, result);
else
LL_DeleteNode(list, PREV);
}
} while (LL_Next(list) == 0);
}
}
/** Go to the n-th node in the list and return its data.
* Go to to the list node with the given \c index
* and return the data.
@@ -811,6 +898,7 @@ LL_Sort(LinkedList *list, int (*compare)(void *, void *))
return 0;
}
void
LL_dprint(LinkedList *list)
{
+7 -2
View File
@@ -101,11 +101,11 @@
/** Symbolic values for directions */
typedef enum _direction {
FIRST = -2,
HEAD = -2,
PREV = -1,
CURRENT = 0,
NEXT = +1,
LAST = +2
TAIL = +2
} Direction;
@@ -130,6 +130,9 @@ LinkedList *LL_new(void);
// Destroying lists...
int LL_Destroy(LinkedList *list);
// move "current" node
LL_node *LL_GoTo(LinkedList *list, Direction whereto);
// Returns to the beginning of the list...
int LL_Rewind(LinkedList *list);
// Goes to the end of the list...
@@ -179,6 +182,8 @@ int LL_Length(LinkedList *list); // Returns # of nodes in entire list
// Searching...
void *LL_Find(LinkedList *list, int (*compare)(void *, void *), void *value);
void LL_ForAll(LinkedList *list, void *(*action)(void *, void *), void *value);
// Array operation...
void *LL_GetByIndex(LinkedList *list, int index); // gets the nth node, 0 being the first