Created
January 4, 2025 15:08
-
-
Save st235/b8bbf94e730362aefb288fa715dea1f2 to your computer and use it in GitHub Desktop.
Programming in Lua. Exercise 30.1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // Exercise 30.1: | |
| // Modify the dir_iter function in the directory example | |
| // so that it closes the DIR structure when it reaches | |
| // the end of the traversal. | |
| // With this change, | |
| // the program does not need to wait for a garbage collection | |
| // to release a resource that it knows it will not need anymore. | |
| // (When you close the directory, | |
| // you should set the address stored in the userdatum to NULL, | |
| // to signal to the finalizer that the directory is already closed. | |
| // Also, function dir_iter will have to check whether the directory | |
| // is not closed before using it.) | |
| #define LUA_COMPAT_APIINTCASTS | |
| #include <cmath> | |
| #include <cstdint> | |
| #include <dirent.h> | |
| #include <exception> | |
| #include <iomanip> | |
| #include <iostream> | |
| #include <limits> | |
| #include <string> | |
| #include <vector> | |
| #include <stack> | |
| #include <unordered_set> | |
| #include "lua.hpp" | |
| namespace { | |
| bool AbortWithMessage(const char* message) { | |
| std::cout << message << std::endl; | |
| std::abort(); | |
| } | |
| bool LoadFile(lua_State* state, const std::string& filename) { | |
| return !(luaL_loadfile(state, filename.c_str()) || lua_pcall(state, 0, 0, 0)); | |
| } | |
| int dir_iter(lua_State *L) { | |
| DIR** dir_ptr = (DIR**) lua_touserdata(L, lua_upvalueindex(1)); | |
| struct dirent* entry; | |
| if (*dir_ptr && (entry = readdir(*dir_ptr)) != NULL) { | |
| lua_pushstring(L, entry->d_name); | |
| return 1; | |
| } | |
| // Directory is empty. | |
| if (*dir_ptr) { | |
| closedir(*dir_ptr); | |
| *dir_ptr = nullptr; | |
| } | |
| return 0; | |
| } | |
| int l_dir(lua_State *L) { | |
| const char *path = luaL_checkstring(L, 1); | |
| DIR** d = (DIR**) lua_newuserdata(L, sizeof(DIR*)); | |
| luaL_getmetatable(L, "LuaBook.dir"); | |
| lua_setmetatable(L, -2); | |
| *d = opendir(path); | |
| if (*d == NULL) { | |
| luaL_error(L, "cannot open %s: %s", path, strerror(errno)); | |
| } | |
| lua_pushcclosure(L, dir_iter, 1); | |
| return 1; | |
| } | |
| int dir_gc(lua_State *L) { | |
| DIR* d = *(DIR**) lua_touserdata(L, 1); | |
| if (d) { | |
| closedir(d); | |
| } | |
| return 0; | |
| } | |
| const struct luaL_Reg dirlib[] = { | |
| {"open", l_dir}, | |
| {NULL, NULL} | |
| }; | |
| int luaopen_dir(lua_State *L) { | |
| luaL_newmetatable(L, "LuaBook.dir"); | |
| lua_pushcfunction(L, dir_gc); | |
| lua_setfield(L, -2, "__gc"); | |
| luaL_newlib(L, dirlib); | |
| lua_setglobal(L, "dir"); | |
| return 0; | |
| } | |
| } // namespace | |
| int main(int argc, char* argv[]) { | |
| if (argc < 2) { | |
| std::cout << "Please, specify lua script file to run." << std::endl; | |
| return 0; | |
| } | |
| lua_State* L = luaL_newstate(); | |
| luaL_openlibs(L); | |
| luaopen_dir(L); | |
| if (!LoadFile(L, std::string(argv[1]))) { | |
| AbortWithMessage(lua_tostring(L, -1)); | |
| return -1; | |
| } | |
| return 0; | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| for fname in dir.open(".") do | |
| print(fname) | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| . | |
| .. | |
| CMakeFiles | |
| Makefile | |
| cmake_install.cmake | |
| deps | |
| CMakeCache.txt | |
| lua-test |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment