aboutsummaryrefslogtreecommitdiff
path: root/mod/fs.c
diff options
context:
space:
mode:
Diffstat (limited to 'mod/fs.c')
-rw-r--r--mod/fs.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/mod/fs.c b/mod/fs.c
new file mode 100644
index 0000000..e08dfda
--- /dev/null
+++ b/mod/fs.c
@@ -0,0 +1,103 @@
+/*
+ * melisma - extensible and scriptable audio engine
+ * Copyright (C) 2026 Ludvig Gunne Lindström
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <errno.h>
+#include <dirent.h>
+#include <lauxlib.h>
+
+static const char *dirent_typestr(struct dirent *de)
+{
+ switch (de->d_type)
+ {
+ case DT_BLK: return "b";
+ case DT_CHR: return "c";
+ case DT_DIR: return "d";
+ case DT_FIFO: return "p";
+ case DT_REG: return "f";
+ case DT_LNK: return "l";
+ case DT_SOCK: return "s";
+ default: return "?";
+ }
+}
+
+static void push_dirent(lua_State *s, struct dirent *de)
+{
+ lua_newtable(s);
+ int tbl = lua_gettop(s);
+
+ lua_pushstring(s,de->d_name);
+ lua_setfield(s,tbl,"name");
+
+ lua_pushstring(s,dirent_typestr(de));
+ lua_setfield(s,tbl,"type");
+
+ lua_settop(s,tbl);
+}
+
+static int l_readdir(lua_State *s)
+{
+ const char *path = luaL_checkstring(s,1);
+ DIR *dirp = opendir(path);
+
+ if (dirp == NULL)
+ {
+ luaL_error(s,strerror(errno));
+ }
+
+ lua_newtable(s);
+ int tbl = lua_gettop(s);
+
+ int i = 1;
+ struct dirent *de;
+ while ((de = readdir(dirp)) != NULL)
+ {
+ push_dirent(s,de);
+ lua_rawseti(s,tbl,i++);
+ }
+
+ closedir(dirp);
+ lua_settop(s,tbl);
+ return 1;
+}
+
+int luaopen_melisma_fs(lua_State *s)
+{
+/*** File system utilities.
+@module fs
+*/
+ lua_newtable(s);
+ int tbl = lua_gettop(s);
+
+/*** List directory contents.
+@function readdir
+@tparam string path Directory path.
+@treturn table Directory contents.
+@usage
+local fs = require 'melisma.fs'
+local contents = fs.readdir('.')
+for _,entry in ipairs(contents) do
+ print(entry.name, entry.type)
+end
+*/
+ lua_pushcfunction(s,l_readdir);
+ lua_setfield(s,tbl,"readdir");
+
+ lua_settop(s,tbl);
+ return 1;
+}