Bug Summary

File:build-analysis/../src/xmms/fetchspec.c
Warning:line 410, column 32
Function call argument is an uninitialized value

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#include <xmmspriv/xmms_fetch_spec.h>
17#include <xmmspriv/xmms_fetch_info.h>
18#include <xmms/xmms_log.h>
19#include <string.h>
20#include <stdlib.h>
21
22static gboolean
23metadata_value_from_string (const gchar *name, guint32 *value)
24{
25 if (name == NULL((void*)0)) {
26 return FALSE(0);
27 } else if (strcmp (name, "id") == 0) {
28 *value = METADATA_ID;
29 } else if (strcmp (name, "field") == 0) {
30 *value = METADATA_KEY;
31 } else if (strcmp (name, "value") == 0) {
32 *value = METADATA_VALUE;
33 } else if (strcmp (name, "source") == 0) {
34 *value = METADATA_SOURCE;
35 } else {
36 return FALSE(0);
37 }
38
39 return TRUE(!(0));
40}
41
42static gboolean
43aggregate_value_from_string (const gchar *name, guint32 *value)
44{
45 if (name == NULL((void*)0)) {
46 return FALSE(0);
47 } else if (strcmp (name, "first") == 0) {
48 *value = AGGREGATE_FIRST;
49 } else if (strcmp (name, "sum") == 0) {
50 *value = AGGREGATE_SUM;
51 } else if (strcmp (name, "max") == 0) {
52 *value = AGGREGATE_MAX;
53 } else if (strcmp (name, "min") == 0) {
54 *value = AGGREGATE_MIN;
55 } else if (strcmp (name, "list") == 0) {
56 *value = AGGREGATE_LIST;
57 } else if (strcmp (name, "set") == 0) {
58 *value = AGGREGATE_SET;
59 } else if (strcmp (name, "random") == 0) {
60 *value = AGGREGATE_RANDOM;
61 } else if (strcmp (name, "avg") == 0) {
62 *value = AGGREGATE_AVG;
63 } else {
64 return FALSE(0);
65 }
66
67 return TRUE(!(0));
68}
69
70/**
71 * Sanitize the 'get' property of a 'metadata' fetch specification.
72 */
73static xmmsv_t *
74normalize_metadata_get (xmmsv_t *fetch, xmms_error_t *err)
75{
76 xmmsv_list_iter_t *it;
77 xmmsv_t *get, *list;
78 guint32 values;
79
80 if (!xmmsv_dict_get (fetch, "get", &get) ||
81 xmmsv_get_type (get) != XMMSV_TYPE_LIST ||
82 xmmsv_list_get_size (get) < 1) {
83 const gchar *message = "'get' must be a non-empty list of strings.";
84 xmms_error_set (err, XMMS_ERROR_INVAL, message);
85 return NULL((void*)0);
86 }
87
88 list = xmmsv_new_list ();
89 values = 0;
90
91 /* Scan for duplicates or invalid values */
92 xmmsv_get_list_iter (get, &it);
93 while (xmmsv_list_iter_valid (it)) {
94 const gchar *value = NULL((void*)0);
95 guint32 get_as_int, mask;
96
97 xmmsv_list_iter_entry_string (it, &value);
98
99 if (!metadata_value_from_string (value, &get_as_int)) {
100 const gchar *message = "'get' entries must be 'id', 'field', 'value' or 'source'.";
101 xmms_error_set (err, XMMS_ERROR_INVAL, message);
102 xmmsv_unref (list);
103 return NULL((void*)0);
104 }
105
106 mask = 1 << (get_as_int + 1);
107 if (values & mask) {
108 const gchar *message = "'get' entries must be unique.";
109 xmms_error_set (err, XMMS_ERROR_INVAL, message);
110 xmmsv_unref (list);
111 return NULL((void*)0);
112 }
113
114 values |= mask;
115
116 xmmsv_list_append_int (list, get_as_int);
117 xmmsv_list_iter_next (it);
118 }
119
120 return list;
121}
122
123static xmmsv_t *
124normalize_metadata_fields (xmmsv_t *fetch, xmms_error_t *err)
125{
126 gpointer SENTINEL = GINT_TO_POINTER (0x31337)((gpointer) (glong) (0x31337));
127 GHashTable *table;
128
129 xmmsv_list_iter_t *it;
130 xmmsv_t *fields;
131
132 if (!xmmsv_dict_get (fetch, "fields", &fields)) {
133 /* No fields means that we should fetch all fields */
134 return NULL((void*)0);
135 }
136
137 if (xmmsv_get_type (fields) != XMMSV_TYPE_LIST) {
138 const gchar *message = "'fields' must be a list of strings.";
139 xmms_error_set (err, XMMS_ERROR_INVAL, message);
140 return NULL((void*)0);
141 }
142
143 if (xmmsv_list_get_size (fields) < 1) {
144 /* No fields means that we should fetch all fields */
145 return NULL((void*)0);
146 }
147
148 table = g_hash_table_new (g_str_hash, g_str_equal);
149
150 xmmsv_get_list_iter (fields, &it);
151 while (xmmsv_list_iter_valid (it)) {
152 const gchar *value = NULL((void*)0);
153
154 if (!xmmsv_list_iter_entry_string (it, &value)) {
155 const gchar *message = "'fields' entries must be of string type.";
156 xmms_error_set (err, XMMS_ERROR_INVAL, message);
157 g_hash_table_unref (table);
158 return NULL((void*)0);
159 }
160
161 if (g_hash_table_lookup (table, (gpointer) value) == SENTINEL) {
162 const gchar *message = "'fields' entries must be unique.";
163 xmms_error_set (err, XMMS_ERROR_INVAL, message);
164 g_hash_table_unref (table);
165 return NULL((void*)0);
166 }
167
168 g_hash_table_insert (table, (gpointer) value, SENTINEL);
169
170 xmmsv_list_iter_next (it);
171 }
172
173 g_hash_table_unref (table);
174
175 return fields;
176}
177
178
179static s4_sourcepref_t *
180normalize_source_preferences (xmmsv_t *fetch, s4_sourcepref_t *prefs, xmms_error_t *err)
181{
182 s4_sourcepref_t *sp;
183 xmmsv_list_iter_t *it;
184 const char **strv;
185 const gchar *str;
186 xmmsv_t *list;
187 gint length, idx;
188
189 if (!xmmsv_dict_get (fetch, "source-preference", &list)) {
190 return s4_sourcepref_ref (prefs);
191 }
192
193 if (xmmsv_get_type (list) != XMMSV_TYPE_LIST) {
194 const gchar *message = "'source-preference' must be a list of strings.";
195 xmms_error_set (err, XMMS_ERROR_INVAL, message);
196 return NULL((void*)0);
197 }
198
199 length = xmmsv_list_get_size (list);
200 if (length == 0) {
201 return s4_sourcepref_ref (prefs);
202 }
203
204 strv = g_new0 (const char *, length + 1)((const char * *) g_malloc0_n ((length + 1), sizeof (const char
*)))
;
205
206 idx = 0;
207
208 xmmsv_get_list_iter (list, &it);
209 while (xmmsv_list_iter_valid (it)) {
210 if (!xmmsv_list_iter_entry_string (it, &str)) {
211 const gchar *message = "'source-preference' must be a list of strings.";
212 xmms_error_set (err, XMMS_ERROR_INVAL, message);
213 g_free (strv);
214 return NULL((void*)0);
215 }
216
217 strv[idx++] = str;
218
219 xmmsv_list_iter_next (it);
220 }
221
222 sp = s4_sourcepref_create (strv);
223 g_free (strv);
224
225 return sp;
226}
227
228static gint
229normalize_aggregate_function (xmmsv_t *fetch, xmms_error_t *err)
230{
231 const gchar *name;
232 guint32 aggregate;
233
234 if (xmmsv_dict_entry_get_type (fetch, "aggregate") == XMMSV_TYPE_NONE) {
235 xmmsv_dict_set_string (fetch, "aggregate", "first");
236 }
237
238 /* Default to first as the aggregation function */
239 if (!xmmsv_dict_entry_get_string (fetch, "aggregate", &name)) {
240 xmms_error_set (err, XMMS_ERROR_INVAL, "'aggregate' must be a string.");
241 return -1;
242 }
243
244 if (!aggregate_value_from_string (name, &aggregate)) {
245 const gchar *message = "'aggregate' must be 'first', 'sum', 'max', 'min', 'list', 'set', 'random', or 'avg'";
246 xmms_error_set (err, XMMS_ERROR_INVAL, message);
247 return -1;
248 }
249
250 return aggregate;
251}
252
253
254static xmms_fetch_spec_t *
255xmms_fetch_spec_new_metadata (xmmsv_t *fetch, xmms_fetch_info_t *info,
256 s4_sourcepref_t *prefs, xmms_error_t *err)
257{
258 xmms_fetch_spec_t *ret = NULL((void*)0);
259 s4_sourcepref_t *sp;
260 const gchar *key;
261 xmmsv_t *gets, *fields;
262 gint i, size, aggregate, get;
263
264 aggregate = normalize_aggregate_function (fetch, err);
265 if (xmms_error_iserror (err)((err)->code != XMMS_ERROR_NONE)) {
266 return NULL((void*)0);
267 }
268
269 fields = normalize_metadata_fields (fetch, err);
270 if (xmms_error_iserror (err)((err)->code != XMMS_ERROR_NONE)) {
271 return NULL((void*)0);
272 }
273
274 gets = normalize_metadata_get (fetch, err);
275 if (xmms_error_iserror (err)((err)->code != XMMS_ERROR_NONE)) {
276 return NULL((void*)0);
277 }
278
279 sp = normalize_source_preferences (fetch, prefs, err);
280 if (xmms_error_iserror (err)((err)->code != XMMS_ERROR_NONE)) {
281 xmmsv_unref (gets);
282 return NULL((void*)0);
283 }
284
285 ret = g_new0 (xmms_fetch_spec_t, 1)((xmms_fetch_spec_t *) g_malloc0_n ((1), sizeof (xmms_fetch_spec_t
)))
;
286 ret->type = FETCH_METADATA;
287 ret->data.metadata.aggr_func = aggregate;
288
289 for (i = 0; i < 4 && xmmsv_list_get_intxmmsv_list_get_int32 (gets, i, &get); i++) {
290 ret->data.metadata.get[i] = get;
291 }
292 ret->data.metadata.get_size = i;
293
294 if (fields != NULL((void*)0)) {
295 size = xmmsv_list_get_size (fields);
296 ret->data.metadata.col_count = size;
297 ret->data.metadata.cols = g_new (gint32, size)((gint32 *) g_malloc_n ((size), sizeof (gint32)));
298 for (i = 0; xmmsv_list_get_string (fields, i, &key); i++) {
299 ret->data.metadata.cols[i] = xmms_fetch_info_add_key (info, fetch, key, sp);
300 }
301 } else {
302 /* No fields requested, fetching all available */
303 ret->data.metadata.col_count = 1;
304 ret->data.metadata.cols = g_new0 (gint32, 1)((gint32 *) g_malloc0_n ((1), sizeof (gint32)));
305 ret->data.metadata.cols[0] = xmms_fetch_info_add_key (info, fetch, NULL((void*)0), sp);
306 }
307
308 s4_sourcepref_unref (sp);
309 xmmsv_unref (gets);
310
311 return ret;
312}
313
314static gboolean
315cluster_by_from_string (const gchar *name, gint *value)
316{
317 if (name == NULL((void*)0)) {
318 return FALSE(0);
319 } else if (strcmp (name, "id") == 0) {
320 *value = CLUSTER_BY_ID;
321 } else if (strcmp (name, "position") == 0) {
322 *value = CLUSTER_BY_POSITION;
323 } else if (strcmp (name, "value") == 0) {
324 *value = CLUSTER_BY_VALUE;
325 } else {
326 return FALSE(0);
327 }
328
329 return TRUE(!(0));
330}
331
332/**
333 * Decodes a cluster fetch specification from a dictionary.
334 * The 'cluster-by' must be one of 'id', 'position' or 'value'. If set
335 * to 'value', then an additional 'cluster-field' will be used to specify
336 * which meta data attribute to cluster on.
337 */
338static xmms_fetch_spec_t *
339xmms_fetch_spec_new_cluster (xmmsv_t *fetch, xmms_fetch_info_t *info,
340 s4_sourcepref_t *prefs, xmms_error_t *err)
341{
342 xmmsv_t *cluster_by, *cluster_field, *cluster_data;
37
'cluster_field' declared without an initial value
343 xmms_fetch_spec_t *data, *spec = NULL((void*)0);
344 s4_sourcepref_t *sp;
345 const gchar *value = NULL((void*)0);
346 const gchar *field = NULL((void*)0);
347 const gchar *fallback = NULL((void*)0);
348 gint cluster_type;
349
350 if (!xmmsv_dict_get (fetch, "cluster-by", &cluster_by)) {
38
Assuming the condition is false
39
Taking false branch
351 cluster_by = xmmsv_new_string ("value");
352 xmmsv_dict_set (fetch, "cluster-by", cluster_by);
353 xmmsv_unref (cluster_by);
354 }
355
356 if (!xmmsv_dict_entry_get_string (fetch, "cluster-by", &value)) {
40
Assuming the condition is false
41
Taking false branch
357 const gchar *message = "'cluster-by' must be a string.";
358 xmms_error_set (err, XMMS_ERROR_INVAL, message);
359 return NULL((void*)0);
360 }
361
362 xmmsv_get_string (cluster_by, &value);
363
364 if (!cluster_by_from_string (value, &cluster_type)) {
42
Assuming the condition is false
43
Taking false branch
365 const gchar *message = "'cluster-by' must be 'id', 'position', or 'value'.";
366 xmms_error_set (err, XMMS_ERROR_INVAL, message);
367 return NULL((void*)0);
368 }
369
370 if (cluster_type == CLUSTER_BY_VALUE) {
44
Assuming 'cluster_type' is not equal to CLUSTER_BY_VALUE
45
Taking false branch
371 if (!xmmsv_dict_entry_get_string (fetch, "cluster-field", &field)) {
372 const gchar *message = "'cluster-field' must if 'cluster-by' is 'value'.";
373 xmms_error_set (err, XMMS_ERROR_INVAL, message);
374 return NULL((void*)0);
375 }
376 }
377
378 if (!xmmsv_dict_get (fetch, "data", &cluster_data)) {
46
Assuming the condition is false
47
Taking false branch
379 const gchar *message = "Required field 'data' not set in cluster.";
380 xmms_error_set (err, XMMS_ERROR_INVAL, message);
381 return NULL((void*)0);
382 }
383
384 if (xmmsv_dict_entry_get_type (fetch, "cluster-fallback") == XMMSV_TYPE_NONE) {
48
Assuming the condition is true
49
Taking true branch
385 fallback = NULL((void*)0);
386 } else if (!xmmsv_dict_entry_get_string (fetch, "cluster-fallback", &fallback)) {
387 const gchar *message = "Optional field 'default' must be a string.";
388 xmms_error_set (err, XMMS_ERROR_INVAL, message);
389 return NULL((void*)0);
390 }
391
392 sp = normalize_source_preferences (fetch, prefs, err);
393 if (xmms_error_iserror (err)((err)->code != XMMS_ERROR_NONE)) {
50
Taking false branch
394 return NULL((void*)0);
395 }
396
397 data = xmms_fetch_spec_new (cluster_data, info, sp, err);
398 if (xmms_error_iserror (err)((err)->code != XMMS_ERROR_NONE)) {
51
Taking false branch
399 s4_sourcepref_unref (sp);
400 return NULL((void*)0);
401 }
402
403 spec = g_new0 (xmms_fetch_spec_t, 1)((xmms_fetch_spec_t *) g_malloc0_n ((1), sizeof (xmms_fetch_spec_t
)))
;
404 spec->data.cluster.data = data;
405 spec->data.cluster.type = cluster_type;
406 spec->data.cluster.fallback = fallback;
407
408 switch (spec->data.cluster.type) {
52
Control jumps to 'case CLUSTER_BY_ID:' at line 409
409 case CLUSTER_BY_ID:
410 spec->data.cluster.column = xmms_fetch_info_add_song_id(info, cluster_field);
53
Function call argument is an uninitialized value
411 break;
412 case CLUSTER_BY_VALUE:
413 xmmsv_dict_get (fetch, "cluster-field", &cluster_field);
414 spec->data.cluster.column = xmms_fetch_info_add_key (info, cluster_field,
415 field, sp);
416 break;
417 case CLUSTER_BY_POSITION:
418 /* do nothing */
419 break;
420 default:
421 g_assert_not_reached ()do { g_assertion_message_expr ("core", "../src/xmms/fetchspec.c"
, 421, ((const char*) (__func__)), ((void*)0)); } while (0)
;
422 }
423
424 s4_sourcepref_unref (sp);
425
426 return spec;
427}
428
429static xmms_fetch_spec_t *
430xmms_fetch_spec_new_cluster_list (xmmsv_t *fetch, xmms_fetch_info_t *info,
431 s4_sourcepref_t *prefs, xmms_error_t *err)
432{
433 xmms_fetch_spec_t *spec;
434
435 spec = xmms_fetch_spec_new_cluster (fetch, info, prefs, err);
36
Calling 'xmms_fetch_spec_new_cluster'
436 if (spec != NULL((void*)0))
437 spec->type = FETCH_CLUSTER_LIST;
438
439 return spec;
440}
441
442
443static xmms_fetch_spec_t *
444xmms_fetch_spec_new_cluster_dict (xmmsv_t *fetch, xmms_fetch_info_t *info,
445 s4_sourcepref_t *prefs, xmms_error_t *err)
446{
447 xmms_fetch_spec_t *spec;
448
449 spec = xmms_fetch_spec_new_cluster (fetch, info, prefs, err);
450 if (spec != NULL((void*)0))
451 spec->type = FETCH_CLUSTER_DICT;
452
453 return spec;
454}
455
456
457static xmms_fetch_spec_t *
458xmms_fetch_spec_new_organize (xmmsv_t *fetch, xmms_fetch_info_t *info,
459 s4_sourcepref_t *prefs, xmms_error_t *err)
460{
461 xmms_fetch_spec_t *spec;
462 xmmsv_dict_iter_t *it;
463 s4_sourcepref_t *sp;
464 xmmsv_t *org_data;
465 gint org_idx;
466
467 if (!xmmsv_dict_get (fetch, "data", &org_data)) {
15
Assuming the condition is false
16
Taking false branch
468 xmms_error_set (err, XMMS_ERROR_INVAL, "Required field 'data' not set in organize.");
469 return NULL((void*)0);
470 }
471
472 if (xmmsv_get_type (org_data) != XMMSV_TYPE_DICT) {
17
Assuming the condition is false
18
Taking false branch
473 xmms_error_set (err, XMMS_ERROR_INVAL, "Field 'data' in organize must be a dict.");
474 return NULL((void*)0);
475 }
476
477 sp = normalize_source_preferences (fetch, prefs, err);
478 if (xmms_error_iserror (err)((err)->code != XMMS_ERROR_NONE)) {
19
Taking false branch
479 return NULL((void*)0);
480 }
481
482 spec = g_new0 (xmms_fetch_spec_t, 1)((xmms_fetch_spec_t *) g_malloc0_n ((1), sizeof (xmms_fetch_spec_t
)))
;
483 spec->type = FETCH_ORGANIZE;
484
485 spec->data.organize.count = xmmsv_dict_get_size (org_data);
486 spec->data.organize.keys = g_new0 (const char *, spec->data.organize.count)((const char * *) g_malloc0_n ((spec->data.organize.count)
, sizeof (const char *)))
;
487 spec->data.organize.data = g_new0 (xmms_fetch_spec_t *, spec->data.organize.count)((xmms_fetch_spec_t * *) g_malloc0_n ((spec->data.organize
.count), sizeof (xmms_fetch_spec_t *)))
;
488
489 org_idx = 0;
490 xmmsv_get_dict_iter (org_data, &it);
491 while (xmmsv_dict_iter_valid (it)) {
20
Loop condition is true. Entering loop body
22
Loop condition is true. Entering loop body
24
Loop condition is true. Entering loop body
492 xmms_fetch_spec_t *orgee;
493 const gchar *str;
494 xmmsv_t *entry;
495
496 xmmsv_dict_iter_pair (it, &str, &entry);
497
498 orgee = xmms_fetch_spec_new (entry, info, sp, err);
25
Calling 'xmms_fetch_spec_new'
499 if (xmms_error_iserror (err)((err)->code != XMMS_ERROR_NONE)) {
21
Taking false branch
23
Taking false branch
500 xmms_fetch_spec_free (spec);
501 spec = NULL((void*)0);
502 break;
503 }
504
505 spec->data.organize.keys[org_idx] = str;
506 spec->data.organize.data[org_idx] = orgee;
507
508 org_idx++;
509 xmmsv_dict_iter_next (it);
510 }
511 xmmsv_dict_iter_explicit_destroy (it);
512
513 s4_sourcepref_unref (sp);
514
515 return spec;
516}
517
518static xmms_fetch_spec_t *
519xmms_fetch_spec_new_count (xmmsv_t *fetch, xmms_fetch_info_t *info,
520 s4_sourcepref_t *prefs, xmms_error_t *err)
521{
522 xmms_fetch_spec_t *ret;
523
524 ret = g_new0 (xmms_fetch_spec_t, 1)((xmms_fetch_spec_t *) g_malloc0_n ((1), sizeof (xmms_fetch_spec_t
)))
;
525 ret->type = FETCH_COUNT;
526
527 return ret;
528}
529
530
531
532/**
533 * Converts a fetch specification in xmmsv_t form into a
534 * fetch_spec_t structure
535 */
536xmms_fetch_spec_t *
537xmms_fetch_spec_new (xmmsv_t *fetch, xmms_fetch_info_t *info,
538 s4_sourcepref_t *prefs, xmms_error_t *err)
539{
540 const char *type;
541
542 if (xmmsv_get_type (fetch) != XMMSV_TYPE_DICT) {
1
Assuming the condition is false
2
Taking false branch
26
Assuming the condition is false
27
Taking false branch
543 xmms_error_set (err, XMMS_ERROR_INVAL, "A fetch specification must be a dict.");
544 return NULL((void*)0);
545 }
546
547 if (xmmsv_dict_entry_get_type (fetch, "type") == XMMSV_TYPE_NONE) {
3
Assuming the condition is false
4
Taking false branch
28
Assuming the condition is false
29
Taking false branch
548 xmmsv_dict_set_string (fetch, "type", "metadata");
549 }
550
551 if (!xmmsv_dict_entry_get_string (fetch, "type", &type)) {
5
Assuming the condition is false
6
Taking false branch
30
Assuming the condition is false
31
Taking false branch
552 xmms_error_set (err, XMMS_ERROR_INVAL, "A fetch specification must have a type.");
553 return NULL((void*)0);
554 }
555
556 if (strcmp (type, "metadata") == 0) {
7
Assuming the condition is false
8
Taking false branch
32
Assuming the condition is false
33
Taking false branch
557 return xmms_fetch_spec_new_metadata (fetch, info, prefs, err);
558 } else if (strcmp (type, "cluster-list") == 0) {
9
Assuming the condition is false
10
Taking false branch
34
Taking true branch
559 return xmms_fetch_spec_new_cluster_list (fetch, info, prefs, err);
35
Calling 'xmms_fetch_spec_new_cluster_list'
560 } else if (strcmp (type, "cluster-dict") == 0) {
11
Assuming the condition is false
12
Taking false branch
561 return xmms_fetch_spec_new_cluster_dict (fetch, info, prefs, err);
562 } else if (strcmp (type, "organize") == 0) {
13
Taking true branch
563 return xmms_fetch_spec_new_organize (fetch, info, prefs, err);
14
Calling 'xmms_fetch_spec_new_organize'
564 } else if (strcmp (type, "count") == 0) {
565 return xmms_fetch_spec_new_count (fetch, info, prefs, err);
566 }
567
568 xmms_error_set (err, XMMS_ERROR_INVAL, "Unknown fetch type.");
569
570 return NULL((void*)0);
571}
572
573
574void
575xmms_fetch_spec_free (xmms_fetch_spec_t *spec)
576{
577 int i;
578 if (spec == NULL((void*)0))
579 return;
580
581 switch (spec->type) {
582 case FETCH_METADATA:
583 g_free (spec->data.metadata.cols);
584 break;
585 case FETCH_CLUSTER_DICT:
586 case FETCH_CLUSTER_LIST:
587 xmms_fetch_spec_free (spec->data.cluster.data);
588 break;
589 case FETCH_ORGANIZE:
590 for (i = 0; i < spec->data.organize.count; i++) {
591 xmms_fetch_spec_free (spec->data.organize.data[i]);
592 }
593
594 g_free (spec->data.organize.keys);
595 g_free (spec->data.organize.data);
596 break;
597 case FETCH_COUNT: /* Nothing to free */
598 break;
599 default:
600 g_assert_not_reached ()do { g_assertion_message_expr ("core", "../src/xmms/fetchspec.c"
, 600, ((const char*) (__func__)), ((void*)0)); } while (0)
;
601 }
602
603 g_free (spec);
604}