summaryrefslogtreecommitdiffstats
path: root/core/m_option.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2013-02-16 23:24:10 +0100
committerwm4 <wm4@nowhere>2013-02-20 23:45:56 +0100
commit0bad744d68a0ac066c5e648c8fd1673d1459478f (patch)
tree2470d210837710b7a77efe766f2bc13ded62d0c1 /core/m_option.c
parent68daee220c305220bfeb8f4f473b981b2d34af70 (diff)
downloadmpv-0bad744d68a0ac066c5e648c8fd1673d1459478f.tar.bz2
mpv-0bad744d68a0ac066c5e648c8fd1673d1459478f.tar.xz
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).
Diffstat (limited to 'core/m_option.c')
-rw-r--r--core/m_option.c69
1 files changed, 62 insertions, 7 deletions
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 <libavutil/avstring.h>
#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)