From 0b624384cd52be20e61284551d832b499d7b7707 Mon Sep 17 00:00:00 2001 From: Jonathan McCrohan Date: Sat, 14 Apr 2012 12:56:48 +0100 Subject: Imported Upstream version 2.1.8.20120216 --- cphidgetlist.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 cphidgetlist.c (limited to 'cphidgetlist.c') 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; +} + -- cgit v1.2.3