From 0bad744d68a0ac066c5e648c8fd1673d1459478f Mon Sep 17 00:00:00 2001 From: wm4 Date: Sat, 16 Feb 2013 23:24:10 +0100 Subject: options: parse C-style escapes for some options Being able to insert newline characters ("\n") is useful for --osd-status-msg, and possibly also for anything that prints to the terminal. Espcially --term-osd-esc looks relatively useless without being able to specify escapes. Maybe parsing escapes should happen during command line / config parsing instead (for all options). --- DOCS/man/en/options.rst | 13 +++++++--- core/cfg-mplayer.h | 9 ++++--- core/m_option.c | 69 ++++++++++++++++++++++++++++++++++++++++++++----- core/m_option.h | 3 +++ 4 files changed, 79 insertions(+), 15 deletions(-) diff --git a/DOCS/man/en/options.rst b/DOCS/man/en/options.rst index b1d630f68e..14548f807c 100644 --- a/DOCS/man/en/options.rst +++ b/DOCS/man/en/options.rst @@ -1437,7 +1437,7 @@ --playing-msg= Print out a string before starting playback. The string is expanded for - properties, e.g. ``--playing-msg=file: \${filename}`` will print the string + properties, e.g. ``--playing-msg=file: ${filename}`` will print the string ``file:`` followed by a space and the currently played filename. The following expansions are supported: @@ -1445,7 +1445,7 @@ \${NAME} Expands to the value of the property ``NAME``. If ``NAME`` starts with ``=``, use the raw value of the property. If retrieving the property - fails, expand to an error string. (Use ``\${NAME:}`` with a trailing + fails, expand to an error string. (Use ``${NAME:}`` with a trailing ``:`` to expand to an empty string instead.) \${NAME:STR} Expands to the value of the property ``NAME``, or ``STR`` if the @@ -1456,14 +1456,19 @@ \${?NAME:STR} Expands to ``STR`` (recursively) if the property ``NAME`` is available. \$\$ - Expands to ``\$``. + Expands to ``$``. \$} Expands to ``}``. (To produce this character inside recursive expansion.) \$> - Disable property expansion and special handling of ``\$`` for the rest + Disable property expansion and special handling of ``$`` for the rest of the string. + This option also parses C-style escapes. Example: + + - ``\n`` becomes a newline character + - ``\\`` expands to ``\`` + --status-msg= Print out a custom string during playback instead of the standard status line. Expands properties. See ``--playing-msg``. diff --git a/core/cfg-mplayer.h b/core/cfg-mplayer.h index a0b3f95f42..621d026d0d 100644 --- a/core/cfg-mplayer.h +++ b/core/cfg-mplayer.h @@ -675,10 +675,11 @@ const m_option_t mplayer_opts[]={ {"auto", 2}, {"no", 0})), - OPT_STRING("term-osd-esc", term_osd_esc, 0, OPTDEF_STR("\x1b[A\r\x1b[K")), - OPT_STRING("playing-msg", playing_msg, 0), - OPT_STRING("status-msg", status_msg, 0), - OPT_STRING("osd-status-msg", osd_status_msg, 0), + OPT_STRING("term-osd-esc", term_osd_esc, M_OPT_PARSE_ESCAPES, + OPTDEF_STR("\x1b[A\r\x1b[K")), + OPT_STRING("playing-msg", playing_msg, M_OPT_PARSE_ESCAPES), + OPT_STRING("status-msg", status_msg, M_OPT_PARSE_ESCAPES), + OPT_STRING("osd-status-msg", osd_status_msg, M_OPT_PARSE_ESCAPES), {"slave-broken", &slave_mode, CONF_TYPE_FLAG,CONF_GLOBAL , 0, 1, NULL}, OPT_FLAG("idle", player_idle_mode, CONF_GLOBAL), diff --git a/core/m_option.c b/core/m_option.c index 595675cebb..7d6f9a53b7 100644 --- a/core/m_option.c +++ b/core/m_option.c @@ -35,6 +35,7 @@ #include #include "talloc.h" +#include "core/mp_common.h" #include "core/m_option.h" #include "core/mp_msg.h" #include "stream/url.h" @@ -674,6 +675,39 @@ const m_option_type_t m_option_type_float = { #undef VAL #define VAL(x) (*(char **)(x)) +static char *unescape_string(void *talloc_ctx, bstr str) +{ + char *res = talloc_strdup(talloc_ctx, ""); + while (str.len) { + bstr rest; + bool esc = bstr_split_tok(str, "\\", &str, &rest); + res = talloc_strndup_append_buffer(res, str.start, str.len); + if (esc) { + if (!mp_parse_escape(&rest, &res)) { + talloc_free(res); + return NULL; + } + } + str = rest; + } + return res; +} + +static char *escape_string(char *str0) +{ + char *res = talloc_strdup(NULL, ""); + bstr str = bstr0(str0); + while (str.len) { + bstr rest; + bool esc = bstr_split_tok(str, "\\", &str, &rest); + res = talloc_strndup_append_buffer(res, str.start, str.len); + if (esc) + res = talloc_strdup_append_buffer(res, "\\\\"); + str = rest; + } + return res; +} + static int clamp_str(const m_option_t *opt, void *val) { char *v = VAL(val); @@ -688,21 +722,39 @@ static int clamp_str(const m_option_t *opt, void *val) static int parse_str(const m_option_t *opt, struct bstr name, struct bstr param, void *dst) { - if (param.start == NULL) - return M_OPT_MISSING_PARAM; + int r = 1; + void *tmp = talloc_new(NULL); + + if (param.start == NULL) { + r = M_OPT_MISSING_PARAM; + goto exit; + } + + if (opt->flags & M_OPT_PARSE_ESCAPES) { + char *res = unescape_string(tmp, param); + if (!res) { + mp_msg(MSGT_CFGPARSER, MSGL_ERR, + "Parameter has broken escapes: %.*s\n", BSTR_P(param)); + r = M_OPT_INVALID; + goto exit; + } + param = bstr0(res); + } if ((opt->flags & M_OPT_MIN) && (param.len < opt->min)) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Parameter must be >= %d chars: %.*s\n", (int) opt->min, BSTR_P(param)); - return M_OPT_OUT_OF_RANGE; + r = M_OPT_OUT_OF_RANGE; + goto exit; } if ((opt->flags & M_OPT_MAX) && (param.len > opt->max)) { mp_msg(MSGT_CFGPARSER, MSGL_ERR, "Parameter must be <= %d chars: %.*s\n", (int) opt->max, BSTR_P(param)); - return M_OPT_OUT_OF_RANGE; + r = M_OPT_OUT_OF_RANGE; + goto exit; } if (dst) { @@ -710,13 +762,16 @@ static int parse_str(const m_option_t *opt, struct bstr name, VAL(dst) = bstrdup0(NULL, param); } - return 1; - +exit: + talloc_free(tmp); + return r; } static char *print_str(const m_option_t *opt, const void *val) { - return (val && VAL(val)) ? talloc_strdup(NULL, VAL(val)) : NULL; + bool need_escape = opt->flags & M_OPT_PARSE_ESCAPES; + char *s = val ? VAL(val) : NULL; + return s ? (need_escape ? escape_string(s) : talloc_strdup(NULL, s)) : NULL; } static void copy_str(const m_option_t *opt, void *dst, const void *src) diff --git a/core/m_option.h b/core/m_option.h index 9ae8797a44..bbf1efaec7 100644 --- a/core/m_option.h +++ b/core/m_option.h @@ -366,6 +366,9 @@ struct m_option { // See M_OPT_TYPE_OPTIONAL_PARAM. #define M_OPT_OPTIONAL_PARAM (1 << 10) +// Parse C-style escapes like "\n" (for CONF_TYPE_STRING only) +#define M_OPT_PARSE_ESCAPES (1 << 11) + // These are kept for compatibility with older code. #define CONF_MIN M_OPT_MIN #define CONF_MAX M_OPT_MAX -- cgit v1.2.3