mirror of
https://github.com/mpv-player/mpv
synced 2024-12-26 00:42:57 +00:00
options: add automagic hack for handling sub-option deprecations
I decided that it's too much work to convert all the VO/AOs to the new option system manually at once. So here's a shitty hack instead, which achieves almost the same thing. (The only user-visible difference is that e.g. --vo=name:help will list the sub-options normally, instead of showing them as deprecation placeholders. Also, the sub-option parser will verify each option normally, instead of deferring to the global option parser.) Another advantage is that once we drop the deprecated options, converting the remaining things will be easier, because we obviously don't need to add the compatibility hacks. Using this mechanism is separate in the next commit to keep the diff noise down.
This commit is contained in:
parent
327cb2a06c
commit
633eb30cbe
@ -110,6 +110,7 @@ static bool get_desc(struct m_obj_desc *dst, int index)
|
||||
.priv_defaults = ao->priv_defaults,
|
||||
.options = ao->options,
|
||||
.global_opts = ao->global_opts,
|
||||
.legacy_prefix = ao->legacy_prefix,
|
||||
.hidden = ao->encode,
|
||||
.p = ao,
|
||||
};
|
||||
|
@ -182,6 +182,7 @@ struct ao_driver {
|
||||
const void *priv_defaults;
|
||||
const struct m_option *options;
|
||||
const struct m_sub_options *global_opts;
|
||||
const char *legacy_prefix;
|
||||
};
|
||||
|
||||
// These functions can be called by AOs.
|
||||
|
@ -258,15 +258,28 @@ struct m_config *m_config_from_obj_desc_noalloc(void *talloc_ctx,
|
||||
}
|
||||
|
||||
static int m_config_set_obj_params(struct m_config *config, struct mp_log *log,
|
||||
struct mpv_global *global, char **args)
|
||||
struct mpv_global *global,
|
||||
struct m_obj_desc *desc, char **args)
|
||||
{
|
||||
for (int n = 0; args && args[n * 2 + 0]; n++) {
|
||||
const char *opt = args[n * 2 + 0];
|
||||
const char *val = args[n * 2 + 1];
|
||||
struct m_config_option *co = m_config_get_co(config, bstr0(opt));
|
||||
if (!co)
|
||||
continue;
|
||||
struct m_config *target = config;
|
||||
if (co && co->opt->type == &m_option_type_subopt_legacy) {
|
||||
const char *newopt = co->opt->priv;
|
||||
bool is_legacy = co->opt->type == &m_option_type_subopt_legacy;
|
||||
bool force_legacy = !!desc->legacy_prefix;
|
||||
if (is_legacy || force_legacy) {
|
||||
// Legacy: redirect deprecated sub-options to global ones.
|
||||
char tmp[100];
|
||||
const char *newopt;
|
||||
if (is_legacy) {
|
||||
newopt = co->opt->priv;
|
||||
} else {
|
||||
snprintf(tmp, sizeof(tmp), "%s-%s", desc->legacy_prefix, opt);
|
||||
newopt = tmp;
|
||||
}
|
||||
assert(global);
|
||||
target = mp_get_root_config(global);
|
||||
mp_warn(log, "Using suboptions is deprecated. Use the global '--%s' "
|
||||
@ -289,14 +302,29 @@ struct m_config *m_config_from_obj_desc_and_args(void *ta_parent,
|
||||
for (int n = 0; defaults && defaults[n].name; n++) {
|
||||
struct m_obj_settings *entry = &defaults[n];
|
||||
if (name && strcmp(entry->name, name) == 0) {
|
||||
if (m_config_set_obj_params(config, log, global, entry->attribs) < 0)
|
||||
if (m_config_set_obj_params(config, log, global, desc, entry->attribs) < 0)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_config_set_obj_params(config, log, global, args) < 0)
|
||||
if (m_config_set_obj_params(config, log, global, desc, args) < 0)
|
||||
goto error;
|
||||
|
||||
if (desc->legacy_prefix) {
|
||||
assert(global);
|
||||
struct m_config *root = mp_get_root_config(global);
|
||||
// In this mode, the AO/VO will still access the options via its priv
|
||||
// struct (like with real sub-options). We have to copy them over.
|
||||
for (int n = 0; n < config->num_opts; n++) {
|
||||
struct m_config_option *co = &config->opts[n];
|
||||
char opt[100];
|
||||
snprintf(opt, sizeof(opt), "%s-%s", desc->legacy_prefix, co->name);
|
||||
struct m_config_option *g = m_config_get_co(root, bstr0(opt));
|
||||
assert(g);
|
||||
m_option_copy(co->opt, co->data, g->data);
|
||||
}
|
||||
}
|
||||
|
||||
return config;
|
||||
error:
|
||||
talloc_free(config);
|
||||
@ -415,6 +443,20 @@ static void add_global_subopts(struct m_config *config,
|
||||
break;
|
||||
if (desc.global_opts)
|
||||
add_sub_options(config, NULL, desc.global_opts);
|
||||
if (desc.legacy_prefix && desc.options) {
|
||||
// Legacy: auto-add sub-options as global options (using the prefix).
|
||||
struct m_config_option parent = {
|
||||
.name = desc.legacy_prefix,
|
||||
.group = 0,
|
||||
};
|
||||
struct m_sub_options *conf = talloc(config, struct m_sub_options);
|
||||
*conf = (struct m_sub_options){
|
||||
.opts = desc.options,
|
||||
.defaults = desc.priv_defaults,
|
||||
.size = desc.priv_size,
|
||||
};
|
||||
add_sub_options(config, &parent, conf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,6 +132,10 @@ struct m_obj_desc {
|
||||
const char *replaced_name;
|
||||
// For convenience: these are added as global command-line options.
|
||||
const struct m_sub_options *global_opts;
|
||||
// Evil hack to essentially force-move .options to global_opts. All options
|
||||
// will be added as global options with the given prefix, and using
|
||||
// sub-options will be treated as deprecated and redirected.
|
||||
const char *legacy_prefix;
|
||||
};
|
||||
|
||||
// Extra definition needed for \ref m_option_type_obj_settings_list options.
|
||||
|
@ -173,6 +173,7 @@ static bool get_desc(struct m_obj_desc *dst, int index)
|
||||
.priv_defaults = vo->priv_defaults,
|
||||
.options = vo->options,
|
||||
.global_opts = vo->global_opts,
|
||||
.legacy_prefix = vo->legacy_prefix,
|
||||
.hidden = vo->encode || !strcmp(vo->name, "opengl-cb"),
|
||||
.p = vo,
|
||||
};
|
||||
|
@ -295,11 +295,17 @@ struct vo_driver {
|
||||
const void *priv_defaults;
|
||||
|
||||
// List of options to parse into priv struct (requires priv_size to be set)
|
||||
// Deprecated. Use global options or global_opts instead.
|
||||
const struct m_option *options;
|
||||
|
||||
// Global options to register if the VO is compiled in.
|
||||
// mp_get_config_group() or other function can be used to access them.
|
||||
const struct m_sub_options *global_opts;
|
||||
|
||||
// Evil hack: add .options as global options, using the provided prefix.
|
||||
// For further evilness, the options will be copied to the priv struct
|
||||
// like with normal .options behavior.
|
||||
const char *legacy_prefix;
|
||||
};
|
||||
|
||||
struct vo {
|
||||
|
Loading…
Reference in New Issue
Block a user