diff options
Diffstat (limited to 'options/m_config.c')
-rw-r--r-- | options/m_config.c | 162 |
1 files changed, 81 insertions, 81 deletions
diff --git a/options/m_config.c b/options/m_config.c index b6e1720f39..dabea4647c 100644 --- a/options/m_config.c +++ b/options/m_config.c @@ -83,57 +83,6 @@ struct m_opt_backup { void *backup; }; -static int parse_include(struct m_config *config, struct bstr param, bool set, - int flags) -{ - if (param.len == 0) - return M_OPT_MISSING_PARAM; - if (!set) - return 1; - if (config->recursion_depth >= MAX_RECURSION_DEPTH) { - MP_ERR(config, "Maximum 'include' nesting depth exceeded.\n"); - return M_OPT_INVALID; - } - char *filename = bstrdup0(NULL, param); - config->recursion_depth += 1; - config->includefunc(config->includefunc_ctx, filename, flags); - config->recursion_depth -= 1; - talloc_free(filename); - return 1; -} - -static int parse_profile(struct m_config *config, const struct m_option *opt, - struct bstr name, struct bstr param, bool set, int flags) -{ - if (!bstrcmp0(param, "help")) { - struct m_profile *p; - if (!config->profiles) { - MP_INFO(config, "No profiles have been defined.\n"); - return M_OPT_EXIT; - } - MP_INFO(config, "Available profiles:\n"); - for (p = config->profiles; p; p = p->next) - MP_INFO(config, "\t%s\t%s\n", p->name, p->desc ? p->desc : ""); - MP_INFO(config, "\n"); - return M_OPT_EXIT; - } - - char **list = NULL; - int r = m_option_type_string_list.parse(config->log, opt, name, param, &list); - if (r < 0) - return r; - if (!list || !list[0]) - return M_OPT_INVALID; - for (int i = 0; list[i]; i++) { - if (set) - r = m_config_set_profile(config, list[i], flags); - if (r < 0) - break; - } - m_option_free(opt, &list); - return r; -} - static int show_profile(struct m_config *config, bstr param) { struct m_profile *p; @@ -171,17 +120,6 @@ static int show_profile(struct m_config *config, bstr param) return M_OPT_EXIT; } -static int list_options(struct m_config *config, bstr val, bool show_help) -{ - char s[100]; - snprintf(s, sizeof(s), "%.*s", BSTR_P(val)); - if (show_help) - mp_info(config->log, "%s", mp_help_text); - if (s[0]) - m_config_print_option_list(config, s); - return M_OPT_EXIT; -} - // The memcpys are supposed to work around the strict aliasing violation, // that would result if we just dereferenced a void** (where the void** is // actually casted from struct some_type* ). The dummy struct type is in @@ -729,6 +667,73 @@ void m_config_mark_co_flags(struct m_config_option *co, int flags) co->is_set_from_config = true; } +// Special options that don't really fit into the option handling mode. They +// usually store no data, but trigger actions. Caller is assumed to have called +// handle_set_opt_flags() to make sure the option can be set. +// Returns M_OPT_UNKNOWN if the option is not a special option. +static int m_config_handle_special_options(struct m_config *config, + struct m_config_option *co, + void *data, int flags) +{ + if (config->use_profiles && strcmp(co->name, "profile") == 0) { + char **list = *(char ***)data; + + if (list && list[0] && !list[1] && strcmp(list[0], "help") == 0) { + if (!config->profiles) { + MP_INFO(config, "No profiles have been defined.\n"); + return M_OPT_EXIT; + } + MP_INFO(config, "Available profiles:\n"); + for (struct m_profile *p = config->profiles; p; p = p->next) + MP_INFO(config, "\t%s\t%s\n", p->name, p->desc ? p->desc : ""); + MP_INFO(config, "\n"); + return M_OPT_EXIT; + } + + for (int n = 0; list && list[n]; n++) { + int r = m_config_set_profile(config, list[n], flags); + if (r < 0) + return r; + } + return 0; + } + + if (config->includefunc && strcmp(co->name, "include") == 0) { + char *param = *(char **)data; + if (!param || !param[0]) + return M_OPT_MISSING_PARAM; + if (config->recursion_depth >= MAX_RECURSION_DEPTH) { + MP_ERR(config, "Maximum 'include' nesting depth exceeded.\n"); + return M_OPT_INVALID; + } + config->recursion_depth += 1; + config->includefunc(config->includefunc_ctx, param, flags); + config->recursion_depth -= 1; + return 1; + } + + if (config->use_profiles && strcmp(co->name, "show-profile") == 0) + return show_profile(config, bstr0(*(char **)data)); + + if (config->is_toplevel && (strcmp(co->name, "h") == 0 || + strcmp(co->name, "help") == 0)) + { + char *h = *(char **)data; + mp_info(config->log, "%s", mp_help_text); + if (h && h[0]) + m_config_print_option_list(config, h); + return M_OPT_EXIT; + } + + if (strcmp(co->name, "list-options") == 0) { + m_config_print_option_list(config, "*"); + return M_OPT_EXIT; + } + + return M_OPT_UNKNOWN; +} + + // Unlike m_config_set_option_raw() this does not go through the property layer // via config.option_set_callback. int m_config_set_option_raw_direct(struct m_config *config, @@ -738,15 +743,19 @@ int m_config_set_option_raw_direct(struct m_config *config, if (!co) return M_OPT_UNKNOWN; - // This affects some special options like "include", "profile". Maybe these - // should work, or maybe not. For now they would require special code. - if (!co->data) - return M_OPT_UNKNOWN; - int r = handle_set_opt_flags(config, co, flags); if (r <= 1) return r; + r = m_config_handle_special_options(config, co, data, flags); + if (r != M_OPT_UNKNOWN) + return r; + + // This affects some special options like "playlist", "v". Maybe these + // should work, or maybe not. For now they would require special code. + if (!co->data) + return flags & M_SETOPT_FROM_CMDLINE ? 0 : M_OPT_UNKNOWN; + m_option_copy(co->opt, co->data, data); m_config_mark_co_flags(co, flags); @@ -761,6 +770,9 @@ int m_config_set_option_raw_direct(struct m_config *config, int m_config_set_option_raw(struct m_config *config, struct m_config_option *co, void *data, int flags) { + if (!co) + return M_OPT_UNKNOWN; + if (config->option_set_callback) { int r = handle_set_opt_flags(config, co, flags); if (r <= 1) @@ -824,18 +836,6 @@ static int m_config_parse_option(struct m_config *config, struct bstr name, BSTR_P(name), BSTR_P(param), flags); } - if (config->includefunc && bstr_equals0(name, "include")) - return parse_include(config, param, set, flags); - if (config->use_profiles && bstr_equals0(name, "profile")) - return parse_profile(config, co->opt, name, param, set, flags); - if (config->use_profiles && bstr_equals0(name, "show-profile")) - return show_profile(config, param); - if (config->is_toplevel && (bstr_equals0(name, "h") || - bstr_equals0(name, "help"))) - return list_options(config, param, true); - if (bstr_equals0(name, "list-options")) - return list_options(config, bstr0("*"), false); - union m_option_value val = {0}; // Some option types are "impure" and work on the existing data. @@ -845,7 +845,7 @@ static int m_config_parse_option(struct m_config *config, struct bstr name, r = m_option_parse(config->log, co->opt, name, param, &val); - if (r >= 0 && co->data) + if (r >= 0) r = m_config_set_option_raw(config, co, &val, flags); m_option_free(co->opt, &val); @@ -1076,7 +1076,7 @@ int m_config_set_profile(struct m_config *config, char *name, int flags) if (config->profile_depth > MAX_PROFILE_DEPTH) { MP_WARN(config, "WARNING: Profile inclusion too deep.\n"); - return M_OPT_UNKNOWN; + return M_OPT_INVALID; } config->profile_depth++; for (int i = 0; i < p->num_opts; i++) { |