Browse Source

i18n: Add section merge + duplicate key detection to gettext.

Jeroen van Rijn 1 year ago
parent
commit
f8c4ee3d3c
2 changed files with 27 additions and 7 deletions
  1. 15 4
      core/text/i18n/gettext.odin
  2. 12 3
      tests/core/text/i18n/test_core_text_i18n.odin

+ 15 - 4
core/text/i18n/gettext.odin

@@ -93,9 +93,9 @@ parse_mo_from_bytes :: proc(data: []byte, options := DEFAULT_PARSE_OPTIONS, plur
 			return translation, .MO_File_Incorrect_Plural_Count
 			return translation, .MO_File_Incorrect_Plural_Count
 		}
 		}
 
 
-		section_name := ""
 		for k in keys {
 		for k in keys {
-			key := string(k)
+			section_name := ""
+			key          := string(k)
 
 
 			// Scan for <context>EOT<key>
 			// Scan for <context>EOT<key>
 			for ch, i in k {
 			for ch, i in k {
@@ -105,12 +105,25 @@ parse_mo_from_bytes :: proc(data: []byte, options := DEFAULT_PARSE_OPTIONS, plur
 					break
 					break
 				}
 				}
 			}
 			}
+
+			// If we merge sections, then all entries end in the "" context.
+			if options.merge_sections {
+				section_name = ""
+			}
+
 			section_name, _ = strings.intern_get(&translation.intern, section_name)
 			section_name, _ = strings.intern_get(&translation.intern, section_name)
 			if section_name not_in translation.k_v {
 			if section_name not_in translation.k_v {
 				translation.k_v[section_name] = {}
 				translation.k_v[section_name] = {}
 			}
 			}
 
 
+			section         := &translation.k_v[section_name]
 			interned_key, _ := strings.intern_get(&translation.intern, string(key))
 			interned_key, _ := strings.intern_get(&translation.intern, string(key))
+
+			// Duplicate key should not be allowed.
+			if interned_key in section {
+				return translation, .Duplicate_Key
+			}
+
 			interned_vals := make([]string, len(vals))
 			interned_vals := make([]string, len(vals))
 			last_val: string
 			last_val: string
 
 
@@ -118,8 +131,6 @@ parse_mo_from_bytes :: proc(data: []byte, options := DEFAULT_PARSE_OPTIONS, plur
 				interned_vals[i], _ = strings.intern_get(&translation.intern, string(v))
 				interned_vals[i], _ = strings.intern_get(&translation.intern, string(v))
 				last_val = interned_vals[i]
 				last_val = interned_vals[i]
 			}
 			}
-
-			section := &translation.k_v[section_name]
 			section[interned_key] = interned_vals
 			section[interned_key] = interned_vals
 		}
 		}
 	}
 	}

+ 12 - 3
tests/core/text/i18n/test_core_text_i18n.odin

@@ -86,6 +86,15 @@ TESTS := []Test_Suite{
 		},
 		},
 	},
 	},
 
 
+	{
+		file    = "assets/I18N/mixed_context.mo",
+		loader  = i18n.parse_mo_file,
+		plural  = nil,
+		// Message1 exists twice, once within Context, which has been merged into ""
+		err     = .Duplicate_Key,
+		options = {merge_sections = true},
+	},
+
 	{
 	{
 		file   = "assets/I18N/nl_NL.mo",
 		file   = "assets/I18N/nl_NL.mo",
 		loader = i18n.parse_mo_file,
 		loader = i18n.parse_mo_file,
@@ -128,7 +137,7 @@ 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
+		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.
@@ -151,7 +160,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
+		plural  = nil, // Default pluralizer
 		options = {merge_sections = true},
 		options = {merge_sections = true},
 		err     = .Duplicate_Key,
 		err     = .Duplicate_Key,
 	},
 	},
@@ -160,7 +169,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
+		plural  = nil, // Default pluralizer
 	},
 	},
 }
 }