Zig 0.17.0-dev (Split by item)

This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig library itself.

start

Initializes a global Progress instance.

Asserts there is only one global Progress instance.

Call Node.end when done.

If an error occurs, start_failure will be populated.

Progress.start
pub fn start(io: Io, options: Options) Node

File

lib/std/Progress.zig:600

Code

pub fn start(io: Io, options: Options) Node {
    // Ensure there is only 1 global Progress object.
    if (global_progress.node_end_index != 0) {
        debug_start_trace.dump();
        unreachable;
    }
    debug_start_trace.add("first initialized here");

    @memset(&global_progress.node_parents, .unused);
    @memset(&global_progress.ipc, .{ .locked = false, .valid = false, .generation = 0 });
    const root_node = Node.init(@fromBackingInt(@intCast(0)), .none, options.root_name, options.estimated_total_items);
    global_progress.node_end_index = 1;

    assert(options.draw_buffer.len >= 200);
    global_progress.draw_buffer = options.draw_buffer;
    global_progress.refresh_rate_ns = @intCast(options.refresh_rate_ns.toNanoseconds());
    global_progress.initial_delay_ns = @intCast(options.initial_delay_ns.toNanoseconds());

    if (noop_impl) return .none;

    global_progress.io = io;

    if (io.vtable.progressParentFile(io.userdata)) |ipc_file| {
        global_progress.update_worker = io.concurrent(ipcThreadRun, .{ io, ipc_file }) catch |err| {
            global_progress.start_failure = .{ .spawn_ipc_worker = err };
            return .none;
        };
    } else |env_err| switch (env_err) {
        error.EnvironmentVariableMissing => {
            if (options.disable_printing) return .none;
            const stderr: Io.File = .stderr();
            global_progress.terminal = stderr;
            if (stderr.enableAnsiEscapeCodes(io)) |_| {
                global_progress.terminal_mode = .ansi_escape_codes;
            } else |_| if (is_windows) {
                var get_console_cp = windows.CONSOLE.USER_IO.GET_CP(.Output);
                // Normally, we would pass `null` to `operate` here as the kernel32
                // function does not accept a handle, however, if we pass one anyway,
                // then we will get an error if the handle is not associated with
                // this process's console, effectively combining an `isTty` check
                // into the same syscall.
                switch (get_console_cp.operate(io, stderr) catch |err| switch (err) {
                    error.Canceled => {
                        io.recancel();
                        return .none;
                    },
                }) {
                    .SUCCESS => global_progress.terminal_mode = .{ .windows_api = .{
                        .code_page = get_console_cp.Data.CodePage,
                    } },
                    .INVALID_HANDLE => {},
                    else => {},
                }
            }
            if (future: switch (global_progress.terminal_mode) {
                .off => return .none,
                .ansi_escape_codes => {
                    if (have_sigwinch) {
                        const act: posix.Sigaction = .{
                            .handler = .{ .sigaction = handleSigWinch },
                            .mask = posix.sigemptyset(),
                            .flags = (posix.SA.SIGINFO | posix.SA.RESTART),
                        };
                        posix.sigaction(.WINCH, &act, null);
                    }
                    break :future io.concurrent(updateTask, .{io});
                },
                .windows_api => io.concurrent(windowsApiUpdateTask, .{io}),
            }) |future| {
                global_progress.update_worker = future;
            } else |err| {
                global_progress.start_failure = .{ .spawn_update_worker = err };
                return .none;
            }
        },
        else => |e| {
            global_progress.start_failure = .{ .parent_ipc = e };
            return .none;
        },
    }

    return root_node;
}