mirror of https://github.com/mpv-player/mpv
m_option: move code around
Move the helper functions for parsing -vf, and rename some.
This commit is contained in:
parent
3d87ca6b5e
commit
f9f40a417f
285
core/m_option.c
285
core/m_option.c
|
@ -1786,6 +1786,141 @@ static int find_obj_desc(struct bstr name, const m_obj_list_t *l,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void obj_setting_free(m_obj_settings_t *item)
|
||||
{
|
||||
talloc_free(item->name);
|
||||
talloc_free(item->label);
|
||||
free_str_list(&(item->attribs));
|
||||
}
|
||||
|
||||
// If at least one item has a label, compare labels only - otherwise ignore them.
|
||||
static bool obj_setting_equals(m_obj_settings_t *a, m_obj_settings_t *b)
|
||||
{
|
||||
bstr la = bstr0(a->label), lb = bstr0(b->label);
|
||||
if (la.len || lb.len)
|
||||
return bstr_equals(la, lb);
|
||||
if (strcmp(a->name, b->name) != 0)
|
||||
return false;
|
||||
|
||||
int a_attr_count = 0;
|
||||
while (a->attribs && a->attribs[a_attr_count])
|
||||
a_attr_count++;
|
||||
int b_attr_count = 0;
|
||||
while (b->attribs && b->attribs[b_attr_count])
|
||||
b_attr_count++;
|
||||
if (a_attr_count != b_attr_count)
|
||||
return false;
|
||||
for (int n = 0; n < a_attr_count; n++) {
|
||||
if (strcmp(a->attribs[n], b->attribs[n]) != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int obj_settings_list_num_items(m_obj_settings_t *obj_list)
|
||||
{
|
||||
int num = 0;
|
||||
while (obj_list && obj_list[num].name)
|
||||
num++;
|
||||
return num;
|
||||
}
|
||||
|
||||
static void obj_settings_list_del_at(m_obj_settings_t **p_obj_list, int idx)
|
||||
{
|
||||
m_obj_settings_t *obj_list = *p_obj_list;
|
||||
int num = obj_settings_list_num_items(obj_list);
|
||||
|
||||
assert(idx >= 0 && idx < num);
|
||||
|
||||
obj_setting_free(&obj_list[idx]);
|
||||
|
||||
// Note: the NULL-terminating element is moved down as part of this
|
||||
memmove(&obj_list[idx], &obj_list[idx + 1],
|
||||
sizeof(m_obj_settings_t) * (num - idx));
|
||||
|
||||
*p_obj_list = talloc_realloc(NULL, obj_list, struct m_obj_settings, num);
|
||||
}
|
||||
|
||||
// Insert such that *p_obj_list[idx] is set to item.
|
||||
// If idx < 0, set idx = count + idx + 1 (i.e. -1 inserts it as last element).
|
||||
// Memory referenced by *item is not copied.
|
||||
static void obj_settings_list_insert_at(m_obj_settings_t **p_obj_list, int idx,
|
||||
m_obj_settings_t *item)
|
||||
{
|
||||
int num = obj_settings_list_num_items(*p_obj_list);
|
||||
if (idx < 0)
|
||||
idx = num + idx + 1;
|
||||
assert(idx >= 0 && idx <= num);
|
||||
*p_obj_list = talloc_realloc(NULL, *p_obj_list, struct m_obj_settings,
|
||||
num + 2);
|
||||
memmove(*p_obj_list + idx + 1, *p_obj_list + idx,
|
||||
(num - idx) * sizeof(m_obj_settings_t));
|
||||
(*p_obj_list)[idx] = *item;
|
||||
(*p_obj_list)[num + 1] = (m_obj_settings_t){0};
|
||||
}
|
||||
|
||||
static int obj_settings_list_find_by_label(m_obj_settings_t *obj_list,
|
||||
bstr label)
|
||||
{
|
||||
for (int n = 0; obj_list && obj_list[n].name; n++) {
|
||||
if (label.len && bstr_equals0(label, obj_list[n].label))
|
||||
return n;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int obj_settings_list_find_by_label0(m_obj_settings_t *obj_list,
|
||||
const char *label)
|
||||
{
|
||||
return obj_settings_list_find_by_label(obj_list, bstr0(label));
|
||||
}
|
||||
|
||||
static void free_obj_settings_list(void *dst)
|
||||
{
|
||||
int n;
|
||||
m_obj_settings_t *d;
|
||||
|
||||
if (!dst || !VAL(dst))
|
||||
return;
|
||||
|
||||
d = VAL(dst);
|
||||
for (n = 0; d[n].name; n++)
|
||||
obj_setting_free(&d[n]);
|
||||
talloc_free(d);
|
||||
VAL(dst) = NULL;
|
||||
}
|
||||
|
||||
static void copy_obj_settings_list(const m_option_t *opt, void *dst,
|
||||
const void *src)
|
||||
{
|
||||
m_obj_settings_t *d, *s;
|
||||
int n;
|
||||
|
||||
if (!(dst && src))
|
||||
return;
|
||||
|
||||
s = VAL(src);
|
||||
|
||||
if (VAL(dst))
|
||||
free_obj_settings_list(dst);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
for (n = 0; s[n].name; n++)
|
||||
/* NOP */;
|
||||
d = talloc_array(NULL, struct m_obj_settings, n + 1);
|
||||
for (n = 0; s[n].name; n++) {
|
||||
d[n].name = talloc_strdup(NULL, s[n].name);
|
||||
d[n].label = talloc_strdup(NULL, s[n].label);
|
||||
d[n].attribs = NULL;
|
||||
copy_str_list(NULL, &(d[n].attribs), &(s[n].attribs));
|
||||
}
|
||||
d[n].name = NULL;
|
||||
d[n].label = NULL;
|
||||
d[n].attribs = NULL;
|
||||
VAL(dst) = d;
|
||||
}
|
||||
|
||||
// Consider -vf a=b=c:d=e. This verifies "b"="c" and "d"="e" and that the
|
||||
// option names/values are correct. Try to determine whether an option
|
||||
// without '=' sets a flag, or whether it's a positional argument.
|
||||
|
@ -1998,88 +2133,6 @@ static int parse_obj_settings(struct bstr opt, struct bstr *pstr,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int obj_settings_list_num_items(m_obj_settings_t *obj_list)
|
||||
{
|
||||
int num = 0;
|
||||
while (obj_list && obj_list[num].name)
|
||||
num++;
|
||||
return num;
|
||||
}
|
||||
|
||||
static void obj_settings_free_item(m_obj_settings_t *item)
|
||||
{
|
||||
talloc_free(item->name);
|
||||
talloc_free(item->label);
|
||||
free_str_list(&(item->attribs));
|
||||
}
|
||||
|
||||
static void del_obj_settings_list_at(m_obj_settings_t **p_obj_list, int idx)
|
||||
{
|
||||
m_obj_settings_t *obj_list = *p_obj_list;
|
||||
int num = obj_settings_list_num_items(obj_list);
|
||||
|
||||
assert(idx >= 0 && idx < num);
|
||||
|
||||
obj_settings_free_item(&obj_list[idx]);
|
||||
|
||||
// Note: the NULL-terminating element is moved down as part of this
|
||||
memmove(&obj_list[idx], &obj_list[idx + 1],
|
||||
sizeof(m_obj_settings_t) * (num - idx));
|
||||
|
||||
*p_obj_list = talloc_realloc(NULL, obj_list, struct m_obj_settings, num);
|
||||
}
|
||||
|
||||
// Insert such that *p_obj_list[idx] is set to item.
|
||||
// If idx < 0, set idx = count + idx + 1 (i.e. -1 inserts it as last element).
|
||||
// Memory referenced by *item is not copied.
|
||||
static void insert_obj_settings_list_at(m_obj_settings_t **p_obj_list, int idx,
|
||||
m_obj_settings_t *item)
|
||||
{
|
||||
int num = obj_settings_list_num_items(*p_obj_list);
|
||||
if (idx < 0)
|
||||
idx = num + idx + 1;
|
||||
assert(idx >= 0 && idx <= num);
|
||||
*p_obj_list = talloc_realloc(NULL, *p_obj_list, struct m_obj_settings,
|
||||
num + 2);
|
||||
memmove(*p_obj_list + idx + 1, *p_obj_list + idx,
|
||||
(num - idx) * sizeof(m_obj_settings_t));
|
||||
(*p_obj_list)[idx] = *item;
|
||||
(*p_obj_list)[num + 1] = (m_obj_settings_t){0};
|
||||
}
|
||||
|
||||
// If at least one item has a label, compare labels only - otherwise ignore them.
|
||||
static bool obj_setting_equals(m_obj_settings_t *a, m_obj_settings_t *b)
|
||||
{
|
||||
bstr la = bstr0(a->label), lb = bstr0(b->label);
|
||||
if (la.len || lb.len)
|
||||
return bstr_equals(la, lb);
|
||||
if (strcmp(a->name, b->name) != 0)
|
||||
return false;
|
||||
|
||||
int a_attr_count = 0;
|
||||
while (a->attribs && a->attribs[a_attr_count])
|
||||
a_attr_count++;
|
||||
int b_attr_count = 0;
|
||||
while (b->attribs && b->attribs[b_attr_count])
|
||||
b_attr_count++;
|
||||
if (a_attr_count != b_attr_count)
|
||||
return false;
|
||||
for (int n = 0; n < a_attr_count; n++) {
|
||||
if (strcmp(a->attribs[n], b->attribs[n]) != 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int obj_settings_find_by_label(m_obj_settings_t *obj_list, bstr label)
|
||||
{
|
||||
for (int n = 0; obj_list && obj_list[n].name; n++) {
|
||||
if (label.len && bstr_equals0(label, obj_list[n].label))
|
||||
return n;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int obj_settings_list_del(struct bstr opt_name, struct bstr param,
|
||||
void *dst)
|
||||
{
|
||||
|
@ -2101,7 +2154,7 @@ static int obj_settings_list_del(struct bstr opt_name, struct bstr param,
|
|||
bstr_split_tok(param, ",", &item, ¶m);
|
||||
|
||||
if (bstr_eatstart0(&item, "@")) {
|
||||
int label_index = obj_settings_find_by_label(obj_list, item);
|
||||
int label_index = obj_settings_list_find_by_label(obj_list, item);
|
||||
if (label_index >= 0) {
|
||||
mark_del[label_index] = true;
|
||||
goto found;
|
||||
|
@ -2147,7 +2200,7 @@ static int obj_settings_list_del(struct bstr opt_name, struct bstr param,
|
|||
if (dst) {
|
||||
for (int n = idx_max - 1; n >= 0; n--) {
|
||||
if (mark_del[n])
|
||||
del_obj_settings_list_at(&obj_list, n);
|
||||
obj_settings_list_del_at(&obj_list, n);
|
||||
}
|
||||
VAL(dst) = obj_list;
|
||||
}
|
||||
|
@ -2156,21 +2209,6 @@ static int obj_settings_list_del(struct bstr opt_name, struct bstr param,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void free_obj_settings_list(void *dst)
|
||||
{
|
||||
int n;
|
||||
m_obj_settings_t *d;
|
||||
|
||||
if (!dst || !VAL(dst))
|
||||
return;
|
||||
|
||||
d = VAL(dst);
|
||||
for (n = 0; d[n].name; n++)
|
||||
obj_settings_free_item(&d[n]);
|
||||
talloc_free(d);
|
||||
VAL(dst) = NULL;
|
||||
}
|
||||
|
||||
static int parse_obj_settings_list(const m_option_t *opt, struct bstr name,
|
||||
struct bstr param, void *dst)
|
||||
{
|
||||
|
@ -2258,27 +2296,27 @@ static int parse_obj_settings_list(const m_option_t *opt, struct bstr name,
|
|||
if (op == OP_PRE) {
|
||||
int prepend_counter = 0;
|
||||
for (int n = 0; res && res[n].name; n++) {
|
||||
int label = obj_settings_find_by_label(list, bstr0(res[n].label));
|
||||
int label = obj_settings_list_find_by_label0(list, res[n].label);
|
||||
if (label < 0) {
|
||||
insert_obj_settings_list_at(&list, prepend_counter, &res[n]);
|
||||
obj_settings_list_insert_at(&list, prepend_counter, &res[n]);
|
||||
prepend_counter++;
|
||||
} else {
|
||||
// Prefer replacement semantics, instead of actually
|
||||
// prepending.
|
||||
obj_settings_free_item(&list[label]);
|
||||
obj_setting_free(&list[label]);
|
||||
list[label] = res[n];
|
||||
}
|
||||
}
|
||||
talloc_free(res);
|
||||
} else if (op == OP_ADD) {
|
||||
for (int n = 0; res && res[n].name; n++) {
|
||||
int label = obj_settings_find_by_label(list, bstr0(res[n].label));
|
||||
int label = obj_settings_list_find_by_label0(list, res[n].label);
|
||||
if (label < 0) {
|
||||
insert_obj_settings_list_at(&list, -1, &res[n]);
|
||||
obj_settings_list_insert_at(&list, -1, &res[n]);
|
||||
} else {
|
||||
// Prefer replacement semantics, instead of actually
|
||||
// appending.
|
||||
obj_settings_free_item(&list[label]);
|
||||
obj_setting_free(&list[label]);
|
||||
list[label] = res[n];
|
||||
}
|
||||
}
|
||||
|
@ -2293,10 +2331,10 @@ static int parse_obj_settings_list(const m_option_t *opt, struct bstr name,
|
|||
}
|
||||
}
|
||||
if (found < 0) {
|
||||
insert_obj_settings_list_at(&list, -1, &res[n]);
|
||||
obj_settings_list_insert_at(&list, -1, &res[n]);
|
||||
} else {
|
||||
del_obj_settings_list_at(&list, found);
|
||||
obj_settings_free_item(&res[n]);
|
||||
obj_settings_list_del_at(&list, found);
|
||||
obj_setting_free(&res[n]);
|
||||
}
|
||||
}
|
||||
talloc_free(res);
|
||||
|
@ -2310,37 +2348,6 @@ static int parse_obj_settings_list(const m_option_t *opt, struct bstr name,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static void copy_obj_settings_list(const m_option_t *opt, void *dst,
|
||||
const void *src)
|
||||
{
|
||||
m_obj_settings_t *d, *s;
|
||||
int n;
|
||||
|
||||
if (!(dst && src))
|
||||
return;
|
||||
|
||||
s = VAL(src);
|
||||
|
||||
if (VAL(dst))
|
||||
free_obj_settings_list(dst);
|
||||
if (!s)
|
||||
return;
|
||||
|
||||
for (n = 0; s[n].name; n++)
|
||||
/* NOP */;
|
||||
d = talloc_array(NULL, struct m_obj_settings, n + 1);
|
||||
for (n = 0; s[n].name; n++) {
|
||||
d[n].name = talloc_strdup(NULL, s[n].name);
|
||||
d[n].label = talloc_strdup(NULL, s[n].label);
|
||||
d[n].attribs = NULL;
|
||||
copy_str_list(NULL, &(d[n].attribs), &(s[n].attribs));
|
||||
}
|
||||
d[n].name = NULL;
|
||||
d[n].label = NULL;
|
||||
d[n].attribs = NULL;
|
||||
VAL(dst) = d;
|
||||
}
|
||||
|
||||
const m_option_type_t m_option_type_obj_settings_list = {
|
||||
.name = "Object settings list",
|
||||
.size = sizeof(m_obj_settings_t *),
|
||||
|
|
Loading…
Reference in New Issue