mirror of
https://codeberg.org/ziglings/exercises.git
synced 2025-09-20 14:45:36 +00:00
Merge branch 'main' into test-expect
This commit is contained in:
commit
a46db7e0e8
13
README.md
13
README.md
|
@ -25,10 +25,9 @@ language such as C.
|
||||||
|
|
||||||
Each exercise is self-contained and self-explained. However,
|
Each exercise is self-contained and self-explained. However,
|
||||||
you're encouraged to also check out these Zig language resources
|
you're encouraged to also check out these Zig language resources
|
||||||
for more detail:
|
for more details:
|
||||||
|
|
||||||
* https://ziglang.org/learn/
|
* https://ziglang.org/learn/
|
||||||
* https://ziglearn.org/
|
|
||||||
* https://ziglang.org/documentation/master/
|
* https://ziglang.org/documentation/master/
|
||||||
* [Zig in Depth! (video series)](https://www.youtube.com/watch?v=MMtvGA1YhW4&list=PLtB7CL7EG7pCw7Xy1SQC53Gl8pI7aDg9t&pp=iAQB)
|
* [Zig in Depth! (video series)](https://www.youtube.com/watch?v=MMtvGA1YhW4&list=PLtB7CL7EG7pCw7Xy1SQC53Gl8pI7aDg9t&pp=iAQB)
|
||||||
|
|
||||||
|
@ -45,7 +44,7 @@ Verify the installation and build number of `zig` like so:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ zig version
|
$ zig version
|
||||||
0.15.0-dev.xxxx+xxxxxxxxx
|
0.16.0-dev.xxxx+xxxxxxxxx
|
||||||
```
|
```
|
||||||
|
|
||||||
Clone this repository with Git:
|
Clone this repository with Git:
|
||||||
|
@ -73,8 +72,8 @@ the appropriate tag.
|
||||||
The Zig language is under very active development. In order to be
|
The Zig language is under very active development. In order to be
|
||||||
current, Ziglings tracks **development** builds of the Zig
|
current, Ziglings tracks **development** builds of the Zig
|
||||||
compiler rather than versioned **release** builds. The last
|
compiler rather than versioned **release** builds. The last
|
||||||
stable release was `0.14.1`, but Ziglings needs a dev build with
|
stable release was `0.15.1`, but Ziglings needs a dev build with
|
||||||
pre-release version "0.15.0" and a build number at least as high
|
pre-release version "0.16.0" and a build number at least as high
|
||||||
as that shown in the example version check above.
|
as that shown in the example version check above.
|
||||||
|
|
||||||
It is likely that you'll download a build which is _greater_ than
|
It is likely that you'll download a build which is _greater_ than
|
||||||
|
@ -87,7 +86,9 @@ that if you update one, you may need to also update the other.
|
||||||
|
|
||||||
### Version Changes
|
### Version Changes
|
||||||
|
|
||||||
Version-0.14.0-dev.1573
|
* *2025-08-15* zig 0.15.0-dev.1519 - changes in array list, see [#24801](https://github.com/ziglang/zig/pull/24801)
|
||||||
|
* *2025-08-08* zig 0.15.0-dev.1380 - changes in build system, see [#24588](https://github.com/ziglang/zig/pull/24588)
|
||||||
|
* *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)
|
||||||
|
|
31
build.zig
31
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.1519";
|
||||||
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;
|
const GetStdHandle = std.os.windows.kernel32.GetStdHandle;
|
||||||
extern "kernel32" fn GetConsoleMode(console: ?*anyopaque, out_mode: *DWORD) callconv(WINAPI) u32;
|
const GetConsoleMode = std.os.windows.kernel32.GetConsoleMode;
|
||||||
extern "kernel32" fn SetConsoleMode(console: ?*anyopaque, mode: DWORD) callconv(WINAPI) u32;
|
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;
|
||||||
|
@ -493,7 +492,7 @@ const ZiglingStep = struct {
|
||||||
const path = join(b.allocator, &.{ self.work_path, exercise_path }) catch
|
const path = join(b.allocator, &.{ self.work_path, exercise_path }) catch
|
||||||
@panic("OOM");
|
@panic("OOM");
|
||||||
|
|
||||||
var zig_args = std.ArrayList([]const u8).init(b.allocator);
|
var zig_args = std.array_list.Managed([]const u8).init(b.allocator);
|
||||||
defer zig_args.deinit();
|
defer zig_args.deinit();
|
||||||
|
|
||||||
zig_args.append(b.graph.zig_exe) catch @panic("OOM");
|
zig_args.append(b.graph.zig_exe) catch @panic("OOM");
|
||||||
|
@ -509,6 +508,10 @@ const ZiglingStep = struct {
|
||||||
zig_args.append("-lc") catch @panic("OOM");
|
zig_args.append("-lc") catch @panic("OOM");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (b.reference_trace) |rt| {
|
||||||
|
zig_args.append(b.fmt("-freference-trace={}", .{rt})) catch @panic("OOM");
|
||||||
|
}
|
||||||
|
|
||||||
zig_args.append(b.pathFromRoot(path)) catch @panic("OOM");
|
zig_args.append(b.pathFromRoot(path)) catch @panic("OOM");
|
||||||
|
|
||||||
zig_args.append("--cache-dir") catch @panic("OOM");
|
zig_args.append("--cache-dir") catch @panic("OOM");
|
||||||
|
@ -520,7 +523,7 @@ const ZiglingStep = struct {
|
||||||
// NOTE: After many changes in zig build system, we need to create the cache path manually.
|
// NOTE: After many changes in zig build system, we need to create the cache path manually.
|
||||||
// See https://github.com/ziglang/zig/pull/21115
|
// See https://github.com/ziglang/zig/pull/21115
|
||||||
// Maybe there is a better way (in the future).
|
// Maybe there is a better way (in the future).
|
||||||
const exe_dir = try self.step.evalZigProcess(zig_args.items, prog_node, false);
|
const exe_dir = try self.step.evalZigProcess(zig_args.items, prog_node, false, null, b.allocator);
|
||||||
const exe_name = switch (self.exercise.kind) {
|
const exe_name = switch (self.exercise.kind) {
|
||||||
.exe => self.exercise.name(),
|
.exe => self.exercise.name(),
|
||||||
.@"test" => "test",
|
.@"test" => "test",
|
||||||
|
@ -582,17 +585,17 @@ fn resetLine() void {
|
||||||
/// Removes trailing whitespace for each line in buf, also ensuring that there
|
/// Removes trailing whitespace for each line in buf, also ensuring that there
|
||||||
/// are no trailing LF characters at the end.
|
/// are no trailing LF characters at the end.
|
||||||
pub fn trimLines(allocator: std.mem.Allocator, buf: []const u8) ![]const u8 {
|
pub fn trimLines(allocator: std.mem.Allocator, buf: []const u8) ![]const u8 {
|
||||||
var list = try std.ArrayList(u8).initCapacity(allocator, buf.len);
|
var list = try std.array_list.Aligned(u8, null).initCapacity(allocator, buf.len);
|
||||||
|
|
||||||
var iter = std.mem.splitSequence(u8, buf, " \n");
|
var iter = std.mem.splitSequence(u8, buf, " \n");
|
||||||
while (iter.next()) |line| {
|
while (iter.next()) |line| {
|
||||||
// TODO: trimming CR characters is probably not necessary.
|
// TODO: trimming CR characters is probably not necessary.
|
||||||
const data = std.mem.trimRight(u8, line, " \r");
|
const data = std.mem.trimRight(u8, line, " \r");
|
||||||
try list.appendSlice(data);
|
try list.appendSlice(allocator, data);
|
||||||
try list.append('\n');
|
try list.append(allocator, '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = try list.toOwnedSlice(); // TODO: probably not necessary
|
const result = try list.toOwnedSlice(allocator); // TODO: probably not necessary
|
||||||
|
|
||||||
// Remove the trailing LF character, that is always present in the exercise
|
// Remove the trailing LF character, that is always present in the exercise
|
||||||
// output.
|
// output.
|
||||||
|
@ -1064,7 +1067,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.",
|
||||||
},
|
},
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
// example that takes two parameters. As you can see, parameters
|
// example that takes two parameters. As you can see, parameters
|
||||||
// are declared just like any other types ("name": "type"):
|
// are declared just like any other types ("name": "type"):
|
||||||
//
|
//
|
||||||
// fn myFunction(number: u8, is_lucky: bool) {
|
// fn myFunction(number: u8, is_lucky: bool) void {
|
||||||
// ...
|
// ...
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
|
|
|
@ -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", .{});
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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:
|
||||||
|
|
|
@ -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." });
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
--- exercises/026_hello2.zig 2023-10-03 22:15:22.122241138 +0200
|
--- exercises/026_hello2.zig 2025-07-22 09:55:51.337832401 +0200
|
||||||
+++ answers/026_hello2.zig 2023-10-05 20:04:06.959431737 +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", .{});
|
- stdout.interface.print("Hello world!\n", .{});
|
||||||
+ try stdout.print("Hello world!\n", .{});
|
+ try stdout.interface.print("Hello world!\n", .{});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
--- exercises/034_quiz4.zig 2023-10-03 22:15:22.122241138 +0200
|
--- exercises/034_quiz4.zig 2025-07-22 09:55:51.337832401 +0200
|
||||||
+++ answers/034_quiz4.zig 2023-10-05 20:04:06.996099091 +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});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +0,0 @@
|
||||||
--- exercises/084_async.zig 2023-10-03 22:15:22.125574535 +0200
|
|
||||||
+++ answers/084_async.zig 2023-10-05 20:04:07.219436606 +0200
|
|
||||||
@@ -48,7 +48,7 @@
|
|
||||||
pub fn main() void {
|
|
||||||
// Additional Hint: you can assign things to '_' when you
|
|
||||||
// don't intend to do anything with them.
|
|
||||||
- foo();
|
|
||||||
+ _ = async foo();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn foo() void {
|
|
|
@ -1,10 +0,0 @@
|
||||||
--- exercises/085_async2.zig 2023-10-03 22:15:22.125574535 +0200
|
|
||||||
+++ answers/085_async2.zig 2023-10-05 20:04:07.226103397 +0200
|
|
||||||
@@ -19,6 +19,7 @@
|
|
||||||
|
|
||||||
pub fn main() void {
|
|
||||||
var foo_frame = async foo();
|
|
||||||
+ resume foo_frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn foo() void {
|
|
|
@ -1,16 +0,0 @@
|
||||||
--- exercises/086_async3.zig 2023-10-03 22:15:22.125574535 +0200
|
|
||||||
+++ answers/086_async3.zig 2023-10-05 20:04:07.229436793 +0200
|
|
||||||
@@ -13,7 +13,12 @@
|
|
||||||
const n = 5;
|
|
||||||
var foo_frame = async foo(n);
|
|
||||||
|
|
||||||
- ???
|
|
||||||
+ // Silly solution. You can also use a loop.
|
|
||||||
+ resume foo_frame;
|
|
||||||
+ resume foo_frame;
|
|
||||||
+ resume foo_frame;
|
|
||||||
+ resume foo_frame;
|
|
||||||
+ resume foo_frame;
|
|
||||||
|
|
||||||
print("\n", .{});
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
--- exercises/087_async4.zig 2023-10-03 22:15:22.125574535 +0200
|
|
||||||
+++ answers/087_async4.zig 2023-10-05 20:04:07.236103584 +0200
|
|
||||||
@@ -16,7 +16,7 @@
|
|
||||||
|
|
||||||
while (global_counter <= 5) {
|
|
||||||
print("{} ", .{global_counter});
|
|
||||||
- ???
|
|
||||||
+ resume foo_frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
print("\n", .{});
|
|
||||||
@@ -24,7 +24,7 @@
|
|
||||||
|
|
||||||
fn foo() void {
|
|
||||||
while (true) {
|
|
||||||
- ???
|
|
||||||
- ???
|
|
||||||
+ global_counter += 1;
|
|
||||||
+ suspend {}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
--- exercises/088_async5.zig 2023-10-03 22:15:22.125574535 +0200
|
|
||||||
+++ answers/088_async5.zig 2023-10-05 20:04:07.239436980 +0200
|
|
||||||
@@ -36,7 +36,7 @@
|
|
||||||
pub fn main() void {
|
|
||||||
var myframe = async getPageTitle("http://example.com");
|
|
||||||
|
|
||||||
- var value = ???
|
|
||||||
+ var value = await myframe;
|
|
||||||
|
|
||||||
print("{s}\n", .{value});
|
|
||||||
}
|
|
|
@ -1,13 +0,0 @@
|
||||||
--- exercises/089_async6.zig 2023-10-03 22:15:22.125574535 +0200
|
|
||||||
+++ answers/089_async6.zig 2023-10-05 20:04:07.242770376 +0200
|
|
||||||
@@ -41,8 +41,8 @@
|
|
||||||
var com_frame = async getPageTitle("http://example.com");
|
|
||||||
var org_frame = async getPageTitle("http://example.org");
|
|
||||||
|
|
||||||
- var com_title = com_frame;
|
|
||||||
- var org_title = org_frame;
|
|
||||||
+ var com_title = await com_frame;
|
|
||||||
+ var org_title = await org_frame;
|
|
||||||
|
|
||||||
print(".com: {s}, .org: {s}.\n", .{ com_title, org_title });
|
|
||||||
}
|
|
|
@ -1,11 +0,0 @@
|
||||||
--- exercises/090_async7.zig 2023-10-03 22:15:22.125574535 +0200
|
|
||||||
+++ answers/090_async7.zig 2023-10-05 20:04:07.249437167 +0200
|
|
||||||
@@ -29,7 +29,7 @@
|
|
||||||
// The main() function can not be async. But we know
|
|
||||||
// getBeef() will not suspend with this particular
|
|
||||||
// invocation. Please make this okay:
|
|
||||||
- var my_beef = getBeef(0);
|
|
||||||
+ var my_beef = nosuspend getBeef(0);
|
|
||||||
|
|
||||||
print("beef? {X}!\n", .{my_beef});
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
--- exercises/091_async8.zig 2023-10-03 22:15:22.125574535 +0200
|
|
||||||
+++ answers/091_async8.zig 2023-10-05 20:04:07.252770563 +0200
|
|
||||||
@@ -17,7 +17,7 @@
|
|
||||||
|
|
||||||
var frame = async suspendable();
|
|
||||||
|
|
||||||
- print("X", .{});
|
|
||||||
+ print("D", .{});
|
|
||||||
|
|
||||||
resume frame;
|
|
||||||
|
|
||||||
@@ -25,11 +25,11 @@
|
|
||||||
}
|
|
||||||
|
|
||||||
fn suspendable() void {
|
|
||||||
- print("X", .{});
|
|
||||||
+ print("B", .{});
|
|
||||||
|
|
||||||
suspend {
|
|
||||||
- print("X", .{});
|
|
||||||
+ print("C", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
- print("X", .{});
|
|
||||||
+ print("E", .{});
|
|
||||||
}
|
|
|
@ -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 {
|
fn readLine(reader: *fs.File.Reader, buf: []u8) !?[]const u8 {
|
||||||
if (try reader.readUntilDelimiterOrEof(buf, '\n')) |line| {
|
try reader.interface.readSliceAll(buf);
|
||||||
return mem.trimRight(u8, line, " \r\n");
|
return mem.trimRight(u8, buf, " \r\n");
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user