summaryrefslogtreecommitdiffstats
path: root/options
diff options
context:
space:
mode:
Diffstat (limited to 'options')
-rw-r--r--options/m_config.h2
-rw-r--r--options/m_config_core.c82
-rw-r--r--options/m_config_core.h7
-rw-r--r--options/m_config_frontend.c76
-rw-r--r--options/m_config_frontend.h16
-rw-r--r--options/m_option.c408
-rw-r--r--options/m_option.h88
-rw-r--r--options/m_property.c47
-rw-r--r--options/m_property.h22
-rw-r--r--options/options.c754
-rw-r--r--options/options.h272
-rw-r--r--options/parse_commandline.c11
-rw-r--r--options/parse_configfile.c49
-rw-r--r--options/parse_configfile.h5
-rw-r--r--options/path.c236
-rw-r--r--options/path.h54
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=