Browse Source

Merge pull request 'Fix zig 0.15.0-dev.1149+4e6a04929 build errors' (#283) from zawupf/ziglings-exercises:zig-0.15 into main

Reviewed-on: https://codeberg.org/ziglings/exercises/pulls/283
Chris Boesch 3 weeks ago
parent
commit
1f6ce9a268

+ 2 - 1
README.md

@@ -87,7 +87,8 @@ that if you update one, you may need to also update the other.
 
 
 ### Version Changes
 ### Version Changes
 
 
-Version-0.14.0-dev.1573
+Version-0.15.0-dev.1092
+* *2025-07-22* zig 0.15.0-dev.1092 - various changes due to new I/O API, see [#24488](https://github.com/ziglang/zig/pull/24488)
 * *2024-09-16* zig 0.14.0-dev.1573 - introduction of labeled switch, see [#21257](https://github.com/ziglang/zig/pull/21257)
 * *2024-09-16* zig 0.14.0-dev.1573 - introduction of labeled switch, see [#21257](https://github.com/ziglang/zig/pull/21257)
 * *2024-09-02* zig 0.14.0-dev.1409 - several changes in std.builtin, see [#21225](https://github.com/ziglang/zig/pull/21225)
 * *2024-09-02* zig 0.14.0-dev.1409 - several changes in std.builtin, see [#21225](https://github.com/ziglang/zig/pull/21225)
 * *2024-08-04* zig 0.14.0-dev.1224 - several changes in build system, see [#21115](https://github.com/ziglang/zig/pull/21115)
 * *2024-08-04* zig 0.14.0-dev.1224 - several changes in build system, see [#21115](https://github.com/ziglang/zig/pull/21115)

+ 7 - 8
build.zig

@@ -15,7 +15,7 @@ const print = std.debug.print;
 //     1) Getting Started
 //     1) Getting Started
 //     2) Version Changes
 //     2) Version Changes
 comptime {
 comptime {
-    const required_zig = "0.14.0-dev.1573";
+    const required_zig = "0.15.0-dev.1092";
     const current_zig = builtin.zig_version;
     const current_zig = builtin.zig_version;
     const min_zig = std.SemanticVersion.parse(required_zig) catch unreachable;
     const min_zig = std.SemanticVersion.parse(required_zig) catch unreachable;
     if (current_zig.order(min_zig) == .lt) {
     if (current_zig.order(min_zig) == .lt) {
@@ -126,19 +126,18 @@ pub fn build(b: *Build) !void {
     if (!validate_exercises()) std.process.exit(2);
     if (!validate_exercises()) std.process.exit(2);
 
 
     use_color_escapes = false;
     use_color_escapes = false;
-    if (std.io.getStdErr().supportsAnsiEscapeCodes()) {
+    if (std.fs.File.stderr().supportsAnsiEscapeCodes()) {
         use_color_escapes = true;
         use_color_escapes = true;
     } else if (builtin.os.tag == .windows) {
     } else if (builtin.os.tag == .windows) {
         const w32 = struct {
         const w32 = struct {
-            const WINAPI = std.os.windows.WINAPI;
             const DWORD = std.os.windows.DWORD;
             const DWORD = std.os.windows.DWORD;
             const ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
             const ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x0004;
             const STD_ERROR_HANDLE: DWORD = @bitCast(@as(i32, -12));
             const STD_ERROR_HANDLE: DWORD = @bitCast(@as(i32, -12));
-            extern "kernel32" fn GetStdHandle(id: DWORD) callconv(WINAPI) ?*anyopaque;
-            extern "kernel32" fn GetConsoleMode(console: ?*anyopaque, out_mode: *DWORD) callconv(WINAPI) u32;
-            extern "kernel32" fn SetConsoleMode(console: ?*anyopaque, mode: DWORD) callconv(WINAPI) u32;
+            const GetStdHandle = std.os.windows.kernel32.GetStdHandle;
+            const GetConsoleMode = std.os.windows.kernel32.GetConsoleMode;
+            const SetConsoleMode = std.os.windows.kernel32.SetConsoleMode;
         };
         };
-        const handle = w32.GetStdHandle(w32.STD_ERROR_HANDLE);
+        const handle = w32.GetStdHandle(w32.STD_ERROR_HANDLE).?;
         var mode: w32.DWORD = 0;
         var mode: w32.DWORD = 0;
         if (w32.GetConsoleMode(handle, &mode) != 0) {
         if (w32.GetConsoleMode(handle, &mode) != 0) {
             mode |= w32.ENABLE_VIRTUAL_TERMINAL_PROCESSING;
             mode |= w32.ENABLE_VIRTUAL_TERMINAL_PROCESSING;
@@ -1064,7 +1063,7 @@ const exercises = [_]Exercise{
     .{
     .{
         .main_file = "082_anonymous_structs3.zig",
         .main_file = "082_anonymous_structs3.zig",
         .output =
         .output =
-        \\"0"(bool):true "1"(bool):false "2"(i32):42 "3"(f32):3.141592e0
+        \\"0"(bool):true "1"(bool):false "2"(i32):42 "3"(f32):3.141592
         ,
         ,
         .hint = "This one is a challenge! But you have everything you need.",
         .hint = "This one is a challenge! But you have everything you need.",
     },
     },

+ 2 - 2
exercises/026_hello2.zig

@@ -16,12 +16,12 @@ const std = @import("std");
 //
 //
 pub fn main() !void {
 pub fn main() !void {
     // We get a Writer for Standard Out so we can print() to it.
     // We get a Writer for Standard Out so we can print() to it.
-    const stdout = std.io.getStdOut().writer();
+    var stdout = std.fs.File.stdout().writer(&.{});
 
 
     // Unlike std.debug.print(), the Standard Out writer can fail
     // Unlike std.debug.print(), the Standard Out writer can fail
     // with an error. We don't care _what_ the error is, we want
     // with an error. We don't care _what_ the error is, we want
     // to be able to pass it up as a return value of main().
     // to be able to pass it up as a return value of main().
     //
     //
     // We just learned of a single statement which can accomplish this.
     // We just learned of a single statement which can accomplish this.
-    stdout.print("Hello world!\n", .{});
+    stdout.interface.print("Hello world!\n", .{});
 }
 }

+ 2 - 2
exercises/034_quiz4.zig

@@ -10,11 +10,11 @@ const std = @import("std");
 const NumError = error{IllegalNumber};
 const NumError = error{IllegalNumber};
 
 
 pub fn main() void {
 pub fn main() void {
-    const stdout = std.io.getStdOut().writer();
+    var stdout = std.fs.File.stdout().writer(&.{});
 
 
     const my_num: u32 = getNumber();
     const my_num: u32 = getNumber();
 
 
-    try stdout.print("my_num={}\n", .{my_num});
+    try stdout.interface.print("my_num={}\n", .{my_num});
 }
 }
 
 
 // This function is obviously weird and non-functional. But you will not be changing it for this quiz.
 // This function is obviously weird and non-functional. But you will not be changing it for this quiz.

+ 2 - 2
exercises/098_bit_manipulation2.zig

@@ -32,7 +32,7 @@ const print = std.debug.print;
 
 
 pub fn main() !void {
 pub fn main() !void {
     // let's check the pangram
     // let's check the pangram
-    print("Is this a pangram? {?}!\n", .{isPangram("The quick brown fox jumps over the lazy dog.")});
+    print("Is this a pangram? {}!\n", .{isPangram("The quick brown fox jumps over the lazy dog.")});
 }
 }
 
 
 fn isPangram(str: []const u8) bool {
 fn isPangram(str: []const u8) bool {
@@ -45,7 +45,7 @@ fn isPangram(str: []const u8) bool {
     // loop about all characters in the string
     // loop about all characters in the string
     for (str) |c| {
     for (str) |c| {
         // if the character is an alphabetical character
         // if the character is an alphabetical character
-        if (ascii.isASCII(c) and ascii.isAlphabetic(c)) {
+        if (ascii.isAscii(c) and ascii.isAlphabetic(c)) {
             // then we set the bit at the position
             // then we set the bit at the position
             //
             //
             // to do this, we use a little trick:
             // to do this, we use a little trick:

+ 3 - 3
exercises/104_threading.zig

@@ -106,7 +106,7 @@ pub fn main() !void {
 
 
         // After the threads have been started,
         // After the threads have been started,
         // they run in parallel and we can still do some work in between.
         // they run in parallel and we can still do some work in between.
-        std.time.sleep(1500 * std.time.ns_per_ms);
+        std.Thread.sleep(1500 * std.time.ns_per_ms);
         std.debug.print("Some weird stuff, after starting the threads.\n", .{});
         std.debug.print("Some weird stuff, after starting the threads.\n", .{});
     }
     }
     // After we have left the closed area, we wait until
     // After we have left the closed area, we wait until
@@ -117,12 +117,12 @@ pub fn main() !void {
 // This function is started with every thread that we set up.
 // This function is started with every thread that we set up.
 // In our example, we pass the number of the thread as a parameter.
 // In our example, we pass the number of the thread as a parameter.
 fn thread_function(num: usize) !void {
 fn thread_function(num: usize) !void {
-    std.time.sleep(200 * num * std.time.ns_per_ms);
+    std.Thread.sleep(200 * num * std.time.ns_per_ms);
     std.debug.print("thread {d}: {s}\n", .{ num, "started." });
     std.debug.print("thread {d}: {s}\n", .{ num, "started." });
 
 
     // This timer simulates the work of the thread.
     // This timer simulates the work of the thread.
     const work_time = 3 * ((5 - num % 3) - 2);
     const work_time = 3 * ((5 - num % 3) - 2);
-    std.time.sleep(work_time * std.time.ns_per_s);
+    std.Thread.sleep(work_time * std.time.ns_per_s);
 
 
     std.debug.print("thread {d}: {s}\n", .{ num, "finished." });
     std.debug.print("thread {d}: {s}\n", .{ num, "finished." });
 }
 }

+ 4 - 4
patches/patches/026_hello2.patch

@@ -1,9 +1,9 @@
---- exercises/026_hello2.zig	2023-10-03 22:15:22.122241138 +0200
-+++ answers/026_hello2.zig	2023-10-05 20:04:06.959431737 +0200
+--- exercises/026_hello2.zig	2025-07-22 09:55:51.337832401 +0200
++++ answers/026_hello2.zig	2025-07-22 10:00:11.233348058 +0200
 @@ -23,5 +23,5 @@
 @@ -23,5 +23,5 @@
      // to be able to pass it up as a return value of main().
      // to be able to pass it up as a return value of main().
      //
      //
      // We just learned of a single statement which can accomplish this.
      // We just learned of a single statement which can accomplish this.
--    stdout.print("Hello world!\n", .{});
-+    try stdout.print("Hello world!\n", .{});
+-    stdout.interface.print("Hello world!\n", .{});
++    try stdout.interface.print("Hello world!\n", .{});
  }
  }

+ 4 - 4
patches/patches/034_quiz4.patch

@@ -1,15 +1,15 @@
---- exercises/034_quiz4.zig	2023-10-03 22:15:22.122241138 +0200
-+++ answers/034_quiz4.zig	2023-10-05 20:04:06.996099091 +0200
+--- exercises/034_quiz4.zig	2025-07-22 09:55:51.337832401 +0200
++++ answers/034_quiz4.zig	2025-07-22 10:05:08.320323184 +0200
 @@ -9,10 +9,10 @@
 @@ -9,10 +9,10 @@
  
  
  const NumError = error{IllegalNumber};
  const NumError = error{IllegalNumber};
  
  
 -pub fn main() void {
 -pub fn main() void {
 +pub fn main() !void {
 +pub fn main() !void {
-     const stdout = std.io.getStdOut().writer();
+     var stdout = std.fs.File.stdout().writer(&.{});
  
  
 -    const my_num: u32 = getNumber();
 -    const my_num: u32 = getNumber();
 +    const my_num: u32 = try getNumber();
 +    const my_num: u32 = try getNumber();
  
  
-     try stdout.print("my_num={}\n", .{my_num});
+     try stdout.interface.print("my_num={}\n", .{my_num});
  }
  }

+ 12 - 14
test/tests.zig

@@ -161,7 +161,7 @@ const CheckNamedStep = struct {
         );
         );
         defer stderr_file.close();
         defer stderr_file.close();
 
 
-        const stderr = stderr_file.reader();
+        var stderr = stderr_file.readerStreaming(&.{});
         {
         {
             // Skip the logo.
             // Skip the logo.
             const nlines = mem.count(u8, root.logo, "\n");
             const nlines = mem.count(u8, root.logo, "\n");
@@ -169,10 +169,10 @@ const CheckNamedStep = struct {
 
 
             var lineno: usize = 0;
             var lineno: usize = 0;
             while (lineno < nlines) : (lineno += 1) {
             while (lineno < nlines) : (lineno += 1) {
-                _ = try readLine(stderr, &buf);
+                _ = try readLine(&stderr, &buf);
             }
             }
         }
         }
-        try check_output(step, ex, stderr);
+        try check_output(step, ex, &stderr);
     }
     }
 };
 };
 
 
@@ -213,7 +213,7 @@ const CheckStep = struct {
         );
         );
         defer stderr_file.close();
         defer stderr_file.close();
 
 
-        const stderr = stderr_file.reader();
+        var stderr = stderr_file.readerStreaming(&.{});
         for (exercises) |ex| {
         for (exercises) |ex| {
             if (ex.number() == 1) {
             if (ex.number() == 1) {
                 // Skip the logo.
                 // Skip the logo.
@@ -222,15 +222,15 @@ const CheckStep = struct {
 
 
                 var lineno: usize = 0;
                 var lineno: usize = 0;
                 while (lineno < nlines) : (lineno += 1) {
                 while (lineno < nlines) : (lineno += 1) {
-                    _ = try readLine(stderr, &buf);
+                    _ = try readLine(&stderr, &buf);
                 }
                 }
             }
             }
-            try check_output(step, ex, stderr);
+            try check_output(step, ex, &stderr);
         }
         }
     }
     }
 };
 };
 
 
-fn check_output(step: *Step, exercise: Exercise, reader: Reader) !void {
+fn check_output(step: *Step, exercise: Exercise, reader: *Reader) !void {
     const b = step.owner;
     const b = step.owner;
 
 
     var buf: [1024]u8 = undefined;
     var buf: [1024]u8 = undefined;
@@ -297,12 +297,9 @@ fn check(
     }
     }
 }
 }
 
 
-fn readLine(reader: fs.File.Reader, buf: []u8) !?[]const u8 {
-    if (try reader.readUntilDelimiterOrEof(buf, '\n')) |line| {
-        return mem.trimRight(u8, line, " \r\n");
-    }
-
-    return null;
+fn readLine(reader: *fs.File.Reader, buf: []u8) !?[]const u8 {
+    try reader.interface.readSliceAll(buf);
+    return mem.trimRight(u8, buf, " \r\n");
 }
 }
 
 
 /// Fails with a custom error message.
 /// Fails with a custom error message.
@@ -405,7 +402,8 @@ fn heal(allocator: Allocator, exercises: []const Exercise, work_path: []const u8
 /// difference that returns an error when the temp path cannot be created.
 /// difference that returns an error when the temp path cannot be created.
 pub fn makeTempPath(b: *Build) ![]const u8 {
 pub fn makeTempPath(b: *Build) ![]const u8 {
     const rand_int = std.crypto.random.int(u64);
     const rand_int = std.crypto.random.int(u64);
-    const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ Build.hex64(rand_int);
+    const rand_hex64 = std.fmt.hex(rand_int);
+    const tmp_dir_sub_path = "tmp" ++ fs.path.sep_str ++ rand_hex64;
     const path = b.cache_root.join(b.allocator, &.{tmp_dir_sub_path}) catch
     const path = b.cache_root.join(b.allocator, &.{tmp_dir_sub_path}) catch
         @panic("OOM");
         @panic("OOM");
     try b.cache_root.handle.makePath(tmp_dir_sub_path);
     try b.cache_root.handle.makePath(tmp_dir_sub_path);