@@ -6,6 +6,43 @@ const std = @import("std");
66// The zlua module is made available in build.zig
77const zlua = @import ("zlua" );
88
9+ const ReadError = error {BufferTooSmall };
10+
11+ fn readlineStdin (out_buf : []u8 ) anyerror ! usize {
12+ const builtin = @import ("builtin" );
13+ // Backwards compatibility with zig-0.14
14+ // TODO remove when zig-0.15 is released
15+ if (builtin .zig_version .major == 0 and builtin .zig_version .minor < 15 ) {
16+ var stdin = std .io .getStdIn ().reader ();
17+ return try stdin .read (out_buf );
18+ } else {
19+ var in_buf : [4096 ]u8 = undefined ;
20+ var stdin_file = std .fs .File .stdin ().reader (& in_buf );
21+ const stdin = & stdin_file .interface ;
22+ const s = try stdin .takeDelimiterExclusive ('\n ' );
23+ if (s .len < out_buf .len ) {
24+ @memcpy (out_buf [0.. s .len ], s );
25+ return s .len ;
26+ }
27+ return error .BufferTooSmall ;
28+ }
29+ }
30+
31+ fn flushedStdoutPrint (comptime fmt : []const u8 , args : anytype ) ! void {
32+ const builtin = @import ("builtin" );
33+ // Backwards compatibility with zig-0.14
34+ // TODO remove when zig-0.15 is released
35+ if (builtin .zig_version .major == 0 and builtin .zig_version .minor < 15 ) {
36+ try std .io .getStdOut ().writer ().print (fmt , args );
37+ } else {
38+ var out_buf : [4096 ]u8 = undefined ;
39+ var w = std .fs .File .stdout ().writer (& out_buf );
40+ const stdout = & w .interface ;
41+ try stdout .print (fmt , args );
42+ try stdout .flush ();
43+ }
44+ }
45+
946pub fn main () anyerror ! void {
1047 var gpa = std .heap .GeneralPurposeAllocator (.{}){};
1148 const allocator = gpa .allocator ();
@@ -20,24 +57,20 @@ pub fn main() anyerror!void {
2057 // Open all Lua standard libraries
2158 lua .openLibs ();
2259
23- var in_buf : [4096 ]u8 = undefined ;
24- var out_buf : [4096 ]u8 = undefined ;
25- var stdin_file = std .fs .File .stdin ().reader (& in_buf );
26- const stdin = & stdin_file .interface ;
27- var stdout_file = std .fs .File .stdout ().writer (& out_buf );
28- const stdout = & stdout_file .interface ;
29-
30- var buffer : [256 ]u8 = undefined ;
3160 while (true ) {
32- _ = try stdout . writeAll ("> " );
61+ try flushedStdoutPrint ("> " , .{} );
3362
3463 // Read a line of input
35- const len = try stdin .readSliceShort (& buffer );
36- if (len == 0 ) break ; // EOF
37- if (len >= buffer .len - 1 ) {
38- try stdout .print ("error: line too long!\n " , .{});
39- continue ;
40- }
64+ var buffer : [256 ]u8 = undefined ;
65+ const len = readlineStdin (buffer [0 .. buffer .len - 1 ]) catch | err | {
66+ switch (err ) {
67+ error .BufferTooSmall = > {
68+ try flushedStdoutPrint ("error: line too long!\n " , .{});
69+ continue ;
70+ },
71+ else = > return err ,
72+ }
73+ };
4174
4275 // Ensure the buffer is null-terminated so the Lua API can read the length
4376 buffer [len ] = 0 ;
@@ -46,7 +79,7 @@ pub fn main() anyerror!void {
4679 lua .loadString (buffer [0.. len :0 ]) catch {
4780 // If there was an error, Lua will place an error string on the top of the stack.
4881 // Here we print out the string to inform the user of the issue.
49- try stdout . print ("{s}\n " , .{lua .toString (-1 ) catch unreachable });
82+ try flushedStdoutPrint ("{s}\n " , .{lua .toString (-1 ) catch unreachable });
5083
5184 // Remove the error from the stack and go back to the prompt
5285 lua .pop (1 );
@@ -56,7 +89,7 @@ pub fn main() anyerror!void {
5689 // Execute a line of Lua code
5790 lua .protectedCall (.{}) catch {
5891 // Error handling here is the same as above.
59- try stdout . print ("{s}\n " , .{lua .toString (-1 ) catch unreachable });
92+ try flushedStdoutPrint ("{s}\n " , .{lua .toString (-1 ) catch unreachable });
6093 lua .pop (1 );
6194 };
6295 }
0 commit comments