mirror of
https://github.com/aseprite/aseprite.git
synced 2025-04-25 03:02:31 +00:00
236 lines
5.5 KiB
C++
236 lines
5.5 KiB
C++
// Aseprite
|
|
// Copyright (C) 2019-2020 Igara Studio S.A.
|
|
//
|
|
// This program is distributed under the terms of
|
|
// the End-User License Agreement for Aseprite.
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include "app/app.h"
|
|
#include "app/resource_finder.h"
|
|
#include "app/script/luacpp.h"
|
|
#include "app/script/security.h"
|
|
#include "base/fs.h"
|
|
|
|
namespace app {
|
|
namespace script {
|
|
|
|
namespace {
|
|
|
|
struct AppFS { };
|
|
|
|
int AppFS_pathSeparator(lua_State* L)
|
|
{
|
|
const char sep[2] = { base::path_separator, 0 };
|
|
lua_pushstring(L, sep);
|
|
return 1;
|
|
}
|
|
|
|
template<std::string (*Func)(const std::string& path)>
|
|
int AppFS_pathElement(lua_State* L)
|
|
{
|
|
const char* fn = lua_tostring(L, 1);
|
|
if (fn)
|
|
lua_pushstring(L, Func(fn).c_str());
|
|
else
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int AppFS_joinPath(lua_State* L)
|
|
{
|
|
const char* fn = lua_tostring(L, 1);
|
|
if (!fn) {
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
std::string result(fn);
|
|
const int n = lua_gettop(L);
|
|
for (int i=2; i<=n; ++i) {
|
|
const char* part = lua_tostring(L, i);
|
|
if (part)
|
|
result = base::join_path(result, part);
|
|
}
|
|
lua_pushstring(L, result.c_str());
|
|
return 1;
|
|
}
|
|
|
|
template<std::string (*Func)()>
|
|
int AppFS_get_specialPath(lua_State* L)
|
|
{
|
|
lua_pushstring(L, Func().c_str());
|
|
return 1;
|
|
}
|
|
|
|
int AppFS_get_userConfigPath(lua_State* L)
|
|
{
|
|
ResourceFinder rf(false);
|
|
rf.includeUserDir("");
|
|
std::string dir = rf.defaultFilename();
|
|
lua_pushstring(L, dir.c_str());
|
|
return 1;
|
|
}
|
|
|
|
int AppFS_isFile(lua_State* L)
|
|
{
|
|
const char* fn = lua_tostring(L, 1);
|
|
if (fn)
|
|
lua_pushboolean(L, base::is_file(fn));
|
|
else
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
int AppFS_isDirectory(lua_State* L)
|
|
{
|
|
const char* fn = lua_tostring(L, 1);
|
|
if (fn)
|
|
lua_pushboolean(L, base::is_directory(fn));
|
|
else
|
|
lua_pushboolean(L, false);
|
|
return 1;
|
|
}
|
|
|
|
int AppFS_fileSize(lua_State* L)
|
|
{
|
|
const char* fn = lua_tostring(L, 1);
|
|
if (fn)
|
|
lua_pushinteger(L, base::file_size(fn));
|
|
else
|
|
lua_pushnil(L);
|
|
return 1;
|
|
}
|
|
|
|
int AppFS_listFiles(lua_State* L)
|
|
{
|
|
const char* path = lua_tostring(L, 1);
|
|
lua_newtable(L);
|
|
if (path) {
|
|
int i = 0;
|
|
for (auto fn : base::list_files(path)) {
|
|
lua_pushstring(L, fn.c_str());
|
|
lua_seti(L, -2, ++i);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int AppFS_makeDirectory(lua_State* L)
|
|
{
|
|
const char* path = luaL_checkstring(L, 1);
|
|
if (base::is_directory(path)) {
|
|
lua_pushboolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
if (!ask_access(L, path, FileAccessMode::Full, ResourceType::File))
|
|
return luaL_error(L, "the script doesn't have access to create the directory '%s'", path);
|
|
|
|
try {
|
|
// TODO don't throw exception from base::make_directory() function
|
|
base::make_directory(path);
|
|
}
|
|
catch (const std::exception&) {
|
|
// Do nothing
|
|
}
|
|
lua_pushboolean(L, base::is_directory(path));
|
|
return 1;
|
|
}
|
|
|
|
int AppFS_makeAllDirectories(lua_State* L)
|
|
{
|
|
const char* path = luaL_checkstring(L, 1);
|
|
if (base::is_directory(path)) {
|
|
lua_pushboolean(L, true);
|
|
return 1;
|
|
}
|
|
|
|
if (!ask_access(L, path, FileAccessMode::Write, ResourceType::File))
|
|
return luaL_error(L, "the script doesn't have access to create all directories '%s'", path);
|
|
|
|
try {
|
|
base::make_all_directories(path);
|
|
}
|
|
catch (const std::exception&) {
|
|
// Do nothing
|
|
}
|
|
lua_pushboolean(L, base::is_directory(path));
|
|
return 1;
|
|
}
|
|
|
|
int AppFS_removeDirectory(lua_State* L)
|
|
{
|
|
const char* path = luaL_checkstring(L, 1);
|
|
if (!base::is_directory(path)) {
|
|
lua_pushboolean(L, (base::is_file(path) ? false: // Cannot remove files
|
|
true)); // The directory is already removed
|
|
return 1;
|
|
}
|
|
|
|
if (!ask_access(L, path, FileAccessMode::Write, ResourceType::File))
|
|
return luaL_error(L, "the script doesn't have access to remove the directory '%s'", path);
|
|
|
|
try {
|
|
base::remove_directory(path);
|
|
}
|
|
catch (const std::exception&) {
|
|
// do nothing...
|
|
}
|
|
lua_pushboolean(L, !base::is_directory(path));
|
|
return 1;
|
|
}
|
|
|
|
const Property AppFS_properties[] = {
|
|
{ "pathSeparator", AppFS_pathSeparator, nullptr },
|
|
// Special folder names
|
|
{ "currentPath", AppFS_get_specialPath<base::get_current_path>, nullptr },
|
|
{ "appPath", AppFS_get_specialPath<base::get_app_path>, nullptr },
|
|
{ "tempPath", AppFS_get_specialPath<base::get_temp_path>, nullptr },
|
|
{ "userDocsPath", AppFS_get_specialPath<base::get_user_docs_folder>, nullptr },
|
|
{ "userConfigPath", AppFS_get_userConfigPath, nullptr },
|
|
{ nullptr, nullptr, nullptr }
|
|
};
|
|
|
|
const luaL_Reg AppFS_methods[] = {
|
|
// Path manipulation
|
|
{ "filePath", AppFS_pathElement<base::get_file_path> },
|
|
{ "fileName", AppFS_pathElement<base::get_file_name> },
|
|
{ "fileExtension", AppFS_pathElement<base::get_file_extension> },
|
|
{ "fileTitle", AppFS_pathElement<base::get_file_title> },
|
|
{ "filePathAndTitle", AppFS_pathElement<base::get_file_title_with_path> },
|
|
{ "normalizePath", AppFS_pathElement<base::normalize_path> },
|
|
{ "joinPath", AppFS_joinPath },
|
|
// File system information
|
|
{ "isFile", AppFS_isFile },
|
|
{ "isDirectory", AppFS_isDirectory },
|
|
{ "fileSize", AppFS_fileSize },
|
|
{ "listFiles", AppFS_listFiles },
|
|
// Manipulate directories
|
|
{ "makeDirectory", AppFS_makeDirectory },
|
|
{ "makeAllDirectories", AppFS_makeAllDirectories },
|
|
{ "removeDirectory", AppFS_removeDirectory },
|
|
{ nullptr, nullptr }
|
|
};
|
|
|
|
} // anonymous namespace
|
|
|
|
DEF_MTNAME(AppFS);
|
|
|
|
void register_app_fs_object(lua_State* L)
|
|
{
|
|
REG_CLASS(L, AppFS);
|
|
REG_CLASS_PROPERTIES(L, AppFS);
|
|
|
|
lua_getglobal(L, "app");
|
|
lua_pushstring(L, "fs");
|
|
push_new<AppFS>(L);
|
|
lua_rawset(L, -3);
|
|
lua_pop(L, 1);
|
|
}
|
|
|
|
} // namespace script
|
|
} // namespace app
|