summaryrefslogtreecommitdiff
path: root/lib/lua
diff options
context:
space:
mode:
Diffstat (limited to 'lib/lua')
-rw-r--r--lib/lua/include/lualib.h5
-rw-r--r--lib/lua/src/LuaLib/ldirlib.c101
2 files changed, 105 insertions, 1 deletions
diff --git a/lib/lua/include/lualib.h b/lib/lua/include/lualib.h
index bec0b94..081d7c3 100644
--- a/lib/lua/include/lualib.h
+++ b/lib/lua/include/lualib.h
@@ -1,5 +1,5 @@
/*
-** $Id: lualib.h,v 1.3 2003-12-11 16:53:28 pixel Exp $
+** $Id: lualib.h,v 1.4 2004-11-27 21:01:20 pixel Exp $
** Lua standard libraries
** See Copyright Notice in lua.h
*/
@@ -38,6 +38,9 @@ LUALIB_API int luaopen_math (lua_State *L);
#define LUA_DBLIBNAME "debug"
LUALIB_API int luaopen_debug (lua_State *L);
+#define LUA_DIRLIBNAME "dir"
+LUALIB_API int luaopen_dir (lua_State *L);
+
LUALIB_API int luaopen_loadlib (lua_State *L);
diff --git a/lib/lua/src/LuaLib/ldirlib.c b/lib/lua/src/LuaLib/ldirlib.c
new file mode 100644
index 0000000..b6760da
--- /dev/null
+++ b/lib/lua/src/LuaLib/ldirlib.c
@@ -0,0 +1,101 @@
+#include <stdlib.h>
+#include <dirent.h>
+#include <errno.h>
+#ifdef _WIN32
+#include <sys/stat.h>
+#else
+#include <sys/stat.h>
+#include <sys/type.h>
+#endif
+
+#define ldirlib_c
+
+#include "lua.h"
+
+#include "lauxlib.h"
+#include "lualib.h"
+
+/* forward declaration for the iterator function */
+static int dir_iter (lua_State *L);
+
+static int l_dir (lua_State *L) {
+ const char *path = luaL_checkstring(L, 1);
+
+ /* create a userdatum to store a DIR address */
+ DIR **d = (DIR **)lua_newuserdata(L, sizeof(DIR *));
+
+ /* set its metatable */
+ luaL_getmetatable(L, "LuaBook.dir");
+ lua_setmetatable(L, -2);
+
+ /* try to open the given directory */
+ *d = opendir(path);
+ if (*d == NULL) /* error opening the directory? */
+ luaL_error(L, "cannot open %s: %s", path,
+ strerror(errno));
+
+ /* creates and returns the iterator function
+ (its sole upvalue, the directory userdatum,
+ is already on the stack top */
+ lua_pushcclosure(L, dir_iter, 1);
+ return 1;
+}
+
+static int dir_iter (lua_State *L) {
+ DIR *d = *(DIR **)lua_touserdata(L, lua_upvalueindex(1));
+ struct dirent *entry;
+#ifdef _WIN32
+ struct _stat file_stat;
+#else
+ struct stat file_stat;
+#endif
+ if ((entry = readdir(d)) != NULL) {
+ lua_newtable(L);
+ lua_pushstring(L, "name");
+ lua_pushstring(L, entry->d_name);
+ lua_settable(L, -3);
+#ifdef _WIN32
+ _stat(entry->d_name, &file_stat);
+#else
+ stat(entry->d_name, &file_stat);
+#endif
+ lua_pushstring(L, "type");
+ lua_pushnumber(L, (S_IFREG & file_stat.st_mode) ? 2 : ((S_IFDIR & file_stat.st_mode) ? 1 : 0));
+ lua_settable(L, -3);
+
+ return 1;
+ }
+ else return 0; /* no more values to return */
+}
+
+static int dir_gc (lua_State *L) {
+ DIR *d = *(DIR **)lua_touserdata(L, 1);
+ if (d) closedir(d);
+ return 0;
+}
+
+static const luaL_reg dirlib[] = {
+ {NULL, NULL}
+};
+
+int luaopen_dir (lua_State *L) {
+ luaL_openlib(L, LUA_DIRLIBNAME, dirlib, 0);
+ luaL_newmetatable(L, "LuaBook.dir");
+
+ /* set its __gc field */
+ lua_pushstring(L, "__gc");
+ lua_pushcfunction(L, dir_gc);
+ lua_settable(L, -3);
+
+ /* register the `dir' function */
+ lua_pushcfunction(L, l_dir);
+ lua_setglobal(L, "dir");
+
+ lua_pushnumber(L, 1);
+ lua_setglobal(L, "FLAG_DIR");
+
+ lua_pushnumber(L, 2);
+ lua_setglobal(L, "FLAG_FILE");
+
+ return 0;
+}