summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--DOCS/man/lua.rst14
-rw-r--r--misc/json.c5
-rw-r--r--misc/json.h1
-rw-r--r--player/lua.c26
4 files changed, 46 insertions, 0 deletions
diff --git a/DOCS/man/lua.rst b/DOCS/man/lua.rst
index c49d2c388c..2eddbb8f2f 100644
--- a/DOCS/man/lua.rst
+++ b/DOCS/man/lua.rst
@@ -593,6 +593,20 @@ strictly part of the guaranteed API.
In all cases, ``mp.resume_all()`` is implicitly called.
+``utils.parse_json(str [, trail])``
+ Parses the given string argument as JSON, and returns it as a Lua table. On
+ error, returns ``nil, error``. (Currently, ``error`` is just a string
+ reading ``error``, because there is no fine-grained error reporting of any
+ kind.)
+
+ The returned value uses similar conventions as ``mp.get_property_native()``
+ to distinguish empty objects and arrays.
+
+ If the ``trail`` parameter is ``true`` (or any value equal to ``true``),
+ then trailing non-whitespace text is tolerated by the function, and the
+ trailing text is returned as 3rd return value. (The 3rd return value is
+ always there, but with ``trail`` set, no error is raised.)
+
Events
------
diff --git a/misc/json.c b/misc/json.c
index 489f087987..b301296ebe 100644
--- a/misc/json.c
+++ b/misc/json.c
@@ -70,6 +70,11 @@ static void eat_ws(char **src)
}
}
+void json_skip_whitespace(char **src)
+{
+ eat_ws(src);
+}
+
static int read_str(void *ta_parent, struct mpv_node *dst, char **src)
{
if (!eat_c(src, '"'))
diff --git a/misc/json.h b/misc/json.h
index e8551fe2a7..f5ad4cf258 100644
--- a/misc/json.h
+++ b/misc/json.h
@@ -22,6 +22,7 @@
#include "libmpv/client.h"
int json_parse(void *ta_parent, struct mpv_node *dst, char **src, int max_depth);
+void json_skip_whitespace(char **src);
int json_write(char **s, struct mpv_node *src);
#endif
diff --git a/player/lua.c b/player/lua.c
index b565dedfe2..306f3a66f5 100644
--- a/player/lua.c
+++ b/player/lua.c
@@ -40,6 +40,7 @@
#include "input/input.h"
#include "options/path.h"
#include "misc/bstr.h"
+#include "misc/json.h"
#include "osdep/timer.h"
#include "osdep/threads.h"
#include "stream/stream.h"
@@ -1290,6 +1291,30 @@ done:
}
#endif
+static int script_parse_json(lua_State *L)
+{
+ void *tmp = mp_lua_PITA(L);
+ char *text = talloc_strdup(tmp, luaL_checkstring(L, 1));
+ bool trail = lua_toboolean(L, 2);
+ bool ok = false;
+ struct mpv_node node;
+ if (json_parse(tmp, &node, &text, 32) >= 0) {
+ json_skip_whitespace(&text);
+ ok = !text[0] || !trail;
+ }
+ if (ok) {
+ if (!pushnode(L, &node, 64))
+ luaL_error(L, "stack overflow");
+ lua_pushnil(L);
+ } else {
+ lua_pushnil(L);
+ lua_pushstring(L, "error");
+ }
+ lua_pushstring(L, text);
+ talloc_free_children(tmp);
+ return 3;
+}
+
#define FN_ENTRY(name) {#name, script_ ## name}
struct fn_entry {
const char *name;
@@ -1339,6 +1364,7 @@ static const struct fn_entry utils_fns[] = {
#if HAVE_POSIX_SPAWN
FN_ENTRY(subprocess),
#endif
+ FN_ENTRY(parse_json),
{0}
};