aboutsummaryrefslogtreecommitdiff
path: root/src/link/tapi.zig
blob: 35193b0eec3ae4692776ea25d5db23c0d8034359 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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
const std = @import("std");
const fs = std.fs;
const mem = std.mem;
const log = std.log.scoped(.tapi);

const Allocator = mem.Allocator;
const Yaml = @import("tapi/yaml.zig").Yaml;

pub const LibStub = struct {
    /// Underlying memory for stub's contents.
    yaml: Yaml,

    /// Typed contents of the tbd file.
    inner: []Tbd,

    const Tbd = struct {
        tbd_version: u3,
        targets: []const []const u8,
        uuids: []const struct {
            target: []const u8,
            value: []const u8,
        },
        install_name: []const u8,
        current_version: ?union(enum) {
            string: []const u8,
            float: f64,
            int: u64,
        },
        compatibility_version: ?union(enum) {
            string: []const u8,
            float: f64,
            int: u64,
        },
        reexported_libraries: ?[]const struct {
            targets: []const []const u8,
            libraries: []const []const u8,
        },
        parent_umbrella: ?[]const struct {
            targets: []const []const u8,
            umbrella: []const u8,
        },
        exports: ?[]const struct {
            targets: []const []const u8,
            symbols: ?[]const []const u8,
            objc_classes: ?[]const []const u8,
        },
        reexports: ?[]const struct {
            targets: []const []const u8,
            symbols: ?[]const []const u8,
            objc_classes: ?[]const []const u8,
        },
        allowable_clients: ?[]const struct {
            targets: []const []const u8,
            clients: []const []const u8,
        },
        objc_classes: ?[]const []const u8,
    };

    pub fn loadFromFile(allocator: *Allocator, file: fs.File) !LibStub {
        const source = try file.readToEndAlloc(allocator, std.math.maxInt(u32));
        defer allocator.free(source);

        var lib_stub = LibStub{
            .yaml = try Yaml.load(allocator, source),
            .inner = undefined,
        };

        lib_stub.inner = lib_stub.yaml.parse([]Tbd) catch |err| blk: {
            switch (err) {
                error.TypeMismatch => {
                    // TODO clean this up.
                    var out = try lib_stub.yaml.arena.allocator.alloc(Tbd, 1);
                    out[0] = try lib_stub.yaml.parse(Tbd);
                    break :blk out;
                },
                else => |e| return e,
            }
        };

        return lib_stub;
    }

    pub fn deinit(self: *LibStub) void {
        self.yaml.deinit();
    }
};