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