diff --git a/example/c-vt/src/main.c b/example/c-vt/src/main.c index 45269d1d4..406e617b6 100644 --- a/example/c-vt/src/main.c +++ b/example/c-vt/src/main.c @@ -1,3 +1,9 @@ +#include +#include + int main() { - return 42; + GhosttyOscParser parser; + ghostty_vt_osc_new(NULL, &parser); + ghostty_vt_osc_free(parser); + return 0; } diff --git a/include/ghostty-vt.h b/include/ghostty-vt.h index 7bbbdf3da..3c4f6212d 100644 --- a/include/ghostty-vt.h +++ b/include/ghostty-vt.h @@ -14,7 +14,7 @@ extern "C" { //------------------------------------------------------------------- // Types -typedef struct GhosttyOscParser GhosttyOscParser; +typedef struct GhosttyOscParser *GhosttyOscParser; typedef enum { GHOSTTY_VT_SUCCESS = 0, @@ -131,6 +131,9 @@ typedef struct { //------------------------------------------------------------------- // Functions +GhosttyVtResult ghostty_vt_osc_new(const GhosttyVtAllocator*, GhosttyOscParser*); +void ghostty_vt_osc_free(GhosttyOscParser); + #ifdef __cplusplus } #endif diff --git a/src/lib/allocator.zig b/src/lib/allocator.zig index ef296f23d..de1453dbe 100644 --- a/src/lib/allocator.zig +++ b/src/lib/allocator.zig @@ -13,6 +13,22 @@ pub const VTable = extern struct { free: *const fn (*anyopaque, memory: [*]u8, memory_len: usize, alignment: u8, ret_addr: usize) callconv(.c) void, }; +/// Returns an allocator to use for the given possibly-null C allocator, +/// ensuring some allocator is always returned. +pub fn default(c_alloc_: ?*const Allocator) std.mem.Allocator { + // If we're given an allocator, use it. + if (c_alloc_) |c_alloc| return c_alloc.zig(); + + // If we have libc, use that. We prefer libc if we have it because + // its generally fast but also lets the embedder easily override + // malloc/free with custom allocators like mimalloc or something. + if (comptime builtin.link_libc) return std.heap.c_allocator; + + // No libc, use the preferred allocator for releases which is the + // Zig SMP allocator. + return std.heap.smp_allocator; +} + /// The Allocator interface for custom memory allocation strategies /// within C libghostty APIs. /// diff --git a/src/terminal/c_api.zig b/src/terminal/c_api.zig index 079a16fb3..debffdc59 100644 --- a/src/terminal/c_api.zig +++ b/src/terminal/c_api.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const builtin = @import("builtin"); const lib_alloc = @import("../lib/allocator.zig"); const CAllocator = lib_alloc.Allocator; const osc = @import("osc.zig"); @@ -13,10 +14,10 @@ pub const Result = enum(c_int) { }; pub fn ghostty_vt_osc_new( - c_alloc: *const CAllocator, + c_alloc_: ?*const CAllocator, result: *GhosttyOscParser, ) callconv(.c) Result { - const alloc = c_alloc.zig(); + const alloc = lib_alloc.default(c_alloc_); const ptr = alloc.create(osc.Parser) catch return .out_of_memory; ptr.* = .initAlloc(alloc); result.* = .{ .parser = ptr };