From 10048b0d31d0db923ae39c6bbd67139ed6252f6f Mon Sep 17 00:00:00 2001 From: Sam Atman Date: Wed, 30 Apr 2025 20:30:39 -0400 Subject: Allocation Failure Tests These turned up an excessive amount of allocations in CanonData and CompatData, which have been reduced to two through the somewhat squirrely use of 'magic numbers'. There are now allocation tests for every allocated structure in the library, and they run to completion in a reasonable amount of time. So, that's nice. --- src/DisplayWidth.zig | 72 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 26 deletions(-) (limited to 'src/DisplayWidth.zig') diff --git a/src/DisplayWidth.zig b/src/DisplayWidth.zig index c0d6d96..4c63be4 100644 --- a/src/DisplayWidth.zig +++ b/src/DisplayWidth.zig @@ -1,27 +1,18 @@ -const std = @import("std"); -const builtin = @import("builtin"); -const options = @import("options"); -const ArrayList = std.ArrayList; -const compress = std.compress; -const mem = std.mem; -const simd = std.simd; -const testing = std.testing; - -const ascii = @import("ascii"); -const CodePointIterator = @import("code_point").Iterator; -pub const DisplayWidthData = @import("DisplayWidthData"); +//! Display Width module +//! +//! Answers questions about the printable width in monospaced fonts of the +//! string of interest. -const Graphemes = @import("Graphemes"); - -graphemes: Graphemes, +graphemes: Graphemes = undefined, s1: []u16 = undefined, s2: []i4 = undefined, -owns_graphemes: bool, +owns_graphemes: bool = true, const DisplayWidth = @This(); -pub fn init(allocator: mem.Allocator) mem.Allocator.Error!DisplayWidth { - var dw: DisplayWidth = try DisplayWidth.setup(allocator); +pub fn init(allocator: Allocator) Allocator.Error!DisplayWidth { + var dw = DisplayWidth{}; + try dw.setup(allocator); errdefer { allocator.free(dw.s1); allocator.free(dw.s2); @@ -32,15 +23,16 @@ pub fn init(allocator: mem.Allocator) mem.Allocator.Error!DisplayWidth { return dw; } -pub fn initWithGraphemes(allocator: mem.Allocator, graphemes: Graphemes) mem.Allocator.Error!DisplayWidth { - var dw = try DisplayWidth.setup(allocator); +pub fn initWithGraphemes(allocator: Allocator, graphemes: Graphemes) Allocator.Error!DisplayWidth { + var dw = DisplayWidth{}; + try dw.setup(allocator); dw.graphemes = graphemes; dw.owns_graphemes = false; return dw; } // Sets up the DisplayWidthData, leaving the GraphemeData undefined. -fn setup(allocator: mem.Allocator) mem.Allocator.Error!DisplayWidth { +fn setup(dw: *DisplayWidth, allocator: Allocator) Allocator.Error!void { const decompressor = compress.flate.inflate.decompressor; const in_bytes = @embedFile("dwp"); var in_fbs = std.io.fixedBufferStream(in_bytes); @@ -49,8 +41,6 @@ fn setup(allocator: mem.Allocator) mem.Allocator.Error!DisplayWidth { const endian = builtin.cpu.arch.endian(); - var dw: DisplayWidth = undefined; - const stage_1_len: u16 = reader.readInt(u16, endian) catch unreachable; dw.s1 = try allocator.alloc(u16, stage_1_len); errdefer allocator.free(dw.s1); @@ -60,11 +50,9 @@ fn setup(allocator: mem.Allocator) mem.Allocator.Error!DisplayWidth { dw.s2 = try allocator.alloc(i4, stage_2_len); errdefer allocator.free(dw.s2); for (0..stage_2_len) |i| dw.s2[i] = @intCast(reader.readInt(i8, endian) catch unreachable); - - return dw; } -pub fn deinit(dw: *const DisplayWidth, allocator: mem.Allocator) void { +pub fn deinit(dw: *const DisplayWidth, allocator: Allocator) void { allocator.free(dw.s1); allocator.free(dw.s2); if (dw.owns_graphemes) dw.graphemes.deinit(allocator); @@ -445,3 +433,35 @@ test "wrap" { const want = "The quick \nbrown fox \njumped \nover the \nlazy dog!"; try testing.expectEqualStrings(want, got); } + +fn testAllocation(allocator: Allocator) !void { + { + var dw = try DisplayWidth.init(allocator); + dw.deinit(allocator); + } + { + var graph = try Graphemes.init(allocator); + defer graph.deinit(allocator); + var dw = try DisplayWidth.initWithGraphemes(allocator, graph); + dw.deinit(allocator); + } +} + +test "allocation test" { + try testing.checkAllAllocationFailures(testing.allocator, testAllocation, .{}); +} + +const std = @import("std"); +const builtin = @import("builtin"); +const options = @import("options"); +const ArrayList = std.ArrayList; +const compress = std.compress; +const mem = std.mem; +const Allocator = mem.Allocator; +const simd = std.simd; +const testing = std.testing; + +const ascii = @import("ascii"); +const CodePointIterator = @import("code_point").Iterator; + +const Graphemes = @import("Graphemes"); -- cgit v1.2.3