summaryrefslogtreecommitdiff
path: root/src/DisplayWidth.zig
diff options
context:
space:
mode:
Diffstat (limited to 'src/DisplayWidth.zig')
-rw-r--r--src/DisplayWidth.zig72
1 files changed, 46 insertions, 26 deletions
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 @@
1const std = @import("std"); 1//! Display Width module
2const builtin = @import("builtin"); 2//!
3const options = @import("options"); 3//! Answers questions about the printable width in monospaced fonts of the
4const ArrayList = std.ArrayList; 4//! string of interest.
5const compress = std.compress;
6const mem = std.mem;
7const simd = std.simd;
8const testing = std.testing;
9
10const ascii = @import("ascii");
11const CodePointIterator = @import("code_point").Iterator;
12pub const DisplayWidthData = @import("DisplayWidthData");
13 5
14const Graphemes = @import("Graphemes"); 6graphemes: Graphemes = undefined,
15
16graphemes: Graphemes,
17s1: []u16 = undefined, 7s1: []u16 = undefined,
18s2: []i4 = undefined, 8s2: []i4 = undefined,
19owns_graphemes: bool, 9owns_graphemes: bool = true,
20 10
21const DisplayWidth = @This(); 11const DisplayWidth = @This();
22 12
23pub fn init(allocator: mem.Allocator) mem.Allocator.Error!DisplayWidth { 13pub fn init(allocator: Allocator) Allocator.Error!DisplayWidth {
24 var dw: DisplayWidth = try DisplayWidth.setup(allocator); 14 var dw = DisplayWidth{};
15 try dw.setup(allocator);
25 errdefer { 16 errdefer {
26 allocator.free(dw.s1); 17 allocator.free(dw.s1);
27 allocator.free(dw.s2); 18 allocator.free(dw.s2);
@@ -32,15 +23,16 @@ pub fn init(allocator: mem.Allocator) mem.Allocator.Error!DisplayWidth {
32 return dw; 23 return dw;
33} 24}
34 25
35pub fn initWithGraphemes(allocator: mem.Allocator, graphemes: Graphemes) mem.Allocator.Error!DisplayWidth { 26pub fn initWithGraphemes(allocator: Allocator, graphemes: Graphemes) Allocator.Error!DisplayWidth {
36 var dw = try DisplayWidth.setup(allocator); 27 var dw = DisplayWidth{};
28 try dw.setup(allocator);
37 dw.graphemes = graphemes; 29 dw.graphemes = graphemes;
38 dw.owns_graphemes = false; 30 dw.owns_graphemes = false;
39 return dw; 31 return dw;
40} 32}
41 33
42// Sets up the DisplayWidthData, leaving the GraphemeData undefined. 34// Sets up the DisplayWidthData, leaving the GraphemeData undefined.
43fn setup(allocator: mem.Allocator) mem.Allocator.Error!DisplayWidth { 35fn setup(dw: *DisplayWidth, allocator: Allocator) Allocator.Error!void {
44 const decompressor = compress.flate.inflate.decompressor; 36 const decompressor = compress.flate.inflate.decompressor;
45 const in_bytes = @embedFile("dwp"); 37 const in_bytes = @embedFile("dwp");
46 var in_fbs = std.io.fixedBufferStream(in_bytes); 38 var in_fbs = std.io.fixedBufferStream(in_bytes);
@@ -49,8 +41,6 @@ fn setup(allocator: mem.Allocator) mem.Allocator.Error!DisplayWidth {
49 41
50 const endian = builtin.cpu.arch.endian(); 42 const endian = builtin.cpu.arch.endian();
51 43
52 var dw: DisplayWidth = undefined;
53
54 const stage_1_len: u16 = reader.readInt(u16, endian) catch unreachable; 44 const stage_1_len: u16 = reader.readInt(u16, endian) catch unreachable;
55 dw.s1 = try allocator.alloc(u16, stage_1_len); 45 dw.s1 = try allocator.alloc(u16, stage_1_len);
56 errdefer allocator.free(dw.s1); 46 errdefer allocator.free(dw.s1);
@@ -60,11 +50,9 @@ fn setup(allocator: mem.Allocator) mem.Allocator.Error!DisplayWidth {
60 dw.s2 = try allocator.alloc(i4, stage_2_len); 50 dw.s2 = try allocator.alloc(i4, stage_2_len);
61 errdefer allocator.free(dw.s2); 51 errdefer allocator.free(dw.s2);
62 for (0..stage_2_len) |i| dw.s2[i] = @intCast(reader.readInt(i8, endian) catch unreachable); 52 for (0..stage_2_len) |i| dw.s2[i] = @intCast(reader.readInt(i8, endian) catch unreachable);
63
64 return dw;
65} 53}
66 54
67pub fn deinit(dw: *const DisplayWidth, allocator: mem.Allocator) void { 55pub fn deinit(dw: *const DisplayWidth, allocator: Allocator) void {
68 allocator.free(dw.s1); 56 allocator.free(dw.s1);
69 allocator.free(dw.s2); 57 allocator.free(dw.s2);
70 if (dw.owns_graphemes) dw.graphemes.deinit(allocator); 58 if (dw.owns_graphemes) dw.graphemes.deinit(allocator);
@@ -445,3 +433,35 @@ test "wrap" {
445 const want = "The quick \nbrown fox \njumped \nover the \nlazy dog!"; 433 const want = "The quick \nbrown fox \njumped \nover the \nlazy dog!";
446 try testing.expectEqualStrings(want, got); 434 try testing.expectEqualStrings(want, got);
447} 435}
436
437fn testAllocation(allocator: Allocator) !void {
438 {
439 var dw = try DisplayWidth.init(allocator);
440 dw.deinit(allocator);
441 }
442 {
443 var graph = try Graphemes.init(allocator);
444 defer graph.deinit(allocator);
445 var dw = try DisplayWidth.initWithGraphemes(allocator, graph);
446 dw.deinit(allocator);
447 }
448}
449
450test "allocation test" {
451 try testing.checkAllAllocationFailures(testing.allocator, testAllocation, .{});
452}
453
454const std = @import("std");
455const builtin = @import("builtin");
456const options = @import("options");
457const ArrayList = std.ArrayList;
458const compress = std.compress;
459const mem = std.mem;
460const Allocator = mem.Allocator;
461const simd = std.simd;
462const testing = std.testing;
463
464const ascii = @import("ascii");
465const CodePointIterator = @import("code_point").Iterator;
466
467const Graphemes = @import("Graphemes");