summaryrefslogtreecommitdiffstats
path: root/options/m_option.c
diff options
context:
space:
mode:
Diffstat (limited to 'options/m_option.c')
-rw-r--r--options/m_option.c422
1 files changed, 219 insertions, 203 deletions
diff --git a/options/m_option.c b/options/m_option.c
index 4d222df500..3d9ae26669 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=level,module2=level,...\n\n"
"'module' is output prefix as shown with -v, or a prefix\n"
"of it. level is one of:\n\n"
" fatal error warn info status v debug trace\n\n"
@@ -1928,7 +1897,7 @@ const m_option_type_t m_option_type_dummy_flag = {
// Read s sub-option name, or a positional sub-opt value.
// termset is a string containing the set of chars that terminate an option.
-// Return 0 on succes, M_OPT_ error code otherwise.
+// Return 0 on success, M_OPT_ error code otherwise.
// optname is for error reporting.
static int read_subparam(struct mp_log *log, bstr optname, char *termset,
bstr *str, bstr *out_subparam)
@@ -2254,7 +2223,7 @@ void m_geometry_apply(int *xpos, int *ypos, int *widw, int *widh,
*widw = *widh * asp;
}
// Center window after resize. If valid x:y values are passed to
- // geometry, then those values will be overriden.
+ // geometry, then those values will be overridden.
*xpos += prew / 2 - *widw / 2;
*ypos += preh / 2 - *widh / 2;
}
@@ -2361,6 +2330,64 @@ const m_option_type_t m_option_type_size_box = {
.equal = geometry_equal,
};
+void m_rect_apply(struct mp_rect *rc, int w, int h, struct m_geometry *gm)
+{
+ *rc = (struct mp_rect){0, 0, w, h};
+ if (!w || !h)
+ return;
+ m_geometry_apply(&rc->x0, &rc->y0, &rc->x1, &rc->y1, w, h, gm);
+ if (!gm->xy_valid && gm->wh_valid && rc->x1 == 0 && rc->y1 == 0)
+ return;
+ if (!gm->wh_valid || rc->x1 == 0 || rc->x1 == INT_MIN)
+ rc->x1 = w - rc->x0;
+ if (!gm->wh_valid || rc->y1 == 0 || rc->y1 == INT_MIN)
+ rc->y1 = h - rc->y0;
+ if (gm->wh_valid && (gm->w || gm->h))
+ rc->x1 += rc->x0;
+ if (gm->wh_valid && (gm->w || gm->h))
+ rc->y1 += rc->y0;
+}
+
+static int parse_rect(struct mp_log *log, const m_option_t *opt,
+ struct bstr name, struct bstr param, void *dst)
+{
+ bool is_help = bstr_equals0(param, "help");
+ if (is_help)
+ goto exit;
+
+ struct m_geometry gm;
+ if (!parse_geometry_str(&gm, param))
+ goto exit;
+
+ bool invalid = gm.x_sign || gm.y_sign || gm.ws;
+ invalid |= gm.wh_valid && (gm.w < 0 || gm.h < 0);
+ invalid |= gm.wh_valid && !gm.xy_valid && gm.w <= 0 && gm.h <= 0;
+
+ if (invalid)
+ goto exit;
+
+ if (dst)
+ *((struct m_geometry *)dst) = gm;
+
+ return 1;
+
+exit:
+ if (!is_help) {
+ mp_err(log, "Option %.*s: invalid rect: '%.*s'\n",
+ BSTR_P(name), BSTR_P(param));
+ }
+ mp_info(log, "Valid format: W[%%][xH[%%]][+x+y]\n");
+ return is_help ? M_OPT_EXIT : M_OPT_INVALID;
+}
+
+const m_option_type_t m_option_type_rect = {
+ .name = "Video rect",
+ .size = sizeof(struct m_geometry),
+ .parse = parse_rect,
+ .print = print_geometry,
+ .copy = copy_opt,
+ .equal = geometry_equal,
+};
#include "video/img_format.h"
@@ -2628,21 +2655,33 @@ const m_option_type_t m_option_type_channels = {
static int parse_timestring(struct bstr str, double *time, char endchar)
{
- int a, b, len;
- double d;
+ int h, m, len;
+ double s;
*time = 0; /* ensure initialization for error cases */
- if (bstr_sscanf(str, "%d:%d:%lf%n", &a, &b, &d, &len) >= 3)
- *time = 3600 * a + 60 * b + d;
- else if (bstr_sscanf(str, "%d:%lf%n", &a, &d, &len) >= 2)
- *time = 60 * a + d;
- else if (bstr_sscanf(str, "%lf%n", &d, &len) >= 1)
- *time = d;
- else
+ bool neg = bstr_eatstart0(&str, "-");
+ if (!neg)
+ bstr_eatstart0(&str, "+");
+ if (bstrchr(str, '-') >= 0 || bstrchr(str, '+') >= 0)
+ return 0; /* the timestamp shouldn't contain anymore +/- after this point */
+ if (bstr_sscanf(str, "%d:%d:%lf%n", &h, &m, &s, &len) >= 3) {
+ if (m >= 60 || s >= 60)
+ return 0; /* minutes or seconds are out of range */
+ *time = 3600 * h + 60 * m + s;
+ } else if (bstr_sscanf(str, "%d:%lf%n", &m, &s, &len) >= 2) {
+ if (s >= 60)
+ return 0; /* seconds are out of range */
+ *time = 60 * m + s;
+ } else if (bstr_sscanf(str, "%lf%n", &s, &len) >= 1) {
+ *time = s;
+ } else {
return 0; /* unsupported time format */
+ }
if (len < str.len && str.start[len] != endchar)
return 0; /* invalid extra characters at the end */
if (!isfinite(*time))
return 0;
+ if (neg)
+ *time = -*time;
return len;
}
@@ -2783,8 +2822,7 @@ static char *print_rel_time(const m_option_t *opt, const void *val)
case REL_TIME_ABSOLUTE:
return talloc_asprintf(NULL, "%g", t->pos);
case REL_TIME_RELATIVE:
- return talloc_asprintf(NULL, "%s%g",
- (t->pos >= 0) ? "+" : "-", fabs(t->pos));
+ return talloc_asprintf(NULL, "%+g", t->pos);
case REL_TIME_CHAPTER:
return talloc_asprintf(NULL, "#%g", t->pos);
case REL_TIME_PERCENT:
@@ -3128,7 +3166,7 @@ print_help: ;
} else if (list->print_unknown_entry_help) {
list->print_unknown_entry_help(log, mp_tprintf(80, "%.*s", BSTR_P(name)));
} else {
- mp_warn(log, "Option %.*s: item %.*s doesn't exist.\n",
+ mp_warn(log, "Option %.*s: item '%.*s' isn't supported.\n",
BSTR_P(opt_name), BSTR_P(name));
}
r = M_OPT_EXIT;
@@ -3183,7 +3221,7 @@ static int parse_obj_settings(struct mp_log *log, struct bstr opt, int op,
int idx = bstrspn(*pstr, NAMECH);
str = bstr_splice(*pstr, 0, idx);
if (!str.len) {
- mp_err(log, "Option %.*s: filter name expected.\n", BSTR_P(opt));
+ mp_err(log, "Option %.*s: item name expected.\n", BSTR_P(opt));
return M_OPT_INVALID;
}
*pstr = bstr_cut(*pstr, idx);
@@ -3199,10 +3237,8 @@ static int parse_obj_settings(struct mp_log *log, struct bstr opt, int op,
} else {
char name[80];
snprintf(name, sizeof(name), "%.*s", BSTR_P(str));
- if (!list->allow_unknown_entries ||
- (list->check_unknown_entry && !list->check_unknown_entry(name)))
- {
- mp_err(log, "Option %.*s: %.*s doesn't exist.\n",
+ if (list->check_unknown_entry && !list->check_unknown_entry(name)) {
+ mp_err(log, "Option %.*s: '%.*s' isn't supported.\n",
BSTR_P(opt), BSTR_P(str));
return M_OPT_INVALID;
}
@@ -3235,11 +3271,10 @@ done: ;
return 1;
}
-// Parse a single entry for -vf-del (return 0 if not applicable)
+// Parse a single entry for -vf-remove (return 0 if not applicable)
// mark_del is bounded by the number of items in dst
static int parse_obj_settings_del(struct mp_log *log, struct bstr opt_name,
- struct bstr *param, int op,
- void *dst, bool *mark_del)
+ struct bstr *param, void *dst, bool *mark_del)
{
bstr s = *param;
if (bstr_eatstart0(&s, "@")) {
@@ -3251,7 +3286,8 @@ static int parse_obj_settings_del(struct mp_log *log, struct bstr opt_name,
if (bstr_startswith0(s, ":"))
return 0;
if (dst) {
- int label_index = obj_settings_list_find_by_label(VAL(dst), label);
+ int label_index = 0;
+ label_index = obj_settings_list_find_by_label(VAL(dst), label);
if (label_index >= 0) {
mark_del[label_index] = true;
} else {
@@ -3262,30 +3298,7 @@ static int parse_obj_settings_del(struct mp_log *log, struct bstr opt_name,
*param = s;
return 1;
}
-
- if (op == OP_REMOVE)
- return 0;
-
- bstr rest;
- long long id = bstrtoll(s, &rest, 0);
- if (rest.len == s.len)
- return 0;
-
- if (dst) {
- int num = obj_settings_list_num_items(VAL(dst));
- if (id < 0)
- id = num + id;
-
- if (id >= 0 && id < num) {
- mark_del[id] = true;
- } else {
- mp_warn(log, "Option %.*s: Index %lld is out of range.\n",
- BSTR_P(opt_name), id);
- }
- }
-
- *param = rest;
- return 1;
+ return 0;
}
static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
@@ -3295,7 +3308,7 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
int op = OP_NONE;
bool *mark_del = NULL;
int num_items = obj_settings_list_num_items(dst ? VAL(dst) : 0);
- struct m_obj_list *ol = opt->priv;
+ const struct m_obj_list *ol = opt->priv;
assert(opt->priv);
@@ -3307,11 +3320,6 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
op = OP_NONE;
} 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, "-remove")) {
op = OP_REMOVE;
} else if (bstr_endswith0(name, "-clr")) {
@@ -3324,23 +3332,19 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
" %s-set\n"
" Overwrite the old list with the given list\n\n"
" %s-append\n"
- " Append the given filter to the current list\n\n"
+ " Append the given item to the current list\n\n"
" %s-add\n"
" Append the given list to the current list\n\n"
" %s-pre\n"
" Prepend the given list to the current list\n\n"
" %s-remove\n"
- " Remove the given filter from the current list\n\n"
- " %s-del x,y,...\n"
- " Remove the given elements. Take the list element index (starting from 0).\n"
- " Negative index can be used (i.e. -1 is the last element).\n"
- " Filter names work as well.\n\n"
+ " Remove the given item from the current list\n\n"
" %s-toggle\n"
- " Add the filter to the list, or remove it if it's already added.\n\n"
+ " Add the item to the list, or remove it if it's already added.\n\n"
" %s-clr\n"
" Clear the current list.\n\n",
opt->name, opt->name, opt->name, opt->name, opt->name,
- opt->name, opt->name, opt->name, opt->name);
+ opt->name, opt->name, opt->name);
return M_OPT_EXIT;
}
@@ -3375,7 +3379,7 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
if (dst)
free_obj_settings_list(dst);
return 0;
- } else if (op == OP_DEL || op == OP_REMOVE) {
+ } else if (op == OP_REMOVE) {
mark_del = talloc_zero_array(NULL, bool, num_items + 1);
}
@@ -3384,20 +3388,26 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
while (param.len > 0) {
int r = 0;
- if (op == OP_DEL || op == OP_REMOVE)
- r = parse_obj_settings_del(log, name, &param, op, dst, mark_del);
+ if (op == OP_REMOVE)
+ r = parse_obj_settings_del(log, name, &param, dst, mark_del);
if (r == 0) {
r = parse_obj_settings(log, name, op, &param, ol, dst ? &res : NULL);
}
- if (r < 0)
+ if (r < 0) {
+ free_obj_settings_list(&res);
return r;
+ }
if (param.len > 0) {
const char sep[2] = {OPTION_LIST_SEPARATOR, 0};
- if (!bstr_eatstart0(&param, sep))
+ if (!bstr_eatstart0(&param, sep)) {
+ free_obj_settings_list(&res);
return M_OPT_INVALID;
+ }
if (param.len == 0) {
- if (!ol->allow_trailer)
+ if (!ol->allow_trailer) {
+ free_obj_settings_list(&res);
return M_OPT_INVALID;
+ }
if (dst) {
m_obj_settings_t item = {
.name = talloc_strdup(NULL, ""),
@@ -3410,8 +3420,9 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
if (op != OP_NONE && res && res[0].name && res[1].name) {
if (op == OP_APPEND) {
- mp_err(log, "Option %.*s: -append takes only 1 filter (no ',').\n",
+ mp_err(log, "Option %.*s: -append takes only 1 item (no ',').\n",
BSTR_P(name));
+ free_obj_settings_list(&res);
return M_OPT_INVALID;
}
mp_warn(log, "Passing more than 1 argument to %.*s is deprecated!\n",
@@ -3472,19 +3483,15 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
}
}
talloc_free(res);
- } else if (op == OP_DEL || op == OP_REMOVE) {
+ } else if (op == OP_REMOVE) {
for (int n = num_items - 1; n >= 0; n--) {
if (mark_del[n])
obj_settings_list_del_at(&list, n);
}
for (int n = 0; res && res[n].name; n++) {
int found = obj_settings_find_by_content(list, &res[n]);
- if (found < 0) {
- if (op == OP_DEL)
- mp_warn(log, "Option %.*s: Item not found\n", BSTR_P(name));
- } else {
+ if (found >= 0)
obj_settings_list_del_at(&list, found);
- }
}
free_obj_settings_list(&res);
} else {
@@ -3650,7 +3657,7 @@ static bool obj_settings_list_equal(const m_option_t *opt, void *pa, void *pb)
struct m_obj_settings *b = VAL(pb);
if (a == b || !a || !b)
- return a == b;
+ return a == b || (!a && !b[0].name) || (!b && !a[0].name);
for (int n = 0; a[n].name || b[n].name; n++) {
if (!a[n].name || !b[n].name)
@@ -3690,7 +3697,6 @@ const m_option_type_t m_option_type_obj_settings_list = {
{"add"},
{"append"},
{"clr", M_OPT_TYPE_OPTIONAL_PARAM},
- {"del"},
{"help", M_OPT_TYPE_OPTIONAL_PARAM},
{"pre"},
{"set"},
@@ -3757,6 +3763,16 @@ static void dup_node(void *ta_parent, struct mpv_node *node)
}
break;
}
+ case MPV_FORMAT_BYTE_ARRAY: {
+ struct mpv_byte_array *old = node->u.ba;
+ struct mpv_byte_array *new = talloc_zero(ta_parent, struct mpv_byte_array);
+ node->u.ba = new;
+ if (old->size > 0) {
+ *new = *old;
+ new->data = talloc_memdup(new, old->data, old->size);
+ }
+ break;
+ }
case MPV_FORMAT_NONE:
case MPV_FORMAT_FLAG:
case MPV_FORMAT_INT64:
@@ -3770,7 +3786,7 @@ static void dup_node(void *ta_parent, struct mpv_node *node)
static void copy_node(const m_option_t *opt, void *dst, const void *src)
{
- assert(sizeof(struct mpv_node) <= sizeof(union m_option_value));
+ static_assert(sizeof(struct mpv_node) <= sizeof(union m_option_value), "");
if (!(dst && src))
return;