fix canonicalizing some zh locales (#6885)

resolve #6870

---------

Signed-off-by: Aaron Ruan <i@ar212.com>
This commit is contained in:
Aaron Ruan
2025-03-25 22:46:14 +08:00
committed by GitHub
parent 5d9bee98e8
commit 416b617de9

View File

@@ -107,6 +107,9 @@ pub fn canonicalizeLocale(
buf: []u8,
locale: []const u8,
) error{NoSpaceLeft}![:0]const u8 {
// Fix zh locales for macOS
if (fixZhLocale(locale)) |fixed| return fixed;
// Buffer must be 16 or at least as long as the locale and null term
if (buf.len < @max(16, locale.len + 1)) return error.NoSpaceLeft;
@@ -125,6 +128,30 @@ pub fn canonicalizeLocale(
return buf[0..slice.len :0];
}
/// Handles some zh locales canonicalization because internal libintl
/// canonicalization function doesn't handle correctly in these cases.
fn fixZhLocale(locale: []const u8) ?[:0]const u8 {
var it = std.mem.splitScalar(u8, locale, '-');
const name = it.next() orelse return null;
if (!std.mem.eql(u8, name, "zh")) return null;
const script = it.next() orelse return null;
const region = it.next() orelse return null;
if (std.mem.eql(u8, script, "Hans")) {
if (std.mem.eql(u8, region, "SG")) return "zh_SG";
return "zh_CN";
}
if (std.mem.eql(u8, script, "Hant")) {
if (std.mem.eql(u8, region, "MO")) return "zh_MO";
if (std.mem.eql(u8, region, "HK")) return "zh_HK";
return "zh_TW";
}
return null;
}
/// This can be called at any point a compile-time-known locale is
/// available. This will use comptime to verify the locale is supported.
pub fn staticLocale(comptime v: [*:0]const u8) [*:0]const u8 {
@@ -159,6 +186,12 @@ test "canonicalizeLocale darwin" {
try testing.expectEqualStrings("zh_CN", try canonicalizeLocale(&buf, "zh-Hans"));
try testing.expectEqualStrings("zh_TW", try canonicalizeLocale(&buf, "zh-Hant"));
try testing.expectEqualStrings("zh_CN", try canonicalizeLocale(&buf, "zh-Hans-CN"));
try testing.expectEqualStrings("zh_SG", try canonicalizeLocale(&buf, "zh-Hans-SG"));
try testing.expectEqualStrings("zh_TW", try canonicalizeLocale(&buf, "zh-Hant-TW"));
try testing.expectEqualStrings("zh_HK", try canonicalizeLocale(&buf, "zh-Hant-HK"));
try testing.expectEqualStrings("zh_MO", try canonicalizeLocale(&buf, "zh-Hant-MO"));
// This is just an edge case I want to make sure we're aware of:
// canonicalizeLocale does not handle encodings and will turn them into
// underscores. We should parse them out before calling this function.