From a9bd4535d2eac283824d8598aa17f1f44f83a74a Mon Sep 17 00:00:00 2001 From: wm4 Date: Fri, 15 Apr 2016 11:31:24 +0200 Subject: client API: improve mpv_set_property() handling of MPV_FORMAT_NODE If a mpv_node wrapped a string, the behavior was different from calling mpv_set_property() with MPV_FORMAT_STRING directly. Change this. The original intention was to be strict about types if MPV_FORMAT_NODE is used. But I think the result was less than ideal, and the same change towards less strict behavior was made to mpv_set_option() ages ago. --- options/m_option.c | 15 +++++++++++++++ options/m_option.h | 4 ++++ options/m_property.c | 17 +++++------------ 3 files changed, 24 insertions(+), 12 deletions(-) (limited to 'options') diff --git a/options/m_option.c b/options/m_option.c index 1d929269b0..1d8b1d0bf6 100644 --- a/options/m_option.c +++ b/options/m_option.c @@ -106,6 +106,21 @@ const m_option_t *m_option_list_find(const m_option_t *list, const char *name) return m_option_list_findb(list, bstr0(name)); } +int m_option_set_node_or_string(struct mp_log *log, const m_option_t *opt, + const char *name, void *dst, struct mpv_node *src) +{ + if (src->format == MPV_FORMAT_STRING) { + // The af and vf option unfortunately require this, because the + // option name includes the "action". + bstr optname = bstr0(name), a, b; + if (bstr_split_tok(optname, "/", &a, &b)) + optname = b; + return m_option_parse(log, opt, optname, bstr0(src->u.string), dst); + } else { + return m_option_set_node(opt, dst, src); + } +} + // Default function that just does a memcpy static void copy_opt(const m_option_t *opt, void *dst, const void *src) diff --git a/options/m_option.h b/options/m_option.h index 320a9e5b99..7e6550691a 100644 --- a/options/m_option.h +++ b/options/m_option.h @@ -504,6 +504,10 @@ static inline int m_option_set_node(const m_option_t *opt, void *dst, return M_OPT_UNKNOWN; } +// Call m_option_parse for strings, m_option_set_node otherwise. +int m_option_set_node_or_string(struct mp_log *log, const m_option_t *opt, + const char *name, void *dst, struct mpv_node *src); + // see m_option_type.get static inline int m_option_get_node(const m_option_t *opt, void *ta_parent, struct mpv_node *dst, void *src) diff --git a/options/m_property.c b/options/m_property.c index 951b788d4b..de2361b868 100644 --- a/options/m_property.c +++ b/options/m_property.c @@ -104,16 +104,8 @@ int m_property_do(struct mp_log *log, const struct m_property *prop_list, return str != NULL; } case M_PROPERTY_SET_STRING: { - if (!log) - return M_PROPERTY_ERROR; - bstr optname = bstr0(name), a, b; - if (bstr_split_tok(optname, "/", &a, &b)) - optname = b; - if (m_option_parse(log, &opt, optname, bstr0(arg), &val) < 0) - return M_PROPERTY_ERROR; - r = do_action(prop_list, name, M_PROPERTY_SET, &val, ctx); - m_option_free(&opt, &val); - return r; + struct mpv_node node = { .format = MPV_FORMAT_STRING, .u.string = arg }; + return do_action(prop_list, name, M_PROPERTY_SET_NODE, &node, ctx); } case M_PROPERTY_SWITCH: { if (!log) @@ -163,11 +155,12 @@ int m_property_do(struct mp_log *log, const struct m_property *prop_list, return r; } case M_PROPERTY_SET_NODE: { + if (!log) + return M_PROPERTY_ERROR; if ((r = do_action(prop_list, name, M_PROPERTY_SET_NODE, arg, ctx)) != M_PROPERTY_NOT_IMPLEMENTED) return r; - struct mpv_node *node = arg; - int err = m_option_set_node(&opt, &val, node); + int err = m_option_set_node_or_string(log, &opt, name, &val, arg); if (err == M_OPT_UNKNOWN) { r = M_PROPERTY_NOT_IMPLEMENTED; } else if (err < 0) { -- cgit v1.2.3