From fe01a41aac7a0945dc38bd9293ecf279c3672151 Mon Sep 17 00:00:00 2001 From: Riley King-Saunders Date: Thu, 6 Mar 2025 17:54:26 +1100 Subject: [PATCH] Added fs.is_newer function to filesystem library --- include/lua_filesystem.h | 5 ++ src/lua_filesystem.cpp | 107 ++++++++++++++++++++++++++++++++++++++- thirdparty/uniproc | 2 +- 3 files changed, 111 insertions(+), 3 deletions(-) diff --git a/include/lua_filesystem.h b/include/lua_filesystem.h index 6b9f0fe..61a55f9 100644 --- a/include/lua_filesystem.h +++ b/include/lua_filesystem.h @@ -20,6 +20,11 @@ int lua_fs_forall_dir_next(lua_State* L); int lua_fs_foreach_dir_dtor(lua_State* L); int lua_fs_forall_dir_dtor(lua_State* L); +// Returns true when a is newer than b. If b does not exist it returns true. If a does not exist it returns false +// boolean | table function fs.is_newer(path_a: string | number, path_b: string | table[string]) +int lua_fs_is_newer(lua_State* L); +// table | nil function fs.filter_newer(path_a: string | number, path_b: string | table[string]) +int lua_fs_filter_newer(lua_State* L); // number | nil function fs.last_modified(path: string) int lua_fs_last_modified(lua_State* L); diff --git a/src/lua_filesystem.cpp b/src/lua_filesystem.cpp index f57ba01..62dc5a5 100644 --- a/src/lua_filesystem.cpp +++ b/src/lua_filesystem.cpp @@ -1,5 +1,6 @@ #include "lua_filesystem.h" #include +#include int luaopen_filesystem(lua_State* L) { @@ -14,10 +15,16 @@ int luaopen_filesystem(lua_State* L) lua_pushcfunction(L, lua_fs_forall_dir_dtor); lua_setfield(L, -2, "__gc"); - + // Push functions lua_newtable(L); + lua_pushcfunction(L, lua_fs_is_newer); + lua_setfield(L, -2, "is_newer"); + + lua_pushcfunction(L, lua_fs_filter_newer); + lua_setfield(L, -2, "filter_newer"); + lua_pushcfunction(L, lua_fs_absolute); lua_setfield(L, -2, "absolute"); @@ -251,11 +258,107 @@ int lua_fs_file_directory(lua_State* L) return 0; } +int lua_fs_is_newer(lua_State* L) +{ + luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a full file path"); + const char* test_file = lua_tostring(L, 1); + if (!std::filesystem::exists(test_file)) + { + lua_pushboolean(L, false); + return 1; + } + + if (lua_type(L, 2) == LUA_TTABLE) + { + size_t tbl_len = lua_objlen(L, 2); + lua_newtable(L); + for (size_t i = 1; i <= tbl_len; ++i) + { + lua_rawgeti(L, 2, i); + if (lua_type(L, -1) != LUA_TSTRING) + return luaL_error(L, "Expected second argument at index %llu to be a string, not %s\n", + i, lua_typename(L, lua_type(L, -1))); + const char* target = lua_tostring(L, 2); + lua_pushboolean(L, + std::filesystem::last_write_time(test_file) > std::filesystem::last_write_time(target)); + lua_rawseti(L, -2, i); + lua_pop(L, 1); + } + return 1; + } + else if (lua_type(L, 2) == LUA_TSTRING) + { + const char* target = lua_tostring(L, 2); + if (!std::filesystem::exists(target)) + { + lua_pushboolean(L, true); + return 1; + } + lua_pushboolean(L, + std::filesystem::last_write_time(test_file) > std::filesystem::last_write_time(target)); + return 1; + } + else return luaL_error(L, "Expected second argument to be a string or table of strings"); +} + +int lua_fs_filter_newer(lua_State* L) +{ + luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a full file path"); + const char* test_file = lua_tostring(L, 1); + if (!std::filesystem::exists(test_file)) + { + lua_pushnil(L); + return 1; + } + + if (lua_type(L, 2) == LUA_TTABLE) + { + size_t tbl_len = lua_objlen(L, 2); + lua_newtable(L); + for (size_t i = 1; i <= tbl_len; ++i) + { + lua_rawgeti(L, 2, i); + if (lua_type(L, -1) != LUA_TSTRING) + return luaL_error(L, "Expected second argument at index %llu to be a string, not %s\n", + i, lua_typename(L, lua_type(L, -1))); + const char* target = lua_tostring(L, 2); + if (std::filesystem::last_write_time(test_file) > std::filesystem::last_write_time(target)) + { + lua_pushvalue(L, -1); + lua_rawseti(L, -2, lua_objlen(L, -2)+1); + } + lua_pop(L, 1); + } + return 1; + } + else if (lua_type(L, 2) == LUA_TSTRING) + { + const char* target = lua_tostring(L, 2); + if (!std::filesystem::exists(target)) + { + lua_pushvalue(L, 2); + return 1; + } + + if (std::filesystem::last_write_time(test_file) > std::filesystem::last_write_time(target)) + lua_pushvalue(L, 2); + else lua_pushnil(L); + + return 1; + } + else return luaL_error(L, "Expected second argument to be a string or table of strings"); +} + int lua_fs_last_modified(lua_State* L) { luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a full file path"); try { - lua_pushinteger(L, std::filesystem::last_write_time(std::filesystem::path(lua_tostring(L, 1))).time_since_epoch().count()); + const uint64_t file_last_write = std::chrono::duration_cast( + std::chrono::clock_cast( + std::filesystem::last_write_time(lua_tostring(L, 1)) + ).time_since_epoch() + ).count(); + lua_pushinteger(L, file_last_write); return 1; } catch (const std::exception& e) { diff --git a/thirdparty/uniproc b/thirdparty/uniproc index f4927bf..500fe17 160000 --- a/thirdparty/uniproc +++ b/thirdparty/uniproc @@ -1 +1 @@ -Subproject commit f4927bf136dd9edda93527cc39299e760523318b +Subproject commit 500fe170769d9608c2c36163da055b5fc2157c11