|
From: <enl...@li...> - 2001-04-14 07:19:46
|
Enlightenment CVS committal
Author : rbdpngn
Project : e17
Module : libs/ewd
Dir : e17/libs/ewd/src
Modified Files:
Ewd.h Makefile.am ewd_list.c ewd_list.h ewd_macros.h
Added Files:
ewd_dlist.c ewd_dlist.h ewd_hash.c ewd_hash.h
ewd_list_private.h ewd_threads.c ewd_threads.h ewd_tree.c
ewd_tree.h ewd_value.c ewd_value.h
Log Message:
This stuff is not quite up to the level I was hoping to have before committing,
but smugg wanted to use some of the new list functions for EWL, so here it goes.
Currently, the list code is pretty good, added the means for adding a free
callback as well as a function for iterating through the list and executing a
specified function for each node's data. Also created single linked lists as
well as the double linked lists that were already in place. The single linked
lists have all the methods as the double except for moving to the previous node.
The AVL tree is also included in this commit and was fairly well tested under
another project I was working on. Unfortunately, I haven't had a chance to test
it thoroughly since modifying it for EWD.
Also, I've included the beginnings of attempts at making the data structures
threadsafe. This is optional and pthreads should not be required to be installed
to use the lib.
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewd/src/Ewd.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -3 -r1.1.1.1 -r1.2
--- Ewd.h 2001/04/09 19:49:16 1.1.1.1
+++ Ewd.h 2001/04/14 07:19:16 1.2
@@ -1,3 +1,6 @@
+#ifndef _EWD_H
+#define _EWD_H
+
#include <stdio.h>
#include <stdlib.h>
@@ -9,5 +12,15 @@
#define FALSE 0
#endif
+#ifndef PACKAGE
+#define PACKAGE "Ewd"
+#endif
+
+#include <ewd_threads.h>
+#include <ewd_value.h>
#include <ewd_list.h>
+#include <ewd_dlist.h>
+#include <ewd_tree.h>
#include <ewd_macros.h>
+
+#endif
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewd/src/Makefile.am,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -3 -r1.2 -r1.3
--- Makefile.am 2001/04/10 16:19:14 1.2
+++ Makefile.am 2001/04/14 07:19:16 1.3
@@ -6,10 +6,18 @@
installed_headers_DATA = \
Ewd.h \
ewd_list.h \
+ ewd_dlist.h \
+ ewd_list_private.h \
+ ewd_tree.h \
+ ewd_value.h \
+ ewd_threads.h \
ewd_macros.h
libewd_la_SOURCES = \
+ ewd_value.c \
ewd_list.c \
+ ewd_dlist.c \
+ ewd_tree.c
libewd_la_LIBADD = -lm
libewd_la_LDFLAGS = -version-info 0:0:0
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewd/src/ewd_list.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -3 -r1.1.1.1 -r1.2
--- ewd_list.c 2001/04/09 19:49:18 1.1.1.1
+++ ewd_list.c 2001/04/14 07:19:16 1.2
@@ -1,225 +1,440 @@
-#include <Ewd.h>
+#include <../config.h>
-static int ewd_list_node_init();
+#include <Ewd.h>
+#include <ewd_list_private.h>
-/* Creating and initializing new list structures */
-Ewd_List *
-ewd_list_new()
+/*
+ * Description: Create and initialize a new list.
+ * Parameters: None
+ * Returns: Returns a new initialized list.
+ */
+Ewd_List *ewd_list_new()
{
Ewd_List *list = NULL;
- list = (Ewd_List *) malloc(sizeof(Ewd_List));
-
+ list = (Ewd_List *)malloc(sizeof(Ewd_List));
if (!list)
return NULL;
- memset(list, 0, sizeof(Ewd_List));
+ if (!ewd_list_init(list)) {
+ IF_FREE(list);
+ return NULL;
+ }
return list;
}
-/* Free the list and it's nodes */
-void
-ewd_list_destroy(Ewd_List * _ewd_list)
+/*
+ * Description: Initialize a list to some sane starting values.
+ * Parameters: 1. list - the list to initialize
+ * Returns: FALSE if an error occurs, TRUE if successful
+ */
+int ewd_list_init(Ewd_List *list)
{
- Ewd_List_Node *node;
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
- if (!_ewd_list)
- return;
+ memset(list, 0, sizeof(Ewd_List));
- node = _ewd_list->first;
- while (node) {
- Ewd_List_Node *old;
+ EWD_INIT_STRUCT_LOCK(list);
- old = node;
- node = node->next;
- ewd_list_node_destroy(old);
- }
+ return TRUE;
+}
+
+/*
+ * Description: Free a list and all of it's nodes.
+ * Parameters: 1. list - the list to be free'd
+ * Returns: None
+ */
+void ewd_list_destroy(Ewd_List * list)
+{
+ CHECK_PARAM_POINTER("list", list);
+
+ EWD_LOCK_STRUCT(list);
+
+ while (list->first)
+ _ewd_list_remove_first(list);
+
+ EWD_UNLOCK_STRUCT(list);
+
+ IF_FREE(list);
+}
+
+/*
+ * Description: Add a function that will be called at node destroy time, the
+ * function will be passed the value of the node to be destroyed.
+ * Parameters: 1. list - the list that will use this function when nodes are
+ * destroyed.
+ * 2. free_func - the function that will be passed the value of
+ * the node being freed.
+ * Returns: TRUE on successful set, FALSE otherwise.
+ */
+int ewd_list_set_free_cb(Ewd_List * list, Ewd_Free_Cb free_func)
+{
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+
+ list->free_func = free_func;
+
+ EWD_UNLOCK_STRUCT(list);
+
+ return TRUE;
+}
+
+/*
+ * Description: Checks the list for any nodes.
+ * Parameters: 1. list - the list to check
+ * Returns: TRUE if no nodes in list, FALSE if the list contains nodes
+ */
+int ewd_list_is_empty(Ewd_List * list)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_is_empty(list);
+ EWD_UNLOCK_STRUCT(list);
- free(_ewd_list);
+ return ret;
}
/* Check to see if the list has any data in it */
-int
-ewd_list_is_empty(Ewd_List * _ewd_list)
+int _ewd_list_is_empty(Ewd_List * list)
{
- if (!_ewd_list)
- return TRUE;
+ if (!list)
+ return FALSE;
- if (_ewd_list->nodes)
+ if (list->nodes)
return FALSE;
return TRUE;
}
+/*
+ * Description: Returns the number of the current node
+ * Parameters: 1. list - the list to return the number of the current node
+ * Returns: The number of the current node in the list.
+ */
+int ewd_list_index(Ewd_List * list)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_index(list);
+ EWD_UNLOCK_STRUCT(list);
+
+ return ret;
+}
+
+/* Find the current position in the list */
+int _ewd_list_index(Ewd_List * list)
+{
+ int index;
+
+ if (!list)
+ return FALSE;
+
+ index = list->index;
+
+ return index;
+}
+
+/*
+ * Description: Find the number of nodes in the list.
+ * Parameters: 1. list - the list to find the number of nodes
+ * Returns: The number of nodes in the list.
+ */
+int ewd_list_nodes(Ewd_List * list)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_nodes(list);
+ EWD_UNLOCK_STRUCT(list);
+
+ return ret;
+}
+
/* Find the current position in the list */
-int
-ewd_list_index(Ewd_List * _ewd_list)
+int _ewd_list_nodes(Ewd_List * list)
{
- if (!_ewd_list)
+ int index;
+
+ if (!list)
return FALSE;
- return _ewd_list->index;
+ index = list->nodes;
+
+ return index;
}
+/*
+ * Description: Append data to the list.
+ * Parameters: 1. list - the list to append the data
+ * 2. data - the data to append to the list.
+ * Returns: FALSE if an error occurs, TRUE if the data is appended successfully
+ */
+int ewd_list_append(Ewd_List * list, void *data)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_append(list, data);
+ EWD_UNLOCK_STRUCT(list);
+
+ return ret;
+}
+
/* For adding items to the end of the list */
-void
-ewd_list_append(Ewd_List * _ewd_list, void *_data)
+int _ewd_list_append(Ewd_List * list, void *data)
{
Ewd_List_Node *end = NULL;
- if (!_ewd_list)
- return;
+ if (!list)
+ return FALSE;
end = ewd_list_node_new();
if (!end)
- return;
+ return FALSE;
- end->prev = _ewd_list->last;
- if (_ewd_list->last)
- _ewd_list->last->next = end;
-
- end->data = _data;
- _ewd_list->last = end;
-
- if (_ewd_list->first == NULL) {
- _ewd_list->first = _ewd_list->current = end;
- _ewd_list->index = 1;
+ if (list->last) {
+ EWD_LOCK_STRUCT(list->last);
+ list->last->next = end;
+ EWD_UNLOCK_STRUCT(list->last);
}
+
+ EWD_LOCK_STRUCT(end);
+ end->data = data;
+ EWD_UNLOCK_STRUCT(end);
+
+ list->last = end;
+
+ if (list->first == NULL) {
+
+ list->first = list->current = end;
+
+ list->index = 1;
+ }
+
+ list->nodes++;
- _ewd_list->nodes++;
+ return TRUE;
+}
+
+/*
+ * Description: Prepend data to the beginning of the list
+ * Parameters: 1. list - the list to prepend the data
+ * 2. data - the data to prepend to the list
+ * Returns: FALSE if an error occurs, TRUE if data prepended successfully
+ */
+int ewd_list_prepend(Ewd_List * list, void *data)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_prepend(list, data);
+ EWD_UNLOCK_STRUCT(list);
+
+ return ret;
}
/* For adding items to the beginning of the list */
-void
-ewd_list_prepend(Ewd_List * _ewd_list, void *_data)
+int _ewd_list_prepend(Ewd_List * list, void *data)
{
Ewd_List_Node *start = NULL;
- if (!_ewd_list || !_data)
- return;
+ if (!list)
+ return FALSE;
/* Create a new node to add to the list */
start = ewd_list_node_new();
if (!start)
- return;
+ return FALSE;
/* Put it at the beginning of the list */
- start->next = _ewd_list->first;
- if (_ewd_list->first)
- _ewd_list->first->prev = start;
-
- start->data = _data;
- _ewd_list->first = start;
-
- /* If there's no current item selected, select the first one
- * otherwise increment the index */
- if (!_ewd_list->current) {
- _ewd_list->current = _ewd_list->first;
- _ewd_list->index = 1;
- } else
- _ewd_list->index++;
+ EWD_LOCK_STRUCT(start);
+ start->next = list->first;
+ start->data = data;
+ EWD_UNLOCK_STRUCT(start);
+ list->first = start;
+
+ /* If there's no current item selected, select the first one */
+ if (!list->current)
+ list->current = list->first;
+
/* If no last node, then the first node is the last node */
- if (_ewd_list->last == NULL)
- _ewd_list->last = _ewd_list->first;
+ if (list->last == NULL)
+ list->last = list->first;
- _ewd_list->nodes++;
+ list->nodes++;
+ list->index++;
+
+ return TRUE;
}
+/*
+ * Description: Insert data at the current point in the list
+ * Parameters: 1. list - the list to hold the inserted data
+ * 2. data - the data to insert into the list
+ * Returns: FALSE on an error, TRUE on success
+ */
+int ewd_list_insert(Ewd_List * list, void *data)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_insert(list, data);
+ EWD_LOCK_STRUCT(list);
+
+ return ret;
+}
+
/* For adding items in front of the current position in the list */
-void
-ewd_list_insert(Ewd_List * _ewd_list, void *_data)
+int _ewd_list_insert(Ewd_List * list, void *data)
{
Ewd_List_Node *new = NULL;
- if (!_ewd_list || !_data)
- return;
+ if (!list)
+ return FALSE;
/*
* If the current point is at the beginning of the list, then it's the
* same as prepending it to the list.
*/
- if (_ewd_list->current == _ewd_list->first) {
- ewd_list_prepend(_ewd_list, _data);
- return;
- } else if (!_ewd_list->current) {
- ewd_list_append(_ewd_list, _data);
- return;
- }
+ if (list->current == list->first)
+ return _ewd_list_prepend(list, data);
+ else if (!list->current || list->current == list->last)
+ return _ewd_list_append(list, data);
/* Create the node to insert into the list */
new = ewd_list_node_new();
if (!new)
- return;
+ return FALSE;
/* Setup the fields of the new node */
- new->data = _data;
- new->next = _ewd_list->current;
- new->prev = _ewd_list->current->prev;
- if (_ewd_list->current->prev)
- _ewd_list->current->prev->next = new;
- _ewd_list->current->prev = new;
+ EWD_LOCK_STRUCT(new);
+ new->data = data;
+ new->next = list->current;
+ EWD_UNLOCK_STRUCT(new);
+
+ /* And hook the node into the list */
+ _ewd_list_goto_index(list, _ewd_list_index(list) - 1);
+
+ EWD_LOCK_STRUCT(list->current);
+ list->current->next = new;
+ EWD_UNLOCK_STRUCT(list->current);
+
+ list->current = new;
+ list->index++;
+ list->nodes++;
+
+ return TRUE;
+}
- _ewd_list->index++;
- _ewd_list->nodes++;
+/*
+ * Description: Remove the current item from the list.
+ * Parameters: 1. list - the list to remove the current item
+ * Returns: TRUE on success, FALSE on error
+ */
+int ewd_list_remove(Ewd_List * list)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_remove(list);
+ EWD_UNLOCK_STRUCT(list);
+
+ return ret;
}
/* Remove the current item from the list */
-void
-ewd_list_remove(Ewd_List * _ewd_list)
+int _ewd_list_remove(Ewd_List * list)
{
Ewd_List_Node *old;
- if (!_ewd_list)
- return;
+ if (!list)
+ return FALSE;
- if (ewd_list_is_empty(_ewd_list))
- return;
+ if (_ewd_list_is_empty(list))
+ return FALSE;
- if (!_ewd_list->current)
- return;
+ if (!list->current)
+ return FALSE;
- if (_ewd_list->current == _ewd_list->first) {
- ewd_list_remove_first(_ewd_list);
- return;
- }
+ if (list->current == list->first)
+ return _ewd_list_remove_first(list);
- if (_ewd_list->current == _ewd_list->last) {
- ewd_list_remove_last(_ewd_list);
- return;
- }
+ if (list->current == list->last)
+ return _ewd_list_remove_last(list);
+
+ old = list->current;
+
+ _ewd_list_goto_index(list, ewd_list_index(list));
- _ewd_list->current->prev->next = _ewd_list->current->next;
- _ewd_list->current->next->prev = _ewd_list->current->prev;
+ EWD_LOCK_STRUCT(list->current);
+ EWD_LOCK_STRUCT(old);
- old = _ewd_list->current;
- _ewd_list->current = _ewd_list->current->next;
+ list->current->next = old->next;
+ old->next = NULL;
+
+ EWD_UNLOCK_STRUCT(old);
+ EWD_UNLOCK_STRUCT(list->current);
+
+ ewd_list_node_destroy(old, list->free_func);
+ list->nodes--;
- ewd_list_node_destroy(old);
- _ewd_list->nodes--;
+ return TRUE;
+}
+
+/*
+ * Description: Remove the first item from the list.
+ * Parameters: 1. list - the list to remove the current item
+ * Returns: TRUE on success, FALSE on error
+ */
+int ewd_list_remove_first(Ewd_List * list)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_remove_first(list);
+ EWD_UNLOCK_STRUCT(list);
+
+ return ret;
}
/* Remove the first item from the list */
-void
-ewd_list_remove_first(Ewd_List * list)
+int _ewd_list_remove_first(Ewd_List * list)
{
Ewd_List_Node *old;
if (!list)
- return;
+ return FALSE;
- if (ewd_list_is_empty(list))
- return;
+ if (_ewd_list_is_empty(list))
+ return FALSE;
if (!list->first)
- return;
+ return FALSE;
old = list->first;
list->first = list->first->next;
- if (list->first)
- list->first->prev = NULL;
if (list->current == old)
list->current = list->first;
@@ -229,185 +444,319 @@
if (list->last == old)
list->last = list->first;
- ewd_list_node_destroy(old);
+ ewd_list_node_destroy(old, list->free_func);
list->nodes--;
+
+ return TRUE;
}
+/*
+ * Description: Remove the last item from the list.
+ * Parameters: 1. list - the list to remove the last node from
+ * Returns: TRUE on success, FALSE on error
+ */
+int ewd_list_remove_last(Ewd_List * list)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_remove_last(list);
+ EWD_UNLOCK_STRUCT(list);
+
+ return ret;
+}
+
/* Remove the last item from the list */
-void
-ewd_list_remove_last(Ewd_List * _ewd_list)
+int _ewd_list_remove_last(Ewd_List * list)
{
+ int index;
Ewd_List_Node *old;
+
+ if (!list)
+ return FALSE;
+
+ if (_ewd_list_is_empty(list))
+ return FALSE;
+
+ if (!list->last)
+ return FALSE;
- if (!_ewd_list)
- return;
+ old = list->last;
+ if (list->current == list->last)
+ index = list->nodes - 1;
+ else
+ index = _ewd_list_index(list);
+
+ _ewd_list_goto_index(list, list->nodes - 1);
+ list->last = list->current;
+ _ewd_list_goto_index(list, index);
+
+ EWD_LOCK_STRUCT(old);
+ old->next = NULL;
+ EWD_UNLOCK_STRUCT(old);
+
+ ewd_list_node_destroy(old, list->free_func);
+ list->nodes--;
+
+ return TRUE;
+}
- if (ewd_list_is_empty(_ewd_list))
- return;
+/*
+ * Description: Move the current item to the index number
+ * Parameters: 1. list - the list to move the current item
+ * 2. index - the position to move the current item
+ * Returns: TRUE on success, FALSE on error
+ */
+int ewd_list_goto_index(Ewd_List * list, int index)
+{
+ int ret;
- if (!_ewd_list->last)
- return;
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
- old = _ewd_list->last;
- if (_ewd_list->last->prev)
- _ewd_list->last->prev = NULL;
- _ewd_list->last = _ewd_list->first->prev;
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_goto_index(list, index);
+ EWD_UNLOCK_STRUCT(list);
- ewd_list_node_destroy(old);
- _ewd_list->nodes--;
+ return ret;
}
-/* Set the current position to the node at index */
-void
-ewd_list_goto_index(Ewd_List * _ewd_list, int _index)
+/* This is the non-threadsafe version, use this inside internal functions that
+ * already lock the list */
+int _ewd_list_goto_index(Ewd_List *list, int index)
{
int i;
- Ewd_List_Node *node;
- if (!_ewd_list)
- return;
+ if (!list)
+ return FALSE;
- node = _ewd_list->first;
- for (i = 0; i < _index && node; i++, node = node->next);
+ if (_ewd_list_is_empty(list))
+ return FALSE;
- if (!node)
- return;
+ if (index > _ewd_list_nodes(list) || index < 0)
+ return FALSE;
+
+ _ewd_list_goto_first(list);
+
+ for (i = 1; i < index && _ewd_list_next(list); i++);
+
+ list->index = i;
+
+ return TRUE;
+}
- _ewd_list->current = node;
- _ewd_list->index = _index;
+/*
+ * Description: Move the current item to the node that contains data
+ * Parameters: 1. list - the list to move the current item in
+ * 2. data - the data to find and set the current item to
+ * Returns: TRUE on success, FALSE on error
+ */
+int ewd_list_goto(Ewd_List * list, void *data)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_goto(list, data);
+ EWD_UNLOCK_STRUCT(list);
+
+ return ret;
}
/* Set the current position to the node containing data */
-void
-ewd_list_goto(Ewd_List * _ewd_list, void *_data)
+int _ewd_list_goto(Ewd_List * list, void *data)
{
int index;
Ewd_List_Node *node;
- if (!_ewd_list)
- return;
+ if (!list)
+ return FALSE;
index = 1;
- node = _ewd_list->first;
+
+ node = list->first;
+ EWD_LOCK_STRUCT(node);
while (node && node->data) {
- if (node->data == _data)
+ if (node->data == data)
break;
+ EWD_UNLOCK_STRUCT(node);
+
node = node->next;
+
+ EWD_LOCK_STRUCT(node);
index++;
}
if (!node)
- return;
+ return FALSE;
+ EWD_UNLOCK_STRUCT(node);
- _ewd_list->current = node;
- _ewd_list->index = index;
+ list->current = node;
+ list->index = index;
+
+ return TRUE;
}
+/*
+ * Description: :
+ */
+int ewd_list_goto_first(Ewd_List *list)
+{
+ int ret;
+
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_goto_first(list);
+ EWD_UNLOCK_STRUCT(list);
+
+ return ret;
+}
+
/* Set the current position to the start of the list */
-void
-ewd_list_goto_first(Ewd_List * _ewd_list)
+int _ewd_list_goto_first(Ewd_List * list)
+{
+
+ if (!list)
+ return FALSE;
+
+ list->current = list->first;
+ list->index = 1;
+
+ return TRUE;
+}
+
+int ewd_list_goto_last(Ewd_List * list)
{
- if (!_ewd_list)
- return;
+ int ret;
- _ewd_list->current = _ewd_list->first;
- _ewd_list->index = 1;
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_goto_last(list);
+ EWD_UNLOCK_STRUCT(list);
+
+ return ret;
}
/* Set the current position to the end of the list */
-void
-ewd_list_goto_last(Ewd_List * _ewd_list)
+int _ewd_list_goto_last(Ewd_List * list)
{
- if (!_ewd_list)
- return;
+ if (!list)
+ return FALSE;
+
+ list->current = list->last;
+ list->index = list->nodes;
- _ewd_list->current = _ewd_list->last;
- _ewd_list->index = _ewd_list->nodes;
+ return TRUE;
}
-/* Return the data of the current node without incrementing */
-void *
-ewd_list_current(Ewd_List * _ewd_list)
+void *ewd_list_current(Ewd_List * list)
{
- if (!_ewd_list) return FALSE;
+ void *ret;
- if (!_ewd_list->current)
- return NULL;
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_current(list);
+ EWD_UNLOCK_STRUCT(list);
- return _ewd_list->current->data;
+ return ret;
}
-/* Return the data contained in the current node and go to the next node */
-void *
-ewd_list_next(Ewd_List * _ewd_list)
+/* Return the data of the current node without incrementing */
+void *_ewd_list_current(Ewd_List * list)
{
- Ewd_List_Node *ret;
+ void *ret;
- if (!_ewd_list) return FALSE;
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
- if (!_ewd_list->current)
+ if (!list->current)
return NULL;
- if (_ewd_list->current == _ewd_list->current->next)
- return NULL;
+ EWD_LOCK_STRUCT(list->current);
+ ret = list->current->data;
+ EWD_UNLOCK_STRUCT(list->current);
- ret = _ewd_list->current;
- _ewd_list->current = _ewd_list->current->next;
- _ewd_list->index++;
+ return ret;
+}
- return ret->data;
+void *ewd_list_next(Ewd_List * list)
+{
+ void *data;
+
+ EWD_LOCK_STRUCT(list);
+ data = _ewd_list_next(list);
+ EWD_UNLOCK_STRUCT(list);
+
+ return data;
}
-/* Return the data contained in the current node and go to the previous node */
-void *
-ewd_list_previous(Ewd_List * _ewd_list)
+/* Return the data contained in the current node and go to the next node */
+void *_ewd_list_next(Ewd_List * list)
{
+ void *data;
Ewd_List_Node *ret;
- if (!_ewd_list) return FALSE;
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
- if (!_ewd_list->current)
+ if (!list->current)
return NULL;
- ret = _ewd_list->current;
- _ewd_list->current = _ewd_list->current->prev;
- _ewd_list->index--;
+ EWD_LOCK_STRUCT(list->current);
+ if (list->current == list->current->next)
+ return NULL;
+
+ ret = list->current;
+ EWD_UNLOCK_STRUCT(list->current);
+
+ list->current = list->current->next;
+ list->index++;
+
+ EWD_LOCK_STRUCT(ret);
+ data = ret->data;
+ EWD_UNLOCK_STRUCT(ret);
- return ret->data;
+ return data;
}
/* Initialize a node to starting values */
-static int
-ewd_list_node_init(Ewd_List_Node * _ewd_node)
+int ewd_list_node_init(Ewd_List_Node * node)
{
- if (!_ewd_node) return FALSE;
- _ewd_node->next = NULL;
- _ewd_node->prev = NULL;
- _ewd_node->data = NULL;
+
+ CHECK_PARAM_POINTER_RETURN("node", node, FALSE);
+
+ node->next = NULL;
+ node->data = NULL;
+
+ EWD_INIT_STRUCT_LOCK(node);
return TRUE;
}
/* Remove all nodes from the list */
-void
-ewd_list_clear(Ewd_List * _ewd_list)
+int ewd_list_clear(Ewd_List * list)
{
- if (!_ewd_list)
- return;
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
- if (ewd_list_is_empty(_ewd_list))
- return;
+ EWD_LOCK_STRUCT(list);
- ewd_list_goto_first(_ewd_list);
- while (_ewd_list->current)
- ewd_list_remove(_ewd_list);
+ if (_ewd_list_is_empty(list))
+ return TRUE;
+
+ _ewd_list_goto_first(list);
+
+ if (list->current) {
+ _ewd_list_remove(list);
+ }
- memset(_ewd_list, 0, sizeof(Ewd_List));
+ EWD_UNLOCK_STRUCT(list);
+
+ return TRUE;
}
/* Allocate and initialize a new list node */
-Ewd_List_Node *
-ewd_list_node_new()
+Ewd_List_Node *ewd_list_node_new()
{
Ewd_List_Node *new;
@@ -417,19 +766,66 @@
return NULL;
if (!ewd_list_node_init(new)) {
- free(new);
+ IF_FREE(new);
return NULL;
}
return new;
}
-void
-ewd_list_node_destroy(Ewd_List_Node * _ewd_node)
+int ewd_list_node_destroy(Ewd_List_Node * node, Ewd_Free_Cb free_func)
{
- if (!_ewd_node) return;
+ CHECK_PARAM_POINTER_RETURN("node", node,
+ FALSE);
+
+ EWD_LOCK_STRUCT(node);
- IF_FREE(_ewd_node);
+ if (free_func)
+ free_func(node->data);
+
+ EWD_UNLOCK_STRUCT(node);
+
+ FREE(node);
+
+ return TRUE;
+}
+
+/*
+ * Description: Execute function for each node in the list.
+ * Parameters: 1. list - The list to retrieve nodes from.
+ * 2. function - The function to pass each node from the list to.
+ * Returns: FALSE if there is an error, TRUE otherwise.
+ */
+int ewd_list_for_each(Ewd_List *list, Ewd_For_Each function)
+{
+ int ret;
- return;
+ CHECK_PARAM_POINTER_RETURN("list", list, FALSE);
+
+ EWD_LOCK_STRUCT(list);
+ ret = _ewd_list_for_each(list, function);
+ EWD_UNLOCK_STRUCT(list);
+
+ return ret;
+}
+
+int _ewd_list_for_each(Ewd_List *list, Ewd_For_Each function)
+{
+ int i, index;
+ int nodes;
+
+ if (!list || !function)
+ return FALSE;
+
+ index = _ewd_list_index(list);
+ nodes = _ewd_list_nodes(list);
+ _ewd_list_goto_first(list);
+
+ for (i = 0; i < nodes; i++) {
+ function(ewd_list_next(list));
+ }
+
+ _ewd_list_goto_index(list, index);
+
+ return TRUE;
}
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewd/src/ewd_list.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -3 -r1.1.1.1 -r1.2
--- ewd_list.h 2001/04/09 19:49:18 1.1.1.1
+++ ewd_list.h 2001/04/14 07:19:16 1.2
@@ -1,59 +1,74 @@
-
#ifndef __EWD_LIST_H__
#define __EWD_LIST_H__
typedef struct _ewd_list Ewd_List;
+#define EWD_LIST(list) ((Ewd_List *)list)
+
typedef struct _ewd_list_node Ewd_List_Node;
+#define EWD_LIST_NODE(node) ((Ewd_List_Node *)node)
struct _ewd_list_node {
- void * data;
- struct _ewd_list_node *prev;
+ void *data;
struct _ewd_list_node *next;
+
+ EWD_DECLARE_LOCK;
};
struct _ewd_list {
- Ewd_List_Node * first; /* The first node in the list */
- Ewd_List_Node * last; /* The last node in the list */
- Ewd_List_Node * current; /* The current node in the list */
-
- int nodes; /* The number of nodes in the list */
- int index; /* The position from the front of the list of current node */
+ Ewd_List_Node *first; /* The first node in the list */
+ Ewd_List_Node *last; /* The last node in the list */
+ Ewd_List_Node *current; /* The current node in the list */
+
+ Ewd_Free_Cb free_func; /* The callback to free data in nodes */
+
+ int nodes; /* The number of nodes in the list */
+ int index; /* The position from the front of the
+ list of current node */
+ EWD_DECLARE_LOCK;
};
/* Creating and initializing new list structures */
-Ewd_List * ewd_list_new();
+Ewd_List *ewd_list_new();
+int ewd_list_init(Ewd_List *list);
/* Adding items to the list */
-void ewd_list_append(Ewd_List * _e_list, void *_data);
-void ewd_list_prepend(Ewd_List * _e_list, void *_data);
-void ewd_list_insert(Ewd_List * _e_list, void *_data);
+int ewd_list_append(Ewd_List * list, void *_data);
+int ewd_list_prepend(Ewd_List * list, void *_data);
+int ewd_list_insert(Ewd_List * list, void *_data);
/* Removing items from the list */
-void ewd_list_remove(Ewd_List * _e_list);
-void ewd_list_remove_first(Ewd_List * _e_list);
-void ewd_list_remove_last(Ewd_List * _e_list);
+int ewd_list_remove(Ewd_List * list);
+int ewd_list_remove_first(Ewd_List * list);
+int ewd_list_remove_last(Ewd_List * list);
+
+/* Retrieve the current position in the list */
+int ewd_list_index(Ewd_List * list);
+int ewd_list_nodes(Ewd_List * list);
/* Traversing the list */
-void ewd_list_goto_first(Ewd_List * _e_list);
-void ewd_list_goto_last(Ewd_List * _e_list);
-void ewd_list_goto_index(Ewd_List * _e_list, int index);
-void ewd_list_goto(Ewd_List * _e_list, void * _data);
+int ewd_list_goto_first(Ewd_List * list);
+int ewd_list_goto_last(Ewd_List * list);
+int ewd_list_goto_index(Ewd_List * list, int index);
+int ewd_list_goto(Ewd_List * list, void *_data);
/* Traversing the list and returning data */
-void * ewd_list_next(Ewd_List * _e_list);
-void * ewd_list_previous(Ewd_List * _e_list);
+void *ewd_list_next(Ewd_List * list);
/* Check to see if there is any data in the list */
-int ewd_list_is_empty(Ewd_List * _e_list);
+int ewd_list_is_empty(Ewd_List * list);
/* Remove every node in the list without free'ing it */
-void ewd_list_clear(Ewd_List * _e_list);
+int ewd_list_clear(Ewd_List * list);
+void ewd_list_destroy(Ewd_List *list);
/* Creating and initializing list nodes */
-Ewd_List_Node * ewd_list_node_new();
+Ewd_List_Node *ewd_list_node_new();
+int ewd_list_node_init(Ewd_List_Node *new);
/* Destroying nodes */
-void ewd_list_node_destroy(Ewd_List_Node * _e_node);
+int ewd_list_node_destroy(Ewd_List_Node * _e_node, Ewd_Free_Cb free_func);
+
+int ewd_list_set_free_cb(Ewd_List * list, Ewd_Free_Cb free_func);
#endif
===================================================================
RCS file: /cvsroot/enlightenment/e17/libs/ewd/src/ewd_macros.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -3 -r1.1.1.1 -r1.2
--- ewd_macros.h 2001/04/09 19:49:18 1.1.1.1
+++ ewd_macros.h 2001/04/14 07:19:16 1.2
@@ -1,4 +1,9 @@
+#ifndef __EWD_MACROS_H__
+#define __EWD_MACROS_H__
+
+/* Wrappers around free() that helps debug free() bugs such as freeing NULL
+ * or accessing a pointer that has already been freed */
#ifndef IF_FREE
#define IF_FREE(ptr) if (ptr) free(ptr); ptr = NULL;
#endif
@@ -6,3 +11,57 @@
#ifndef FREE
#define FREE(ptr) free(ptr); ptr = NULL;
#endif
+
+/* Debugging printf, basically a wrapper to fprintf that checks the level
+ * of the message and checks that it is to be printed at the current debugging
+ * level */
+#ifndef DPRINTF
+#define DPRINTF(debug, format, args...) \
+if (debug >= DEBUG_LEVEL) \
+ fprintf(stderr, format, args);
+#endif
+
+/* convenience macros for checking pointer parameters for non-NULL */
+#ifndef CHECK_PARAM_POINTER_RETURN
+#define CHECK_PARAM_POINTER_RETURN(sparam, param, ret) \
+if (!(param)) \
+{ \
+ fprintf(stderr, "***** %s Developer Warning ***** :\n" \
+ "\tThis program is calling:\n\n" \
+ "\t%s();\n\n" \
+ "\tWith the parameter:\n\n" \
+ "\t%s\n\n" \
+ "\tbeing NULL. Please fix your program.\n", PACKAGE, \
+ __FUNCTION__,\
+ sparam); \
+ return ret; \
+}
+#endif
+
+#ifndef CHECK_PARAM_POINTER
+#define CHECK_PARAM_POINTER(sparam, param) \
+if (!(param)) \
+{ \
+ fprintf(stderr, "***** %s Developer Warning ***** :\n" \
+ "\tThis program is calling:\n\n" \
+ "\t%s();\n\n" \
+ "\tWith the parameter:\n\n" \
+ "\t%s\n\n" \
+ "\tbeing NULL. Please fix your program.\n", PACKAGE, \
+ __FUNCTION__, \
+ sparam); \
+ return; \
+}
+#endif
+
+/* Use the larger of a and b */
+#ifndef MAX
+#define MAX(a, b) (((a) > (b)) ? (a) : (b))
+#endif
+
+/* Use the smaller of a and b */
+#ifndef MIN
+#define MIN(a, b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#endif /* __EWL_MACROS_H__ */
|