summaryrefslogtreecommitdiffstats
path: root/core/m_config.c
diff options
context:
space:
mode:
Diffstat (limited to 'core/m_config.c')
-rw-r--r--core/m_config.c74
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, &param, 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)