diff options
author | wm4 <wm4@nowhere> | 2015-01-12 04:54:34 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2015-01-12 04:57:56 +0100 |
commit | 3f3e1547ba6db29d626c0008f2e52bfd971327be (patch) | |
tree | 082a663dc8af62b8da7dfbd2e50ef12600db5387 /common/tags.c | |
parent | f3a978cd17157ef98528945d89209b43ae41099e (diff) | |
download | mpv-3f3e1547ba6db29d626c0008f2e52bfd971327be.tar.bz2 mpv-3f3e1547ba6db29d626c0008f2e52bfd971327be.tar.xz |
player: change --display-tags behavior
Remove the "all" special-behavior, and instead interpret trailing "*"
characters. --display-tags=all is replaced by --display-tags=* as a
special-case of the new behavior.
See #1404.
Note that the most straight-forward value for matchlen in the normal
case would be INT_MAX, because it should be using the entire string.
I used keylen+1 instead, because glibc seems to handle this case
incorrectly:
snprintf(buf, sizeof(buf), "%.*s", INT_MAX, "hello");
The result is empty, instead of just containing the string argument.
This might be a glibc bug; it works with other libcs (even MinGW-w64).
Diffstat (limited to 'common/tags.c')
-rw-r--r-- | common/tags.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/common/tags.c b/common/tags.c index c38d002243..04dabd8cdf 100644 --- a/common/tags.c +++ b/common/tags.c @@ -15,6 +15,9 @@ * with mpv. If not, see <http://www.gnu.org/licenses/>. */ +#include <stddef.h> +#include <limits.h> +#include <strings.h> #include <libavutil/dict.h> #include "tags.h" #include "misc/bstr.h" @@ -76,19 +79,25 @@ struct mp_tags *mp_tags_dup(void *tparent, struct mp_tags *tags) // Return a copy of the tags, but containing only keys in list. Also forces // the order and casing of the keys (for cosmetic reasons). -// The special key "all" matches all keys. +// A trailing '*' matches the rest. struct mp_tags *mp_tags_filtered(void *tparent, struct mp_tags *tags, char **list) { struct mp_tags *new = talloc_zero(tparent, struct mp_tags); for (int n = 0; list && list[n]; n++) { char *key = list[n]; - if (strcasecmp(key, "all") == 0) { - talloc_free(new); - return mp_tags_dup(tparent, tags); + size_t keylen = strlen(key); + if (keylen >= INT_MAX) + continue; + bool prefix = keylen && key[keylen - 1] == '*'; + int matchlen = prefix ? keylen - 1 : keylen + 1; + for (int x = 0; x < tags->num_keys; x++) { + if (strncasecmp(tags->keys[x], key, matchlen) == 0) { + char skey[320]; + snprintf(skey, sizeof(skey), "%.*s%s", matchlen, key, + prefix ? tags->keys[x] + keylen - 1 : ""); + mp_tags_set_str(new, skey, tags->values[x]); + } } - char *value = mp_tags_get_str(tags, key); - if (value) - mp_tags_set_str(new, key, value); } return new; } |