aboutsummaryrefslogtreecommitdiff
path: root/src/root.zig
blob: 9552bc5c25017bac9278bbc669357843208583e8 (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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
const std = @import("std");
const testing = std.testing;
const Allocator = std.mem.Allocator;
const galloc = @import("galloc.zig");

const git = @cImport({
    @cInclude("git2.h");
});

const GitError = error{
    InitError,
    DeinitError,
    OpenError,
};

const git_allocator = extern struct {
    gmalloc: ?*const fn (size: usize, payload: ?*anyopaque) callconv(.C) ?*anyopaque,
    grealloc: ?*const fn (ptr: ?*anyopaque, size: usize, payload: ?*anyopaque) callconv(.C) ?*anyopaque,
    gfree: ?*const fn (ptr: ?*anyopaque) callconv(.C) void,
};

pub var alloc: galloc.GitAllocator = undefined;

fn malloc(size: usize, _: ?*anyopaque) callconv(.C) ?*anyopaque {
    std.debug.print("MALLOC {}\n", .{size});
    return alloc.malloc(size);
}

fn relloc(ptr: ?*anyopaque, size: usize, _: ?*anyopaque) callconv(.C) ?*anyopaque {
    std.debug.print("REALLOC {} {?}\n", .{ size, ptr });
    const new_ptr = alloc.realloc(ptr, size);
    return new_ptr;
}

fn free(ptr: ?*anyopaque) callconv(.C) void {
    std.debug.print("FREE\n", .{});
    alloc.free(ptr);
}

pub fn initGit(a: std.mem.Allocator) GitError!void {
    alloc = galloc.GitAllocator.init(a);

    const cAlloc = git_allocator{
        .gmalloc = malloc,
        .grealloc = relloc,
        .gfree = free,
    };

    _ = git.git_libgit2_opts(git.GIT_OPT_SET_ALLOCATOR, &cAlloc);

    const code = git.git_libgit2_init();
    if (code < 0) {
        return GitError.InitError;
    }
}

pub fn deInitGit() !void {
    defer alloc.deinit();
    const code = git.git_libgit2_shutdown();
    if (code < 0) {
        return GitError.DeinitError;
    }
}

pub const Repository = struct {
    allocator: Allocator = undefined,
    repository: ?*git.git_repository = null,

    pub fn init(a: Allocator) !Repository {
        return Repository{
            .allocator = a,
        };
    }

    pub fn open(self: *Repository, path: []const u8) GitError!void {
        const code = git.git_repository_open(@ptrCast(&self.repository), path.ptr);
        if (code < 0) {
            return GitError.OpenError;
        }
    }

    pub fn deinit(self: *Repository) void {
        if (self.repository) |repo| {
            git.git_repository_free(repo);
        }
    }
};

test "init deinit" {
    try initGit(testing.allocator);
    try deInitGit();
}

test "open repository" {
    try initGit(testing.allocator);

    var repository = try Repository.init(std.testing.allocator);
    try repository.open(".");

    repository.deinit();
    try deInitGit();
}