Initial release commit
This commit is contained in:
331
src/lua_filesystem.cpp
Normal file
331
src/lua_filesystem.cpp
Normal file
@@ -0,0 +1,331 @@
|
||||
#include "lua_filesystem.h"
|
||||
#include <filesystem>
|
||||
|
||||
int luaopen_filesystem(lua_State* L)
|
||||
{
|
||||
luaL_newmetatable(L, "fs.file_handle");
|
||||
|
||||
// Push iterator state metatables
|
||||
luaL_newmetatable(L, "fs.stdlibcpp.filesystem.directory_iterator");
|
||||
lua_pushcfunction(L, lua_fs_foreach_dir_dtor);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
luaL_newmetatable(L, "fs.stdlibcpp.filesystem.recursive_directory_iterator");
|
||||
lua_pushcfunction(L, lua_fs_forall_dir_dtor);
|
||||
lua_setfield(L, -2, "__gc");
|
||||
|
||||
|
||||
// Push functions
|
||||
lua_newtable(L);
|
||||
|
||||
lua_pushcfunction(L, lua_fs_absolute);
|
||||
lua_setfield(L, -2, "absolute");
|
||||
|
||||
lua_pushcfunction(L, lua_fs_create_dir);
|
||||
lua_setfield(L, -2, "create_dir");
|
||||
|
||||
lua_pushcfunction(L, lua_fs_exists);
|
||||
lua_setfield(L, -2, "exists");
|
||||
|
||||
lua_pushcfunction(L, lua_fs_file_directory);
|
||||
lua_setfield(L, -2, "dir");
|
||||
|
||||
lua_pushcfunction(L, lua_fs_file_extension);
|
||||
lua_setfield(L, -2, "extension");
|
||||
|
||||
lua_pushcfunction(L, lua_fs_file_name);
|
||||
lua_setfield(L, -2, "file_name");
|
||||
|
||||
lua_pushcfunction(L, lua_fs_forall_dir);
|
||||
lua_setfield(L, -2, "forall");
|
||||
|
||||
lua_pushcfunction(L, lua_fs_foreach_dir);
|
||||
lua_setfield(L, -2, "foreach");
|
||||
|
||||
lua_pushcfunction(L, lua_fs_is_dir);
|
||||
lua_setfield(L, -2, "is_dir");
|
||||
|
||||
lua_pushcfunction(L, lua_fs_is_file);
|
||||
lua_setfield(L, -2, "is_file");
|
||||
|
||||
lua_pushcfunction(L, lua_fs_last_modified);
|
||||
lua_setfield(L, -2, "last_modified");
|
||||
|
||||
lua_pushcfunction(L, lua_fs_list_dir);
|
||||
lua_setfield(L, -2, "list_dir");
|
||||
|
||||
lua_pushcfunction(L, lua_fs_list_alldirs);
|
||||
lua_setfield(L, -2, "list_alldirs");
|
||||
|
||||
lua_pushcfunction(L, lua_fs_relative);
|
||||
lua_setfield(L, -2, "relative_to");
|
||||
|
||||
lua_pushvalue(L, -1);
|
||||
lua_setfield(L, LUA_GLOBALSINDEX, "fs");
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_fs_list_dir(lua_State* L)
|
||||
{
|
||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a path to make the second argument relative to");
|
||||
const char* fpath = lua_tostring(L, 1);
|
||||
lua_newtable(L);
|
||||
uint32_t i = 1;
|
||||
for (const std::filesystem::path& p : std::filesystem::directory_iterator(fpath))
|
||||
{
|
||||
const std::string x = p.string();
|
||||
lua_pushlstring(L, x.c_str(), x.size());
|
||||
lua_rawseti(L, -2, i);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_fs_list_alldirs(lua_State* L)
|
||||
{
|
||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a path to make the second argument relative to");
|
||||
const char* fpath = lua_tostring(L, 1);
|
||||
lua_newtable(L);
|
||||
uint32_t i = 1;
|
||||
for (const std::filesystem::path& p : std::filesystem::directory_iterator(fpath))
|
||||
{
|
||||
const std::string x = p.string();
|
||||
lua_pushlstring(L, x.c_str(), x.size());
|
||||
lua_rawseti(L, -2, i);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_fs_foreach_dir(lua_State* L)
|
||||
{
|
||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a path");
|
||||
const char* path = lua_tostring(L, 1);
|
||||
|
||||
void* ud = lua_newuserdata(L, sizeof(std::filesystem::directory_iterator));
|
||||
new (ud) std::filesystem::directory_iterator(path);
|
||||
|
||||
luaL_getmetatable(L, "fs.stdlibcpp.filesystem.directory_iterator");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushcclosure(L, lua_fs_foreach_dir_next, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_fs_forall_dir(lua_State* L)
|
||||
{
|
||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a path");
|
||||
const char* path = lua_tostring(L, 1);
|
||||
|
||||
void* ud = lua_newuserdata(L, sizeof(std::filesystem::recursive_directory_iterator));
|
||||
new (ud) std::filesystem::recursive_directory_iterator(path);
|
||||
|
||||
luaL_getmetatable(L, "fs.stdlibcpp.filesystem.recursive_directory_iterator");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pushcclosure(L, lua_fs_forall_dir_next, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_fs_foreach_dir_next(lua_State* L)
|
||||
{
|
||||
int idx = lua_upvalueindex(1);
|
||||
luaL_argcheck(L, lua_type(L, idx) == LUA_TUSERDATA, 1, "Expected first argument to fs.foreach_dir_next to be userdata<std::filesystem::directory_iterator>");
|
||||
void* ud = luaL_checkudata(L, idx, "fs.stdlibcpp.filesystem.directory_iterator");
|
||||
luaL_argcheck(L, ud != nullptr, 1, "Expected first argument's userdata type to be a std::filesystem::directory_iterator");
|
||||
std::filesystem::directory_iterator& x = *(std::filesystem::directory_iterator*)ud;
|
||||
if (x._At_end())
|
||||
return 0;
|
||||
std::string p = (*x).path().string();
|
||||
lua_pushlstring(L, p.c_str(), p.size());
|
||||
x++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_fs_forall_dir_next(lua_State* L)
|
||||
{
|
||||
int idx = lua_upvalueindex(1);
|
||||
luaL_argcheck(L, lua_type(L, idx) == LUA_TUSERDATA, 1, "Expected first argument to fs.forall_dir_next to be userdata<std::filesystem::recursive_directory_iterator>");
|
||||
void* ud = luaL_checkudata(L, idx, "fs.stdlibcpp.filesystem.recursive_directory_iterator");
|
||||
luaL_argcheck(L, ud != nullptr, 1, "Expected first argument's userdata type to be a std::filesystem::recursive_directory_iterator");
|
||||
std::filesystem::recursive_directory_iterator& x = *(std::filesystem::recursive_directory_iterator*)ud;
|
||||
if (x == std::filesystem::recursive_directory_iterator{})
|
||||
return 0;
|
||||
std::string p = (*x).path().string();
|
||||
lua_pushlstring(L, p.c_str(), p.size());
|
||||
x++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_fs_foreach_dir_dtor(lua_State* L)
|
||||
{
|
||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TUSERDATA, 1, "Expected first argument to fs.foreach_dir_next to be userdata<std::filesystem::directory_iterator>");
|
||||
void* ud = luaL_checkudata(L, 1, "fs.stdlibcpp.filesystem.directory_iterator");
|
||||
luaL_argcheck(L, ud != nullptr, 1, "Expected first argument's userdata type to be a std::filesystem::directory_iterator");
|
||||
std::filesystem::directory_iterator& x = *(std::filesystem::directory_iterator*)ud;
|
||||
x.~directory_iterator();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_fs_forall_dir_dtor(lua_State* L)
|
||||
{
|
||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TUSERDATA, 1, "Expected first argument to fs.forall_dir_next to be userdata<std::filesystem::recursive_directory_iterator>");
|
||||
void* ud = luaL_checkudata(L, 1, "fs.stdlibcpp.filesystem.recursive_directory_iterator");
|
||||
luaL_argcheck(L, ud != nullptr, 1, "Expected first argument's userdata type to be a std::filesystem::recursive_directory_iterator");
|
||||
std::filesystem::recursive_directory_iterator& x = *(std::filesystem::recursive_directory_iterator*)ud;
|
||||
x.~recursive_directory_iterator();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_fs_relative(lua_State* L)
|
||||
{
|
||||
try {
|
||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a path to make the second argument relative to");
|
||||
luaL_argcheck(L, lua_type(L, 2) == LUA_TSTRING, 2, "Expected second argument to be a string representing a full file path");
|
||||
const std::string f = std::filesystem::relative(std::filesystem::path(lua_tostring(L, 1)), std::filesystem::path(lua_tostring(L, 2))).string();
|
||||
lua_pushlstring(L, f.c_str(), f.size());
|
||||
return 1;
|
||||
} catch (const std::exception& e)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, e.what());
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
int lua_fs_absolute(lua_State* L)
|
||||
{
|
||||
try {
|
||||
luaL_argcheck(L, lua_type(L, 1) == LUA_TSTRING, 1, "Expected first argument to be a string representing a full file path");
|
||||
const std::string f = std::filesystem::absolute(std::filesystem::path(lua_tostring(L, 1))).string();
|
||||
lua_pushlstring(L, f.c_str(), f.size());
|
||||
return 1;
|
||||
} catch (const std::exception& e)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, e.what());
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
int lua_fs_file_name(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 {
|
||||
const std::string f = std::filesystem::path(lua_tostring(L, 1)).filename().string();
|
||||
lua_pushlstring(L, f.c_str(), f.size());
|
||||
return 1;
|
||||
} catch (const std::exception& e)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, e.what());
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
|
||||
int lua_fs_file_extension(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 {
|
||||
const std::string f = std::filesystem::path(lua_tostring(L, 1)).extension().string();
|
||||
lua_pushlstring(L, f.c_str(), f.size());
|
||||
} catch (const std::exception& e)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, e.what());
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_fs_file_directory(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 {
|
||||
const std::string f = std::filesystem::path(lua_tostring(L, 1)).remove_filename().string();
|
||||
lua_pushlstring(L, f.c_str(), f.size());
|
||||
return 1;
|
||||
} catch (const std::exception& e)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, e.what());
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
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());
|
||||
return 1;
|
||||
} catch (const std::exception& e)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, e.what());
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_fs_exists(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_pushboolean(L, std::filesystem::exists(lua_tostring(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, e.what());
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_fs_is_dir(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_pushboolean(L, std::filesystem::is_directory(lua_tostring(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, e.what());
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_fs_is_file(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_pushboolean(L, std::filesystem::is_regular_file(lua_tostring(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, e.what());
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_fs_create_dir(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_pushboolean(L, std::filesystem::create_directories(lua_tostring(L, 1)));
|
||||
return 1;
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
lua_pushnil(L);
|
||||
lua_pushstring(L, e.what());
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user