Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
wine-mirror
GitHub Repository: wine-mirror/wine
Path: blob/master/libs/fluidsynth/src/utils/fluid_list.c
4396 views
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 *
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
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
58
delete1_fluid_list(fluid_list_t *list)
59
{
60
FLUID_FREE(list);
61
}
62
63
fluid_list_t *
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 *
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 *
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 *
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 *
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 *
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 *
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 *
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
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
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
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
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
339