summaryrefslogtreecommitdiffstats
path: root/player/lua.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-05-26 21:46:01 +0200
committerwm4 <wm4@nowhere>2014-05-26 21:59:29 +0200
commit6f20d6b74e247847dcfa36fdab0498f7280ab270 (patch)
treeb72568437e86d8fae94ff16326b31a4551db3131 /player/lua.c
parent9c18a920ff0c5af3ed8868d38081e5ccb4d9ddc1 (diff)
downloadmpv-6f20d6b74e247847dcfa36fdab0498f7280ab270.tar.bz2
mpv-6f20d6b74e247847dcfa36fdab0498f7280ab270.tar.xz
lua: fix compilation with lua 5.2
Commit e2e450f9 started making use of luaL_register(), but OF COURSE this function disappeared in Lua 5.2, and was replaced with a 5.2-only alternative, slightly different mechanism. So just NIH our own function. This is actually slightly more correct, since it forces the user to call "require" to actually make the module visible for builtin C-only modules other than "mp". Fix autoload.lua accordingly.
Diffstat (limited to 'player/lua.c')
-rw-r--r--player/lua.c50
1 files changed, 42 insertions, 8 deletions
diff --git a/player/lua.c b/player/lua.c
index 60e380b554..efbd21b18e 100644
--- a/player/lua.c
+++ b/player/lua.c
@@ -187,6 +187,23 @@ static bool require(lua_State *L, const char *name)
return true;
}
+// Push the table of a module. If it doesn't exist, it's created.
+// The Lua script can call "require(module)" to "load" it.
+static void push_module_table(lua_State *L, const char *module)
+{
+ lua_getglobal(L, "package"); // package
+ lua_getfield(L, -1, "loaded"); // package loaded
+ lua_remove(L, -2); // loaded
+ lua_getfield(L, -1, module); // loaded module
+ if (lua_isnil(L, -1)) {
+ lua_pop(L, 1); // loaded
+ lua_newtable(L); // loaded module
+ lua_pushvalue(L, -1); // loaded module module
+ lua_setfield(L, -3, module); // loaded module
+ }
+ lua_remove(L, -2); // module
+}
+
static int load_lua(struct mpv_handle *client, const char *fname)
{
struct MPContext *mpctx = mp_client_get_core(client);
@@ -212,13 +229,14 @@ static int load_lua(struct mpv_handle *client, const char *fname)
lua_setfield(L, LUA_REGISTRYINDEX, "wrap_cpcall"); // -
luaL_openlibs(L);
+ add_functions(ctx); // mp
+
+ push_module_table(L, "mp"); // mp
- lua_newtable(L); // mp
+ // "mp" is available by default, and no "require 'mp'" is needed
lua_pushvalue(L, -1); // mp mp
lua_setglobal(L, "mp"); // mp
- add_functions(ctx); // mp
-
lua_pushstring(L, ctx->name); // mp name
lua_setfield(L, -2, "script_name"); // mp
@@ -1044,8 +1062,12 @@ static int script_join_path(lua_State *L)
}
#define FN_ENTRY(name) {#name, script_ ## name}
+struct fn_entry {
+ const char *name;
+ int (*fn)(lua_State *L);
+};
-static struct luaL_Reg main_fns[] = {
+static const struct fn_entry main_fns[] = {
FN_ENTRY(log),
FN_ENTRY(suspend),
FN_ENTRY(resume),
@@ -1080,18 +1102,31 @@ static struct luaL_Reg main_fns[] = {
{0}
};
-static struct luaL_Reg utils_fns[] = {
+static struct fn_entry utils_fns[] = {
FN_ENTRY(readdir),
FN_ENTRY(split_path),
FN_ENTRY(join_path),
{0}
};
+static void register_package_fns(lua_State *L, char *module,
+ const struct fn_entry *e)
+{
+ push_module_table(L, module); // modtable
+ for (int n = 0; e[n].name; n++) {
+ lua_pushcclosure(L, e[n].fn, 0); // modtable fn
+ lua_setfield(L, -2, e[n].name); // modtable
+ }
+ lua_pop(L, 1); // -
+}
+
static void add_functions(struct script_ctx *ctx)
{
lua_State *L = ctx->state;
- luaL_register(L, "mp", main_fns); // mp
+ register_package_fns(L, "mp", main_fns);
+
+ push_module_table(L, "mp"); // mp
lua_pushinteger(L, 0);
lua_pushcclosure(L, script_get_property, 1);
@@ -1103,8 +1138,7 @@ static void add_functions(struct script_ctx *ctx)
lua_pop(L, 1); // -
- luaL_register(L, "mp.utils", utils_fns);
- lua_pop(L, 1);
+ register_package_fns(L, "mp.utils", utils_fns);
}
const struct mp_scripting mp_scripting_lua = {