Mercurial > pidgin
comparison src/protocols/icq/list.c @ 2086:424a40f12a6c
[gaim-migrate @ 2096]
moving protocols from plugins/ to src/protocols. making it so that you can select which protocols are compiled statically.
committer: Tailor Script <tailor@pidgin.im>
author | Eric Warmenhoven <eric@warmenhoven.org> |
---|---|
date | Tue, 31 Jul 2001 01:00:39 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
2085:7ebb4322f89b | 2086:424a40f12a6c |
---|---|
1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ | |
2 | |
3 /* | |
4 * $Id: list.c 2096 2001-07-31 01:00:39Z warmenhoven $ | |
5 * | |
6 * Copyright (C) 1998-2001, Denis V. Dmitrienko <denis@null.net> and | |
7 * Bill Soudan <soudan@kde.org> | |
8 * | |
9 * This program is free software; you can redistribute it and/or modify | |
10 * it under the terms of the GNU General Public License as published by | |
11 * the Free Software Foundation; either version 2 of the License, or | |
12 * (at your option) any later version. | |
13 * | |
14 * This program is distributed in the hope that it will be useful, | |
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
17 * GNU General Public License for more details. | |
18 * | |
19 * You should have received a copy of the GNU General Public License | |
20 * along with this program; if not, write to the Free Software | |
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | |
22 * | |
23 */ | |
24 | |
25 /* | |
26 * linked list functions | |
27 */ | |
28 | |
29 #include <stdlib.h> | |
30 #include <stdio.h> | |
31 | |
32 #include "list.h" | |
33 | |
34 icq_List *icq_ListNew() | |
35 { | |
36 icq_List *plist=(icq_List *)malloc(sizeof(icq_List)); | |
37 | |
38 plist->head=0; | |
39 plist->tail=0; | |
40 plist->count=0; | |
41 | |
42 return plist; | |
43 } | |
44 | |
45 /* Frees all list nodes and list itself */ | |
46 void icq_ListDelete(icq_List *plist, void (*item_free_f)(void *)) | |
47 { | |
48 if (item_free_f) | |
49 icq_ListFree(plist, item_free_f); | |
50 free(plist); | |
51 } | |
52 | |
53 /* Only frees the list nodes */ | |
54 void icq_ListFree(icq_List *plist, void (*item_free_f)(void *)) | |
55 { | |
56 icq_ListNode *p=plist->head; | |
57 | |
58 #ifdef LIST_TRACE | |
59 printf("icq_ListFree(%p)\n", plist); | |
60 icq_ListDump(plist); | |
61 #endif | |
62 | |
63 while(p) | |
64 { | |
65 icq_ListNode *ptemp=p; | |
66 | |
67 p=p->next; | |
68 (*item_free_f)((void *)ptemp->item); | |
69 icq_ListRemoveNode(plist, ptemp); | |
70 } | |
71 } | |
72 | |
73 void icq_ListInsertSorted(icq_List *plist, void *pitem) | |
74 { | |
75 icq_ListNode *i=plist->head; | |
76 int done = 0; | |
77 | |
78 while (i && !done) | |
79 { | |
80 if ((*plist->compare_function)(pitem, i->item)<0) | |
81 done = 1; | |
82 else | |
83 i=i->next; | |
84 } | |
85 | |
86 icq_ListInsert(plist, i, pitem); | |
87 } | |
88 | |
89 void icq_ListInsert(icq_List *plist, icq_ListNode *pnode, void *pitem) | |
90 { | |
91 icq_ListNode *pnew=(icq_ListNode *)malloc(sizeof(icq_ListNode)); | |
92 pnew->item=pitem; | |
93 | |
94 #ifdef LIST_TRACE | |
95 printf("inserting %x (node=%x) into list %x\n", pitem, pnew, plist); | |
96 #endif | |
97 | |
98 plist->count++; | |
99 | |
100 /* null source node signifies insert at end of icq_List */ | |
101 if(!pnode) | |
102 { | |
103 pnew->previous=plist->tail; | |
104 pnew->next=0; | |
105 if(plist->tail) | |
106 plist->tail->next=pnew; | |
107 plist->tail=pnew; | |
108 | |
109 if(!plist->head) | |
110 plist->head=pnew; | |
111 } | |
112 else | |
113 { | |
114 pnew->previous=pnode->previous; | |
115 pnew->next=pnode; | |
116 | |
117 if(pnew->previous) | |
118 pnew->previous->next=pnew; | |
119 | |
120 if(pnew->next) | |
121 pnode->previous=pnew; | |
122 | |
123 if(plist->head==pnode) | |
124 plist->head=pnew; | |
125 } | |
126 | |
127 #ifdef LIST_TRACE | |
128 icq_ListDump(plist); | |
129 #endif | |
130 } | |
131 | |
132 void *icq_ListRemoveNode(icq_List *plist, icq_ListNode *p) | |
133 { | |
134 void *pitem; | |
135 | |
136 if(!p) | |
137 return 0; | |
138 | |
139 #ifdef LIST_TRACE | |
140 printf("removing %x (node=%x) from list %x\n", p->item, p, plist); | |
141 #endif | |
142 | |
143 plist->count--; | |
144 | |
145 if(p->next) | |
146 p->next->previous=p->previous; | |
147 | |
148 if(p->previous) | |
149 p->previous->next=p->next; | |
150 | |
151 if(plist->head==p) | |
152 plist->head=p->next; | |
153 | |
154 if(plist->tail==p) | |
155 plist->tail=p->previous; | |
156 | |
157 p->next=0; | |
158 p->previous=0; | |
159 | |
160 #ifdef LIST_TRACE | |
161 icq_ListDump(plist); | |
162 #endif | |
163 | |
164 pitem=p->item; | |
165 | |
166 free(p); | |
167 | |
168 return pitem; | |
169 } | |
170 | |
171 void *icq_ListTraverse(icq_List *plist, int (*item_f)(void *, va_list), ...) | |
172 { | |
173 icq_ListNode *i=plist->head; | |
174 int f=0; | |
175 va_list ap; | |
176 | |
177 #ifdef LIST_TRACE | |
178 printf("icq_ListTraverse(%p)\n", plist); | |
179 icq_ListDump(plist); | |
180 #endif | |
181 va_start(ap, item_f); | |
182 | |
183 /* call item_f for each item in list until end of list or item | |
184 * function returns 0 */ | |
185 while(i && !f) | |
186 { | |
187 icq_ListNode *pnext=i->next; | |
188 | |
189 if(!(f=(*item_f)(i->item, ap))) | |
190 i=pnext; | |
191 } | |
192 | |
193 va_end(ap); | |
194 | |
195 if (i) | |
196 return i->item; | |
197 else | |
198 return 0; | |
199 } | |
200 | |
201 int icq_ListDump(icq_List *plist) | |
202 { | |
203 icq_ListNode *p=plist->head; | |
204 | |
205 printf("list %lx { head=%lx, tail=%lx, count=%d }\ncontents: ", | |
206 (long)plist, (long)plist->head, (long)plist->tail, plist->count); | |
207 | |
208 while(p) | |
209 { | |
210 printf("%lx, ", (long)p->item); | |
211 p=p->next; | |
212 } | |
213 printf("end\n"); | |
214 | |
215 return 0; | |
216 } | |
217 | |
218 void *icq_ListFirst(icq_List *plist) | |
219 { | |
220 if(plist->head) | |
221 return plist->head->item; | |
222 else | |
223 return 0; | |
224 } | |
225 | |
226 void *icq_ListLast(icq_List *plist) | |
227 { | |
228 if(plist->tail) | |
229 return plist->tail->item; | |
230 else | |
231 return 0; | |
232 } | |
233 | |
234 void *icq_ListAt(icq_List *plist, int num) | |
235 { | |
236 icq_ListNode *ptr = plist->head; | |
237 while(ptr && num) | |
238 { | |
239 num--; | |
240 ptr = ptr->next; | |
241 } | |
242 if(!num) | |
243 return ptr->item; | |
244 else | |
245 return 0L; | |
246 } | |
247 | |
248 icq_ListNode *icq_ListFind(icq_List *plist, void *pitem) | |
249 { | |
250 icq_ListNode *p=plist->head; | |
251 | |
252 while(p) | |
253 { | |
254 if(p->item==pitem) | |
255 return p; | |
256 p=p->next; | |
257 } | |
258 return 0; | |
259 } | |
260 | |
261 void *icq_ListRemove(icq_List *plist, void *pitem) | |
262 { | |
263 icq_ListNode *p=icq_ListFind(plist, pitem); | |
264 | |
265 if(p) | |
266 return icq_ListRemoveNode(plist, p); | |
267 else | |
268 return 0; | |
269 } |