diff --git a/binding/lua_filesystem.cpp b/binding/lua_filesystem.cpp index bbf584c2..49b6ba6d 100644 --- a/binding/lua_filesystem.cpp +++ b/binding/lua_filesystem.cpp @@ -2,14 +2,11 @@ #include #include #include -#include #include #include #include #include #include -#include -#include #include #include @@ -162,31 +159,6 @@ namespace bee::lua_filesystem { fs::path val; }; - class path_view_ref { - public: - path_view_ref(lua_State* L, int idx) { - if (lua_type(L, idx) == LUA_TSTRING) { -#if defined(_WIN32) - str = wtf8::u2w(lua::checkstrview(L, idx)); - view = str; -#else - view = lua::checkstrview(L, idx); -#endif - } else { - view = lua::checkudata(L, idx).native(); - } - } - operator path_view() const noexcept { - return view; - } - - private: -#if defined(_WIN32) - std::wstring str; -#endif - path_view view; - }; - namespace path { static int constructor(lua_State* L) { if (lua_gettop(L) == 0) { @@ -871,55 +843,6 @@ namespace bee::lua_filesystem { using pairs = pairs_directory; using pairs_r = pairs_directory; - static int exe_path(lua_State* L) { - auto r = sys::exe_path(); - if (!r) { - return lua::push_error(L, error::sys_errmsg("exe_path")); - } - lua::newudata(L, *r); - return 1; - } - - static int dll_path(lua_State* L) { - auto r = sys::dll_path(); - if (!r) { - return lua::push_error(L, error::sys_errmsg("dll_path")); - } - lua::newudata(L, *r); - return 1; - } - - static int filelock(lua_State* L) { - path_view_ref path(L, 1); - auto fd = file_handle::lock(path); - if (!fd) { - return lua::push_error(L, error::sys_errmsg("filelock")); - } - auto f = fd.to_file(file_handle::mode::write); - if (!f) { - auto errmsg = error::crt_errmsg("filelock"); - fd.close(); - return lua::push_error(L, errmsg); - } - lua::newfile(L, f); - return 1; - } - - static int fullpath(lua_State* L) { - path_view_ref path(L, 1); - auto fd = file_handle::open_link(path); - if (!fd) { - return lua::push_error(L, error::sys_errmsg("fullpath")); - } - auto fullpath = fd.path(); - fd.close(); - if (!fullpath) { - return lua::push_error(L, error::sys_errmsg("fullpath")); - } - lua::newudata(L, std::move(*fullpath)); - return 1; - } - static int luaopen(lua_State* L) { static luaL_Reg lib[] = { { "path", path::constructor }, @@ -948,10 +871,6 @@ namespace bee::lua_filesystem { { "temp_directory_path", lua::cxx::cfunc }, { "pairs", lua::cxx::cfunc }, { "pairs_r", lua::cxx::cfunc }, - { "exe_path", exe_path }, - { "dll_path", dll_path }, - { "filelock", filelock }, - { "fullpath", fullpath }, { "copy_options", NULL }, { "perm_options", NULL }, { "directory_options", NULL }, @@ -996,6 +915,10 @@ namespace bee::lua_filesystem { DEFINE_LUAOPEN(filesystem) namespace bee::lua { + fs::path& new_path(lua_State* L, fs::path&& path) { + return lua::newudata(L, std::forward(path)); + } + template <> struct udata { static inline auto metatable = bee::lua_filesystem::path::metatable; diff --git a/binding/lua_sys.cpp b/binding/lua_sys.cpp new file mode 100644 index 00000000..106ae515 --- /dev/null +++ b/binding/lua_sys.cpp @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(_WIN32) +# include +# include +#endif + +namespace bee::lua { + fs::path& new_path(lua_State* L, fs::path&& path); +} + +namespace bee::lua_sys { + class path_view_ref { + public: + path_view_ref(lua_State* L, int idx) { + if (lua_type(L, idx) == LUA_TSTRING) { +#if defined(_WIN32) + str = wtf8::u2w(lua::checkstrview(L, idx)); + view = str; +#else + view = lua::checkstrview(L, idx); +#endif + } else { + view = lua::checkudata(L, idx).native(); + } + } + operator path_view() const noexcept { + return view; + } + + private: +#if defined(_WIN32) + std::wstring str; +#endif + path_view view; + }; + + static int exe_path(lua_State* L) { + auto r = sys::exe_path(); + if (!r) { + return lua::push_error(L, error::sys_errmsg("exe_path")); + } + lua::new_path(L, std::move(*r)); + return 1; + } + + static int dll_path(lua_State* L) { + auto r = sys::dll_path(); + if (!r) { + return lua::push_error(L, error::sys_errmsg("dll_path")); + } + lua::new_path(L, std::move(*r)); + return 1; + } + + static int filelock(lua_State* L) { + path_view_ref path(L, 1); + auto fd = file_handle::lock(path); + if (!fd) { + return lua::push_error(L, error::sys_errmsg("filelock")); + } + auto f = fd.to_file(file_handle::mode::write); + if (!f) { + auto errmsg = error::crt_errmsg("filelock"); + fd.close(); + return lua::push_error(L, errmsg); + } + lua::newfile(L, f); + return 1; + } + + static int fullpath(lua_State* L) { + path_view_ref path(L, 1); + auto fd = file_handle::open_link(path); + if (!fd) { + return lua::push_error(L, error::sys_errmsg("fullpath")); + } + auto fullpath = fd.path(); + fd.close(); + if (!fullpath) { + return lua::push_error(L, error::sys_errmsg("fullpath")); + } + lua::new_path(L, std::move(*fullpath)); + return 1; + } + + static int luaopen(lua_State* L) { + static luaL_Reg lib[] = { + { "exe_path", exe_path }, + { "dll_path", dll_path }, + { "filelock", filelock }, + { "fullpath", fullpath }, + { NULL, NULL }, + }; + luaL_newlibtable(L, lib); + luaL_setfuncs(L, lib, 0); + + return 1; + } +} + +DEFINE_LUAOPEN(sys) diff --git a/test/test.lua b/test/test.lua index 2cc9cba9..4bed6a29 100644 --- a/test/test.lua +++ b/test/test.lua @@ -38,6 +38,7 @@ require "test_epoll" require "test_filewatch" require "test_time" require "test_channel" +require "test_sys" do local fs = require "bee.filesystem" diff --git a/test/test_filesystem.lua b/test/test_filesystem.lua index 5a1fcb31..25de9e32 100644 --- a/test/test_filesystem.lua +++ b/test/test_filesystem.lua @@ -732,56 +732,6 @@ function test_fs:test_last_write_time() last_write_time("temp.txt") end ---function test_fs:test_exe_path() --- local function getexe() --- local i = 0 --- while arg[i] ~= nil do --- i = i - 1 --- end --- return fs.path(arg[i + 1]) --- end --- assertPathEquals(fs.exe_path(), fs.absolute(getexe())) ---end - ---function test_fs:test_dll_path() --- local function getdll() --- local i = 0 --- while arg[i] ~= nil do --- i = i - 1 --- end --- return fs.path(arg[i + 1]):parent_path() / ("bee." .. __EXT__) --- end --- assertPathEquals(fs.dll_path(), fs.absolute(getdll())) ---end - -function test_fs:test_filelock_1() - local lock = fs.path("temp.lock") - local f1 = lt.assertIsUserdata(fs.filelock(lock)) - lt.assertEquals(fs.filelock(lock), nil) - f1:close() - local f2 = lt.assertIsUserdata(fs.filelock(lock)) - f2:close() - fs.remove(fs.path("temp.lock")) -end - -function test_fs:test_filelock_2() - local process = shell:runlua([[ - local fs = require "bee.filesystem" - fs.filelock(fs.path("temp.lock")) - io.stdout:write "ok" - io.stdout:flush() - io.read "a" -]], { stdin = true, stdout = true, stderr = true }) - lt.assertEquals(process.stdout:read(2), "ok") - lt.assertEquals(fs.filelock(fs.path("temp.lock")), nil) - process.stdin:close() - lt.assertEquals(process.stderr:read "a", "") - lt.assertEquals(process:wait(), 0) - local f = lt.assertIsUserdata(fs.filelock(fs.path("temp.lock"))) - f:close() - fs.remove(fs.path("temp.lock")) -end - function test_fs:test_tostring() local function test(s) lt.assertEquals(fs.path(s):string(), s) diff --git a/test/test_sys.lua b/test/test_sys.lua new file mode 100644 index 00000000..87e1b6ed --- /dev/null +++ b/test/test_sys.lua @@ -0,0 +1,34 @@ +local fs = require "bee.filesystem" +local sys = require "bee.sys" +local lt = require "ltest" +local shell = require "shell" + +local test_sys = lt.test "sys" + +function test_sys:test_filelock_1() + local lock = "temp.lock" + local f1 = lt.assertIsUserdata(sys.filelock(lock)) + lt.assertEquals(sys.filelock(lock), nil) + f1:close() + local f2 = lt.assertIsUserdata(sys.filelock(lock)) + f2:close() + fs.remove "temp.lock" +end + +function test_sys:test_filelock_2() + local process = shell:runlua([[ + local sys = require "bee.sys" + sys.filelock "temp.lock" + io.stdout:write "ok" + io.stdout:flush() + io.read "a" +]], { stdin = true, stdout = true, stderr = true }) + lt.assertEquals(process.stdout:read(2), "ok") + lt.assertEquals(sys.filelock "temp.lock", nil) + process.stdin:close() + lt.assertEquals(process.stderr:read "a", "") + lt.assertEquals(process:wait(), 0) + local f = lt.assertIsUserdata(sys.filelock "temp.lock") + f:close() + fs.remove "temp.lock" +end