From 0559d7bd06a97593db58109ba42f67aa4e23abd9 Mon Sep 17 00:00:00 2001 From: Dudemanguy Date: Thu, 1 Aug 2024 11:30:47 -0500 Subject: [PATCH] options: convert some guarded options to new warning mechanism mpv has an internal inconsistency where some options are guarded at compile time and others are not. One advantage of guarding certain options is that it prevents users from using something that can't possibly work (e.g. windows-specific options on a linux machine). However, this hurts the portability of mpv config files and means it's possible for configs to break depending on a machine. This is not so nice. Attempt to have our cake and eat it too by introducing a new not_available boolean which can optionally be set when defining options. Naturally, you just set this to the negation of the preprocessor that applies. Instead of doing a hard error, mpv will print out a generic warning message that you are trying to use an option that cannot ever work with the binary. As a downside of this new approach, a bunch of windows-specific defines have to be explicitly handled which is ugly. --- input/input.c | 4 +- options/m_config_core.c | 10 ++ options/m_config_core.h | 5 + options/m_config_frontend.c | 10 ++ options/m_config_frontend.h | 1 + options/m_option.h | 6 + options/options.c | 211 +++++++++++++++++++++++++----------- 7 files changed, 180 insertions(+), 67 deletions(-) diff --git a/input/input.c b/input/input.c index 80916bd78f952..19a157b0cd725 100644 --- a/input/input.c +++ b/input/input.c @@ -218,9 +218,7 @@ const struct m_sub_options input_config = { {"input-preprocess-wheel", OPT_BOOL(preprocess_wheel)}, {"input-touch-emulate-mouse", OPT_BOOL(touch_emulate_mouse)}, {"input-dragging-deadzone", OPT_INT(dragging_deadzone)}, -#if HAVE_SDL2_GAMEPAD - {"input-gamepad", OPT_BOOL(use_gamepad)}, -#endif + {"input-gamepad", OPT_BOOL(use_gamepad), .not_available = !HAVE_SDL2_GAMEPAD}, {"window-dragging", OPT_BOOL(allow_win_drag)}, {0} }, diff --git a/options/m_config_core.c b/options/m_config_core.c index 3be11468e027b..febbf3841032e 100644 --- a/options/m_config_core.c +++ b/options/m_config_core.c @@ -207,6 +207,16 @@ static void get_opt_from_id(struct m_config_shadow *shadow, int32_t id, *out_opt_index = opt_index; } +bool m_config_shadow_opt_not_available(struct m_config_shadow *shadow, + int32_t id) +{ + int group_index, opt_index; + get_opt_from_id(shadow, id, &group_index, &opt_index); + + return shadow->groups[group_index].group->not_available || + shadow->groups[group_index].group->opts[opt_index].not_available; +} + const struct m_option *m_config_shadow_get_opt(struct m_config_shadow *shadow, int32_t id) { diff --git a/options/m_config_core.h b/options/m_config_core.h index 738858b41a6b7..ac89e4efefb45 100644 --- a/options/m_config_core.h +++ b/options/m_config_core.h @@ -161,6 +161,11 @@ bool m_config_shadow_get_next_opt(struct m_config_shadow *shadow, int32_t *p_id) // covered by the m_config_cache. bool m_config_cache_get_next_opt(struct m_config_cache *cache, int32_t *p_id); + +// Check if the option is flagged as not available. +bool m_config_shadow_opt_not_available(struct m_config_shadow *shadow, + int32_t id); + // Return the m_option that was used to declare this option. // 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 28db357dd15c5..6270d02353fc8 100644 --- a/options/m_config_frontend.c +++ b/options/m_config_frontend.c @@ -298,6 +298,13 @@ static struct m_config_option *m_config_get_co_any(const struct m_config *config return NULL; const char *prefix = config->is_toplevel ? "--" : ""; + if (co->not_available) { + if (!co->warning_was_printed) { + MP_WARN(config, "Warning: support for option %s%s is not compiled in the mpv binary.\n", + prefix, co->name); + co->warning_was_printed = true; + } + } if (co->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, @@ -556,6 +563,7 @@ struct m_config *m_config_new(void *talloc_ctx, struct mp_log *log, struct m_config_option co = { .name = talloc_strdup(config, opt_name), + .not_available = m_config_shadow_opt_not_available(config->shadow, optid), .opt = m_config_shadow_get_opt(config->shadow, optid), .opt_id = optid, }; @@ -844,6 +852,8 @@ void m_config_print_option_list(const struct m_config *config, const char *name) const struct m_option *opt = co->opt; if (strcmp(name, "*") != 0 && !strstr(co->name, name)) continue; + if (co->not_available) + continue; MP_INFO(config, " %s%-30s", prefix, co->name); if (opt->type == &m_option_type_choice) { MP_INFO(config, " Choices:"); diff --git a/options/m_config_frontend.h b/options/m_config_frontend.h index 6108d9feeccc2..a0b9bb46ccda2 100644 --- a/options/m_config_frontend.h +++ b/options/m_config_frontend.h @@ -50,6 +50,7 @@ struct m_config_option { bool is_set_from_config : 1; // Set by a config file bool is_set_locally : 1; // Has a backup entry bool warning_was_printed : 1; + bool not_available; // Option is missing compile-time support int32_t opt_id; // For some m_config APIs const char *name; // Full name (ie option-subopt) const struct m_option *opt; // Option description diff --git a/options/m_option.h b/options/m_option.h index 7facb563e1f04..161760e1991d3 100644 --- a/options/m_option.h +++ b/options/m_option.h @@ -216,6 +216,8 @@ struct m_sub_options { // Change flags passed to mp_option_change_callback() if any option that is // directly or indirectly part of this group is changed. int change_flags; + // If all sub_options require something during compile to work. + bool not_available; // Return further sub-options, for example for optional components. If set, // this is called with increasing index (starting from 0), as long as true // is returned. If true is returned and *sub is set in any of these calls, @@ -393,6 +395,10 @@ struct m_option { // If the option is an alias, use the prefix of sub option. bool alias_use_prefix; + // If the option requires something during compile time to work potentially + // flag it is as not not_available. + bool not_available; + int offset; // Most numeric types restrict the range to [min, max] if min