Function parse [src]

Prototype

pub fn parse( allocator: Allocator, libc_file: []const u8, target: std.Target, ) !LibCInstallation

Parameters

allocator: Allocatorlibc_file: []const u8target: std.Target

Source

pub fn parse( allocator: Allocator, libc_file: []const u8, target: std.Target, ) !LibCInstallation { var self: LibCInstallation = .{}; const fields = std.meta.fields(LibCInstallation); const FoundKey = struct { found: bool, allocated: ?[:0]u8, }; var found_keys = [1]FoundKey{FoundKey{ .found = false, .allocated = null }} ** fields.len; errdefer { self = .{}; for (found_keys) |found_key| { if (found_key.allocated) |s| allocator.free(s); } } const contents = try std.fs.cwd().readFileAlloc(allocator, libc_file, std.math.maxInt(usize)); defer allocator.free(contents); var it = std.mem.tokenizeScalar(u8, contents, '\n'); 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 (fields, 0..) |field, 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.dupeZ(u8, value); @field(self, field.name) = found_keys[i].allocated; } break; } } } inline for (fields, 0..) |field, 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) { log.err("gcc_dir may not be empty for {s}", .{@tagName(os_tag)}); return error.ParseError; } return self; }