reimplemented list_remove to deal with lists of any kind of data

This commit is contained in:
Aurelien Foret 2005-05-03 17:24:20 +00:00
parent 220c084770
commit 9177ce7962
2 changed files with 48 additions and 45 deletions

View file

@ -44,9 +44,10 @@ int _alpm_list_check(PMList* list)
} }
for(it = list; it && it->next; it = it->next); for(it = list; it && it->next; it = it->next);
if(it != list->last) {
return(0); if(it != list->last) {
} return(0);
}
return(1); return(1);
} }
@ -155,56 +156,57 @@ PMList* pm_list_add_sorted(PMList *list, void *data, pm_fn_cmp fn)
return(list); return(list);
} }
/* list: the beginning of the list /* Remove an item in a list. Use the given comparaison function to find the
* item: the item in the list to be removed * item.
* * If the item is found, 'data' is pointing to the removed element.
* returns: * Otherwise, it is set to NULL.
* list with item removed * Return the new list (without the removed element).
*/ */
PMList *_alpm_list_remove(PMList *haystack, void *needle, pm_fn_cmp fn, void **data)
PMList* _alpm_list_remove(PMList* list, PMList* item)
{ {
assert(_alpm_list_check(list)); PMList *i = haystack;
if(list == NULL || item == NULL) { if(data) {
return(NULL); *data = NULL;
} }
/* Remove first item in list. */ while(i) {
if(item == list) { if(i->data == NULL) {
if(list->next == NULL) { /* Only item in list. */ continue;
pm_list_free(item);
return(NULL);
} else {
list->next->prev = NULL;
list->next->last = list->last;
list = list->next;
item->prev = item->next = NULL;
pm_list_free(item);
return(list);
} }
if(fn(needle, i->data) == 0) {
break;
}
i = i->next;
} }
/* Remove last item in list. */ if(i) {
if(list->last == item) { /* we found a matching item */
list->last = item->prev; if(i->next) {
item->prev->next = NULL; i->next->prev = i->prev;
item->prev = item->next = NULL; }
pm_list_free(item); if(i->prev) {
return(list); i->prev->next = i->next;
}
if(i == haystack) {
/* The item found is the first in the chain */
if(haystack->next) {
haystack->next->last = haystack->last;
}
haystack = haystack->next;
} else if(i == haystack->last) {
/* The item found is the last in the chain */
haystack->last = i->prev;
}
if(data) {
*data = i->data;
}
i->data = NULL;
free(i);
} }
/* Remove middle item in list. */ return(haystack);
assert(item->prev != NULL && item->next != NULL);
item->prev->next = item->next;
item->next->prev = item->prev;
item->prev = item->next = NULL;
pm_list_free(item);
assert(_alpm_list_check(list));
return(list);
} }
int pm_list_count(PMList *list) int pm_list_count(PMList *list)
@ -245,8 +247,9 @@ PMList *pm_list_is_strin(char *needle, PMList *haystack)
PMList* pm_list_last(PMList *list) PMList* pm_list_last(PMList *list)
{ {
if (list == NULL) if(list == NULL) {
return(NULL); return(NULL);
}
assert(list->last != NULL); assert(list->last != NULL);

View file

@ -50,7 +50,7 @@ PMList *pm_list_new();
void pm_list_free(PMList *list); void pm_list_free(PMList *list);
PMList *pm_list_add(PMList *list, void *data); PMList *pm_list_add(PMList *list, void *data);
PMList *pm_list_add_sorted(PMList *list, void *data, pm_fn_cmp fn); PMList *pm_list_add_sorted(PMList *list, void *data, pm_fn_cmp fn);
PMList* _alpm_list_remove(PMList* list, PMList* item); PMList *_alpm_list_remove(PMList *haystack, void *needle, pm_fn_cmp fn, void **data);
int pm_list_count(PMList *list); int pm_list_count(PMList *list);
int pm_list_is_in(void *needle, PMList *haystack); int pm_list_is_in(void *needle, PMList *haystack);
PMList *pm_list_is_strin(char *needle, PMList *haystack); PMList *pm_list_is_strin(char *needle, PMList *haystack);