diff options
| author | Jonathan Marler <johnnymarler@gmail.com> | 2022-02-04 22:36:24 -0700 |
|---|---|---|
| committer | Jonathan Marler <johnnymarler@gmail.com> | 2022-05-11 18:41:23 -0600 |
| commit | e65d8f82c5f98b20236f571fe4a4e40924ea8dc2 (patch) | |
| tree | 8f32cc1f06809c43cce5430e0428bc94d15b6df3 /lib/std/process.zig | |
| parent | 69f0a5587d0db07546e91968b21135fdef856136 (diff) | |
| download | zig-e65d8f82c5f98b20236f571fe4a4e40924ea8dc2.tar.gz zig-e65d8f82c5f98b20236f571fe4a4e40924ea8dc2.zip | |
add unicode support
Diffstat (limited to 'lib/std/process.zig')
| -rw-r--r-- | lib/std/process.zig | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/lib/std/process.zig b/lib/std/process.zig index 0b891bbdf5..8892f1cc88 100644 --- a/lib/std/process.zig +++ b/lib/std/process.zig @@ -63,26 +63,42 @@ pub const EnvMap = struct { ); pub const EnvNameHashContext = struct { + fn upcase(c: u21) u21 { + if (c <= std.math.maxInt(u16)) + return std.os.windows.ntdll.RtlUpcaseUnicodeChar(c); + return c; + } + pub fn hash(self: @This(), s: []const u8) u64 { _ = self; if (builtin.os.tag == .windows) { const h = std.hash.Wyhash.init(0); - // TODO: improve this, instead of iterating over ascii, - // iterate over with unicode - for (s) |c| { - var s_upper = [_]u8 { std.ascii.toLower(c) }; - h.update(s_upper); + var it = std.unicode.Utf8View(s).iterator(); + while (it.nextCodepoint()) |cp| { + const cp_upper = upcase(cp); + h.update(&[_]u8{ + @intCast(u8, (cp_upper >> 16) & 0xff), + @intCast(u8, (cp_upper >> 8) & 0xff), + @intCast(u8, (cp_upper >> 0) & 0xff), + }); } return h.final(); } return std.hash_map.hashString(s); } + pub fn eql(self: @This(), a: []const u8, b: []const u8) bool { _ = self; if (builtin.os.tag == .windows) { - // TODO: improve this, instead of comparing ascii - // compare with unicode - return std.ascii.eqlIgnoreCase(a, b); + var it_a = std.unicode.Utf8View(a).iterator(); + var it_b = std.unicode.Utf8View(b).iterator(); + while (true) { + const c_a = it_a.nextCodepoint() orelse break; + const c_b = it_b.nextCodepoint() orelse return false; + if (upcase(c_a) != upcase(c_b)) + return false; + } + if (it_b.nextCodepoint()) return false; } return std.hash_map.eqlString(a, b); } |
