fix canonicalizing some zh locales

Signed-off-by: Aaron Ruan <i@ar212.com>
This commit is contained in:
Aaron Ruan
2025-03-23 23:36:37 +08:00
parent 1980f9aed4
commit 0adbe6c428

View File

@ -108,12 +108,15 @@ pub fn canonicalizeLocale(
// 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;
// Fix zh locales for macOS
const updated = fixZHLocale(locale);
// Copy our locale into the buffer since it modifies in place.
// This must be null-terminated.
@memcpy(buf[0..locale.len], locale);
buf[locale.len] = 0;
@memcpy(buf[0..updated.len], updated);
buf[updated.len] = 0;
_libintl_locale_name_canonicalize(buf[0..locale.len :0]);
_libintl_locale_name_canonicalize(buf[0..updated.len :0]);
// Convert the null-terminated result buffer into a slice. We
// need to search for the null terminator and slice it back.
@ -123,6 +126,24 @@ pub fn canonicalizeLocale(
return buf[0..slice.len :0];
}
fn fixZHLocale(locale: []const u8) []const u8 {
if (locale.len == 10 and std.mem.eql(u8, locale[0..2], "zh")) {
const script = locale[3..7];
const region = locale[8..10];
if (std.mem.eql(u8, script, "Hans")) {
if (std.mem.eql(u8, region, "SG")) return "zh-SG";
return "zh-CN";
} else if (std.mem.eql(u8, script, "Hant")) {
if (std.mem.eql(u8, region, "HK")) return "zh-HK";
if (std.mem.eql(u8, region, "MO")) return "zh-MO";
return "zh-TW";
}
}
return locale;
}
/// 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 {
@ -157,6 +178,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.