lua: expose JSON parser

The JSON parser was introduced for the IPC protocol, but I guess it's
useful here too.

The motivation for this commit is the same as with 8e4fa5fc (again).
This commit is contained in:
wm4 2014-10-19 05:27:35 +02:00
parent 987146362e
commit 5548c75e55
4 changed files with 46 additions and 0 deletions

View File

@ -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
------

View File

@ -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, '"'))

View File

@ -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

View File

@ -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}
};