Mercurial > pidgin
annotate plugins/icq/list.c @ 1857:9ea0b9531bc9
[gaim-migrate @ 1867]
hi
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Fri, 18 May 2001 23:58:13 +0000 |
parents | 0ef6603d986e |
children | 8ed70631ed15 |
rev | line source |
---|---|
1152 | 1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 /* | |
1498
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
3 $Id: list.c 1508 2001-02-22 23:07:34Z warmenhoven $ |
1152 | 4 $Log$ |
1498
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
5 Revision 1.4 2001/02/22 23:07:34 warmenhoven |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
6 updating icqlib |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
7 |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
8 Revision 1.15 2001/02/22 05:38:45 bills |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
9 added sorted list capability - see list_insert_sorted and new |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
10 compare_function list struct member |
1152 | 11 |
12 Revision 1.14 2000/07/10 01:44:20 bills | |
13 i really don't learn - removed LIST_TRACE define | |
14 | |
15 Revision 1.13 2000/07/10 01:43:48 bills | |
16 argh - last list buglet fixed, removed free(node) call from list_free | |
17 | |
18 Revision 1.12 2000/07/10 01:31:17 bills | |
19 oops - removed #define LIST_TRACE and #define QUEUE_DEBUG | |
20 | |
1498
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
21 */ |
1152 | 22 |
23 /* | |
24 * linked list functions | |
25 */ | |
26 | |
27 #include <stdlib.h> | |
28 #include <stdio.h> | |
29 | |
30 #include "list.h" | |
31 | |
32 list *list_new() | |
33 { | |
34 list *plist=(list *)malloc(sizeof(list)); | |
35 | |
36 plist->head=0; | |
37 plist->tail=0; | |
38 plist->count=0; | |
39 | |
40 return plist; | |
41 } | |
42 | |
43 /* Frees all list nodes and list itself */ | |
44 void list_delete(list *plist, void (*item_free_f)(void *)) | |
45 { | |
46 list_free(plist, item_free_f); | |
47 free(plist); | |
48 } | |
49 | |
50 /* Only frees the list nodes */ | |
51 void list_free(list *plist, void (*item_free_f)(void *)) | |
52 { | |
53 list_node *p=plist->head; | |
54 | |
55 #ifdef LIST_TRACE | |
56 printf("list_free(%p)\n", plist); | |
57 list_dump(plist); | |
58 #endif | |
59 | |
60 while(p) | |
61 { | |
62 list_node *ptemp=p; | |
63 | |
64 p=p->next; | |
65 (*item_free_f)((void *)ptemp->item); | |
66 list_remove_node(plist, ptemp); | |
67 } | |
68 } | |
69 | |
1498
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
70 void list_insert_sorted(list *plist, void *pitem) |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
71 { |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
72 list_node *i=plist->head; |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
73 int done; |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
74 |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
75 while (i && !done) |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
76 { |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
77 if ((*plist->compare_function)(pitem, i->item)<0) |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
78 done = 1; |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
79 else |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
80 i=i->next; |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
81 } |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
82 |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
83 list_insert(plist, i, pitem); |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
84 } |
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
85 |
1152 | 86 void list_insert(list *plist, list_node *pnode, void *pitem) |
87 { | |
88 list_node *pnew=(list_node *)malloc(sizeof(list_node)); | |
89 pnew->item=pitem; | |
90 | |
91 #ifdef LIST_TRACE | |
92 printf("inserting %x (node=%x) into list %x\n", pitem, pnew, plist); | |
93 #endif | |
94 | |
95 plist->count++; | |
96 | |
97 /* null source node signifies insert at end of list */ | |
98 if(!pnode) | |
99 { | |
100 pnew->previous=plist->tail; | |
101 pnew->next=0; | |
102 if(plist->tail) | |
103 plist->tail->next=pnew; | |
104 plist->tail=pnew; | |
105 | |
106 if(!plist->head) | |
107 plist->head=pnew; | |
108 } | |
109 else | |
110 { | |
111 pnew->previous=pnode->previous; | |
112 pnew->next=pnode; | |
113 | |
114 if(pnew->previous) | |
115 pnew->previous->next=pnew; | |
116 | |
117 if(pnew->next) | |
118 pnode->previous=pnew; | |
119 | |
120 if(plist->head==pnode) | |
121 plist->head=pnew; | |
122 } | |
123 | |
124 #ifdef LIST_TRACE | |
125 list_dump(plist); | |
126 #endif | |
127 } | |
128 | |
129 void *list_remove_node(list *plist, list_node *p) | |
130 { | |
131 void *pitem; | |
132 | |
133 if(!p) | |
134 return 0; | |
135 | |
136 #ifdef LIST_TRACE | |
137 printf("removing %x (node=%x) from list %x\n", p->item, p, plist); | |
138 #endif | |
139 | |
140 plist->count--; | |
141 | |
142 if(p->next) | |
143 p->next->previous=p->previous; | |
144 | |
145 if(p->previous) | |
146 p->previous->next=p->next; | |
147 | |
148 if(plist->head==p) | |
149 plist->head=p->next; | |
150 | |
151 if(plist->tail==p) | |
152 plist->tail=p->previous; | |
153 | |
154 p->next=0; | |
155 p->previous=0; | |
156 | |
157 #ifdef LIST_TRACE | |
158 list_dump(plist); | |
159 #endif | |
160 | |
161 pitem=p->item; | |
162 | |
163 free(p); | |
164 | |
165 return pitem; | |
166 } | |
167 | |
168 void *list_traverse(list *plist, int (*item_f)(void *, va_list), ...) | |
169 { | |
170 list_node *i=plist->head; | |
171 int f=0; | |
172 va_list ap; | |
173 | |
174 #ifdef LIST_TRACE | |
175 printf("list_traverse(%p)\n", plist); | |
176 list_dump(plist); | |
177 #endif | |
178 va_start(ap, item_f); | |
179 | |
180 /* call item_f for each item in list until end of list or item | |
181 * function returns 0 */ | |
182 while(i && !f) | |
183 { | |
184 list_node *pnext=i->next; | |
185 | |
186 if(!(f=(*item_f)(i->item, ap))) | |
187 i=pnext; | |
188 } | |
1498
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
189 |
1152 | 190 va_end(ap); |
1498
0ef6603d986e
[gaim-migrate @ 1508]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
1432
diff
changeset
|
191 |
1152 | 192 if (i) |
193 return i->item; | |
194 else | |
195 return 0; | |
196 } | |
197 | |
198 int list_dump(list *plist) | |
199 { | |
200 list_node *p=plist->head; | |
201 | |
202 printf("list %x { head=%x, tail=%x, count=%d }\ncontents: ", | |
203 (int)plist, (int)plist->head, (int)plist->tail, plist->count); | |
204 | |
205 while(p) | |
206 { | |
207 printf("%x, ", (int)p->item); | |
208 p=p->next; | |
209 } | |
210 printf("end\n"); | |
211 | |
212 return 0; | |
213 } | |
214 | |
215 void *list_first(list *plist) | |
216 { | |
217 if(plist->head) | |
218 return plist->head->item; | |
219 else | |
220 return 0; | |
221 } | |
222 | |
223 void *list_last(list *plist) | |
224 { | |
225 if(plist->tail) | |
226 return plist->tail->item; | |
227 else | |
228 return 0; | |
229 } | |
230 | |
231 void *list_at(list *plist, int num) | |
232 { | |
233 list_node *ptr = plist->head; | |
234 while(ptr && num) | |
235 { | |
236 num--; | |
237 ptr = ptr->next; | |
238 } | |
239 if(!num) | |
240 return ptr->item; | |
241 else | |
242 return 0L; | |
243 } | |
244 | |
245 list_node *list_find(list *plist, void *pitem) | |
246 { | |
247 list_node *p=plist->head; | |
248 | |
249 while(p) | |
250 { | |
251 if(p->item==pitem) | |
252 return p; | |
253 p=p->next; | |
254 } | |
255 return 0; | |
256 } | |
257 | |
258 void *list_remove(list *plist, void *pitem) | |
259 { | |
260 list_node *p=list_find(plist, pitem); | |
261 | |
262 if(p) | |
263 return list_remove_node(plist, p); | |
264 else | |
265 return 0; | |
266 } |