summaryrefslogtreecommitdiffstats
path: root/core/m_config.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2012-09-21 09:22:25 +0200
committerwm4 <wm4@nowhere>2013-02-09 00:21:17 +0100
commit267a889cc2c5ca688a2b8fc93cf8e5349a3c8a44 (patch)
treeee2561f256db05092e61fa797be4b7ecaf3db991 /core/m_config.c
parent5412993724aee1126bfc8dfbc0422ebe5251b9b6 (diff)
downloadmpv-267a889cc2c5ca688a2b8fc93cf8e5349a3c8a44.tar.bz2
mpv-267a889cc2c5ca688a2b8fc93cf8e5349a3c8a44.tar.xz
options: unify single dash and double dash options
There were two option syntax variations: "old": -opt value "new": --opt=value "-opt=value" was invalid, and "--opt value" meant "--opt=" followed by a separate option "value" (i.e. interpreted as filename). There isn't really any reason to do this. The "old" syntax used to be ambiguous (you had to call the option parser to know whether the following argument is an option value or a new option), but that has been removed. Further, using "=" in the option string is always unambiguous. Since the distinction between the two option variants is confusing, just remove the difference and allow "--opt value" and "-opt=value". To make this easier, do some other cleanups as well (e.g. avoid having to do a manual lookup of the option just to check for M_OPT_PRE_PARSE, which somehow ended up with finally getting rid of the m_config.mode member). Error reporting is still a mess, and we opt for reporting too many rather than too few errors to the user. There shouldn't be many user-visible changes. The --framedrop and --term-osd options now always require parameters. The --mute option is intentionally made ambiguous: it works like a flag option, but a value can be passed to it explicitly ("--mute=auto"). If the interpretation of the option is ambiguous (like "--mute auto"), the second string is interpreted as separate option or filename. (Normal flag options are actually ambiguous in this way too.)
Diffstat (limited to 'core/m_config.c')
-rw-r--r--core/m_config.c126
1 files changed, 65 insertions, 61 deletions
diff --git a/core/m_config.c b/core/m_config.c
index f95af2baea..2d994bb802 100644
--- a/core/m_config.c
+++ b/core/m_config.c
@@ -384,20 +384,18 @@ struct m_config_option *m_config_get_co(const struct m_config *config,
}
static int parse_subopts(struct m_config *config, void *optstruct, char *name,
- char *prefix, struct bstr param, bool set);
+ char *prefix, struct bstr param, int flags);
static int m_config_parse_option(struct m_config *config, void *optstruct,
- struct bstr name, struct bstr param, bool set)
+ struct bstr name, struct bstr param, int flags)
{
assert(config != NULL);
assert(name.len != 0);
+ bool set = !(flags & M_SETOPT_CHECK_ONLY);
- if (m_config_map_option(config, &name, &param) == M_OPT_INVALID) {
- mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
- "A no-* option can't take parameters: --%.*s=%.*s\n",
- BSTR_P(name), BSTR_P(param));
- return M_OPT_INVALID;
- }
+ 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)
@@ -406,8 +404,11 @@ static int m_config_parse_option(struct m_config *config, void *optstruct,
// This is the only mandatory function
assert(co->opt->type->parse);
+ if ((flags & M_SETOPT_PRE_PARSE_ONLY) && !(co->opt->flags & M_OPT_PRE_PARSE))
+ return 0;
+
// Check if this option isn't forbidden in the current mode
- if ((config->mode == M_CONFIG_FILE) && (co->opt->flags & M_OPT_NOCFG)) {
+ if ((flags & M_SETOPT_FROM_CONFIG_FILE) && (co->opt->flags & M_OPT_NOCFG)) {
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
"The %.*s option can't be used in a config file.\n",
BSTR_P(name));
@@ -430,7 +431,7 @@ static int m_config_parse_option(struct m_config *config, void *optstruct,
char prefix[110];
assert(strlen(co->name) < 100);
sprintf(prefix, "%s:", co->name);
- return parse_subopts(config, optstruct, co->name, prefix, param, set);
+ return parse_subopts(config, optstruct, co->name, prefix, param, flags);
}
if (set)
@@ -440,7 +441,7 @@ static int m_config_parse_option(struct m_config *config, void *optstruct,
}
static int parse_subopts(struct m_config *config, void *optstruct, char *name,
- char *prefix, struct bstr param, bool set)
+ char *prefix, struct bstr param, int flags)
{
char **lst = NULL;
// Split the argument into child options
@@ -453,21 +454,15 @@ static int parse_subopts(struct m_config *config, void *optstruct, char *name,
char n[110];
if (snprintf(n, 110, "%s%s", prefix, lst[2 * i]) > 100)
abort();
- int sr = m_config_parse_option(config, optstruct, bstr0(n),
- bstr0(lst[2 * i + 1]), 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) {
+ r = m_config_parse_option(config, optstruct, bstr0(n),
+ bstr0(lst[2 * i + 1]), flags);
+ if (r < 0) {
+ if (r > M_OPT_EXIT) {
mp_tmsg(MSGT_CFGPARSER, MSGL_ERR,
- "Error: suboption '%s' of '%s' must have "
- "a parameter!\n", lst[2 * i], name);
+ "Error parsing suboption %s/%s (%s)\n",
+ name, lst[2 * i], m_option_strerror(r));
r = M_OPT_INVALID;
- } else
- r = sr;
+ }
break;
}
}
@@ -475,39 +470,38 @@ static int parse_subopts(struct m_config *config, void *optstruct, char *name,
return r;
}
-int m_config_set_option(struct m_config *config, struct bstr name,
- struct bstr param)
+int m_config_parse_suboptions(struct m_config *config, char *name,
+ char *subopts)
{
- mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Setting %.*s=%.*s\n", BSTR_P(name),
- BSTR_P(param));
- return m_config_parse_option(config, config->optstruct, name, param, true);
+ if (!subopts || !*subopts)
+ return 0;
+ int r = parse_subopts(config, config->optstruct, name, "", bstr0(subopts), 0);
+ if (r < 0 && r > M_OPT_EXIT) {
+ mp_tmsg(MSGT_CFGPARSER, MSGL_ERR, "Error parsing suboption %s (%s)\n",
+ name, m_option_strerror(r));
+ r = M_OPT_INVALID;
+ }
+ return r;
}
-int m_config_check_option(struct m_config *config, struct bstr name,
- struct bstr param)
+int m_config_set_option_ext(struct m_config *config, struct bstr name,
+ struct bstr param, int flags)
{
- int r;
- mp_msg(MSGT_CFGPARSER, MSGL_DBG2, "Checking %.*s=%.*s\n", BSTR_P(name),
- BSTR_P(param));
- r = m_config_parse_option(config, NULL, name, 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));
- return M_OPT_INVALID;
+ int r = m_config_parse_option(config, config->optstruct, name, param, flags);
+ if (r < 0 && r > M_OPT_EXIT) {
+ mp_tmsg(MSGT_CFGPARSER, MSGL_ERR, "Error parsing option %.*s (%s)\n",
+ BSTR_P(name), m_option_strerror(r));
+ r = M_OPT_INVALID;
}
return r;
}
-int m_config_parse_suboptions(struct m_config *config, char *name,
- char *subopts)
+int m_config_set_option(struct m_config *config, struct bstr name,
+ struct bstr param)
{
- if (!subopts || !*subopts)
- return 0;
- return parse_subopts(config, config->optstruct, name, "", bstr0(subopts),
- true);
+ return m_config_set_option_ext(config, name, param, 0);
}
-
const struct m_option *m_config_get_option(const struct m_config *config,
struct bstr name)
{
@@ -522,16 +516,24 @@ 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)
+int m_config_map_option(struct m_config *config, bstr *name, bstr *param,
+ bool ambiguous)
{
bstr s = *name;
- if (m_config_get_option(config, s))
- return 0;
+ const struct m_option *opt = m_config_get_option(config, s);
+ 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)))
+ return 0;
+ return 1;
+ }
if (!bstr_eatstart0(&s, "no-"))
return M_OPT_UNKNOWN;
- const struct m_option *opt = m_config_get_option(config, s);
+ 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;
@@ -539,7 +541,7 @@ int m_config_map_option(struct m_config *config, bstr *name, bstr *param)
if (bstr_startswith(bstr0(opt->name), bstr0("no-")))
return M_OPT_UNKNOWN;
if (param->len)
- return M_OPT_INVALID;
+ return M_OPT_DISALLOW_PARAM;
*name = s;
*param = bstr0("no");
return 0;
@@ -610,14 +612,16 @@ void m_profile_set_desc(struct m_profile *p, char *desc)
}
int m_config_set_profile_option(struct m_config *config, struct m_profile *p,
- char *name, char *val)
+ bstr name, bstr val)
{
- int i = m_config_check_option0(config, name, val);
+ int i = m_config_set_option_ext(config, name, val,
+ M_SETOPT_CHECK_ONLY |
+ M_SETOPT_FROM_CONFIG_FILE);
if (i < 0)
return i;
p->opts = talloc_realloc(p, p->opts, char *, 2 * (p->num_opts + 2));
- p->opts[p->num_opts * 2] = talloc_strdup(p, name);
- p->opts[p->num_opts * 2 + 1] = talloc_strdup(p, val);
+ p->opts[p->num_opts * 2] = bstrdup0(p, name);
+ p->opts[p->num_opts * 2 + 1] = bstrdup0(p, val);
p->num_opts++;
p->opts[p->num_opts * 2] = p->opts[p->num_opts * 2 + 1] = NULL;
return 1;
@@ -625,19 +629,19 @@ int m_config_set_profile_option(struct m_config *config, struct m_profile *p,
void m_config_set_profile(struct m_config *config, struct m_profile *p)
{
- int i;
if (config->profile_depth > MAX_PROFILE_DEPTH) {
mp_tmsg(MSGT_CFGPARSER, MSGL_WARN,
"WARNING: Profile inclusion too deep.\n");
return;
}
- int prev_mode = config->mode;
- config->mode = M_CONFIG_FILE;
config->profile_depth++;
- for (i = 0; i < p->num_opts; i++)
- m_config_set_option0(config, p->opts[2 * i], p->opts[2 * i + 1]);
+ for (int i = 0; i < p->num_opts; i++) {
+ m_config_set_option_ext(config,
+ bstr0(p->opts[2 * i]),
+ bstr0(p->opts[2 * i + 1]),
+ M_SETOPT_FROM_CONFIG_FILE);
+ }
config->profile_depth--;
- config->mode = prev_mode;
}
void *m_config_alloc_struct(void *talloc_parent,