1 /* active_list.h - the opkg package management system
3 Tick Chen <tick@openmoko.com>
5 Copyright (C) 2008 Openmoko Inc.
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.
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.
18 #include "active_list.h"
23 #include "libbb/libbb.h"
25 void active_list_init(struct active_list
*ptr
)
27 INIT_LIST_HEAD(&ptr
->node
);
28 INIT_LIST_HEAD(&ptr
->depend
);
34 struct active_list
*active_list_next(struct active_list
*head
,
35 struct active_list
*ptr
)
37 struct active_list
*next
= NULL
;
39 opkg_msg(ERROR
, "Internal error: head=%p, ptr=%p\n", head
, ptr
);
44 next
= list_entry(ptr
->node
.next
, struct active_list
, node
);
48 if (ptr
->depended
&& &ptr
->depended
->depend
== ptr
->node
.next
) {
51 while (next
->depend
.next
!= &next
->depend
) {
52 next
= list_entry(next
->depend
.next
, struct active_list
, node
);
57 struct active_list
*active_list_prev(struct active_list
*head
,
58 struct active_list
*ptr
)
60 struct active_list
*prev
= NULL
;
62 opkg_msg(ERROR
, "Internal error: head=%p, ptr=%p\n", head
, ptr
);
67 if (ptr
->depend
.prev
!= &ptr
->depend
) {
68 prev
= list_entry(ptr
->depend
.prev
, struct active_list
, node
);
71 if (ptr
->depended
&& ptr
->depended
!= head
72 && &ptr
->depended
->depend
== ptr
->node
.prev
) {
74 list_entry(ptr
->depended
->node
.prev
, struct active_list
,
77 prev
= list_entry(ptr
->node
.prev
, struct active_list
, node
);
83 struct active_list
*active_list_move_node(struct active_list
*old_head
,
84 struct active_list
*new_head
,
85 struct active_list
*node
)
87 struct active_list
*prev
;
88 if (!old_head
|| !new_head
|| !node
)
90 if (old_head
== new_head
)
92 prev
= active_list_prev(old_head
, node
);
93 active_list_add(new_head
, node
);
97 static void list_head_clear(struct list_head
*head
)
99 struct active_list
*next
;
100 struct list_head
*n
, *ptr
;
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
);
108 active_list_init(next
);
112 void active_list_clear(struct active_list
*head
)
114 list_head_clear(&head
->node
);
115 if (head
->depend
.next
!= &head
->depend
) {
116 list_head_clear(&head
->depend
);
118 active_list_init(head
);
121 void active_list_add(struct active_list
*head
, struct active_list
*node
)
123 list_del_init(&node
->node
);
124 list_add_tail(&node
->node
, &head
->node
);
125 node
->depended
= head
;
128 struct active_list
*active_list_head_new(void)
130 struct active_list
*head
= xcalloc(1, sizeof(struct active_list
));
131 active_list_init(head
);
135 void active_list_head_delete(struct active_list
*head
)
137 active_list_clear(head
);