From 3e53d3ae08d41b21d9edcd0f9bbd9e0edbdfb138 Mon Sep 17 00:00:00 2001 From: Matthias Andreas Benkard Date: Sat, 16 Aug 2025 13:02:47 +0200 Subject: Unify input handling. --- src/cmd/lib/types.zig | 59 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 56 insertions(+), 3 deletions(-) (limited to 'src/cmd/lib') diff --git a/src/cmd/lib/types.zig b/src/cmd/lib/types.zig index f663a64..f6a32c0 100644 --- a/src/cmd/lib/types.zig +++ b/src/cmd/lib/types.zig @@ -72,6 +72,59 @@ pub const InputSource = struct { } }; +pub const StdinInputReader = struct { + pub fn readLine(self: *StdinInputReader, allocator: Allocator) !?[]const u8 { + _ = self; + const stdin = std.io.getStdIn().reader(); + + // Read line from stdin with proper DOS handling + const line = stdin.readUntilDelimiterOrEofAlloc(allocator, '\n', 4096) catch |err| switch (err) { + error.StreamTooLong => { + // Line too long, skip to next line + while (true) { + const ch = stdin.readByte() catch return null; + if (ch == '\n') break; + } + return try allocator.dupe(u8, ""); + }, + else => return null, + }; + + if (line) |input| { + // Check for Ctrl+Z (EOF marker) - ASCII 26 or ^Z text + if ((input.len == 1 and input[0] == 26) or + (input.len == 2 and input[0] == '^' and input[1] == 'Z')) + { + allocator.free(input); + return null; // EOF + } + + // Remove trailing \r if present (DOS line endings) + if (input.len > 0 and input[input.len - 1] == '\r') { + const trimmed = try allocator.dupe(u8, input[0 .. input.len - 1]); + allocator.free(input); + return trimmed; + } else { + return input; + } + } else { + return null; // EOF + } + } +}; + +pub const InputReader = union(enum) { + source: *InputSource, + stdin: *StdinInputReader, + + pub fn readLine(self: *InputReader, allocator: Allocator) !?[]const u8 { + switch (self.*) { + .source => |source| return source.readLine(allocator), + .stdin => |stdin| return stdin.readLine(allocator), + } + } +}; + pub const OutputWriter = union(enum) { capture: *OutputCapture, stdout: *StdoutOutputCapture, @@ -89,14 +142,14 @@ pub const ExecuteCommandFn = *const fn (Command, Allocator, ?*OutputCapture, ?*I pub const CommandContext = struct { allocator: Allocator, output_writer: OutputWriter, - input_source: ?*InputSource, + input_reader: InputReader, execute_command: ExecuteCommandFn, - pub fn init(allocator: Allocator, output_writer: OutputWriter, input_source: ?*InputSource, execute_command: ExecuteCommandFn) CommandContext { + pub fn init(allocator: Allocator, output_writer: OutputWriter, input_reader: InputReader, execute_command: ExecuteCommandFn) CommandContext { return CommandContext{ .allocator = allocator, .output_writer = output_writer, - .input_source = input_source, + .input_reader = input_reader, .execute_command = execute_command, }; } -- cgit v1.2.1