diff --git a/src/fontconfig.zig b/src/fontconfig.zig index fe11c30..f8f70cc 100644 --- a/src/fontconfig.zig +++ b/src/fontconfig.zig @@ -23,7 +23,7 @@ pub const Font = struct { const Self = @This(); 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 { c.FcPatternDestroy(self.pattern); c.FcFontSetDestroy(self.fontset); + for (self.list.items) |*f| f.deinit(); self.list.deinit(); } @@ -83,9 +84,19 @@ pub fn deinit() void { if (deinited) @panic("Cannot deinitialize this library more than once"); deinited = true; if (fc_config) |conf| { - log.debug("destroying config: do not use library or call me again", .{}); - c.FcConfigDestroy(conf); + log.debug("destroying config ({*}): do not use library or call me again", .{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; } @@ -107,7 +118,10 @@ pub const FontQuery = struct { 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) 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; // Pretty sure we want this... diff --git a/src/main.zig b/src/main.zig index 8967c83..e4be061 100644 --- a/src/main.zig +++ b/src/main.zig @@ -12,8 +12,7 @@ const all_chars = blk: { break :blk all; }; pub fn main() !u8 { - // TODO: Add back in - // defer fontconfig.deinit(); + defer fontconfig.deinit(); var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); defer arena.deinit(); const allocator = arena.allocator(); @@ -75,20 +74,22 @@ pub fn main() !u8 { return 0; } const exclude_previous = options.fonts != null; + var fl: ?fontconfig.FontList = null; + defer if (fl) |*f| f.deinit(); const fonts: []fontconfig.Font = blk: { if (options.fonts == null) break :blk &[_]fontconfig.Font{}; const fo = options.fonts.?; var si = std.mem.splitScalar(u8, fo, ','); var fq = fontconfig.FontQuery.init(allocator); 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 // defer fl.deinit(); var al = try std.ArrayList(fontconfig.Font).initCapacity(allocator, std.mem.count(u8, fo, ",") + 2); defer al.deinit(); while (si.next()) |font_str| { const font = font_blk: { - for (fl.list.items) |f| + for (fl.?.list.items) |f| if (std.ascii.eqlIgnoreCase(f.family, font_str)) break :font_blk f; try std.io.getStdErr().writer().print("Error: Font '{s}' not installed", .{font_str});