1 /* GLIB - Library of useful routines for C programming
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02110-1301, USA.
18 */
19
20 /*
21 * Modified by the GLib Team and others 1997-1999. See the AUTHORS
22 * file for a list of people on the GLib Team. See the ChangeLog
23 * files for a list of changes. These files are distributed with
24 * GLib at ftp://ftp.gtk.org/pub/gtk/.
25 */
26
27
28
29 #include "fluid_sys.h"
30 #include "fluid_list.h"
31
32
33 fluid_list_t *
new_fluid_list(void)34 new_fluid_list(void)
35 {
36 fluid_list_t *list;
37 list = (fluid_list_t *) FLUID_MALLOC(sizeof(fluid_list_t));
38 list->data = NULL;
39 list->next = NULL;
40 return list;
41 }
42
43 void
delete_fluid_list(fluid_list_t * list)44 delete_fluid_list(fluid_list_t *list)
45 {
46 fluid_list_t *next;
47 fluid_return_if_fail(list != NULL);
48
49 while(list)
50 {
51 next = list->next;
52 FLUID_FREE(list);
53 list = next;
54 }
55 }
56
57 void
delete1_fluid_list(fluid_list_t * list)58 delete1_fluid_list(fluid_list_t *list)
59 {
60 FLUID_FREE(list);
61 }
62
63 fluid_list_t *
fluid_list_append(fluid_list_t * list,void * data)64 fluid_list_append(fluid_list_t *list, void *data)
65 {
66 fluid_list_t *new_list;
67 fluid_list_t *last;
68
69 new_list = new_fluid_list();
70 new_list->data = data;
71
72 if(list)
73 {
74 last = fluid_list_last(list);
75 /* g_assert (last != NULL); */
76 last->next = new_list;
77
78 return list;
79 }
80 else
81 {
82 return new_list;
83 }
84 }
85
86 fluid_list_t *
fluid_list_prepend(fluid_list_t * list,void * data)87 fluid_list_prepend(fluid_list_t *list, void *data)
88 {
89 fluid_list_t *new_list;
90
91 new_list = new_fluid_list();
92 new_list->data = data;
93 new_list->next = list;
94
95 return new_list;
96 }
97
98 fluid_list_t *
fluid_list_nth(fluid_list_t * list,int n)99 fluid_list_nth(fluid_list_t *list, int n)
100 {
101 while((n-- > 0) && list)
102 {
103 list = list->next;
104 }
105
106 return list;
107 }
108
109 fluid_list_t *
fluid_list_remove(fluid_list_t * list,void * data)110 fluid_list_remove(fluid_list_t *list, void *data)
111 {
112 fluid_list_t *tmp;
113 fluid_list_t *prev;
114
115 prev = NULL;
116 tmp = list;
117
118 while(tmp)
119 {
120 if(tmp->data == data)
121 {
122 if(prev)
123 {
124 prev->next = tmp->next;
125 }
126
127 if(list == tmp)
128 {
129 list = list->next;
130 }
131
132 tmp->next = NULL;
133 delete_fluid_list(tmp);
134
135 break;
136 }
137
138 prev = tmp;
139 tmp = tmp->next;
140 }
141
142 return list;
143 }
144
145 fluid_list_t *
fluid_list_remove_link(fluid_list_t * list,fluid_list_t * link)146 fluid_list_remove_link(fluid_list_t *list, fluid_list_t *link)
147 {
148 fluid_list_t *tmp;
149 fluid_list_t *prev;
150
151 prev = NULL;
152 tmp = list;
153
154 while(tmp)
155 {
156 if(tmp == link)
157 {
158 if(prev)
159 {
160 prev->next = tmp->next;
161 }
162
163 if(list == tmp)
164 {
165 list = list->next;
166 }
167
168 tmp->next = NULL;
169 break;
170 }
171
172 prev = tmp;
173 tmp = tmp->next;
174 }
175
176 return list;
177 }
178
179 static fluid_list_t *
fluid_list_sort_merge(fluid_list_t * l1,fluid_list_t * l2,fluid_compare_func_t compare_func)180 fluid_list_sort_merge(fluid_list_t *l1, fluid_list_t *l2, fluid_compare_func_t compare_func)
181 {
182 fluid_list_t list, *l;
183
184 l = &list;
185
186 while(l1 && l2)
187 {
188 if(compare_func(l1->data, l2->data) < 0)
189 {
190 l = l->next = l1;
191 l1 = l1->next;
192 }
193 else
194 {
195 l = l->next = l2;
196 l2 = l2->next;
197 }
198 }
199
200 l->next = l1 ? l1 : l2;
201
202 return list.next;
203 }
204
205 fluid_list_t *
fluid_list_sort(fluid_list_t * list,fluid_compare_func_t compare_func)206 fluid_list_sort(fluid_list_t *list, fluid_compare_func_t compare_func)
207 {
208 fluid_list_t *l1, *l2;
209
210 if(!list)
211 {
212 return NULL;
213 }
214
215 if(!list->next)
216 {
217 return list;
218 }
219
220 l1 = list;
221 l2 = list->next;
222
223 while((l2 = l2->next) != NULL)
224 {
225 if((l2 = l2->next) == NULL)
226 {
227 break;
228 }
229
230 l1 = l1->next;
231 }
232
233 l2 = l1->next;
234 l1->next = NULL;
235
236 return fluid_list_sort_merge(fluid_list_sort(list, compare_func),
237 fluid_list_sort(l2, compare_func),
238 compare_func);
239 }
240
241
242 fluid_list_t *
fluid_list_last(fluid_list_t * list)243 fluid_list_last(fluid_list_t *list)
244 {
245 if(list)
246 {
247 while(list->next)
248 {
249 list = list->next;
250 }
251 }
252
253 return list;
254 }
255
256 int
fluid_list_size(fluid_list_t * list)257 fluid_list_size(fluid_list_t *list)
258 {
259 int n = 0;
260
261 while(list)
262 {
263 n++;
264 list = list->next;
265 }
266
267 return n;
268 }
269
fluid_list_insert_at(fluid_list_t * list,int n,void * data)270 fluid_list_t *fluid_list_insert_at(fluid_list_t *list, int n, void *data)
271 {
272 fluid_list_t *new_list;
273 fluid_list_t *cur;
274 fluid_list_t *prev = NULL;
275
276 new_list = new_fluid_list();
277 new_list->data = data;
278
279 cur = list;
280
281 while((n-- > 0) && cur)
282 {
283 prev = cur;
284 cur = cur->next;
285 }
286
287 new_list->next = cur;
288
289 if(prev)
290 {
291 prev->next = new_list;
292 return list;
293 }
294 else
295 {
296 return new_list;
297 }
298 }
299
300 /* Compare function to sort strings alphabetically,
301 * for use with fluid_list_sort(). */
302 int
fluid_list_str_compare_func(const void * a,const void * b)303 fluid_list_str_compare_func(const void *a, const void *b)
304 {
305 if(a && b)
306 {
307 return FLUID_STRCMP(a, b);
308 }
309
310 if(!a && !b)
311 {
312 return 0;
313 }
314
315 if(a)
316 {
317 return -1;
318 }
319
320 return 1;
321 }
322
fluid_list_idx(fluid_list_t * list,void * data)323 int fluid_list_idx(fluid_list_t *list, void *data)
324 {
325 int i = 0;
326
327 while(list)
328 {
329 if (list->data == data)
330 {
331 return i;
332 }
333 list = list->next;
334 }
335
336 return -1;
337 }
338