diff options
Diffstat (limited to 'options')
-rw-r--r-- | options/m_config.h | 2 | ||||
-rw-r--r-- | options/m_config_core.c | 82 | ||||
-rw-r--r-- | options/m_config_core.h | 7 | ||||
-rw-r--r-- | options/m_config_frontend.c | 76 | ||||
-rw-r--r-- | options/m_config_frontend.h | 16 | ||||
-rw-r--r-- | options/m_option.c | 408 | ||||
-rw-r--r-- | options/m_option.h | 88 | ||||
-rw-r--r-- | options/m_property.c | 47 | ||||
-rw-r--r-- | options/m_property.h | 22 | ||||
-rw-r--r-- | options/options.c | 754 | ||||
-rw-r--r-- | options/options.h | 272 | ||||
-rw-r--r-- | options/parse_commandline.c | 11 | ||||
-rw-r--r-- | options/parse_configfile.c | 49 | ||||
-rw-r--r-- | options/parse_configfile.h | 5 | ||||
-rw-r--r-- | options/path.c | 236 | ||||
-rw-r--r-- | options/path.h | 54 |
16 files changed, 1072 insertions, 1057 deletions
diff --git a/options/m_config.h b/options/m_config.h index d2ce2b4467..a6bade90c9 100644 --- a/options/m_config.h +++ b/options/m_config.h @@ -1 +1 @@ -#include "m_config_core.h"
\ No newline at end of file +#include "m_config_core.h" diff --git a/options/m_config_core.c b/options/m_config_core.c index f82b886670..08a76eb76d 100644 --- a/options/m_config_core.c +++ b/options/m_config_core.c @@ -15,29 +15,29 @@ * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ -#include <stdlib.h> -#include <stdio.h> +#include <assert.h> #include <errno.h> +#include <stdatomic.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> #include <string.h> #include <strings.h> -#include <assert.h> -#include <stdbool.h> -#include <pthread.h> -#include "m_config_core.h" -#include "options/m_option.h" #include "common/common.h" #include "common/global.h" -#include "common/msg.h" #include "common/msg_control.h" +#include "common/msg.h" +#include "m_config_core.h" #include "misc/dispatch.h" -#include "osdep/atomic.h" +#include "options/m_option.h" +#include "osdep/threads.h" // For use with m_config_cache. struct m_config_shadow { - pthread_mutex_t lock; + mp_mutex lock; // Incremented on every option change. - mp_atomic_uint64 ts; + _Atomic uint64_t ts; // -- immutable after init // List of m_sub_options instances. // Index 0 is the top-level and is always present. @@ -105,8 +105,6 @@ struct m_group_data { uint64_t ts; // timestamp of the data copy }; -static const union m_option_value default_value = {0}; - static void add_sub_group(struct m_config_shadow *shadow, const char *name_prefix, int parent_group_index, int parent_ptr, const struct m_sub_options *subopts); @@ -241,7 +239,7 @@ const void *m_config_shadow_get_opt_default(struct m_config_shadow *shadow, if (subopt->defaults) return (char *)subopt->defaults + opt->offset; - return &default_value; + return &m_option_value_default; } void *m_config_cache_get_opt_data(struct m_config_cache *cache, int32_t id) @@ -419,14 +417,14 @@ static void shadow_destroy(void *p) assert(shadow->num_listeners == 0); talloc_free(shadow->data); - pthread_mutex_destroy(&shadow->lock); + mp_mutex_destroy(&shadow->lock); } struct m_config_shadow *m_config_shadow_new(const struct m_sub_options *root) { struct m_config_shadow *shadow = talloc_zero(NULL, struct m_config_shadow); talloc_set_destructor(shadow, shadow_destroy); - pthread_mutex_init(&shadow->lock, NULL); + mp_mutex_init(&shadow->lock); add_sub_group(shadow, NULL, -1, -1, root); @@ -568,9 +566,9 @@ struct m_config_cache *m_config_cache_from_shadow(void *ta_parent, in->shadow = shadow; in->src = shadow->data; - pthread_mutex_lock(&shadow->lock); + mp_mutex_lock(&shadow->lock); in->data = allocate_option_data(cache, shadow, group_index, in->src); - pthread_mutex_unlock(&shadow->lock); + mp_mutex_unlock(&shadow->lock); cache->opts = in->data->gdata[0].udata; @@ -677,7 +675,7 @@ bool m_config_cache_update(struct m_config_cache *cache) if (!cache_check_update(cache)) return false; - pthread_mutex_lock(&shadow->lock); + mp_mutex_lock(&shadow->lock); bool res = false; while (1) { void *p; @@ -686,7 +684,7 @@ bool m_config_cache_update(struct m_config_cache *cache) break; res = true; } - pthread_mutex_unlock(&shadow->lock); + mp_mutex_unlock(&shadow->lock); return res; } @@ -699,9 +697,9 @@ bool m_config_cache_get_next_changed(struct m_config_cache *cache, void **opt) if (!cache_check_update(cache) && in->upd_group < 0) return false; - pthread_mutex_lock(&shadow->lock); + mp_mutex_lock(&shadow->lock); update_next_option(cache, opt); - pthread_mutex_unlock(&shadow->lock); + mp_mutex_unlock(&shadow->lock); return !!*opt; } @@ -746,7 +744,7 @@ bool m_config_cache_write_opt(struct m_config_cache *cache, void *ptr) struct m_config_group *g = &shadow->groups[group_idx]; const struct m_option *opt = &g->group->opts[opt_idx]; - pthread_mutex_lock(&shadow->lock); + mp_mutex_lock(&shadow->lock); struct m_group_data *gdst = m_config_gdata(in->data, group_idx); struct m_group_data *gsrc = m_config_gdata(in->src, group_idx); @@ -765,7 +763,7 @@ bool m_config_cache_write_opt(struct m_config_cache *cache, void *ptr) } } - pthread_mutex_unlock(&shadow->lock); + mp_mutex_unlock(&shadow->lock); return changed; } @@ -776,7 +774,7 @@ void m_config_cache_set_wakeup_cb(struct m_config_cache *cache, struct config_cache *in = cache->internal; struct m_config_shadow *shadow = in->shadow; - pthread_mutex_lock(&shadow->lock); + mp_mutex_lock(&shadow->lock); if (in->in_list) { for (int n = 0; n < shadow->num_listeners; n++) { if (shadow->listeners[n] == in) { @@ -798,7 +796,7 @@ void m_config_cache_set_wakeup_cb(struct m_config_cache *cache, in->wakeup_cb = cb; in->wakeup_cb_ctx = cb_ctx; } - pthread_mutex_unlock(&shadow->lock); + mp_mutex_unlock(&shadow->lock); } static void dispatch_notify(void *p) @@ -850,38 +848,6 @@ void *mp_get_config_group(void *ta_parent, struct mpv_global *global, return cache->opts; } -void mp_read_option_raw(struct mpv_global *global, const char *name, - const struct m_option_type *type, void *dst) -{ - struct m_config_shadow *shadow = global->config; - - int32_t optid = -1; - while (m_config_shadow_get_next_opt(shadow, &optid)) { - char buf[M_CONFIG_MAX_OPT_NAME_LEN]; - const char *opt_name = - m_config_shadow_get_opt_name(shadow, optid, buf, sizeof(buf)); - - if (strcmp(name, opt_name) == 0) { - const struct m_option *opt = m_config_shadow_get_opt(shadow, optid); - - int group_index, opt_index; - get_opt_from_id(shadow, optid, &group_index, &opt_index); - - struct m_group_data *gdata = m_config_gdata(shadow->data, group_index); - assert(gdata); - - assert(opt->offset >= 0); - assert(opt->type == type); - - memset(dst, 0, opt->type->size); - m_option_copy(opt, dst, gdata->udata + opt->offset); - return; - } - } - - assert(0); // not found -} - static const struct m_config_group *find_group(struct mpv_global *global, const struct m_option *cfg) { diff --git a/options/m_config_core.h b/options/m_config_core.h index c4902be9d1..a9558423d8 100644 --- a/options/m_config_core.h +++ b/options/m_config_core.h @@ -131,13 +131,6 @@ bool m_config_cache_write_opt(struct m_config_cache *cache, void *ptr); void *mp_get_config_group(void *ta_parent, struct mpv_global *global, const struct m_sub_options *group); -// Read a single global option in a thread-safe way. For multiple options, -// use m_config_cache. The option must exist and match the provided type (the -// type is used as a sanity check only). Performs semi-expensive lookup. -// Warning: new code must not use this. -void mp_read_option_raw(struct mpv_global *global, const char *name, - const struct m_option_type *type, void *dst); - // Allocate a priv struct that is backed by global options (like AOs and VOs, // anything that uses m_obj_list.use_global_options == true). // The result contains a snapshot of the current option values of desc->options. diff --git a/options/m_config_frontend.c b/options/m_config_frontend.c index a3356c4111..d800cdb75d 100644 --- a/options/m_config_frontend.c +++ b/options/m_config_frontend.c @@ -15,28 +15,28 @@ * License along with mpv. If not, see <http://www.gnu.org/licenses/>. */ +#include <assert.h> +#include <errno.h> #include <float.h> -#include <stdlib.h> +#include <stdatomic.h> +#include <stdbool.h> #include <stdio.h> -#include <errno.h> +#include <stdlib.h> #include <string.h> #include <strings.h> -#include <assert.h> -#include <stdbool.h> -#include <pthread.h> #include "libmpv/client.h" -#include "m_config.h" -#include "m_config_frontend.h" -#include "options/m_option.h" #include "common/common.h" #include "common/global.h" -#include "common/msg.h" #include "common/msg_control.h" +#include "common/msg.h" +#include "m_config_frontend.h" +#include "m_config.h" #include "misc/dispatch.h" #include "misc/node.h" -#include "osdep/atomic.h" +#include "options/m_option.h" +#include "osdep/threads.h" extern const char mp_help_text[]; @@ -168,18 +168,9 @@ static int m_config_set_obj_params(struct m_config *config, struct mp_log *log, struct m_config *m_config_from_obj_desc_and_args(void *ta_parent, struct mp_log *log, struct mpv_global *global, struct m_obj_desc *desc, - const char *name, struct m_obj_settings *defaults, char **args) + char **args) { struct m_config *config = m_config_from_obj_desc(ta_parent, log, global, desc); - - 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, desc, entry->attribs) < 0) - goto error; - } - } - if (m_config_set_obj_params(config, log, global, desc, args) < 0) goto error; @@ -244,6 +235,26 @@ void m_config_restore_backups(struct m_config *config) restore_backups(&config->backup_opts, config); } +bool m_config_watch_later_backup_opt_changed(struct m_config *config, + char *opt_name) +{ + struct m_config_option *co = m_config_get_co(config, bstr0(opt_name)); + if (!co) { + MP_ERR(config, "Option %s not found.\n", opt_name); + return false; + } + + for (struct m_opt_backup *bc = config->watch_later_backup_opts; bc; + bc = bc->next) { + if (strcmp(bc->co->name, co->name) == 0) { + struct m_config_option *bc_co = (struct m_config_option *)bc->backup; + return !m_option_equal(co->opt, co->data, bc_co); + } + } + + return false; +} + void m_config_backup_opt(struct m_config *config, const char *opt) { struct m_config_option *co = m_config_get_co(config, bstr0(opt)); @@ -260,6 +271,11 @@ void m_config_backup_all_opts(struct m_config *config) ensure_backup(&config->backup_opts, BACKUP_LOCAL, &config->opts[n]); } +void m_config_backup_watch_later_opts(struct m_config *config) +{ + for (int n = 0; n < config->num_opts; n++) + ensure_backup(&config->watch_later_backup_opts, 0, &config->opts[n]); +} struct m_config_option *m_config_get_co_raw(const struct m_config *config, struct bstr name) @@ -509,6 +525,13 @@ static void config_destroy(void *p) config->option_change_callback = NULL; m_config_restore_backups(config); + struct m_opt_backup **list = &config->watch_later_backup_opts; + while (*list) { + struct m_opt_backup *bc = *list; + *list = bc->next; + talloc_free(bc); + } + talloc_free(config->cache); talloc_free(config->shadow); } @@ -726,7 +749,7 @@ int m_config_set_option_cli(struct m_config *config, struct bstr name, BSTR_P(name), BSTR_P(param), flags); } - union m_option_value val = {0}; + union m_option_value val = m_option_value_default; // Some option types are "impure" and work on the existing data. // (Prime examples: --vf-add, --sub-file) @@ -760,7 +783,7 @@ int m_config_set_option_node(struct m_config *config, bstr name, // Do this on an "empty" type to make setting the option strictly overwrite // the old value, as opposed to e.g. appending to lists. - union m_option_value val = {0}; + union m_option_value val = m_option_value_default; if (data->format == MPV_FORMAT_STRING) { bstr param = bstr0(data->u.string); @@ -826,7 +849,7 @@ void m_config_print_option_list(const struct m_config *config, const char *name) MP_INFO(config, " %s%-30s", prefix, co->name); if (opt->type == &m_option_type_choice) { MP_INFO(config, " Choices:"); - struct m_opt_choice_alternatives *alt = opt->priv; + const struct m_opt_choice_alternatives *alt = opt->priv; for (int n = 0; alt[n].name; n++) MP_INFO(config, " %s", alt[n].name); if (opt->min < opt->max) @@ -845,11 +868,10 @@ void m_config_print_option_list(const struct m_config *config, const char *name) } char *def = NULL; const void *defptr = m_config_get_co_default(config, co); - const union m_option_value default_value = {0}; if (!defptr) - defptr = &default_value; + defptr = &m_option_value_default; if (defptr) - def = m_option_pretty_print(opt, defptr); + def = m_option_pretty_print(opt, defptr, false); if (def) { MP_INFO(config, " (default: %s)", def); talloc_free(def); @@ -1009,7 +1031,7 @@ int m_config_restore_profile(struct m_config *config, char *name) return M_OPT_INVALID; if (!p->backups) - MP_WARN(config, "Profile contains no restore data.\n"); + MP_WARN(config, "Profile '%s' contains no restore data.\n", name); restore_backups(&p->backups, config); diff --git a/options/m_config_frontend.h b/options/m_config_frontend.h index ee6b9aec46..6108d9feec 100644 --- a/options/m_config_frontend.h +++ b/options/m_config_frontend.h @@ -17,9 +17,10 @@ #pragma once +#include <stdatomic.h> +#include <stdbool.h> #include <stddef.h> #include <stdint.h> -#include <stdbool.h> #include "common/common.h" #include "common/global.h" @@ -29,7 +30,6 @@ #include "misc/bstr.h" #include "misc/dispatch.h" #include "options/m_option.h" -#include "osdep/atomic.h" // m_config provides an API to manipulate the config variables in MPlayer. // It makes use of the Options API to provide a context stack that @@ -75,6 +75,7 @@ typedef struct m_config { int profile_backup_flags; struct m_opt_backup *backup_opts; + struct m_opt_backup *watch_later_backup_opts; bool use_profiles; bool is_toplevel; @@ -114,10 +115,9 @@ struct m_config *m_config_new(void *talloc_ctx, struct mp_log *log, // different sub-options for every filter (represented by separate desc // structs). // args is an array of key/value pairs (args=[k0, v0, k1, v1, ..., NULL]). -// name/defaults is only needed for the legacy af-defaults/vf-defaults options. struct m_config *m_config_from_obj_desc_and_args(void *ta_parent, struct mp_log *log, struct mpv_global *global, struct m_obj_desc *desc, - const char *name, struct m_obj_settings *defaults, char **args); + char **args); // Like m_config_from_obj_desc_and_args(), but don't allocate option the // struct, i.e. m_config.optstruct==NULL. This is used by the sub-option @@ -134,10 +134,18 @@ void m_config_backup_opt(struct m_config *config, const char *opt); // Call m_config_backup_opt() on all options. void m_config_backup_all_opts(struct m_config *config); +// Backup options on startup so that quit-watch-later can compare the current +// values to their backups, and save them only if they have been changed. +void m_config_backup_watch_later_opts(struct m_config *config); + // Restore all options backed up with m_config_backup_opt(), and delete the // backups afterwards. void m_config_restore_backups(struct m_config *config); +// Whether opt_name is different from its initial value. +bool m_config_watch_later_backup_opt_changed(struct m_config *config, + char *opt_name); + enum { M_SETOPT_PRE_PARSE_ONLY = 1, // Silently ignore non-M_OPT_PRE_PARSE opt. M_SETOPT_CHECK_ONLY = 2, // Don't set, just check name/value diff --git a/options/m_option.c b/options/m_option.c index 4d222df500..4646510f21 100644 --- a/options/m_option.c +++ b/options/m_option.c @@ -61,6 +61,31 @@ const char m_option_path_separator = OPTION_PATH_SEPARATOR; #define OPT_INT_MAX(opt, T, Tm) ((opt)->min < (opt)->max \ ? ((opt)->max >= (double)(Tm) ? (Tm) : (T)((opt)->max)) : (Tm)) +int m_option_parse(struct mp_log *log, const m_option_t *opt, + struct bstr name, struct bstr param, void *dst) +{ + int r = M_OPT_INVALID; + if (bstr_equals0(param, "help") && opt->help) { + r = opt->help(log, opt, name); + if (r < 0) + return r; + } + + r = opt->type->parse(log, opt, name, param, dst); + if (r < 0) + return r; + + if (opt->validate) { + r = opt->validate(log, opt, name, dst); + if (r < 0) { + if (opt->type->free) + opt->type->free(dst); + return r; + } + } + return 1; +} + char *m_option_strerror(int code) { switch (code) { @@ -86,7 +111,7 @@ int m_option_required_params(const m_option_t *opt) if (opt->flags & M_OPT_OPTIONAL_PARAM) return 0; if (opt->type == &m_option_type_choice) { - struct m_opt_choice_alternatives *alt; + const struct m_opt_choice_alternatives *alt; for (alt = opt->priv; alt->name; alt++) { if (strcmp(alt->name, "yes") == 0) return 0; @@ -245,6 +270,7 @@ static bool flag_equal(const m_option_t *opt, void *a, void *b) return VAL(a) == VAL(b); } +// Only exists for libmpv interopability and should not be used anywhere. const m_option_type_t m_option_type_flag = { // need yes or no in config files .name = "Flag", @@ -595,7 +621,7 @@ const char *m_opt_choice_str(const struct m_opt_choice_alternatives *choices, static void print_choice_values(struct mp_log *log, const struct m_option *opt) { - struct m_opt_choice_alternatives *alt = opt->priv; + const struct m_opt_choice_alternatives *alt = opt->priv; for ( ; alt->name; alt++) mp_info(log, " %s\n", alt->name[0] ? alt->name : "(passing nothing)"); if (opt->min < opt->max) @@ -605,7 +631,7 @@ static void print_choice_values(struct mp_log *log, const struct m_option *opt) static int parse_choice(struct mp_log *log, const struct m_option *opt, struct bstr name, struct bstr param, void *dst) { - struct m_opt_choice_alternatives *alt = opt->priv; + const struct m_opt_choice_alternatives *alt = opt->priv; for ( ; alt->name; alt++) { if (!bstrcmp0(param, alt->name)) break; @@ -652,7 +678,7 @@ static void choice_get_min_max(const struct m_option *opt, int *min, int *max) assert(opt->type == &m_option_type_choice); *min = INT_MAX; *max = INT_MIN; - for (struct m_opt_choice_alternatives *alt = opt->priv; alt->name; alt++) { + for (const struct m_opt_choice_alternatives *alt = opt->priv; alt->name; alt++) { *min = MPMIN(*min, alt->value); *max = MPMAX(*max, alt->value); } @@ -696,7 +722,7 @@ static void add_choice(const m_option_t *opt, void *val, double add, bool wrap) } } - for (struct m_opt_choice_alternatives *alt = opt->priv; alt->name; alt++) + for (const struct m_opt_choice_alternatives *alt = opt->priv; alt->name; alt++) check_choice(dir, ival, &found, &best, alt->value); if (!found) { @@ -729,11 +755,12 @@ static int choice_set(const m_option_t *opt, void *dst, struct mpv_node *src) return r; } -static struct m_opt_choice_alternatives *get_choice(const m_option_t *opt, - const void *val, int *out_val) +static const struct m_opt_choice_alternatives *get_choice(const m_option_t *opt, + const void *val, + int *out_val) { int v = *(int *)val; - struct m_opt_choice_alternatives *alt; + const struct m_opt_choice_alternatives *alt; for (alt = opt->priv; alt->name; alt++) { if (alt->value == v) return alt; @@ -744,14 +771,14 @@ static struct m_opt_choice_alternatives *get_choice(const m_option_t *opt, return NULL; } } - abort(); + MP_ASSERT_UNREACHABLE(); } static int choice_get(const m_option_t *opt, void *ta_parent, struct mpv_node *dst, void *src) { int ival = 0; - struct m_opt_choice_alternatives *alt = get_choice(opt, src, &ival); + const struct m_opt_choice_alternatives *alt = get_choice(opt, src, &ival); // If a choice string looks like a number, return it as number if (alt) { char *end = NULL; @@ -783,7 +810,7 @@ static int choice_get(const m_option_t *opt, void *ta_parent, static char *print_choice(const m_option_t *opt, const void *val) { int ival = 0; - struct m_opt_choice_alternatives *alt = get_choice(opt, val, &ival); + const struct m_opt_choice_alternatives *alt = get_choice(opt, val, &ival); return alt ? talloc_strdup(NULL, alt->name) : talloc_asprintf(NULL, "%d", ival); } @@ -803,7 +830,7 @@ const struct m_option_type m_option_type_choice = { static int apply_flag(const struct m_option *opt, int *val, bstr flag) { - struct m_opt_choice_alternatives *alt; + const struct m_opt_choice_alternatives *alt; for (alt = opt->priv; alt->name; alt++) { if (bstr_equals0(flag, alt->name)) { if (*val & alt->value) @@ -817,8 +844,8 @@ static int apply_flag(const struct m_option *opt, int *val, bstr flag) static const char *find_next_flag(const struct m_option *opt, int *val) { - struct m_opt_choice_alternatives *best = NULL; - struct m_opt_choice_alternatives *alt; + const struct m_opt_choice_alternatives *best = NULL; + const struct m_opt_choice_alternatives *alt; for (alt = opt->priv; alt->name; alt++) { if (alt->value && (alt->value & (*val)) == alt->value) { if (!best || av_popcount64(alt->value) > av_popcount64(best->value)) @@ -845,7 +872,7 @@ static int parse_flags(struct mp_log *log, const struct m_option *opt, mp_fatal(log, "Invalid flag for option %.*s: %.*s\n", BSTR_P(name), BSTR_P(flag)); mp_info(log, "Valid flags are:\n"); - struct m_opt_choice_alternatives *alt; + const struct m_opt_choice_alternatives *alt; for (alt = opt->priv; alt->name; alt++) mp_info(log, " %s\n", alt->name); mp_info(log, "Flags can usually be combined with '+'.\n"); @@ -996,12 +1023,12 @@ static char *print_double(const m_option_t *opt, const void *val) return talloc_asprintf(NULL, "%f", f); } -static char *print_double_f3(const m_option_t *opt, const void *val) +static char *pretty_print_double(const m_option_t *opt, const void *val) { double f = VAL(val); if (isnan(f)) return print_double(opt, val); - return talloc_asprintf(NULL, "%.3f", f); + return mp_format_double(NULL, f, 4, false, false, !(opt->flags & M_OPT_FIXED_LEN_PRINT)); } static void add_double(const m_option_t *opt, void *val, double add, bool wrap) @@ -1073,7 +1100,33 @@ const m_option_type_t m_option_type_double = { .size = sizeof(double), .parse = parse_double, .print = print_double, - .pretty_print = print_double_f3, + .pretty_print = pretty_print_double, + .copy = copy_opt, + .add = add_double, + .multiply = multiply_double, + .set = double_set, + .get = double_get, + .equal = double_equal, +}; + +static int parse_double_aspect(struct mp_log *log, const m_option_t *opt, + struct bstr name, struct bstr param, void *dst) +{ + if (bstr_equals0(param, "no")) { + if (dst) + VAL(dst) = 0.0; + return 1; + } + return parse_double(log, opt, name, param, dst); +} + +const m_option_type_t m_option_type_aspect = { + .name = "Aspect", + .size = sizeof(double), + .flags = M_OPT_TYPE_CHOICE | M_OPT_TYPE_USES_RANGE, + .parse = parse_double_aspect, + .print = print_double, + .pretty_print = pretty_print_double, .copy = copy_opt, .add = add_double, .multiply = multiply_double, @@ -1101,10 +1154,10 @@ static char *print_float(const m_option_t *opt, const void *val) return print_double(opt, &tmp); } -static char *print_float_f3(const m_option_t *opt, const void *val) +static char *pretty_print_float(const m_option_t *opt, const void *val) { double tmp = VAL(val); - return print_double_f3(opt, &tmp); + return pretty_print_double(opt, &tmp); } static void add_float(const m_option_t *opt, void *val, double add, bool wrap) @@ -1149,33 +1202,7 @@ const m_option_type_t m_option_type_float = { .size = sizeof(float), .parse = parse_float, .print = print_float, - .pretty_print = print_float_f3, - .copy = copy_opt, - .add = add_float, - .multiply = multiply_float, - .set = float_set, - .get = float_get, - .equal = float_equal, -}; - -static int parse_float_aspect(struct mp_log *log, const m_option_t *opt, - struct bstr name, struct bstr param, void *dst) -{ - if (bstr_equals0(param, "no")) { - if (dst) - VAL(dst) = 0.0f; - return 1; - } - return parse_float(log, opt, name, param, dst); -} - -const m_option_type_t m_option_type_aspect = { - .name = "Aspect", - .size = sizeof(float), - .flags = M_OPT_TYPE_CHOICE | M_OPT_TYPE_USES_RANGE, - .parse = parse_float_aspect, - .print = print_float, - .pretty_print = print_float_f3, + .pretty_print = pretty_print_float, .copy = copy_opt, .add = add_float, .multiply = multiply_float, @@ -1192,13 +1219,6 @@ const m_option_type_t m_option_type_aspect = { static int parse_str(struct mp_log *log, const m_option_t *opt, struct bstr name, struct bstr param, void *dst) { - m_opt_string_validate_fn validate = opt->priv; - if (validate) { - int r = validate(log, opt, name, param); - if (r < 0) - return r; - } - if (dst) { talloc_free(VAL(dst)); VAL(dst) = bstrdup0(NULL, param); @@ -1272,11 +1292,10 @@ const m_option_type_t m_option_type_string = { #define OP_NONE 0 #define OP_ADD 1 #define OP_PRE 2 -#define OP_DEL 3 -#define OP_CLR 4 -#define OP_TOGGLE 5 -#define OP_APPEND 6 -#define OP_REMOVE 7 +#define OP_CLR 3 +#define OP_TOGGLE 4 +#define OP_APPEND 5 +#define OP_REMOVE 6 static void free_str_list(void *dst) { @@ -1318,55 +1337,6 @@ static int str_list_add(char **add, int n, void *dst, int pre) return 1; } -static int str_list_del(struct mp_log *log, char **del, int n, void *dst) -{ - char **lst, *ep; - int i, ln, s; - long idx; - - lst = VAL(dst); - - for (ln = 0; lst && lst[ln]; ln++) - /**/; - s = ln; - - for (i = 0; del[i] != NULL; i++) { - idx = strtol(del[i], &ep, 0); - if (*ep) { - mp_err(log, "Invalid index: %s\n", del[i]); - talloc_free(del[i]); - continue; - } - talloc_free(del[i]); - if (idx < 0 || idx >= ln) { - mp_err(log, "Index %ld is out of range.\n", idx); - continue; - } else if (!lst[idx]) - continue; - talloc_free(lst[idx]); - lst[idx] = NULL; - s--; - } - talloc_free(del); - - if (s == 0) { - talloc_free(lst); - VAL(dst) = NULL; - return 1; - } - - // Don't bother shrinking the list allocation - for (i = 0, n = 0; i < ln; i++) { - if (!lst[i]) - continue; - lst[n] = lst[i]; - n++; - } - lst[s] = NULL; - - return 1; -} - static struct bstr get_nextsep(struct bstr *ptr, char sep, bool modify) { struct bstr str = *ptr; @@ -1413,11 +1383,6 @@ static int parse_str_list_impl(struct mp_log *log, const m_option_t *opt, multi = false; } else if (bstr_endswith0(name, "-pre")) { op = OP_PRE; - } else if (bstr_endswith0(name, "-del")) { - op = OP_DEL; - mp_warn(log, "Option %.*s: -del is deprecated! " - "Use -remove (removes by content instead of by index).\n", - BSTR_P(name)); } else if (bstr_endswith0(name, "-clr")) { op = OP_CLR; } else if (bstr_endswith0(name, "-set")) { @@ -1431,14 +1396,20 @@ static int parse_str_list_impl(struct mp_log *log, const m_option_t *opt, if (op == OP_TOGGLE || op == OP_REMOVE) { if (dst) { char **list = VAL(dst); - int index = find_list_bstr(list, param); - if (index >= 0) { - char *old = list[index]; - for (int n = index; list[n]; n++) - list[n] = list[n + 1]; - talloc_free(old); + bool found = false; + int index = 0; + do { + index = find_list_bstr(list, param); + if (index >= 0) { + found = true; + char *old = list[index]; + for (int n = index; list[n]; n++) + list[n] = list[n + 1]; + talloc_free(old); + } + } while (index >= 0); + if (found) return 1; - } } if (op == OP_REMOVE) return 1; // ignore if not found @@ -1499,8 +1470,6 @@ static int parse_str_list_impl(struct mp_log *log, const m_option_t *opt, return str_list_add(res, n, dst, 0); case OP_PRE: return str_list_add(res, n, dst, 1); - case OP_DEL: - return str_list_del(log, res, n, dst); } if (VAL(dst)) @@ -1543,6 +1512,7 @@ static char *print_str_list(const m_option_t *opt, const void *src) { char **lst = NULL; char *ret = NULL; + const char sep = opt->priv ? *(char *)opt->priv : OPTION_LIST_SEPARATOR; if (!(src && VAL(src))) return talloc_strdup(NULL, ""); @@ -1550,7 +1520,7 @@ static char *print_str_list(const m_option_t *opt, const void *src) for (int i = 0; lst[i]; i++) { if (ret) - ret = talloc_strdup_append_buffer(ret, ","); + ret = talloc_strndup_append_buffer(ret, &sep, 1); ret = talloc_strdup_append_buffer(ret, lst[i]); } return ret; @@ -1630,7 +1600,6 @@ const m_option_type_t m_option_type_string_list = { {"add"}, {"append"}, {"clr", M_OPT_TYPE_OPTIONAL_PARAM}, - {"del"}, {"pre"}, {"set"}, {"toggle"}, @@ -1736,7 +1705,7 @@ static int parse_keyvalue_list(struct mp_log *log, const m_option_t *opt, } if (param.len) { - mp_err(log, "Unparseable garbage at end of option value: '%.*s'\n", + mp_err(log, "Unparsable garbage at end of option value: '%.*s'\n", BSTR_P(param)); r = M_OPT_INVALID; } @@ -1846,7 +1815,7 @@ static int parse_msglevels(struct mp_log *log, const m_option_t *opt, struct bstr name, struct bstr param, void *dst) { if (bstr_equals0(param, "help")) { - mp_info(log, "Syntax:\n\n --msglevel=module1=level,module2=level,...\n\n" + mp_info(log, "Syntax:\n\n --msg-level=module1= |