From 0a1588d39b2c30421909c87e60b1510ffd338497 Mon Sep 17 00:00:00 2001 From: wm4 Date: Wed, 18 Dec 2019 06:31:39 +0100 Subject: 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.) --- DOCS/man/input.rst | 4 ++++ DOCS/man/mpv.rst | 3 +++ DOCS/man/vf.rst | 22 +++++++++++++++++----- options/m_option.c | 43 ++++++++++++++++++++++++++++++++++++------- 4 files changed, 60 insertions(+), 12 deletions(-) diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst index 08edf618b1..8f8a5681cc 100644 --- a/DOCS/man/input.rst +++ b/DOCS/man/input.rst @@ -725,6 +725,10 @@ Input Commands that are Possibly Subject to Change ``vf `` 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: diff --git a/DOCS/man/mpv.rst b/DOCS/man/mpv.rst index 9ff62ae4f0..a96dd1149e 100644 --- a/DOCS/man/mpv.rst +++ b/DOCS/man/mpv.rst @@ -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 diff --git a/DOCS/man/vf.rst b/DOCS/man/vf.rst index a9288d7a93..7f0b0f9bc9 100644 --- a/DOCS/man/vf.rst +++ b/DOCS/man/vf.rst @@ -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. diff --git a/options/m_option.c b/options/m_option.c index 2ebe79cff3..c472b94d6f 100644 --- a/options/m_option.c +++ b/options/m_option.c @@ -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, ¶m, dst, mark_del); + if (op == OP_DEL || op == OP_REMOVE) + r = parse_obj_settings_del(log, name, ¶m, op, dst, mark_del); if (r == 0) { r = parse_obj_settings(log, name, op, ¶m, 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} }, }; -- cgit v1.2.3