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 }