⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 m_option.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 3 页
字号:
  }  ret[n*2] = ret[n*2+1] = NULL;    *_ret = ret;    return 1;}static int parse_obj_params(m_option_t* opt,char *name,			    char *param, void* dst, int src) {  char** opts;  int r;  m_obj_params_t* p = opt->priv;  m_struct_t* desc = p->desc;  char* cpy = strdup(param);    // We need the object desc  if(!p)    return M_OPT_INVALID;    r = get_obj_params(name,desc->name,cpy,desc,p->separator,&opts);  free(cpy);  if(r < 0)    return r;  if(!dst)    return 1;  for(r = 0 ; opts[r] ; r += 2)    m_struct_set(desc,dst,opts[r],opts[r+1]);  return 1;     }m_option_type_t m_option_type_obj_params = {  "Object params",  "",  0,  0,  parse_obj_params,  NULL,  NULL,  NULL,  NULL,  NULL};/// Some predefined types as a definition would be quite lengthy/// Span argumentsstatic m_span_t m_span_params_dflts = { -1, -1 };static m_option_t m_span_params_fields[] = {  {"start", M_ST_OFF(m_span_t,start), CONF_TYPE_INT, M_OPT_MIN, 1 ,0, NULL},  {"end", M_ST_OFF(m_span_t,end), CONF_TYPE_INT, M_OPT_MIN , 1 ,0, NULL},  { NULL, NULL, 0, 0, 0, 0,  NULL }};static struct m_struct_st m_span_opts = {  "m_span",  sizeof(m_span_t),  &m_span_params_dflts,  m_span_params_fields};m_obj_params_t m_span_params_def = {  &m_span_opts,  '-'};static int parse_obj_settings(char* opt,char* str,m_obj_list_t* list,			      m_obj_settings_t **_ret, int ret_n) {  int r;  char *param,**plist = NULL;  m_struct_t* desc;  m_obj_settings_t *ret = _ret ? *_ret : NULL;    // Now check that the object exists  param = strchr(str,'=');  if(param) {    param[0] = '\0';    param++;    if(strlen(param) <= 0)      param = NULL;  }  if(!find_obj_desc(str,list,&desc)) {    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: %s doesn't exist.\n",opt,str);    return M_OPT_INVALID;  }  if(param) {    if(!desc && _ret) {      plist = calloc(4,sizeof(char*));      plist[0] = strdup("_oldargs_");      plist[1] = strdup(param);    } else if(desc) {      r = get_obj_params(opt,str,param,desc,':',_ret ? &plist : NULL);      if(r < 0)	return r;    }  }  if(!_ret)    return 1;  ret = realloc(ret,(ret_n+2)*sizeof(m_obj_settings_t));  memset(&ret[ret_n],0,2*sizeof(m_obj_settings_t));  ret[ret_n].name = strdup(str);  ret[ret_n].attribs = plist;  *_ret = ret;  return 1;}static void free_obj_settings_list(void* dst);static int obj_settings_list_del(char *opt_name,char *param,void* dst, int src) {  char** str_list = NULL;  int r,i,idx_max = 0;  char* rem_id = "_removed_marker_";  m_option_t list_opt = {opt_name , NULL, CONF_TYPE_STRING_LIST,			   0, 0, 0, NULL };  m_obj_settings_t* obj_list = dst ? VAL(dst) : NULL;  if(dst && !obj_list) {    mp_msg(MSGT_CFGPARSER, MSGL_WARN, "Option %s: the list is empty.\n",opt_name);    return 1;  } else if(obj_list) {    for(idx_max = 0 ; obj_list[idx_max].name != NULL ; idx_max++)      /* NOP */;  }  r = m_option_parse(&list_opt,opt_name,param,&str_list,src);  if(r < 0 || !str_list)    return r;  for(r = 0 ; str_list[r] ; r++) {    int id;    char* endptr;    id = strtol(str_list[r],&endptr,0);    if(endptr == str_list[r]) {      mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: invalid parameter. We need a list of integers which are the indices of the elements to remove.\n",opt_name);      m_option_free(&list_opt,&str_list);      return M_OPT_INVALID;    }    if(!obj_list) continue;    if(id >= idx_max || id < -idx_max) {      mp_msg(MSGT_CFGPARSER, MSGL_WARN, "Option %s: Index %d is out of range.\n",opt_name,id);      continue;    }    if(id < 0)      id = idx_max + id;    free(obj_list[id].name);    free_str_list(&(obj_list[id].attribs));    obj_list[id].name = rem_id;  }  if(!dst) {    m_option_free(&list_opt,&str_list);    return 1;  }  for(i = 0 ; obj_list[i].name ; i++) {    while(obj_list[i].name == rem_id) {      memmove(&obj_list[i],&obj_list[i+1],sizeof(m_obj_settings_t)*(idx_max - i));      idx_max--;    }  }  obj_list = realloc(obj_list,sizeof(m_obj_settings_t)*(idx_max+1));  VAL(dst) = obj_list;  return 1;}static int parse_obj_settings_list(m_option_t* opt,char *name,				   char *param, void* dst, int src) {  int n = 0,r,len = strlen(opt->name);  char *str;  char *ptr, *last_ptr;  m_obj_settings_t *res = NULL,*queue = NULL,*head = NULL;  int op = OP_NONE;  // We need the objects list  if(!opt->priv)    return M_OPT_INVALID;  if(opt->name[len-1] == '*' && ((int)strlen(name) > len - 1)) {    char* n = &name[len-1];    if(strcasecmp(n,"-add") == 0)      op = OP_ADD;    else if(strcasecmp(n,"-pre") == 0)      op = OP_PRE;    else if(strcasecmp(n,"-del") == 0)      op = OP_DEL;    else if(strcasecmp(n,"-clr") == 0)      op = OP_CLR;    else {      char prefix[len];      strncpy(prefix,opt->name,len-1);      prefix[len-1] = '\0';      mp_msg(MSGT_VFILTER,MSGL_ERR, "Option %s: unknown postfix %s\n"	     "Supported postfixes are:\n"	     "  %s-add\n"	     " Append the given list to the current list\n\n"	     "  %s-pre\n"	     " Prepend the given list to the current list\n\n"	     "  %s-del x,y,...\n"	     " Remove the given elements. Take the list element index (starting from 0).\n"	     " Negative index can be used (i.e. -1 is the last element)\n\n"	     "  %s-clr\n"	     " Clear the current list.\n",name,n,prefix,prefix,prefix,prefix);            return M_OPT_UNKNOWN;    }  }  // Clear the list ??  if(op == OP_CLR) {    if(dst)      free_obj_settings_list(dst);    return 0;  }  if (param == NULL || strlen(param) == 0)    return M_OPT_MISSING_PARAM;  switch(op) {  case OP_ADD:    if(dst) head = VAL(dst);    break;  case OP_PRE:    if(dst) queue = VAL(dst);     break;  case OP_DEL:    return obj_settings_list_del(name,param,dst,src);  case OP_NONE:    if(dst && VAL(dst))      free_obj_settings_list(dst);    break;  default:    mp_msg(MSGT_VFILTER,MSGL_ERR, "Option %s: FIXME\n",name);    return M_OPT_UNKNOWN;  }  if(!strcmp(param,"help")) {    m_obj_list_t* ol = opt->priv;    mp_msg(MSGT_VFILTER,MSGL_INFO,"Available video filters:\n");    for(n = 0 ; ol->list[n] ; n++)      mp_msg(MSGT_VFILTER,MSGL_INFO,"  %-15s: %s\n",	     M_ST_MB(char*,ol->list[n],ol->name_off),	     M_ST_MB(char*,ol->list[n],ol->info_off));    return M_OPT_EXIT;  }  ptr = str = strdup(param);  while(ptr[0] != '\0') {    last_ptr = ptr;    ptr = strchr(ptr,LIST_SEPARATOR);    if(!ptr) {      r = parse_obj_settings(name,last_ptr,opt->priv,dst ? &res : NULL,n);      if(r < 0) {	free(str);	return r;      }      n++;      break;    }    ptr[0] = '\0';    r = parse_obj_settings(name,last_ptr,opt->priv,dst ? &res : NULL,n);    if(r < 0) {      free(str);      return r;    }    ptr++;    n++;  }  free(str);  if(n == 0)    return M_OPT_INVALID;  if( ((opt->flags & M_OPT_MIN) && (n < opt->min)) ||       ((opt->flags & M_OPT_MAX) && (n > opt->max)) )    return M_OPT_OUT_OF_RANGE;    if(dst) {    if(queue) {      int qsize;      for(qsize = 0 ; queue[qsize].name ; qsize++)	/* NOP */;      res = realloc(res,(qsize+n+1)*sizeof(m_obj_settings_t));      memcpy(&res[n],queue,(qsize+1)*sizeof(m_obj_settings_t));      n += qsize;      free(queue);    }    if(head) {      int hsize;      for(hsize = 0 ; head[hsize].name ; hsize++)	/* NOP */;      head = realloc(head,(hsize+n+1)*sizeof(m_obj_settings_t));      memcpy(&head[hsize],res,(n+1)*sizeof(m_obj_settings_t));      free(res);      res = head;    }          VAL(dst) = res;  }  return 1;}static void free_obj_settings_list(void* dst) {  int n;  m_obj_settings_t *d;  if(!dst || !VAL(dst)) return;  d = VAL(dst);#ifndef NO_FREE  for(n = 0 ; d[n].name ; n++) {    free(d[n].name);    free_str_list(&(d[n].attribs));  }  free(d);#endif  VAL(dst) = NULL;}static void copy_obj_settings_list(m_option_t* opt,void* dst, void* src) {  m_obj_settings_t *d,*s;  int n;  if(!(dst && src))    return;  s = VAL(src);  if(VAL(dst))    free_obj_settings_list(dst);  if(!s) return;            for(n = 0 ; s[n].name ; n++)    /* NOP */;  d = malloc((n+1)*sizeof(m_obj_settings_t));  for(n = 0 ; s[n].name ; n++) {    d[n].name = strdup(s[n].name);    d[n].attribs = NULL;    copy_str_list(NULL,&(d[n].attribs),&(s[n].attribs));  }  d[n].name = NULL;  d[n].attribs = NULL;  VAL(dst) = d;}m_option_type_t m_option_type_obj_settings_list = {  "Object settings list",  "",  sizeof(m_obj_settings_t*),  M_OPT_TYPE_DYNAMIC|M_OPT_TYPE_ALLOW_WILDCARD,  parse_obj_settings_list,  NULL,  copy_obj_settings_list,  copy_obj_settings_list,  copy_obj_settings_list,  free_obj_settings_list,};static int parse_obj_presets(m_option_t* opt,char *name,			    char *param, void* dst, int src) {  m_obj_presets_t* obj_p = (m_obj_presets_t*)opt->priv;  m_struct_t *in_desc,*out_desc;  int s,i;  unsigned char* pre = obj_p->presets;  char* pre_name = NULL;  if(!obj_p) {    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Presets need a pointer to a m_obj_presets_t in the priv field.\n",name);    return M_OPT_PARSER_ERR;  }  if(!param)    return M_OPT_MISSING_PARAM;  in_desc = obj_p->in_desc;  out_desc = obj_p->out_desc ? obj_p->out_desc : obj_p->in_desc;  s = in_desc->size;  if(!strcmp(param,"help")) {    mp_msg(MSGT_CFGPARSER, MSGL_INFO, "Available presets for %s->%s:",out_desc->name,name);    for(pre = obj_p->presets;(pre_name = M_ST_MB(char*,pre,obj_p->name_off)) ; 	pre +=  s)       mp_msg(MSGT_CFGPARSER, MSGL_ERR, " %s",pre_name);    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "\n");    return M_OPT_EXIT;  }  for(pre_name = M_ST_MB(char*,pre,obj_p->name_off) ; pre_name ;      pre +=  s, pre_name = M_ST_MB(char*,pre,obj_p->name_off)) {    if(!strcmp(pre_name,param)) break;  }  if(!pre_name) {    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: There is no preset named %s\n"	   "Available presets are:",name,param);    for(pre = obj_p->presets;(pre_name = M_ST_MB(char*,pre,obj_p->name_off)) ; 	pre +=  s)       mp_msg(MSGT_CFGPARSER, MSGL_ERR, " %s",pre_name);    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "\n");    return M_OPT_INVALID;  }  if(!dst) return 1;    for(i = 0 ; in_desc->fields[i].name ; i++) {    m_option_t* out_opt = m_option_list_find(out_desc->fields,					     in_desc->fields[i].name);    if(!out_opt) {      mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Unable to find the target option for field %s.\nPlease report this to the developers.\n",name,in_desc->fields[i].name);      return M_OPT_PARSER_ERR;    }    m_option_copy(out_opt,M_ST_MB_P(dst,out_opt->p),M_ST_MB_P(pre,in_desc->fields[i].p));  }  return 1;}m_option_type_t m_option_type_obj_presets = {  "Object presets",  "",  0,  0,  parse_obj_presets,  NULL,  NULL,  NULL,  NULL,  NULL};static int parse_custom_url(m_option_t* opt,char *name,			    char *url, void* dst, int src) {  int pos1, pos2, r, v6addr = 0;  char *ptr1=NULL, *ptr2=NULL, *ptr3=NULL, *ptr4=NULL;  m_struct_t* desc = opt->priv;    if(!desc) {    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Custom URL needs a pointer to a m_struct_t in the priv field.\n",name);    return M_OPT_PARSER_ERR;  }  // extract the protocol  ptr1 = strstr(url, "://");  if( ptr1==NULL ) {    // Filename only    if(m_option_list_find(desc->fields,"filename")) {      m_struct_set(desc,dst,"filename",url);      return 1;    }    mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Option %s: URL doesn't have a valid protocol!\n",name);    return M_OPT_INVALID;  }  pos1 = ptr1-url;  if(dst && m_option_list_find(desc->fields,"protocol")) {    ptr1[0] = '\0';    r = m_struct_set(desc,dst,"protocol",url);    ptr1[0] = ':';    if(r < 0) {      mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Error while setting protocol.\n",name);      return r;    }  }  // jump the "://"  ptr1 += 3;  pos1 += 3;  // check if a username:password is given  ptr2 = strstr(ptr1, "@");  ptr3 = strstr(ptr1, "/");  if( ptr3!=NULL && ptr3<ptr2 ) {    // it isn't really a username but rather a part of the path    ptr2 = NULL;  }  if( ptr2!=NULL ) {        // We got something, at least a username...    int len = ptr2-ptr1;    if(!m_option_list_find(desc->fields,"username")) {      mp_msg(MSGT_CFGPARSER, MSGL_WARN, "Option %s: This URL doesn't have a username part.\n",name);      // skip    } else {      ptr3 = strstr(ptr1, ":");      if( ptr3!=NULL && ptr3<ptr2 ) {	// We also have a password	int len2 = ptr2-ptr3-1;	if(!m_option_list_find(desc->fields,"password")) {	  mp_msg(MSGT_CFGPARSER, MSGL_WARN, "Option %s: This URL doesn't have a password part.\n",name);	  // skip	} else { // Username and password   	  if(dst) {	    ptr3[0] = '\0';	    r = m_struct_set(desc,dst,"username",ptr1);	    ptr3[0] = ':';	    if(r < 0) {	      mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Error while setting username.\n",name);	      return r;	    }	    ptr2[0] = '\0';	    r = m_struct_set(desc,dst,"password",ptr3+1);	    ptr2[0] = '@';	    if(r < 0) {	      mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Error while setting password.\n",name);	      return r;	    }	  }	}      } else { // User name only	ptr2[0] = '\0';	r = m_struct_set(desc,dst,"username",ptr1);	ptr2[0] = '@';	if(r < 0) {	  mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Error while setting username.\n",name);	  return r;	}      }    }    ptr1 = ptr2+1;    pos1 = ptr1-url;  }  // before looking for a port number check if we have an IPv6 type numeric address  // in an IPv6 URL the numeric address should be inside square braces.  ptr2 = strstr(ptr1, "[");  ptr3 = strstr(ptr1, "]");  // If the [] is after the first it isn't the hostname  ptr4 = strstr(ptr1, "/");  if( ptr2!=NULL && ptr3!=NULL && (ptr2 < ptr3) && (!ptr4 || ptr4 > ptr3)) {    // we have an IPv6 numeric address    ptr1++;    pos1++;    ptr2 = ptr3;    v6addr = 1;  } else {    ptr2 = ptr1;    }  // look if the port is given  ptr2 = strstr(ptr2, ":");  // If the : is after the first / it isn't the port  ptr3 = strstr(ptr1, "/");  if(ptr3 && ptr3 - ptr2 < 0) ptr2 = NULL;  if( ptr2==NULL ) {    // No port is given    // Look if a path is given    if( ptr3==NULL ) {      // No path/filename      // So we have an URL like http://www.hostname.com      pos2 = strlen(url);    } else {      // We have an URL like http://www.hostname.com/file.txt      pos2 = ptr3-url;    }  } else {    // We have an URL beginning like http://www.hostname.com:1212    // Get the port number    if(!m_option_list_find(desc->fields,"port")) {      mp_msg(MSGT_CFGPARSER, MSGL_WARN, "Option %s: This URL doesn't have a port part.\n",name);      // skip    } else {      if(dst) {	int p = atoi(ptr2+1);	char tmp[100];	snprintf(tmp,99,"%d",p);	r = m_struct_set(desc,dst,"port",tmp);	if(r < 0) {	  mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Error while setting port.\n",name);	  return r;	}      }    }    pos2 = ptr2-url;  }  if( v6addr ) pos2--;  // Get the hostname  if(pos2-pos1 > 0) {    if(!m_option_list_find(desc->fields,"hostname")) {      mp_msg(MSGT_CFGPARSER, MSGL_WARN, "Option %s: This URL doesn't have a hostname part.\n",name);      // skip    } else {      char tmp[pos2-pos1+1];      strncpy(tmp,ptr1, pos2-pos1);      tmp[pos2-pos1] = '\0';      r = m_struct_set(desc,dst,"hostname",tmp);      if(r < 0) {	mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Error while setting hostname.\n",name);	return r;      }    }  }  // Look if a path is given  ptr2 = strstr(ptr1, "/");  if( ptr2!=NULL ) {    // A path/filename is given    // check if it's not a trailing '/'    if( strlen(ptr2)>1 ) {      // copy the path/filename in the URL container      if(!m_option_list_find(desc->fields,"filename")) {	mp_msg(MSGT_CFGPARSER, MSGL_WARN, "Option %s: This URL doesn't have a hostname part.\n",name);	// skip      } else {	if(dst) {	  int l = strlen(ptr2+1) + 1;	  char* fname = ptr2+1;	  if(l > 1) {	    fname = malloc(l);	    url_unescape_string(fname,ptr2+1);	  }	  r = m_struct_set(desc,dst,"filename",fname);	  if(fname != ptr2+1)	    free(fname);	  if(r < 0) {	    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %s: Error while setting filename.\n",name);	    return r;	  }	}      }    }  }  return 1;}/// TODO : Write the other needed funcs for 'normal' optionsm_option_type_t m_option_type_custom_url = {  "Custom URL",  "",  0,  0,  parse_custom_url,  NULL,  NULL,  NULL,  NULL,  NULL};	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -