diff --git a/build.zig b/build.zig index 1c46370..e6a043e 100644 --- a/build.zig +++ b/build.zig @@ -447,9 +447,11 @@ pub fn build_exe( const keybind_test_run_cmd = blk: { const tests = b.addTest(.{ - .root_source_file = b.path("src/keybind/keybind.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("src/keybind/keybind.zig"), + .target = target, + .optimize = optimize, + }), }); tests.root_module.addImport("cbor", cbor_mod); tests.root_module.addImport("command", command_mod); @@ -568,10 +570,12 @@ pub fn build_exe( const exe = b.addExecutable(.{ .name = exe_name, - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, - .strip = strip, + .root_module = b.createModule(.{ + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + .strip = strip, + }), .win32_manifest = b.path("src/win32/flow.manifest"), }); @@ -620,9 +624,11 @@ pub fn build_exe( const check_exe = b.addExecutable(.{ .name = exe_name, - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }), }); check_exe.root_module.addImport("build_options", options_mod); @@ -645,12 +651,14 @@ pub fn build_exe( check_step.dependOn(&check_exe.step); const tests = b.addTest(.{ - .root_source_file = b.path("test/tests.zig"), - .target = target, - .optimize = optimize, + .root_module = b.createModule(.{ + .root_source_file = b.path("test/tests.zig"), + .target = target, + .optimize = optimize, + .strip = strip, + }), .use_llvm = use_llvm, .use_lld = use_llvm, - .strip = strip, }); tests.pie = pie; diff --git a/build.zig.zon b/build.zig.zon index 66453d6..5e901f6 100644 --- a/build.zig.zon +++ b/build.zig.zon @@ -18,8 +18,8 @@ .hash = "dizzy-1.0.0-q40X4YCRAAAGYO9QOZiYYSOwiiFlqZlecMuQcxPiBcXM", }, .thespian = .{ - .url = "git+https://github.com/neurocyte/thespian?ref=master#8b2535db199d2215bea438abb323f3e3f6c58d99", - .hash = "thespian-0.0.1-owFOjjQbBgABzTPy7sWTQMJ7Ts5ielIYO3_6hfhxbQa_", + .url = "git+https://github.com/neurocyte/thespian?ref=master#d9c93e9783546f2fb040ffcff84576fe46d6495b", + .hash = "thespian-0.0.1-owFOjjQbBgAxIs7QYErDVaESLxgLdNQcoTIgU-QoNqlt", }, .themes = .{ .url = "https://github.com/neurocyte/flow-themes/releases/download/master-952f9f630ea9544088fd30293666ee0650b7a690/flow-themes.tar.gz", diff --git a/src/list_languages.zig b/src/list_languages.zig index 6efbd10..376424c 100644 --- a/src/list_languages.zig +++ b/src/list_languages.zig @@ -10,7 +10,7 @@ const checkmark_width = if (builtin.os.tag != .windows) 2 else 3; const success_mark = if (builtin.os.tag != .windows) "✓ " else "[y]"; const fail_mark = if (builtin.os.tag != .windows) "✘ " else "[n]"; -pub fn list(allocator: std.mem.Allocator, writer: anytype, tty_config: std.io.tty.Config) !void { +pub fn list(allocator: std.mem.Allocator, writer: *std.io.Writer, tty_config: std.io.tty.Config) !void { var max_language_len: usize = 0; var max_langserver_len: usize = 0; var max_formatter_len: usize = 0; diff --git a/src/main.zig b/src/main.zig index e914235..d102022 100644 --- a/src/main.zig +++ b/src/main.zig @@ -122,32 +122,41 @@ pub fn main() anyerror!void { scratch: bool, new_file: bool, version: bool, + + positional: struct { + trailing: []const []const u8, + }, }; - var arg_iter = try std.process.argsWithAllocator(a); - defer arg_iter.deinit(); + const args_alloc = try std.process.argsAlloc(a); + defer std.process.argsFree(a, args_alloc); var diag: flags.Diagnostics = undefined; - var positional_args = std.ArrayList([]const u8).init(a); - defer positional_args.deinit(); - const args = flags.parse(&arg_iter, "flow", Flags, .{ + const args = flags.parse(args_alloc, "flow", Flags, .{ .diagnostics = &diag, - .trailing_list = &positional_args, }) catch |err| { if (err == error.PrintedHelp) exit(0); - diag.help.generated.render(std.io.getStdOut(), flags.ColorScheme.default) catch {}; + try diag.printUsage(&flags.ColorScheme.default); exit(1); return err; }; + var stdout_buf: [4096]u8 = undefined; + var stdout_file = std.fs.File.stdout().writer(&stdout_buf); + const stdout = &stdout_file.interface; + defer stdout.flush() catch {}; + var stderr_buf: [4096]u8 = undefined; + var stderr_file = std.fs.File.stderr().writer(&stderr_buf); + const stderr = &stderr_file.interface; + defer stderr.flush() catch {}; + if (args.version) - return std.io.getStdOut().writeAll(version_info); + return std.fs.File.stdout().writeAll(version_info); if (args.list_languages) { - const stdout = std.io.getStdOut(); - const tty_config = std.io.tty.detectConfig(stdout); - return list_languages.list(a, stdout.writer(), tty_config); + const tty_config = std.io.tty.detectConfig(std.fs.File.stdout()); + return list_languages.list(a, stdout, tty_config); } if (builtin.os.tag != .windows and @hasDecl(renderer, "install_crash_handler")) { @@ -158,11 +167,12 @@ pub fn main() anyerror!void { if (args.debug_wait) { std.debug.print("press return to start", .{}); var buf: [1]u8 = undefined; - _ = try std.io.getStdIn().read(&buf); + _ = try std.fs.File.stdin().read(&buf); } if (c.setlocale(c.LC_ALL, "") == null) { - try std.io.getStdErr().writer().print("Failed to set locale. Is your locale valid?\n", .{}); + try stderr.print("Failed to set locale. Is your locale valid?\n", .{}); + stderr.flush() catch {}; exit(1); } @@ -245,7 +255,7 @@ pub fn main() anyerror!void { defer links.deinit(); var prev: ?*file_link.Dest = null; var line_next: ?usize = null; - for (positional_args.items) |arg| { + for (args.positional.trailing.items) |arg| { if (arg.len == 0) continue; if (!args.literal and arg[0] == '+') { @@ -372,17 +382,17 @@ fn count_args() usize { return count; } -fn trace(m: thespian.message.c_buffer_type) callconv(.C) void { +fn trace(m: thespian.message.c_buffer_type) callconv(.c) void { thespian.message.from(m).to_json_cb(trace_json); } -fn trace_json(json: thespian.message.json_string_view) callconv(.C) void { +fn trace_json(json: thespian.message.json_string_view) callconv(.c) void { const callstack_depth = 10; ___tracy_emit_message(json.base, json.len, callstack_depth); } extern fn ___tracy_emit_message(txt: [*]const u8, size: usize, callstack: c_int) void; -fn trace_to_file(m: thespian.message.c_buffer_type) callconv(.C) void { +fn trace_to_file(m: thespian.message.c_buffer_type) callconv(.c) void { const State = struct { file: std.fs.File, last_time: i64, diff --git a/src/renderer/vaxis/renderer.zig b/src/renderer/vaxis/renderer.zig index f9343de..1e5c703 100644 --- a/src/renderer/vaxis/renderer.zig +++ b/src/renderer/vaxis/renderer.zig @@ -156,7 +156,10 @@ fn handle_crash(sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque self.tty.deinit(); } if (builtin.os.tag == .linux and jit_debugger_enabled) { - handleSegfaultPosixNoAbort(sig, info, ctx_ptr); + var buf: [4096]u8 = undefined; + var stderr = std.fs.File.stderr().writer(&buf); + defer stderr.interface.flush() catch {}; + handleSegfaultPosixNoAbort(&stderr.interface, sig, info, ctx_ptr); @import("thespian").sighdl_debugger(sig, @ptrCast(@constCast(info)), ctx_ptr); std.posix.abort(); } else { @@ -165,7 +168,7 @@ fn handle_crash(sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque unreachable; } -fn handleSegfaultPosixNoAbort(sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque) void { +fn handleSegfaultPosixNoAbort(stderr: *std.io.Writer, sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque) void { const debug = @import("std/debug.zig"); debug.resetSegfaultHandler(); const addr = switch (builtin.os.tag) { @@ -177,7 +180,7 @@ fn handleSegfaultPosixNoAbort(sig: i32, info: *const std.posix.siginfo_t, ctx_pt else => unreachable, }; const code = if (builtin.os.tag == .netbsd) info.info.code else info.code; - debug.dumpSegfaultInfoPosix(sig, code, addr, ctx_ptr); + debug.dumpSegfaultInfoPosix(stderr, sig, code, addr, ctx_ptr); } pub fn run(self: *Self) Error!void { diff --git a/src/renderer/vaxis/std/debug.zig b/src/renderer/vaxis/std/debug.zig index b5f8697..1d84502 100644 --- a/src/renderer/vaxis/std/debug.zig +++ b/src/renderer/vaxis/std/debug.zig @@ -384,16 +384,14 @@ pub inline fn getContext(context: *ThreadContext) bool { /// Tries to print the stack trace starting from the supplied base pointer to stderr, /// unbuffered, and ignores any error returned. /// TODO multithreaded awareness -pub fn dumpStackTraceFromBase(context: *ThreadContext) void { +pub fn dumpStackTraceFromBase(stderr: *io.Writer, context: *ThreadContext) void { nosuspend { if (builtin.target.cpu.arch.isWasm()) { if (native_os == .wasi) { - const stderr = io.getStdErr().writer(); stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return; } return; } - const stderr = io.getStdErr().writer(); if (builtin.strip_debug_info) { stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return; return; @@ -402,7 +400,7 @@ pub fn dumpStackTraceFromBase(context: *ThreadContext) void { stderr.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}) catch return; return; }; - const tty_config = io.tty.detectConfig(io.getStdErr()); + const tty_config = io.tty.detectConfig(fs.File.stderr()); if (native_os == .windows) { // On x86_64 and aarch64, the stack will be unwound using RtlVirtualUnwind using the context // provided by the exception handler. On x86, RtlVirtualUnwind doesn't exist. Instead, a new backtrace @@ -759,7 +757,7 @@ pub const StackIterator = struct { "flushw" else "ta 3" // ST_FLUSH_WINDOWS - ::: "memory"); + ::: .{ .memory = true }); } return StackIterator{ @@ -1425,14 +1423,22 @@ pub fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*an lockStdErr(); defer unlockStdErr(); - dumpSegfaultInfoPosix(sig, code, addr, ctx_ptr); + var buf: [4096]u8 = undefined; + var stderr = fs.File.stderr().writer(&buf); + defer stderr.interface.flush() catch {}; + + dumpSegfaultInfoPosix(&stderr.interface, sig, code, addr, ctx_ptr); } waitForOtherThreadToFinishPanicking(); }, else => { + var buf: [4096]u8 = undefined; + var stderr = fs.File.stderr().writer(&buf); + defer stderr.interface.flush() catch {}; + // panic mutex already locked - dumpSegfaultInfoPosix(sig, code, addr, ctx_ptr); + dumpSegfaultInfoPosix(&stderr.interface, sig, code, addr, ctx_ptr); }, }; @@ -1442,8 +1448,7 @@ pub fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*an posix.abort(); } -pub fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopaque) void { - const stderr = io.getStdErr().writer(); +pub fn dumpSegfaultInfoPosix(stderr: *io.Writer, sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopaque) void { _ = switch (sig) { posix.SIG.SEGV => if (native_arch == .x86_64 and native_os == .linux and code == 128) // SI_KERNEL // x86_64 doesn't have a full 64-bit virtual address space. @@ -1491,7 +1496,7 @@ pub fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopa }, @ptrCast(ctx)).__mcontext_data; } relocateContext(&new_ctx); - dumpStackTraceFromBase(&new_ctx); + dumpStackTraceFromBase(stderr, &new_ctx); }, else => {}, }