summaryrefslogtreecommitdiffstats
path: root/player
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-05-25 19:51:11 +0200
committerwm4 <wm4@nowhere>2014-05-25 19:51:11 +0200
commite2e450f96177c17bea5f15abee87b1671ecdc75d (patch)
treea235911e1fbe620532b41f32a647ff45f7ced378 /player
parente648f7e783e9b063bbef4dcbb5f2c9e7a8c8e4e4 (diff)
downloadmpv-e2e450f96177c17bea5f15abee87b1671ecdc75d.tar.bz2
mpv-e2e450f96177c17bea5f15abee87b1671ecdc75d.tar.xz
lua: add some filesystem utility functions
We need this only because Lua's stdlib is so scarce. Lua doesn't intend to include a complete stdlib - they confine themselves to standard C, both for portability reasons and to keep the code minimal. But standard C does not provide much either. It would be possible to use Lua POSIX wrapper libraries, but that would be a messy (and unobvious) dependency. It's better to implement the missing functions ourselves, as long as they're small in number.
Diffstat (limited to 'player')
-rw-r--r--player/lua.c82
1 files changed, 72 insertions, 10 deletions
diff --git a/player/lua.c b/player/lua.c
index 4e1f3d04d2..60e380b554 100644
--- a/player/lua.c
+++ b/player/lua.c
@@ -985,14 +985,67 @@ static int script_get_wakeup_pipe(lua_State *L)
return 1;
}
-struct fn_entry {
- const char *name;
- int (*fn)(lua_State *L);
-};
+static int script_readdir(lua_State *L)
+{
+ // 0 1 2 3
+ const char *fmts[] = {"all", "files", "dirs", "normal", NULL};
+ const char *path = luaL_checkstring(L, 1);
+ int t = luaL_checkoption(L, 2, "normal", fmts);
+ DIR *dir = opendir(path);
+ if (!dir) {
+ lua_pushnil(L);
+ lua_pushstring(L, "error");
+ return 2;
+ }
+ lua_newtable(L); // list
+ char *fullpath = NULL;
+ struct dirent *e;
+ int n = 0;
+ while ((e = readdir(dir))) {
+ char *name = e->d_name;
+ if (t) {
+ if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
+ continue;
+ if (fullpath)
+ fullpath[0] = '\0';
+ fullpath = talloc_asprintf_append(fullpath, "%s/%s", path, name);
+ struct stat st;
+ if (mp_stat(fullpath, &st))
+ continue;
+ if (!(((t & 1) && S_ISREG(st.st_mode)) ||
+ ((t & 2) && S_ISDIR(st.st_mode))))
+ continue;
+ }
+ lua_pushinteger(L, ++n); // list index
+ lua_pushstring(L, name); // list index name
+ lua_settable(L, -3); // list
+ }
+ talloc_free(fullpath);
+ return 1;
+}
+
+static int script_split_path(lua_State *L)
+{
+ const char *p = luaL_checkstring(L, 1);
+ bstr fname = mp_dirname(p);
+ lua_pushlstring(L, fname.start, fname.len);
+ lua_pushstring(L, mp_basename(p));
+ return 2;
+}
+
+static int script_join_path(lua_State *L)
+{
+ const char *p1 = luaL_checkstring(L, 1);
+ const char *p2 = luaL_checkstring(L, 2);
+ char *r = mp_path_join(NULL, bstr0(p1), bstr0(p2));
+ lua_pushstring(L, r);
+ talloc_free(r);
+ return 1;
+}
#define FN_ENTRY(name) {#name, script_ ## name}
-static struct fn_entry fn_list[] = {
+static struct luaL_Reg main_fns[] = {
FN_ENTRY(log),
FN_ENTRY(suspend),
FN_ENTRY(resume),
@@ -1024,17 +1077,21 @@ static struct fn_entry fn_list[] = {
FN_ENTRY(format_time),
FN_ENTRY(enable_messages),
FN_ENTRY(get_wakeup_pipe),
+ {0}
+};
+
+static struct luaL_Reg utils_fns[] = {
+ FN_ENTRY(readdir),
+ FN_ENTRY(split_path),
+ FN_ENTRY(join_path),
+ {0}
};
-// On stack: mp table
static void add_functions(struct script_ctx *ctx)
{
lua_State *L = ctx->state;
- for (int n = 0; n < MP_ARRAY_SIZE(fn_list); n++) {
- lua_pushcfunction(L, fn_list[n].fn);
- lua_setfield(L, -2, fn_list[n].name);
- }
+ luaL_register(L, "mp", main_fns); // mp
lua_pushinteger(L, 0);
lua_pushcclosure(L, script_get_property, 1);
@@ -1043,6 +1100,11 @@ static void add_functions(struct script_ctx *ctx)
lua_pushinteger(L, 1);
lua_pushcclosure(L, script_get_property, 1);
lua_setfield(L, -2, "get_property_osd");
+
+ lua_pop(L, 1); // -
+
+ luaL_register(L, "mp.utils", utils_fns);
+ lua_pop(L, 1);
}
const struct mp_scripting mp_scripting_lua = {