1//! Wrapper around the 'zg' PropsData library.
2const std = @import("std");
3const PropsData = @import("zg:PropsData");
4const tracer = @import("tracer");
5
6var props: ?PropsData = undefined;
7var props_memory: []u8 = undefined;
8
9const raw_allocator = if (@import("builtin").target.cpu.arch.isWasm())
10 std.heap.wasm_allocator
11else
12 std.heap.page_allocator;
13
14pub fn init() !void {
15 if (props != null) return;
16
17 const trace = tracer.trace(@src());
18 defer trace.end();
19
20 // The uncompressed unicode data has a fixed size allocated on startup.
21 // In practice, it is never freed.
22 const allocation_size = 8704 + 34560 + 8704 + 17664 + 8704 + 25856;
23 if (allocation_size == 0) {
24 var logging_alloc = std.heap.loggingAllocator(std.heap.page_allocator);
25 props = try PropsData.init(logging_alloc.allocator());
26 std.log.err("please write the above numbers into unicode.zig to prealloc this", .{});
27 std.process.exit(1);
28 }
29
30 props_memory = try raw_allocator.alloc(u8, allocation_size);
31 errdefer std.heap.page_allocator.free(props_memory);
32
33 var fba = std.heap.FixedBufferAllocator.init(props_memory);
34 props = try PropsData.init(fba.allocator());
35 std.debug.assert(fba.end_index == allocation_size);
36}
37
38pub fn deinit() void {
39 std.debug.assert(props != null);
40 raw_allocator.free(props_memory);
41 props = null;
42 props_memory = undefined;
43}
44
45/// True if `cp` is a mathematical symbol.
46pub inline fn isMath(cp: u21) bool {
47 return props.?.isMath(cp);
48}
49
50/// True if `cp` is an alphabetic character.
51pub inline fn isAlphabetic(cp: u21) bool {
52 return props.?.isAlphabetic(cp);
53}
54
55/// True if `cp` is a valid identifier start character.
56pub inline fn isIdStart(cp: u21) bool {
57 return props.?.isIdStart(cp);
58}
59
60/// True if `cp` is a valid identifier continuation character.
61pub inline fn isIdContinue(cp: u21) bool {
62 return props.?.isIdContinue(cp);
63}
64
65/// True if `cp` is a valid extended identifier start character.
66pub inline fn isXidStart(cp: u21) bool {
67 return props.?.isXidStart(cp);
68}
69
70/// True if `cp` is a valid extended identifier continuation character.
71pub inline fn isXidContinue(cp: u21) bool {
72 return props.?.isXidContinue(cp);
73}
74
75/// True if `cp` is a whitespace character.
76pub inline fn isWhitespace(cp: u21) bool {
77 return props.?.isWhitespace(cp);
78}
79
80/// True if `cp` is a hexadecimal digit.
81pub inline fn isHexDigit(cp: u21) bool {
82 return props.?.isHexDigit(cp);
83}
84
85/// True if `cp` is a diacritic mark.
86pub inline fn isDiacritic(cp: u21) bool {
87 return props.?.isDiacritic(cp);
88}
89
90/// True if `cp` is numeric.
91pub inline fn isNumeric(cp: u21) bool {
92 return props.?.isNumeric(cp);
93}
94
95/// True if `cp` is a digit.
96pub inline fn isDigit(cp: u21) bool {
97 return props.?.isDigit(cp);
98}
99
100/// True if `cp` is decimal.
101pub inline fn isDecimal(cp: u21) bool {
102 return props.?.isDecimal(cp);
103}