From 26029cfbb0724c709edcd999895d5a88d77ecb0d Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Sun, 23 Jun 2024 00:58:16 -0500 Subject: [PATCH] m_option: add a way for aliases to use sub option prefix Previously, using m_option_type_alias required that the alias have the full name of the option value. This is limited if you are reusing the same opts struct in different sub options. Fix this by add an additional field to m_option to signal whether or not prefixes should be taken into account for the alias option. Instead of blindly using whatever is stored in opt->priv as the name, we can construct the desired option name for either case (using the prefix or not). --- options/m_config_core.c | 13 +++++++++++++ options/m_config_core.h | 4 ++++ options/m_config_frontend.c | 12 +++++++++--- options/m_option.h | 3 +++ player/command.c | 10 +++++++--- 5 files changed, 36 insertions(+), 6 deletions(-) diff --git a/options/m_config_core.c b/options/m_config_core.c index 2c9979688a..3be11468e0 100644 --- a/options/m_config_core.c +++ b/options/m_config_core.c @@ -227,6 +227,19 @@ const char *m_config_shadow_get_opt_name(struct m_config_shadow *shadow, g->group->opts[opt_index].name); } +const char *m_config_shadow_get_alias_from_opt(struct m_config_shadow *shadow, int32_t id, + char *buf, size_t buf_size) +{ + int group_index, opt_index; + get_opt_from_id(shadow, id, &group_index, &opt_index); + + struct m_config_group *g = &shadow->groups[group_index]; + const struct m_option *opt = &shadow->groups[group_index].group->opts[opt_index]; + if (opt->alias_use_prefix) + return concat_name_buf(buf, buf_size, g->prefix, (const char *)opt->priv); + return (const char *)opt->priv; +} + const void *m_config_shadow_get_opt_default(struct m_config_shadow *shadow, int32_t id) { diff --git a/options/m_config_core.h b/options/m_config_core.h index a9558423d8..738858b41a 100644 --- a/options/m_config_core.h +++ b/options/m_config_core.h @@ -175,6 +175,10 @@ const struct m_option *m_config_shadow_get_opt(struct m_config_shadow *shadow, const char *m_config_shadow_get_opt_name(struct m_config_shadow *shadow, int32_t id, char *buf, size_t buf_size); +// Resolve alias mapping from opt. +const char *m_config_shadow_get_alias_from_opt(struct m_config_shadow *shadow, int32_t id, + char *buf, size_t buf_size); + // Pointer to default value, using m_option.type. NULL if option without data. // id must be a valid option ID as returned by m_config_shadow_get_next_opt() or // m_config_cache_get_next_opt(). diff --git a/options/m_config_frontend.c b/options/m_config_frontend.c index 1e8a80ad49..16dba07a68 100644 --- a/options/m_config_frontend.c +++ b/options/m_config_frontend.c @@ -302,7 +302,9 @@ static struct m_config_option *m_config_get_co_any(const struct m_config *config const char *prefix = config->is_toplevel ? "--" : ""; if (co->opt->type == &m_option_type_alias) { - const char *alias = (const char *)co->opt->priv; + char buf[M_CONFIG_MAX_OPT_NAME_LEN]; + const char *alias = m_config_shadow_get_alias_from_opt(config->shadow, co->opt_id, + buf, sizeof(buf)); if (co->opt->deprecation_message && !co->warning_was_printed) { if (co->opt->deprecation_message[0]) { MP_WARN(config, "Warning: option %s%s was replaced with " @@ -881,8 +883,12 @@ void m_config_print_option_list(const struct m_config *config, const char *name) MP_INFO(config, " [file]"); if (opt->deprecation_message) MP_INFO(config, " [deprecated]"); - if (opt->type == &m_option_type_alias) - MP_INFO(config, " for %s", (char *)opt->priv); + if (opt->type == &m_option_type_alias) { + char buf[M_CONFIG_MAX_OPT_NAME_LEN]; + const char *alias = m_config_shadow_get_alias_from_opt(config->shadow, co->opt_id, + buf, sizeof(buf)); + MP_INFO(config, " for %s", alias); + } if (opt->type == &m_option_type_cli_alias) MP_INFO(config, " for --%s (CLI/config files only)", (char *)opt->priv); MP_INFO(config, "\n"); diff --git a/options/m_option.h b/options/m_option.h index 9a5058ccaf..becad208c3 100644 --- a/options/m_option.h +++ b/options/m_option.h @@ -389,6 +389,9 @@ struct m_option { // Always force an option update even if the written value does not change. bool force_update; + // If the option is an alias, use the prefix of sub option. + bool alias_use_prefix; + int offset; // Most numeric types restrict the range to [min, max] if minopt->type == &m_option_type_alias) { - prop.priv = co->opt->priv; + char buf[M_CONFIG_MAX_OPT_NAME_LEN]; + const char *alias = m_config_shadow_get_alias_from_opt(mpctx->mconfig->shadow, co->opt_id, + buf, sizeof(buf)); + prop.priv = talloc_strdup(ctx, alias); prop.call = co->opt->deprecation_message ? mp_property_deprecated_alias : mp_property_alias; @@ -7198,8 +7201,9 @@ void command_init(struct MPContext *mpctx) // be set as property. struct m_config_option *co2 = co; while (co2 && co2->opt->type == &m_option_type_alias) { - const char *alias = (const char *)co2->opt->priv; - co2 = m_config_get_co_raw(mpctx->mconfig, bstr0(alias)); + const char *co2_alias = m_config_shadow_get_alias_from_opt(mpctx->mconfig->shadow, co2->opt_id, + buf, sizeof(buf)); + co2 = m_config_get_co_raw(mpctx->mconfig, bstr0(co2_alias)); } if (!co2) continue;