~jamii/focus

focus/bin/focus.zig -rw-r--r-- 2.6 KiB
d013411bJamie Brandon Highlight zig control flow a month ago
                                                                                
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
const builtin = @import("builtin");
const std = @import("std");

const focus = @import("../lib/focus.zig");

pub var gpa = if (builtin.mode == .Debug)
    std.heap.GeneralPurposeAllocator(.{
        .never_unmap = false,
    }){}
else
    null;

const Action = union(enum) {
    Angel,
    Request: focus.Request,
};

pub fn main() void {
    const allocator = if (builtin.mode == .Debug) &gpa.allocator else std.heap.c_allocator;
    var arena = focus.common.ArenaAllocator.init(allocator);

    const args = std.process.argsAlloc(&arena.allocator) catch focus.common.oom();

    var action: Action = .{ .Request = .CreateEmptyWindow };
    for (args[1..]) |c_arg| {
        const arg: []const u8 = c_arg;
        if (std.mem.startsWith(u8, arg, "--")) {
            if (focus.meta.deepEqual(arg, "--angel")) {
                action = .Angel;
            } else if (focus.meta.deepEqual(arg, "--launcher")) {
                action = .{ .Request = .CreateLauncherWindow };
            } else {
                focus.common.panic("Unrecognized arg: {s}", .{arg});
            }
        } else {
            const absolute_filename = std.fs.path.resolve(&arena.allocator, &[_][]const u8{arg}) catch focus.common.oom();
            action = .{ .Request = .{ .CreateEditorWindow = absolute_filename } };
        }
    }

    const socket_path = focus.common.format(&arena.allocator, "#{s}", .{args[0]});
    const server_socket = focus.createServerSocket(socket_path);

    switch (action) {
        .Angel => {
            // no daemon (we're probably in a debugger)
            if (server_socket.state != .Bound)
                focus.common.panic("Couldn't bind server socket", .{});
            focus.run(allocator, server_socket);
        },
        .Request => |request| {
            // if we successfully bound the socket then we need to create the daemon
            if (server_socket.state == .Bound) {
                const log_filename = focus.common.format(&arena.allocator, "/home/jamie/.log/{s}.log", .{std.fs.path.basename(args[0])});
                if (focus.daemonize(log_filename) == .Child) {
                    focus.run(allocator, server_socket);
                    // run doesn't return
                    unreachable;
                }
            }

            // ask the main process to do something
            const client_socket = focus.createClientSocket();
            focus.sendRequest(client_socket, server_socket, request);

            // wait until it's done
            const exit_code = focus.waitReply(client_socket);
            arena.deinit();
            std.os.exit(exit_code);
        },
    }
}