diff --git a/std/atomic/queue.zig b/std/atomic/queue.zig index c0c050f0ba..3c18032587 100644 --- a/std/atomic/queue.zig +++ b/std/atomic/queue.zig @@ -103,25 +103,32 @@ pub fn Queue(comptime T: type) type { } pub fn dump(self: *Self) void { + var stderr_file = std.io.getStdErr() catch return; + const stderr = &stderr_file.outStream().stream; + const Error = @typeInfo(@typeOf(stderr)).Pointer.child.Error; + + self.dumpToStream(Error, stderr) catch return; + } + + pub fn dumpToStream(self: *Self, comptime Error: type, stream: *std.io.OutStream(Error)) Error!void { + const S = struct.{ + fn dumpRecursive(s: *std.io.OutStream(Error), optional_node: ?*Node, indent: usize) Error!void { + try s.writeByteNTimes(' ', indent); + if (optional_node) |node| { + try s.print("0x{x}={}\n", @ptrToInt(node), node.data); + try dumpRecursive(s, node.next, indent + 1); + } else { + try s.print("(null)\n"); + } + } + }; const held = self.mutex.acquire(); defer held.release(); - std.debug.warn("head: "); - dumpRecursive(self.head, 0); - std.debug.warn("tail: "); - dumpRecursive(self.tail, 0); - } - - fn dumpRecursive(optional_node: ?*Node, indent: usize) void { - var stderr_file = std.io.getStdErr() catch return; - const stderr = &stderr_file.outStream().stream; - stderr.writeByteNTimes(' ', indent) catch return; - if (optional_node) |node| { - std.debug.warn("0x{x}={}\n", @ptrToInt(node), node.data); - dumpRecursive(node.next, indent + 1); - } else { - std.debug.warn("(null)\n"); - } + try stream.print("head: "); + try S.dumpRecursive(stream, self.head, 0); + try stream.print("tail: "); + try S.dumpRecursive(stream, self.tail, 0); } }; } @@ -274,3 +281,63 @@ test "std.atomic.Queue single-threaded" { assert(queue.get() == null); } + +test "std.atomic.Queue dump" { + const mem = std.mem; + const SliceOutStream = std.io.SliceOutStream; + var buffer: [1024]u8 = undefined; + var expected_buffer: [1024]u8 = undefined; + var sos = SliceOutStream.init(buffer[0..]); + + var queue = Queue(i32).init(); + + // Test empty stream + sos.reset(); + try queue.dumpToStream(SliceOutStream.Error, &sos.stream); + assert(mem.eql(u8, buffer[0..sos.pos], + \\head: (null) + \\tail: (null) + \\ + )); + + // Test a stream with one element + var node_0 = Queue(i32).Node.{ + .data = 1, + .next = undefined, + .prev = undefined, + }; + queue.put(&node_0); + + sos.reset(); + try queue.dumpToStream(SliceOutStream.Error, &sos.stream); + + var expected = try std.fmt.bufPrint(expected_buffer[0..], + \\head: 0x{x}=1 + \\ (null) + \\tail: 0x{x}=1 + \\ (null) + \\ + , @ptrToInt(queue.head), @ptrToInt(queue.tail)); + assert(mem.eql(u8, buffer[0..sos.pos], expected)); + + // Test a stream with two elements + var node_1 = Queue(i32).Node.{ + .data = 2, + .next = undefined, + .prev = undefined, + }; + queue.put(&node_1); + + sos.reset(); + try queue.dumpToStream(SliceOutStream.Error, &sos.stream); + + expected = try std.fmt.bufPrint(expected_buffer[0..], + \\head: 0x{x}=1 + \\ 0x{x}=2 + \\ (null) + \\tail: 0x{x}=2 + \\ (null) + \\ + , @ptrToInt(queue.head), @ptrToInt(queue.head.?.next), @ptrToInt(queue.tail)); + assert(mem.eql(u8, buffer[0..sos.pos], expected)); +} diff --git a/std/io.zig b/std/io.zig index c35eda821c..69d77a0fc9 100644 --- a/std/io.zig +++ b/std/io.zig @@ -442,7 +442,7 @@ pub const SliceOutStream = struct.{ pub stream: Stream, - pos: usize, + pub pos: usize, slice: []u8, pub fn init(slice: []u8) SliceOutStream {