From b65a804bb28c899cca0173a07a9b9e7fb7d5f9d4 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Fri, 16 Aug 2024 14:42:32 -0700 Subject: [PATCH] almost yeeted it all! --- src/Surface.zig | 4 +- src/cli/list_themes.zig | 2 +- src/config/CAPI.zig | 2 +- src/config/Config.zig | 2 +- src/main.zig | 11 +++- src/main_ghostty.zig | 137 +--------------------------------------- 6 files changed, 15 insertions(+), 143 deletions(-) diff --git a/src/Surface.zig b/src/Surface.zig index fc3144ade..4b5b3f98c 100644 --- a/src/Surface.zig +++ b/src/Surface.zig @@ -20,9 +20,9 @@ const builtin = @import("builtin"); const assert = std.debug.assert; const Allocator = std.mem.Allocator; const ArenaAllocator = std.heap.ArenaAllocator; +const global_state = &@import("global.zig").state; const oni = @import("oniguruma"); const unicode = @import("unicode/main.zig"); -const main = @import("main.zig"); const renderer = @import("renderer.zig"); const termio = @import("termio.zig"); const objc = @import("objc"); @@ -448,7 +448,7 @@ pub fn init( .shell_integration = config.@"shell-integration", .shell_integration_features = config.@"shell-integration-features", .working_directory = config.@"working-directory", - .resources_dir = main.state.resources_dir, + .resources_dir = global_state.resources_dir, .term = config.term, // Get the cgroup if we're on linux and have the decl. I'd love diff --git a/src/cli/list_themes.zig b/src/cli/list_themes.zig index 82c461893..beceab112 100644 --- a/src/cli/list_themes.zig +++ b/src/cli/list_themes.zig @@ -5,7 +5,7 @@ const Action = @import("action.zig").Action; const Arena = std.heap.ArenaAllocator; const Allocator = std.mem.Allocator; const Config = @import("../config/Config.zig"); -const global_state = &@import("../main.zig").state; +const global_state = &@import("../global.zig").state; pub const Options = struct { pub fn deinit(self: Options) void { diff --git a/src/config/CAPI.zig b/src/config/CAPI.zig index ef50c4e2b..1949d6e91 100644 --- a/src/config/CAPI.zig +++ b/src/config/CAPI.zig @@ -1,7 +1,7 @@ const std = @import("std"); const cli = @import("../cli.zig"); const inputpkg = @import("../input.zig"); -const global = &@import("../main.zig").state; +const global = &@import("../global.zig").state; const Config = @import("Config.zig"); const c_get = @import("c_get.zig"); diff --git a/src/config/Config.zig b/src/config/Config.zig index ace9c5e4a..a5d1c1e68 100644 --- a/src/config/Config.zig +++ b/src/config/Config.zig @@ -15,7 +15,7 @@ const builtin = @import("builtin"); const assert = std.debug.assert; const Allocator = std.mem.Allocator; const ArenaAllocator = std.heap.ArenaAllocator; -const global_state = &@import("../main.zig").state; +const global_state = &@import("../global.zig").state; const fontpkg = @import("../font/main.zig"); const inputpkg = @import("../input.zig"); const terminal = @import("../terminal/main.zig"); diff --git a/src/main.zig b/src/main.zig index 3a5357471..a1f8d4a44 100644 --- a/src/main.zig +++ b/src/main.zig @@ -1,7 +1,7 @@ const build_config = @import("build_config.zig"); -// See build_config.ExeEntrypoint for why we do this. -pub usingnamespace switch (build_config.exe_entrypoint) { +/// See build_config.ExeEntrypoint for why we do this. +const entrypoint = switch (build_config.exe_entrypoint) { .ghostty => @import("main_ghostty.zig"), .helpgen => @import("helpgen.zig"), .mdgen_ghostty_1 => @import("build/mdgen/main_ghostty_1.zig"), @@ -12,3 +12,10 @@ pub usingnamespace switch (build_config.exe_entrypoint) { .bench_grapheme_break => @import("bench/grapheme-break.zig"), .bench_page_init => @import("bench/page-init.zig"), }; + +/// The main entrypoint for the program. +pub const main = entrypoint.main; + +test { + _ = entrypoint; +} diff --git a/src/main_ghostty.zig b/src/main_ghostty.zig index 6354214d0..559b399fe 100644 --- a/src/main_ghostty.zig +++ b/src/main_ghostty.zig @@ -21,12 +21,7 @@ const apprt = @import("apprt.zig"); const App = @import("App.zig"); const Ghostty = @import("main_c.zig").Ghostty; - -/// Global process state. This is initialized in main() for exe artifacts -/// and by ghostty_init() for lib artifacts. This should ONLY be used by -/// the C API. The Zig API should NOT use any global state and should -/// rely on allocators being passed in as parameters. -pub var state: GlobalState = undefined; +const state = &@import("global.zig").state; /// The return type for main() depends on the build artifact. The lib build /// also calls "main" in order to run the CLI actions, but it calls it as @@ -172,136 +167,6 @@ pub const std_options: std.Options = .{ .logFn = logFn, }; -/// This represents the global process state. There should only -/// be one of these at any given moment. This is extracted into a dedicated -/// struct because it is reused by main and the static C lib. -pub const GlobalState = struct { - const GPA = std.heap.GeneralPurposeAllocator(.{}); - - gpa: ?GPA, - alloc: std.mem.Allocator, - action: ?cli.Action, - logging: Logging, - - /// The app resources directory, equivalent to zig-out/share when we build - /// from source. This is null if we can't detect it. - resources_dir: ?[]const u8, - - /// Where logging should go - pub const Logging = union(enum) { - disabled: void, - stderr: void, - }; - - /// Initialize the global state. - pub fn init(self: *GlobalState) !void { - // Initialize ourself to nothing so we don't have any extra state. - // IMPORTANT: this MUST be initialized before any log output because - // the log function uses the global state. - self.* = .{ - .gpa = null, - .alloc = undefined, - .action = null, - .logging = .{ .stderr = {} }, - .resources_dir = null, - }; - errdefer self.deinit(); - - self.gpa = gpa: { - // Use the libc allocator if it is available because it is WAY - // faster than GPA. We only do this in release modes so that we - // can get easy memory leak detection in debug modes. - if (builtin.link_libc) { - if (switch (builtin.mode) { - .ReleaseSafe, .ReleaseFast => true, - - // We also use it if we can detect we're running under - // Valgrind since Valgrind only instruments the C allocator - else => std.valgrind.runningOnValgrind() > 0, - }) break :gpa null; - } - - break :gpa GPA{}; - }; - - self.alloc = if (self.gpa) |*value| - value.allocator() - else if (builtin.link_libc) - std.heap.c_allocator - else - unreachable; - - // We first try to parse any action that we may be executing. - self.action = try cli.Action.detectCLI(self.alloc); - - // If we have an action executing, we disable logging by default - // since we write to stderr we don't want logs messing up our - // output. - if (self.action != null) self.logging = .{ .disabled = {} }; - - // For lib mode we always disable stderr logging by default. - if (comptime build_config.app_runtime == .none) { - self.logging = .{ .disabled = {} }; - } - - // I don't love the env var name but I don't have it in my heart - // to parse CLI args 3 times (once for actions, once for config, - // maybe once for logging) so for now this is an easy way to do - // this. Env vars are useful for logging too because they are - // easy to set. - if ((try internal_os.getenv(self.alloc, "GHOSTTY_LOG"))) |v| { - defer v.deinit(self.alloc); - if (v.value.len > 0) { - self.logging = .{ .stderr = {} }; - } - } - - // Output some debug information right away - std.log.info("ghostty version={s}", .{build_config.version_string}); - std.log.info("ghostty build optimize={s}", .{build_config.mode_string}); - std.log.info("runtime={}", .{build_config.app_runtime}); - std.log.info("font_backend={}", .{build_config.font_backend}); - if (comptime build_config.font_backend.hasHarfbuzz()) { - std.log.info("dependency harfbuzz={s}", .{harfbuzz.versionString()}); - } - if (comptime build_config.font_backend.hasFontconfig()) { - std.log.info("dependency fontconfig={d}", .{fontconfig.version()}); - } - std.log.info("renderer={}", .{renderer.Renderer}); - std.log.info("libxev backend={}", .{xev.backend}); - - // First things first, we fix our file descriptors - internal_os.fixMaxFiles(); - - // We need to make sure the process locale is set properly. Locale - // affects a lot of behaviors in a shell. - try internal_os.ensureLocale(self.alloc); - - // Initialize glslang for shader compilation - try glslang.init(); - - // Initialize oniguruma for regex - try oni.init(&.{oni.Encoding.utf8}); - - // Find our resources directory once for the app so every launch - // hereafter can use this cached value. - self.resources_dir = try internal_os.resourcesDir(self.alloc); - errdefer if (self.resources_dir) |dir| self.alloc.free(dir); - } - - /// Cleans up the global state. This doesn't _need_ to be called but - /// doing so in dev modes will check for memory leaks. - pub fn deinit(self: *GlobalState) void { - if (self.resources_dir) |dir| self.alloc.free(dir); - - if (self.gpa) |*value| { - // We want to ensure that we deinit the GPA because this is - // the point at which it will output if there were safety violations. - _ = value.deinit(); - } - } -}; - test { _ = @import("circ_buf.zig"); _ = @import("pty.zig");