summaryrefslogtreecommitdiffabout
path: root/libetpan/src/data-types/clist.c
Unidiff
Diffstat (limited to 'libetpan/src/data-types/clist.c') (more/less context) (ignore whitespace changes)
-rw-r--r--libetpan/src/data-types/clist.c265
1 files changed, 265 insertions, 0 deletions
diff --git a/libetpan/src/data-types/clist.c b/libetpan/src/data-types/clist.c
new file mode 100644
index 0000000..0b216de
--- a/dev/null
+++ b/libetpan/src/data-types/clist.c
@@ -0,0 +1,265 @@
1/*
2 * libEtPan! -- a mail stuff library
3 *
4 * clist - Implements simple generic double-linked pointer lists
5 *
6 * Copyright (c) 1999-2005, Gaël Roualland <gael.roualland@iname.com>
7 * interface changes - 2005 - DINH Viet Hoa
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the libEtPan! project nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35/*
36 * $Id$
37 */
38
39#include <stdlib.h>
40#include "clist.h"
41
42clist * clist_new() {
43 clist * lst;
44
45 lst = (clist *) malloc(sizeof(clist));
46 if (!lst) return NULL;
47
48 lst->first = lst->last = NULL;
49 lst->count = 0;
50
51 return lst;
52}
53
54void clist_free(clist * lst) {
55 clistcell * l1, * l2;
56
57 l1 = lst->first;
58 while (l1) {
59 l2 = l1->next;
60 free(l1);
61 l1 = l2;
62 }
63
64 free(lst);
65}
66
67#ifdef NO_MACROS
68int clist_isempty(clist * lst) {
69 return ((lst->first==lst->last) && (lst->last==NULL));
70}
71
72clistiter * clist_begin(clist * lst) {
73 return lst->first;
74}
75
76clistiter * clist_end(clist * lst) {
77 return lst->last;
78}
79
80clistiter * clist_next(clistiter * iter) {
81 if (iter)
82 return iter->next;
83 else
84 return NULL;
85}
86
87clistiter * clist_previous(clistiter * iter) {
88 if (iter)
89 return iter->previous;
90 else
91 return NULL;
92}
93
94void * clist_content(clistiter * iter) {
95 if (iter)
96 return iter->data;
97 else
98 return NULL;
99}
100
101int clist_count(clist * lst) {
102 return lst->count;
103}
104
105int clist_prepend(clist * lst, void * data) {
106 return clist_insert_before(lst, lst->first, data);
107}
108
109int clist_append(clist * lst, void * data) {
110 return clist_insert_after(lst, lst->last, data);
111}
112#endif
113
114int clist_insert_before(clist * lst, clistiter * iter, void * data) {
115 clistcell * c;
116
117 c = (clistcell *) malloc(sizeof(clistcell));
118 if (!c) return -1;
119
120 c->data = data;
121 lst->count++;
122
123 if (clist_isempty(lst)) {
124 c->previous = c->next = NULL;
125 lst->first = lst->last = c;
126 return 0;
127 }
128
129 if (!iter) {
130 c->previous = lst->last;
131 c->previous->next = c;
132 c->next = NULL;
133 lst->last = c;
134 return 0;
135 }
136
137 c->previous = iter->previous;
138 c->next = iter;
139 c->next->previous = c;
140 if (c->previous)
141 c->previous->next = c;
142 else
143 lst->first = c;
144
145 return 0;
146}
147
148int clist_insert_after(clist * lst, clistiter * iter, void * data) {
149 clistcell * c;
150
151 c = (clistcell *) malloc(sizeof(clistcell));
152 if (!c) return -1;
153
154 c->data = data;
155 lst->count++;
156
157 if (clist_isempty(lst)) {
158 c->previous = c->next = NULL;
159 lst->first = lst->last = c;
160 return 0;
161 }
162
163 if (!iter) {
164 c->previous = lst->last;
165 c->previous->next = c;
166 c->next = NULL;
167 lst->last = c;
168 return 0;
169 }
170
171 c->previous = iter;
172 c->next = iter->next;
173 if (c->next)
174 c->next->previous = c;
175 else
176 lst->last = c;
177 c->previous->next = c;
178
179 return 0;
180}
181
182clistiter * clist_delete(clist * lst, clistiter * iter) {
183 clistiter * ret;
184
185 if (!iter) return NULL;
186
187 if (iter->previous)
188 iter->previous->next = iter->next;
189 else
190 lst->first = iter->next;
191
192 if (iter->next) {
193 iter->next->previous = iter->previous;
194 ret = iter->next;
195 } else {
196 lst->last = iter->previous;
197 ret = NULL;
198 }
199
200 free(iter);
201 lst->count--;
202
203 return ret;
204}
205
206
207
208void clist_foreach(clist * lst, clist_func func, void * data)
209{
210 clistiter * cur;
211
212 for(cur = clist_begin(lst) ; cur != NULL ; cur = cur->next)
213 func(cur->data, data);
214}
215
216void clist_concat(clist * dest, clist * src)
217{
218 if (src->first == NULL) {
219 /* do nothing */
220 }
221 else if (dest->last == NULL) {
222 dest->first = src->first;
223 dest->last = src->last;
224 }
225 else {
226 dest->last->next = src->first;
227 src->first->previous = dest->last;
228 dest->last = src->last;
229 }
230
231 dest->count += src->count;
232 src->last = src->first = NULL;
233}
234
235static inline clistiter * internal_clist_nth(clist * lst, int index)
236{
237 clistiter * cur;
238
239 cur = clist_begin(lst);
240 while ((index > 0) && (cur != NULL)) {
241 cur = cur->next;
242 index --;
243 }
244
245 if (cur == NULL)
246 return NULL;
247
248 return cur;
249}
250
251void * clist_nth_data(clist * lst, int index)
252{
253 clistiter * cur;
254
255 cur = internal_clist_nth(lst, index);
256 if (cur == NULL)
257 return NULL;
258
259 return cur->data;
260}
261
262clistiter * clist_nth(clist * lst, int index)
263{
264 return internal_clist_nth(lst, index);
265}