diff --git a/build.zig b/build.zig index 3b7542a..5201d6e 100644 --- a/build.zig +++ b/build.zig @@ -45,7 +45,7 @@ pub fn build(b: *std.Build) void { const xkbcommon = b.dependency("xkbcommon", .{}).module("xkbcommon"); const pixman = b.dependency("pixman", .{}).module("pixman"); const wlroots = b.dependency("wlroots", .{}).module("wlroots"); - const zlua = b.dependency("zlua", .{}).module("zlua"); + const zlua = b.dependency("zlua", .{ .lang = .luajit }).module("zlua"); const clap = b.dependency("clap", .{}).module("clap"); wlroots.addImport("wayland", wayland); diff --git a/build.zig.zon b/build.zig.zon index e66c88f..b4a523b 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -21,8 +21,8 @@ .hash = "wlroots-0.19.3-jmOlcuL_AwBHhLCwpFsXbTizE3q9BugFmGX-XIxqcPMc", }, .zlua = .{ - .url = "git+https://github.com/natecraddock/ziglua#39f8df588d0864070deffa308ef575bf492777a0", - .hash = "zlua-0.1.0-hGRpC6E9BQDBGKPqzmCRsI6Xd8jH9KohccmX69-L6HyS", + .url = "git+https://github.com/natecraddock/ziglua?ref=0.6.0#315b7f25efd29d9e2143d6c0ab685bb7f640450f", + .hash = "zlua-0.1.0-hGRpCww-BQCx3cX6zbKWfTgOx6B7Peo4P17RK2hm7-xV", }, .clap = .{ .url = "https://github.com/Hejsil/zig-clap/archive/refs/tags/0.11.0.tar.gz", diff --git a/src/RemoteLua.zig b/src/RemoteLua.zig index d5e5f92..93d0e04 100644 --- a/src/RemoteLua.zig +++ b/src/RemoteLua.zig @@ -4,6 +4,7 @@ const std = @import("std"); const zlua = @import("zlua"); const wayland = @import("wayland"); const Utils = @import("Utils.zig"); +const LuaUtils = @import("lua/LuaUtils.zig"); const Lua = @import("lua/Lua.zig"); const wl = wayland.server.wl; const mez = wayland.server.zmez; @@ -65,7 +66,7 @@ remote: *RemoteLua, }, 0) catch return catchLuaFail(remote); defer gpa.free(str); - zlua.Lua.loadBuffer(L, str, "=repl", zlua.Mode.text) catch { + zlua.Lua.loadBuffer(L, str, "=repl") catch { L.pop(L.getTop()); L.loadString(chunk) catch { catchLuaFail(remote); @@ -82,8 +83,7 @@ remote: *RemoteLua, var i: i32 = 1; const nresults = L.getTop(); while (i <= nresults) : (i += 1) { - // TODO: support lua5.1 and luajit? - sendNewLogEntry(L.toStringEx(i)); + sendNewLogEntry(LuaUtils.toStringEx(L)); L.pop(-1); } }, @@ -101,6 +101,6 @@ fn handleDestroy(_: *mez.RemoteLuaV1, remote_lua: *RemoteLua) void { } fn catchLuaFail(remote: *RemoteLua) void { - const err: [:0]const u8 = remote.L.toStringEx(-1); + const err: [:0]const u8 = LuaUtils.toStringEx(remote.L); sendNewLogEntry(std.mem.sliceTo(err, 0)); } diff --git a/src/lua/Lua.zig b/src/lua/Lua.zig index f993e9c..90e164d 100644 --- a/src/lua/Lua.zig +++ b/src/lua/Lua.zig @@ -4,6 +4,7 @@ const std = @import("std"); const config = @import("config"); const zlua = @import("zlua"); +const LuaUtils = @import("LuaUtils.zig"); const Bridge = @import("Bridge.zig"); const Fs = @import("Fs.zig"); const Input = @import("Input.zig"); @@ -110,32 +111,32 @@ pub fn openLibs(self: *zlua.Lua) void { } { const fs_funcs = zlua.fnRegsFromType(Fs); - self.newLib(fs_funcs); + LuaUtils.newLib(self, fs_funcs); self.setField(-2, "fs"); } { const input_funcs = zlua.fnRegsFromType(Input); - self.newLib(input_funcs); + LuaUtils.newLib(self, input_funcs); self.setField(-2, "input"); } { const hook_funcs = zlua.fnRegsFromType(Hook); - self.newLib(hook_funcs); + LuaUtils.newLib(self, hook_funcs); self.setField(-2, "hook"); } { const api_funcs = zlua.fnRegsFromType(Api); - self.newLib(api_funcs); + LuaUtils.newLib(self, api_funcs); self.setField(-2, "api"); } { const view_funcs = zlua.fnRegsFromType(View); - self.newLib(view_funcs); + LuaUtils.newLib(self, view_funcs); self.setField(-2, "view"); } { const output_funcs = zlua.fnRegsFromType(Output); - self.newLib(output_funcs); + LuaUtils.newLib(self, output_funcs); self.setField(-2, "output"); } } diff --git a/src/lua/LuaUtils.zig b/src/lua/LuaUtils.zig index d99f30d..bcc5761 100644 --- a/src/lua/LuaUtils.zig +++ b/src/lua/LuaUtils.zig @@ -24,3 +24,22 @@ pub fn coerceInteger(comptime x: type, number: zlua.Integer) error{InvalidIntege else => @compileError("unsupported type"), } } + +pub fn newLib(L: *zlua.Lua, f: []const zlua.FnReg) void { + L.newLibTable(f); // documented as being unavailable, but it is. + for (f) |value| { + if (value.func == null) continue; + L.pushClosure(value.func.?, 0); + L.setField(-2, value.name); + } +} + +/// makes a best effort to convert the value at the top of the stack to a string +/// if we're unable to do so return "nil" +pub fn toStringEx(L: *zlua.Lua) [:0]const u8 { + const errstr = "nil"; + _ = L.getGlobal("tostring") catch return errstr; + L.insert(1); + L.protectedCall(.{ .args = 1, .results = 1 }) catch return errstr; + return L.toString(-1) catch errstr; +}