From 7eb4fc19de542db0d3e271123f24773e0c8c481e Mon Sep 17 00:00:00 2001
From: Alexander Gavrilov
Date: Thu, 14 Jun 2012 12:46:12 +0400
Subject: [PATCH] Make dfhack.run_script usable from other scripts, and
document it.
---
LUA_API.rst | 12 ++++++++++++
Lua API.html | 10 ++++++++++
library/Core.cpp | 10 +++-------
library/lua/dfhack.lua | 13 +++++++++----
4 files changed, 34 insertions(+), 11 deletions(-)
diff --git a/LUA_API.rst b/LUA_API.rst
index f40b786d2..2859f8678 100644
--- a/LUA_API.rst
+++ b/LUA_API.rst
@@ -491,6 +491,13 @@ Currently it defines the following features:
Compares to coroutine.resume like dfhack.safecall vs pcall.
+* ``dfhack.run_script(name[,args...])``
+
+ Run a lua script in hack/scripts/, as if it was started from dfhack command-line.
+ The ``name`` argument should be the name stem, as would be used on the command line.
+ Note that the script is re-read from the file every time it is called, and errors
+ are propagated to the caller.
+
* ``dfhack.with_suspend(f[,args...])``
Calls ``f`` with arguments after grabbing the DF core suspend lock.
@@ -1148,6 +1155,11 @@ Internal API
These functions are intended for the use by dfhack developers,
and are only documented here for completeness:
+* ``dfhack.internal.scripts``
+
+ The table used by ``dfhack.run_script()`` to give every script its own
+ global environment, persistent between calls to the script.
+
* ``dfhack.internal.getAddress(name)``
Returns the global address ``name``, or *nil*.
diff --git a/Lua API.html b/Lua API.html
index 5574c55b8..047457985 100644
--- a/Lua API.html
+++ b/Lua API.html
@@ -766,6 +766,12 @@ returning. Intended as a convenience function.
dfhack.saferesume(coroutine[,args...])
Compares to coroutine.resume like dfhack.safecall vs pcall.
+dfhack.run_script(name[,args...])
+Run a lua script in hack/scripts/, as if it was started from dfhack command-line.
+The name argument should be the name stem, as would be used on the command line.
+Note that the script is re-read from the file every time it is called, and errors
+are propagated to the caller.
+
dfhack.with_suspend(f[,args...])
Calls f with arguments after grabbing the DF core suspend lock.
Suspending is necessary for accessing a consistent state of DF memory.
@@ -1310,6 +1316,10 @@ Returns true, was_only_planned if removed; or false if none fo
These functions are intended for the use by dfhack developers,
and are only documented here for completeness:
+dfhack.internal.scripts
+The table used by dfhack.run_script() to give every script its own
+global environment, persistent between calls to the script.
+
dfhack.internal.getAddress(name)
Returns the global address name, or nil.
diff --git a/library/Core.cpp b/library/Core.cpp
index 620fc81d2..a1090450f 100644
--- a/library/Core.cpp
+++ b/library/Core.cpp
@@ -264,16 +264,12 @@ static bool init_run_script(color_ostream &out, lua_State *state, void *info)
return true;
}
-static command_result runLuaScript(color_ostream &out, std::string filename, vector &args)
+static command_result runLuaScript(color_ostream &out, std::string name, vector &args)
{
ScriptArgs data;
- data.pcmd = &filename;
+ data.pcmd = &name;
data.pargs = &args;
-#ifndef LINUX_BUILD
- filename = toLower(filename);
-#endif
-
bool ok = Lua::RunCoreQueryLoop(out, Lua::Core::State, init_run_script, &data);
return ok ? CR_OK : CR_FAILURE;
@@ -619,7 +615,7 @@ command_result Core::runCommand(color_ostream &con, const std::string &first, ve
{
auto filename = getHackPath() + "scripts/" + first + ".lua";
if (fileExists(filename))
- res = runLuaScript(con, filename, parts);
+ res = runLuaScript(con, first, parts);
else
con.printerr("%s is not a recognized command.\n", first.c_str());
}
diff --git a/library/lua/dfhack.lua b/library/lua/dfhack.lua
index 926600c0f..4cdb4c950 100644
--- a/library/lua/dfhack.lua
+++ b/library/lua/dfhack.lua
@@ -273,19 +273,24 @@ end
-- Command scripts
-dfhack.scripts = dfhack.scripts or {}
+dfhack.internal.scripts = dfhack.internal.scripts or {}
-function dfhack.run_script(file,...)
- local env = dfhack.scripts[file]
+local scripts = dfhack.internal.scripts
+local hack_path = dfhack.getHackPath()
+
+function dfhack.run_script(name,...)
+ local key = string.lower(name)
+ local file = hack_path..'scripts/'..name..'.lua'
+ local env = scripts[key]
if env == nil then
env = {}
setmetatable(env, { __index = base_env })
- dfhack.scripts[file] = env
end
local f,perr = loadfile(file, 't', env)
if f == nil then
error(perr)
end
+ scripts[key] = env
return f(...)
end