address most memory leaks
All checks were successful
Generic zig build / build (push) Successful in 1m6s

This commit is contained in:
Emil Lerch 2024-05-05 09:16:19 -07:00
parent 8ab28400c4
commit 31fe824a8b
Signed by: lobo
GPG Key ID: A7B62D657EF764F8
2 changed files with 23 additions and 8 deletions

View File

@ -23,7 +23,7 @@ pub const Font = struct {
const Self = @This(); const Self = @This();
pub fn deinit(self: *Self) void { pub fn deinit(self: *Self) void {
freeAllCharacters(self.supported_chars.ptr); freeAllCharacters(@ptrCast(@alignCast(@constCast(self.supported_chars.ptr))));
} }
}; };
@ -47,6 +47,7 @@ pub const FontList = struct {
pub fn deinit(self: *Self) void { pub fn deinit(self: *Self) void {
c.FcPatternDestroy(self.pattern); c.FcPatternDestroy(self.pattern);
c.FcFontSetDestroy(self.fontset); c.FcFontSetDestroy(self.fontset);
for (self.list.items) |*f| f.deinit();
self.list.deinit(); self.list.deinit();
} }
@ -83,9 +84,19 @@ pub fn deinit() void {
if (deinited) @panic("Cannot deinitialize this library more than once"); if (deinited) @panic("Cannot deinitialize this library more than once");
deinited = true; deinited = true;
if (fc_config) |conf| { if (fc_config) |conf| {
log.debug("destroying config: do not use library or call me again", .{}); log.debug("destroying config ({*}): do not use library or call me again", .{conf});
c.FcConfigDestroy(conf); // TODO: Well, our pointers line up, but we still end up with a seg fault,
// with valgrind reporting the following stack trace:
// Invalid read of size 4
// at 0x4868565: FcPatternDestroy (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0)
// by 0x4860A48: FcFontSetDestroy (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0)
// by 0x485386E: FcConfigDestroy (in /usr/lib/x86_64-linux-gnu/libfontconfig.so.1.12.0)
// by 0x147FEB8: fontconfig.deinit
//
// While that's here, all our deinits look good, so...?
// c.FcConfigDestroy(conf);
} }
// c.FcFini();
fc_config = null; fc_config = null;
} }
@ -107,7 +118,10 @@ pub const FontQuery = struct {
pub fn fontList(self: *Self, pattern: [:0]const u8) !FontList { pub fn fontList(self: *Self, pattern: [:0]const u8) !FontList {
if (fc_config == null and deinited) @panic("fontconfig C library is in an inconsistent state - should not use"); if (fc_config == null and deinited) @panic("fontconfig C library is in an inconsistent state - should not use");
if (fc_config == null) fc_config = c.FcInitLoadConfigAndFonts(); if (fc_config == null) {
fc_config = c.FcInitLoadConfigAndFonts();
log.debug("config loaded ({*})", .{fc_config.?});
}
const config = if (fc_config) |conf| conf else return error.FontConfigInitLoadFailure; const config = if (fc_config) |conf| conf else return error.FontConfigInitLoadFailure;
// Pretty sure we want this... // Pretty sure we want this...

View File

@ -12,8 +12,7 @@ const all_chars = blk: {
break :blk all; break :blk all;
}; };
pub fn main() !u8 { pub fn main() !u8 {
// TODO: Add back in defer fontconfig.deinit();
// defer fontconfig.deinit();
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
defer arena.deinit(); defer arena.deinit();
const allocator = arena.allocator(); const allocator = arena.allocator();
@ -75,20 +74,22 @@ pub fn main() !u8 {
return 0; return 0;
} }
const exclude_previous = options.fonts != null; const exclude_previous = options.fonts != null;
var fl: ?fontconfig.FontList = null;
defer if (fl) |*f| f.deinit();
const fonts: []fontconfig.Font = blk: { const fonts: []fontconfig.Font = blk: {
if (options.fonts == null) break :blk &[_]fontconfig.Font{}; if (options.fonts == null) break :blk &[_]fontconfig.Font{};
const fo = options.fonts.?; const fo = options.fonts.?;
var si = std.mem.splitScalar(u8, fo, ','); var si = std.mem.splitScalar(u8, fo, ',');
var fq = fontconfig.FontQuery.init(allocator); var fq = fontconfig.FontQuery.init(allocator);
defer fq.deinit(); defer fq.deinit();
const fl = try fq.fontList(options.pattern); fl = try fq.fontList(options.pattern);
// This messes with data after, and we don't need to deinit anyway // This messes with data after, and we don't need to deinit anyway
// defer fl.deinit(); // defer fl.deinit();
var al = try std.ArrayList(fontconfig.Font).initCapacity(allocator, std.mem.count(u8, fo, ",") + 2); var al = try std.ArrayList(fontconfig.Font).initCapacity(allocator, std.mem.count(u8, fo, ",") + 2);
defer al.deinit(); defer al.deinit();
while (si.next()) |font_str| { while (si.next()) |font_str| {
const font = font_blk: { const font = font_blk: {
for (fl.list.items) |f| for (fl.?.list.items) |f|
if (std.ascii.eqlIgnoreCase(f.family, font_str)) if (std.ascii.eqlIgnoreCase(f.family, font_str))
break :font_blk f; break :font_blk f;
try std.io.getStdErr().writer().print("Error: Font '{s}' not installed", .{font_str}); try std.io.getStdErr().writer().print("Error: Font '{s}' not installed", .{font_str});