pkg: coalesce soem flag members into a packed bit field
[oweals/opkg-lede.git] / libopkg / void_list.c
index 81a51af95eb37a481929e4104dd0b863a1a05b1b..e8fa80869734e3df64f49ef044b3f96be64054ab 100644 (file)
@@ -1,4 +1,4 @@
-/* void_list.c - the itsy package management system
+/* void_list.c - the opkg package management system
 
    Carl D. Worth
 
    General Public License for more details.
 */
 
-#include "includes.h"
-#include <errno.h>
-
 #include "void_list.h"
+#include "libbb/libbb.h"
 
-int void_list_elt_init(void_list_elt_t *elt, void *data)
+void void_list_elt_init(void_list_elt_t * elt, void *data)
 {
-    elt->next = NULL;
-    elt->data = data;
-
-    return 0;
+       INIT_LIST_HEAD(&elt->node);
+       elt->data = data;
 }
 
-void void_list_elt_deinit(void_list_elt_t *elt)
+static void_list_elt_t *void_list_elt_new(void *data)
 {
-    void_list_elt_init(elt, NULL);
+       void_list_elt_t *elt;
+       /* freed in void_list_elt_deinit */
+       elt = xcalloc(1, sizeof(void_list_elt_t));
+       void_list_elt_init(elt, data);
+       return elt;
 }
 
-int void_list_init(void_list_t *list)
+void void_list_elt_deinit(void_list_elt_t * elt)
 {
-    void_list_elt_init(&list->pre_head, NULL);
-    list->head = NULL;
-    list->pre_head.next = list->head;
-    list->tail = NULL;
+       list_del_init(&elt->node);
+       void_list_elt_init(elt, NULL);
+       free(elt);
+}
 
-    return 0;
+void void_list_init(void_list_t * list)
+{
+       INIT_LIST_HEAD(&list->head);
 }
 
-void void_list_deinit(void_list_t *list)
+void void_list_deinit(void_list_t * list)
 {
-    void_list_elt_t *elt;
+       void_list_elt_t *elt;
 
-    while (list->head) {
-       elt = void_list_pop(list);
-       void_list_elt_deinit(elt);
-       /* malloced in void_list_append */
-       free(elt);
-    }
+       while (!void_list_empty(list)) {
+               elt = void_list_pop(list);
+               void_list_elt_deinit(elt);
+       }
+       INIT_LIST_HEAD(&list->head);
 }
 
-int void_list_append(void_list_t *list, void *data)
+void void_list_append(void_list_t * list, void *data)
 {
-    void_list_elt_t *elt;
-
-    /* freed in void_list_deinit */
-    elt = malloc(sizeof(void_list_elt_t));
-    if (elt == NULL) {
-       fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
-       return ENOMEM;
-    }
-
-    void_list_elt_init(elt, data);
-
-    if (list->tail) {
-       list->tail->next = elt;
-       list->tail = elt;
-    } else {
-       list->head = elt;
-       list->pre_head.next = list->head;
-       list->tail = elt;
-    }
-
-    return 0;
+       void_list_elt_t *elt = void_list_elt_new(data);
+       list_add_tail(&elt->node, &list->head);
 }
 
-int void_list_push(void_list_t *list, void *data)
+void void_list_push(void_list_t * list, void *data)
 {
-    void_list_elt_t *elt;
-
-    elt = malloc(sizeof(void_list_elt_t));
-    if (elt == NULL) {
-       fprintf(stderr, "%s: out of memory\n", __FUNCTION__);
-       return ENOMEM;
-    }
-
-    void_list_elt_init(elt, data);
-
-    elt->next = list->head;
-    list->head->next = elt;
-    if (list->tail == NULL) {
-       list->tail = list->head;
-    }
-
-    return 0;
+       void_list_elt_t *elt = void_list_elt_new(data);
+       list_add(&elt->node, &list->head);
 }
 
-void_list_elt_t *void_list_pop(void_list_t *list)
+void_list_elt_t *void_list_pop(void_list_t * list)
 {
-    void_list_elt_t *elt;
+       struct list_head *node;
 
-    elt = list->head;
+       if (void_list_empty(list))
+               return NULL;
+       node = list->head.next;
+       list_del_init(node);
+       return list_entry(node, void_list_elt_t, node);
+}
 
-    if (list->head) {
-       list->head = list->head->next;
-       list->pre_head.next = list->head;
-       if (list->head == NULL) {
-           list->tail = NULL;
+void *void_list_remove(void_list_t * list, void_list_elt_t ** iter)
+{
+       void_list_elt_t *pos, *n;
+       void_list_elt_t *old_elt;
+       void *old_data = NULL;
+
+       old_elt = *iter;
+       if (!old_elt)
+               return old_data;
+       old_data = old_elt->data;
+
+       list_for_each_entry_safe(pos, n, &list->head, node) {
+               if (pos == old_elt)
+                       break;
+       }
+       if (pos != old_elt) {
+               opkg_msg(ERROR, "Internal error: element not found in list.\n");
+               return NULL;
        }
-    }
 
-    return elt;
+       *iter = list_entry(pos->node.prev, void_list_elt_t, node);
+       void_list_elt_deinit(pos);
+
+       return old_data;
 }
 
-void *void_list_remove(void_list_t *list, void_list_elt_t **iter)
+/* remove element containing elt data, using cmp(elt->data, target_data) == 0. */
+void *void_list_remove_elt(void_list_t * list, const void *target_data,
+                          void_list_cmp_t cmp)
 {
-    void_list_elt_t *prior;
-    void_list_elt_t *old_elt;
-    void *old_data;
-
-    old_elt = *iter;
-    old_data = old_elt->data;
-
-    if (old_elt == list->head) {
-       prior = &list->pre_head;
-       void_list_pop(list);
-    } else {
-       for (prior = list->head; prior; prior = prior->next) {
-           if (prior->next == old_elt) {
-               break;
-           }
+       void_list_elt_t *pos, *n;
+       void *old_data = NULL;
+       list_for_each_entry_safe(pos, n, &list->head, node) {
+               if (pos->data && cmp(pos->data, target_data) == 0) {
+                       old_data = pos->data;
+                       void_list_elt_deinit(pos);
+                       break;
+               }
        }
-       if (prior == NULL || prior->next != old_elt) {
-           fprintf(stderr, "%s: ERROR: element not found in list\n", __FUNCTION__);
-           return NULL;
-       }
-       prior->next = old_elt->next;
+       return old_data;
+}
 
-       if (old_elt == list->tail) {
-           list->tail = prior;
+void_list_elt_t *void_list_first(void_list_t * list)
+{
+       struct list_head *elt;
+       if (!list)
+               return NULL;
+       elt = list->head.next;
+       if (elt == &list->head) {
+               return NULL;
        }
-    }
+       return list_entry(elt, void_list_elt_t, node);
+}
 
-    void_list_elt_deinit(old_elt);
-    *iter = prior;
+void_list_elt_t *void_list_prev(void_list_t * list, void_list_elt_t * node)
+{
+       struct list_head *elt;
+       if (!list || !node)
+               return NULL;
+       elt = node->node.prev;
+       if (elt == &list->head) {
+               return NULL;
+       }
+       return list_entry(elt, void_list_elt_t, node);
+}
 
-    return old_data;
+void_list_elt_t *void_list_next(void_list_t * list, void_list_elt_t * node)
+{
+       struct list_head *elt;
+       if (!list || !node)
+               return NULL;
+       elt = node->node.next;
+       if (elt == &list->head) {
+               return NULL;
+       }
+       return list_entry(elt, void_list_elt_t, node);
 }
 
-/* remove element containing elt data, using cmp(elt->data, target_data) == 0. */
-void *void_list_remove_elt(void_list_t *list, const void *target_data, void_list_cmp_t cmp)
+void_list_elt_t *void_list_last(void_list_t * list)
 {
-     void_list_elt_t *prior;
-     void_list_elt_t *old_elt = NULL;
-     void *old_data = NULL;
-
-     /* first element */
-     if (list->head && list->head->data && (cmp(list->head->data, target_data) == 0)) {
-         old_elt = list->head;
-         old_data = list->head->data;
-         void_list_pop(list);
-     } else {
-         int found = 0;
-         for (prior = list->head; prior && prior->next; prior = prior->next) {
-              if (prior->next->data && (cmp(prior->next->data, target_data) == 0)) {
-                   old_elt = prior->next;
-                   old_data = old_elt->data;
-                   found = 1;
-                   break;
-              }
-         }
-         if (!found) {
-              return NULL;
-         }
-         prior->next = old_elt->next;
-
-         if (old_elt == list->tail) {
-              list->tail = prior;
-         }
-     }
-     if (old_elt)
-         void_list_elt_deinit(old_elt);
-
-     if (old_data)
-         return old_data;
-     else
-         return NULL;
+       struct list_head *elt;
+       if (!list)
+               return NULL;
+       elt = list->head.prev;
+       if (elt == &list->head) {
+               return NULL;
+       }
+       return list_entry(elt, void_list_elt_t, node);
 }