From 6d29beb91b019e1995cdb7c4aaf7a043de4bf053 Mon Sep 17 00:00:00 2001 From: Nat Goodspeed Date: Fri, 20 Sep 2024 15:13:43 -0400 Subject: Add ability to pass command-line arguments to a Lua script. Introduce `ScriptCommand` class that parses a command line into a script name and optional args, using bash-like quoting and escaping. `ScriptCommand` searches for a file with that script name on a passed list of directories; the directories may be specified relative to a particular base directory. `ScriptCommand` supports the special case of a script name containing unescaped spaces. It guarantees that either the returned script file exists, or its `error()` string is non-empty. Replace `LLLeap::create()` logic, from which `ScriptCommand` was partly derived, with a `ScriptCommand` instance. Make `LLLUAmanager::runScriptFile()` use a `ScriptCommand` instance to parse the passed command line. Subsume `LLAppViewer::init()` script-path-searching logic for `--luafile` into `ScriptCommand`. In fact that lambda now simply calls `LLLUAmanager::runScriptFile()`. Make `lluau::dostring()` accept an optional vector of script argument strings. Following PUC-Rio Lua convention, pass these arguments into a Lua script as the predefined global `arg`, and also as the script's `...` argument. `LuaState::expr()` also accepts and passes through script argument strings. Change the log tag for the Lua script interruption message: if we want it, we can still enable it, but we don't necessarily want it along with all other "Lua" DEBUG messages. Remove `LuaState::script_finished_fn`, which isn't used any more. Also remove the corresponding `LLLUAmanager::script_finished_fn`. This allows us to simplify `~LuaState()` slightly, as well as the parameter signatures for `LLLUAmanager::runScriptFile()` and `runScriptLine()`. --- indra/newview/llluamanager.h | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) (limited to 'indra/newview/llluamanager.h') diff --git a/indra/newview/llluamanager.h b/indra/newview/llluamanager.h index df76ddd3e2..b98b5d4ef6 100644 --- a/indra/newview/llluamanager.h +++ b/indra/newview/llluamanager.h @@ -44,9 +44,6 @@ class LLLUAmanager friend class ScriptObserver; public: - // Pass a callback with this signature to obtain the error message, if - // any, from running a script or source string. Empty msg means success. - typedef std::function script_finished_fn; // Pass a callback with this signature to obtain the result, if any, of // running a script or source string. // count < 0 means error, and result.asString() is the error message. @@ -58,20 +55,31 @@ public: // same semantics as script_result_fn parameters typedef std::pair script_result; - static void runScriptFile(const std::string &filename, bool autorun = false, script_result_fn result_cb = {}, - script_finished_fn finished_cb = {}); + // Run the script specified by the command line passed as @a filename. + // This can be followed by some number of command-line arguments, which + // a Lua script can view using either '...' or predefined global 'arg'. + // The script pathname or its arguments can be quoted using 'single + // quotes' or "double quotes", or special characters can be \escaped. + // runScriptFile() recognizes the case in which the whole 'filename' + // string is a path containing spaces; if so no arguments are permitted. + // In either form, if the script pathname isn't absolute, it is sought on + // LuaCommandPath. + // If autorun is true, statistics will count this as an autorun script. + static void runScriptFile(const std::string &filename, bool autorun = false, + script_result_fn result_cb = {}); // Start running a Lua script file, returning an LLCoros::Future whose // get() method will pause the calling coroutine until it can deliver the // (count, result) pair described above. Between startScriptFile() and // Future::get(), the caller and the Lua script coroutine will run // concurrently. + // @a filename is as described for runScriptFile(). static LLCoros::Future startScriptFile(const std::string& filename); // Run a Lua script file, and pause the calling coroutine until it completes. // The return value is the (count, result) pair described above. + // @a filename is as described for runScriptFile(). static script_result waitScriptFile(const std::string& filename); - static void runScriptLine(const std::string &chunk, script_result_fn result_cb = {}, - script_finished_fn finished_cb = {}); + static void runScriptLine(const std::string &chunk, script_result_fn result_cb = {}); // Start running a Lua chunk, returning an LLCoros::Future whose // get() method will pause the calling coroutine until it can deliver the // (count, result) pair described above. Between startScriptLine() and -- cgit v1.2.3