Added fs.is_newer function to filesystem library

This commit is contained in:
2025-03-06 17:54:26 +11:00
parent dbf91e0ebc
commit fe01a41aac
3 changed files with 111 additions and 3 deletions

View File

@@ -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<boolean> function fs.is_newer(path_a: string | number, path_b: string | table[string])
int lua_fs_is_newer(lua_State* L);
// table<string> | 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);

View File

@@ -1,5 +1,6 @@
#include "lua_filesystem.h"
#include <filesystem>
#include <chrono>
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::milliseconds>(
std::chrono::clock_cast<std::chrono::system_clock>(
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)
{