summaryrefslogtreecommitdiff
path: root/lib/libalpm/alpm_list.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libalpm/alpm_list.c')
-rw-r--r--lib/libalpm/alpm_list.c164
1 files changed, 87 insertions, 77 deletions
diff --git a/lib/libalpm/alpm_list.c b/lib/libalpm/alpm_list.c
index 57c8376a..87567402 100644
--- a/lib/libalpm/alpm_list.c
+++ b/lib/libalpm/alpm_list.c
@@ -1,7 +1,7 @@
/*
* alpm_list.c
*
- * Copyright (c) 2002-2007 by Judd Vinet <jvinet@zeroflux.org>
+ * Copyright (c) 2002-2008 by Judd Vinet <jvinet@zeroflux.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,15 +17,16 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
-
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
/* libalpm */
#include "alpm_list.h"
-#include "util.h"
+
+/* check exported library symbols with: nm -C -D <lib> */
+#define SYMEXPORT __attribute__((visibility("default")))
+#define SYMHIDDEN __attribute__((visibility("internal")))
/**
* @addtogroup alpm_list List Functions
@@ -40,25 +41,6 @@
/* Allocation */
/**
- * @brief Allocate a new alpm_list_t.
- *
- * @return a new alpm_list_t item, or NULL on failure
- */
-alpm_list_t SYMEXPORT *alpm_list_new()
-{
- alpm_list_t *list = NULL;
-
- list = malloc(sizeof(alpm_list_t));
- if(list) {
- list->data = NULL;
- list->prev = list; /* maintain a back reference to the tail pointer */
- list->next = NULL;
- }
-
- return(list);
-}
-
-/**
* @brief Free a list, but not the contained data.
*
* @param list the list to free
@@ -107,30 +89,26 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)
{
alpm_list_t *ptr, *lp;
- ptr = list;
+ ptr = calloc(1, sizeof(alpm_list_t));
if(ptr == NULL) {
- ptr = alpm_list_new();
- if(ptr == NULL) {
- return(NULL);
- }
+ return(list);
}
- lp = alpm_list_last(ptr);
- if(lp == ptr && lp->data == NULL) {
- /* nada */
- } else {
- lp->next = alpm_list_new();
- if(lp->next == NULL) {
- return(NULL);
- }
- lp->next->prev = lp;
- lp = lp->next;
- list->prev = lp;
+ ptr->data = data;
+ ptr->next = NULL;
+
+ /* Special case: the input list is empty */
+ if(list == NULL) {
+ ptr->prev = ptr;
+ return(ptr);
}
- lp->data = data;
+ lp = alpm_list_last(list);
+ lp->next = ptr;
+ ptr->prev = lp;
+ list->prev = ptr;
- return(ptr);
+ return(list);
}
/**
@@ -144,12 +122,15 @@ alpm_list_t SYMEXPORT *alpm_list_add(alpm_list_t *list, void *data)
*/
alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_list_fn_cmp fn)
{
- if(!fn) {
- return alpm_list_add(list, data);
+ if(!fn || !list) {
+ return(alpm_list_add(list, data));
} else {
alpm_list_t *add = NULL, *prev = NULL, *next = list;
- add = alpm_list_new();
+ add = calloc(1, sizeof(alpm_list_t));
+ if(add == NULL) {
+ return(list);
+ }
add->data = data;
/* Find insertion point. */
@@ -159,26 +140,25 @@ alpm_list_t SYMEXPORT *alpm_list_add_sorted(alpm_list_t *list, void *data, alpm_
next = next->next;
}
- /* Insert node before insertion point. */
- add->prev = prev;
- add->next = next;
-
- if(next != NULL) {
- next->prev = add; /* Not at end. */
- }
-
- if(prev != NULL) {
- prev->next = add; /* In middle. */
- } else {
- list = add; /* At beginning, or new list */
- }
-
- if(next == NULL) {
- /* At end, adjust tail pointer on head node */
+ /* Insert the add node to the list */
+ if(prev == NULL) { /* special case: we insert add as the first element */
+ add->prev = list->prev; /* list != NULL */
+ add->next = list;
list->prev = add;
+ return(add);
+ } else if(next == NULL) { /* another special case: add last element */
+ add->prev = prev;
+ add->next = NULL;
+ prev->next = add;
+ list->prev = add;
+ return(list);
+ } else {
+ add->prev = prev;
+ add->next = next;
+ next->prev = add;
+ prev->next = add;
+ return(list);
}
-
- return(list);
}
}
@@ -198,10 +178,10 @@ alpm_list_t SYMEXPORT *alpm_list_join(alpm_list_t *first, alpm_list_t *second)
alpm_list_t *tmp;
if (first == NULL) {
- return second;
+ return(second);
}
if (second == NULL) {
- return first;
+ return(first);
}
/* tmp is the last element of the first list */
tmp = first->prev;
@@ -327,7 +307,7 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack, const void *needl
continue;
}
tmp = i->next;
- if(fn(needle, i->data) == 0) {
+ if(fn(i->data, needle) == 0) {
/* we found a matching item */
if(i == haystack) {
/* Special case: removing the head node which has a back reference to
@@ -371,6 +351,22 @@ alpm_list_t SYMEXPORT *alpm_list_remove(alpm_list_t *haystack, const void *needl
}
/**
+ * @brief Remove a string from a list.
+ *
+ * @param haystack the list to remove the item from
+ * @param needle the data member of the item we're removing
+ * @param data output parameter containing data of the removed item
+ *
+ * @return the resultant list
+ */
+alpm_list_t SYMEXPORT *alpm_list_remove_str(alpm_list_t *haystack,
+ const char *needle, char **data)
+{
+ return(alpm_list_remove(haystack, (const void *)needle,
+ (alpm_list_fn_cmp)strcmp, (void **)data));
+}
+
+/**
* @brief Create a new list without any duplicates.
*
* This does NOT copy data members.
@@ -464,18 +460,22 @@ alpm_list_t SYMEXPORT *alpm_list_copy_data(const alpm_list_t *list,
alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)
{
const alpm_list_t *lp;
- alpm_list_t *newlist = NULL;
+ alpm_list_t *newlist = NULL, *backup;
- lp = alpm_list_last(list);
- if(list) {
- /* break our reverse circular list */
- list->prev = NULL;
+ if(list == NULL) {
+ return(NULL);
}
+ lp = alpm_list_last(list);
+ /* break our reverse circular list */
+ backup = list->prev;
+ list->prev = NULL;
+
while(lp) {
newlist = alpm_list_add(newlist, lp->data);
lp = lp->prev;
}
+ list->prev = backup; /* restore tail pointer */
return(newlist);
}
@@ -490,14 +490,18 @@ alpm_list_t SYMEXPORT *alpm_list_reverse(alpm_list_t *list)
*/
inline alpm_list_t SYMEXPORT *alpm_list_first(const alpm_list_t *list)
{
- return((alpm_list_t*)list);
+ if(list) {
+ return((alpm_list_t*)list);
+ } else {
+ return(NULL);
+ }
}
/**
* @brief Return nth element from list (starting from 0).
*
* @param list the list
- * @param n the index of the item to find
+ * @param n the index of the item to find (n < alpm_list_count(list) IS needed)
*
* @return an alpm_list_t node for index `n`
*/
@@ -519,7 +523,11 @@ alpm_list_t SYMEXPORT *alpm_list_nth(const alpm_list_t *list, int n)
*/
inline alpm_list_t SYMEXPORT *alpm_list_next(const alpm_list_t *node)
{
- return(node->next);
+ if(node) {
+ return(node->next);
+ } else {
+ return(NULL);
+ }
}
/**
@@ -594,7 +602,7 @@ void SYMEXPORT *alpm_list_find(const alpm_list_t *haystack, const void *needle,
}
/* trivial helper function for alpm_list_find_ptr */
-static int ptrcmp(const void *p, const void *q)
+static int ptr_cmp(const void *p, const void *q)
{
return(p != q);
}
@@ -611,7 +619,7 @@ static int ptrcmp(const void *p, const void *q)
*/
void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, const void *needle)
{
- return(alpm_list_find(haystack, needle, ptrcmp));
+ return(alpm_list_find(haystack, needle, ptr_cmp));
}
/**
@@ -622,9 +630,11 @@ void SYMEXPORT *alpm_list_find_ptr(const alpm_list_t *haystack, const void *need
*
* @return `needle` if found, NULL otherwise
*/
-char SYMEXPORT *alpm_list_find_str(const alpm_list_t *haystack, const char *needle)
+char SYMEXPORT *alpm_list_find_str(const alpm_list_t *haystack,
+ const char *needle)
{
- return((char *)alpm_list_find(haystack, (const void*)needle, (alpm_list_fn_cmp)strcmp));
+ return((char *)alpm_list_find(haystack, (const void*)needle,
+ (alpm_list_fn_cmp)strcmp));
}
/**