Browse Source

Add a require path (much like package.path) to love.filesystem, allowing to override the searched file paths for require

--HG--
branch : minor
Bart van Strien 11 years ago
parent
commit
ddf6816548
1 changed files with 53 additions and 35 deletions
  1. 53 35
      src/modules/filesystem/wrap_Filesystem.cpp

+ 53 - 35
src/modules/filesystem/wrap_Filesystem.cpp

@@ -28,6 +28,11 @@
 // SDL
 // SDL
 #include <SDL_loadso.h>
 #include <SDL_loadso.h>
 
 
+// STL
+#include <vector>
+#include <string>
+#include <sstream>
+
 namespace love
 namespace love
 {
 {
 namespace filesystem
 namespace filesystem
@@ -505,58 +510,69 @@ int w_isSymlink(lua_State *L)
 	return 1;
 	return 1;
 }
 }
 
 
-int loader(lua_State *L)
+static std::vector<std::string> requirePath = {"?.lua", "?/init.lua"};
+
+int w_getRequirePath(lua_State *L)
 {
 {
-	const char *filename = lua_tostring(L, -1);
+	std::stringstream path;
+	bool seperator = false;
+	for (auto &element : requirePath)
+	{
+		if (seperator)
+			path << ";";
+		else
+			seperator = true;
 
 
-	std::string tmp(filename);
-	tmp += ".lua";
+		path << element;
+	}
 
 
-	int size = tmp.size();
+	luax_pushstring(L, path.str());
+	return 1;
+}
 
 
-	for (int i=0; i<size-4; i++)
-	{
-		if (tmp[i] == '.')
-		{
-			tmp[i] = '/';
-		}
-	}
+int w_setRequirePath(lua_State *L)
+{
+	std::string element = luax_checkstring(L, 1);
 
 
-	// Check whether file exists.
-	if (instance()->isFile(tmp.c_str()))
-	{
-		lua_pop(L, 1);
-		lua_pushstring(L, tmp.c_str());
-		// Ok, load it.
-		return w_load(L);
-	}
+	requirePath.clear();
+	std::stringstream path;
+	path << element;
+
+	while(std::getline(path, element, ';'))
+		requirePath.push_back(element);
+
+	return 0;
+}
 
 
-	tmp = filename;
-	size = tmp.size();
-	for (int i=0; i<size; i++)
+int loader(lua_State *L)
+{
+	std::string modulename = luax_tostring(L, 1);
+
+	for (char &c : modulename)
 	{
 	{
-		if (tmp[i] == '.')
-		{
-			tmp[i] = '/';
-		}
+		if (c == '.')
+			c = '/';
 	}
 	}
 
 
-	if (instance()->isDirectory(tmp.c_str()))
+	auto *inst = instance();
+	for (std::string element : requirePath)
 	{
 	{
-		tmp += "/init.lua";
-		if (instance()->isFile(tmp.c_str()))
+		size_t pos = element.find('?');
+		if (pos == std::string::npos)
+			continue;
+
+		element.replace(pos, 1, modulename);
+		if (inst->isFile(element.c_str()))
 		{
 		{
 			lua_pop(L, 1);
 			lua_pop(L, 1);
-			lua_pushstring(L, tmp.c_str());
-			// Ok, load it.
+			lua_pushstring(L, element.c_str());
 			return w_load(L);
 			return w_load(L);
 		}
 		}
 	}
 	}
 
 
-	std::string errstr = "\n\tno file '%s' in LOVE game directories.";
-	errstr += errstr;
+	std::string errstr = "\n\tno '%s' in LOVE game directories.";
 
 
-	lua_pushfstring(L, errstr.c_str(), (tmp + ".lua").c_str(), (tmp + "/init.lua").c_str());
+	lua_pushfstring(L, errstr.c_str(), modulename.c_str());
 	return 1;
 	return 1;
 }
 }
 
 
@@ -667,6 +683,8 @@ static const luaL_Reg functions[] =
 	{ "areSymlinksEnabled", w_areSymlinksEnabled },
 	{ "areSymlinksEnabled", w_areSymlinksEnabled },
 	{ "isSymlink", w_isSymlink },
 	{ "isSymlink", w_isSymlink },
 	{ "newFileData", w_newFileData },
 	{ "newFileData", w_newFileData },
+	{ "getRequirePath", w_getRequirePath },
+	{ "setRequirePath", w_setRequirePath },
 	{ 0, 0 }
 	{ 0, 0 }
 };
 };