From 6ff0b0f1ba692fb939cf1bfcd039bf22a3e59042 Mon Sep 17 00:00:00 2001 From: by Date: Thu, 16 Jul 2026 23:48:43 +0800 Subject: [PATCH] fix(rtt): Down.mode() uses self.flags instead of self.mode - Bug: Down.mode() referenced self.mode (the method itself) instead of the flags field, causing a compile error on Zig 0.17 - Fix: changed self.mode to self.flags, matching the Up.mode() pattern - Add build.zig test step with 5 unit tests covering mode get/set, Writer/Reader compilation, and Up mode verification - Add test for Down set_mode + mode round-trip --- modules/rtt/build.zig | 13 ++++++ modules/rtt/src/rtt.zig | 87 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/modules/rtt/build.zig b/modules/rtt/build.zig index 0eb89932b..1473588ba 100644 --- a/modules/rtt/build.zig +++ b/modules/rtt/build.zig @@ -3,9 +3,22 @@ const std = @import("std"); pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); + _ = b.addModule("rtt", .{ .root_source_file = b.path("src/rtt.zig"), .target = target, .optimize = optimize, }); + + const test_step = b.step("test", "Run unit tests"); + const lib_tests = b.addTest(.{ + .name = "rtt-tests", + .root_module = b.createModule(.{ + .root_source_file = b.path("src/rtt.zig"), + .target = target, + .optimize = optimize, + }), + }); + const run_lib_tests = b.addRunArtifact(lib_tests); + test_step.dependOn(&run_lib_tests.step); } diff --git a/modules/rtt/src/rtt.zig b/modules/rtt/src/rtt.zig index 358e6274a..1acfb2151 100644 --- a/modules/rtt/src/rtt.zig +++ b/modules/rtt/src/rtt.zig @@ -33,6 +33,91 @@ const Header = extern struct { } }; +test { + // Verify Down mode() returns correct mode after init + const LockOps = struct { + fn lock(_: *anyopaque) void {} + fn unlock(_: *anyopaque) void {} + }; + const my_lock: AnyLock = .{ .context = undefined, .lock_fn = LockOps.lock, .unlock_fn = LockOps.unlock }; + const TestDown = channel.Down(my_lock, struct { + inline fn barrier() void {} + }.barrier); + var buf: [64]u8 align(4) = undefined; + var d: TestDown = undefined; + d.init("test", &buf, .NoBlockSkip); + try std.testing.expectEqual(.NoBlockSkip, d.mode()); +} + +test { + // Verify Down set_mode changes mode + const LockOps = struct { + fn lock(_: *anyopaque) void {} + fn unlock(_: *anyopaque) void {} + }; + const my_lock: AnyLock = .{ .context = undefined, .lock_fn = LockOps.lock, .unlock_fn = LockOps.unlock }; + const TestDown = channel.Down(my_lock, struct { + inline fn barrier() void {} + }.barrier); + var buf: [64]u8 align(4) = undefined; + var d: TestDown = undefined; + d.init("test", &buf, .BlockIfFull); + try std.testing.expectEqual(.BlockIfFull, d.mode()); + d.set_mode(.NoBlockTrim); + try std.testing.expectEqual(.NoBlockTrim, d.mode()); +} + +test { + // Verify Up channel Writer compiles and drain works + const LockOps = struct { + fn lock(_: *anyopaque) void {} + fn unlock(_: *anyopaque) void {} + }; + const my_lock: AnyLock = .{ .context = undefined, .lock_fn = LockOps.lock, .unlock_fn = LockOps.unlock }; + const TestUp = channel.Up(my_lock, struct { + inline fn barrier() void {} + }.barrier); + var buf: [128]u8 align(4) = undefined; + var u: TestUp = undefined; + u.init("test", &buf, .NoBlockTrim); + var wbuf: [32]u8 = undefined; + var w = u.writer(&wbuf); + _ = w.interface.write("hello") catch 0; +} + +test { + // Verify Down channel Reader compiles + const LockOps = struct { + fn lock(_: *anyopaque) void {} + fn unlock(_: *anyopaque) void {} + }; + const my_lock: AnyLock = .{ .context = undefined, .lock_fn = LockOps.lock, .unlock_fn = LockOps.unlock }; + const TestDown = channel.Down(my_lock, struct { + inline fn barrier() void {} + }.barrier); + var buf: [64]u8 align(4) = undefined; + var d: TestDown = undefined; + d.init("test", &buf, .NoBlockSkip); + var rbuf: [32]u8 = undefined; + _ = d.reader(&rbuf); +} + +test { + // Verify Up mode() returns correct mode + const LockOps = struct { + fn lock(_: *anyopaque) void {} + fn unlock(_: *anyopaque) void {} + }; + const my_lock: AnyLock = .{ .context = undefined, .lock_fn = LockOps.lock, .unlock_fn = LockOps.unlock }; + const TestUp = channel.Up(my_lock, struct { + inline fn barrier() void {} + }.barrier); + var buf: [128]u8 align(4) = undefined; + var u: TestUp = undefined; + u.init("test", &buf, .BlockIfFull); + try std.testing.expectEqual(.BlockIfFull, u.mode()); +} + pub const channel = struct { pub const Mode = enum(usize) { NoBlockSkip = 0, @@ -305,7 +390,7 @@ pub const channel = struct { } pub fn mode(self: *Self) Mode { - return @enumFromInt(self.mode & 3); + return @enumFromInt(self.flags & 3); } pub fn set_mode(self: *Self, mode_: Mode) void {