From 94ce5581265d6a217be5d6451ca1d54a5fc0cc51 Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Thu, 27 Jul 2017 19:54:56 -0300 Subject: [PATCH] require now looks for both .dylib and .so extensions for C dynamic libraries in macOS, instead of just .so. It also now replaces all occurrences of '??' and '?' in the path with the module filename and module name respectively, rather than just the first occurrence. --HG-- branch : minor --- src/modules/filesystem/physfs/File.cpp | 9 ++- src/modules/filesystem/wrap_Filesystem.cpp | 66 ++++++++++++++-------- 2 files changed, 48 insertions(+), 27 deletions(-) diff --git a/src/modules/filesystem/physfs/File.cpp b/src/modules/filesystem/physfs/File.cpp index 5d7670b73..0b2f47a34 100644 --- a/src/modules/filesystem/physfs/File.cpp +++ b/src/modules/filesystem/physfs/File.cpp @@ -151,8 +151,6 @@ int64 File::read(void *dst, int64 size) int64 max = (int64)PHYSFS_fileLength(file); size = (size == ALL) ? max : size; size = (size > max) ? max : size; - // Sadly, we'll have to clamp to 32 bits here - size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size; if (size < 0) throw love::Exception("Invalid read size."); @@ -160,6 +158,8 @@ int64 File::read(void *dst, int64 size) #ifdef LOVE_USE_PHYSFS_2_1 int64 read = PHYSFS_readBytes(file, dst, (PHYSFS_uint64) size); #else + // Sadly, we'll have to clamp to 32 bits here + size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size; int64 read = (int64)PHYSFS_read(file, dst, 1, (PHYSFS_uint32) size); #endif @@ -171,9 +171,6 @@ bool File::write(const void *data, int64 size) if (!file || (mode != MODE_WRITE && mode != MODE_APPEND)) throw love::Exception("File is not opened for writing."); - // Another clamp, for the time being. - size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size; - if (size < 0) throw love::Exception("Invalid write size."); @@ -181,6 +178,8 @@ bool File::write(const void *data, int64 size) #ifdef LOVE_USE_PHYSFS_2_1 int64 written = PHYSFS_writeBytes(file, data, (PHYSFS_uint64) size); #else + // Another clamp, for the time being. + size = (size > LOVE_UINT32_MAX) ? LOVE_UINT32_MAX : size; int64 written = (int64) PHYSFS_write(file, data, 1, (PHYSFS_uint32) size); #endif diff --git a/src/modules/filesystem/wrap_Filesystem.cpp b/src/modules/filesystem/wrap_Filesystem.cpp index f6d03870c..319bc69e8 100644 --- a/src/modules/filesystem/wrap_Filesystem.cpp +++ b/src/modules/filesystem/wrap_Filesystem.cpp @@ -634,6 +634,22 @@ int w_setCRequirePath(lua_State *L) return 0; } +static void replaceAll(std::string &str, const std::string &substr, const std::string &replacement) +{ + std::vector locations; + size_t pos = 0; + size_t sublen = substr.length(); + + while ((pos = str.find(substr, pos)) != std::string::npos) + { + locations.push_back(pos); + pos += sublen; + } + + for (int i = (int) locations.size() - 1; i >= 0; i--) + str.replace(locations[i], sublen, replacement); +} + int loader(lua_State *L) { std::string modulename = luax_tostring(L, 1); @@ -647,9 +663,7 @@ int loader(lua_State *L) auto *inst = instance(); for (std::string element : inst->getRequirePath()) { - size_t pos = 0; - while ((pos = element.find('?', pos)) != std::string::npos) - element.replace(pos, 1, modulename); + replaceAll(element, "?", modulename); if (inst->isFile(element.c_str())) { @@ -665,14 +679,16 @@ int loader(lua_State *L) return 1; } -inline const char *library_extension() +static const char *library_extensions[] = { #ifdef LOVE_WINDOWS - return ".dll"; + ".dll" +#elif defined(LOVE_MACOSX) || defined(LOVE_IOS) + ".dylib", ".so" #else - return ".so"; + ".so" #endif -} +}; int extloader(lua_State *L) { @@ -694,25 +710,31 @@ int extloader(lua_State *L) void *handle = nullptr; auto *inst = instance(); - for (std::string element : inst->getCRequirePath()) + + for (const std::string &el : inst->getCRequirePath()) { - // Replace ?? with the filename and extension - size_t pos = element.find("??"); - if (pos != std::string::npos) - element.replace(pos, 2, tokenized_name + library_extension()); - // Or ? with just the filename - pos = element.find('?'); - if (pos != std::string::npos) - element.replace(pos, 1, tokenized_name); + for (const char *ext : library_extensions) + { + std::string element = el; - if (!inst->isFile(element.c_str())) - continue; + // Replace ?? with the filename and extension + replaceAll(element, "??", tokenized_name + ext); - // Now resolve the full path, as we're bypassing physfs for the next part. - element = inst->getRealDirectory(element.c_str()) + LOVE_PATH_SEPARATOR + element; + // And ? with just the filename + replaceAll(element, "?", tokenized_name); + + if (!inst->isFile(element.c_str())) + continue; + + // Now resolve the full path, as we're bypassing physfs for the next part. + std::string filepath = inst->getRealDirectory(element.c_str()) + LOVE_PATH_SEPARATOR + element; + + handle = SDL_LoadObject(filepath.c_str()); + // Can fail, for instance if it turned out the source was a zip + if (handle) + break; + } - handle = SDL_LoadObject(element.c_str()); - // Can fail, for instance if it turned out the source was a zip if (handle) break; }