summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAvi Halachmi (:avih) <avihpit@yahoo.com>2021-07-28 12:29:08 +0300
committeravih <avih@users.noreply.github.com>2021-07-30 09:52:34 +0300
commit9f6cbf3a4d0b994f0ab42d59479f48cc7b4f8923 (patch)
treee2a5009e20874988fe1af1bf619da5d8359bc292
parent73c9509720e59aec059e206506c0cf461d635c9f (diff)
downloadmpv-9f6cbf3a4d0b994f0ab42d59479f48cc7b4f8923.tar.bz2
mpv-9f6cbf3a4d0b994f0ab42d59479f48cc7b4f8923.tar.xz
input: arguments quoting: support single-quotes
Users expect single quotes to work when the value includes literal backslashes or double-quotes (or as general quoting like in shell). The updated docs also include some previously-missing notes: - newline is only supported in double quotes. - adjacent (quoted) arguments don't join into one. Supporting mixed quoting (adjacent quoted strings) would make mpv's parsing more complete, but would require delicate effort of larger scope, for two reasons: - We'd need to also support escaping outside of quotes and do our best about backward compatibility. - The parsed value can either be a substring of the input or a newly-allocated string, which would be delicate when joining. Not critical to add right now.
-rw-r--r--DOCS/man/input.rst23
-rw-r--r--input/cmd.c12
2 files changed, 26 insertions, 9 deletions
diff --git a/DOCS/man/input.rst b/DOCS/man/input.rst
index 12cb75afde..d890471de2 100644
--- a/DOCS/man/input.rst
+++ b/DOCS/man/input.rst
@@ -162,7 +162,7 @@ a number of other places.
|
| ``<command> ::= [<prefixes>] <command_name> (<argument>)*``
-| ``<argument> ::= (<unquoted> | " <double_quoted> " | `X <custom_quoted> X`)``
+| ``<argument> ::= (<unquoted> | " <double_quoted> " | ' <single_quoted> ' | `X <custom_quoted> X`)``
``command_name`` is an unquoted string with the command name itself. See
`List of Input Commands`_ for a list.
@@ -171,14 +171,21 @@ Arguments are separated by whitespaces even if the command expects only one
argument. Arguments with whitespaces or other special characters must be quoted,
or the command cannot be parsed correctly.
-Double quoted arguments start and end with ``"``. Custom quotes start with `````
-(back-quote) followed by any ASCII character, and end in the same pair in
-reverse order, e.g. ```-foo-``` or ````bar````. The final pair sequence is not
-allowed inside the string - in these examples ``-``` and `````` respectively.
+Double quotes interpret JSON/C-style escaping, like ``\t`` or ``\"`` or ``\\``.
+JSON escapes according to RFC 8259, minus surrogate pair escapes. This is the
+only form which allows newlines at the value - as ``\n``.
-Custom quotes take their content literally, while inside double quotes
-JSON/C-style escaping can be used. JSON escapes according to RFC 8259, minus
-surrogate pair escapes, should be a safe subset that can be used.
+Single quotes take the content literally, and cannot include the single-quote
+character at the value.
+
+Custom quotes also take the content literally, but are more flexible than single
+quotes. They start with ````` (back-quote) followed by any ASCII character,
+and end at the first occurance of the same pair in reverse order, e.g.
+```-foo-``` or ````bar````. The final pair sequence is not allowed at the
+value - in these examples ``-``` and `````` respectively. In the second
+example the last character of the value also can't be a back-quote.
+
+Mixed quoting at the same argument, like ``'foo'"bar"``, is not supported.
Note that argument parsing and property expansion happen at different stages.
First, arguments are determined as described above, and then, where applicable,
diff --git a/input/cmd.c b/input/cmd.c
index 9f0c758b0c..0ab06e3574 100644
--- a/input/cmd.c
+++ b/input/cmd.c
@@ -336,11 +336,21 @@ static int pctx_read_token(struct parse_ctx *ctx, bstr *out)
return -1;
}
if (!bstr_eatstart0(&ctx->str, "\"")) {
- MP_ERR(ctx, "Unterminated quotes: ...>%.*s<.\n", BSTR_P(start));
+ MP_ERR(ctx, "Unterminated double quote: ...>%.*s<.\n", BSTR_P(start));
return -1;
}
return 1;
}
+ if (bstr_eatstart0(&ctx->str, "'")) {
+ int next = bstrchr(ctx->str, '\'');
+ if (next < 0) {
+ MP_ERR(ctx, "Unterminated single quote: ...>%.*s<.\n", BSTR_P(start));
+ return -1;
+ }
+ *out = bstr_splice(ctx->str, 0, next);
+ ctx->str = bstr_cut(ctx->str, next+1);
+ return 1;
+ }
if (ctx->start.len > 1 && bstr_eatstart0(&ctx->str, "`")) {
char endquote[2] = {ctx->str.start[0], '`'};
ctx->str = bstr_cut(ctx->str, 1);