an experimental irc client
at e59dbf3eeede483cfabdc384137106d3e4dbb7f3 117 lines 3.3 kB view raw
1const std = @import("std"); 2const options = @import("build_options"); 3const builtin = @import("builtin"); 4const comlink = @import("comlink.zig"); 5const vaxis = @import("vaxis"); 6const ziglua = @import("ziglua"); 7 8const Lua = ziglua.Lua; 9 10const log = std.log.scoped(.main); 11 12pub const panic = vaxis.panic_handler; 13 14pub const std_options: std.Options = .{ 15 .log_scope_levels = &.{ 16 .{ .scope = .vaxis, .level = .warn }, 17 .{ .scope = .vaxis_parser, .level = .warn }, 18 }, 19}; 20 21pub const version = options.version; 22 23/// Called after receiving a terminating signal 24fn cleanUp(sig: c_int) callconv(.C) void { 25 if (vaxis.Tty.global_tty) |gty| { 26 const reset: []const u8 = vaxis.ctlseqs.csi_u_pop ++ 27 vaxis.ctlseqs.mouse_reset ++ 28 vaxis.ctlseqs.bp_reset ++ 29 vaxis.ctlseqs.rmcup; 30 31 gty.anyWriter().writeAll(reset) catch {}; 32 33 gty.deinit(); 34 } 35 if (sig < 255 and sig >= 0) 36 std.process.exit(@as(u8, @intCast(sig))) 37 else 38 std.process.exit(1); 39} 40 41pub fn main() !void { 42 var gpa = std.heap.GeneralPurposeAllocator(.{}){}; 43 defer { 44 if (builtin.mode == .Debug) { 45 const deinit_status = gpa.deinit(); 46 if (deinit_status == .leak) { 47 std.log.err("memory leak", .{}); 48 } 49 } 50 } 51 const alloc = gpa.allocator(); 52 53 var args = try std.process.argsWithAllocator(alloc); 54 while (args.next()) |arg| { 55 if (argMatch("-v", "--version", arg)) { 56 const stdout = std.io.getStdOut(); 57 try stdout.writer().print("comlink {s}\n", .{version}); 58 return; 59 } 60 } 61 62 // Handle termination signals 63 switch (builtin.os.tag) { 64 .windows => {}, 65 else => { 66 var action: std.posix.Sigaction = .{ 67 .handler = .{ .handler = cleanUp }, 68 .mask = switch (builtin.os.tag) { 69 .macos => 0, 70 else => std.posix.empty_sigset, 71 }, 72 .flags = 0, 73 }; 74 try std.posix.sigaction(std.posix.SIG.INT, &action, null); 75 try std.posix.sigaction(std.posix.SIG.TERM, &action, null); 76 }, 77 } 78 79 comlink.Command.user_commands = std.StringHashMap(i32).init(alloc); 80 defer comlink.Command.user_commands.deinit(); 81 82 const lua = try Lua.init(&alloc); 83 defer lua.deinit(); 84 85 var app = try comlink.App.init(alloc); 86 defer app.deinit(); 87 88 app.run(lua) catch |err| { 89 switch (err) { 90 // ziglua errors 91 error.LuaError => { 92 const msg = lua.toString(-1) catch ""; 93 const duped = alloc.dupe(u8, msg) catch ""; 94 app.deinit(); 95 defer alloc.free(duped); 96 log.err("{s}", .{duped}); 97 return err; 98 }, 99 else => return err, 100 } 101 }; 102} 103 104fn argMatch(maybe_short: ?[]const u8, maybe_long: ?[]const u8, arg: [:0]const u8) bool { 105 if (maybe_short) |short| { 106 if (std.mem.eql(u8, short, arg)) return true; 107 } 108 if (maybe_long) |long| { 109 if (std.mem.eql(u8, long, arg)) return true; 110 } 111 return false; 112} 113 114test { 115 _ = @import("format.zig"); 116 _ = @import("irc.zig"); 117}