diff --git a/data/core/common.lua b/data/core/common.lua index 548b5faa..3df3e8f1 100644 --- a/data/core/common.lua +++ b/data/core/common.lua @@ -322,4 +322,51 @@ function common.mkdirp(path) return true end +function common.rm(path, recursively) + local stat = system.get_file_info(path) + if not stat or (stat.type ~= "file" and stat.type ~= "dir") then + return false, "invalid path given", path + end + + if stat.type == "file" then + local removed, error = os.remove(path) + if not removed then + return false, error, path + end + else + local contents = system.list_dir(path) + if #contents > 0 and not recursively then + return false, "directory is not empty", path + end + + for _, item in pairs(contents) do + local item_path = path .. PATHSEP .. item + local item_stat = system.get_file_info(item_path) + + if not item_stat then + return false, "invalid file encountered", item_path + end + + if item_stat.type == "dir" then + local deleted, error, ipath = common.rm(item_path, recursively) + if not deleted then + return false, error, ipath + end + elseif item_stat.type == "file" then + local removed, error = os.remove(item_path) + if not removed then + return false, error, item_path + end + end + end + + local removed, error = system.rmdir(path) + if not removed then + return false, error, path + end + end + + return true +end + return common diff --git a/src/api/system.c b/src/api/system.c index 4b98509f..2f1bf763 100644 --- a/src/api/system.c +++ b/src/api/system.c @@ -10,6 +10,7 @@ #ifdef _WIN32 #include #include + #include #endif extern SDL_Window *window; @@ -384,6 +385,52 @@ static int f_show_fatal_error(lua_State *L) { } +// removes an empty directory +static int f_rmdir(lua_State *L) { + const char *path = luaL_checkstring(L, 1); + +#ifdef _WIN32 + int deleted = RemoveDirectoryA(path); + if(deleted > 0) { + lua_pushboolean(L, 1); + } else { + DWORD error_code = GetLastError(); + LPVOID message; + + FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + error_code, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &message, + 0, + NULL + ); + + lua_pushboolean(L, 0); + lua_pushlstring(L, (LPCTSTR)message, lstrlen((LPCTSTR)message)); + LocalFree(message); + + return 2; + } +#else + int deleted = remove(path); + if(deleted < 0) { + lua_pushboolean(L, 0); + lua_pushstring(L, strerror(errno)); + + return 2; + } else { + lua_pushboolean(L, 1); + } +#endif + + return 1; +} + + static int f_chdir(lua_State *L) { const char *path = luaL_checkstring(L, 1); int err = chdir(path); @@ -604,6 +651,7 @@ static const luaL_Reg lib[] = { { "set_window_size", f_set_window_size }, { "window_has_focus", f_window_has_focus }, { "show_fatal_error", f_show_fatal_error }, + { "rmdir", f_rmdir }, { "chdir", f_chdir }, { "mkdir", f_mkdir }, { "list_dir", f_list_dir },