From b823a49b6a57bc1736b33a0816b42aaaf86cf839 Mon Sep 17 00:00:00 2001 From: Sam Atman Date: Fri, 6 Feb 2026 13:07:03 -0500 Subject: zg module, casing improvements --- src/CaseFolding.zig | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) (limited to 'src/CaseFolding.zig') diff --git a/src/CaseFolding.zig b/src/CaseFolding.zig index d69cddc..b7aa020 100644 --- a/src/CaseFolding.zig +++ b/src/CaseFolding.zig @@ -103,7 +103,16 @@ pub fn compatCaselessMatch( a: []const u8, b: []const u8, ) Allocator.Error!bool { - if (ascii.isAsciiOnly(a) and ascii.isAsciiOnly(b)) return std.ascii.eqlIgnoreCase(a, b); + var a_in = a; + var b_in = b; + + // Ascii short path. Only applies if they're the same length: + if (a_in.len == b_in.len) { + const prefix = ascii.caselessCmpLen(a_in, b_in); + if (prefix == a_in.len) return true; + a_in = a_in[prefix..]; + b_in = b_in[prefix..]; + } // Process a const nfd_a = try Normalize.nfxdCodePoints(allocator, a, .nfd); @@ -192,10 +201,19 @@ pub fn canonCaselessMatch( a: []const u8, b: []const u8, ) Allocator.Error!bool { - if (ascii.isAsciiOnly(a) and ascii.isAsciiOnly(b)) return std.ascii.eqlIgnoreCase(a, b); + var a_in = a; + var b_in = b; + + // Ascii short path. Only applies if they're the same length: + if (a_in.len == b_in.len) { + const prefix = ascii.caselessCmpLen(a_in, b_in); + if (prefix == a_in.len) return true; + a_in = a_in[prefix..]; + b_in = b_in[prefix..]; + } // Process a - const nfd_a = try Normalize.nfxdCodePoints(allocator, a, .nfd); + const nfd_a = try Normalize.nfxdCodePoints(allocator, a_in, .nfd); defer allocator.free(nfd_a); var need_free_cf_nfd_a = false; @@ -215,7 +233,7 @@ pub fn canonCaselessMatch( defer if (need_free_nfd_cf_nfd_a) allocator.free(nfd_cf_nfd_a); // Process b - const nfd_b = try Normalize.nfxdCodePoints(allocator, b, .nfd); + const nfd_b = try Normalize.nfxdCodePoints(allocator, b_in, .nfd); defer allocator.free(nfd_b); var need_free_cf_nfd_b = false; -- cgit v1.2.3