diff options
author | Mnikolenko Productengine <mnikolenko@productengine.com> | 2024-02-23 16:57:00 +0200 |
---|---|---|
committer | Mnikolenko Productengine <mnikolenko@productengine.com> | 2024-02-23 16:57:00 +0200 |
commit | 49785357e07f6309e2504b56829d9916f75168b2 (patch) | |
tree | 3c1c1f6f2ae167f806b47bf062e54bdb9838f1d7 /indra/newview/llluamanager.cpp | |
parent | 32bf9c7b7a9d2b2428b052d74389ec48ccc427cf (diff) |
require() code clean-up
Diffstat (limited to 'indra/newview/llluamanager.cpp')
-rw-r--r-- | indra/newview/llluamanager.cpp | 89 |
1 files changed, 25 insertions, 64 deletions
diff --git a/indra/newview/llluamanager.cpp b/indra/newview/llluamanager.cpp index 164738bc3b..671410d420 100644 --- a/indra/newview/llluamanager.cpp +++ b/indra/newview/llluamanager.cpp @@ -46,6 +46,7 @@ extern LLUIListener sUIListener; #endif // ! LL_TEST #include <boost/algorithm/string/replace.hpp> +#include <filesystem> #include "luau/luacode.h" #include "luau/lua.h" @@ -307,8 +308,7 @@ void LLLUAmanager::runScriptFile(LuaState& L, const std::string& filename, scrip if (in_file.is_open()) { - std::string text{std::istreambuf_iterator<char>(in_file), - std::istreambuf_iterator<char>()}; + std::string text{std::istreambuf_iterator<char>(in_file), {}}; auto [count, result] = L.expr(filename, text); if (cb) { @@ -402,28 +402,6 @@ void LLLUAmanager::runScriptOnLogin() #endif // ! LL_TEST } - -bool is_absolute_path(std::string_view path) -{ -#ifdef LL_WINDOWS - // Must either begin with "X:/", "X:\", "/", or "\", where X is a drive letter - return (path.size() >= 3 && isalpha(path[0]) && path[1] == ':' && (path[2] == '/' || path[2] == '\\')) || - (path.size() >= 1 && (path[0] == '/' || path[0] == '\\')); -#else - // Must begin with '/' - return path.size() >= 1 && path[0] == '/'; -#endif -} - -std::string join_paths(const std::string &lhs, const std::string &rhs) -{ - std::string result = lhs; - if (!result.empty() && result.back() != '/' && result.back() != '\\') - result += '/'; - result += rhs; - return result; -} - std::string read_file(const std::string &name) { llifstream in_file; @@ -431,20 +409,22 @@ std::string read_file(const std::string &name) if (in_file.is_open()) { - std::string text {std::istreambuf_iterator<char>(in_file), std::istreambuf_iterator<char>()}; + std::string text {std::istreambuf_iterator<char>(in_file), {}}; return text; } return std::string(); } -LLRequireResolver::LLRequireResolver(lua_State *L, std::string path) : mPathToResolve(std::move(path)), L(L) +LLRequireResolver::LLRequireResolver(lua_State *L, const std::string& path) : mPathToResolve(path), L(L) { lua_Debug ar; lua_getinfo(L, 1, "s", &ar); mSourceChunkname = ar.source; - if (is_absolute_path(mPathToResolve)) + mPathToResolve = std::filesystem::path(mPathToResolve).lexically_normal().string(); + + if (std::filesystem::path(mPathToResolve).is_absolute()) luaL_argerrorL(L, 1, "cannot require a full path"); std::replace(mPathToResolve.begin(), mPathToResolve.end(), '\\', '/'); @@ -457,7 +437,7 @@ LLRequireResolver::LLRequireResolver(lua_State *L, std::string path) : mPathToRe if (status != ModuleStatus::FileRead) return ResolvedRequire {status}; else - return ResolvedRequire {status, std::move(resolver.mChunkname), std::move(resolver.mAbsolutePath), std::move(resolver.mSourceCode)}; + return ResolvedRequire {status, resolver.mAbsolutePath, resolver.mSourceCode}; } LLRequireResolver::ModuleStatus LLRequireResolver::findModule() @@ -467,26 +447,24 @@ LLRequireResolver::ModuleStatus LLRequireResolver::findModule() // Put _MODULES table on stack for checking and saving to the cache luaL_findtable(L, LUA_REGISTRYINDEX, "_MODULES", 1); + // Check if the module is already in _MODULES table, read from file otherwise LLRequireResolver::ModuleStatus moduleStatus = findModuleImpl(); if (moduleStatus != LLRequireResolver::ModuleStatus::NotFound) return moduleStatus; - if (is_absolute_path(mPathToResolve)) + if (std::filesystem::path(mPathToResolve).is_absolute()) return moduleStatus; - std::vector<std::string> lib_paths; - - lib_paths.push_back(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "")); + std::vector<std::string> lib_paths {gDirUtilp->getExpandedFilename(LL_PATH_SCRIPTS, "lua")}; - for (size_t i = 0; i < lib_paths.size(); ++i) + for (const auto& path : lib_paths) { - std::string absolutePathOpt = join_paths(lib_paths[i], mPathToResolve); + std::string absolutePathOpt = (std::filesystem::path(path) / mPathToResolve).u8string(); if (absolutePathOpt.empty()) luaL_errorL(L, "error requiring module"); - mChunkname = absolutePathOpt; mAbsolutePath = absolutePathOpt; moduleStatus = findModuleImpl(); @@ -500,16 +478,12 @@ LLRequireResolver::ModuleStatus LLRequireResolver::findModule() LLRequireResolver::ModuleStatus LLRequireResolver::findModuleImpl() { - std::string possibleSuffixes[] = {".luau", ".lua"}; - - size_t unsuffixedAbsolutePathSize = mAbsolutePath.size(); + std::string possibleSuffixedPaths[] = {mAbsolutePath + ".luau", mAbsolutePath + ".lua"}; - for (auto possibleSuffix : possibleSuffixes) + for (auto suffixedPath : possibleSuffixedPaths) { - mAbsolutePath += possibleSuffix; - - // Check cache for module - lua_getfield(L, -1, mAbsolutePath.c_str()); + // Check _MODULES cache for module + lua_getfield(L, -1, suffixedPath.c_str()); if (!lua_isnil(L, -1)) { return ModuleStatus::Cached; @@ -517,15 +491,12 @@ LLRequireResolver::ModuleStatus LLRequireResolver::findModuleImpl() lua_pop(L, 1); // Try to read the matching file - std::string source = read_file(mAbsolutePath); + std::string source = read_file(suffixedPath); if (!source.empty()) { - mChunkname = "=" + mChunkname + possibleSuffix; mSourceCode = source; return ModuleStatus::FileRead; } - - mAbsolutePath.resize(unsuffixedAbsolutePathSize); // truncate to remove suffix } return ModuleStatus::NotFound; @@ -533,17 +504,12 @@ LLRequireResolver::ModuleStatus LLRequireResolver::findModuleImpl() void LLRequireResolver::resolveAndStoreDefaultPaths() { - if (!is_absolute_path(mPathToResolve)) + if (!std::filesystem::path(mPathToResolve).is_absolute()) { - std::string path = gDirUtilp->getDirName(mSourceChunkname); - std::replace(path.begin(), path.end(), '\\', '/'); - path = join_paths(path, mPathToResolve); - mAbsolutePath = path; - mChunkname = path; + mAbsolutePath = (std::filesystem::path((mSourceChunkname)).parent_path() / mPathToResolve).u8string();; } else { - mChunkname = mPathToResolve; mAbsolutePath = mPathToResolve; } } @@ -558,9 +524,9 @@ static int finishrequire(lua_State *L) lua_function(require, "require(module_name) : module_name can be fullpath or just the name, in both cases without .lua") { - std::string name = luaL_checkstring(L, 1); + std::string name = lua_tostdstring(L, 1); - LLRequireResolver::ResolvedRequire resolvedRequire = LLRequireResolver::resolveRequire(L, std::move(name)); + LLRequireResolver::ResolvedRequire resolvedRequire = LLRequireResolver::resolveRequire(L, name); if (resolvedRequire.status == LLRequireResolver::ModuleStatus::Cached) return finishrequire(L); @@ -577,18 +543,13 @@ lua_function(require, "require(module_name) : module_name can be fullpath or jus luaL_sandboxthread(ML); { - // now we can compile & run module on the new thread - size_t bytecodeSize = 0; - std::unique_ptr<char[], freer> bytecode { - luau_compile(resolvedRequire.sourceCode.c_str(), resolvedRequire.sourceCode.length(), nullptr, &bytecodeSize)}; - - if (luau_load(ML, resolvedRequire.chunkName.c_str(), bytecode.get(), bytecodeSize, 0) == 0) + if (lluau::loadstring(ML, resolvedRequire.absolutePath.c_str(), resolvedRequire.sourceCode.c_str()) == LUA_OK) { int status = lua_resume(ML, L, 0); - if (status == 0) + if (status == LUA_OK) { - if (lua_gettop(ML) == 0) + if (lua_gettop(ML) == LUA_OK) lua_pushstring(ML, "module must return a value"); else if (!lua_istable(ML, -1) && !lua_isfunction(ML, -1)) lua_pushstring(ML, "module must return a table or function"); |