changeset 4292:1cee88ee8db5

Bug fix for subconfig option. A -tv option containing the on parameter is now take as an entry. New functions to set/get options and know if an option is alredy set. A few comments.
author albeu
date Mon, 21 Jan 2002 10:45:53 +0000
parents e889d37f25b2
children 1b6f6519b037
files cfgparser.c cfgparser.h playtree.c
diffstat 3 files changed, 387 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/cfgparser.c	Mon Jan 21 09:44:31 2002 +0000
+++ b/cfgparser.c	Mon Jan 21 10:45:53 2002 +0000
@@ -67,22 +67,21 @@
 
   if(save) {
     for(sl = 0; save[sl].opt != NULL; sl++){
-      // Check to not allocate the same arg two times
+      // Check to not save 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));
+    if(save[sl].opt)
       return;
-    }
-    memset(&save[sl],0,2*sizeof(config_save_t));
-    save[sl].opt = conf;
   }
 
+  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 :
@@ -323,6 +322,69 @@
       entry = play_tree_new();
       play_tree_add_file(entry,s);
       free(s);
+    } else if(strcasecmp(opt,"tv") == 0) {
+      char *s,*pr,*prs;
+      char *ps,*pe,*channel=NULL;
+      char *as;
+      int on=0;
+      if(!param)
+	return ERR_MISSING_PARAM;
+      ps = param;
+      pe = strchr(param,':');
+      pr = prs = (char*)malloc((strlen(param)+1)*sizeof(char));
+      pr[0] = '\0';
+      while(ps) {
+	if(!pe)
+	  pe = ps + strlen(ps);
+
+	as = strchr(ps,'=');
+	if(as && as[1] != '\0' && pe-as > 0)
+	  as++;
+	else
+	  as = NULL;
+	if( !as && pe-ps == 2 &&  strncasecmp("on",ps,2) == 0 )
+	  on = 1;
+	else if(as  && as-ps == 8  && strncasecmp("channel",ps,6) == 0 && pe-as > 0) {
+	  channel = (char*)realloc(channel,(pe-as+1)*sizeof(char));
+	  strncpy(channel,as,pe-as);
+	  channel[pe-as] = '\0';
+	} else if(pe-ps > 0) {
+	  if(prs != pr) {
+	    prs[0] = ':';
+	    prs++;
+	  }
+	  strncpy(prs,ps,pe-ps);
+	  prs += pe-ps;
+	  prs[0] = '\0';
+	}
+
+	if(pe[0] != '\0') {
+	  ps = pe+1;
+	  pe = strchr(ps,':');
+	} else
+	  ps = NULL;
+      }
+
+      if(on) {
+	int l=5;
+	
+	if(channel)
+	  l += strlen(channel);
+	s = (char*) malloc((l+1)*sizeof(char));
+	if(channel)
+	  sprintf(s,"tv://%s",channel);
+	else
+	  sprintf(s,"tv://");
+	entry = play_tree_new();
+	play_tree_add_file(entry,s);
+	if(strlen(pr) > 0)
+	  play_tree_set_param(entry,"tv",pr);
+	free(s);
+      }
+      free(pr);
+      if(channel)
+	free(channel);
+	  
     }
   }
 
@@ -394,7 +456,8 @@
 	  return ret;
 	else
 	  ret = -1;
-	if(! IS_RUNNING(config) && ! IS_GLOBAL(config) && ! (conf[i].flags & CONF_GLOBAL) )
+	if(! IS_RUNNING(config) && ! IS_GLOBAL(config) && 
+	   ! (conf[i].flags & CONF_GLOBAL)  && conf[i].type != CONF_TYPE_SUBCONFIG  )
 	  m_config_push(config);
 	if( !(conf[i].flags & CONF_NOSAVE) && ! (conf[i].flags & CONF_GLOBAL) )
 	  m_config_save_option(config,&conf[i],opt,param);
@@ -560,7 +623,7 @@
 			sublist[0] = subconf;
 			for (subconf_optnr = 0; subconf[subconf_optnr].name != NULL; subconf_optnr++)
 			    /* NOTHING */;
-
+			config->sub_conf = opt;
 			token = strtok(p, (char *)&(":"));
 			while(token)
 			{
@@ -590,7 +653,7 @@
 			    }
 			    token = strtok(NULL, (char *)&(":"));
 			}
-
+			config->sub_conf = NULL;
 			free(subparam);
 			free(subopt);
 			free(p);
@@ -605,15 +668,23 @@
 			break;
 	}
 out:
-	if(ret >= 0 && ! IS_RUNNING(config) && ! IS_GLOBAL(config) && ! (conf[i].flags & CONF_GLOBAL)) {
+	if(ret >= 0 && ! IS_RUNNING(config) && ! IS_GLOBAL(config) && ! (conf[i].flags & CONF_GLOBAL) && conf[i].type != CONF_TYPE_SUBCONFIG ) {
 	  play_tree_t* dest = config->last_entry ? config->last_entry : config->last_parent;
+	  char* o;
 #ifdef MP_DEBUG
 	  assert(dest != NULL);
 #endif
+	  if(config->sub_conf) {
+	    o = (char*)malloc((strlen(config->sub_conf) + 1 + strlen(opt) + 1)*sizeof(char));
+	    sprintf(o,"%s:%s",config->sub_conf,opt);
+	  } else
+	    o =strdup(opt);
+
 	  if(ret == 0)
-	    play_tree_set_param(dest,opt,NULL);
+	    play_tree_set_param(dest,o,NULL);
 	  else if(ret > 0)
-	    play_tree_set_param(dest,opt,param);
+	    play_tree_set_param(dest,o,param);
+	  free(o);
 	  m_config_pop(config); 
 	}
 	return ret;
@@ -624,13 +695,34 @@
 }
 
 int m_config_set_option(m_config_t *config,char *opt, char *param) {
-
+  char *e;
 #ifdef MP_DEBUG
   assert(config != NULL);
   assert(config->opt_list != NULL);
   assert(opt != NULL);
 #endif
   mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Setting option %s=%s\n",opt,param);
+  e = strchr(opt,':');
+  if(e && e[1] != '\0') {
+    int ret;
+    config_t* opt_list[] = { NULL, NULL };
+    char* s = (char*)malloc((e-opt+1)*sizeof(char));
+    strncpy(s,opt,e-opt);
+    s[e-opt] = '\0';
+    opt_list[0] = m_config_get_option_ptr(config,s);
+    if(!opt_list[0]) {
+      mp_msg(MSGT_CFGPARSER, MSGL_ERR,"m_config_set_option %s=%s : no %s subconfig\n",opt,param,s);
+      free(s);
+      return ERR_NOT_AN_OPTION;
+    }
+    e++;
+    s = (char*)realloc(s,strlen(e) + 1);
+    strcpy(s,e);
+    ret = config_read_option(config,opt_list,s,param);
+    free(s);
+    return ret;
+  }
+
   return config_read_option(config,config->opt_list,opt,param);
 }
 
@@ -942,7 +1034,7 @@
 	return -1;
 }
 
-void
+int
 m_config_register_options(m_config_t *config,config_t *args) {
   int list_len = 0;
   config_t** conf_list = config->opt_list;
@@ -960,26 +1052,42 @@
   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;
+    return 0;
   }
   conf_list[list_len] = args;
   conf_list[list_len+1] = NULL;
 
   config->opt_list = conf_list;
+
+  return 1;
 }
 
 config_t*
 m_config_get_option(m_config_t *config, char* arg) {
   int i,j;
+  char *e;
   config_t *conf;
   config_t **conf_list;
+  config_t* cl[] = { NULL, NULL };
 
 #ifdef MP_DEBUG
   assert(config != NULL);
   assert(arg != NULL);
 #endif
 
-  conf_list = config->opt_list;
+  e = strchr(arg,':');
+
+  if(e) {
+    char *s;
+    s = (char*)malloc((e-arg+1)*sizeof(char));
+    strncpy(s,arg,e-arg);
+    s[e-arg] = '\0';
+    cl[0] = m_config_get_option(config,s);
+    conf_list = cl;
+    free(s);
+  } else
+    conf_list = config->opt_list;
+
   if(conf_list) {
     for(j = 0 ; conf_list[j] != NULL ; j++) {
       conf = conf_list[j];
@@ -994,20 +1102,122 @@
 
 void*
 m_config_get_option_ptr(m_config_t *config, char* arg) {
-  config_t* conf = m_config_get_option(config,arg);
+  config_t* conf;
+
+#ifdef MP_DEBUG
+  assert(config != NULL);
+  assert(arg != NULL);
+#endif
+
+  conf = m_config_get_option(config,arg);
   if(!conf) return NULL;
   return conf->p;
 }
 
+int
+m_config_get_int (m_config_t *config, char* arg,int* err_ret) {
+  int *ret;
+
+#ifdef MP_DEBUG
+  assert(config != NULL);
+  assert(arg != NULL);
+#endif
+
+  ret = m_config_get_option_ptr(config,arg);
+  if(err_ret)
+    *err_ret = 0;
+  if(!ret) {
+    if(err_ret)
+      *err_ret = 1;
+    return -1;
+  } else
+    return (*ret);
+}
+
+float
+m_config_get_float (m_config_t *config, char* arg,int* err_ret) {
+  float *ret;
+
+#ifdef MP_DEBUG
+  assert(config != NULL);
+  assert(arg != NULL);
+#endif
+
+  ret = m_config_get_option_ptr(config,arg);
+  if(err_ret)
+    *err_ret = 0;
+  if(!ret) {
+    if(err_ret)
+      *err_ret = 1;
+    return -1;
+  } else
+    return (*ret);
+}
+
 #define AS_INT(c) (*((int*)c->p))
 
 int
+m_config_set_int(m_config_t *config, char* arg,int val) {
+  config_t* opt;
+
+#ifdef MP_DEBUG
+  assert(config != NULL);
+  assert(arg != NULL);
+#endif
+
+  opt = m_config_get_option(config,arg);
+
+  if(!opt || opt->type != CONF_TYPE_INT)
+    return ERR_NOT_AN_OPTION;
+
+  if(opt->flags & CONF_MIN && val < opt->min)
+    return ERR_OUT_OF_RANGE;
+  if(opt->flags & CONF_MAX && val > opt->max)
+    return ERR_OUT_OF_RANGE;
+
+  m_config_save_option(config,opt,arg,NULL);
+  AS_INT(opt) = val;
+
+  return 1;
+}
+
+int
+m_config_set_float(m_config_t *config, char* arg,float val) {
+  config_t* opt;
+
+#ifdef MP_DEBUG
+  assert(config != NULL);
+  assert(arg != NULL);
+#endif
+
+  opt = m_config_get_option(config,arg);
+
+  if(!opt || opt->type != CONF_TYPE_FLOAT)
+    return ERR_NOT_AN_OPTION;
+
+  if(opt->flags & CONF_MIN && val < opt->min)
+    return ERR_OUT_OF_RANGE;
+  if(opt->flags & CONF_MAX && val > opt->max)
+    return ERR_OUT_OF_RANGE;
+
+  m_config_save_option(config,opt,arg,NULL);
+  *((float*)opt->p) = val;
+
+  return 1;
+}
+
+
+int
 m_config_switch_flag(m_config_t *config, char* opt) {
   config_t *conf;
-  
+ 
+#ifdef MP_DEBUG
+  assert(config != NULL);
+  assert(opt != NULL);
+#endif
+ 
   conf = m_config_get_option(config,opt);
-  if(!conf) return 0;
-  if(conf->type != CONF_TYPE_FLAG) return 0;
+  if(!conf || conf->type != CONF_TYPE_FLAG) return 0;
   if( AS_INT(conf) == conf->min) AS_INT(conf) = conf->max;
   else if(AS_INT(conf) == conf->max) AS_INT(conf) = conf->min;
   else return 0;
@@ -1015,12 +1225,67 @@
   return 1;
 }
     
-void
-m_config_set_flag(m_config_t *config, char* opt, int max) {
+int
+m_config_set_flag(m_config_t *config, char* opt, int state) {
   config_t *conf;
+
+#ifdef MP_DEBUG
+  assert(config != NULL);
+  assert(opt != NULL);
+#endif
+
+  conf = m_config_get_option(config,opt);
+  if(!conf || conf->type != CONF_TYPE_FLAG) return 0;
+  if(state) AS_INT(conf) = conf->max;
+  else AS_INT(conf) = conf->min;
+  return 1;
+}
+
+int
+m_config_get_flag(m_config_t *config, char* opt) {
+  config_t *conf;
+
+#ifdef MP_DEBUG
+  assert(config != NULL);
+  assert(opt != NULL);
+#endif
+
   conf = m_config_get_option(config,opt);
-  if(!conf) return;
-  if(conf->type != CONF_TYPE_FLAG) return;
-  if(max) AS_INT(conf) = conf->max;
-  else AS_INT(conf) = conf->min;
+  if(!conf || conf->type != CONF_TYPE_FLAG) return -1;
+  if(AS_INT(conf) == conf->max)
+    return 1;
+  else if(AS_INT(conf) == conf->min)
+    return 0;
+  else
+    return -1;
 }
+
+int m_config_is_option_set(m_config_t *config, char* arg) {
+  config_t* opt;
+  config_save_t* save;
+  int l,i;
+
+#ifdef MP_DEBUG
+  assert(config != NULL);
+  assert(arg != NULL);
+#endif
+
+  opt = m_config_get_option(config,arg);
+
+  if(!opt) 
+    return -1;
+
+  for(l = config->cs_level ; l >= 0 ; l--) {
+    save = config->config_stack[l];
+    if(!save) 
+      continue;
+    for(i = 0 ; save[i].opt != NULL ; i++) {
+      if(save[i].opt == opt)
+	return 1;
+    }
+  }
+
+  return 0;
+}
+
+#undef AS_INT
--- a/cfgparser.h	Mon Jan 21 09:44:31 2002 +0000
+++ b/cfgparser.h	Mon Jan 21 10:45:53 2002 +0000
@@ -46,6 +46,8 @@
 	unsigned int type;
 	unsigned int flags;
 	float min,max;
+  /* Use this field when your need to do something before a new value is
+     assigned to your option */
 	cfg_default_func_t default_func;
 };
 
@@ -57,6 +59,7 @@
   int cs_level;
   int parser_mode;  /* COMMAND_LINE or CONFIG_FILE */
   int flags;
+  char* sub_conf; // When we save a subconfig
   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
@@ -87,29 +90,100 @@
 
 /* parse_command_line returns:
  * 	-1 on error (invalid option...)
- * 	 0 if there was no filename on command line
- * 	 1 if there were filenames
+ * 	 1 otherwise
  */
 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);
-
-int m_config_switch_flag(m_config_t *config, char* opt);
-
-void m_config_set_flag(m_config_t *config, char* opt, int max);
-
-void* m_config_get_option_ptr(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);
 
+/*
+ * Return 0 on error 1 on success
+ */
 int m_config_pop(m_config_t* config);
+
+/*
+ * Return 0 on error 1 on success
+ */
+int m_config_register_options(m_config_t *config,config_t *args);
+
+/*
+ * For all the following function when it's a subconfig option
+ * you must give an option name like 'tv:channel' and not just 
+ * 'channel'
+ */
+
+/*
+ * Return 1 on sucess 0 on failure
+ */
+int m_config_set_option(m_config_t *config,char *opt, char *param);
+
+/*
+ * Get the config struct defining an option
+ * Return NULL on error
+ */
+config_t* m_config_get_option(m_config_t *config, char* arg);
+
+/*
+ * Get the p field of the struct defining an option
+ * Return NULL on error
+ */
+void* m_config_get_option_ptr(m_config_t *config, char* arg);
+
+/*
+ * Tell is an option is alredy set or not
+ * Return -1 one error (requested option arg exist)
+ * Otherwise 0 or 1
+ */
+int m_config_is_option_set(m_config_t *config, char* arg);
+
+/*
+ * Return 0 on error 1 on success
+ */
+int m_config_switch_flag(m_config_t *config, char* opt);
+
+/*
+ * Return 0 on error 1 on success
+ */
+int m_config_set_flag(m_config_t *config, char* opt, int max);
+
+/*
+ * Return the value of a flag (O or 1) and -1 on error
+ */
+int m_config_get_flag(m_config_t *config, char* opt);
+
+/*
+ * Set the value of an int option
+ * Return 0 on error 1 on success
+ */
+int
+m_config_set_int(m_config_t *config, char* arg,int val);
+
+/*
+ * Get the value of an int option
+ * Return the option value or -1 on error
+ * If err_ret is not NULL it's set to 1 on error
+ */
+int
+m_config_get_int (m_config_t *config, char* arg,int* err_ret);
+
+/*
+ * Set the value of a float option
+ * Return 0 on error 1 on success
+ */
+int
+m_config_set_float(m_config_t *config, char* arg,float val);
+
+
+/*
+ * Get the value of a float option
+ * Return the option value or -1 on error
+ * If err_ret is not NULL it's set to 1 on error
+ */
+float
+m_config_get_float (m_config_t *config, char* arg,int* err_ret);
+
 #endif /* __CONFIG_H */
--- a/playtree.c	Mon Jan 21 09:44:31 2002 +0000
+++ b/playtree.c	Mon Jan 21 10:45:53 2002 +0000
@@ -403,8 +403,9 @@
 
   
   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",
+    int e;
+    if((e = m_config_set_option(iter->config,pt->params[n].name,pt->params[n].value)) < 0) {
+      mp_msg(MSGT_PLAYTREE,MSGL_ERR,"Error %d while setting option '%s' with value '%s'\n",e,
 	     pt->params[n].name,pt->params[n].value);      
     }
   }