diff options
Diffstat (limited to 'core/m_config.c')
-rw-r--r-- | core/m_config.c | 74 |
1 files changed, 46 insertions, 28 deletions
diff --git a/core/m_config.c b/core/m_config.c index 2d994bb802..6ecfa13a39 100644 --- a/core/m_config.c +++ b/core/m_config.c @@ -257,6 +257,43 @@ void m_config_leave_file_local(struct m_config *config) } } +// Given an option --opt, add --no-opt (if applicable). +static void add_negation_option(struct m_config *config, + struct m_config_option *parent, + const struct m_option *opt) +{ + int value; + if (opt->type == CONF_TYPE_FLAG) { + value = opt->min; + } 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 = talloc_asprintf(no_opt, "no-%s", opt->name), + .type = CONF_TYPE_STORE, + .flags = opt->flags & (M_OPT_NOCFG | M_OPT_GLOBAL | M_OPT_LOCAL | + M_OPT_PRE_PARSE | M_OPT_PREFIXED | M_OPT_MERGE), + .new = opt->new, + .p = opt->p, + .offset = opt->offset, + .max = value, + }; + m_config_add_option(config, parent, no_opt); +} + static void add_options(struct m_config *config, struct m_config_option *parent, const struct m_option *defs) @@ -352,6 +389,8 @@ static void m_config_add_option(struct m_config *config, co->next = config->opts; config->opts = co; } + + add_negation_option(config, parent, arg); } int m_config_register_options(struct m_config *config, @@ -393,10 +432,6 @@ static int m_config_parse_option(struct m_config *config, void *optstruct, assert(name.len != 0); bool set = !(flags & M_SETOPT_CHECK_ONLY); - int r = m_config_map_option(config, &name, ¶m, false); - if (r < 0) - return r; - struct m_config_option *co = m_config_get_co(config, name); if (!co) return M_OPT_UNKNOWN; @@ -516,35 +551,18 @@ const struct m_option *m_config_get_option(const struct m_config *config, return NULL; } -int m_config_map_option(struct m_config *config, bstr *name, bstr *param, - bool ambiguous) +int m_config_option_requires_param(struct m_config *config, bstr name) { - bstr s = *name; - const struct m_option *opt = m_config_get_option(config, s); + const struct m_option *opt = m_config_get_option(config, name); if (opt) { - if (bstr_endswith0(s, "-clr")) - return (ambiguous || !param->len) ? 0 : M_OPT_DISALLOW_PARAM; - if (ambiguous && ((opt->flags & M_OPT_OPTIONAL_PARAM) || - (opt->type->flags & M_OPT_TYPE_OPTIONAL_PARAM))) + if (bstr_endswith0(name, "-clr")) + return 0; + if (((opt->flags & M_OPT_OPTIONAL_PARAM) || + (opt->type->flags & M_OPT_TYPE_OPTIONAL_PARAM))) return 0; return 1; } - - if (!bstr_eatstart0(&s, "no-")) - return M_OPT_UNKNOWN; - - opt = m_config_get_option(config, s); - if (!opt || (opt->type != &m_option_type_flag - && opt->type != &m_option_type_choice)) - return M_OPT_UNKNOWN; - // Avoid allowing "--no-no-opt". - if (bstr_startswith(bstr0(opt->name), bstr0("no-"))) - return M_OPT_UNKNOWN; - if (param->len) - return M_OPT_DISALLOW_PARAM; - *name = s; - *param = bstr0("no"); - return 0; + return M_OPT_UNKNOWN; } void m_config_print_option_list(const struct m_config *config) |