static play_tree_t* asx_parse_entry(ASX_Parser_t* parser,char* buffer,char** _attribs) { int nref=0; play_tree_t *ref; ref = play_tree_new(); while(buffer && buffer[0] != '\0') { char *element,*body,**attribs; int r = asx_get_element(parser,&buffer,&element,&body,&attribs); if(r < 0) { asx_warning_body_parse_error(parser,"ENTRY"); play_tree_free(ref,1); return NULL; } else if (r == 0) { // No more element break; } if(strcasecmp(element,"REF") == 0) { asx_parse_ref(parser,attribs,ref); mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to entry\n",element); nref++; } else mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element); free(element); free(body); asx_free_attribs(attribs); } if(nref <= 0) { play_tree_free(ref,1); return NULL; } return ref; }
void play_tree_free(play_tree_t* pt, int children) { play_tree_t* iter; #ifdef MP_DEBUG assert(pt != NULL); #endif if(children) { for(iter = pt->child; iter != NULL; ) { play_tree_t* nxt=iter->next; play_tree_free(iter,1); iter = nxt; } pt->child = NULL; } play_tree_remove(pt,0,0); for(iter = pt->child ; iter != NULL ; iter = iter->next) iter->parent = NULL; //if(pt->params) free(pt->params); if(pt->files) { int i; for(i = 0 ; pt->files[i] != NULL ; i++) free(pt->files[i]); free(pt->files); } free(pt); }
void play_tree_remove(play_tree_t* pt, int free_it, int with_children) { #ifdef MP_DEBUG assert(pt != NULL); #endif // Middle of list if(pt->prev && pt->next) { #ifdef MP_DEBUG assert(pt->prev->next == pt); assert(pt->next->prev == pt); #endif pt->prev->next = pt->next; pt->next->prev = pt->prev; } // End of list else if(pt->prev) { #ifdef MP_DEBUG assert(pt->prev->next == pt); #endif pt->prev->next = NULL; } // Beginning of list else if(pt->next) { #ifdef MP_DEBUG assert(pt->next->prev == pt); #endif pt->next->prev = NULL; if(pt->parent) { #ifdef MP_DEBUG assert(pt->parent->child == pt); #endif pt->parent->child = pt->next; } } // The only one else if(pt->parent) { #ifdef MP_DEBUG assert(pt->parent->child == pt); #endif pt->parent->child = NULL; } pt->prev = pt->next = pt->parent = NULL; if(free_it) play_tree_free(pt,with_children); }
void play_tree_free_list(play_tree_t* pt, int children) { play_tree_t* iter; #ifdef MP_DEBUG assert(pt != NULL); #endif for(iter = pt ; iter->prev != NULL ; iter = iter->prev) /* NOTHING */; while(iter) { play_tree_t* nxt = iter->next; play_tree_free(iter, children); iter = nxt; } }
/** \ingroup ConfigParsers */ play_tree_t* m_config_parse_mp_command_line(m_config_t *config, int argc, char **argv) { int i,j,start_title=-1,end_title=-1; char *opt,*splitpos=NULL; char entbuf[15]; int no_more_opts = 0; int opt_exit = 0; // flag indicating whether mplayer should exit without playing anything play_tree_t *last_parent, *last_entry = NULL, *root; #ifdef MP_DEBUG assert(config != NULL); assert(argv != NULL); assert(argc >= 1); #endif config->mode = M_COMMAND_LINE; mode = GLOBAL; #ifdef CONFIG_MACOSX_FINDER root=macosx_finder_args(config, argc, argv); if(root) return root; #endif last_parent = root = play_tree_new(); for (i = 1; i < argc; i++) { //next: opt = argv[i]; /* check for -- (no more options id.) except --help! */ if ((*opt == '-') && (*(opt+1) == '-') && (*(opt+2) == 0)) { no_more_opts = 1; if (i+1 >= argc) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_NoFileGivenOnCommandLine); goto err_out; } continue; } if((opt[0] == '{') && (opt[1] == '\0')) { play_tree_t* entry = play_tree_new(); UNSET_GLOBAL; if(last_parent->flags & PLAY_TREE_RND) entry->flags |= PLAY_TREE_RND; if(last_entry == NULL) { play_tree_set_child(last_parent,entry); } else { play_tree_append_entry(last_entry,entry); last_entry = NULL; } last_parent = entry; continue; } if((opt[0] == '}') && (opt[1] == '\0')) { if( ! last_parent || ! last_parent->parent) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, "too much }-\n"); goto err_out; } last_entry = last_parent; last_parent = last_entry->parent; continue; } if ((no_more_opts == 0) && (*opt == '-') && (*(opt+1) != 0)) /* option */ { int tmp = 0; /* remove trailing '-' */ opt++; mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "this_opt = option: %s\n", opt); // We handle here some specific option // Loop option when it apply to a group if(strcasecmp(opt,"loop") == 0 && (! last_entry || last_entry->child) ) { int l; char* end = NULL; l = (i+1<argc) ? strtol(argv[i+1],&end,0) : 0; if(!end || *end != '\0') { mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_TheLoopOptionMustBeAnInteger, argv[i+1]); tmp = ERR_OUT_OF_RANGE; } else { play_tree_t* pt = last_entry ? last_entry : last_parent; l = l <= 0 ? -1 : l; pt->loop = l; tmp = 1; } } else if(strcasecmp(opt,"shuffle") == 0) { if(last_entry && last_entry->child) last_entry->flags |= PLAY_TREE_RND; else last_parent->flags |= PLAY_TREE_RND; } else if(strcasecmp(opt,"noshuffle") == 0) { if(last_entry && last_entry->child) last_entry->flags &= ~PLAY_TREE_RND; else last_parent->flags &= ~PLAY_TREE_RND; } else { const m_option_t* mp_opt = NULL; play_tree_t* entry = NULL; tmp = is_entry_option(opt,(i+1<argc) ? argv[i + 1] : NULL,&entry); if(tmp > 0) { // It's an entry if(entry) { add_entry(&last_parent,&last_entry,entry); if((last_parent->flags & PLAY_TREE_RND) && entry->child) entry->flags |= PLAY_TREE_RND; UNSET_GLOBAL; } else if(mode == LOCAL) // Entry is empty we have to drop his params mode = DROP_LOCAL; } else if(tmp == 0) { // 'normal' options mp_opt = m_config_get_option(config,opt); if (mp_opt != NULL) { // Option exist if(mode == GLOBAL || (mp_opt->flags & M_OPT_GLOBAL)) tmp = (i+1<argc) ? m_config_set_option(config, opt, argv[i + 1]) : m_config_set_option(config, opt, NULL); else { tmp = m_config_check_option(config, opt, (i+1<argc) ? argv[i + 1] : NULL); if(tmp >= 0 && mode != DROP_LOCAL) { play_tree_t* pt = last_entry ? last_entry : last_parent; play_tree_set_param(pt,opt, argv[i + 1]); } } } else { tmp = M_OPT_UNKNOWN; mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_UnknownOptionOnCommandLine, opt); } } } if (tmp <= M_OPT_EXIT) { opt_exit = 1; tmp = M_OPT_EXIT - tmp; } else if (tmp < 0) { mp_msg(MSGT_CFGPARSER, MSGL_FATAL, MSGTR_ErrorParsingOptionOnCommandLine, opt); goto err_out; } i += tmp; } else /* filename */ { int is_dvdnav = strstr(argv[i],"dvdnav://") != NULL; play_tree_t* entry = play_tree_new(); mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Adding file %s\n",argv[i]); // if required expand DVD filename entries like dvd://1-3 into component titles if ( strstr(argv[i],"dvd://") != NULL || is_dvdnav) { int offset = is_dvdnav ? 9 : 6; splitpos=strstr(argv[i]+offset,"-"); if(splitpos != NULL) { start_title=strtol(argv[i]+offset,NULL,10); if (start_title<0) { //entries like dvd://-2 start title implied 1 end_title=abs(start_title); start_title=1; } else { end_title=strtol(splitpos+1,NULL,10); } if (dvd_range(start_title) && dvd_range(end_title) && (start_title<end_title)) { for (j=start_title;j<=end_title;j++) { if (j!=start_title) entry=play_tree_new(); snprintf(entbuf,sizeof(entbuf),is_dvdnav ? "dvdnav://%d" : "dvd://%d",j); play_tree_add_file(entry,entbuf); add_entry(&last_parent,&last_entry,entry); last_entry = entry; } } else { mp_msg(MSGT_CFGPARSER, MSGL_ERR, MSGTR_InvalidPlayEntry, argv[i]); } } else { // dvd:// or dvd://x entry play_tree_add_file(entry,argv[i]); } } else { play_tree_add_file(entry,argv[i]); } // Lock stdin if it will be used as input if(strcasecmp(argv[i],"-") == 0) m_config_set_option(config,"noconsolecontrols",NULL); add_entry(&last_parent,&last_entry,entry); UNSET_GLOBAL; // We start entry specific options } } if (opt_exit) goto err_out; if(last_parent != root) mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Missing }- ?\n"); return root; err_out: play_tree_free(root,1); return NULL; }
play_tree_t* asx_parser_build_tree(char* buffer,int deep) { char *element,*asx_body,**asx_attribs,*body = NULL, **attribs; int r; play_tree_t *asx,*entry,*list = NULL; ASX_Parser_t* parser = asx_parser_new(); parser->line = 1; parser->deep = deep; r = asx_get_element(parser,&buffer,&element,&asx_body,&asx_attribs); if(r < 0) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"At line %d : Syntax error ???",parser->line); asx_parser_free(parser); return NULL; } else if(r == 0) { // No contents mp_msg(MSGT_PLAYTREE,MSGL_ERR,"empty asx element"); asx_parser_free(parser); return NULL; } if(strcasecmp(element,"ASX") != 0) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"first element isn't ASX, it's %s\n",element); asx_free_attribs(asx_attribs); asx_parser_free(parser); return NULL; } if(!asx_body) { mp_msg(MSGT_PLAYTREE,MSGL_ERR,"ASX element is empty"); asx_free_attribs(asx_attribs); asx_parser_free(parser); return NULL; } asx = play_tree_new(); buffer = asx_body; while(buffer && buffer[0] != '\0') { r = asx_get_element(parser,&buffer,&element,&body,&attribs); if(r < 0) { asx_warning_body_parse_error(parser,"ASX"); asx_parser_free(parser); return NULL; } else if (r == 0) { // No more element break; } if(strcasecmp(element,"ENTRY") == 0) { entry = asx_parse_entry(parser,body,attribs); if(entry) { if(!list) list = entry; else play_tree_append_entry(list,entry); mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to asx\n",element); } } else if(strcasecmp(element,"ENTRYREF") == 0) { entry = asx_parse_entryref(parser,body,attribs); if(entry) { if(!list) list = entry; else play_tree_append_entry(list,entry); mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to asx\n",element); } } else if(strcasecmp(element,"REPEAT") == 0) { entry = asx_parse_repeat(parser,body,attribs); if(entry) { if(!list) list = entry; else play_tree_append_entry(list,entry); mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to asx\n",element); } } else mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element); if(body) free(body); asx_free_attribs(attribs); } free(asx_body); asx_free_attribs(asx_attribs); asx_parser_free(parser); if(!list) { play_tree_free(asx,1); return NULL; } play_tree_set_child(asx,list); return asx; }
static play_tree_t* asx_parse_repeat(ASX_Parser_t* parser,char* buffer,char** _attribs) { char *element,*body,**attribs; play_tree_t *repeat, *list=NULL, *entry; char* count; int r; repeat = play_tree_new(); count = asx_get_attrib("COUNT",_attribs); if(count == NULL) { mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Setting element repeat loop to infinit\n"); repeat->loop = -1; // Infinit } else { repeat->loop = atoi(count); free(count); if(repeat->loop == 0) repeat->loop = 1; mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Setting element repeat loop to %d\n",repeat->loop); } while(buffer && buffer[0] != '\0') { r = asx_get_element(parser,&buffer,&element,&body,&attribs); if(r < 0) { asx_warning_body_parse_error(parser,"REPEAT"); return NULL; } else if (r == 0) { // No more element break; } if(strcasecmp(element,"ENTRY") == 0) { entry = asx_parse_entry(parser,body,attribs); if(entry) { if(!list) list = entry; else play_tree_append_entry(list,entry); mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to repeat\n",element); } } else if(strcasecmp(element,"ENTRYREF") == 0) { entry = asx_parse_entryref(parser,body,attribs); if(entry) { if(!list) list = entry; else play_tree_append_entry(list,entry); mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to repeat\n",element); } } else if(strcasecmp(element,"REPEAT") == 0) { entry = asx_parse_repeat(parser,body,attribs); if(entry) { if(!list) list = entry; else play_tree_append_entry(list,entry); mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Adding element %s to repeat\n",element); } } else if(strcasecmp(element,"PARAM") == 0) { asx_parse_param(parser,attribs,repeat); } else mp_msg(MSGT_PLAYTREE,MSGL_DBG2,"Ignoring element %s\n",element); if(body) free(body); asx_free_attribs(attribs); } if(!list) { play_tree_free(repeat,1); return NULL; } play_tree_set_child(repeat,list); return repeat; }