diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 940f20f..a2a95b2 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,7 +7,8 @@ on: branches: [ "main" ] jobs: - test: + #------ zig-dev builds ------ + test_zig_nightly: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest, ubuntu-24.04-arm] @@ -24,8 +25,29 @@ jobs: version: master - name: Run tests - run: make test + run: make test_zig_nightly + #------ zig-0.14 ------ + test_zig_014: + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest, ubuntu-24.04-arm] + + runs-on: ${{matrix.os}} + + steps: + - name: Clone Ziglua + uses: actions/checkout@v3 + + - name: Setup Zig + uses: mlugg/setup-zig@v2 + with: + version: "0.14.1" + + - name: Run tests + run: make test_zig_014 + + #------ cross compilation ------ test_cross: strategy: matrix: diff --git a/examples/interpreter.zig b/examples/interpreter.zig index e219431..141df2d 100644 --- a/examples/interpreter.zig +++ b/examples/interpreter.zig @@ -6,6 +6,43 @@ const std = @import("std"); // The zlua module is made available in build.zig const zlua = @import("zlua"); +const ReadError = error{BufferTooSmall}; + +fn readlineStdin(out_buf: []u8) anyerror!usize { + const builtin = @import("builtin"); + // Backwards compatibility with zig-0.14 + // TODO remove when zig-0.15 is released + if (builtin.zig_version.major == 0 and builtin.zig_version.minor < 15) { + var stdin = std.io.getStdIn().reader(); + return try stdin.read(out_buf); + } else { + var in_buf: [4096]u8 = undefined; + var stdin_file = std.fs.File.stdin().reader(&in_buf); + const stdin = &stdin_file.interface; + const s = try stdin.takeDelimiterExclusive('\n'); + if (s.len < out_buf.len) { + @memcpy(out_buf[0..s.len], s); + return s.len; + } + return error.BufferTooSmall; + } +} + +fn flushedStdoutPrint(comptime fmt: []const u8, args: anytype) !void { + const builtin = @import("builtin"); + // Backwards compatibility with zig-0.14 + // TODO remove when zig-0.15 is released + if (builtin.zig_version.major == 0 and builtin.zig_version.minor < 15) { + try std.io.getStdOut().writer().print(fmt, args); + } else { + var out_buf: [4096]u8 = undefined; + var w = std.fs.File.stdout().writer(&out_buf); + const stdout = &w.interface; + try stdout.print(fmt, args); + try stdout.flush(); + } +} + pub fn main() anyerror!void { var gpa = std.heap.GeneralPurposeAllocator(.{}){}; const allocator = gpa.allocator(); @@ -20,24 +57,20 @@ pub fn main() anyerror!void { // Open all Lua standard libraries lua.openLibs(); - var in_buf: [4096]u8 = undefined; - var out_buf: [4096]u8 = undefined; - var stdin_file = std.fs.File.stdin().reader(&in_buf); - const stdin = &stdin_file.interface; - var stdout_file = std.fs.File.stdout().writer(&out_buf); - const stdout = &stdout_file.interface; - - var buffer: [256]u8 = undefined; while (true) { - _ = try stdout.writeAll("> "); + try flushedStdoutPrint("> ", .{}); // Read a line of input - const len = try stdin.readSliceShort(&buffer); - if (len == 0) break; // EOF - if (len >= buffer.len - 1) { - try stdout.print("error: line too long!\n", .{}); - continue; - } + var buffer: [256]u8 = undefined; + const len = readlineStdin(buffer[0 .. buffer.len - 1]) catch |err| { + switch (err) { + error.BufferTooSmall => { + try flushedStdoutPrint("error: line too long!\n", .{}); + continue; + }, + else => return err, + } + }; // Ensure the buffer is null-terminated so the Lua API can read the length buffer[len] = 0; @@ -46,7 +79,7 @@ pub fn main() anyerror!void { lua.loadString(buffer[0..len :0]) catch { // If there was an error, Lua will place an error string on the top of the stack. // Here we print out the string to inform the user of the issue. - try stdout.print("{s}\n", .{lua.toString(-1) catch unreachable}); + try flushedStdoutPrint("{s}\n", .{lua.toString(-1) catch unreachable}); // Remove the error from the stack and go back to the prompt lua.pop(1); @@ -56,7 +89,7 @@ pub fn main() anyerror!void { // Execute a line of Lua code lua.protectedCall(.{}) catch { // Error handling here is the same as above. - try stdout.print("{s}\n", .{lua.toString(-1) catch unreachable}); + try flushedStdoutPrint("{s}\n", .{lua.toString(-1) catch unreachable}); lua.pop(1); }; } diff --git a/makefile b/makefile index d8cc488..a4bd3a6 100644 --- a/makefile +++ b/makefile @@ -1,6 +1,6 @@ .PHONY: test docs -test: +test_zig_nightly: zig build test --summary failures -Dlang=lua51 zig build test --summary failures -Dlang=lua52 zig build test --summary failures -Dlang=lua53 @@ -13,6 +13,17 @@ test: zig build -Dlang=luajit +# A subset of tests that are expected to work also on zig-0.14 +test_zig_014: + zig build test --summary failures -Dlang=lua52 + zig build test --summary failures -Dlang=lua53 + zig build test --summary failures -Dlang=lua54 + zig build test --summary failures -Dlang=luau + + zig build install-example-interpreter + zig build install-example-zig-function + zig build -Dlang=luau install-example-luau-bytecode + test_cross: zig build -Dlang=lua51 -Dtarget=aarch64-linux zig build -Dlang=lua51 -Dtarget=aarch64-linux-gnu