Merge pull request #3595 from Kelimion/i18n-fix

Fix .mo parser: Number of plurals
This commit is contained in:
Jeroen van Rijn
2024-05-17 12:15:40 +02:00
committed by GitHub
3 changed files with 62 additions and 28 deletions
+3 -3
View File
@@ -93,15 +93,15 @@ parse_mo_from_bytes :: proc(data: []byte, options := DEFAULT_PARSE_OPTIONS, plur
keys := bytes.split(key, zero) keys := bytes.split(key, zero)
vals := bytes.split(val, zero) vals := bytes.split(val, zero)
if len(keys) != len(vals) || max(len(keys), len(vals)) > MAX_PLURALS { if (len(keys) != 1 && len(keys) != 2) || len(vals) > MAX_PLURALS {
return translation, .MO_File_Incorrect_Plural_Count return translation, .MO_File_Incorrect_Plural_Count
} }
for k in keys { for k in keys {
interned_key, _ := strings.intern_get(&translation.intern, string(k)) interned_key, _ := strings.intern_get(&translation.intern, string(k))
interned_vals := make([]string, len(keys)) interned_vals := make([]string, len(vals))
last_val: string last_val: string
i := 0 i := 0
Binary file not shown.
+59 -25
View File
@@ -38,44 +38,75 @@ Test :: struct {
Test_Suite :: struct { Test_Suite :: struct {
file: string, file: string,
loader: proc(string, i18n.Parse_Options, proc(int) -> int, mem.Allocator) -> (^i18n.Translation, i18n.Error), loader: proc(string, i18n.Parse_Options, proc(int) -> int, mem.Allocator) -> (^i18n.Translation, i18n.Error),
plural: proc(int) -> int,
err: i18n.Error, err: i18n.Error,
options: i18n.Parse_Options, options: i18n.Parse_Options,
tests: []Test, tests: []Test,
} }
// Custom pluralizer for plur.mo
plur_mo_pluralizer :: proc(n: int) -> (slot: int) {
switch {
case n == 1: return 0
case n != 0 && n % 1_000_000 == 0: return 1
case: return 2
}
}
TESTS := []Test_Suite{ TESTS := []Test_Suite{
{
file = "assets/I18N/plur.mo",
loader = i18n.parse_mo_file,
plural = plur_mo_pluralizer,
tests = {
// These are in the catalog.
{"", "Message1", "This is message 1", 1},
{"", "Message1", "This is message 1 - plural A", 1_000_000},
{"", "Message1", "This is message 1 - plural B", 42},
{"", "Message1/plural", "This is message 1", 1},
{"", "Message1/plural", "This is message 1 - plural A", 1_000_000},
{"", "Message1/plural", "This is message 1 - plural B", 42},
// This isn't in the catalog, so should ruturn the key.
{"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
},
},
{ {
file = "assets/I18N/nl_NL.mo", file = "assets/I18N/nl_NL.mo",
loader = i18n.parse_mo_file, loader = i18n.parse_mo_file,
plural = nil, // Default pluralizer
tests = { tests = {
// These are in the catalog. // These are in the catalog.
{ "", "There are 69,105 leaves here.", "Er zijn hier 69.105 bladeren.", 1 }, {"", "There are 69,105 leaves here.", "Er zijn hier 69.105 bladeren.", 1},
{ "", "Hellope, World!", "Hallo, Wereld!", 1 }, {"", "Hellope, World!", "Hallo, Wereld!", 1},
{ "", "There is %d leaf.\n", "Er is %d blad.\n", 1 }, {"", "There is %d leaf.\n", "Er is %d blad.\n", 1},
{ "", "There are %d leaves.\n", "Er is %d blad.\n", 1 }, {"", "There are %d leaves.\n", "Er is %d blad.\n", 1},
{ "", "There is %d leaf.\n", "Er zijn %d bladeren.\n", 42 }, {"", "There is %d leaf.\n", "Er zijn %d bladeren.\n", 42},
{ "", "There are %d leaves.\n", "Er zijn %d bladeren.\n", 42 }, {"", "There are %d leaves.\n", "Er zijn %d bladeren.\n", 42},
// This isn't in the catalog, so should ruturn the key. // This isn't in the catalog, so should ruturn the key.
{ "", "Come visit us on Discord!", "Come visit us on Discord!", 1 }, {"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
}, },
}, },
// QT Linguist with default loader options. // QT Linguist with default loader options.
{ {
file = "assets/I18N/nl_NL-qt-ts.ts", file = "assets/I18N/nl_NL-qt-ts.ts",
loader = i18n.parse_qt_linguist_file, loader = i18n.parse_qt_linguist_file,
plural = nil, // Default pluralizer
tests = { tests = {
// These are in the catalog. // These are in the catalog.
{ "Page", "Text for translation", "Tekst om te vertalen", 1}, {"Page", "Text for translation", "Tekst om te vertalen", 1},
{ "Page", "Also text to translate", "Ook tekst om te vertalen", 1}, {"Page", "Also text to translate", "Ook tekst om te vertalen", 1},
{ "installscript", "99 bottles of beer on the wall", "99 flessen bier op de muur", 1}, {"installscript", "99 bottles of beer on the wall", "99 flessen bier op de muur", 1},
{ "apple_count", "%d apple(s)", "%d appel", 1}, {"apple_count", "%d apple(s)", "%d appel", 1},
{ "apple_count", "%d apple(s)", "%d appels", 42}, {"apple_count", "%d apple(s)", "%d appels", 42},
// These aren't in the catalog, so should ruturn the key. // These aren't in the catalog, so should ruturn the key.
{ "", "Come visit us on Discord!", "Come visit us on Discord!", 1 }, {"", "Come visit us on Discord!", "Come visit us on Discord!", 1},
{ "Fake_Section", "Come visit us on Discord!", "Come visit us on Discord!", 1 }, {"Fake_Section", "Come visit us on Discord!", "Come visit us on Discord!", 1},
}, },
}, },
@@ -83,21 +114,22 @@ TESTS := []Test_Suite{
{ {
file = "assets/I18N/nl_NL-qt-ts.ts", file = "assets/I18N/nl_NL-qt-ts.ts",
loader = i18n.parse_qt_linguist_file, loader = i18n.parse_qt_linguist_file,
plural = nil, // Default pluralizer
options = {merge_sections = true}, options = {merge_sections = true},
tests = { tests = {
// All of them are now in section "", lookup with original section should return the key. // All of them are now in section "", lookup with original section should return the key.
{ "", "Text for translation", "Tekst om te vertalen", 1}, {"", "Text for translation", "Tekst om te vertalen", 1},
{ "", "Also text to translate", "Ook tekst om te vertalen", 1}, {"", "Also text to translate", "Ook tekst om te vertalen", 1},
{ "", "99 bottles of beer on the wall", "99 flessen bier op de muur", 1}, {"", "99 bottles of beer on the wall", "99 flessen bier op de muur", 1},
{ "", "%d apple(s)", "%d appel", 1}, {"", "%d apple(s)", "%d appel", 1},
{ "", "%d apple(s)", "%d appels", 42}, {"", "%d apple(s)", "%d appels", 42},
// All of them are now in section "", lookup with original section should return the key. // All of them are now in section "", lookup with original section should return the key.
{ "Page", "Text for translation", "Text for translation", 1}, {"Page", "Text for translation", "Text for translation", 1},
{ "Page", "Also text to translate", "Also text to translate", 1}, {"Page", "Also text to translate", "Also text to translate", 1},
{ "installscript", "99 bottles of beer on the wall", "99 bottles of beer on the wall", 1}, {"installscript", "99 bottles of beer on the wall", "99 bottles of beer on the wall", 1},
{ "apple_count", "%d apple(s)", "%d apple(s)", 1}, {"apple_count", "%d apple(s)", "%d apple(s)", 1},
{ "apple_count", "%d apple(s)", "%d apple(s)", 42}, {"apple_count", "%d apple(s)", "%d apple(s)", 42},
}, },
}, },
@@ -105,6 +137,7 @@ TESTS := []Test_Suite{
{ {
file = "assets/I18N/duplicate-key.ts", file = "assets/I18N/duplicate-key.ts",
loader = i18n.parse_qt_linguist_file, loader = i18n.parse_qt_linguist_file,
plural = nil, // Default pluralizer
options = {merge_sections = true}, options = {merge_sections = true},
err = .Duplicate_Key, err = .Duplicate_Key,
}, },
@@ -113,6 +146,7 @@ TESTS := []Test_Suite{
{ {
file = "assets/I18N/duplicate-key.ts", file = "assets/I18N/duplicate-key.ts",
loader = i18n.parse_qt_linguist_file, loader = i18n.parse_qt_linguist_file,
plural = nil, // Default pluralizer
}, },
} }
@@ -122,7 +156,7 @@ tests :: proc(t: ^testing.T) {
err: i18n.Error err: i18n.Error
for suite in TESTS { for suite in TESTS {
cat, err = suite.loader(suite.file, suite.options, nil, context.allocator) cat, err = suite.loader(suite.file, suite.options, suite.plural, context.allocator)
msg := fmt.tprintf("Expected loading %v to return %v, got %v", suite.file, suite.err, err) msg := fmt.tprintf("Expected loading %v to return %v, got %v", suite.file, suite.err, err)
expect(t, err == suite.err, msg) expect(t, err == suite.err, msg)