feature. See also
. The project being documented here (as the example) is the Zig library itself.
LibCInstallation.parse
pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const std.Target) !LibCInstallation
File
Code
pub fn parse(allocator: Allocator, io: Io, libc_file: []const u8, target: *const std.Target) !LibCInstallation {
var self: LibCInstallation = .{};
const field_names = comptime std.meta.fieldNames(LibCInstallation);
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;
}