]> git.decadent.org.uk Git - ion3.git/blob - libtu/ptrlist.c
1ea6726eafe04ddddb89b0a570e9bd419a6ee8cd
[ion3.git] / libtu / ptrlist.c
1 /*
2  * libtu/ptrlist.c
3  *
4  * Copyright (c) Tuomo Valkonen 1999-2005. 
5  *
6  * You may distribute and modify this library under the terms of either
7  * the Clarified Artistic License or the GNU LGPL, version 2.1 or later.
8  */
9
10 #include "obj.h"
11 #include "ptrlist.h"
12 #include "types.h"
13 #include "dlist.h"
14 #include "misc.h"
15
16
17 static void free_node(PtrList **ptrlist, PtrList *node)
18 {
19     UNLINK_ITEM(*ptrlist, node, next, prev);
20     free(node);
21 }
22
23
24 static PtrList *mknode(void *ptr)
25 {
26     PtrList *node;
27     
28     if(ptr==NULL)
29         return NULL;
30     
31     node=ALLOC(PtrList);
32     
33     if(node==NULL)
34         return FALSE;
35         
36     node->ptr=ptr;
37     
38     return node;
39 }
40
41
42 static PtrList *ptrlist_find_node(PtrList *ptrlist, void *ptr)
43 {
44     PtrList *node=ptrlist;
45     
46     while(node!=NULL){
47         if(node->ptr==ptr)
48             break;
49         node=node->next;
50     }
51     
52     return node;
53 }
54
55
56 bool ptrlist_insert_last(PtrList **ptrlist, void *ptr)
57 {
58     PtrList *node=mknode(ptr);
59     
60     if(node==NULL)
61         return FALSE;
62     
63     LINK_ITEM_LAST(*ptrlist, node, next, prev);
64     
65     return TRUE;
66 }
67
68
69 bool ptrlist_insert_first(PtrList **ptrlist, void *ptr)
70 {
71     PtrList *node=mknode(ptr);
72     
73     if(node==NULL)
74         return FALSE;
75     
76     LINK_ITEM_FIRST(*ptrlist, node, next, prev);
77     
78     return TRUE;
79 }
80
81
82 bool ptrlist_reinsert_last(PtrList **ptrlist, void *ptr)
83 {
84     PtrList *node=ptrlist_find_node(*ptrlist, ptr);
85     
86     if(node==NULL)
87         return FALSE;
88     
89     UNLINK_ITEM(*ptrlist, node, next, prev);
90     LINK_ITEM_LAST(*ptrlist, node, next, prev);
91     
92     return TRUE;
93 }
94
95
96 bool ptrlist_reinsert_first(PtrList **ptrlist, void *ptr)
97 {
98     PtrList *node=ptrlist_find_node(*ptrlist, ptr);
99     
100     if(node==NULL)
101         return FALSE;
102     
103     UNLINK_ITEM(*ptrlist, node, next, prev);
104     LINK_ITEM_FIRST(*ptrlist, node, next, prev);
105     
106     return TRUE;
107 }
108
109
110 bool ptrlist_remove(PtrList **ptrlist, void *ptr)
111 {
112     PtrList *node=ptrlist_find_node(*ptrlist, ptr);
113     
114     if(node!=NULL)
115         free_node(ptrlist, node);
116     
117     return (node!=NULL);
118 }
119
120
121 void ptrlist_clear(PtrList **ptrlist)
122 {
123     while(*ptrlist!=NULL)
124         free_node(ptrlist, *ptrlist);
125 }
126
127
128 PtrListIterTmp ptrlist_iter_tmp=NULL;
129
130
131 void ptrlist_iter_init(PtrListIterTmp *state, PtrList *ptrlist)
132 {
133     *state=ptrlist;
134 }
135
136
137 void *ptrlist_iter(PtrListIterTmp *state)
138 {
139     void *ptr=NULL;
140     
141     if(*state!=NULL){
142         ptr=(*state)->ptr;
143         (*state)=(*state)->next;
144     }
145     
146     return ptr;
147 }
148
149
150 void ptrlist_iter_rev_init(PtrListIterTmp *state, PtrList *ptrlist)
151 {
152     *state=(ptrlist==NULL ? NULL : ptrlist->prev);
153 }
154
155
156 void *ptrlist_iter_rev(PtrListIterTmp *state)
157 {
158     void *ptr=NULL;
159     
160     if(*state!=NULL){
161         ptr=(*state)->ptr;
162         *state=(*state)->prev;
163         if((*state)->next==NULL)
164             *state=NULL;
165     }
166     
167     return ptr;
168 }
169
170
171 void *ptrlist_take_first(PtrList **ptrlist)
172 {
173     PtrList *node=*ptrlist;
174     void *ptr;
175     
176     if(node==NULL)
177         return NULL;
178     
179     ptr=node->ptr;
180     
181     free_node(ptrlist, node);
182     
183     return ptr;
184 }
185     
186         
187 void *ptrlist_take_last(PtrList **ptrlist)
188 {
189     PtrList *node=*ptrlist;
190     void *ptr;
191     
192     if(node==NULL)
193         return NULL;
194     
195     node=node->prev;
196     
197     ptr=node->ptr;
198     
199     free_node(ptrlist, node);
200     
201     return ptr;
202 }