Merged default into minor

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2014-07-30 01:32:10 -03:00
42 changed files with 640 additions and 356 deletions
+41 -15
View File
@@ -21,6 +21,7 @@
#include "common/config.h"
#include <iostream>
#include <sstream>
#include "common/utf8.h"
#include "common/b64.h"
@@ -47,6 +48,21 @@ namespace
{
return input.substr(getDriveDelim(input)+1);
}
std::string normalize(const std::string &input)
{
std::stringstream out;
bool seenSep = false, isSep = false;
for (size_t i = 0; i < input.size(); ++i)
{
isSep = (input[i] == LOVE_PATH_SEPARATOR[0]);
if (!isSep || !seenSep)
out << input[i];
seenSep = isSep;
}
return out.str();
}
}
namespace love
@@ -116,6 +132,8 @@ bool Filesystem::setIdentity(const char *ident, bool appendToPath)
else
save_path_full += save_path_relative;
save_path_full = normalize(save_path_full);
// We now have something like:
// save_identity: game
// save_path_relative: ./LOVE/game
@@ -354,40 +372,33 @@ const char *Filesystem::getWorkingDirectory()
std::string Filesystem::getUserDirectory()
{
return std::string(PHYSFS_getUserDir());
static std::string userDir = normalize(PHYSFS_getUserDir());
return userDir;
}
std::string Filesystem::getAppdataDirectory()
{
#ifdef LOVE_WINDOWS
if (appdata.empty())
{
#ifdef LOVE_WINDOWS
wchar_t *w_appdata = _wgetenv(L"APPDATA");
appdata = to_utf8(w_appdata);
replace_char(appdata, '\\', '/');
}
return appdata;
#elif defined(LOVE_MACOSX)
if (appdata.empty())
{
std::string udir = getUserDirectory();
udir.append("/Library/Application Support");
appdata = udir;
}
return appdata;
appdata = normalize(udir);
#elif defined(LOVE_LINUX)
if (appdata.empty())
{
char *xdgdatahome = getenv("XDG_DATA_HOME");
if (!xdgdatahome)
appdata = std::string(getUserDirectory()) + "/.local/share/";
appdata = normalize(std::string(getUserDirectory()) + "/.local/share/");
else
appdata = xdgdatahome;
#else
appdata = getUserDirectory();
#endif
}
return appdata;
#else
return getUserDirectory();
#endif
}
@@ -645,6 +656,21 @@ int64 Filesystem::getSize(const char *filename) const
return size;
}
void Filesystem::setSymlinksEnabled(bool enable)
{
PHYSFS_permitSymbolicLinks(enable ? 1 : 0);
}
bool Filesystem::areSymlinksEnabled() const
{
return PHYSFS_symbolicLinksPermitted() != 0;
}
bool Filesystem::isSymlink(const char *filename) const
{
return PHYSFS_isSymbolicLink(filename) != 0;
}
} // physfs
} // filesystem
} // love
@@ -80,6 +80,8 @@ public:
Filesystem();
virtual ~Filesystem();
// Implements Module.
virtual ModuleType getModuleType() const { return M_FILESYSTEM; }
const char *getName() const;
void init(const char *arg0);
@@ -237,6 +239,22 @@ public:
**/
int64 getSize(const char *filename) const;
/**
* Enable or disable symbolic link support in love.filesystem.
**/
void setSymlinksEnabled(bool enable);
/**
* Gets whether symbolic link support is enabled.
**/
bool areSymlinksEnabled() const;
/**
* Gets whether a filepath is actually a symlink.
* Always returns false if symlinks are not enabled.
**/
bool isSymlink(const char *filename) const;
/**
* Text file line-reading iterator function used and
* pushed on the Lua stack by love.filesystem.lines
+65 -42
View File
@@ -32,20 +32,20 @@ namespace love
{
namespace filesystem
{
static physfs::Filesystem *instance = 0;
#define instance() (Module::getInstance<physfs::Filesystem>(Module::M_FILESYSTEM))
bool hack_setupWriteDirectory()
{
if (instance != 0)
return instance->setupWriteDirectory();
if (instance() != 0)
return instance()->setupWriteDirectory();
return false;
}
int w_init(lua_State *L)
{
const char *arg0 = luaL_checkstring(L, 1);
luax_catchexcept(L, [&](){ instance->init(arg0); });
luax_catchexcept(L, [&](){ instance()->init(arg0); });
return 0;
}
@@ -53,13 +53,13 @@ int w_setFused(lua_State *L)
{
// no error checking needed, everything, even nothing
// can be converted to a boolean
instance->setFused(luax_toboolean(L, 1));
instance()->setFused(luax_toboolean(L, 1));
return 0;
}
int w_isFused(lua_State *L)
{
luax_pushboolean(L, instance->isFused());
luax_pushboolean(L, instance()->isFused());
return 1;
}
@@ -68,7 +68,7 @@ int w_setIdentity(lua_State *L)
const char *arg = luaL_checkstring(L, 1);
bool append = luax_optboolean(L, 2, false);
if (!instance->setIdentity(arg, append))
if (!instance()->setIdentity(arg, append))
return luaL_error(L, "Could not set write directory.");
return 0;
@@ -76,7 +76,7 @@ int w_setIdentity(lua_State *L)
int w_getIdentity(lua_State *L)
{
lua_pushstring(L, instance->getIdentity());
lua_pushstring(L, instance()->getIdentity());
return 1;
}
@@ -84,7 +84,7 @@ int w_setSource(lua_State *L)
{
const char *arg = luaL_checkstring(L, 1);
if (!instance->setSource(arg))
if (!instance()->setSource(arg))
return luaL_error(L, "Could not set source.");
return 0;
@@ -92,7 +92,7 @@ int w_setSource(lua_State *L)
int w_getSource(lua_State *L)
{
lua_pushstring(L, instance->getSource());
lua_pushstring(L, instance()->getSource());
return 1;
}
@@ -102,7 +102,7 @@ int w_mount(lua_State *L)
const char *mountpoint = luaL_checkstring(L, 2);
bool append = luax_optboolean(L, 3, false);
luax_pushboolean(L, instance->mount(archive, mountpoint, append));
luax_pushboolean(L, instance()->mount(archive, mountpoint, append));
return 1;
}
@@ -110,7 +110,7 @@ int w_unmount(lua_State *L)
{
const char *archive = luaL_checkstring(L, 1);
luax_pushboolean(L, instance->unmount(archive));
luax_pushboolean(L, instance()->unmount(archive));
return 1;
}
@@ -128,7 +128,7 @@ int w_newFile(lua_State *L)
return luaL_error(L, "Incorrect file open mode: %s", str);
}
File *t = instance->newFile(filename);
File *t = instance()->newFile(filename);
if (mode != File::CLOSED)
{
@@ -156,7 +156,7 @@ FileData *luax_getfiledata(lua_State *L, int idx)
if (lua_isstring(L, idx))
{
const char *filename = luaL_checkstring(L, idx);
file = instance->newFile(filename);
file = instance()->newFile(filename);
}
else if (luax_istype(L, idx, FILESYSTEM_FILE_T))
{
@@ -231,10 +231,10 @@ int w_newFileData(lua_State *L)
switch (decoder)
{
case FileData::FILE:
t = instance->newFileData((void *)str, (int)length, filename);
t = instance()->newFileData((void *)str, (int)length, filename);
break;
case FileData::BASE64:
t = instance->newFileData(str, filename);
t = instance()->newFileData(str, filename);
break;
default:
return luaL_error(L, "Invalid FileData decoder: %s", decstr);
@@ -246,59 +246,59 @@ int w_newFileData(lua_State *L)
int w_getWorkingDirectory(lua_State *L)
{
lua_pushstring(L, instance->getWorkingDirectory());
lua_pushstring(L, instance()->getWorkingDirectory());
return 1;
}
int w_getUserDirectory(lua_State *L)
{
luax_pushstring(L, instance->getUserDirectory());
luax_pushstring(L, instance()->getUserDirectory());
return 1;
}
int w_getAppdataDirectory(lua_State *L)
{
luax_pushstring(L, instance->getAppdataDirectory());
luax_pushstring(L, instance()->getAppdataDirectory());
return 1;
}
int w_getSaveDirectory(lua_State *L)
{
lua_pushstring(L, instance->getSaveDirectory());
lua_pushstring(L, instance()->getSaveDirectory());
return 1;
}
int w_getSourceBaseDirectory(lua_State *L)
{
luax_pushstring(L, instance->getSourceBaseDirectory());
luax_pushstring(L, instance()->getSourceBaseDirectory());
return 1;
}
int w_isDirectory(lua_State *L)
{
const char *arg = luaL_checkstring(L, 1);
luax_pushboolean(L, instance->isDirectory(arg));
luax_pushboolean(L, instance()->isDirectory(arg));
return 1;
}
int w_isFile(lua_State *L)
{
const char *arg = luaL_checkstring(L, 1);
luax_pushboolean(L, instance->isFile(arg));
luax_pushboolean(L, instance()->isFile(arg));
return 1;
}
int w_createDirectory(lua_State *L)
{
const char *arg = luaL_checkstring(L, 1);
luax_pushboolean(L, instance->createDirectory(arg));
luax_pushboolean(L, instance()->createDirectory(arg));
return 1;
}
int w_remove(lua_State *L)
{
const char *arg = luaL_checkstring(L, 1);
luax_pushboolean(L, instance->remove(arg));
luax_pushboolean(L, instance()->remove(arg));
return 1;
}
@@ -310,7 +310,7 @@ int w_read(lua_State *L)
Data *data = 0;
try
{
data = instance->read(filename, len);
data = instance()->read(filename, len);
}
catch (love::Exception &e)
{
@@ -356,9 +356,9 @@ static int w_write_or_append(lua_State *L, File::Mode mode)
try
{
if (mode == File::APPEND)
instance->append(filename, (const void *) input, len);
instance()->append(filename, (const void *) input, len);
else
instance->write(filename, (const void *) input, len);
instance()->write(filename, (const void *) input, len);
}
catch (love::Exception &e)
{
@@ -381,7 +381,7 @@ int w_append(lua_State *L)
int w_getDirectoryItems(lua_State *L)
{
return instance->getDirectoryItems(L);
return instance()->getDirectoryItems(L);
}
int w_lines(lua_State *L)
@@ -390,7 +390,7 @@ int w_lines(lua_State *L)
if (lua_isstring(L, 1))
{
file = instance->newFile(lua_tostring(L, 1));
file = instance()->newFile(lua_tostring(L, 1));
bool success = false;
luax_catchexcept(L, [&](){ success = file->open(File::READ); });
@@ -414,7 +414,7 @@ int w_load(lua_State *L)
Data *data = 0;
try
{
data = instance->read(filename.c_str());
data = instance()->read(filename.c_str());
}
catch (love::Exception &e)
{
@@ -444,7 +444,7 @@ int w_getLastModified(lua_State *L)
int64 time = 0;
try
{
time = instance->getLastModified(filename);
time = instance()->getLastModified(filename);
}
catch (love::Exception &e)
{
@@ -462,7 +462,7 @@ int w_getSize(lua_State *L)
int64 size = -1;
try
{
size = instance->getSize(filename);
size = instance()->getSize(filename);
}
catch (love::Exception &e)
{
@@ -479,6 +479,25 @@ int w_getSize(lua_State *L)
return 1;
}
int w_setSymlinksEnabled(lua_State *L)
{
instance()->setSymlinksEnabled(luax_toboolean(L, 1));
return 0;
}
int w_areSymlinksEnabled(lua_State *L)
{
luax_pushboolean(L, instance()->areSymlinksEnabled());
return 1;
}
int w_isSymlink(lua_State *L)
{
const char *filename = luaL_checkstring(L, 1);
luax_pushboolean(L, instance()->isSymlink(filename));
return 1;
}
int loader(lua_State *L)
{
const char *filename = lua_tostring(L, -1);
@@ -497,7 +516,7 @@ int loader(lua_State *L)
}
// Check whether file exists.
if (instance->isFile(tmp.c_str()))
if (instance()->isFile(tmp.c_str()))
{
lua_pop(L, 1);
lua_pushstring(L, tmp.c_str());
@@ -515,10 +534,10 @@ int loader(lua_State *L)
}
}
if (instance->isDirectory(tmp.c_str()))
if (instance()->isDirectory(tmp.c_str()))
{
tmp += "/init.lua";
if (instance->isFile(tmp.c_str()))
if (instance()->isFile(tmp.c_str()))
{
lua_pop(L, 1);
lua_pushstring(L, tmp.c_str());
@@ -563,15 +582,15 @@ int extloader(lua_State *L)
void *handle = nullptr;
// If the game is fused, try looking for the DLL in the game's read paths.
if (instance->isFused())
if (instance()->isFused())
{
try
{
std::string dir = instance->getRealDirectory(tokenized_name.c_str());
std::string dir = instance()->getRealDirectory(tokenized_name.c_str());
// We don't want to look in the game's source, because it can be a
// zip sometimes and a folder other times.
if (dir.find(instance->getSource()) == std::string::npos)
if (dir.find(instance()->getSource()) == std::string::npos)
handle = SDL_LoadObject((dir + LOVE_PATH_SEPARATOR + tokenized_name).c_str());
}
catch (love::Exception &)
@@ -582,7 +601,7 @@ int extloader(lua_State *L)
if (!handle)
{
std::string path = std::string(instance->getAppdataDirectory()) + LOVE_PATH_SEPARATOR LOVE_APPDATA_FOLDER LOVE_PATH_SEPARATOR + tokenized_name;
std::string path = std::string(instance()->getAppdataDirectory()) + LOVE_PATH_SEPARATOR LOVE_APPDATA_FOLDER LOVE_PATH_SEPARATOR + tokenized_name;
handle = SDL_LoadObject(path.c_str());
}
@@ -637,6 +656,9 @@ static const luaL_Reg functions[] =
{ "load", w_load },
{ "getLastModified", w_getLastModified },
{ "getSize", w_getSize },
{ "setSymlinksEnabled", w_setSymlinksEnabled },
{ "areSymlinksEnabled", w_areSymlinksEnabled },
{ "isSymlink", w_isSymlink },
{ "newFileData", w_newFileData },
{ 0, 0 }
};
@@ -650,7 +672,8 @@ static const lua_CFunction types[] =
extern "C" int luaopen_love_filesystem(lua_State *L)
{
if (instance == 0)
physfs::Filesystem *instance = instance();
if (instance == nullptr)
{
luax_catchexcept(L, [&](){ instance = new physfs::Filesystem(); });
}
+3
View File
@@ -70,6 +70,9 @@ int w_lines(lua_State *L);
int w_load(lua_State *L);
int w_getLastModified(lua_State *L);
int w_getSize(lua_State *L);
int w_setSymlinksEnabled(lua_State *L);
int w_areSymlinksEnabled(lua_State *L);
int w_isSymlink(lua_State *L);
int loader(lua_State *L);
int extloader(lua_State *L);
extern "C" LOVE_EXPORT int luaopen_love_filesystem(lua_State *L);