vo, ao: disable positional parameter suboptions

Positional parameters cause problems because they can be ambiguous with
flag options. If a flag option is removed or turned into a non-flag
option, it'll usually be interpreted as value for the first sub-option
(as positional parameter), resulting in very confusing error messages.
This changes it into a simple "option not found" error.

I don't expect that anyone really used positional parameters with --vo
or --ao. Although the docs for --ao=pulse seem to encourage positional
parameters for the host/sink options, which means it could possibly
annoy some PulseAudio users.

--vf and --af are still mostly used with positional parameters, so this
must be a configurable option in the option parser.
This commit is contained in:
wm4 2016-09-01 14:21:32 +02:00
parent ec3c428e5f
commit 6b4f560f3c
5 changed files with 14 additions and 8 deletions

View File

@ -183,7 +183,7 @@ Available audio output drivers are:
``pulse``
PulseAudio audio output driver
``[<host>][:<output sink>]``
``host=<host>``, ``sink=<sink>``
Specify the host and optionally output sink to use. An empty <host>
string uses a local connection, "localhost" uses network transfer
(most likely not what you want).

View File

@ -121,6 +121,7 @@ const struct m_obj_list ao_obj_list = {
.description = "audio outputs",
.allow_unknown_entries = true,
.allow_trailer = true,
.disallow_positional_parameters = true,
};
static struct ao *ao_alloc(bool probing, struct mpv_global *global,

View File

@ -2648,7 +2648,8 @@ static void copy_obj_settings_list(const m_option_t *opt, void *dst,
// without '=' sets a flag, or whether it's a positional argument.
static int get_obj_param(struct mp_log *log, bstr opt_name, bstr obj_name,
struct m_config *config, bstr name, bstr val,
int flags, int *nold, bstr *out_name, bstr *out_val)
int flags, bool nopos,
int *nold, bstr *out_name, bstr *out_val)
{
int r;
@ -2658,7 +2659,7 @@ static int get_obj_param(struct mp_log *log, bstr opt_name, bstr obj_name,
// va.start != NULL => of the form name=val (not positional)
// 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) {
if (val.start || m_config_option_requires_param(config, name) == 0 || nopos) {
r = m_config_set_option_ext(config, name, val, flags);
if (r < 0) {
if (r == M_OPT_UNKNOWN) {
@ -2714,7 +2715,7 @@ static int get_obj_param(struct mp_log *log, bstr opt_name, bstr obj_name,
// desc is optional.
static int m_obj_parse_sub_config(struct mp_log *log, struct bstr opt_name,
struct bstr name, struct bstr *pstr,
struct m_config *config, int flags,
struct m_config *config, int flags, bool nopos,
struct m_obj_desc *desc, char ***ret)
{
int nold = 0;
@ -2735,8 +2736,8 @@ static int m_obj_parse_sub_config(struct mp_log *log, struct bstr opt_name,
goto exit;
if (bstr_equals0(fname, "help"))
goto print_help;
r = get_obj_param(log, opt_name, name, config, fname, fval, flags, &nold,
&fname, &fval);
r = get_obj_param(log, opt_name, name, config, fname, fval, flags,
nopos, &nold, &fname, &fval);
if (r < 0)
goto exit;
@ -2791,6 +2792,7 @@ static int parse_obj_settings(struct mp_log *log, struct bstr opt,
char **plist = NULL;
struct m_obj_desc desc;
bstr label = {0};
bool nopos = list->disallow_positional_parameters;
if (bstr_eatstart0(pstr, "@")) {
if (!bstr_split_tok(*pstr, ":", &label, pstr)) {
@ -2826,7 +2828,7 @@ static int parse_obj_settings(struct mp_log *log, struct bstr opt,
struct m_config *config = m_config_from_obj_desc_noalloc(NULL, log, &desc);
bstr s = bstr0(desc.init_options);
m_obj_parse_sub_config(log, opt, str, &s, config,
M_SETOPT_CHECK_ONLY, NULL, &plist);
M_SETOPT_CHECK_ONLY, nopos, NULL, &plist);
assert(s.len == 0);
talloc_free(config);
}
@ -2836,7 +2838,7 @@ static int parse_obj_settings(struct mp_log *log, struct bstr opt,
if (!skip)
config = m_config_from_obj_desc_noalloc(NULL, log, &desc);
r = m_obj_parse_sub_config(log, opt, str, pstr, config,
M_SETOPT_CHECK_ONLY, &desc,
M_SETOPT_CHECK_ONLY, nopos, &desc,
_ret ? &plist : NULL);
talloc_free(config);
if (r < 0)

View File

@ -142,6 +142,8 @@ struct m_obj_list {
// Allow unknown entries, for which a dummy entry is inserted, and whose
// options are skipped and ignored.
bool allow_unknown_entries;
// This helps with confusing error messages if unknown flag options are used.
bool disallow_positional_parameters;
};
// Find entry by name

View File

@ -193,6 +193,7 @@ const struct m_obj_list vo_obj_list = {
},
.allow_unknown_entries = true,
.allow_trailer = true,
.disallow_positional_parameters = true,
};
static void dispatch_wakeup_cb(void *ptr)