structstd.process.ArgIteratorWasi[src]

Fields

allocator: Allocator
index: usize
args: [][:0]u8

Error Sets

Error SetInitError[src]

Errors

anyerror means the error set is known only at runtime.

OutOfMemory
Unexpected UnexpectedError

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.

Source Code

Source code
pub const InitError = error{OutOfMemory} || posix.UnexpectedError

Functions

Functioninit[src]

pub fn init(allocator: Allocator) InitError!ArgIteratorWasi

You must call deinit to free the internal buffer of the iterator after you are done.

Parameters

allocator: Allocator

Source Code

Source code
pub fn init(allocator: Allocator) InitError!ArgIteratorWasi {
    const fetched_args = try ArgIteratorWasi.internalInit(allocator);
    return ArgIteratorWasi{
        .allocator = allocator,
        .index = 0,
        .args = fetched_args,
    };
}

Functionnext[src]

pub fn next(self: *ArgIteratorWasi) ?[:0]const u8

Parameters

Source Code

Source code
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;
}

Functionskip[src]

pub fn skip(self: *ArgIteratorWasi) bool

Parameters

Source Code

Source code
pub fn skip(self: *ArgIteratorWasi) bool {
    if (self.index == self.args.len) return false;

    self.index += 1;
    return true;
}

Functiondeinit[src]

pub fn deinit(self: *ArgIteratorWasi) void

Call to free the internal buffer of the iterator.

Parameters

Source Code

Source code
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);
}

Source Code

Source code
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);
    }
}