1 /* active_list.h - the opkg package management system 2 3 Tick Chen <tick@openmoko.com> 4 5 Copyright (C) 2008 Openmoko Inc. 6 7 This program is free software; you can redistribute it and/or 8 modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2, or (at 10 your option) any later version. 11 12 This program is distributed in the hope that it will be useful, but 13 WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 General Public License for more details. 16 */ 17 18 #include "active_list.h" 19 #include <stdio.h> 20 #include <string.h> 21 #include <stdlib.h> 22 23 #include "libbb/libbb.h" 24 25 void active_list_init(struct active_list *ptr) 26 { 27 INIT_LIST_HEAD(&ptr->node); 28 INIT_LIST_HEAD(&ptr->depend); 29 ptr->depended = NULL; 30 } 31 32 /** 33 */ 34 struct active_list *active_list_next(struct active_list *head, 35 struct active_list *ptr) 36 { 37 struct active_list *next = NULL; 38 if (!head) { 39 opkg_msg(ERROR, "Internal error: head=%p, ptr=%p\n", head, ptr); 40 return NULL; 41 } 42 if (!ptr) 43 ptr = head; 44 next = list_entry(ptr->node.next, struct active_list, node); 45 if (next == head) { 46 return NULL; 47 } 48 if (ptr->depended && &ptr->depended->depend == ptr->node.next) { 49 return ptr->depended; 50 } 51 while (next->depend.next != &next->depend) { 52 next = list_entry(next->depend.next, struct active_list, node); 53 } 54 return next; 55 } 56 57 struct active_list *active_list_prev(struct active_list *head, 58 struct active_list *ptr) 59 { 60 struct active_list *prev = NULL; 61 if (!head) { 62 opkg_msg(ERROR, "Internal error: head=%p, ptr=%p\n", head, ptr); 63 return NULL; 64 } 65 if (!ptr) 66 ptr = head; 67 if (ptr->depend.prev != &ptr->depend) { 68 prev = list_entry(ptr->depend.prev, struct active_list, node); 69 return prev; 70 } 71 if (ptr->depended && ptr->depended != head 72 && &ptr->depended->depend == ptr->node.prev) { 73 prev = 74 list_entry(ptr->depended->node.prev, struct active_list, 75 node); 76 } else 77 prev = list_entry(ptr->node.prev, struct active_list, node); 78 if (prev == head) 79 return NULL; 80 return prev; 81 } 82 83 struct active_list *active_list_move_node(struct active_list *old_head, 84 struct active_list *new_head, 85 struct active_list *node) 86 { 87 struct active_list *prev; 88 if (!old_head || !new_head || !node) 89 return NULL; 90 if (old_head == new_head) 91 return node; 92 prev = active_list_prev(old_head, node); 93 active_list_add(new_head, node); 94 return prev; 95 } 96 97 static void list_head_clear(struct list_head *head) 98 { 99 struct active_list *next; 100 struct list_head *n, *ptr; 101 if (!head) 102 return; 103 list_for_each_safe(ptr, n, head) { 104 next = list_entry(ptr, struct active_list, node); 105 if (next->depend.next != &next->depend) { 106 list_head_clear(&next->depend); 107 } 108 active_list_init(next); 109 } 110 } 111 112 void active_list_clear(struct active_list *head) 113 { 114 list_head_clear(&head->node); 115 if (head->depend.next != &head->depend) { 116 list_head_clear(&head->depend); 117 } 118 active_list_init(head); 119 } 120 121 void active_list_add(struct active_list *head, struct active_list *node) 122 { 123 list_del_init(&node->node); 124 list_add_tail(&node->node, &head->node); 125 node->depended = head; 126 } 127 128 struct active_list *active_list_head_new(void) 129 { 130 struct active_list *head = xcalloc(1, sizeof(struct active_list)); 131 active_list_init(head); 132 return head; 133 } 134 135 void active_list_head_delete(struct active_list *head) 136 { 137 active_list_clear(head); 138 free(head); 139 } 140
This page was automatically generated by LXR 0.3.1. • OpenWrt