mirror of
https://github.com/mpv-player/mpv.git
synced 2024-09-20 03:52:22 +02:00
options: handle escape sequences in e.g. --playing-msg differently
M_OPT_PARSE_ESCAPES was pretty stupid, and broke the (useful) assumption that string variables contain exactly the same value as set by the option. Simplify it, and move escape handling to the place where it's used. Escape handling itself is not terribly useful, but still allows useful things like multiline custom OSD with "\n".
This commit is contained in:
parent
857952dce3
commit
98dc8206ae
@ -745,36 +745,6 @@ 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)
|
||||
{
|
||||
bstr dst = {0};
|
||||
while (str.len) {
|
||||
if (!mp_append_escaped_string(talloc_ctx, &dst, &str)) {
|
||||
talloc_free(dst.start);
|
||||
return NULL;
|
||||
}
|
||||
if (!bstr_eatstart0(&str, "\""))
|
||||
break;
|
||||
bstr_xappend(talloc_ctx, &dst, bstr0("\""));
|
||||
}
|
||||
return dst.start;
|
||||
}
|
||||
|
||||
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);
|
||||
@ -789,43 +759,26 @@ static int clamp_str(const m_option_t *opt, void *val)
|
||||
static int parse_str(struct mp_log *log, const m_option_t *opt,
|
||||
struct bstr name, struct bstr param, void *dst)
|
||||
{
|
||||
int r = 1;
|
||||
void *tmp = talloc_new(NULL);
|
||||
|
||||
if (param.start == NULL) {
|
||||
r = M_OPT_MISSING_PARAM;
|
||||
goto exit;
|
||||
}
|
||||
if (param.start == NULL)
|
||||
return M_OPT_MISSING_PARAM;
|
||||
|
||||
m_opt_string_validate_fn validate = opt->priv;
|
||||
if (validate) {
|
||||
r = validate(log, opt, name, param);
|
||||
int r = validate(log, opt, name, param);
|
||||
if (r < 0)
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (opt->flags & M_OPT_PARSE_ESCAPES) {
|
||||
char *res = unescape_string(tmp, param);
|
||||
if (!res) {
|
||||
mp_err(log, "Parameter has broken escapes: %.*s\n", BSTR_P(param));
|
||||
r = M_OPT_INVALID;
|
||||
goto exit;
|
||||
}
|
||||
param = bstr0(res);
|
||||
return r;
|
||||
}
|
||||
|
||||
if ((opt->flags & M_OPT_MIN) && (param.len < opt->min)) {
|
||||
mp_err(log, "Parameter must be >= %d chars: %.*s\n",
|
||||
(int) opt->min, BSTR_P(param));
|
||||
r = M_OPT_OUT_OF_RANGE;
|
||||
goto exit;
|
||||
return M_OPT_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
if ((opt->flags & M_OPT_MAX) && (param.len > opt->max)) {
|
||||
mp_err(log, "Parameter must be <= %d chars: %.*s\n",
|
||||
(int) opt->max, BSTR_P(param));
|
||||
r = M_OPT_OUT_OF_RANGE;
|
||||
goto exit;
|
||||
return M_OPT_OUT_OF_RANGE;
|
||||
}
|
||||
|
||||
if (dst) {
|
||||
@ -833,16 +786,12 @@ static int parse_str(struct mp_log *log, const m_option_t *opt,
|
||||
VAL(dst) = bstrdup0(NULL, param);
|
||||
}
|
||||
|
||||
exit:
|
||||
talloc_free(tmp);
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *print_str(const m_option_t *opt, const void *val)
|
||||
{
|
||||
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;
|
||||
return talloc_strdup(NULL, val ? VAL(val) : NULL);
|
||||
}
|
||||
|
||||
static void copy_str(const m_option_t *opt, void *dst, const void *src)
|
||||
|
@ -338,9 +338,6 @@ 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
|
||||
|
@ -602,9 +602,9 @@ const m_option_t mp_opts[] = {
|
||||
OPT_FLAG("term-osd-bar", term_osd_bar, 0),
|
||||
OPT_STRING("term-osd-bar-chars", term_osd_bar_chars, 0),
|
||||
|
||||
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),
|
||||
OPT_STRING("playing-msg", playing_msg, 0),
|
||||
OPT_STRING("status-msg", status_msg, 0),
|
||||
OPT_STRING("osd-status-msg", osd_status_msg, 0),
|
||||
|
||||
OPT_FLAG("slave-broken", slave_mode, CONF_GLOBAL),
|
||||
OPT_FLAG("idle", player_idle_mode, CONF_GLOBAL),
|
||||
|
@ -2221,6 +2221,27 @@ char *mp_property_expand_string(struct MPContext *mpctx, const char *str)
|
||||
return m_properties_expand_string(mp_properties, str, mpctx);
|
||||
}
|
||||
|
||||
// Before expanding properties, parse C-style escapes like "\n"
|
||||
char *mp_property_expand_escaped_string(struct MPContext *mpctx, const char *str)
|
||||
{
|
||||
void *tmp = talloc_new(NULL);
|
||||
bstr strb = bstr0(str);
|
||||
bstr dst = {0};
|
||||
while (strb.len) {
|
||||
if (!mp_append_escaped_string(tmp, &dst, &strb)) {
|
||||
talloc_free(tmp);
|
||||
return talloc_strdup(NULL, "(broken escape sequences)");
|
||||
}
|
||||
// pass " through literally
|
||||
if (!bstr_eatstart0(&strb, "\""))
|
||||
break;
|
||||
bstr_xappend(tmp, &dst, bstr0("\""));
|
||||
}
|
||||
char *r = mp_property_expand_string(mpctx, dst.start);
|
||||
talloc_free(tmp);
|
||||
return r;
|
||||
}
|
||||
|
||||
void property_print_help(struct mp_log *log)
|
||||
{
|
||||
m_properties_print_help_list(log, mp_properties);
|
||||
|
@ -28,6 +28,7 @@ void command_uninit(struct MPContext *mpctx);
|
||||
|
||||
void run_command(struct MPContext *mpctx, struct mp_cmd *cmd);
|
||||
char *mp_property_expand_string(struct MPContext *mpctx, const char *str);
|
||||
char *mp_property_expand_escaped_string(struct MPContext *mpctx, const char *str);
|
||||
void property_print_help(struct mp_log *log);
|
||||
int mp_property_do(const char* name, int action, void* val,
|
||||
struct MPContext *mpctx);
|
||||
|
@ -159,7 +159,7 @@ void print_status(struct MPContext *mpctx)
|
||||
}
|
||||
|
||||
if (opts->status_msg) {
|
||||
char *r = mp_property_expand_string(mpctx, opts->status_msg);
|
||||
char *r = mp_property_expand_escaped_string(mpctx, opts->status_msg);
|
||||
term_osd_set_status(mpctx, r);
|
||||
talloc_free(r);
|
||||
return;
|
||||
@ -428,7 +428,7 @@ static void sadd_osd_status(char **buffer, struct MPContext *mpctx, bool full)
|
||||
saddf_osd_function_sym(buffer, sym);
|
||||
char *custom_msg = mpctx->opts->osd_status_msg;
|
||||
if (custom_msg && full) {
|
||||
char *text = mp_property_expand_string(mpctx, custom_msg);
|
||||
char *text = mp_property_expand_escaped_string(mpctx, custom_msg);
|
||||
*buffer = talloc_strdup_append(*buffer, text);
|
||||
talloc_free(text);
|
||||
} else {
|
||||
|
@ -1244,7 +1244,8 @@ void run_playloop(struct MPContext *mpctx)
|
||||
|
||||
if (opts->playing_msg && !mpctx->playing_msg_shown && new_frame_shown) {
|
||||
mpctx->playing_msg_shown = true;
|
||||
char *msg = mp_property_expand_string(mpctx, opts->playing_msg);
|
||||
char *msg =
|
||||
mp_property_expand_escaped_string(mpctx, opts->playing_msg);
|
||||
MP_INFO(mpctx, "%s\n", msg);
|
||||
talloc_free(msg);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user