summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--3rdparty/lua-linenoise/linenoise.c198
-rw-r--r--scripts/src/3rdparty.lua2
-rw-r--r--src/frontend/mame/luaengine.cpp2
3 files changed, 202 insertions, 0 deletions
diff --git a/3rdparty/lua-linenoise/linenoise.c b/3rdparty/lua-linenoise/linenoise.c
new file mode 100644
index 00000000000..670a71c2b22
--- /dev/null
+++ b/3rdparty/lua-linenoise/linenoise.c
@@ -0,0 +1,198 @@
+/* vim:sts=4 sw=4 expandtab
+ */
+
+/*
+* Copyright (c) 2011-2015 Rob Hoelz <rob@hoelz.ro>
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is furnished
+* to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all
+* copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <stdlib.h>
+#include "linenoise.h"
+
+#define LN_COMPLETION_TYPE "linenoiseCompletions*"
+
+static int completion_func_ref;
+static lua_State *completion_state;
+
+static int handle_ln_error(lua_State *L)
+{
+ lua_pushnil(L);
+ return 1;
+}
+
+static int handle_ln_ok(lua_State *L)
+{
+ lua_pushboolean(L, 1);
+ return 1;
+}
+
+static void completion_callback_wrapper(const char *line, linenoiseCompletions *completions)
+{
+ lua_State *L = completion_state;
+
+ lua_rawgeti(L, LUA_REGISTRYINDEX, completion_func_ref);
+ *((linenoiseCompletions **) lua_newuserdata(L, sizeof(linenoiseCompletions *))) = completions;
+ luaL_getmetatable(L, LN_COMPLETION_TYPE);
+ lua_setmetatable(L, -2);
+
+ lua_pushstring(L, line);
+
+ lua_pcall(L, 2, 0, 0);
+}
+
+static int l_linenoise(lua_State *L)
+{
+ const char *prompt = luaL_checkstring(L, 1);
+ char *line;
+
+ completion_state = L;
+ line = linenoise(prompt);
+ completion_state = NULL;
+
+ if(! line) {
+ return handle_ln_error(L);
+ }
+ lua_pushstring(L, line);
+ free(line);
+ return 1;
+}
+
+static int lines_next(lua_State *L)
+{
+ lua_pushcfunction(L, l_linenoise);
+ lua_pushvalue(L, lua_upvalueindex(1));
+ lua_call(L, 1, 1);
+ return 1;
+}
+
+static int l_lines(lua_State *L)
+{
+ luaL_checkstring(L, 1);
+ lua_pushcclosure(L, lines_next, 1);
+ return 1;
+}
+
+static int l_historyadd(lua_State *L)
+{
+ const char *line = luaL_checkstring(L, 1);
+
+ if(! linenoiseHistoryAdd(line)) {
+ return handle_ln_error(L);
+ }
+
+ return handle_ln_ok(L);
+}
+
+static int l_historysetmaxlen(lua_State *L)
+{
+ int len = luaL_checkinteger(L, 1);
+
+ if(! linenoiseHistorySetMaxLen(len)) {
+ return handle_ln_error(L);
+ }
+
+ return handle_ln_ok(L);
+}
+
+static int l_historysave(lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+
+ if(linenoiseHistorySave((char *) filename) < 0) {
+ return handle_ln_error(L);
+ }
+ return handle_ln_ok(L);
+}
+
+static int l_historyload(lua_State *L)
+{
+ const char *filename = luaL_checkstring(L, 1);
+
+ if(linenoiseHistoryLoad((char *) filename) < 0) {
+ return handle_ln_error(L);
+ }
+ return handle_ln_ok(L);
+}
+
+static int l_clearscreen(lua_State *L)
+{
+ linenoiseClearScreen();
+ return handle_ln_ok(L);
+}
+
+static int l_setcompletion(lua_State *L)
+{
+ luaL_checktype(L, 1, LUA_TFUNCTION);
+
+ lua_pushvalue(L, 1);
+ completion_func_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+ linenoiseSetCompletionCallback(completion_callback_wrapper);
+
+ return handle_ln_ok(L);
+}
+
+static int l_addcompletion(lua_State *L)
+{
+ linenoiseCompletions *completions = *((linenoiseCompletions **) luaL_checkudata(L, 1, LN_COMPLETION_TYPE));
+ const char *entry = luaL_checkstring(L, 2);
+
+ linenoiseAddCompletion(completions, (char *) entry);
+
+ return handle_ln_ok(L);
+}
+
+luaL_Reg linenoise_funcs[] = {
+ { "linenoise", l_linenoise },
+ { "historyadd", l_historyadd },
+ { "historysetmaxlen", l_historysetmaxlen },
+ { "historysave", l_historysave },
+ { "historyload", l_historyload },
+ { "clearscreen", l_clearscreen },
+ { "setcompletion", l_setcompletion},
+ { "addcompletion", l_addcompletion },
+
+ /* Aliases for more consistent function names */
+ { "addhistory", l_historyadd },
+ { "sethistorymaxlen", l_historysetmaxlen },
+ { "savehistory", l_historysave },
+ { "loadhistory", l_historyload },
+
+ { "line", l_linenoise },
+ { "lines", l_lines },
+
+ { NULL, NULL }
+};
+
+int luaopen_linenoise(lua_State *L)
+{
+ lua_newtable(L);
+
+ luaL_newmetatable(L, LN_COMPLETION_TYPE);
+ lua_pushboolean(L, 0);
+ lua_setfield(L, -2, "__metatable");
+ lua_pop(L, 1);
+#if LUA_VERSION_NUM > 501
+ luaL_setfuncs(L,linenoise_funcs,0);
+#else
+ luaL_register(L, NULL, linenoise_funcs);
+#endif
+ return 1;
+}
diff --git a/scripts/src/3rdparty.lua b/scripts/src/3rdparty.lua
index db9b94d6adc..9925f0821dd 100644
--- a/scripts/src/3rdparty.lua
+++ b/scripts/src/3rdparty.lua
@@ -555,6 +555,7 @@ project "lualibs"
includedirs {
MAME_DIR .. "3rdparty",
+ MAME_DIR .. "3rdparty/linenoise-ng/include",
}
includedirs {
ext_includedir("lua"),
@@ -564,6 +565,7 @@ project "lualibs"
files {
MAME_DIR .. "3rdparty/lua-zlib/lua_zlib.c",
MAME_DIR .. "3rdparty/luafilesystem/src/lfs.c",
+ MAME_DIR .. "3rdparty/lua-linenoise/linenoise.c",
}
end
diff --git a/src/frontend/mame/luaengine.cpp b/src/frontend/mame/luaengine.cpp
index 10a4280b597..b9ca13e17f0 100644
--- a/src/frontend/mame/luaengine.cpp
+++ b/src/frontend/mame/luaengine.cpp
@@ -33,6 +33,7 @@
extern "C" {
int luaopen_zlib(lua_State *L);
int luaopen_lfs(lua_State *L);
+ int luaopen_linenoise(lua_State *L);
}
namespace sol
@@ -523,6 +524,7 @@ lua_engine::lua_engine()
// Get package.preload so we can store builtins in it.
sol()["package"]["preload"]["zlib"] = &luaopen_zlib;
sol()["package"]["preload"]["lfs"] = &luaopen_lfs;
+ sol()["package"]["preload"]["linenoise"] = &luaopen_linenoise;
lua_gc(m_lua_state, LUA_GCRESTART, 0);
}