add Doxygen documentation (partially)
This commit is contained in:
+317
-146
@@ -1,3 +1,19 @@
|
||||
/** \file LL.c
|
||||
* Define routines to deal with doubly linked lists
|
||||
*/
|
||||
|
||||
/* This file is part of LCDproc.
|
||||
*
|
||||
* This file is released under the GNU General Public License. Refer to the
|
||||
* COPYING file distributed with this package.
|
||||
*
|
||||
* Copyright(c) 1999, William Ferrell
|
||||
* (c) 2000, Guillaume Filion
|
||||
* (c) 2001, Joris Robijn
|
||||
* (c) 2008, Peter Marschall
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "LL.h"
|
||||
@@ -9,14 +25,16 @@
|
||||
//TODO: Comment everything
|
||||
//TODO: Test everything?
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Creates a new list...
|
||||
|
||||
/** Create new linked list.
|
||||
* \return Pointer to freshly created list object; \c NULL on error.
|
||||
*/
|
||||
LinkedList *
|
||||
LL_new ()
|
||||
LL_new()
|
||||
{
|
||||
LinkedList *list;
|
||||
|
||||
list = malloc (sizeof (LinkedList));
|
||||
list = malloc(sizeof(LinkedList));
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
@@ -31,12 +49,17 @@ LL_new ()
|
||||
return list;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// TODO: test this function
|
||||
// Destroys the entire list
|
||||
// Warning! Does not free the list data! (only the list itself)
|
||||
|
||||
/** Destroy the entire list.
|
||||
*
|
||||
* Note: this does not free the data, only the list itself
|
||||
*
|
||||
* \param list List object to be destroyed.
|
||||
* \retval <0 error
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_Destroy (LinkedList * list)
|
||||
LL_Destroy(LinkedList *list)
|
||||
{
|
||||
LL_node *node, *next;
|
||||
|
||||
@@ -48,35 +71,46 @@ LL_Destroy (LinkedList * list)
|
||||
for (node = node->next; node && node->next; node = next) {
|
||||
// Avoid accessing "node" after it's freed.. :)
|
||||
next = node->next;
|
||||
if (LL_node_Destroy (node) < 0)
|
||||
if (LL_node_Destroy(node) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
free (list);
|
||||
free(list);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// TODO: test this function
|
||||
// Warning! This does not assert that the node data is free!
|
||||
|
||||
/** Destroy a node.
|
||||
*
|
||||
* Warning! This does not assert that the node data is free!
|
||||
*
|
||||
* \param node Node to be destroyed.
|
||||
* \retval <0 error
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_node_Destroy (LL_node * node)
|
||||
LL_node_Destroy(LL_node *node)
|
||||
{
|
||||
if (!node)
|
||||
return -1;
|
||||
|
||||
if (LL_node_Unlink (node) < 0)
|
||||
if (LL_node_Unlink(node) < 0)
|
||||
return -1;
|
||||
|
||||
free (node);
|
||||
free(node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Unlink a node from the list.
|
||||
* \param node Node to be unlinked.
|
||||
* \retval <0 error
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_node_Unlink (LL_node * node)
|
||||
LL_node_Unlink(LL_node *node)
|
||||
{
|
||||
LL_node *next, *prev;
|
||||
|
||||
@@ -97,25 +131,37 @@ LL_node_Unlink (LL_node * node)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Frees the data in a list node, if not NULL...
|
||||
|
||||
/** Free the data in a list node.
|
||||
* \param node Node, whose data is to be destroyed.
|
||||
* \retval <0 error: illegal node, or no node data to destroy.
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_node_DestroyData (LL_node * node)
|
||||
LL_node_DestroyData(LL_node *node)
|
||||
{
|
||||
if (!node)
|
||||
return -1;
|
||||
|
||||
if (node->data)
|
||||
free (node->data);
|
||||
if (node->data) {
|
||||
free(node->data);
|
||||
// prevent accidential double free()
|
||||
node->data = NULL;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Returns to the beginning of the list...
|
||||
|
||||
/* Return to the beginning of the list.
|
||||
* Set list's "current" pointer to the first node in the list.
|
||||
* \param list List object.
|
||||
* \retval <0 error: no list given
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_Rewind (LinkedList * list)
|
||||
LL_Rewind(LinkedList *list)
|
||||
{
|
||||
if (!list)
|
||||
return -1;
|
||||
@@ -133,10 +179,15 @@ LL_Rewind (LinkedList * list)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Goes to the end of the list...
|
||||
|
||||
/** Jump to the end of the list.
|
||||
* Set list's "current" pointer to the last node in the list.
|
||||
* \param list List object.
|
||||
* \retval <0 error: no list given
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_End (LinkedList * list)
|
||||
LL_End(LinkedList *list)
|
||||
{
|
||||
if (!list)
|
||||
return -1;
|
||||
@@ -149,10 +200,15 @@ LL_End (LinkedList * list)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Go to the next node
|
||||
|
||||
/** Go to the next node of the list.
|
||||
* Advance list's "current" pointer to the next node in the list.
|
||||
* \param list List object.
|
||||
* \retval <0 error: no list given or no next node
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_Next (LinkedList * list)
|
||||
LL_Next(LinkedList *list)
|
||||
{
|
||||
if (!list)
|
||||
return -1;
|
||||
@@ -167,10 +223,15 @@ LL_Next (LinkedList * list)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Go to the previous node
|
||||
|
||||
/** Go to the previous node of the list.
|
||||
* Set list's "current" pointer to the previous node in the list.
|
||||
* \param list List object.
|
||||
* \retval <0 error: no list given or no previous node
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_Prev (LinkedList * list)
|
||||
LL_Prev(LinkedList *list)
|
||||
{
|
||||
if (!list)
|
||||
return -1;
|
||||
@@ -185,10 +246,14 @@ LL_Prev (LinkedList * list)
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Data manipulation
|
||||
|
||||
/** Access current node's data.
|
||||
* \param list List object.
|
||||
* \retval <0 error: no list given, or no data in current node
|
||||
* \retval 0 success
|
||||
*/
|
||||
void *
|
||||
LL_Get (LinkedList * list)
|
||||
LL_Get(LinkedList *list)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
@@ -198,9 +263,15 @@ LL_Get (LinkedList * list)
|
||||
return list->current->data;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Set/change current node's data.
|
||||
* \param list List object.
|
||||
* \param data Pointer to data to be set.
|
||||
* \retval <0 error: no list given, or no current node
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_Put (LinkedList * list, void *data)
|
||||
LL_Put(LinkedList *list, void *data)
|
||||
{
|
||||
if (!list)
|
||||
return -1;
|
||||
@@ -212,9 +283,13 @@ LL_Put (LinkedList * list, void *data)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Get current node in list.
|
||||
* \param list List object.
|
||||
* \return Pointer to current node.
|
||||
*/
|
||||
LL_node *
|
||||
LL_GetNode (LinkedList * list)
|
||||
LL_GetNode(LinkedList *list)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
@@ -222,10 +297,18 @@ LL_GetNode (LinkedList * list)
|
||||
return list->current;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Don't use this unless you know what you're doing.
|
||||
|
||||
/** Set list's current pointr to a specific node.
|
||||
*
|
||||
* Warning: Don't use this unless you know what you're doing.
|
||||
*
|
||||
* \param list List object.
|
||||
* \param list List object.
|
||||
* \retval <0 error
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_PutNode (LinkedList * list, LL_node * node)
|
||||
LL_PutNode(LinkedList *list, LL_node *node)
|
||||
{
|
||||
if (!list)
|
||||
return -1;
|
||||
@@ -237,62 +320,87 @@ LL_PutNode (LinkedList * list, LL_node * node)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Access list's first node's data.
|
||||
* Set list's "current" pointer to the first node and return its data.
|
||||
* \param list List object.
|
||||
* \return Pointer to first node's data; \c NULL on error.
|
||||
*/
|
||||
void *
|
||||
LL_GetFirst (LinkedList * list) // gets data from first node
|
||||
LL_GetFirst(LinkedList *list)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
if (0 > LL_Rewind (list))
|
||||
if (0 > LL_Rewind(list))
|
||||
return NULL;
|
||||
|
||||
return LL_Get (list);
|
||||
return LL_Get(list);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
/** Access next node's data.
|
||||
* Advance list's "current" pointer to the next node and return its data.
|
||||
* \param list List object.
|
||||
* \return Pointer to next node's data; \c NULL on error.
|
||||
*/
|
||||
void *
|
||||
LL_GetNext (LinkedList * list) // ... next node
|
||||
LL_GetNext(LinkedList *list)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
if (0 > LL_Next (list))
|
||||
if (0 > LL_Next(list))
|
||||
return NULL;
|
||||
|
||||
return LL_Get (list);
|
||||
return LL_Get(list);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Access previous node's data.
|
||||
* Set list's "current" pointer to the previous node, and return its data.
|
||||
* \param list List object.
|
||||
* \return Pointer to previous node's data; \c NULL on error.
|
||||
*/
|
||||
void *
|
||||
LL_GetPrev (LinkedList * list) // ... prev node
|
||||
LL_GetPrev(LinkedList *list)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
if (0 > LL_Prev (list))
|
||||
if (0 > LL_Prev(list))
|
||||
return NULL;
|
||||
|
||||
return LL_Get (list);
|
||||
return LL_Get(list);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Access list's last node's data.
|
||||
* Set list's "current" pointer to the last node and return its data.
|
||||
* \param list List object.
|
||||
* \return Pointer to last node's data; \c NULL on error.
|
||||
*/
|
||||
void *
|
||||
LL_GetLast (LinkedList * list) // ... last node
|
||||
LL_GetLast(LinkedList *list)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
if (0 > LL_End (list))
|
||||
if (0 > LL_End(list))
|
||||
return NULL;
|
||||
|
||||
return LL_Get (list);
|
||||
return LL_Get(list);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Add/append a new node after current one in the list.
|
||||
* \param list List object.
|
||||
* \param add Pointer to new node's data.
|
||||
* \retval <0 error
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_AddNode (LinkedList * list, void *add) // Adds node AFTER current one
|
||||
LL_AddNode(LinkedList *list, void *add)
|
||||
{
|
||||
LL_node *node;
|
||||
|
||||
@@ -304,7 +412,7 @@ LL_AddNode (LinkedList * list, void *add) // Adds node AFTER current one
|
||||
|
||||
//LL_dprint(list);
|
||||
|
||||
node = malloc (sizeof (LL_node));
|
||||
node = malloc(sizeof(LL_node));
|
||||
if (!node)
|
||||
return -1;
|
||||
//printf("Allocated node\n");
|
||||
@@ -346,9 +454,15 @@ LL_AddNode (LinkedList * list, void *add) // Adds node AFTER current one
|
||||
return 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Add/insert a new node before current one in the list.
|
||||
* \param list List object.
|
||||
* \param add Pointer to new node's data.
|
||||
* \retval <0 error
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_InsertNode (LinkedList * list, void *add) // Adds node BEFORE current one
|
||||
LL_InsertNode(LinkedList *list, void *add)
|
||||
{
|
||||
LL_node *node;
|
||||
|
||||
@@ -359,7 +473,7 @@ LL_InsertNode (LinkedList * list, void *add) // Adds node BEFORE current one
|
||||
if (!list->current)
|
||||
return -1;
|
||||
|
||||
node = malloc (sizeof (LL_node));
|
||||
node = malloc(sizeof(LL_node));
|
||||
if (!node)
|
||||
return -1;
|
||||
|
||||
@@ -384,7 +498,7 @@ LL_InsertNode (LinkedList * list, void *add) // Adds node BEFORE current one
|
||||
// Removes a node from the link
|
||||
// ... and advances one node forward
|
||||
void *
|
||||
LL_DeleteNode (LinkedList * list)
|
||||
LL_DeleteNode(LinkedList *list)
|
||||
{
|
||||
LL_node *next, *prev;
|
||||
void *data;
|
||||
@@ -399,8 +513,8 @@ LL_DeleteNode (LinkedList * list)
|
||||
return NULL;
|
||||
|
||||
/*
|
||||
printf ("LL_DeleteNode: Before...\n");
|
||||
LL_dprint (list);
|
||||
printf("LL_DeleteNode: Before...\n");
|
||||
LL_dprint(list);
|
||||
*/
|
||||
|
||||
next = list->current->next;
|
||||
@@ -419,42 +533,53 @@ LL_DeleteNode (LinkedList * list)
|
||||
//if(list->current->data) free(list->current->data);
|
||||
list->current->data = NULL;
|
||||
|
||||
free (list->current);
|
||||
free(list->current);
|
||||
|
||||
list->current = next;
|
||||
|
||||
/*
|
||||
printf ("LL_DeleteNode: After...\n");
|
||||
LL_dprint (list);
|
||||
printf("LL_DeleteNode: After...\n");
|
||||
LL_dprint(list);
|
||||
*/
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Removes a specific node...
|
||||
|
||||
/** Remove a specific node from the list.
|
||||
* find a node by a pointer to it's data and remove it.
|
||||
* \param list List object.
|
||||
* \param data Pointer to data of not to delete.
|
||||
* \return Pointer to data of deleted node; \c NULL on error.
|
||||
*/
|
||||
void *
|
||||
LL_Remove (LinkedList * list, void *data)
|
||||
LL_Remove(LinkedList *list, void *data)
|
||||
{
|
||||
void *find;
|
||||
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
LL_Rewind (list);
|
||||
LL_Rewind(list);
|
||||
do {
|
||||
find = LL_Get (list);
|
||||
find = LL_Get(list);
|
||||
if (find == data)
|
||||
return LL_DeleteNode (list);
|
||||
} while (LL_Next (list) == 0);
|
||||
return LL_DeleteNode(list);
|
||||
} while (LL_Next(list) == 0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Stack operations
|
||||
|
||||
/** Add/append a new node after the last one in the list.
|
||||
* Jump to the last node in the list and append a new node.
|
||||
* \param list List object.
|
||||
* \param add Pointer to new node's data.
|
||||
* \retval <0 error
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_Push (LinkedList * list, void *add) // Add node to end of list
|
||||
LL_Push(LinkedList *list, void *add) // Add node to end of list
|
||||
{
|
||||
if (!list)
|
||||
return -1;
|
||||
@@ -462,69 +587,97 @@ LL_Push (LinkedList * list, void *add) // Add node to end of list
|
||||
return -1;
|
||||
|
||||
// printf("Going to end of list...\n");
|
||||
LL_End (list);
|
||||
LL_End(list);
|
||||
|
||||
// printf("Adding node...\n");
|
||||
return LL_AddNode (list, add);
|
||||
return LL_AddNode(list, add);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Remove the last node from the list, and return its data.
|
||||
* Jump to the last node in the list, remove it from the list and return its data.
|
||||
* \param list List object.
|
||||
* \return Pointer to data of deleted node; \c NULL on error.
|
||||
*/
|
||||
void *
|
||||
LL_Pop (LinkedList * list) // Remove node from end of list
|
||||
LL_Pop(LinkedList *list) // Remove node from end of list
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
if (0 > LL_End (list))
|
||||
if (0 > LL_End(list))
|
||||
return NULL;
|
||||
|
||||
return LL_DeleteNode (list);
|
||||
return LL_DeleteNode(list);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Access list's last node's data.
|
||||
* Set list's "current" pointer to the last node and return its data.
|
||||
* \param list List object.
|
||||
* \return Pointer to last node's data; \c NULL on error.
|
||||
*/
|
||||
void *
|
||||
LL_Top (LinkedList * list) // Peek at end node
|
||||
LL_Top(LinkedList *list) // Peek at end node
|
||||
{
|
||||
return LL_GetLast (list);
|
||||
return LL_GetLast(list);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Remove the first node from the list, and return its data.
|
||||
* Jump to the first node in the list, remove it from the list and return its data.
|
||||
* \param list List object.
|
||||
* \return Pointer to data of deleted node; \c NULL on error.
|
||||
*/
|
||||
void *
|
||||
LL_Shift (LinkedList * list) // Remove node from start of list
|
||||
LL_Shift(LinkedList *list) // Remove node from start of list
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
if (0 > LL_Rewind (list))
|
||||
if (0 > LL_Rewind(list))
|
||||
return NULL;
|
||||
|
||||
return LL_DeleteNode (list);
|
||||
return LL_DeleteNode(list);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Access list's first node's data.
|
||||
* Set list's "current" pointer to the first node and return its data.
|
||||
* \param list List object.
|
||||
* \return Pointer to first node's data; \c NULL on error.
|
||||
*/
|
||||
void *
|
||||
LL_Look (LinkedList * list) // Peek at first node
|
||||
LL_Look(LinkedList *list) // Peek at first node
|
||||
{
|
||||
return LL_GetFirst (list);
|
||||
return LL_GetFirst(list);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Add/insert a new node before the first one in the list.
|
||||
* Jump to the first node in the list and insert a new node before that one.
|
||||
* \param list List object.
|
||||
* \param add Pointer to new node's data.
|
||||
* \retval <0 error
|
||||
* \retval 0 success
|
||||
*/
|
||||
int
|
||||
LL_Unshift (LinkedList * list, void *add) // Add node to beginning of list
|
||||
LL_Unshift(LinkedList *list, void *add) // Add node to beginning of list
|
||||
{
|
||||
if (!list)
|
||||
return -1;
|
||||
if (!add)
|
||||
return -1;
|
||||
|
||||
LL_Rewind (list);
|
||||
LL_Rewind(list);
|
||||
|
||||
return LL_InsertNode (list, add);
|
||||
return LL_InsertNode(list, add);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
LL_Roll (LinkedList * list) // Make last node first
|
||||
LL_Roll(LinkedList *list) // Make last node first
|
||||
{
|
||||
LL_node *node, *next;
|
||||
|
||||
@@ -532,7 +685,7 @@ LL_Roll (LinkedList * list) // Make last node first
|
||||
return -1;
|
||||
//if(!list->current) return -1;
|
||||
|
||||
if (0 > LL_End (list))
|
||||
if (0 > LL_End(list))
|
||||
return -1;
|
||||
|
||||
// Avoid rolling an empty list, or unlinking the head/tail...
|
||||
@@ -549,9 +702,9 @@ LL_Roll (LinkedList * list) // Make last node first
|
||||
|
||||
node = list->current;
|
||||
|
||||
LL_node_Unlink (node);
|
||||
LL_node_Unlink(node);
|
||||
|
||||
if (0 > LL_Rewind (list))
|
||||
if (0 > LL_Rewind(list))
|
||||
return -1;
|
||||
|
||||
next = list->head.next;
|
||||
@@ -564,9 +717,10 @@ LL_Roll (LinkedList * list) // Make last node first
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
LL_UnRoll (LinkedList * list) // Roll the other way...
|
||||
LL_UnRoll(LinkedList *list) // Roll the other way...
|
||||
{
|
||||
LL_node *node, *prev;
|
||||
|
||||
@@ -574,7 +728,7 @@ LL_UnRoll (LinkedList * list) // Roll the other way...
|
||||
return -1;
|
||||
//if(!list->current) return -1;
|
||||
|
||||
if (0 > LL_Rewind (list))
|
||||
if (0 > LL_Rewind(list))
|
||||
return -1;
|
||||
|
||||
// Avoid rolling an empty list, or unlinking the head/tail...
|
||||
@@ -591,9 +745,9 @@ LL_UnRoll (LinkedList * list) // Roll the other way...
|
||||
|
||||
node = list->current;
|
||||
|
||||
LL_node_Unlink (node);
|
||||
LL_node_Unlink(node);
|
||||
|
||||
if (0 > LL_End (list))
|
||||
if (0 > LL_End(list))
|
||||
return -1;
|
||||
|
||||
prev = list->tail.prev;
|
||||
@@ -606,11 +760,12 @@ LL_UnRoll (LinkedList * list) // Roll the other way...
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Add an item to the end of its "priority group"
|
||||
// The list is assumed to be sorted already...
|
||||
int
|
||||
LL_PriorityEnqueue (LinkedList * list, void *add, int compare (void *, void *))
|
||||
LL_PriorityEnqueue(LinkedList *list, void *add, int compare(void *, void *))
|
||||
{
|
||||
void *data;
|
||||
int i;
|
||||
@@ -624,28 +779,29 @@ LL_PriorityEnqueue (LinkedList * list, void *add, int compare (void *, void *))
|
||||
|
||||
// From the end of the list, keep searching while we're "less than"
|
||||
// the given nodes...
|
||||
LL_End (list);
|
||||
LL_End(list);
|
||||
do {
|
||||
data = LL_Get (list);
|
||||
data = LL_Get(list);
|
||||
if (data) {
|
||||
i = compare (add, data);
|
||||
i = compare(add, data);
|
||||
if (i >= 0) // If we're in the right place, add it and exit
|
||||
{
|
||||
LL_AddNode (list, add);
|
||||
LL_AddNode(list, add);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} while (LL_Prev (list) == 0);
|
||||
} while (LL_Prev(list) == 0);
|
||||
|
||||
// If we're less than *everything*, put it at the beginning
|
||||
LL_Unshift (list, add);
|
||||
LL_Unshift(list, add);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
LL_SwapNodes (LL_node * one, LL_node * two) // Switch two nodes positions...
|
||||
LL_SwapNodes(LL_node *one, LL_node *two) // Switch two nodes positions...
|
||||
{
|
||||
LL_node *firstprev, *firstnext;
|
||||
LL_node *secondprev, *secondnext;
|
||||
@@ -687,16 +843,21 @@ LL_SwapNodes (LL_node * one, LL_node * two) // Switch two nodes positions...
|
||||
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
int
|
||||
LL_nSwapNodes (int one, int two) // Switch two nodes positions...
|
||||
LL_nSwapNodes(int one, int two) // Switch two nodes positions...
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
/** Calculate the length of a list.
|
||||
* \param list List object.
|
||||
* \return Number of nodes in the list; \c -1 on error.
|
||||
*/
|
||||
int
|
||||
LL_Length (LinkedList * list) // Returns # of nodes in entire list
|
||||
LL_Length(LinkedList *list) // Returns # of nodes in entire list
|
||||
{
|
||||
LL_node *node;
|
||||
int num = 0;
|
||||
@@ -712,6 +873,7 @@ LL_Length (LinkedList * list) // Returns # of nodes in entire list
|
||||
return num;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Searching...
|
||||
// Goes to the list item which matches "value", and returns the
|
||||
@@ -722,7 +884,7 @@ LL_Length (LinkedList * list) // Returns # of nodes in entire list
|
||||
// Note that this does *not* rewind the list first! You should do
|
||||
// it yourself if you want to start from the beginning!
|
||||
void *
|
||||
LL_Find (LinkedList * list, int compare (void *, void *), void *value)
|
||||
LL_Find(LinkedList *list, int compare(void *, void *), void *value)
|
||||
{
|
||||
void *data;
|
||||
|
||||
@@ -734,22 +896,23 @@ LL_Find (LinkedList * list, int compare (void *, void *), void *value)
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
data = LL_Get (list);
|
||||
if (0 == compare (data, value))
|
||||
data = LL_Get(list);
|
||||
if (0 == compare(data, value))
|
||||
return data;
|
||||
|
||||
} while (LL_Next (list) == 0);
|
||||
} while (LL_Next(list) == 0);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Array like...
|
||||
// Goes to the nth list item, and returns the
|
||||
// data found there.
|
||||
//
|
||||
void *
|
||||
LL_GetByIndex (LinkedList * list, int index)
|
||||
LL_GetByIndex(LinkedList *list, int index)
|
||||
{
|
||||
LL_node *node;
|
||||
int num = 0;
|
||||
@@ -767,11 +930,19 @@ LL_GetByIndex (LinkedList * list, int index)
|
||||
return NULL; // got past the end
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Sorts the list, then rewinds it...
|
||||
//
|
||||
|
||||
/** Sort list by its contents.
|
||||
* The list gets sorted using a comparison function for the data of its nodes.
|
||||
* After the sorting, the list's current pointer is set to the first node.
|
||||
* \param list List object.
|
||||
* \param compare Pointer to a comparison function, that takes to void pointers
|
||||
is arguments and returns an int > 0 when the first argument
|
||||
is considered greater then the second.
|
||||
* \retval <0 error
|
||||
* \retval 0 success.
|
||||
*/
|
||||
int
|
||||
LL_Sort (LinkedList * list, int compare (void *, void *))
|
||||
LL_Sort(LinkedList *list, int compare(void *, void *))
|
||||
{
|
||||
int i, j; // Junk / loop variables
|
||||
int numnodes; // number of nodes in list
|
||||
@@ -783,28 +954,28 @@ LL_Sort (LinkedList * list, int compare (void *, void *))
|
||||
if (!compare)
|
||||
return -1;
|
||||
|
||||
numnodes = LL_Length (list); // get the number of nodes...
|
||||
if (0 > LL_End (list))
|
||||
numnodes = LL_Length(list); // get the number of nodes...
|
||||
if (0 > LL_End(list))
|
||||
return -1; // Find the last node.
|
||||
last = LL_GetNode (list);
|
||||
last = LL_GetNode(list);
|
||||
|
||||
if (numnodes < 2)
|
||||
return 0;
|
||||
|
||||
for (i = numnodes - 1; i > 0; i--) {
|
||||
LL_Rewind (list); // get the first node again
|
||||
LL_Rewind(list); // get the first node again
|
||||
best = last; // reset our "best" node
|
||||
|
||||
for (j = 0; j < i; j++) {
|
||||
current = LL_GetNode (list);
|
||||
current = LL_GetNode(list);
|
||||
// If we found a better match...
|
||||
if (compare (current->data, best->data) > 0) {
|
||||
if (compare(current->data, best->data) > 0) {
|
||||
best = current; // keep track of the "best" match
|
||||
}
|
||||
LL_Next (list); // Go to the next node.
|
||||
LL_Next(list); // Go to the next node.
|
||||
}
|
||||
|
||||
LL_SwapNodes (last, best); // Switch two nodes...
|
||||
LL_SwapNodes(last, best); // Switch two nodes...
|
||||
if (best)
|
||||
last = best->prev;
|
||||
else
|
||||
@@ -814,24 +985,24 @@ LL_Sort (LinkedList * list, int compare (void *, void *))
|
||||
}
|
||||
|
||||
//return LLFindFirst(current); // return pointer to the first node.
|
||||
LL_Rewind (list);
|
||||
LL_Rewind(list);
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
LL_dprint (LinkedList * list)
|
||||
LL_dprint(LinkedList *list)
|
||||
{
|
||||
LL_node *current;
|
||||
|
||||
current = &list->head;
|
||||
|
||||
printf ("Head: prev:\t0x%p\taddr:\t0x%p\tnext:\t0x%p\n", list->head.prev, &list->head, list->head.next);
|
||||
printf("Head: prev:\t0x%p\taddr:\t0x%p\tnext:\t0x%p\n", list->head.prev, &list->head, list->head.next);
|
||||
|
||||
for (current = current->next; current != &list->tail; current = current->next) {
|
||||
printf ("node: prev:\t0x%p\taddr:\t0x%p\tnext:\t0x%p\n", current->prev, current, current->next);
|
||||
printf("node: prev:\t0x%p\taddr:\t0x%p\tnext:\t0x%p\n", current->prev, current, current->next);
|
||||
}
|
||||
|
||||
printf ("Tail: prev:\t0x%p\taddr:\t0x%p\tnext:\t0x%p\n", list->tail.prev, &list->tail, list->tail.next);
|
||||
printf("Tail: prev:\t0x%p\taddr:\t0x%p\tnext:\t0x%p\n", list->tail.prev, &list->tail, list->tail.next);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user