mirror of
https://github.com/mpv-player/mpv
synced 2025-03-29 15:00:27 +00:00
options: support parsing values into substructs
Add an alternate mode for option parser objects (struct m_config) which is not inherently tied to any particular instance of an option value struct. Instead, this type or parsers can be used to initialize defaults in or parse values into a struct given as a parameter. They do not have the save slot functionality used for main player configuration. The new functionality will be used to replace the separate subopt_helper.c parsing code that is currently used to parse per-object suboptions in VOs etc. Previously, option default values were handled by initializing them in external code before creating a parser. This initialization was done with constants even for dynamically-allocated types like strings. Because trying to free a pointer to a constant would cause a crash when trying to replace the default with another value, parser initialization code then replaced all the original defaults with dynamically-allocated copies. This replace-with-copy behavior is no longer supported for new-style options; instead the option definition itself may contain a default value (new OPTDEF macros), and the new function m_config_initialize() is used to set all options to their default values. Convert the existing initialized dynamically allocated options in main config (the string options --dumpfile, --term-osd-esc, --input=conf) to use this. Other non-dynamic ones could be later converted to use this style of initialization too. There's currently no public call to free all dynamically allocated options in a given option struct because I intend to use talloc functionality for that (make them children of the struct and free with it).
This commit is contained in:
parent
f63dbaddb6
commit
dc2a4863af
@ -863,7 +863,7 @@ const m_option_t mplayer_opts[]={
|
||||
OPT_FLAG_ON("benchmark", benchmark, 0),
|
||||
|
||||
// dump some stream out instead of playing the file
|
||||
OPT_STRING("dumpfile", stream_dump_name, 0),
|
||||
OPT_STRING("dumpfile", stream_dump_name, 0, OPTDEF_STR("stream.dump")),
|
||||
{"dumpaudio", &stream_dump_type, CONF_TYPE_FLAG, 0, 0, 1, NULL},
|
||||
{"dumpvideo", &stream_dump_type, CONF_TYPE_FLAG, 0, 0, 2, NULL},
|
||||
{"dumpsub", &stream_dump_type, CONF_TYPE_FLAG, 0, 0, 3, NULL},
|
||||
@ -912,7 +912,7 @@ const m_option_t mplayer_opts[]={
|
||||
#endif
|
||||
|
||||
OPT_MAKE_FLAGS("term-osd", term_osd, 0),
|
||||
OPT_STRING("term-osd-esc", term_osd_esc, 0),
|
||||
OPT_STRING("term-osd-esc", term_osd_esc, 0, OPTDEF_STR("\x1b[A\r\x1b[K")),
|
||||
OPT_STRING("playing-msg", playing_msg, 0),
|
||||
|
||||
{"slave", &slave_mode, CONF_TYPE_FLAG,CONF_GLOBAL , 0, 1, NULL},
|
||||
|
@ -22,7 +22,6 @@ void set_default_mplayer_options(struct MPOpts *opts)
|
||||
.vo_gamma_hue = 1000,
|
||||
.osd_level = 1,
|
||||
.osd_duration = 1000,
|
||||
.stream_dump_name = "stream.dump",
|
||||
.loop_times = -1,
|
||||
.ordered_chapters = 1,
|
||||
.chapter_merge_threshold = 100,
|
||||
@ -33,7 +32,6 @@ void set_default_mplayer_options(struct MPOpts *opts)
|
||||
.user_correct_pts = -1,
|
||||
.initial_audio_sync = 1,
|
||||
.term_osd = 1,
|
||||
.term_osd_esc = "\x1b[A\r\x1b[K",
|
||||
.consolecontrols = 1,
|
||||
.doubleclick_time = 300,
|
||||
.audio_id = -1,
|
||||
@ -60,7 +58,6 @@ void set_default_mplayer_options(struct MPOpts *opts)
|
||||
.error_concealment = 3,
|
||||
},
|
||||
.input = {
|
||||
.config_file = "input.conf",
|
||||
.key_fifo_size = 7,
|
||||
.ar_delay = 100,
|
||||
.ar_rate = 8,
|
||||
|
@ -638,7 +638,7 @@ static int print_cmd_list(m_option_t *cfg, char *optname, char *optparam);
|
||||
|
||||
// Our command line options
|
||||
static const m_option_t input_conf[] = {
|
||||
OPT_STRING("conf", input.config_file, CONF_GLOBAL),
|
||||
OPT_STRING("conf", input.config_file, CONF_GLOBAL, OPTDEF_STR("input.conf")),
|
||||
OPT_INT("ar-delay", input.ar_delay, CONF_GLOBAL),
|
||||
OPT_INT("ar-rate", input.ar_rate, CONF_GLOBAL),
|
||||
{ "keylist", print_key_list, CONF_TYPE_PRINT_FUNC, CONF_NOCFG },
|
||||
|
132
m_config.c
132
m_config.c
@ -148,11 +148,11 @@ static void m_option_save(const struct m_config *config,
|
||||
}
|
||||
}
|
||||
|
||||
static void m_option_set(const struct m_config *config,
|
||||
static void m_option_set(void *optstruct,
|
||||
const struct m_option *opt, const void *src)
|
||||
{
|
||||
if (opt->type->copy) {
|
||||
void *dst = m_option_get_ptr(opt, config->optstruct);
|
||||
void *dst = m_option_get_ptr(opt, optstruct);
|
||||
opt->type->copy(opt, dst, src);
|
||||
}
|
||||
}
|
||||
@ -176,6 +176,7 @@ struct m_config *m_config_new(void *optstruct,
|
||||
};
|
||||
|
||||
config = talloc_zero(NULL, struct m_config);
|
||||
config->full = true;
|
||||
config->lvl = 1; // 0 Is the defaults
|
||||
struct m_option *self_opts = talloc_memdup(config, ref_opts,
|
||||
sizeof(ref_opts));
|
||||
@ -195,8 +196,16 @@ struct m_config *m_config_new(void *optstruct,
|
||||
return config;
|
||||
}
|
||||
|
||||
struct m_config *m_config_simple(const struct m_option *options)
|
||||
{
|
||||
struct m_config *config = talloc_zero(NULL, struct m_config);
|
||||
m_config_register_options(config, options);
|
||||
return config;
|
||||
}
|
||||
|
||||
void m_config_free(struct m_config *config)
|
||||
{
|
||||
assert(config->full); // use talloc_free() for simple
|
||||
struct m_config_option *copt;
|
||||
for (copt = config->opts; copt; copt = copt->next) {
|
||||
if (copt->flags & M_CFG_OPT_ALIAS)
|
||||
@ -213,6 +222,17 @@ void m_config_free(struct m_config *config)
|
||||
talloc_free(config);
|
||||
}
|
||||
|
||||
void m_config_initialize(struct m_config *config, void *optstruct)
|
||||
{
|
||||
struct m_config_option *copt;
|
||||
for (copt = config->opts; copt; copt = copt->next) {
|
||||
const struct m_option *opt = copt->opt;
|
||||
if (!opt->defval)
|
||||
continue;
|
||||
m_option_set(optstruct, opt, opt->defval);
|
||||
}
|
||||
}
|
||||
|
||||
void m_config_push(struct m_config *config)
|
||||
{
|
||||
struct m_config_option *co;
|
||||
@ -278,7 +298,7 @@ void m_config_pop(struct m_config *config)
|
||||
pop++;
|
||||
}
|
||||
if (pop) // We removed some ctx -> set the previous value
|
||||
m_option_set(config, co->opt, co->slots->data);
|
||||
m_option_set(config->optstruct, co->opt, co->slots->data);
|
||||
}
|
||||
|
||||
config->lvl--;
|
||||
@ -314,7 +334,7 @@ static void m_config_add_option(struct m_config *config,
|
||||
struct m_config_save_slot *sl;
|
||||
|
||||
assert(config != NULL);
|
||||
assert(config->lvl > 0);
|
||||
assert(config->lvl > 0 || !config->full);
|
||||
assert(arg != NULL);
|
||||
|
||||
// Allocate a new entry for this option
|
||||
@ -346,18 +366,18 @@ static void m_config_add_option(struct m_config *config,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(co->flags & M_CFG_OPT_ALIAS)) {
|
||||
if (config->full && !(co->flags & M_CFG_OPT_ALIAS)) {
|
||||
// Allocate a slot for the defaults
|
||||
sl = talloc_zero_size(co, sizeof(struct m_config_save_slot) +
|
||||
arg->type->size);
|
||||
m_option_save(config, arg, sl->data);
|
||||
// Hack to avoid too much trouble with dynamically allocated data:
|
||||
// We replace original default and always use a dynamic version
|
||||
if ((arg->type->flags & M_OPT_TYPE_DYNAMIC)) {
|
||||
if (!arg->new && (arg->type->flags & M_OPT_TYPE_DYNAMIC)) {
|
||||
char **hackptr = m_option_get_ptr(arg, config->optstruct);
|
||||
if (hackptr && *hackptr) {
|
||||
*hackptr = NULL;
|
||||
m_option_set(config, arg, sl->data);
|
||||
m_option_set(config->optstruct, arg, sl->data);
|
||||
}
|
||||
}
|
||||
sl->lvl = 0;
|
||||
@ -377,7 +397,7 @@ int m_config_register_options(struct m_config *config,
|
||||
const struct m_option *args)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(config->lvl > 0);
|
||||
assert(config->lvl > 0 || !config->full);
|
||||
assert(args != NULL);
|
||||
|
||||
add_options(config, args, NULL, NULL);
|
||||
@ -403,12 +423,15 @@ static struct m_config_option *m_config_get_co(const struct m_config *config,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int m_config_parse_option(struct m_config *config,
|
||||
static int parse_subopts(struct m_config *config, void *optstruct, char *name,
|
||||
char *prefix, struct bstr param, bool set);
|
||||
|
||||
static int m_config_parse_option(struct m_config *config, void *optstruct,
|
||||
struct bstr name, struct bstr param,
|
||||
bool ambiguous_param, bool set)
|
||||
{
|
||||
assert(config != NULL);
|
||||
assert(config->lvl > 0);
|
||||
assert(config->lvl > 0 || !config->full);
|
||||
assert(name.len != 0);
|
||||
|
||||
struct m_config_option *co = m_config_get_co(config, name);
|
||||
@ -453,43 +476,13 @@ static int m_config_parse_option(struct m_config *config,
|
||||
|
||||
// Option with children are a bit different to parse
|
||||
if (co->opt->type->flags & M_OPT_TYPE_HAS_CHILD) {
|
||||
char **lst = NULL;
|
||||
// Parse the child options
|
||||
int r = m_option_parse(co->opt, name, param, false, &lst);
|
||||
// Set them now
|
||||
if (r >= 0)
|
||||
for (int 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]);
|
||||
int sr = m_config_parse_option(config, bstr(n),
|
||||
bstr(lst[2 * i + 1]), false,
|
||||
set);
|
||||
if (sr < 0) {
|
||||
if (sr == M_OPT_UNKNOWN) {
|
||||
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
|
||||
"Error: option '%s' has no suboption '%s'.\n",
|
||||
co->name, lst[2 * i]);
|
||||
r = M_OPT_INVALID;
|
||||
} else if (sr == M_OPT_MISSING_PARAM) {
|
||||
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
|
||||
"Error: suboption '%s' of '%s' must have "
|
||||
"a parameter!\n", lst[2 * i], co->name);
|
||||
r = M_OPT_INVALID;
|
||||
} else
|
||||
r = sr;
|
||||
}
|
||||
}
|
||||
talloc_free(lst[2 * i]);
|
||||
talloc_free(lst[2 * i + 1]);
|
||||
}
|
||||
talloc_free(lst);
|
||||
return r;
|
||||
char prefix[110];
|
||||
assert(strlen(co->name) < 100);
|
||||
sprintf(prefix, "%s:", co->name);
|
||||
return parse_subopts(config, optstruct, co->name, prefix, param, set);
|
||||
}
|
||||
|
||||
void *dst = set ? m_option_get_ptr(co->opt, config->optstruct) : NULL;
|
||||
void *dst = set ? m_option_get_ptr(co->opt, optstruct) : NULL;
|
||||
int r = m_option_parse(co->opt, name, param, ambiguous_param, dst);
|
||||
// Parsing failed ?
|
||||
if (r < 0)
|
||||
@ -500,12 +493,49 @@ static int m_config_parse_option(struct m_config *config,
|
||||
return r;
|
||||
}
|
||||
|
||||
static int parse_subopts(struct m_config *config, void *optstruct, char *name,
|
||||
char *prefix, struct bstr param, bool set)
|
||||
{
|
||||
char **lst = NULL;
|
||||
// Split the argument into child options
|
||||
int r = m_option_type_subconfig.parse(NULL, bstr(""), param, false, &lst);
|
||||
if (r < 0)
|
||||
return r;
|
||||
// Parse the child options
|
||||
for (int i = 0; lst && lst[2 * i]; i++) {
|
||||
// Build the full name
|
||||
char n[110];
|
||||
if (snprintf(n, 110, "%s%s", prefix, lst[2 * i]) > 100)
|
||||
abort();
|
||||
int sr = m_config_parse_option(config, optstruct, bstr(n),
|
||||
bstr(lst[2 * i + 1]), false, set);
|
||||
if (sr < 0) {
|
||||
if (sr == M_OPT_UNKNOWN) {
|
||||
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
|
||||
"Error: option '%s' has no suboption '%s'.\n",
|
||||
name, lst[2 * i]);
|
||||
r = M_OPT_INVALID;
|
||||
} else if (sr == M_OPT_MISSING_PARAM) {
|
||||
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
|
||||
"Error: suboption '%s' of '%s' must have "
|
||||
"a parameter!\n", lst[2 * i], name);
|
||||
r = M_OPT_INVALID;
|
||||
} else
|
||||
r = sr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
talloc_free(lst);
|
||||
return r;
|
||||
}
|
||||
|
||||
int m_config_set_option(struct m_config *config, struct bstr name,
|
||||
struct bstr param, bool ambiguous_param)
|
||||
{
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Setting %.*s=%.*s\n", BSTR_P(name),
|
||||
BSTR_P(param));
|
||||
return m_config_parse_option(config, name, param, ambiguous_param, 1);
|
||||
return m_config_parse_option(config, config->optstruct, name, param,
|
||||
ambiguous_param, true);
|
||||
}
|
||||
|
||||
int m_config_check_option(struct m_config *config, struct bstr name,
|
||||
@ -514,7 +544,7 @@ int m_config_check_option(struct m_config *config, struct bstr name,
|
||||
int r;
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Checking %.*s=%.*s\n", BSTR_P(name),
|
||||
BSTR_P(param));
|
||||
r = m_config_parse_option(config, name, param, ambiguous_param, 0);
|
||||
r = m_config_parse_option(config, NULL, name, param, ambiguous_param, 0);
|
||||
if (r == M_OPT_MISSING_PARAM) {
|
||||
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
|
||||
"Error: option '%.*s' must have a parameter!\n", BSTR_P(name));
|
||||
@ -523,6 +553,14 @@ int m_config_check_option(struct m_config *config, struct bstr name,
|
||||
return r;
|
||||
}
|
||||
|
||||
int m_config_parse_suboptions(struct m_config *config, void *optstruct,
|
||||
char *name, char *subopts)
|
||||
{
|
||||
if (!subopts || !*subopts)
|
||||
return 0;
|
||||
return parse_subopts(config, optstruct, name, "", bstr(subopts), true);
|
||||
}
|
||||
|
||||
|
||||
const struct m_option *m_config_get_option(const struct m_config *config,
|
||||
struct bstr name)
|
||||
|
@ -96,6 +96,7 @@ typedef struct m_config {
|
||||
|
||||
void *optstruct; // struct mpopts or other
|
||||
int (*includefunc)(struct m_config *conf, char *filename);
|
||||
bool full; // main config with save slot handling etc
|
||||
} m_config_t;
|
||||
|
||||
|
||||
@ -110,6 +111,10 @@ struct m_config *
|
||||
m_config_new(void *optstruct,
|
||||
int includefunc(struct m_config *conf, char *filename));
|
||||
|
||||
struct m_config *m_config_simple(const struct m_option *options);
|
||||
|
||||
void m_config_initialize(struct m_config *conf, void *optstruct);
|
||||
|
||||
// Free a config object.
|
||||
void m_config_free(struct m_config *config);
|
||||
|
||||
@ -162,6 +167,9 @@ static inline int m_config_check_option0(struct m_config *config,
|
||||
return m_config_check_option(config, bstr(name), bstr(param), ambiguous);
|
||||
}
|
||||
|
||||
int m_config_parse_suboptions(struct m_config *config, void *optstruct,
|
||||
char *name, char *subopts);
|
||||
|
||||
|
||||
/* Get the option matching the given name.
|
||||
* \param config The config object.
|
||||
|
19
m_option.c
19
m_option.c
@ -821,14 +821,13 @@ const m_option_type_t m_option_type_print_func = {
|
||||
static int parse_subconf(const m_option_t *opt, struct bstr name,
|
||||
struct bstr param, bool ambiguous_param, void *dst)
|
||||
{
|
||||
int nr = 0, i;
|
||||
int nr = 0;
|
||||
char **lst = NULL;
|
||||
|
||||
if (param.len == 0)
|
||||
return M_OPT_MISSING_PARAM;
|
||||
|
||||
struct bstr p = param;
|
||||
const struct m_option *subopts = opt->p;
|
||||
|
||||
while (p.len) {
|
||||
int optlen = bstrcspn(p, ":=");
|
||||
@ -874,23 +873,11 @@ static int parse_subconf(const m_option_t *opt, struct bstr name,
|
||||
return M_OPT_INVALID;
|
||||
}
|
||||
|
||||
for (i = 0; subopts[i].name; i++)
|
||||
if (!bstrcmp0(subopt, subopts[i].name))
|
||||
break;
|
||||
if (!subopts[i].name) {
|
||||
mp_msg(MSGT_CFGPARSER, MSGL_ERR,
|
||||
"Option %.*s: Unknown suboption %.*s\n",
|
||||
BSTR_P(name), BSTR_P(subopt));
|
||||
return M_OPT_UNKNOWN;
|
||||
}
|
||||
int r = m_option_parse(&subopts[i], subopt, subparam, false, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (dst) {
|
||||
lst = talloc_realloc(NULL, lst, char *, 2 * (nr + 2));
|
||||
lst[2 * nr] = bstrdup0(NULL, subopt);
|
||||
lst[2 * nr] = bstrdup0(lst, subopt);
|
||||
lst[2 * nr + 1] = subparam.len == 0 ? NULL :
|
||||
bstrdup0(NULL, subparam);
|
||||
bstrdup0(lst, subparam);
|
||||
memset(&lst[2 * (nr + 1)], 0, 2 * sizeof(char *));
|
||||
nr++;
|
||||
}
|
||||
|
50
m_option.h
50
m_option.h
@ -256,6 +256,9 @@ struct m_option {
|
||||
int new;
|
||||
|
||||
int offset;
|
||||
|
||||
// Initialize variable to given default before parsing options
|
||||
void *defval;
|
||||
};
|
||||
|
||||
|
||||
@ -424,22 +427,39 @@ static inline void m_option_free(const m_option_t *opt, void *dst)
|
||||
#define OPT_START_CONDITIONAL(enable, featurename) OPT_START_CONDITIONAL_AFTERMACROEVAL(enable, featurename)
|
||||
#define OPT_START_CONDITIONAL_AFTERMACROEVAL(enable, featurename) {"conditional functionality: " #enable, .p = featurename}
|
||||
|
||||
#define OPT_FLAG_ON(optname, varname, flags) {optname, NULL, &m_option_type_flag, flags, 0, 1, NULL, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPT_FLAG_OFF(optname, varname, flags) {optname, NULL, &m_option_type_flag, flags, 1, 0, NULL, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPTDEF_STR(s) .defval = (void *)&(char * const){s}
|
||||
#define OPTDEF_INT(i) .defval = (void *)&(const int){i}
|
||||
|
||||
#define OPT_GENERAL(optname, varname, flagv, ...) {.name = optname, .flags = flagv, .new = 1, .offset = offsetof(OPT_BASE_STRUCT, varname), __VA_ARGS__}
|
||||
|
||||
/* The OPT_FLAG_CONSTANTS->OPT_FLAG_CONSTANTS_ kind of redirection exists to
|
||||
* make the code fully standard-conforming: the C standard requires that
|
||||
* __VA_ARGS__ has at least one argument (though GCC for example would accept
|
||||
* 0). Thus the first OPT_FLAG_CONSTANTS is a wrapper which just adds one
|
||||
* argument to ensure __VA_ARGS__ is not empty when calling the next macro.
|
||||
*/
|
||||
#define OPT_FLAG_ON(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_flag, .max = 1)
|
||||
#define OPT_FLAG_OFF(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_flag, .min = 1)
|
||||
#define OPT_MAKE_FLAGS(optname, varname, flags) OPT_FLAG_ON(optname, varname, flags), OPT_FLAG_OFF("no" optname, varname, flags)
|
||||
#define OPT_FLAG_CONSTANTS(optname, varname, flags, offvalue, value) {optname, NULL, &m_option_type_flag, flags, offvalue, value, NULL, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPT_STRINGLIST(optname, varname, flags) {optname, NULL, &m_option_type_string_list, flags, 0, 0, NULL, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPT_PATHLIST(optname, varname, flags) {optname, NULL, &m_option_type_string_list, flags, 0, 0, (void *)&(const char){OPTION_PATH_SEPARATOR}, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPT_INT(optname, varname, flags) {optname, NULL, &m_option_type_int, flags, 0, 0, NULL, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPT_INTRANGE(optname, varname, flags, min, max) {optname, NULL, &m_option_type_int, (flags) | CONF_RANGE, min, max, NULL, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPT_INTPAIR(optname, varname, flags) {optname, NULL, &m_option_type_intpair, (flags), 0, 0, NULL, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPT_FLOATRANGE(optname, varname, flags, min, max) {optname, NULL, &m_option_type_float, (flags) | CONF_RANGE, min, max, NULL, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPT_STRING(optname, varname, flags) {optname, NULL, &m_option_type_string, flags, 0, 0, NULL, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPT_SETTINGSLIST(optname, varname, flags, objlist) {optname, NULL, &m_option_type_obj_settings_list, flags, 0, 0, objlist, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPT_AUDIOFORMAT(optname, varname, flags) {optname, NULL, &m_option_type_afmt, flags, 0, 0, NULL, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPT_FLAG_CONSTANTS(...) OPT_FLAG_CONSTANTS_(__VA_ARGS__, .type = &m_option_type_flag)
|
||||
#define OPT_FLAG_CONSTANTS_(optname, varname, flags, offvalue, value, ...) OPT_GENERAL(optname, varname, flags, .min = offvalue, .max = value, __VA_ARGS__)
|
||||
#define OPT_STRINGLIST(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_string_list)
|
||||
#define OPT_PATHLIST(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_string_list, .priv = (void *)&(const char){OPTION_PATH_SEPARATOR})
|
||||
#define OPT_INT(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_int)
|
||||
#define OPT_INTRANGE(...) OPT_RANGE_(__VA_ARGS__, .type = &m_option_type_int)
|
||||
#define OPT_RANGE_(optname, varname, flags, minval, maxval, ...) OPT_GENERAL(optname, varname, (flags) | CONF_RANGE, .min = minval, .max = maxval, __VA_ARGS__)
|
||||
#define OPT_INTPAIR(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_intpair)
|
||||
#define OPT_FLOAT(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_float)
|
||||
#define OPT_FLOATRANGE(...) OPT_RANGE_(__VA_ARGS__, .type = &m_option_type_float)
|
||||
#define OPT_STRING(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_string)
|
||||
#define OPT_SETTINGSLIST(optname, varname, flags, objlist) OPT_GENERAL(optname, varname, flags, .type = &m_option_type_obj_settings_list, .priv = objlist)
|
||||
#define OPT_AUDIOFORMAT(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_afmt)
|
||||
#define OPT_HELPER_REMOVEPAREN(...) __VA_ARGS__
|
||||
#define OPT_CHOICE(optname, varname, flags, choices) {optname, NULL, &m_option_type_choice, flags, 0, 0, (void *)&(const struct m_opt_choice_alternatives[]){OPT_HELPER_REMOVEPAREN choices, {NULL}}, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPT_TIME(optname, varname, flags) {optname, NULL, &m_option_type_time, flags, 0, 0, NULL, 1, offsetof(struct MPOpts, varname)}
|
||||
#define OPT_ERRORMESSAGE(optname, message) {optname, message, CONF_TYPE_PRINT}
|
||||
#define OPT_CHOICE(...) OPT_CHOICE_(__VA_ARGS__, .type = &m_option_type_choice)
|
||||
#define OPT_CHOICE_(optname, varname, flags, choices, ...) OPT_GENERAL(optname, varname, flags, .priv = (void *)&(const struct m_opt_choice_alternatives[]){OPT_HELPER_REMOVEPAREN choices, {NULL}}, __VA_ARGS__)
|
||||
#define OPT_TIME(...) OPT_GENERAL(__VA_ARGS__, .type = &m_option_type_time)
|
||||
#define OPT_ERRORMESSAGE(optname, message) {.name = optname, .p = message, .type = &m_option_type_print}
|
||||
|
||||
#define OPT_BASE_STRUCT struct MPOpts
|
||||
|
||||
#endif /* MPLAYER_M_OPTION_H */
|
||||
|
@ -3942,6 +3942,7 @@ int main(int argc, char *argv[])
|
||||
m_config_register_options(mpctx->mconfig, mplayer_opts);
|
||||
m_config_register_options(mpctx->mconfig, common_opts);
|
||||
mp_input_register_options(mpctx->mconfig);
|
||||
m_config_initialize(mpctx->mconfig, opts);
|
||||
|
||||
// Preparse the command line
|
||||
m_config_preparse_command_line(mpctx->mconfig, argc, argv, &verbose);
|
||||
|
Loading…
Reference in New Issue
Block a user