[Mplayer-cvslog] CVS: main m_config.c,NONE,1.1 m_config.h,NONE,1.1 m_option.c,NONE,1.1 m_option.h,NONE,1.1 parser-cfg.c,NONE,1.1 parser-mecmd.c,NONE,1.1 parser-mecmd.h,NONE,1.1 parser-mpcmd.c,NONE,1.1 playtree.c,1.15,1.16 playtree.h,1.4,1.5 playtreeparser.c,1.13,1.14 playtreeparser.h,1.2,1.3 Makefile,1.231,1.232 asxparser.c,1.6,1.7 asxparser.h,1.2,1.3 cfg-mplayer.h,1.181,1.182 cfgparser.c,1.60,1.61 cfgparser.h,1.17,1.18 configure,1.602,1.603 mencoder.c,1.184,1.185 mplayer.c,1.610,1.611

Alban Bedel CVS albeu at mplayerhq.hu
Tue Nov 12 02:57:14 CET 2002


Update of /cvsroot/mplayer/main
In directory mail:/var/tmp.root/cvs-serv2160

Modified Files:
	playtree.c playtree.h playtreeparser.c playtreeparser.h 
	Makefile asxparser.c asxparser.h cfg-mplayer.h cfgparser.c 
	cfgparser.h configure mencoder.c mplayer.c 
Added Files:
	m_config.c m_config.h m_option.c m_option.h parser-cfg.c 
	parser-mecmd.c parser-mecmd.h parser-mpcmd.c 
Log Message:
New config system + cleanup of header inter dependency


--- NEW FILE ---

#include "config.h"

#ifdef NEW_CONFIG

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#ifdef MP_DEBUG
#include <assert.h>
#endif


#include "m_config.h"
#include "m_option.h"
#include "mp_msg.h"

m_config_t*
m_config_new(void) {
  m_config_t* config;

  config = (m_config_t*)calloc(1,sizeof(m_config_t));
  config->lvl = 1; // 0 Is the defaults
  return config;
}

void
m_config_free(m_config_t* config) {
  m_config_option_t *i = config->opts, *ct;
  m_config_save_slot_t *sl,*st;

#ifdef MP_DEBUG
  assert(config != NULL);
#endif
  
  while(i) {
    sl = i->slots;
    while(sl) {
      m_option_free(i->opt,sl->data);
      st = sl->prev;
      free(sl);
      sl = st;
    }
    if(i->name != i->opt->name)
      free(i->name);
    ct = i->next;
    free(i);
    ct = i;
  }
  free(config);  
}

void
m_config_push(m_config_t* config) {
  m_config_option_t *co;
  m_config_save_slot_t *slot;

#ifdef MP_DEBUG
  assert(config != NULL);
  assert(config->lvl > 0);
#endif

  config->lvl++;

  for(co = config->opts ; co ; co = co->next ) {
    if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD)
      continue;
    if(co->opt->flags & (M_OPT_GLOBAL|M_OPT_NOSAVE))
      continue;
    if((co->opt->flags & M_OPT_OLD) && !co->flags)
      continue;

    // Update the current status
    m_option_save(co->opt,co->slots->data,co->opt->p);
    
    // Allocate a new slot    
    slot = (m_config_save_slot_t*)calloc(1,sizeof(m_config_save_slot_t) + co->opt->type->size);
    slot->lvl = config->lvl;
    slot->prev = co->slots;
    co->slots = slot;
    m_option_copy(co->opt,co->slots->data,co->slots->prev->data);
    // Reset our flags
    co->flags=0;
  }
  
  mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config pushed level is now %d\n",config->lvl);
}

void
m_config_pop(m_config_t* config) {
  m_config_option_t *co;
  m_config_save_slot_t *slot;

#ifdef MP_DEBUG
  assert(config != NULL);
  assert(config->lvl > 1);
#endif

  for(co = config->opts ; co ; co = co->next ) {
    int pop = 0;
    if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD)
      continue;
    if(co->opt->flags & (M_OPT_GLOBAL|M_OPT_NOSAVE))
      continue;
    if(co->slots->lvl > config->lvl)
      mp_msg(MSGT_CFGPARSER, MSGL_WARN,"Too old save slot found from lvl %d : %d !!!\n",config->lvl,co->slots->lvl);
    
    while(co->slots->lvl >= config->lvl) {
      m_option_free(co->opt,co->slots->data);
      slot = co->slots;
      co->slots = slot->prev;
      free(slot);
      pop++;
    }
    if(pop) // We removed some ctx -> set the previous value
      m_option_set(co->opt,co->opt->p,co->slots->data);
  }

  config->lvl--;
  mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Config poped level=%d\n",config->lvl);
}

static void
m_config_add_option(m_config_t *config, m_option_t *arg, char* prefix) {
  m_config_option_t *co;
  m_config_save_slot_t* sl;

#ifdef MP_DEBUG
  assert(config != NULL);
  assert(config->lvl > 0);
  assert(arg != NULL);
#endif

  // Allocate a new entry for this option
  co = (m_config_option_t*)calloc(1,sizeof(m_config_option_t) + arg->type->size);
  co->opt = arg;

  // Fill in the full name
  if(prefix && strlen(prefix) > 0) {
    int l = strlen(prefix) + 1 + strlen(arg->name) + 1;
    co->name = (char*) malloc(l);
    sprintf(co->name,"%s:%s",prefix,arg->name);
  } else
    co->name = arg->name;

  // Option with childs -> add them
  if(arg->type->flags & M_OPT_TYPE_HAS_CHILD) {
    m_option_t *ol = arg->p;
    int i;
    for(i = 0 ; ol[i].name != NULL ; i++)
      m_config_add_option(config,&ol[i], co->name);
  } else {
    // Allocate a slot for the defaults
    sl = (m_config_save_slot_t*)calloc(1,sizeof(m_config_save_slot_t) + arg->type->size);
    m_option_save(arg,sl->data,(void**)arg->p);
    // Hack to avoid too much trouble with dynamicly allocated data :
    // We always use a dynamic version
    if((arg->type->flags & M_OPT_TYPE_DYNAMIC) && arg->p && (*(void**)arg->p)) {
      *(void**)arg->p = NULL;
      m_option_set(arg,arg->p,sl->data);
    }
    sl->lvl = 0;
    co->slots = (m_config_save_slot_t*)calloc(1,sizeof(m_config_save_slot_t) + arg->type->size);
    co->slots->prev = sl;
    co->slots->lvl = config->lvl;
    m_option_copy(co->opt,co->slots->data,sl->data);
  }
  co->next = config->opts;
  config->opts = co;
}

int
m_config_register_options(m_config_t *config, m_option_t *args) {
  int i;

#ifdef MP_DEBUG
  assert(config != NULL);
  assert(config->lvl > 0);
  assert(args != NULL);
#endif

  for(i = 0 ; args[i].name != NULL ; i++)
    m_config_add_option(config,&args[i],NULL);

  return 1;
}

static m_config_option_t* 
m_config_get_co(m_config_t *config, char* arg) {
  m_config_option_t *co;

  for(co = config->opts ; co ; co = co->next ) {
    int l = strlen(co->name) - 1;
    if((co->opt->type->flags & M_OPT_TYPE_ALLOW_WILDCARD) && 
       (co->name[l] == '*')) {
      if(strncasecmp(co->name,arg,l) == 0)
	return co;
    } else if(strcasecmp(co->name,arg) == 0)
      return co;
  }
  return NULL;
}

static int
m_config_parse_option(m_config_t *config, char* arg, char* param,int set) {
  m_config_option_t *co;
  int r = 0;

#ifdef MP_DEBUG
  assert(config != NULL);
  assert(config->lvl > 0);
  assert(arg != NULL);
#endif

  co = m_config_get_co(config,arg);
  if(!co)
    return M_OPT_UNKNOW;

#ifdef MP_DEBUG
  // This is the only mandatory function
  assert(co->opt->type->parse);
#endif

  // Check if this option isn't forbiden in the current mode
  if((config->mode == M_CONFIG_FILE) && (co->opt->flags & M_OPT_NOCFG)) {
    mp_msg(MSGT_CFGPARSER, MSGL_ERR,"The %s option can't be used in a config file\n",config->lvl);
    return M_OPT_INVALID;
  }
  if((config->mode == M_COMMAND_LINE) && (co->opt->flags & M_OPT_NOCMD)) {
    mp_msg(MSGT_CFGPARSER, MSGL_ERR,"The %s option can't be used on the command line\n",config->lvl);
    return M_OPT_INVALID;
  }

  // Option with childs are a bit different to parse
  if(co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) {
    char** lst = NULL;
    int i,sr;
    // Parse the child options
    r = m_option_parse(co->opt,arg,param,&lst,config->mode);
    // Set them now
    for(i = 0 ; lst && lst[2*i] ; i++) {
      int l = strlen(co->name) + 1 + strlen(lst[2*i]) + 1;
      if(r >= 0) {
	// Build the full name
	char n[l];
	sprintf(n,"%s:%s",co->name,lst[2*i]);
	sr = m_config_parse_option(config,n,lst[2*i+1],set);
	if(sr < 0) r = sr;
      }
      free(lst[2*i]);
      free(lst[2*i+1]);
    }
    if(lst) free(lst);      
  } else
    r = m_option_parse(co->opt,arg,param,set ? co->slots->data : NULL,config->mode);

  // Parsing failed ?
  if(r < 0)
    return r;
  // Set the option
  if(set) {
    m_option_set(co->opt,co->opt->p,co->slots->data);
    co->flags = 1;
  }

  return r;
}

int
m_config_set_option(m_config_t *config, char* arg, char* param) {
  mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Setting %s=%s\n",arg,param);
  return m_config_parse_option(config,arg,param,1);
}

int
m_config_check_option(m_config_t *config, char* arg, char* param) {
  mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Checking %s=%s\n",arg,param);
  return m_config_parse_option(config,arg,param,0);
}


m_option_t*
m_config_get_option(m_config_t *config, char* arg) {
  m_config_option_t *co;

#ifdef MP_DEBUG
  assert(config != NULL);
  assert(config->lvl > 0);
  assert(arg != NULL);
#endif

  co = m_config_get_co(config,arg);
  if(co)
    return co->opt;
  else
    return NULL;
}

void*
m_config_get_option_ptr(m_config_t *config, char* arg) {
  m_option_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;
}

void
m_config_print_option_list(m_config_t *config) {
  char min[50],max[50];
  m_config_option_t* co;
  int count = 0;

  if(!config->opts) return;

  printf("\n Name                 Type            Min        Max      Global  CL    Cfg\n\n");
  for(co = config->opts ; co ; co = co->next) {
    m_option_t* opt = co->opt;
    if(opt->type->flags & M_OPT_TYPE_HAS_CHILD) continue;
    if(opt->flags & M_OPT_MIN)
      sprintf(min,"%-8.0f",opt->min);
    else
      strcpy(min,"No");
    if(opt->flags & M_OPT_MAX)
      sprintf(max,"%-8.0f",opt->max);
    else
      strcpy(max,"No");
    printf(" %-20.20s %-15.15s %-10.10s %-10.10s %-3.3s   %-3.3s   %-3.3s\n",
	   co->name,
	   co->opt->type->name,
	   min,
	   max,
	   opt->flags & CONF_GLOBAL ? "Yes" : "No",
	   opt->flags & CONF_NOCMD ? "No" : "Yes",
	   opt->flags & CONF_NOCFG ? "No" : "Yes");
    count++;
  }
  printf("\nTotal: %d options\n",count);
}

#endif // NEW_CONFIG

--- NEW FILE ---

#ifndef NEW_CONFIG
#warning "Including m_config.h but NEW_CONFIG is disabled"
#else

typedef struct m_config_option m_config_option_t;
typedef struct m_config_save_slot m_config_save_slot_t;
struct m_option;
struct m_option_type;

struct m_config_save_slot {
  m_config_save_slot_t* prev;
  int lvl;
  unsigned char data[0];
};

struct m_config_option {
  m_config_option_t* next;
  char* name; // Full name (ie option:subopt)
  struct m_option* opt;
  m_config_save_slot_t* slots;
  unsigned int flags; // currently it only tell if the option was set
};

typedef struct m_config {
  m_config_option_t* opts;
  int lvl; // Current stack level
  int mode;
} m_config_t;


//////////////////////////// Functions ///////////////////////////////////

m_config_t*
m_config_new(void);

void
m_config_free(m_config_t* config);

void
m_config_push(m_config_t* config);

void
m_config_pop(m_config_t* config);

int
m_config_register_options(m_config_t *config, struct m_option *args);

int
m_config_set_option(m_config_t *config, char* arg, char* param);

int
m_config_check_option(m_config_t *config, char* arg, char* param);

struct m_option*
m_config_get_option(m_config_t *config, char* arg);

/////////////////////////////////////////////////////////////////////////////////////
/////////////////////////// Backward compat. stuff ////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

typedef struct config config_t;
struct config {
  char *name;
  void *p; 
  struct m_option_type* type;
  unsigned int flags;
  float min,max;
  void* priv;
};


#define CONF_MIN		(1<<0)
#define CONF_MAX		(1<<1)
#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)
#define CONF_OLD		(1<<6)

#define ERR_NOT_AN_OPTION	 -1
#define ERR_MISSING_PARAM	 -2
#define ERR_OUT_OF_RANGE	 -3
#define ERR_FUNC_ERR	 -4

#endif

--- NEW FILE ---

#include "config.h"

#ifdef NEW_CONFIG

#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdio.h>
#include <stdarg.h>
#include <inttypes.h>

#include "m_option.h"
//#include "m_config.h"
#include "mp_msg.h"

// Default function that just do a memcpy

static void copy_opt(m_option_t* opt,void* dst,void* src) {
[...969 lines suppressed...]
  if(e && e[0] != '\0')
    r = parse_play_pos(&span->end,name,s);
  
  return r;  
}

m_option_type_t m_option_type_span = {
  "Span",
  "The syntax is 1[hh:mm:ss.zz]-5[hh:mm:ss.zz]",
  sizeof(m_span_t),
  0,
  parse_span,
  NULL,
  copy_opt,
  copy_opt,
  NULL,
  NULL
};

#endif

--- NEW FILE ---

#ifndef NEW_CONFIG
#warning "Including m_option.h but NEW_CONFIG is disabled"
#else

typedef struct m_option_type m_option_type_t;
typedef struct m_option m_option_t;

///////////////////////////// Options types declarations ////////////////////////////

// Simple types
extern m_option_type_t m_option_type_flag;
extern m_option_type_t m_option_type_int;
extern m_option_type_t m_option_type_float;
extern m_option_type_t m_option_type_string;
extern m_option_type_t m_option_type_string_list;
extern m_option_type_t m_option_type_position;

extern m_option_type_t m_option_type_print;
extern m_option_type_t m_option_type_subconfig;
extern m_option_type_t m_option_type_imgfmt;

// Func based types 
extern m_option_type_t m_option_type_func_full;
extern m_option_type_t m_option_type_func_param;
extern m_option_type_t m_option_type_func;

typedef void (*m_opt_default_func_t)(m_option_t *, char*);
typedef int (*m_opt_func_full_t)(m_option_t *, char *, char *);
typedef int (*m_opt_func_param_t)(m_option_t *, char *);
typedef int (*m_opt_func_t)(m_option_t *);
///////////// Backward compat
typedef m_opt_default_func_t cfg_default_func_t;
typedef m_opt_func_full_t cfg_func_arg_param_t;
typedef m_opt_func_param_t cfg_func_param_t;
typedef m_opt_func_t cfg_func_t;

// Track/Chapter range
// accept range in the form 1[hh:mm:ss.zz]-5[hh:mm:ss.zz]
// ommited fields are assumed to be 0
// Not finished !!!!
typedef struct {
  int idx; // in the e.g 1 or 5
  unsigned int seconds; // hh:mm:ss converted in seconds
  unsigned int sectors; // zz
} m_play_pos_t;

typedef struct {
  m_play_pos_t start;
  m_play_pos_t end;
} m_span_t;
extern m_option_type_t m_option_type_span;

// Don't be stupid keep tho old names ;-)
#define CONF_TYPE_FLAG		(&m_option_type_flag)
#define CONF_TYPE_INT		(&m_option_type_int)
#define CONF_TYPE_FLOAT		(&m_option_type_float)
#define CONF_TYPE_STRING		(&m_option_type_string)
#define CONF_TYPE_FUNC		(&m_option_type_func)
#define CONF_TYPE_FUNC_PARAM	(&m_option_type_func_param)
#define CONF_TYPE_PRINT		(&m_option_type_print)
#define CONF_TYPE_FUNC_FULL	(&m_option_type_func_full)
#define CONF_TYPE_SUBCONFIG	(&m_option_type_subconfig)
#define CONF_TYPE_STRING_LIST           (&m_option_type_string_list)
#define CONF_TYPE_POSITION	(&m_option_type_position)
#define CONF_TYPE_IMGFMT		(&m_option_type_imgfmt)
#define CONF_TYPE_SPAN		(&m_option_type_span)


/////////////////////////////////////////////////////////////////////////////////////////////

struct m_option_type {
  char* name;
  char* comments; // syntax desc, etc
  unsigned int size; // size needed for a save slot
  unsigned int flags;

  // parse is the only requiered function all others can be NULL
  // If dst if non-NULL it should create/update the save slot
  // If dst is NULL it should just test the validity of the arg if possible
  // Src tell from where come this setting (ie cfg file, command line, playlist, ....
  // It should return 1 if param was used, 0 if not.
  // On error it must return 1 of the error code below
  int (*parse)(m_option_t* opt,char *name, char *param, void* dst, int src);
  // Print back a value in human form
  char* (*print)(m_option_t* opt,  void* val);

  // These 3 will be a memcpy in 50% of the case, it's called to save/restore the status of
  // the var it's there for complex type like CONF_TYPE_FUNC*
  // update a save slot (dst) from the current value in the prog (src)
  void (*save)(m_option_t* opt,void* dst, void* src);
  // set the current value (dst) from a save slot
  void (*set)(m_option_t* opt,void* dst, void* src);
  // Copy betewen 2 slot (if NULL and size > 0 a memcpy will be used
  void (*copy)(m_option_t* opt,void* dst, void* src);
  // Free the data allocated for a save slot if needed
  void (*free)(void* dst);
};

/// This is the same thing as a struct config it have been renamed
/// to remove this config_t, m_config_t mess. Sorry about that,
/// config_t is still provided for backward compat.
struct m_option {
  char *name;
  void *p; 
  m_option_type_t* type;
  unsigned int flags;
  float min,max;
  // This used to be function pointer to hold a 'reverse to defaults' func.
  // Nom it can be used to pass any type of extra args.
  // Passing a 'default func' is still valid for all func based option types
  void* priv; // Type dependent data (for all kind of extended setting)
};


//////////////////////////////// Option flags /////////////////////////////////

// Option flags
#define M_OPT_MIN		(1<<0)
#define M_OPT_MAX		(1<<1)
#define M_OPT_RANGE		(M_OPT_MIN|M_OPT_MAX)
#define M_OPT_NOCFG		(1<<2)
#define M_OPT_NOCMD		(1<<3)
// This option is global : it won't be saved on push and the command
// line parser will set it when it's parsed (ie. it won't be set later)
// e.g options : -v, -quiet
#define M_OPT_GLOBAL		(1<<4)
// Do not save this option : it won't be saved on push but the command
// line parser will put it with it's entry (ie : it may be set later)
// e.g options : -include
#define M_OPT_NOSAVE		(1<<5)
// Emulate old behaviour by pushing the option only if it was set by the user
#define M_OPT_OLD		(1<<6)


///////////////////////////// Option type flags ///////////////////////////////////

// These flags are for the parsers. The description here apply to the m_config_t
// based parsers (ie. cmd line and config file parsers)
// Some parser will refuse option types that have some of these flags

// This flag is used for the subconfig
// When this flag is set, opt->p should point to another m_option_t array
// Only the parse function will be called. If dst is set, it should create/update
// an array of char* containg opt/val pairs.
// Then the options in the child array will then be set automaticly.
// You can only affect the way suboption are parsed.
// Also note that suboptions may be directly accessed by using -option:subopt blah :-)
#define M_OPT_TYPE_HAS_CHILD		(1<<0)
// If this flag is set the option type support option name with * at the end (used for -aa*)
// This only affect the option name matching, the option type have to implement
// the needed stuff.
#define M_OPT_TYPE_ALLOW_WILDCARD	(1<<1)
// This flag indicate that the data is dynamicly allocated (opt->p point to a pointer)
// It enable a little hack wich replace the initial value by a dynamic copy
// in case the initial value is staticly allocated (pretty common with strings)
#define M_OPT_TYPE_DYNAMIC		(1<<2)
/// If this is set the parse function doesn't directly return
// the wanted thing. Options use this if for some reasons they have to wait
// until the set call to be able to correctly set the target var.
// So for those types you have to first parse and then set the target var
// If this flag isn't set you can parse directly to the target var
// It's used for the callback based option as the callback call may append
// later on.
#define M_OPT_TYPE_INDIRECT		(1<<3)


///////////////////////////// Parser flags ////////////////////////////////////////

// Config mode : some parser type behave differently depending
// on config->mode value wich is passed in the src param of parse()
#define M_CONFIG_FILE 0
#define M_COMMAND_LINE 1

// Option parser error code
#define M_OPT_UNKNOW		-1
#define M_OPT_MISSING_PARAM	-2
#define M_OPT_INVALID		-3
#define M_OPT_OUT_OF_RANGE	-4
#define M_OPT_PARSER_ERR		-5


inline static int
m_option_parse(m_option_t* opt,char *name, char *param, void* dst, int src) {
  return opt->type->parse(opt,name,param,dst,src);
}

inline static  char*
m_option_print(m_option_t* opt,  void* val_ptr) {
  if(opt->type->print)
    return opt->type->print(opt,val_ptr);
  else
    return NULL;
}

inline static  void
m_option_save(m_option_t* opt,void* dst, void* src) {
  if(opt->type->save)
    opt->type->save(opt,dst,src);
}

inline static  void
m_option_set(m_option_t* opt,void* dst, void* src) {
  if(opt->type->set)
    opt->type->set(opt,dst,src);
}

inline  static void
m_option_copy(m_option_t* opt,void* dst, void* src) {
  if(opt->type->copy)
    opt->type->set(opt,dst,src);
  else if(opt->type->size > 0)
    memcpy(dst,src,opt->type->size);
}

inline static void
m_option_free(m_option_t* opt,void* dst) {
  if(opt->type->free)
    opt->type->free(dst);
}

#endif

--- NEW FILE ---

#include "config.h"

#ifdef NEW_CONFIG

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ctype.h>

#ifdef MP_DEBUG
#include <assert.h>
#endif

#include "mp_msg.h"
#include "m_option.h"
#include "m_config.h"

#define MAX_RECURSION_DEPTH	8

static int recursion_depth = 0;

int m_config_parse_config_file(m_config_t* config, char *conffile)
{
#define PRINT_LINENUM	mp_msg(MSGT_CFGPARSER,MSGL_V,"%s(%d): ", conffile, line_num)
#define MAX_LINE_LEN	1000
#define MAX_OPT_LEN	100
#define MAX_PARAM_LEN	100
	FILE *fp;
	char *line;
	char opt[MAX_OPT_LEN + 1];
	char param[MAX_PARAM_LEN + 1];
	char c;		/* for the "" and '' check */
	int tmp;
	int line_num = 0;
	int line_pos;	/* line pos */
	int opt_pos;	/* opt pos */
	int param_pos;	/* param pos */
	int ret = 1;
	int errors = 0;
	int prev_mode = config->mode;

#ifdef MP_DEBUG
	assert(config != NULL);
	//	assert(conf_list != NULL);
#endif
	mp_msg(MSGT_CFGPARSER,MSGL_INFO,"Reading config file %s", conffile);

	if (recursion_depth > MAX_RECURSION_DEPTH) {
		mp_msg(MSGT_CFGPARSER,MSGL_ERR,": too deep 'include'. check your configfiles\n");
		ret = -1;
		goto out;
	} else
	  
	config->mode = M_CONFIG_FILE;

	if ((line = (char *) malloc(MAX_LINE_LEN + 1)) == NULL) {
		mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"\ncan't get memory for 'line': %s", strerror(errno));
		ret = -1;
		goto out;
	}

	if ((fp = fopen(conffile, "r")) == NULL) {
	  mp_msg(MSGT_CFGPARSER,MSGL_ERR,": %s\n", strerror(errno));
		free(line);
		ret = 0;
		goto out;
	}
	mp_msg(MSGT_CFGPARSER,MSGL_INFO,"\n");

	while (fgets(line, MAX_LINE_LEN, fp)) {
		if (errors >= 16) {
			mp_msg(MSGT_CFGPARSER,MSGL_FATAL,"too many errors\n");
			goto out;
		}

		line_num++;
		line_pos = 0;

		/* skip whitespaces */
		while (isspace(line[line_pos]))
			++line_pos;

		/* EOL / comment */
		if (line[line_pos] == '\0' || line[line_pos] == '#')
			continue;

		/* read option. */
		for (opt_pos = 0; isprint(line[line_pos]) &&
				line[line_pos] != ' ' &&
				line[line_pos] != '#' &&
				line[line_pos] != '='; /* NOTHING */) {
			opt[opt_pos++] = line[line_pos++];
			if (opt_pos >= MAX_OPT_LEN) {
				PRINT_LINENUM;
				mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long option\n");
				errors++;
				ret = -1;
				goto nextline;
			}
		}
		if (opt_pos == 0) {
			PRINT_LINENUM;
			mp_msg(MSGT_CFGPARSER,MSGL_ERR,"parse error\n");
			ret = -1;
			errors++;
			continue;
		}
		opt[opt_pos] = '\0';

#ifdef MP_DEBUG
		PRINT_LINENUM;
		mp_msg(MSGT_CFGPARSER,MSGL_V,"option: %s\n", opt);
#endif

		/* skip whitespaces */
		while (isspace(line[line_pos]))
			++line_pos;

		/* check '=' */
		if (line[line_pos++] != '=') {
			PRINT_LINENUM;
			mp_msg(MSGT_CFGPARSER,MSGL_ERR,"option without parameter\n");
			ret = -1;
			errors++;
			continue;
		}

		/* whitespaces... */
		while (isspace(line[line_pos]))
			++line_pos;

		/* read the parameter */
		if (line[line_pos] == '"' || line[line_pos] == '\'') {
			c = line[line_pos];
			++line_pos;
			for (param_pos = 0; line[line_pos] != c; /* NOTHING */) {
				param[param_pos++] = line[line_pos++];
				if (param_pos >= MAX_PARAM_LEN) {
					PRINT_LINENUM;
					mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long parameter\n");
					ret = -1;
					errors++;
					goto nextline;
				}
			}
			line_pos++;	/* skip the closing " or ' */
		} else {
			for (param_pos = 0; isprint(line[line_pos]) && !isspace(line[line_pos])
					&& line[line_pos] != '#'; /* NOTHING */) {
				param[param_pos++] = line[line_pos++];
				if (param_pos >= MAX_PARAM_LEN) {
					PRINT_LINENUM;
					mp_msg(MSGT_CFGPARSER,MSGL_ERR,"too long parameter\n");
					ret = -1;
					errors++;
					goto nextline;
				}
			}
		}
		param[param_pos] = '\0';

		/* did we read a parameter? */
		if (param_pos == 0) {
			PRINT_LINENUM;
			mp_msg(MSGT_CFGPARSER,MSGL_ERR,"option without parameter\n");
			ret = -1;
			errors++;
			continue;
		}

#ifdef MP_DEBUG
		PRINT_LINENUM;
		mp_msg(MSGT_CFGPARSER,MSGL_V,"parameter: %s\n", param);
#endif

		/* now, check if we have some more chars on the line */
		/* whitespace... */
		while (isspace(line[line_pos]))
			++line_pos;

		/* EOL / comment */
		if (line[line_pos] != '\0' && line[line_pos] != '#') {
			PRINT_LINENUM;
			mp_msg(MSGT_CFGPARSER,MSGL_WARN,"extra characters on line: %s\n", line+line_pos);
			ret = -1;
		}

		tmp = m_config_set_option(config, opt, param);
		if (tmp < 0) {
			PRINT_LINENUM;
			mp_msg(MSGT_CFGPARSER,MSGL_INFO,"%s\n", opt);
			ret = -1;
			errors++;
			continue;
			/* break */
		}	
nextline:
		;
	}

	free(line);
	fclose(fp);
out:
	config->mode = prev_mode;
	--recursion_depth;
	return ret;
}

#endif

--- NEW FILE ---

#include "config.h"

#ifdef NEW_CONFIG

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#ifdef MP_DEBUG
#include <assert.h>
#endif

#include "mp_msg.h"
#include "m_option.h"
#include "m_config.h"
#include "parser-mecmd.h"


void
m_entry_list_free(m_entry_t* lst) {
  int i,j;

  for(i = 0 ; lst[i].name != NULL ; i++){
    free(lst[i].name);
    for(j = 0 ; lst[i].opts[2*j] != NULL ; j++) {
      free(lst[i].opts[2*j]);
      free(lst[i].opts[2*j+1]);
    }
    free(lst[i].opts);
  }
  free(lst);
}

int
m_entry_set_options(m_config_t *config, m_entry_t* entry) {
  int i,r;

  for(i = 0 ; entry->opts[2*i] != NULL ; i++){
    r = m_config_set_option(config,entry->opts[2*i],entry->opts[2*i+1]);
    if(r < 0)
      return 0;
  }
  return 1;
}


  

m_entry_t*
m_config_parse_me_command_line(m_config_t *config, int argc, char **argv)
{
  int i,nf = 0,no = 0;
  int tmp;
  char *opt;
  int no_more_opts = 0;
  m_entry_t *lst = NULL, *entry = NULL;
  void add_file(char* file) {
    mp_msg(MSGT_CFGPARSER, MSGL_DBG2,"Adding file %s\n",argv[i]);
    lst = realloc(lst,(nf+2)*sizeof(m_entry_t));
    lst[nf].name = strdup(file);
    lst[nf].opts = calloc(2,sizeof(char*));
    entry = &lst[nf];
    no = 0;
    memset(&lst[nf+1],0,sizeof(m_entry_t));
    nf++;
  }
	
#ifdef MP_DEBUG
  assert(config != NULL);
  assert(argv != NULL);
  assert(argc >= 1);
#endif

  config->mode = M_COMMAND_LINE;

  lst = calloc(1,sizeof(m_entry_t));

  for (i = 1; i < argc; i++) {
    //next:
    opt = argv[i];
    /* check for -- (no more options id.) except --help! */
    if ((*opt == '-') && (*(opt+1) == '-') && (*(opt+2) != 'h'))
      {
	no_more_opts = 1;
	if (i+1 >= argc)
	  {
	    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "You added '--' but no filenames presented!\n");
	    goto err_out;
	  }
	continue;
      }
			
    if ((no_more_opts == 0) && (*opt == '-') && (*(opt+1) != 0)) /* option */
      {
	m_option_t* mp_opt = NULL;
	/* remove trailing '-' */
	opt++;
	mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "this_opt = option: %s\n", opt);
	mp_opt = m_config_get_option(config,opt);
	if(!mp_opt) {
	  tmp = M_OPT_UNKNOW;
	  mp_msg(MSGT_CFGPARSER, MSGL_ERR, "%s in not an MEncoder option\n",opt);
	  goto err_out;
	}
	// Hack for the -vcd ... options
	if(strcasecmp(opt,"vcd") == 0)
	  add_file("VCD Track");
	if(strcasecmp(opt,"dvd") == 0)
	  add_file("DVD Title");
	if(strcasecmp(opt,"tv") == 0 && argv[i + 1]) { // TV is a bit more tricky
	  char* param = argv[i + 1];
	  char* on = strstr(param,"on");
	  for( ; on ; on = strstr(on + 1,"on")) {
	    if(on[2] != ':' && on[2] != '\0') continue;
	    if(on != param && *(on - 1) != ':') continue;
	    add_file("TV Channel");
	    break;
	  }
	}
	if(!entry || (mp_opt->flags & M_OPT_GLOBAL))
	  tmp = m_config_set_option(config, opt, argv[i + 1]);
	else {
	  tmp = m_config_check_option(config, opt, argv[i + 1]);
	  if(tmp >= 0) {
	    entry->opts = realloc(entry->opts,(no+2)*2*sizeof(char*));
	    entry->opts[2*no] = strdup(opt);
	    entry->opts[2*no+1] = argv[i + 1] ? strdup(argv[i + 1]) : NULL;
	    entry->opts[2*no+2] =  entry->opts[2*no+3] = NULL;
	    no++;
	  }
	}
	if (tmp < 0)
	  goto err_out;
	i += tmp;
      } else /* filename */
	add_file(argv[i]);
  }

  if(nf == 0) {
    m_entry_list_free(lst);
    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "No file given\n");
    return NULL;
  }
  return lst;

 err_out:
   m_entry_list_free(lst);
  return NULL;
}

#endif

--- NEW FILE ---

/// A simple parser with per-entry settings.

typedef struct m_entry_st {
  char* name; // Filename, url or whatever
  char** opts; // NULL terminated list of name,val pairs 
} m_entry_t;

// Free a list returned by m_config_parse_command_line
void
m_entry_list_free(m_entry_t* lst);
// Use this when you switch to another entry
int
m_entry_set_options(m_config_t *config, m_entry_t* entry);

m_entry_t*
m_config_parse_me_command_line(m_config_t *config, int argc, char **argv);


--- NEW FILE ---

#include "config.h"

#ifdef NEW_CONFIG

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

#ifdef MP_DEBUG
#include <assert.h>
#endif

#include "mp_msg.h"
#include "m_option.h"
#include "m_config.h"
#include "playtree.h"

static int recursion_depth = 0;
static int mode = 0;

#define GLOBAL 0
#define LOCAL 1
#define DROP_LOCAL 2

#define UNSET_GLOBAL (mode = LOCAL)
// Use this 1 if you want to have only global option (no per file option)
// #define UNSET_GLOBAL (mode = GLOBAL)


static int is_entry_option(char *opt, char *param, play_tree_t** ret) {
  play_tree_t* entry = NULL;

  *ret = NULL;

  if(strcasecmp(opt,"playlist") == 0) { // We handle playlist here
    if(!param)
      return M_OPT_MISSING_PARAM;
    entry = parse_playlist_file(param);
    if(!entry)
      return 1;
  } else if(strcasecmp(opt,"vcd") == 0) {
    char* s;
    if(!param)
      return M_OPT_MISSING_PARAM;
    s = (char*)malloc((strlen(param) + 6 + 1)*sizeof(char));
    sprintf(s,"vcd://%s",param);
    entry = play_tree_new();
    play_tree_add_file(entry,s);
    free(s);
  } else if(strcasecmp(opt,"dvd") == 0) {
    char* s;
    if(!param)
      return M_OPT_MISSING_PARAM;
    s = (char*)malloc((strlen(param) + 6 + 1)*sizeof(char));
    sprintf(s,"dvd://%s",param);
    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 M_OPT_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);
	  
  }

  if(entry) {
    *ret = entry;
    return 1;
  } else
    return 0;
}

play_tree_t*
m_config_parse_mp_command_line(m_config_t *config, int argc, char **argv)
{
  int i;
  int tmp = 0;
  char *opt;
  int no_more_opts = 0;
  play_tree_t *last_parent, *last_entry = NULL, *root;
  void add_entry(play_tree_t *entry) {
    if(last_entry == NULL)
      play_tree_set_child(last_parent,entry);		      
    else 
      play_tree_append_entry(last_entry,entry);
    last_entry = entry;
  }

#ifdef MP_DEBUG
  assert(config != NULL);
  assert(argv != NULL);
  assert(argc >= 1);
#endif

  config->mode = M_COMMAND_LINE;
  mode = GLOBAL;
  last_parent = root = play_tree_new();
  /* in order to work recursion detection properly in parse_config_file */
  ++recursion_depth;

  for (i = 1; i < argc; i++) {
    //next:
    opt = argv[i];
    /* check for -- (no more options id.) except --help! */
    if ((*opt == '-') && (*(opt+1) == '-') && (*(opt+2) != 'h'))
      {
	no_more_opts = 1;
	if (i+1 >= argc)
	  {
	    mp_msg(MSGT_CFGPARSER, MSGL_ERR, "You added '--' but no filenames presented!\n");
	    goto err_out;
	  }
	continue;
      }
    if((opt[0] == '{') && (opt[1] == '\0'))
      {
	play_tree_t* entry = play_tree_new();
	UNSET_GLOBAL;
	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 */
      {
	/* remove trailing '-' */
	opt++;

	mp_msg(MSGT_CFGPARSER, MSGL_DBG3, "this_opt = option: %s\n", opt);
	// We handle here some specific option
	if(strcasecmp(opt,"list-options") == 0) {
	  m_config_print_option_list(config);
	  exit(1);
	  // Loop option when it apply to a group
	} else if(strcasecmp(opt,"loop") == 0 &&
		  (! last_entry || last_entry->child) ) {
	  int l;
	  char* end;
	  l = strtol(argv[i+1],&end,0);
	  if(!end)
	    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 {
	  m_option_t* mp_opt = NULL;
	  play_tree_t* entry = NULL;

	  tmp = is_entry_option(opt,argv[i + 1],&entry);
	  if(tmp > 0)  { // It's an entry
	    if(entry) {
	      add_entry(entry);
	      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 = m_config_set_option(config, opt, argv[i + 1]);
	      else {
		tmp = m_config_check_option(config, opt, argv[i + 1]);
		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_UNKNOW;
	      mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Unknow option on the command line: %s\n",opt);
	    }
	  }
	}

	if (tmp < 0)
	  goto err_out;
	i += tmp;
      }
    else /* filename */
      {
	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]);
	// Lock stdin if it will be used as input
	if(strcasecmp(argv[i],"-") == 0)
	  m_config_set_option(config,"use-stdin",NULL);
	add_entry(entry);
	UNSET_GLOBAL; // We start entry specific options

      }
  }

  --recursion_depth;
  if(last_parent != root)
    mp_msg(MSGT_CFGPARSER, MSGL_ERR,"Missing }- ?\n");
  return root;

 err_out:
  --recursion_depth;
  play_tree_free(root,1);
  return NULL;
}

#endif

Index: playtree.c
===================================================================
RCS file: /cvsroot/mplayer/main/playtree.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- playtree.c	2 Nov 2002 22:44:15 -0000	1.15
+++ playtree.c	12 Nov 2002 01:56:21 -0000	1.16
@@ -8,6 +8,7 @@
 #ifdef MP_DEBUG
 #include <assert.h>
 #endif
+#include "cfgparser.h"
 #include "playtree.h"
 #include "mp_msg.h"
 

Index: playtree.h
===================================================================
RCS file: /cvsroot/mplayer/main/playtree.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- playtree.h	20 Mar 2002 10:27:27 -0000	1.4
+++ playtree.h	12 Nov 2002 01:56:21 -0000	1.5
@@ -2,8 +2,8 @@
 #ifndef __PLAYTREE_H
 #define __PLAYTREE_H
 
-#include "libmpdemux/stream.h"
-
+struct stream_st;
+struct m_config;
 
 #define PLAY_TREE_ITER_ERROR 0
 #define PLAY_TREE_ITER_ENTRY 1
@@ -20,7 +20,6 @@
 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;
@@ -56,7 +55,7 @@
 struct play_tree_iter {
   play_tree_t* root; // Iter root tree
   play_tree_t* tree; // Current tree
-  m_config_t* config; 
+  struct m_config* config; 
   int loop;  // Looping status
   int file;
   int num_files;
@@ -124,7 +123,7 @@
 /// Iterator
 
 play_tree_iter_t*
-play_tree_iter_new(play_tree_t* pt, m_config_t* config);
+play_tree_iter_new(play_tree_t* pt, struct m_config* config);
 
 play_tree_iter_t*
 play_tree_iter_new_copy(play_tree_iter_t* old);
@@ -148,7 +147,7 @@
 play_tree_iter_get_file(play_tree_iter_t* iter, int d);
 
 play_tree_t*
-parse_playtree(stream_t *stream);
+parse_playtree(struct stream_st *stream);
 
 play_tree_t*
 play_tree_cleanup(play_tree_t* pt);

Index: playtreeparser.c
===================================================================
RCS file: /cvsroot/mplayer/main/playtreeparser.c,v
retrieving revision 1.13
retrieving revision 1.14
diff -u -r1.13 -r1.14
--- playtreeparser.c	7 Jul 2002 04:07:57 -0000	1.13
+++ playtreeparser.c	12 Nov 2002 01:56:21 -0000	1.14
@@ -11,6 +11,7 @@
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
+#include "cfgparser.h"
 #include "playtree.h"
 #include "playtreeparser.h"
 #include "libmpdemux/stream.h"

Index: playtreeparser.h
===================================================================
RCS file: /cvsroot/mplayer/main/playtreeparser.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- playtreeparser.h	21 Feb 2002 13:12:53 -0000	1.2
+++ playtreeparser.h	12 Nov 2002 01:56:21 -0000	1.3
@@ -2,11 +2,10 @@
 #ifndef __PLAYTREEPARSER_H
 #define __PLAYTREEPARSER_H
 
-#include "playtree.h"
-#include "libmpdemux/stream.h"
+struct stream_st;
 
 typedef struct play_tree_parser {
-  stream_t* stream;
+  struct stream_st* stream;
   char *buffer,*iter,*line;
   int buffer_size , buffer_end;
   int deep,keep;
@@ -14,7 +13,7 @@
 
 
 play_tree_parser_t*
-play_tree_parser_new(stream_t* stream,int deep);
+play_tree_parser_new(struct stream_st* stream,int deep);
 
 void
 play_tree_parser_free(play_tree_parser_t* p);

Index: Makefile
===================================================================
RCS file: /cvsroot/mplayer/main/Makefile,v
retrieving revision 1.231
retrieving revision 1.232
diff -u -r1.231 -r1.232
--- Makefile	10 Nov 2002 13:12:34 -0000	1.231
+++ Makefile	12 Nov 2002 01:56:21 -0000	1.232
@@ -26,9 +26,9 @@
 # a BSD compatible 'install' program
 INSTALL = install
 
-SRCS_COMMON = cpudetect.c codec-cfg.c cfgparser.c my_profile.c spudec.c playtree.c playtreeparser.c asxparser.c vobsub.c subreader.c sub_cc.c find_sub.c
-SRCS_MENCODER = mencoder.c mp_msg-mencoder.c $(SRCS_COMMON) libao2/afmt.c divx4_vbr.c libvo/aclib.c libvo/osd.c libvo/sub.c libvo/font_load.c libvo/font_load_ft.c xvid_vbr.c
-SRCS_MPLAYER = mplayer.c mp_msg.c $(SRCS_COMMON) mixer.c
+SRCS_COMMON = cpudetect.c codec-cfg.c cfgparser.c my_profile.c spudec.c playtree.c playtreeparser.c asxparser.c vobsub.c subreader.c sub_cc.c find_sub.c m_config.c m_option.c parser-cfg.c
+SRCS_MENCODER = mencoder.c mp_msg-mencoder.c $(SRCS_COMMON) libao2/afmt.c divx4_vbr.c libvo/aclib.c libvo/osd.c libvo/sub.c libvo/font_load.c libvo/font_load_ft.c xvid_vbr.c parser-mecmd.c
+SRCS_MPLAYER = mplayer.c mp_msg.c $(SRCS_COMMON) mixer.c parser-mpcmd.c
 
 ifeq ($(UNRARLIB),yes)
 SRCS_COMMON += unrarlib.c

Index: asxparser.c
===================================================================
RCS file: /cvsroot/mplayer/main/asxparser.c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- asxparser.c	25 Oct 2002 14:13:32 -0000	1.6
+++ asxparser.c	12 Nov 2002 01:56:21 -0000	1.7
@@ -1,3 +1,4 @@
+#include "config.h"
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -5,7 +6,9 @@
 #include <string.h>
 #include <unistd.h>
 
+#include "playtree.h"
 #include "playtreeparser.h"
+#include "libmpdemux/stream.h"
 #include "asxparser.h"
 #include "mp_msg.h"
 #include "cfgparser.h"

Index: asxparser.h
===================================================================
RCS file: /cvsroot/mplayer/main/asxparser.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- asxparser.h	22 Jan 2002 22:47:17 -0000	1.2
+++ asxparser.h	12 Nov 2002 01:56:21 -0000	1.3
@@ -1,5 +1,4 @@
 
-#include "playtree.h"
 
 typedef struct _ASX_Parser_t ASX_Parser_t;
 

Index: cfg-mplayer.h
===================================================================
RCS file: /cvsroot/mplayer/main/cfg-mplayer.h,v
retrieving revision 1.181
retrieving revision 1.182
diff -u -r1.181 -r1.182
--- cfg-mplayer.h	10 Nov 2002 13:57:35 -0000	1.181
+++ cfg-mplayer.h	12 Nov 2002 01:56:21 -0000	1.182
@@ -252,8 +252,8 @@
 	{"x", &opt_screen_size_x, CONF_TYPE_INT, CONF_RANGE, 0, 4096, NULL},
 	{"y", &opt_screen_size_y, CONF_TYPE_INT, CONF_RANGE, 0, 4096, NULL},
 	// set screen dimensions (when not detectable or virtual!=visible)
-	{"screenw", &vo_screenwidth, CONF_TYPE_INT, CONF_RANGE, 0, 4096, NULL},
-	{"screenh", &vo_screenheight, CONF_TYPE_INT, CONF_RANGE, 0, 4096, NULL},
+	{"screenw", &vo_screenwidth, CONF_TYPE_INT, CONF_RANGE|CONF_OLD, 0, 4096, NULL},
+	{"screenh", &vo_screenheight, CONF_TYPE_INT, CONF_RANGE|CONF_OLD, 0, 4096, NULL},
 	// Geometry string
 	{"geometry", &vo_geometry, CONF_TYPE_STRING, 0, 0, 0, NULL},
 	// set aspect ratio of monitor - usefull for 16:9 TVout

Index: cfgparser.c
===================================================================
RCS file: /cvsroot/mplayer/main/cfgparser.c,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -r1.60 -r1.61
--- cfgparser.c	6 Nov 2002 23:54:21 -0000	1.60
+++ cfgparser.c	12 Nov 2002 01:56:21 -0000	1.61
@@ -19,6 +19,8 @@
 
 #include "config.h"
 
+#ifndef NEW_CONFIG
+
 #ifdef USE_SETLOCALE
 #include <locale.h>
 #endif
@@ -50,6 +52,7 @@
 #endif
 
 #include "cfgparser.h"
+#include "playtree.h"
 
 static void m_config_list_options(m_config_t *config);
 static void m_config_error(int err,char* opt,char* val);
@@ -1536,3 +1539,5 @@
     break;
   }
 }
+
+#endif

Index: cfgparser.h
===================================================================
RCS file: /cvsroot/mplayer/main/cfgparser.h,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- cfgparser.h	1 Sep 2002 14:30:40 -0000	1.17
+++ cfgparser.h	12 Nov 2002 01:56:21 -0000	1.18
@@ -2,6 +2,14 @@
  * command line and config file parser
  */
 
+#ifdef NEW_CONFIG
+#ifdef MP_DEBUG
+#warning "NEW_CONFIG defined but still using the old cfgparser.h"
+#endif
+#include "m_config.h"
+#include "m_option.h"
+#else
+
 #ifndef __CONFIG_H
 #define __CONFIG_H
 
@@ -32,13 +40,14 @@
 #define CONF_NOCMD		(1<<3)
 #define CONF_GLOBAL		(1<<4)
 #define CONF_NOSAVE                            (1<<5)
+#define CONF_OLD                                  (1<<6)
 
 
 typedef struct config config_t;
 typedef struct m_config m_config_t;
 typedef struct config_save config_save_t;
 
-#include "playtree.h"
+struct play_tree;
 
 typedef void (*cfg_default_func_t)(config_t *, char*);
 
@@ -62,9 +71,9 @@
   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
+  struct play_tree* pt; // play tree we use for playlist option, etc
+  struct play_tree* last_entry; // last added entry
+  struct play_tree* last_parent; // if last_entry is NULL we must create child of this
   int recursion_depth;
 };
 
@@ -97,7 +106,7 @@
  */
 int m_config_parse_command_line(m_config_t* config, int argc, char **argv);
 
-m_config_t* m_config_new(play_tree_t* pt);
+m_config_t* m_config_new(struct play_tree* pt);
 
 void m_config_free(m_config_t* config);
 
@@ -190,3 +199,5 @@
 m_config_get_float (m_config_t *config, char* arg,int* err_ret);
 
 #endif /* __CONFIG_H */
+
+#endif /* NEW_CONFIG */

Index: configure
===================================================================
RCS file: /cvsroot/mplayer/main/configure,v
retrieving revision 1.602
retrieving revision 1.603
diff -u -r1.602 -r1.603
--- configure	11 Nov 2002 18:25:02 -0000	1.602
+++ configure	12 Nov 2002 01:56:21 -0000	1.603
@@ -151,6 +151,7 @@
   --disable-cdparanoia   Disable cdparanoia support [autodetect]
   --enable-freetype      Enable freetype2 font rendering support [disabled]
   --disable-unrarlib     Disable Unique RAR File Library [enabled]
+  --enable-new-conf      Enable new config stuff [disabled]
 
 Codecs:
   --enable-gif		 enable gif89a output support [autodetect]
@@ -1013,6 +1014,7 @@
 _big_endian=auto
 _freetype=no
 _shared_pp=no
+_new_conf=no
 
 for ac_option do
   case "$ac_option" in
@@ -1193,6 +1195,9 @@
   --enable-shared-pp) _shared_pp=yes ;;
   --disable-shared-pp) _shared_pp=no ;;
 
+  --enable-new-conf) _new_conf=yes ;;
+  --disable-new-conf) _new_conf=no ;;
+
   --language=*)
     LINGUAS=`echo $ac_option | cut -d '=' -f 2`
     ;;
@@ -4235,6 +4240,14 @@
 fi
 echores "$_shared_pp"
 
+echocheck "New config"
+if test "$_new_conf" = yes ; then
+    _def_new_conf='#define NEW_CONFIG 1'
+else
+    _def_new_conf='#undef NEW_CONFIG'
+fi
+echores "$_new_conf"
+
 # --------------- GUI specific tests begin -------------------
 echocheck "GUI"
 echo "$_gui"
@@ -4968,6 +4981,9 @@
 
 /* enables / disables new input joystick support */
 $_def_joystick
+
+/* enables / disables new config */
+$_def_new_conf
 
 /* Extension defines */
 $_def_3dnow	// only define if you have 3DNOW (AMD k6-2, AMD Athlon, iDT WinChip, etc.)

Index: mencoder.c
===================================================================
RCS file: /cvsroot/mplayer/main/mencoder.c,v
retrieving revision 1.184
retrieving revision 1.185
diff -u -r1.184 -r1.185
--- mencoder.c	6 Nov 2002 23:54:21 -0000	1.184
+++ mencoder.c	12 Nov 2002 01:56:21 -0000	1.185
@@ -33,7 +33,14 @@
 #include "cpudetect.h"
 
 #include "codec-cfg.h"
+#ifdef NEW_CONFIG
+#include "m_option.h"
+#include "m_config.h"
+#include "parser-mecmd.h"
+#else
 #include "cfgparser.h"
+#include "playtree.h"
+#endif
 
 #include "libmpdemux/stream.h"
 #include "libmpdemux/demuxer.h"
@@ -41,7 +48,6 @@
 #include "libmpdemux/mp3_hdr.h"
 #include "libmpdemux/aviwrite.h"
 
-#include "playtree.h"
 
 #include "libvo/video_out.h"
 
@@ -196,6 +202,12 @@
 
 m_config_t* mconfig;
 
+#ifdef NEW_CONFIG
+extern int
+m_config_parse_config_file(m_config_t* config, char *conffile);
+#endif
+
+
 static int cfg_inc_verbose(struct config *conf){ ++verbose; return 0;}
 
 static int cfg_include(struct config *conf, char *filename){
@@ -326,8 +338,12 @@
 double v_pts_corr=0;
 double v_timer_corr=0;
 
+#ifdef NEW_CONFIG
+m_entry_t* filelist = NULL;
+#else
 play_tree_t* playtree;
 play_tree_iter_t* playtree_iter;
+#endif
 char* filename=NULL;
 char* frameno_filename="frameno.avi";
 
@@ -357,13 +373,24 @@
   }
 }
 
-  // FIXME: get rid of -dvd and other tricky options and config/playtree
+  // FIXME: get rid of -dvd and other tricky options
   stream2=open_stream(frameno_filename,0,&i);
   if(stream2){
     demuxer2=demux_open(stream2,DEMUXER_TYPE_AVI,-1,-1,-2);
     if(demuxer2) printf(MSGTR_UsingPass3ControllFile,frameno_filename);
   }
 
+  // New config code
+#ifdef NEW_CONFIG
+ mconfig = m_config_new();
+ m_config_register_options(mconfig,mencoder_opts);
+ parse_cfgfiles(mconfig);
+ filelist = m_config_parse_me_command_line(mconfig, argc, argv);
+ if(!filelist) mencoder_exit(1, "error parsing cmdline");
+ m_entry_set_options(mconfig,&filelist[0]);
+ filename = filelist[0].name;
+ // Warn the user if he put more than 1 filename ?
+#else
   playtree = play_tree_new();
   mconfig = m_config_new(playtree);
   m_config_register_options(mconfig,mencoder_opts);
@@ -381,6 +408,7 @@
       filename = play_tree_iter_get_file(playtree_iter,1);
     }
   }
+#endif
 
   if(!filename && !vcd_track && !dvd_title && !tv_param_on){
 	printf(MSGTR_MissingFilename);

Index: mplayer.c
===================================================================
RCS file: /cvsroot/mplayer/main/mplayer.c,v
retrieving revision 1.610
retrieving revision 1.611
diff -u -r1.610 -r1.611
--- mplayer.c	6 Nov 2002 23:54:21 -0000	1.610
+++ mplayer.c	12 Nov 2002 01:56:21 -0000	1.611
@@ -26,7 +26,12 @@
 #define HELP_MP_DEFINE_STATIC
 #include "help_mp.h"
 
+#ifdef NEW_CONFIG
+#include "m_option.h"
+#include "m_config.h"
+#else
 #include "cfgparser.h"
+#endif
 #include "cfg-mplayer-def.h"
 
 #ifdef USE_SUB
@@ -101,6 +106,13 @@
 
 m_config_t* mconfig;
 
+#ifdef NEW_CONFIG
+extern play_tree_t*
+m_config_parse_mp_command_line(m_config_t *config, int argc, char **argv);
+extern int
+m_config_parse_config_file(m_config_t* config, char *conffile);
+#endif
+
 //**************************************************************************//
 //             Config file
 //**************************************************************************//
@@ -584,9 +596,13 @@
       (strrchr(argv[0],'/') && !strcmp(strrchr(argv[0],'/'),"/gmplayer") ) )
           use_gui=1;
 
+#ifdef NEW_CONFIG
+    mconfig = m_config_new();
+#else
     playtree = play_tree_new();
 
     mconfig = m_config_new(playtree);
+#endif
     m_config_register_options(mconfig,mplayer_opts);
     // TODO : add something to let modules register their options
     mp_input_register_options(mconfig);
@@ -596,7 +612,13 @@
     if ( use_gui ) cfg_read();
 #endif
 
+#ifdef NEW_CONFIG
+    playtree = m_config_parse_mp_command_line(mconfig, argc, argv);
+    if(playtree == NULL)
+      exit(1);
+#else
     if(m_config_parse_command_line(mconfig, argc, argv) < 0) exit(1); // error parsing cmdline
+#endif
 
     playtree = play_tree_cleanup(playtree);
     if(playtree) {




More information about the MPlayer-cvslog mailing list