Mercurial > mplayer.hg
comparison asxparser.c @ 4043:25590564842f
tree-based playlist parser code by Alban Bedel <albeu@free.fr>
author | arpi |
---|---|
date | Tue, 08 Jan 2002 01:24:25 +0000 |
parents | |
children | da61596bcd87 |
comparison
equal
deleted
inserted
replaced
4042:d651a7b5d213 | 4043:25590564842f |
---|---|
1 | |
2 #include <stdlib.h> | |
3 #include <stdio.h> | |
4 #include <stdarg.h> | |
5 #include <string.h> | |
6 | |
7 #include "asxparser.h" | |
8 #include "mp_msg.h" | |
9 | |
10 ////// List utils | |
11 | |
12 typedef void (*ASX_FreeFunc)(void* arg); | |
13 | |
14 void | |
15 asx_list_add(void* list_ptr,void* entry){ | |
16 void** list = *(void***)list_ptr; | |
17 int c = 0; | |
18 | |
19 if(list != NULL) | |
20 for( ; list[c] != NULL; c++) ; | |
21 | |
22 list = (void*)realloc(list,sizeof(void*)*(c+2)); | |
23 | |
24 list[c] = entry; | |
25 list[c+1] = NULL; | |
26 | |
27 *(void***)list_ptr = list; | |
28 } | |
29 | |
30 | |
31 void | |
32 asx_list_remove(void* list_ptr,void* entry,ASX_FreeFunc free_func) { | |
33 void** list = *(void***)list_ptr; | |
34 int c,e = -1; | |
35 | |
36 if(list == NULL) return; | |
37 | |
38 for(c = 0 ; list[c] != NULL; c++){ | |
39 if(list[c] == entry) e = c; | |
40 } | |
41 | |
42 if(e == -1) return; // Not found | |
43 | |
44 if(free_func != NULL) free_func(list[e]); | |
45 | |
46 if(c == 1) { // Only one entry, we drop all | |
47 free(list); | |
48 *(void**)list_ptr = NULL; | |
49 return; | |
50 } | |
51 | |
52 if(c > e) // If c==e the memmove is not needed | |
53 memmove(list+e,list+e+1,(c-e)*sizeof(void*)); | |
54 | |
55 list = (void*)realloc(list,(c-1)*sizeof(void*)); | |
56 list[c-1] = NULL; | |
57 | |
58 *(void***)list_ptr = list; | |
59 } | |
60 | |
61 void | |
62 asx_list_free(void* list_ptr,ASX_FreeFunc free_func) { | |
63 void** ptr = *(void***)list_ptr; | |
64 if(ptr == NULL) return; | |
65 if(free_func != NULL) { | |
66 for( ; *ptr != NULL ; ptr++) | |
67 free_func(*ptr); | |
68 } | |
69 free(*(void**)list_ptr); | |
70 *(void**)list_ptr = NULL; | |
71 } | |
72 | |
73 /////// Attribs utils | |
74 | |
75 static char* | |
76 asx_get_attrib(char* attrib,char** attribs) { | |
77 char** ptr; | |
78 | |
79 if(attrib == NULL || attribs == NULL) return NULL; | |
80 for(ptr = attribs; ptr[0] != NULL; ptr += 2){ | |
81 if(strcasecmp(ptr[0],attrib) == 0) | |
82 return strdup(ptr[1]); | |
83 } | |
84 return NULL; | |
85 } | |
86 | |
87 static int | |
88 asx_attrib_to_enum(char* val,char** valid_vals) { | |
89 char** ptr; | |
90 int r = 0; | |
91 | |
92 if(valid_vals == NULL || val == NULL) return -2; | |
93 for(ptr = valid_vals ; ptr[0] != NULL ; ptr++) { | |
94 if(strcasecmp(val,ptr[0]) == 0) return r; | |
95 r++; | |
96 } | |
97 | |
98 return -1; | |
99 } | |
100 | |
101 static void | |
102 asx_warning_attrib_invalid(ASX_Parser_t* parser, char* elem, char* attrib, | |
103 char** valid_vals,char* val) { | |
104 char *str,*vals,**ptr; | |
105 int len; | |
106 | |
107 if(valid_vals == NULL || valid_vals[0] == NULL) return; | |
108 | |
109 len = strlen(valid_vals[0]) + 1; | |
110 for(ptr = valid_vals+1 ; ptr[0] != NULL; ptr++) { | |
111 len += strlen(ptr[0]); | |
112 len += ((ptr[1] == NULL) ? 4 : 2); | |
113 } | |
114 str = vals = (char*)malloc(len); | |
115 vals += sprintf(vals,"%s",valid_vals[0]); | |
116 for(ptr = valid_vals + 1 ; ptr[0] != NULL ; ptr++) { | |
117 if(ptr[1] == NULL) | |
118 vals += sprintf(vals," or %s",ptr[0]); | |
119 else | |
120 vals += sprintf(vals,", %s",ptr[0]); | |
121 } | |
122 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"at line %d : attribute %s of element %s is invalid (%s). Valid values are %s", | |
123 parser->line,attrib,elem,val,str); | |
124 free(str); | |
125 } | |
126 | |
127 static int | |
128 asx_get_yes_no_attrib(ASX_Parser_t* parser, char* element, char* attrib,char** attribs,int def) { | |
129 char* val = asx_get_attrib(attrib,attribs); | |
130 char* valids[] = { "NO", "YES", NULL }; | |
131 int r; | |
132 | |
133 if(val == NULL) return def; | |
134 r = asx_attrib_to_enum(val,valids); | |
135 | |
136 if(r < 0) { | |
137 asx_warning_attrib_invalid(parser,element,attrib,valids,val); | |
138 r = def; | |
139 } | |
140 | |
141 free(val); | |
142 return r; | |
143 } | |
144 | |
145 #define asx_free_attribs(a) asx_list_free((void***)&a,free) | |
146 | |
147 #define asx_warning_attrib_required(p,e,a) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : element %s don't have the required attribute %s",p->line,e,a) | |
148 #define asx_warning_body_parse_error(p,e) mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : error while parsing %s body",p->line,e) | |
149 | |
150 ASX_Parser_t* | |
151 asx_parser_new(void) { | |
152 ASX_Parser_t* parser = calloc(1,sizeof(ASX_Parser_t)); | |
153 return parser; | |
154 } | |
155 | |
156 void | |
157 asx_parser_free(ASX_Parser_t* parser) { | |
158 if(!parser) return; | |
159 if(parser->ret_stack) free(parser->ret_stack); | |
160 free(parser); | |
161 | |
162 } | |
163 | |
164 #define LETTER "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
165 #define SPACE " \n\t\r" | |
166 | |
167 static int | |
168 asx_parse_attribs(ASX_Parser_t* parser,char* buffer,char*** _attribs) { | |
169 char *ptr1, *ptr2, *ptr3; | |
170 int n_attrib = 0; | |
171 char **attribs = NULL; | |
172 char *attrib, *val; | |
173 | |
174 ptr1 = buffer; | |
175 while(1) { | |
176 for( ; strchr(SPACE,*ptr1) != NULL; ptr1++) { // Skip space | |
177 if(*ptr1 == '\0') break; | |
178 } | |
179 ptr3 = strchr(ptr1,'='); | |
180 if(ptr3 == NULL) break; | |
181 for(ptr2 = ptr3-1; strchr(SPACE,*ptr2) != NULL; ptr2--) { | |
182 if (ptr2 == ptr1) { | |
183 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : this should never append, back to attribute begin while skipping end space",parser->line); | |
184 break; | |
185 } | |
186 } | |
187 attrib = (char*)malloc(ptr2-ptr1+2); | |
188 strncpy(attrib,ptr1,ptr2-ptr1+1); | |
189 attrib[ptr2-ptr1+1] = '\0'; | |
190 | |
191 ptr1 = strchr(ptr3,'"'); | |
192 if(ptr1 == NULL || ptr1[1] == '\0') { | |
193 mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : can't find attribute %s value",parser->line,attrib); | |
194 free(attrib); | |
195 break; | |
196 } | |
197 ptr1++; | |
198 ptr2 = strchr(ptr1,'"'); | |
199 if (ptr2 == NULL) { | |
200 mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : value of attribute %s isn't finished",parser->line,attrib); | |
201 free(attrib); | |
202 break; | |
203 } | |
204 val = (char*)malloc(ptr2-ptr1+1); | |
205 strncpy(val,ptr1,ptr2-ptr1); | |
206 val[ptr2-ptr1] = '\0'; | |
207 n_attrib++; | |
208 | |
209 attribs = (char**)realloc(attribs,2*n_attrib*sizeof(char*)+1); | |
210 attribs[n_attrib*2-2] = attrib; | |
211 attribs[n_attrib*2-1] = val; | |
212 | |
213 ptr1 = ptr2+2; | |
214 } | |
215 | |
216 if(n_attrib > 0) | |
217 attribs[n_attrib*2] = NULL; | |
218 | |
219 *_attribs = attribs; | |
220 | |
221 return n_attrib; | |
222 } | |
223 | |
224 /* | |
225 * Return -1 on error, 0 when nothing is found, 1 on sucess | |
226 */ | |
227 static int | |
228 asx_get_element(ASX_Parser_t* parser,char** _buffer, | |
229 char** _element,char** _body,char*** _attribs) { | |
230 char *ptr1,*ptr2, *ptr3, *ptr4; | |
231 char *attribs = NULL; | |
232 char *element = NULL, *body = NULL, *ret = NULL, *buffer; | |
233 int n_attrib = 0; | |
234 int body_line = 0,attrib_line,ret_line; | |
235 | |
236 if(_buffer == NULL || _element == NULL || _body == NULL || _attribs == NULL) { | |
237 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : asx_get_element called with invalid value",parser->line); | |
238 return -1; | |
239 } | |
240 | |
241 *_body = *_element = NULL; | |
242 *_attribs = NULL; | |
243 buffer = *_buffer; | |
244 | |
245 if(buffer == NULL) return 0; | |
246 | |
247 if(parser->ret_stack && /*parser->last_body && */buffer != parser->last_body) { | |
248 ASX_LineSave_t* ls = parser->ret_stack; | |
249 int i; | |
250 for(i = 0 ; i < parser->ret_stack_size ; i++) { | |
251 if(buffer == ls[i].buffer) { | |
252 parser->line = ls[i].line; | |
253 break; | |
254 } | |
255 | |
256 } | |
257 if( i < parser->ret_stack_size) { | |
258 i++; | |
259 if( i < parser->ret_stack_size) | |
260 memmove(parser->ret_stack,parser->ret_stack+i, (parser->ret_stack_size - i)*sizeof(ASX_LineSave_t)); | |
261 parser->ret_stack_size -= i; | |
262 parser->ret_stack = (ASX_LineSave_t*)realloc(parser->ret_stack,parser->ret_stack_size*sizeof(ASX_LineSave_t)); | |
263 } | |
264 } | |
265 | |
266 ptr1 = buffer; | |
267 while(1) { | |
268 for( ; ptr1[0] != '<' ; ptr1++) { | |
269 if(ptr1[0] == '\0') { | |
270 ptr1 = NULL; | |
271 break; | |
272 } | |
273 if(ptr1[0] == '\n') parser->line++; | |
274 } | |
275 //ptr1 = strchr(ptr1,'<'); | |
276 if(!ptr1 || ptr1[1] == '\0') return 0; // Nothing found | |
277 | |
278 if(strncmp(ptr1,"<!--",4) == 0) { // Comments | |
279 for( ; strncmp(ptr1,"-->",3) != 0 ; ptr1++) { | |
280 if(ptr1[0] == '\0') { | |
281 ptr1 = NULL; | |
282 break; | |
283 } | |
284 if(ptr1[0] == '\n') parser->line++; | |
285 } | |
286 //ptr1 = strstr(ptr1,"-->"); | |
287 if(!ptr1) { | |
288 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : unfinished comment",parser->line); | |
289 return -1; | |
290 } | |
291 } else { | |
292 break; | |
293 } | |
294 } | |
295 | |
296 // Is this space skip very useful ?? | |
297 for(ptr1++; strchr(SPACE,ptr1[0]) != NULL; ptr1++) { // Skip space | |
298 if(ptr1[0] == '\0') { | |
299 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line); | |
300 return -1; | |
301 } | |
302 if(ptr1[0] == '\n') parser->line++; | |
303 } | |
304 | |
305 for(ptr2 = ptr1; strchr(LETTER,*ptr2) != NULL;ptr2++) { // Go to end of name | |
306 if(*ptr2 == '\0'){ | |
307 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line); | |
308 return -1; | |
309 } | |
310 if(ptr2[0] == '\n') parser->line++; | |
311 } | |
312 | |
313 element = (char*)malloc(ptr2-ptr1+1); | |
314 strncpy(element,ptr1,ptr2-ptr1); | |
315 element[ptr2-ptr1] = '\0'; | |
316 | |
317 for( ; strchr(SPACE,*ptr2) != NULL; ptr2++) { // Skip space | |
318 if(ptr2[0] == '\0') { | |
319 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line); | |
320 free(element); | |
321 return -1; | |
322 } | |
323 if(ptr2[0] == '\n') parser->line++; | |
324 } | |
325 attrib_line = parser->line; | |
326 | |
327 | |
328 | |
329 for(ptr3 = ptr2; ptr3[0] != '\0'; ptr3++) { // Go to element end | |
330 if(ptr3[0] == '>' || strncmp(ptr3,"/>",2) == 0) | |
331 break; | |
332 if(ptr3[0] == '\n') parser->line++; | |
333 } | |
334 if(ptr3[0] == '\0' || ptr3[1] == '\0') { // End of file | |
335 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing element start",parser->line); | |
336 free(element); | |
337 return -1; | |
338 } | |
339 | |
340 // Save attribs string | |
341 if(ptr3-ptr2 > 0) { | |
342 attribs = (char*)malloc(ptr3-ptr2+1); | |
343 strncpy(attribs,ptr2,ptr3-ptr2); | |
344 attribs[ptr3-ptr2] = '\0'; | |
345 } | |
346 //bs_line = parser->line; | |
347 if(ptr3[0] != '/') { // Not Self closed element | |
348 ptr3++; | |
349 for( ; strchr(SPACE,*ptr3) != NULL; ptr3++) { // Skip space on body begin | |
350 if(*ptr3 == '\0') { | |
351 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing %s element body",parser->line,element); | |
352 free(element); | |
353 if(attribs) free(attribs); | |
354 return -1; | |
355 } | |
356 if(ptr3[0] == '\n') parser->line++; | |
357 } | |
358 ptr4 = ptr3; | |
359 body_line = parser->line; | |
360 while(1) { // Find closing element | |
361 for( ; strncmp(ptr4,"</",2) != 0; ptr4++) { | |
362 if(ptr4[0] == '\0') { | |
363 ptr4 = NULL; | |
364 break; | |
365 } | |
366 if(ptr4[0] == '\n') parser->line++; | |
367 } | |
368 //ptr4 = strstr(ptr4,"</"); | |
369 if(ptr4 == NULL || ptr4[2] == '\0') { | |
370 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : EOB reached while parsing %s element body",parser->line,element); | |
371 free(element); | |
372 if(attribs) free(attribs); | |
373 return -1; | |
374 } | |
375 if(strncasecmp(element,ptr4+2,strlen(element)) == 0) { // Extract body | |
376 ret = ptr4+strlen(element)+3; | |
377 if(ptr4 != ptr3) { | |
378 ptr4--; | |
379 for( ; ptr4 != ptr3 && strchr(SPACE,*ptr4) != NULL; ptr4--) ;// Skip space on body end | |
380 // if(ptr4[0] == '\0') parser->line--; | |
381 //} | |
382 ptr4++; | |
383 body = (char*)malloc(ptr4-ptr3+1); | |
384 strncpy(body,ptr3,ptr4-ptr3); | |
385 body[ptr4-ptr3] = '\0'; | |
386 } | |
387 break; | |
388 } else { | |
389 ptr4 += 2; | |
390 } | |
391 } | |
392 } else { | |
393 ret = ptr3 + 2; // 2 is for /> | |
394 } | |
395 | |
396 for( ; ret[0] != '\0' && strchr(SPACE,ret[0]) != NULL; ret++) { // Skip space | |
397 if(ret[0] == '\n') parser->line++; | |
398 } | |
399 | |
400 ret_line = parser->line; | |
401 | |
402 if(attribs) { | |
403 parser->line = attrib_line; | |
404 n_attrib = asx_parse_attribs(parser,attribs,_attribs); | |
405 free(attribs); | |
406 if(n_attrib < 0) { | |
407 mp_msg(MSGT_PLAYTREE,MSGL_WARN,"At line %d : error while parsing element %s attributes",parser->line,element); | |
408 free(element); | |
409 free(body); | |
410 return -1; | |
411 } | |
412 } else | |
413 *_attribs = NULL; | |
414 | |
415 *_element = element; | |
416 *_body = body; | |
417 | |
418 parser->last_body = body; | |
419 parser->ret_stack_size++; | |
420 parser->ret_stack = (ASX_LineSave_t*)realloc(parser->ret_stack,parser->ret_stack_size*sizeof(ASX_LineSave_t)); | |
421 if(parser->ret_stack_size > 1) | |
422 memmove(parser->ret_stack+1,parser->ret_stack,(parser->ret_stack_size-1)*sizeof(ASX_LineSave_t)); | |
423 parser->ret_stack[0].buffer = ret; | |
424 parser->ret_stack[0].line = ret_line; | |
425 parser->line = body ? body_line : ret_line; | |
426 | |
427 *_buffer = ret; | |
428 return 1; | |
429 | |
430 } | |
431 | |
432 static void | |
433 asx_parse_ref(ASX_Parser_t* parser, char** attribs, play_tree_t* pt) { | |
434 char *href; | |
435 | |
436 href = asx_get_attrib("HREF",attribs); | |
437 if(href == NULL) { | |
438 asx_warning_attrib_required(parser,"ENTRYREF" ,"HREF" ); | |
439 return; | |
440 } | |
441 | |
442 play_tree_add_file(pt,href); | |
443 | |
444 mp_msg(MSGT_PLAYTREE,MSGL_V,"Adding file %s to element entry\n",href); | |
445 | |
446 free(href); | |
447 | |
448 } | |
449 | |
450 static play_tree_t* | |
451 asx_parse_entryref(ASX_Parser_t* parser,char* buffer,char** _attribs) { | |
452 mp_msg(MSGT_PLAYTREE,MSGL_INFO,"Need to implement entryref\n"); | |
453 return NULL; | |
454 } | |
455 | |
456 static play_tree_t* | |
457 asx_parse_entry(ASX_Parser_t* parser,char* buffer,char** _attribs) { | |
458 char *element,*body,**attribs; | |
459 int r,nref=0; | |
460 play_tree_t *ref; | |
461 | |
462 ref = play_tree_new(); | |
463 | |
464 while(buffer && buffer[0] != '\0') { | |
465 r = asx_get_element(parser,&buffer,&element,&body,&attribs); | |
466 if(r < 0) { | |
467 asx_warning_body_parse_error(parser,"ENTRY"); | |
468 return NULL; | |
469 } else if (r == 0) { // No more element | |
470 break; | |
471 } | |
472 if(strcasecmp(element,"REF") == 0) { | |
473 asx_parse_ref(parser,attribs,ref); | |
474 mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to entry\n",element); | |
475 nref++; | |
476 } else | |
477 mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element); | |
478 if(body) free(body); | |
479 asx_free_attribs(attribs); | |
480 } | |
481 | |
482 if(nref <= 0) { | |
483 play_tree_free(ref,1); | |
484 return NULL; | |
485 } | |
486 return ref; | |
487 | |
488 } | |
489 | |
490 | |
491 static play_tree_t* | |
492 asx_parse_repeat(ASX_Parser_t* parser,char* buffer,char** _attribs) { | |
493 char *element,*body,**attribs; | |
494 play_tree_t *repeat, *list=NULL, *entry; | |
495 char* count; | |
496 int r; | |
497 | |
498 repeat = play_tree_new(); | |
499 | |
500 count = asx_get_attrib("COUNT",_attribs); | |
501 if(count == NULL) { | |
502 mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Setting element repeat loop to infinit\n"); | |
503 repeat->loop = -1; // Infinit | |
504 } else { | |
505 repeat->loop = atoi(count); | |
506 free(count); | |
507 if(repeat->loop == 0) repeat->loop = 1; | |
508 mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Setting element repeat loop to %d\n",repeat->loop); | |
509 } | |
510 | |
511 while(buffer && buffer[0] != '\0') { | |
512 r = asx_get_element(parser,&buffer,&element,&body,&attribs); | |
513 if(r < 0) { | |
514 asx_warning_body_parse_error(parser,"REPEAT"); | |
515 return NULL; | |
516 } else if (r == 0) { // No more element | |
517 break; | |
518 } | |
519 if(strcasecmp(element,"ENTRY") == 0) { | |
520 entry = asx_parse_entry(parser,body,attribs); | |
521 if(entry) { | |
522 if(!list) list = entry; | |
523 else play_tree_append_entry(list,entry); | |
524 mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to repeat\n",element); | |
525 } | |
526 } else if(strcasecmp(element,"ENTRYREF") == 0) { | |
527 entry = asx_parse_entryref(parser,body,attribs); | |
528 if(entry) { | |
529 if(!list) list = entry; | |
530 else play_tree_append_entry(list,entry); | |
531 mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to repeat\n",element); | |
532 } | |
533 } else if(strcasecmp(element,"REPEAT") == 0) { | |
534 entry = asx_parse_repeat(parser,body,attribs); | |
535 if(entry) { | |
536 if(!list) list = entry; | |
537 else play_tree_append_entry(list,entry); | |
538 mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to repeat\n",element); | |
539 } | |
540 } else | |
541 mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element); | |
542 if(body) free(body); | |
543 asx_free_attribs(attribs); | |
544 } | |
545 | |
546 if(!list) { | |
547 play_tree_free(repeat,1); | |
548 return NULL; | |
549 } | |
550 play_tree_set_child(repeat,list); | |
551 | |
552 return repeat; | |
553 | |
554 } | |
555 | |
556 | |
557 | |
558 play_tree_t* | |
559 asx_parser_build_tree(char* buffer) { | |
560 char *element,*asx_body,**asx_attribs,*body, **attribs; | |
561 int r; | |
562 play_tree_t *asx,*entry,*list = NULL; | |
563 ASX_Parser_t* parser = asx_parser_new(); | |
564 | |
565 parser->line = 1; | |
566 | |
567 r = asx_get_element(parser,&buffer,&element,&asx_body,&asx_attribs); | |
568 if(r < 0) { | |
569 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : Syntax error ???",parser->line); | |
570 asx_parser_free(parser); | |
571 return NULL; | |
572 } else if(r == 0) { // No contents | |
573 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"empty asx element"); | |
574 asx_parser_free(parser); | |
575 return NULL; | |
576 } | |
577 | |
578 if(strcasecmp(element,"ASX") != 0) { | |
579 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"first element isn't ASX, it's %s\n",element); | |
580 asx_free_attribs(asx_attribs); | |
581 if(body) free(body); | |
582 asx_parser_free(parser); | |
583 return NULL; | |
584 } | |
585 | |
586 if(!asx_body) { | |
587 mp_msg(MSGT_PLAYTREE,MSGL_ERR,"ASX element is empty"); | |
588 asx_free_attribs(asx_attribs); | |
589 asx_parser_free(parser); | |
590 return NULL; | |
591 } | |
592 | |
593 asx = play_tree_new(); | |
594 buffer = asx_body; | |
595 while(buffer && buffer[0] != '\0') { | |
596 r = asx_get_element(parser,&buffer,&element,&body,&attribs); | |
597 if(r < 0) { | |
598 asx_warning_body_parse_error(parser,"ASX"); | |
599 asx_parser_free(parser); | |
600 return NULL; | |
601 } else if (r == 0) { // No more element | |
602 break; | |
603 } | |
604 if(strcasecmp(element,"ENTRY") == 0) { | |
605 entry = asx_parse_entry(parser,body,attribs); | |
606 if(entry) { | |
607 if(!list) list = entry; | |
608 else play_tree_append_entry(list,entry); | |
609 mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to asx\n",element); | |
610 } | |
611 } else if(strcasecmp(element,"ENTRYREF") == 0) { | |
612 entry = asx_parse_entryref(parser,body,attribs); | |
613 if(entry) { | |
614 if(!list) list = entry; | |
615 else play_tree_append_entry(list,entry); | |
616 mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to asx\n",element); | |
617 } | |
618 } else if(strcasecmp(element,"REPEAT") == 0) { | |
619 entry = asx_parse_repeat(parser,body,attribs); | |
620 if(entry) { | |
621 if(!list) list = entry; | |
622 else play_tree_append_entry(list,entry); | |
623 mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to asx\n",element); | |
624 } | |
625 } else | |
626 mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element); | |
627 if(body) free(body); | |
628 asx_free_attribs(attribs); | |
629 } | |
630 | |
631 free(asx_body); | |
632 asx_free_attribs(asx_attribs); | |
633 asx_parser_free(parser); | |
634 | |
635 | |
636 if(!list) { | |
637 play_tree_free(asx,1); | |
638 | |
639 return NULL; | |
640 } | |
641 | |
642 play_tree_set_child(asx,list); | |
643 | |
644 return asx; | |
645 } |