2016-11-19 09:28:01 +00:00
|
|
|
#include "lovr/filesystem.h"
|
|
|
|
#include "filesystem/filesystem.h"
|
2016-11-02 03:27:15 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
// Loader to help Lua's require understand PhysFS.
|
|
|
|
static int filesystemLoader(lua_State* L) {
|
|
|
|
const char* module = luaL_checkstring(L, -1);
|
|
|
|
char* dot;
|
|
|
|
|
|
|
|
while ((dot = strchr(module, '.')) != NULL) {
|
|
|
|
*dot = '/';
|
|
|
|
}
|
|
|
|
|
|
|
|
const char* requirePath[] = {
|
|
|
|
"?.lua",
|
|
|
|
"?/init.lua"
|
|
|
|
};
|
|
|
|
|
2016-11-14 22:16:16 +00:00
|
|
|
for (size_t i = 0; i < sizeof(requirePath) / sizeof(char*); i++) {
|
2016-11-02 03:27:15 +00:00
|
|
|
char filename[256];
|
|
|
|
char* sub = strchr(requirePath[i], '?');
|
|
|
|
|
|
|
|
memset(filename, 0, 256);
|
|
|
|
|
|
|
|
if (sub) {
|
|
|
|
int index = (int) (sub - requirePath[i]);
|
|
|
|
strncat(filename, requirePath[i], index);
|
|
|
|
strncat(filename, module, strlen(module));
|
|
|
|
strncat(filename, requirePath[i] + index + 1, strlen(requirePath[i]) - index);
|
|
|
|
|
|
|
|
if (lovrFilesystemIsFile(filename)) {
|
|
|
|
int size;
|
2016-11-05 22:55:01 +00:00
|
|
|
void* data = lovrFilesystemRead(filename, &size);
|
2016-11-02 03:27:15 +00:00
|
|
|
|
|
|
|
if (data) {
|
|
|
|
if (!luaL_loadbuffer(L, data, size, filename)) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
free(data);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
2016-11-01 00:14:31 +00:00
|
|
|
|
|
|
|
const luaL_Reg lovrFilesystem[] = {
|
2016-11-01 01:35:00 +00:00
|
|
|
{ "init", l_lovrFilesystemInitialize },
|
2016-11-07 22:31:11 +00:00
|
|
|
{ "append", l_lovrFilesystemAppend },
|
2016-11-01 00:14:31 +00:00
|
|
|
{ "exists", l_lovrFilesystemExists },
|
|
|
|
{ "getExecutablePath", l_lovrFilesystemGetExecutablePath },
|
2016-11-07 22:30:32 +00:00
|
|
|
{ "getIdentity", l_lovrFilesystemGetIdentity },
|
|
|
|
{ "getRealDirectory", l_lovrFilesystemGetRealDirectory },
|
|
|
|
{ "getSource", l_lovrFilesystemGetSource },
|
|
|
|
{ "getUserDirectory", l_lovrFilesystemGetUserDirectory },
|
2016-11-01 01:35:00 +00:00
|
|
|
{ "isDirectory", l_lovrFilesystemIsDirectory },
|
|
|
|
{ "isFile", l_lovrFilesystemIsFile },
|
2017-03-02 04:08:13 +00:00
|
|
|
{ "load", l_lovrFilesystemLoad },
|
2016-11-05 22:55:01 +00:00
|
|
|
{ "read", l_lovrFilesystemRead },
|
2016-11-07 22:30:32 +00:00
|
|
|
{ "setIdentity", l_lovrFilesystemSetIdentity },
|
2016-11-01 00:14:31 +00:00
|
|
|
{ "setSource", l_lovrFilesystemSetSource },
|
2016-11-07 22:31:02 +00:00
|
|
|
{ "write", l_lovrFilesystemWrite },
|
2016-11-01 00:14:31 +00:00
|
|
|
{ NULL, NULL }
|
|
|
|
};
|
|
|
|
|
|
|
|
int l_lovrFilesystemInit(lua_State* L) {
|
|
|
|
lua_newtable(L);
|
|
|
|
luaL_register(L, NULL, lovrFilesystem);
|
2016-11-02 03:27:15 +00:00
|
|
|
|
|
|
|
// Add custom package loader
|
2016-11-29 07:37:50 +00:00
|
|
|
lua_getglobal(L, "table");
|
|
|
|
lua_getfield(L, -1, "insert");
|
2016-11-02 03:27:15 +00:00
|
|
|
lua_getglobal(L, "package");
|
|
|
|
lua_getfield(L, -1, "loaders");
|
2016-11-29 07:37:50 +00:00
|
|
|
lua_remove(L, -2);
|
2016-11-02 03:27:15 +00:00
|
|
|
if (lua_istable(L, -1)) {
|
2016-11-29 07:37:50 +00:00
|
|
|
lua_pushinteger(L, 2); // Insert our loader after package.preload
|
2016-11-02 03:27:15 +00:00
|
|
|
lua_pushcfunction(L, filesystemLoader);
|
2016-11-29 07:37:50 +00:00
|
|
|
lua_call(L, 3, 0);
|
2016-11-02 03:27:15 +00:00
|
|
|
}
|
|
|
|
|
2016-11-29 07:37:50 +00:00
|
|
|
lua_pop(L, 1);
|
2016-11-02 03:27:15 +00:00
|
|
|
|
2016-11-01 00:14:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrFilesystemInitialize(lua_State* L) {
|
|
|
|
const char* arg0 = luaL_checkstring(L, 1);
|
|
|
|
lovrFilesystemInit(arg0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2016-11-07 22:31:11 +00:00
|
|
|
int l_lovrFilesystemAppend(lua_State* L) {
|
|
|
|
size_t size;
|
|
|
|
const char* path = luaL_checkstring(L, 1);
|
|
|
|
const char* content = luaL_checklstring(L, 2, &size);
|
|
|
|
lua_pushnumber(L, lovrFilesystemAppend(path, content, size));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-11-01 00:14:31 +00:00
|
|
|
int l_lovrFilesystemExists(lua_State* L) {
|
|
|
|
const char* path = luaL_checkstring(L, 1);
|
|
|
|
lua_pushboolean(L, lovrFilesystemExists(path));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrFilesystemGetExecutablePath(lua_State* L) {
|
2016-11-07 22:30:32 +00:00
|
|
|
char buffer[1024];
|
2016-11-01 00:14:31 +00:00
|
|
|
|
2016-11-07 22:30:32 +00:00
|
|
|
if (lovrFilesystemGetExecutablePath(buffer, sizeof(buffer))) {
|
|
|
|
lua_pushnil(L);
|
|
|
|
} else {
|
|
|
|
lua_pushstring(L, buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrFilesystemGetIdentity(lua_State* L) {
|
2016-11-08 21:45:12 +00:00
|
|
|
lua_pushstring(L, lovrFilesystemGetIdentity());
|
2016-11-07 22:30:32 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrFilesystemGetRealDirectory(lua_State* L) {
|
|
|
|
const char* path = luaL_checkstring(L, 1);
|
2016-11-08 21:45:12 +00:00
|
|
|
lua_pushstring(L, lovrFilesystemGetRealDirectory(path));
|
2016-11-07 22:30:32 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrFilesystemGetSource(lua_State* L) {
|
2016-11-08 21:45:12 +00:00
|
|
|
lua_pushstring(L, lovrFilesystemGetSource());
|
2016-11-01 00:14:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-11-07 22:30:32 +00:00
|
|
|
int l_lovrFilesystemGetUserDirectory(lua_State* L) {
|
|
|
|
lua_pushstring(L, lovrFilesystemGetUserDirectory());
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-11-01 01:35:00 +00:00
|
|
|
int l_lovrFilesystemIsDirectory(lua_State* L) {
|
|
|
|
const char* path = luaL_checkstring(L, 1);
|
|
|
|
lua_pushboolean(L, lovrFilesystemIsDirectory(path));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrFilesystemIsFile(lua_State* L) {
|
|
|
|
const char* path = luaL_checkstring(L, 1);
|
|
|
|
lua_pushboolean(L, lovrFilesystemIsFile(path));
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2017-03-02 04:08:13 +00:00
|
|
|
int l_lovrFilesystemLoad(lua_State* L) {
|
|
|
|
const char* path = luaL_checkstring(L, 1);
|
|
|
|
int size;
|
|
|
|
char* content = lovrFilesystemRead(path, &size);
|
|
|
|
|
|
|
|
int status = luaL_loadbuffer(L, content, size, path);
|
|
|
|
switch (status) {
|
|
|
|
case LUA_ERRMEM: return luaL_error(L, "Memory allocation error: %s", lua_tostring(L, -1));
|
|
|
|
case LUA_ERRSYNTAX: return luaL_error(L, "Syntax error: %s", lua_tostring(L, -1));
|
|
|
|
default: return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-05 22:55:01 +00:00
|
|
|
int l_lovrFilesystemRead(lua_State* L) {
|
|
|
|
const char* path = luaL_checkstring(L, 1);
|
|
|
|
int size;
|
2016-11-07 22:30:32 +00:00
|
|
|
char* content = lovrFilesystemRead(path, &size);
|
|
|
|
if (!content) {
|
2016-11-05 22:55:01 +00:00
|
|
|
return luaL_error(L, "Could not read file '%s'", path);
|
|
|
|
}
|
|
|
|
|
2016-11-07 22:30:32 +00:00
|
|
|
lua_pushlstring(L, content, size);
|
2016-11-08 06:23:13 +00:00
|
|
|
free(content);
|
2016-11-05 22:55:01 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2016-11-07 22:30:32 +00:00
|
|
|
int l_lovrFilesystemSetIdentity(lua_State* L) {
|
|
|
|
const char* identity = luaL_checkstring(L, 1);
|
2016-11-01 00:14:31 +00:00
|
|
|
|
2016-11-07 22:30:32 +00:00
|
|
|
if (lovrFilesystemSetIdentity(identity)) {
|
2016-11-12 09:19:47 +00:00
|
|
|
return 0;
|
2016-11-01 00:14:31 +00:00
|
|
|
}
|
|
|
|
|
2016-11-07 22:30:32 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int l_lovrFilesystemSetSource(lua_State* L) {
|
|
|
|
const char* source = luaL_checkstring(L, 1);
|
|
|
|
lua_pushboolean(L, !lovrFilesystemSetSource(source));
|
2016-11-01 00:14:31 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2016-11-07 22:31:02 +00:00
|
|
|
|
|
|
|
int l_lovrFilesystemWrite(lua_State* L) {
|
|
|
|
size_t size;
|
|
|
|
const char* path = luaL_checkstring(L, 1);
|
|
|
|
const char* content = luaL_checklstring(L, 2, &size);
|
|
|
|
lua_pushnumber(L, lovrFilesystemWrite(path, content, size));
|
|
|
|
return 1;
|
|
|
|
}
|