diff options
-rw-r--r-- | core/m_config.c | 16 | ||||
-rw-r--r-- | core/m_config.h | 5 | ||||
-rw-r--r-- | core/m_option.c | 50 | ||||
-rw-r--r-- | core/m_option.h | 5 | ||||
-rw-r--r-- | core/mplayer.c | 2 | ||||
-rw-r--r-- | video/out/vo_opengl.c | 6 |
6 files changed, 48 insertions, 36 deletions
diff --git a/core/m_config.c b/core/m_config.c index dda55fb107..6ae3e9e764 100644 --- a/core/m_config.c +++ b/core/m_config.c @@ -191,7 +191,8 @@ static int config_destroy(void *p) struct m_config *m_config_new(void *talloc_parent, size_t size, const void *defaults, - const struct m_option *options) + const struct m_option *options, + const char *suboptinit) { struct m_config *config = talloc(talloc_parent, struct m_config); talloc_set_destructor(config, config_destroy); @@ -199,6 +200,7 @@ struct m_config *m_config_new(void *talloc_parent, size_t size, .optstruct_size = size, .optstruct_defaults = defaults, .options = options, + .suboptinit = suboptinit, }; if (size) { // size==0 means a dummy object is created config->optstruct = talloc_zero_size(config, size); @@ -207,6 +209,13 @@ struct m_config *m_config_new(void *talloc_parent, size_t size, if (options) add_options(config, NULL, options); } + if (suboptinit) { + bstr s = bstr0(suboptinit); + int r = m_obj_parse_sub_config(bstr0("internal"), bstr0("-"), &s, + config, 0, NULL); + if (r < 0 || s.len > 0) + mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Internal error: preset broken\n"); + } return config; } @@ -214,7 +223,7 @@ struct m_config *m_config_from_obj_desc(void *talloc_parent, struct m_obj_desc *desc) { return m_config_new(talloc_parent, desc->priv_size, desc->priv_defaults, - desc->options); + desc->options, desc->init_options); } int m_config_set_obj_params(struct m_config *conf, char **args) @@ -638,7 +647,8 @@ int m_config_option_requires_param(struct m_config *config, bstr name) static struct m_config *get_defaults(const struct m_config *config) { return m_config_new(NULL, config->optstruct_size, - config->optstruct_defaults, config->options); + config->optstruct_defaults, config->options, + config->suboptinit); } static char *get_option_value_string(const struct m_config *config, diff --git a/core/m_config.h b/core/m_config.h index dbc334c3aa..09b4961a06 100644 --- a/core/m_config.h +++ b/core/m_config.h @@ -72,6 +72,7 @@ typedef struct m_config { const void *optstruct_defaults; size_t optstruct_size; const struct m_option *options; // top-level options + const char *suboptinit; void *optstruct; // struct mpopts or other } m_config_t; @@ -83,10 +84,12 @@ typedef struct m_config { // contains default values for all options // options: list of options. Each option defines a member of the optstruct // and a corresponding option switch or sub-option field. +// suboptinit: if not NULL, initialize the suboption string (used for presets) // Note that the m_config object will keep pointers to defaults and options. struct m_config *m_config_new(void *talloc_parent, size_t size, const void *defaults, - const struct m_option *options); + const struct m_option *options, + const char *suboptinit); struct m_config *m_config_from_obj_desc(void *talloc_parent, struct m_obj_desc *desc); diff --git a/core/m_option.c b/core/m_option.c index 339b6017f4..abcb13c038 100644 --- a/core/m_option.c +++ b/core/m_option.c @@ -1963,7 +1963,7 @@ static void copy_obj_settings_list(const m_option_t *opt, void *dst, // option names/values are correct. Try to determine whether an option // without '=' sets a flag, or whether it's a positional argument. static int get_obj_param(bstr opt_name, bstr obj_name, struct m_config *config, - bstr name, bstr val, int *nold, + bstr name, bstr val, int flags, int *nold, bstr *out_name, bstr *out_val) { int r; @@ -1975,7 +1975,7 @@ static int get_obj_param(bstr opt_name, bstr obj_name, struct m_config *config, // If it's just "name", and the associated option exists and is a flag, // don't accept it as positional argument. if (val.start || m_config_option_requires_param(config, name) == 0) { - r = m_config_set_option(config, name, val); + r = m_config_set_option_ext(config, name, val, flags); if (r < 0) { if (r == M_OPT_UNKNOWN) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, @@ -2007,7 +2007,7 @@ static int get_obj_param(bstr opt_name, bstr obj_name, struct m_config *config, BSTR_P(opt_name), BSTR_P(obj_name), *nold, *nold); return M_OPT_OUT_OF_RANGE; } - r = m_config_set_option(config, bstr0(opt), val); + r = m_config_set_option_ext(config, bstr0(opt), val, flags); if (r < 0) { if (r > M_OPT_EXIT) mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: " @@ -2023,11 +2023,14 @@ static int get_obj_param(bstr opt_name, bstr obj_name, struct m_config *config, } // Consider -vf a=b:c:d. This parses "b:c:d" into name/value pairs, stored as -// linear array in *_ret. In particular, desc contains what options a the +// linear array in *_ret. In particular, config contains what options a the // object takes, and verifies the option values as well. -static int get_obj_params(struct bstr opt_name, struct bstr name, - struct bstr *pstr, struct m_obj_desc *desc, - char ***ret) +// If config is NULL, all parameters are accepted without checking. +// _ret set to NULL can be used for checking-only. +// flags can contain any M_SETOPT_* flag. +int m_obj_parse_sub_config(struct bstr opt_name, struct bstr name, + struct bstr *pstr, struct m_config *config, + int flags, char ***ret) { int nold = 0; char **args = NULL; @@ -2040,8 +2043,6 @@ static int get_obj_params(struct bstr opt_name, struct bstr name, num_args++; } - struct m_config *config = desc ? m_config_from_obj_desc(NULL, desc) : NULL; - while (pstr->len > 0) { bstr fname, fval; r = split_subconf(opt_name, pstr, &fname, &fval); @@ -2049,7 +2050,7 @@ static int get_obj_params(struct bstr opt_name, struct bstr name, goto exit; if (bstr_equals0(fname, "help")) goto print_help; - r = get_obj_param(opt_name, name, config, fname, fval, &nold, + r = get_obj_param(opt_name, name, config, fname, fval, flags, &nold, &fname, &fval); if (r < 0) goto exit; @@ -2088,7 +2089,6 @@ print_help: ; exit: free_str_list(&args); - talloc_free(config); return r; } @@ -2121,8 +2121,11 @@ static int parse_obj_settings(struct bstr opt, struct bstr *pstr, if (bstr_eatstart0(pstr, "=") || bstr_eatstart0(pstr, ":")) has_param = true; + bool legacy = false; bool skip = false; - if (!m_obj_list_find(&desc, list, str)) { + if (m_obj_list_find(&desc, list, str)) { + legacy = !desc.priv_size && list->legacy_hacks; + } else { if (!list->allow_unknown_entries) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Option %.*s: %.*s doesn't exist.\n", BSTR_P(opt), BSTR_P(str)); @@ -2132,21 +2135,8 @@ static int parse_obj_settings(struct bstr opt, struct bstr *pstr, skip = true; } - if (desc.init_options && _ret) { - bstr s = bstr0(desc.init_options); - r = get_obj_params(opt, str, &s, &desc, &plist); - if (r < 0 || s.len > 0) { - mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Internal error: preset broken\n"); - return r; - } - } - if (has_param) { - if (skip) { - r = get_obj_params(opt, str, pstr, NULL, _ret ? &plist : NULL); - if (r < 0) - return r; - } else if (!desc.priv_size && list->legacy_hacks) { + if (legacy) { // Should perhaps be parsed as escape-able string. But this is a // compatibility path, so it's not worth the trouble. int next = bstrcspn(*pstr, ","); @@ -2164,7 +2154,13 @@ static int parse_obj_settings(struct bstr opt, struct bstr *pstr, plist[1] = bstrto0(NULL, param); } } else { - r = get_obj_params(opt, str, pstr, &desc, _ret ? &plist : NULL); + struct m_config *config = NULL; + if (!skip) + config = m_config_from_obj_desc(NULL, &desc); + r = m_obj_parse_sub_config(opt, str, pstr, config, + M_SETOPT_CHECK_ONLY, + _ret ? &plist : NULL); + talloc_free(config); if (r < 0) return r; } diff --git a/core/m_option.h b/core/m_option.h index 9cd5202b90..6d44ce6696 100644 --- a/core/m_option.h +++ b/core/m_option.h @@ -32,6 +32,7 @@ typedef struct m_option_type m_option_type_t; typedef struct m_option m_option_t; struct m_struct_st; +struct m_config; ///////////////////////////// Options types declarations //////////////////// @@ -150,6 +151,10 @@ typedef struct m_obj_settings { */ extern const m_option_type_t m_option_type_obj_settings_list; +int m_obj_parse_sub_config(struct bstr opt_name, struct bstr name, + struct bstr *pstr, struct m_config *config, + int flags, char ***ret); + // Parse an URL into a struct. /** The option priv field (\ref m_option::priv) must point to a * \ref m_struct_st describing which fields of the URL must be used. diff --git a/core/mplayer.c b/core/mplayer.c index 4ccfc6f526..0238e10be3 100644 --- a/core/mplayer.c +++ b/core/mplayer.c @@ -4609,7 +4609,7 @@ static int mpv_main(int argc, char *argv[]) // Create the config context and register the options mpctx->mconfig = m_config_new(mpctx, sizeof(struct MPOpts), - &mp_default_opts, mp_opts); + &mp_default_opts, mp_opts, NULL); mpctx->opts = mpctx->mconfig->optstruct; mpctx->mconfig->includefunc = cfg_include; mpctx->mconfig->use_profiles = true; diff --git a/video/out/vo_opengl.c b/video/out/vo_opengl.c index 2a2dbf9e21..ee9c2a06ee 100644 --- a/video/out/vo_opengl.c +++ b/video/out/vo_opengl.c @@ -199,11 +199,9 @@ static bool reparse_cmdline(struct gl_priv *p, char *args) opts = p->renderer_opts; } else { cfg = m_config_new(NULL, sizeof(*opts), gl_video_conf.defaults, - gl_video_conf.opts); + gl_video_conf.opts, + p->vo->driver->init_option_string); opts = cfg->optstruct; - const char *init = p->vo->driver->init_option_string; - if (init) - m_config_parse_suboptions(cfg, "opengl", (char *)init); r = m_config_parse_suboptions(cfg, "opengl", args); } |