Bug Summary

File:build-analysis/../src/lib/xmmstypes/xmmsv_list.c
Warning:line 87, column 3
Use of memory after it is freed

Annotated Source Code

1/* XMMS2 - X Music Multiplexer System
2 * Copyright (C) 2003-2017 XMMS2 Team
3 *
4 * PLUGINS ARE NOT CONSIDERED TO BE DERIVED WORK !!!
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library 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 * Lesser General Public License for more details.
15 */
16
17#include <stdlib.h>
18#include <string.h>
19
20#include <xmmscpriv/xmmsv.h>
21#include <xmmscpriv/xmms_list.h>
22
23#include <xmmsc/xmmsv.h>
24
25struct xmmsv_list_iter_St {
26 xmmsv_list_internal_t *parent;
27 int position;
28};
29
30struct xmmsv_list_internal_St {
31 xmmsv_t **list;
32 xmmsv_t *parent_value;
33 int size;
34 int allocated;
35 bool_Bool restricted;
36 xmmsv_type_t restricttype;
37 x_list_t *iterators;
38};
39
40static void _xmmsv_list_iter_free (xmmsv_list_iter_t *it);
41
42static int
43_xmmsv_list_position_normalize (int *pos, int size, int allow_append)
44{
45 x_return_val_if_fail (size >= 0, 0)if (!(size >= 0)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "size >= 0", __FUNCTION__
, "../src/lib/xmmstypes/xmmsv_list.c", 45); return (0); }
;
46
47 if (*pos < 0) {
48 if (-*pos > size)
49 return 0;
50 *pos = size + *pos;
51 }
52
53 if (*pos > size)
54 return 0;
55
56 if (!allow_append && *pos == size)
57 return 0;
58
59 return 1;
60}
61
62static xmmsv_list_internal_t *
63_xmmsv_list_new (void)
64{
65 xmmsv_list_internal_t *list;
66
67 list = x_new0 (xmmsv_list_internal_t, 1)calloc (1, sizeof (xmmsv_list_internal_t) * (1));
68 if (!list) {
69 x_oom ()xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL, "Out of memory in %s at %s:%d"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 69)
;
70 return NULL((void*)0);
71 }
72
73 /* list is all empty for now! */
74
75 return list;
76}
77
78void
79_xmmsv_list_free (xmmsv_list_internal_t *l)
80{
81 xmmsv_list_iter_t *it;
82 int i;
83
84 /* free iterators */
85 while (l->iterators) {
1
Loop condition is true. Entering loop body
5
Loop condition is true. Entering loop body
86 it = (xmmsv_list_iter_t *) l->iterators->data;
87 _xmmsv_list_iter_free (it);
2
Calling '_xmmsv_list_iter_free'
4
Returning; memory was released via 1st parameter
6
Use of memory after it is freed
88 }
89
90 /* unref contents */
91 for (i = 0; i < l->size; i++) {
92 xmmsv_unref (l->list[i]);
93 }
94
95 free (l->list);
96 free (l);
97}
98
99static int
100_xmmsv_list_resize (xmmsv_list_internal_t *l, int newsize)
101{
102 xmmsv_t **newmem;
103
104 newmem = realloc (l->list, newsize * sizeof (xmmsv_t *));
105
106 if (newsize != 0 && newmem == NULL((void*)0)) {
107 x_oom ()xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL, "Out of memory in %s at %s:%d"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 107)
;
108 return 0;
109 }
110
111 l->list = newmem;
112 l->allocated = newsize;
113
114 return 1;
115}
116
117static int
118_xmmsv_list_insert (xmmsv_list_internal_t *l, int pos, xmmsv_t *val)
119{
120 xmmsv_list_iter_t *it;
121 x_list_t *n;
122
123 if (!_xmmsv_list_position_normalize (&pos, l->size, 1)) {
124 return 0;
125 }
126
127 if (l->restricted) {
128 x_return_val_if_fail (xmmsv_is_type (val, l->restricttype), 0)if (!(xmmsv_is_type (val, l->restricttype))) { xmmsc_log (
"xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d"
, "xmmsv_is_type (val, l->restricttype)", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 128); return (0); }
;
129 }
130
131 /* We need more memory, reallocate */
132 if (l->size == l->allocated) {
133 int success;
134 size_t double_size;
135 if (l->allocated > 0) {
136 double_size = l->allocated << 1;
137 } else {
138 double_size = 1;
139 }
140 success = _xmmsv_list_resize (l, double_size);
141 x_return_val_if_fail (success, 0)if (!(success)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "success", __FUNCTION__
, "../src/lib/xmmstypes/xmmsv_list.c", 141); return (0); }
;
142 }
143
144 /* move existing items out of the way */
145 if (l->size > pos) {
146 memmove (l->list + pos + 1, l->list + pos,
147 (l->size - pos) * sizeof (xmmsv_t *));
148 }
149
150 l->list[pos] = xmmsv_ref (val);
151 l->size++;
152
153 /* update iterators pos */
154 for (n = l->iterators; n; n = n->next) {
155 it = (xmmsv_list_iter_t *) n->data;
156 if (it->position > pos) {
157 it->position++;
158 }
159 }
160
161 return 1;
162}
163
164static int
165_xmmsv_list_append (xmmsv_list_internal_t *l, xmmsv_t *val)
166{
167 return _xmmsv_list_insert (l, l->size, val);
168}
169
170static int
171_xmmsv_list_remove (xmmsv_list_internal_t *l, int pos)
172{
173 xmmsv_list_iter_t *it;
174 int half_size;
175 x_list_t *n;
176
177 /* prevent removing after the last element */
178 if (!_xmmsv_list_position_normalize (&pos, l->size, 0)) {
179 return 0;
180 }
181
182 xmmsv_unref (l->list[pos]);
183
184 l->size--;
185
186 /* fill the gap */
187 if (pos < l->size) {
188 memmove (l->list + pos, l->list + pos + 1,
189 (l->size - pos) * sizeof (xmmsv_t *));
190 }
191
192 /* Reduce memory usage by two if possible */
193 half_size = l->allocated >> 1;
194 if (l->size <= half_size) {
195 int success;
196 success = _xmmsv_list_resize (l, half_size);
197 x_return_val_if_fail (success, 0)if (!(success)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "success", __FUNCTION__
, "../src/lib/xmmstypes/xmmsv_list.c", 197); return (0); }
;
198 }
199
200 /* update iterator pos */
201 for (n = l->iterators; n; n = n->next) {
202 it = (xmmsv_list_iter_t *) n->data;
203 if (it->position > pos) {
204 it->position--;
205 }
206 }
207
208 return 1;
209}
210
211static int
212_xmmsv_list_move (xmmsv_list_internal_t *l, int old_pos, int new_pos)
213{
214 xmmsv_t *v;
215 xmmsv_list_iter_t *it;
216 x_list_t *n;
217
218 if (!_xmmsv_list_position_normalize (&old_pos, l->size, 0)) {
219 return 0;
220 }
221 if (!_xmmsv_list_position_normalize (&new_pos, l->size, 0)) {
222 return 0;
223 }
224
225 v = l->list[old_pos];
226 if (old_pos < new_pos) {
227 memmove (l->list + old_pos, l->list + old_pos + 1,
228 (new_pos - old_pos) * sizeof (xmmsv_t *));
229 l->list[new_pos] = v;
230
231 /* update iterator pos */
232 for (n = l->iterators; n; n = n->next) {
233 it = (xmmsv_list_iter_t *) n->data;
234 if (it->position >= old_pos && it->position <= new_pos) {
235 if (it->position == old_pos) {
236 it->position = new_pos;
237 } else {
238 it->position--;
239 }
240 }
241 }
242 } else {
243 memmove (l->list + new_pos + 1, l->list + new_pos,
244 (old_pos - new_pos) * sizeof (xmmsv_t *));
245 l->list[new_pos] = v;
246
247 /* update iterator pos */
248 for (n = l->iterators; n; n = n->next) {
249 it = (xmmsv_list_iter_t *) n->data;
250 if (it->position >= new_pos && it->position <= old_pos) {
251 if (it->position == old_pos) {
252 it->position = new_pos;
253 } else {
254 it->position++;
255 }
256 }
257 }
258 }
259
260 return 1;
261}
262
263static void
264_xmmsv_list_clear (xmmsv_list_internal_t *l)
265{
266 xmmsv_list_iter_t *it;
267 x_list_t *n;
268 int i;
269
270 /* unref all stored values */
271 for (i = 0; i < l->size; i++) {
272 xmmsv_unref (l->list[i]);
273 }
274
275 /* free list, declare empty */
276 free (l->list);
277 l->list = NULL((void*)0);
278
279 l->size = 0;
280 l->allocated = 0;
281
282 /* reset iterator pos */
283 for (n = l->iterators; n; n = n->next) {
284 it = (xmmsv_list_iter_t *) n->data;
285 it->position = 0;
286 }
287}
288
289static void
290_xmmsv_list_sort (xmmsv_list_internal_t *l, xmmsv_list_compare_func_t comparator)
291{
292 qsort (l->list, l->size, sizeof (xmmsv_t *),
293 (int (*)(const void *, const void *)) comparator);
294}
295
296/**
297 * Allocates a new list #xmmsv_t.
298 * @return The new #xmmsv_t. Must be unreferenced with
299 * #xmmsv_unref.
300 */
301xmmsv_t *
302xmmsv_new_list (void)
303{
304 xmmsv_t *val = _xmmsv_new (XMMSV_TYPE_LIST);
305
306 if (val) {
307 val->value.list = _xmmsv_list_new ();
308 val->value.list->parent_value = val;
309 }
310
311 return val;
312}
313
314/**
315 * Get the element at the given position in the list #xmmsv_t. This
316 * function does not increase the refcount of the element, the
317 * reference is still owned by the list.
318 *
319 * @param listv A #xmmsv_t containing a list.
320 * @param pos The position in the list. If negative, start counting
321 * from the end (-1 is the last element, etc).
322 * @param val Pointer set to a borrowed reference to the element at
323 * the given position in the list.
324 * @return 1 upon success otherwise 0
325 */
326int
327xmmsv_list_get (xmmsv_t *listv, int pos, xmmsv_t **val)
328{
329 xmmsv_list_internal_t *l;
330
331 x_return_val_if_fail (listv, 0)if (!(listv)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "listv", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 331); return (0); }
;
332 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0)if (!(xmmsv_is_type (listv, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (listv, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 332); return
(0); }
;
333
334 l = listv->value.list;
335
336 /* prevent accessing after the last element */
337 if (!_xmmsv_list_position_normalize (&pos, l->size, 0)) {
338 return 0;
339 }
340
341 if (val) {
342 *val = l->list[pos];
343 }
344
345 return 1;
346}
347
348/**
349 * Set the element at the given position in the list #xmmsv_t.
350 *
351 * @param listv A #xmmsv_t containing a list.
352 * @param pos The position in the list. If negative, start counting
353 * from the end (-1 is the last element, etc).
354 * @param val The element to put at the given position in the list.
355 * @return 1 upon success otherwise 0
356 */
357int
358xmmsv_list_set (xmmsv_t *listv, int pos, xmmsv_t *val)
359{
360 xmmsv_t *old_val;
361 xmmsv_list_internal_t *l;
362
363 x_return_val_if_fail (listv, 0)if (!(listv)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "listv", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 363); return (0); }
;
364 x_return_val_if_fail (val, 0)if (!(val)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "val", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 364); return (0); }
;
365 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0)if (!(xmmsv_is_type (listv, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (listv, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 365); return
(0); }
;
366
367 l = listv->value.list;
368
369 if (!_xmmsv_list_position_normalize (&pos, l->size, 0)) {
370 return 0;
371 }
372
373 old_val = l->list[pos];
374 l->list[pos] = xmmsv_ref (val);
375 xmmsv_unref (old_val);
376
377 return 1;
378}
379
380/**
381 * Insert an element at the given position in the list #xmmsv_t.
382 * The list will hold a reference to the element until it's removed.
383 *
384 * @param listv A #xmmsv_t containing a list.
385 * @param pos The position in the list. If negative, start counting
386 * from the end (-1 is the last element, etc).
387 * @param val The element to insert.
388 * @return 1 upon success otherwise 0
389 */
390int
391xmmsv_list_insert (xmmsv_t *listv, int pos, xmmsv_t *val)
392{
393 x_return_val_if_fail (listv, 0)if (!(listv)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "listv", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 393); return (0); }
;
394 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0)if (!(xmmsv_is_type (listv, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (listv, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 394); return
(0); }
;
395 x_return_val_if_fail (val, 0)if (!(val)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "val", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 395); return (0); }
;
396
397 return _xmmsv_list_insert (listv->value.list, pos, val);
398}
399
400/**
401 * Remove the element at the given position from the list #xmmsv_t.
402 *
403 * @param listv A #xmmsv_t containing a list.
404 * @param pos The position in the list. If negative, start counting
405 * from the end (-1 is the last element, etc).
406 * @return 1 upon success otherwise 0
407 */
408int
409xmmsv_list_remove (xmmsv_t *listv, int pos)
410{
411 x_return_val_if_fail (listv, 0)if (!(listv)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "listv", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 411); return (0); }
;
412 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0)if (!(xmmsv_is_type (listv, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (listv, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 412); return
(0); }
;
413
414 return _xmmsv_list_remove (listv->value.list, pos);
415}
416
417/**
418 * Move the element from position #old to position #new.
419 *
420 * #xmmsv_list_iter_t's remain pointing at their element (which might or might
421 * not be at a different position).
422 *
423 * @param listv A #xmmsv_t containing a list
424 * @param old The original position in the list. If negative, start counting
425 * from the end (-1 is the last element, etc.)
426 * @param new The new position in the list. If negative start counting from the
427 * end (-1 is the last element, etc.) For the sake of counting the
428 * element to be moved is still at its old position.
429 * @return 1 upon success otherwise 0
430 */
431int
432xmmsv_list_move (xmmsv_t *listv, int old_pos, int new_pos)
433{
434 x_return_val_if_fail (listv, 0)if (!(listv)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "listv", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 434); return (0); }
;
435 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0)if (!(xmmsv_is_type (listv, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (listv, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 435); return
(0); }
;
436
437 return _xmmsv_list_move (listv->value.list, old_pos, new_pos);
438}
439
440/**
441 * Append an element to the end of the list #xmmsv_t.
442 * The list will hold a reference to the element until it's removed.
443 *
444 * @param listv A #xmmsv_t containing a list.
445 * @param val The element to append.
446 * @return 1 upon success otherwise 0
447 */
448int
449xmmsv_list_append (xmmsv_t *listv, xmmsv_t *val)
450{
451 x_return_val_if_fail (listv, 0)if (!(listv)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "listv", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 451); return (0); }
;
452 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0)if (!(xmmsv_is_type (listv, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (listv, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 452); return
(0); }
;
453 x_return_val_if_fail (val, 0)if (!(val)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "val", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 453); return (0); }
;
454
455 return _xmmsv_list_append (listv->value.list, val);
456}
457
458/**
459 * Empty the list from all its elements.
460 *
461 * @param listv A #xmmsv_t containing a list.
462 * @return 1 upon success otherwise 0
463 */
464int
465xmmsv_list_clear (xmmsv_t *listv)
466{
467 x_return_val_if_fail (listv, 0)if (!(listv)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "listv", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 467); return (0); }
;
468 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0)if (!(xmmsv_is_type (listv, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (listv, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 468); return
(0); }
;
469
470 _xmmsv_list_clear (listv->value.list);
471
472 return 1;
473}
474
475/**
476 * Sort the list using the supplied comparator.
477 *
478 * @param listv A #xmmsv_t containing a list.
479 * @return 1 upon success otherwise 0
480 */
481int
482xmmsv_list_sort (xmmsv_t *listv, xmmsv_list_compare_func_t comparator)
483{
484 x_return_val_if_fail (comparator, 0)if (!(comparator)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "comparator", __FUNCTION__
, "../src/lib/xmmstypes/xmmsv_list.c", 484); return (0); }
;
485 x_return_val_if_fail (listv, 0)if (!(listv)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "listv", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 485); return (0); }
;
486 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0)if (!(xmmsv_is_type (listv, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (listv, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 486); return
(0); }
;
487
488 _xmmsv_list_sort (listv->value.list, comparator);
489
490 return 1;
491}
492
493/**
494 * Apply a function to each element in the list, in sequential order.
495 *
496 * @param listv A #xmmsv_t containing a list.
497 * @param function The function to apply to each element.
498 * @param user_data User data passed to the foreach function.
499 * @return 1 upon success otherwise 0
500 */
501int
502xmmsv_list_foreach (xmmsv_t *listv, xmmsv_list_foreach_func func,
503 void* user_data)
504{
505 xmmsv_list_iter_t *it;
506 xmmsv_t *v;
507
508 x_return_val_if_fail (listv, 0)if (!(listv)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "listv", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 508); return (0); }
;
509 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0)if (!(xmmsv_is_type (listv, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (listv, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 509); return
(0); }
;
510 x_return_val_if_fail (xmmsv_get_list_iter (listv, &it), 0)if (!(xmmsv_get_list_iter (listv, &it))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_get_list_iter (listv, &it)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 510); return
(0); }
;
511
512 while (xmmsv_list_iter_entry (it, &v)) {
513 func (v, user_data);
514 xmmsv_list_iter_next (it);
515 }
516
517 _xmmsv_list_iter_free (it);
518
519 return 1;
520}
521
522/**
523 * Return the size of the list.
524 *
525 * @param listv The #xmmsv_t containing the list.
526 * @return The size of the list, or -1 if listv is invalid.
527 */
528int
529xmmsv_list_get_size (xmmsv_t *listv)
530{
531 x_return_val_if_fail (listv, -1)if (!(listv)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "listv", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 531); return (-1); }
;
532 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), -1)if (!(xmmsv_is_type (listv, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (listv, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 532); return
(-1); }
;
533
534 return listv->value.list->size;
535}
536
537
538int
539xmmsv_list_restrict_type (xmmsv_t *listv, xmmsv_type_t type)
540{
541 x_return_val_if_fail (xmmsv_list_has_type (listv, type), 0)if (!(xmmsv_list_has_type (listv, type))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_list_has_type (listv, type)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 541); return
(0); }
;
542 x_return_val_if_fail (!listv->value.list->restricted ||if (!(!listv->value.list->restricted || listv->value
.list->restricttype == type)) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "!listv->value.list->restricted || listv->value.list->restricttype == type"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 543); return
(0); }
543 listv->value.list->restricttype == type, 0)if (!(!listv->value.list->restricted || listv->value
.list->restricttype == type)) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "!listv->value.list->restricted || listv->value.list->restricttype == type"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 543); return
(0); }
;
544
545 listv->value.list->restricted = true1;
546 listv->value.list->restricttype = type;
547
548 return 1;
549}
550
551/**
552 * Gets the current type restriction of a list.
553 *
554 * @param listv The list to Check
555 * @return the xmmsv_type_t of the restricted type, or XMMSV_TYPE_NONE if no restriction.
556 */
557int
558xmmsv_list_get_type (xmmsv_t *listv, xmmsv_type_t *type)
559{
560 x_return_val_if_fail (listv, false)if (!(listv)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "listv", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 560); return (0); }
;
561 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), false)if (!(xmmsv_is_type (listv, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (listv, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 561); return
(0); }
;
562 if (listv->value.list->restricted) {
563 *type = listv->value.list->restricttype;
564 } else {
565 *type = XMMSV_TYPE_NONE;
566 }
567 return true1;
568}
569
570/**
571 * Checks if all elements in the list has the given type
572 *
573 * @param listv The list to check
574 * @param type The type to check for
575 * @return non-zero if all elements in the list has the type, 0 otherwise
576 */
577int
578xmmsv_list_has_type (xmmsv_t *listv, xmmsv_type_t type)
579{
580 xmmsv_list_iter_t *it;
581 xmmsv_t *v;
582
583 x_return_val_if_fail (listv, 0)if (!(listv)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "listv", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 583); return (0); }
;
584 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), 0)if (!(xmmsv_is_type (listv, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (listv, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 584); return
(0); }
;
585
586 if (listv->value.list->restricted)
587 return listv->value.list->restricttype == type;
588
589 x_return_val_if_fail (xmmsv_get_list_iter (listv, &it), 0)if (!(xmmsv_get_list_iter (listv, &it))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_get_list_iter (listv, &it)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 589); return
(0); }
;
590 while (xmmsv_list_iter_entry (it, &v)) {
591 if (!xmmsv_is_type (v, type)) {
592 _xmmsv_list_iter_free (it);
593 return 0;
594 }
595 xmmsv_list_iter_next (it);
596 }
597
598 _xmmsv_list_iter_free (it);
599
600 return 1;
601}
602
603/**
604 * Get the index of an element in the list. This function compares the
605 * pointers and not the actual values contained in the elements.
606 *
607 * @param listv The #xmmsv_t containing the list
608 * @param val The element to find
609 * @return The index of the element if found, -1 otherwise
610 */
611int
612xmmsv_list_index_of (xmmsv_t *listv, xmmsv_t *val)
613{
614 xmmsv_list_iter_t *it;
615 xmmsv_t *v;
616 int i = 0, ret = -1;
617
618 x_return_val_if_fail (listv, -1)if (!(listv)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "listv", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 618); return (-1); }
;
619 x_return_val_if_fail (xmmsv_is_type (listv, XMMSV_TYPE_LIST), -1)if (!(xmmsv_is_type (listv, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (listv, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 619); return
(-1); }
;
620
621 if (!xmmsv_get_list_iter (listv, &it))
622 return -1;
623
624 while (xmmsv_list_iter_entry (it, &v)) {
625 if (v == val) {
626 ret = i;
627 break;
628 }
629 xmmsv_list_iter_next (it);
630 i++;
631 }
632
633 xmmsv_list_iter_explicit_destroy (it);
634
635 return ret;
636}
637
638static xmmsv_list_iter_t *
639_xmmsv_list_iter_new (xmmsv_list_internal_t *l)
640{
641 xmmsv_list_iter_t *it;
642
643 it = x_new0 (xmmsv_list_iter_t, 1)calloc (1, sizeof (xmmsv_list_iter_t) * (1));
644 if (!it) {
645 x_oom ()xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL, "Out of memory in %s at %s:%d"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 645)
;
646 return NULL((void*)0);
647 }
648
649 it->parent = l;
650 it->position = 0;
651
652 /* register iterator into parent */
653 l->iterators = x_list_prepend (l->iterators, it);
654
655 return it;
656}
657
658/**
659 * Retrieves a list iterator from a list #xmmsv_t.
660 *
661 * @param val a #xmmsv_t containing a list.
662 * @param it An #xmmsv_list_iter_t that can be used to access the list
663 * data. The iterator will be freed when the value is freed.
664 * @return 1 upon success otherwise 0
665 */
666int
667xmmsv_get_list_iter (const xmmsv_t *val, xmmsv_list_iter_t **it)
668{
669 xmmsv_list_iter_t *new_it;
670
671 if (!val || val->type != XMMSV_TYPE_LIST) {
672 *it = NULL((void*)0);
673 return 0;
674 }
675
676 new_it = _xmmsv_list_iter_new (val->value.list);
677 if (!new_it) {
678 *it = NULL((void*)0);
679 return 0;
680 }
681
682 *it = new_it;
683
684 return 1;
685}
686
687static void
688_xmmsv_list_iter_free (xmmsv_list_iter_t *it)
689{
690 /* unref iterator from list and free it */
691 it->parent->iterators = x_list_remove (it->parent->iterators, it);
692 free (it);
3
Memory is released
693}
694
695/**
696 * Explicitly free list iterator.
697 *
698 * Immediately frees any resources used by this iterator. The iterator
699 * is freed automatically when the list is freed, but this function is
700 * useful when the list can be long lived.
701 *
702 * @param it iterator to free
703 *
704 */
705void
706xmmsv_list_iter_explicit_destroy (xmmsv_list_iter_t *it)
707{
708 _xmmsv_list_iter_free (it);
709}
710
711/**
712 * Get the element currently pointed at by the iterator. This function
713 * does not increase the refcount of the element, the reference is
714 * still owned by the list. If iterator does not point on a valid
715 * element xmmsv_list_iter_entry returns 0 and leaves val untouched.
716 *
717 * @param it A #xmmsv_list_iter_t.
718 * @param val Pointer set to a borrowed reference to the element
719 * pointed at by the iterator.
720 * @return 1 upon success otherwise 0
721 */
722int
723xmmsv_list_iter_entry (xmmsv_list_iter_t *it, xmmsv_t **val)
724{
725 if (!xmmsv_list_iter_valid (it))
726 return 0;
727
728 *val = it->parent->list[it->position];
729
730 return 1;
731}
732
733/**
734 * Check whether the iterator is valid and points to a valid element.
735 *
736 * @param it A #xmmsv_list_iter_t.
737 * @return 1 if the iterator is valid, 0 otherwise
738 */
739int
740xmmsv_list_iter_valid (xmmsv_list_iter_t *it)
741{
742 return it && (it->position < it->parent->size) && (it->position >= 0);
743}
744
745/**
746 * Rewind the iterator to the start of the list.
747 *
748 * @param it A #xmmsv_list_iter_t.
749 */
750void
751xmmsv_list_iter_first (xmmsv_list_iter_t *it)
752{
753 x_return_if_fail (it)if (!(it)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "it", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 753); return; }
;
754
755 it->position = 0;
756}
757
758/**
759 * Move the iterator to end of the list.
760 *
761 * @param listv A #xmmsv_list_iter_t.
762 */
763void
764xmmsv_list_iter_last (xmmsv_list_iter_t *it)
765{
766 x_return_if_fail (it)if (!(it)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "it", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 766); return; }
;
767
768 if (it->parent->size > 0) {
769 it->position = it->parent->size - 1;
770 } else {
771 it->position = it->parent->size;
772 }
773}
774
775/**
776 * Advance the iterator to the next element in the list.
777 *
778 * @param it A #xmmsv_list_iter_t.
779 */
780void
781xmmsv_list_iter_next (xmmsv_list_iter_t *it)
782{
783 x_return_if_fail (it)if (!(it)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "it", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 783); return; }
;
784
785 if (it->position < it->parent->size) {
786 it->position++;
787 }
788}
789
790/**
791 * Move the iterator to the previous element in the list.
792 *
793 * @param listv A #xmmsv_list_iter_t.
794 */
795void
796xmmsv_list_iter_prev (xmmsv_list_iter_t *it)
797{
798 x_return_if_fail (it)if (!(it)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "it", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 798); return; }
;
799
800 if (it->position >= 0) {
801 it->position--;
802 }
803}
804
805
806/**
807 * Move the iterator to the n-th element in the list.
808 *
809 * @param it A #xmmsv_list_iter_t.
810 * @param pos The position in the list. If negative, start counting
811 * from the end (-1 is the last element, etc).
812 * @return 1 upon success otherwise 0
813 */
814int
815xmmsv_list_iter_seek (xmmsv_list_iter_t *it, int pos)
816{
817 x_return_val_if_fail (it, 0)if (!(it)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "it", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 817); return (0); }
;
818
819 if (!_xmmsv_list_position_normalize (&pos, it->parent->size, 1)) {
820 return 0;
821 }
822 it->position = pos;
823
824 return 1;
825}
826
827/**
828 * Tell the position of the iterator.
829 *
830 * @param it A #xmmsv_list_iter_t.
831 * @return The position of the iterator, or -1 if invalid.
832 */
833int
834xmmsv_list_iter_tell (const xmmsv_list_iter_t *it)
835{
836 x_return_val_if_fail (it, -1)if (!(it)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "it", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 836); return (-1); }
;
837
838 return it->position;
839}
840
841/**
842 * Return the parent #xmmsv_t of an iterator.
843 *
844 * @param it A #xmmsv_list_iter_t.
845 * @return The parent #xmmsv_t of the iterator, or NULL if invalid.
846 */
847xmmsv_t*
848xmmsv_list_iter_get_parent (const xmmsv_list_iter_t *it)
849{
850 x_return_val_if_fail (it, NULL)if (!(it)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "it", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 850); return (((void*)0)); }
;
851
852 return it->parent->parent_value;
853}
854
855/**
856 * Replace an element in the list at the position pointed at by the
857 * iterator.
858 *
859 * @param it A #xmmsv_list_iter_t.
860 * @param val The element to insert.
861 * @return 1 upon success otherwise 0
862 */
863int
864xmmsv_list_iter_set (xmmsv_list_iter_t *it, xmmsv_t *val)
865{
866 x_return_val_if_fail (it, 0)if (!(it)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "it", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 866); return (0); }
;
867 x_return_val_if_fail (val, 0)if (!(val)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "val", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 867); return (0); }
;
868
869 return xmmsv_list_set (it->parent->parent_value, it->position, val);
870}
871
872/**
873 * Insert an element in the list at the position pointed at by the
874 * iterator.
875 *
876 * @param it A #xmmsv_list_iter_t.
877 * @param val The element to insert.
878 * @return 1 upon success otherwise 0
879 */
880int
881xmmsv_list_iter_insert (xmmsv_list_iter_t *it, xmmsv_t *val)
882{
883 x_return_val_if_fail (it, 0)if (!(it)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "it", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 883); return (0); }
;
884 x_return_val_if_fail (val, 0)if (!(val)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "val", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 884); return (0); }
;
885
886 return _xmmsv_list_insert (it->parent, it->position, val);
887}
888
889/**
890 * Remove the element in the list at the position pointed at by the
891 * iterator.
892 *
893 * @param it A #xmmsv_list_iter_t.
894 * @return 1 upon success otherwise 0
895 */
896int
897xmmsv_list_iter_remove (xmmsv_list_iter_t *it)
898{
899 x_return_val_if_fail (it, 0)if (!(it)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "it", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 899); return (0); }
;
900
901 return _xmmsv_list_remove (it->parent, it->position);
902}
903
904static int
905_xmmsv_list_flatten (xmmsv_t *list, xmmsv_t *result, int depth)
906{
907 xmmsv_list_iter_t *it;
908 xmmsv_t *val;
909 int ret = 1;
910
911 x_return_val_if_fail (xmmsv_is_type (list, XMMSV_TYPE_LIST), 0)if (!(xmmsv_is_type (list, XMMSV_TYPE_LIST))) { xmmsc_log ("xmmsc/xmmstypes"
, XMMS_LOG_LEVEL_FAIL, "Check '%s' failed in %s at %s:%d", "xmmsv_is_type (list, XMMSV_TYPE_LIST)"
, __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c", 911); return
(0); }
;
912
913 for (xmmsv_get_list_iter (list, &it);
914 xmmsv_list_iter_entry (it, &val) && ret;
915 xmmsv_list_iter_next (it)) {
916 if (depth == 0) {
917 xmmsv_list_append (result, val);
918 } else {
919 ret = _xmmsv_list_flatten (val, result, depth - 1);
920 }
921 }
922
923 return ret;
924}
925
926/**
927 * Flattens a list of lists.
928 *
929 * @param list The list to flatten
930 * @param depth The level of lists to flatten.
931 * @return A new flattened list, or NULL on error.
932 */
933xmmsv_t *
934xmmsv_list_flatten (xmmsv_t *list, int depth)
935{
936 x_return_val_if_fail (list, NULL)if (!(list)) { xmmsc_log ("xmmsc/xmmstypes", XMMS_LOG_LEVEL_FAIL
, "Check '%s' failed in %s at %s:%d", "list", __FUNCTION__, "../src/lib/xmmstypes/xmmsv_list.c"
, 936); return (((void*)0)); }
;
937 xmmsv_t *result = xmmsv_new_list ();
938
939 if (!_xmmsv_list_flatten (list, result, depth)) {
940 xmmsv_unref (result);
941 return NULL((void*)0);
942 }
943
944 return result;
945}
946
947/* macro-magically define list extractors */
948#define GEN_LIST_EXTRACTOR_FUNC(typename, type)int xmmsv_list_get_typename (xmmsv_t *val, int pos, type *r) {
xmmsv_t *v; if (!xmmsv_list_get (val, pos, &v)) { return
0; } return xmmsv_get_typename (v, r); }
\
949 int \
950 xmmsv_list_get_##typename (xmmsv_t *val, int pos, type *r) \
951 { \
952 xmmsv_t *v; \
953 if (!xmmsv_list_get (val, pos, &v)) { \
954 return 0; \
955 } \
956 return xmmsv_get_##typename (v, r); \
957 }
958
959GEN_LIST_EXTRACTOR_FUNC (string, const char *)int xmmsv_list_get_string (xmmsv_t *val, int pos, const char *
*r) { xmmsv_t *v; if (!xmmsv_list_get (val, pos, &v)) { return
0; } return xmmsv_get_string (v, r); }
960GEN_LIST_EXTRACTOR_FUNC (int32, int32_t)int xmmsv_list_get_int32 (xmmsv_t *val, int pos, int32_t *r) {
xmmsv_t *v; if (!xmmsv_list_get (val, pos, &v)) { return
0; } return xmmsv_get_int32 (v, r); }
961GEN_LIST_EXTRACTOR_FUNC (int64, int64_t)int xmmsv_list_get_int64 (xmmsv_t *val, int pos, int64_t *r) {
xmmsv_t *v; if (!xmmsv_list_get (val, pos, &v)) { return
0; } return xmmsv_get_int64 (v, r); }
962GEN_LIST_EXTRACTOR_FUNC (float, float)int xmmsv_list_get_float (xmmsv_t *val, int pos, float *r) { xmmsv_t
*v; if (!xmmsv_list_get (val, pos, &v)) { return 0; } return
xmmsv_get_float (v, r); }
963
964int
965xmmsv_list_get_coll (xmmsv_t *val, int pos, xmmsv_t **r)
966{
967 return xmmsv_list_get (val, pos, r);
968}
969
970/* macro-magically define list set functions */
971#define GEN_LIST_SET_FUNC(typename, type)int xmmsv_list_set_typename (xmmsv_t *list, int pos, type elem
) { int ret; xmmsv_t *v; v = xmmsv_new_typename (elem); ret =
xmmsv_list_set (list, pos, v); xmmsv_unref (v); return ret; }
\
972 int \
973 xmmsv_list_set_##typename (xmmsv_t *list, int pos, type elem) \
974 { \
975 int ret; \
976 xmmsv_t *v; \
977 \
978 v = xmmsv_new_##typename (elem); \
979 ret = xmmsv_list_set (list, pos, v); \
980 xmmsv_unref (v); \
981 \
982 return ret; \
983 }
984
985GEN_LIST_SET_FUNC (string, const char *)int xmmsv_list_set_string (xmmsv_t *list, int pos, const char
* elem) { int ret; xmmsv_t *v; v = xmmsv_new_string (elem); ret
= xmmsv_list_set (list, pos, v); xmmsv_unref (v); return ret
; }
986GEN_LIST_SET_FUNC (int, int64_t)int xmmsv_list_set_int (xmmsv_t *list, int pos, int64_t elem)
{ int ret; xmmsv_t *v; v = xmmsv_new_int (elem); ret = xmmsv_list_set
(list, pos, v); xmmsv_unref (v); return ret; }
987GEN_LIST_SET_FUNC (float, float)int xmmsv_list_set_float (xmmsv_t *list, int pos, float elem)
{ int ret; xmmsv_t *v; v = xmmsv_new_float (elem); ret = xmmsv_list_set
(list, pos, v); xmmsv_unref (v); return ret; }
988
989int
990xmmsv_list_set_coll (xmmsv_t *list, int pos, xmmsv_t *elem)
991{
992 return xmmsv_list_set (list, pos, elem);
993}
994
995/* macro-magically define list insert functions */
996#define GEN_LIST_INSERT_FUNC(typename, type)int xmmsv_list_insert_typename (xmmsv_t *list, int pos, type elem
) { int ret; xmmsv_t *v; v = xmmsv_new_typename (elem); ret =
xmmsv_list_insert (list, pos, v); xmmsv_unref (v); return ret
; }
\
997 int \
998 xmmsv_list_insert_##typename (xmmsv_t *list, int pos, type elem) \
999 { \
1000 int ret; \
1001 xmmsv_t *v; \
1002 \
1003 v = xmmsv_new_##typename (elem); \
1004 ret = xmmsv_list_insert (list, pos, v); \
1005 xmmsv_unref (v); \
1006 \
1007 return ret; \
1008 }
1009
1010GEN_LIST_INSERT_FUNC (string, const char *)int xmmsv_list_insert_string (xmmsv_t *list, int pos, const char
* elem) { int ret; xmmsv_t *v; v = xmmsv_new_string (elem); ret
= xmmsv_list_insert (list, pos, v); xmmsv_unref (v); return ret
; }
1011GEN_LIST_INSERT_FUNC (int, int64_t)int xmmsv_list_insert_int (xmmsv_t *list, int pos, int64_t elem
) { int ret; xmmsv_t *v; v = xmmsv_new_int (elem); ret = xmmsv_list_insert
(list, pos, v); xmmsv_unref (v); return ret; }
1012GEN_LIST_INSERT_FUNC (float, float)int xmmsv_list_insert_float (xmmsv_t *list, int pos, float elem
) { int ret; xmmsv_t *v; v = xmmsv_new_float (elem); ret = xmmsv_list_insert
(list, pos, v); xmmsv_unref (v); return ret; }
1013
1014int
1015xmmsv_list_insert_coll (xmmsv_t *list, int pos, xmmsv_t *elem)
1016{
1017 return xmmsv_list_insert (list, pos, elem);
1018}
1019
1020/* macro-magically define list append functions */
1021#define GEN_LIST_APPEND_FUNC(typename, type)int xmmsv_list_append_typename (xmmsv_t *list, type elem) { int
ret; xmmsv_t *v; v = xmmsv_new_typename (elem); ret = xmmsv_list_append
(list, v); xmmsv_unref (v); return ret; }
\
1022 int \
1023 xmmsv_list_append_##typename (xmmsv_t *list, type elem) \
1024 { \
1025 int ret; \
1026 xmmsv_t *v; \
1027 \
1028 v = xmmsv_new_##typename (elem); \
1029 ret = xmmsv_list_append (list, v); \
1030 xmmsv_unref (v); \
1031 \
1032 return ret; \
1033 }
1034
1035GEN_LIST_APPEND_FUNC (string, const char *)int xmmsv_list_append_string (xmmsv_t *list, const char * elem
) { int ret; xmmsv_t *v; v = xmmsv_new_string (elem); ret = xmmsv_list_append
(list, v); xmmsv_unref (v); return ret; }
1036GEN_LIST_APPEND_FUNC (int, int64_t)int xmmsv_list_append_int (xmmsv_t *list, int64_t elem) { int
ret; xmmsv_t *v; v = xmmsv_new_int (elem); ret = xmmsv_list_append
(list, v); xmmsv_unref (v); return ret; }
1037GEN_LIST_APPEND_FUNC (float, float)int xmmsv_list_append_float (xmmsv_t *list, float elem) { int
ret; xmmsv_t *v; v = xmmsv_new_float (elem); ret = xmmsv_list_append
(list, v); xmmsv_unref (v); return ret; }
1038
1039int
1040xmmsv_list_append_coll (xmmsv_t *list, xmmsv_t *elem)
1041{
1042 return xmmsv_list_append (list, elem);
1043}
1044
1045/* macro-magically define list_iter extractors */
1046#define GEN_LIST_ITER_EXTRACTOR_FUNC(typename, type)int xmmsv_list_iter_entry_typename (xmmsv_list_iter_t *it, type
*r) { xmmsv_t *v; if (!xmmsv_list_iter_entry (it, &v)) {
return 0; } return xmmsv_get_typename (v, r); }
\
1047 int \
1048 xmmsv_list_iter_entry_##typename (xmmsv_list_iter_t *it, type *r) \
1049 { \
1050 xmmsv_t *v; \
1051 if (!xmmsv_list_iter_entry (it, &v)) { \
1052 return 0; \
1053 } \
1054 return xmmsv_get_##typename (v, r); \
1055 }
1056
1057GEN_LIST_ITER_EXTRACTOR_FUNC (string, const char *)int xmmsv_list_iter_entry_string (xmmsv_list_iter_t *it, const
char * *r) { xmmsv_t *v; if (!xmmsv_list_iter_entry (it, &
v)) { return 0; } return xmmsv_get_string (v, r); }
1058GEN_LIST_ITER_EXTRACTOR_FUNC (int32, int32_t)int xmmsv_list_iter_entry_int32 (xmmsv_list_iter_t *it, int32_t
*r) { xmmsv_t *v; if (!xmmsv_list_iter_entry (it, &v)) {
return 0; } return xmmsv_get_int32 (v, r); }
1059GEN_LIST_ITER_EXTRACTOR_FUNC (int64, int64_t)int xmmsv_list_iter_entry_int64 (xmmsv_list_iter_t *it, int64_t
*r) { xmmsv_t *v; if (!xmmsv_list_iter_entry (it, &v)) {
return 0; } return xmmsv_get_int64 (v, r); }
1060GEN_LIST_ITER_EXTRACTOR_FUNC (float, float)int xmmsv_list_iter_entry_float (xmmsv_list_iter_t *it, float
*r) { xmmsv_t *v; if (!xmmsv_list_iter_entry (it, &v)) {
return 0; } return xmmsv_get_float (v, r); }
1061
1062int
1063xmmsv_list_iter_entry_coll (xmmsv_list_iter_t *it, xmmsv_t **r)
1064{
1065 return xmmsv_list_iter_entry (it, r);
1066}
1067
1068/* macro-magically define list_iter insert functions */
1069#define GEN_LIST_ITER_INSERT_FUNC(typename, type)int xmmsv_list_iter_insert_typename (xmmsv_list_iter_t *it, type
elem) { int ret; xmmsv_t *v; v = xmmsv_new_typename (elem); ret
= xmmsv_list_iter_insert (it, v); xmmsv_unref (v); return ret
; }
\
1070 int \
1071 xmmsv_list_iter_insert_##typename (xmmsv_list_iter_t *it, type elem) \
1072 { \
1073 int ret; \
1074 xmmsv_t *v; \
1075 \
1076 v = xmmsv_new_##typename (elem); \
1077 ret = xmmsv_list_iter_insert (it, v); \
1078 xmmsv_unref (v); \
1079 \
1080 return ret; \
1081 }
1082
1083GEN_LIST_ITER_INSERT_FUNC (string, const char *)int xmmsv_list_iter_insert_string (xmmsv_list_iter_t *it, const
char * elem) { int ret; xmmsv_t *v; v = xmmsv_new_string (elem
); ret = xmmsv_list_iter_insert (it, v); xmmsv_unref (v); return
ret; }
1084GEN_LIST_ITER_INSERT_FUNC (int, int64_t)int xmmsv_list_iter_insert_int (xmmsv_list_iter_t *it, int64_t
elem) { int ret; xmmsv_t *v; v = xmmsv_new_int (elem); ret =
xmmsv_list_iter_insert (it, v); xmmsv_unref (v); return ret;
}
1085GEN_LIST_ITER_INSERT_FUNC (float, float)int xmmsv_list_iter_insert_float (xmmsv_list_iter_t *it, float
elem) { int ret; xmmsv_t *v; v = xmmsv_new_float (elem); ret
= xmmsv_list_iter_insert (it, v); xmmsv_unref (v); return ret
; }
1086
1087int
1088xmmsv_list_iter_insert_coll (xmmsv_list_iter_t *it, xmmsv_t *elem)
1089{
1090 return xmmsv_list_iter_insert (it, elem);
1091}