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.

posixGetUserInfoPasswdStream

process.posixGetUserInfoPasswdStream
fn posixGetUserInfoPasswdStream(name: []const u8, reader: *std.Io.Reader) !UserInfo

File

lib/std/process.zig:138

Code

fn posixGetUserInfoPasswdStream(name: []const u8, reader: *std.Io.Reader) !UserInfo {
    const State = enum {
        start,
        wait_for_next_line,
        skip_password,
        read_user_id,
        read_group_id,
    };

    var name_index: usize = 0;
    var uid: posix.uid_t = 0;
    var gid: posix.gid_t = 0;

    sw: switch (State.start) {
        .start => switch (try reader.takeByte()) {
            ':' => {
                if (name_index == name.len) {
                    continue :sw .skip_password;
                } else {
                    continue :sw .wait_for_next_line;
                }
            },
            '\n' => return error.CorruptPasswordFile,
            else => |byte| {
                if (name_index == name.len or name[name_index] != byte) {
                    continue :sw .wait_for_next_line;
                }
                name_index += 1;
                continue :sw .start;
            },
        },
        .wait_for_next_line => switch (try reader.takeByte()) {
            '\n' => {
                name_index = 0;
                continue :sw .start;
            },
            else => continue :sw .wait_for_next_line,
        },
        .skip_password => switch (try reader.takeByte()) {
            '\n' => return error.CorruptPasswordFile,
            ':' => {
                continue :sw .read_user_id;
            },
            else => continue :sw .skip_password,
        },
        .read_user_id => switch (try reader.takeByte()) {
            ':' => {
                continue :sw .read_group_id;
            },
            '\n' => return error.CorruptPasswordFile,
            else => |byte| {
                const digit = switch (byte) {
                    '0'...'9' => byte - '0',
                    else => return error.CorruptPasswordFile,
                };
                {
                    const ov = @mulWithOverflow(uid, 10);
                    if (ov[1] != 0) return error.CorruptPasswordFile;
                    uid = ov[0];
                }
                {
                    const ov = @addWithOverflow(uid, digit);
                    if (ov[1] != 0) return error.CorruptPasswordFile;
                    uid = ov[0];
                }
                continue :sw .read_user_id;
            },
        },
        .read_group_id => switch (try reader.takeByte()) {
            '\n', ':' => return .{
                .uid = uid,
                .gid = gid,
            },
            else => |byte| {
                const digit = switch (byte) {
                    '0'...'9' => byte - '0',
                    else => return error.CorruptPasswordFile,
                };
                {
                    const ov = @mulWithOverflow(gid, 10);
                    if (ov[1] != 0) return error.CorruptPasswordFile;
                    gid = ov[0];
                }
                {
                    const ov = @addWithOverflow(gid, digit);
                    if (ov[1] != 0) return error.CorruptPasswordFile;
                    gid = ov[0];
                }
                continue :sw .read_group_id;
            },
        },
    }
    comptime unreachable;
}