use comptime to make C String interface nicer

pull/8886/head
Jeffrey C. Ollie 2025-09-24 16:33:18 -05:00
parent c5786c5d38
commit 79685f87c4
No known key found for this signature in database
GPG Key ID: 1BB9EB7EA602265B
2 changed files with 27 additions and 6 deletions

View File

@ -131,7 +131,7 @@ export fn ghostty_config_open_path() c.String {
};
// Capacity is len + 1 due to sentinel
return .fromSlice(path, path.len + 1);
return .fromSlice(path);
}
/// Sync with ghostty_diagnostic_s

View File

@ -63,21 +63,42 @@ const Info = extern struct {
pub const String = extern struct {
ptr: ?[*]const u8,
len: usize,
cap: usize,
sentinel: bool,
pub const empty: String = .{
.ptr = null,
.len = 0,
.cap = 0,
.sentinel = false,
};
pub fn fromSlice(slice: []const u8, cap: usize) String {
pub fn fromSlice(slice: anytype) String {
return .{
.ptr = slice.ptr,
.len = slice.len,
.cap = cap,
.sentinel = sentinel: {
const info = @typeInfo(@TypeOf(slice));
switch (info) {
.pointer => |p| {
if (p.size != .slice) @compileError("only slices supported");
if (p.child != u8) @compileError("only u8 slices supported");
const sentinel_ = p.sentinel();
if (sentinel_) |sentinel| if (sentinel != 0) @compileError("only 0 is supported for sentinels");
break :sentinel sentinel_ != null;
},
else => @compileError("only []const u8 and [:0]const u8"),
}
},
};
}
pub fn deinit(self: *const String) void {
const ptr = self.ptr orelse return;
if (self.sentinel) {
state.alloc.free(ptr[0..self.len :0]);
} else {
state.alloc.free(ptr[0..self.len]);
}
}
};
/// Initialize ghostty global state.
@ -132,5 +153,5 @@ pub export fn ghostty_translate(msgid: [*:0]const u8) [*:0]const u8 {
/// Free a string allocated by Ghostty.
pub export fn ghostty_string_free(str: String) void {
state.alloc.free(str.ptr.?[0..str.cap]);
str.deinit();
}