Zig 0.17.0-dev (Split by item)

Shortcut keys
?
Show these tips
S
Focus search field
Esc
Clear focus & close tips
U
Jump to source code
↑
Move up in search results
↓
Move down in search results
↵
Go to active search result
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 standard library. Public Function

parse

Public Function
std.zig.LibCInstallation.parse
pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const std.Target) !LibCInstallation

Params

File

zig/LibCInstallation.zig:43
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const std.Target) !LibCInstallation {
    var self: LibCInstallation = .{};

    const field_names = @typeInfo(LibCInstallation).@"struct".field_names;
    const FoundKey = struct {
        found: bool,
        allocated: ?[]u8,
    };

    var found_keys: [field_names.len]FoundKey = @splat(.{ .found = false, .allocated = null });
    errdefer {
        self = .{};
        for (found_keys) |found_key| {
            if (found_key.allocated) |s| allocator.free(s);
        }
    }

    const contents = try Io.Dir.cwd().readFileAlloc(io, libc_file, allocator, .limited(std.math.maxInt(usize)));
    defer allocator.free(contents);

    var it = std.mem.tokenizeAny(u8, contents, "\n\r");
    while (it.next()) |line| {
        if (line.len == 0 or line[0] == '#') continue;
        var line_it = std.mem.splitScalar(u8, line, '=');
        const name = line_it.first();
        const value = line_it.rest();
        inline for (field_names, 0..) |field_name, i| {
            if (std.mem.eql(u8, name, field_name)) {
                found_keys[i].found = true;
                if (value.len == 0) {
                    @field(self, field_name) = null;
                } else {
                    found_keys[i].allocated = try allocator.dupe(u8, value);
                    @field(self, field_name) = found_keys[i].allocated;
                }
                break;
            }
        }
    }
    inline for (field_names, 0..) |field_name, i| {
        if (!found_keys[i].found) {
            log.err("missing field: {s}", .{field_name});
            return error.ParseError;
        }
    }
    if (self.include_dir == null) {
        log.err("include_dir may not be empty", .{});
        return error.ParseError;
    }
    if (self.sys_include_dir == null) {
        log.err("sys_include_dir may not be empty", .{});
        return error.ParseError;
    }

    const os_tag = target.os.tag;
    if (self.crt_dir == null and !target.os.tag.isDarwin()) {
        log.err("crt_dir may not be empty for {s}", .{@tagName(os_tag)});
        return error.ParseError;
    }

    if (self.msvc_lib_dir == null and os_tag == .windows and (target.abi == .msvc or target.abi == .itanium)) {
        log.err("msvc_lib_dir may not be empty for {s}-{s}", .{
            @tagName(os_tag),
            @tagName(target.abi),
        });
        return error.ParseError;
    }
    if (self.kernel32_lib_dir == null and os_tag == .windows and (target.abi == .msvc or target.abi == .itanium)) {
        log.err("kernel32_lib_dir may not be empty for {s}-{s}", .{
            @tagName(os_tag),
            @tagName(target.abi),
        });
        return error.ParseError;
    }

    if (self.gcc_dir == null and (os_tag == .haiku or os_tag == .serenity)) {
        log.err("gcc_dir may not be empty for {s}", .{@tagName(os_tag)});
        return error.ParseError;
    }

    return self;
}