Fix FSF address (Tobias Mueller, #470445)
[platform/upstream/evolution-data-server.git] / camel / camel-list-utils.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * Authors: Michael Zucchi <notzed@ximian.com>
4  *
5  * Copyright 2004 Novell, Inc. (www.novell.com)
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of version 2 of the GNU Lesser General Public
9  * License as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <glib.h>
28
29 #include "camel-list-utils.h"
30
31 /**
32  * camel_dlist_init:
33  * @v: 
34  * 
35  * Initialise a double-linked list header.  All list headers must be
36  * initialised before use.
37  **/
38 void camel_dlist_init(CamelDList *v)
39 {
40         v->head = (CamelDListNode *)&v->tail;
41         v->tail = NULL;
42         v->tailpred = (CamelDListNode *)&v->head;
43 }
44
45 /**
46  * camel_dlist_addhead:
47  * @l: An initialised list header.
48  * @n: A node, the next and prev pointers will be overwritten.
49  * 
50  * Add the list node @n to the head (start) of the list @l.
51  * 
52  * Return value: @n.
53  **/
54 CamelDListNode *camel_dlist_addhead(CamelDList *l, CamelDListNode *n)
55 {
56         n->next = l->head;
57         n->prev = (CamelDListNode *)&l->head;
58         l->head->prev = n;
59         l->head = n;
60         return n;
61 }
62
63 /**
64  * camel_dlist_addtail:
65  * @l: An intialised list header.
66  * @n: A node, the next and prev pointers will be overwritten.
67  * 
68  * Add the list onde @n to the tail (end) of the list @l.
69  * 
70  * Return value: @n.
71  **/
72 CamelDListNode *camel_dlist_addtail(CamelDList *l, CamelDListNode *n)
73 {
74         n->next = (CamelDListNode *)&l->tail;
75         n->prev = l->tailpred;
76         l->tailpred->next = n;
77         l->tailpred = n;
78         return n;
79 }
80
81 /**
82  * camel_dlist_remove:
83  * @n: A node which is part of a list.
84  * 
85  * Remove @n from the list it's in.  @n must belong to a list.
86  * 
87  * Return value: @n.
88  **/
89 CamelDListNode *camel_dlist_remove(CamelDListNode *n)
90 {
91         n->next->prev = n->prev;
92         n->prev->next = n->next;
93         return n;
94 }
95
96 /**
97  * camel_dlist_remhead:
98  * @l: An initialised list, maybe containing items.
99  * 
100  * Remove the head node (start) of the list.
101  * 
102  * xReturn value: The previously first-node in the list, or NULLif @l
103  * is an empty list.
104  **/
105 CamelDListNode *camel_dlist_remhead(CamelDList *l)
106 {
107         CamelDListNode *n, *nn;
108
109         n = l->head;
110         nn = n->next;
111         if (nn) {
112                 nn->prev = n->prev;
113                 l->head = nn;
114                 return n;
115         }
116         return NULL;
117 }
118
119 /**
120  * camel_dlist_remtail:
121  * @l: An initialised list, maybe containing items.
122  * 
123  * Remove the last node in the list.
124  * 
125  * Return value: The previously last-node in the list, or NULL if @l
126  * is an empty list.
127  **/
128 CamelDListNode *camel_dlist_remtail(CamelDList *l)
129 {
130         CamelDListNode *n, *np;
131
132         n = l->tailpred;
133         np = n->prev;
134         if (np) {
135                 np->next = n->next;
136                 l->tailpred = np;
137                 return n;
138         }
139         return NULL;
140 }
141
142 /**
143  * camel_dlist_empty:
144  * @l: An initialised list header.
145  * 
146  * Returns %TRUE if @l is an empty list.
147  * 
148  * Return value: %TRUE if @l is an empty list, %FALSE otherwise.
149  **/
150 int camel_dlist_empty(CamelDList *l)
151 {
152         return (l->head == (CamelDListNode *)&l->tail);
153 }
154
155 /**
156  * camel_dlist_length:
157  * @l: An initialised list header.
158  * 
159  * Returns the number of nodes in the list @l.
160  * 
161  * Return value: The number of nodes.
162  **/
163 int camel_dlist_length(CamelDList *l)
164 {
165         CamelDListNode *n, *nn;
166         int count = 0;
167
168         n = l->head;
169         nn = n->next;
170         while (nn) {
171                 count++;
172                 n = nn;
173                 nn = n->next;
174         }
175
176         return count;
177 }
178
179 /* This is just for orthogonal completeness */
180
181 void camel_slist_init(CamelSList *v)
182 {
183         v->head = NULL;
184 }
185
186 CamelSListNode *camel_slist_addhead(CamelSList *l, CamelSListNode *n)
187 {
188         n->next = l->head;
189         l->head = n;
190
191         return n;
192 }
193
194 CamelSListNode *camel_slist_addtail(CamelSList *l, CamelSListNode *n)
195 {
196         CamelSListNode *p;
197
198         p = (CamelSListNode *)l;
199         while (p->next)
200                 p = p->next;
201         n->next = NULL;
202         p->next = n;
203
204         return n;
205 }
206
207 CamelSListNode *camel_slist_remove(CamelSList *l, CamelSListNode *n)
208 {
209         CamelSListNode *p, *q;
210
211         p = (CamelSListNode *)l;
212         while ( (q = p->next) ) {
213                 if (q == n) {
214                         p->next = n->next;
215                         return n;
216                 }
217                 p = q;
218         }
219
220         g_warning("Trying to remove SList node not present in SList");
221
222         return NULL;
223 }
224
225 CamelSListNode *camel_slist_remhead(CamelSList *l)
226 {
227         CamelSListNode *n;
228
229         n = l->head;
230         if (n)
231                 l->head = n->next;
232
233         return n;
234 }
235
236 CamelSListNode *camel_slist_remtail(CamelSList *l)
237 {
238         CamelSListNode *n, *p;
239
240         n = l->head;
241         if (l->head == NULL)
242                 return NULL;
243         p = (CamelSListNode *)l;
244         while (n->next) {
245                 p = n;
246                 n = n->next;
247         }
248         p->next = NULL;
249
250         return n;
251 }
252
253 int camel_slist_empty(CamelSList *l)
254 {
255         return (l->head == NULL);
256 }
257
258 int camel_slist_length(CamelSList *l)
259 {
260         CamelSListNode *n;
261         int count = 0;
262
263         n = l->head;
264         while (n) {
265                 count++;
266                 n = n->next;
267         }
268
269         return count;
270 }
271