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