authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-20 13:43:05-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-20 15:30:00-05:00
logb0d2ebe529593566f209d34d5bbbfd72cde2a6b9
tree3b280e2487e1577af2d064daff57bb8233ec4b0d
parent3d53a95718bbf7abd17cf69c623aff4e9a97a0b4

remove std.io.readLine

This was deceptive. It was always meant to be sort of a "GNU readline" sort of thing where it provides a Command Line Interface to input text. However that functionality did not exist and it was basically a red herring for people trying to read line-delimited input from a stream. In this commit the API is deleted, so that people can find the proper API more easily. A CLI text input abstraction would be useful but may not even need to be in the standard library. As you can see in this commit, the guess_number CLI game gets by just fine by using `std.fs.File.read`.

2 files changed, 7 insertions(+), 74 deletions(-)

lib/std/io.zig-67
......@@ -790,73 +790,6 @@ pub const BufferedAtomicFile = struct {
790790 }
791791};
792792
793pub fn readLine(buf: *std.Buffer) ![]u8 {
794 var stdin_stream = getStdIn().inStream();
795 return readLineFrom(&stdin_stream.stream, buf);
796}
797
798/// Reads all characters until the next newline into buf, and returns
799/// a slice of the characters read (excluding the newline character(s)).
800pub fn readLineFrom(stream: var, buf: *std.Buffer) ![]u8 {
801 const start = buf.len();
802 while (true) {
803 const byte = try stream.readByte();
804 switch (byte) {
805 '\r' => {
806 // trash the following \n
807 _ = try stream.readByte();
808 return buf.toSlice()[start..];
809 },
810 '\n' => return buf.toSlice()[start..],
811 else => try buf.appendByte(byte),
812 }
813 }
814}
815
816test "io.readLineFrom" {
817 var buf = try std.Buffer.initSize(testing.allocator, 0);
818 defer buf.deinit();
819 var mem_stream = SliceInStream.init(
820 \\Line 1
821 \\Line 22
822 \\Line 333
823 );
824 const stream = &mem_stream.stream;
825
826 testing.expectEqualSlices(u8, "Line 1", try readLineFrom(stream, &buf));
827 testing.expectEqualSlices(u8, "Line 22", try readLineFrom(stream, &buf));
828 testing.expectError(error.EndOfStream, readLineFrom(stream, &buf));
829 testing.expectEqualSlices(u8, "Line 1Line 22Line 333", buf.toSlice());
830}
831
832pub fn readLineSlice(slice: []u8) ![]u8 {
833 var stdin_stream = getStdIn().inStream();
834 return readLineSliceFrom(&stdin_stream.stream, slice);
835}
836
837/// Reads all characters until the next newline into slice, and returns
838/// a slice of the characters read (excluding the newline character(s)).
839pub fn readLineSliceFrom(stream: var, slice: []u8) ![]u8 {
840 // We cannot use Buffer.fromOwnedSlice, as it wants to append a null byte
841 // after taking ownership, which would always require an allocation.
842 var buf = std.Buffer{ .list = std.ArrayList(u8).fromOwnedSlice(testing.failing_allocator, slice) };
843 try buf.resize(0);
844 return try readLineFrom(stream, &buf);
845}
846
847test "io.readLineSliceFrom" {
848 var buf: [7]u8 = undefined;
849 var mem_stream = SliceInStream.init(
850 \\Line 1
851 \\Line 22
852 \\Line 333
853 );
854 const stream = &mem_stream.stream;
855
856 testing.expectEqualSlices(u8, "Line 1", try readLineSliceFrom(stream, buf[0..]));
857 testing.expectError(error.OutOfMemory, readLineSliceFrom(stream, buf[0..]));
858}
859
860793pub const Packing = enum {
861794 /// Pack data to byte alignment
862795 Byte,
test/standalone/guess_number/main.zig+7-7
......@@ -5,6 +5,7 @@ const fmt = std.fmt;
55
66pub fn main() !void {
77 const stdout = &io.getStdOut().outStream().stream;
8 const stdin = io.getStdIn();
89
910 try stdout.print("Welcome to the Guess Number Game in Zig.\n", .{});
1011
......@@ -22,13 +23,12 @@ pub fn main() !void {
2223 try stdout.print("\nGuess a number between 1 and 100: ", .{});
2324 var line_buf: [20]u8 = undefined;
2425
25 const line = io.readLineSlice(line_buf[0..]) catch |err| switch (err) {
26 error.OutOfMemory => {
27 try stdout.print("Input too long.\n", .{});
28 continue;
29 },
30 else => return err,
31 };
26 const amt = try stdin.read(&line_buf);
27 if (amt == line_buf.len) {
28 try stdout.print("Input too long.\n", .{});
29 continue;
30 }
31 const line = std.mem.trimRight(u8, line_buf[0..amt], "\r\n");
3232
3333 const guess = fmt.parseUnsigned(u8, line, 10) catch {
3434 try stdout.print("Invalid number.\n", .{});