anyerror means the error set is known only at runtime.
The Operating System returned an undocumented error code.
This error is in theory not possible, but it would be better to handle this error than to invoke undefined behavior.
When this error code is observed, it usually means the Zig Standard Library needs a small patch to add the error code to the error set for the respective function.
pub const InitError = error{OutOfMemory} || posix.UnexpectedErrorpub fn init(allocator: Allocator) InitError!ArgIteratorWasiYou must call deinit to free the internal buffer of the iterator after you are done.
allocator: Allocatorpub fn init(allocator: Allocator) InitError!ArgIteratorWasi {
const fetched_args = try ArgIteratorWasi.internalInit(allocator);
return ArgIteratorWasi{
.allocator = allocator,
.index = 0,
.args = fetched_args,
};
}pub fn next(self: *ArgIteratorWasi) ?[:0]const u8self: *ArgIteratorWasipub fn next(self: *ArgIteratorWasi) ?[:0]const u8 {
if (self.index == self.args.len) return null;
const arg = self.args[self.index];
self.index += 1;
return arg;
}pub fn skip(self: *ArgIteratorWasi) boolself: *ArgIteratorWasipub fn skip(self: *ArgIteratorWasi) bool {
if (self.index == self.args.len) return false;
self.index += 1;
return true;
}pub fn deinit(self: *ArgIteratorWasi) voidCall to free the internal buffer of the iterator.
self: *ArgIteratorWasipub fn deinit(self: *ArgIteratorWasi) void {
const last_item = self.args[self.args.len - 1];
const last_byte_addr = @intFromPtr(last_item.ptr) + last_item.len + 1; // null terminated
const first_item_ptr = self.args[0].ptr;
const len = last_byte_addr - @intFromPtr(first_item_ptr);
self.allocator.free(first_item_ptr[0..len]);
self.allocator.free(self.args);
}pub const ArgIteratorWasi = struct {
allocator: Allocator,
index: usize,
args: [][:0]u8,
pub const InitError = error{OutOfMemory} || posix.UnexpectedError;
/// You must call deinit to free the internal buffer of the
/// iterator after you are done.
pub fn init(allocator: Allocator) InitError!ArgIteratorWasi {
const fetched_args = try ArgIteratorWasi.internalInit(allocator);
return ArgIteratorWasi{
.allocator = allocator,
.index = 0,
.args = fetched_args,
};
}
fn internalInit(allocator: Allocator) InitError![][:0]u8 {
var count: usize = undefined;
var buf_size: usize = undefined;
switch (std.os.wasi.args_sizes_get(&count, &buf_size)) {
.SUCCESS => {},
else => |err| return posix.unexpectedErrno(err),
}
if (count == 0) {
return &[_][:0]u8{};
}
const argv = try allocator.alloc([*:0]u8, count);
defer allocator.free(argv);
const argv_buf = try allocator.alloc(u8, buf_size);
switch (std.os.wasi.args_get(argv.ptr, argv_buf.ptr)) {
.SUCCESS => {},
else => |err| return posix.unexpectedErrno(err),
}
var result_args = try allocator.alloc([:0]u8, count);
var i: usize = 0;
while (i < count) : (i += 1) {
result_args[i] = mem.sliceTo(argv[i], 0);
}
return result_args;
}
pub fn next(self: *ArgIteratorWasi) ?[:0]const u8 {
if (self.index == self.args.len) return null;
const arg = self.args[self.index];
self.index += 1;
return arg;
}
pub fn skip(self: *ArgIteratorWasi) bool {
if (self.index == self.args.len) return false;
self.index += 1;
return true;
}
/// Call to free the internal buffer of the iterator.
pub fn deinit(self: *ArgIteratorWasi) void {
const last_item = self.args[self.args.len - 1];
const last_byte_addr = @intFromPtr(last_item.ptr) + last_item.len + 1; // null terminated
const first_item_ptr = self.args[0].ptr;
const len = last_byte_addr - @intFromPtr(first_item_ptr);
self.allocator.free(first_item_ptr[0..len]);
self.allocator.free(self.args);
}
}