aboutsummaryrefslogtreecommitdiffstats
path: root/cphidgetlist.c
diff options
context:
space:
mode:
authorJonathan McCrohan <jmccrohan@gmail.com>2012-04-14 12:56:48 +0100
committerJonathan McCrohan <jmccrohan@gmail.com>2012-04-14 12:56:48 +0100
commit0b624384cd52be20e61284551d832b499d7b7707 (patch)
tree6f95a4bbef47abc9720b96c0722e8f632aef228a /cphidgetlist.c
downloadlibphidget21-0b624384cd52be20e61284551d832b499d7b7707.tar.gz
Imported Upstream version 2.1.8.20120216upstream/2.1.8.20120216
Diffstat (limited to 'cphidgetlist.c')
-rw-r--r--cphidgetlist.c148
1 files changed, 148 insertions, 0 deletions
diff --git a/cphidgetlist.c b/cphidgetlist.c
new file mode 100644
index 0000000..ed5bea1
--- /dev/null
+++ b/cphidgetlist.c
@@ -0,0 +1,148 @@
+#include "stdafx.h"
+#include "cphidgetlist.h"
+
+/* Adds an element to a list - Duplicates are not allowed.
+ * Return: EPHIDGET_OK on success
+ * EPHIDGET_DUPLICATE if the element already exists in the list
+ */
+int CList_addToList(CListHandle *list, void *element,
+ int (*compare_fptr)(void *element1, void *element2))
+{
+ int result = 0;
+ CListHandle trav = 0, newentry = 0;
+
+ TESTPTRS(list, element)
+
+ /* The very first thing we do is make sure none of these already exist in the list */
+ result = CList_findInList(*list, element, compare_fptr, NULL);
+ switch (result) {
+ case EPHIDGET_OK:
+ return EPHIDGET_DUPLICATE;
+ case EPHIDGET_NOTFOUND:
+ break;
+ default:
+ return result;
+ }
+
+ newentry = (CListHandle)malloc(sizeof(CList));
+ if (!newentry) return EPHIDGET_NOMEMORY;
+ ZEROMEM(newentry, sizeof(CList));
+
+ newentry->next = 0;
+ newentry->element = element;
+
+ if (!*list)
+ *list = newentry;
+ else
+ {
+ for (trav = *list; trav->next; trav = trav->next);
+ trav->next = newentry;
+ }
+ return EPHIDGET_OK;
+}
+
+/* this returns success even if the element is not found in the list
+ * this also removes duplicates.
+ *
+ * but! if we find in the list the exact element, rather then just a match, we need to free it after!
+ * interating, or the compare function will croak!
+ */
+int CList_removeFromList(CListHandle *list, void *element,
+ int (*compare_fptr)(void *element1, void *element2),
+ int freeDevice, void (*free_fptr)(void *element))
+{
+ CListHandle traverse = 0, last = 0;
+ int freeElement = PFALSE;
+
+ TESTPTRS(list, element)
+
+ for (traverse=*list; traverse; traverse = traverse->next) {
+ if(compare_fptr(element, traverse->element)) {
+ if(traverse == *list) {
+ *list = traverse->next;
+ if(freeDevice && traverse->element)
+ {
+ // don't free element in the middle of iterating!
+ if(traverse->element == element)
+ freeElement=PTRUE;
+ else
+ free_fptr(traverse->element);
+ traverse->element = 0;
+ }
+ free(traverse); traverse = NULL;
+ traverse=*list;
+ break;
+ }
+ else {
+ last->next=traverse->next;
+ if(freeDevice && traverse->element)
+ {
+ // don't free element in the middle of iterating!
+ if(traverse->element == element)
+ freeElement=PTRUE;
+ else
+ free_fptr(traverse->element);
+ traverse->element = 0;
+ }
+ free(traverse); traverse = NULL;
+ traverse=last;
+ }
+ }
+ last = traverse;
+ }
+
+ /* element itself was found in the list, and we want it freed - free it here */
+ if(freeElement)
+ free_fptr(element);
+
+ return EPHIDGET_OK;
+}
+
+/* this takes any list, and frees all of the list element,
+ and can also free the elements that they point to */
+int CList_emptyList(CListHandle *list, int freeDevices, void (*free_fptr)(void *element))
+{
+ CListHandle last = 0, traverse = 0;
+
+ TESTPTR(list)
+
+ last = 0;
+ for(traverse = *list; traverse; last = traverse, traverse = traverse->next)
+ {
+ if(traverse->element && freeDevices)
+ {
+ free_fptr(traverse->element);
+ traverse->element = 0;
+ }
+ if(last)
+ {
+ free(last); last = NULL;
+ }
+ }
+ if(last)
+ {
+ free(last); last = NULL;
+ }
+
+ *list = 0;
+
+ return EPHIDGET_OK;
+}
+
+/* returns EPHIDGET_OK if the device is in the list */
+int CList_findInList(CListHandle list, void *element,
+ int (*compare_fptr)(void *element1, void *element2), void **found_element)
+{
+ CListHandle trav = 0;
+
+ TESTPTR(element)
+
+ for (trav=list; trav; trav = trav->next) {
+ if(compare_fptr(element, trav->element)) {
+ if(found_element) *found_element = trav->element;
+ return EPHIDGET_OK;
+ }
+ }
+ return EPHIDGET_NOTFOUND;
+}
+