Merge remote-tracking branch 'lethosor/lua-runcommand' into develop

develop
lethosor 2021-01-29 20:27:38 -05:00
commit 4126585573
No known key found for this signature in database
GPG Key ID: 76A269552F4F58C1
5 changed files with 92 additions and 33 deletions

@ -833,6 +833,9 @@ can be omitted.
* ``dfhack.getCompiledDFVersion()``
* ``dfhack.getGitDescription()``
* ``dfhack.getGitCommit()``
* ``dfhack.getGitXmlCommit()``
* ``dfhack.getGitXmlExpectedCommit()``
* ``dfhack.gitXmlMatch()``
* ``dfhack.isRelease()``
Return information about the DFHack build in use.
@ -899,6 +902,28 @@ can be omitted.
Note that the returned string may be longer than the input string. For
example, ``ä`` is replaced with ``a``, and ``æ`` is replaced with ``ae``.
* ``dfhack.run_command(command[, ...])``
Run an arbitrary DFHack command, with the core suspended, and send output to
the DFHack console. The command can be passed as a table, multiple string
arguments, or a single string argument (not recommended - in this case, the
usual DFHack console tokenization is used).
A ``command_result`` constant starting with ``CR_`` is returned, where ``CR_OK``
indicates success.
The following examples are equivalent::
dfhack.run_command({'ls', '-a'})
dfhack.run_command('ls', '-a')
dfhack.run_command('ls -a') -- not recommended
* ``dfhack.run_command_silent(command[, ...])``
Similar to ``run_command()``, but instead of printing to the console,
returns an ``output, command_result`` pair. ``output`` is a single string -
see ``dfhack.internal.runCommand()`` to obtain colors as well.
Gui module
----------
@ -2235,11 +2260,6 @@ 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.getPE()``
Returns the PE timestamp of the DF executable (only on Windows)
@ -2354,6 +2374,21 @@ and are only documented here for completeness:
This requires an extension to be specified (``.lua`` or ``.rb``) - use
``dfhack.findScript()`` to include the ``.lua`` extension automatically.
* ``dfhack.internal.runCommand(command[, use_console])``
Runs a DFHack command with the core suspended. Used internally by the
``dfhack.run_command()`` family of functions.
- ``command``: either a table of strings or a single string which is parsed by
the default console tokenization strategy (not recommended)
- ``use_console``: if true, output is sent directly to the DFHack console
Returns a table with a ``status`` key set to a ``command_result`` constant
(``status = CR_OK`` indicates success). Additionally, if ``use_console`` is
not true, enumerated table entries of the form ``{color, text}`` are included,
e.g. ``result[1][0]`` is the color of the first piece of text printed (a
``COLOR_`` constant). These entries can be iterated over with ``ipairs()``.
* ``dfhack.internal.md5(string)``
Returns the MD5 hash of the given string.
@ -2513,6 +2548,12 @@ environment by the mandatory init file dfhack.lua:
SC_WORLD_LOADED, SC_WORLD_UNLOADED, SC_MAP_LOADED,
SC_MAP_UNLOADED, SC_VIEWSCREEN_CHANGED, SC_CORE_INITIALIZED
* Command result constants (equivalent to ``command_result`` in C++), used by
``dfhack.run_command()`` and related functions:
CR_OK, CR_LINK_FAILURE, CR_NEEDS_CONSOLE, CR_NOT_IMPLEMENTED, CR_FAILURE,
CR_WRONG_USAGE, CR_NOT_FOUND
* Functions already described above
safecall, qerror, mkmodule, reload

@ -405,6 +405,8 @@ namespace DFHack
/// A simple line edit (raw mode)
int lineedit(const std::string& prompt, std::string& output, recursive_mutex * lock, CommandHistory & ch)
{
if(state == con_lineedit)
return Console::FAILURE;
output.clear();
reset_color();
this->prompt = prompt;
@ -414,7 +416,9 @@ namespace DFHack
fflush(dfout_C);
// FIXME: what do we do here???
//SDL_recursive_mutexV(lock);
state = con_lineedit;
std::getline(std::cin, output);
state = con_unclaimed;
//SDL_recursive_mutexP(lock);
return output.size();
}
@ -422,8 +426,6 @@ namespace DFHack
{
int count;
if (enable_raw() == -1) return 0;
if(state == con_lineedit)
return Console::FAILURE;
state = con_lineedit;
count = prompt_loop(lock,ch);
state = con_unclaimed;

@ -376,6 +376,8 @@ namespace DFHack
}
int lineedit(const std::string & prompt, std::string & output, recursive_mutex * lock, CommandHistory & ch)
{
if(state == con_lineedit)
return Console::FAILURE;
output.clear();
reset_color();
int count;

@ -2822,13 +2822,29 @@ static int internal_diffscan(lua_State *L)
static int internal_runCommand(lua_State *L)
{
buffered_color_ostream out;
color_ostream *out = NULL;
std::unique_ptr<buffered_color_ostream> out_buffer;
command_result res;
if (lua_gettop(L) == 0)
{
lua_pushstring(L, "");
}
int type_1 = lua_type(L, 1);
bool use_console = lua_toboolean(L, 2);
if (use_console)
{
out = Lua::GetOutput(L);
if (!out)
{
out = &Core::getInstance().getConsole();
}
}
else
{
out_buffer.reset(new buffered_color_ostream());
out = out_buffer.get();
}
if (type_1 == LUA_TTABLE)
{
std::string command = "";
@ -2843,13 +2859,13 @@ static int internal_runCommand(lua_State *L)
lua_pop(L, 1); // remove value, leave key
}
CoreSuspender suspend;
res = Core::getInstance().runCommand(out, command, args);
res = Core::getInstance().runCommand(*out, command, args);
}
else if (type_1 == LUA_TSTRING)
{
std::string command = lua_tostring(L, 1);
CoreSuspender suspend;
res = Core::getInstance().runCommand(out, command);
res = Core::getInstance().runCommand(*out, command);
}
else
{
@ -2857,22 +2873,28 @@ static int internal_runCommand(lua_State *L)
lua_pushfstring(L, "Expected table, got %s", lua_typename(L, type_1));
return 2;
}
auto fragments = out.fragments();
lua_newtable(L);
lua_pushinteger(L, (int)res);
lua_setfield(L, -2, "status");
int i = 1;
for (auto iter = fragments.begin(); iter != fragments.end(); iter++, i++)
if (out_buffer)
{
int color = iter->first;
std::string output = iter->second;
lua_createtable(L, 2, 0);
lua_pushinteger(L, color);
lua_rawseti(L, -2, 1);
lua_pushstring(L, output.c_str());
lua_rawseti(L, -2, 2);
lua_rawseti(L, -2, i);
auto fragments = out_buffer->fragments();
int i = 1;
for (auto iter = fragments.begin(); iter != fragments.end(); iter++, i++)
{
int color = iter->first;
std::string output = iter->second;
lua_createtable(L, 2, 0);
lua_pushinteger(L, color);
lua_rawseti(L, -2, 1);
lua_pushstring(L, output.c_str());
lua_rawseti(L, -2, 2);
lua_rawseti(L, -2, i);
}
}
lua_pushvalue(L, -1);
return 1;
}

@ -735,8 +735,7 @@ function dfhack.script_help(script_name, extension)
return help
end
local function _run_command(...)
args = {...}
local function _run_command(args, use_console)
if type(args[1]) == 'table' then
command = args[1]
elseif #args > 1 and type(args[2]) == 'table' then
@ -750,11 +749,11 @@ local function _run_command(...)
else
error('Invalid arguments')
end
return internal.runCommand(command)
return internal.runCommand(command, use_console)
end
function dfhack.run_command_silent(...)
local result = _run_command(...)
local result = _run_command({...})
local output = ""
for i, f in pairs(result) do
if type(f) == 'table' then
@ -765,14 +764,7 @@ function dfhack.run_command_silent(...)
end
function dfhack.run_command(...)
local result = _run_command(...)
for i, f in pairs(result) do
if type(f) == 'table' then
dfhack.color(f[1])
dfhack.print(f[2])
end
end
dfhack.color(COLOR_RESET)
local result = _run_command({...}, true)
return result.status
end