From ef4a38a54e18b59df94dccfd9f819281b88ce579 Mon Sep 17 00:00:00 2001 From: arpi Date: Mon, 14 Jan 2002 23:38:49 +0000 Subject: playtree-based config patch by Alban Bedel git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@4157 b3059339-0415-0410-9bf9-f77b7e298cf2 --- Makefile | 4 +- cfgparser.c | 534 ++++++++++++++++++++++++++++++++++++++++++++++--------- cfgparser.h | 63 ++++++- dec_video.c | 4 + mencoder.c | 31 +++- mplayer.c | 132 ++++++++------ playtree.c | 150 +++++++++++----- playtree.h | 27 +-- playtreeparser.c | 5 +- 9 files changed, 741 insertions(+), 209 deletions(-) diff --git a/Makefile b/Makefile index 7e074981e6..c718fee605 100644 --- a/Makefile +++ b/Makefile @@ -27,9 +27,9 @@ MANDIR = ${prefix}/man # a BSD compatible 'install' program INSTALL = install -SRCS_COMMON = cyuv.c adpcm.c xacodec.c cpudetect.c mp_msg.c ac3-iec958.c dec_audio.c dec_video.c msvidc.c cinepak.c fli.c qtrle.c codec-cfg.c cfgparser.c my_profile.c RTjpegN.c minilzo.c nuppelvideo.c spudec.c +SRCS_COMMON = cyuv.c adpcm.c xacodec.c cpudetect.c mp_msg.c ac3-iec958.c dec_audio.c dec_video.c msvidc.c cinepak.c fli.c qtrle.c codec-cfg.c cfgparser.c my_profile.c RTjpegN.c minilzo.c nuppelvideo.c spudec.c playtree.c playtreeparser.c asxparser.c SRCS_MENCODER = mencoder.c $(SRCS_COMMON) libao2/afmt.c divx4_vbr.c libvo/aclib.c libvo/img_format.c libvo/osd.c -SRCS_MPLAYER = mplayer.c $(SRCS_COMMON) find_sub.c subreader.c lirc_mp.c mixer.c playtree.c playtreeparser.c asxparser.c vobsub.c +SRCS_MPLAYER = mplayer.c $(SRCS_COMMON) find_sub.c subreader.c lirc_mp.c mixer.c vobsub.c OBJS_MENCODER = $(SRCS_MENCODER:.c=.o) OBJS_MPLAYER = $(SRCS_MPLAYER:.c=.o) diff --git a/cfgparser.c b/cfgparser.c index efa42ad367..69b87b777e 100644 --- a/cfgparser.c +++ b/cfgparser.c @@ -15,6 +15,7 @@ #include #include #include +#include "config.h" #include "mp_msg.h" @@ -23,84 +24,345 @@ #define MAX_RECURSION_DEPTH 8 -#ifdef DEBUG +#ifdef MP_DEBUG #include #endif #include "cfgparser.h" -static struct config *config; -static int nr_options; /* number of options in 'conf' */ -static int parser_mode; /* COMMAND_LINE or CONFIG_FILE */ -static int recursion_depth = 0; -static int init_conf(struct config *conf, int mode) -{ -#ifdef DEBUG - assert(conf != NULL); + +static void +m_config_save_option(m_config_t* config, config_t* conf,char* opt, char *param) { + config_save_t* save; + int sl=0; + +#ifdef MP_DEBUG + assert(config != NULL); + assert(config->cs_level >= 0); + assert(conf != NULL); + assert(opt != NULL); + assert( ! (conf->flags & CONF_NOSAVE)); +#endif + + switch(conf->type) { + case CONF_TYPE_PRINT : + case CONF_TYPE_SUBCONFIG : + return; + default : + } + + mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Saving option %s\n",opt); + + save = config->config_stack[config->cs_level]; + + if(save) { + for(sl = 0; save[sl].opt != NULL; sl++){ + // Check to not allocate the same arg two times + if(save[sl].opt == conf && (save[sl].opt_name == NULL || strcasecmp(save[sl].opt_name,opt) == 0)) + break; + } + + } + if(save == NULL || save[sl].opt == NULL) { + save = (config_save_t*)realloc(save,(sl+2)*sizeof(config_save_t)); + if(save == NULL) { + mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Can't allocate %d bytes of memory : %s\n",(sl+2)*sizeof(config_save_t),strerror(errno)); + return; + } + memset(&save[sl],0,2*sizeof(config_save_t)); + save[sl].opt = conf; + } + + + switch(conf->type) { + case CONF_TYPE_FLAG : + case CONF_TYPE_INT : + save[sl].param.as_int = *((int*)conf->p); + break; + case CONF_TYPE_FLOAT : + save[sl].param.as_float = *((float*)conf->p); + break; + case CONF_TYPE_STRING : + save[sl].param.as_pointer = *((char**)conf->p); + break; + case CONF_TYPE_FUNC_FULL : + if(strcasecmp(conf->name,opt) != 0) save->opt_name = strdup(opt); + case CONF_TYPE_FUNC_PARAM : + save->param.as_pointer = strdup(param); + case CONF_TYPE_FUNC : + break; + default : + printf("Should never append in m_config_save_option : conf->type=%d\n",conf->type); + } + + config->config_stack[config->cs_level] = save; +} + +static int +m_config_revert_option(m_config_t* config, config_save_t* save) { + char* arg = NULL; + config_save_t* iter=NULL; + int i=-1; + +#ifdef MP_DEBUG + assert(config != NULL); + assert(config->cs_level >= 0); + assert(save != NULL); +#endif + + + arg = save->opt_name ? save->opt_name : save->opt->name; + mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Reverting option %s\n",arg); + + if(save->opt->default_func) + save->opt->default_func(save->opt,arg); + + switch(save->opt->type) { + case CONF_TYPE_FLAG : + case CONF_TYPE_INT : + *((int*)save->opt->p) = save->param.as_int; + break; + case CONF_TYPE_FLOAT : + *((float*)save->opt->p) = save->param.as_float; + break; + case CONF_TYPE_STRING : + *((char**)save->opt->p) = save->param.as_pointer; + break; + case CONF_TYPE_FUNC_PARAM : + case CONF_TYPE_FUNC_FULL : + case CONF_TYPE_FUNC : + if(config->cs_level > 0) { + for(i = config->cs_level - 1 ; i >= 0 ; i--){ + if(config->config_stack[i] == NULL) continue; + for(iter = config->config_stack[i]; iter != NULL && iter->opt != NULL ; iter++) { + if(iter->opt == save->opt && + strcasecmp(save->param.as_pointer,iter->param.as_pointer) == 0 && + (save->opt_name == NULL || + (iter->opt_name && strcasecmp(save->opt_name,iter->opt_name)))) break; + } + } + } + free(save->param.as_pointer); + if(save->opt_name) free(save->opt_name); + save->opt_name = save->param.as_pointer = NULL; + if(i < 0) break; + arg = iter->opt_name ? iter->opt_name : iter->opt->name; + switch(iter->opt->type) { + case CONF_TYPE_FUNC : + if ((((cfg_func_t) iter->opt->p)(iter->opt)) < 0) + return -1; + break; + case CONF_TYPE_FUNC_PARAM : + if (iter->param.as_pointer == NULL) { + printf("We lost param for option %s?\n",iter->opt->name); + return -1; + } + if ((((cfg_func_param_t) iter->opt->p)(iter->opt, (char*)iter->param.as_pointer)) < 0) + return -1; + break; + case CONF_TYPE_FUNC_FULL : + if (iter->param.as_pointer != NULL && ((char*)iter->param.as_pointer)[0]=='-'){ + if( ((cfg_func_arg_param_t) iter->opt->p)(iter->opt, arg, NULL) < 0) + return -1; + }else { + if (((cfg_func_arg_param_t) save->opt->p)(iter->opt, arg, (char*)iter->param.as_pointer) < 0) + return -1; + + } + break; + } + break; + default : + printf("Why do we reverse this : name=%s type=%d ?\n",save->opt->name,save->opt->type); + } + + return 1; +} + +void +m_config_push(m_config_t* config) { + +#ifdef MP_DEBUG + assert(config != NULL); + assert(config->cs_level >= 0); #endif - /* calculate the number of options in 'conf' */ - for (nr_options = 0; conf[nr_options].name != NULL; nr_options++) - /* NOTHING */; + config->cs_level++; + config->config_stack = (config_save_t**)realloc(config->config_stack ,sizeof(config_save_t*)*(config->cs_level+1)); + if(config->config_stack == NULL) { + mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Can't allocate %d bytes of memory : %s\n",sizeof(config_save_t*)*(config->cs_level+1),strerror(errno)); + config->cs_level = -1; + return; + } + config->config_stack[config->cs_level] = NULL; + mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config pushed level=%d\n",config->cs_level); +} + +int +m_config_pop(m_config_t* config) { + int i,ret= 1; + config_save_t* cs; + +#ifdef MP_DEBUG + assert(config != NULL); + assert(config->cs_level > 0); +#endif + + if(config->config_stack[config->cs_level] != NULL) { + cs = config->config_stack[config->cs_level]; + for(i=0; cs[i].opt != NULL ; i++ ) { + if (m_config_revert_option(config,&cs[i]) < 0) + ret = -1; + } + free(config->config_stack[config->cs_level]); + } + config->config_stack = (config_save_t**)realloc(config->config_stack ,sizeof(config_save_t*)*config->cs_level); + config->cs_level--; + if(config->cs_level > 0 && config->config_stack == NULL) { + mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Can't allocate %d bytes of memory : %s\n",sizeof(config_save_t*)*config->cs_level,strerror(errno)); + config->cs_level = -1; + return -1; + } + mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config poped level=%d\n",config->cs_level); + return ret; +} + +m_config_t* +m_config_new(play_tree_t* pt) { + m_config_t* config; + +#ifdef MP_DEBUG + assert(pt != NULL); +#endif + + config = (m_config_t*)calloc(1,sizeof(m_config_t)); + if(config == NULL) { + mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Can't allocate %d bytes of memory : %s\n",sizeof(m_config_t),strerror(errno)); + return NULL; + } + config->config_stack = (config_save_t**)calloc(1,sizeof(config_save_t*)); + if(config->config_stack == NULL) { + mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Can't allocate %d bytes of memory : %s\n",sizeof(config_save_t*),strerror(errno)); + free(config); + return NULL; + } + config->global = 1; // We always start with global options + config->pt = pt; + return config; +} + +void +m_config_free(m_config_t* config) { + +#ifdef MP_DEBUG + assert(config != NULL); +#endif + + free(config->opt_list); + free(config->config_stack); + free(config); +} + + +static int init_conf(m_config_t *config, int mode) +{ +#ifdef MP_DEBUG + assert(config != NULL); + assert(config->pt != NULL); + assert(config->last_entry == NULL || config->last_entry->parent == config->pt); - config = conf; -#ifdef DEBUG if (mode != COMMAND_LINE && mode != CONFIG_FILE) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, "init_conf: wrong mode!\n"); return -1; } #endif - parser_mode = mode; + config->parser_mode = mode; + config->global = 1; return 1; } -static int read_option(struct config *conf, int conf_optnr, char *opt, char *param) + +static int config_read_option(m_config_t *config,config_t** conf_list, char *opt, char *param) { - int i; + int i=0,nconf = 0; long tmp_int; double tmp_float; int ret = -1; char *endptr; + config_t* conf=NULL; - mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "read_option: conf=%p optnr=%d opt='%s' param='%s'\n", - conf, conf_optnr, opt, param); - for (i = 0; i < conf_optnr; i++) { - int namelength; - /* allow 'aa*' in config.name */ - namelength=strlen(conf[i].name); - if ( (conf[i].name[namelength-1]=='*') && - !memcmp(opt, conf[i].name, namelength-1)) - break; - - - if (!strcasecmp(opt, conf[i].name)) +#ifdef MP_DEBUG + assert(config != NULL); + assert(conf_list != NULL); + assert(opt != NULL); +#endif + + mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "read_option: conf=%p opt='%s' param='%s'\n", + conf, opt, param); + for(nconf = 0 ; conf_list&& conf_list[nconf] != NULL; nconf++) { + conf = conf_list[nconf]; + for (i = 0; conf[i].name != NULL; i++) { + int namelength; + /* allow 'aa*' in config.name */ + namelength=strlen(conf[i].name); + if ( (conf[i].name[namelength-1]=='*') && + !memcmp(opt, conf[i].name, namelength-1)) + break; + if (!strcasecmp(opt, conf[i].name)) break; + } } - if (i == conf_optnr) { - if (parser_mode == CONFIG_FILE) - mp_msg(MSGT_CFGPARSER, MSGL_ERR, "invalid option: %s\n", opt); + if (conf[i].name == NULL) { + if (config->parser_mode == CONFIG_FILE) + mp_msg(MSGT_CFGPARSER, MSGL_ERR, "invalid option:\n"); ret = ERR_NOT_AN_OPTION; goto out; } mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "read_option: name='%s' p=%p type=%d\n", conf[i].name, conf[i].p, conf[i].type); - if (conf[i].flags & CONF_NOCFG && parser_mode == CONFIG_FILE) { - mp_msg(MSGT_CFGPARSER, MSGL_ERR, "this option can only be used on command line: %s\n", opt); + if (conf[i].flags & CONF_NOCFG && config->parser_mode == CONFIG_FILE) { + mp_msg(MSGT_CFGPARSER, MSGL_ERR, "this option can only be used on command line:\n", opt); ret = ERR_NOT_AN_OPTION; goto out; } - if (conf[i].flags & CONF_NOCMD && parser_mode == COMMAND_LINE) { - mp_msg(MSGT_CFGPARSER, MSGL_ERR, "this option can only be used in config file: %s\n", opt); + if (conf[i].flags & CONF_NOCMD && config->parser_mode == COMMAND_LINE) { + mp_msg(MSGT_CFGPARSER, MSGL_ERR, "this option can only be used in config file:\n", opt); ret = ERR_NOT_AN_OPTION; goto out; } - + if(strcasecmp(opt,"playlist") == 0) { // We handle playlist here + play_tree_t* list; +#ifdef MP_DEBUG + assert(config->pt != NULL); +#endif + if(!param) { + mp_msg(MSGT_CFGPARSER, MSGL_ERR, "playlist option need a filename\n"); + ret = ERR_MISSING_PARAM; + goto out; + } + list = parse_playlist_file(param); + if(list) { + if(config->last_entry) { + play_tree_append_entry(config->last_entry,list); + } + else + play_tree_set_child(config->pt,list); + config->last_entry = list; + } + if(config->parser_mode == COMMAND_LINE) + config->global = 0; + return 1; + } + if(config->global == 0 && ! (conf[i].flags & CONF_GLOBAL) ) + m_config_push(config); + if( !(conf[i].flags & CONF_NOSAVE) && ! (conf[i].flags & CONF_GLOBAL) ) + m_config_save_option(config,&conf[i],opt,param); switch (conf[i].type) { case CONF_TYPE_FLAG: /* flags need a parameter in config file */ - if (parser_mode == CONFIG_FILE) { + if (config->parser_mode == CONFIG_FILE) { if (!strcasecmp(param, "yes") || /* any other language? */ !strcasecmp(param, "ja") || !strcasecmp(param, "si") || @@ -214,7 +476,7 @@ static int read_option(struct config *conf, int conf_optnr, char *opt, char *par case CONF_TYPE_FUNC_PARAM: if (param == NULL) goto err_missing_param; - if ((((cfg_func_param_t) conf[i].p)(config + i, param)) < 0) { + if ((((cfg_func_param_t) conf[i].p)(conf + i, param)) < 0) { ret = ERR_FUNC_ERR; goto out; } @@ -222,17 +484,17 @@ static int read_option(struct config *conf, int conf_optnr, char *opt, char *par break; case CONF_TYPE_FUNC_FULL: if (param!=NULL && param[0]=='-'){ - ret=((cfg_func_arg_param_t) conf[i].p)(config + i, opt, NULL); + ret=((cfg_func_arg_param_t) conf[i].p)(conf + i, opt, NULL); if (ret>=0) ret=0; /* if we return >=0: param is processed again (if there is any) */ }else{ - ret=((cfg_func_arg_param_t) conf[i].p)(config + i, opt, param); + ret=((cfg_func_arg_param_t) conf[i].p)(conf + i, opt, param); /* if we return 0: need no param, precess it again */ /* if we return 1: accepted param */ } break; case CONF_TYPE_FUNC: - if ((((cfg_func_t) conf[i].p)(config + i)) < 0) { + if ((((cfg_func_t) conf[i].p)(conf + i)) < 0) { ret = ERR_FUNC_ERR; goto out; } @@ -243,9 +505,9 @@ static int read_option(struct config *conf, int conf_optnr, char *opt, char *par char *subparam; char *subopt; int subconf_optnr; - struct config *subconf; + config_t *subconf; + config_t *sublist[] = { NULL , NULL }; char *token; - int sscanf_ret; if (param == NULL) goto err_missing_param; @@ -254,16 +516,17 @@ static int read_option(struct config *conf, int conf_optnr, char *opt, char *par subopt = malloc(strlen(param)+1); subconf = conf[i].p; + sublist[0] = subconf; for (subconf_optnr = 0; subconf[subconf_optnr].name != NULL; subconf_optnr++) /* NOTHING */; token = strtok(param, (char *)&(":")); while(token) { + int sscanf_ret; /* clear out */ subopt[0] = subparam[0] = 0; -// sscanf_ret = sscanf(token, "%[^=]=%[^\n\0]", subopt, subparam); sscanf_ret = sscanf(token, "%[^=]=%s", subopt, subparam); mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "token: '%s', i=%d, subopt='%s', subparam='%s' (ret: %d)\n", token, i, subopt, subparam, sscanf_ret); @@ -272,7 +535,7 @@ static int read_option(struct config *conf, int conf_optnr, char *opt, char *par case 1: subparam[0] = 0; case 2: - if ((ret = read_option((struct config *)subconf, subconf_optnr, subopt, subparam)) < 0) + if ((ret = config_read_option(config,sublist, subopt, subparam)) < 0) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Subconfig parsing returned error: %d in token: %s\n", ret, token); @@ -300,6 +563,17 @@ static int read_option(struct config *conf, int conf_optnr, char *opt, char *par break; } out: + if(config->global == 0 && ! (conf[i].flags & CONF_GLOBAL)) { + play_tree_t* dest = config->last_entry ? config->last_entry : config->last_parent; +#ifdef MP_DEBUG + assert(dest != NULL); +#endif + if(ret == 0) + play_tree_set_param(dest,opt,NULL); + else if(ret > 0) + play_tree_set_param(dest,opt,param); + m_config_pop(config); + } return ret; err_missing_param: mp_msg(MSGT_CFGPARSER, MSGL_ERR, "missing parameter for option: %s\n", opt); @@ -307,7 +581,17 @@ err_missing_param: goto out; } -int parse_config_file(struct config *conf, char *conffile) +int m_config_set_option(m_config_t *config,char *opt, char *param) { + +#ifdef MP_DEBUG + assert(config != NULL); + assert(opt != NULL); +#endif + mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Setting option %s=%s\n",opt,param); + return config_read_option(config,config->opt_list,opt,param); +} + +int m_config_parse_config_file(m_config_t *config, char *conffile) { #define PRINT_LINENUM printf("%s(%d): ", conffile, line_num) #define MAX_LINE_LEN 1000 @@ -326,19 +610,20 @@ int parse_config_file(struct config *conf, char *conffile) int ret = 1; int errors = 0; -#ifdef DEBUG - assert(conffile != NULL); +#ifdef MP_DEBUG + assert(config != NULL); + // assert(conf_list != NULL); #endif - if (++recursion_depth > 1) + if (++config->recursion_depth > 1) printf("Reading config file: %s", conffile); - if (recursion_depth > MAX_RECURSION_DEPTH) { + if (config->recursion_depth > MAX_RECURSION_DEPTH) { printf(": too deep 'include'. check your configfiles\n"); ret = -1; goto out; } - if (init_conf(conf, CONFIG_FILE) == -1) { + if (init_conf(config, CONFIG_FILE) == -1) { ret = -1; goto out; } @@ -350,13 +635,13 @@ int parse_config_file(struct config *conf, char *conffile) } if ((fp = fopen(conffile, "r")) == NULL) { - if (recursion_depth > 1) + if (config->recursion_depth > 1) printf(": %s\n", strerror(errno)); free(line); ret = 0; goto out; } - if (recursion_depth > 1) + if (config->recursion_depth > 1) printf("\n"); while (fgets(line, MAX_LINE_LEN, fp)) { @@ -399,7 +684,7 @@ int parse_config_file(struct config *conf, char *conffile) } opt[opt_pos] = '\0'; -#ifdef DEBUG +#ifdef MP_DEBUG PRINT_LINENUM; printf("option: %s\n", opt); #endif @@ -460,7 +745,7 @@ int parse_config_file(struct config *conf, char *conffile) continue; } -#ifdef DEBUG +#ifdef MP_DEBUG PRINT_LINENUM; printf("parameter: %s\n", param); #endif @@ -477,7 +762,7 @@ int parse_config_file(struct config *conf, char *conffile) ret = -1; } - tmp = read_option(config, nr_options, opt, param); + tmp = m_config_set_option(config, opt, param); switch (tmp) { case ERR_NOT_AN_OPTION: case ERR_MISSING_PARAM: @@ -497,33 +782,34 @@ nextline: free(line); fclose(fp); out: - --recursion_depth; + --config->recursion_depth; return ret; } -int parse_command_line(struct config *conf, int argc, char **argv, char **envp, char ***filenames) +int m_config_parse_command_line(m_config_t *config, int argc, char **argv, char **envp) { int i; - char **f = NULL; - int f_nr = 0; int tmp; char *opt; int no_more_opts = 0; -#ifdef DEBUG +#ifdef MP_DEBUG + assert(config != NULL); + assert(config->pt != NULL); assert(argv != NULL); assert(envp != NULL); assert(argc >= 1); #endif - - if (init_conf(conf, COMMAND_LINE) == -1) - return -1; - + + if (init_conf(config, COMMAND_LINE) == -1) + return -1; + if(config->last_parent == NULL) + config->last_parent = config->pt; /* in order to work recursion detection properly in parse_config_file */ - ++recursion_depth; + ++config->recursion_depth; for (i = 1; i < argc; i++) { -next: + //next: opt = argv[i]; /* check for -- (no more options id.) except --help! */ if ((*opt == '-') && (*(opt+1) == '-') && (*(opt+2) != 'h')) @@ -534,9 +820,32 @@ next: mp_msg(MSGT_CFGPARSER, MSGL_ERR, "You added '--' but no filenames presented!\n"); goto err_out; } - i++; - goto next; + continue; } + if((opt[0] == '{') && (opt[1] == '\0')) + { + play_tree_t* entry = play_tree_new(); + config->global = 0; + if(config->last_entry == NULL) { + play_tree_set_child(config->last_parent,entry); + } else { + play_tree_append_entry(config->last_entry,entry); + config->last_entry = NULL; + } + config->last_parent = entry; + continue; + } + + if((opt[0] == '}') && (opt[1] == '\0')) + { + if( ! config->last_parent || ! config->last_parent->parent) { + mp_msg(MSGT_CFGPARSER, MSGL_ERR, "too much }-\n"); + goto err_out; + } + config->last_entry = config->last_parent; + config->last_parent = config->last_entry->parent; + continue; + } if ((no_more_opts == 0) && (*opt == '-') && (*(opt+1) != 0)) /* option */ { @@ -544,8 +853,7 @@ next: opt++; mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "this_opt = option: %s\n", opt); - - tmp = read_option(config, nr_options, opt, argv[i + 1]); + tmp = m_config_set_option(config, opt, argv[i + 1]); switch (tmp) { case ERR_NOT_AN_OPTION: @@ -562,26 +870,82 @@ next: } else /* filename */ { - mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "this_opt = filename: %s\n", opt); - + play_tree_t* entry = play_tree_new(); + mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Adding file %s\n",argv[i]); + play_tree_add_file(entry,argv[i]); /* opt is not an option -> treat it as a filename */ - if (!(f = (char **) realloc(f, sizeof(*f) * (f_nr + 2)))) - goto err_out_mem; - - f[f_nr++] = argv[i]; + config->global = 0; // We start entry specific options + if(config->last_entry == NULL) + play_tree_set_child(config->last_parent,entry); + else + play_tree_append_entry(config->last_entry,entry); + config->last_entry = entry; } } - if (f) - f[f_nr] = NULL; - if (filenames) - *filenames = f; - --recursion_depth; - return f_nr; //filenames_nr; + --config->recursion_depth; + if(config->last_parent != config->pt) + mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Missing }- ?\n"); + config->global = 1; + return 1; +#if 0 err_out_mem: mp_msg(MSGT_CFGPARSER, MSGL_ERR, "can't allocate memory for filenames (%s)\n", strerror(errno)); +#endif err_out: - --recursion_depth; + --config->recursion_depth; + config->global = 1; mp_msg(MSGT_CFGPARSER, MSGL_ERR, "command line: %s\n", argv[i]); return -1; } + +void +m_config_register_options(m_config_t *config,config_t *args) { + int list_len = 0; + config_t** conf_list = config->opt_list; + +#ifdef MP_DEBUG + assert(config != NULL); + assert(args != NULL); +#endif + + if(conf_list) { + for ( ; conf_list[list_len] != NULL; list_len++) + /* NOTHING */; + } + + conf_list = (config_t**)realloc(conf_list,sizeof(struct conf*)*(list_len+2)); + if(conf_list == NULL) { + mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Can't allocate %d bytes of memory : %s\n",sizeof(struct conf*)*(list_len+2),strerror(errno)); + return; + } + conf_list[list_len] = args; + conf_list[list_len+1] = NULL; + + config->opt_list = conf_list; +} + +config_t* +m_config_get_option(m_config_t *config, char* arg) { + int i; + config_t *conf; + config_t **conf_list; + +#ifdef MP_DEBUG + assert(config != NULL); + assert(arg != NULL); +#endif + + conf_list = config->opt_list; + if(conf_list) { + for(conf = conf_list[0]; conf != NULL ; conf ++) { + for(i=0; conf[i].name != NULL; i++) { + if(strcasecmp(conf[i].name,arg) == 0) + return &conf[i]; + } + } + } + return NULL; +} + + diff --git a/cfgparser.h b/cfgparser.h index 54c924da32..bf4ccb6870 100644 --- a/cfgparser.h +++ b/cfgparser.h @@ -28,6 +28,17 @@ #define CONF_RANGE (CONF_MIN|CONF_MAX) #define CONF_NOCFG (1<<2) #define CONF_NOCMD (1<<3) +#define CONF_GLOBAL (1<<4) +#define CONF_NOSAVE (1<<5) + + +typedef struct config config_t; +typedef struct m_config m_config_t; +typedef struct config_save config_save_t; + +#include "playtree.h" + +typedef void (*cfg_default_func_t)(config_t *, char*); struct config { char *name; @@ -35,24 +46,64 @@ struct config { unsigned int type; unsigned int flags; float min,max; + cfg_default_func_t default_func; +}; + + + +struct m_config { + config_t** opt_list; + config_save_t** config_stack; + int cs_level; + int parser_mode; /* COMMAND_LINE or CONFIG_FILE */ + int global; // Are we parsing global option + play_tree_t* pt; // play tree we use for playlist option, etc + play_tree_t* last_entry; // last added entry + play_tree_t* last_parent; // if last_entry is NULL we must create child of this + int recursion_depth; +}; + +struct config_save { + config_t* opt; + union { + int as_int; + float as_float; + void* as_pointer; + } param; + char* opt_name; }; -typedef int (*cfg_func_arg_param_t)(struct config *, char *, char *); -typedef int (*cfg_func_param_t)(struct config *, char *); -typedef int (*cfg_func_t)(struct config *); + +typedef int (*cfg_func_arg_param_t)(config_t *, char *, char *); +typedef int (*cfg_func_param_t)(config_t *, char *); +typedef int (*cfg_func_t)(config_t *); /* parse_config_file returns: * -1 on error (can't malloc, invalid option...) * 0 if can't open configfile * 1 on success */ -int parse_config_file(struct config *conf, char *conffile); +int m_config_parse_config_file(m_config_t *config, char *conffile); /* parse_command_line returns: * -1 on error (invalid option...) * 0 if there was no filename on command line - * >=1 if there were filenames + * 1 if there were filenames */ -int parse_command_line(struct config *conf, int argc, char **argv, char **envp, char ***filenames); +int m_config_parse_command_line(m_config_t* config, int argc, char **argv, char **envp); + + +void m_config_register_options(m_config_t *config,config_t *args); + +int m_config_set_option(m_config_t *config,char *opt, char *param); + +config_t* m_config_get_option(m_config_t *config, char* arg); + +m_config_t* m_config_new(play_tree_t* pt); + +void m_config_free(m_config_t* config); + +void m_config_push(m_config_t* config); +int m_config_pop(m_config_t* config); #endif /* __CONFIG_H */ diff --git a/dec_video.c b/dec_video.c index 0f500a313c..7a5ac2f0dc 100644 --- a/dec_video.c +++ b/dec_video.c @@ -331,6 +331,10 @@ void uninit_video(sh_video_t *sh_video){ xacodec_exit(); break; #endif + case VFM_DIVX4: + case VFM_ODIVX: + decore(0x123,DEC_OPT_RELEASE,NULL,NULL); + break; } if(sh_video->our_out_buffer){ free(sh_video->our_out_buffer); diff --git a/mencoder.c b/mencoder.c index b6d2522623..d01af2f442 100644 --- a/mencoder.c +++ b/mencoder.c @@ -31,6 +31,7 @@ static char* banner_text= #include "stream.h" #include "demuxer.h" #include "stheader.h" +#include "playtree.h" #include "aviwrite.h" @@ -171,10 +172,12 @@ static int vo_w=0, vo_h=0; #include "cfgparser.h" +m_config_t* mconfig; + static int cfg_inc_verbose(struct config *conf){ ++verbose; return 0;} static int cfg_include(struct config *conf, char *filename){ - return parse_config_file(conf, filename); + return m_config_parse_config_file(mconfig, filename); } #include "get_path.c" @@ -340,9 +343,9 @@ float audio_preload=0.5; double v_pts_corr=0; double v_timer_corr=0; -char** filenames=NULL; +play_tree_t* playtree; +play_tree_iter_t* playtree_iter; char* filename=NULL; -int num_filenames; int decoded_frameno=0; @@ -378,16 +381,30 @@ divx4_param.rc_reaction_period = 10; divx4_param.rc_reaction_ratio = 20; #endif - num_filenames=parse_command_line(conf, argc, argv, envp, &filenames); - if(num_filenames<0) exit(1); // error parsing cmdline - if(!num_filenames && !vcd_track && !dvd_title && !tv_param_on){ + playtree = play_tree_new(); + mconfig = m_config_new(playtree); + m_config_register_options(mconfig,mencoder_opts); + + if(m_config_parse_command_line(mconfig, argc, argv, envp) < 0) exit(1); // error parsing cmdline + playtree = play_tree_cleanup(playtree); + if(playtree) { + playtree_iter = play_tree_iter_new(playtree,mconfig); + if(playtree_iter) { + if(play_tree_iter_step(playtree_iter,0,0) != PLAY_TREE_ITER_ENTRY) { + play_tree_iter_free(playtree_iter); + playtree_iter = NULL; + } + filename = play_tree_iter_get_file(playtree_iter,1); + } + } + + if(!filename && !vcd_track && !dvd_title && !tv_param_on){ printf("\nMissing filename!\n\n"); exit(1); } mp_msg_init(verbose+MSGL_STATUS); - filename=(num_filenames>0)?filenames[0]:NULL; stream=open_stream(filename,vcd_track,&file_format); if(!stream){ diff --git a/mplayer.c b/mplayer.c index 0597adea84..2f99326255 100644 --- a/mplayer.c +++ b/mplayer.c @@ -97,6 +97,19 @@ extern tvi_handle_t *tv_handler; play_tree_t* playtree; +#define PT_NEXT_ENTRY 1 +#define PT_PREV_ENTRY -1 +#define PT_NEXT_SRC 2 +#define PT_PREV_SRC -2 +#define PT_UP_NEXT 3 +#define PT_UP_PREV -3 + +//**************************************************************************// +// Config +//**************************************************************************// + +m_config_t* mconfig; + //**************************************************************************// // Config file //**************************************************************************// @@ -104,7 +117,7 @@ play_tree_t* playtree; static int cfg_inc_verbose(struct config *conf){ ++verbose; return 0;} static int cfg_include(struct config *conf, char *filename){ - return parse_config_file(conf, filename); + return m_config_parse_config_file(mconfig, filename); } #include "get_path.c" @@ -234,6 +247,10 @@ static int fullscreen=0; static int vidmode=0; static int softzoom=0; static int flip=-1; +// We need this opt_* because the values are then calculated so the options use the opt_* +// and before each file we reset the calculated value using this opt_* values +static int opt_screen_size_x=0;//SCREEN_SIZE_X; +static int opt_screen_size_y=0;//SCREEN_SIZE_Y; static int screen_size_x=0;//SCREEN_SIZE_X; static int screen_size_y=0;//SCREEN_SIZE_Y; static int screen_size_xy=0; @@ -373,11 +390,11 @@ void exit_sighandler(int x){ #include "mixer.h" #include "cfg-mplayer.h" -void parse_cfgfiles( void ) +void parse_cfgfiles( m_config_t* conf ) { char *conffile; int conffile_fd; -if (parse_config_file(conf, "/etc/mplayer.conf") < 0) +if (m_config_parse_config_file(conf, "/etc/mplayer.conf") < 0) exit(1); if ((conffile = get_path("")) == NULL) { mp_msg(MSGT_CPLAYER,MSGL_WARN,MSGTR_NoHomeDir); @@ -392,7 +409,7 @@ if ((conffile = get_path("")) == NULL) { write(conffile_fd, default_config, strlen(default_config)); close(conffile_fd); } - if (parse_config_file(conf, conffile) < 0) + if (m_config_parse_config_file(conf, conffile) < 0) exit(1); free(conffile); } @@ -417,13 +434,10 @@ static sh_video_t *sh_video=NULL; // for multifile support: play_tree_iter_t* playtree_iter = NULL; -char **filenames=NULL; -int num_filenames=0; -int curr_filename=0; char* filename=NULL; //"MI2-Trailer.avi"; int file_format=DEMUXER_TYPE_UNKNOWN; -// + int delay_corrected=1; char* title="MPlayer"; @@ -493,36 +507,20 @@ int gui_no_filename=0; (strrchr(argv[0],'/') && !strcmp(strrchr(argv[0],'/'),"/gmplayer") ) ) use_gui=1; - parse_cfgfiles(); - num_filenames=parse_command_line(conf, argc, argv, envp, &filenames); - if(num_filenames<0) exit(1); // error parsing cmdline - playtree = play_tree_new(); - { - play_tree_t* list = NULL; - int i; - play_tree_t *entry = NULL, *tree = play_tree_new(); - for(i= 0; i < num_filenames ; i++) { - entry = entry != NULL ? play_tree_new() : tree; - play_tree_add_file(entry,filenames[i]); - play_tree_append_entry(tree,entry); - } - - entry = play_tree_new(); - play_tree_set_child(entry,tree); - list = entry; - if(playlist_file!=NULL) { - entry = parse_playlist_file(playlist_file); - if(entry != NULL){ - if(list) play_tree_append_entry(list,entry); - else list = entry; - } - } - if(list) play_tree_set_child(playtree,list); - } + + mconfig = m_config_new(playtree); + m_config_register_options(mconfig,mplayer_opts); + // TODO : add something to let modules register their options + parse_cfgfiles(mconfig); + + + + if(m_config_parse_command_line(mconfig, argc, argv, envp) < 0) exit(1); // error parsing cmdline + playtree = play_tree_cleanup(playtree); if(playtree) { - playtree_iter = play_tree_iter_new(playtree); + playtree_iter = play_tree_iter_new(playtree,mconfig); if(playtree_iter) { if(play_tree_iter_step(playtree_iter,0,0) != PLAY_TREE_ITER_ENTRY) { play_tree_iter_free(playtree_iter); @@ -606,7 +604,6 @@ if(!parse_codec_cfg(get_path("codecs.conf"))){ printf("CommandLine:"); for(i=1;icodec->outfmt[i]; - if(out_fmt==0xFFFFFFFF) continue; + if(out_fmt==(signed int)0xFFFFFFFF) continue; #ifdef USE_LIBVO2 vo_flags=vo2_query_format(video_out); #else @@ -1223,10 +1220,12 @@ current_module="init_libvo"; if(!screen_size_xy) screen_size_xy=vo_screenwidth; // scale with asp.ratio } #endif + // Set default VGA 1:1 aspect as fallback ::atmos if(movie_aspect>-1.0) sh_video->aspect = movie_aspect; // cmdline overrides autodetect // if(!sh_video->aspect) sh_video->aspect=1.0; - + screen_size_x = opt_screen_size_x; + screen_size_y = opt_screen_size_y; if(screen_size_xy||screen_size_x||screen_size_y){ if(screen_size_xy>0){ if(screen_size_xy<=8){ @@ -1829,7 +1828,9 @@ if(auto_quality>0){ #endif if(osd_function==OSD_PAUSE){ +#ifdef HAVE_NEW_GUI int gui_pause_flag=0; // gany! +#endif mp_msg(MSGT_CPLAYER,MSGL_STATUS,"\n------ PAUSED -------\r");fflush(stdout); #ifdef HAVE_NEW_GUI if(use_gui) mplShMem->Playing=2; @@ -1963,18 +1964,10 @@ if(step_sec>0) { break; // quit case KEY_ESC: // ESC - case 'q': exit_player(MSGTR_Exit_quit); - case '>': - if(curr_filename>=num_filenames-1) - break; + case 'q': + exit_player(MSGTR_Exit_quit); case KEY_ENTER: // ESC - eof=2; // jump to next file - break; - case '<': - if(curr_filename < 1) - break; - curr_filename-=2; - eof=2; + eof=1; // force jump to next file : quit if no next file break; case 'g': grab_frames=2;break; // pause @@ -1985,26 +1978,42 @@ if(step_sec>0) { case KEY_HOME: { play_tree_iter_t* i = play_tree_iter_new_copy(playtree_iter); - if(play_tree_iter_step(i,1,0) == PLAY_TREE_ITER_ENTRY) - eof = 1; + if(play_tree_iter_up_step(i,1,0) == PLAY_TREE_ITER_ENTRY) + eof = PT_UP_NEXT; play_tree_iter_free(i); } break; case KEY_END: + { + play_tree_iter_t* i = play_tree_iter_new_copy(playtree_iter); + if(play_tree_iter_up_step(i,-1,0) == PLAY_TREE_ITER_ENTRY) + eof = PT_UP_PREV; + play_tree_iter_free(i); + } + break; + case '>': + { + play_tree_iter_t* i = play_tree_iter_new_copy(playtree_iter); + if(play_tree_iter_step(i,1,0) == PLAY_TREE_ITER_ENTRY) + eof = PT_NEXT_ENTRY; + play_tree_iter_free(i); + } + break; + case '<': { play_tree_iter_t* i = play_tree_iter_new_copy(playtree_iter); if(play_tree_iter_step(i,-1,0) == PLAY_TREE_ITER_ENTRY) - eof = -1; + eof = PT_PREV_ENTRY; play_tree_iter_free(i); } break; case KEY_INS: if(playtree_iter->num_files > 1 && playtree_iter->file < playtree_iter->num_files) - eof = 2; + eof = PT_NEXT_SRC; break; case KEY_DEL: if(playtree_iter->num_files > 1 && playtree_iter->file > 1) - eof = -2; + eof = PT_PREV_SRC; break; case 'o': // toggle OSD osd_level=(osd_level+1)%3; @@ -2345,7 +2354,7 @@ mp_msg(MSGT_GLOBAL,MSGL_V,"EOF code: %d \n",eof); goto_next_file: // don't jump here after ao/vo/getch initialization! -if(eof == 1 || eof == -1) { +if(eof == PT_NEXT_ENTRY || eof == PT_PREV_ENTRY) { if(play_tree_iter_step(playtree_iter,eof,0) == PLAY_TREE_ITER_ENTRY) { uninit_player(INITED_ALL-(INITED_GUI+INITED_LIRC)); eof = 1; @@ -2353,9 +2362,18 @@ if(eof == 1 || eof == -1) { play_tree_iter_free(playtree_iter); playtree_iter = NULL; } -} else { +} else if (eof == PT_UP_NEXT || eof == PT_UP_PREV) { + eof = eof == PT_UP_NEXT ? 1 : -1; + if(play_tree_iter_up_step(playtree_iter,eof,0) == PLAY_TREE_ITER_ENTRY) { + uninit_player(INITED_ALL-(INITED_GUI+INITED_LIRC)); + eof = 1; + } else { + play_tree_iter_free(playtree_iter); + playtree_iter = NULL; + } +}else { // NEXT PREV SRC uninit_player(INITED_ALL-(INITED_GUI+INITED_LIRC)); - eof = eof == -2 ? -1 : 1; + eof = eof == PT_PREV_SRC ? -1 : 1; } goto_next_file_src: // When we have multiple src for file diff --git a/playtree.c b/playtree.c index 4f1944397d..119f5374e8 100644 --- a/playtree.c +++ b/playtree.c @@ -1,9 +1,12 @@ +#include "config.h" #include #include #include #include +#ifdef MP_DEBUG #include +#endif #include "playtree.h" #include "mp_msg.h" @@ -22,7 +25,7 @@ void play_tree_free(play_tree_t* pt, int childs) { play_tree_t* iter; -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); #endif @@ -52,7 +55,7 @@ void play_tree_free_list(play_tree_t* pt, int childs) { play_tree_t* iter; -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); #endif @@ -69,7 +72,7 @@ void play_tree_append_entry(play_tree_t* pt, play_tree_t* entry) { play_tree_t* iter; -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); assert(entry != NULL); #endif @@ -90,7 +93,7 @@ void play_tree_prepend_entry(play_tree_t* pt, play_tree_t* entry) { play_tree_t* iter; -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); assert(entry != NULL); #endif @@ -104,7 +107,7 @@ play_tree_prepend_entry(play_tree_t* pt, play_tree_t* entry) { iter->prev = entry; if(entry->parent) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(entry->parent->child == iter); #endif entry->parent->child = entry; @@ -114,7 +117,7 @@ play_tree_prepend_entry(play_tree_t* pt, play_tree_t* entry) { void play_tree_insert_entry(play_tree_t* pt, play_tree_t* entry) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); assert(entry != NULL); #endif @@ -122,7 +125,7 @@ play_tree_insert_entry(play_tree_t* pt, play_tree_t* entry) { entry->parent = pt->parent; entry->prev = pt; if(pt->next) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt->next->prev == pt); #endif entry->next = pt->next; @@ -136,13 +139,13 @@ play_tree_insert_entry(play_tree_t* pt, play_tree_t* entry) { void play_tree_remove(play_tree_t* pt, int free_it,int with_childs) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); #endif // Middle of list if(pt->prev && pt->next) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt->prev->next == pt); assert(pt->next->prev == pt); #endif @@ -150,25 +153,25 @@ play_tree_remove(play_tree_t* pt, int free_it,int with_childs) { pt->next->prev = pt->prev; } // End of list else if(pt->prev) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt->prev->next == pt); #endif pt->prev->next = NULL; } // Begining of list else if(pt->next) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt->next->prev == pt); #endif pt->next->prev = NULL; if(pt->parent) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt->parent->child == pt); #endif pt->parent->child = pt->next; } } // The only one else if(pt->parent) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt->parent->child == pt); #endif pt->parent->child = NULL; @@ -184,7 +187,7 @@ void play_tree_set_child(play_tree_t* pt, play_tree_t* child) { play_tree_t* iter; -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); assert(pt->files == NULL); #endif @@ -207,7 +210,7 @@ void play_tree_set_parent(play_tree_t* pt, play_tree_t* parent) { play_tree_t* iter; -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); #endif @@ -232,7 +235,7 @@ void play_tree_add_file(play_tree_t* pt,char* file) { int n = 0; -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); assert(pt->child == NULL); assert(file != NULL); @@ -257,7 +260,7 @@ int play_tree_remove_file(play_tree_t* pt,char* file) { int n,f = -1; -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); assert(file != NULL); assert(pt->files != NULL); @@ -271,7 +274,7 @@ play_tree_remove_file(play_tree_t* pt,char* file) { if(f < 0) // Not found return 0; -#ifdef DEBUG +#ifdef MP_DEBUG assert(n > f); #endif @@ -292,12 +295,11 @@ play_tree_remove_file(play_tree_t* pt,char* file) { return 1; } -#if 0 void play_tree_set_param(play_tree_t* pt, char* name, char* val) { int n = 0,ni = -1; -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); assert(name != NULL); #endif @@ -325,9 +327,9 @@ play_tree_set_param(play_tree_t* pt, char* name, char* val) { int play_tree_unset_param(play_tree_t* pt, char* name) { - int n,ni = 0; + int n,ni = -1; -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); assert(name != NULL); assert(pt->params != NULL); @@ -341,10 +343,16 @@ play_tree_unset_param(play_tree_t* pt, char* name) { if(ni < 0) return 0; + if(pt->params[ni].name) free(pt->params[ni].name); + if(pt->params[ni].value) free(pt->params[ni].value); + if(n > 1) { memmove(&pt->params[ni],&pt->params[ni+1],(n-ni)*sizeof(play_tree_param_t)); pt->params = (play_tree_param_t*)realloc(pt->params,n*sizeof(play_tree_param_t)); - assert(pt->params != NULL); + if(pt->params == NULL) { + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Can't allocate %d bytes of memory\n",n*sizeof(play_tree_param_t)); + return -1; + } } else { free(pt->params); pt->params = NULL; @@ -353,14 +361,53 @@ play_tree_unset_param(play_tree_t* pt, char* name) { return 1; } +static int +play_tree_iter_push_params(play_tree_iter_t* iter) { + int n; + play_tree_t* pt; +#ifdef MP_DEBUG + assert(iter != NULL); + assert(iter->config != NULL); + assert(iter->tree != NULL); +#endif + + pt = iter->tree; + + if(pt->params == NULL) + return 0; + + m_config_push(iter->config); + for(n = 0; pt->params[n].name != NULL ; n++) { + if(m_config_set_option(iter->config,pt->params[n].name,pt->params[n].value) < 0) { + mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Error while setting option '%s' with value '%s'\n", + pt->params[n].name,pt->params[n].value); + } + } + //printf("Param pushed\n"); + return 1; +} + +static void +play_tree_iter_pop_params(play_tree_iter_t* iter) { + +#ifdef MP_DEBUG + assert(iter != NULL); + assert(iter->config != NULL); #endif + if(iter->tree->params == NULL) + return; + //printf("Poping params\n"); + m_config_pop(iter->config); +} + play_tree_iter_t* -play_tree_iter_new(play_tree_t* pt) { +play_tree_iter_new(play_tree_t* pt,m_config_t* config) { play_tree_iter_t* iter; -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); + assert(config != NULL); #endif if( ! play_tree_is_valid(pt)) @@ -370,6 +417,7 @@ play_tree_iter_new(play_tree_t* pt) { if(! iter) return NULL; iter->root = pt; iter->tree = NULL; + iter->config = config; if(pt->parent) iter->loop = pt->parent->loop; @@ -380,12 +428,12 @@ play_tree_iter_new(play_tree_t* pt) { void play_tree_iter_free(play_tree_iter_t* iter) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(iter != NULL); #endif if(iter->status_stack) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(iter->stack_size > 0); #endif free(iter->status_stack); @@ -398,9 +446,10 @@ int play_tree_iter_step(play_tree_iter_t* iter, int d,int with_nodes) { play_tree_t* pt; -#ifdef DEBUG +#ifdef MP_DEBUG assert(iter != NULL); assert(iter->root != NULL); + //printf("PT : Stepping = %d\n",d); #endif if(iter->tree == NULL) { @@ -408,6 +457,11 @@ play_tree_iter_step(play_tree_iter_t* iter, int d,int with_nodes) { return play_tree_iter_step(iter,0,with_nodes); } + if(iter->config && iter->entry_pushed) { + play_tree_iter_pop_params(iter); + iter->entry_pushed = 0; + } + iter->file = 0; if( d > 0 ) pt = iter->tree->next; @@ -454,14 +508,17 @@ play_tree_iter_step(play_tree_iter_t* iter, int d,int with_nodes) { return play_tree_iter_step(iter,d,with_nodes); } -#ifdef DEBUG - assert(iter->tree->files != NULL); +#ifdef MP_DEBUG + assert(pt->files != NULL); #endif iter->tree = pt; for(d = 0 ; iter->tree->files[d] != NULL ; d++) /* NOTHING */; iter->num_files = d; + + if(iter->config) + iter->entry_pushed = play_tree_iter_push_params(iter); return PLAY_TREE_ITER_ENTRY; @@ -471,7 +528,7 @@ static int play_tree_is_valid(play_tree_t* pt) { play_tree_t* iter; -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); #endif @@ -489,22 +546,22 @@ play_tree_is_valid(play_tree_t* pt) { int play_tree_iter_up_step(play_tree_iter_t* iter, int d,int with_nodes) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(iter != NULL); assert(iter->tree != NULL); + //printf("PT : Go UP\n"); #endif iter->file = 0; if(iter->tree->parent == iter->root->parent) return PLAY_TREE_ITER_END; -#ifdef DEBUG +#ifdef MP_DEBUG assert(iter->tree->parent != NULL); assert(iter->stack_size > 0); assert(iter->status_stack != NULL); #endif - - // Pop status + iter->stack_size--; iter->loop = iter->status_stack[iter->stack_size]; iter->status_stack = (int*)realloc(iter->status_stack,iter->stack_size*sizeof(int)); @@ -513,20 +570,30 @@ play_tree_iter_up_step(play_tree_iter_t* iter, int d,int with_nodes) { return PLAY_TREE_ITER_ERROR; } iter->tree = iter->tree->parent; + + // Pop subtree params + if(iter->config) + play_tree_iter_pop_params(iter); + return play_tree_iter_step(iter,d,with_nodes); } int play_tree_iter_down_step(play_tree_iter_t* iter, int d,int with_nodes) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(iter->tree->files == NULL); assert(iter->tree->child != NULL); assert(iter->tree->child->parent == iter->tree); + //printf("PT : Go DOWN\n"); #endif iter->file = 0; - // Push status + + // Push subtree params + if(iter->config) + play_tree_iter_push_params(iter); + iter->stack_size++; iter->status_stack = (int*)realloc(iter->status_stack,iter->stack_size*sizeof(int)); if(iter->status_stack == NULL) { @@ -544,13 +611,14 @@ play_tree_iter_down_step(play_tree_iter_t* iter, int d,int with_nodes) { /*NOTING*/; iter->tree = pt; } + return play_tree_iter_step(iter,0,with_nodes); } char* play_tree_iter_get_file(play_tree_iter_t* iter, int d) { -#ifdef DEBUG +#ifdef MP_DEBUG assert(iter != NULL); assert(iter->tree->child == NULL); #endif @@ -574,7 +642,7 @@ play_tree_t* play_tree_cleanup(play_tree_t* pt) { play_tree_t* iter, *tmp, *first; -#ifdef DEBUG +#ifdef MP_DEBUG assert(pt != NULL); #endif @@ -608,7 +676,7 @@ play_tree_iter_t* play_tree_iter_new_copy(play_tree_iter_t* old) { play_tree_iter_t* iter; -#ifdef DEBUG +#ifdef MP_DEBUG assert(old != NULL); #endif @@ -628,5 +696,7 @@ play_tree_iter_new_copy(play_tree_iter_t* old) { } memcpy(iter->status_stack,old->status_stack,iter->stack_size*sizeof(int)); } + iter->config = NULL; + return iter; } diff --git a/playtree.h b/playtree.h index ef293ec2b7..f6636a27af 100644 --- a/playtree.h +++ b/playtree.h @@ -1,6 +1,10 @@ +#ifndef __PLAYTREE_H +#define __PLAYTREE_H + #include "libmpdemux/stream.h" + #define PLAY_TREE_ITER_ERROR 0 #define PLAY_TREE_ITER_ENTRY 1 #define PLAY_TREE_ITER_NODE 2 @@ -8,11 +12,12 @@ typedef struct play_tree play_tree_t; typedef struct play_tree_iter play_tree_iter_t; +typedef struct play_tree_param play_tree_param_t; + +#include "cfgparser.h" #if 0 typedef struct play_tree_info play_tree_info_t; -typedef struct play_tree_param play_tree_param_t; - // TODO : a attrib,val pair system and not something hardcoded struct play_tree_info { char* title; @@ -21,12 +26,13 @@ struct play_tree_info { char* abstract; // Some more ?? } +#endif struct play_tree_param { char* name; char* value; -} -#endif +}; + struct play_tree { play_tree_t* parent; @@ -35,8 +41,7 @@ struct play_tree { play_tree_t* prev; //play_tree_info_t info; - //int n_param; - //play_tree_param_t* params; + play_tree_param_t* params; int loop; char** files; }; @@ -44,10 +49,11 @@ struct play_tree { struct play_tree_iter { play_tree_t* root; // Iter root tree play_tree_t* tree; // Current tree - // struct m_config* config; + m_config_t* config; int loop; // Looping status int file; int num_files; + int entry_pushed; int* status_stack; // loop/valid stack to save/revert status when we go up/down int stack_size; // status stack size @@ -97,7 +103,6 @@ int play_tree_remove_file(play_tree_t* pt,char* file); -#if 0 // Val can be NULL void play_tree_set_param(play_tree_t* pt, char* name, char* val); @@ -105,13 +110,11 @@ play_tree_set_param(play_tree_t* pt, char* name, char* val); int play_tree_unset_param(play_tree_t* pt, char* name); -#endif - /// Iterator play_tree_iter_t* -play_tree_iter_new(play_tree_t* pt); +play_tree_iter_new(play_tree_t* pt, m_config_t* config); play_tree_iter_t* play_tree_iter_new_copy(play_tree_iter_t* old); @@ -142,3 +145,5 @@ play_tree_cleanup(play_tree_t* pt); play_tree_t* parse_playlist_file(char* file); + +#endif diff --git a/playtreeparser.c b/playtreeparser.c index 19dc14c209..0d0ba72625 100644 --- a/playtreeparser.c +++ b/playtreeparser.c @@ -1,8 +1,11 @@ +#include "config.h" #include #include #include +#ifdef MP_DEBUG #include +#endif #include #include #include @@ -240,7 +243,7 @@ play_tree_t* parse_playtree(stream_t *stream) { play_tree_t* tree = NULL; -#ifdef DEBUG +#ifdef MP_DEBUG assert(stream != NULL); assert(stream->type == STREAMTYPE_PLAYLIST); #endif -- cgit v1.2.3