diff options
-rw-r--r-- | options/m_config.c | 162 | ||||
-rw-r--r-- | options/options.c | 19 |
2 files changed, 87 insertions, 94 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++) { diff --git a/options/options.c b/options/options.c index 324a1c9a3e..1bcdc720f2 100644 --- a/options/options.c +++ b/options/options.c @@ -56,18 +56,11 @@ #include "video/out/opengl/hwdec.h" #endif -extern const char mp_help_text[]; - static void print_version(struct mp_log *log) { mp_print_version(log, true); } -static void print_help(struct mp_log *log) -{ - mp_info(log, "%s", mp_help_text); -} - extern const struct m_sub_options tv_params_conf; extern const struct m_sub_options stream_cdda_conf; extern const struct m_sub_options stream_dvb_conf; @@ -274,6 +267,12 @@ const m_option_t mp_opts[] = { { "list-options", CONF_TYPE_STORE, CONF_NOCFG | M_OPT_FIXED, .offset = -1}, OPT_FLAG("list-properties", property_print_help, CONF_NOCFG | M_OPT_FIXED | M_OPT_NOPROP), + { "help", CONF_TYPE_STRING, CONF_NOCFG | M_OPT_FIXED, .offset = -1}, + { "h", CONF_TYPE_STRING, CONF_NOCFG | M_OPT_FIXED, .offset = -1}, + + OPT_PRINT("list-protocols", stream_print_proto_list), + OPT_PRINT("version", print_version), + OPT_PRINT("V", print_version), OPT_CHOICE("player-operation-mode", operation_mode, M_OPT_FIXED | M_OPT_PRE_PARSE | M_OPT_NOPROP, @@ -704,12 +703,6 @@ const m_option_t mp_opts[] = { OPT_SUBSTRUCT("", input_opts, input_config, 0), - OPT_PRINT("list-protocols", stream_print_proto_list), - OPT_PRINT("help", print_help), - OPT_PRINT("h", print_help), - OPT_PRINT("version", print_version), - OPT_PRINT("V", print_version), - OPT_SUBSTRUCT("", vo, vo_sub_opts, 0), OPT_SUBSTRUCT("", demux_opts, demux_conf, 0), |