diff options
author | wm4 <wm4@nowhere> | 2016-08-31 16:45:58 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-08-31 16:45:58 +0200 |
commit | e024906408c4d079e77b136de9b0562a93daadce (patch) | |
tree | 5a9442aaf0dc296ce2d280f6d14453e45fc056b4 | |
parent | ce8dae3f0d9d269fc925f3a83abde4cde3b36ebb (diff) | |
download | mpv-e024906408c4d079e77b136de9b0562a93daadce.tar.bz2 mpv-e024906408c4d079e77b136de9b0562a93daadce.tar.xz |
m_config: handle --no-... options differently
Instead of adding "no-"-prefixed aliases to the internal option list,
which will act like normal options, do it in the parsing stage. This
turns out to be simpler (and cheaper), and avoids adding aliased
options.
-rw-r--r-- | DOCS/interface-changes.rst | 5 | ||||
-rw-r--r-- | options/m_config.c | 97 |
2 files changed, 49 insertions, 53 deletions
diff --git a/DOCS/interface-changes.rst b/DOCS/interface-changes.rst index f02f6588ff..4188aa0adc 100644 --- a/DOCS/interface-changes.rst +++ b/DOCS/interface-changes.rst @@ -19,6 +19,11 @@ Interface changes :: + --- mpv 0.21.0 --- + - subtle changes in how "--no-..." options are treated mean that they are + not accessible under "options/..." anymore (instead, these are resolved + at parsing time). This does not affect options which start with "--no-", + but do not use the mechanism for negation options. --- mpv 0.20.0 --- - add --image-display-duration option - this also means that image duration is not influenced by --mf-fps anymore in the general case (this is an diff --git a/options/m_config.c b/options/m_config.c index 8a4d5998d6..cd18e57b9d 100644 --- a/options/m_config.c +++ b/options/m_config.c @@ -298,51 +298,6 @@ void m_config_backup_all_opts(struct m_config *config) ensure_backup(config, &config->opts[n]); } -// Given an option --opt, add --no-opt (if applicable). -static void add_negation_option(struct m_config *config, - struct m_config_option *orig, - const char *parent_name) -{ - const struct m_option *opt = orig->opt; - int value; - if (opt->type == CONF_TYPE_FLAG) { - value = 0; - } else if (opt->type == CONF_TYPE_CHOICE) { - // Find out whether there's a "no" choice. - // m_option_parse() should be used for this, but it prints - // unsilenceable error messages. - struct m_opt_choice_alternatives *alt = opt->priv; - for ( ; alt->name; alt++) { - if (strcmp(alt->name, "no") == 0) - break; - } - if (!alt->name) - return; - value = alt->value; - } else { - return; - } - struct m_option *no_opt = talloc_ptrtype(config, no_opt); - *no_opt = (struct m_option) { - .name = opt->name, - .type = CONF_TYPE_STORE, - .flags = opt->flags & (M_OPT_NOCFG | M_OPT_GLOBAL | M_OPT_PRE_PARSE), - .offset = opt->offset, - .max = value, - }; - // Add --no-sub-opt - struct m_config_option co = *orig; - co.name = talloc_asprintf(config, "no-%s", orig->name); - co.opt = no_opt; - co.is_hidden = true; - MP_TARRAY_APPEND(config, config->opts, config->num_opts, co); - // Add --sub-no-opt (unfortunately needed for: "--sub=...:no-opt") - if (parent_name[0]) { - co.name = talloc_asprintf(config, "%s-no-%s", parent_name, opt->name); - MP_TARRAY_APPEND(config, config->opts, config->num_opts, co); - } -} - static void m_config_add_option(struct m_config *config, struct m_config_option *parent, void *optstruct, @@ -439,8 +394,6 @@ static void m_config_add_option(struct m_config *config, if (arg->name[0]) // no own name -> hidden MP_TARRAY_APPEND(config, config->opts, config->num_opts, co); - add_negation_option(config, &co, parent_name); - if (co.opt->type == &m_option_type_alias) { co.is_hidden = true; const char *alias = (const char *)co.opt->priv; @@ -610,14 +563,42 @@ int m_config_set_option_raw(struct m_config *config, struct m_config_option *co, static int parse_subopts(struct m_config *config, char *name, char *prefix, struct bstr param, int flags); +// Used to turn "--no-foo" into "--foo=no". +static struct m_config_option *m_config_find_negation_opt(struct m_config *config, + struct bstr *name) +{ + assert(!m_config_get_co(config, *name)); + + if (!bstr_eatstart0(name, "no-")) + return NULL; + + struct m_config_option *co = m_config_get_co(config, *name); + + // Not all choice types have this value - if they don't, then parsing them + // will simply result in an error. Good enough. + if (co && co->opt->type != CONF_TYPE_FLAG && + co->opt->type != CONF_TYPE_CHOICE) + co = NULL; + + return co; +} + static int m_config_parse_option(struct m_config *config, struct bstr name, struct bstr param, int flags) { assert(config != NULL); struct m_config_option *co = m_config_get_co(config, name); - if (!co) - return M_OPT_UNKNOWN; + if (!co) { + co = m_config_find_negation_opt(config, &name); + if (!co) + return M_OPT_UNKNOWN; + + if (param.len) + return M_OPT_DISALLOW_PARAM; + + param = bstr0("no"); + } // This is the only mandatory function assert(co->opt->type->parse); @@ -720,12 +701,22 @@ int m_config_set_option(struct m_config *config, struct bstr name, int m_config_set_option_node(struct m_config *config, bstr name, struct mpv_node *data, int flags) { - struct m_config_option *co = m_config_get_co(config, name); - if (!co) - return M_OPT_UNKNOWN; - + struct mpv_node tmp; int r; + struct m_config_option *co = m_config_get_co(config, name); + if (!co) { + co = m_config_find_negation_opt(config, &name); + if (!co) + return M_OPT_UNKNOWN; + if (!(data->format == MPV_FORMAT_STRING && !bstr0(data->u.string).len) && + !(data->format == MPV_FORMAT_FLAG && data->u.flag == 1)) + return M_OPT_INVALID; + tmp.format = MPV_FORMAT_STRING; + tmp.u.string = "no"; + data = &tmp; + } + // Do this on an "empty" type to make setting the option strictly overwrite // the old value, as opposed to e.g. appending to lists. union m_option_value val = {0}; |