diff --git a/osx.c b/osx.c index 399ea8b..98cb2c9 100644 --- a/osx.c +++ b/osx.c @@ -193,9 +193,7 @@ static bool os_dir_filter(lua_State *L, const char *name) return result; } -static int os_dir_iter(lua_State *L); - -static int os_dir(lua_State *L) +static int os_dir_open(lua_State *L) { const char *path = luaL_checkstring(L, 1); @@ -204,9 +202,42 @@ static int os_dir(lua_State *L) dir->hn = os_opendir(path); dir->closeflag = false; if (!dir->hn) - luaL_error(L, "%s: %s", path, strerror(errno)); + return os_pushfail(L, path); luaL_setmetatable(L, DF_LUA_DIRHANDLE); + return 1; +} + +static int os_dir_close(lua_State *L) +{ + df_os_dir *dir = todir(L); + + os_closedir(dir->hn); + dir->closeflag = true; + return 0; +} + +static int os_dir_gc(lua_State *L) +{ + df_os_dir *dir = luaL_checkudata(L, 1, DF_LUA_DIRHANDLE); + + if (!dir->closeflag) + os_dir_close(L); + + return 0; +} + +static int os_dir_iter(lua_State *L); + +static int os_dir(lua_State *L) +{ + lua_pushcfunction(L, os_dir_open); + lua_pushvalue(L, 1); + lua_call(L, 1, 2); + if (lua_isnil(L, -2)) + lua_error(L); + + lua_pop(L, 1); lua_pushcclosure(L, os_dir_iter, 2); return 1; @@ -239,7 +270,7 @@ nextfilename: return 1; } -static int os_dir_read(lua_State *L) +static int os_dir_readdir(lua_State *L) { df_os_dir *dir = todir(L); @@ -253,28 +284,9 @@ static int os_dir_read(lua_State *L) return 1; } -static int os_dir_close(lua_State *L) +static int os_dir_dolistfiles(lua_State *L, bool closeflag, const char *path) { df_os_dir *dir = todir(L); - - os_closedir(dir->hn); - dir->closeflag = true; - return 0; -} - -static int os_dir_gc(lua_State *L) -{ - df_os_dir *dir = luaL_checkudata(L, 1, DF_LUA_DIRHANDLE); - - if (!dir->closeflag) - os_dir_close(L); - - return 0; -} - -static int os_listfiles(lua_State *L) -{ - const char *path = luaL_checkstring(L, 1); bool dofilter = false; if (!lua_isnoneornil(L, 2)) { @@ -282,18 +294,13 @@ static int os_listfiles(lua_State *L) dofilter = true; } - df_os_dirhn hn = os_opendir(path); - if (!hn) - return os_pushfail(L, path); + char *filename; + int i = 1; lua_newtable(L); - const char *filename; - int i = 1; - int err; - errno = 0; - while ((filename = os_readdir(hn)) != NULL) { + while ((filename = os_readdir(dir->hn)) != NULL) { if (strcmp(filename, ".") == 0 || strcmp(filename, "..") == 0) continue; if (dofilter && !os_dir_filter(L, filename)) @@ -303,15 +310,40 @@ static int os_listfiles(lua_State *L) lua_pushstring(L, filename); lua_settable(L, -3); } - err = errno; - os_closedir(hn); - if (err != 0) + int err = errno; + if (closeflag) + os_dir_close(L); + if (err != 0) { + errno = err; return os_pushfail(L, path); - + } return 1; } +static int os_dir_listfiles(lua_State *L) +{ + return os_dir_dolistfiles(L, false, NULL); +} + +static int os_listfiles(lua_State *L) +{ + const char *path = luaL_checkstring(L, 1); + if (lua_isnone(L, 2)) + lua_pushnil(L); + + lua_pushcfunction(L, os_dir_open); + lua_pushvalue(L, 1); + lua_call(L, 1, 2); + if (lua_isnil(L, -2)) + lua_error(L); + + lua_copy(L, -2, 1); + lua_pop(L, 2); + + return os_dir_dolistfiles(L, true, path); +} + static int os_stat(lua_State *L) { const char *path = NULL; @@ -517,7 +549,8 @@ static void createmeta(lua_State *L) { NULL, NULL } }; static const luaL_Reg meth[] = { - { "read", os_dir_read }, + { "readdir", os_dir_readdir }, + { "listfiles", os_dir_listfiles }, { "close", os_dir_close }, { NULL, NULL } }; @@ -534,6 +567,7 @@ DF_OSXMOD_API int luaopen_osx(lua_State *L) { static const luaL_Reg funcs[] = { { "listfiles", os_listfiles }, + { "opendir", os_dir_open }, { "dir", os_dir }, { "stat", os_stat }, { "mkdir", os_mkdir },