options: add -remove action to list options

Actually I wanted this for key/value lists only, but add it to the
others for consistency too. (For vf/af it barely makes even sense, but
anyway.)
This commit is contained in:
wm4 2019-12-18 06:31:39 +01:00
parent 8bdedf9062
commit 0a1588d39b
4 changed files with 60 additions and 12 deletions

View File

@ -725,6 +725,10 @@ Input Commands that are Possibly Subject to Change
``vf <operation> <value>``
Change video filter chain.
The semantics are exactly the same as with option parsing (see
`VIDEO FILTERS`_). As such the text below is a redundant and incomplete
summary.
The first argument decides what happens:
<set>

View File

@ -496,6 +496,7 @@ Suffix Meaning
-add Append 1 or more items (same syntax as -set)
-pre Prepend 1 or more items (same syntax as -set)
-clr Clear the option (remove all items)
-remove Delete item if present (does not interpret escapes)
-del Delete 1 or more items by integer index
-toggle Append an item, or remove if if it already exists (no escapes)
============= ===============================================
@ -518,6 +519,7 @@ Suffix Meaning
-set Set a list of items (using ``,`` as separator)
-append Append a single item (escapes for the key, no escapes for the value)
-add Append 1 or more items (same syntax as -set)
-remove Delete item by key if present (does not interpret escapes)
============= ===============================================
Keys are unique within the list. If an already present key is set, the existing
@ -538,6 +540,7 @@ Suffix Meaning
-add Append 1 or more filters (same syntax as -set)
-pre Prepend 1 or more filters (same syntax as -set)
-clr Clear the option (remove all filters)
-remove Delete filter if present
-del Delete 1 or more filters by integer index or filter label
-toggle Append a filter, or remove if if it already exists
-help Pseudo operation that prints a help text to the terminal

View File

@ -96,12 +96,24 @@ filter list.
Prepends the filters given as arguments to the filter list. (Passing
multiple filters is currently still possible, but deprecated.)
``--vf-remove=filter``
Deletes the filter from the list. The filter can be either given the way it
was added (filter name and its full argument list), or by label (prefixed
with ``@``). Matching of filters works as follows: if either of the compared
filters has a label set, only the labels are compared. If none of the
filters have a label, the filter name, arguments, and argument order are
compared.
``-vf-toggle=filter``
Add the given filter to the list if it was not present yet, or remove it
from the list if it was present. Matching of filters works as described in
``--vf-remove``.
``--vf-del=filter``
Deletes the filter. The filter can even given the way it was added (filter
name and its full argument list), by label (prefixed with ``@``), or as
index number. Index numbers start at 0, negative numbers address the end of
the list (-1 is the last). (Passing multiple filters is currently still
possible, but deprecated.)
Sort of like ``--vf-remove``, but also accepts an index number. Index
numbers start at 0, negative numbers address the end of the list (-1 is the
last). (Passing multiple filters is currently still possible, but
deprecated.)
``--vf-clr``
Completely empties the filter list.

View File

@ -1265,6 +1265,7 @@ const m_option_type_t m_option_type_string = {
#define OP_CLR 4
#define OP_TOGGLE 5
#define OP_APPEND 6
#define OP_REMOVE 7
static void free_str_list(void *dst)
{
@ -1408,6 +1409,12 @@ static int parse_str_list_impl(struct mp_log *log, const m_option_t *opt,
} else if (bstr_endswith0(name, "-set")) {
op = OP_NONE;
} else if (bstr_endswith0(name, "-toggle")) {
op = OP_TOGGLE;
} else if (bstr_endswith0(name, "-remove")) {
op = OP_REMOVE;
}
if (op == OP_TOGGLE || op == OP_REMOVE) {
if (dst) {
char **list = VAL(dst);
int index = find_list_bstr(list, param);
@ -1419,6 +1426,8 @@ static int parse_str_list_impl(struct mp_log *log, const m_option_t *opt,
return 1;
}
}
if (op == OP_REMOVE)
return 1; // ignore if not found
op = OP_ADD;
multi = false;
}
@ -1614,6 +1623,7 @@ const m_option_type_t m_option_type_string_list = {
{"pre"},
{"set"},
{"toggle"},
{"remove"},
{0}
},
};
@ -1659,6 +1669,14 @@ static int parse_keyvalue_list(struct mp_log *log, const m_option_t *opt,
append = true;
} else if (bstr_endswith0(name, "-append")) {
append = full_value = true;
} else if (bstr_endswith0(name, "-remove")) {
lst = dst ? VAL(dst) : NULL;
int index = dst ? keyvalue_list_find_key(lst, param) : -1;
if (index >= 0) {
keyvalue_list_del_key(lst, index);
VAL(dst) = lst;
}
return 1;
}
if (append && dst) {
@ -1790,6 +1808,7 @@ const m_option_type_t m_option_type_keyvalue_list = {
{"add"},
{"append"},
{"set"},
{"remove"},
{0}
},
};
@ -3202,7 +3221,8 @@ done: ;
// Parse a single entry for -vf-del (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, void *dst, bool *mark_del)
struct bstr *param, int op,
void *dst, bool *mark_del)
{
bstr s = *param;
if (bstr_eatstart0(&s, "@")) {
@ -3226,6 +3246,9 @@ static int parse_obj_settings_del(struct mp_log *log, struct bstr opt_name,
return 1;
}
if (op == OP_REMOVE)
return 0;
bstr rest;
long long id = bstrtoll(s, &rest, 0);
if (rest.len == s.len)
@ -3269,6 +3292,8 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
op = OP_PRE;
} else if (bstr_endswith0(name, "-del")) {
op = OP_DEL;
} else if (bstr_endswith0(name, "-remove")) {
op = OP_REMOVE;
} else if (bstr_endswith0(name, "-clr")) {
op = OP_CLR;
} else if (bstr_endswith0(name, "-toggle")) {
@ -3284,6 +3309,8 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
" 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"
@ -3293,7 +3320,7 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
" %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;
}
@ -3328,7 +3355,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) {
} else if (op == OP_DEL || op == OP_REMOVE) {
mark_del = talloc_zero_array(NULL, bool, num_items + 1);
}
@ -3337,8 +3364,8 @@ 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)
r = parse_obj_settings_del(log, name, &param, dst, mark_del);
if (op == OP_DEL || op == OP_REMOVE)
r = parse_obj_settings_del(log, name, &param, op, dst, mark_del);
if (r == 0) {
r = parse_obj_settings(log, name, op, &param, ol, dst ? &res : NULL);
}
@ -3425,7 +3452,7 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
}
}
talloc_free(res);
} else if (op == OP_DEL) {
} else if (op == OP_DEL || op == OP_REMOVE) {
for (int n = num_items - 1; n >= 0; n--) {
if (mark_del[n])
obj_settings_list_del_at(&list, n);
@ -3433,7 +3460,8 @@ static int parse_obj_settings_list(struct mp_log *log, const m_option_t *opt,
for (int n = 0; res && res[n].name; n++) {
int found = obj_settings_find_by_content(list, &res[n]);
if (found < 0) {
mp_warn(log, "Option %.*s: Item not found\n", BSTR_P(name));
if (op == OP_DEL)
mp_warn(log, "Option %.*s: Item not found\n", BSTR_P(name));
} else {
obj_settings_list_del_at(&list, found);
}
@ -3635,6 +3663,7 @@ const m_option_type_t m_option_type_obj_settings_list = {
{"pre"},
{"set"},
{"toggle"},
{"remove"},
{0}
},
};