mirror of
https://github.com/moparisthebest/pacman
synced 2024-12-23 00:08:50 -05:00
Add new alpm_list_remove_item() function
This takes in the list and a list item, and does the pointer dance necessary to remove it from the list regardless of whether it is first, last, or somewhere in the middle. It is useful for callers that already know what item needs to be removed and have a pointer to it rather than doing a search by data that the plain alpm_list_remove() does. Refactor alpm_list_remove() to use this function as well. Signed-off-by: Dan McGee <dan@archlinux.org>
This commit is contained in:
parent
09e582b411
commit
14fd1e63a2
@ -285,6 +285,53 @@ alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn
|
|||||||
return(list);
|
return(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Remove an item from the list.
|
||||||
|
* item is not freed; this is the respnsiblity of the caller.
|
||||||
|
*
|
||||||
|
* @param haystack the list to remove the item from
|
||||||
|
* @param item the item to remove from the list
|
||||||
|
*
|
||||||
|
* @return the resultant list
|
||||||
|
*/
|
||||||
|
alpm_list_t SYMEXPORT *alpm_list_remove_item(alpm_list_t *haystack,
|
||||||
|
alpm_list_t *item)
|
||||||
|
{
|
||||||
|
if(haystack == NULL || item == NULL) {
|
||||||
|
return(haystack);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(item == haystack) {
|
||||||
|
/* Special case: removing the head node which has a back reference to
|
||||||
|
* the tail node */
|
||||||
|
haystack = item->next;
|
||||||
|
if(haystack) {
|
||||||
|
haystack->prev = item->prev;
|
||||||
|
}
|
||||||
|
item->prev = NULL;
|
||||||
|
} else if(item == haystack->prev) {
|
||||||
|
/* Special case: removing the tail node, so we need to fix the back
|
||||||
|
* reference on the head node. We also know tail != head. */
|
||||||
|
if(item->prev) {
|
||||||
|
/* i->next should always be null */
|
||||||
|
item->prev->next = item->next;
|
||||||
|
haystack->prev = item->prev;
|
||||||
|
item->prev = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Normal case, non-head and non-tail node */
|
||||||
|
if(item->next) {
|
||||||
|
item->next->prev = item->prev;
|
||||||
|
}
|
||||||
|
if(item->prev) {
|
||||||
|
item->prev->next = item->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(haystack);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Remove an item from the list.
|
* @brief Remove an item from the list.
|
||||||
*
|
*
|
||||||
@ -295,9 +342,10 @@ alpm_list_t SYMEXPORT *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn
|
|||||||
*
|
*
|
||||||
* @return the resultant list
|
* @return the resultant list
|
||||||
*/
|
*/
|
||||||
alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack, const void *needle, alpm_list_fn_cmp fn, void **data)
|
alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack,
|
||||||
|
const void *needle, alpm_list_fn_cmp fn, void **data)
|
||||||
{
|
{
|
||||||
alpm_list_t *i = haystack, *tmp = NULL;
|
alpm_list_t *i = haystack;
|
||||||
|
|
||||||
if(data) {
|
if(data) {
|
||||||
*data = NULL;
|
*data = NULL;
|
||||||
@ -312,44 +360,16 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack, const void *needl
|
|||||||
i = i->next;
|
i = i->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
tmp = i->next;
|
|
||||||
if(fn(i->data, needle) == 0) {
|
if(fn(i->data, needle) == 0) {
|
||||||
/* we found a matching item */
|
haystack = alpm_list_remove_item(haystack, i);
|
||||||
if(i == haystack) {
|
|
||||||
/* Special case: removing the head node which has a back reference to
|
|
||||||
* the tail node */
|
|
||||||
haystack = i->next;
|
|
||||||
if(haystack) {
|
|
||||||
haystack->prev = i->prev;
|
|
||||||
}
|
|
||||||
i->prev = NULL;
|
|
||||||
} else if(i == haystack->prev) {
|
|
||||||
/* Special case: removing the tail node, so we need to fix the back
|
|
||||||
* reference on the head node. We also know tail != head. */
|
|
||||||
if(i->prev) {
|
|
||||||
/* i->next should always be null */
|
|
||||||
i->prev->next = i->next;
|
|
||||||
haystack->prev = i->prev;
|
|
||||||
i->prev = NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Normal case, non-head and non-tail node */
|
|
||||||
if(i->next) {
|
|
||||||
i->next->prev = i->prev;
|
|
||||||
}
|
|
||||||
if(i->prev) {
|
|
||||||
i->prev->next = i->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data) {
|
if(data) {
|
||||||
*data = i->data;
|
*data = i->data;
|
||||||
}
|
}
|
||||||
i->data = NULL;
|
|
||||||
free(i);
|
free(i);
|
||||||
i = NULL;
|
break;
|
||||||
} else {
|
} else {
|
||||||
i = tmp;
|
i = i->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ alpm_list_t *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_list_fn_cm
|
|||||||
alpm_list_t *alpm_list_join(alpm_list_t *first, alpm_list_t *second);
|
alpm_list_t *alpm_list_join(alpm_list_t *first, alpm_list_t *second);
|
||||||
alpm_list_t *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, alpm_list_fn_cmp fn);
|
alpm_list_t *alpm_list_mmerge(alpm_list_t *left, alpm_list_t *right, alpm_list_fn_cmp fn);
|
||||||
alpm_list_t *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn_cmp fn);
|
alpm_list_t *alpm_list_msort(alpm_list_t *list, size_t n, alpm_list_fn_cmp fn);
|
||||||
|
alpm_list_t *alpm_list_remove_item(alpm_list_t *haystack, alpm_list_t *item);
|
||||||
alpm_list_t *alpm_list_remove(alpm_list_t *haystack, const void *needle, alpm_list_fn_cmp fn, void **data);
|
alpm_list_t *alpm_list_remove(alpm_list_t *haystack, const void *needle, alpm_list_fn_cmp fn, void **data);
|
||||||
alpm_list_t *alpm_list_remove_str(alpm_list_t *haystack, const char *needle, char **data);
|
alpm_list_t *alpm_list_remove_str(alpm_list_t *haystack, const char *needle, char **data);
|
||||||
alpm_list_t *alpm_list_remove_dupes(const alpm_list_t *list);
|
alpm_list_t *alpm_list_remove_dupes(const alpm_list_t *list);
|
||||||
|
Loading…
Reference in New Issue
Block a user